]> git.ipfire.org Git - pakfire.git/blame - python/pakfire/packages/installed.py
Fix display of installsizechange.
[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
4f91860e
MT
163 @property
164 def hash1(self):
165 return self.metadata.get("hash1")
166
a5f5fced
MT
167 @property
168 def scriptlet(self):
169 return self.metadata.get("scriptlet")
170
4f91860e
MT
171 @property
172 def filename(self):
9b68f47c 173 return self.metadata.get("filename")
4f91860e 174
47a4cb89
MT
175 @property
176 def filelist(self):
9b68f47c
MT
177 if self._filelist is None:
178 self._filelist = []
862bea4d 179
9b68f47c
MT
180 c = self.db.cursor()
181 c.execute("SELECT * FROM files WHERE pkg = ?", (self.id,))
862bea4d 182
9b68f47c
MT
183 for row in c.fetchall():
184 file = pakfire.filelist.FileDatabase(self.pakfire, self.db, row["id"], row)
185 self._filelist.append(file)
47a4cb89 186
9b68f47c 187 return self._filelist
47a4cb89 188
6ee3d6b9
MT
189 @property
190 def configfiles(self):
482d1ada
MT
191 ret = []
192
193 for file in self.filelist:
194 if not file.is_config():
195 continue
196
197 ret.append(file)
198
199 return ret
6ee3d6b9 200
a88d2cdc
MT
201 def _does_provide_file(self, requires):
202 """
203 A faster version to find a file in the database.
204 """
205 c = self.db.cursor()
311ce792 206 c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?",
a2d1644c 207 (requires.requires, self.id))
a88d2cdc
MT
208
209 ret = False
210 for pkg in c:
a2d1644c
MT
211 ret = True
212 break
a88d2cdc
MT
213
214 c.close()
215
216 return ret
217
14ea3228 218 def download(self, text=""):
4f91860e
MT
219 """
220 Downloads the package from repository and returns a new instance
221 of BinaryPackage.
222 """
d4c94aa5
MT
223
224 # XXX a bit hacky, but InstalledRepository has no cache.
225 if self.repo.name == "installed":
226 return self
227
4f91860e
MT
228 # Marker, if we need to download the package.
229 download = True
230
231 # Add shortcut for cache.
232 cache = self.repo.cache
233
234 cache_filename = "packages/%s" % os.path.basename(self.filename)
235
236 # Check if file already exists in cache.
237 if cache.exists(cache_filename):
238 # If the file does already exist, we check if the hash1 matches.
239 if cache.verify(cache_filename, self.hash1):
240 # We already got the right file. Skip download.
241 download = False
242 else:
243 # The file in cache has a wrong hash. Remove it and repeat download.
244 cache.remove(cache_filename)
245
246 if download:
4f91860e
MT
247 # Make sure filename is of type string (and not unicode)
248 filename = str(self.filename)
249
14ea3228
MT
250 # Get a package grabber and add mirror download capabilities to it.
251 grabber = pakfire.downloader.PackageDownloader(
252 text=text + os.path.basename(filename),
253 )
254 grabber = self.repo.mirrors.group(grabber)
255
256 i = grabber.urlopen(filename)
257
258 # Open input and output files and download the file.
259 o = cache.open(cache_filename, "w")
4f91860e
MT
260
261 buf = i.read(BUFFER_SIZE)
262 while buf:
263 o.write(buf)
264 buf = i.read(BUFFER_SIZE)
265
266 i.close()
267 o.close()
268
269 # Verify if the download was okay.
270 if not cache.verify(cache_filename, self.hash1):
271 raise Exception, "XXX this should never happen..."
272
273 filename = os.path.join(cache.path, cache_filename)
274 return BinaryPackage(self.pakfire, self.repo, filename)
fa6d335b 275
e871a081
MT
276 def cleanup(self, message, prefix):
277 c = self.db.cursor()
278
279 # Get all files, that are in this package and check for all of
280 # them if they need to be removed.
281 files = self.filelist
282
283 # Fetch the whole filelist of the system from the database and create
284 # a diff. Exclude files from this package - of course.
9999260a 285 c.execute("SELECT DISTINCT name FROM files WHERE pkg != ?", (self.id,))
e871a081 286
9999260a 287 installed_files = set()
e871a081 288 for row in c:
9999260a 289 installed_files.add(row["name"])
e871a081
MT
290 c.close()
291
9999260a
MT
292 # List with files to be removed.
293 remove_files = []
294
295 for f in files:
296 if f.name in installed_files:
297 continue
298
299 remove_files.append(f)
300
301 self._remove_files(remove_files, message, prefix)
e871a081 302
0f8d6745
MT
303 @property
304 def signatures(self):
305 # Database packages do not have any signatures.
306 return []
307
e871a081 308
fa6d335b
MT
309# XXX maybe we can remove this later?
310class InstalledPackage(DatabasePackage):
311 type = "installed"
312