"""This is the main flask distribusi page""" import os import zipfile import shutil from datetime import timedelta from flask import ( render_template, redirect, flash, url_for, session, send_from_directory, ) from sqlalchemy.exc import ( IntegrityError, InvalidRequestError, ) from flask_login import ( logout_user, login_required, current_user, ) from flask_wtf.csrf import CSRFError from app import create_app, db, login_manager from usermodel import User from distribusimodel import Distribusis # Forms! from forms.uploadform import UploadForm from forms.distribusiform import DistribusiForm from forms.themeform import ThemeForm from forms.editorform import EditorForm from forms.selectorform import SelectorForm from statuspengguna.helper import AreFilesUploaded from statuspengguna.helper import HasDistribusi from statuspengguna.loginuser import LoginUser from statuspengguna.registeruser import RegisterUser # Tada! from distribusi.cli import build_argparser from distribusi.distribusi import distribusify APP = create_app() @APP.before_request def session_handler(): session.permanent = True APP.permanent_session_lifetime = timedelta(minutes=30) @APP.route("/") def index(): distribusis = Distribusis.query.filter( Distribusis.distribusiname.isnot(None) ).all() distribusies = {} for distribusi in distribusis: user = User.query.filter_by(id=distribusi.userid).first() distribusies[distribusi.distribusiname] = user.email return render_template("index.html", distribusies=distribusies) @APP.route("/distribusi", methods=["GET", "POST"]) @login_required def distribusi(): uploadform = UploadForm() distribusiform = DistribusiForm() themeform = ThemeForm() selectorform = SelectorForm() selectorform.distribusis.choices = distribusisfields() files_uploaded = AreFilesUploaded() has_distribusi = HasDistribusi() user = User.query.filter_by(email=current_user.email).first() distribusi = Distribusis.query.filter_by(userid=user.id).first() if distribusiform.validate_on_submit(): zipfilename = "{}.zip".format(distribusi.distribusiname) userfolder = os.path.join("stash", distribusi.distribusiname) unzipfile = os.path.join(userfolder, zipfilename) print(unzipfile) if os.path.exists(unzipfile): with zipfile.ZipFile(unzipfile, "r") as zip_ref: # To do, replace extractall with inspection and extract zip_ref.extractall(userfolder) if os.path.exists(unzipfile): os.remove(os.path.join(userfolder, zipfilename)) # To Do: Make sure nothing can be executed from the upload folder cssfile = "" for filename in os.listdir(userfolder): if filename.endswith(".css"): cssfile = os.path.join(userfolder, filename) parser = build_argparser() args = parser.parse_args(["-s", cssfile]) distribusify(args, userfolder) return redirect(url_for("index")) template = render_template( "distribusi.html", uploadform=uploadform, distribusiform=distribusiform, themeform=themeform, selectorform=selectorform, files_uploaded=files_uploaded, has_distribusi=has_distribusi, ) return template @APP.route("/upload", methods=["POST"]) @login_required def upload(): uploadform = UploadForm() distribusiform = DistribusiForm() themeform = ThemeForm() files_uploaded = False if uploadform.validate_on_submit(): user = User.query.filter_by(email=current_user.email).first() try: newdistribusi = Distribusis( distribusiname=uploadform.sitename.data, userid=user.id, year=uploadform.academicyear.data, term=uploadform.term.data, tags=uploadform.tags.data, ) db.session.add(newdistribusi) db.session.commit() except InvalidRequestError: db.session.rollback() uploadform.sitename.errors.append("Something went wrong!") flash("Something went wrong!", "danger") except IntegrityError: db.session.rollback() uploadform.sitename.errors.append( "distribusi name already exists!" ) flash("distribusi name already exists!", "warning") zipfilename = "{}.zip".format(newdistribusi.distribusiname) zipfile = uploadform.zipfile.data zipfile.save(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)) newuserfolder = os.path.join("stash", newdistribusi.distribusiname) if not os.path.exists(newuserfolder): os.mkdir(newuserfolder) copyzipfile = os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename) shutil.copy(copyzipfile, newuserfolder) os.remove(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)) files_uploaded = AreFilesUploaded() template = render_template( "distribusi.html", uploadform=uploadform, distribusiform=distribusiform, themeform=themeform, files_uploaded=files_uploaded, ) return template @APP.route("/theme", methods=["GET", "POST"]) @login_required def theme(): uploadform = UploadForm() distribusiform = DistribusiForm() themeform = ThemeForm() files_uploaded = AreFilesUploaded() if themeform.validate_on_submit(): user = User.query.filter_by(email=current_user.email).first() distribusi = Distribusis.query.filter_by(userid=user.id).first() newuserfolder = os.path.join("stash", distribusi.distribusiname) copycssfile = os.path.join( "themes", "{}.css".format(themeform.theme.data), ) shutil.copy(copycssfile, newuserfolder) template = render_template( "distribusi.html", uploadform=uploadform, distribusiform=distribusiform, themeform=themeform, files_uploaded=files_uploaded, ) return template @APP.route("/editor", methods=["GET", "POST"]) @login_required def editor(): editorform = EditorForm() files_uploaded = AreFilesUploaded() user = User.query.filter_by(email=current_user.email).first() if editorform.validate_on_submit(): userfolder = os.path.join("stash", user.distribusiname) cssfilename = "{}.css".format(editorform.cssname.data) with open(os.path.join(userfolder, cssfilename), "w") as cssfile: cssfile.write(editorform.css.data) cssfile.close template = render_template( "editor.html", files_uploaded=files_uploaded, editorform=editorform, ) return template @APP.route("/stash/") def distribusistash(path): return send_from_directory("stash", path) @APP.route("/admin") @login_required def admin(): return "admin" @APP.route("/logout") @login_required def logout(): logout_user() return redirect(url_for("index")) @APP.route("/login", methods=["GET", "POST"]) def login(): result = LoginUser() return result @APP.route("/register", methods=["GET", "POST"]) def register(): result = RegisterUser() return result @APP.errorhandler(CSRFError) def handle_csrf_error(e): return render_template("csrf_error.html", reason=e.description), 400 @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) def distribusisfields(): distribusinames = [] user = User.query.filter_by(email=current_user.email).first() for distribusi in Distribusis.query.filter_by(userid=user.id).all(): distribusinames.append(distribusi.distribusiname) return distribusinames if __name__ == "__main__": APP.debug = True APP.run(port=5000)