Merge pull request #843 from rtfd/merge-1.6

1.6 Compat
refactor-builder
Eric Holscher 2014-07-31 14:35:37 -07:00
commit c9602934fc
78 changed files with 812 additions and 699 deletions

View File

@ -7,20 +7,33 @@
--allow-external lazr.authentication
--allow-unverified lazr.authentication
# Basic tools
virtualenv==1.11.1
## Upgraded packages
pip==1.5.6
virtualenv==1.11.6
docutils==0.11
pip==1.5.1
Sphinx==1.2.2
django==1.4.13
south==0.7.6
django>=1.6
django-tastypie==0.11.1
django-haystack==2.1.0
celery-haystack==0.7.2
django-guardian==1.2.0
django-extensions==1.3.8
South==0.8.4
djangorestframework==2.3.14
django-nose==1.2
requests==2.3.0
slumber==0.6.0
lxml==3.3.5
# Basic tools
redis==2.7.1
hiredis==0.1.2
requests==2.0
slumber==0.6
celery==3.0.24
django-celery==3.0.23
mkdocs==0.4
django-allauth==0.16.1
# VCS
bzr==2.5b4
@ -30,22 +43,16 @@ httplib2==0.7.7
# Search
elasticsearch==0.4.3
celery-haystack==0.6.2
pyquery==1.2.2
# Utils
django-gravatar2==1.0.6
doc2dash==1.1.0
lxml==3.0.2
pytz==2013b
beautifulsoup4==4.1.3
Unipath==0.2.1
django-extensions==0.7.1
django-guardian==1.0.4
django-kombu==0.9.4
django-nose==1.1
django-profiles==0.2
django-secure==0.1.2
mimeparse==0.1.3
mock==1.0.1
@ -59,18 +66,12 @@ Distutils2==1.0a3
distlib==0.1.2
# Commenting stuff
djangorestframework==2.3.6
django-cors-headers==0.11
# Pegged git requirements
git+https://github.com/toastdriven/django-haystack@259274e4127f723d76b893c87a82777f9490b960#egg=django_haystack
git+https://github.com/alex/django-filter.git#egg=django-filter
git+https://github.com/alex/django-taggit.git@36f6dabcf10e27c7d9442a94243d4189f2a4f121#egg=django_taggit-dev
git+https://github.com/ericflo/django-pagination.git@e5f669036c#egg=django_pagination-dev
git+https://github.com/nathanborror/django-basic-apps.git@171fdbe21a0dbbb38919a383cc265cb3cbc73771#egg=django_basic_apps-dev
git+https://github.com/nathanborror/django-registration.git@dc0b564b7bfb79f58592fe8ad836729a85ec17ae#egg=django_registration-dev
git+https://github.com/toastdriven/django-tastypie.git@c5451b90b18b0cb64841b2276d543230d5f58231#egg=django_tastypie-dev
git+https://github.com/ericholscher/readthedocs-sphinx-ext#egg=readthedocs_ext
# Websupport
git+https://github.com/ericholscher/django-sphinx-websupport#egg=websupport
git+https://github.com/alex/django-taggit.git#egg=django_taggit-dev

View File

@ -2,7 +2,7 @@ import logging
import json
from django.contrib.auth.models import User
from django.conf.urls.defaults import url
from django.conf.urls import url
from django.shortcuts import get_object_or_404
from tastypie import fields
@ -18,7 +18,7 @@ from projects.utils import highest_version, mkversion, slugify_uniquely
from projects import tasks
from djangome import views as djangome
from .utils import SearchMixin, PostAuthentication, EnhancedModelResource
from .utils import SearchMixin, PostAuthentication
log = logging.getLogger(__name__)
@ -57,14 +57,14 @@ class ProjectResource(ModelResource, SearchMixin):
If a new resource is created, return ``HttpCreated`` (201 Created).
"""
deserialized = self.deserialize(
request, request.raw_post_data,
request, request.body,
format=request.META.get('CONTENT_TYPE', 'application/json')
)
# Force this in an ugly way, at least should do "reverse"
deserialized["users"] = ["/api/v1/user/%s/" % request.user.id]
bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized))
self.is_valid(bundle, request)
bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized), request=request)
self.is_valid(bundle)
updated_bundle = self.obj_create(bundle, request=request)
return HttpCreated(location=self.get_resource_uri(updated_bundle))
@ -79,7 +79,7 @@ class ProjectResource(ModelResource, SearchMixin):
project = get_object_or_404(Project, pk=kwargs['pk'])
try:
post_data = self.deserialize(
request, request.raw_post_data,
request, request.body,
format=request.META.get('CONTENT_TYPE', 'application/json')
)
data = json.loads(post_data)
@ -115,11 +115,10 @@ class ProjectResource(ModelResource, SearchMixin):
]
class VersionResource(EnhancedModelResource):
class VersionResource(ModelResource):
project = fields.ForeignKey(ProjectResource, 'project', full=True)
class Meta:
queryset = Version.objects.all()
allowed_methods = ['get', 'put', 'post']
always_return_data = True
queryset = Version.objects.public()
@ -204,7 +203,7 @@ class VersionResource(EnhancedModelResource):
]
class BuildResource(EnhancedModelResource):
class BuildResource(ModelResource):
project = fields.ForeignKey('api.base.ProjectResource', 'project')
version = fields.ForeignKey('api.base.VersionResource', 'version')
@ -235,7 +234,7 @@ class BuildResource(EnhancedModelResource):
]
class FileResource(EnhancedModelResource, SearchMixin):
class FileResource(ModelResource, SearchMixin):
project = fields.ForeignKey(ProjectResource, 'project', full=True)
class Meta:

View File

@ -148,7 +148,7 @@ class PostAuthentication(BasicAuthentication):
class EnhancedModelResource(ModelResource):
def obj_get_list(self, request=None, **kwargs):
def obj_get_list(self, request=None, *args, **kwargs):
"""
A ORM-specific implementation of ``obj_get_list``.

View File

