]>
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 | ||
1317485d MT |
129 | @property |
130 | def uuid(self): | |
131 | return self.metadata.get("uuid") | |
132 | ||
e399ad3a MT |
133 | @property |
134 | def size(self): | |
a5f5fced | 135 | return self.metadata.get("size", 0) |
e399ad3a | 136 | |
0304200a MT |
137 | @property |
138 | def inst_size(self): | |
139 | # XXX to be done | |
140 | return 0 | |
141 | ||
47a4cb89 MT |
142 | @property |
143 | def provides(self): | |
c605d735 | 144 | return self.metadata.get("provides", "").split() |
47a4cb89 MT |
145 | |
146 | @property | |
147 | def requires(self): | |
c605d735 | 148 | return self.metadata.get("requires", "").split() |
47a4cb89 MT |
149 | |
150 | @property | |
151 | def conflicts(self): | |
c605d735 | 152 | return self.metadata.get("conflicts", "").split() |
ae20b05f MT |
153 | |
154 | @property | |
155 | def obsoletes(self): | |
c605d735 | 156 | return self.metadata.get("obsoletes", "").split() |
47a4cb89 | 157 | |
4f91860e MT |
158 | @property |
159 | def hash1(self): | |
160 | return self.metadata.get("hash1") | |
161 | ||
a5f5fced MT |
162 | @property |
163 | def scriptlet(self): | |
164 | return self.metadata.get("scriptlet") | |
165 | ||
4f91860e MT |
166 | @property |
167 | def filename(self): | |
168 | return self.metadata.get("filename") # XXX basename? | |
169 | ||
47a4cb89 MT |
170 | @property |
171 | def filelist(self): | |
862bea4d MT |
172 | filelist = [] |
173 | ||
ae20b05f | 174 | c = self.db.cursor() |
862bea4d MT |
175 | c.execute("SELECT id FROM files WHERE pkg = ?", (self.id,)) |
176 | ||
177 | for id in c: | |
178 | file = pakfire.filelist.FileDatabase(self.pakfire, self.db, id[0]) | |
179 | filelist.append(file) | |
47a4cb89 | 180 | |
862bea4d | 181 | return filelist |
47a4cb89 | 182 | |
6ee3d6b9 MT |
183 | @property |
184 | def configfiles(self): | |
185 | return [] # XXX to be done | |
186 | ||
a88d2cdc MT |
187 | def _does_provide_file(self, requires): |
188 | """ | |
189 | A faster version to find a file in the database. | |
190 | """ | |
191 | c = self.db.cursor() | |
311ce792 | 192 | c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?", |
a2d1644c | 193 | (requires.requires, self.id)) |
a88d2cdc MT |
194 | |
195 | ret = False | |
196 | for pkg in c: | |
a2d1644c MT |
197 | ret = True |
198 | break | |
a88d2cdc MT |
199 | |
200 | c.close() | |
201 | ||
202 | return ret | |
203 | ||
14ea3228 | 204 | def download(self, text=""): |
4f91860e MT |
205 | """ |
206 | Downloads the package from repository and returns a new instance | |
207 | of BinaryPackage. | |
208 | """ | |
d4c94aa5 MT |
209 | |
210 | # XXX a bit hacky, but InstalledRepository has no cache. | |
211 | if self.repo.name == "installed": | |
212 | return self | |
213 | ||
4f91860e MT |
214 | # Marker, if we need to download the package. |
215 | download = True | |
216 | ||
217 | # Add shortcut for cache. | |
218 | cache = self.repo.cache | |
219 | ||
220 | cache_filename = "packages/%s" % os.path.basename(self.filename) | |
221 | ||
222 | # Check if file already exists in cache. | |
223 | if cache.exists(cache_filename): | |
224 | # If the file does already exist, we check if the hash1 matches. | |
225 | if cache.verify(cache_filename, self.hash1): | |
226 | # We already got the right file. Skip download. | |
227 | download = False | |
228 | else: | |
229 | # The file in cache has a wrong hash. Remove it and repeat download. | |
230 | cache.remove(cache_filename) | |
231 | ||
232 | if download: | |
4f91860e MT |
233 | # Make sure filename is of type string (and not unicode) |
234 | filename = str(self.filename) | |
235 | ||
14ea3228 MT |
236 | # Get a package grabber and add mirror download capabilities to it. |
237 | grabber = pakfire.downloader.PackageDownloader( | |
238 | text=text + os.path.basename(filename), | |
239 | ) | |
240 | grabber = self.repo.mirrors.group(grabber) | |
241 | ||
242 | i = grabber.urlopen(filename) | |
243 | ||
244 | # Open input and output files and download the file. | |
245 | o = cache.open(cache_filename, "w") | |
4f91860e MT |
246 | |
247 | buf = i.read(BUFFER_SIZE) | |
248 | while buf: | |
249 | o.write(buf) | |
250 | buf = i.read(BUFFER_SIZE) | |
251 | ||
252 | i.close() | |
253 | o.close() | |
254 | ||
255 | # Verify if the download was okay. | |
256 | if not cache.verify(cache_filename, self.hash1): | |
257 | raise Exception, "XXX this should never happen..." | |
258 | ||
259 | filename = os.path.join(cache.path, cache_filename) | |
260 | return BinaryPackage(self.pakfire, self.repo, filename) | |
fa6d335b | 261 | |
e871a081 MT |
262 | def cleanup(self, message, prefix): |
263 | c = self.db.cursor() | |
264 | ||
265 | # Get all files, that are in this package and check for all of | |
266 | # them if they need to be removed. | |
267 | files = self.filelist | |
268 | ||
269 | # Fetch the whole filelist of the system from the database and create | |
270 | # a diff. Exclude files from this package - of course. | |
271 | c.execute("SELECT name FROM files WHERE pkg != ?", (self.id,)) | |
272 | ||
273 | for row in c: | |
274 | # Check if file in filelist. | |
275 | if row["name"] in files: | |
276 | files.remove(row["name"]) | |
277 | ||
278 | c.close() | |
279 | ||
280 | self._remove_files(files, message, prefix) | |
281 | ||
282 | ||
fa6d335b MT |
283 | # XXX maybe we can remove this later? |
284 | class InstalledPackage(DatabasePackage): | |
285 | type = "installed" | |
286 |