Fix all pep8 and eslint errors :0
This commit is contained in:
+1
-2
@@ -29,7 +29,7 @@ pep8:
|
||||
stage: lint
|
||||
script:
|
||||
- pip install -r requirements.txt
|
||||
- pep8 --exclude='*/migrations/*' --count .
|
||||
- pep8 --config=setup.cfg --count .
|
||||
|
||||
eslint:
|
||||
image: node:7.10.0
|
||||
@@ -37,4 +37,3 @@ eslint:
|
||||
script:
|
||||
- npm install -g eslint
|
||||
- eslint .
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from infoscreen.models import HSLDataModel
|
||||
from django.conf import settings
|
||||
import urllib.request
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from infoscreen.models import HSLDataModel
|
||||
|
||||
|
||||
class HSLFetcher:
|
||||
|
||||
|
||||
last_fetched = datetime.fromtimestamp(0) # epoch
|
||||
INTERVAL = 1 # minutes
|
||||
logging.info("Set up scheduled HSL API fetch every {} minutes".format(INTERVAL))
|
||||
@@ -25,13 +28,13 @@ class HSLFetcher:
|
||||
data = json.loads(src)
|
||||
|
||||
arr = []
|
||||
|
||||
time=datetime.now()+timedelta(minutes = settings.HSL_DEPARTURE_THRESHOLD)
|
||||
time="{0:02d}{0:02d}".format(time.hour,time.minute)
|
||||
|
||||
time = datetime.now() + timedelta(minute=settings.HSL_DEPARTURE_THRESHOLD)
|
||||
time = "{0:02d}{0:02d}".format(time.hour, time.minute)
|
||||
for element in data:
|
||||
src = urllib.request.urlopen(
|
||||
"https://api.reittiopas.fi/hsl/prod/?userhash={}&request=stop&code={}&dep_limit=20&time={}"
|
||||
.format(settings.HSL_USERHASH, element['code'],time)).read().decode("utf-8")
|
||||
.format(settings.HSL_USERHASH, element['code'], time)).read().decode("utf-8")
|
||||
|
||||
parsed = json.loads(src)[0]
|
||||
arr.append({"name": parsed['name_fi'], "lines": parsed['lines'],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from infoscreen.hsl_fetcher import HSLFetcher
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Loads HSL timetables and save to json file.'
|
||||
|
||||
|
||||
+17
-9
@@ -1,11 +1,13 @@
|
||||
from datetime import datetime
|
||||
|
||||
from django.db import models
|
||||
from django import forms
|
||||
from django.utils import timezone
|
||||
from datetime import datetime
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
||||
class InfoItem(models.Model):
|
||||
|
||||
class __meta__:
|
||||
@@ -73,27 +75,30 @@ class InfoItem(models.Model):
|
||||
|
||||
class ABBInfoItem(InfoItem):
|
||||
display_name = _("ABB jobs")
|
||||
|
||||
def get_template_url(self):
|
||||
return "/static/html/abb.html"
|
||||
|
||||
@staticmethod
|
||||
def get_create_template_url():
|
||||
return "/static/html/abb_create.html"
|
||||
|
||||
|
||||
|
||||
class ApyInfoItem(InfoItem):
|
||||
display_name = _("APY Item")
|
||||
|
||||
def get_template_url(self):
|
||||
return "/static/html/apy.html"
|
||||
|
||||
@staticmethod
|
||||
def get_create_template_url():
|
||||
return "/static/html/apy_create.html"
|
||||
|
||||
|
||||
|
||||
class ExternalWebsiteInfoItem(InfoItem):
|
||||
display_name = _("External website")
|
||||
url = models.TextField()
|
||||
|
||||
def get_template_url(self):
|
||||
return "/static/html/external_website.html?url={}".format(self.name)
|
||||
|
||||
@@ -114,8 +119,8 @@ class ExternalWebsiteInfoItem(InfoItem):
|
||||
|
||||
def get_list(self):
|
||||
return {
|
||||
'id':self.id,
|
||||
'name':self.name,
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'url': self.url,
|
||||
}
|
||||
|
||||
@@ -137,8 +142,10 @@ class ExternalWebsiteInfoItem(InfoItem):
|
||||
pass
|
||||
self.save()
|
||||
|
||||
|
||||
class SossoInfoItem(InfoItem):
|
||||
display_name = _("Sössö articles")
|
||||
|
||||
def get_template_url(self):
|
||||
return "/static/html/sosso.html"
|
||||
|
||||
@@ -146,6 +153,7 @@ class SossoInfoItem(InfoItem):
|
||||
def get_create_template_url():
|
||||
return "/static/html/sosso_create.html"
|
||||
|
||||
|
||||
class EventInfoItem(InfoItem):
|
||||
display_name = _("Events")
|
||||
|
||||
@@ -157,7 +165,6 @@ class EventInfoItem(InfoItem):
|
||||
return "/static/html/events_create.html"
|
||||
|
||||
|
||||
|
||||
class ImageInfoItem(InfoItem):
|
||||
display_name = _("Image")
|
||||
img = models.ImageField(upload_to="infoimages/")
|
||||
@@ -178,6 +185,7 @@ class ImageInfoItem(InfoItem):
|
||||
|
||||
class HslInfoItem(InfoItem):
|
||||
display_name = _("HSL timetables")
|
||||
|
||||
def get_template_url(self):
|
||||
return "/static/html/hsl.html"
|
||||
|
||||
@@ -275,15 +283,15 @@ class Rotation(models.Model):
|
||||
instance_list = list(map(lambda i: i.get_dict(), filtered))
|
||||
|
||||
return {
|
||||
'id':self.id,
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'instances': instance_list,
|
||||
}
|
||||
|
||||
def get_list(self):
|
||||
return {
|
||||
'id':self.id,
|
||||
'name':self.name,
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
}
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -27,7 +27,7 @@ app.service("InstanceList", ["$http", function($http){
|
||||
'item_type': item_type,
|
||||
'duration': duration,
|
||||
}
|
||||
$http.post("/infoscreen/instance", data).then(function(response){
|
||||
$http.post("/infoscreen/instance", data).then(function(response) { //eslint-disable-line no-unused-vars
|
||||
self.getRotation(rotation_id);
|
||||
});
|
||||
};
|
||||
@@ -46,7 +46,7 @@ app.service("InstanceList", ["$http", function($http){
|
||||
});
|
||||
}
|
||||
this.deleteInstance = function(id){
|
||||
$http.delete("/infoscreen/instance/"+id).then(function(response){
|
||||
$http.delete("/infoscreen/instance/"+id).then(function(response) { //eslint-disable-line no-unused-vars
|
||||
self.getRotation(self.selected_rot.id);
|
||||
});
|
||||
}
|
||||
@@ -55,7 +55,7 @@ app.service("InstanceList", ["$http", function($http){
|
||||
$http.post("/infoscreen/create_rotation", data);
|
||||
}
|
||||
this.deleteRotation = function(id) {
|
||||
$http.delete("/infoscreen/delete_rotation/" + id).then(function(response) {
|
||||
$http.delete("/infoscreen/delete_rotation/" + id).then(function(response) { //eslint-disable-line no-unused-vars
|
||||
});
|
||||
}
|
||||
}]);
|
||||
@@ -77,7 +77,7 @@ app.service("ItemList", ["$http",'InstanceList', function($http, InstanceList){
|
||||
InstanceList.getRotation(InstanceList.selected_rot.id);
|
||||
});
|
||||
};
|
||||
this.refreshCB = function(response){
|
||||
this.refreshCB = function(response) { //eslint-disable-line no-unused-vars
|
||||
self.loadItems();
|
||||
};
|
||||
}]);
|
||||
|
||||
@@ -15,7 +15,7 @@ app.controller('infoscreen_main', function($scope,$http,$timeout){
|
||||
else {
|
||||
$scope.next();
|
||||
}
|
||||
},function(response){
|
||||
},function(response) { //eslint-disable-line no-unused-vars
|
||||
$timeout(get_rotation, 10000);
|
||||
});
|
||||
}
|
||||
@@ -107,12 +107,12 @@ app.controller('timetableCtrl',
|
||||
function($scope, $http, $interval) {
|
||||
function load(){
|
||||
$http.get('/infoscreen/hsl_data')
|
||||
.then(function(data, status, headers, config) {
|
||||
.then(function(data, status, headers, config) { //eslint-disable-line no-unused-vars
|
||||
$scope.arr=[];
|
||||
parse(data);
|
||||
});
|
||||
$http.get('/infoscreen/hsl_data/settings')
|
||||
.then(function(data, status, headers, config) {
|
||||
.then(function(data, status, headers, config) { //eslint-disable-line no-unused-vars
|
||||
$scope.departureThreshold = data.data['departure_threshold'];
|
||||
$scope.hurryThreshold = data.data['hurry_threshold'];
|
||||
});
|
||||
@@ -139,8 +139,8 @@ app.controller('timetableCtrl',
|
||||
var line = stop['departures'][lineIndex];
|
||||
var time = line['time'];
|
||||
var date = line['date'];
|
||||
var hours = Math.floor(line['time'] / 100);
|
||||
var minutes = line['time'] % 100;
|
||||
var hours = Math.floor(time / 100);
|
||||
var minutes = time % 100;
|
||||
if (hours >= 24) {
|
||||
hours -= 24;
|
||||
date++;
|
||||
@@ -198,12 +198,12 @@ app.controller('timetableCtrl',
|
||||
function delOld(){
|
||||
var tooSoon = typeof($scope.departureThreshold) != 'undefined' ? $scope.departureThreshold: 0;
|
||||
var hurry = typeof($scope.hurryThreshold) != 'undefined' ? $scope.hurryThreshold : 0;
|
||||
f = new Date();
|
||||
for(var a=$scope.arr.length-1; a>=0; a--){
|
||||
var f = new Date();
|
||||
for (var a=$scope.arr.length-1; a>=0; a--) {
|
||||
var time=$scope.arr[a]['time'].split(":");
|
||||
date=$scope.arr[a]['date'].toString();
|
||||
d= new Date(f);
|
||||
d.setFullYear(date.substring(0,4),date.substring(4,6)-1,date.substring(6,8));
|
||||
var date=$scope.arr[a]['date'].toString();
|
||||
var d = new Date(f);
|
||||
d.setFullYear(date.substring(0,4), date.substring(4,6)-1, date.substring(6,8));
|
||||
d.setHours(time[0]);
|
||||
d.setMinutes(time[1]);
|
||||
var diff=(d.getTime()-f.getTime());
|
||||
|
||||
+16
-14
@@ -4,36 +4,38 @@ from infoscreen.models import SossoInfoItem
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
import infoscreen.views
|
||||
|
||||
'''
|
||||
Test cases for testing infoscreen methods
|
||||
'''
|
||||
|
||||
class InfoscreenTestCase(TestCase):
|
||||
'''
|
||||
Create some dummy models
|
||||
Test cases for testing infoscreen methods
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
'''
|
||||
Create some dummy models
|
||||
'''
|
||||
Rotation.objects.create(name="test_rot")
|
||||
SossoInfoItem.objects.create()
|
||||
|
||||
'''
|
||||
Check if the dummy model actually exists
|
||||
'''
|
||||
def test_rotation_created(self):
|
||||
'''
|
||||
Check if the dummy model actually exists
|
||||
'''
|
||||
rot = Rotation.objects.get(name="test_rot")
|
||||
self.assertIsNotNone(rot)
|
||||
|
||||
'''
|
||||
Check if the dummy model actually exists
|
||||
'''
|
||||
def test_sosso_infoitem_created(self):
|
||||
'''
|
||||
Check if the dummy model actually exists
|
||||
'''
|
||||
item = SossoInfoItem.objects.get()
|
||||
self.assertIsNotNone(item)
|
||||
|
||||
'''
|
||||
Check if infoItems returns a response with non-zero content length
|
||||
That would mean that something meaningful has been included in the response
|
||||
'''
|
||||
def test_get_infoitems(self):
|
||||
'''
|
||||
Check if infoItems returns a response with non-zero content length
|
||||
That would mean that something meaningful has been included in the response
|
||||
'''
|
||||
req = HttpRequest()
|
||||
resp = infoscreen.views.info_items(req)
|
||||
content = resp.content.decode('utf-8')
|
||||
|
||||
+23
-25
@@ -1,6 +1,5 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
#infoscreen
|
||||
from infoscreen.views import index
|
||||
from infoscreen.views import admin
|
||||
from infoscreen.views import default
|
||||
@@ -26,28 +25,27 @@ from infoscreen.views import hsl_timetable_settings
|
||||
from infoscreen.views import get_apy_json
|
||||
|
||||
urlpatterns = [
|
||||
#infoscreen
|
||||
url(r'^$', default),
|
||||
url(r'^admin$', admin),
|
||||
url(r'^(?P<idx>\d+)$', index),
|
||||
url(r'^items$', info_items),
|
||||
url(r'^rotation/(?P<idx>\d+)$', rotation),
|
||||
url(r'^rotations$', rotations),
|
||||
url(r'^instance$', createInstance),
|
||||
url(r'^instance/(?P<idx>\d+)$', deleteInstance),
|
||||
url(r'^types$', info_types),
|
||||
url(r'^delete_item/(?P<type_id>\d+)/(?P<idx>\d+)$', delete_info_item),
|
||||
url(r'^create_external_image$', createExternalImageInfoItem),
|
||||
url(r'^create_image$', create_image_item),
|
||||
url(r'^create_abbitem$', createABBItem),
|
||||
url(r'^create_sossoitem$', createSossoItem),
|
||||
url(r'^create_eventitem$', createEventItem),
|
||||
url(r'^create_hslitem$', createHslItem),
|
||||
url(r'^create_apyitem$', createApyItem),
|
||||
url(r'^create_websiteitem$', createExternalWebsiteItem),
|
||||
url(r'^create_rotation$', create_rotation),
|
||||
url(r'^delete_rotation/(?P<id>\d+)$', delete_rotation),
|
||||
url(r'^hsl_data$', CurrentHSLView),
|
||||
url(r'^hsl_data/settings$', hsl_timetable_settings),
|
||||
url(r'^apyjson', get_apy_json),
|
||||
url(r'^$', default),
|
||||
url(r'^admin$', admin),
|
||||
url(r'^(?P<idx>\d+)$', index),
|
||||
url(r'^items$', info_items),
|
||||
url(r'^rotation/(?P<idx>\d+)$', rotation),
|
||||
url(r'^rotations$', rotations),
|
||||
url(r'^instance$', createInstance),
|
||||
url(r'^instance/(?P<idx>\d+)$', deleteInstance),
|
||||
url(r'^types$', info_types),
|
||||
url(r'^delete_item/(?P<type_id>\d+)/(?P<idx>\d+)$', delete_info_item),
|
||||
url(r'^create_external_image$', createExternalImageInfoItem),
|
||||
url(r'^create_image$', create_image_item),
|
||||
url(r'^create_abbitem$', createABBItem),
|
||||
url(r'^create_sossoitem$', createSossoItem),
|
||||
url(r'^create_eventitem$', createEventItem),
|
||||
url(r'^create_hslitem$', createHslItem),
|
||||
url(r'^create_apyitem$', createApyItem),
|
||||
url(r'^create_websiteitem$', createExternalWebsiteItem),
|
||||
url(r'^create_rotation$', create_rotation),
|
||||
url(r'^delete_rotation/(?P<id>\d+)$', delete_rotation),
|
||||
url(r'^hsl_data$', CurrentHSLView),
|
||||
url(r'^hsl_data/settings$', hsl_timetable_settings),
|
||||
url(r'^apyjson', get_apy_json),
|
||||
]
|
||||
|
||||
+14
-11
@@ -1,10 +1,16 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse,HttpResponseBadRequest
|
||||
from django.http import HttpResponse, HttpResponseBadRequest
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
|
||||
import sikweb.settings as settings
|
||||
import json
|
||||
import logging
|
||||
import threading
|
||||
import requests
|
||||
|
||||
from infoscreen.models import Rotation, InfoItem, InfoInstance
|
||||
from infoscreen.models import ABBInfoItem, ExternalImageInfoItem, ImageInfoItem, SossoInfoItem, HslInfoItem
|
||||
from infoscreen.models import EventInfoItem
|
||||
@@ -13,11 +19,6 @@ from infoscreen.models import ImageUploadForm
|
||||
from infoscreen.models import HSLDataModel
|
||||
from infoscreen.models import ApyInfoItem
|
||||
from infoscreen.hsl_fetcher import HSLFetcher
|
||||
import sikweb.settings as settings
|
||||
import json
|
||||
import logging
|
||||
import threading
|
||||
import requests
|
||||
|
||||
|
||||
def index(request, idx, *args, **kwargs):
|
||||
@@ -29,17 +30,18 @@ def admin(request, *args, **kwargs):
|
||||
return render(request, 'infoscreen_admin.html', {})
|
||||
|
||||
|
||||
def default(request,*args,**kwargs):
|
||||
def default(request, *args, **kwargs):
|
||||
try:
|
||||
first = Rotation.objects.all()[0].id
|
||||
except:
|
||||
first = 0
|
||||
return index(request,first ,*args, **kwargs)
|
||||
return index(request, first, *args, **kwargs)
|
||||
|
||||
|
||||
def get_apy_json(request):
|
||||
return HttpResponse(requests.get("https://api-diilikone.apy.fi/deals/top-groups").text)
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
def rotation(request, idx, *args, **kwargs):
|
||||
try:
|
||||
@@ -65,7 +67,7 @@ def create_item_generator(model):
|
||||
model.create_from_dict(data)
|
||||
return HttpResponse('{"status":"success"}')
|
||||
except RuntimeError as e:
|
||||
return HttpResponseBadRequest(json.dumps({"status":"failure", "error":str(e)}))
|
||||
return HttpResponseBadRequest(json.dumps({"status": "failure", "error": str(e)}))
|
||||
return create_item
|
||||
|
||||
|
||||
@@ -145,7 +147,7 @@ def info_items(request, *args, **kwargs):
|
||||
@ensure_csrf_cookie
|
||||
@permission_required('infoscreen.change_infoinstance', login_url='/login')
|
||||
def create_image_item(request, *args, **kwargs):
|
||||
form = ImageUploadForm(request.POST,request.FILES)
|
||||
form = ImageUploadForm(request.POST, request.FILES)
|
||||
if not form.is_valid():
|
||||
return HttpResponseBadRequest('{"status": "failure",'
|
||||
'"error": "invalid data supplied"}')
|
||||
@@ -191,6 +193,7 @@ def delete_rotation(request, *args, **kwargs):
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
def hsl_timetable_settings(request, *args, **kwargs):
|
||||
d = {"departure_threshold": settings.HSL_DEPARTURE_THRESHOLD,
|
||||
@@ -198,6 +201,7 @@ def hsl_timetable_settings(request, *args, **kwargs):
|
||||
resp = json.dumps(d)
|
||||
return HttpResponse(resp, status=200)
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
def CurrentHSLView(request, *args, **kwargs):
|
||||
|
||||
@@ -213,7 +217,6 @@ def CurrentHSLView(request, *args, **kwargs):
|
||||
return HttpResponse(data[len(data) - 1].data, status=200)
|
||||
|
||||
|
||||
|
||||
createInstance = create_item_generator(InfoInstance)
|
||||
deleteInstance = delete_item_generator(InfoInstance)
|
||||
createABBItem = create_item_generator(ABBInfoItem)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class MembersConfig(AppConfig):
|
||||
name = 'members'
|
||||
|
||||
+2
-1
@@ -16,8 +16,9 @@ class PaymentForm(forms.ModelForm):
|
||||
model = Payment
|
||||
fields = ['date', 'source', 'member']
|
||||
|
||||
|
||||
class ApplicationForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Request
|
||||
fields = ['first_name', 'last_name', 'email', 'AYY', 'jas', 'POR']
|
||||
fields = ['first_name', 'last_name', 'email', 'AYY', 'jas', 'POR']
|
||||
|
||||
+1
-1
@@ -109,4 +109,4 @@ class Member(BaseMember):
|
||||
POR=array[3],
|
||||
AYY=bool(array[4]),
|
||||
jas=bool(array[5]),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
from rest_framework import permissions
|
||||
from django.contrib.auth.models import Permission, User
|
||||
|
||||
class HasRights(permissions.BasePermission):
|
||||
message = "You need rights to access this content."
|
||||
|
||||
def has_permission(self, request, view):
|
||||
if request.user.has_perm('members.change_member'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@@ -1,68 +0,0 @@
|
||||
from rest_framework import serializers
|
||||
from django.utils import timezone
|
||||
from datetime import datetime
|
||||
from members.models import Member, Request
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class MemberSerializer(serializers.Serializer):
|
||||
id = serializers.IntegerField(read_only=True)
|
||||
first_name = serializers.CharField(required=True, max_length=127)
|
||||
last_name = serializers.CharField(required=True, max_length=127)
|
||||
email = serializers.EmailField(min_length=None, max_length=None, required=True)
|
||||
POR = serializers.CharField(max_length=255)
|
||||
AYY = serializers.BooleanField(default=False)
|
||||
jas = serializers.BooleanField(default=False)
|
||||
created = serializers.DateTimeField(default=timezone.now)
|
||||
paid = serializers.DateTimeField(default=datetime.fromtimestamp(0))
|
||||
|
||||
def create(self, validated_data):
|
||||
'''
|
||||
Create and return a new Member instance, given the validated data.
|
||||
'''
|
||||
return Member.objects.create(**validated_data)
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
'''
|
||||
Update and return an existing Member instance given the validated data.
|
||||
'''
|
||||
instance.first_name = validated_data.get('first_name', instance.first_name)
|
||||
instance.last_name = validated_data.get('last_name', instance.last_name)
|
||||
instance.email = validated_data.get('email', instance.email)
|
||||
instance.POR = validated_data.get('POR', instance.POR)
|
||||
instance.AYY = validated_data.get('AYY', instance.AYY)
|
||||
instance.jas = validated_data.get('jas', instance.jas)
|
||||
instance.created = validated_data.get('created', instance.created)
|
||||
instance.paid = validated_data.get('paid', instance.paid)
|
||||
instance.save()
|
||||
return instance
|
||||
|
||||
class MemberRequestSerializer(serializers.Serializer):
|
||||
id = serializers.IntegerField(read_only=True)
|
||||
submitted = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
|
||||
first_name = serializers.CharField(required=True, max_length=127)
|
||||
last_name = serializers.CharField(required=True, max_length=127)
|
||||
email = serializers.EmailField(min_length=None, max_length=None, required=True)
|
||||
POR = serializers.CharField(max_length=255)
|
||||
AYY = serializers.BooleanField(default=False)
|
||||
jas = serializers.BooleanField(default=False)
|
||||
|
||||
def created(self, validated_data):
|
||||
'''
|
||||
Create and return a new MemberRequest instance, given the validated data.
|
||||
'''
|
||||
return MemberRequest.objects.create(**validated_data)
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
'''
|
||||
Update and return an existing Member request instance given the validated data.
|
||||
'''
|
||||
instance.submitted = validated_data.get('submitted', instance.submitted)
|
||||
instance.first_name = validated_data.get('first_name', instance.first_name)
|
||||
instance.last_name = validated_data.get('last_name', instance.last_name)
|
||||
instance.email = validated_data.get('email', instance.email)
|
||||
instance.POR = validated_data.get('POR', instance.POR)
|
||||
instance.AYY = validated_data.get('AYY', instance.AYY)
|
||||
instance.jas = validated_data.get('jas', instance.jas)
|
||||
instance.save()
|
||||
return instance
|
||||
+2
-2
@@ -8,7 +8,7 @@ class MemberTable(tables.Table):
|
||||
|
||||
options = tables.TemplateColumn(
|
||||
'<a class="data-table-button btn btn-primary" href="/members/edit/{{ record.id }}">' +
|
||||
_('Edit') +
|
||||
_('Edit') +
|
||||
'</a>'
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ class PaymentTable(tables.Table):
|
||||
|
||||
options = tables.TemplateColumn(
|
||||
'<a class="data-table-button btn btn-primary" href="/members/edit_payment/{{ record.id }}">' +
|
||||
_('Edit') +
|
||||
_('Edit') +
|
||||
'</a>'
|
||||
)
|
||||
|
||||
|
||||
+3
-1
@@ -1,9 +1,11 @@
|
||||
from django.test import TestCase, Client
|
||||
from members.models import Member
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
import time
|
||||
|
||||
from members.models import Member
|
||||
|
||||
|
||||
class MemberRegisterTestCase(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
|
||||
class BurstRateThrottle(UserRateThrottle):
|
||||
scope = 'burst'
|
||||
|
||||
class SustainedRateThrottle(UserRateThrottle):
|
||||
scope = 'sustained'
|
||||
+49
-49
@@ -2,8 +2,9 @@ from django.conf.urls import url
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
# members
|
||||
from members.views import member_list, payment_add, payment_submit, application_delete_confirm, application_delete, \
|
||||
application_accept, import_csv, export_csv
|
||||
from members.views import member_list, payment_add, payment_submit
|
||||
from members.views import application_delete_confirm, application_delete
|
||||
from members.views import application_accept, import_csv, export_csv
|
||||
from members.views import settings_page, payment_edit
|
||||
from members.views import payment_delete_confirm
|
||||
from members.views import payment_delete, payment_update
|
||||
@@ -26,69 +27,68 @@ favicon_view = RedirectView.as_view(url='static/img/favicon.ico', permanent=True
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
# landing page
|
||||
url(r'^$', member_list),
|
||||
url(r'^list$', member_list),
|
||||
# landing page
|
||||
url(r'^$', member_list),
|
||||
url(r'^list$', member_list),
|
||||
|
||||
# add member form view
|
||||
url(r'^add$', member_add),
|
||||
# add member form view
|
||||
url(r'^add$', member_add),
|
||||
|
||||
# add many members view
|
||||
url(r'^add_many$', member_add_many),
|
||||
# add many members view
|
||||
url(r'^add_many$', member_add_many),
|
||||
|
||||
# edit member information view
|
||||
url(r'^edit/(?P<index>\d+)$', member_edit),
|
||||
# edit member information view
|
||||
url(r'^edit/(?P<index>\d+)$', member_edit),
|
||||
|
||||
# delete confirmation view
|
||||
url(r'^delete_member_confirm/(?P<index>\d+)$', member_delete_confirm),
|
||||
# delete confirmation view
|
||||
url(r'^delete_member_confirm/(?P<index>\d+)$', member_delete_confirm),
|
||||
|
||||
# list all member applications
|
||||
url(r'^applications$', application_list),
|
||||
# list all member applications
|
||||
url(r'^applications$', application_list),
|
||||
|
||||
# edit member application
|
||||
url(r'^edit_application/(?P<index>\d+)$', application_edit),
|
||||
# edit member application
|
||||
url(r'^edit_application/(?P<index>\d+)$', application_edit),
|
||||
|
||||
# post request targets
|
||||
url(r'^submit_member$', member_submit),
|
||||
url(r'^update_member$', member_update),
|
||||
url(r'^delete_member$', member_delete),
|
||||
url(r'^submit_payment$', payment_submit),
|
||||
url(r'^update_payment$', payment_update),
|
||||
url(r'^delete_payment$', payment_delete),
|
||||
url(r'^accept_application$', application_accept),
|
||||
url(r'^delete_application$', application_delete),
|
||||
# post request targets
|
||||
url(r'^submit_member$', member_submit),
|
||||
url(r'^update_member$', member_update),
|
||||
url(r'^delete_member$', member_delete),
|
||||
url(r'^submit_payment$', payment_submit),
|
||||
url(r'^update_payment$', payment_update),
|
||||
url(r'^delete_payment$', payment_delete),
|
||||
url(r'^accept_application$', application_accept),
|
||||
url(r'^delete_application$', application_delete),
|
||||
|
||||
# the actual member application form
|
||||
url(r'^application/$', application_form),
|
||||
# the actual member application form
|
||||
url(r'^application/$', application_form),
|
||||
|
||||
# success page for the application
|
||||
url(r'^application/success$', application_form_success),
|
||||
# success page for the application
|
||||
url(r'^application/success$', application_form_success),
|
||||
|
||||
# delete confirmation view for applications
|
||||
url(r'^delete_application_confirm/(?P<index>\d+)$', application_delete_confirm),
|
||||
# delete confirmation view for applications
|
||||
url(r'^delete_application_confirm/(?P<index>\d+)$', application_delete_confirm),
|
||||
|
||||
# list all payment events
|
||||
url(r'^payments$', payment_list),
|
||||
# list all payment events
|
||||
url(r'^payments$', payment_list),
|
||||
|
||||
# add payment event
|
||||
url(r'^add_payment$', payment_add),
|
||||
# add payment event
|
||||
url(r'^add_payment$', payment_add),
|
||||
|
||||
# edit payment event
|
||||
url(r'^edit_payment/(?P<index>\d+)$', payment_edit),
|
||||
# edit payment event
|
||||
url(r'^edit_payment/(?P<index>\d+)$', payment_edit),
|
||||
|
||||
# delete confirmation view
|
||||
url(r'^delete_payment_confirm/(?P<index>\d+)$', payment_delete_confirm),
|
||||
# delete confirmation view
|
||||
url(r'^delete_payment_confirm/(?P<index>\d+)$', payment_delete_confirm),
|
||||
|
||||
# settings page
|
||||
url(r'^settings$', settings_page),
|
||||
# settings page
|
||||
url(r'^settings$', settings_page),
|
||||
|
||||
# send CSV member data by POST
|
||||
url(r'^import_csv', import_csv),
|
||||
# send CSV member data by POST
|
||||
url(r'^import_csv', import_csv),
|
||||
|
||||
# download CSV member data
|
||||
url(r'^export_csv', export_csv),
|
||||
# download CSV member data
|
||||
url(r'^export_csv', export_csv),
|
||||
|
||||
# favourite icon
|
||||
url(r'^favicon\.ico$', favicon_view),
|
||||
# favourite icon
|
||||
url(r'^favicon\.ico$', favicon_view),
|
||||
]
|
||||
|
||||
|
||||
+14
-16
@@ -47,13 +47,11 @@ def validate_recaptcha(response):
|
||||
|
||||
|
||||
def send_mail_wrapper(subject, message):
|
||||
send_mail(
|
||||
subject,
|
||||
message,
|
||||
'no-reply@sahkoinsinoorikilta.fi',
|
||||
['viestintamestari@sahkoinsinoorikilta.fi'],
|
||||
fail_silently=False
|
||||
)
|
||||
send_mail(subject,
|
||||
message,
|
||||
'no-reply@sahkoinsinoorikilta.fi',
|
||||
['viestintamestari@sahkoinsinoorikilta.fi'],
|
||||
fail_silently=False)
|
||||
|
||||
|
||||
def convert_table_to_html(table, request):
|
||||
@@ -84,10 +82,10 @@ def member_list(request, *args, **kwargs):
|
||||
members = Member.objects.all()
|
||||
|
||||
table = MemberTable(members,
|
||||
request=request,
|
||||
exclude=['id'],
|
||||
attrs={'class': 'table table-bordered table-hover'},
|
||||
)
|
||||
request=request,
|
||||
exclude=['id'],
|
||||
attrs={'class': 'table table-bordered table-hover'})
|
||||
|
||||
table.paginate(page=request.GET.get('page', 1), per_page=25)
|
||||
table_html = convert_table_to_html(table, request)
|
||||
|
||||
@@ -136,8 +134,8 @@ def member_submit(request, *args, **kwargs):
|
||||
form.save()
|
||||
memberlogger.info("Saved new member to member register with the following info: {}".format(form))
|
||||
notification = "{} {} {}.".format(_("Successfully added member"),
|
||||
form.cleaned_data['last_name'],
|
||||
form.cleaned_data['first_name'])
|
||||
form.cleaned_data['last_name'],
|
||||
form.cleaned_data['first_name'])
|
||||
|
||||
return HttpResponseRedirect('/members/list?notification={}'.format(html.escape(notification)))
|
||||
else:
|
||||
@@ -299,9 +297,9 @@ def payment_list(request, *args, **kwargs):
|
||||
payments = Payment.objects.all()
|
||||
|
||||
table = PaymentTable(payments,
|
||||
request=request,
|
||||
exclude=['id'],
|
||||
attrs={'class': 'table table-bordered table-hover'})
|
||||
request=request,
|
||||
exclude=['id'],
|
||||
attrs={'class': 'table table-bordered table-hover'})
|
||||
|
||||
table.paginate(page=request.GET.get('page', 1), per_page=25)
|
||||
table_html = convert_table_to_html(table, request)
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import random
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
|
||||
import django
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'sikweb.settings'
|
||||
from django.conf import settings
|
||||
|
||||
django.setup()
|
||||
#django related stuff should be imported below this
|
||||
from members.models import Member, Request
|
||||
from infoscreen.models import ExternalImageInfoItem, Rotation, InfoInstance
|
||||
from misc.namegenerator import generate_names
|
||||
MEMBERAMOUNT = 30
|
||||
MEMBERREQUESTAMOUNT = 3
|
||||
|
||||
print ("""THIS SCRIPT WILL GENERATE DUMMY VALUES TO DATABASE
|
||||
AND SHOULD __NEVER__ BE RUN ON PRODUCTION.
|
||||
IF YOU ARE ON PRODUCTION ABORT (ctrl-c) IMMEDIATELY!!!!
|
||||
CONTINUING IN 10 SECONDS""")
|
||||
time.sleep(10)
|
||||
|
||||
names = generate_names(MEMBERAMOUNT)
|
||||
maildomains = ["example.coms",'ggmail.om',"notmail.dom"] #intentionally wrong
|
||||
places = ["Helsinki", "Espoo", "Korso","Kerava", "Kouvostoliitto"]
|
||||
for i in range(MEMBERAMOUNT):
|
||||
f,l = names[i]
|
||||
mail = "{}.{}@{}".format(f.lower(),l.lower(),random.choice(maildomains))
|
||||
por = random.choice(places)
|
||||
ayy = random.randint(0,1)
|
||||
jas = random.randint(0,1)
|
||||
Member.objects.create(first_name=f,
|
||||
last_name=l,
|
||||
email=mail,
|
||||
POR=por,
|
||||
AYY=ayy,
|
||||
jas=jas)
|
||||
|
||||
i_item = ExternalImageInfoItem.objects.create(
|
||||
name="Heavy",
|
||||
url="https://i.imgur.com/XXSSqDG.gif"
|
||||
)
|
||||
rot = Rotation.objects.create(name="Demo")
|
||||
inst = InfoInstance.objects.create(
|
||||
rotation=rot,
|
||||
item=i_item,
|
||||
duration=20.0
|
||||
)
|
||||
|
||||
# for m in list(Member.objects.all())[:5]:
|
||||
# MemberRequest.objects.create(member=m)
|
||||
names = generate_names(MEMBERREQUESTAMOUNT)
|
||||
maildomains = ["example.coms",'ggmail.om',"notmail.dom"] #intentionally wrong
|
||||
places = ["Helsinki", "Espoo", "Korso","Kerava", "Kouvostoliitto"]
|
||||
for i in range(MEMBERREQUESTAMOUNT):
|
||||
f,l = names[i]
|
||||
mail = "{}.{}@{}".format(f.lower(),l.lower(),random.choice(maildomains))
|
||||
por = random.choice(places)
|
||||
ayy = random.randint(0,1)
|
||||
jas = random.randint(0,1)
|
||||
Request.objects.create(first_name=f,
|
||||
last_name=l,
|
||||
email=mail,
|
||||
POR=por,
|
||||
AYY=ayy,
|
||||
jas=jas)
|
||||
@@ -1,6 +1,7 @@
|
||||
import random
|
||||
import os
|
||||
|
||||
|
||||
def generate_names(n):
|
||||
'''
|
||||
generates list of n random names
|
||||
@@ -13,6 +14,5 @@ def generate_names(n):
|
||||
|
||||
names = []
|
||||
for i in range(n):
|
||||
names.append((random.choice(fs),random.choice(ls)))
|
||||
names.append((random.choice(fs), random.choice(ls)))
|
||||
return names
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[pep8]
|
||||
max-line-length = 120
|
||||
ignore = E501,E722
|
||||
exclude = '*/migrations/*'
|
||||
@@ -150,20 +150,20 @@ REST_FRAMEWORK = {
|
||||
# Email settings (tested working with gmail)
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST='smtp.gmail.com'
|
||||
EMAIL_PORT=587
|
||||
EMAIL_HOST = 'smtp.gmail.com'
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_HOST_USER = '<gmailtunnarisi>@gmail.com'
|
||||
EMAIL_HOST_PASSWORD = '<gmail_passu>'
|
||||
DEFAULT_FROM_EMAIL = 'SIK Viestintä <sikviestinta@gmail.com>'
|
||||
|
||||
|
||||
#ReCaptcha
|
||||
# ReCaptcha
|
||||
# http://www.yaconiello.com/blog/integrating-google-recaptcha-to-django/
|
||||
|
||||
GOOGLE_RECAPTCHA_SITE_KEY = "YOUR-PUBLIC-KEY"
|
||||
GOOGLE_RECAPTCHA_SECRET_KEY = "YOUR-PRIVATE-KEY"
|
||||
|
||||
#Logger level
|
||||
# Logger level
|
||||
|
||||
LOGGERLEVEL = logging.ERROR
|
||||
LOGPATH = "logs/debug.log"
|
||||
@@ -182,8 +182,6 @@ LOCALE_PATHS = (
|
||||
os.path.join(BASE_DIR, 'locale'),
|
||||
)
|
||||
|
||||
print("LOCALE_PATHS: {}".format(LOCALE_PATHS))
|
||||
|
||||
TIME_ZONE = 'Europe/Helsinki'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
+10
-12
@@ -28,19 +28,17 @@ import members.urls
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'', include('webapp.urls')),
|
||||
url(r'^members/', include('members.urls')),
|
||||
url(r'^infoscreen/', include('infoscreen.urls')),
|
||||
url(r'', include('webapp.urls')),
|
||||
url(r'^members/', include('members.urls')),
|
||||
url(r'^infoscreen/', include('infoscreen.urls')),
|
||||
|
||||
# admin
|
||||
url(r'^admin/', admin.site.urls),
|
||||
|
||||
# i18n default view for changing the active language
|
||||
url(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
|
||||
# staticfiles default view for static files in development
|
||||
url(r'^static/(?P<path>.*)$', static_views.serve),
|
||||
url(r'^media/(?P<path>.*)$', static_serve, {'document_root': settings.MEDIA_ROOT}),
|
||||
# admin
|
||||
url(r'^admin/', admin.site.urls),
|
||||
|
||||
# i18n default view for changing the active language
|
||||
url(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
|
||||
# staticfiles default view for static files in development
|
||||
url(r'^static/(?P<path>.*)$', static_views.serve),
|
||||
url(r'^media/(?P<path>.*)$', static_serve, {'document_root': settings.MEDIA_ROOT}),
|
||||
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
user_name = "admin"
|
||||
password = "password123"
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import time
|
||||
import random
|
||||
|
||||
from members.models import Member, Request
|
||||
from infoscreen.models import ExternalImageInfoItem, Rotation, InfoInstance
|
||||
from misc.namegenerator import generate_names
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
print('THIS SCRIPT WILL GENERATE DUMMY VALUES TO DATABASE '
|
||||
'AND SHOULD __NEVER__ BE RUN ON PRODUCTION. '
|
||||
'IF YOU ARE ON PRODUCTION ABORT (ctrl-c) IMMEDIATELY!!!! '
|
||||
'CONTINUING IN 10 SECONDS')
|
||||
|
||||
time.sleep(10)
|
||||
|
||||
DOMAINS = ["example.coms", 'ggmail.om', "notmail.dom"] # intentionally wrong
|
||||
PLACES = ["Helsinki", "Espoo", "Korso", "Kerava", "Kouvostoliitto"]
|
||||
MEMBER_COUNT = 30
|
||||
MEMBER_REQUEST_COUNT = 3
|
||||
|
||||
names = generate_names(MEMBER_COUNT)
|
||||
for i in range(MEMBER_COUNT):
|
||||
first, last = names[i]
|
||||
mail = "{}.{}@{}".format(first.lower(), last.lower(), random.choice(DOMAINS))
|
||||
|
||||
por = random.choice(PLACES)
|
||||
ayy = random.randint(0, 1)
|
||||
jas = random.randint(0, 1)
|
||||
Member.objects.create(first_name=first,
|
||||
last_name=last,
|
||||
email=mail,
|
||||
POR=por,
|
||||
AYY=ayy,
|
||||
jas=jas)
|
||||
|
||||
i_item = ExternalImageInfoItem.objects.create(
|
||||
name="Heavy",
|
||||
url="https://i.imgur.com/XXSSqDG.gif"
|
||||
)
|
||||
|
||||
rot = Rotation.objects.create(name="Demo")
|
||||
inst = InfoInstance.objects.create(
|
||||
rotation=rot,
|
||||
item=i_item,
|
||||
duration=20.0
|
||||
)
|
||||
|
||||
names = generate_names(MEMBER_COUNT)
|
||||
for i in range(MEMBER_COUNT):
|
||||
first, last = names[i]
|
||||
mail = "{}.{}@{}".format(first.lower(), last.lower(), random.choice(DOMAINS))
|
||||
|
||||
por = random.choice(PLACES)
|
||||
ayy = random.randint(0, 1)
|
||||
jas = random.randint(0, 1)
|
||||
Member.objects.create(first_name=first,
|
||||
last_name=last,
|
||||
email=mail,
|
||||
POR=por,
|
||||
AYY=ayy,
|
||||
jas=jas)
|
||||
@@ -1,8 +1,8 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
'''
|
||||
Creates initial skeleton for the webapp.
|
||||
@@ -10,19 +10,25 @@ class Command(BaseCommand):
|
||||
'''
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
|
||||
self.stdout.write("Creating sikadmin group")
|
||||
sikadmin_group, created = Group.objects.get_or_create(name="sikadmin")
|
||||
if not created:
|
||||
self.stdout.write("The group 'sikadmin' already existed and was not therefore created")
|
||||
self.stdout.write('The group "sikadmin" already existed'
|
||||
'and was not therefore created')
|
||||
|
||||
self.stdout.write("Creating sikadmin permission")
|
||||
group_ctype = ContentType.objects.get_for_model(Group) # TODO Use some sikadmin native model when such exists
|
||||
sikadmin_permission, created = Permission.objects.get_or_create(codename='sikadmin',
|
||||
content_type=group_ctype,
|
||||
name='SIK Admin')
|
||||
|
||||
# TODO Use some sikadmin native model when such exists
|
||||
group_ctype = ContentType.objects.get_for_model(Group)
|
||||
sikadmin_permission, created = Permission.objects.get_or_create(
|
||||
codename='sikadmin',
|
||||
content_type=group_ctype,
|
||||
name='SIK Admin')
|
||||
|
||||
if not created:
|
||||
self.stdout.write("The permission 'sikadmin' already existed and was not therefore created")
|
||||
self.stdout.write('The permission "sikadmin" already existed'
|
||||
'and was not therefore created')
|
||||
|
||||
self.stdout.write("Giving sikadmin group permission to sikadmin")
|
||||
if sikadmin_group.permissions.filter(id=sikadmin_permission.id).exists():
|
||||
@@ -31,4 +37,3 @@ class Command(BaseCommand):
|
||||
sikadmin_group.permissions.add(sikadmin_permission)
|
||||
|
||||
self.stdout.write("Initialization successful")
|
||||
|
||||
|
||||
+10
-5
@@ -1,8 +1,11 @@
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class Tag(models.Model):
|
||||
dummyname = models.CharField(max_length=127) # ALWAYS USE TRANSLATED NAME!!!
|
||||
# ALWAYS USE TRANSLATED NAME!!!
|
||||
dummyname = models.CharField(max_length=127)
|
||||
|
||||
|
||||
class TagTr(models.Model):
|
||||
'''
|
||||
@@ -12,21 +15,23 @@ class TagTr(models.Model):
|
||||
name = models.CharField(max_length=127)
|
||||
translation_for = models.ForeignKey('Tag', related_name='translations')
|
||||
|
||||
|
||||
class Info(models.Model):
|
||||
'''
|
||||
model containing something showing on some info feed
|
||||
'''
|
||||
publish_time = models.DateTimeField(default=timezone.now)
|
||||
#published_by = models.Foreignkey(User) #<-- TODO create usermodel
|
||||
tags = models.ManyToManyField(Tag,related_name="news")
|
||||
|
||||
# published_by = models.Foreignkey(User) #<-- TODO create usermodel
|
||||
tags = models.ManyToManyField(Tag, related_name="news")
|
||||
|
||||
|
||||
class InfoTr(models.Model):
|
||||
'''
|
||||
Model containing translations for news
|
||||
'''
|
||||
lang = models.CharField(max_length=2, default='fi')
|
||||
|
||||
|
||||
topic = models.CharField(max_length=255)
|
||||
content = models.TextField()
|
||||
translation_for = models.ForeignKey('Info', related_name='translations')
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
var app = angular.module('webApp', []);
|
||||
@@ -1,9 +1,10 @@
|
||||
{% load i18n %}
|
||||
<!DOCTYPE html>
|
||||
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load staticfiles %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="webApp">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@@ -11,26 +12,13 @@
|
||||
<meta name="author" content="veedeeämkoo">
|
||||
<link rel="stylesheet" href="{% static "css/webapp.css" %}">
|
||||
|
||||
<title>Aalto-yliopiston Sähköinsinöörikilta ry</title>
|
||||
<title>{% trans "Aalto-yliopiston Sähköinsinöörikilta ry" %}</title>
|
||||
|
||||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" rel = "stylesheet">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-route.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
|
||||
|
||||
<!-- DatePicker -->
|
||||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-messages.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-animate.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-aria.min.js"></script>
|
||||
|
||||
<script src="{% static "js/controllers.js" %}"></script>
|
||||
|
||||
<script src="{% static "js/lib/jquery-3.1.0.min.js" %}"></script>
|
||||
<script src="{% static "js/lib/bootstrap.min.js" %}"></script>
|
||||
<link rel="stylesheet" href="{% static "css/lib/bootstrap.min.css" %}">
|
||||
<script src="{% static "js/lib/underscore-min.js" %}"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
+6
-8
@@ -1,18 +1,16 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
# main
|
||||
from webapp.views import main_index
|
||||
from webapp.views import admin_index
|
||||
# login
|
||||
from webapp.views import login_view
|
||||
from webapp.views import logout_view
|
||||
|
||||
urlpatterns = [
|
||||
# main
|
||||
url(r'^$', main_index),
|
||||
url(r'^sikadmin$', admin_index),
|
||||
# main
|
||||
url(r'^$', main_index),
|
||||
url(r'^sikadmin$', admin_index),
|
||||
|
||||
# login stuff
|
||||
url(r'^login$', login_view),
|
||||
url(r'^logout$', logout_view),
|
||||
# login stuff
|
||||
url(r'^login$', login_view),
|
||||
url(r'^logout$', logout_view),
|
||||
]
|
||||
|
||||
+11
-5
@@ -6,20 +6,23 @@ from django.contrib.auth.decorators import permission_required
|
||||
from django.conf import settings
|
||||
import logging
|
||||
|
||||
webilogger = logging.getLogger(__name__)
|
||||
logging.basicConfig(format='[%(levelname)s]%(asctime)s %(message)s', level=settings.LOGGERLEVEL, filename=settings.LOGPATH)
|
||||
webapplogger = logging.getLogger(__name__)
|
||||
logging.basicConfig(format='[%(levelname)s]%(asctime)s %(message)s',
|
||||
level=settings.LOGGERLEVEL, filename=settings.LOGPATH)
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
def main_index(request, *args, **kwargs):
|
||||
return render(request, "main_index.html", {})
|
||||
|
||||
|
||||
@require_http_methods(["GET", "POST"])
|
||||
@ensure_csrf_cookie
|
||||
@permission_required('members.change_member', login_url='/login')
|
||||
def admin_index(request, *args, **kwargs):
|
||||
return render(request, "admin_index.html", {})
|
||||
|
||||
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def login_view(request, *args, **kwargs):
|
||||
if request.method == "POST":
|
||||
@@ -28,15 +31,18 @@ def login_view(request, *args, **kwargs):
|
||||
user = authenticate(username=uname, password=pw)
|
||||
if user is not None:
|
||||
login(request, user)
|
||||
original_site = request.GET.get("next",None) or "/"
|
||||
original_site = request.GET.get("next", None) or "/"
|
||||
return redirect(original_site)
|
||||
return render(request, "login.html", {"error" : "☹ Kirjautuminen kosahti. Yritä uudelleen!"})
|
||||
return render(request, "login.html", {"error": "☹ Kirjautuminen kosahti. Yritä uudelleen!"})
|
||||
|
||||
# user got here by a get request
|
||||
user = request.user
|
||||
if user.is_authenticated():
|
||||
return redirect("/") # user shoud not be here authenticated with get but get rid if is
|
||||
# user shoud not be here authenticated with get but get rid if is
|
||||
return redirect("/")
|
||||
return render(request, "login.html", {})
|
||||
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def logout_view(request, *args, **kwargs):
|
||||
logout(request)
|
||||
|
||||
Reference in New Issue
Block a user