mirror of
https://github.com/kennethreitz-archive/chishop.git
synced 2026-06-05 23:40:18 +00:00
Merge branch 'runeh/master'
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
[buildout]
|
||||
parts = django
|
||||
eggs =
|
||||
eggs = pkginfo
|
||||
|
||||
[django]
|
||||
recipe = djangorecipe
|
||||
@@ -8,4 +8,4 @@ version = 1.0.2
|
||||
settings = development
|
||||
eggs = ${buildout:eggs}
|
||||
project = chishop
|
||||
wsgi = true
|
||||
wsgi = true
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
"""
|
||||
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):
|
||||
if path.endswith((".zip", ".tar.gz")):
|
||||
return pkginfo.SDist(path)
|
||||
elif path.endswith(".egg"):
|
||||
return pkginfo.BDist(path)
|
||||
else:
|
||||
print "Couldn't get metadata from %s. Not added to chishop" % os.path.basename(path)
|
||||
return None
|
||||
@@ -14,7 +14,7 @@ modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Neither the name of Ask Solem nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
@@ -107,6 +107,12 @@ class Project(models.Model):
|
||||
def get_pypi_absolute_url(self):
|
||||
return ('djangopypi-pypi_show_links', (), {'dist_name': self.name})
|
||||
|
||||
def get_release(self, version):
|
||||
"""Return the release object for version, or None"""
|
||||
try:
|
||||
self.releases.get(version=version)
|
||||
except Release.DoesNotExist:
|
||||
return None
|
||||
|
||||
class Release(models.Model):
|
||||
version = models.CharField(max_length=128)
|
||||
@@ -155,5 +161,3 @@ class Release(models.Model):
|
||||
|
||||
def get_dl_url(self):
|
||||
return "%s#md5=%s" % (self.distribution.url, self.md5_digest)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user