Просмотр исходного кода

Change username action for users.

Ralfp 12 лет назад
Родитель
Сommit
77a1c51e55

+ 39 - 3
misago/usercp/acl.py

@@ -1,18 +1,47 @@
-from django.utils.translation import ugettext_lazy as _
+from datetime import timedelta
 from django import forms
+from django.utils.translation import ugettext_lazy as _
+from django.utils import timezone
 from misago.acl.builder import BaseACL
 from misago.forms import YesNoSwitch
 
 def make_form(request, role, form):
     if role.token != 'guest':
+        form.base_fields['name_changes_allowed'] = forms.IntegerField(min_value=0,initial=1)
+        form.base_fields['changes_expire'] = forms.IntegerField(min_value=0,initial=0)
         form.base_fields['can_use_signature'] = forms.BooleanField(widget=YesNoSwitch,initial=False,required=False)
         form.layout.append((
-                            _("Signature"),
-                            (('can_use_signature', {'label': _("Can have signature")}),),
+                            _("User Profile"),
+                            (
+                             ('name_changes_allowed', {'label': _("Allowed Username changes number"), 'help_text': _("Enter zero to don't allow users with this role to change their names.")}),
+                             ('changes_expire', {'label': _("Don't count username changes older than"), 'help_text': _("Number of days since name change that makes that change no longer count to limit. For example, if you enter 7 days and set changes limit 3, users with this rank will not be able to make more than three changes in duration of 7 days. Enter zero to make all changes count.")}),
+                             ('can_use_signature', {'label': _("Can have signature")}),
+                             ),
                             ))
 
 
 class UserCPACL(BaseACL):
+    def show_username_change(self):
+        return self.acl['name_changes_allowed'] > 0
+    
+    def changes_expire(self):
+        return self.acl['changes_expire'] > 0
+    
+    def changes_left(self, user):
+        if not self.acl['name_changes_allowed']:
+            return 0
+        
+        if self.acl['changes_expire']:
+            changes_left = self.acl['name_changes_allowed'] - user.namechanges.filter(
+                                                    date__gte=timezone.now() - timedelta(days=self.acl['changes_expire']),
+                                                    ).count()
+        else:
+            changes_left = self.acl['name_changes_allowed'] - user.namechanges.all().count()
+            
+        if changes_left:
+            return changes_left
+        return 0
+    
     def can_use_signature(self):
         return self.acl['signature']
 
@@ -20,8 +49,15 @@ class UserCPACL(BaseACL):
 def build(acl, roles):
     acl.usercp = UserCPACL()
     acl.usercp.acl['signature'] = False
+    acl.usercp.acl['name_changes_allowed'] = 0
+    acl.usercp.acl['changes_expire'] = 0
     
     for role in roles:
         if 'can_use_signature' in role and role['can_use_signature'] > acl.usercp.acl['signature']:
             acl.usercp.acl['signature'] = role['can_use_signature']
 
+        if 'name_changes_allowed' in role and role['name_changes_allowed'] > acl.usercp.acl['name_changes_allowed']:
+            acl.usercp.acl['name_changes_allowed'] = role['name_changes_allowed']
+
+        if 'changes_expire' in role and role['changes_expire'] > acl.usercp.acl['changes_expire']:
+            acl.usercp.acl['changes_expire'] = role['changes_expire']

+ 6 - 0
misago/usercp/models.py

@@ -0,0 +1,6 @@
+from django.db import models
+
+class UsernameChange(models.Model):
+    user = models.ForeignKey('users.User', related_name='namechanges')
+    date = models.DateTimeField()
+    old_username = models.CharField(max_length=255)

+ 8 - 7
misago/usercp/template.py

@@ -11,13 +11,14 @@ def RequestContext(request, context=None):
         usercp_module = import_module(extension + '.usercp')
         try:
             append_links = usercp_module.register_usercp_extension(request)
-            for link in append_links:
-                token = link[0][link[0].find('_') + 1:]
-                context['tabs'].append({
-                                        'route': link[0],
-                                        'active': context['tab'] == token,
-                                        'name': link[1],
-                                        })
+            if append_links:
+                for link in append_links:
+                    token = link[0][link[0].find('_') + 1:]
+                    context['tabs'].append({
+                                            'route': link[0],
+                                            'active': context['tab'] == token,
+                                            'name': link[1],
+                                            })
         except AttributeError:
             pass
     

+ 30 - 0
misago/usercp/username/forms.py

@@ -0,0 +1,30 @@
+from django import forms
+from django.core.exceptions import ValidationError
+from django.utils.translation import ugettext_lazy as _
+from misago.forms import Form
+
+class UsernameChangeForm(Form):
+    username = forms.CharField(max_length=255)
+    error_source = 'username'
+    
+    layout = [
+              [
+               None,
+               [
+                ('username', {'label': _("Change Username to"), 'help_text': _("Enter new desired username.")}),
+                ],
+               ],
+              ]
+    
+    def clean_username(self):
+        org_username = self.request.user.username
+        
+        self.request.user.set_username(self.cleaned_data['username'])
+        if org_username == self.request.user.username:
+            raise ValidationError(_("Your new username is same as current one."))
+        
+        try:
+            self.request.user.full_clean()
+        except ValidationError as e:
+            self.request.user.is_username_valid(e)
+        return self.cleaned_data['username']