@ -1,4 +1,4 @@
from django.conf.urls.defaults import patterns, url
from django.conf.urls import patterns, url
urlpatterns = patterns(

View File

@ -2,7 +2,7 @@ import simplejson
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.views.generic.list_detail import object_list
from core.generic.list_detail import object_list
from bookmarks.models import Bookmark

View File

@ -1,22 +1,16 @@
from django.conf.urls.defaults import patterns, url
from django.conf.urls import patterns, url
from .views import BuildList, BuildDetail
urlpatterns = patterns(
# base view, flake8 complains if it is on the previous line.
'builds.views',
url(r'^$',
'build_list',
name='builds_list'),
url(r'^(?P<project_slug>[-\w]+)/(?P<pk>\d+)/$',
'build_detail',
BuildDetail.as_view(),
name='builds_detail'),
url(r'^(?P<project_slug>[-\w]+)/$',
'build_list',
BuildList.as_view(),
name='builds_project_list'),
url(r'^tag/(?P<tag>\w+)/$',
'build_list',
name='builds_tag_list'),
)

View File

@ -1,53 +1,50 @@
from django.shortcuts import get_object_or_404
from django.views.generic.list_detail import object_list, object_detail
from taggit.models import Tag
from django.views.generic import ListView, DetailView
from builds.models import Build
from builds.filters import BuildFilter
from projects.models import Project
class BuildList(ListView):
model = Build
def build_list(request, project_slug=None, tag=None):
"""Show a list of builds.
"""
project = get_object_or_404(Project.objects.protected(request.user),
slug=project_slug)
queryset = Build.objects.filter(project=project)
def get_queryset(self):
self.project_slug = self.kwargs.get('project_slug', None)
if tag:
tag = get_object_or_404(Tag, slug=tag)
queryset = queryset.filter(project__tags__in=[tag.slug])
else:
tag = None
self.project = get_object_or_404(
Project.objects.protected(self.request.user),
slug=self.project_slug
)
queryset = Build.objects.filter(project=self.project)
filter = BuildFilter(request.GET, queryset=queryset)
active_builds = queryset.exclude(state="finished").values('id')
return queryset
return object_list(
request,
queryset=queryset,
extra_context={
'project': project,
'filter': filter,
'tag': tag,
'active_builds': active_builds
},
template_object_name='build',
)
def get_context_data(self, **kwargs):
context = super(BuildList, self).get_context_data(**kwargs)
filter = BuildFilter(self.request.GET, queryset=self.queryset)
active_builds = self.get_queryset().exclude(state="finished").values('id')
def build_detail(request, project_slug, pk):
"""Show the details of a particular build.
"""
project = get_object_or_404(Project.objects.protected(request.user),
slug=project_slug)
queryset = Build.objects.filter(project=project)
context['project'] = self.project
context['filter'] = filter
context['active_builds'] = active_builds
return context
return object_detail(
request,
queryset=queryset,
object_id=pk,
extra_context={'project': project},
template_object_name='build',
)
class BuildDetail(DetailView):
model = Build
def get_queryset(self):
self.project_slug = self.kwargs.get('project_slug', None)
self.project = get_object_or_404(
Project.objects.protected(self.request.user),
slug=self.project_slug
)
queryset = Build.objects.filter(project=self.project)
return queryset
def get_context_data(self, **kwargs):
context = super(BuildDetail, self).get_context_data(**kwargs)
context['project'] = self.project
return context

View File

@ -1,4 +1,4 @@
from django.conf.urls.defaults import patterns, url
from django.conf.urls import patterns, url
urlpatterns = patterns(
'', # base view, flake8 complains if it is on the previous line.

View File

@ -13,7 +13,7 @@ class UserProfile (models.Model):
"""
user = models.ForeignKey(User, verbose_name=_('User'), unique=True,
related_name='profile')
whitelisted = models.BooleanField(_('Whitelisted'))
whitelisted = models.BooleanField(_('Whitelisted'), default=False)
homepage = models.CharField(_('Homepage'), max_length=100, blank=True)
allow_email = models.BooleanField(_('Allow email'),
help_text=_('Show your email on VCS '
@ -55,6 +55,6 @@ class UserProfile (models.Model):
def create_profile(sender, **kwargs):
if kwargs['created'] is True:
try:
UserProfile.objects.create(user_id=kwargs['instance'].id)
UserProfile.objects.create(user_id=kwargs['instance'].id, whitelisted=False)
except DatabaseError:
pass

View File

@ -1,4 +1,4 @@
from django.conf.urls.defaults import patterns, url
from django.conf.urls import patterns, url
urlpatterns = patterns(
'', # base view, flake8 complains if it is on the previous line.

View File

@ -1,4 +1,4 @@
from django.conf.urls.defaults import url, patterns
from django.conf.urls import url, patterns
from projects.constants import LANGUAGES_REGEX
from urls import urlpatterns as main_patterns

View File

@ -0,0 +1,45 @@
{% extends "account/base.html" %}
{% load i18n %}
{% load account %}
{% load url from future %}
{% block head_title %}{% trans "Sign In" %}{% endblock %}
{% block content %}
<h1>{% trans "Sign In" %}</h1>
{% if socialaccount.providers %}
<p>{% blocktrans with site.name as site_name %}Please sign in with one
of your existing third party accounts. Or, <a href="{{ signup_url }}">sign up</a>
for a {{site_name}} account and sign in below:{% endblocktrans %}</p>
<div class="socialaccount_ballot">
<ul class="socialaccount_providers">
{% include "socialaccount/snippets/provider_list.html" with process="login" %}
</ul>
<div class="login-or">{% trans 'or' %}</div>
</div>
{% include "socialaccount/snippets/login_extra.html" %}
{% else %}
<p>{% blocktrans %}If you have not created an account yet, then please
<a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}</p>
{% endif %}
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
{% blocktrans %}If you forgot your password, <a href="/accounts/password/reset/">reset it.</a>{% endblocktrans %}
</form>
{% endblock %}

View File

@ -1,7 +1,10 @@
import urllib
import hashlib
from django import template
from django.utils.hashcompat import hashlib
from django.conf import settings
from django.utils.safestring import mark_safe
from django.utils.encoding import force_bytes, force_text
register = template.Library()
@ -36,3 +39,16 @@ def make_document_url(project, version=None, page=None):
else:
path = ""
return base_url + path
@register.filter(is_safe=True)
def restructuredtext(value):
try:
from docutils.core import publish_parts
except ImportError:
if settings.DEBUG:
raise template.TemplateSyntaxError("Error in 'restructuredtext' filter: The Python docutils library isn't installed.")
return force_text(value)
else:
docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
parts = publish_parts(source=force_bytes(value), writer_name="html4css1", settings_overrides=docutils_settings)
return mark_safe(force_text(parts["fragment"]))

View File

@ -9,7 +9,7 @@ from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponseNotFound
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from django.views.decorators.csrf import csrf_view_exempt
from django.views.decorators.csrf import csrf_exempt
from django.views.static import serve
from django.views.generic import TemplateView
@ -107,7 +107,7 @@ def live_builds(request):
context_instance=RequestContext(request))
@csrf_view_exempt
@csrf_exempt
def wipe_version(request, project_slug, version_slug):
version = get_object_or_404(Version, project__slug=project_slug,
slug=version_slug)
@ -191,7 +191,7 @@ def _build_url(url, branches):
return HttpResponse(msg)
@csrf_view_exempt
@csrf_exempt
def github_build(request):
"""
A post-commit hook for github.
@ -231,7 +231,7 @@ def github_build(request):
return HttpResponse("You must POST to this resource.")
@csrf_view_exempt
@csrf_exempt
def bitbucket_build(request):
if request.method == 'POST':
payload = request.POST.get('payload')
@ -253,7 +253,7 @@ def bitbucket_build(request):
return HttpResponse("You must POST to this resource.")
@csrf_view_exempt
@csrf_exempt
def generic_build(request, pk=None):
try:
project = Project.objects.get(pk=pk)

View File

@ -1,5 +1,11 @@
#!/usr/bin/env python
import os
import sys
import settings.sqlite
from django.core.management import execute_manager
execute_manager(settings.sqlite)
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.sqlite")
sys.path.append('readthedocs')
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

View File

View File

@ -0,0 +1,43 @@
"""
URLConf for Django user profile management.
Recommended usage is to use a call to ``include()`` in your project's
root URLConf to include this URLConf for any URL beginning with
'/profiles/'.
If the default behavior of the profile views is acceptable to you,
simply use a line like this in your root URLConf to set up the default
URLs for profiles::
(r'^profiles/', include('profiles.urls')),
But if you'd like to customize the behavior (e.g., by passing extra
arguments to the various views) or split up the URLs, feel free to set
up your own URL patterns for these views instead. If you do, it's a
good idea to keep the name ``profiles_profile_detail`` for the pattern
which points to the ``profile_detail`` view, since several views use
``reverse()`` with that name to generate a default post-submission
redirect. If you don't use that name, remember to explicitly pass
``success_url`` to those views.
"""
from django.conf.urls import *
from profiles import views
urlpatterns = patterns('',
url(r'^create/$',
views.create_profile,
name='profiles_create_profile'),
url(r'^edit/$',
views.edit_profile,
name='profiles_edit_profile'),
url(r'^(?P<username>\w+)/$',
views.profile_detail,
name='profiles_profile_detail'),
url(r'^$',
views.ProfileListView.as_view(),
name='profiles_profile_list'),
)

View File

@ -0,0 +1,46 @@
"""
Utility functions for retrieving and generating forms for the
site-specific user profile model specified in the
``AUTH_PROFILE_MODULE`` setting.
"""
from django import forms
from django.conf import settings
from django.db.models import get_model
from django.contrib.auth.models import SiteProfileNotAvailable
def get_profile_model():
"""
Return the model class for the currently-active user profile
model, as defined by the ``AUTH_PROFILE_MODULE`` setting. If that
setting is missing, raise
``django.contrib.auth.models.SiteProfileNotAvailable``.
"""
if (not hasattr(settings, 'AUTH_PROFILE_MODULE')) or \
(not settings.AUTH_PROFILE_MODULE):
raise SiteProfileNotAvailable
profile_mod = get_model(*settings.AUTH_PROFILE_MODULE.split('.'))
if profile_mod is None:
raise SiteProfileNotAvailable
return profile_mod
def get_profile_form():
"""
Return a form class (a subclass of the default ``ModelForm``)
suitable for creating/editing instances of the site-specific user
profile model, as defined by the ``AUTH_PROFILE_MODULE``
setting. If that setting is missing, raise
``django.contrib.auth.models.SiteProfileNotAvailable``.
"""
profile_mod = get_profile_model()
class _ProfileForm(forms.ModelForm):
class Meta:
model = profile_mod
exclude = ('user',) # User will be filled in by the view.
return _ProfileForm

View File

@ -0,0 +1,343 @@
"""
Views for creating, editing and viewing site-specific user profiles.
"""
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.http import Http404
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.generic.list import ListView
from profiles import utils
def create_profile(request, form_class=None, success_url=None,
template_name='profiles/create_profile.html',
extra_context=None):
"""
Create a profile for the current user, if one doesn't already
exist.
If the user already has a profile, as determined by
``request.user.get_profile()``, a redirect will be issued to the
:view:`profiles.views.edit_profile` view. If no profile model has
been specified in the ``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
**Optional arguments:**
``extra_context``
A dictionary of variables to add to the template context. Any
callable object in this dictionary will be called to produce
the end result which appears in the context.
``form_class``
The form class to use for validating and creating the user
profile. This form class must define a method named
``save()``, implementing the same argument signature as the
``save()`` method of a standard Django ``ModelForm`` (this
view will call ``save(commit=False)`` to obtain the profile
object, and fill in the user before the final save). If the
profile object includes many-to-many relations, the convention
established by ``ModelForm`` of using a method named
``save_m2m()`` will be used, and so your form class should
also define this method.
If this argument is not supplied, this view will use a
``ModelForm`` automatically generated from the model specified
by ``AUTH_PROFILE_MODULE``.
``success_url``
The URL to redirect to after successful profile creation. If
this argument is not supplied, this will default to the URL of
:view:`profiles.views.profile_detail` for the newly-created
profile object.
``template_name``
The template to use when displaying the profile-creation
form. If not supplied, this will default to
:template:`profiles/create_profile.html`.
**Context:**
``form``
The profile-creation form.
**Template:**
``template_name`` keyword argument, or
:template:`profiles/create_profile.html`.
"""
try:
profile_obj = request.user.get_profile()
return HttpResponseRedirect(reverse('profiles_edit_profile'))
except ObjectDoesNotExist:
pass
#
# We set up success_url here, rather than as the default value for
# the argument. Trying to do it as the argument's default would
# mean evaluating the call to reverse() at the time this module is
# first imported, which introduces a circular dependency: to
# perform the reverse lookup we need access to profiles/urls.py,
# but profiles/urls.py in turn imports this module.
#
if success_url is None:
success_url = reverse('profiles_profile_detail',
kwargs={ 'username': request.user.username })
if form_class is None:
form_class = utils.get_profile_form()
if request.method == 'POST':
form = form_class(data=request.POST, files=request.FILES)
if form.is_valid():
profile_obj = form.save(commit=False)
profile_obj.user = request.user
profile_obj.save()
if hasattr(form, 'save_m2m'):
form.save_m2m()
return HttpResponseRedirect(success_url)
else:
form = form_class()
if extra_context is None:
extra_context = {}
context = RequestContext(request)
for key, value in extra_context.items():
context[key] = callable(value) and value() or value
return render_to_response(template_name,
{ 'form': form },
context_instance=context)
create_profile = login_required(create_profile)
def edit_profile(request, form_class=None, success_url=None,
template_name='profiles/edit_profile.html',
extra_context=None):
"""
Edit the current user's profile.
If the user does not already have a profile (as determined by
``User.get_profile()``), a redirect will be issued to the
:view:`profiles.views.create_profile` view; if no profile model
has been specified in the ``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
**Optional arguments:**
``extra_context``
A dictionary of variables to add to the template context. Any
callable object in this dictionary will be called to produce
the end result which appears in the context.
``form_class``
The form class to use for validating and editing the user
profile. This form class must operate similarly to a standard
Django ``ModelForm`` in that it must accept an instance of the
object to be edited as the keyword argument ``instance`` to
its constructor, and it must implement a method named
``save()`` which will save the updates to the object. If this
argument is not specified, this view will use a ``ModelForm``
generated from the model specified in the
``AUTH_PROFILE_MODULE`` setting.
``success_url``
The URL to redirect to following a successful edit. If not
specified, this will default to the URL of
:view:`profiles.views.profile_detail` for the profile object
being edited.
``template_name``
The template to use when displaying the profile-editing
form. If not specified, this will default to
:template:`profiles/edit_profile.html`.
**Context:**
``form``
The form for editing the profile.
``profile``
The user's current profile.
**Template:**
``template_name`` keyword argument or
:template:`profiles/edit_profile.html`.
"""
try:
profile_obj = request.user.get_profile()
except ObjectDoesNotExist:
return HttpResponseRedirect(reverse('profiles_create_profile'))
#
# See the comment in create_profile() for discussion of why
# success_url is set up here, rather than as a default value for
# the argument.
#
if success_url is None:
success_url = reverse('profiles_profile_detail',
kwargs={ 'username': request.user.username })
if form_class is None:
form_class = utils.get_profile_form()
if request.method == 'POST':
form = form_class(data=request.POST, files=request.FILES, instance=profile_obj)
if form.is_valid():
form.save()
return HttpResponseRedirect(success_url)
else:
form = form_class(instance=profile_obj)
if extra_context is None:
extra_context = {}
context = RequestContext(request)
for key, value in extra_context.items():
context[key] = callable(value) and value() or value
return render_to_response(template_name,
{ 'form': form,
'profile': profile_obj, },
context_instance=context)
edit_profile = login_required(edit_profile)
def profile_detail(request, username, public_profile_field=None,
template_name='profiles/profile_detail.html',
extra_context=None):
"""
Detail view of a user's profile.
If no profile model has been specified in the
``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
If the user has not yet created a profile, ``Http404`` will be
raised.
**Required arguments:**
``username``
The username of the user whose profile is being displayed.
**Optional arguments:**
``extra_context``
A dictionary of variables to add to the template context. Any
callable object in this dictionary will be called to produce
the end result which appears in the context.
``public_profile_field``
The name of a ``BooleanField`` on the profile model; if the
value of that field on the user's profile is ``False``, the
``profile`` variable in the template will be ``None``. Use
this feature to allow users to mark their profiles as not
being publicly viewable.
If this argument is not specified, it will be assumed that all
users' profiles are publicly viewable.
``template_name``
The name of the template to use for displaying the profile. If
not specified, this will default to
:template:`profiles/profile_detail.html`.
**Context:**
``profile``
The user's profile, or ``None`` if the user's profile is not
publicly viewable (see the description of
``public_profile_field`` above).
**Template:**
``template_name`` keyword argument or
:template:`profiles/profile_detail.html`.
"""
user = get_object_or_404(User, username=username)
try:
profile_obj = user.get_profile()
except ObjectDoesNotExist:
raise Http404
if public_profile_field is not None and \
not getattr(profile_obj, public_profile_field):
profile_obj = None
if extra_context is None:
extra_context = {}
context = RequestContext(request)
for key, value in extra_context.items():
context[key] = callable(value) and value() or value
return render_to_response(template_name,
{ 'profile': profile_obj },
context_instance=context)
class ProfileListView(ListView):
"""
A list of user profiles.
If no profile model has been specified in the
``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
**Optional arguments:**
``public_profile_field``
The name of a ``BooleanField`` on the profile model; if the
value of that field on a user's profile is ``False``, that
profile will be excluded from the list. Use this feature to
allow users to mark their profiles as not being publicly
viewable.
If this argument is not specified, it will be assumed that all
users' profiles are publicly viewable.
``template_name``
The name of the template to use for displaying the profiles. If
not specified, this will default to
:template:`profiles/profile_list.html`.
Additionally, all arguments accepted by the
:view:`django.views.generic.list_detail.object_list` generic view
will be accepted here, and applied in the same fashion, with one
exception: ``queryset`` will always be the ``QuerySet`` of the
model specified by the ``AUTH_PROFILE_MODULE`` setting, optionally
filtered to remove non-publicly-viewable proiles.
**Context:**
Same as the :view:`django.views.generic.list_detail.object_list`
generic view.
**Template:**
``template_name`` keyword argument or
:template:`profiles/profile_list.html`.
"""
public_profile_field = None
template_name = 'profiles/profile_list.html'
def get_model(self):
return utils.get_profile_model()
def get_queryset(self):
queryset = self.get_model()._default_manager.all()
if self.public_profile_field is not None:
queryset = queryset.filter(**{self.public_profile_field: True})
return queryset

View File

@ -111,11 +111,9 @@ class Project(models.Model):
repo_type = models.CharField(_('Repository type'), max_length=10,
choices=constants.REPO_CHOICES, default='git')
project_url = models.URLField(_('Project URL'), blank=True,
help_text=_('The project\'s homepage'),
verify_exists=False)
help_text=_('The project\'s homepage'))
canonical_url = models.URLField(_('Canonical URL'), blank=True,
help_text=_('The official URL that the docs live at. This can be at readthedocs.org, or somewhere else. Ex. http://docs.fabfile.org'),
verify_exists=False)
help_text=_('The official URL that the docs live at. This can be at readthedocs.org, or somewhere else. Ex. http://docs.fabfile.org'))
version = models.CharField(_('Version'), max_length=100, blank=True,
help_text=_('Project version these docs apply '
'to, i.e. 1.0a'))
@ -167,13 +165,15 @@ class Project(models.Model):
help_text=_('Path from project root to conf.py file (ex. docs/conf.py)'
'. Leave blank if you want us to find it for you.'))
featured = models.BooleanField(_('Featured'))
skip = models.BooleanField(_('Skip'))
featured = models.BooleanField(_('Featured'), default=False)
skip = models.BooleanField(_('Skip'), default=False)
mirror = models.BooleanField(_('Mirror'), default=False)
use_virtualenv = models.BooleanField(
_('Use virtualenv'),
help_text=_("Install your project inside a virtualenv using setup.py "
"install"))
"install"),
default=False
)
# This model attribute holds the python interpreter used to create the
# virtual environment
@ -188,7 +188,9 @@ class Project(models.Model):
use_system_packages = models.BooleanField(
_('Use system packages'),
help_text=_("Give the virtual environment access to the global "
"site-packages dir."))
"site-packages dir."),
default=False
)
django_packages_url = models.CharField(_('Django Packages URL'),
max_length=255, blank=True)
privacy_level = models.CharField(
@ -218,9 +220,9 @@ class Project(models.Model):
related_name='translations',
blank=True, null=True)
# Version State
# Version State
num_major = models.IntegerField(
_('Number of Major versions'),
_('Number of Major versions'),
max_length=3,
default=2,
null=True,
@ -228,7 +230,7 @@ class Project(models.Model):
help_text=_("2 means supporting 3.X.X and 2.X.X, but not 1.X.X")
)
num_minor = models.IntegerField(
_('Number of Minor versions'),
_('Number of Minor versions'),
max_length=3,
default=2,
null=True,
@ -236,7 +238,7 @@ class Project(models.Model):
help_text=_("2 means supporting 2.2.X and 2.1.X, but not 2.0.X")
)
num_point = models.IntegerField(
_('Number of Point versions'),
_('Number of Point versions'),
max_length=3,
default=2,
null=True,
@ -481,7 +483,7 @@ class Project(models.Model):
#
# Paths for symlinks in project doc_path.
#
#
def cnames_symlink_path(self, domain):
"""
Path in the doc_path that we symlink cnames
@ -587,7 +589,7 @@ class Project(models.Model):
The path to the static metadata JSON settings file
"""
return os.path.join(self.doc_path, 'metadata.json')
def conf_file(self, version='latest'):
if self.conf_py_file:
log.debug('Inserting conf.py file path from model')
@ -840,7 +842,7 @@ class EmailHook(Notification):
class WebHook(Notification):
url = models.URLField(blank=True, verify_exists=False,
url = models.URLField(blank=True,
help_text=_('URL to send the webhook to'))
def __unicode__(self):

View File

@ -130,9 +130,12 @@ def move_files(version, results):
core_utils.copy(from_path, to_path)
# Always move PDF's because the return code lies.
if 'pdf' in results:
from_path = version.project.artifact_path(version=version.slug, type='sphinx_pdf')
to_path = os.path.join(settings.MEDIA_ROOT, 'pdf', version.project.slug, version.slug)
core_utils.copy(from_path, to_path)
try:
from_path = version.project.artifact_path(version=version.slug, type='sphinx_pdf')
to_path = os.path.join(settings.MEDIA_ROOT, 'pdf', version.project.slug, version.slug)
core_utils.copy(from_path, to_path)
except:
pass
if 'epub' in results and results['epub'][0] == 0:
from_path = version.project.artifact_path(version=version.slug, type='sphinx_epub')
to_path = os.path.join(settings.MEDIA_ROOT, 'epub', version.project.slug, version.slug)
@ -549,6 +552,7 @@ def create_build(version, api, record):
version='/api/v1/version/%s/' % version.pk,
type='html',
state='triggered',
success=True,
))
else:
build = {}

