mirror of
https://github.com/kennethreitz-archive/chishop.git
synced 2026-06-21 16:00:58 +00:00
143 lines
4.8 KiB
Python
143 lines
4.8 KiB
Python
"""
|
|
Management command for adding a package to the repository. Supposed to be the
|
|
equivelant of calling easy_install, but the install target is the chishop.
|
|
"""
|
|
|
|
from __future__ import with_statement
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
import urllib
|
|
|
|
import pkginfo
|
|
|
|
from django.core.files.base import File
|
|
from django.core.management.base import LabelCommand
|
|
from optparse import make_option
|
|
from contextlib import contextmanager
|
|
from urlparse import urlsplit
|
|
from setuptools.package_index import PackageIndex
|
|
from django.contrib.auth.models import User
|
|
from djangopypi.models import Project, Release, Classifier
|
|
|
|
|
|
|
|
|
|
|
|
@contextmanager
|
|
def tempdir():
|
|
"""Simple context that provides a temporary directory that is deleted
|
|
when the context is exited."""
|
|
d = tempfile.mkdtemp(".tmp", "djangopypi.")
|
|
yield d
|
|
shutil.rmtree(d)
|
|
|
|
class Command(LabelCommand):
|
|
option_list = LabelCommand.option_list + (
|
|
make_option("-o", "--owner", help="add packages as OWNER",
|
|
metavar="OWNER", default=None),
|
|
)
|
|
help = """Add one or more packages to the repository. Each argument can
|
|
be a package name or a URL to an archive or egg. Package names honour
|
|
the same rules as easy_install with regard to indicating versions etc.
|
|
|
|
If a version of the package exists, but is older than what we want to install,
|
|
the owner remains the same.
|
|
|
|
For new packages there needs to be an owner. If the --owner option is present
|
|
we use that value. If not, we try to match the maintainer of the package, form
|
|
the metadata, with a user in out database, based on the If it's a new package
|
|
and the maintainer emailmatches someone in our user list, we use that. If not,
|
|
the package can not be
|
|
added"""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.pypi = PackageIndex()
|
|
LabelCommand.__init__(self, *args, **kwargs)
|
|
|
|
def handle_label(self, label, **options):
|
|
with tempdir() as tmp:
|
|
path = self.pypi.download(label, tmp)
|
|
if path:
|
|
self._save_package(path, options["owner"])
|
|
else:
|
|
print "Could not add %s. Not found." % label
|
|
|
|
def _save_package(self, path, ownerid):
|
|
meta = self._get_meta(path)
|
|
|
|
try:
|
|
# can't use get_or_create as that demands there be an owner
|
|
project = Project.objects.get(name=meta.name)
|
|
isnewproject = False
|
|
except Project.DoesNotExist:
|
|
project = Project(name=meta.name)
|
|
isnewproject = True
|
|
|
|
release = project.get_release(meta.version)
|
|
if not isnewproject and release and release.version == meta.version:
|
|
print "%s-%s already added" % (meta.name, meta.version)
|
|
return
|
|
|
|
# algorithm as follows: If owner is given, try to grab user with that
|
|
# username from db. If doesn't exist, bail. If no owner set look at
|
|
# mail address from metadata and try to get that user. If it exists
|
|
# use it. If not, bail.
|
|
owner = None
|
|
|
|
if ownerid:
|
|
try:
|
|
if "@" in ownerid:
|
|
owner = User.objects.get(email=ownerid)
|
|
else:
|
|
owner = User.objects.get(username=ownerid)
|
|
except User.DoesNotExist:
|
|
pass
|
|
else:
|
|
try:
|
|
owner = User.objects.get(email=meta.author_email)
|
|
except User.DoesNotExist:
|
|
pass
|
|
|
|
if not owner:
|
|
print "No owner defined. Use --owner to force one"
|
|
return
|
|
|
|
# at this point we have metadata and an owner, can safely add it.
|
|
|
|
project.owner = owner
|
|
# Some packages don't have proper licence, seems to be a problem
|
|
# with setup.py upload. Use "UNKNOWN"
|
|
project.license = meta.license or "Unknown"
|
|
project.metadata_version = meta.metadata_version
|
|
project.author = meta.author
|
|
project.home_page = meta.home_page
|
|
project.download_url = meta.download_url
|
|
project.summary = meta.summary
|
|
project.description = meta.description
|
|
project.author_email = meta.author_email
|
|
|
|
project.save()
|
|
|
|
for classifier in meta.classifiers:
|
|
project.classifiers.add(
|
|
Classifier.objects.get_or_create(name=classifier)[0])
|
|
|
|
release = Release()
|
|
release.version = meta.version
|
|
release.project = project
|
|
filename = os.path.basename(path)
|
|
|
|
file = File(open(path, "rb"))
|
|
release.distribution.save(filename, file)
|
|
release.save()
|
|
print "%s-%s added" % (meta.name, meta.version)
|
|
|
|
def _get_meta(self, path):
|
|
data = pkginfo.get_metadata(path)
|
|
if data:
|
|
return data
|
|
else:
|
|
print "Couldn't get metadata from %s. Not added to chishop" % os.path.basename(path)
|
|
return None
|