diff --git a/src/djangopypi/djangopypi/models.py b/src/djangopypi/djangopypi/models.py
index 6c9c602..1fbe772 100644
--- a/src/djangopypi/djangopypi/models.py
+++ b/src/djangopypi/djangopypi/models.py
@@ -2,6 +2,7 @@ import os
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
+from django.utils import simplejson as json
from django.contrib.auth.models import User
@@ -21,8 +22,10 @@ class Project(models.Model):
name = models.CharField(max_length=255, unique=True, primary_key=True)
auto_hide = models.BooleanField(default=True, blank=False)
allow_comments = models.BooleanField(default=True, blank=False)
- owners = models.ManyToManyField(User, related_name="projects_owned")
- maintainers = models.ManyToManyField(User, related_name="projects_maintained")
+ owners = models.ManyToManyField(User, blank=True,
+ related_name="projects_owned")
+ maintainers = models.ManyToManyField(User, blank=True,
+ related_name="projects_maintained")
class Meta:
verbose_name = _(u"project")
@@ -38,7 +41,21 @@ class Project(models.Model):
@models.permalink
def get_pypi_absolute_url(self):
return ('djangopypi-pypi_show_links', (), {'dist_name': self.name})
-
+
+ @property
+ def description(self):
+ latest = self.latest
+ if latest:
+ return latest.description
+ return u''
+
+ @property
+ def latest(self):
+ try:
+ return self.releases.latest()
+ except Release.DoesNotExist:
+ return None
+
def get_release(self, version):
"""Return the release object for version, or None"""
try:
@@ -57,6 +74,8 @@ class Release(models.Model):
verbose_name = _(u"release")
verbose_name_plural = _(u"releases")
unique_together = ("project", "version")
+ get_latest_by = 'created'
+ ordering = ['-created']
def __unicode__(self):
return self.release_name
@@ -65,6 +84,29 @@ class Release(models.Model):
def release_name(self):
return u"%s-%s" % (self.project.name, self.version)
+ @property
+ def parsed_package_info(self):
+ if not hasattr(self,'_parsed_package_info'):
+ try:
+ self._parsed_package_info = json.loads(self.package_info)
+ except Exception, e:
+ print str(e)
+ self._parsed_package_info = {}
+ return self._parsed_package_info
+
+ @property
+ def description(self):
+ return self.parsed_package_info.get('description',u'')
+
+ def save(self, *args, **kwargs):
+ if hasattr(self,'_parsed_package_info'):
+ try:
+ self.package_info = json.dumps(self._parsed_package_info)
+ delattr(self,'_parsed_package_info')
+ except Exception, e:
+ print str(e)
+ return super(Release, self).save(*args, **kwargs)
+
@models.permalink
def get_absolute_url(self):
return ('djangopypi-show_version', (), {'project': self.project.name,
diff --git a/src/djangopypi/djangopypi/settings.py b/src/djangopypi/djangopypi/settings.py
index 23d5a26..771f151 100644
--- a/src/djangopypi/djangopypi/settings.py
+++ b/src/djangopypi/djangopypi/settings.py
@@ -65,8 +65,9 @@ if not hasattr(settings,'DJANGOPYPI_PYTHON_VERSIONS'):
('3.2','3.2'),
)
-if not hasattr(settings, 'DJANGOPYPI_SIMPLE_VIEW'):
- settings.DJANGOPYPI_SIMPLE_VIEW = 'djangopypi.views.simple'
+if not hasattr(settings, 'DJANGOPYPI_FALLBACK_VIEW'):
+ from djangopypi import views
+ settings.DJANGOPYPI_FALLBACK_VIEW = views.index
if not hasattr(settings,'DJANGOPYPI_ACTION_VIEWS'):
from djangopypi.views.dists import register_or_upload
@@ -76,5 +77,7 @@ if not hasattr(settings,'DJANGOPYPI_ACTION_VIEWS'):
"file_upload": register_or_upload, #``sdist`` command
"submit": register_or_upload, #``register`` command
"user": create_user, # registering a user
+
+
}
\ No newline at end of file
diff --git a/src/djangopypi/djangopypi/templates/djangopypi/project_list.html b/src/djangopypi/djangopypi/templates/djangopypi/project_list.html
new file mode 100644
index 0000000..1c5e3bc
--- /dev/null
+++ b/src/djangopypi/djangopypi/templates/djangopypi/project_list.html
@@ -0,0 +1,13 @@
+
+
+ Project List
+
+
+ Project List
+
+ {% for project in project_list %}
+ - {{ project.name }}{% if project.description %}: {{ project.description }}{% endif %}
+ {% endfor %}
+
+
+
\ No newline at end of file
diff --git a/src/djangopypi/djangopypi/urls.py b/src/djangopypi/djangopypi/urls.py
index 9623178..53f2032 100644
--- a/src/djangopypi/djangopypi/urls.py
+++ b/src/djangopypi/djangopypi/urls.py
@@ -2,9 +2,7 @@
from django.conf.urls.defaults import patterns, url, include
urlpatterns = patterns("djangopypi.views",
- # Simple PyPI
- url(r'^simple/$', "simple",
- name="djangopypi-simple"),
+ url(r'^pypi/$', "index", name="djangopypi-index"),
url(r'^simple/(?P[\w\d_\.\-]+)/(?P[\w\.\d\-_]+)/$',
"show_version",
@@ -13,8 +11,7 @@ urlpatterns = patterns("djangopypi.views",
url(r'^simple/(?P[\w\d_\.\-]+)/$', "show_links",
name="djangopypi-show_links"),
- url(r'^$', "root", {'template_name': 'djangopypi/pypi.html'},
- name="djangopypi-pypi"),
+ url(r'^$', "root", name="djangopypi-root"),
url(r'^(?P[\w\d_\.\-]+)/$', "show_links",
{'template_name': 'djangopypi/pypi_show_links.html'},
diff --git a/src/djangopypi/djangopypi/views/__init__.py b/src/djangopypi/djangopypi/views/__init__.py
index 02557cb..6871ac7 100644
--- a/src/djangopypi/djangopypi/views/__init__.py
+++ b/src/djangopypi/djangopypi/views/__init__.py
@@ -3,6 +3,9 @@ from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
+from django.views.generic import list_detail
+
+
from djangopypi.models import Project, Release
from djangopypi.http import HttpResponseNotImplemented
@@ -13,29 +16,26 @@ from djangopypi.views.search import search
-def root(request, root_redirect=None, **kwargs):
- if request.method != 'POST':
- if root_redirect is None:
- root_redirect = reverse(settings.DJANGOPYPI_SIMPLE_VIEW)
- return HttpResponseRedirect(root_redirect)
-
- parse_distutils_request(request)
+def root(request, fallback_view=None, **kwargs):
+ """ Root view of the package index, handle incoming actions from distutils
+ or redirect to a more user friendly view """
+ if request.method != 'POST':
+ if fallback_view is None:
+ fallback_view = settings.DJANGOPYPI_FALLBACK_VIEW
+ return fallback_view(request, **kwargs)
+
+ parse_distutils_request(request)
+ print str(request.POST)
action = request.POST.get(':action','')
if not action in settings.DJANGOPYPI_ACTION_VIEWS:
+ print 'unknown action: %s' % (action,)
return HttpResponseNotImplemented("The action %s is not implemented" % (action,))
- return settings.DJANGOPYPI_ACTION_VIEWS(request, **kwargs)
+ return settings.DJANGOPYPI_ACTION_VIEWS[action](request, **kwargs)
-def simple(request, template_name="djangopypi/simple.html"):
- context = RequestContext(request, {
- "dists": Project.objects.all().order_by("name"),
- "title": 'Package Index',
- })
-
- return render_to_response(template_name, context_instance=context)
def show_links(request, dist_name,
diff --git a/src/djangopypi/djangopypi/views/dists.py b/src/djangopypi/djangopypi/views/distutils.py
similarity index 100%
rename from src/djangopypi/djangopypi/views/dists.py
rename to src/djangopypi/djangopypi/views/distutils.py
diff --git a/src/djangopypi/djangopypi/views/packages.py b/src/djangopypi/djangopypi/views/packages.py
new file mode 100644
index 0000000..2f465f7
--- /dev/null
+++ b/src/djangopypi/djangopypi/views/packages.py
@@ -0,0 +1,21 @@
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from django.http import Http404, HttpResponseRedirect
+from django.views.generic import list_detail
+from django.shortcuts import get_object_or_404
+
+
+from djangopypi.models import Project, Release
+from djangopypi.views import release as release_views
+
+
+
+def index(request, **kwargs):
+ kwargs.setdefault('template_object_name','project')
+ return list_detail.object_list(request, queryset=Project.objects.all(),
+ **kwargs)
+
+def details(request, project, **kwargs):
+ kwargs.setdefault('template_object_name','project')
+ return list_detail.object_detail(request, queryset=Project.objects.all(),
+ object_id=project, **kwargs)
\ No newline at end of file