From python-checkins at python.org Mon Dec 12 19:31:13 2011 From: python-checkins at python.org (martin.von.loewis) Date: Mon, 12 Dec 2011 19:31:13 +0100 (CET) Subject: [Pypi-checkins] r999 - trunk/pypi Message-ID: <3T2CRP5TmrzPKW@mail.python.org> Author: martin.von.loewis Date: Mon Dec 12 19:31:13 2011 New Revision: 999 Modified: trunk/pypi/rpc.py trunk/pypi/store.py Log: Add browse RPC. Modified: trunk/pypi/rpc.py ============================================================================== --- trunk/pypi/rpc.py (original) +++ trunk/pypi/rpc.py Mon Dec 12 19:31:13 2011 @@ -21,6 +21,7 @@ self.register_function(release_data) self.register_function(release_data, name='package_data') # Deprecated self.register_function(search) + self.register_function(browse) self.register_function(updated_releases) self.register_function(changelog) self.register_function(changed_packages) @@ -119,6 +120,19 @@ spec['_pypi_hidden'] = 'FALSE' return [row.as_dict() for row in store.query_packages(spec, operator)] +def browse(store, categories): + if not isinstance(categories, list): + raise TypeError, "Parameter categories must be a list" + classifier_ids = store.get_classifier_ids(categories) + print classifier_ids + if len(classifier_ids) != len(categories): + for c in categories: + if c not in classifier_ids: + raise ValueError, 'Unknown category "%s"' % c + ids = classifier_ids.values() + packages, tally = store.browse(ids) + return [(name, version) for name, version, desc in packages] + def updated_releases(store, since): result = store.updated_releases(since) return [(row['name'], row['version']) for row in result] Modified: trunk/pypi/store.py ============================================================================== --- trunk/pypi/store.py (original) +++ trunk/pypi/store.py Mon Dec 12 19:31:13 2011 @@ -705,6 +705,15 @@ ' order by classifier') return Result(None, cursor.fetchall(), self._Classifiers) + _ClassifierID = FastResultRow('classifier id') + def get_classifier_ids(self, classifiers): + '''Map list of classifiers to classifier IDs''' + cursor = self.get_cursor() + placeholders = ','.join(['%s'] * len(classifiers)) + safe_execute(cursor, 'select classifier, id from trove_classifiers ' + 'where classifier in (%s)' % placeholders, classifiers) + return dict(cursor.fetchall()) + _Release_Classifiers = FastResultRow('classifier trove_id!') def get_release_classifiers(self, name, version): ''' Fetch the list of classifiers for the release. From python-checkins at python.org Mon Dec 19 06:14:26 2011 From: python-checkins at python.org (richard) Date: Mon, 19 Dec 2011 06:14:26 +0100 (CET) Subject: [Pypi-checkins] r1000 - trunk/pypi Message-ID: <3T69Qp1y1QzPwK@mail.python.org> Author: richard Date: Mon Dec 19 06:14:26 2011 New Revision: 1000 Modified: trunk/pypi/webui.py Log: fix latest package lookup unfortunately some whitespace changes are going in as well Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Dec 19 06:14:26 2011 @@ -8,7 +8,7 @@ try: import json except ImportError: - import simplejson as json + import simplejson as json try: import psycopg2 OperationalError = psycopg2.OperationalError @@ -27,7 +27,7 @@ urllib.URLopener.open_https = orig # OpenId provider imports -OPENID_FILESTORE = '/tmp/openid-filestore' +OPENID_FILESTORE = '/tmp/openid-filestore' from openid.server import server as OpenIDServer @@ -369,7 +369,7 @@ line = temp[index] # count spaces to align entry nicely spaces = len(line.lstrip()) - len(line) - temp[index] = "\n".join((line, ' ' * spaces + token)) + temp[index] = "\n".join((line, ' ' * spaces + token)) content = '\n'.join(temp) except IndexError: # this should not happen with correct HTML syntax @@ -1091,7 +1091,7 @@ else: l = self.store.get_latest_release(name, hidden=False) try: - version = l[-1][1] + version = l[0][1] except IndexError: raise NotFound, 'no releases' info = self.store.get_package(name, version) @@ -1187,7 +1187,7 @@ self.handler.set_content_type('application/json; charset="UTF-8"') #filename = '%s-%s.json'%(name.encode('ascii', 'replace'), # version.encode('ascii', 'replace')) - #self.handler.send_header('Content-Disposition', + #self.handler.send_header('Content-Disposition', # 'attachment; filename=%s'%filename) self.handler.send_header('Content-Disposition', 'inline') self.handler.end_headers() @@ -1337,7 +1337,7 @@ info = self.store.get_package(name, version) if not info: raise NotFound - return info, latest_version + return info, latest_version def display(self, name=None, version=None, ok_message=None, error_message=None): @@ -1384,7 +1384,7 @@ column = column[:-3] value = self.store.get_cheesecake_index(int(value)) elif column == 'bugtrack_url': - bugtrack_url = value + bugtrack_url = value value = info[column] release[column] = value @@ -2958,7 +2958,7 @@ self.handler.send_header("Content-length", str(len(payload))) self.handler.end_headers() self.handler.wfile.write(payload) - + def openid_endpoint(self): """Handle OpenID requests""" orequest = self.oid_server.decodeRequest(self.form) @@ -2982,7 +2982,7 @@ self.openid_response(self.oid_server.handleRequest(orequest)) else: raise OpenIDError, "Unknown mode: %s" % orequest.mode - + def openid_decide_page(self, orequest): """ The page that asks the user if they really want to trust this trust_root @@ -2995,12 +2995,12 @@ self.write_template('openid_notloggedin.pt', title="OpenID login attempt") return - + if orequest.identity == "http://specs.openid.net/auth/2.0/identifier_select": pending_id = self.openid_user_url() else: pending_id = orequest.identity - + orequest_args=orequest.message.toPostArgs() del orequest_args[':action'] # They are logged in - ask if they want to trust this root @@ -3012,17 +3012,17 @@ return_to=orequest.return_to, trust_root=orequest.trust_root, pending_id = pending_id) - + def openid_decide_post(self): """Handle POST request from decide form""" if self.env['REQUEST_METHOD'] != "POST": raise OpenIDError, "OpenID request must be a POST" - + from openid.message import Message del self.form[':action'] message = Message.fromPostArgs(self.form) orequest = OpenIDServer.CheckIDRequest.fromMessage(message, self.oid_server.op_endpoint) - + if self.form.has_key('allow'): answer = orequest.answer(True, identity=self.openid_user_url()) return self.openid_response(answer) @@ -3036,7 +3036,7 @@ return self.openid_response(answer) else: raise OpenIDError, "OpenID post request failure" - + def openid_response(self, oresponse): """Convert a webresponse from the OpenID library into a WebUI http response""" @@ -3045,13 +3045,13 @@ raise Redirect, str(webresponse.headers['location']) elif webresponse.code == 302: raise RedirectFound, str(webresponse.headers['location']) - + self.handler.send_response(webresponse.code) for key, value in webresponse.headers.items(): self.handler.send_header(key, str(value)) self.handler.end_headers() self.handler.wfile.write(webresponse.body) - + def openid_is_authorized(self, orequest): """ This should check that they own the given identity, From python-checkins at python.org Mon Dec 19 06:48:28 2011 From: python-checkins at python.org (richard) Date: Mon, 19 Dec 2011 06:48:28 +0100 (CET) Subject: [Pypi-checkins] r1001 - in trunk/pypi: . templates Message-ID: <3T6BB41s97zQ7K@mail.python.org> Author: richard Date: Mon Dec 19 06:48:28 2011 New Revision: 1001 Modified: trunk/pypi/templates/standard_template.pt trunk/pypi/webui.py Log: fix URLs so clients don't have to redirect; allow packages_rss (??) Modified: trunk/pypi/templates/standard_template.pt ============================================================================== --- trunk/pypi/templates/standard_template.pt (original) +++ trunk/pypi/templates/standard_template.pt Mon Dec 19 06:48:28 2011 @@ -11,8 +11,8 @@ <meta tal:attributes="content data/keywords" /> <meta tal:attributes="content data/description" /> - <link rel="alternate" type="application/rss+xml" title="RSS: 40 latest updates" href="http://www.python.org/pypi?:action=rss"/> - <link rel="alternate" type="application/rss+xml" title="RSS: 40 newest packages" href="http://www.python.org/pypi?:action=packages_rss"/> + <link rel="alternate" type="application/rss+xml" title="RSS: 40 latest updates" href="http://pypi.python.org/pypi?:action=rss"/> + <link rel="alternate" type="application/rss+xml" title="RSS: 40 newest packages" href="http://pypi.python.org/pypi?:action=packages_rss"/> <link media="screen" tal:attributes="href string:${app/config/pydotorg}styles/screen-switcher-default.css" type="text/css" id="screen-switcher-stylesheet" rel="stylesheet" /> <link media="screen" tal:attributes="href string:${app/config/pydotorg}styles/netscape4.css" type="text/css" rel="stylesheet" /> <link media="print" tal:attributes="href string:${app/config/pydotorg}styles/print.css" type="text/css" rel="stylesheet" /> Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Dec 19 06:48:28 2011 @@ -567,7 +567,7 @@ password_reset role role_form list_classifiers login logout files file_upload show_md5 doc_upload claim openid openid_return dropid clear_auth addkey delkey lasthour json gae_file about delete_user - rss_regen openid_endpoint openid_decide_post'''.split(): + rss_regen openid_endpoint openid_decide_post packages_rss'''.split(): getattr(self, action)() else: #raise NotFound, 'Unknown action %s' % action From python-checkins at python.org Tue Dec 20 02:35:32 2011 From: python-checkins at python.org (richard) Date: Tue, 20 Dec 2011 02:35:32 +0100 (CET) Subject: [Pypi-checkins] r1002 - trunk/pypi/templates Message-ID: <3T6hWm1Ym0zPmc@mail.python.org> Author: richard Date: Tue Dec 20 02:35:31 2011 New Revision: 1002 Modified: trunk/pypi/templates/packages-rss.xml Log: link to latest version Modified: trunk/pypi/templates/packages-rss.xml ============================================================================== --- trunk/pypi/templates/packages-rss.xml (original) +++ trunk/pypi/templates/packages-rss.xml Tue Dec 20 02:35:31 2011 @@ -11,8 +11,7 @@ <item tal:repeat="release app/store/latest_packages"> <title tal:content="string:${release/name} ${release/version}" /> - <link tal:content="python:'http://pypi.python.org%s'%app.packageURL( - release['name'], release['version'])" /> + <link tal:content="python:'http://pypi.python.org%s'%app.packageURL(release['name'], None)" /> <description tal:content="release/summary" /> <pubDate tal:content="python:release['submitted_date'].strftime('%d %b %Y %H:%M:%S GMT')" /> </item> From python-checkins at python.org Tue Dec 20 02:41:53 2011 From: python-checkins at python.org (richard) Date: Tue, 20 Dec 2011 02:41:53 +0100 (CET) Subject: [Pypi-checkins] r1003 - trunk/pypi/templates Message-ID: <3T6hg52pszzPtk@mail.python.org> Author: richard Date: Tue Dec 20 02:41:53 2011 New Revision: 1003 Modified: trunk/pypi/templates/packages-rss.xml Log: try using a guid to allow RSS readers to cope with release updates in later RSS versions Modified: trunk/pypi/templates/packages-rss.xml ============================================================================== --- trunk/pypi/templates/packages-rss.xml (original) +++ trunk/pypi/templates/packages-rss.xml Tue Dec 20 02:41:53 2011 @@ -10,8 +10,9 @@ <language>en</language> <item tal:repeat="release app/store/latest_packages"> - <title tal:content="string:${release/name} ${release/version}" /> + <title tal:content="${release/name} added to PyPI" /> <link tal:content="python:'http://pypi.python.org%s'%app.packageURL(release['name'], None)" /> + <guid tal:content="python:'http://pypi.python.org%s'%app.packageURL(release['name'], None)" /> <description tal:content="release/summary" /> <pubDate tal:content="python:release['submitted_date'].strftime('%d %b %Y %H:%M:%S GMT')" /> </item> From python-checkins at python.org Tue Dec 20 02:45:18 2011 From: python-checkins at python.org (richard) Date: Tue, 20 Dec 2011 02:45:18 +0100 (CET) Subject: [Pypi-checkins] r1004 - trunk/pypi/templates Message-ID: <3T6hl22t9LzMcV@mail.python.org> Author: richard Date: Tue Dec 20 02:45:18 2011 New Revision: 1004 Modified: trunk/pypi/templates/packages-rss.xml Log: whoops Modified: trunk/pypi/templates/packages-rss.xml ============================================================================== --- trunk/pypi/templates/packages-rss.xml (original) +++ trunk/pypi/templates/packages-rss.xml Tue Dec 20 02:45:18 2011 @@ -10,7 +10,7 @@ <language>en</language> <item tal:repeat="release app/store/latest_packages"> - <title tal:content="${release/name} added to PyPI" /> + <title tal:content="string:${release/name} added to PyPI" /> <link tal:content="python:'http://pypi.python.org%s'%app.packageURL(release['name'], None)" /> <guid tal:content="python:'http://pypi.python.org%s'%app.packageURL(release['name'], None)" /> <description tal:content="release/summary" />