freehg / repos / forms.py

from django import newforms as forms

import re

from freehg.repos.models import Repo
from django.contrib.auth.models import User
from django.contrib.auth import authenticate

username_re = re.compile(r'^\w+$')

class NewRepoForm(forms.Form):
    user = None
    reponame = forms.CharField(max_length=30,
            widget=forms.TextInput(attrs={'class': 'required title'}),
            label=u"Repository Name", help_text=u"the name used in the url")
    long_name = forms.CharField(max_length=50, required=False,
            label=u"Aesthetic Name",
            widget=forms.TextInput(attrs={'class': 'required text'}),
            help_text=u"optional version of the name fit for human consumption")
    description = forms.CharField(max_length=5000, required=False,
            widget=forms.Textarea())

    def clean_reponame(self):
        reponame = self.cleaned_data.get('reponame', None)
        if reponame:
            reponame = reponame.lower()
            if not re.search(r'^\w(\w|-|\.)+\w$', reponame):
                msg = (u'Repository names can only contain letters, ' +
                       u'numbers, underscores, dashes and periods. ' +
                       u'They must begin and end with a letter or number.')
                raise forms.ValidationError(msg)
            if self.user:
                try:
                    repo = self.user.repo_set.get(name__exact=reponame)
                except Repo.DoesNotExist:
                    return reponame
                raise forms.ValidationError(
                        u'You already have a repository with this name.')

    def create_repo(self):
        """
        Creates a new repository, but doesn't save it.

        This method assumes that self.user is a valid user.
        """
        return self.user.repo_set.create(
                name=self.cleaned_data['reponame'],
                long_name=self.cleaned_data['long_name'],
                description=self.cleaned_data['description'])

required_dict = {'class': 'required text short'}

class NewAccountForm(forms.Form):
    username = forms.CharField(max_length=30, label=u'Username',
            widget=forms.TextInput(attrs={'class': 'required text short'}))
    password1 = forms.CharField(label=u'Password',
            widget=forms.PasswordInput(attrs={'class': 'required text short'}))
    password2 = forms.CharField(label=u'Password (again)',
            widget=forms.PasswordInput(attrs={'class': 'required text short'}),
            help_text="What if you made a typo?")
    tos = forms.BooleanField()

    def clean_username(self):
        """
        Validates that the username is alphanumeric and is not already
        in use.
        
        """
        if 'username' in self.cleaned_data:
            if not username_re.search(self.cleaned_data['username']):
                msg = (u'Usernames can only contain letters, ' +
                        u'numbers and underscores')
                raise forms.ValidationError(msg)
            try:
                user = User.objects.get(
                        username__exact=self.cleaned_data['username'])
            except User.DoesNotExist:
                return self.cleaned_data['username']
            raise forms.ValidationError(u'This username is already taken. ' +
                    u'Please choose another.')

    def clean_password2(self):
        """
        Validates that the two password inputs match.
        
        """
        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data and \
           self.cleaned_data['password1'] == self.cleaned_data['password2']:
            return self.cleaned_data['password2']
        raise forms.ValidationError(u'You must type the same password each time')
    
    def clean_tos(self):
        """
        Validates that the user accepted the Terms of Service.
        
        """
        if self.cleaned_data.get('tos', False):
            return self.cleaned_data['tos']
        raise forms.ValidationError(u'You must agree to the terms to register')


class LoginForm(forms.Form):
    username = forms.CharField(max_length=30,
                               widget=forms.TextInput(attrs=required_dict),
                               label=u'Username')
    password = forms.CharField(widget=forms.PasswordInput(attrs=required_dict),
                                label=u'Password')

    def clean(self):
        print self._errors
        if not self._errors:
            self.user = authenticate(username=self.cleaned_data['username'],
                    password=self.cleaned_data['password'])
            if not self.user:
                raise forms.ValidationError(u'Invalid username and password.')
            elif not self.user.is_active:
                raise forms.ValidationError(u'Your account has been disabled.')
            else:
                return self.cleaned_data['username']
        return self.cleaned_data


class EditRepoForm(forms.Form):
    def __init__(self, repo, data=None, **kwargs):
        self.repo = repo
        if data is None:
            data = dict(reponame=repo.name, long_name=repo.long_name,
                    description=repo.description)
        forms.Form.__init__(self, data, **kwargs)
    reponame = forms.CharField(max_length=30,
            widget=forms.TextInput(attrs={'class': 'required title'}),
            label=u"Repository Name", help_text=u"the name used in the url. " +
            u"(Changing this will change the url.)")
    long_name = forms.CharField(max_length=50, required=False,
            label=u"Aesthetic Name",
            widget=forms.TextInput(attrs={'class': 'required text'}),
            help_text=u"optional version of the name fit for human consumption")
    description = forms.CharField(max_length=5000, required=False,
            widget=forms.Textarea())

    def clean_reponame(self):
        reponame = self.cleaned_data.get('reponame', None)
        if reponame and reponame != self.repo.name:
            reponame = reponame.lower()
            if not re.search(r'^\w(\w|-|\.)+\w$', reponame):
                msg = (u'Repository names can only contain letters, ' +
                       u'numbers, underscores, dashes and periods. ' +
                       u'They must begin and end with a letter or number.')
                raise forms.ValidationError(msg)
            try:
                repo = self.repo.owner.repo_set.get(name__exact=reponame)
            except Repo.DoesNotExist:
                return reponame
            raise forms.ValidationError(
                    u'You already have a repository with this name.')
        return reponame
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.