diff --git a/deploy/manage.py b/deploy/manage.py index 3e4eedc..f9726f9 100755 --- a/deploy/manage.py +++ b/deploy/manage.py @@ -1,14 +1,10 @@ #!/usr/bin/env python -from django.core.management import execute_manager -import imp -try: - imp.find_module('settings') # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) - sys.exit(1) - -import settings +import os +import sys if __name__ == "__main__": - execute_manager(settings) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/deploy/search_settings.py b/deploy/search_settings.py index 09ba861..547e657 100644 --- a/deploy/search_settings.py +++ b/deploy/search_settings.py @@ -1,32 +1,32 @@ -# See: http://docs.haystacksearch.org/dev/settings.html for details -# Many of the settings below are just their default values (to be explicit) +SEARCH_ENGINE = None -HAYSTACK_SEARCH_ENGINE = None +try: + import xapian + SEARCH_ENGINE = { + 'default': { + 'ENGINE': 'xapian_backend.XapianEngine', + 'PATH': os.path.join(DATA_DIR, 'xapian_index'), + 'INCLUDE_SPELLING': True, + 'BATCH_SIZE': 100, + }, + } -if HAYSTACK_SEARCH_ENGINE is None: - try: - import xapian - HAYSTACK_SEARCH_ENGINE = 'xapian' - HAYSTACK_XAPIAN_PATH = os.path.join(DATA_DIR, 'xapian_index') - except ImportError: - pass +except ImportError: + import whoosh + SEARCH_ENGINE = { + 'default': { + 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', + 'PATH': os.path.join(DATA_DIR, 'whoosh_index'), + 'STORAGE': 'file', + 'POST_LIMIT': 128 * 1024 * 1024, + 'INCLUDE_SPELLING': True, + 'BATCH_SIZE': 100, + }, + } -if HAYSTACK_SEARCH_ENGINE is None: - try: - import whoosh - HAYSTACK_SEARCH_ENGINE = 'whoosh' - HAYSTACK_WHOOSH_PATH = os.path.join(DATA_DIR, 'whoosh_index') - except ImportError: - pass - -if HAYSTACK_SEARCH_ENGINE is None: - raise RuntimeError("Neither xapian nor whoosh is installed") - -HAYSTACK_SITECONF = 'scipy_central.search_sites' +HAYSTACK_CONNECTIONS = SEARCH_ENGINE HAYSTACK_DEFAULT_OPERATOR = 'AND' -HAYSTACK_INCLUDE_SPELLING = True HAYSTACK_SEARCH_RESULTS_PER_PAGE = SPC['entries_per_page'] -HAYSTACK_BATCH_SIZE = 100 HAYSTACK_ITERATOR_LOAD_PER_QUERY = 10 HAYSTACK_LIMIT_TO_REGISTERED_MODELS = True HAYSTACK_SILENTLY_FAIL = True diff --git a/deploy/settings.py b/deploy/settings.py index 8626465..010b266 100644 --- a/deploy/settings.py +++ b/deploy/settings.py @@ -69,11 +69,6 @@ # Example: "http://media.lawrence.com/static/" STATIC_URL = '/static/' -# URL prefix for admin static files -- CSS, JavaScript and images. -# Make sure to use a trailing slash. -# Examples: "http://foo.com/static/admin/", "/static/admin/". -ADMIN_MEDIA_PREFIX = '/static/admin/' - # Additional locations of static files STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'media'), @@ -108,7 +103,10 @@ 'django.contrib.messages.middleware.MessageMiddleware', ) -ROOT_URLCONF = 'urls' +ROOT_URLCONF = 'deploy.urls' + +# Python dotted path to the WSGI application used by Django's runserver. +WSGI_APPLICATION = 'deploy.wsgi.application' TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". @@ -154,8 +152,6 @@ 'scipy_central.feeds', ) -# Authentication related: -AUTH_PROFILE_MODULE = 'person.UserProfile' # Link the user is redirected to if not logged in and they try to perform # a function that only logged in users can do LOGIN_URL = '/user/login/' @@ -260,6 +256,12 @@ }, }, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'handlers': { 'null': { 'level':'DEBUG', @@ -274,6 +276,7 @@ 'mail_admins': { 'level': 'ERROR', + 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' }, diff --git a/deploy/templates/404.html b/deploy/templates/404.html index 798f8b9..c9edbfe 100644 --- a/deploy/templates/404.html +++ b/deploy/templates/404.html @@ -12,6 +12,6 @@

404


-

Try searching for it on the main page.

+

Try searching for it on the main page.

