portal-oddajanje-solar/app.py

225 lines
7.0 KiB
Python
Raw Normal View History

import logging
2020-10-23 08:07:14 +00:00
import os
import configparser
import re
2020-10-23 08:07:14 +00:00
from pathlib import Path
2021-05-05 12:26:26 +00:00
from werkzeug.security import check_password_hash
2020-10-23 08:07:14 +00:00
2021-05-05 12:26:26 +00:00
from flask import Flask, render_template, request, redirect, flash
2020-10-23 08:07:14 +00:00
from flask_dropzone import Dropzone
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
2021-05-05 12:26:26 +00:00
from flask_login import LoginManager, login_required, login_user, current_user
from portal.model import db, RegisteredUser
2020-10-23 08:07:14 +00:00
import portal.base
2021-05-05 12:26:26 +00:00
import portal.solar
2021-05-05 12:26:26 +00:00
# TODO: Implement user registration.
# TODO: Integrate Shibboleth login.
# TODO: make logging level configurable
logging.basicConfig(level=logging.DEBUG, format='[APP LOGGER] %(asctime)s %(levelname)s: %(message)s')
######################
# Load configuration #
######################
config = configparser.ConfigParser()
config.read('config.ini')
config = config['DEFAULT']
MAIL_HOST = config['MAIL_HOST']
MAIL_LOGIN = config['MAIL_LOGIN']
MAIL_PASS = config['MAIL_PASS']
2021-05-05 12:26:26 +00:00
APP_SECRET_KEY = bytes.fromhex(config['APP_SECRET_KEY'])
SMTP_PORT = int(config['SMTP_PORT'])
IMAP_PORT = int(config['IMAP_PORT'])
MAX_UPLOAD_SIZE = int(config['MAX_UPLOAD_SIZE']) # Bytes
MAX_FILES_PER_UPLOAD = int(config['MAX_FILES_PER_UPLOAD'])
CONTRACT_CLIENT_CONTACT = config['CONTRACT_CLIENT_CONTACT']
MAIL_SUBJECT = config['MAIL_SUBJECT']
MAIL_BODY = config['MAIL_BODY']
SQL_CONN_STR = config['SQL_CONN_STR']
DESC_PREVODI = config['DESC_PREVODI']
DESC_GIGAFIDA = config['DESC_GIGAFIDA']
if 'UPLOADS_DIR' in config:
UPLOADS_DIR = Path(config['UPLOADS_DIR'])
else:
UPLOADS_DIR = Path(__file__).resolve().parent / 'uploads'
if not UPLOADS_DIR.exists:
UPLOADS_DIR.mkdir(parents=True)
# Override configs with environment variables, if set
if 'PORTALDS4DS1_MAIL_HOST' in os.environ:
MAIL_HOST = os.environ['PORTALDS4DS1_MAIL_HOST']
if 'PORTALDS4DS1_MAIL_LOGIN' in os.environ:
MAIL_LOGIN = os.environ['PORTALDS4DS1_MAIL_LOGIN']
if 'PORTALDS4DS1_MAIL_PASS' in os.environ:
MAIL_PASS = os.environ['PORTALDS4DS1_MAIL_PASS']
2021-05-05 12:26:26 +00:00
if 'PORTALDS4DS1_APP_SECRET_KEY' in os.environ:
APP_SECRET_KEY = bytes.fromhex(os.environ['PORTALDS4DS1_APP_SECRET_KEY'])
if 'PORTALDS4DS1_SMTP_PORT' in os.environ:
SMTP_PORT = int(os.environ['PORTALDS4DS1_SMTP_PORT'])
if 'PORTALDS4DS1_IMAP_PORT' in os.environ:
IMAP_PORT = int(os.environ['PORTALDS4DS1_IMAP_PORT'])
if 'PORTALDS4DS1_MAX_UPLOAD_SIZE' in os.environ:
MAX_UPLOAD_SIZE = int(os.environ['PORTALDS4DS1_MAX_UPLOAD_SIZE'])
if 'PORTALDS4DS1_MAX_FILES_PER_UPLOAD' in os.environ:
MAX_FILES_PER_UPLOAD = int(os.environ['PORTALDS4DS1_MAX_FILES_PER_UPLOAD'])
if 'PORTALDS4DS1_CONTRACT_CLIENT_CONTACT' in os.environ:
CONTRACT_CLIENT_CONTACT = os.environ['PORTALDS4DS1_CONTRACT_CLIENT_CONTACT']
if 'PORTALDS4DS1_UPLOADS_DIR' in os.environ:
UPLOADS_DIR = os.environ['PORTALDS4DS1_UPLOADS_DIR']
if 'PORTALDS4DS1_MAIL_SUBJECT' in os.environ:
MAIL_SUBJECT = os.environ['PORTALDS4DS1_MAIL_SUBJECT']
if 'PORTALDS4DS1_MAIL_BODY' in os.environ:
MAIL_BODY = os.environ['PORTALDS4DS1_MAIL_BODY']
if 'PORTALDS4DS1_SQL_CONN_STR' in os.environ:
SQL_CONN_STR = os.environ['PORTALDS4DS1_SQL_CONN_STR']
if 'PORTALDS4DS1_DESC_PREVODI' in os.environ:
DESC_PREVODI = os.environ['PORTALDS4DS1_DESC_PREVODI']
if 'PORTALDS4DS1_DESC_GIGAFIDA' in os.environ:
DESC_GIGAFIDA = os.environ['PORTALDS4DS1_DESC_GIGAFIDA']
VALID_CORPUS_NAMES = ['prevodi', 'gigafida', 'solar']
######################
2020-10-23 08:07:14 +00:00
app = Flask(__name__)
app.config.update(
2021-05-05 12:26:26 +00:00
SECRET_KEY = APP_SECRET_KEY,
UPLOADED_PATH = UPLOADS_DIR,
MAX_CONTENT_LENGTH = MAX_UPLOAD_SIZE,
TEMPLATES_AUTO_RELOAD = True,
SQLALCHEMY_DATABASE_URI = SQL_CONN_STR,
SQLALCHEMY_ECHO = True
2020-10-23 08:07:14 +00:00
)
# Run "python app.py db -?" to see more info about DB migrations.
manager = Manager(app)
db.init_app(app)
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)
# Set up dropzone.js to serve all the stuff for "file dropping" on the web interface.
2020-10-23 08:07:14 +00:00
dropzone = Dropzone(app)
upload_handler = portal.base.UploadHandler(
UPLOADS_DIR=UPLOADS_DIR,
MAIL_HOST=MAIL_HOST,
MAIL_LOGIN=MAIL_LOGIN,
MAIL_PASS=MAIL_PASS,
SMTP_PORT=SMTP_PORT,
IMAP_PORT=IMAP_PORT,
MAIL_SUBJECT=MAIL_SUBJECT,
MAIL_BODY=MAIL_BODY,
2021-05-05 12:26:26 +00:00
CONTRACT_CLIENT_CONTACT=CONTRACT_CLIENT_CONTACT,
MAX_FILES_PER_UPLOAD=MAX_FILES_PER_UPLOAD
)
2021-05-05 12:26:26 +00:00
# Use flask-login to manage user sessions where they are required.
login_manager = LoginManager(app)
login_manager.init_app(app)
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
2020-10-23 08:07:14 +00:00
2021-03-10 19:01:21 +00:00
@app.route('/')
2020-10-23 08:07:14 +00:00
def index():
return render_template('index.html')
@app.route('/<corpus_name>')
def index_corpus(corpus_name):
if corpus_name not in VALID_CORPUS_NAMES:
return 'Korpus "{}" ne obstaja.'.format(corpus_name), 404
if corpus_name == 'prevodi':
description = DESC_PREVODI
elif corpus_name == 'gigafida':
description = DESC_GIGAFIDA
elif corpus_name == 'solar':
2021-05-05 12:26:26 +00:00
if current_user.is_authenticated:
return redirect('/solar/oddaja')
return redirect('/solar/login')
return render_template('basic.html',
corpus_name=corpus_name, description=description, max_files=MAX_FILES_PER_UPLOAD)
2021-05-05 12:26:26 +00:00
@login_manager.user_loader
def load_user(user_id):
return RegisteredUser.query.get(int(user_id))
2021-05-05 12:26:26 +00:00
@app.route('/<corpus_name>/login')
def login_get(corpus_name):
return render_template('login.html', corpus_name=corpus_name)
2021-05-05 12:26:26 +00:00
@app.route('/<corpus_name>/login', methods=['POST'])
def login_post(corpus_name):
email = request.form.get('email')
password = request.form.get('password')
remember = True if request.form.get('remember') else False
2020-10-23 08:07:14 +00:00
2021-05-05 12:26:26 +00:00
user = RegisteredUser.query.filter_by(email=email).first()
2020-10-23 08:07:14 +00:00
2021-05-05 12:26:26 +00:00
# TODO: Check if user is authorized to login to this corpus.
2020-10-23 08:07:14 +00:00
2021-05-05 12:26:26 +00:00
if not user or not check_password_hash(user.pass_hash, password):
flash('Napačni podatki za prijavo. Poskusite ponovno.')
return redirect('/{}/login'.format(corpus_name))
2021-05-05 12:26:26 +00:00
if not user.active:
flash('Vaš uporabniški račun še ni bil aktiviran.')
return redirect('/{}/login'.format(corpus_name))
2021-05-05 12:26:26 +00:00
login_user(user, remember=remember)
2021-05-05 12:26:26 +00:00
if corpus_name == 'solar':
return redirect('/solar/oddaja')
return redirect('/{}/home'.format(corpus_name))
2021-05-05 12:26:26 +00:00
@app.route('/<corpus_name>/home')
@login_required
def profile(corpus_name):
return render_template('login.html', corpus_name=corpus_name)
2021-05-05 12:26:26 +00:00
# TODO: Move solar stuff to seperate file using Flask blueprints.
2021-05-05 12:26:26 +00:00
@app.route('/solar/oddaja')
@login_required
def solar_oddaja():
return render_template('solar-oddaja.html')
2021-05-05 12:26:26 +00:00
@app.route('/<corpus_name>/upload', methods=['POST'])
def handle_upload(corpus_name):
if corpus_name not in VALID_CORPUS_NAMES:
return 404
if corpus_name == 'solar':
if current_user.is_authenticated:
return portal.solar.handle_upload(request, upload_handler)
return 404
else:
return portal.base.handle_upload_unauthenticated(request, corpus_name)
2020-10-23 08:07:14 +00:00
if __name__ == '__main__':
app.run(debug=True)