first commit

This commit is contained in:
bglacial 2019-01-13 22:35:24 +01:00
commit ff0e2213f3
58 changed files with 892 additions and 0 deletions

0
api/__init__.py Normal file
View File

BIN
api/__init__.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

33
api/readme.md Normal file
View File

@ -0,0 +1,33 @@
cd /mnt/d/Dev/Applications/timelaps_api
service postgresql start
service apache2 start
#
# Installation
#
#Prepare database
python3 manage.py makemigrations
#Create admin tables
python3 manage.py migrate
#Create admin user
python3 manage.py createsuperuser --email admin@gmail.com --username admin
#Prepare database for timelaps
python3 manage.py makemigrations timelaps
#migrate timelaps
python3 manage.py migrate
#
# Exploitation
#
#Exécuter les tests
python3 manage.py test
#Lancement du server
python3 manage.py runserver

126
api/settings.py Normal file
View File

@ -0,0 +1,126 @@
"""
Django settings for api project.
Generated by 'django-admin startproject' using Django 1.11.18.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'kn^0_9ho(9(gs)6c(z!@82s5=94ye$^6q&i4h57)ds61=7vsge'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'timelaps',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'api.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'api.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'timelaps2',
'USER': 'timelaps',
'PASSWORD': 'Dpz9jou99',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'

BIN
api/settings.pyc Normal file

Binary file not shown.

26
api/urls.py Normal file
View File

@ -0,0 +1,26 @@
"""api URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.urls import path
from django.urls import re_path
from django.urls import include
urlpatterns = [
url(r'^admin/', admin.site.urls),
re_path('api/', include('timelaps.urls'))
]

BIN
api/urls.pyc Normal file

Binary file not shown.

16
api/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for api project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings")
application = get_wsgi_application()

22
manage.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)

0
timelaps/__init__.py Normal file
View File

BIN
timelaps/__init__.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

14
timelaps/admin.py Normal file
View File

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Driver)
admin.site.register(Race)
admin.site.register(Relay)
admin.site.register(Rules)
admin.site.register(Team)
admin.site.register(TeamPilot)

BIN
timelaps/admin.pyc Normal file

Binary file not shown.

8
timelaps/apps.py Normal file
View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig
class TimelapsConfig(AppConfig):
name = 'timelaps'

View File

@ -0,0 +1,82 @@
# Generated by Django 2.1.5 on 2019-01-12 08:54
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Driver',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('first_name', models.CharField(max_length=30)),
('last_name', models.CharField(max_length=30)),
],
),
migrations.CreateModel(
name='Race',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('start_date', models.DateField()),
('end_date', models.DateField(null=True)),
('duration', models.IntegerField()),
('comment', models.CharField(max_length=256)),
],
),
migrations.CreateModel(
name='Relay',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('relay_start', models.DateField()),
('relay_end', models.DateField(null=True)),
('has_refuel', models.BooleanField(default=False)),
('pilot_chrono', models.IntegerField(null=True)),
('comment', models.CharField(max_length=256, null=True)),
],
),
migrations.CreateModel(
name='Rule',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('min_stand_duration', models.IntegerField()),
('max_autonomy_dry', models.IntegerField()),
('max_autonomy_wet', models.IntegerField()),
('max_driving_duration', models.IntegerField(null=True)),
('relay_default_duration', models.IntegerField(null=True)),
],
),
migrations.CreateModel(
name='Team',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
],
),
migrations.CreateModel(
name='TeamPilot',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pilot', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='timelaps.Driver')),
('race', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='timelaps.Race')),
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='timelaps.Team')),
],
),
migrations.AddField(
model_name='relay',
name='team',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='timelaps.Team'),
),
migrations.AddField(
model_name='race',
name='fk_rules',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='timelaps.Rule'),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 2.1.5 on 2019-01-12 08:58
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0001_initial'),
]
operations = [
migrations.RenameModel(
old_name='Rule',
new_name='Rules',
),
]

View File