{% endblock %} diff --git a/deploy/templates/base-includes/footer-outside.html b/deploy/templates/base-includes/footer-outside.html index 78dcd25..ca22e23 100644 --- a/deploy/templates/base-includes/footer-outside.html +++ b/deploy/templates/base-includes/footer-outside.html @@ -2,11 +2,11 @@
\ No newline at end of file diff --git a/deploy/templates/base-includes/rightsidebar.html b/deploy/templates/base-includes/rightsidebar.html index d48659f..2a3366f 100644 --- a/deploy/templates/base-includes/rightsidebar.html +++ b/deploy/templates/base-includes/rightsidebar.html @@ -14,14 +14,14 @@ {% if user.id == item.created_by.id %} {% endif %} {% else %} {% endif %} @@ -30,7 +30,7 @@ {% if item.entry.sub_type == "snippet" %} {% endif %} @@ -55,7 +55,7 @@ @@ -64,16 +64,16 @@ {% for item in "authors"|top_authors:8 %}
  • {{ item.user.username }}
  • {% endfor %} -
  • Show All
  • +
  • Show All
  • diff --git a/deploy/templates/registration/activate.html b/deploy/templates/registration/activate.html index 34707ef..7e870c8 100644 --- a/deploy/templates/registration/activate.html +++ b/deploy/templates/registration/activate.html @@ -9,6 +9,6 @@

    Account activation failed

    You supplied an invalid activation key: {{activation_key}}

    -

    Please request a new password reset key

    +

    Please request a new password reset key

    {% endblock %} diff --git a/deploy/templates/registration/activation_complete.html b/deploy/templates/registration/activation_complete.html index 9ac330c..190d35c 100644 --- a/deploy/templates/registration/activation_complete.html +++ b/deploy/templates/registration/activation_complete.html @@ -10,7 +10,7 @@

    Any previous code or links you have submitted will now be available for other users to see.

    -

    Please sign in and edit your profile.

    +

    Please sign in and edit your profile.

    {% endblock %} diff --git a/deploy/templates/registration/login.html b/deploy/templates/registration/login.html index 5cb5457..c67ddd3 100644 --- a/deploy/templates/registration/login.html +++ b/deploy/templates/registration/login.html @@ -12,7 +12,7 @@

    Sign In

    -
    + {% csrf_token %} {% if form.non_field_errors %}
    @@ -46,8 +46,8 @@

    Sign In

    {% endif %} - Register -

    Forgot your username or password?

    + Register +

    Forgot your username or password?

    diff --git a/deploy/templates/registration/logout.html b/deploy/templates/registration/logout.html index 02d3164..cca061f 100644 --- a/deploy/templates/registration/logout.html +++ b/deploy/templates/registration/logout.html @@ -7,7 +7,7 @@

    You have been Signed out

    -

    Sign in again or go to the home page

    +

    Sign in again or go to the home page

    {% endblock %} \ No newline at end of file diff --git a/deploy/templates/registration/password_change_done.html b/deploy/templates/registration/password_change_done.html index a6f3665..1e85de2 100644 --- a/deploy/templates/registration/password_change_done.html +++ b/deploy/templates/registration/password_change_done.html @@ -7,6 +7,6 @@

    Password successfully changed

    -

    Your password has been changed. Continue by updating your public profile

    +

    Your password has been changed. Continue by updating your public profile

    {% endblock %} \ No newline at end of file diff --git a/deploy/templates/registration/password_change_form.html b/deploy/templates/registration/password_change_form.html index 5d36ea1..efab6be 100644 --- a/deploy/templates/registration/password_change_form.html +++ b/deploy/templates/registration/password_change_form.html @@ -47,7 +47,7 @@

    Change your password

    {% endif %} -

    Rather reset your password by email?

    +

    Rather reset your password by email?

    diff --git a/deploy/templates/registration/password_reset_confirm.html b/deploy/templates/registration/password_reset_confirm.html index d0a45a7..81f377e 100644 --- a/deploy/templates/registration/password_reset_confirm.html +++ b/deploy/templates/registration/password_reset_confirm.html @@ -58,7 +58,7 @@

    Create a new password

    Password reset unsuccessful

    -

    The password reset link was invalid, possibly because it has already been used. Please request a new password reset.

    +

    The password reset link was invalid, possibly because it has already been used. Please request a new password reset.

    {% endif %} diff --git a/deploy/templates/registration/registration_closed.html b/deploy/templates/registration/registration_closed.html index 45c0a06..519dd41 100644 --- a/deploy/templates/registration/registration_closed.html +++ b/deploy/templates/registration/registration_closed.html @@ -5,9 +5,9 @@ {% block content %}
    -

    New accounts are currently not permitted on SciPy Central

    +

    New accounts are currently not permitted on SciPy Central

    -

    Please read our About page for more information

    +

    Please read our About page for more information

    {% endblock %} diff --git a/deploy/templates/search/includes/main-search-box.html b/deploy/templates/search/includes/main-search-box.html index 8a05bfc..a6a489f 100644 --- a/deploy/templates/search/includes/main-search-box.html +++ b/deploy/templates/search/includes/main-search-box.html @@ -1,6 +1,6 @@ diff --git a/deploy/urls.py b/deploy/urls.py index 64cdbaf..6419a0d 100644 --- a/deploy/urls.py +++ b/deploy/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import patterns, include, url +from django.conf.urls import patterns, include, url from django.conf import settings # Uncomment the next two lines to enable the admin: diff --git a/deploy/wsgi.py b/deploy/wsgi.py new file mode 100644 index 0000000..0b7699a --- /dev/null +++ b/deploy/wsgi.py @@ -0,0 +1,20 @@ +""" +WSGI config for SciPyCentral project. +""" +import os + +# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks +# if running multiple sites in the same mod_wsgi process. To fix this, use +# mod_wsgi daemon mode with each site in its own daemon process, or use +# os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings" +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + +# This application object is used by any WSGI server configured to use this +# file. This includes Django's development server, if the WSGI_APPLICATION +# setting points here. +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() + +# Apply WSGI middleware here. +# from helloworld.wsgi import HelloWorldApplication +# application = HelloWorldApplication(application) diff --git a/requirements.txt b/requirements.txt index 1012dae..a4b932b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -Django >=1.4,<1.5 -django-haystack <2.0.0 -Whoosh <2.5.0 +Django==1.5 +django-haystack==2.1.0 +Whoosh==2.5.1 South -django-registration ==0.8 +django-registration==1.0 django-widget-tweaks Sphinx Pygments diff --git a/scipy_central/feeds/feeds.py b/scipy_central/feeds/feeds.py index 8d6f3ec..718a50f 100644 --- a/scipy_central/feeds/feeds.py +++ b/scipy_central/feeds/feeds.py @@ -1,8 +1,8 @@ # django imports -from django.template.defaultfilters import slugify from django.shortcuts import get_object_or_404 from django.contrib.syndication.views import Feed from django.utils.feedgenerator import Atom1Feed +from django.utils.text import slugify # scipycentral imports from scipy_central.submission.models import Submission, Revision diff --git a/scipy_central/feeds/urls.py b/scipy_central/feeds/urls.py index 6449618..946715b 100644 --- a/scipy_central/feeds/urls.py +++ b/scipy_central/feeds/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import patterns, url +from django.conf.urls import patterns, url import feeds urlpatterns = patterns('scipy_central.feeds.views', diff --git a/scipy_central/pages/templates/pages/about-licenses.html b/scipy_central/pages/templates/pages/about-licenses.html index d446b2d..906c120 100644 --- a/scipy_central/pages/templates/pages/about-licenses.html +++ b/scipy_central/pages/templates/pages/about-licenses.html @@ -48,7 +48,7 @@

    I want to submit code, what can/can't I do?

    described above. If you prefer a different license for your code, please host the code on another website (e.g. GitHub, BitBucket, Google Code), and feel free to create a link submission, rather than + {% url 'spc-new-submission' item_type='link' %}">create a link submission, rather than a code submission.

    Code snippets must use the CC0 license, since it does not require diff --git a/scipy_central/pages/templates/pages/front-page.html b/scipy_central/pages/templates/pages/front-page.html index 421acec..184119b 100644 --- a/scipy_central/pages/templates/pages/front-page.html +++ b/scipy_central/pages/templates/pages/front-page.html @@ -24,7 +24,7 @@

    Welcome. SciPy Central is a collection o {% endfor %} @@ -37,7 +37,7 @@

    Welcome. SciPy Central is a collection o {% endwith %} {% endfor %} diff --git a/scipy_central/pages/templates/pages/make-submission-buttons.html b/scipy_central/pages/templates/pages/make-submission-buttons.html index ac45378..92b8487 100644 --- a/scipy_central/pages/templates/pages/make-submission-buttons.html +++ b/scipy_central/pages/templates/pages/make-submission-buttons.html @@ -1,7 +1,7 @@ {# DEPRRCATED #}
    -
    + {% csrf_token %}
    • diff --git a/scipy_central/pages/urls.py b/scipy_central/pages/urls.py index 5342267..86a3ac1 100644 --- a/scipy_central/pages/urls.py +++ b/scipy_central/pages/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import patterns, url +from django.conf.urls import patterns, url urlpatterns = patterns('scipy_central.pages.views', diff --git a/scipy_central/person/admin.py b/scipy_central/person/admin.py index 25c7142..9108a5c 100644 --- a/scipy_central/person/admin.py +++ b/scipy_central/person/admin.py @@ -1,22 +1,25 @@ +from django.db.models import signals from django.contrib import admin -from models import User, UserProfile +from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.models import User from django.contrib.auth.signals import user_logged_in -from django.db.models import signals + +# scipy_central imports +import models, views # 3rd-party ``registration`` app: connect up the signals -import views from registration.signals import user_registered, user_activated -class UserProfileAdmin(admin.ModelAdmin): - list_display = ('pk', 'user', 'is_validated', 'affiliation', 'country', - 'reputation', 'bio', 'uri', 'openid', - 'contactable_via_site', 'allow_user_to_email') - list_display_links = ('user',) - list_per_page = 1000 - ordering = ('user',) - -admin.site.register(UserProfile, UserProfileAdmin) +class UserProfileInline(admin.StackedInline): + model = models.UserProfile + can_delete = False + verbose_name_plural = 'profile' + +class UserAdmin(UserAdmin): + inlines = (UserProfileInline, ) +admin.site.unregister(User) +admin.site.register(User, UserAdmin) # Hook up the signals here. Doing it in models.py results in circular imports. user_registered.connect(views.create_new_account) diff --git a/scipy_central/person/management.py b/scipy_central/person/management.py index fdd06df..7c9da26 100644 --- a/scipy_central/person/management.py +++ b/scipy_central/person/management.py @@ -12,19 +12,18 @@ def validate_superuser(app, created_models, verbosity, **kwargs): #print(app_label, app_name, app_models) if app_label == 'auth': - from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db.models import get_model from django.contrib.auth.models import User - user_class = get_model(*settings.AUTH_PROFILE_MODULE.split('.', 2)) - if not user_class: - raise ImproperlyConfigured('Could not get custom user model') + user_profile = get_model("person", "UserProfile") + if not user_profile: + raise ImproperlyConfigured('Could not get user profile model') users = User.objects.all() if len(users)==1 and users[0].is_superuser: - print('Validating superuser in the subclassed user table') + print('Validating superuser in the user profile table') - user = user_class.objects.create(user=users[0]) + user = user_profile.objects.create(user=users[0]) user.is_validated = True user.save() diff --git a/scipy_central/person/models.py b/scipy_central/person/models.py index ca5f48f..810c815 100644 --- a/scipy_central/person/models.py +++ b/scipy_central/person/models.py @@ -1,72 +1,8 @@ -from django.contrib.auth.models import User from django.db import models +from django.contrib.auth.models import User from scipy_central.utils import unique_slugify -from registration.backends.default import DefaultBackend -from django.contrib.sites.models import Site -from django.contrib.sites.models import RequestSite -from registration import signals -from registration.models import RegistrationProfile import hashlib -class SciPyRegistrationBackend(DefaultBackend): - - def register(self, request, **kwargs): - """ - Given a username, email address and password, register a new - user account, which will initially be inactive. - - Along with the new ``User`` object, a new - ``registration.models.RegistrationProfile`` will be created, - tied to that ``User``, containing the activation key which - will be used for this account. - - An email will be sent to the supplied email address; this - email should contain an activation link. The email will be - rendered using two templates. See the documentation for - ``RegistrationProfile.send_activation_email()`` for - information about these templates and the contexts provided to - them. - - After the ``User`` and ``RegistrationProfile`` are created and - the activation email is sent, the signal - ``registration.signals.user_registered`` will be sent, with - the new ``User`` as the keyword argument ``user`` and the - class of this backend as the sender. - - """ - username, email, password = kwargs['username'], kwargs['email'], kwargs['password1'] - if Site._meta.installed: - site = Site.objects.get_current() - else: - site = RequestSite(request) - - # We are creating a user with the same email address. We have already - # verified in ``forms.py`` that this isn't a mistake. Go ahead and pull - # the existing user from the DB and return that user instead. - if User.objects.filter(email__iexact=email): - new_user = User.objects.filter(email__iexact=email)[0] - new_user.username = username - new_user.set_password(password) - new_user.save() - - # Resave their profile also (updates the slug) - new_user_profile = UserProfile.objects.get(user=new_user) - new_user_profile.save() - - # Complete the activation email part - registration_profile = RegistrationProfile.objects.create_profile(new_user) - registration_profile.send_activation_email(site) - else: - - new_user = RegistrationProfile.objects.create_inactive_user(\ - username, email,password, site) - - signals.user_registered.send(sender=self.__class__, - user=new_user, - request=request) - return new_user - - class Country(models.Model): """ Model for a country """ # Country's official name @@ -82,8 +18,21 @@ def __unicode__(self): class UserProfile(models.Model): - # See https://docs.djangoproject.com/en/1.3/topics/auth/ + """ + Profile settings for `django.contrib.auth.models.User` + We are not using django-1.5 User profile extension feature since + the below settings don't belong to "authentication" part. + + The UserProfile for every `User` object is created upon + receiving signals mentioned in `models.py` + For future (note): + The `openid` field can't be used for authentication + in case if we support openid in future! + + Custom user model inherited from Abstract User class + has to be used + """ user = models.OneToOneField(User, unique=True, related_name="profile") # Slug field diff --git a/scipy_central/person/search_indexes.py b/scipy_central/person/search_indexes.py index 78f7e66..19e0a5f 100644 --- a/scipy_central/person/search_indexes.py +++ b/scipy_central/person/search_indexes.py @@ -1,9 +1,9 @@ -from haystack import indexes, site +from haystack import indexes from models import UserProfile # SearchIndex object for each revision in the database -class UserProfileIndex(indexes.RealTimeSearchIndex): +class UserProfileIndex(indexes.SearchIndex, indexes.Indexable): # The main field to search in: see template search/indexes/person/userprofile_text.txt text = indexes.CharField(document=True, use_template=True) @@ -14,7 +14,7 @@ class UserProfileIndex(indexes.RealTimeSearchIndex): def get_model(self): return UserProfile - def index_queryset(self): + def index_queryset(self, **kwargs): # The ``Revision`` model has its own managers that does the right # thing in calling ``all()``. return self.get_model().objects.filter(is_validated=True) @@ -27,4 +27,3 @@ def prepare(self, object): return self.prepared_data -site.register(UserProfile, UserProfileIndex) diff --git a/scipy_central/person/templates/person/profile.html b/scipy_central/person/templates/person/profile.html index ac8966d..3880447 100644 --- a/scipy_central/person/templates/person/profile.html +++ b/scipy_central/person/templates/person/profile.html @@ -56,7 +56,7 @@

      {{theuser.username}}

      {% for tag in theuser.profile.interests.all %}
    • - {{tag.name}} + {{tag.name}}
    • {% endfor %}
    @@ -80,8 +80,8 @@

    {{theuser.username}}

    Settings diff --git a/scipy_central/person/urls.py b/scipy_central/person/urls.py index 8d3d1d8..2a3bc76 100644 --- a/scipy_central/person/urls.py +++ b/scipy_central/person/urls.py @@ -1,16 +1,19 @@ -from django.conf.urls.defaults import patterns, url -from registration.views import register -from forms import SignUpForm -#from models import SciPyRegistrationBackend +from django.conf.urls import patterns, url, include +from views import SciPyRegistrationBackend urlpatterns = patterns('scipy_central.person.views', # Just override ``registration`` app's URL for registration so that we # can provide our own form class. Everything else from that app's default # settings are OK for our site. - url(r'^register/$', register, - {'backend': 'scipy_central.person.models.SciPyRegistrationBackend', - 'form_class': SignUpForm}, - name='registration_register'), + + # NOTE: the {% url 'registration_register' %} template tag technically + # never matches with the below url Since the overridden url and built-in url + # happens to be same, it does not matter and we don't have to care! + # If we want to change the below url from register/ to something else, + # `name` argument has to be changed along with template tags in all templates + url(r'^register/$', SciPyRegistrationBackend.as_view(), name='registration_register'), + + url(r'^', include('registration.backends.default.urls')), # The page where the user is redirected to on sign in url(r'^profile/$', 'sign_in_landing', name='spc-after-sign-in'), diff --git a/scipy_central/person/views.py b/scipy_central/person/views.py index 86d06a0..13a9f4e 100644 --- a/scipy_central/person/views.py +++ b/scipy_central/person/views.py @@ -1,4 +1,7 @@ from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from django.contrib.sites.models import Site +from django.contrib.sites.models import RequestSite from django.shortcuts import render_to_response, redirect from django.template import RequestContext from django.core.exceptions import ObjectDoesNotExist @@ -6,7 +9,6 @@ from django.template.loader import render_to_string from django.db.utils import IntegrityError - # Imports from other SciPy Central apps from scipy_central.pages.views import page_404_error from scipy_central.submission.models import Revision @@ -15,9 +17,16 @@ from scipy_central.tagging.views import get_and_create_tags from scipy_central.pagehit.views import create_hit +# 3rd party imports +from registration.backends.default.views import RegistrationView +from registration.models import RegistrationProfile +from registration import signals + +# local package imports import models import forms +# python import random import logging @@ -128,13 +137,13 @@ def profile_page(request, slug=None, user_id=None): """ try: if user_id: - the_user = models.User.objects.get(id=user_id) + the_user = User.objects.get(id=user_id) if the_user.is_active: return redirect(profile_page, the_user.profile.slug) elif slug is None: the_user = request.user else: - the_user = models.User.objects.get(profile__slug=slug) + the_user = User.objects.get(profile__slug=slug) except ObjectDoesNotExist: return page_404_error(request, 'No profile for that user.') @@ -173,7 +182,7 @@ def create_new_account_internal(email): We assume the ``email`` has already been validated as an email address. """ # First check if that email address have been used; return ``False`` - previous = models.User.objects.filter(email=email) + previous = User.objects.filter(email=email) if len(previous) > 0: return previous[0] @@ -182,7 +191,7 @@ def create_new_account_internal(email): for i in range(50)]) username = 'Unvalidated %s-%s' % (email.split('@')[0], temp_password[2:6]) - new_user = models.User.objects.create(username=username, email=email) + new_user = User.objects.create(username=username, email=email) new_user.set_password(temp_password) new_user.is_active = False @@ -219,3 +228,63 @@ def account_activation(user, **kwargs): rev.is_displayed = True rev.validation_hash = None rev.save() + +class SciPyRegistrationBackend(RegistrationView): + + form_class = forms.SignUpForm + + def register(self, request, **kwargs): + """ + Given a username, email address and password, register a new + user account, which will initially be inactive. + + Along with the new ``User`` object, a new + ``registration.models.RegistrationProfile`` will be created, + tied to that ``User``, containing the activation key which + will be used for this account. + + An email will be sent to the supplied email address; this + email should contain an activation link. The email will be + rendered using two templates. See the documentation for + ``RegistrationProfile.send_activation_email()`` for + information about these templates and the contexts provided to + them. + + After the ``User`` and ``RegistrationProfile`` are created and + the activation email is sent, the signal + ``registration.signals.user_registered`` will be sent, with + the new ``User`` as the keyword argument ``user`` and the + class of this backend as the sender. + + """ + username, email, password = kwargs['username'], kwargs['email'], kwargs['password1'] + if Site._meta.installed: + site = Site.objects.get_current() + else: + site = RequestSite(request) + + # We are creating a user with the same email address. We have already + # verified in ``forms.py`` that this isn't a mistake. Go ahead and pull + # the existing user from the DB and return that user instead. + if User.objects.filter(email__iexact=email): + new_user = User.objects.filter(email__iexact=email)[0] + new_user.username = username + new_user.set_password(password) + new_user.save() + + # Resave their profile also (updates the slug) + new_user_profile = UserProfile.objects.get(user=new_user) + new_user_profile.save() + + # Complete the activation email part + registration_profile = RegistrationProfile.objects.create_profile(new_user) + registration_profile.send_activation_email(site) + else: + + new_user = RegistrationProfile.objects.create_inactive_user(\ + username, email,password, site) + + signals.user_registered.send(sender=self.__class__, + user=new_user, + request=request) + return new_user diff --git a/scipy_central/rest_comments/urls.py b/scipy_central/rest_comments/urls.py index 533225f..4456925 100644 --- a/scipy_central/rest_comments/urls.py +++ b/scipy_central/rest_comments/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import url, patterns +from django.conf.urls import url, patterns urlpatterns = patterns('scipy_central.rest_comments.views', diff --git a/scipy_central/screenshot/urls.py b/scipy_central/screenshot/urls.py index 3b67840..938dd83 100644 --- a/scipy_central/screenshot/urls.py +++ b/scipy_central/screenshot/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import url, patterns +from django.conf.urls import url, patterns urlpatterns = patterns('scipy_central.screenshot.views', diff --git a/scipy_central/submission/models.py b/scipy_central/submission/models.py index cc339c9..c4ee3bc 100644 --- a/scipy_central/submission/models.py +++ b/scipy_central/submission/models.py @@ -2,11 +2,11 @@ from django.db import models from django.conf import settings +from django.contrib.auth.models import User from django.core.urlresolvers import reverse -from django.template.defaultfilters import slugify -from scipy_central.person.models import User from scipy_central.utils import ensuredir +from django.utils.text import slugify class Module(models.Model): """ diff --git a/scipy_central/submission/search_indexes.py b/scipy_central/submission/search_indexes.py index 918a4d3..033ec82 100644 --- a/scipy_central/submission/search_indexes.py +++ b/scipy_central/submission/search_indexes.py @@ -1,9 +1,9 @@ -from haystack import indexes, site +from haystack import indexes from models import Revision # SearchIndex object for each revision in the database -class RevisionIndex(indexes.RealTimeSearchIndex): +class RevisionIndex(indexes.SearchIndex, indexes.Indexable): # The main field to search in: see template search/indexes/submission/revision_text.txt text = indexes.CharField(document=True, use_template=True)#model_attr='description') @@ -20,7 +20,7 @@ class RevisionIndex(indexes.RealTimeSearchIndex): def get_model(self): return Revision - def index_queryset(self): + def index_queryset(self, **kwargs): # The ``Revision`` model has its own managers that does the right # thing in calling ``all()``. return self.get_model().objects.all() @@ -33,4 +33,3 @@ def prepare(self, object): return self.prepared_data -site.register(Revision, RevisionIndex) diff --git a/scipy_central/submission/templates/submission/item.html b/scipy_central/submission/templates/submission/item.html index 1209c36..eebb16d 100644 --- a/scipy_central/submission/templates/submission/item.html +++ b/scipy_central/submission/templates/submission/item.html @@ -30,7 +30,7 @@

    {{item.title}}

    Submitted by
    -
    {% if item.entry.created_by.profile.is_validated %}{{item.entry.created_by.username}} on {% if item.entry.date_created %}{{item.entry.date_created|naturalday:"d F Y"}}{% else %}today{% endif %}{% else %}Your name will be here once you validate yourself by email{% endif %}
    +
    {% if item.entry.created_by.profile.is_validated %}{{item.entry.created_by.username}} on {% if item.entry.date_created %}{{item.entry.date_created|naturalday:"d F Y"}}{% else %}today{% endif %}{% else %}Your name will be here once you validate yourself by email{% endif %}
    {% if item.entry.sub_type == "link" %}
    Link
    @@ -43,7 +43,7 @@

    {{item.title}}

    {% if preview %} Links to the ZIP file contents will appear here {% else %} - File + File {% endif %} {% endif %} @@ -54,7 +54,7 @@

    {{item.title}}

    {% if preview %} Links to the ZIP file contents will appear here {% else %} - All files + All files {% endif %} {% endif %} @@ -70,7 +70,7 @@

    {{item.title}}

    Updated by
    - {% if item.created_by.profile.is_validated %}{{item.created_by.username}}{% else %}Unvalidated user{% endif %} on {% if item.date_created %}{{item.date_created|naturalday:"d F Y"}}{% else %}today{% endif %} + {% if item.created_by.profile.is_validated %}{{item.created_by.username}}{% else %}Unvalidated user{% endif %} on {% if item.date_created %}{{item.date_created|naturalday:"d F Y"}}{% else %}today{% endif %}
    {% endif %} @@ -78,7 +78,7 @@

    {{item.title}}

    diff --git a/scipy_central/submission/templates/submission/new-item.html b/scipy_central/submission/templates/submission/new-item.html index 7da1130..a11db50 100644 --- a/scipy_central/submission/templates/submission/new-item.html +++ b/scipy_central/submission/templates/submission/new-item.html @@ -25,7 +25,7 @@ }) .autocomplete({ source: function( request, response ) { - $.getJSON( "{% url spc-tagging-ajax %}", { + $.getJSON( "{% url 'spc-tagging-ajax' %}", { term: extractLast( request.term ) }, response ); }, @@ -56,9 +56,9 @@

    -{% url spc-new-submission item_type='snippet' as ref_url1 %} -{% url spc-new-submission item_type='link' as ref_url2 %} -{% url spc-new-submission item_type='package' as ref_url3 %} +{% url 'spc-new-submission' item_type='snippet' as ref_url1 %} +{% url 'spc-new-submission' item_type='link' as ref_url2 %} +{% url 'spc-new-submission' item_type='package' as ref_url3 %} {% if request.path == ref_url1 %}Snippet Submission {% elif request.path == ref_url2 %}Link Submission {% elif request.path == ref_url3 %}Package Submission @@ -100,7 +100,7 @@

    Upload Image
    @@ -123,7 +123,7 @@

    var options = { target: '#spc-item-upload-output-ajax-adds-it', success: function() { $('#spc-item-upload-output-ajax-adds-it').fadeIn('slow'); }, - url: '{% url spc-screenshot-add %}', + url: '{% url "spc-screenshot-add" %}', type: 'post', clearForm: true, resetForm: true, diff --git a/scipy_central/submission/templates/submission/show-tag-cloud.html b/scipy_central/submission/templates/submission/show-tag-cloud.html index 99d4e8f..bd9c645 100644 --- a/scipy_central/submission/templates/submission/show-tag-cloud.html +++ b/scipy_central/submission/templates/submission/show-tag-cloud.html @@ -8,7 +8,7 @@

    All tags

    {% for item in "submission.TagCreation"|cloud:0 %} - {{item.tag.name}} + {{item.tag.name}} {% endfor %}
    {% endblock %} diff --git a/scipy_central/submission/templates/submission/show-top-contributors.html b/scipy_central/submission/templates/submission/show-top-contributors.html index 40972dd..bcd7a85 100644 --- a/scipy_central/submission/templates/submission/show-top-contributors.html +++ b/scipy_central/submission/templates/submission/show-top-contributors.html @@ -38,7 +38,7 @@
      {#The ``entry`` objects must be from the ``submission.Revision`` class #} {% for entry in entries.object_list %} -
    • {{entry.username}} +
    • {{entry.username}} diff --git a/scipy_central/submission/templates/submission/thank-user.html b/scipy_central/submission/templates/submission/thank-user.html index 8f59958..fbb6580 100644 --- a/scipy_central/submission/templates/submission/thank-user.html +++ b/scipy_central/submission/templates/submission/thank-user.html @@ -10,7 +10,7 @@

      {{extra_message|safe}} -

      Go back to the main page. +

      Go back to the main page.

    {% endblock %} diff --git a/scipy_central/submission/urls.py b/scipy_central/submission/urls.py index 25e8c43..c72bd74 100644 --- a/scipy_central/submission/urls.py +++ b/scipy_central/submission/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import url, patterns +from django.conf.urls import url, patterns urlpatterns = patterns('scipy_central.submission.views', diff --git a/scipy_central/submission/views.py b/scipy_central/submission/views.py index c519996..8fbfbdb 100644 --- a/scipy_central/submission/views.py +++ b/scipy_central/submission/views.py @@ -3,7 +3,6 @@ from django.template import RequestContext from django.conf import settings from django.core.exceptions import ObjectDoesNotExist -from django.template.defaultfilters import slugify from django.template.loader import render_to_string from django import template from django.contrib.auth.decorators import login_required @@ -11,6 +10,7 @@ from django.utils.hashcompat import sha_constructor from django.core.files.uploadedfile import UploadedFile from django.utils.encoding import force_unicode, smart_str +from django.utils.text import slugify # Imports from this app and other SPC apps from scipy_central.person.views import create_new_account_internal @@ -589,7 +589,7 @@ def new_or_edit_submission(request, item_type, bound_form=False, submission=None context['finish_button_text'] = 'Finish submission' # %% is required in below string to correctly format html = ("""
    - \n {%% csrf_token %%}\n {{item.as_hidden}} diff --git a/scipy_central/tagging/models.py b/scipy_central/tagging/models.py index 3c1d8a5..bbdf88a 100644 --- a/scipy_central/tagging/models.py +++ b/scipy_central/tagging/models.py @@ -1,5 +1,5 @@ from django.db import models -from django.template.defaultfilters import slugify +from django.utils.text import slugify import logging logger = logging.getLogger('scipycentral') diff --git a/scipy_central/tagging/tests.py b/scipy_central/tagging/tests.py index c6008e3..e6c33ce 100644 --- a/scipy_central/tagging/tests.py +++ b/scipy_central/tagging/tests.py @@ -13,13 +13,13 @@ def test_adding_repeated_tag(self): """ # Always use ``get_or_create(...)`` rather than relying on # ``create(...)`` to return a valid tag. - t1, _ = Tag.objects.get_or_create(name='testing tag') - t2, _ = Tag.objects.get_or_create(name='testing tag') + t1, _ = Tag.objects.get_or_create(name=u'testing tag') + t2, _ = Tag.objects.get_or_create(name=u'testing tag') self.assertEqual(t1.id, t2.id) def unicode_tags(self): self.assertRaises(ValidationError, Tag.objects.get_or_create, - name='さようなら') + name=u'さようなら') class TagParsing(TestCase): diff --git a/scipy_central/tagging/urls.py b/scipy_central/tagging/urls.py index c633b97..017b911 100644 --- a/scipy_central/tagging/urls.py +++ b/scipy_central/tagging/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import url, patterns +from django.conf.urls import url, patterns urlpatterns = patterns('scipy_central.tagging.views', diff --git a/scipy_central/tagging/views.py b/scipy_central/tagging/views.py index 21201f2..3a6711c 100644 --- a/scipy_central/tagging/views.py +++ b/scipy_central/tagging/views.py @@ -1,7 +1,7 @@ from django.http import HttpResponse from django.utils import simplejson -from django.template.defaultfilters import slugify from django.utils.encoding import force_unicode +from django.utils.text import slugify from django.core.exceptions import ValidationError import models diff --git a/scipy_central/urls.py b/scipy_central/urls.py index 323d6ae..a7d0f1b 100644 --- a/scipy_central/urls.py +++ b/scipy_central/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import url, include, patterns +from django.conf.urls import url, include, patterns urlpatterns = patterns('scipy_central', # NOTE: internal name for front page (defined in scipy_central.pages.urls) @@ -7,7 +7,7 @@ # Major pages in the site: front page, about page, search, etc url(r'', include('scipy_central.pages.urls')), - # User authentication and profile viewing. + # User registration, authentication and profile viewing. url(r'^user/', include('scipy_central.person.urls'), ), # Submissions: new and existing, including previous revisions @@ -16,11 +16,6 @@ # reST comment converted to HTML url(r'rest/', include('scipy_central.rest_comments.urls')), - # Django-registration: new accounts, password resets, etc - # NOTE: the default backend is overriden ONLY for new account registration - # in scipy_central.person.urls - (r'^user/', include('registration.backends.default.urls')), - # Tagging (r'^tagging/', include('scipy_central.tagging.urls')), diff --git a/scipy_central/utils/__init__.py b/scipy_central/utils/__init__.py index 3932ab6..6d55095 100644 --- a/scipy_central/utils/__init__.py +++ b/scipy_central/utils/__init__.py @@ -1,4 +1,4 @@ -from django.template.defaultfilters import slugify +from django.utils.text import slugify from django.conf import settings from django.core.mail import send_mail, BadHeaderError from django.core.paginator import Paginator, InvalidPage, EmptyPage