import os import shutil import zipfile from distribusi.distribusi import distribusify from flask import flash, redirect, render_template, url_for from flask_login import current_user from sqlalchemy.exc import ( DatabaseError, DataError, InterfaceError, InvalidRequestError, ) from app import db, APP from distribusikan.add_files_to_describer import add_distribusi_files_to_db from distribusikan.distribusi_selector import selector_visible from distribusikan.distribusis_info import DistribusisInfo from distribusikan.forms.distribusiform import DistribusiForm from distribusikan.forms.publicthemeform import PublicThemeForm from distribusikan.forms.selectorform import SelectorForm from distribusikan.forms.themeform import ThemeForm # Forms! from distribusikan.forms.uploadform import UploadForm from models.distribusi_model import Distribusis from models.user_model import User # UserPengguna from statuspengguna.helper import UserHelper def distribusi_workflow(): distribusiform = DistribusiForm() current_distribusi = UserHelper.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(): userfolder = os.path.join("stash", distribusi.distribusiname) cssfile = get_css_file(distribusi) unzip_distribusi_files(distribusi, userfolder) clean_up_distribusi_files(userfolder) add_distribusi_files_to_db(distribusi.distribusiname) run_distribusi(userfolder, cssfile) set_distribusi_to_visible(distribusi, user) delete_css_file(cssfile) return redirect(url_for("index")) return render_distribusi_template(distribusiform, current_distribusi) def unzip_distribusi_files(distribusi, userfolder): zipfilename = "{}.zip".format(distribusi.distribusiname) unzipfile = os.path.join(userfolder, zipfilename) if os.path.exists(unzipfile): with zipfile.ZipFile(unzipfile, "r") as zip_ref: zip_ref.extractall(userfolder) # after extracting all files remove zip file. if os.path.exists(unzipfile): os.remove(os.path.join(userfolder, zipfilename)) def clean_up_distribusi_files(userfolder): if os.path.exists(userfolder): remove_mac_folders(userfolder) def remove_mac_folders(path): for filename in os.listdir(path): fullpath = os.path.join(path, filename) if filename.startswith("."): if os.path.isdir(fullpath): shutil.rmtree(fullpath) else: os.remove(fullpath) if filename == "__MACOSX": shutil.rmtree(fullpath) if os.path.isdir(fullpath): remove_mac_folders(fullpath) def get_css_file(distribusi): cssfile = "" cssfolder = os.path.join("themes/userthemes", distribusi.distribusiname) if os.path.exists(cssfolder): for filename in os.listdir(cssfolder): if filename.endswith(".css"): cssfile = os.path.join(cssfolder, filename) return cssfile def run_distribusi(userfolder, cssfile): APP.logger.info( f"Run distribusi on this folder: {userfolder} with css:{cssfile}" ) distribusify(userfolder, cssfile) def set_distribusi_to_visible(distribusi, user): try: distribusi.visible = True user.currentdistribusi = None db.session.commit() except (InvalidRequestError, DataError, InterfaceError, DatabaseError): db.session.rollback() flash("Unknown error occured!") def delete_css_file(cssfile): if os.path.exists(cssfile): os.remove(cssfile) def render_distribusi_template(distribusiform, current_distribusi): uploadform = UploadForm() themeform = ThemeForm() publicthemeform = PublicThemeForm() publicthemeform.publicthemes.choices = DistribusisInfo.public_themes() selectorform = SelectorForm() selectorform.distribusis.choices = DistribusisInfo.user_distribusinames() selectorvisible = selector_visible() files_uploaded = UserHelper.is_zip_uploaded(current_distribusi) distribusi_live = UserHelper.is_distribusi_live(current_distribusi) css_selected = UserHelper.is_css_selected(current_distribusi) limit_reached = UserHelper.distribusi_limit_reached() template = render_template( "distribusi.html", uploadform=uploadform, distribusiform=distribusiform, themeform=themeform, publicthemeform=publicthemeform, selectorform=selectorform, files_uploaded=files_uploaded, distribusi_live=distribusi_live, css_selected=css_selected, selectorvisible=selectorvisible, limit_reached=limit_reached, ) return template