]>
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 MT |
24 | import pakfire.downloader |
25 | ||
47a4cb89 | 26 | from base import Package |
e0636b31 | 27 | from file import BinaryPackage |
4f91860e | 28 | |
e871a081 | 29 | import pakfire.util as util |
4f91860e | 30 | from pakfire.constants import * |
47a4cb89 | 31 | |
fa6d335b MT |
32 | class DatabasePackage(Package): |
33 | type = "db" | |
47a4cb89 | 34 | |
4f91860e MT |
35 | def __init__(self, pakfire, repo, db, data): |
36 | Package.__init__(self, pakfire, repo) | |
3723913b | 37 | |
47a4cb89 MT |
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 | |
8537c16d | 99 | def groups(self): |
e74f185d MT |
100 | groups = self.metadata.get("groups", "") |
101 | ||
102 | if groups: | |
103 | return groups.split() | |
104 | ||
105 | return [] | |
47a4cb89 MT |
106 | |
107 | @property | |
0c665250 MT |
108 | def build_date(self): |
109 | return self.metadata.get("build_date") | |
110 | ||
111 | @property | |
112 | def build_time(self): | |
b566f7e3 MT |
113 | build_time = self.metadata.get("build_time", 0) |
114 | ||
6b151a68 MT |
115 | try: |
116 | return int(build_time) | |
117 | except TypeError: | |
118 | return 0 | |
47a4cb89 MT |
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 | ||
1317485d MT |
128 | @property |
129 | def uuid(self): | |
130 | return self.metadata.get("uuid") | |
131 | ||
e399ad3a MT |
132 | @property |
133 | def size(self): | |
a5f5fced | 134 | return self.metadata.get("size", 0) |
e399ad3a | 135 | |
0304200a MT |
136 | @property |
137 | def inst_size(self): | |
138 | # XXX to be done | |
139 | return 0 | |
140 | ||
47a4cb89 MT |
141 | @property |
142 | def provides(self): | |
c605d735 | 143 | return self.metadata.get("provides", "").split() |
47a4cb89 MT |
144 | |
145 | @property | |
146 | def requires(self): | |
c605d735 | 147 | return self.metadata.get("requires", "").split() |
47a4cb89 MT |
148 | |
149 | @property | |
150 | def conflicts(self): | |
c605d735 | 151 | return self.metadata.get("conflicts", "").split() |
ae20b05f MT |
152 | |
153 | @property | |
154 | def obsoletes(self): | |
c605d735 | 155 | return self.metadata.get("obsoletes", "").split() |
47a4cb89 | 156 | |
4f91860e MT |
157 | @property |
158 | def hash1(self): | |
159 | return self.metadata.get("hash1") | |
160 | ||
a5f5fced MT |
161 | @property |
162 | def scriptlet(self): | |
163 | return self.metadata.get("scriptlet") | |
164 | ||
4f91860e MT |
165 | @property |
166 | def filename(self): | |
167 | return self.metadata.get("filename") # XXX basename? | |
168 | ||
47a4cb89 MT |
169 | @property |
170 | def filelist(self): | |
ae20b05f MT |
171 | c = self.db.cursor() |
172 | try: | |
b6da0663 | 173 | c.execute("SELECT name FROM files WHERE pkg = ?", (self.id,)) |
47a4cb89 | 174 | |
ae20b05f MT |
175 | return [f["name"] for f in c] |
176 | finally: | |
b6da0663 | 177 | c.close() |
47a4cb89 | 178 | |
6ee3d6b9 MT |
179 | @property |
180 | def configfiles(self): | |
181 | return [] # XXX to be done | |
182 | ||
a88d2cdc MT |
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() | |
311ce792 | 188 | c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?", |
a2d1644c | 189 | (requires.requires, self.id)) |
a88d2cdc MT |
190 | |
191 | ret = False | |
192 | for pkg in c: | |
a2d1644c MT |
193 | ret = True |
194 | break | |
a88d2cdc MT |
195 | |
196 | c.close() | |
197 | ||
198 | return ret | |
199 | ||
14ea3228 | 200 | def download(self, text=""): |
4f91860e MT |
201 | """ |
202 | Downloads the package from repository and returns a new instance | |
203 | of BinaryPackage. | |
204 | """ | |
d4c94aa5 MT |
205 | |
206 | # XXX a bit hacky, but InstalledRepository has no cache. | |
207 | if self.repo.name == "installed": | |
208 | return self | |
209 | ||
4f91860e MT |
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: | |
4f91860e MT |
229 | # Make sure filename is of type string (and not unicode) |
230 | filename = str(self.filename) | |
231 | ||
14ea3228 MT |
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") | |
4f91860e MT |
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) | |
fa6d335b | 257 | |
e871a081 MT |
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 | ||
fa6d335b MT |
279 | # XXX maybe we can remove this later? |
280 | class InstalledPackage(DatabasePackage): | |
281 | type = "installed" | |
282 |