···1212 brew install spatialite-tools
1313 brew install gdal
14141515+1616+Static files
1717+------------
1818+1919+The default folder for Django's ``STATICFILES_DIRS`` value is ``/static/dist/``, therefore all
2020+static data have to be created by **gulp**.
···11+// Import jquery and bootstrap to be accessible for all project
22+import $ from 'jquery';
33+import jQuery from 'jquery';
44+import bootstrap from 'bootstrap';
55+window.$ = $;
66+window.jQuery = jQuery;
upvcarshare/static/src/sass/guide.scss
This is a binary file and will not be displayed.
+13
upvcarshare/static/src/sass/project.scss
···11+// Import own SCSS files that override Bootstrap
22+// -----------------------------------------------------------------------------
33+@import "variables";
44+55+66+// Import Bootstrap
77+// -----------------------------------------------------------------------------
88+@import "bootstrap/scss/bootstrap";
99+1010+// Project specific
1111+// -----------------------------------------------------------------------------
1212+@import "guide";
1313+@import "patches";
···11+# -*- coding: utf-8 -*-
22+from __future__ import unicode_literals, print_function, absolute_import
33+44+from django import forms
55+from django.utils.translation import ugettext_lazy as _
66+77+from users.models import User
88+99+1010+class SignInForm(forms.Form):
1111+ """Form for handle in a user can log in."""
1212+ username = forms.fields.CharField(
1313+ widget=forms.TextInput(attrs={
1414+ "class": "form-control",
1515+ "placeholder": _("Username"),
1616+ "autocapitalize": "off",
1717+ "autocorrect": "off",
1818+ "autofocus": "autofocus",
1919+ }),
2020+ error_messages={'required': _('The username is required')}
2121+ )
2222+ password = forms.fields.CharField(
2323+ widget=forms.PasswordInput(attrs={
2424+ "class": "form-control",
2525+ "placeholder": _("Password")
2626+ }),
2727+ error_messages={'required': _('The password is required')}
2828+ )
2929+3030+ def clean_username(self):
3131+ username = self.cleaned_data.get('username')
3232+ if not User.objects.filter(username=username).exists():
3333+ raise forms.ValidationError(_("Username not found"))
3434+ return username
3535+3636+ def clean_password(self):
3737+ password = self.cleaned_data.get('password')
3838+ username = self.cleaned_data.get('username')
3939+ try:
4040+ user = User.objects.get(username=username)
4141+ if not user.check_password(password):
4242+ raise forms.ValidationError(_("Password incorrect"))
4343+ except User.DoesNotExist:
4444+ pass
4545+ return password
4646+4747+4848+class UserForm(forms.ModelForm):
4949+5050+ class Meta:
5151+ model = User
5252+ fields = ["first_name", "last_name", "email", "default_address", "default_position", "default_distance"]
+2-1
upvcarshare/users/migrations/0001_initial.py
···11# -*- coding: utf-8 -*-
22-# Generated by Django 1.9.5 on 2016-05-16 13:04
22+# Generated by Django 1.9.5 on 2016-05-18 12:09
33from __future__ import unicode_literals
4455import django.contrib.auth.models
···3333 ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
3434 ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
3535 ('default_address', models.TextField(blank=True, null=True)),
3636+ ('default_distance', models.PositiveIntegerField(blank=True, default=500, null=True)),
3637 ('default_position', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=2062)),
3738 ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
3839 ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
+24-1
upvcarshare/users/models.py
···44from django.contrib.auth.base_user import AbstractBaseUser
55from django.contrib.auth.models import PermissionsMixin, AbstractUser, UserManager
66from django.contrib.gis.db import models
77+from django.contrib.gis.gdal import SpatialReference, CoordTransform
78from django.utils.translation import ugettext_lazy as _
89from rest_framework.authtoken.models import Token
9101010-from journeys import DEFAULT_PROJECTED_SRID
1111+from journeys import DEFAULT_PROJECTED_SRID, DEFAULT_DISTANCE, DEFAULT_WGS84_SRID
111212131314class User(AbstractUser):
1415 """Custom user model."""
1516 default_address = models.TextField(null=True, blank=True)
1717+1818+ default_distance = models.PositiveIntegerField(null=True, blank=True, default=DEFAULT_DISTANCE)
1619 default_position = models.PointField(null=True, blank=True, srid=DEFAULT_PROJECTED_SRID)
17201821 objects = UserManager()
···2023 class Meta:
2124 verbose_name = _('user')
2225 verbose_name_plural = _('users')
2626+2727+ def get_default_position_wgs84(self):
2828+ """Transforms position to WGS-84 system."""
2929+ if self.default_position is None:
3030+ return None
3131+ destination_coord = SpatialReference(DEFAULT_WGS84_SRID)
3232+ origin_coord = SpatialReference(DEFAULT_PROJECTED_SRID)
3333+ trans = CoordTransform(origin_coord, destination_coord)
3434+ position = self.default_position
3535+ position.transform(trans)
3636+ return position
3737+3838+ def set_default_position_wgs84(self, position):
3939+ """Transforms an input to projected coordinates."""
4040+ destination_coord = SpatialReference(DEFAULT_PROJECTED_SRID)
4141+ origin_coord = SpatialReference(DEFAULT_WGS84_SRID)
4242+ trans = CoordTransform(origin_coord, destination_coord)
4343+ position.transform(trans)
4444+ self.default_position = position
4545+ return self.default_position
23462447 def save(self, *args, **kwargs):
2548 """Override to create API Token."""