~afb/smart/mongodb

« back to all changes in this revision

Viewing changes to smart/backends/rpm/document.py

  • Committer: Anders F Bjorklund
  • Date: 2011-05-30 21:55:04 UTC
  • Revision ID: afb@users.sourceforge.net-20110530215504-cd6gn60llaocrv6z
initial implementation of rpm-mongo

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright (c) 2005 Canonical
 
3
# Copyright (c) 2004 Conectiva, Inc.
 
4
#
 
5
# Written by Anders F Bjorklund <afb@users.sourceforge.net>
 
6
#
 
7
# This file is part of Smart Package Manager.
 
8
#
 
9
# Smart Package Manager is free software; you can redistribute it and/or
 
10
# modify it under the terms of the GNU General Public License as published
 
11
# by the Free Software Foundation; either version 2 of the License, or (at
 
12
# your option) any later version.
 
13
#
 
14
# Smart Package Manager is distributed in the hope that it will be useful,
 
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
# General Public License for more details.
 
18
#
 
19
# You should have received a copy of the GNU General Public License
 
20
# along with Smart Package Manager; if not, write to the Free Software
 
21
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
22
#
 
23
from smart.cache import PackageInfo, Loader
 
24
from smart.backends.rpm.base import *
 
25
 
 
26
from smart import *
 
27
import posixpath
 
28
import locale
 
29
import os
 
30
import calendar
 
31
 
 
32
class RPMDocumentPackageInfo(PackageInfo):
 
33
 
 
34
    def __init__(self, package, loader, info):
 
35
        PackageInfo.__init__(self, package)
 
36
        self._loader = loader
 
37
        self._info = info
 
38
 
 
39
    def getURLs(self):
 
40
        url = self._info.get("Location")
 
41
        baseurl = self._info.get("BaseURL")
 
42
        if baseurl == '(none)': baseurl = None
 
43
        if url:
 
44
            return [posixpath.join(baseurl or self._loader._baseurl, str(url))]
 
45
        return []
 
46
 
 
47
    def getBuildTime(self):
 
48
        t = self._info.get("Buildtime")
 
49
        if t:
 
50
            return int(calendar.timegm(t.utctimetuple()))
 
51
        return None
 
52
 
 
53
    def getInstalledSize(self):
 
54
        return self._info.get("Size")
 
55
 
 
56
    def getSize(self, url):
 
57
        return self._info.get("Packagesize")
 
58
 
 
59
    def getMD5(self, url):
 
60
        return None
 
61
 
 
62
    def getSHA(self, url):
 
63
        return self._info.get("SHA")
 
64
 
 
65
    def getSHA256(self, url):
 
66
        return None
 
67
 
 
68
    def getDescription(self):
 
69
        return self._info.get("Description", "")
 
70
 
 
71
    def getSummary(self):
 
72
        return self._info.get("Summary", "")
 
73
 
 
74
    def getReferenceURLs(self):
 
75
        return [self._info.get("Url", "")]
 
76
 
 
77
    def getSource(self):
 
78
        sourcerpm = self._info.get("Sourcerpm", "")
 
79
        sourcerpm = sourcerpm.replace(".src", "")
 
80
        sourcerpm = sourcerpm.replace(".nosrc", "")
 
81
        return sourcerpm.replace(".rpm", "")
 
82
    
 
83
    def getGroup(self):
 
84
        return self._info.get("Group", "")
 
85
 
 
86
    def getLicense(self):
 
87
        return self._info.get("License", "")
 
88
 
 
89
 
 
90
class RPMDocumentLoader(Loader):
 
91
 
 
92
    def __init__(self, collection, filelistscoll, baseurl):
 
93
        Loader.__init__(self)
 
94
        self._collection = collection
 
95
        self._filelistscoll = filelistscoll
 
96
        self._baseurl = baseurl
 
97
        self._fileprovides = {}
 
98
        self._parsedflist = False
 
99
        self._pkgids = {}
 
100
 
 
101
    def reset(self):
 
102
        Loader.reset(self)
 
103
        self._fileprovides.clear()
 
104
        self._parsedflist = False
 
105
        self._pkgids.clear()
 
106
 
 
107
    def getInfo(self, pkg):
 
108
        return RPMDocumentPackageInfo(pkg, self, pkg.loaders[self])
 
109
 
 
110
    def getLoadSteps(self):
 
111
        return self._collection.count()
 
112
 
 
113
    def load(self):
 
114
        COMPMAP = { "EQ":"=", "LT":"<", "LE":"<=", "GT":">", "GE":">="}
 
115
 
 
116
        # Prepare progress reporting.
 
117
        progress = iface.getProgress(self._cache)
 
118
 
 
119
        # Prepare package information.
 
120
        reqdict = {}
 
121
        prvdict = {}
 
122
        upgdict = {}
 
123
        cnfdict = {}
 
124
        filedict = {}
 
125
            
 
126
        def strver(e, v, r):
 
127
            version = v
 
128
            if e and e != "0":
 
129
                version = "%s:%s" % (e, version)
 
130
            if r:
 
131
                version = "%s-%s" % (version, r)
 
132
            if version:
 
133
                return str(version)
 
134
            else:
 
135
                return None
 
136
 
 
137
        def strrel(flags):
 
138
            return COMPMAP.get(flags)
 
139
 
 
140
        for doc in self._collection.find():
 
141
            pkgid = str(doc["_id"])
 
142
            
 
143
            arch = str(doc["Arch"])
 
144
            if rpm.archscore(arch) == 0:
 
145
                progress.add(1)
 
146
                continue
 
147
 
 
148
            name = str(doc["Name"])
 
149
 
 
150
            e = doc["Epoch"]
 
151
            ver = doc["Version"]
 