View File

@ -1,81 +1,83 @@
from django.conf.urls.defaults import patterns, url
from django.conf.urls import patterns, url
from projects.views.private import AliasList, ProjectDashboard
urlpatterns = patterns(
# base view, flake8 complains if it is on the previous line.
'projects.views.private',
'',
url(r'^$',
'project_dashboard',
ProjectDashboard.as_view(),
name='projects_dashboard'),
url(r'^import/$',
'project_import',
'projects.views.private.project_import',
name='projects_import'),
url(r'^(?P<project_slug>[-\w]+)/$',
'project_manage',
'projects.views.private.project_manage',
name='projects_manage'),
url(r'^(?P<project_slug>[-\w]+)/alias/(?P<id>\d+)/',
'edit_alias',
'projects.views.private.edit_alias',
name='projects_alias_edit'),
url(r'^(?P<project_slug>[-\w]+)/alias/$',
'edit_alias',
'projects.views.private.edit_alias',
name='projects_alias_create'),
url(r'^(?P<project_slug>[-\w]+)/alias/list/$',
'list_alias',
AliasList.as_view(),
name='projects_alias_list'),
url(r'^(?P<project_slug>[-\w]+)/edit/$',
'project_edit',
'projects.views.private.project_edit',
name='projects_edit'),
url(r'^(?P<project_slug>[-\w]+)/advanced/$',
'project_advanced',
'projects.views.private.project_advanced',
name='projects_advanced'),
url(r'^(?P<project_slug>[-\w]+)/version/(?P<version_slug>[-\w.]+)/$',
'project_version_detail',
'projects.views.private.project_version_detail',
name='project_version_detail'),
url(r'^(?P<project_slug>[-\w]+)/versions/$',
'project_versions',
'projects.views.private.project_versions',
name='projects_versions'),
url(r'^(?P<project_slug>[-\w]+)/delete/$',
'project_delete',
'projects.views.private.project_delete',
name='projects_delete'),
url(r'^(?P<project_slug>[-\w]+)/subprojects/delete/(?P<child_slug>[-\w]+)/$', # noqa
'project_subprojects_delete',
'projects.views.private.project_subprojects_delete',
name='projects_subprojects_delete'),
url(r'^(?P<project_slug>[-\w]+)/subprojects/$',
'project_subprojects',
'projects.views.private.project_subprojects',
name='projects_subprojects'),
url(r'^(?P<project_slug>[-\w]+)/users/$',
'project_users',
'projects.views.private.project_users',
name='projects_users'),
url(r'^(?P<project_slug>[-\w]+)/users/delete/$',
'project_users_delete',
'projects.views.private.project_users_delete',
name='projects_users_delete'),
url(r'^(?P<project_slug>[-\w]+)/notifications/$',
'project_notifications',
'projects.views.private.project_notifications',
name='projects_notifications'),
url(r'^(?P<project_slug>[-\w]+)/notifications/delete/$',
'project_notifications_delete',
'projects.views.private.project_notifications_delete',
name='projects_notification_delete'),
url(r'^(?P<project_slug>[-\w]+)/translations/$',
'project_translations',
'projects.views.private.project_translations',
name='projects_translations'),
url(r'^(?P<project_slug>[-\w]+)/translations/delete/(?P<child_slug>[-\w]+)/$', # noqa
'project_translations_delete',
'projects.views.private.project_translations_delete',
name='projects_translations_delete'),
)