+ 2 - 1
misago/usercp/username/usercp.py

@@ -1,4 +1,5 @@
 from django.utils.translation import ugettext_lazy as _
 
 def register_usercp_extension(request):
-    return (('usercp_username', _('Change Username')),)
+    if request.acl.usercp.show_username_change():
+        return (('usercp_username', _('Change Username')),)

+ 41 - 0
misago/usercp/username/views.py

@@ -1,9 +1,50 @@
+from datetime import timedelta
+from django.core.urlresolvers import reverse
+from django.shortcuts import redirect
+from django.utils import timezone
+from django.utils.translation import ugettext as _
 from misago.authn.decorators import block_guest
+from misago.forms import FormLayout
+from misago.messages import Message
 from misago.usercp.template import RequestContext
+from misago.usercp.models import UsernameChange
+from misago.usercp.username.forms import UsernameChangeForm
+from misago.views import error404
 
 @block_guest
 def username(request):
+    if not request.acl.usercp.show_username_change():
+        return error404(request)
+    
+    changes_left = request.acl.usercp.changes_left(request.user)
+    
+    next_change = None
+    if request.acl.usercp.changes_expire() and not changes_left:
+        next_change = request.user.namechanges.filter(
+                                                      date__gte=timezone.now() - timedelta(days=request.acl.usercp.acl['changes_expire']),
+                                                      ).order_by('-date')[0]
+        next_change = next_change.date + timedelta(days=request.acl.usercp.acl['changes_expire'])
+    
+    message = request.messages.get_message('usercp_username')
+    if request.method == 'POST':
+        org_username = request.user.username
+        form = UsernameChangeForm(request.POST, request=request)
+        if form.is_valid():
+            request.user.username = form.cleaned_data['username']
+            request.user.save(force_update=True)
+            request.messages.set_flash(Message(_("Your username has been changed")), 'success', 'usercp_username')
+            request.user.namechanges.create(date=timezone.now(),old_username=org_username)
+            return redirect(reverse('usercp_username'))
+        message = Message(form.non_field_errors()[0], 'error')
+    else:
+        form = UsernameChangeForm(request=request)
+    
     return request.theme.render_to_response('usercp/username.html',
                                             context_instance=RequestContext(request, {
+                                              'message': message,
+                                              'changes_left': changes_left,
+                                              'form': FormLayout(form),
+                                              'next_change': next_change,
+                                              'changes_history': request.user.namechanges.order_by('-date')[:10],
                                               'tab': 'username',
                                              }));

+ 46 - 0
templates/sora/usercp/username.html

@@ -1,6 +1,7 @@
 {% extends "sora/usercp/layout.html" %}
 {% load i18n %}
 {% load url from future %}
+{% import "_forms.html" as form_theme with context %}
 {% import "sora/macros.html" as macros with context %}
 
 {% block title %}{{ macros.page_title(title=_('Change your Username')) }}{% endblock %}
@@ -8,4 +9,49 @@
 {% block action %}
 {{ super() }}
 <h2>{% trans %}Change your Username{% endtrans %}</h2>
+{% if message %}{{ macros.draw_message(message, 'alert-form') }}{% endif %}
+<p class="lead">{% if changes_left > 0 -%}
+{% trans count=changes_left -%}
+You can change your username one more time.
+{%- pluralize -%}
+You can change your username {{ count }} more times.
+{%- endtrans %}
+{%- else -%}
+{% trans %}You have exceeded the maximum number of name changes.{% endtrans %}
+{%- if acl.usercp.changes_expire() -%}
+<br>
+{% trans next_change=next_change|reldate|low %}You will be able to change your username on {{ next_change }}{% endtrans %}
+{%- endif %}
+{%- endif %}</p>
+{% if changes_left > 0 %}
+<form action="{% url 'usercp_username' %}" method="post">
+  {{ form_theme.form_widget(form, width=9) }}
+  <div class="form-actions">
+  	<button name="save" type="submit" class="btn btn-primary">{% trans %}Change Name{% endtrans %}</button>
+  </div>
+</form>
+{% endif %}
+{% if changes_history|length > 0 %}
+<h3>{% trans count=changes_history|length -%}
+Last name changes
+{%- pluralize -%}
+Last {{ count }} name changes
+{%- endtrans %}</h3>
+<table class="table table-striped">
+  <thead>
+    <tr>
+      <th class="span3">{% trans %}Old Name{% endtrans %}</th>
+      <th>{% trans %}Change Date{% endtrans %}</th>
+    </tr>
+  </thead>
+  <tbody>
+    {% for change in changes_history %}
+    <tr>
+      <td><strong>{{ change.old_username }}</strong></td>
+      <td>{{ change.date|reltimesince }}</td>
+    </tr>
+    {% endfor %}
+  </tbody>
+</table>
+{% endif %}
 {% endblock %}