distribusi-verse: medium-tech web app content management system for the web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
9.4 KiB

"""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()
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()
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)
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,
)
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)