]>
Commit | Line | Data |
---|---|---|
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 |
22 | import os |
23 | ||
14ea3228 | 24 | import pakfire.downloader |
862bea4d | 25 | import pakfire.filelist |
14ea3228 | 26 | |
47a4cb89 | 27 | from base import Package |
e0636b31 | 28 | from file import BinaryPackage |
4f91860e | 29 | |
e871a081 | 30 | import pakfire.util as util |
4f91860e | 31 | from pakfire.constants import * |
47a4cb89 | 32 | |
fa6d335b MT |
33 | class 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 = {} | |
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 | |
8537c16d | 100 | def groups(self): |
e74f185d MT |
101 | groups = self.metadata.get("groups", "") |
102 | ||
103 | if groups: | |
104 | return groups.split() | |
105 | ||
106 | return [] | |
47a4cb89 MT |
107 | |
108 | @property | |
0c665250 MT |
109 | def build_date(self): |
110 | return self.metadata.get("build_date") | |
111 | ||
112 | @property | |
113 | def build_time(self): | |
b566f7e3 MT |
114 | build_time = self.metadata.get("build_time", 0) |
115 | ||
6b151a68 MT |
116 | try: |
117 | return int(build_time) | |
118 | except TypeError: | |
119 | return 0 | |
47a4cb89 MT |
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 | ||
85a1120f MT |
129 | @property |
130 | def vendor(self): | |
131 | return self.metadata.get("vendor") | |
132 | ||
1317485d MT |
133 | @property |
134 | def uuid(self): | |
135 | return self.metadata.get("uuid") | |
136 | ||
e399ad3a MT |
137 | @property |
138 | def size(self): | |
a5f5fced | 139 | return self.metadata.get("size", 0) |
e399ad3a | 140 | |
0304200a MT |
141 | @property |
142 | def inst_size(self): | |
143 | # XXX to be done | |
144 | return 0 | |
145 | ||
47a4cb89 MT |
146 | @property |
147 | def provides(self): | |
c605d735 | 148 | return self.metadata.get("provides", "").split() |
47a4cb89 MT |
149 | |
150 | @property | |
151 | def requires(self): | |
c605d735 | 152 | return self.metadata.get("requires", "").split() |
47a4cb89 MT |
153 | |
154 | @property | |
155 | def conflicts(self): | |
c605d735 | 156 | return self.metadata.get("conflicts", "").split() |
ae20b05f MT |
157 | |
158 | @property | |
159 | def obsoletes(self): | |
c605d735 | 160 | return self.metadata.get("obsoletes", "").split() |
47a4cb89 | 161 | |
4f91860e MT |
162 | @property |
163 | def hash1(self): | |
164 | return self.metadata.get("hash1") | |
165 | ||
a5f5fced MT |
166 | @property |
167 | def scriptlet(self): | |
168 | return self.metadata.get("scriptlet") | |
169 | ||
4f91860e MT |
170 | @property |
171 | def filename(self): | |
172 | return self.metadata.get("filename") # XXX basename? | |
173 | ||
47a4cb89 MT |
174 | @property |
175 | def filelist(self): | |
862bea4d MT |
176 | filelist = [] |
177 | ||
ae20b05f | 178 | c = self.db.cursor() |
862bea4d MT |
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) | |
47a4cb89 | 184 | |
862bea4d | 185 | return filelist |
47a4cb89 | 186 | |
6ee3d6b9 MT |
187 | @property |
188 | def configfiles(self): | |
482d1ada MT |
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 | |
6ee3d6b9 | 198 | |
a88d2cdc MT |
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() | |
311ce792 | 204 | c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?", |
a2d1644c | 205 | (requires.requires, self.id)) |
a88d2cdc MT |
206 | |
207 | ret = False | |
208 | for pkg in c: | |
a2d1644c MT |
209 | ret = True |
210 | break | |
a88d2cdc MT |
211 | |
212 | c.close() | |
213 | ||
214 | return ret | |
215 | ||
14ea3228 | 216 | def download(self, text=""): |
4f91860e MT |
217 | """ |
218 | Downloads the package from repository and returns a new instance | |
219 | of BinaryPackage. | |
220 | """ | |
d4c94aa5 MT |
221 | |
222 | # XXX a bit hacky, but InstalledRepository has no cache. | |
223 | if self.repo.name == "installed": | |
224 | return self | |
225 | ||
4f91860e MT |
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: | |
4f91860e MT |
245 | # Make sure filename is of type string (and not unicode) |
246 | filename = str(self.filename) | |
247 | ||
14ea3228 MT |
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") | |
4f91860e MT |
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) | |
fa6d335b | 273 | |
e871a081 MT |
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. | |
9999260a | 283 | c.execute("SELECT DISTINCT name FROM files WHERE pkg != ?", (self.id,)) |
e871a081 | 284 | |
9999260a | 285 | installed_files = set() |
e871a081 | 286 | for row in c: |
9999260a | 287 | installed_files.add(row["name"]) |
e871a081 MT |
288 | c.close() |
289 | ||
9999260a MT |
290 | # List with files to be removed. |
291 | remove_files = [] | |
292 | ||
293 | for f in files: | |
294 | if f.name in installed_files: | |
295 | continue | |
296 | ||
297 | remove_files.append(f) | |
298 | ||
299 | self._remove_files(remove_files, message, prefix) | |
e871a081 MT |
300 | |
301 | ||
fa6d335b MT |
302 | # XXX maybe we can remove this later? |
303 | class InstalledPackage(DatabasePackage): | |
304 | type = "installed" | |
305 |