Merge lp:~mac9416/unwrapt/modularization into lp:unwrapt
- modularization
- Merge into stable
Proposed by
mac9416
Status: | Merged |
---|---|
Merged at revision: | 53 |
Proposed branch: | lp:~mac9416/unwrapt/modularization |
Merge into: | lp:unwrapt |
Diff against target: |
447 lines (+116/-84) 3 files modified
example.py (+6/-2) unwrapt/DefinitionBase.py (+5/-2) unwrapt/definitions/aptdef/__init__.py (+105/-80) |
To merge this branch: | bzr merge lp:~mac9416/unwrapt/modularization |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chris Oliver | Approve | ||
Review via email: mp+32608@code.launchpad.net |
This proposal has been superseded by a proposal from 2010-08-13.
Commit message
Description of the change
I tried to modularize a couple of things, and in the process hacked the existing code to pieces. There's still a lot of work to do, so feel free to do the same to mine. :-)
To post a comment you must log in.
Revision history for this message
mac9416 (mac9416) wrote : | # |
Revision history for this message
Chris Oliver (excid3) wrote : | # |
Yeah I did not update it because I wanted to make sure recent changes were tested in my personal branch before pushing. I think it was all good and I forgot to push. :P
Revision history for this message
Chris Oliver (excid3) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'example.py' | |||
2 | --- example.py 2010-08-01 19:34:08 +0000 | |||
3 | +++ example.py 2010-08-13 17:34:44 +0000 | |||
4 | @@ -29,7 +29,8 @@ | |||
5 | 29 | #apt.set_proxy({"http": "http://192.168.1.100:3128"}, "username", "password") | 29 | #apt.set_proxy({"http": "http://192.168.1.100:3128"}, "username", "password") |
6 | 30 | 30 | ||
7 | 31 | # Configure the apt client | 31 | # Configure the apt client |
9 | 32 | apt.set_architecture("amd64") | 32 | #apt.set_architecture("amd64") |
10 | 33 | apt.set_architecture("i386") | ||
11 | 33 | 34 | ||
12 | 34 | apt.set_status("/var/lib/dpkg/status") | 35 | apt.set_status("/var/lib/dpkg/status") |
13 | 35 | 36 | ||
14 | @@ -51,7 +52,10 @@ | |||
15 | 51 | 52 | ||
16 | 52 | print "%i available packages" % len(apt.get_available_package_names()) | 53 | print "%i available packages" % len(apt.get_available_package_names()) |
17 | 53 | 54 | ||
19 | 54 | #apt.update(directory="/var/lib/apt/lists", download=False) | 55 | #FIXME: /var/lib/apt is not the download directory. We should have the ability |
20 | 56 | # to individually specify the download directories. | ||
21 | 57 | #apt.set_download_directory("/var/lib/apt") | ||
22 | 58 | #apt.update(download=False) | ||
23 | 55 | 59 | ||
24 | 56 | apt.update() | 60 | apt.update() |
25 | 57 | 61 | ||
26 | 58 | 62 | ||
27 | === modified file 'unwrapt/DefinitionBase.py' | |||
28 | --- unwrapt/DefinitionBase.py 2010-08-01 19:34:08 +0000 | |||
29 | +++ unwrapt/DefinitionBase.py 2010-08-13 17:34:44 +0000 | |||
30 | @@ -90,6 +90,7 @@ | |||
31 | 90 | 90 | ||
32 | 91 | - directory is the location of the | 91 | - directory is the location of the |
33 | 92 | """ | 92 | """ |
34 | 93 | #FIXME: that docstring. | ||
35 | 93 | 94 | ||
36 | 94 | self.download_directory = os.path.abspath(os.path.expanduser(directory)) | 95 | self.download_directory = os.path.abspath(os.path.expanduser(directory)) |
37 | 95 | 96 | ||
38 | @@ -163,6 +164,7 @@ | |||
39 | 163 | 164 | ||
40 | 164 | pass | 165 | pass |
41 | 165 | 166 | ||
42 | 167 | |||
43 | 166 | @callback | 168 | @callback |
44 | 167 | def update(self, reporthook=None, directory=None, download=True): | 169 | def update(self, reporthook=None, directory=None, download=True): |
45 | 168 | """ | 170 | """ |
46 | @@ -202,6 +204,7 @@ | |||
47 | 202 | 204 | ||
48 | 203 | pass | 205 | pass |
49 | 204 | 206 | ||
50 | 207 | |||
51 | 205 | @callback | 208 | @callback |
52 | 206 | def get_latest_binary(self, package): | 209 | def get_latest_binary(self, package): |
53 | 207 | """ | 210 | """ |
54 | @@ -268,7 +271,8 @@ | |||
55 | 268 | 271 | ||
56 | 269 | For example: | 272 | For example: |
57 | 270 | 273 | ||
59 | 271 | client.mark_package("firefox") | 274 | package = client.get_latest_binary("firefox") |
60 | 275 | client.mark_package(package) | ||
61 | 272 | """ | 276 | """ |
62 | 273 | 277 | ||
63 | 274 | pass | 278 | pass |
64 | @@ -289,7 +293,6 @@ | |||
65 | 289 | For example: | 293 | For example: |
66 | 290 | 294 | ||
67 | 291 | client.apply_changes() | 295 | client.apply_changes() |
68 | 292 | |||
69 | 293 | """ | 296 | """ |
70 | 294 | 297 | ||
71 | 295 | pass | 298 | pass |
72 | 296 | 299 | ||
73 | === modified file 'unwrapt/definitions/aptdef/__init__.py' | |||
74 | --- unwrapt/definitions/aptdef/__init__.py 2010-08-01 19:34:08 +0000 | |||
75 | +++ unwrapt/definitions/aptdef/__init__.py 2010-08-13 17:34:44 +0000 | |||
76 | @@ -51,14 +51,12 @@ | |||
77 | 51 | 51 | ||
78 | 52 | 52 | ||
79 | 53 | #TODO: Move this code to proper library location | 53 | #TODO: Move this code to proper library location |
81 | 54 | def url_join(first, last): | 54 | def url_join(*args): |
82 | 55 | """ Returns full URL """ | 55 | """ Returns full URL """ |
89 | 56 | if first.endswith('/'): | 56 | # Strip any leading or trailing slashes from the parts. |
90 | 57 | if last.startswith('/'): return first + last[1:] | 57 | args = [x.strip("/") for x in args] |
91 | 58 | else: return first + last | 58 | |
92 | 59 | else: | 59 | return "/".join(args) |
87 | 60 | if last.startswith('/'): return first + last | ||
88 | 61 | else: return first + '/' + last | ||
93 | 62 | 60 | ||
94 | 63 | 61 | ||
95 | 64 | #class Repository(Base): | 62 | #class Repository(Base): |
96 | @@ -108,10 +106,15 @@ | |||
97 | 108 | 106 | ||
98 | 109 | 107 | ||
99 | 110 | def to_url(repository, architecture, format): | 108 | def to_url(repository, architecture, format): |
101 | 111 | return url_join(repository["url"], url_join(architecture, format)) | 109 | return url_join(repository["url"], architecture, format) |
102 | 112 | 110 | ||
103 | 113 | 111 | ||
104 | 114 | def to_filename(directory, url): | 112 | def to_filename(directory, url): |
105 | 113 | """ | ||
106 | 114 | Forms a full filename from a directory and url. | ||
107 | 115 | i.e. Strips the url of the protocol prefix, replaces all slashes with | ||
108 | 116 | underscores, and appends it to directory. | ||
109 | 117 | """ | ||
110 | 115 | return os.path.join(directory, url.split("//")[1].replace("/", "_")) | 118 | return os.path.join(directory, url.split("//")[1].replace("/", "_")) |
111 | 116 | 119 | ||
112 | 117 | 120 | ||
113 | @@ -147,8 +150,13 @@ | |||
114 | 147 | supported = ["amd64", "armel", "i386", "ia64", "powerpc", "sparc"] | 150 | supported = ["amd64", "armel", "i386", "ia64", "powerpc", "sparc"] |
115 | 148 | status_properties = ["Package", "Version", "Status", "Provides"] | 151 | status_properties = ["Package", "Version", "Status", "Provides"] |
116 | 149 | binary_dependencies = ["Pre-Depends", "Depends", "Recommends"] | 152 | binary_dependencies = ["Pre-Depends", "Depends", "Recommends"] |
118 | 150 | supported_statuses = ["install ok installed", "to be installed", "to be downloaded"] | 153 | supported_statuses = ["install ok installed", |
119 | 154 | "to be downloaded", | ||
120 | 155 | "dependency to be downloaded", | ||
121 | 156 | "to be installed", | ||
122 | 157 | "dependency to be installed"] | ||
123 | 151 | 158 | ||
124 | 159 | #FIXME: This seems redundant. Could it be moved to DefinitionBase? | ||
125 | 152 | def on_set_proxy(self, proxy, username=None, password=None): | 160 | def on_set_proxy(self, proxy, username=None, password=None): |
126 | 153 | self.proxy = {"proxy": proxy, | 161 | self.proxy = {"proxy": proxy, |
127 | 154 | "user": username, | 162 | "user": username, |
128 | @@ -184,7 +192,7 @@ | |||
129 | 184 | self.repositories[count]["url"] = url | 192 | self.repositories[count]["url"] = url |
130 | 185 | self.repositories[count]["dist"] = dist | 193 | self.repositories[count]["dist"] = dist |
131 | 186 | self.repositories[count]["section"] = section | 194 | self.repositories[count]["section"] = section |
133 | 187 | self.repositories[count]["url"] = url_join(url, url_join("dists", url_join(dist, section))) | 195 | self.repositories[count]["url"] = url_join(url, "dists", dist, section) |
134 | 188 | 196 | ||
135 | 189 | count += 1 | 197 | count += 1 |
136 | 190 | 198 | ||
137 | @@ -218,13 +226,22 @@ | |||
138 | 218 | """ | 226 | """ |
139 | 219 | This is a missing docstring ZOMG! | 227 | This is a missing docstring ZOMG! |
140 | 220 | """ | 228 | """ |
141 | 229 | |||
142 | 230 | if download: | ||
143 | 231 | self.on_download_lists(reporthook) | ||
144 | 232 | |||
145 | 233 | # Read the newly-downloaded lists. | ||
146 | 234 | self.on_read_lists() | ||
147 | 235 | |||
148 | 236 | |||
149 | 237 | def on_download_lists(self, reporthook=None): | ||
150 | 221 | 238 | ||
151 | 222 | directory = os.path.join(self.download_directory, "lists") | 239 | directory = os.path.join(self.download_directory, "lists") |
152 | 223 | 240 | ||
154 | 224 | #TODO: This function obviously needs to be split up and modularized :) | 241 | # If the download directory does not exist, create it |
155 | 242 | if not os.path.exists(directory): | ||
156 | 243 | os.makedirs(directory) | ||
157 | 225 | 244 | ||
158 | 226 | # This is a list of files we downloaded and now need to parse | ||
159 | 227 | downloaded = [] | ||
160 | 228 | for repo in self.__iter_repositories(): | 245 | for repo in self.__iter_repositories(): |
161 | 229 | 246 | ||
162 | 230 | # Build the strings | 247 | # Build the strings |
163 | @@ -232,31 +249,31 @@ | |||
164 | 232 | filename = to_filename(directory, url) | 249 | filename = to_filename(directory, url) |
165 | 233 | display_name = "Repository => %s / %s" % (repo["dist"], repo["section"]) | 250 | display_name = "Repository => %s / %s" % (repo["dist"], repo["section"]) |
166 | 234 | 251 | ||
167 | 235 | # If the download directory does not exist, create it | ||
168 | 236 | if not os.path.exists(directory): | ||
169 | 237 | os.makedirs(directory) | ||
170 | 238 | |||
171 | 239 | # Download | 252 | # Download |
172 | 240 | #TODO: pass proxy information and catch exceptions | 253 | #TODO: pass proxy information and catch exceptions |
173 | 241 | #TODO: Support bz2 and unarchived Packages files | 254 | #TODO: Support bz2 and unarchived Packages files |
174 | 242 | filename = "%s.gz" % filename | 255 | filename = "%s.gz" % filename |
186 | 243 | if download: | 256 | download_url("%s.gz" % url, filename, display_name, proxy=self.proxy["proxy"], username=self.proxy["user"], password=self.proxy["pass"]) |
187 | 244 | download_url("%s.gz" % url, filename, display_name, proxy=self.proxy["proxy"], username=self.proxy["user"], password=self.proxy["pass"]) | 257 | |
188 | 245 | downloaded.append((repo, filename)) | 258 | |
189 | 246 | 259 | def on_read_lists(self): | |
190 | 247 | #TODO: Improve this. For now we are just opening local files in | 260 | |
191 | 248 | # unextracted format (what you find in /var/lib/apt/lists) since | 261 | directory = os.path.join(self.download_directory, "lists") |
192 | 249 | # that's an easy way to do things. This won't open the gz files | 262 | |
193 | 250 | # that Unwrapt downloads however | 263 | lists = [] |
194 | 251 | else: # Files that are pre-downloaded | 264 | for repo in self.__iter_repositories(): |
195 | 252 | downloaded.append((repo, filename[:-3])) | 265 | |
196 | 253 | 266 | # Build the strings | |
197 | 267 | url = to_url(repo, self.architecture, "Packages") | ||
198 | 268 | filename = to_filename(directory, url) | ||
199 | 269 | filename = "%s.gz" % filename # Works only if the index files are gz | ||
200 | 270 | lists.append((repo, filename)) | ||
201 | 254 | 271 | ||
202 | 255 | self.packages = {} | 272 | self.packages = {} |
203 | 256 | 273 | ||
205 | 257 | total = len(downloaded) | 274 | total = len(lists) |
206 | 258 | # Now parse each file, extracting as necessary | 275 | # Now parse each file, extracting as necessary |
208 | 259 | for i, value in enumerate(downloaded): | 276 | for i, value in enumerate(lists): |
209 | 260 | repo, filename = value | 277 | repo, filename = value |
210 | 261 | 278 | ||
211 | 262 | # Display percent read | 279 | # Display percent read |
212 | @@ -264,17 +281,19 @@ | |||
213 | 264 | sys.stdout.write("\rReading package lists... %3i%%" % frac) | 281 | sys.stdout.write("\rReading package lists... %3i%%" % frac) |
214 | 265 | sys.stdout.flush() | 282 | sys.stdout.flush() |
215 | 266 | 283 | ||
217 | 267 | # Parse packages into dictionary | 284 | # Attempt to open the package list. |
218 | 268 | try: | 285 | try: |
219 | 269 | if filename.endswith(".gz"): | 286 | if filename.endswith(".gz"): |
220 | 270 | f = gzip.open(filename, "rb") | 287 | f = gzip.open(filename, "rb") |
221 | 271 | else: | 288 | else: |
228 | 272 | f = open(filename, "rb") | 289 | f = open(filename, "rb") |
229 | 273 | 290 | except: #FIXME: specify exception. | |
230 | 274 | self.__parse(repo, f) | 291 | logging.error("\nPackage list does not exist: %s" % filename) |
231 | 275 | f.close() | 292 | continue |
232 | 276 | except: | 293 | |
233 | 277 | logging.error("\nPackage list does not exist: %s" % filename) | 294 | # Parse packages into dictionary |
234 | 295 | self.__parse(repo, f) | ||
235 | 296 | f.close() | ||
236 | 278 | 297 | ||
237 | 279 | #TODO: Insert items into database | 298 | #TODO: Insert items into database |
238 | 280 | 299 | ||
239 | @@ -282,6 +301,7 @@ | |||
240 | 282 | sys.stdout.write("\n") | 301 | sys.stdout.write("\n") |
241 | 283 | 302 | ||
242 | 284 | logging.info("%i packages available" % len(self.packages)) | 303 | logging.info("%i packages available" % len(self.packages)) |
243 | 304 | |||
244 | 285 | 305 | ||
245 | 286 | def __parse(self, repo, f): | 306 | def __parse(self, repo, f): |
246 | 287 | """ | 307 | """ |
247 | @@ -328,7 +348,6 @@ | |||
248 | 328 | installed statuses. | 348 | installed statuses. |
249 | 329 | """ | 349 | """ |
250 | 330 | 350 | ||
251 | 331 | |||
252 | 332 | f = open(status, "rb") | 351 | f = open(status, "rb") |
253 | 333 | 352 | ||
254 | 334 | self.status = {} | 353 | self.status = {} |
255 | @@ -420,7 +439,7 @@ | |||
256 | 420 | return self.packages[package] | 439 | return self.packages[package] |
257 | 421 | 440 | ||
258 | 422 | 441 | ||
260 | 423 | def on_mark_package(self, metadata): | 442 | def on_mark_package(self, metadata, dependency=False): |
261 | 424 | """ | 443 | """ |
262 | 425 | Get a list of dependencies based on package metadata | 444 | Get a list of dependencies based on package metadata |
263 | 426 | """ | 445 | """ |
264 | @@ -431,25 +450,21 @@ | |||
265 | 431 | #TODO: This function obviously needs to be split up and modularized :) | 450 | #TODO: This function obviously needs to be split up and modularized :) |
266 | 432 | 451 | ||
267 | 433 | # First check if the package is installed already? | 452 | # First check if the package is installed already? |
271 | 434 | if metadata["Package"] in self.status: | 453 | status = self.on_get_package_status(metadata["Package"]) |
272 | 435 | raise AttributeError, "Package already set to status: %s" % \ | 454 | if status != "not installed": |
273 | 436 | self.status[metadata["Package"]]["Status"] | 455 | raise AttributeError, "Package already set to status: %s" % status |
274 | 437 | 456 | ||
275 | 438 | # Mark the package itself | 457 | # Mark the package itself |
277 | 439 | metadata["Status"] = "to be downloaded" | 458 | if not dependency: metadata["Status"] = "to be downloaded" |
278 | 459 | else: metadata["Status"] = "dependency to be downloaded" | ||
279 | 440 | self.status[metadata["Package"]] = metadata | 460 | self.status[metadata["Package"]] = metadata |
280 | 441 | 461 | ||
281 | 442 | logging.info("Finding dependencies for %s..." % metadata["Package"]) | 462 | logging.info("Finding dependencies for %s..." % metadata["Package"]) |
282 | 443 | 463 | ||
289 | 444 | # Build a string of the necessary sections we need | 464 | depends = self.on_get_package_dependencies(metadata) |
284 | 445 | depends = [] | ||
285 | 446 | for section in self.binary_dependencies: | ||
286 | 447 | if section in metadata: | ||
287 | 448 | depends.append(metadata[section]) | ||
288 | 449 | depends = ", ".join(depends) | ||
290 | 450 | 465 | ||
291 | 451 | # Do the dependency calculations | 466 | # Do the dependency calculations |
293 | 452 | for dep in depends.split(", "): | 467 | for dep in depends: |
294 | 453 | 468 | ||
295 | 454 | # In case we have some ORs | 469 | # In case we have some ORs |
296 | 455 | options = dep.split(" | ") | 470 | options = dep.split(" | ") |
297 | @@ -470,7 +485,7 @@ | |||
298 | 470 | # Test for compatible version just in case | 485 | # Test for compatible version just in case |
299 | 471 | if len(details) > 1: | 486 | if len(details) > 1: |
300 | 472 | comparison = details[1][1:] # strip the '(' | 487 | comparison = details[1][1:] # strip the '(' |
302 | 473 | version = details [2][:-1] # strip the ')' | 488 | version = details[2][:-1] # strip the ')' |
303 | 474 | 489 | ||
304 | 475 | satisfied = DpkgVersion(self.status[name]["Version"]).compare_string(comparison, version) | 490 | satisfied = DpkgVersion(self.status[name]["Version"]).compare_string(comparison, version) |
305 | 476 | 491 | ||
306 | @@ -492,15 +507,26 @@ | |||
307 | 492 | 507 | ||
308 | 493 | # Mark sub-dependencies as well | 508 | # Mark sub-dependencies as well |
309 | 494 | if pkg: | 509 | if pkg: |
313 | 495 | self.on_mark_package(pkg) | 510 | self.on_mark_package(pkg, dependency=True) |
314 | 496 | 511 | ||
315 | 497 | 512 | ||
316 | 513 | def on_get_package_dependencies(self, metadata): | ||
317 | 514 | |||
318 | 515 | # Build a string of the necessary sections we need | ||
319 | 516 | depends = [] | ||
320 | 517 | for section in self.binary_dependencies: | ||
321 | 518 | if section in metadata: | ||
322 | 519 | depends += metadata[section].split(", ") | ||
323 | 520 | |||
324 | 521 | return depends | ||
325 | 522 | |||
326 | 523 | |||
327 | 498 | def on_apply_changes(self): | 524 | def on_apply_changes(self): |
328 | 499 | 525 | ||
329 | 500 | directory = os.path.join(self.download_directory, "packages") | 526 | directory = os.path.join(self.download_directory, "packages") |
330 | 501 | 527 | ||
331 | 502 | # Build the list of package urls to download | 528 | # Build the list of package urls to download |
333 | 503 | downloads = [(key, value["Repository"]["url"].split("dists")[0] + value["Filename"]) for key, value in self.status.items() if value["Status"] == "to be downloaded"] | 529 | downloads = [(key, value["Repository"]["url"].split("dists")[0] + value["Filename"]) for key, value in self.status.items() if value["Status"] in ["to be downloaded", "dependency to be downloaded"]] |
334 | 504 | 530 | ||
335 | 505 | #downloads = [] | 531 | #downloads = [] |
336 | 506 | #for key, value in self.status.items(): | 532 | #for key, value in self.status.items(): |
337 | @@ -517,12 +543,16 @@ | |||
338 | 517 | for key, url in downloads: | 543 | for key, url in downloads: |
339 | 518 | download_url(url, "%s/%s" % (directory, url.rsplit("/", 1)[1]), proxy=self.proxy["proxy"], username=self.proxy["user"], password=self.proxy["pass"]) | 544 | download_url(url, "%s/%s" % (directory, url.rsplit("/", 1)[1]), proxy=self.proxy["proxy"], username=self.proxy["user"], password=self.proxy["pass"]) |
340 | 519 | # Once it's downloaded, mark this package status to "to be installed" | 545 | # Once it's downloaded, mark this package status to "to be installed" |
342 | 520 | self.status[key]["Status"] = "to be installed" | 546 | # or "dependency to be installed", depending on what it is now. |
343 | 547 | if self.status[key]["Status"] == "to be downloaded": | ||
344 | 548 | self.status[key]["Status"] = "to be installed" | ||
345 | 549 | elif self.status[key]["Status"] == "dependency to be downloaded": | ||
346 | 550 | self.status[key]["Status"] = "dependency to be installed" | ||
347 | 521 | 551 | ||
348 | 522 | 552 | ||
349 | 523 | def on_save_changes(self, status): | 553 | def on_save_changes(self, status): |
350 | 524 | 554 | ||
352 | 525 | # This will NOT create a staus file to override /var/lib/dpkg/status | 555 | # This will NOT create a status file to override /var/lib/dpkg/status |
353 | 526 | # so DO NOT try to replace the system status file. | 556 | # so DO NOT try to replace the system status file. |
354 | 527 | # YOU HAVE BEEN WARNED | 557 | # YOU HAVE BEEN WARNED |
355 | 528 | 558 | ||
356 | @@ -541,22 +571,19 @@ | |||
357 | 541 | 571 | ||
358 | 542 | 572 | ||
359 | 543 | def on_cancel_changes(self, downloads, installs): | 573 | def on_cancel_changes(self, downloads, installs): |
360 | 544 | |||
361 | 545 | cancellations = [] | ||
362 | 546 | 574 | ||
363 | 547 | for key, value in self.status.items(): | 575 | for key, value in self.status.items(): |
370 | 548 | if downloads and value["Status"] == "to be downloaded" or \ | 576 | if downloads and value["Status"] in \ |
371 | 549 | installs and value["Status"] == "to be installed": | 577 | ["to be downloaded", "dependency to be downloaded"] or \ |
372 | 550 | cancellations.append(key) | 578 | installs and value["Status"] in \ |
373 | 551 | 579 | ["to be installed", "dependency to be installed"]: | |
374 | 552 | for key in cancellations: | 580 | del self.status[key] |
369 | 553 | del self.status[key] | ||
375 | 554 | 581 | ||
376 | 555 | 582 | ||
377 | 556 | def on_get_changes_size(self): | 583 | def on_get_changes_size(self): |
378 | 557 | 584 | ||
379 | 558 | # Build list of packages to be downloaded | 585 | # Build list of packages to be downloaded |
381 | 559 | packages = [(value["Package"], value["Version"]) for key, value in self.status.items() if value["Status"] == "to be downloaded"] | 586 | packages = [(value["Package"], value["Version"]) for key, value in self.status.items() if value["Status"] in ["to be downloaded", "dependency to be downloaded"]] |
382 | 560 | 587 | ||
383 | 561 | count = 0 | 588 | count = 0 |
384 | 562 | total = 0 | 589 | total = 0 |
385 | @@ -582,36 +609,36 @@ | |||
386 | 582 | We will take the approach of installing by copying the lists to | 609 | We will take the approach of installing by copying the lists to |
387 | 583 | /var/lib/apt/lists and the packages to /var/cache/apt/archives and | 610 | /var/lib/apt/lists and the packages to /var/cache/apt/archives and |
388 | 584 | calling apt-get update and then apt-get install on the packages | 611 | calling apt-get update and then apt-get install on the packages |
390 | 585 | which have the stats of "to be installed". This prevents tampering | 612 | which have the status of "to be installed". This prevents tampering |
391 | 586 | with sources.list and works more or less the exact same if we made | 613 | with sources.list and works more or less the exact same if we made |
392 | 587 | a local repository. | 614 | a local repository. |
393 | 588 | """ | 615 | """ |
394 | 589 | 616 | ||
396 | 590 | if not os.geteuid()==0: | 617 | if not os.geteuid() == 0: |
397 | 591 | raise PermissionsError, "You may only install as root" | 618 | raise PermissionsError, "You may only install as root" |
398 | 592 | 619 | ||
399 | 593 | # Copy lists over | 620 | # Copy lists over |
404 | 594 | try: | 621 | for repo in self.__iter_repositories(): |
405 | 595 | for repo in self.__iter_repositories(): | 622 | url = to_url(repo, self.architecture, "Packages") |
406 | 596 | url = to_url(repo, self.architecture, "Packages") | 623 | filename = to_filename(os.path.join(self.download_directory, "lists"), url) |
403 | 597 | filename = to_filename(os.path.join(self.download_directory, "lists"), url) | ||
407 | 598 | 624 | ||
408 | 625 | try: | ||
409 | 599 | # Extract the gz | 626 | # Extract the gz |
410 | 600 | g = gzip.open("%s.gz" % filename, "rb") | 627 | g = gzip.open("%s.gz" % filename, "rb") |
411 | 601 | f = open(os.path.join("/var/lib/apt/lists", os.path.basename(filename)), "wb") | 628 | f = open(os.path.join("/var/lib/apt/lists", os.path.basename(filename)), "wb") |
412 | 602 | f.write(g.read()) | 629 | f.write(g.read()) |
413 | 603 | f.close() | 630 | f.close() |
414 | 604 | g.close() | 631 | g.close() |
418 | 605 | except IOError, e: | 632 | except IOError, e: |
419 | 606 | # We will just ignore this, it only trip out if the user did download=False on update() | 633 | # We will just ignore this, it only trip out if the user did download=False on update() |
420 | 607 | pass | 634 | pass |
421 | 608 | 635 | ||
422 | 609 | 636 | ||
423 | 610 | # Copy packages over | 637 | # Copy packages over |
424 | 611 | for key, value in self.status.items(): | 638 | for key, value in self.status.items(): |
426 | 612 | if value["Status"] == "to be installed": | 639 | if value["Status"] in ["to be installed", "dependency to be installed"]: |
427 | 613 | pkg_filename = self.get_binary_version(value["Package"], value["Version"])["Filename"].rsplit("/", 1)[1] | 640 | pkg_filename = self.get_binary_version(value["Package"], value["Version"])["Filename"].rsplit("/", 1)[1] |
429 | 614 | filename = os.path.join(self.download_directory, os.path.join("packages", pkg_filename)) | 641 | filename = os.path.join(self.download_directory, "packages", pkg_filename) |
430 | 615 | dest = os.path.join("/var/cache/apt/archives", os.path.basename(filename)) | 642 | dest = os.path.join("/var/cache/apt/archives", os.path.basename(filename)) |
431 | 616 | shutil.copyfile(filename, dest) | 643 | shutil.copyfile(filename, dest) |
432 | 617 | 644 | ||
433 | @@ -619,7 +646,7 @@ | |||
434 | 619 | # Call apt-get install with the packages | 646 | # Call apt-get install with the packages |
435 | 620 | packages = [value["Package"] for key, value in self.status.items() if value["Status"] == "to be installed"] | 647 | packages = [value["Package"] for key, value in self.status.items() if value["Status"] == "to be installed"] |
436 | 621 | 648 | ||
438 | 622 | subprocess.call("apt-get update", shell=True) | 649 | subprocess.call("apt-gcache gencaches", shell=True) |
439 | 623 | subprocess.call("apt-get -y install %s" % " ".join(packages), shell=True) | 650 | subprocess.call("apt-get -y install %s" % " ".join(packages), shell=True) |
440 | 624 | 651 | ||
441 | 625 | 652 | ||
442 | @@ -642,5 +669,3 @@ | |||
443 | 642 | 669 | ||
444 | 643 | 670 | ||
445 | 644 | return upgrades | 671 | return upgrades |
446 | 645 | |||
447 | 646 |
lp:unwrapt was out of date. I've updated it to lp:~excid3/keryx/unwrapt. Resubmitting.