Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
14 changes: 13 additions & 1 deletion pylab/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using [Terms of serivce](http://pylab.lt/terms/){:target=_blank} to force link to TOS open in new tab instead of replacing current page, possibly loosing filled form values.

"creation and work done for Python workshops will belong to Python workshops."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to refer to Wikipedia TOS and additionally tosdr.org badge could be added.

Also, intellectual property can't be given to anyone and no content should belong to Python workshops, TOS should tell, that you agree that all created content will be released to public under a CC licence. And for code, terms off LICENSE file in each repository applies.

Anyway this is tricky part.

),
}

def __init__(self, *args, **kwargs):
Expand All @@ -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)
Expand All @@ -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."
))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are using this in two form, maybe a mixin should be created?


class Meta:
model = auth_models.User
Expand All @@ -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()
30 changes: 30 additions & 0 deletions pylab/accounts/migrations/0002_auto_20150730_1059.py
Original file line number Diff line number Diff line change
@@ -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),
),
]
1 change: 1 addition & 0 deletions pylab/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion pylab/accounts/static/css/accounts.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@
}
}


#id_accepted_terms {
width: 10%;
}
18 changes: 17 additions & 1 deletion pylab/accounts/tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, you could use factory boy. Factory for user is already defined in pylab.website.core.factories. Since accepted_terms should be True in most tests, then I guess it should be added to factory as default value.


def test_user_settings(self):
resp = self.app.get('/accounts/settings/', user='u1')
Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A css or xpath query to a particular field would be much better. Now any field can have has-error and this might give false positive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
133 changes: 86 additions & 47 deletions pylab/locale/lt/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -27,22 +27,36 @@ 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."
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"
Expand Down Expand Up @@ -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ų"
Expand All @@ -105,65 +147,26 @@ 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."
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"
Expand Down Expand Up @@ -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 ""
Expand Down Expand Up @@ -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."