152
            rel = doc["Release"]
 
153
            version = strver(e, ver, rel)
 
154
            
 
155
            for ename, erelation, e, ver, rel in doc["Requires"]:
 
156
                if (not ename or
 
157
                        ename[:7] in ("rpmlib(", "config(")):
 
158
                        continue
 
159
 
 
160
                ename = str(ename)
 
161
                erelation = strrel(erelation)
 
162
                eversion = strver(e, ver, rel)
 
163
                reqdict[(RPMRequires,
 
164
                        ename, erelation, eversion)] = True
 
165
 
 
166
            for ename, erelation, e, ver, rel in doc["Provides"]:
 
167
                ename = str(ename)
 
168
                erelation = strrel(erelation)
 
169
                eversion = strver(e, ver, rel)
 
170
                if ename[0] == "/":
 
171
                    filedict[ename] = True
 
172
                else:
 
173
                    if ename == name and eversion == version:
 
174
                        eversion = "%s@%s" % (eversion, arch)
 
175
                        Prv = RPMNameProvides
 
176
                    else:
 
177
                        Prv = RPMProvides
 
178
                    prvdict[(Prv, ename.encode('utf-8'), eversion)] = True
 
179
 
 
180
            for ename, erelation, e, ver, rel in doc["Obsoletes"]:
 
181
                ename = str(ename)
 
182
                erelation = strrel(erelation)
 
183
                eversion = strver(e, ver, rel)
 
184
                tup = (RPMObsoletes, ename, erelation, eversion)
 
185
                upgdict[tup] = True
 
186
                cnfdict[tup] = True
 
187
 
 
188
            for ename, erelation, e, ver, rel in doc["Conflicts"]:
 
189
                ename = str(ename)
 
190
                erelation = strrel(erelation)
 
191
                eversion = strver(e, ver, rel)
 
192
                cnfdict[(RPMConflicts,
 
193
                        ename, erelation, eversion)] = True
 
194
            
 
195
            for file, type in doc["Files"]:
 
196
                filedict[file] = True
 
197
 
 
198
            # Use all the information acquired to build the package.
 
199
 
 
200
            versionarch = str("%s@%s" % (version, arch))
 
201
 
 
202
            upgdict[(RPMObsoletes,
 
203
                             str(name), '<', versionarch)] = True
 
204
 
 
205
            reqargs = [x for x in reqdict
 
206
                               if not ((x[2] is None or "=" in x[2]) and
 
207
                                       (RPMProvides, x[1], x[3]) in prvdict or
 
208
                                       system_provides.match(*x[:3]))]
 
209
            prvargs = prvdict.keys()
 
210
            cnfargs = cnfdict.keys()
 
211
            upgargs = upgdict.keys()
 
212
 
 
213
            pkg = self.buildPackage((RPMPackage, str(name), versionarch),
 
214
                                    prvargs, reqargs, upgargs, cnfargs)
 
215
            pkg.loaders[self] = doc
 
216
 
 
217
            # Store the provided files for future usage.
 
218
            if filedict:
 
219
                for filename in filedict:
 
220
                    lst = self._fileprovides.get(filename)
 
221
                    if not lst:
 
222
                        self._fileprovides[filename] = [pkg]
 
223
                    else:
 
224
                        lst.append(pkg)
 
225
 
 
226
            if pkgid:
 
227
                self._pkgids[pkgid] = pkg
 
228
 
 
229
            # Reset all information.
 
230
            reqdict.clear()
 
231
            prvdict.clear()
 
232
            upgdict.clear()
 
233
            cnfdict.clear()
 
234
            filedict.clear()
 
235
 
 
236
            # Update progress
 
237
            progress.add(1)
 
238
            progress.show()
 
239
 
 
240
    def loadFileProvides(self, fndict):
 
241
        bfp = self.buildFileProvides
 
242
        parsed = self._parsedflist
 
243
        for fn in fndict:
 
244
            if fn not in self._fileprovides:
 
245
                if not parsed:
 
246
                    self._parsedflist = parsed = True
 
247
                    self.parseFilesList(fndict)
 
248
                    if fn not in self._fileprovides:
 
249
                        pkgs = self._fileprovides[fn] = ()
 
250
                    else:
 
251
                        pkgs = self._fileprovides[fn]
 
252
                else:
 
253
                    pkgs = self._fileprovides[fn] = ()
 
254
            else:
 
255
                pkgs = self._fileprovides[fn]
 
256
 
 
257
            if pkgs:
 
258
                for pkg in pkgs:
 
259
                    bfp(pkg, (RPMProvides, fn, None))
 
260
 
 
261
 
 
262
    def parseFilesList(self, fndict):
 
263
        pkgids = self._pkgids
 
264
        fileprovides = self._fileprovides
 
265
 
 
266
        if not self._filelistscoll:
 
267
            return
 
268
        
 
269
        for doc in self._filelistscoll.find():
 
270
            if doc["Arch"] == "src":
 
271
                continue
 
272
            pkg = pkgids.get(doc["_id"])
 
273
            for file, type in doc["Files"]:
 
274
                if file in fndict:
 
275
                    pkgs = fileprovides.get(file)
 
276
                    if not pkgs:
 
277
                        fileprovides[file] = [pkg]
 
278
                    else:
 
279
                        pkgs.append(pkg)
 
280
 
 
281
def enablePsyco(psyco):
 
282
    psyco.bind(RPMDocumentLoader.load)
 
283
    psyco.bind(RPMDocumentLoader.loadFileProvides)
 
284
    psyco.bind(RPMDocumentLoader.parseFilesList)
 
285
 
 
286
hooks.register("enable-psyco", enablePsyco)
 
287
 
 
288
# vim:ts=4:sw=4:et