# Path: folivora/models.py
# class Package(models.Model):
#     PYPI = 'pypi'
#     PROVIDER_CHOICES = (
#         (PYPI, 'PyPi'),
#     )
# 
#     name = models.CharField(_('name'), max_length=255, unique=True)
#     normalized_name = models.CharField(_('Normalized Name'), max_length=255,
#                                        unique=True)
#     url = models.URLField(_('url'))
#     provider = models.CharField(_('provider'), max_length=255,
#         choices=PROVIDER_CHOICES, default=PYPI)
#     initial_sync_done = models.BooleanField(default=False)
# 
#     @classmethod
#     def create_with_provider_url(cls, name, provider='pypi', url=None):
#         if url is None:
#             url = urlparse.urljoin(DEFAULT_SERVER, name)
#         pkg = cls(name=name, url=url, provider=provider)
#         pkg.save()
#         return pkg
# 
#     def sync_versions(self):
#         if self.initial_sync_done:
#             return
#         client = CheeseShop()
#         versions = client.get_package_versions(self.name)
#         for version in versions:
#             urls = client.get_release_urls(self.name, version)
#             if urls:
#                 url = urls[0]
#                 utime = time.mktime(url['upload_time'].timetuple())
#                 release_date = make_aware(
#                     datetime.datetime.fromtimestamp(utime),
#                     pytz.UTC)
#                 PackageVersion.objects.get_or_create(
#                     package=self,
#                     version=version,
#                     release_date=release_date)
#         self.initial_sync_done = True
#         self.save()
# 
#     def save(self, *args, **kwargs):
#         if not self.normalized_name:
#             self.normalized_name = normalize_name(self.name)
#         super(Package, self).save(*args, **kwargs)
# 
#     class Meta:
#         verbose_name = _('package')
#         verbose_name_plural = _('packages')
#         unique_together = ('name', 'provider')
# 
#     def __unicode__(self):
#         return self.name
# 
#     def __repr__(self):
#         return '<%s: %s>' % (self.__class__.__name__, self.name)
# 
# class SyncState(models.Model):
#     """Generic model to store syncronization states."""
#     CHANGELOG = 'changelog'
# 
#     TYPE_CHOICES = (
#         (_('Changelog'), CHANGELOG),
#     )
# 
#     STATE_DOWN = 'down'
#     STATE_RUNNING = 'running'
# 
#     STATE_CHOICES = (
#         (_('Down'), STATE_DOWN),
#         (_('Running'), STATE_RUNNING),
#     )
# 
#     type = models.CharField(max_length=255, choices=TYPE_CHOICES, unique=True)
#     state = models.CharField(max_length=255, choices=STATE_CHOICES,
#                              default=STATE_RUNNING)
#     last_sync = models.DateTimeField(_('Last Sync'), default=now)
# 
# Path: folivora/utils/pypi.py
# class CheeseShop(object):
# 
#     def __init__(self, server=DEFAULT_SERVER):
#         self.xmlrpc = xmlrpclib.Server(server)
# 
#     def get_package_versions(self, package_name):
#         """Fetch list of available versions for a package.
# 
#         :param package_name: Name of the package to query.
#         """
#         return self.xmlrpc.package_releases(package_name)
# 
#     def get_package_list(self):
#         """Fetch the master list of package names."""
#         return self.xmlrpc.list_packages()
# 
#     def search(self, spec, operator):
#         """Query using search spec."""
#         return self.xmlrpc.search(spec, operator.lower())
# 
#     def get_changelog(self, hours, force_seconds=False):
#         """Query the changelog.
# 
#         :param hours: Hours from now to specify the changelog size.
#         :param force_seconds: Force that `hours` are the seconds to use.
#         """
#         seconds = get_seconds(hours) if not force_seconds else hours
#         return self.xmlrpc.changelog(seconds)
# 
#     def get_updated_releases(self, hours, force_seconds):
#         """Query all updated releases within `hours`.
# 
#         :param hours: Specify the number of hours to find updated releases.
#         :param force_seconds: Force that `hours` are the seconds to use.
#         """
#         seconds = get_seconds(hours) if not force_seconds else hours
#         return self.xmlrpc.updated_releases(seconds)
# 
#     def get_release_urls(self, package_name, version):
#         """Query for all available release urls of `package_name`.
# 
#         :param package_name: Name of the package.
#         :param version: Version of the package.
#         """
#         return self.xmlrpc.release_urls(package_name, version)
# 
#     def get_release_data(self, package_name, version=None):
#         """Query for specific release data.
# 
#         :param package_name: Name of the package.
#         :param version: Version to query the data. If `None`, it's latest
#                         version will be used.
#         """
#         if version is None:
#             versions = self.get_package_versions(package_name)
#             if not versions:
#                 return {}
#             version = versions[-1]
#         return self.xmlrpc.release_data(package_name, version)
# 
# DEFAULT_SERVER = 'http://pypi.python.org/pypi/'


import sys
import urlparse
import datetime
import logging
import time
import pytz
from django.utils import timezone
from folivora.models import Package, SyncState
from folivora.utils.pypi import CheeseShop, DEFAULT_SERVER
#!/usr/bin/env python
#-*- coding: utf-8 -*-


SERVER = CheeseShop(DEFAULT_SERVER)


def sync():
    if ('delete_all' in sys.argv and
        raw_input('sure (this resets everything)? [y/n]: ') == 'y'):
            Package.objects.all().delete()

    SyncState.objects.all().delete()

