]> git.ipfire.org Git - people/ms/pakfire.git/blob - python/pakfire/packages/installed.py
Add "vendor" to database and add possibility to migrate databases.
[people/ms/pakfire.git] / python / pakfire / packages / installed.py
1 #!/usr/bin/python
2 ###############################################################################
3 # #
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
6 # #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
11 # #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
16 # #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 # #
20 ###############################################################################
21
22 import os
23
24 import pakfire.downloader
25 import pakfire.filelist
26
27 from base import Package
28 from file import BinaryPackage
29
30 import pakfire.util as util
31 from pakfire.constants import *
32
33 class DatabasePackage(Package):
34 type = "db"
35
36 def __init__(self, pakfire, repo, db, data):
37 Package.__init__(self, pakfire, repo)
38
39 self.db = db
40
41 self._data = {}
42
43 for key in data.keys():
44 self._data[key] = data[key]
45
46 def __repr__(self):
47 return "<%s %s>" % (self.__class__.__name__, self.friendly_name)
48
49 @property
50 def metadata(self):
51 return self._data
52
53 @property
54 def id(self):
55 id = self.metadata.get("id")
56 if not id:
57 id = 0
58
59 return id
60
61 @property
62 def name(self):
63 return self.metadata.get("name")
64
65 @property
66 def version(self):
67 return self.metadata.get("version")
68
69 @property
70 def release(self):
71 return self.metadata.get("release")
72
73 @property
74 def epoch(self):
75 epoch = self.metadata.get("epoch", 0)
76
77 return int(epoch)
78
79 @property
80 def arch(self):
81 return self.metadata.get("arch")
82
83 @property
84 def maintainer(self):
85 return self.metadata.get("maintainer")
86
87 @property
88 def license(self):
89 return self.metadata.get("license")
90
91 @property
92 def summary(self):
93 return self.metadata.get("summary")
94
95 @property
96 def description(self):
97 return self.metadata.get("description")
98
99 @property
100 def groups(self):
101 groups = self.metadata.get("groups", "")
102
103 if groups:
104 return groups.split()
105
106 return []
107
108 @property
109 def build_date(self):
110 return self.metadata.get("build_date")
111
112 @property
113 def build_time(self):
114 build_time = self.metadata.get("build_time", 0)
115
116 try:
117 return int(build_time)
118 except TypeError:
119 return 0
120
121 @property
122 def build_host(self):
123 return self.metadata.get("build_host")
124
125 @property
126 def build_id(self):
127 return self.metadata.get("build_id")
128
129 @property
130 def vendor(self):
131 return self.metadata.get("vendor")
132
133 @property
134 def uuid(self):
135 return self.metadata.get("uuid")
136
137 @property
138 def size(self):
139 return self.metadata.get("size", 0)
140
141 @property
142 def inst_size(self):
143 # XXX to be done
144 return 0
145
146 @property
147 def provides(self):
148 return self.metadata.get("provides", "").split()
149
150 @property
151 def requires(self):
152 return self.metadata.get("requires", "").split()
153
154 @property
155 def conflicts(self):
156 return self.metadata.get("conflicts", "").split()
157
158 @property
159 def obsoletes(self):
160 return self.metadata.get("obsoletes", "").split()
161
162 @property
163 def hash1(self):
164 return self.metadata.get("hash1")
165
166 @property
167 def scriptlet(self):
168 return self.metadata.get("scriptlet")
169
170 @property
171 def filename(self):
172 return self.metadata.get("filename") # XXX basename?
173
174 @property
175 def filelist(self):
176 filelist = []
177
178 c = self.db.cursor()
179 c.execute("SELECT id FROM files WHERE pkg = ?", (self.id,))
180
181 for id in c:
182 file = pakfire.filelist.FileDatabase(self.pakfire, self.db, id[0])
183 filelist.append(file)
184
185 return filelist
186
187 @property
188 def configfiles(self):
189 ret = []
190
191 for file in self.filelist:
192 if not file.is_config():
193 continue
194
195 ret.append(file)
196
197 return ret
198
199 def _does_provide_file(self, requires):
200 """
201 A faster version to find a file in the database.
202 """
203 c = self.db.cursor()
204 c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?",
205 (requires.requires, self.id))
206
207 ret = False
208 for pkg in c:
209 ret = True
210 break
211
212 c.close()
213
214 return ret
215
216 def download(self, text=""):
217 """
218 Downloads the package from repository and returns a new instance
219 of BinaryPackage.
220 """
221
222 # XXX a bit hacky, but InstalledRepository has no cache.
223 if self.repo.name == "installed":
224 return self
225
226 # Marker, if we need to download the package.
227 download = True
228
229 # Add shortcut for cache.
230 cache = self.repo.cache
231
232 cache_filename = "packages/%s" % os.path.basename(self.filename)
233
234 # Check if file already exists in cache.
235 if cache.exists(cache_filename):
236 # If the file does already exist, we check if the hash1 matches.
237 if cache.verify(cache_filename, self.hash1):
238 # We already got the right file. Skip download.
239 download = False
240 else:
241 # The file in cache has a wrong hash. Remove it and repeat download.
242 cache.remove(cache_filename)
243
244 if download:
245 # Make sure filename is of type string (and not unicode)
246 filename = str(self.filename)
247
248 # Get a package grabber and add mirror download capabilities to it.
249 grabber = pakfire.downloader.PackageDownloader(
250 text=text + os.path.basename(filename),
251 )
252 grabber = self.repo.mirrors.group(grabber)
253
254 i = grabber.urlopen(filename)
255
256 # Open input and output files and download the file.
257 o = cache.open(cache_filename, "w")
258
259 buf = i.read(BUFFER_SIZE)
260 while buf:
261 o.write(buf)
262 buf = i.read(BUFFER_SIZE)
263
264 i.close()
265 o.close()
266
267 # Verify if the download was okay.
268 if not cache.verify(cache_filename, self.hash1):
269 raise Exception, "XXX this should never happen..."
270
271 filename = os.path.join(cache.path, cache_filename)
272 return BinaryPackage(self.pakfire, self.repo, filename)
273
274 def cleanup(self, message, prefix):
275 c = self.db.cursor()
276
277 # Get all files, that are in this package and check for all of
278 # them if they need to be removed.
279 files = self.filelist
280
281 # Fetch the whole filelist of the system from the database and create
282 # a diff. Exclude files from this package - of course.
283 c.execute("SELECT name FROM files WHERE pkg != ?", (self.id,))
284
285 for row in c:
286 # Check if file in filelist.
287 for f in files:
288 if not row["name"] == f.name:
289 continue
290
291 files.remove(f)
292 break
293 c.close()
294
295 self._remove_files(files, message, prefix)
296
297
298 # XXX maybe we can remove this later?
299 class InstalledPackage(DatabasePackage):
300 type = "installed"
301