From 3ca7a5b9aaed6368fffcdb9f1863a4bdf63bb7aa Mon Sep 17 00:00:00 2001 From: Guillaume Gauvrit Date: Wed, 28 Jun 2017 21:48:25 +0200 Subject: [PATCH] Fix issue #80: hyphen in the package name resolution --- pyshop/config.py | 11 ++++++++--- pyshop/helpers/pypi.py | 25 +++++++++++++++++++++---- pyshop/views/simple.py | 24 ++---------------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/pyshop/config.py b/pyshop/config.py index 59afeab..9958d39 100644 --- a/pyshop/config.py +++ b/pyshop/config.py @@ -37,6 +37,7 @@ def includeme(config): """ Pyramid includeme file for the :class:`pyramid.config.Configurator` """ + settings = config.registry.settings # config.add_renderer('json', JSONP()) # release file download @@ -50,9 +51,13 @@ def includeme(config): # i18n config.add_translation_dirs('locale/') + pypi_url = settings.get('pyshop.pypi.url', 'https://pypi.python.org/pypi') + simple_url = settings.get( + 'pyshop.pypi.simple_url', 'https://pypi.python.org/simple').rstrip('/') # PyPI url for XML RPC service consume - pypi.set_proxy(config.registry.settings['pyshop.pypi.url'], - config.registry.settings.get('pyshop.pypi.transport_proxy')) + pypi.set_proxy(pypi_url, + simple_url, + settings.get('pyshop.pypi.transport_proxy')) # Javascript + Media config.add_static_view('static', 'static', cache_max_age=3600) @@ -124,7 +129,7 @@ def includeme(config): # Web Services - if asbool(config.registry.settings.get('pyshop.enable_xmlrpc', 'true')): + if asbool(settings.get('pyshop.enable_xmlrpc', 'true')): config.add_view('pyshop.views.xmlrpc.PyPI', name='pypi') # Backoffice Views diff --git a/pyshop/helpers/pypi.py b/pyshop/helpers/pypi.py index d704292..6d6f530 100644 --- a/pyshop/helpers/pypi.py +++ b/pyshop/helpers/pypi.py @@ -19,7 +19,7 @@ """ - +import logging try: import xmlrpc.client as xmlrpc except ImportError: @@ -27,8 +27,9 @@ import requests - +log = logging.getLogger(__name__) proxy = None +PYPI_SIMPLE_URL = None class RequestsTransport(xmlrpc.Transport): @@ -86,10 +87,26 @@ def _build_url(self, host, handler): return '%s://%s%s' % (self.scheme, host, handler) +def resolve_name(package_name): + """ Return the """ + log.info('Resolving hyphenation of %s', package_name) + url = '{}/{}'.format(PYPI_SIMPLE_URL, package_name) + response = requests.get(url, + allow_redirects=False) + if 300 <= response.status_code < 400: + loc = response.headers['Location'].rstrip('/') + real_package_name = loc.rsplit('/', 1).pop() + log.info('Package %s is %s in upstream index', + package_name, real_package_name) + return real_package_name + else: + response.raise_for_status() + -def set_proxy(proxy_url, transport_proxy=None): +def set_proxy(proxy_url, simple_url, transport_proxy=None): """Create the proxy to PyPI XML-RPC Server""" - global proxy + global proxy, PYPI_SIMPLE_URL + PYPI_SIMPLE_URL = simple_url proxy = xmlrpc.ServerProxy( proxy_url, transport=RequestsTransport(proxy_url.startswith('https://')), diff --git a/pyshop/views/simple.py b/pyshop/views/simple.py index 8cb278c..de1ca62 100644 --- a/pyshop/views/simple.py +++ b/pyshop/views/simple.py @@ -264,28 +264,8 @@ def _create_release_file(self, release, data): ) def _search_package(self, package_name): - api = pypi.proxy - - search_result = api.search({'name': package_name}) - search_count = len(search_result) - if not search_count: - return None - - package_name = package_name.lower().replace('-', '_') - search_result = [ - pkg - for pkg in search_result - if pkg['name'].lower() == package_name or - pkg['name'].lower().replace('-', '_') == package_name - ] - log.debug('Found %s, matched %s', - search_count, len(search_result)) - - if not search_result: - return None - - package_name = search_result[0]['name'] - pypi_versions = api.package_releases(package_name, True) + package_name = pypi.resolve_name(package_name) + pypi_versions = pypi.proxy.package_releases(package_name, True) return to_unicode(package_name), pypi_versions def render(self):