]> git.ipfire.org Git - pakfire.git/blame - python/pakfire/packages/installed.py
QA: Fix replacing all sorts of python interpreters.
[pakfire.git] / python / pakfire / packages / installed.py
CommitLineData
47a4cb89 1#!/usr/bin/python
b792d887
MT
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###############################################################################
47a4cb89 21
4f91860e
MT
22import os
23
14ea3228 24import pakfire.downloader
862bea4d 25import pakfire.filelist
14ea3228 26
47a4cb89 27from base import Package
e0636b31 28from file import BinaryPackage
4f91860e 29
e871a081 30import pakfire.util as util
4f91860e 31from pakfire.constants import *
47a4cb89 32
fa6d335b
MT
33class DatabasePackage(Package):
34 type = "db"
47a4cb89 35
4f91860e
MT
36 def __init__(self, pakfire, repo, db, data):
37 Package.__init__(self, pakfire, repo)
3723913b 38
47a4cb89
MT
39 self.db = db
40
41 self._data = {}
9b68f47c 42 self._filelist = None
47a4cb89
MT
43
44 for key in data.keys():
45 self._data[key] = data[key]
46
47 def __repr__(self):
48 return "<%s %s>" % (self.__class__.__name__, self.friendly_name)
49
50 @property
51 def metadata(self):
52 return self._data
53
54 @property
55 def id(self):
56 id = self.metadata.get("id")
57 if not id:
58 id = 0
59
60 return id
61
62 @property
63 def name(self):
64 return self.metadata.get("name")
65
66 @property
67 def version(self):
68 return self.metadata.get("version")
69
70 @property
71 def release(self):
72 return self.metadata.get("release")
73
74 @property
75 def epoch(self):
76 epoch = self.metadata.get("epoch", 0)
77
78 return int(epoch)
79
80 @property
81 def arch(self):
82 return self.metadata.get("arch")
83
84 @property
85 def maintainer(self):
86 return self.metadata.get("maintainer")
87
88 @property
89 def license(self):
90 return self.metadata.get("license")
91
92 @property
93 def summary(self):
94 return self.metadata.get("summary")
95
96 @property
97 def description(self):
98 return self.metadata.get("description")
99
100 @property
8537c16d 101 def groups(self):
e74f185d
MT
102 groups = self.metadata.get("groups", "")
103
104 if groups:
105 return groups.split()
106
107 return []
47a4cb89
MT
108
109 @property
0c665250
MT
110 def build_date(self):
111 return self.metadata.get("build_date")
112
113 @property
114 def build_time(self):
b566f7e3
MT
115 build_time = self.metadata.get("build_time", 0)
116
6b151a68
MT
117 try:
118 return int(build_time)
119 except TypeError:
120 return 0
47a4cb89
MT
121
122 @property
123 def build_host(self):
124 return self.metadata.get("build_host")
125
126 @property
127 def build_id(self):
128 return self.metadata.get("build_id")
129
85a1120f
MT
130 @property
131 def vendor(self):
132 return self.metadata.get("vendor")
133
1317485d
MT
134 @property
135 def uuid(self):
136 return self.metadata.get("uuid")
137
e399ad3a
MT
138 @property
139 def size(self):
a5f5fced 140 return self.metadata.get("size", 0)
e399ad3a 141
0304200a
MT
142 @property
143 def inst_size(self):
144 # XXX to be done
145 return 0
146
47a4cb89
MT
147 @property
148 def provides(self):
63029754 149 return self.metadata.get("provides", "").splitlines()
47a4cb89
MT
150
151 @property
152 def requires(self):
63029754 153 return self.metadata.get("requires", "").splitlines()
47a4cb89
MT
154
155 @property
156 def conflicts(self):
63029754 157 return self.metadata.get("conflicts", "").splitlines()
ae20b05f
MT
158
159 @property
160 def obsoletes(self):
63029754 161 return self.metadata.get("obsoletes", "").splitlines()
47a4cb89 162
a60f0f7d
MT
163 @property
164 def recommends(self):
165 recommends = self.metadata.get("recommends", None)
166
167 if recommends:
168 return recommends.splitlines()
169
170 return []
171
172 @property
173 def suggests(self):
174 suggests = self.metadata.get("suggests", None)
175
176 if suggests:
177 return suggests.splitlines()
178
179 return []
180
4f91860e
MT
181 @property
182 def hash1(self):
183 return self.metadata.get("hash1")
184
a5f5fced
MT
185 @property
186 def scriptlet(self):
187 return self.metadata.get("scriptlet")
188
4f91860e
MT
189 @property
190 def filename(self):
9b68f47c 191 return self.metadata.get("filename")
4f91860e 192
47a4cb89
MT
193 @property
194 def filelist(self):
9b68f47c
MT
195 if self._filelist is None:
196 self._filelist = []
862bea4d 197
9b68f47c
MT
198 c = self.db.cursor()
199 c.execute("SELECT * FROM files WHERE pkg = ?", (self.id,))
862bea4d 200
9b68f47c
MT
201 for row in c.fetchall():
202 file = pakfire.filelist.FileDatabase(self.pakfire, self.db, row["id"], row)
203 self._filelist.append(file)
47a4cb89 204
9b68f47c 205 return self._filelist
47a4cb89 206
6ee3d6b9
MT
207 @property
208 def configfiles(self):
482d1ada
MT
209 ret = []
210
211 for file in self.filelist:
212 if not file.is_config():
213 continue
214
215 ret.append(file)
216
217 return ret
6ee3d6b9 218
a88d2cdc
MT
219 def _does_provide_file(self, requires):
220 """
221 A faster version to find a file in the database.
222 """
223 c = self.db.cursor()
311ce792 224 c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?",
a2d1644c 225 (requires.requires, self.id))
a88d2cdc
MT
226
227 ret = False
228 for pkg in c:
a2d1644c
MT
229 ret = True
230 break
a88d2cdc
MT
231
232 c.close()
233
234 return ret
235
14ea3228 236 def download(self, text=""):
4f91860e
MT
237 """
238 Downloads the package from repository and returns a new instance
239 of BinaryPackage.
240 """
d4c94aa5
MT
241
242 # XXX a bit hacky, but InstalledRepository has no cache.
243 if self.repo.name == "installed":
244 return self
245
4f91860e
MT
246 # Marker, if we need to download the package.
247 download = True
248
249 # Add shortcut for cache.
250 cache = self.repo.cache
251
252 cache_filename = "packages/%s" % os.path.basename(self.filename)
253
254 # Check if file already exists in cache.
255 if cache.exists(cache_filename):
256 # If the file does already exist, we check if the hash1 matches.
257 if cache.verify(cache_filename, self.hash1):
258 # We already got the right file. Skip download.
259 download = False
260 else:
261 # The file in cache has a wrong hash. Remove it and repeat download.
262 cache.remove(cache_filename)
263
264 if download:
4f91860e
MT
265 # Make sure filename is of type string (and not unicode)
266 filename = str(self.filename)
267
14ea3228
MT
268 # Get a package grabber and add mirror download capabilities to it.
269 grabber = pakfire.downloader.PackageDownloader(
270 text=text + os.path.basename(filename),
271 )
272 grabber = self.repo.mirrors.group(grabber)
273
274 i = grabber.urlopen(filename)
275
276 # Open input and output files and download the file.
277 o = cache.open(cache_filename, "w")
4f91860e
MT
278
279 buf = i.read(BUFFER_SIZE)
280 while buf:
281 o.write(buf)
282 buf = i.read(BUFFER_SIZE)
283
284 i.close()
285 o.close()
286
287 # Verify if the download was okay.
288 if not cache.verify(cache_filename, self.hash1):
289 raise Exception, "XXX this should never happen..."
290
291 filename = os.path.join(cache.path, cache_filename)
292 return BinaryPackage(self.pakfire, self.repo, filename)
fa6d335b 293
e871a081
MT
294 def cleanup(self, message, prefix):
295 c = self.db.cursor()
296
297 # Get all files, that are in this package and check for all of
298 # them if they need to be removed.
299 files = self.filelist
300
301 # Fetch the whole filelist of the system from the database and create
302 # a diff. Exclude files from this package - of course.
9999260a 303 c.execute("SELECT DISTINCT name FROM files WHERE pkg != ?", (self.id,))
e871a081 304
9999260a 305 installed_files = set()
e871a081 306 for row in c:
9999260a 307 installed_files.add(row["name"])
e871a081
MT
308 c.close()
309
9999260a
MT
310 # List with files to be removed.
311 remove_files = []
312
313 for f in files:
314 if f.name in installed_files:
315 continue
316
317 remove_files.append(f)
318
319 self._remove_files(remove_files, message, prefix)
e871a081 320
0f8d6745
MT
321 @property
322 def signatures(self):
323 # Database packages do not have any signatures.
324 return []
325
e871a081 326
fa6d335b
MT
327# XXX maybe we can remove this later?
328class InstalledPackage(DatabasePackage):
329 type = "installed"
330