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.
 
 
 
 
 

341 lines
9.9 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.selectorform import SelectorForm
# CRUD!
from selector import (
SelectNewDistribusi,
SelectUpdateDistribusi,
DeleteDistribusi,
SelectorVisible,
)
from editor import EditCss
# Upload
from upload import UploadNewDistribusi, UploadUpdatedFiles
# UserPengguna
from statuspengguna.helper import (
IsZipUploaded,
IsCssSelected,
CurrentDistribusi,
HasDistribusi,
IsDistribusiLive,
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.visible.isnot(False)
).all()
distribusies = {}
for distribusi in distribusis:
user = User.query.filter_by(id=distribusi.userid).first()
singledistribusi = {
"username": user.username,
"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)
distribusi_live = IsDistribusiLive(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 = ""
cssfolder = os.path.join(
"themes/userstyles", distribusi.distribusiname
)
for filename in os.listdir(cssfolder):
if filename.endswith(".css"):
cssfile = os.path.join(cssfolder, filename)
parser = build_argparser()
args = parser.parse_args(["-s", cssfile])
distribusify(args, userfolder)
distribusi.visible = True
user.currentdistribusi = None
os.remove(cssfile)
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,
distribusi_live=distribusi_live,
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" or HasDistribusi() is False:
uploadform = UploadNewDistribusi(APP.config["UPLOAD_FOLDER"])
else:
uploadform = UploadUpdatedFiles(APP.config["UPLOAD_FOLDER"])
files_uploaded = IsZipUploaded(uploadform.sitename.data)
distribusi_live = IsDistribusiLive(current_distribusi)
css_selected = IsCssSelected(current_distribusi)
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
distribusi_live=distribusi_live,
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()
print(current_distribusi)
files_uploaded = IsZipUploaded(current_distribusi)
distribusi_live = IsDistribusiLive(current_distribusi)
css_selected = IsCssSelected(current_distribusi)
if themeform.validate_on_submit():
newcssfolder = os.path.join("themes/userstyles", current_distribusi)
if not os.path.exists(newcssfolder):
os.mkdir(newcssfolder)
copycssfile = os.path.join(
"themes",
"{}.css".format(themeform.theme.data),
)
shutil.copy(copycssfile, newcssfolder)
css_selected = IsCssSelected(current_distribusi)
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
distribusi_live=distribusi_live,
css_selected=css_selected,
selectorvisible=selectorvisible,
)
return template
@APP.route("/editor", methods=["GET", "POST"])
@login_required
def editor():
return EditCss()
@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)
distribusi_live = IsDistribusiLive(current_distribusi)
# because the user has chosen to update his distribusi, we assume
# no selected css.
css_selected = False
selectorvisible = SelectorVisible()
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
themeform=themeform,
selectorform=selectorform,
files_uploaded=files_uploaded,
distribusi_live=distribusi_live,
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)