diff options
author | Ask Solem <askh@opera.com> | 2009-11-11 16:57:38 +0100 |
---|---|---|
committer | Ask Solem <askh@opera.com> | 2009-11-11 16:57:38 +0100 |
commit | 0de66ebcf2bfb305a38d77229bd9a776ae8d1b8e (patch) | |
tree | 72b3dffa42cbbcccd82dfb28b015bff7658176f7 | |
parent | 55cb4b7bb9ad31497e44698194598b626d9f9609 (diff) | |
parent | 8990f1186516132d768ff6a86b2d789a1c3db7aa (diff) | |
download | chishop-0de66ebcf2bfb305a38d77229bd9a776ae8d1b8e.tar.bz2 chishop-0de66ebcf2bfb305a38d77229bd9a776ae8d1b8e.tar.xz chishop-0de66ebcf2bfb305a38d77229bd9a776ae8d1b8e.zip |
Merge branch 'sverrejoh/master'
21 files changed, 254 insertions, 18 deletions
@@ -6,27 +6,23 @@ ChiShop/DjangoPyPI | |||
6 | Installation | 6 | Installation |
7 | ============ | 7 | ============ |
8 | 8 | ||
9 | First you have to install the dependencies:: | 9 | Install dependencies:: |
10 | 10 | ||
11 | $ python setup.py build | 11 | $ python bootstrap.py --distribute |
12 | # python setup.py install # (run as root) | 12 | $ ./bin/buildout |
13 | 13 | ||
14 | Initial configuration | 14 | Initial configuration |
15 | --------------------- | 15 | --------------------- |
16 | :: | 16 | :: |
17 | 17 | ||
18 | $ cd chipshop/ | 18 | $ $EDITOR chishop/settings.py |
19 | 19 | $ ./bin/django syncdb | |
20 | $ $EDITOR settings.py | ||
21 | |||
22 | $ python manage.py syncdb | ||
23 | 20 | ||
24 | Run the PyPI server | 21 | Run the PyPI server |
25 | ------------------- | 22 | ------------------- |
26 | :: | 23 | :: |
27 | 24 | ||
28 | $ python manage.py runserver | 25 | $ ./bin/django runserver |
29 | |||
30 | 26 | ||
31 | Please note that ``chishop/media/dists`` has to be writable by the | 27 | Please note that ``chishop/media/dists`` has to be writable by the |
32 | user the web-server is running as. | 28 | user the web-server is running as. |
diff --git a/bootstrap.py b/bootstrap.py new file mode 100644 index 0000000..b964024 --- /dev/null +++ b/bootstrap.py | |||
@@ -0,0 +1,121 @@ | |||
1 | ############################################################################## | ||
2 | # | ||
3 | # Copyright (c) 2006 Zope Corporation and Contributors. | ||
4 | # All Rights Reserved. | ||
5 | # | ||
6 | # This software is subject to the provisions of the Zope Public License, | ||
7 | # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
8 | # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
9 | # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
10 | # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
11 | # FOR A PARTICULAR PURPOSE. | ||
12 | # | ||
13 | ############################################################################## | ||
14 | """Bootstrap a buildout-based project | ||
15 | |||
16 | Simply run this script in a directory containing a buildout.cfg. | ||
17 | The script accepts buildout command-line options, so you can | ||
18 | use the -c option to specify an alternate configuration file. | ||
19 | |||
20 | $Id$ | ||
21 | """ | ||
22 | |||
23 | import os, shutil, sys, tempfile, urllib2 | ||
24 | from optparse import OptionParser | ||
25 | |||
26 | tmpeggs = tempfile.mkdtemp() | ||
27 | |||
28 | is_jython = sys.platform.startswith('java') | ||
29 | |||
30 | # parsing arguments | ||
31 | parser = OptionParser() | ||
32 | parser.add_option("-v", "--version", dest="version", | ||
33 | help="use a specific zc.buildout version") | ||
34 | parser.add_option("-d", "--distribute", | ||
35 | action="store_true", dest="distribute", default=False, | ||
36 | help="Use Disribute rather than Setuptools.") | ||
37 | |||
38 | parser.add_option("-c", None, action="store", dest="config_file", | ||
39 | help=("Specify the path to the buildout configuration " | ||
40 | "file to be used.")) | ||
41 | |||
42 | options, args = parser.parse_args() | ||
43 | |||
44 | # if -c was provided, we push it back into args for buildout' main function | ||
45 | if options.config_file is not None: | ||
46 | args += ['-c', options.config_file] | ||
47 | |||
48 | if options.version is not None: | ||
49 | VERSION = '==%s' % options.version | ||
50 | else: | ||
51 | VERSION = '' | ||
52 | |||
53 | USE_DISTRIBUTE = options.distribute | ||
54 | args = args + ['bootstrap'] | ||
55 | |||
56 | to_reload = False | ||
57 | try: | ||
58 | import pkg_resources | ||
59 | if not hasattr(pkg_resources, '_distribute'): | ||
60 | to_reload = True | ||
61 | raise ImportError | ||
62 | except ImportError: | ||
63 | ez = {} | ||
64 | if USE_DISTRIBUTE: | ||
65 | exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py' | ||
66 | ).read() in ez | ||
67 | ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True) | ||
68 | else: | ||
69 | exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' | ||
70 | ).read() in ez | ||
71 | ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) | ||
72 | |||
73 | if to_reload: | ||
74 | reload(pkg_resources) | ||
75 | else: | ||
76 | import pkg_resources | ||
77 | |||
78 | if sys.platform == 'win32': | ||
79 | def quote(c): | ||
80 | if ' ' in c: | ||
81 | return '"%s"' % c # work around spawn lamosity on windows | ||
82 | else: | ||
83 | return c | ||
84 | else: | ||
85 | def quote (c): | ||
86 | return c | ||
87 | |||
88 | cmd = 'from setuptools.command.easy_install import main; main()' | ||
89 | ws = pkg_resources.working_set | ||
90 | |||
91 | if USE_DISTRIBUTE: | ||
92 | requirement = 'distribute' | ||
93 | else: | ||
94 | requirement = 'setuptools' | ||
95 | |||
96 | if is_jython: | ||
97 | import subprocess | ||
98 | |||
99 | assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', | ||
100 | quote(tmpeggs), 'zc.buildout' + VERSION], | ||
101 | env=dict(os.environ, | ||
102 | PYTHONPATH= | ||
103 | ws.find(pkg_resources.Requirement.parse(requirement)).location | ||
104 | ), | ||
105 | ).wait() == 0 | ||
106 | |||
107 | else: | ||
108 | assert os.spawnle( | ||
109 | os.P_WAIT, sys.executable, quote (sys.executable), | ||
110 | '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION, | ||
111 | dict(os.environ, | ||
112 | PYTHONPATH= | ||
113 | ws.find(pkg_resources.Requirement.parse(requirement)).location | ||
114 | ), | ||
115 | ) == 0 | ||
116 | |||
117 | ws.add_entry(tmpeggs) | ||
118 | ws.require('zc.buildout' + VERSION) | ||
119 | import zc.buildout.buildout | ||
120 | zc.buildout.buildout.main(args) | ||
121 | shutil.rmtree(tmpeggs) | ||
diff --git a/buildout.cfg b/buildout.cfg index fc36b3c..160db4c 100644 --- a/buildout.cfg +++ b/buildout.cfg | |||
@@ -1,11 +1,15 @@ | |||
1 | [buildout] | 1 | [buildout] |
2 | parts = django | 2 | parts = django |
3 | find-links = http://bitbucket.org/ubernostrum/django-registration/downloads/django-registration-0.8-alpha-1.tar.gz | ||
4 | unzip = true | ||
3 | eggs = pkginfo | 5 | eggs = pkginfo |
6 | django-registration==0.8-alpha-1 | ||
4 | 7 | ||
5 | [django] | 8 | [django] |
6 | recipe = djangorecipe | 9 | recipe = djangorecipe |
7 | version = 1.0.2 | 10 | version = 1.1.1 |
8 | settings = development | 11 | settings = settings |
9 | eggs = ${buildout:eggs} | 12 | eggs = ${buildout:eggs} |
13 | test = djangopypi | ||
10 | project = chishop | 14 | project = chishop |
11 | wsgi = true | 15 | wsgi = true |
diff --git a/chishop/settings.py b/chishop/settings.py index 00cf06d..ee286b5 100644 --- a/chishop/settings.py +++ b/chishop/settings.py | |||
@@ -16,6 +16,14 @@ DJANGOPYPI_RELEASE_UPLOAD_TO = 'dists' | |||
16 | # change to False if you do not want Django's default server to serve static pages | 16 | # change to False if you do not want Django's default server to serve static pages |
17 | LOCAL_DEVELOPMENT = True | 17 | LOCAL_DEVELOPMENT = True |
18 | 18 | ||
19 | REGISTRATION_OPEN = True | ||
20 | ACCOUNT_ACTIVATION_DAYS = 7 | ||
21 | LOGIN_REDIRECT_URL = "/" | ||
22 | |||
23 | EMAIL_HOST = '' | ||
24 | DEFAULT_FROM_EMAIL = '' | ||
25 | SERVER_EMAIL = DEFAULT_FROM_EMAIL | ||
26 | |||
19 | MANAGERS = ADMINS | 27 | MANAGERS = ADMINS |
20 | 28 | ||
21 | DATABASE_ENGINE = '' | 29 | DATABASE_ENGINE = '' |
@@ -77,6 +85,14 @@ MIDDLEWARE_CLASSES = ( | |||
77 | 85 | ||
78 | ROOT_URLCONF = 'urls' | 86 | ROOT_URLCONF = 'urls' |
79 | 87 | ||
88 | TEMPLATE_CONTEXT_PROCESSORS = ( | ||
89 | "django.core.context_processors.auth", | ||
90 | "django.core.context_processors.debug", | ||
91 | "django.core.context_processors.i18n", | ||
92 | "django.core.context_processors.media", | ||
93 | "django.core.context_processors.request", | ||
94 | ) | ||
95 | |||
80 | TEMPLATE_DIRS = ( | 96 | TEMPLATE_DIRS = ( |
81 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". | 97 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". |
82 | # Always use forward slashes, even on Windows. | 98 | # Always use forward slashes, even on Windows. |
@@ -92,5 +108,6 @@ INSTALLED_APPS = ( | |||
92 | 'django.contrib.admin', | 108 | 'django.contrib.admin', |
93 | 'django.contrib.markup', | 109 | 'django.contrib.markup', |
94 | 'django.contrib.admindocs', | 110 | 'django.contrib.admindocs', |
111 | 'registration', | ||
95 | 'djangopypi', | 112 | 'djangopypi', |
96 | ) | 113 | ) |
diff --git a/chishop/templates/base.html b/chishop/templates/base.html index cc21bf5..76483ce 100644 --- a/chishop/templates/base.html +++ b/chishop/templates/base.html | |||
@@ -20,6 +20,16 @@ | |||
20 | {% block site_logo %}{% endblock %} | 20 | {% block site_logo %}{% endblock %} |
21 | <h1 id="site-name">{% block site_name_header %}{% endblock %}</h1> | 21 | <h1 id="site-name">{% block site_name_header %}{% endblock %}</h1> |
22 | </div> | 22 | </div> |
23 | |||
24 | <div id="user-tools"> | ||
25 | {% if user.is_authenticated %} | ||
26 | Welcome, <strong>{{user.username}}</strong>. | ||
27 | <a href="{% url django.contrib.auth.views.logout %}?next={{request.path}}">Log out</a> | ||
28 | {% else %} | ||
29 | <a href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Log in</a> / | ||
30 | <a href="{% url registration_register %}">Register</a> | ||
31 | {% endif %} | ||
32 | </div> | ||
23 | </div> | 33 | </div> |
24 | <!-- END Header --> | 34 | <!-- END Header --> |
25 | 35 | ||
@@ -60,4 +70,3 @@ | |||
60 | 70 | ||
61 | </body> | 71 | </body> |
62 | </html> | 72 | </html> |
63 | |||
diff --git a/djangopypi/templates/djangopypi/pypi.html b/chishop/templates/djangopypi/pypi.html index f98cf44..f98cf44 100644 --- a/djangopypi/templates/djangopypi/pypi.html +++ b/chishop/templates/djangopypi/pypi.html | |||
diff --git a/djangopypi/templates/djangopypi/pypi_show_links.html b/chishop/templates/djangopypi/pypi_show_links.html index 6b239d1..6b239d1 100644 --- a/djangopypi/templates/djangopypi/pypi_show_links.html +++ b/chishop/templates/djangopypi/pypi_show_links.html | |||
diff --git a/djangopypi/templates/djangopypi/show_links.html b/chishop/templates/djangopypi/show_links.html index 57a1268..57a1268 100644 --- a/djangopypi/templates/djangopypi/show_links.html +++ b/chishop/templates/djangopypi/show_links.html | |||
diff --git a/djangopypi/templates/djangopypi/show_version.html b/chishop/templates/djangopypi/show_version.html index d3b393a..d3b393a 100644 --- a/djangopypi/templates/djangopypi/show_version.html +++ b/chishop/templates/djangopypi/show_version.html | |||
diff --git a/djangopypi/templates/djangopypi/simple.html b/chishop/templates/djangopypi/simple.html index 6a21d5c..6a21d5c 100644 --- a/djangopypi/templates/djangopypi/simple.html +++ b/chishop/templates/djangopypi/simple.html | |||
diff --git a/chishop/templates/registration/activate.html b/chishop/templates/registration/activate.html new file mode 100644 index 0000000..bc67771 --- /dev/null +++ b/chishop/templates/registration/activate.html | |||
@@ -0,0 +1,8 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block content %} | ||
4 | <h1>Activation Failed</h1> | ||
5 | <p> | ||
6 | Activation with key {{activation_key}} failed. | ||
7 | </p> | ||
8 | {% endblock %} | ||
diff --git a/chishop/templates/registration/activation_complete.html b/chishop/templates/registration/activation_complete.html new file mode 100644 index 0000000..c8e8aca --- /dev/null +++ b/chishop/templates/registration/activation_complete.html | |||
@@ -0,0 +1,9 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block content %} | ||
4 | <h1>Activation complete.</h1> | ||
5 | <p> | ||
6 | Hello {{user}}, you are registered. | ||
7 | Go <a href="/">here</a> to get back to the main page. | ||
8 | </p> | ||
9 | {% endblock %} | ||
diff --git a/chishop/templates/registration/activation_email.txt b/chishop/templates/registration/activation_email.txt new file mode 100644 index 0000000..0a25329 --- /dev/null +++ b/chishop/templates/registration/activation_email.txt | |||
@@ -0,0 +1,6 @@ | |||
1 | Welcome to Chishop. | ||
2 | |||
3 | Please click here to activate your account: | ||
4 | http://{{site}}/accounts/activate/{{activation_key}}/ | ||
5 | |||
6 | Account has to be activated within {{expiration_days}} days. | ||
diff --git a/chishop/templates/registration/activation_email_subject.txt b/chishop/templates/registration/activation_email_subject.txt new file mode 100644 index 0000000..93618cc --- /dev/null +++ b/chishop/templates/registration/activation_email_subject.txt | |||
@@ -0,0 +1 @@ | |||
Account Activation - {{ site }} | |||
diff --git a/chishop/templates/registration/login.html b/chishop/templates/registration/login.html new file mode 100644 index 0000000..6c7f799 --- /dev/null +++ b/chishop/templates/registration/login.html | |||
@@ -0,0 +1,8 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block content %} | ||
4 | <form method="post" action=""> | ||
5 | {{form.as_p}} | ||
6 | <input type="submit" value="Login"> | ||
7 | </form> | ||
8 | {% endblock %} | ||
diff --git a/chishop/templates/registration/logout.html b/chishop/templates/registration/logout.html new file mode 100644 index 0000000..06483a8 --- /dev/null +++ b/chishop/templates/registration/logout.html | |||
@@ -0,0 +1,7 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block main_content %} | ||
4 | <p> | ||
5 | {%trans "Logged out."%} | ||
6 | </p> | ||
7 | {% endblock %} | ||
diff --git a/chishop/templates/registration/registration_closed.html b/chishop/templates/registration/registration_closed.html new file mode 100644 index 0000000..c92e80b --- /dev/null +++ b/chishop/templates/registration/registration_closed.html | |||
@@ -0,0 +1,8 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block content %} | ||
4 | <h1>Registration Closed</h1> | ||
5 | <p> | ||
6 | Registration is disabled. | ||
7 | </p> | ||
8 | {% endblock %} | ||
diff --git a/chishop/templates/registration/registration_complete.html b/chishop/templates/registration/registration_complete.html new file mode 100644 index 0000000..d9a19cf --- /dev/null +++ b/chishop/templates/registration/registration_complete.html | |||
@@ -0,0 +1,8 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block content %} | ||
4 | <h1>Registration complete</h1> | ||
5 | <p> | ||
6 | An activation mail has been sent to you. | ||
7 | </p> | ||
8 | {% endblock %} | ||
diff --git a/chishop/templates/registration/registration_form.html b/chishop/templates/registration/registration_form.html new file mode 100644 index 0000000..719a875 --- /dev/null +++ b/chishop/templates/registration/registration_form.html | |||
@@ -0,0 +1,8 @@ | |||
1 | {% extends "base_site.html" %} | ||
2 | |||
3 | {% block content %} | ||
4 | <h1>Register</h1> | ||
5 | <form method="post" action=""> | ||
6 | {{form.as_p}} | ||
7 | <input type="submit" value="Register"> | ||
8 | {% endblock %} | ||
diff --git a/chishop/urls.py b/chishop/urls.py index b9f3e65..ab2e8a9 100644 --- a/chishop/urls.py +++ b/chishop/urls.py | |||
@@ -18,6 +18,9 @@ urlpatterns += patterns("", | |||
18 | url(r'^admin/doc/', include("django.contrib.admindocs.urls")), | 18 | url(r'^admin/doc/', include("django.contrib.admindocs.urls")), |
19 | url(r'^admin/(.*)', admin.site.root), | 19 | url(r'^admin/(.*)', admin.site.root), |
20 | 20 | ||
21 | # Registration | ||
22 | url(r'^accounts/', include('registration.backends.default.urls')), | ||
23 | |||
24 | # The Chishop | ||
21 | url(r'', include("djangopypi.urls")) | 25 | url(r'', include("djangopypi.urls")) |
22 | ) | 26 | ) |
23 | |||
diff --git a/djangopypi/views.py b/djangopypi/views.py index 816a170..597598f 100644 --- a/djangopypi/views.py +++ b/djangopypi/views.py | |||
@@ -10,15 +10,17 @@ from django.conf import settings | |||
10 | from django.http import Http404, HttpResponse, HttpResponseBadRequest | 10 | from django.http import Http404, HttpResponse, HttpResponseBadRequest |
11 | from django.http import QueryDict, HttpResponseForbidden | 11 | from django.http import QueryDict, HttpResponseForbidden |
12 | from django.shortcuts import render_to_response | 12 | from django.shortcuts import render_to_response |
13 | from djangopypi.models import Project, Classifier, Release, UPLOAD_TO | ||
14 | from djangopypi.forms import ProjectForm, ReleaseForm | ||
15 | from django.template import RequestContext | 13 | from django.template import RequestContext |
16 | from django.utils.datastructures import MultiValueDict | 14 | from django.utils.datastructures import MultiValueDict |
17 | from django.utils.translation import ugettext_lazy as _ | 15 | from django.utils.translation import ugettext_lazy as _ |
18 | from django.core.files.uploadedfile import SimpleUploadedFile | 16 | from django.core.files.uploadedfile import SimpleUploadedFile |
19 | from django.contrib.auth import authenticate, login | 17 | from django.contrib.auth import authenticate, login |
20 | from djangopypi.http import HttpResponseNotImplemented | 18 | from registration.backends import get_backend |
21 | from djangopypi.http import HttpResponseUnauthorized | 19 | from registration.forms import RegistrationForm |
20 | |||
21 | from djangopypi.models import Project, Classifier, Release, UPLOAD_TO | ||
22 | from djangopypi.forms import ProjectForm, ReleaseForm | ||
23 | from djangopypi.http import HttpResponseNotImplemented, HttpResponseUnauthorized | ||
22 | from djangopypi.utils import decode_fs | 24 | from djangopypi.utils import decode_fs |
23 | 25 | ||
24 | 26 | ||
@@ -108,12 +110,33 @@ def register_or_upload(request, post_data, files): | |||
108 | 110 | ||
109 | return submit_project_or_release(user, post_data, files) | 111 | return submit_project_or_release(user, post_data, files) |
110 | 112 | ||
113 | def create_user(request, post_data, files): | ||
114 | """Create new user from a distutil client request""" | ||
115 | form = RegistrationForm({"username": post_data["name"], | ||
116 | "email": post_data["email"], | ||
117 | "password1": post_data["password"], | ||
118 | "password2": post_data["password"]}) | ||
119 | if not form.is_valid(): | ||
120 | # Dist Utils requires error msg in HTTP status: "HTTP/1.1 400 msg" | ||
121 | # Which is HTTP/WSGI incompatible, so we're just returning a empty 400. | ||
122 | return HttpResponseBadRequest() | ||
123 | |||
124 | backend = get_backend("registration.backends.default.DefaultBackend") | ||
125 | if not backend.registration_allowed(request): | ||
126 | return HttpResponseBadRequest() | ||
127 | new_user = backend.register(request, **form.cleaned_data) | ||
128 | return HttpResponse("OK\n", status=200, mimetype='text/plain') | ||
129 | |||
130 | |||
111 | ACTIONS = { | 131 | ACTIONS = { |
112 | # file_upload is the action used with distutils ``sdist`` command. | 132 | # file_upload is the action used with distutils ``sdist`` command. |
113 | "file_upload": register_or_upload, | 133 | "file_upload": register_or_upload, |
114 | 134 | ||
115 | # submit is the :action used with distutils ``register`` command. | 135 | # submit is the :action used with distutils ``register`` command. |
116 | "submit": register_or_upload, | 136 | "submit": register_or_upload, |
137 | |||
138 | # user is the action used when registering a new user | ||
139 | "user": create_user, | ||
117 | } | 140 | } |
118 | 141 | ||
119 | 142 | ||