aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsk Solem <askh@modwheel.net>2009-03-17 10:24:12 +0100
committerAsk Solem Hoel <askh@opera.com>2009-03-17 10:24:12 +0100
commitbce41a16d3e2004c9ecefedb7cff94ebf2955755 (patch)
treeaecfc1fb44463a22de7226be9ffedbc43c7a34f1
downloadchishop-bce41a16d3e2004c9ecefedb7cff94ebf2955755.tar.bz2
chishop-bce41a16d3e2004c9ecefedb7cff94ebf2955755.tar.xz
chishop-bce41a16d3e2004c9ecefedb7cff94ebf2955755.zip
Initial checkin
-rw-r--r--__init__.py0
-rw-r--r--djangopypi/__init__.py0
-rw-r--r--djangopypi/admin.py5
-rw-r--r--djangopypi/forms.py35
-rw-r--r--djangopypi/models.py85
-rw-r--r--djangopypi/templates/djangopypi/show_links.html8
-rw-r--r--djangopypi/templates/djangopypi/show_version.html6
-rw-r--r--djangopypi/templates/djangopypi/simple.html5
-rw-r--r--djangopypi/views.py85
-rw-r--r--manage.py11
-rwxr-xr-xmedia/_0
-rwxr-xr-xmedia/dists/django-greystripe-0.1.tar.gzbin0 -> 4653 bytes
-rwxr-xr-xmedia/foo.txt0
-rw-r--r--settings.py91
-rw-r--r--urls.py33
15 files changed, 364 insertions, 0 deletions
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/__init__.py
diff --git a/djangopypi/__init__.py b/djangopypi/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/djangopypi/__init__.py
diff --git a/djangopypi/admin.py b/djangopypi/admin.py
new file mode 100644
index 0000000..6e20fd3
--- /dev/null
+++ b/djangopypi/admin.py
@@ -0,0 +1,5 @@
1from django.contrib import admin
2from djangopypi.models import Project, Release
3
4admin.site.register(Project)
5admin.site.register(Release)
diff --git a/djangopypi/forms.py b/djangopypi/forms.py
new file mode 100644
index 0000000..922301b
--- /dev/null
+++ b/djangopypi/forms.py
@@ -0,0 +1,35 @@
1from django import forms
2from djangopypi.models import Project, Classifier, Release
3
4class ProjectRegisterForm(forms.Form):
5 name = forms.CharField()
6 license = forms.CharField(required=False)
7 metadata_version = forms.CharField(initial="1.0")
8 author = forms.CharField(required=False)
9 home_page = forms.CharField(required=False)
10 download_url = forms.CharField(required=False)
11 summary = forms.CharField(required=False)
12 description = forms.CharField(required=False)
13 author_email = forms.CharField(required=False)
14 version = forms.CharField()
15 platform = forms.CharField(required=False)
16
17 def save(self, classifiers, file=None):
18 values = dict(self.cleaned_data)
19 name = values.pop("name")
20 version = values.pop("version")
21 platform = values.pop("platform")
22 project, c = Project.objects.get_or_create(name=name, defaults=values)
23 for classifier in classifiers:
24 project.classifiers.add(
25 Classifier.objects.get_or_create(name=classifier)[0])
26 release, c = Release.objects.get_or_create(version=version,
27 platform=platform, project=project)
28 if file:
29 release.distribution.save(file.name, file, save=True)
30 release.save()
31
32
33
34
35
diff --git a/djangopypi/models.py b/djangopypi/models.py
new file mode 100644
index 0000000..34276a5
--- /dev/null
+++ b/djangopypi/models.py
@@ -0,0 +1,85 @@
1import os
2from django.db import models
3from django.utils.translation import ugettext_lazy as _
4
5OS_NAMES = (
6 ("aix", "AIX"),
7 ("beos", "BeOS"),
8 ("debian", "Debian Linux"),
9 ("dos", "DOS"),
10 ("freebsd", "FreeBSD"),
11 ("hpux", "HP/UX"),
12 ("mac", "Mac System x."),
13 ("macos", "MacOS X"),
14 ("mandrake", "Mandrake Linux"),
15 ("netbsd", "NetBSD"),
16 ("openbsd", "OpenBSD"),
17 ("qnx", "QNX"),
18 ("redhat", "RedHat Linux"),
19 ("solaris", "SUN Solaris"),
20 ("suse", "SuSE Linux"),
21 ("yellowdog", "Yellow Dog Linux"),
22)
23
24ARCHITECTURES = (
25 ("alpha", "Alpha"),
26 ("hppa", "HPPA"),
27 ("ix86", "Intel"),
28 ("powerpc", "PowerPC"),
29 ("sparc", "Sparc"),
30 ("ultrasparc", "UltraSparc"),
31)
32
33class Classifier(models.Model):
34 name = models.CharField(max_length=255, unique=True)
35
36 class Meta:
37 verbose_name = _(u"classifier")
38 verbose_name_plural = _(u"classifiers")
39
40 def __unicode__(self):
41 return self.name
42
43class Project(models.Model):
44 name = models.CharField(max_length=255, unique=True)
45 license = models.CharField(max_length=255, blank=True)
46 metadata_version = models.CharField(max_length=64, default=1.0)
47 author = models.CharField(max_length=128, blank=True)
48 home_page = models.URLField(verify_exists=False, blank=True, null=True)
49 download_url = models.URLField(verify_exists=False, blank=True, null=True)
50 summary = models.TextField(blank=True)
51 description = models.TextField(blank=True)
52 author_email = models.CharField(max_length=255, blank=True)
53 classifiers = models.ManyToManyField(Classifier)
54
55 class Meta:
56 verbose_name = _(u"project")
57 verbose_name_plural = _(u"projects")
58
59 def __unicode__(self):
60 return self.name
61
62class Release(models.Model):
63 version = models.CharField(max_length=128)
64 distribution = models.FileField(upload_to="dists")
65 dist_md5sum = models.CharField(max_length=255, blank=True)
66 platform = models.CharField(max_length=255, blank=True)
67 signature = models.CharField(max_length=128, blank=True)
68 project = models.ForeignKey(Project, related_name="releases")
69
70 class Meta:
71 unique_together = ('version', 'platform')
72 verbose_name = _(u"release")
73 verbose_name_plural = _(u"releases")
74
75 def __unicode__(self):
76 return self.version
77
78 @property
79 def filename(self):
80 return os.path.basename(self.distribution.name)
81
82 @property
83 def path(self):
84 return self.distribution.name
85
diff --git a/djangopypi/templates/djangopypi/show_links.html b/djangopypi/templates/djangopypi/show_links.html
new file mode 100644
index 0000000..b805f47
--- /dev/null
+++ b/djangopypi/templates/djangopypi/show_links.html
@@ -0,0 +1,8 @@
1<html><head><title>Links for {{ dist_name }}</title></head><body>
2<h1>Links for {{ dist_name }}</h1>
3
4{% for release in releases %}
5<a href="/media/{{ release.path }}#md5=release.dist_md5sum"
6>{{ release.filename }}</a><br />
7{% endfor %}
8</body></html>
diff --git a/djangopypi/templates/djangopypi/show_version.html b/djangopypi/templates/djangopypi/show_version.html
new file mode 100644
index 0000000..f0c9d75
--- /dev/null
+++ b/djangopypi/templates/djangopypi/show_version.html
@@ -0,0 +1,6 @@
1<html><head><title>Links for {{ dist_name }} {{ version }}</title></head><body>
2<h1>Links for {{ dist_name }} {{ version }}</h1>
3
4<a href="/media/{{ release.path }}#md5=release.dist_md5sum"
5>{{ release.filename }}</a><br />
6</body></html>
diff --git a/djangopypi/templates/djangopypi/simple.html b/djangopypi/templates/djangopypi/simple.html
new file mode 100644
index 0000000..de761a5
--- /dev/null
+++ b/djangopypi/templates/djangopypi/simple.html
@@ -0,0 +1,5 @@
1<html><head><title>Simple Index</title></head></body>
2{% for dist in dists %}
3<a href="{{ dist.name }}"/>{{ dist.name }}</a><br />
4{% endfor %}
5</body></html>
diff --git a/djangopypi/views.py b/djangopypi/views.py
new file mode 100644
index 0000000..90a9846
--- /dev/null
+++ b/djangopypi/views.py
@@ -0,0 +1,85 @@
1# Create your views here.
2from django.http import HttpResponse, HttpResponseBadRequest, QueryDict
3from django.shortcuts import render_to_response
4from djangopypi.models import Project
5from djangopypi.forms import ProjectRegisterForm
6from django.template import RequestContext
7from yadayada.utils import template_path_builder
8from django.utils.datastructures import MultiValueDict
9from django.core.files.uploadedfile import SimpleUploadedFile
10
11T = template_path_builder("djangopypi")
12
13
14def parse_weird_post_data(data):
15 sep = data.splitlines()[1]
16 items = data.split(sep)
17 post_data = {}
18 files = {}
19 for part in items:
20 if not part.strip():
21 continue
22 item = part.splitlines()
23 if len(item) < 2: continue
24 header = item[1].replace("Content-Disposition: form-data; ", "")
25 kvpairs = header.split(";")
26 headers = {}
27 for kvpair in kvpairs:
28 if not kvpair: continue
29 key, value = kvpair.split("=")
30 headers[key] = value.strip('"')
31 if not "name" in headers: continue
32 content = part[len("\n".join(item[0:2]))+2:len(part)-1]
33 if "filename" in headers:
34 file = SimpleUploadedFile(headers["filename"], content,
35 content_type="application/gzip")
36 files[headers["name"]] = file
37 elif headers["name"] in post_data:
38 post_data[headers["name"]].append(content)
39 else:
40 post_data[headers["name"]] = [content]
41
42 return MultiValueDict(post_data), files
43
44
45def simple(request, template_name=T("simple")):
46 if request.method == "POST":
47 post_data, files = parse_weird_post_data(request.raw_post_data)
48 action = post_data.get(":action")
49 classifiers = post_data.getlist("classifiers")
50 register_form = ProjectRegisterForm(post_data.copy())
51 if register_form.is_valid():
52 return HttpResponse(register_form.save(classifiers,
53 file=files.get("content")))
54 return HttpResponse("Successfully registered.")
55 return HttpResponse("ERRORS: %s" % register_form.errors)
56
57 dists = Project.objects.all()
58 context = RequestContext(request, {
59 "dists": dists,
60 })
61
62 return render_to_response(template_name, context_instance=context)
63
64def show_links(request, dist_name, template_name=T("show_links")):
65 releases = Project.objects.get(name=dist_name) \
66 .releases.all().order_by('-version')
67
68 context = RequestContext(request, {
69 "dist_name": dist_name,
70 "releases": releases,
71 })
72
73 return render_to_response(template_name, context_instance=context)
74
75def show_version(request, dist_name, version, template_name=T("show_version")):
76 release = Project.objects.get(name=dist_name).releases \
77 .get(version=version)
78
79 context = RequestContext(request, {
80 "dist_name": dist_name,
81 "version": version,
82 "release": release,
83 })
84
85 return render_to_response(template_name, context_instance=context)
diff --git a/manage.py b/manage.py
new file mode 100644
index 0000000..5e78ea9
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,11 @@
1#!/usr/bin/env python
2from django.core.management import execute_manager
3try:
4 import settings # Assumed to be in the same directory.
5except ImportError:
6 import sys
7 sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
8 sys.exit(1)
9
10if __name__ == "__main__":
11 execute_manager(settings)
diff --git a/media/_ b/media/_
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/media/_
diff --git a/media/dists/django-greystripe-0.1.tar.gz b/media/dists/django-greystripe-0.1.tar.gz
new file mode 100755
index 0000000..bef3dd7
--- /dev/null
+++ b/media/dists/django-greystripe-0.1.tar.gz
Binary files differ
diff --git a/media/foo.txt b/media/foo.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/media/foo.txt
diff --git a/settings.py b/settings.py
new file mode 100644
index 0000000..8c18760
--- /dev/null
+++ b/settings.py
@@ -0,0 +1,91 @@
1# Django settings for djangopypi project.
2import os
3
4DEBUG = True
5TEMPLATE_DEBUG = DEBUG
6LOCAL_DEVELOPMENT = True
7
8if LOCAL_DEVELOPMENT:
9 import os
10 import sys
11 sys.path.append(os.path.dirname(__file__))
12
13ADMINS = (
14 # ('Your Name', 'your_email@domain.com'),
15)
16
17MANAGERS = ADMINS
18
19DATABASE_ENGINE = 'sqlite3'
20DATABASE_NAME = 'devdatabase.db'
21DATABASE_USER = ''
22DATABASE_PASSWORD = ''
23DATABASE_HOST = ''
24DATABASE_PORT = ''
25
26# Local time zone for this installation. Choices can be found here:
27# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
28# although not all choices may be available on all operating systems.
29# If running in a Windows environment this must be set to the same as your
30# system time zone.
31TIME_ZONE = 'America/Chicago'
32
33# Language code for this installation. All choices can be found here:
34# http://www.i18nguy.com/unicode/language-identifiers.html
35LANGUAGE_CODE = 'en-us'
36
37SITE_ID = 1
38
39# If you set this to False, Django will make some optimizations so as not
40# to load the internationalization machinery.
41USE_I18N = True
42
43# Absolute path to the directory that holds media.
44# Example: "/home/media/media.lawrence.com/"
45here = os.path.abspath(os.path.dirname(__file__))
46MEDIA_ROOT = os.path.join(here, 'media')
47
48# URL that handles the media served from MEDIA_ROOT. Make sure to use a
49# trailing slash if there is a path component (optional in other cases).
50# Examples: "http://media.lawrence.com", "http://example.com/media/"
51MEDIA_URL = 'media/'
52
53MEDIA_PREFIX = "/media/"
54
55# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
56# trailing slash.
57# Examples: "http://foo.com/media/", "/media/".
58ADMIN_MEDIA_PREFIX = '/admin-media/'
59
60# Make this unique, and don't share it with anybody.
61SECRET_KEY = 'w_#0r2hh)=!zbynb*gg&969@)sy#^-^ia3m*+sd4@lst$zyaxu'
62
63# List of callables that know how to import templates from various sources.
64TEMPLATE_LOADERS = (
65 'django.template.loaders.filesystem.load_template_source',
66 'django.template.loaders.app_directories.load_template_source',
67# 'django.template.loaders.eggs.load_template_source',
68)
69
70MIDDLEWARE_CLASSES = (
71 'django.middleware.common.CommonMiddleware',
72 'django.contrib.sessions.middleware.SessionMiddleware',
73 'django.contrib.auth.middleware.AuthenticationMiddleware',
74)
75
76ROOT_URLCONF = 'urls'
77
78TEMPLATE_DIRS = (
79 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
80 # Always use forward slashes, even on Windows.
81 # Don't forget to use absolute paths, not relative paths.
82)
83
84INSTALLED_APPS = (
85 'django.contrib.auth',
86 'django.contrib.contenttypes',
87 'django.contrib.sessions',
88 'django.contrib.sites',
89 'django.contrib.admin',
90 'djangopypi',
91)
diff --git a/urls.py b/urls.py
new file mode 100644
index 0000000..f6709f8
--- /dev/null
+++ b/urls.py
@@ -0,0 +1,33 @@
1# -*- coding: utf-8 -*-
2from django.conf.urls.defaults import patterns, url, include
3from django.conf import settings
4from django.contrib import admin
5
6admin.autodiscover()
7
8urlpatterns = patterns('')
9
10# Serve static pages.
11if settings.LOCAL_DEVELOPMENT:
12 urlpatterns += patterns("django.views",
13 url(r"%s(?P<path>.*)$" % settings.MEDIA_URL[1:], "static.serve", {
14 "document_root": settings.MEDIA_ROOT}))
15urlpatterns += patterns("",
16 # Admin interface
17 url(r'^admin/doc/', include("django.contrib.admindocs.urls")),
18 url(r'^admin/(.*)', admin.site.root),
19
20 # Simple PyPI
21 url(r'^/?$', "djangopypi.views.simple",
22 name="djangopypi-simple"),
23
24 url(r'^(?P<dist_name>[\w\d_\-]+)/(?P<version>[\w\.\d\-_]+)/?',
25 "djangopypi.views.show_version",
26 name="djangopypi-show_version"),
27
28 url(r'^(?P<dist_name>[\w\d_\-]+)/?', "djangopypi.views.show_links",
29 name="djangopypi-show_links"),
30
31
32)
33