Fix all pep8 and eslint errors :0
This commit is contained in:
+1
-2
@@ -29,7 +29,7 @@ pep8:
|
|||||||
stage: lint
|
stage: lint
|
||||||
script:
|
script:
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
- pep8 --exclude='*/migrations/*' --count .
|
- pep8 --config=setup.cfg --count .
|
||||||
|
|
||||||
eslint:
|
eslint:
|
||||||
image: node:7.10.0
|
image: node:7.10.0
|
||||||
@@ -37,4 +37,3 @@ eslint:
|
|||||||
script:
|
script:
|
||||||
- npm install -g eslint
|
- npm install -g eslint
|
||||||
- eslint .
|
- eslint .
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
from infoscreen.models import HSLDataModel
|
|
||||||
from django.conf import settings
|
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from infoscreen.models import HSLDataModel
|
||||||
|
|
||||||
|
|
||||||
class HSLFetcher:
|
class HSLFetcher:
|
||||||
|
|
||||||
last_fetched = datetime.fromtimestamp(0) # epoch
|
last_fetched = datetime.fromtimestamp(0) # epoch
|
||||||
INTERVAL = 1 # minutes
|
INTERVAL = 1 # minutes
|
||||||
logging.info("Set up scheduled HSL API fetch every {} minutes".format(INTERVAL))
|
logging.info("Set up scheduled HSL API fetch every {} minutes".format(INTERVAL))
|
||||||
@@ -25,13 +28,13 @@ class HSLFetcher:
|
|||||||
data = json.loads(src)
|
data = json.loads(src)
|
||||||
|
|
||||||
arr = []
|
arr = []
|
||||||
|
|
||||||
time=datetime.now()+timedelta(minutes = settings.HSL_DEPARTURE_THRESHOLD)
|
time = datetime.now() + timedelta(minute=settings.HSL_DEPARTURE_THRESHOLD)
|
||||||
time="{0:02d}{0:02d}".format(time.hour,time.minute)
|
time = "{0:02d}{0:02d}".format(time.hour, time.minute)
|
||||||
for element in data:
|
for element in data:
|
||||||
src = urllib.request.urlopen(
|
src = urllib.request.urlopen(
|
||||||
"https://api.reittiopas.fi/hsl/prod/?userhash={}&request=stop&code={}&dep_limit=20&time={}"
|
"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]
|
parsed = json.loads(src)[0]
|
||||||
arr.append({"name": parsed['name_fi'], "lines": parsed['lines'],
|
arr.append({"name": parsed['name_fi'], "lines": parsed['lines'],
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from infoscreen.hsl_fetcher import HSLFetcher
|
from infoscreen.hsl_fetcher import HSLFetcher
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Loads HSL timetables and save to json file.'
|
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.db import models
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from datetime import datetime
|
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
|
||||||
class InfoItem(models.Model):
|
class InfoItem(models.Model):
|
||||||
|
|
||||||
class __meta__:
|
class __meta__:
|
||||||
@@ -73,27 +75,30 @@ class InfoItem(models.Model):
|
|||||||
|
|
||||||
class ABBInfoItem(InfoItem):
|
class ABBInfoItem(InfoItem):
|
||||||
display_name = _("ABB jobs")
|
display_name = _("ABB jobs")
|
||||||
|
|
||||||
def get_template_url(self):
|
def get_template_url(self):
|
||||||
return "/static/html/abb.html"
|
return "/static/html/abb.html"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_create_template_url():
|
def get_create_template_url():
|
||||||
return "/static/html/abb_create.html"
|
return "/static/html/abb_create.html"
|
||||||
|
|
||||||
|
|
||||||
class ApyInfoItem(InfoItem):
|
class ApyInfoItem(InfoItem):
|
||||||
display_name = _("APY Item")
|
display_name = _("APY Item")
|
||||||
|
|
||||||
def get_template_url(self):
|
def get_template_url(self):
|
||||||
return "/static/html/apy.html"
|
return "/static/html/apy.html"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_create_template_url():
|
def get_create_template_url():
|
||||||
return "/static/html/apy_create.html"
|
return "/static/html/apy_create.html"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExternalWebsiteInfoItem(InfoItem):
|
class ExternalWebsiteInfoItem(InfoItem):
|
||||||
display_name = _("External website")
|
display_name = _("External website")
|
||||||
url = models.TextField()
|
url = models.TextField()
|
||||||
|
|
||||||
def get_template_url(self):
|
def get_template_url(self):
|
||||||
return "/static/html/external_website.html?url={}".format(self.name)
|
return "/static/html/external_website.html?url={}".format(self.name)
|
||||||
|
|
||||||
@@ -114,8 +119,8 @@ class ExternalWebsiteInfoItem(InfoItem):
|
|||||||
|
|
||||||
def get_list(self):
|
def get_list(self):
|
||||||
return {
|
return {
|
||||||
'id':self.id,
|
'id': self.id,
|
||||||
'name':self.name,
|
'name': self.name,
|
||||||
'url': self.url,
|
'url': self.url,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +142,10 @@ class ExternalWebsiteInfoItem(InfoItem):
|
|||||||
pass
|
pass
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
|
||||||
class SossoInfoItem(InfoItem):
|
class SossoInfoItem(InfoItem):
|
||||||
display_name = _("Sössö articles")
|
display_name = _("Sössö articles")
|
||||||
|
|
||||||
def get_template_url(self):
|
def get_template_url(self):
|
||||||
return "/static/html/sosso.html"
|
return "/static/html/sosso.html"
|
||||||
|
|
||||||
@@ -146,6 +153,7 @@ class SossoInfoItem(InfoItem):
|
|||||||
def get_create_template_url():
|
def get_create_template_url():
|
||||||
return "/static/html/sosso_create.html"
|
return "/static/html/sosso_create.html"
|
||||||
|
|
||||||
|
|
||||||
class EventInfoItem(InfoItem):
|
class EventInfoItem(InfoItem):
|
||||||
display_name = _("Events")
|
display_name = _("Events")
|
||||||
|
|
||||||
@@ -157,7 +165,6 @@ class EventInfoItem(InfoItem):
|
|||||||
return "/static/html/events_create.html"
|
return "/static/html/events_create.html"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ImageInfoItem(InfoItem):
|
class ImageInfoItem(InfoItem):
|
||||||
display_name = _("Image")
|
display_name = _("Image")
|
||||||
img = models.ImageField(upload_to="infoimages/")
|
img = models.ImageField(upload_to="infoimages/")
|
||||||
@@ -178,6 +185,7 @@ class ImageInfoItem(InfoItem):
|
|||||||
|
|
||||||
class HslInfoItem(InfoItem):
|
class HslInfoItem(InfoItem):
|
||||||
display_name = _("HSL timetables")
|
display_name = _("HSL timetables")
|
||||||
|
|
||||||
def get_template_url(self):
|
def get_template_url(self):
|
||||||
return "/static/html/hsl.html"
|
return "/static/html/hsl.html"
|
||||||
|
|
||||||
@@ -275,15 +283,15 @@ class Rotation(models.Model):
|
|||||||
instance_list = list(map(lambda i: i.get_dict(), filtered))
|
instance_list = list(map(lambda i: i.get_dict(), filtered))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id':self.id,
|
'id': self.id,
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'instances': instance_list,
|
'instances': instance_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_list(self):
|
def get_list(self):
|
||||||
return {
|
return {
|
||||||
'id':self.id,
|
'id': self.id,
|
||||||
'name':self.name,
|
'name': self.name,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ app.service("InstanceList", ["$http", function($http){
|
|||||||
'item_type': item_type,
|
'item_type': item_type,
|
||||||
'duration': duration,
|
'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);
|
self.getRotation(rotation_id);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -46,7 +46,7 @@ app.service("InstanceList", ["$http", function($http){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.deleteInstance = function(id){
|
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);
|
self.getRotation(self.selected_rot.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ app.service("InstanceList", ["$http", function($http){
|
|||||||
$http.post("/infoscreen/create_rotation", data);
|
$http.post("/infoscreen/create_rotation", data);
|
||||||
}
|
}
|
||||||
this.deleteRotation = function(id) {
|
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);
|
InstanceList.getRotation(InstanceList.selected_rot.id);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.refreshCB = function(response){
|
this.refreshCB = function(response) { //eslint-disable-line no-unused-vars
|
||||||
self.loadItems();
|
self.loadItems();
|
||||||
};
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ app.controller('infoscreen_main', function($scope,$http,$timeout){
|
|||||||
else {
|
else {
|
||||||
$scope.next();
|
$scope.next();
|
||||||
}
|
}
|
||||||
},function(response){
|
},function(response) { //eslint-disable-line no-unused-vars
|
||||||
$timeout(get_rotation, 10000);
|
$timeout(get_rotation, 10000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -107,12 +107,12 @@ app.controller('timetableCtrl',
|
|||||||
function($scope, $http, $interval) {
|
function($scope, $http, $interval) {
|
||||||
function load(){
|
function load(){
|
||||||
$http.get('/infoscreen/hsl_data')
|
$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=[];
|
$scope.arr=[];
|
||||||
parse(data);
|
parse(data);
|
||||||
});
|
});
|
||||||
$http.get('/infoscreen/hsl_data/settings')
|
$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.departureThreshold = data.data['departure_threshold'];
|
||||||
$scope.hurryThreshold = data.data['hurry_threshold'];
|
$scope.hurryThreshold = data.data['hurry_threshold'];
|
||||||
});
|
});
|
||||||
@@ -139,8 +139,8 @@ app.controller('timetableCtrl',
|
|||||||
var line = stop['departures'][lineIndex];
|
var line = stop['departures'][lineIndex];
|
||||||
var time = line['time'];
|
var time = line['time'];
|
||||||
var date = line['date'];
|
var date = line['date'];
|
||||||
var hours = Math.floor(line['time'] / 100);
|
var hours = Math.floor(time / 100);
|
||||||
var minutes = line['time'] % 100;
|
var minutes = time % 100;
|
||||||
if (hours >= 24) {
|
if (hours >= 24) {
|
||||||
hours -= 24;
|
hours -= 24;
|
||||||
date++;
|
date++;
|
||||||
@@ -198,12 +198,12 @@ app.controller('timetableCtrl',
|
|||||||
function delOld(){
|
function delOld(){
|
||||||
var tooSoon = typeof($scope.departureThreshold) != 'undefined' ? $scope.departureThreshold: 0;
|
var tooSoon = typeof($scope.departureThreshold) != 'undefined' ? $scope.departureThreshold: 0;
|
||||||
var hurry = typeof($scope.hurryThreshold) != 'undefined' ? $scope.hurryThreshold : 0;
|
var hurry = typeof($scope.hurryThreshold) != 'undefined' ? $scope.hurryThreshold : 0;
|
||||||
f = new Date();
|
var f = new Date();
|
||||||
for(var a=$scope.arr.length-1; a>=0; a--){
|
for (var a=$scope.arr.length-1; a>=0; a--) {
|
||||||
var time=$scope.arr[a]['time'].split(":");
|
var time=$scope.arr[a]['time'].split(":");
|
||||||
date=$scope.arr[a]['date'].toString();
|
var date=$scope.arr[a]['date'].toString();
|
||||||
d= new Date(f);
|
var d = new Date(f);
|
||||||
d.setFullYear(date.substring(0,4),date.substring(4,6)-1,date.substring(6,8));
|
d.setFullYear(date.substring(0,4), date.substring(4,6)-1, date.substring(6,8));
|
||||||
d.setHours(time[0]);
|
d.setHours(time[0]);
|
||||||
d.setMinutes(time[1]);
|
d.setMinutes(time[1]);
|
||||||
var diff=(d.getTime()-f.getTime());
|
var diff=(d.getTime()-f.getTime());
|
||||||
|
|||||||
+16
-14
@@ -4,36 +4,38 @@ from infoscreen.models import SossoInfoItem
|
|||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
import infoscreen.views
|
import infoscreen.views
|
||||||
|
|
||||||
'''
|
|
||||||
Test cases for testing infoscreen methods
|
|
||||||
'''
|
|
||||||
class InfoscreenTestCase(TestCase):
|
class InfoscreenTestCase(TestCase):
|
||||||
'''
|
'''
|
||||||
Create some dummy models
|
Test cases for testing infoscreen methods
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
'''
|
||||||
|
Create some dummy models
|
||||||
|
'''
|
||||||
Rotation.objects.create(name="test_rot")
|
Rotation.objects.create(name="test_rot")
|
||||||
SossoInfoItem.objects.create()
|
SossoInfoItem.objects.create()
|
||||||
|
|
||||||
'''
|
|
||||||
Check if the dummy model actually exists
|
|
||||||
'''
|
|
||||||
def test_rotation_created(self):
|
def test_rotation_created(self):
|
||||||
|
'''
|
||||||
|
Check if the dummy model actually exists
|
||||||
|
'''
|
||||||
rot = Rotation.objects.get(name="test_rot")
|
rot = Rotation.objects.get(name="test_rot")
|
||||||
self.assertIsNotNone(rot)
|
self.assertIsNotNone(rot)
|
||||||
|
|
||||||
'''
|
|
||||||
Check if the dummy model actually exists
|
|
||||||
'''
|
|
||||||
def test_sosso_infoitem_created(self):
|
def test_sosso_infoitem_created(self):
|
||||||
|
'''
|
||||||
|
Check if the dummy model actually exists
|
||||||
|
'''
|
||||||
item = SossoInfoItem.objects.get()
|
item = SossoInfoItem.objects.get()
|
||||||
self.assertIsNotNone(item)
|
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):
|
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()
|
req = HttpRequest()
|
||||||
resp = infoscreen.views.info_items(req)
|
resp = infoscreen.views.info_items(req)
|
||||||
content = resp.content.decode('utf-8')
|
content = resp.content.decode('utf-8')
|
||||||
|
|||||||
+23
-25
@@ -1,6 +1,5 @@
|
|||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
#infoscreen
|
|
||||||
from infoscreen.views import index
|
from infoscreen.views import index
|
||||||
from infoscreen.views import admin
|
from infoscreen.views import admin
|
||||||
from infoscreen.views import default
|
from infoscreen.views import default
|
||||||
@@ -26,28 +25,27 @@ from infoscreen.views import hsl_timetable_settings
|
|||||||
from infoscreen.views import get_apy_json
|
from infoscreen.views import get_apy_json
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
#infoscreen
|
url(r'^$', default),
|
||||||
url(r'^$', default),
|
url(r'^admin$', admin),
|
||||||
url(r'^admin$', admin),
|
url(r'^(?P<idx>\d+)$', index),
|
||||||
url(r'^(?P<idx>\d+)$', index),
|
url(r'^items$', info_items),
|
||||||
url(r'^items$', info_items),
|
url(r'^rotation/(?P<idx>\d+)$', rotation),
|
||||||
url(r'^rotation/(?P<idx>\d+)$', rotation),
|
url(r'^rotations$', rotations),
|
||||||
url(r'^rotations$', rotations),
|
url(r'^instance$', createInstance),
|
||||||
url(r'^instance$', createInstance),
|
url(r'^instance/(?P<idx>\d+)$', deleteInstance),
|
||||||
url(r'^instance/(?P<idx>\d+)$', deleteInstance),
|
url(r'^types$', info_types),
|
||||||
url(r'^types$', info_types),
|
url(r'^delete_item/(?P<type_id>\d+)/(?P<idx>\d+)$', delete_info_item),
|
||||||
url(r'^delete_item/(?P<type_id>\d+)/(?P<idx>\d+)$', delete_info_item),
|
url(r'^create_external_image$', createExternalImageInfoItem),
|
||||||
url(r'^create_external_image$', createExternalImageInfoItem),
|
url(r'^create_image$', create_image_item),
|
||||||
url(r'^create_image$', create_image_item),
|
url(r'^create_abbitem$', createABBItem),
|
||||||
url(r'^create_abbitem$', createABBItem),
|
url(r'^create_sossoitem$', createSossoItem),
|
||||||
url(r'^create_sossoitem$', createSossoItem),
|
url(r'^create_eventitem$', createEventItem),
|
||||||
url(r'^create_eventitem$', createEventItem),
|
url(r'^create_hslitem$', createHslItem),
|
||||||
url(r'^create_hslitem$', createHslItem),
|
url(r'^create_apyitem$', createApyItem),
|
||||||
url(r'^create_apyitem$', createApyItem),
|
url(r'^create_websiteitem$', createExternalWebsiteItem),
|
||||||
url(r'^create_websiteitem$', createExternalWebsiteItem),
|
url(r'^create_rotation$', create_rotation),
|
||||||
url(r'^create_rotation$', create_rotation),
|
url(r'^delete_rotation/(?P<id>\d+)$', delete_rotation),
|
||||||
url(r'^delete_rotation/(?P<id>\d+)$', delete_rotation),
|
url(r'^hsl_data$', CurrentHSLView),
|
||||||
url(r'^hsl_data$', CurrentHSLView),
|
url(r'^hsl_data/settings$', hsl_timetable_settings),
|
||||||
url(r'^hsl_data/settings$', hsl_timetable_settings),
|
url(r'^apyjson', get_apy_json),
|
||||||
url(r'^apyjson', get_apy_json),
|
|
||||||
]
|
]
|
||||||
|
|||||||
+14
-11
@@ -1,10 +1,16 @@
|
|||||||
from django.shortcuts import render
|
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.csrf import ensure_csrf_cookie
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.auth.decorators import permission_required
|
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 Rotation, InfoItem, InfoInstance
|
||||||
from infoscreen.models import ABBInfoItem, ExternalImageInfoItem, ImageInfoItem, SossoInfoItem, HslInfoItem
|
from infoscreen.models import ABBInfoItem, ExternalImageInfoItem, ImageInfoItem, SossoInfoItem, HslInfoItem
|
||||||
from infoscreen.models import EventInfoItem
|
from infoscreen.models import EventInfoItem
|
||||||
@@ -13,11 +19,6 @@ from infoscreen.models import ImageUploadForm
|
|||||||
from infoscreen.models import HSLDataModel
|
from infoscreen.models import HSLDataModel
|
||||||
from infoscreen.models import ApyInfoItem
|
from infoscreen.models import ApyInfoItem
|
||||||
from infoscreen.hsl_fetcher import HSLFetcher
|
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):
|
def index(request, idx, *args, **kwargs):
|
||||||
@@ -29,17 +30,18 @@ def admin(request, *args, **kwargs):
|
|||||||
return render(request, 'infoscreen_admin.html', {})
|
return render(request, 'infoscreen_admin.html', {})
|
||||||
|
|
||||||
|
|
||||||
def default(request,*args,**kwargs):
|
def default(request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
first = Rotation.objects.all()[0].id
|
first = Rotation.objects.all()[0].id
|
||||||
except:
|
except:
|
||||||
first = 0
|
first = 0
|
||||||
return index(request,first ,*args, **kwargs)
|
return index(request, first, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def get_apy_json(request):
|
def get_apy_json(request):
|
||||||
return HttpResponse(requests.get("https://api-diilikone.apy.fi/deals/top-groups").text)
|
return HttpResponse(requests.get("https://api-diilikone.apy.fi/deals/top-groups").text)
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def rotation(request, idx, *args, **kwargs):
|
def rotation(request, idx, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
@@ -65,7 +67,7 @@ def create_item_generator(model):
|
|||||||
model.create_from_dict(data)
|
model.create_from_dict(data)
|
||||||
return HttpResponse('{"status":"success"}')
|
return HttpResponse('{"status":"success"}')
|
||||||
except RuntimeError as e:
|
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
|
return create_item
|
||||||
|
|
||||||
|
|
||||||
@@ -145,7 +147,7 @@ def info_items(request, *args, **kwargs):
|
|||||||
@ensure_csrf_cookie
|
@ensure_csrf_cookie
|
||||||
@permission_required('infoscreen.change_infoinstance', login_url='/login')
|
@permission_required('infoscreen.change_infoinstance', login_url='/login')
|
||||||
def create_image_item(request, *args, **kwargs):
|
def create_image_item(request, *args, **kwargs):
|
||||||
form = ImageUploadForm(request.POST,request.FILES)
|
form = ImageUploadForm(request.POST, request.FILES)
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return HttpResponseBadRequest('{"status": "failure",'
|
return HttpResponseBadRequest('{"status": "failure",'
|
||||||
'"error": "invalid data supplied"}')
|
'"error": "invalid data supplied"}')
|
||||||
@@ -191,6 +193,7 @@ def delete_rotation(request, *args, **kwargs):
|
|||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def hsl_timetable_settings(request, *args, **kwargs):
|
def hsl_timetable_settings(request, *args, **kwargs):
|
||||||
d = {"departure_threshold": settings.HSL_DEPARTURE_THRESHOLD,
|
d = {"departure_threshold": settings.HSL_DEPARTURE_THRESHOLD,
|
||||||
@@ -198,6 +201,7 @@ def hsl_timetable_settings(request, *args, **kwargs):
|
|||||||
resp = json.dumps(d)
|
resp = json.dumps(d)
|
||||||
return HttpResponse(resp, status=200)
|
return HttpResponse(resp, status=200)
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def CurrentHSLView(request, *args, **kwargs):
|
def CurrentHSLView(request, *args, **kwargs):
|
||||||
|
|
||||||
@@ -213,7 +217,6 @@ def CurrentHSLView(request, *args, **kwargs):
|
|||||||
return HttpResponse(data[len(data) - 1].data, status=200)
|
return HttpResponse(data[len(data) - 1].data, status=200)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
createInstance = create_item_generator(InfoInstance)
|
createInstance = create_item_generator(InfoInstance)
|
||||||
deleteInstance = delete_item_generator(InfoInstance)
|
deleteInstance = delete_item_generator(InfoInstance)
|
||||||
createABBItem = create_item_generator(ABBInfoItem)
|
createABBItem = create_item_generator(ABBInfoItem)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class MembersConfig(AppConfig):
|
class MembersConfig(AppConfig):
|
||||||
name = 'members'
|
name = 'members'
|
||||||
|
|||||||
+2
-1
@@ -16,8 +16,9 @@ class PaymentForm(forms.ModelForm):
|
|||||||
model = Payment
|
model = Payment
|
||||||
fields = ['date', 'source', 'member']
|
fields = ['date', 'source', 'member']
|
||||||
|
|
||||||
|
|
||||||
class ApplicationForm(forms.ModelForm):
|
class ApplicationForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Request
|
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],
|
POR=array[3],
|
||||||
AYY=bool(array[4]),
|
AYY=bool(array[4]),
|
||||||
jas=bool(array[5]),
|
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(
|
options = tables.TemplateColumn(
|
||||||
'<a class="data-table-button btn btn-primary" href="/members/edit/{{ record.id }}">' +
|
'<a class="data-table-button btn btn-primary" href="/members/edit/{{ record.id }}">' +
|
||||||
_('Edit') +
|
_('Edit') +
|
||||||
'</a>'
|
'</a>'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ class PaymentTable(tables.Table):
|
|||||||
|
|
||||||
options = tables.TemplateColumn(
|
options = tables.TemplateColumn(
|
||||||
'<a class="data-table-button btn btn-primary" href="/members/edit_payment/{{ record.id }}">' +
|
'<a class="data-table-button btn btn-primary" href="/members/edit_payment/{{ record.id }}">' +
|
||||||
_('Edit') +
|
_('Edit') +
|
||||||
'</a>'
|
'</a>'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -1,9 +1,11 @@
|
|||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
from members.models import Member
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from members.models import Member
|
||||||
|
|
||||||
|
|
||||||
class MemberRegisterTestCase(TestCase):
|
class MemberRegisterTestCase(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
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
|
from django.views.generic.base import RedirectView
|
||||||
|
|
||||||
# members
|
# members
|
||||||
from members.views import member_list, payment_add, payment_submit, application_delete_confirm, application_delete, \
|
from members.views import member_list, payment_add, payment_submit
|
||||||
application_accept, import_csv, export_csv
|
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 settings_page, payment_edit
|
||||||
from members.views import payment_delete_confirm
|
from members.views import payment_delete_confirm
|
||||||
from members.views import payment_delete, payment_update
|
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 = [
|
urlpatterns = [
|
||||||
|
|
||||||
# landing page
|
# landing page
|
||||||
url(r'^$', member_list),
|
url(r'^$', member_list),
|
||||||
url(r'^list$', member_list),
|
url(r'^list$', member_list),
|
||||||
|
|
||||||
# add member form view
|
# add member form view
|
||||||
url(r'^add$', member_add),
|
url(r'^add$', member_add),
|
||||||
|
|
||||||
# add many members view
|
# add many members view
|
||||||
url(r'^add_many$', member_add_many),
|
url(r'^add_many$', member_add_many),
|
||||||
|
|
||||||
# edit member information view
|
# edit member information view
|
||||||
url(r'^edit/(?P<index>\d+)$', member_edit),
|
url(r'^edit/(?P<index>\d+)$', member_edit),
|
||||||
|
|
||||||
# delete confirmation view
|
# delete confirmation view
|
||||||
url(r'^delete_member_confirm/(?P<index>\d+)$', member_delete_confirm),
|
url(r'^delete_member_confirm/(?P<index>\d+)$', member_delete_confirm),
|
||||||
|
|
||||||
# list all member applications
|
# list all member applications
|
||||||
url(r'^applications$', application_list),
|
url(r'^applications$', application_list),
|
||||||
|
|
||||||
# edit member application
|
# edit member application
|
||||||
url(r'^edit_application/(?P<index>\d+)$', application_edit),
|
url(r'^edit_application/(?P<index>\d+)$', application_edit),
|
||||||
|
|
||||||
# post request targets
|
# post request targets
|
||||||
url(r'^submit_member$', member_submit),
|
url(r'^submit_member$', member_submit),
|
||||||
url(r'^update_member$', member_update),
|
url(r'^update_member$', member_update),
|
||||||
url(r'^delete_member$', member_delete),
|
url(r'^delete_member$', member_delete),
|
||||||
url(r'^submit_payment$', payment_submit),
|
url(r'^submit_payment$', payment_submit),
|
||||||
url(r'^update_payment$', payment_update),
|
url(r'^update_payment$', payment_update),
|
||||||
url(r'^delete_payment$', payment_delete),
|
url(r'^delete_payment$', payment_delete),
|
||||||
url(r'^accept_application$', application_accept),
|
url(r'^accept_application$', application_accept),
|
||||||
url(r'^delete_application$', application_delete),
|
url(r'^delete_application$', application_delete),
|
||||||
|
|
||||||
# the actual member application form
|
# the actual member application form
|
||||||
url(r'^application/$', application_form),
|
url(r'^application/$', application_form),
|
||||||
|
|
||||||
# success page for the application
|
# success page for the application
|
||||||
url(r'^application/success$', application_form_success),
|
url(r'^application/success$', application_form_success),
|
||||||
|
|
||||||
# delete confirmation view for applications
|
# delete confirmation view for applications
|
||||||
url(r'^delete_application_confirm/(?P<index>\d+)$', application_delete_confirm),
|
url(r'^delete_application_confirm/(?P<index>\d+)$', application_delete_confirm),
|
||||||
|
|
||||||
# list all payment events
|
# list all payment events
|
||||||
url(r'^payments$', payment_list),
|
url(r'^payments$', payment_list),
|
||||||
|
|
||||||
# add payment event
|
# add payment event
|
||||||
url(r'^add_payment$', payment_add),
|
url(r'^add_payment$', payment_add),
|
||||||
|
|
||||||
# edit payment event
|
# edit payment event
|
||||||
url(r'^edit_payment/(?P<index>\d+)$', payment_edit),
|
url(r'^edit_payment/(?P<index>\d+)$', payment_edit),
|
||||||
|
|
||||||
# delete confirmation view
|
# delete confirmation view
|
||||||
url(r'^delete_payment_confirm/(?P<index>\d+)$', payment_delete_confirm),
|
url(r'^delete_payment_confirm/(?P<index>\d+)$', payment_delete_confirm),
|
||||||
|
|
||||||
# settings page
|
# settings page
|
||||||
url(r'^settings$', settings_page),
|
url(r'^settings$', settings_page),
|
||||||
|
|
||||||
# send CSV member data by POST
|
# send CSV member data by POST
|
||||||
url(r'^import_csv', import_csv),
|
url(r'^import_csv', import_csv),
|
||||||
|
|
||||||
# download CSV member data
|
# download CSV member data
|
||||||
url(r'^export_csv', export_csv),
|
url(r'^export_csv', export_csv),
|
||||||
|
|
||||||
# favourite icon
|
# favourite icon
|
||||||
url(r'^favicon\.ico$', favicon_view),
|
url(r'^favicon\.ico$', favicon_view),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
+14
-16
@@ -47,13 +47,11 @@ def validate_recaptcha(response):
|
|||||||
|
|
||||||
|
|
||||||
def send_mail_wrapper(subject, message):
|
def send_mail_wrapper(subject, message):
|
||||||
send_mail(
|
send_mail(subject,
|
||||||
subject,
|
message,
|
||||||
message,
|
'no-reply@sahkoinsinoorikilta.fi',
|
||||||
'no-reply@sahkoinsinoorikilta.fi',
|
['viestintamestari@sahkoinsinoorikilta.fi'],
|
||||||
['viestintamestari@sahkoinsinoorikilta.fi'],
|
fail_silently=False)
|
||||||
fail_silently=False
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def convert_table_to_html(table, request):
|
def convert_table_to_html(table, request):
|
||||||
@@ -84,10 +82,10 @@ def member_list(request, *args, **kwargs):
|
|||||||
members = Member.objects.all()
|
members = Member.objects.all()
|
||||||
|
|
||||||
table = MemberTable(members,
|
table = MemberTable(members,
|
||||||
request=request,
|
request=request,
|
||||||
exclude=['id'],
|
exclude=['id'],
|
||||||
attrs={'class': 'table table-bordered table-hover'},
|
attrs={'class': 'table table-bordered table-hover'})
|
||||||
)
|
|
||||||
table.paginate(page=request.GET.get('page', 1), per_page=25)
|
table.paginate(page=request.GET.get('page', 1), per_page=25)
|
||||||
table_html = convert_table_to_html(table, request)
|
table_html = convert_table_to_html(table, request)
|
||||||
|
|
||||||
@@ -136,8 +134,8 @@ def member_submit(request, *args, **kwargs):
|
|||||||
form.save()
|
form.save()
|
||||||
memberlogger.info("Saved new member to member register with the following info: {}".format(form))
|
memberlogger.info("Saved new member to member register with the following info: {}".format(form))
|
||||||
notification = "{} {} {}.".format(_("Successfully added member"),
|
notification = "{} {} {}.".format(_("Successfully added member"),
|
||||||
form.cleaned_data['last_name'],
|
form.cleaned_data['last_name'],
|
||||||
form.cleaned_data['first_name'])
|
form.cleaned_data['first_name'])
|
||||||
|
|
||||||
return HttpResponseRedirect('/members/list?notification={}'.format(html.escape(notification)))
|
return HttpResponseRedirect('/members/list?notification={}'.format(html.escape(notification)))
|
||||||
else:
|
else:
|
||||||
@@ -299,9 +297,9 @@ def payment_list(request, *args, **kwargs):
|
|||||||
payments = Payment.objects.all()
|
payments = Payment.objects.all()
|
||||||
|
|
||||||
table = PaymentTable(payments,
|
table = PaymentTable(payments,
|
||||||
request=request,
|
request=request,
|
||||||
exclude=['id'],
|
exclude=['id'],
|
||||||
attrs={'class': 'table table-bordered table-hover'})
|
attrs={'class': 'table table-bordered table-hover'})
|
||||||
|
|
||||||
table.paginate(page=request.GET.get('page', 1), per_page=25)
|
table.paginate(page=request.GET.get('page', 1), per_page=25)
|
||||||
table_html = convert_table_to_html(table, request)
|
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 random
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def generate_names(n):
|
def generate_names(n):
|
||||||
'''
|
'''
|
||||||
generates list of n random names
|
generates list of n random names
|
||||||
@@ -13,6 +14,5 @@ def generate_names(n):
|
|||||||
|
|
||||||
names = []
|
names = []
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
names.append((random.choice(fs),random.choice(ls)))
|
names.append((random.choice(fs), random.choice(ls)))
|
||||||
return names
|
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 settings (tested working with gmail)
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
EMAIL_USE_TLS = True
|
EMAIL_USE_TLS = True
|
||||||
EMAIL_HOST='smtp.gmail.com'
|
EMAIL_HOST = 'smtp.gmail.com'
|
||||||
EMAIL_PORT=587
|
EMAIL_PORT = 587
|
||||||
EMAIL_HOST_USER = '<gmailtunnarisi>@gmail.com'
|
EMAIL_HOST_USER = '<gmailtunnarisi>@gmail.com'
|
||||||
EMAIL_HOST_PASSWORD = '<gmail_passu>'
|
EMAIL_HOST_PASSWORD = '<gmail_passu>'
|
||||||
DEFAULT_FROM_EMAIL = 'SIK Viestintä <sikviestinta@gmail.com>'
|
DEFAULT_FROM_EMAIL = 'SIK Viestintä <sikviestinta@gmail.com>'
|
||||||
|
|
||||||
|
|
||||||
#ReCaptcha
|
# ReCaptcha
|
||||||
# http://www.yaconiello.com/blog/integrating-google-recaptcha-to-django/
|
# http://www.yaconiello.com/blog/integrating-google-recaptcha-to-django/
|
||||||
|
|
||||||
GOOGLE_RECAPTCHA_SITE_KEY = "YOUR-PUBLIC-KEY"
|
GOOGLE_RECAPTCHA_SITE_KEY = "YOUR-PUBLIC-KEY"
|
||||||
GOOGLE_RECAPTCHA_SECRET_KEY = "YOUR-PRIVATE-KEY"
|
GOOGLE_RECAPTCHA_SECRET_KEY = "YOUR-PRIVATE-KEY"
|
||||||
|
|
||||||
#Logger level
|
# Logger level
|
||||||
|
|
||||||
LOGGERLEVEL = logging.ERROR
|
LOGGERLEVEL = logging.ERROR
|
||||||
LOGPATH = "logs/debug.log"
|
LOGPATH = "logs/debug.log"
|
||||||
@@ -182,8 +182,6 @@ LOCALE_PATHS = (
|
|||||||
os.path.join(BASE_DIR, 'locale'),
|
os.path.join(BASE_DIR, 'locale'),
|
||||||
)
|
)
|
||||||
|
|
||||||
print("LOCALE_PATHS: {}".format(LOCALE_PATHS))
|
|
||||||
|
|
||||||
TIME_ZONE = 'Europe/Helsinki'
|
TIME_ZONE = 'Europe/Helsinki'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|||||||
+10
-12
@@ -28,19 +28,17 @@ import members.urls
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'', include('webapp.urls')),
|
url(r'', include('webapp.urls')),
|
||||||
url(r'^members/', include('members.urls')),
|
url(r'^members/', include('members.urls')),
|
||||||
url(r'^infoscreen/', include('infoscreen.urls')),
|
url(r'^infoscreen/', include('infoscreen.urls')),
|
||||||
|
|
||||||
# admin
|
# admin
|
||||||
url(r'^admin/', admin.site.urls),
|
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}),
|
|
||||||
|
|
||||||
|
# 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)
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
user_name = "admin"
|
user_name = "admin"
|
||||||
password = "password123"
|
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.core.management.base import BaseCommand, CommandError
|
||||||
|
|
||||||
from django.contrib.auth.models import Group, Permission
|
from django.contrib.auth.models import Group, Permission
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
'''
|
||||||
Creates initial skeleton for the webapp.
|
Creates initial skeleton for the webapp.
|
||||||
@@ -10,19 +10,25 @@ class Command(BaseCommand):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
|
||||||
self.stdout.write("Creating sikadmin group")
|
self.stdout.write("Creating sikadmin group")
|
||||||
sikadmin_group, created = Group.objects.get_or_create(name="sikadmin")
|
sikadmin_group, created = Group.objects.get_or_create(name="sikadmin")
|
||||||
if not created:
|
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")
|
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',
|
# TODO Use some sikadmin native model when such exists
|
||||||
content_type=group_ctype,
|
group_ctype = ContentType.objects.get_for_model(Group)
|
||||||
name='SIK Admin')
|
sikadmin_permission, created = Permission.objects.get_or_create(
|
||||||
|
codename='sikadmin',
|
||||||
|
content_type=group_ctype,
|
||||||
|
name='SIK Admin')
|
||||||
|
|
||||||
if not created:
|
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")
|
self.stdout.write("Giving sikadmin group permission to sikadmin")
|
||||||
if sikadmin_group.permissions.filter(id=sikadmin_permission.id).exists():
|
if sikadmin_group.permissions.filter(id=sikadmin_permission.id).exists():
|
||||||
@@ -31,4 +37,3 @@ class Command(BaseCommand):
|
|||||||
sikadmin_group.permissions.add(sikadmin_permission)
|
sikadmin_group.permissions.add(sikadmin_permission)
|
||||||
|
|
||||||
self.stdout.write("Initialization successful")
|
self.stdout.write("Initialization successful")
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -1,8 +1,11 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
class Tag(models.Model):
|
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):
|
class TagTr(models.Model):
|
||||||
'''
|
'''
|
||||||
@@ -12,21 +15,23 @@ class TagTr(models.Model):
|
|||||||
name = models.CharField(max_length=127)
|
name = models.CharField(max_length=127)
|
||||||
translation_for = models.ForeignKey('Tag', related_name='translations')
|
translation_for = models.ForeignKey('Tag', related_name='translations')
|
||||||
|
|
||||||
|
|
||||||
class Info(models.Model):
|
class Info(models.Model):
|
||||||
'''
|
'''
|
||||||
model containing something showing on some info feed
|
model containing something showing on some info feed
|
||||||
'''
|
'''
|
||||||
publish_time = models.DateTimeField(default=timezone.now)
|
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):
|
class InfoTr(models.Model):
|
||||||
'''
|
'''
|
||||||
Model containing translations for news
|
Model containing translations for news
|
||||||
'''
|
'''
|
||||||
lang = models.CharField(max_length=2, default='fi')
|
lang = models.CharField(max_length=2, default='fi')
|
||||||
|
|
||||||
topic = models.CharField(max_length=255)
|
topic = models.CharField(max_length=255)
|
||||||
content = models.TextField()
|
content = models.TextField()
|
||||||
translation_for = models.ForeignKey('Info', related_name='translations')
|
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 static %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<html lang="en">
|
||||||
<html lang="en" ng-app="webApp">
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@@ -11,26 +12,13 @@
|
|||||||
<meta name="author" content="veedeeämkoo">
|
<meta name="author" content="veedeeämkoo">
|
||||||
<link rel="stylesheet" href="{% static "css/webapp.css" %}">
|
<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) -->
|
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
<script src="{% static "js/lib/jquery-3.1.0.min.js" %}"></script>
|
||||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" rel = "stylesheet">
|
<script src="{% static "js/lib/bootstrap.min.js" %}"></script>
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.js"></script>
|
<link rel="stylesheet" href="{% static "css/lib/bootstrap.min.css" %}">
|
||||||
|
<script src="{% static "js/lib/underscore-min.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>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
+6
-8
@@ -1,18 +1,16 @@
|
|||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
# main
|
|
||||||
from webapp.views import main_index
|
from webapp.views import main_index
|
||||||
from webapp.views import admin_index
|
from webapp.views import admin_index
|
||||||
# login
|
|
||||||
from webapp.views import login_view
|
from webapp.views import login_view
|
||||||
from webapp.views import logout_view
|
from webapp.views import logout_view
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# main
|
# main
|
||||||
url(r'^$', main_index),
|
url(r'^$', main_index),
|
||||||
url(r'^sikadmin$', admin_index),
|
url(r'^sikadmin$', admin_index),
|
||||||
|
|
||||||
# login stuff
|
# login stuff
|
||||||
url(r'^login$', login_view),
|
url(r'^login$', login_view),
|
||||||
url(r'^logout$', logout_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
|
from django.conf import settings
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
webilogger = logging.getLogger(__name__)
|
webapplogger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(format='[%(levelname)s]%(asctime)s %(message)s', level=settings.LOGGERLEVEL, filename=settings.LOGPATH)
|
logging.basicConfig(format='[%(levelname)s]%(asctime)s %(message)s',
|
||||||
|
level=settings.LOGGERLEVEL, filename=settings.LOGPATH)
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def main_index(request, *args, **kwargs):
|
def main_index(request, *args, **kwargs):
|
||||||
return render(request, "main_index.html", {})
|
return render(request, "main_index.html", {})
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
@ensure_csrf_cookie
|
@ensure_csrf_cookie
|
||||||
@permission_required('members.change_member', login_url='/login')
|
@permission_required('members.change_member', login_url='/login')
|
||||||
def admin_index(request, *args, **kwargs):
|
def admin_index(request, *args, **kwargs):
|
||||||
return render(request, "admin_index.html", {})
|
return render(request, "admin_index.html", {})
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def login_view(request, *args, **kwargs):
|
def login_view(request, *args, **kwargs):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
@@ -28,15 +31,18 @@ def login_view(request, *args, **kwargs):
|
|||||||
user = authenticate(username=uname, password=pw)
|
user = authenticate(username=uname, password=pw)
|
||||||
if user is not None:
|
if user is not None:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
original_site = request.GET.get("next",None) or "/"
|
original_site = request.GET.get("next", None) or "/"
|
||||||
return redirect(original_site)
|
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 got here by a get request
|
||||||
user = request.user
|
user = request.user
|
||||||
if user.is_authenticated():
|
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", {})
|
return render(request, "login.html", {})
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def logout_view(request, *args, **kwargs):
|
def logout_view(request, *args, **kwargs):
|
||||||
logout(request)
|
logout(request)
|
||||||
|
|||||||
Reference in New Issue
Block a user