]> git.donarmstrong.com Git - neurodebian.git/blob - deb2rst/archive.py
Initial import.
[neurodebian.git] / deb2rst / archive.py
1 import urllib
2 import apt_pkg as ap
3 import apt
4 from ConfigParser import SafeConfigParser
5 import gzip
6 import subprocess
7
8 class DebianPkgArchive(SafeConfigParser):
9     """
10     """
11     def __init__(self, dists):
12         """
13         :Parameter:
14           dists: list
15             List of Release file URLs, one for each distribution in the archive.
16         """
17         SafeConfigParser.__init__(self)
18
19         for dist in dists:
20             filename, ignored = urllib.urlretrieve(dist)
21             baseurl = '/'.join(dist.split('/')[:-1])
22             self._parseDistribution(filename, baseurl)
23             urllib.urlcleanup()
24
25
26     def __repr__(self):
27         """Generate INI file content for current content.
28         """
29         # make adaptor to use str as file-like (needed for ConfigParser.write()
30         class file2str(object):
31             def __init__(self):
32                 self.__s = ''
33             def write(self, val):
34                 self.__s += val
35             def str(self):
36                 return self.__s
37
38         r = file2str()
39         self.write(r)
40
41         return r.str()
42
43
44     def save(self, filename):
45         """Write current content to a file.
46         """
47         f = open(filename, 'w')
48         self.write(f)
49         f.close()
50
51
52     def ensureUnique(self, section, option, value):
53         if not self.has_option(section, option):
54             self.set(section, option, value)
55         else:
56             if not self.get(section, option) == value:
57                 raise ValueError, "%s: %s is not unique (%s != %s)" \
58                                   % (section, option,
59                                      self.get(section, option), value)
60
61
62     def appendUniqueCSV(self, section, option, value):
63         """
64         """
65         if not self.has_option(section, option):
66             self.set(section, option, value)
67         else:
68             l = self.get(section, option).split(', ')
69             if not value in l:
70                 self.set(section, option, ', '.join(l + [value]))
71
72
73     def _parseDistribution(self, rfile, baseurl):
74         """
75         :Parameter:
76           rfile: filename
77             Release file for the distribution
78           baseurl: str
79             Base URL of this distribution. This path contains the Release file.
80         """
81         # create parser instance
82         rparser = ap.ParseTagFile(open(rfile, 'r'))
83         # get release section content
84         rparser.Step()
85
86         # architectures on this dist
87         archs = rparser.Section['Architectures'].split()
88         components = rparser.Section['Components'].split()
89         codename = rparser.Section['Codename']
90
91         # compile the list of Packages files to parse and parse them
92         for c in components:
93             for a in archs:
94                 # compile URL
95                 pkgsurl = '/'.join([baseurl, c, 'binary-' + a, 'Packages.gz'])
96                 # retrieve
97                 filename, ignored = urllib.urlretrieve(pkgsurl)
98                 # decompress
99                 subprocess.call(['gzip', '-d', filename])
100                 # parse
101                 self._parsePkgsFile(filename[:-3], codename, c)
102             break
103
104
105     def _parsePkgsFile(self, pfile, codename, component):
106         """
107         :Parameters:
108           pfile: Packages filename
109           codename: str
110             Codename of the release
111           component: str
112             The archive component this packages file corresponds to.
113         """
114         pp = ap.ParseTagFile(open(pfile, 'r'))
115
116         while pp.Step():
117             sec = pp.Section
118             self._storePkg(sec, codename, component)
119
120
121     def _storePkg(self, psec, codename, component):
122         """
123         :Parameter:
124           psec: apt_pkg parser section
125         """
126         pkg = psec['Package']
127
128         if not self.has_section(pkg):
129             self.add_section(pkg)
130
131         # which releases
132         self.appendUniqueCSV(pkg, "releases", codename)
133
134         # arch listing
135         self.appendUniqueCSV(pkg, "archs %s" % codename, psec['Architecture'])
136
137         # versions
138         self.ensureUnique(pkg,
139                           "version %s %s" % (codename, psec['Architecture']),
140                           psec['Version'])
141
142         # now the stuff where a single variant is sufficient and where we go for
143         # the latest available one
144         if self.has_option(pkg, "newest version") \
145             and apt.VersionCompare(psec['Version'],
146                                    self.get(pkg, "newest version")) < 0:
147             return
148
149         # everything from here will overwrite existing ones
150
151         # we seems to have an updated package
152         self.set(pkg, "newest version", psec['Version'])
153
154         # description
155         self.set(pkg, "description", psec['Description'])
156
157         # optional stuff
158         if psec.has_key('Homepage'):
159             self.set(pkg, 'homepage', psec['Homepage'])
160
161
162 def genPkgPage(db, pkg):
163     """
164     :Parameters:
165       db: database
166       pkg: str
167         Package name
168     """
169     pass
170
171
172
173 dpa = DebianPkgArchive(
174         [
175             'http://elrond/debian/dists/dapper/Release',
176 #            'http://elrond/debian/dists/etch/Release',
177         ])
178 print dpa