263 lines
14 KiB
Python
263 lines
14 KiB
Python
import logging
|
|
from django.db import models
|
|
from django import forms
|
|
from django.core.exceptions import ValidationError
|
|
import time
|
|
import datetime
|
|
import re
|
|
from django.core.validators import MaxLengthValidator, MinValueValidator, MaxValueValidator
|
|
from django.utils import timezone
|
|
from django.core.exceptions import ValidationError
|
|
from django.utils.translation import ugettext as _, ugettext_noop as _noop
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
import hashlib
|
|
import os, os.path as osp
|
|
from django.utils.translation import gettext_lazy
|
|
|
|
# Create your models here.
|
|
LaunchDate = datetime.date(2019, 7, 13)
|
|
root=''
|
|
INPUT_DATA_DIR='/export/django/srg/data'
|
|
|
|
from django.core.files.storage import FileSystemStorage
|
|
from django.core.validators import EmailValidator
|
|
from django.core.validators import MaxLengthValidator
|
|
|
|
PRESENTATIONS_PATH = '/srv/srg-plan/srg/Uploads'
|
|
|
|
email_notification=['krivonos@iki.rssi.ru',]
|
|
|
|
readme_txt='/srv/srg-plan/srg/README.txt'
|
|
|
|
def get_session_duration_in_min(begin_hh, begin_mm, end_hh, end_mm):
|
|
if (end_hh > begin_hh):
|
|
return (end_hh-begin_hh)*60+end_mm-begin_mm
|
|
else:
|
|
return (24-begin_hh+end_hh)*60+end_mm-begin_mm
|
|
|
|
|
|
class Day(models.Model):
|
|
title = models.CharField(max_length=100)
|
|
Notes = models.TextField("Notes",max_length=2000, null=True, blank=True, validators=[MaxLengthValidator(1600)])
|
|
date = models.DateField(blank=True, null=True)
|
|
DayNumber = models.IntegerField()
|
|
modified = models.DateTimeField(auto_now=True)
|
|
def __unicode__(self):
|
|
return 'Day: ' + "%i" % (self.DayNumber)
|
|
def __str__(self):
|
|
return 'Day: ' + "%i" % (self.DayNumber)
|
|
def get_upload_url(self):
|
|
return "/plan/day/%i/upload" % (self.pk)
|
|
def get_absolute_url(self):
|
|
return "/plan/day/%i" % (self.pk)
|
|
|
|
class SessionBearLakes(models.Model):
|
|
Day = models.OneToOneField(Day, on_delete=models.CASCADE,verbose_name="Day", related_name="BearLakesDay",null=True)
|
|
title = models.CharField(max_length=100,blank=True)
|
|
TimeBegin_hh = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(24)])
|
|
TimeEnd_hh = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(24)])
|
|
TimeBegin_mm = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(60)],blank=True)
|
|
TimeEnd_mm = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(60)],blank=True)
|
|
sysSessionRequest = models.IntegerField(default=0)
|
|
eroSessionRequest = models.IntegerField(default=0)
|
|
artSessionRequest = models.IntegerField(default=0)
|
|
sysNotes = models.TextField("System Notes",max_length=2000, null=True, blank=True, validators=[MaxLengthValidator(1600)])
|
|
eroNotes = models.TextField("eRosita Notes",max_length=2000, null=True, blank=True, validators=[MaxLengthValidator(1600)])
|
|
artNotes = models.TextField("ART-XC Notes",max_length=2000, null=True, blank=True, validators=[MaxLengthValidator(1600)])
|
|
def clean(self, *args, **kwargs):
|
|
# add custom validation here
|
|
|
|
session_duration_min=get_session_duration_in_min(self.TimeBegin_hh,self.TimeBegin_mm, self.TimeEnd_hh,self.TimeEnd_mm)
|
|
request_min=(self.sysSessionRequest+self.eroSessionRequest+self.artSessionRequest)
|
|
if (request_min>session_duration_min):
|
|
msg="Total requested time (sys:%i + ero:%i + art:%i = %i min) cannot be longer than session duration: %i min" % (self.sysSessionRequest,
|
|
self.eroSessionRequest,
|
|
self.artSessionRequest,
|
|
request_min,
|
|
session_duration_min)
|
|
raise forms.ValidationError(msg)
|
|
super(SessionBearLakes, self).clean(*args, **kwargs)
|
|
|
|
def save(self, *args, **kwargs):
|
|
self.full_clean()
|
|
super(SessionBearLakes, self).save(*args, **kwargs)
|
|
|
|
def __unicode__(self):
|
|
return self.title
|
|
def __str__(self):
|
|
return 'Session: Day ' + "%i" % (self.Day.DayNumber)
|
|
def get_absolute_url(self):
|
|
return root+"/plan/BearLakes/%i/show" % (self.Day.DayNumber)
|
|
def get_update_url(self):
|
|
return root+"/plan/BearLakes/%i/update" % (self.Day.DayNumber)
|
|
def get_rest(self):
|
|
session_duration_min=get_session_duration_in_min(self.TimeBegin_hh,self.TimeBegin_mm, self.TimeEnd_hh,self.TimeEnd_mm)
|
|
request_min=(self.sysSessionRequest+self.eroSessionRequest+self.artSessionRequest)
|
|
return "%i" % (session_duration_min - request_min)
|
|
|
|
|
|
class SessionBearLakesForm(forms.ModelForm):
|
|
class Meta:
|
|
model=SessionBearLakes
|
|
fields=('title','TimeBegin_hh','TimeBegin_mm','TimeEnd_hh','TimeEnd_mm','sysSessionRequest','eroSessionRequest','artSessionRequest','sysNotes','eroNotes','artNotes')
|
|
widgets = {
|
|
'title': forms.TextInput(attrs={'style': 'width: 620px;', 'class': 'title'}),
|
|
'TimeBegin_hh': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'TimeBegin_mm': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'TimeEnd_hh': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'TimeEnd_mm': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'sysSessionRequest': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'eroSessionRequest': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'artSessionRequest': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'sysNotes': forms.Textarea(attrs={'style': 'width: 620px;', 'rows': 10}),
|
|
'eroNotes': forms.Textarea(attrs={'style': 'width: 620px;', 'rows': 10}),
|
|
'artNotes': forms.Textarea(attrs={'style': 'width: 620px;', 'rows': 10}),
|
|
}
|
|
|
|
class SessionUssuriysk(models.Model):
|
|
Day = models.OneToOneField(Day, on_delete=models.CASCADE,verbose_name="Day",related_name="UssuriyskDay",null=True)
|
|
title = models.CharField(max_length=100,blank=True)
|
|
TimeBegin_hh = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(24)])
|
|
TimeEnd_hh = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(24)])
|
|
TimeBegin_mm = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(60)],blank=True)
|
|
TimeEnd_mm = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(60)],blank=True)
|
|
sysSessionRequest = models.IntegerField(default=0)
|
|
eroSessionRequest = models.IntegerField(default=0)
|
|
artSessionRequest = models.IntegerField(default=0)
|
|
sysNotes = models.TextField("System Notes",max_length=2000, null=True, blank=True) #,validators=[MaxLengthValidator(1600)])
|
|
eroNotes = models.TextField("eRosita Notes",max_length=2000, null=True, blank=True) #,validators=[MaxLengthValidator(1600)])
|
|
artNotes = models.TextField("ART-XC Notes",max_length=2000, null=True, blank=True) #,validators=[MaxLengthValidator(1600)])
|
|
def clean(self, *args, **kwargs):
|
|
# add custom validation here
|
|
session_duration_min=get_session_duration_in_min(self.TimeBegin_hh,self.TimeBegin_mm, self.TimeEnd_hh,self.TimeEnd_mm)
|
|
request_min=(self.sysSessionRequest+self.eroSessionRequest+self.artSessionRequest)
|
|
if (request_min>session_duration_min):
|
|
msg="Total requested time (sys:%i + ero:%i + art:%i = %i min) cannot be longer than session duration: %i min" % (self.sysSessionRequest,
|
|
self.eroSessionRequest,
|
|
self.artSessionRequest,
|
|
request_min,
|
|
session_duration_min)
|
|
raise forms.ValidationError(msg)
|
|
super(SessionUssuriysk, self).clean(*args, **kwargs)
|
|
|
|
def save(self, *args, **kwargs):
|
|
self.full_clean()
|
|
super(SessionUssuriysk, self).save(*args, **kwargs)
|
|
|
|
def __unicode__(self):
|
|
return self.title
|
|
def __str__(self):
|
|
return 'Session: Day ' + "%i" % (self.Day.DayNumber)
|
|
def get_absolute_url(self):
|
|
return root+"/plan/Ussuriysk/%i/show" % (self.Day.DayNumber)
|
|
def get_update_url(self):
|
|
return root+"/plan/Ussuriysk/%i/update" % (self.Day.DayNumber)
|
|
def get_rest(self):
|
|
session_duration_min=get_session_duration_in_min(self.TimeBegin_hh,self.TimeBegin_mm, self.TimeEnd_hh,self.TimeEnd_mm)
|
|
request_min=(self.sysSessionRequest+self.eroSessionRequest+self.artSessionRequest)
|
|
return "%i" % (session_duration_min - request_min)
|
|
|
|
class SessionUssuriyskForm(forms.ModelForm):
|
|
class Meta:
|
|
model=SessionUssuriysk
|
|
fields=('title','TimeBegin_hh','TimeBegin_mm','TimeEnd_hh','TimeEnd_mm','sysSessionRequest','eroSessionRequest','artSessionRequest','sysNotes','eroNotes','artNotes')
|
|
widgets = {
|
|
'title': forms.TextInput(attrs={'style': 'width: 620px;', 'class': 'title'}),
|
|
'TimeBegin_hh': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'TimeBegin_mm': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'TimeEnd_hh': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'TimeEnd_mm': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'sysSessionRequest': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'eroSessionRequest': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'artSessionRequest': forms.TextInput(attrs={'style': 'width: 70px;', 'class': 'title'}),
|
|
'sysNotes': forms.Textarea(attrs={'style': 'width: 620px;', 'rows': 10}),
|
|
'eroNotes': forms.Textarea(attrs={'style': 'width: 620px;', 'rows': 10}),
|
|
'artNotes': forms.Textarea(attrs={'style': 'width: 620px;', 'rows': 10}),
|
|
}
|
|
|
|
FS = FileSystemStorage(location=PRESENTATIONS_PATH)
|
|
|
|
VALID_CONTENT_TYPES = ['application/pdf', 'image/png', 'application/vnd.ms-powerpoint','application/octet-stream',
|
|
'application/nappdf','application/x-pdf','application/x-bzpdf',
|
|
'application/x-gzpdf','application/force-download','application/x-file-download',
|
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
|
]
|
|
|
|
VALID_EXTENSIONS = ['.pdf', '.ppt', '.pptx', '.png', '.txt', '.dat']
|
|
|
|
def validate_upload_file(value):
|
|
file = value.file
|
|
|
|
_, ext = osp.splitext(file.name)
|
|
if ext not in VALID_EXTENSIONS:
|
|
raise forms.ValidationError(
|
|
'Extension %s not supported.' % ext
|
|
)
|
|
|
|
if file.content_type not in VALID_CONTENT_TYPES:
|
|
raise forms.ValidationError(
|
|
'Filetype %s not supported.' % file.content_type
|
|
)
|
|
|
|
|
|
def upload_filename(instance, filename):
|
|
_, ext = osp.splitext(filename)
|
|
|
|
tohash = filename + str(time.clock())
|
|
#new_fname = hashlib.md5(tohash).hexdigest()
|
|
new_fname = hashlib.md5(tohash.encode('utf-8')).hexdigest()
|
|
return new_fname + ext
|
|
|
|
class UserProfile(models.Model):
|
|
user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
|
|
#target_list = models.ManyToManyField(Target, blank=True)
|
|
#docker_list = models.ManyToManyField(DockerProxy, blank=True)
|
|
|
|
def __unicode__(self):
|
|
return self.user.email
|
|
def __str__(self):
|
|
return self.user.email
|
|
def get_objects(self):
|
|
return self.object_set.all()
|
|
|
|
class LoginUsernameForm(forms.Form):
|
|
username = forms.CharField(max_length=75, label="User name", widget=forms.TextInput(attrs={'class':'form-control', 'style': 'width: 450px;'}))
|
|
password = forms.CharField( widget=forms.PasswordInput(attrs={'class':'form-control', 'style': 'width: 450px;'}), label="Your Password" )
|
|
def clean_username(self):
|
|
username = self.cleaned_data.get('username')
|
|
try:
|
|
User.objects.get(username=username)
|
|
except User.DoesNotExist:
|
|
raise forms.ValidationError('This username is no such username.')
|
|
return username
|
|
|
|
class Upload(models.Model):
|
|
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE, default=None, unique=False, verbose_name="Author")
|
|
day = models.ForeignKey(Day, unique=False, verbose_name="Day", on_delete=models.CASCADE)
|
|
title = models.CharField(max_length=128)
|
|
filename = models.CharField(max_length=256)
|
|
filefield = models.FileField(upload_to=upload_filename, storage=FS, validators=[validate_upload_file])
|
|
uploaded = models.DateTimeField(auto_now_add=True)
|
|
#read_only = models.BooleanField("Read only", default=False)
|
|
def get_delete_url(self):
|
|
return self.day.get_absolute_url() + "/upload/%d/delete" % (self.id)
|
|
|
|
def delete(self, remove_file=True):
|
|
if remove_file:
|
|
FS.delete(str(self.filefield))
|
|
return models.Model.delete(self)
|
|
def __str__(self):
|
|
return '['+"%d" % (self.day.DayNumber)+'] '+self.title
|
|
|
|
|
|
class UploadForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Upload
|
|
fields = ('title', 'filefield')
|
|
widgets = {
|
|
'title': forms.TextInput(attrs={'style': 'width: 620px;', 'class': 'title'}),
|
|
}
|
|
|