distribusi-verse/verse/start.py

347 lines
10 KiB
Python

"""This is the main flask distribusi page"""
import os
import zipfile
import shutil
from datetime import timedelta
from flask import (
render_template,
redirect,
url_for,
session,
send_from_directory,
)
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
# CRUD!
from selector import SelectNewDistribusi
from selector import SelectUpdateDistribusi
from selector import DeleteDistribusi
from selector import SelectorVisible
# Upload
from upload import UploadNewDistribusi
from upload import UploadUpdatedFiles
# UserPengguna
from statuspengguna.helper import IsZipUploaded
from statuspengguna.helper import IsCssSelected
from statuspengguna.helper import CurrentDistribusi
from statuspengguna.helper import ResetUserState
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():
ResetUserState()
uploadform = UploadForm()
distribusis = Distribusis.query.filter(
Distribusis.distribusiname.isnot(None)
).all()
distribusies = {}
for distribusi in distribusis:
user = User.query.filter_by(id=distribusi.userid).first()
singledistribusi = {
"useremail": user.email,
"term": distribusi.term,
"course": distribusi.course,
"year": distribusi.year,
"tags": distribusi.tags.split(','),
}
distribusies[distribusi.distribusiname] = singledistribusi
years = uploadform.academicyear.choices
terms = uploadform.term.choices
courses = uploadform.course.choices
template = render_template(
"index.html",
distribusies=distribusies,
years=years,
terms=terms,
courses=courses,
)
return template
@APP.route("/distribusi", methods=["GET", "POST"])
@login_required
def distribusi():
uploadform = UploadForm()
distribusiform = DistribusiForm()
themeform = ThemeForm()
selectorform = SelectorForm()
selectorform.distribusis.choices = distribusisfields()
selectorvisible = SelectorVisible()
current_distribusi = CurrentDistribusi()
files_uploaded = IsZipUploaded(current_distribusi)
css_selected = IsCssSelected(current_distribusi)
user = User.query.filter_by(email=current_user.email).first()
distribusi = Distribusis.query.filter_by(
distribusiname=current_distribusi
).first()
if distribusiform.validate_on_submit():
zipfilename = "{}.zip".format(distribusi.distribusiname)
userfolder = os.path.join("stash", distribusi.distribusiname)
unzipfile = os.path.join(userfolder, zipfilename)
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)
distribusi.visible = True
user.currentdistribusi = None
db.session.commit()
return redirect(url_for("index"))
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
css_selected=css_selected,
selectorvisible=selectorvisible,
)
return template
@APP.route("/upload", methods=["POST"])
@login_required
def upload():
distribusiform = DistribusiForm()
themeform = ThemeForm()
selectorform = SelectorForm()
selectorform.distribusis.choices = distribusisfields()
selectorvisible = SelectorVisible()
current_distribusi = CurrentDistribusi()
if current_distribusi == "new":
uploadform = UploadNewDistribusi(APP.config["UPLOAD_FOLDER"])
else:
uploadform = UploadUpdatedFiles(APP.config["UPLOAD_FOLDER"])
files_uploaded = IsZipUploaded(uploadform.sitename.data)
css_selected = IsCssSelected(current_distribusi)
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
css_selected=css_selected,
selectorvisible=selectorvisible,
)
return template
@APP.route("/theme", methods=["GET", "POST"])
@login_required
def theme():
uploadform = UploadForm()
distribusiform = DistribusiForm()
themeform = ThemeForm()
selectorform = SelectorForm()
selectorform.distribusis.choices = distribusisfields()
selectorvisible = SelectorVisible()
current_distribusi = CurrentDistribusi()
files_uploaded = IsZipUploaded(current_distribusi)
css_selected = IsCssSelected(current_distribusi)
if themeform.validate_on_submit():
newuserfolder = os.path.join("stash", current_distribusi)
copycssfile = os.path.join(
"themes",
"{}.css".format(themeform.theme.data),
)
shutil.copy(copycssfile, newuserfolder)
css_selected = IsCssSelected(current_distribusi)
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
css_selected=css_selected,
selectorvisible=selectorvisible,
)
return template
@APP.route("/editor", methods=["GET", "POST"])
@login_required
def editor():
editorform = EditorForm()
current_distribusi = CurrentDistribusi()
files_uploaded = IsZipUploaded(current_distribusi)
cssplaceholder = "Try out your CSS here"
with open('themes/editor/placeholder.css') as f:
cssplaceholder = f.read()
editorform.css.data = cssplaceholder
htmlplaceholder = "Write some test HTML here"
with open('themes/editor/placeholder.html') as f:
htmlplaceholder = f.read()
print(htmlplaceholder)
if editorform.validate_on_submit():
userfolder = os.path.join("stash", current_distribusi)
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,
htmlplaceholder=htmlplaceholder,
)
return template
@APP.route("/selector", methods=["GET", "POST"])
@login_required
def selector():
selectorform = SelectorForm()
uploadform = UploadForm()
distribusiform = DistribusiForm()
themeform = ThemeForm()
selectorform = SelectorForm()
selectorform.distribusis.choices = distribusisfields()
current_distribusi = CurrentDistribusi()
if selectorform.validate_on_submit():
if selectorform.new.data:
selectorform = SelectNewDistribusi()
if selectorform.delete.data:
selectorform = DeleteDistribusi(selectorform.distribusis.data)
selectorform.distribusis.choices = distribusisfields()
if selectorform.update.data:
selectorform = SelectUpdateDistribusi(
selectorform.distribusis.data
)
current_distribusi = CurrentDistribusi()
distribusi = Distribusis.query.filter_by(
distribusiname=current_distribusi
).first()
uploadform.sitename.data = distribusi.distribusiname
uploadform.sitename.render_kw = {"readonly": True}
uploadform.term.data = distribusi.term
uploadform.course.data = distribusi.course
uploadform.academicyear.data = distribusi.year
uploadform.tags.data = distribusi.tags
files_uploaded = IsZipUploaded(current_distribusi)
css_selected = IsCssSelected(current_distribusi)
selectorvisible = SelectorVisible()
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
css_selected=css_selected,
selectorvisible=selectorvisible,
)
return template
@APP.route("/stash/<path:path>")
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)