diff --git a/README.rst b/README.rst index e70a3ae..bc51dff 100644 --- a/README.rst +++ b/README.rst @@ -22,7 +22,8 @@ Contacts Development environment ======================= -You need to create database manually:: +Execute these commands in Ubuntu 14.04 or greater to prepare your environment +for development:: $ createdb pylab $ make @@ -119,12 +120,12 @@ you have to be careful with. To avoid refactoring issues, we keep all project data access logic in single Django app called ``core``. Also this helps us to better manage dependencies between apps. Since ``core`` contains data access logic which is lowest layer -according to *multilayered architecture*, this means, that is is very likely, +according to *multilayered architecture*, this means, that it is very likely, that most of the code will depend on this app. So since ``core`` tend to be referenced by many other modules and apps, we keep ``core`` lean. ``website`` app is another special case and it belongs to *application* and -*presentation* layers. This means that no other apps can ``website`` depend on +*presentation* layers. This means that no other apps can depend on ``website``, but ``website`` should depend on all other apps. In other words, ``website`` works like top level app with purpose to connect all components in order to assemble whole project. diff --git a/pylab/accounts/forms.py b/pylab/accounts/forms.py index 9c7a71c..f61e25d 100644 --- a/pylab/accounts/forms.py +++ b/pylab/accounts/forms.py @@ -13,11 +13,15 @@ class UserProfileForm(forms.ModelForm): class Meta: model = accounts_models.UserProfile - fields = ('first_name', 'last_name', 'email', 'language') + fields = ('first_name', 'last_name', 'email', 'language', 'accepted_terms') help_texts = { 'email': _( "Will be used for communication. If you want not to get any emails, leave this field empty." ), + 'accepted_terms': _( + "[Terms of serivce](http://pylab.lt/terms/). Basically, you accept that all your " + "creation and work done for Python workshops will belong to Python workshops." + ), } def __init__(self, *args, **kwargs): @@ -26,6 +30,9 @@ def __init__(self, *args, **kwargs): self.fields['email'].initial = self.instance.user.email self.fields['first_name'].initial = self.instance.user.first_name self.fields['last_name'].initial = self.instance.user.last_name + self.fields['accepted_terms'].required = True + if self.instance.accepted_terms: + self.fields.pop('accepted_terms') def save(self, *args, **kwargs): super(UserProfileForm, self).save(*args, **kwargs) @@ -41,6 +48,10 @@ class SignupForm(forms.ModelForm): ) + tuple(settings.LANGUAGES) language = forms.ChoiceField(label=_('Language'), required=False, choices=LANGUAGE_CHOICES) + accepted_terms = forms.BooleanField(label=_('Accept terms of service'), required=True, help_text=_( + "[Terms of serivce](http://pylab.lt/terms/). Basically, you accept that all your " + "creation and work done for Python workshops will belong to Python workshops." + )) class Meta: model = auth_models.User @@ -58,4 +69,5 @@ def signup(self, request, user): # pylint: disable=unused-argument user.email = self.cleaned_data['email'] user.save() user.profile.language = self.cleaned_data['language'] + user.profile.accepted_terms = self.cleaned_data['accepted_terms'] user.profile.save() diff --git a/pylab/accounts/migrations/0002_auto_20150730_1059.py b/pylab/accounts/migrations/0002_auto_20150730_1059.py new file mode 100644 index 0000000..b500c31 --- /dev/null +++ b/pylab/accounts/migrations/0002_auto_20150730_1059.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='accepted_terms', + field=models.BooleanField(default=False, verbose_name='Accept terms of service'), + ), + migrations.AlterField( + model_name='userprofile', + name='language', + field=models.CharField(choices=[('lt', 'Lithuanian'), ('en', 'English')], default='', max_length=7, blank=True, verbose_name='Language'), + ), + migrations.AlterField( + model_name='userprofile', + name='user', + field=models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/pylab/accounts/models.py b/pylab/accounts/models.py index 0e0ebc4..a210f67 100644 --- a/pylab/accounts/models.py +++ b/pylab/accounts/models.py @@ -9,6 +9,7 @@ class UserProfile(models.Model): user = models.OneToOneField(auth_models.User, related_name='profile') language = models.CharField(_('Language'), max_length=7, choices=settings.LANGUAGES, default='', blank=True) + accepted_terms = models.BooleanField(_('Accept terms of service'), default=False) @receiver(post_save, sender=auth_models.User) diff --git a/pylab/accounts/static/css/accounts.scss b/pylab/accounts/static/css/accounts.scss index 9ec1c67..942b8e6 100644 --- a/pylab/accounts/static/css/accounts.scss +++ b/pylab/accounts/static/css/accounts.scss @@ -27,4 +27,6 @@ } } - +#id_accepted_terms { + width: 10%; +} diff --git a/pylab/accounts/tests/test_settings.py b/pylab/accounts/tests/test_settings.py index 0ffd86e..21c9dc4 100644 --- a/pylab/accounts/tests/test_settings.py +++ b/pylab/accounts/tests/test_settings.py @@ -8,7 +8,9 @@ class SettingsTests(django_webtest.WebTest): def setUp(self): super().setUp() - auth_models.User.objects.create_user('u1') + u1 = auth_models.User.objects.create_user('u1') + u1.profile.accepted_terms = True + u1.profile.save() def test_user_settings(self): resp = self.app.get('/accounts/settings/', user='u1') @@ -47,3 +49,17 @@ def test_user_profile_locale_middleware(self): resp = self.app.get('/accounts/settings/', user='u1') # Website interface is displayed in lithuanian self.assertTrue(b'Saugoti' in resp.content) + + def test_requirement_to_accept_terms_of_service(self): + auth_models.User.objects.create_user('u2_not_accepted_terms_yet') + resp = self.app.get('/accounts/settings/', user='u2_not_accepted_terms_yet') + resp.form['language'] = 'en' + resp = resp.form.submit() + # Don't allow to save unless user accepts terms of service + self.assertEqual(resp.status_int, 200) + self.assertTrue(b'has-error' in resp.content) + resp.form['language'] = 'en' + resp.form['accepted_terms'].checked = True + resp = resp.form.submit() + # Allow to save settings changes because user accepted terms of service + self.assertEqual(resp.status_int, 302) diff --git a/pylab/locale/lt/LC_MESSAGES/django.po b/pylab/locale/lt/LC_MESSAGES/django.po index 2014e76..43e3610 100644 --- a/pylab/locale/lt/LC_MESSAGES/django.po +++ b/pylab/locale/lt/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-07-27 06:02-0500\n" +"POT-Creation-Date: 2015-07-30 14:09-0500\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -27,7 +27,7 @@ msgstr "Pavardė" msgid "Email address" msgstr "El. pašto adresas" -#: accounts/forms.py:19 accounts/forms.py:47 +#: accounts/forms.py:19 accounts/forms.py:61 msgid "" "Will be used for communication. If you want not to get any emails, leave " "this field empty." @@ -35,14 +35,28 @@ msgstr "" "Bus naudojamas komunikacijai. Jei pageidaujate negauti jokių laiškų, " "palikite šį lauką tuščią." -#: accounts/forms.py:25 accounts/forms.py:40 +#: accounts/forms.py:22 accounts/forms.py:52 +msgid "" +"[Terms of serivce](http://pylab.lt/terms/). Basically, you accept that all " +"your creation and work done for Python workshops will belong to Python " +"workshops." +msgstr "" +"[Paslaugų teikimo sąlygas](http://pylab.lt/terms/). Iš esmės, Jūs sutinkate, " +"kad visa Jūsų kūryba ir atliktas darbas Python dirbtuvėms priklausys Python " +"dirbtuvėms." + +#: accounts/forms.py:29 accounts/forms.py:47 msgid "Default" msgstr "Numatytoji" -#: accounts/forms.py:39 accounts/models.py:11 +#: accounts/forms.py:50 accounts/models.py:11 msgid "Language" msgstr "Kalba" +#: accounts/forms.py:51 accounts/models.py:12 +msgid "Accept terms of service" +msgstr "Sutikti su paslaugų teikimo sąlygomis" + #: accounts/templates/accounts/login.html:9 #: accounts/templates/accounts/login.html:24 website/templates/base.html:36 msgid "Login" @@ -97,6 +111,34 @@ msgstr "Profilio nustatymai" msgid "Save" msgstr "Saugoti" +#: core/models.py:15 core/models.py:43 +msgid "Title" +msgstr "Pavadinimas" + +#: core/models.py:16 core/models.py:47 +msgid "Description" +msgstr "Aprašymas" + +#: core/models.py:31 +msgid "Other event" +msgstr "Kitas renginys" + +#: core/models.py:32 +msgid "Project development" +msgstr "Projekto vystymas" + +#: core/models.py:33 +msgid "Initial meeting" +msgstr "Pradinis susitikimas" + +#: core/models.py:34 +msgid "Weekly meeting" +msgstr "Savaitinis susitikimas" + +#: core/models.py:49 +msgid "OpenStreetMap iframe src link." +msgstr "OpenStreetMap iframe src nuoroda." + #: settings/base.py:23 msgid "Lithuanian" msgstr "Lietuvių" @@ -105,7 +147,7 @@ msgstr "Lietuvių" msgid "English" msgstr "Anglų" -#: website/forms.py:16 +#: website/forms.py:17 msgid "" "Describe your project idea. You can use [Markdown](http://daringfireball.net/" "projects/markdown/syntax){:target=_blank} markup." @@ -113,57 +155,18 @@ msgstr "" "Apibūdinkite savo projekto idėją. Galite naudoti [Žymėjimų kalbą](http://" "daringfireball.net/projects/markdown/syntax){:target=_blank}." - #: website/menus.py:18 website/templates/base.html:14 msgid "Summer Python Workshop" msgstr "Vasaros Python dirbtuvės" -#: website/models.py:15 -msgid "Title" -msgstr "Pavadinimas" - -#: website/models.py:16 -msgid "Description" -msgstr "Aprašymas" +#: website/menus.py:19 +msgid "About" +msgstr "Apie" #: website/templates/base.html:34 msgid "Logout" msgstr "Atsijungti" -#: website/templates/website/project_details.html:11 -msgid "Change" -msgstr "Redaguoti" - -#: website/templates/website/project_list.html:8 -msgid "Suggest new project idea" -msgstr "Pasiūlyti naują projekto idėją" - -#: website/templates/website/project_list.html:15 -msgid "Project idea" -msgstr "Projekto idėja" - -#: website/templates/website/project_list.html:27 -msgid "No suggested projects yet." -msgstr "Kol kas nėra pasiūlytų projektų." - -#: website/views.py:35 -#, python-format -msgid "Project „%s“ created." -msgstr "Projektas „%s“ sukurtas." - -#: website/views.py:41 -msgid "Suggest new project" -msgstr "Pasiūlyti naują projektą" - -#: website/views.py:56 -#, python-format -msgid "Project „%s“ updated." -msgstr "Projektas „%s“ atnaujintas." - -#: website/menus.py:19 -msgid "About" -msgstr "Apie" - #: website/templates/website/about.html:7 msgid "About Summer Python Workshop" msgstr "Apie Vasaros Python dirbtuves" @@ -218,6 +221,12 @@ msgid "" "devoted\n" " to clarify aims and user stories for the chosen project." msgstr "" +"Kiekvienos Python dirbtuvės prasideda pradiniu susitikimu, per kurį\n" +" dalyviai balsuoja, kurį projektą jie norėtų įgyvendinti šių dirbtuvių " +"metu.\n" +" Pradinis susitikimas yra truputį ilgesnis, nei įprasti savaitiniai " +"susitikimai ir pagrinde skirti pasirinkto projekto tikslų bei panaudos " +"scenarijų išgryninimui." #: website/templates/website/about.html:34 msgid "" @@ -285,3 +294,33 @@ msgstr "" "serverių, patalpų nuomos, komunalinių mokesčių, hakatonų organizavimo " "sąnaudos, taip pat gali būti samdomi etatiniai Python dirbtuvių " "programuotojai." + +#: website/templates/website/project_details.html:11 +msgid "Change" +msgstr "Redaguoti" + +#: website/templates/website/project_list.html:8 +msgid "Suggest new project idea" +msgstr "Pasiūlyti naują projekto idėją" + +#: website/templates/website/project_list.html:15 +msgid "Project idea" +msgstr "Projekto idėja" + +#: website/templates/website/project_list.html:27 +msgid "No suggested projects yet." +msgstr "Kol kas nėra pasiūlytų projektų." + +#: website/views.py:35 +#, python-format +msgid "Project „%s“ created." +msgstr "Projektas „%s“ sukurtas." + +#: website/views.py:41 +msgid "Suggest new project" +msgstr "Pasiūlyti naują projektą" + +#: website/views.py:56 +#, python-format +msgid "Project „%s“ updated." +msgstr "Projektas „%s“ atnaujintas."