-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a4da5d3
Showing
32 changed files
with
867 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__author__ = 'root' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.contrib import admin | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import logging | ||
|
||
from django.contrib.auth import authenticate | ||
from django.contrib.auth.hashers import make_password | ||
|
||
from rest_framework.decorators import list_route | ||
from rest_framework.permissions import AllowAny, IsAuthenticated | ||
from rest_framework.authtoken.models import Token | ||
from rest_framework import status | ||
from rest_framework.response import Response | ||
from rest_framework.viewsets import ModelViewSet | ||
from account.models import User | ||
|
||
from account.serializers import UserSerializer, SignInSerializer, \ | ||
SignUpSerializer | ||
|
||
|
||
logger = logging.getLogger("api") | ||
|
||
|
||
class UserModelViewSet(ModelViewSet): | ||
|
||
serializer_class = UserSerializer | ||
serializer_classes = { | ||
"signin": SignInSerializer, | ||
"create": SignUpSerializer, | ||
} | ||
|
||
def get_serializer_class(self): | ||
return self.serializer_classes.get(self.action, self.serializer_class) | ||
|
||
def get_queryset(self): | ||
if self.request.user.is_authenticated(): | ||
return User.objects.filter(id=self.request.user.id) | ||
return User.objects.none() | ||
|
||
def get_permissions(self): | ||
if self.request.method in ['POST', 'OPTIONS']: | ||
return [AllowAny()] | ||
else: | ||
return [IsAuthenticated()] | ||
|
||
def create(self, request, *args, **kwargs): | ||
|
||
serializer = self.get_serializer(data=request.data) | ||
if not serializer.is_valid(): | ||
errors = serializer.errors | ||
error_data = { | ||
"error": "Registration error", | ||
"error_code": 102, | ||
"errors": errors | ||
} | ||
return Response(error_data, status.HTTP_400_BAD_REQUEST) | ||
|
||
self.perform_create(serializer) | ||
headers = self.get_success_headers(serializer.data) | ||
|
||
token, created = Token.objects.get_or_create(user=self.request.user) | ||
data = serializer.data.copy() | ||
data["token"] = token.key | ||
data["is_active"] = True | ||
return Response(data, status=status.HTTP_201_CREATED, | ||
headers=headers) | ||
|
||
def perform_create(self, serializer): | ||
password = serializer.validated_data["password"] | ||
self.request.user = serializer.save(password=make_password(password)) | ||
|
||
def list(self, request, *args, **kwargs): | ||
serializer = self.serializer_class(request.user) | ||
return Response(serializer.data, status=status.HTTP_200_OK) | ||
|
||
@list_route(methods=['post']) | ||
def signin(self, request, version): | ||
print(request.data.get("email")) | ||
print(request.data.get("password")) | ||
user = authenticate( | ||
username=request.data.get("email"), | ||
password=request.data.get("password"), | ||
) | ||
if user: | ||
token, created = Token.objects.get_or_create(user=user) | ||
return Response({"token": token.key}, status=status.HTTP_200_OK) | ||
|
||
return Response({"error": "Wrong credentials", "error_code": "101"}, | ||
status=status.HTTP_400_BAD_REQUEST) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class AccountConfig(AppConfig): | ||
name = 'account' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
import django.utils.timezone | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('auth', '0007_alter_validators_add_error_messages'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='User', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('password', models.CharField(max_length=128, verbose_name='password')), | ||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), | ||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), | ||
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), | ||
('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')), | ||
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), | ||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), | ||
('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')), | ||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), | ||
('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')), | ||
('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')), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from django.db import models | ||
from django.utils import timezone | ||
from django.utils.translation import ugettext_lazy as _ | ||
from django.contrib.auth.models import PermissionsMixin | ||
from django.contrib.auth.base_user import BaseUserManager, AbstractBaseUser | ||
|
||
|
||
class UserManager(BaseUserManager): | ||
|
||
def create_user(self, email=None, password=None, **extra_fields): | ||
""" | ||
Creates and saves a User with the given username, email and password. | ||
""" | ||
now = timezone.now() | ||
if not email: | ||
raise ValueError('The given email must be set') | ||
email = UserManager.normalize_email(email) | ||
user = self.model(email=email, | ||
is_staff=False, is_active=True, is_superuser=False, | ||
last_login=now, date_joined=now, **extra_fields) | ||
|
||
user.set_password(password) | ||
user.save(using=self._db) | ||
return user | ||
|
||
def create_superuser(self, email, password, **extra_fields): | ||
u = self.create_user(email, password, **extra_fields) | ||
u.is_staff = True | ||
u.is_active = True | ||
u.is_superuser = True | ||
u.save(using=self._db) | ||
return u | ||
|
||
|
||
class User(AbstractBaseUser, PermissionsMixin): | ||
|
||
first_name = models.CharField(_('first name'), max_length=30, blank=True) | ||
last_name = models.CharField(_('last name'), max_length=30, blank=True) | ||
email = models.EmailField(_('email address'), unique=True) | ||
is_staff = models.BooleanField(_('staff status'), default=False, | ||
help_text=_('Designates whether the user can log into this admin ' | ||
'site.')) | ||
is_active = models.BooleanField(_('active'), default=True, | ||
help_text=_('Designates whether this user should be treated as ' | ||
'active. Unselect this instead of deleting accounts.')) | ||
date_joined = models.DateTimeField(_('date joined'), default=timezone.now) | ||
|
||
objects = UserManager() | ||
|
||
USERNAME_FIELD = 'email' | ||
|
||
def get_full_name(self): | ||
return " ".join((self.first_name, self.last_name)) | ||
|
||
def get_short_name(self): | ||
return self.first_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from rest_framework import serializers | ||
from account.models import User | ||
|
||
|
||
class UserSerializer(serializers.ModelSerializer): | ||
|
||
class Meta: | ||
model = User | ||
fields = ('id', 'email', 'first_name', 'last_name', | ||
'is_active', 'password',) | ||
read_only_fields = ('is_active',) | ||
extra_kwargs = {'password': {'write_only': True, 'required': False}} | ||
|
||
|
||
class SignUpSerializer(UserSerializer): | ||
|
||
class Meta(UserSerializer.Meta): | ||
extra_kwargs = {'password': {'write_only': True, 'required': True}} | ||
|
||
|
||
class SignInSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = User | ||
fields = ('email', 'password',) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env python | ||
import os | ||
import sys | ||
|
||
if __name__ == "__main__": | ||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "nostromo.settings") | ||
|
||
from django.core.management import execute_from_command_line | ||
|
||
execute_from_command_line(sys.argv) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.contrib import admin | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import logging | ||
|
||
from datetime import datetime | ||
|
||
from rest_framework.permissions import IsAuthenticated | ||
from rest_framework import status, viewsets, mixins | ||
from rest_framework.response import Response | ||
|
||
from nostromo.models import DataSet | ||
from nostromo.serializers import DatasetSerializer | ||
|
||
logger = logging.getLogger("api") | ||
|
||
|
||
class DataSetPushView(mixins.CreateModelMixin, viewsets.GenericViewSet): | ||
serializer_class = DatasetSerializer | ||
def get_permissions(self): | ||
return [IsAuthenticated()] | ||
|
||
def create(self, request, *args, **kwargs): | ||
|
||
processed = 0 | ||
success = 0 | ||
for data in request.data: | ||
start_date = datetime.utcfromtimestamp(data['start']/1000) | ||
end_date = datetime.utcfromtimestamp(data['end']/1000) | ||
data_type = data["type"] | ||
|
||
if not DataSet.objects.filter(type=data_type, start_date=start_date, end_date=end_date, user=request.user).exists(): | ||
DataSet.objects.create( | ||
start_date=start_date, | ||
end_date=end_date, | ||
data=data['data'], | ||
user=request.user | ||
) | ||
success += 1 | ||
processed += 1 | ||
duplicates = processed - success | ||
result = { | ||
'processed': processed, | ||
'duplicate': duplicates, | ||
'success': success | ||
} | ||
return Response(result, status=status.HTTP_200_OK) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from django.conf.urls import url, include | ||
from rest_framework.urlpatterns import format_suffix_patterns | ||
from rest_framework import routers | ||
from account.api import UserModelViewSet | ||
from nostromo.api import DataSetPushView | ||
|
||
api_router = routers.DefaultRouter() | ||
api_router.register(r'account', UserModelViewSet, base_name="account") | ||
api_router.register(r'push', DataSetPushView, base_name="push") | ||
|
||
urlpatterns = [ | ||
url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), | ||
url(r'^', include(api_router.urls)), | ||
] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.9 on 2016-03-02 21:07 | ||
from __future__ import unicode_literals | ||
|
||
from django.conf import settings | ||
import django.contrib.postgres.fields.jsonb | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='DataSet', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('type', models.CharField(default='accel', max_length=32)), | ||
('start_date', models.DateTimeField()), | ||
('end_date', models.DateTimeField()), | ||
('data', django.contrib.postgres.fields.jsonb.JSONField()), | ||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='datasets', to=settings.AUTH_USER_MODEL)), | ||
], | ||
), | ||
migrations.AlterUniqueTogether( | ||
name='dataset', | ||
unique_together=set([('user', 'start_date', 'end_date')]), | ||
), | ||
migrations.AlterIndexTogether( | ||
name='dataset', | ||
index_together=set([('user', 'start_date', 'end_date'), ('type', 'start_date', 'end_date'), ('start_date', 'end_date')]), | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from django.db import models | ||
from django.contrib.postgres.fields import JSONField | ||
|
||
class DataSet(models.Model): | ||
user = models.ForeignKey("account.User", related_name=u"datasets") | ||
|
||
types = ( | ||
("accel", "Accelerometer"), | ||
("steps", "Steps"), | ||
("run", "Running"), | ||
("heart", "Heart rate"), | ||
) | ||
|
||
type = models.CharField(max_length=32, default="accel") | ||
|
||
start_date = models.DateTimeField() | ||
end_date = models.DateTimeField() | ||
|
||
data = JSONField() | ||
|
||
class Meta: | ||
unique_together = ( | ||
("user", "start_date", "end_date"), | ||
) | ||
index_together = ( | ||
("user", "start_date", "end_date"), | ||
("type", "start_date", "end_date"), | ||
("start_date", "end_date"), | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from rest_framework import serializers | ||
from nostromo.models import DataSet | ||
|
||
|
||
class DatasetSerializer(serializers.ModelSerializer): | ||
|
||
class Meta: | ||
model = DataSet |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__author__ = 'root' |
Oops, something went wrong.