]> git.ipfire.org Git - pakfire.git/blob - python/pakfire/packages/installed.py
Merge branch 'master' of ssh://git.ipfire.org/pub/git/oddments/pakfire
[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
26 from base import Package
27 from file import BinaryPackage
28
29 import pakfire.util as util
30 from pakfire.constants import *
31
32 class DatabasePackage(Package):
33 type = "db"
34
35 def __init__(self, pakfire, repo, db, data):
36 Package.__init__(self, pakfire, repo)
37
38 self.db = db
39
40 self._data = {}
41
42 for key in data.keys():
43 self._data[key] = data[key]
44
45 def __repr__(self):
46 return "<%s %s>" % (self.__class__.__name__, self.friendly_name)
47
48 @property
49 def metadata(self):
50 return self._data
51
52 @property
53 def id(self):
54 id = self.metadata.get("id")
55 if not id:
56 id = 0
57
58 return id
59
60 @property
61 def name(self):
62 return self.metadata.get("name")
63
64 @property
65 def version(self):
66 return self.metadata.get("version")
67
68 @property
69 def release(self):
70 return self.metadata.get("release")
71
72 @property
73 def epoch(self):
74 epoch = self.metadata.get("epoch", 0)
75
76 return int(epoch)
77
78 @property
79 def arch(self):
80 return self.metadata.get("arch")
81
82 @property
83 def maintainer(self):
84 return self.metadata.get("maintainer")
85
86 @property
87 def license(self):
88 return self.metadata.get("license")
89
90 @property
91 def summary(self):
92 return self.metadata.get("summary")
93
94 @property
95 def description(self):
96 return self.metadata.get("description")
97
98 @property
99 def groups(self):
100 groups = self.metadata.get("groups", "")
101
102 if groups:
103 return groups.split()
104
105 return []
106
107 @property
108 def build_date(self):
109 return self.metadata.get("build_date")
110
111 @property
112 def build_time(self):
113 build_time = self.metadata.get("build_time", 0)
114
115 try:
116 return int(build_time)
117 except TypeError:
118 return 0
119
120 @property
121 def build_host(self):
122 return self.metadata.get("build_host")
123
124 @property
125 def build_id(self):
126 return self.metadata.get("build_id")
127
128 @property
129 def uuid(self):
130 return self.metadata.get("uuid")
131
132 @property
133 def size(self):
134 return self.metadata.get("size", 0)
135
136 @property
137 def inst_size(self):
138 # XXX to be done
139 return 0
140
141 @property
142 def provides(self):
143 return self.metadata.get("provides", "").split()
144
145 @property
146 def requires(self):
147 return self.metadata.get("requires", "").split()
148
149 @property
150 def conflicts(self):
151 return self.metadata.get("conflicts", "").split()
152
153 @property
154 def obsoletes(self):
155 return self.metadata.get("obsoletes", "").split()
156
157 @property
158 def hash1(self):
159 return self.metadata.get("hash1")
160
161 @property
162 def scriptlet(self):
163 return self.metadata.get("scriptlet")
164
165 @property
166 def filename(self):
167 return self.metadata.get("filename") # XXX basename?
168
169 @property
170 def filelist(self):
171 c = self.db.cursor()
172 try:
173 c.execute("SELECT name FROM files WHERE pkg = ?", (self.id,))
174
175 return [f["name"] for f in c]
176 finally:
177 c.close()
178
179 @property
180 def configfiles(self):
181 return [] # XXX to be done
182
183 def _does_provide_file(self, requires):
184 """
185 A faster version to find a file in the database.
186 """
187 c = self.db.cursor()
188 c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?",
189 (requires.requires, self.id))
190
191 ret = False
192 for pkg in c:
193 ret = True
194 break
195
196 c.close()
197
198 return ret
199
200 def download(self, text=""):
201 """
202 Downloads the package from repository and returns a new instance
203 of BinaryPackage.
204 """
205
206 # XXX a bit hacky, but InstalledRepository has no cache.
207 if self.repo.name == "installed":
208 return self
209
210 # Marker, if we need to download the package.
211 download = True
212
213 # Add shortcut for cache.
214 cache = self.repo.cache
215
216 cache_filename = "packages/%s" % os.path.basename(self.filename)
217
218 # Check if file already exists in cache.
219 if cache.exists(cache_filename):
220 # If the file does already exist, we check if the hash1 matches.
221 if cache.verify(cache_filename, self.hash1):
222 # We already got the right file. Skip download.
223 download = False
224 else:
225 # The file in cache has a wrong hash. Remove it and repeat download.
226 cache.remove(cache_filename)
227
228 if download:
229 # Make sure filename is of type string (and not unicode)
230 filename = str(self.filename)
231
232 # Get a package grabber and add mirror download capabilities to it.
233 grabber = pakfire.downloader.PackageDownloader(
234 text=text + os.path.basename(filename),
235 )
236 grabber = self.repo.mirrors.group(grabber)
237
238 i = grabber.urlopen(filename)
239
240 # Open input and output files and download the file.
241 o = cache.open(cache_filename, "w")
242
243 buf = i.read(BUFFER_SIZE)
244 while buf:
245 o.write(buf)
246 buf = i.read(BUFFER_SIZE)
247
248 i.close()
249 o.close()
250
251 # Verify if the download was okay.
252 if not cache.verify(cache_filename, self.hash1):
253 raise Exception, "XXX this should never happen..."
254
255 filename = os.path.join(cache.path, cache_filename)
256 return BinaryPackage(self.pakfire, self.repo, filename)
257
258 def cleanup(self, message, prefix):
259 c = self.db.cursor()
260
261 # Get all files, that are in this package and check for all of
262 # them if they need to be removed.
263 files = self.filelist
264
265 # Fetch the whole filelist of the system from the database and create
266 # a diff. Exclude files from this package - of course.
267 c.execute("SELECT name FROM files WHERE pkg != ?", (self.id,))
268
269 for row in c:
270 # Check if file in filelist.
271 if row["name"] in files:
272 files.remove(row["name"])
273
274 c.close()
275
276 self._remove_files(files, message, prefix)
277
278
279 # XXX maybe we can remove this later?
280 class InstalledPackage(DatabasePackage):
281 type = "installed"
282