View File

@ -1,49 +1,43 @@
from django.conf.urls.defaults import patterns, url
from django.conf.urls import patterns, url
from projects.views.public import ProjectIndex
urlpatterns = patterns(
# base view, flake8 complains if it is on the previous line.
'projects.views.public',
'',
url(r'^$',
'project_index',
ProjectIndex.as_view(),
name='projects_list'),
url(r'^tags/$',
'tag_index',
name='projects_tag_list'),
url(r'^search/$',
'search',
name='project_search'),
url(r'^search/autocomplete/$',
'search_autocomplete',
'projects.views.public.search_autocomplete',
name='search_autocomplete'),
url(r'^autocomplete/version/(?P<project_slug>[-\w]+)/$',
'version_autocomplete',
'projects.views.public.version_autocomplete',
name='version_autocomplete'),
url(r'^autocomplete/filter/version/(?P<project_slug>[-\w]+)/$',
'version_filter_autocomplete',
'projects.views.public.version_filter_autocomplete',
name='version_filter_autocomplete'),
url(r'^tags/(?P<tag>[-\w]+)/$',
'project_index',
ProjectIndex.as_view(),
name='projects_tag_detail'),
url(r'^(?P<project_slug>[-\w]+)/$',
'project_detail',
'projects.views.public.project_detail',
name='projects_detail'),
url(r'^(?P<project_slug>[-\w]+)/downloads/$',
'project_downloads',
'projects.views.public.project_downloads',
name='project_downloads'),
url(r'^(?P<project_slug>[-\w]+)/badge/$',
'project_badge',
'projects.views.public.project_badge',
name='project_badge'),
url(r'^(?P<username>\w+)/$',
'project_index',
'projects.views.public.project_index',
name='projects_user_list'),
)

View File

@ -9,13 +9,14 @@ from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.views.generic.list_detail import object_list
from django.views.generic import ListView
from django.utils.decorators import method_decorator
from guardian.shortcuts import assign
from builds.forms import AliasForm, VersionForm
from builds.filters import VersionFilter
from builds.models import Version
from builds.models import VersionAlias, Version
from projects.forms import (ImportProjectForm, build_versions_form,
build_upload_html_form, SubprojectForm,
UserForm, EmailHookForm, TranslationForm,
@ -24,25 +25,28 @@ from projects.models import Project, EmailHook
from projects import constants
@login_required
def project_dashboard(request):
class ProjectDashboard(ListView):
"""
A dashboard! If you aint know what that means you aint need to.
Essentially we show you an overview of your content.
"""
qs = (Version.objects.active(user=request.user)
.filter(project__users__in=[request.user]))
filter = VersionFilter(constants.IMPORTANT_VERSION_FILTERS, queryset=qs)
return object_list(
request,
queryset=request.user.projects.live(),
page=int(request.GET.get('page', 1)),
template_object_name='project',
template_name='projects/project_dashboard.html',
extra_context={
'filter': filter,
}
)
model = Project
template_name='projects/project_dashboard.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(ProjectDashboard, self).dispatch(*args, **kwargs)
def get_queryset(self):
return self.request.user.projects.live()
def get_context_data(self, **kwargs):
context = super(ProjectDashboard, self).get_context_data(**kwargs)
qs = (Version.objects.active(user=self.request.user)
.filter(project__users__in=[self.request.user]))
filter = VersionFilter(constants.IMPORTANT_VERSION_FILTERS, queryset=self.get_queryset())
context['filter'] = filter
return context
@login_required
@ -216,15 +220,18 @@ def edit_alias(request, project_slug, id=None):
)
@login_required
def list_alias(request, project_slug):
proj = get_object_or_404(Project.objects.all(), slug=project_slug)
return object_list(
request,
queryset=proj.aliases.all(),
template_object_name='alias',
template_name='projects/alias_list.html',
)
class AliasList(ListView):
model = VersionAlias
template_context_name = 'alias'
template_name='projects/alias_list.html',
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(AliasList, self).dispatch(*args, **kwargs)
def get_queryset(self):
self.project = get_object_or_404(Project.objects.all(), slug=self.kwargs.get('project_slug'))
return self.project.aliases.all()
@login_required

View File

@ -5,7 +5,7 @@ from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.views.generic.list_detail import object_list
from django.views.generic import ListView
from django.utils.datastructures import SortedDict
from taggit.models import Tag
@ -16,32 +16,32 @@ from builds.models import Version
from projects.models import Project
def project_index(request, username=None, tag=None):
"""
The list of projects, which will optionally filter by user or tag,
in which case a 'person' or 'tag' will be added to the context
"""
queryset = Project.objects.public(request.user)
if username:
user = get_object_or_404(User, username=username)
queryset = queryset.filter(user=user)
else:
user = None
class ProjectIndex(ListView):
model = Project
if tag:
tag = get_object_or_404(Tag, slug=tag)
queryset = queryset.filter(tags__name__in=[tag.slug])
else:
tag = None
def get_queryset(self):
queryset = Project.objects.public(self.request.user)
if self.kwargs.get('username'):
self.user = get_object_or_404(User, username=self.kwargs.get('username'))
queryset = queryset.filter(user=self.user)
else:
self.user = None
return object_list(
request,
queryset=queryset,
extra_context={'person': user, 'tag': tag},
page=int(request.GET.get('page', 1)),
template_object_name='project',
)
if self.kwargs.get('tag'):
self.tag = get_object_or_404(Tag, slug=self.kwargs.get('tag'))
queryset = queryset.filter(tags__name__in=[self.tag.slug])
else:
self.tag = None
return queryset
def get_context_data(self, **kwargs):
context = super(ProjectIndex, self).get_context_data(**kwargs)
context['person'] = self.user
context['tag'] = self.tag
return context
project_index = ProjectIndex.as_view()
def project_detail(request, project_slug):
"""
@ -118,41 +118,6 @@ def project_downloads(request, project_slug):
)
def tag_index(request):
"""
List of all tags by most common
"""
tag_qs = Project.tags.most_common()
return object_list(
request,
queryset=tag_qs,
page=int(request.GET.get('page', 1)),
template_object_name='tag',
template_name='projects/tag_list.html',
)
def search(request):
"""
our ghetto site search. see roadmap.
"""
if 'q' in request.GET:
term = request.GET['q']
else:
raise Http404
queryset = Project.objects.live(name__icontains=term)
if queryset.count() == 1:
return HttpResponseRedirect(queryset[0].get_absolute_url())
return object_list(
request,
queryset=queryset,
template_object_name='term',
extra_context={'term': term},
template_name='projects/search.html',
)
def search_autocomplete(request):
"""
return a json list of project names

