forked from crunk/distribusi-verse
218 lines
6.2 KiB
Python
218 lines
6.2 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,
|
|
request,
|
|
flash,
|
|
url_for,
|
|
session,
|
|
abort,
|
|
send_from_directory,
|
|
)
|
|
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():
|
|
users = User.query.filter(User.distribusiname.isnot(None)).all()
|
|
distribusinames = []
|
|
for user in users:
|
|
distribusinames.append(user.distribusiname)
|
|
return render_template("index.html", distribusinames=distribusinames)
|
|
|
|
|
|
@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): # noqa: F821
|
|
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")
|
|
login_user(newuser)
|
|
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 redirect(url_for("index"))
|
|
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("/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.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)
|