portal-oddajanje-solar/portal/solar.py
2021-05-24 10:15:54 +02:00

166 lines
5.9 KiB
Python

import logging
import re
import traceback
import hashlib
from datetime import datetime
from sqlalchemy import desc
from portal.base import UploadHandler
from portal.model import db, UploadSolar, ContractsSolar, RegisteredUser, Institution
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()
institution_id = UploadHandler.get_user_institution(user_id)
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)
def handle_upload(self, request, user_id):
err = self.check_upload_request(request)
if err:
return err, 400
err = self.check_form(request.form)
if err:
return err, 400
# Parse request.
upload_metadata = self.extract_upload_metadata('solar', request)
logging.info('Upload from user "{}" with upload id "{}" supplied form data: {}'.format(
user_id,
upload_metadata['upload_id'],
str(upload_metadata['form_data']
)))
# Store uploaded files to disk.
self.store_datafiles(request.files, upload_metadata)
# Store to database.
self.store_metadata(upload_metadata, user_id)
return 'Uspešno ste oddali datotek(e). Št. datotek: {}'.format(len(request.files))
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.'
@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']
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)
for key, val in form.items():
if len(val) > MAXLEN_FORM:
return 'Value in form field "{}" exceeds max len of {}'.format(key, MAXLEN_FORM)
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()