diff --git a/apps/registration/__init__.py b/apps/registration/__init__.py new file mode 100644 index 0000000000..120606f61f --- /dev/null +++ b/apps/registration/__init__.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import + +from django.utils.translation import ugettext_lazy as _ +from django.db import transaction, DatabaseError +from navigation.api import register_links +from common import about_view, license_view + +from .models import RegistrationSingleton + + +def is_not_registered(context): + return RegistrationSingleton.registration_state() == False + + +form_view = {'text': _('Registration'), 'view': 'form_view', 'famfam': 'telephone', 'condition': is_not_registered} + +register_links(['form_view'], [about_view, license_view], menu_name='secondary_menu') +register_links(['form_view', 'about_view', 'license_view'], [form_view], menu_name='secondary_menu') + +with transaction.commit_on_success(): + try: + RegistrationSingleton.objects.get() + except DatabaseError: + transaction.rollback() diff --git a/apps/registration/exceptions.py b/apps/registration/exceptions.py new file mode 100644 index 0000000000..bd495648f1 --- /dev/null +++ b/apps/registration/exceptions.py @@ -0,0 +1,2 @@ +class AlreadyRegistered(Exception): + pass diff --git a/apps/registration/forms.py b/apps/registration/forms.py new file mode 100644 index 0000000000..340efdbfcc --- /dev/null +++ b/apps/registration/forms.py @@ -0,0 +1,48 @@ +from __future__ import absolute_import + +import logging + +from django import forms +from django.utils.translation import ugettext_lazy as _ + +logger = logging.getLogger(__name__) + + +class RegistrationForm(forms.Form): + name = forms.CharField( + label=_(u'Your name:'), + required=True + ) + + email = forms.CharField( + label=_(u'Your email:'), + required=True + ) + + company = forms.CharField( + label=_(u'Company name:'), + required=False + ) + + industry = forms.CharField( + label=_(u'Industry:'), + required=False + ) + + website = forms.CharField( + label=_(u'Company website:'), + required=False + ) + + country = forms.CharField( + label=_(u'Country:'), + required=False + ) + + other = forms.CharField( + widget=forms.widgets.Textarea( + attrs={'rows': 2}, + ), + label=_(u'Other information:'), + required=False + ) diff --git a/apps/registration/literals.py b/apps/registration/literals.py new file mode 100644 index 0000000000..99d3d6c331 --- /dev/null +++ b/apps/registration/literals.py @@ -0,0 +1,4 @@ +FORM_SUBMIT_URL = 'https://docs.google.com/spreadsheet/formResponse' +FORM_KEY = 'dHp4cFBZNHNtc0xwcW9IazVXY1ZmVWc6MQ' +FORM_RECEIVER_FIELD = 'entry.0.single' +TIMEOUT = 5 diff --git a/apps/registration/migrations/0001_initial.py b/apps/registration/migrations/0001_initial.py new file mode 100644 index 0000000000..c837912d94 --- /dev/null +++ b/apps/registration/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'RegistrationSingleton' + db.create_table('registration_registrationsingleton', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('lock_id', self.gf('django.db.models.fields.CharField')(default=1, unique=True, max_length=1)), + ('registered', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('registration_data', self.gf('django.db.models.fields.TextField')(blank=True)), + )) + db.send_create_signal('registration', ['RegistrationSingleton']) + + + def backwards(self, orm): + # Deleting model 'RegistrationSingleton' + db.delete_table('registration_registrationsingleton') + + + models = { + 'registration.registrationsingleton': { + 'Meta': {'object_name': 'RegistrationSingleton'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lock_id': ('django.db.models.fields.CharField', [], {'default': '1', 'unique': 'True', 'max_length': '1'}), + 'registered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'registration_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['registration'] \ No newline at end of file diff --git a/apps/registration/migrations/__init__.py b/apps/registration/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/registration/models.py b/apps/registration/models.py new file mode 100644 index 0000000000..83d25306d3 --- /dev/null +++ b/apps/registration/models.py @@ -0,0 +1,91 @@ +from __future__ import absolute_import + +import requests + +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.utils.simplejson import dumps, loads + +from common.models import Singleton +from lock_manager import Lock, LockError + +from .literals import FORM_SUBMIT_URL, FORM_KEY, FORM_RECEIVER_FIELD, TIMEOUT +from .exceptions import AlreadyRegistered + + +class RegistrationSingleton(Singleton): + _cached_name = None + _registered = None + + registered = models.BooleanField(default=False, verbose_name=_('registered')) + registration_data = models.TextField(verbose_name=_(u'registration data'), blank=True) + + @classmethod + def purge_cache(cls): + cls._cached_name = None + cls._registered = None + + @classmethod + def registration_state(cls): + if cls._registered: + return cls._registered + else: + instance = cls.objects.get() + cls._registered = instance.is_registered + return cls._registered + + @classmethod + def registered_name(cls): + if cls._cached_name: + return cls._cached_name + else: + instance = cls.objects.get() + try: + dictionary = loads(instance.registration_data) + except ValueError: + dictionary = {} + company = dictionary.get('company') + name = dictionary.get('name') + cls._cached_name = company or name or _(u'No name') + + return cls._cached_name + + @property + def is_registered(self): + return self.registered + + def register(self, form): + from installation.models import Installation + + #if self.is_registered: + # raise AlreadyRegistered + + installation = Installation.objects.get() + dictionary = {} + dictionary.update(form.cleaned_data) + dictionary.update({ + 'uuid': installation.uuid + }) + self.registration_data = dumps(dictionary) + self.save() + self.submit() + + def submit(self): + try: + lock = Lock.acquire_lock('upload_registration') + except LockError: + pass + else: + try: + requests.post(FORM_SUBMIT_URL, data={'formkey': FORM_KEY, FORM_RECEIVER_FIELD: self.registration_data}, timeout=TIMEOUT) + except (requests.exceptions.Timeout, requests.exceptions.ConnectionError): + pass + else: + self.registered = True + self.__class__.purge_cache() + self.save() + finally: + lock.release() + + class Meta: + verbose_name = verbose_name_plural = _(u'registration properties') diff --git a/apps/registration/templatetags/__init__.py b/apps/registration/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/registration/templatetags/registration_tags.py b/apps/registration/templatetags/registration_tags.py new file mode 100644 index 0000000000..88ee51553d --- /dev/null +++ b/apps/registration/templatetags/registration_tags.py @@ -0,0 +1,18 @@ +from __future__ import absolute_import + +from django.core.urlresolvers import reverse, NoReverseMatch +from django.template import (TemplateSyntaxError, Library, + VariableDoesNotExist, Node, Variable) +from django.utils.translation import ugettext as _ + +from ..models import RegistrationSingleton + +register = Library() + + +@register.simple_tag +def registered_name(): + if RegistrationSingleton.registration_state(): + return RegistrationSingleton.registered_name() + else: + return _(u'Unregistered') diff --git a/apps/registration/urls.py b/apps/registration/urls.py new file mode 100644 index 0000000000..6e7db863af --- /dev/null +++ b/apps/registration/urls.py @@ -0,0 +1,5 @@ +from django.conf.urls.defaults import patterns, url + +urlpatterns = patterns('registration.views', + url(r'^form/$', 'form_view', (), 'form_view'), +) diff --git a/apps/registration/views.py b/apps/registration/views.py new file mode 100644 index 0000000000..fcde6d15ea --- /dev/null +++ b/apps/registration/views.py @@ -0,0 +1,36 @@ +from __future__ import absolute_import + +from django.utils.translation import ugettext_lazy as _ +from django.http import HttpResponseRedirect +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.contrib import messages + +from .forms import RegistrationForm +from .models import RegistrationSingleton +from .exceptions import AlreadyRegistered + + +def form_view(request): + registration = RegistrationSingleton.objects.get() + + if request.method == 'POST': + form = RegistrationForm(request.POST) + if form.is_valid(): + try: + registration.register(form) + messages.success(request, _(u'Thank you for registering.')) + return HttpResponseRedirect('/') + except AlreadyRegistered: + messages.error(request, _(u'Your copy is already registered.')) + return HttpResponseRedirect('/') + except Exception, e: + messages.error(request, _(u'Error submiting form; %s.') % e) + else: + form = RegistrationForm() + + return render_to_response('generic_form.html', { + 'title': _(u'registration form'), + 'form': form, + }, + context_instance=RequestContext(request))