2021-05-17 12:33:53 +00:00
|
|
|
import logging
|
|
|
|
import re
|
2021-05-24 08:15:54 +00:00
|
|
|
import traceback
|
|
|
|
import hashlib
|
2021-05-17 12:33:53 +00:00
|
|
|
from datetime import datetime
|
2021-05-24 08:15:54 +00:00
|
|
|
from sqlalchemy import desc
|
2021-05-17 12:33:53 +00:00
|
|
|
|
|
|
|
from portal.base import UploadHandler
|
2021-05-24 08:15:54 +00:00
|
|
|
from portal.model import db, UploadSolar, ContractsSolar, RegisteredUser, Institution
|
2021-05-17 12:33:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
VALID_PROGRAMS = {'OS', 'SSG', 'MGP', 'ZG', 'NPI', 'SPI', 'SSI', 'PTI'}
|
|
|
|
VALID_SUBJECTS = {'slo', 'drug-jez', 'drug-druz', 'drug-narav', 'drug-strok', 'drug-izb'}
|
|
|
|
VALID_TEXT_TYPES = {'esej-spis', 'prakticno', 'solski-test', 'delo-v-razredu'}
|
|
|
|
VALID_GRAMMAR_CORRECTIONS = {'popr-ne', 'brez-popr', 'popr-da'}
|
|
|
|
|
|
|
|
MAXLEN_FORM = 150
|
|
|
|
|
|
|
|
|
|
|
|
class UploadHandlerSolar(UploadHandler):
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def store_metadata(upload_metadata, user_id):
|
|
|
|
timestamp = datetime.fromtimestamp(upload_metadata['timestamp'])
|
|
|
|
form_data = upload_metadata['form_data']
|
|
|
|
file_hashes = upload_metadata['file_hashes_dict']
|
|
|
|
sorted_f_hashes = list(file_hashes.values())
|
|
|
|
sorted_f_hashes.sort()
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
institution_id = UploadHandler.get_user_institution(user_id)
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-24 08:15:54 +00:00
|
|
|
model_obj = UploadSolar(
|
|
|
|
upload_user = user_id,
|
|
|
|
institution = institution_id,
|
|
|
|
upload_hash=upload_metadata['upload_id'],
|
|
|
|
timestamp=timestamp,
|
|
|
|
program=form_data['program'],
|
|
|
|
subject=form_data['predmet'],
|
|
|
|
subject_custom=form_data['predmet-custom'],
|
|
|
|
grade=form_data['letnik'],
|
|
|
|
text_type=form_data['vrsta'],
|
|
|
|
text_type_custom=form_data['vrsta-custom'],
|
|
|
|
school_year=form_data['solsko-leto'],
|
|
|
|
grammar_corrections=form_data['jezikovni-popravki'],
|
|
|
|
upload_file_hashes=sorted_f_hashes
|
|
|
|
)
|
|
|
|
self.store_model(model_obj)
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
def handle_upload(self, request, user_id):
|
2021-05-24 08:15:54 +00:00
|
|
|
err = self.check_upload_request(request)
|
2021-05-17 12:33:53 +00:00
|
|
|
if err:
|
|
|
|
return err, 400
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
err = self.check_form(request.form)
|
|
|
|
if err:
|
|
|
|
return err, 400
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
# Parse request.
|
|
|
|
upload_metadata = self.extract_upload_metadata('solar', request)
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
logging.info('Upload from user "{}" with upload id "{}" supplied form data: {}'.format(
|
|
|
|
user_id,
|
|
|
|
upload_metadata['upload_id'],
|
|
|
|
str(upload_metadata['form_data']
|
|
|
|
)))
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
# Store uploaded files to disk.
|
|
|
|
self.store_datafiles(request.files, upload_metadata)
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
# Store to database.
|
|
|
|
self.store_metadata(upload_metadata, user_id)
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
return 'Uspešno ste oddali datotek(e). Št. datotek: {}'.format(len(request.files))
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-24 08:15:54 +00:00
|
|
|
def handle_contract_upload(self, request, user_id):
|
|
|
|
contracts_type = request.form['tip-pogodbe']
|
|
|
|
|
|
|
|
if contracts_type not in ['sola', 'ucenci-starsi']:
|
|
|
|
return 'Neveljaven tip pogodbe.'
|
|
|
|
|
|
|
|
f_obj = None
|
|
|
|
for key, f in request.files.items():
|
|
|
|
if key.startswith('file'):
|
|
|
|
mimetype = f.content_type
|
|
|
|
if mimetype != 'application/pdf':
|
|
|
|
return 'Datoteka "{}" ni formata PDF.'.format(f.filename)
|
|
|
|
else:
|
|
|
|
f_obj = f
|
|
|
|
break
|
|
|
|
|
|
|
|
if not f_obj:
|
|
|
|
return 'Niste naložili nobene datoteke.'
|
|
|
|
|
|
|
|
base = self.get_uploads_subdir('contracts')
|
|
|
|
f_hash = hashlib.md5(f_obj.read())
|
|
|
|
|
|
|
|
# First byte used for indexing, similarly like git does for example.
|
|
|
|
sub_dir = base / f_hash[:2]
|
|
|
|
if not sub_dir.exists():
|
|
|
|
sub_dir.mkdir()
|
|
|
|
|
|
|
|
path = sub_dir / f_hash[2:] + '.pdf'
|
|
|
|
f_obj.save(path)
|
|
|
|
|
|
|
|
user_obj = RegisteredUser.query.filter_by(id=user_id).one()
|
|
|
|
institution_id = user_obj.institution
|
|
|
|
is_institution_moderator = user_obj.institution_moderator
|
|
|
|
|
|
|
|
if institution_id is None:
|
|
|
|
return 'Vaš uporabnik ni dodeljen nobeni inštituciji.'
|
|
|
|
|
|
|
|
if contracts_type == 'sola':
|
|
|
|
if not is_institution_moderator:
|
|
|
|
return 'Vaš uporabnik nima pravic za nalaganje pogodbe s šolo.'
|
|
|
|
Institution.update().values(file_contract=f_hash).where(id=institution_id)
|
|
|
|
|
|
|
|
model_obj = ContractsSolar(
|
|
|
|
institution=institution_id,
|
|
|
|
upload_user=user_id,
|
|
|
|
file_contract=f_hash,
|
|
|
|
contracts_type=contracts_type,
|
|
|
|
)
|
|
|
|
self.store_model(model_obj)
|
|
|
|
return 'Nalaganje pogodbe je bilo uspešno.'
|
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
@staticmethod
|
|
|
|
def check_form(form):
|
|
|
|
program = form['program']
|
|
|
|
predmet = form['predmet']
|
|
|
|
letnik = int(form['letnik'])
|
|
|
|
vrsta = form['vrsta']
|
|
|
|
solsko_leto = form['solsko-leto']
|
|
|
|
jezikovni_popravki = form['jezikovni-popravki']
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
if program not in VALID_PROGRAMS:
|
|
|
|
return 'Invalid program "{}"'.format(program)
|
|
|
|
if predmet not in VALID_SUBJECTS:
|
|
|
|
return 'Invalid subject "{}"'.format(premdet)
|
|
|
|
if letnik < 1 or letnik > 9:
|
|
|
|
return 'Invalid grade: {}'.format(letnik)
|
|
|
|
if vrsta not in VALID_TEXT_TYPES:
|
|
|
|
return 'Invalid text type "{}"'.format(vrsta)
|
|
|
|
if not re.match('^\d{0,2}-\d{0,2}$', solsko_leto):
|
|
|
|
return 'Invalid school year "{}"'.format(solsko_leto)
|
|
|
|
if jezikovni_popravki not in VALID_GRAMMAR_CORRECTIONS:
|
|
|
|
return 'Invalid text type "{}"'.format(jezikovni_popravki)
|
2021-05-05 12:26:26 +00:00
|
|
|
|
2021-05-17 12:33:53 +00:00
|
|
|
for key, val in form.items():
|
|
|
|
if len(val) > MAXLEN_FORM:
|
|
|
|
return 'Value in form field "{}" exceeds max len of {}'.format(key, MAXLEN_FORM)
|
2021-05-24 08:15:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_upload_history(user_id, n=20):
|
|
|
|
return UploadSolar.query.filter_by(upload_user=user_id).order_by(desc(UploadSolar.timestamp)).limit(n).all()
|
|
|
|
|
|
|
|
|
|
|
|
def get_institution_student_contracts(institution_id):
|
|
|
|
return ContractsSolar.query.filter_by(id=institution_id, contract_type='ucenci-starsi').all()
|
|
|
|
|
|
|
|
|
|
|
|
def get_institution_contract(institution_id):
|
|
|
|
return ContractsSolar.query.filter_by(id=institution_id, contract_type='sola').first()
|
|
|
|
|
|
|
|
|
|
|
|
|