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