View File

@ -1,4 +1,4 @@
from django.conf.urls.defaults import url, patterns, include
from django.conf.urls import url, patterns, include
from rest_framework import routers

View File

@ -1,6 +1,6 @@
from os.path import exists
from django.contrib.admin.models import User
from django.contrib.auth.models import User
from projects.models import Project
from rtd_tests.base import RTDTestCase

View File

@ -1,7 +1,7 @@
from os.path import exists
import shutil
from tempfile import mkdtemp
from django.contrib.admin.models import User
from django.contrib.auth.models import User
import json
from projects.models import Project

View File

@ -1,6 +1,6 @@
import shutil
from django.contrib.admin.models import User
from django.contrib.auth.models import User
from projects.models import Project

View File

@ -53,7 +53,6 @@ class PrivacyTests(TestCase):
'num_minor': 2, 'num_major': 2, 'num_point': 2,
'version_privacy_level': version_privacy_level,
'documentation_type': 'sphinx'})
#import ipdb; ipdb.set_trace()
self.assertAlmostEqual(Project.objects.count(), 1)
r = self.client.get('/projects/django-kong/')

View File

@ -100,6 +100,16 @@ MIDDLEWARE_CLASSES = (
#'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
)
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
"django.contrib.auth.backends.ModelBackend",
# `allauth` specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend",
)
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
CORS_ORIGIN_REGEX_WHITELIST = ('^http://(.+)\.readthedocs\.org$', '^https://(.+)\.readthedocs\.org$')
# So people can post to their accounts
CORS_ALLOW_CREDENTIALS = True
@ -115,25 +125,26 @@ TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.request",
# Read the Docs processor
"core.context_processors.readthedocs_processor",
# allauth specific context processors
"allauth.account.context_processors.account",
"allauth.socialaccount.context_processors.socialaccount",
)
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.markup',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.staticfiles',
# third party apps
'pagination',
'registration',
'profiles',
'taggit',
'south',
'basic.flagging',
'djangosecure',
'guardian',
'django_gravatar',
@ -149,16 +160,29 @@ INSTALLED_APPS = [
'haystack',
'tastypie',
# our apps
'projects',
'builds',
'core',
'doc_builder',
'rtd_tests',
'websupport',
'restapi',
# allauth
'allauth',
'allauth.account',
'allauth.socialaccount',
#'allauth.socialaccount.providers.github',
#'allauth.socialaccount.providers.bitbucket',
#'allauth.socialaccount.providers.twitter',
]
SOUTH_MIGRATION_MODULES = {
'taggit': 'taggit.south_migrations',
}
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
@ -175,6 +199,7 @@ CELERY_SEND_TASK_ERROR_EMAILS = False
CELERYD_HIJACK_ROOT_LOGGER = False
# Don't queue a bunch of tasks in the workers
CELERYD_PREFETCH_MULTIPLIER = 1
HAYSTACK_SIGNAL_PROCESSOR = 'celery_haystack.signals.CelerySignalProcessor'
CELERY_ROUTES = {
'celery_haystack.tasks.CeleryHaystackSignalHandler': {
@ -236,6 +261,11 @@ LOGGING = {
'datefmt': "%d/%b/%Y %H:%M:%S"
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'null': {
'level': 'DEBUG',
@ -291,6 +321,7 @@ LOGGING = {
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
},
'console': {

View File

@ -10,7 +10,7 @@
<link rel="icon" type="image/png" href="{{ MEDIA_URL }}images/favicon.png">
<!-- title -->
<title>{% block title %}{% endblock %} | {% block branding %}{% trans "Read the Docs" %} {% endblock %}</title>
<title>{% block title %}{% endblock %}{% block head_title %}{% endblock %} | {% block branding %}{% trans "Read the Docs" %} {% endblock %}</title>
<!-- css -->
<link rel="stylesheet" href="{{ MEDIA_URL }}css/core.css">
@ -146,7 +146,7 @@
})();
$('.rtfd-header-search input:text').autocomplete({
source: '{% url search_autocomplete %}',
source: '{% url "search_autocomplete" %}',
minLength: 2,
open: function(event, ui) {
ac_top = $('.ui-autocomplete').css('top');

View File

@ -30,7 +30,7 @@
<div class="module-header">
<div style="float:right;">
<form method="post" action="{% url generic_build project.pk %}">
<form method="post" action="{% url "generic_build" project.pk %}">
<ul class="build_a_version">
<li style="display: inline-block">
<input style="display: inline-block" type="submit" value="{% trans "Build Version:" %}">

View File

@ -7,7 +7,7 @@
{% block content %}
<ul>
{% for tag in tag_list %}
<li><a href="{% url projects_tag_detail tag.slug %}">{{ tag.name }}</a></li>
<li><a href="{% url "projects_tag_detail" tag.slug %}">{{ tag.name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -1,7 +1,7 @@
{% for bookmark in bookmark_list %}
<li class="module-item">
<a class="module-item-title" href="{{ bookmark.get_absolute_url }}">{{ bookmark.url }}</a>
<a href="{% url projects_user_list bookmark.user.username %}" class="quiet">({{ bookmark.user }})</a>
<a href="{% url "projects_user_list" bookmark.user.username %}" class="quiet">({{ bookmark.user }})</a>
<span class="quiet">{% if bookmark.project.version %}version {{ bookmark.project.version }} -{% endif %} {{ bookmark.date|timesince }} ago</span>
</li>
{% endfor %}

View File

@ -7,14 +7,14 @@
<div class="rtfd-header-title">
<h1>
{% comment %}Translators: Name of the website{% endcomment %}
<a href="{% url core.views.homepage %}">{% trans "Read the Docs" %}</a>
<a href="{% url "core.views.homepage" %}">{% trans "Read the Docs" %}</a>
</h1>
</div>
<!-- END header title -->
<!-- BEGIN global search -->
<div class="rtfd-header-search">
<form action="{% url haystack_project %}" method="GET">
<form action="{% url "haystack_project" %}" method="GET">
<input type="text" name="q" value="{{ term }}" id="id_site_search">
<input type="submit" value="{% trans "Go" %}">
</form>
@ -27,9 +27,9 @@
{% if request.META.PATH_INFO != '/' %}
<div class="rtfd-header-bookmark">
{% if has_bookmark %}
<a href="{% url bookmarks_remove request.META.PATH_INFO %}" class="rtfd-header-bookmark-icon active">{% trans "Remove bookmark" %}</a>
<a href="{% url "bookmarks_remove" request.META.PATH_INFO %}" class="rtfd-header-bookmark-icon active">{% trans "Remove bookmark" %}</a>
{% else %}
<a href="{% url bookmarks_add request.META.PATH_INFO %}" class="rtfd-header-bookmark-icon">{% trans "Bookmark this URL" %}</a>
<a href="{% url "bookmarks_add" request.META.PATH_INFO %}" class="rtfd-header-bookmark-icon">{% trans "Bookmark this URL" %}</a>
{% endif %}
</div>
{% endif %}
@ -41,10 +41,10 @@
<div class="rtfd-header-nav">
<ul>
{% if request.user.is_authenticated %}
<li class="{{ dashboard_active }}"><a href="{% url projects_dashboard %}">{% trans "Dashboard" %}</a></li>
<li><a href="{% url auth_logout %}">{% trans "Log Out" %}</a></li>
<li class="{{ dashboard_active }}"><a href="{% url "projects_dashboard" %}">{% trans "Dashboard" %}</a></li>
<li><a href="{% url "account_logout" %}">{% trans "Log Out" %}</a></li>
{% else %}
<li><a href="{% url auth_login %}">{% trans "Log in" %}</a></li>
<li><a href="{% url "account_login" %}">{% trans "Log in" %}</a></li>
{% endif %}
<li><a href="{% url donate %}">{% trans "Donate" %}</a></li>

View File

@ -14,9 +14,9 @@
<!-- BEGIN header links-->
<div class="home-header-links">
{% comment %}Translators: Note, the full sentence goes 'Sign up' 'or' 'Log in'. But unfortunately the three bits have to be separate.{% endcomment %}
<a class="reg" href="{% url registration_register %}">{% trans "Sign up" %}</a>
<a class="reg" href="{% url "account_signup" %}">{% trans "Sign up" %}</a>
<div class="login-box">
<p>{% trans "or" %} <a class="login" href="{% url auth_login %}">{% trans "Log in" %}</a></p>
<p>{% trans "or" %} <a class="login" href="{% url "account_login" %}">{% trans "Log in" %}</a></p>
</div>
</div>
<!-- END header links -->

View File

@ -27,7 +27,7 @@
<p class="build-success">&nbsp;</p>
{% endif %}
{% else %}
<p class="build-missing">{% trans "There are no builds for this project" %}.{% if request.user in project.users.all %} <a href="{% url projects_edit project.slug %}">{% trans "Is the repo correct?" %}</a>{% endif %}</p>
<p class="build-missing">{% trans "There are no builds for this project" %}.{% if request.user in project.users.all %} <a href="{% url "projects_edit" project.slug %}">{% trans "Is the repo correct?" %}</a>{% endif %}</p>
{% endif %}
<ul>
@ -36,14 +36,14 @@
<li><a href="{{ project.get_docs_url }}">{% trans "View Docs" %}</a></li>
{% endif %}
<li class="{{ downloads_active }}"><a href="{% url project_downloads project.slug %}" rel="nofollow,noindex">{% trans "Downloads" %}</a></li>
<li class="{{ downloads_active }}"><a href="{% url "project_downloads" project.slug %}" rel="nofollow,noindex">{% trans "Downloads" %}</a></li>
{% if project.get_latest_build %}
<li class="{{ builds_active }}"><a href="{{ project.get_builds_url }}">{% trans "Builds" %}</a></li>
{% endif %}
{% if request.user in project.users.all %}
<li class="{{ edit_active }}"><a href="{% url projects_edit project.slug %}"><i class="gear"></i>{% trans "Admin" %}</a></li>
<li class="{{ edit_active }}"><a href="{% url "projects_edit" project.slug %}"><i class="gear"></i>{% trans "Admin" %}</a></li>
{% endif %}

View File

@ -1,5 +1,5 @@
{% load i18n %}
{% load markup %}
{% load core_tags %}
{% if project.description %}
<h3>{% trans "Description" %}</h3>
@ -12,7 +12,7 @@
<!-- BEGIN search bar -->
<div class="search">
<form action="{% url haystack_project %}" method="GET">
<form action="{% url "haystack_project" %}" method="GET">
<input type="text" name="q" value="" placeholder="{% blocktrans %}Search {{ project }}{% endblocktrans %}" id="id_site_search">
<input type="hidden" name="selected_facets" value="project_exact:{{ project.name }}">
<input type="submit" value="{% trans "Search" %}">
@ -57,7 +57,7 @@
{% endif %}
{% if request.user in project.users.all %}
<ul class="module-item-menu">
<li><a href="{% url project_version_detail project.slug version.slug %}">{% trans "Edit" %}</a></li>
<li><a href="{% url "project_version_detail" project.slug version.slug %}">{% trans "Edit" %}</a></li>
</ul>
{% endif %}
</li>
@ -69,7 +69,7 @@
<div class="build_a_version">
<h3>{% trans "Build a version" %}</h3>
<div style="float: left; margin-right: 5px;" class="version_right">
<form method="post" action="{% url generic_build project.pk %}">
<form method="post" action="{% url "generic_build" project.pk %}">
<select id="id_version" name="version_slug">
{% for version in project.ordered_active_versions %}
<option value="{{ version.slug }}">{{ version.slug }}</option>
@ -93,7 +93,7 @@
<h3>{% trans "Tags" %}</h3>
<p>
{% for tag in project.tags.all %}
<a href="{% url projects_tag_detail tag.slug %}">{{ tag.name }}</a>{% if forloop.last %}{% else %}, {% endif %}
<a href="{% url "projects_tag_detail" tag.slug %}">{{ tag.name }}</a>{% if forloop.last %}{% else %}, {% endif %}
{% empty %}
<span class="quiet">{% trans "No tags" %}</span>
{% endfor %}
@ -157,7 +157,7 @@
{% if request.user in project.users.all %}
<h3>{% trans "Post Commit Hook" %}</h3>
<p>
curl -X POST http://{{ PRODUCTION_DOMAIN }}{% url generic_build project.slug %}
curl -X POST http://{{ PRODUCTION_DOMAIN }}{% url "generic_build" project.slug %}
</p>
{% endif %}

View File

@ -9,7 +9,7 @@
{% endif %}
{% if request.user in project.users.all %}
<ul class="module-item-menu">
<li><a href="{% url project_version_detail project.slug version.slug %}">{% trans "Add tags" %}</a></li>
<li><a href="{% url "project_version_detail" project.slug version.slug %}">{% trans "Add tags" %}</a></li>
</ul>
{% endif %}
</li>

View File

@ -7,7 +7,7 @@
<div class="wide-search-bar-wrapper clearfix">
<form action="{% url haystack_project %}" method="GET">
<form action="{% url "haystack_project" %}" method="GET">
<div class="text-input-wrapper">
<input type="text" name="q" value="{{ term }}" id="id_site_search">
</div>
@ -22,7 +22,7 @@
{% comment %}
<script type="text/javascript">
$('.wide-search-bar #id_site_search').autocomplete({
source: '{% url search_autocomplete %}',
source: '{% url "search_autocomplete" %}',
minLength: 2,
open: function(event, ui) {
ac_top = $('.ui-autocomplete').css('top');

View File

@ -5,14 +5,14 @@
<div class="wrapper">
<ul>
<li class="first last {{ projects_active }}"><a href="{% url projects_dashboard %}">{% trans "Projects" %}</a></li>
<li class="first last {{ projects_active }}"><a href="{% url "projects_dashboard" %}">{% trans "Projects" %}</a></li>
{% comment %}
<li class="{% block dash-nav-bookmarks %}{% endblock %}"><a href="{% url user_bookmarks %}">{% trans "Bookmarks" %}</a></li>
<li class="{% block dash-nav-bookmarks %}{% endblock %}"><a href="{% url "user_bookmarks" %}">{% trans "Bookmarks" %}</a></li>
{% endcomment %}
</ul>
<ul>
<li class="first last {{ import_active }}"><a href="{% url projects_import %}">{% trans "Import" %}</a></li>
<li class="first last {{ import_active }}"><a href="{% url "projects_import" %}">{% trans "Import" %}</a></li>
</ul>
<ul>

View File

@ -8,7 +8,7 @@
<div class="rtfd-header-title">
<h1>
{% comment %}Translators: Name of the website{% endcomment %}
<a href="//{{ PRODUCTION_DOMAIN }}{% url core.views.homepage %}">
<a href="//{{ PRODUCTION_DOMAIN }}{% url "core.views.homepage" %}">
{% trans "Read the Docs" %}
</a>
</h1>
@ -17,7 +17,7 @@
<!-- BEGIN global search -->
<div class="rtfd-header-search">
<form action="//{{ PRODUCTION_DOMAIN }}{% url haystack_project %}" method="GET">
<form action="//{{ PRODUCTION_DOMAIN }}{% url "haystack_project" %}" method="GET">
<input type="text" name="q" value="{{ term }}" id="id_site_search">
<input type="submit" value="{% trans "Go" %}">
</form>
@ -29,11 +29,11 @@
<ul>
{% if request.user.is_authenticated %}
<li>
<a href="//{{ PRODUCTION_DOMAIN }}{% url auth_logout %}">{% trans "Log Out" %}</a>
<a href="//{{ PRODUCTION_DOMAIN }}{% url "account_logout" %}">{% trans "Log Out" %}</a>
</li>
{% else %}
<li>
<a href="//{{ PRODUCTION_DOMAIN }}{% url auth_login %}">{% trans "Log in" %}</a>
<a href="//{{ PRODUCTION_DOMAIN }}{% url "account_login" %}">{% trans "Log in" %}</a>
</li>
{% endif %}
</ul>

View File

@ -1,11 +0,0 @@
{% extends "base.html" %}
{% load markup %}
{% block title %}{{ flatpage.title }}{% endblock %}
{% block content-header %}<h1>{{ flatpage.title }}</h1>{% endblock %}
{% block content %}
{{ flatpage.content|restructuredtext }}
{% endblock %}

View File

@ -86,7 +86,7 @@ There's also support for versioning so you can build docs from tags and branches
<div class="module-wrapper">
<div class="module-header">
<h3>{% trans "Recently Updated Projects" %} <span class="small_head"><a href="{% url projects_list %}">{% trans "(All Projects)" %}</a></span></h3>
<h3>{% trans "Recently Updated Projects" %} <span class="small_head"><a href="{% url "projects_list" %}">{% trans "(All Projects)" %}</a></span></h3>
</div>
<div class="module-list">
@ -108,7 +108,7 @@ There's also support for versioning so you can build docs from tags and branches
<div class="module-wrapper">
<div class="module-header">
<h3>{% trans "Most Viewed Pages" %} <span class="small_head"><a href="{% url pageviews_list %}">{% trans "(All Views)" %}</a></span></h3>
<h3>{% trans "Most Viewed Pages" %} <span class="small_head"><a href="{% url "pageviews_list" %}">{% trans "(All Views)" %}</a></span></h3>
</div>
<div class="module-list">
@ -131,7 +131,7 @@ There's also support for versioning so you can build docs from tags and branches
<div class="module-wrapper">
<div class="module-header">
<h3>{% trans "Recently Bookmarked Docs" %} <span class="small_head"><a href="{% url bookmarks_list %}">{% trans "(All Bookmarks)" %}</a></span></h3>
<h3>{% trans "Recently Bookmarked Docs" %} <span class="small_head"><a href="{% url "bookmarks_list" %}">{% trans "(All Bookmarks)" %}</a></span></h3>
</div>
<div class="module-list">

View File

@ -20,7 +20,7 @@
{% with profile.get_form as form %}
{% if profile.user.pk == user.pk %}
<form id="edit_form" method="POST" action="{% url profiles_profile_edit %}">
<form id="edit_form" method="POST" action="{% url "profiles_profile_edit" %}">
{% endif %}
<div class="navigable">

View File

@ -10,6 +10,6 @@
{% block content %}
{% for profile in object_list %}
<p><a href="{% url profiles_profile_detail profile.user %}">{{ profile }}</a></p>
<p><a href="{% url "profiles_profile_detail" profile.user %}">{{ profile }}</a></p>
{% endfor %}
{% endblock %}

View File

@ -25,7 +25,7 @@
<ul>
{% for alias in alias_list %}
<li><a href="{% url projects_alias_edit alias.project.slug alias.pk %}">{{ alias }}</a></li>
<li><a href="{% url "projects_alias_edit" alias.project.slug alias.pk %}">{{ alias }}</a></li>
{% endfor %}
</ul>

View File

@ -35,7 +35,7 @@
{% block content %}
<p class="help_text">
{% trans "Create new documentation here. If you already have docs in a public repository," %}
<a class="" href="{% url projects_import %}">{% trans "import an existing project" %}</a>.
<a class="" href="{% url "projects_import" %}">{% trans "import an existing project" %}</a>.
</p>
<form method="post" action=".">{% csrf_token %}
{{ form.as_p }}

View File

@ -63,9 +63,9 @@
<ul>
{% for project in project_list %}
<li class="module-item col-span">
<a href="{% url projects_manage project.slug %}">{{ project.name }}</a>
<a href="{% url "projects_manage" project.slug %}">{{ project.name }}</a>
<ul class="module-item-menu">
<li><a href="{% url projects_edit project.slug %}"><i class="gear"></i>{% trans "Admin" %}</a></li>
<li><a href="{% url "projects_edit" project.slug %}"><i class="gear"></i>{% trans "Admin" %}</a></li>
<li>&nbsp;&nbsp;</li>
<li><a href="{{ project.get_docs_url }}">{% trans "View Docs" %}</a></li>
</ul>
@ -78,7 +78,7 @@
</div>
</div>
{% else %}
{% url projects_import as projects_import_url %}
{% url "projects_import" as projects_import_url %}
<p class="empty">
{% blocktrans with "https://read-the-docs.readthedocs.org/en/latest/getting_started.html" as getting_started_url %}You don't have any projects. You should <a href="{{ projects_import_url }}">create new docs</a> on the site.<br>
Check out the <a href="{{ getting_started_url }}">Getting Started</a> documentation for information about how to get going.{% endblocktrans %}</p>
@ -91,7 +91,7 @@
<div class="module">
<div class="module-wrapper">
<div class="module-header">
<h3>{% trans "Recently Bookmarked Docs" %} <span class="small_head"><a href="{% url user_bookmarks %}">{% trans "(All My Bookmarks)" %}</a></span></h3>
<h3>{% trans "Recently Bookmarked Docs" %} <span class="small_head"><a href="{% url "user_bookmarks" %}">{% trans "(All My Bookmarks)" %}</a></span></h3>
</div>
<div class="module-list">

View File

@ -1,7 +1,5 @@
{% extends "projects/base_project.html" %}
{% load markup %}
{% block body_class %}project_detail{% endblock %}
{% block title %}{{ project.name }}{% endblock %}

View File

@ -1,6 +1,6 @@
{% extends "projects/base_project.html" %}
{% load i18n markup %}
{% load i18n %}
{% block title %}{{ project.name }}{% endblock %}

View File

@ -37,7 +37,7 @@
<input style="display: inline;" type="submit" value="{% trans "Submit" %}">
{% comment %}Translators: The 'or' here is in between 'Submit' and 'delete'.{% endcomment %}
{% trans "or" %}
<a href="{% url projects_delete project.slug %}">{% trans "delete" %}</a>
<a href="{% url "projects_delete" project.slug %}">{% trans "delete" %}</a>
</p>
</form>
{% endblock %}

View File

@ -12,13 +12,12 @@
{% block content %}
<div class="navigable">
<ul>
<li class="{% block project-edit-active %}{% endblock %}"><a href="{% url projects_edit project.slug %}">{% trans "Settings" %} </a></li>
<li class="{% block project-advanced-active %}{% endblock %}"><a href="{% url projects_advanced project.slug %}">{% trans "Advanced Settings" %} </a></li>
<li class="{% block project-admins-active %}{% endblock %}"><a href="{% url projects_users project.slug %}">{% trans "Maintainers" %}</a></li>
<li class="{% block project-versions-active %}{% endblock %}"><a href="{% url projects_versions project.slug %}" rel="nofollow,noindex">{% trans "Versions" %}</a></li>
<li class="{% block project-translations-active %}{% endblock %}"><a href="{% url projects_translations project.slug %}">{% trans "Translations" %}</a></li>
<li class="{% block project-subprojects-active %}{% endblock %}"><a href="{% url projects_subprojects project.slug %}">{% trans "Subprojects" %}</a></li>
<li class="{% block project-notifications-active %}{% endblock %}"><a href="{% url projects_notifications project.slug %}">{% trans "Notifications" %}</a></li>
<li class="{% block project-edit-active %}{% endblock %}"><a href="{% url "projects_edit" project.slug %}">{% trans "Settings" %} </a></li>
<li class="{% block project-admins-active %}{% endblock %}"><a href="{% url "projects_users" project.slug %}">{% trans "Maintainers" %}</a></li>
<li class="{% block project-versions-active %}{% endblock %}"><a href="{% url "projects_versions" project.slug %}" rel="nofollow,noindex">{% trans "Versions" %}</a></li>
<li class="{% block project-translations-active %}{% endblock %}"><a href="{% url "projects_translations" project.slug %}">{% trans "Translations" %}</a></li>
<li class="{% block project-subprojects-active %}{% endblock %}"><a href="{% url "projects_subprojects" project.slug %}">{% trans "Subprojects" %}</a></li>
<li class="{% block project-notifications-active %}{% endblock %}"><a href="{% url "projects_notifications" project.slug %}">{% trans "Notifications" %}</a></li>
</ul>
<div>
<h2>{% block project_edit_content_header %}{% endblock %}</h2>

View File

@ -29,7 +29,7 @@
{% if emails|length > 0 %}
<h3>{% trans "Remove Notifications" %}</h3>
<p>
<form method="post" action="{% url projects_notification_delete project.slug %}">
<form method="post" action="{% url "projects_notification_delete" project.slug %}">
{% csrf_token %}
<select id="id_email" name="email">
{% for email in emails %}

View File

@ -24,7 +24,7 @@
<a href="{{ relationship.get_absolute_url }}">
{{ relationship.child }}
</a>
(<a href="{% url projects_subprojects_delete relationship.parent.slug relationship.child.slug %}">{% trans "Remove" %}</a>)
(<a href="{% url "projects_subprojects_delete" relationship.parent.slug relationship.child.slug %}">{% trans "Remove" %}</a>)
</li>
{% endfor %}
</ul>
@ -42,7 +42,7 @@
{% block footerjs %}
$('#id_subproject').autocomplete({
source: '{% url search_autocomplete %}',
source: '{% url "search_autocomplete" %}',
minLength: 2,
open: function(event, ui) {
ac_top = $('.ui-autocomplete').css('top');

View File

@ -23,7 +23,7 @@
<li>
<a href="{{ lang_project.get_absolute_url }}">{{ lang_project }}</a>
({{ lang_project.language }})
(<a href="{% url projects_translations_delete project.slug lang_project.slug %}">{% trans "Remove" %}</a>)
(<a href="{% url "projects_translations_delete" project.slug lang_project.slug %}">{% trans "Remove" %}</a>)
</li>
{% endfor %}
</ul>
@ -41,7 +41,7 @@
{% block footerjs %}
$('#id_project').autocomplete({
source: '{% url search_autocomplete %}',
source: '{% url "search_autocomplete" %}',
minLength: 2,
open: function(event, ui) {
ac_top = $('.ui-autocomplete').css('top');

View File

@ -17,7 +17,7 @@
<ul>
{% for user in users %}
<li>
<a href="{% url profiles_profile_detail user.username %}">
<a href="{% url "profiles_profile_detail" user.username %}">
{{ user }}
</a>
</li>
@ -27,7 +27,7 @@
{% if users|length > 1 %}
<h3>{% trans "Remove Maintainer" %}</h3>
<p>
<form method="post" action="{% url projects_users_delete project.slug %}">
<form method="post" action="{% url "projects_users_delete" project.slug %}">
{% csrf_token %}
<select id="id_user" name="username">
{% for user in users %}

View File

@ -10,7 +10,7 @@
{% block content %}
<ul>
{% for tag in tag_list %}
<li><a href="{% url projects_tag_detail tag.slug %}">{{ tag.name }}</a></li>
<li><a href="{% url "projects_tag_detail" tag.slug %}">{{ tag.name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -10,7 +10,7 @@
<p class="help_text">
{% trans "Use this to upload pre-existing HTML documentation for versions that don't build correctly anymore." %}
</p>
<form enctype="multipart/form-data" method="post" action="{% url projects_upload_html project.slug %}"> {% csrf_token %}
<form enctype="multipart/form-data" method="post" action="{% url "projects_upload_html" project.slug %}"> {% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="{% trans "Upload" %}" /></p>
</form>

View File

@ -1,23 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Account activation error" %}{% endblock %}
{% block body_class %}{{ block.super }} registration_activate{% endblock %}
{% block content-header %}
<h1>{% trans "Account activation error" %}</h1>
{% endblock %}
{% block content %}
<p>
{% blocktrans %}The activation key "{{ activation_key }}" is invalid and cannot be used to activate this account.{% endblocktrans %}
{% blocktrans %}Did you really think activation key "{{ activation_key }}" was going to work?!{% endblocktrans %}
</p>
<p>
{% trans "We're not sure how you got that key, but would you mind registering again" %} <a href="{% url registration_register %}">{% trans "here" %}</a>?
</p>
{% endblock %}

View File

@ -1,18 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Account activation complete" %}{% endblock %}
{% block body_class %}{{ block.super }} registration_activation_complete{% endblock %}
{% block content-header %}
<h1>{% trans "Account activation complete, woo!" %}</h1>
{% endblock %}
{% block content %}
<p>{% trans "Your account has been activated." %} ^_^</p>
<p>{% trans "Log in with the username and password you just created," %} <a href="{% url auth_login %}">{% trans "here" %}</a>.</p>
{% endblock %}

View File

@ -1,8 +0,0 @@
{% load i18n %}{% url registration_activate activation_key as activation_url %}{% blocktrans with expiration_days=expiration_days domain=site.domain %}Thank you for registering an account at {{ domain }}.
To activate your registration, please visit the following page:
http://{{ domain }}{{ activation_url }}
This page will expire in {{ expiration_days }} days.
If you didn't register this account you can simply delete this email and we won't bother you again.{% endblocktrans %}

View File

@ -1 +0,0 @@
{% load i18n %}{% blocktrans with site.name as site_name %}{{ site_name }} - activate your account{% endblocktrans %}

View File

@ -1,7 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %}{% trans "Registration" %}{% endblock %}
{% block body_class %}{{ block.super }} {% trans "registration" %}{% endblock %}

View File

@ -1,35 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Log in" %}{% endblock %}
{% block body_class %}{{ block.super }} login_form{% endblock %}
{% block extra_scripts %}
<script type="text/javascript">
$(function () {
$('#id_username').focus();
});
</script>
{% endblock %}
{% block content-header %}
<h1>{% trans "Log in" %}</h1>
{% endblock %}
{% block content %}
<form action="." method="post" class="login_form">{% csrf_token %}
{{ form.as_p }}
<p class="submit"><input type="submit" name="submit" value="{% trans "Log in" %}"></p>
</form>
<p>
{% blocktrans %}If you forgot your password, <a href="/accounts/password/reset/">reset it.</a>{% endblocktrans %}
</p>
<p>
{% blocktrans %}Don't have an account? <a href="/accounts/register/">Register</a> a new one.{% endblocktrans %}
</p>
{% endblock %}

View File

@ -1,23 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Log Out" %}{% endblock %}
{% block body_class %}{{ block.super }}{% endblock %}
{% block content-header %}
<h1>{% trans "You've logged out." %}</h1>
{% endblock %}
{% block content %}
<p>
{% trans "Thanks for visiting!" %}
</p>
<p>
{% url auth_login as login_url %}
{% blocktrans %}If you are looking to log in again, you can do that <a href="{{ login_url }}">here</a>{% endblocktrans %}.
</p>
{% endblock %}

View File

@ -1,14 +0,0 @@
{% extends "dashboard/base_dashboard.html" %}
{% load i18n %}
{% block title %}{% trans 'Password change successful' %}{% endblock %}
{% block dash-nav-change-pw %}active{% endblock %}
{% block content %}
<h1>{% trans 'Password change successful' %}</h1>
<p>{% trans 'Your password was changed.' %}</p>
{% endblock %}

View File

@ -1,52 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %}{% trans 'Password change' %}{% endblock %}
{% block dashboard_bar %}
{% with change_password_active="active" %}
{% include "dashboard/dashboard_bar.html" %}
{% endwith %}
{% endblock %}
{% block content %}<div id="content-main">
<form action="" method="post">{% csrf_token %}
<div>
{% if form.errors %}
<p class="errornote">
{% blocktrans count form.errors.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
</p>
{% endif %}
<h1>{% trans 'Password change' %}</h1>
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
<div class="form-row">
{{ form.old_password.errors }}
<label for="id_old_password" class="required">{% trans 'Old password' %}:</label>{{ form.old_password }}
</div>
<div class="form-row">
{{ form.new_password1.errors }}
<label for="id_new_password1" class="required">{% trans 'New password' %}:</label>{{ form.new_password1 }}
</div>
<div class="form-row">
{{ form.new_password2.errors }}
<label for="id_new_password2" class="required">{% trans 'Password (again)' %}:</label>{{ form.new_password2 }}
</div>
<div class="submit-row">
<input type="submit" value="{% trans 'Change my password' %}" class="default" />
</div>
<script type="text/javascript">document.getElementById("id_old_password").focus();</script>
</div>
</form>
{% endblock %}

View File

@ -1,18 +0,0 @@
{% extends "dashboard/base_dashboard.html" %}
{% block dashboard_bar %}
{% endblock %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
{% block title %}{% trans 'Password reset complete' %}{% endblock %}
{% block content %}
<h1>{% trans 'Password reset complete' %}</h1>
<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p>
<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
{% endblock %}

View File

@ -1,34 +0,0 @@
{% extends "dashboard/base_dashboard.html" %}
{% block dashboard_bar %}
{% endblock %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset confirmation' %}</div>{% endblock %}
{% block title %}{% trans 'Password reset' %}{% endblock %}
{% block content %}
{% if validlink %}
<h1>{% trans 'Enter new password' %}</h1>
<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
<form action="" method="post">{% csrf_token %}
{{ form.new_password1.errors }}
<p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
{{ form.new_password2.errors }}
<p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
</form>
{% else %}
<h1>{% trans 'Password reset unsuccessful' %}</h1>
<p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p>
{% endif %}
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends "dashboard/base_dashboard.html" %}
{% block dashboard_bar %}
{% endblock %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
{% block title %}{% trans 'Password reset successful' %}{% endblock %}
{% block content %}
<h1>{% trans 'Password reset successful' %}</h1>
<p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
{% endblock %}

View File

@ -1,15 +0,0 @@
{% load i18n %}{% autoescape off %}
{% trans "You're receiving this e-mail because you requested a password reset" %}
{% blocktrans %}for your user account at {{ site_name }}{% endblocktrans %}.
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url django.contrib.auth.views.password_reset_confirm uidb36=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}

View File

@ -1,22 +0,0 @@
{% extends "dashboard/base_dashboard.html" %}
{% load i18n %}
{% block dashboard_bar %}
{% endblock %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
{% block title %}{% trans "Password reset" %}{% endblock %}
{% block content %}
<h1>{% trans "Password reset" %}</h1>
<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>
<form action="" method="post">{% csrf_token %}
{{ form.email.errors }}
<p><label for="id_email">{% trans 'E-mail address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p>
</form>
{% endblock %}

View File

@ -1,25 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Registration closed" %}{% endblock %}
{% block body_class %}{{ block.super }} registration_closed{% endblock %}
{% block content-header %}
<h1>{% trans "Eh... Registration closed." %}</h1>
{% endblock %}
{% block content %}
<p>
{% blocktrans %} You registered a long time ago.
We aren't sure if you are a robot or if
something got lost or what.{% endblocktrans %}
{% trans "Please try" %} <a href="{% url registration_register %}">{% trans "registering again" %}</a>.
</p>
<p class="quiet">
{% trans "We hope that isn't too inconvenient." %}
</p>
{% endblock %}

View File

@ -1,24 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Registration complete" %}{% endblock %}
{% block body_class %}{{ block.super }} registration_complete{% endblock %}
{% block content-header %}
<h1>{% trans "Registration complete" %}</h1>
{% endblock %}
{% block content %}
<h3>{% trans "Now activate your account." %}</h3>
<p>
{% blocktrans %}We will be sending you an email with an activation link.
Visit the link to verify this account.{% endblocktrans %}
</p>
<p>
{% trans "Check your email. We'll wait." %}
</p>
{% endblock %}

View File

@ -1,29 +0,0 @@
{% extends "registration/base_registration.html" %}
{% load i18n %}
{% block title %}{% trans "Register for an account" %}{% endblock %}
{% block body_class %}{{ block.super }} registration_form{% endblock %}
{% block extra_scripts %}
<script type="text/javascript">
$(function () {
$('#id_username').focus();
});
</script>
{% endblock %}
{% block content-header %}
<h1>{% trans "Register for an account" %}</h1>
{% endblock %}
{% block content %}
<form action="." method="post">{% csrf_token %}
{{ form.as_p }}
<p class="submit"><input type="submit" value="{% trans "Send me the activation link." %}"></p>
</form>
{% endblock %}

View File

@ -1,7 +1,7 @@
from django.conf.urls.defaults import url, patterns, include
from django.conf.urls import url, patterns, include
from django.contrib import admin
from django.conf import settings
from django.views.generic.simple import direct_to_template
from django.views.generic.base import TemplateView
from tastypie.api import Api
@ -29,7 +29,7 @@ handler404 = 'core.views.server_error_404'
urlpatterns = patterns(
'', # base view, flake8 complains if it is on the previous line.
url(r'^$', 'core.views.homepage'),
url(r'^security/', direct_to_template, {'template': 'security.html'}),
url(r'^security/', TemplateView.as_view(template_name='security.html')),
# For serving docs locally and when nginx isn't
url((r'^docs/(?P<project_slug>[-\w]+)/(?P<lang_slug>%s)/(?P<version_slug>'
@ -73,8 +73,7 @@ urlpatterns = patterns(
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^projects/', include('projects.urls.public')),
url(r'^builds/', include('builds.urls')),
url(r'^flagging/', include('basic.flagging.urls')),
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^accounts/', include('allauth.urls')),
url(r'^search/project/', SearchView.as_view(), name='haystack_project'),
url(r'^search/', include('haystack.urls')),
url(r'^admin/', include(admin.site.urls)),
@ -123,7 +122,6 @@ urlpatterns = patterns(
url(r'^mlt/(?P<project_slug>[-\w]+)/(?P<filename>.*)$',
'core.views.morelikethis',
name='morelikethis'),
url(r'^websupport/', include('websupport.urls')),
)
@ -131,8 +129,7 @@ if settings.DEBUG:
urlpatterns += patterns(
'', # base view, flake8 complains if it is on the previous line.
url('style-catalog/$',
'django.views.generic.simple.direct_to_template',
{'template': 'style_catalog.html'}),
TemplateView.as_view(template_name='style_catalog.html')),
url(regex='^%s/(?P<path>.*)$' % settings.MEDIA_URL.strip('/'),
view='django.views.static.serve',
kwargs={'document_root': settings.MEDIA_ROOT}),