# Path: pypi_portal/extensions.py
# LOG = getLogger(__name__)
# def _on_connect(dbapi_connection, **_):
# 
# Path: pypi_portal/models/pypi.py
# class Package(Base):
#     """Holds all of the packages on PyPI."""
#     name = Column(String(255), unique=True, nullable=False)
#     summary = Column(Text, nullable=False)
#     latest_version = Column(String(128), nullable=False)
# 
# Path: pypi_portal/models/redis.py
# POLL_SIMPLE_THROTTLE = 'pypi_portal:poll_simple_throttle'  # Lock.


from distutils.version import LooseVersion
from logging import getLogger
from flask.ext.celery import single_instance
from pypi_portal.extensions import celery, db, redis
from pypi_portal.models.pypi import Package
from pypi_portal.models.redis import POLL_SIMPLE_THROTTLE
import xmlrpclib

    This task returns something in case the user schedules it from a view. The view can wait up to a certain amount of
    time for this task to finish, and if nothing times out, it can tell the user if it found any new packages.

    Since views can schedule this task, we don't want some rude person hammering PyPI or our application with repeated
    requests. This task is limited to one run per 1 hour at most.

    Returns:
    List of new packages found. Returns None if task is rate-limited.
    """
    # Rate limit.
    lock = redis.lock(POLL_SIMPLE_THROTTLE, timeout=int(THROTTLE))
    have_lock = lock.acquire(blocking=False)
    if not have_lock:
        LOG.warning('poll_simple() task has already executed in the past 4 hours. Rate limiting.')
        return None

    # Query API.
    client = xmlrpclib.ServerProxy('https://pypi.python.org/pypi')
    results = client.search(dict(summary=''))
    if not results:
        LOG.error('Reply from API had no results.')
        return list()

    LOG.debug('Sorting results.')
    results.sort(key=lambda x: (x['name'], LooseVersion(x['version'])))
    filtered = (r for r in results if r['version'][0].isdigit())
    packages = {r['name']: dict(summary=r['summary'], version=r['version'], id=0) for r in filtered}

    LOG.debug('Pruning unchanged packages.')

# Path: pypi_portal/extensions.py
# LOG = getLogger(__name__)
# def _on_connect(dbapi_connection, **_):
# 
# Path: pypi_portal/models/pypi.py
# class Package(Base):
#     """Holds all of the packages on PyPI."""
#     name = Column(String(255), unique=True, nullable=False)
#     summary = Column(Text, nullable=False)
#     latest_version = Column(String(128), nullable=False)
# 
# Path: pypi_portal/models/redis.py
# POLL_SIMPLE_THROTTLE = 'pypi_portal:poll_simple_throttle'  # Lock.


# Path: pypi_portal/tasks/pypi.py
from distutils.version import LooseVersion
from logging import getLogger
from flask.ext.celery import single_instance
from pypi_portal.extensions import celery, db, redis
from pypi_portal.models.pypi import Package
from pypi_portal.models.redis import POLL_SIMPLE_THROTTLE
import xmlrpclib


    This task returns something in case the user schedules it from a view. The view can wait up to a certain amount of
    time for this task to finish, and if nothing times out, it can tell the user if it found any new packages.

    Since views can schedule this task, we don't want some rude person hammering PyPI or our application with repeated
    requests. This task is limited to one run per 1 hour at most.

    Returns:
    List of new packages found. Returns None if task is rate-limited.
    """
    # Rate limit.
    lock = redis.lock(POLL_SIMPLE_THROTTLE, timeout=int(THROTTLE))
    have_lock = lock.acquire(blocking=False)
    if not have_lock:
        LOG.warning('poll_simple() task has already executed in the past 4 hours. Rate limiting.')
        return None

    # Query API.
    client = xmlrpclib.ServerProxy('https://pypi.python.org/pypi')
    results = client.search(dict(summary=''))
    if not results:
        LOG.error('Reply from API had no results.')
        return list()

    LOG.debug('Sorting results.')
    results.sort(key=lambda x: (x['name'], LooseVersion(x['version'])))
    filtered = (r for r in results if r['version'][0].isdigit())
    packages = {r['name']: dict(summary=r['summary'], version=r['version'], id=0) for r in filtered}

    LOG.debug('Pruning unchanged packages.')

    for row in db.session.query(Package.id, Package.name, Package.summary, Package.latest_version):