# Path: folivora/models.py
# class Package(models.Model):
#     PYPI = 'pypi'
#     PROVIDER_CHOICES = (
#         (PYPI, 'PyPi'),
#     )
# 
#     name = models.CharField(_('name'), max_length=255, unique=True)
#     normalized_name = models.CharField(_('Normalized Name'), max_length=255,
#                                        unique=True)
#     url = models.URLField(_('url'))
#     provider = models.CharField(_('provider'), max_length=255,
#         choices=PROVIDER_CHOICES, default=PYPI)
#     initial_sync_done = models.BooleanField(default=False)
# 
#     @classmethod
#     def create_with_provider_url(cls, name, provider='pypi', url=None):
#         if url is None:
#             url = urlparse.urljoin(DEFAULT_SERVER, name)
#         pkg = cls(name=name, url=url, provider=provider)
#         pkg.save()
#         return pkg
# 
#     def sync_versions(self):
#         if self.initial_sync_done:
#             return
#         client = CheeseShop()
#         versions = client.get_package_versions(self.name)
#         for version in versions:
#             urls = client.get_release_urls(self.name, version)
#             if urls:
#                 url = urls[0]
#                 utime = time.mktime(url['upload_time'].timetuple())
#                 release_date = make_aware(
#                     datetime.datetime.fromtimestamp(utime),
#                     pytz.UTC)
#                 PackageVersion.objects.get_or_create(
#                     package=self,
#                     version=version,
#                     release_date=release_date)
#         self.initial_sync_done = True
#         self.save()
# 
#     def save(self, *args, **kwargs):
#         if not self.normalized_name:
#             self.normalized_name = normalize_name(self.name)
#         super(Package, self).save(*args, **kwargs)
# 
#     class Meta:
#         verbose_name = _('package')
#         verbose_name_plural = _('packages')
#         unique_together = ('name', 'provider')
# 
#     def __unicode__(self):
#         return self.name
# 
#     def __repr__(self):
#         return '<%s: %s>' % (self.__class__.__name__, self.name)
# 
# class SyncState(models.Model):
#     """Generic model to store syncronization states."""
#     CHANGELOG = 'changelog'
# 
#     TYPE_CHOICES = (
#         (_('Changelog'), CHANGELOG),
#     )
# 
#     STATE_DOWN = 'down'
#     STATE_RUNNING = 'running'
# 
#     STATE_CHOICES = (
#         (_('Down'), STATE_DOWN),
#         (_('Running'), STATE_RUNNING),
#     )
# 
#     type = models.CharField(max_length=255, choices=TYPE_CHOICES, unique=True)
#     state = models.CharField(max_length=255, choices=STATE_CHOICES,
#                              default=STATE_RUNNING)
#     last_sync = models.DateTimeField(_('Last Sync'), default=now)
# 
# Path: folivora/utils/pypi.py
# class CheeseShop(object):
# 
#     def __init__(self, server=DEFAULT_SERVER):
#         self.xmlrpc = xmlrpclib.Server(server)
# 
#     def get_package_versions(self, package_name):
#         """Fetch list of available versions for a package.
# 
#         :param package_name: Name of the package to query.
#         """
#         return self.xmlrpc.package_releases(package_name)
# 
#     def get_package_list(self):
#         """Fetch the master list of package names."""
#         return self.xmlrpc.list_packages()
# 
#     def search(self, spec, operator):
#         """Query using search spec."""
#         return self.xmlrpc.search(spec, operator.lower())
# 
#     def get_changelog(self, hours, force_seconds=False):
#         """Query the changelog.
# 
#         :param hours: Hours from now to specify the changelog size.
#         :param force_seconds: Force that `hours` are the seconds to use.
#         """
#         seconds = get_seconds(hours) if not force_seconds else hours
#         return self.xmlrpc.changelog(seconds)
# 
#     def get_updated_releases(self, hours, force_seconds):
#         """Query all updated releases within `hours`.
# 
#         :param hours: Specify the number of hours to find updated releases.
#         :param force_seconds: Force that `hours` are the seconds to use.
#         """
#         seconds = get_seconds(hours) if not force_seconds else hours
#         return self.xmlrpc.updated_releases(seconds)
# 
#     def get_release_urls(self, package_name, version):
#         """Query for all available release urls of `package_name`.
# 
#         :param package_name: Name of the package.
#         :param version: Version of the package.
#         """
#         return self.xmlrpc.release_urls(package_name, version)
# 
#     def get_release_data(self, package_name, version=None):
#         """Query for specific release data.
# 
#         :param package_name: Name of the package.
#         :param version: Version to query the data. If `None`, it's latest
#                         version will be used.
#         """
#         if version is None:
#             versions = self.get_package_versions(package_name)
#             if not versions:
#                 return {}
#             version = versions[-1]
#         return self.xmlrpc.release_data(package_name, version)
# 
# DEFAULT_SERVER = 'http://pypi.python.org/pypi/'


# Path: extra/sync.py
import sys
import urlparse
import datetime
import logging
import time
import pytz
from django.utils import timezone
from folivora.models import Package, SyncState
from folivora.utils.pypi import CheeseShop, DEFAULT_SERVER

#!/usr/bin/env python
#-*- coding: utf-8 -*-


SERVER = CheeseShop(DEFAULT_SERVER)


def sync():
    if ('delete_all' in sys.argv and
        raw_input('sure (this resets everything)? [y/n]: ') == 'y'):
            Package.objects.all().delete()

    SyncState.objects.all().delete()

    SyncState.objects.create(type=SyncState.CHANGELOG,