@ -0,0 +1,29 @@
# Generated by Django 2.1.5 on 2019-01-12 09:03
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0002_auto_20190112_0858'),
]
operations = [
migrations.RemoveField(
model_name='relay',
name='team',
),
migrations.AddField(
model_name='relay',
name='team_pilot_id',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='timelaps.TeamPilot'),
preserve_default=False,
),
migrations.AddField(
model_name='teampilot',
name='order',
field=models.IntegerField(null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-01-12 09:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0003_auto_20190112_0903'),
]
operations = [
migrations.AlterField(
model_name='race',
name='comment',
field=models.CharField(max_length=256, null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-01-12 09:07
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0004_auto_20190112_0906'),
]
operations = [
migrations.RenameField(
model_name='driver',
old_name='last_name',
new_name='name',
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 2.1.5 on 2019-01-12 09:12
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0005_auto_20190112_0907'),
]
operations = [
migrations.RenameField(
model_name='teampilot',
old_name='pilot',
new_name='pilot_id',
),
migrations.RenameField(
model_name='teampilot',
old_name='race',
new_name='race_id',
),
migrations.RenameField(
model_name='teampilot',
old_name='team',
new_name='team_id',
),
]

View File

@ -0,0 +1,27 @@
# Generated by Django 2.1.5 on 2019-01-12 09:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0006_auto_20190112_0912'),
]
operations = [
migrations.RenameField(
model_name='driver',
old_name='name',
new_name='last_name',
),
migrations.RemoveField(
model_name='relay',
name='team_pilot_id',
),
migrations.AddField(
model_name='relay',
name='team_pilot_id',
field=models.ManyToManyField(to='timelaps.TeamPilot'),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 2.1.5 on 2019-01-12 09:34
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0007_auto_20190112_0930'),
]
operations = [
migrations.RemoveField(
model_name='relay',
name='team_pilot_id',
),
migrations.AddField(
model_name='relay',
name='team_pilot_id',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='timelaps.TeamPilot'),
preserve_default=False,
),
]

View File

@ -0,0 +1,33 @@
# Generated by Django 2.1.5 on 2019-01-12 09:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0008_auto_20190112_0934'),
]
operations = [
migrations.AlterField(
model_name='race',
name='end_date',
field=models.DateTimeField(null=True),
),
migrations.AlterField(
model_name='race',
name='start_date',
field=models.DateTimeField(),
),
migrations.AlterField(
model_name='relay',
name='relay_end',
field=models.DateTimeField(null=True),
),
migrations.AlterField(
model_name='relay',
name='relay_start',
field=models.DateTimeField(),
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 2.1.5 on 2019-01-12 10:05
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0009_auto_20190112_0938'),
]
operations = [
migrations.RenameField(
model_name='teampilot',
old_name='pilot_id',
new_name='pilot',
),
migrations.RenameField(
model_name='teampilot',
old_name='race_id',
new_name='race',
),
migrations.RenameField(
model_name='teampilot',
old_name='team_id',
new_name='team',
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-01-12 10:17
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0010_auto_20190112_1005'),
]
operations = [
migrations.RenameField(
model_name='relay',
old_name='team_pilot_id',
new_name='team_pilot',
),
]

View File

@ -0,0 +1,83 @@
# Generated by Django 2.1.5 on 2019-01-12 10:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timelaps', '0011_auto_20190112_1017'),
]
operations = [
migrations.AlterField(
model_name='driver',
name='first_name',
field=models.CharField(blank=True, default=None, max_length=30, null=True),
),
migrations.AlterField(
model_name='driver',
name='last_name',
field=models.CharField(blank=True, default=None, max_length=30, null=True),
),
migrations.AlterField(
model_name='race',
name='comment',
field=models.CharField(blank=True, default=None, max_length=256, null=True),
),
migrations.AlterField(
model_name='race',
name='end_date',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='race',
name='name',
field=models.CharField(blank=True, default=None, max_length=30, null=True),
),
migrations.AlterField(
model_name='race',
name='start_date',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='relay',
name='comment',
field=models.CharField(blank=True, default=None, max_length=256, null=True),
),
migrations.AlterField(
model_name='relay',
name='pilot_chrono',
field=models.IntegerField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='relay',
name='relay_end',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='rules',
name='max_driving_duration',
field=models.IntegerField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='rules',
name='min_stand_duration',
field=models.IntegerField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='rules',
name='relay_default_duration',
field=models.IntegerField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='team',
name='name',
field=models.CharField(blank=True, default=None, max_length=30, null=True),
),
migrations.AlterField(
model_name='teampilot',
name='order',
field=models.IntegerField(blank=True, default=None, null=True),
),
]

View File

72
timelaps/models.py Normal file
View File

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Team(models.Model):
# Name of the team
name = models.CharField(max_length=30, default=None, blank=True, null=True)
def __str__(self):
return self.name
class Driver(models.Model):
# Name of the pilot
first_name = models.CharField(max_length=30, default=None, blank=True, null=True)
last_name = models.CharField(max_length=30, default=None, blank=True, null=True)
def __str__(self):
return self.last_name
class Rules(models.Model):
#Minimum time in the pitlane
min_stand_duration = models.IntegerField(default=None, blank=True, null=True)
#Maximum autonomy of the kart in dry condition (In seconds)
max_autonomy_dry = models.IntegerField()
#Maximum autonomy of the kart in wet condition (In seconds)
max_autonomy_wet = models.IntegerField()
#Maximum driving time by driver(In seconds)
max_driving_duration = models.IntegerField(default=None, blank=True, null=True)
#Start and end date of the race
relay_default_duration = models.IntegerField(default=None, blank=True, null=True)
class Race(models.Model):
# Name of the race
name = models.CharField(max_length=30, default=None, blank=True, null=True)
#Start and end date of the race
start_date = models.DateTimeField(default=None, blank=True, null=True)
end_date = models.DateTimeField(default=None, blank=True, null=True)
#Lenth of th race in seconds
duration = models.IntegerField()
#Link to the rules of the race
fk_rules = models.ForeignKey(Rules, on_delete=models.CASCADE)
#Comment the race
comment = models.CharField(max_length=256, default=None, blank=True, null=True)
def __str__(self):
return self.name
class TeamPilot(models.Model):
# Foreign keys to the team pilot and race
team = models.ForeignKey(Team, on_delete=models.CASCADE)
pilot = models.ForeignKey(Driver, on_delete=models.CASCADE)
race = models.ForeignKey(Race, on_delete=models.CASCADE)
order = models.IntegerField(default=None, blank=True, null=True)
class Relay(models.Model):
# Name of the team
team_pilot = models.ForeignKey(TeamPilot, on_delete=models.CASCADE)
#Starting timestamp for the relay
relay_start = models.DateTimeField()
#ending timestamp for the relay
relay_end = models.DateTimeField(default=None, blank=True, null=True)
#Does the pilot did refuel
has_refuel = models.BooleanField(default=False)
#Average chrono for the pulot on this relay
pilot_chrono = models.IntegerField(default=None, blank=True, null=True)
#comment the relay
comment = models.CharField(max_length=256, default=None, blank=True, null=True)

BIN
timelaps/models.pyc Normal file

Binary file not shown.

38
timelaps/serializers.py Normal file
View File

@ -0,0 +1,38 @@
from rest_framework import serializers
from .models import *
class DriverSerializer(serializers.ModelSerializer):
class Meta:
model = Driver
fields = '__all__'
class RaceSerializer(serializers.ModelSerializer):
class Meta:
model = Race
fields = '__all__'
class RelaySerializer(serializers.ModelSerializer):
class Meta:
model = Relay
fields = '__all__'
class RulesSerializer(serializers.ModelSerializer):
class Meta:
model = Rules
fields = '__all__'
class TeamSerializer(serializers.ModelSerializer):
class Meta:
model = Team
fields = '__all__'
class TeamPilotSerializer(serializers.ModelSerializer):
class Meta:
model = TeamPilot
fields = '__all__'
class RelayPilotSerializer(serializers.ModelSerializer):
class Meta:
model = Relay
fields = ('relay_start','relay_end','has_refuel','pilot_chrono','comment','team_pilot','race')

48
timelaps/tests.py Normal file
View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
# Create your tests here.
from django.urls import reverse
from rest_framework.test import APITestCase, APIClient
from rest_framework.views import status
from .models import *
from .serializers import DriverSerializer
"""
# tests for views
class BaseViewTest(APITestCase):
client = APIClient()
@staticmethod
def create_song(title="", artist=""):
if title != "" and artist != "":
Songs.objects.create(title=title, artist=artist)
def setUp(self):
# add test data
self.create_song("like glue", "sean paul")
self.create_song("simple song", "konshens")
self.create_song("love is wicked", "brick and lace")
self.create_song("jam rock", "damien marley")
class GetAllSongsTest(BaseViewTest):
def test_get_all_songs(self):
#This test ensures that all songs added in the setUp method
#exist when we make a GET request to the songs/ endpoint
# hit the API endpoint
response = self.client.get(
reverse("songs-all", kwargs={"version": "v1"})
)
# fetch the data from db
expected = Songs.objects.all()
serialized = SongsSerializer(expected, many=True)
self.assertEqual(response.data, serialized.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
"""

BIN
timelaps/tests.pyc Normal file

Binary file not shown.

13
timelaps/urls.py Normal file
View File

@ -0,0 +1,13 @@
from django.urls import path
from django.conf.urls import url
from .views import *
urlpatterns = [
path('drivers/', ListDriverView.as_view()),
path('races/', ListRaceView.as_view()),
path('relays/', ListRelayView.as_view()),
path('rules/', ListRulesView.as_view()),
path('teams/', ListTeamView.as_view()),
path('teampilots/', ListTeamPilotView.as_view()),
url('race/(?P<raceid>\d+)/team/(?P<teamid>\d+)/relays', ListRelaysByRaceView.as_view()),
]

71
timelaps/views.py Normal file
View File

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from rest_framework import generics
from .models import *
from .serializers import *
# Create your views here.
class ListDriverView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = Driver.objects.all()
serializer_class = DriverSerializer
class ListRaceView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = Race.objects.all()
serializer_class = RaceSerializer
class ListRelayView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = Relay.objects.all()
serializer_class = RelaySerializer
class ListRulesView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = Rules.objects.all()
serializer_class = RulesSerializer
class ListTeamView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = Team.objects.all()
serializer_class = TeamSerializer
class ListTeamPilotView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = TeamPilot.objects.all()
serializer_class = TeamPilotSerializer
class ListRelaysByRaceView(generics.ListAPIView):
queryset = Relay.objects.select_related('team_pilot').all()
serializer_class = RelayPilotSerializer
'''
serializer_class = RelayPilotSerializer
lookup_url_raceid = "raceid"
lookup_url_teamid = "teamid"
def get_queryset(self):
raceid = self.kwargs.get(self.lookup_url_raceid)
teamid = self.kwargs.get(self.lookup_url_teamid)
relays = Relay.objects.filter(team_pilot__team=teamid).filter(team_pilot__race=raceid)
return relays
'''