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.

207 lines
5.8 KiB

"""This is the main flask distribusi page"""
import os
import zipfile
import shutil
from datetime import timedelta
from flask import (
render_template,
redirect,
request,
flash,
url_for,
session,
abort,
)
from sqlalchemy.exc import (
IntegrityError,
DataError,
DatabaseError,
InterfaceError,
InvalidRequestError,
)
from flask_login import (
login_user,
logout_user,
login_required,
current_user,
)
from werkzeug.routing import BuildError
from flask_bcrypt import generate_password_hash, check_password_hash
from flask_wtf.csrf import CSRFError
from app import create_app, db, login_manager
from usermodel import User
# Forms!
from loginform import LoginForm
from registerform import RegisterForm
from uploadform import UploadForm
from distribusiform import DistribusiForm
# 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=1)
@APP.route("/")
def index():
return render_template("index.html")
@APP.route("/login", methods=["GET", "POST"])
def login():
loginform = LoginForm()
if loginform.validate_on_submit():
try:
user = User.query.filter_by(email=loginform.email.data).first()
if check_password_hash(user.password, loginform.password.data):
login_user(user)
flash("Logged in successfully.", "success")
next = request.args.get("next")
if next is not None and not is_safe_url(next):
return abort(400)
return redirect(next or url_for("index"))
else:
flash("Invalid Username or password!", "danger")
except Exception as e:
flash(e, "danger")
return render_template("login.html", loginform=loginform)
@APP.route("/register", methods=["GET", "POST"])
def register():
registerform = RegisterForm()
if registerform.validate_on_submit():
try:
email = registerform.email.data
password = registerform.confirmpassword.data
newuser = User(
email=email,
password=generate_password_hash(password),
)
db.session.add(newuser)
db.session.commit()
flash("Account Succesfully created", "success")
return redirect(url_for("index"))
except InvalidRequestError:
db.session.rollback()
flash("Something went wrong!", "danger")
except IntegrityError:
db.session.rollback()
flash("User already exists!.", "warning")
except DataError:
db.session.rollback()
flash("Invalid Entry", "warning")
except InterfaceError:
db.session.rollback()
flash("Error connecting to the database", "danger")
except DatabaseError:
db.session.rollback()
flash("Error connecting to the database", "danger")
except BuildError:
db.session.rollback()
flash("An error occured !", "danger")
return render_template("register.html", registerform=registerform)
@APP.route("/distribusi", methods=["GET", "POST"])
@login_required
def distribusi():
uploadform = UploadForm()
distribusiform = DistribusiForm()
user = User.query.filter_by(email=current_user.email).first()
if user.distribusiname is None:
print("nothing to deploy!")
if distribusiform.validate_on_submit():
zipfilename = "{}.zip".format(user.distribusiname)
copyzipfile = os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)
newuserfolder = os.path.join("stash", user.distribusiname)
os.mkdir(newuserfolder)
shutil.copy(copyzipfile, newuserfolder)
unzipfile = os.path.join(newuserfolder, zipfilename)
with zipfile.ZipFile(unzipfile, "r") as zip_ref:
# To do, replace extractall with inspection and extract
zip_ref.extractall(newuserfolder)
os.remove(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename))
os.remove(os.path.join(newuserfolder, zipfilename))
# Make sure nothing can be executed from the upload folder
parser = build_argparser()
args = parser.parse_args()
distribusify(args, newuserfolder)
return render_template("index.html")
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
)
return template
@APP.route("/upload", methods=["POST"])
@login_required
def upload():
success = False
uploadform = UploadForm()
distribusiform = DistribusiForm()
if uploadform.validate_on_submit():
user = User.query.filter_by(email=current_user.email).first()
user.distribusiname = uploadform.sitename.data
db.session.commit()
zipfilename = "{}.zip".format(user.distribusiname)
zipfile = uploadform.zipfile.data
zipfile.save(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename))
success = True
template = render_template(
"distribusi.html",
uploadform=uploadform,
distribusiform=distribusiform,
success=success,
)
return template
@APP.route("/admin")
@login_required
def admin():
return "admin"
@APP.route("/logout")
@login_required
def logout():
logout_user()
return redirect(url_for("index"))
@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))
if __name__ == "__main__":
APP.debug = True
APP.run(port=5000)