About us | Join us | Hire us | Contact us | Google Group

root/egg/pypi.py

Revision 222, 4.1 kB (checked in by bjorn, 3 years ago)

Cleanups

Line 
1#!/usr/bin/env python
2# encoding: utf-8
3"""PythonEggs PyPI communication.
4"""
5
6import time, xmlrpclib
7from cache import Egg
8
9# needsync = True => needs to be refetched
10# updated = when was the entry updated on disk
11# timestamp = int(time.time())
12
13
14def sync(store):
15    pypi_xmlrpc = xmlrpclib.Server('http://pypi.python.org/pypi')
16    # http://wiki.python.org/moin/CheeseShopXmlRpc
17
18    now = int(time.time())
19
20    # get and update package list
21    cached_packages = set([ egg.name for egg in store.find(Egg, source=u"pypi") ])
22    packages = set([ unicode(p) for p in pypi_xmlrpc.list_packages() ])
23   
24    # delete packages no longer on pypi
25    for package_name in cached_packages - packages:
26        print "removing", package_name
27        store.find(Egg, name=package_name, source=u"pypi").remove()
28
29    # add new packages
30    for package_name in packages - cached_packages:
31        print "adding", package_name
32        store.add(Egg(name=unicode(package_name), source=u"pypi", needsync=True))
33
34    store.commit()
35   
36    # find last successful update
37    (last,) = store.execute("SELECT max(updated) FROM egg").get_one()
38   
39    # find updated packages, mark them as "missing information"
40    if last:
41        # changelog(since) -> (name, version, timestamp, action)
42        for (package_name, version, timestamp, action) in pypi_xmlrpc.changelog(last):
43            version = unicode(version)
44            package_name = unicode(package_name)
45            print "invalidating cache for %s (%s)" % (package_name, action)
46            for egg in store.find(Egg, name=package_name, source=u"pypi"):
47                egg.needsync = True
48                egg.updated = timestamp
49        store.commit()
50
51    # update packages with missing information
52    # by convention we let all incomplete packages have fullname=None
53    incomplete = [ egg.name for egg in store.find(Egg, source=u"pypi", needsync=True) ]
54    for num, package_name in enumerate(sorted(incomplete)):
55        print "updating %d of %d - %s" % (num+1, len(incomplete), package_name),
56
57        releases = pypi_xmlrpc.package_releases(package_name)
58        if not releases:
59            print "- warning! no releases"
60            # the package is empty; will ignore and rely on changelog to
61            # provide updates for it
62           
63            egg.needssync = False
64            continue
65       
66        # remove old release, replacing with current
67        store.find(Egg, name=package_name, source=u"pypi").remove()
68        store.commit()
69
70        for version in releases:
71            #download_urls = pypi_xmlrpc.release_urls(package_name, version)
72            # ({'url': '...', 'packagetype': 'sdist/bdist'}, ...)
73            data = pypi_xmlrpc.release_data(package_name, version) # dict ...
74            print "- %s" % (version,),
75            e = Egg(
76                installed = False,
77                active = False,
78                name = unicode(package_name),
79                fullname = unicode(data['name']),
80                location = unicode("http://pypi.python.org/pypi/%s" % (package_name,)),
81                version = unicode(version),
82                classifiers = unicode(data['classifiers']),
83                keywords = unicode(data['keywords']),
84                description = unicode(data['description']),
85                summary = unicode(data['summary']),
86                maintainer = unicode(data['maintainer']),
87                maintainer_email = unicode(data['maintainer_email']),
88                author = unicode(data['author']),
89                author_email = unicode(data['author_email']),
90                download_url = unicode(data['download_url']),
91                platform = unicode(data['platform']),
92                obsoletes = unicode(data['obsoletes']),
93                provides = unicode(data['provides']),
94                requires = unicode(data['requires']),
95                license = unicode(data['license']),
96                home_page = unicode(data['home_page']),
97                stable_version = unicode(data['stable_version']),
98                cheesecake_data = data or u"",
99                updated = now,
100                source = u"pypi",
101            )
102            store.add(e)
103        print
104        store.commit()
Note: See TracBrowser for help on using the browser.