Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Re-organize views into views.dists, views.users, views.search

  • Loading branch information...
commit 1e2fdc99abff24259e1c47651ca34373a2dcf9d0 1 parent a2ac029
Ask Solem authored
View
51 djangopypi/http.py
@@ -1,4 +1,8 @@
from django.http import HttpResponse
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.utils.datastructures import MultiValueDict
+from django.contrib.auth import authenticate
+
class HttpResponseNotImplemented(HttpResponse):
status_code = 501
@@ -12,4 +16,51 @@ def __init__(self, realm):
self['WWW-Authenticate'] = 'Basic realm="%s"' % realm
+def parse_distutils_request(request):
+ raw_post_data = request.raw_post_data
+ sep = raw_post_data.splitlines()[1]
+ items = raw_post_data.split(sep)
+ post_data = {}
+ files = {}
+ for part in filter(lambda e: not e.isspace(), items):
+ item = part.splitlines()
+ if len(item) < 2:
+ continue
+ header = item[1].replace("Content-Disposition: form-data; ", "")
+ kvpairs = header.split(";")
+ headers = {}
+ for kvpair in kvpairs:
+ if not kvpair:
+ continue
+ key, value = kvpair.split("=")
+ headers[key] = value.strip('"')
+ if "name" not in headers:
+ continue
+ content = part[len("\n".join(item[0:2]))+2:len(part)-1]
+ if "filename" in headers:
+ file = SimpleUploadedFile(headers["filename"], content,
+ content_type="application/gzip")
+ files["distribution"] = [file]
+ elif headers["name"] in post_data:
+ post_data[headers["name"]].append(content)
+ else:
+ # Distutils sends UNKNOWN for empty fields (e.g platform)
+ # [russell.sim@gmail.com]
+ if content == 'UNKNOWN':
+ post_data[headers["name"]] = [None]
+ else:
+ post_data[headers["name"]] = [content]
+
+ return MultiValueDict(post_data), MultiValueDict(files)
+
+def login_basic_auth(request):
+ authentication = request.META.get("HTTP_AUTHORIZATION")
+ if not authentication:
+ return
+ (authmeth, auth) = authentication.split(' ', 1)
+ if authmeth.lower() != "basic":
+ return
+ auth = auth.strip().decode("base64")
+ username, password = auth.split(":", 1)
+ return authenticate(username=username, password=password)
View
195 djangopypi/views/__init__.py
@@ -1,170 +1,15 @@
-import cgi
-import os
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-from django.conf import settings
-from django.http import Http404, HttpResponse, HttpResponseBadRequest
-from django.http import QueryDict, HttpResponseForbidden
+from django.http import Http404
from django.shortcuts import render_to_response
from django.template import RequestContext
-from django.utils.datastructures import MultiValueDict
-from django.utils.translation import ugettext_lazy as _
-from django.core.files.uploadedfile import SimpleUploadedFile
-from django.contrib.auth import authenticate, login
-from django.db.models import Q
-
-from registration.backends import get_backend
-from registration.forms import RegistrationForm
-from djangopypi.models import Project, Classifier, Release, UPLOAD_TO
-from djangopypi.forms import ProjectForm, ReleaseForm
-from djangopypi.http import HttpResponseUnauthorized
+from djangopypi.models import Project, Release
from djangopypi.http import HttpResponseNotImplemented
-from djangopypi.utils import decode_fs
+from djangopypi.http import parse_distutils_request
+from djangopypi.views.dists import register_or_upload
+from djangopypi.views.users import create_user
from djangopypi.views.search import search
-ALREADY_EXISTS_FMT = _("""A file named "%s" already exists for %s. To fix """
- + "problems with that you should create a new release.")
-
-
-def parse_distutils_request(request):
- raw_post_data = request.raw_post_data
- sep = raw_post_data.splitlines()[1]
- items = raw_post_data.split(sep)
- post_data = {}
- files = {}
- for part in filter(lambda e: not e.isspace(), items):
- item = part.splitlines()
- if len(item) < 2:
- continue
- header = item[1].replace("Content-Disposition: form-data; ", "")
- kvpairs = header.split(";")
- headers = {}
- for kvpair in kvpairs:
- if not kvpair:
- continue
- key, value = kvpair.split("=")
- headers[key] = value.strip('"')
- if "name" not in headers:
- continue
- content = part[len("\n".join(item[0:2]))+2:len(part)-1]
- if "filename" in headers:
- file = SimpleUploadedFile(headers["filename"], content,
- content_type="application/gzip")
- files["distribution"] = [file]
- elif headers["name"] in post_data:
- post_data[headers["name"]].append(content)
- else:
- # Distutils sends UNKNOWN for empty fields (e.g platform)
- # [russell.sim@gmail.com]
- if content == 'UNKNOWN':
- post_data[headers["name"]] = [None]
- else:
- post_data[headers["name"]] = [content]
-
- return MultiValueDict(post_data), MultiValueDict(files)
-
-
-
-def login_basic_auth(request):
- authentication = request.META.get("HTTP_AUTHORIZATION")
- if not authentication:
- return
- (authmeth, auth) = authentication.split(' ', 1)
- if authmeth.lower() != "basic":
- return
- auth = auth.strip().decode("base64")
- username, password = auth.split(":", 1)
- return authenticate(username=username, password=password)
-
-
-def submit_project_or_release(user, post_data, files):
- """Registers/updates a project or release"""
- try:
- project = Project.objects.get(name=post_data['name'])
- if project.owner != user:
- return HttpResponseForbidden(
- "That project is owned by someone else!")
- except Project.DoesNotExist:
- project = None
-
- project_form = ProjectForm(post_data, instance=project)
- if project_form.is_valid():
- project = project_form.save(commit=False)
- project.owner = user
- project.save()
- for c in post_data.getlist('classifiers'):
- classifier, created = Classifier.objects.get_or_create(name=c)
- project.classifiers.add(classifier)
- if files:
- allow_overwrite = getattr(settings,
- "DJANGOPYPI_ALLOW_VERSION_OVERWRITE", False)
- try:
- release = Release.objects.get(version=post_data['version'],
- project=project,
- distribution=UPLOAD_TO + '/' +
- files['distribution']._name)
- if not allow_overwrite:
- return HttpResponseForbidden(ALREADY_EXISTS_FMT % (
- release.filename, release))
- except Release.DoesNotExist:
- release = None
-
- # If the old file already exists, django will append a _ after the
- # filename, however with .tar.gz files django does the "wrong"
- # thing and saves it as project-0.1.2.tar_.gz. So remove it before
- # django sees anything.
- release_form = ReleaseForm(post_data, files, instance=release)
- if release_form.is_valid():
- if release and os.path.exists(release.distribution.path):
- os.remove(release.distribution.path)
- release = release_form.save(commit=False)
- release.project = project
- release.save()
- else:
- return HttpResponseBadRequest(
- "ERRORS: %s" % release_form.errors)
- else:
- return HttpResponseBadRequest("ERRORS: %s" % project_form.errors)
-
- return HttpResponse()
-
-
-def register_or_upload(request, post_data, files):
- user = login_basic_auth(request)
- if not user:
- return HttpResponseUnauthorized('pypi')
-
- login(request, user)
- if not request.user.is_authenticated():
- return HttpResponseForbidden(
- "Not logged in, or invalid username/password.")
-
- return submit_project_or_release(user, post_data, files)
-
-def create_user(request, post_data, files):
- """Create new user from a distutil client request"""
- form = RegistrationForm({"username": post_data["name"],
- "email": post_data["email"],
- "password1": post_data["password"],
- "password2": post_data["password"]})
- if not form.is_valid():
- # Dist Utils requires error msg in HTTP status: "HTTP/1.1 400 msg"
- # Which is HTTP/WSGI incompatible, so we're just returning a empty 400.
- return HttpResponseBadRequest()
-
- backend = get_backend("registration.backends.default.DefaultBackend")
- if not backend.registration_allowed(request):
- return HttpResponseBadRequest()
- new_user = backend.register(request, **form.cleaned_data)
- return HttpResponse("OK\n", status=200, mimetype='text/plain')
-
-
ACTIONS = {
# file_upload is the action used with distutils ``sdist`` command.
"file_upload": register_or_upload,
@@ -216,8 +61,8 @@ def show_links(request, dist_name,
def show_version(request, dist_name, version,
template_name="djangopypi/show_version.html"):
try:
- release = Project.objects.get(name=dist_name).releases \
- .get(version=version)
+ project = Project.objects.get(name=dist_name)
+ release = project.releases.get(version=version)
except (Project.DoesNotExist, Release.DoesNotExist):
raise Http404()
@@ -229,29 +74,3 @@ def show_version(request, dist_name, version,
})
return render_to_response(template_name, context_instance=context)
-
-def search(request):
- search_term = ''
- if request.method == 'POST':
- search_term = request.POST.get('search_term')
- if search_term != '':
- dists = Project.objects.filter(Q(name__contains=search_term) | Q(summary__contains=search_term))
- return render_to_response(
- 'djangopypi/search_results.html',
- {'dists':dists,'search_term':search_term},
- context_instance = RequestContext(request)
- )
- else:
- dists = Project.objects.all()
- return render_to_response(
- 'djangopypi/search_results.html',
- {'search_term':search_term},
- context_instance = RequestContext(request)
- )
- else:
- dists = Project.objects.all()
- return render_to_response(
- 'djangopypi/search_results.html',
- {'search_term':search_term},
- context_instance = RequestContext(request)
- )
View
79 djangopypi/views/dists.py
@@ -0,0 +1,79 @@
+import os
+
+from django.conf import settings
+from django.http import (HttpResponse, HttpResponseForbidden,
+ HttpResponseBadRequest)
+from django.utils.translation import ugettext_lazy as _
+from django.contrib.auth import login
+
+from djangopypi.http import login_basic_auth, HttpResponseUnauthorized
+from djangopypi.forms import ProjectForm, ReleaseForm
+from djangopypi.models import Project, Release, Classifier, UPLOAD_TO
+
+ALREADY_EXISTS_FMT = _(
+ "A file named '%s' already exists for %s. Please create a new release.")
+
+
+def submit_project_or_release(user, post_data, files):
+ """Registers/updates a project or release"""
+ try:
+ project = Project.objects.get(name=post_data['name'])
+ if project.owner != user:
+ return HttpResponseForbidden(
+ "That project is owned by someone else!")
+ except Project.DoesNotExist:
+ project = None
+
+ project_form = ProjectForm(post_data, instance=project)
+ if project_form.is_valid():
+ project = project_form.save(commit=False)
+ project.owner = user
+ project.save()
+ for c in post_data.getlist('classifiers'):
+ classifier, created = Classifier.objects.get_or_create(name=c)
+ project.classifiers.add(classifier)
+ if files:
+ allow_overwrite = getattr(settings,
+ "DJANGOPYPI_ALLOW_VERSION_OVERWRITE", False)
+ try:
+ release = Release.objects.get(version=post_data['version'],
+ project=project,
+ distribution=UPLOAD_TO + '/' +
+ files['distribution']._name)
+ if not allow_overwrite:
+ return HttpResponseForbidden(ALREADY_EXISTS_FMT % (
+ release.filename, release))
+ except Release.DoesNotExist:
+ release = None
+
+ # If the old file already exists, django will append a _ after the
+ # filename, however with .tar.gz files django does the "wrong"
+ # thing and saves it as project-0.1.2.tar_.gz. So remove it before
+ # django sees anything.
+ release_form = ReleaseForm(post_data, files, instance=release)
+ if release_form.is_valid():
+ if release and os.path.exists(release.distribution.path):
+ os.remove(release.distribution.path)
+ release = release_form.save(commit=False)
+ release.project = project
+ release.save()
+ else:
+ return HttpResponseBadRequest(
+ "ERRORS: %s" % release_form.errors)
+ else:
+ return HttpResponseBadRequest("ERRORS: %s" % project_form.errors)
+
+ return HttpResponse()
+
+
+def register_or_upload(request, post_data, files):
+ user = login_basic_auth(request)
+ if not user:
+ return HttpResponseUnauthorized('pypi')
+
+ login(request, user)
+ if not request.user.is_authenticated():
+ return HttpResponseForbidden(
+ "Not logged in, or invalid username/password.")
+
+ return submit_project_or_release(user, post_data, files)
View
24 djangopypi/views/search.py
@@ -0,0 +1,24 @@
+from django.template import RequestContext
+from django.shortcuts import render_to_response
+from django.db.models.query import Q
+
+from djangopypi.models import Project
+
+
+def _search_query(q):
+ return Q(name__contains=q) | Q(summary__contains=q)
+
+
+def search(request, template="djangopypi/search_results.html"):
+ context = RequestContext(request, {"dists": None, "search_term": ""})
+
+ if request.method == "POST":
+ search_term = context["search_term"] = request.POST.get("search_term")
+ if search_term:
+ query = _search_query(search_term)
+ context["dists"] = Project.objects.filter(query)
+
+ if context["dists"] is None:
+ context["dists"] = Project.objects.all()
+
+ return render_to_response(template, context_instance=context)
View
24 djangopypi/views/users.py
@@ -0,0 +1,24 @@
+from django.http import HttpResponse, HttpResponseBadRequest
+
+from registration.forms import RegistrationForm
+from registration.backends import get_backend
+
+DEFAULT_BACKEND = "registration.backends.default.DefaultBackend"
+
+
+def create_user(request, post_data, files, backend_name=DEFAULT_BACKEND):
+ """Create new user from a distutil client request"""
+ form = RegistrationForm({"username": post_data["name"],
+ "email": post_data["email"],
+ "password1": post_data["password"],
+ "password2": post_data["password"]})
+ if not form.is_valid():
+ # Dist Utils requires error msg in HTTP status: "HTTP/1.1 400 msg"
+ # Which is HTTP/WSGI incompatible, so we're just returning a empty 400.
+ return HttpResponseBadRequest()
+
+ backend = get_backend(backend_name)
+ if not backend.registration_allowed(request):
+ return HttpResponseBadRequest()
+ new_user = backend.register(request, **form.cleaned_data)
+ return HttpResponse("OK\n", status=200, mimetype='text/plain')
Please sign in to comment.
Something went wrong with that request. Please try again.