import os import shutil import bleach from bleach_allowlist import all_styles from flask import render_template from sqlalchemy.exc import ( DatabaseError, DataError, InterfaceError, InvalidRequestError, ) from werkzeug.utils import secure_filename from app import db from distribusikan.distribusisinfo import DistribusisInfo from distribusikan.forms.distribusiform import DistribusiForm from distribusikan.forms.editorform import EditorForm from distribusikan.forms.publicthemeform import PublicThemeForm from distribusikan.forms.selectorform import SelectorForm from distribusikan.forms.themeform import ThemeForm from distribusikan.forms.uploadform import UploadForm from models.distribusi_model import Distribusis from statuspengguna.helper import UserHelper def Editor(): editorform = EditorForm() current_distribusi = UserHelper.current_distribusi() if editorform.validate_on_submit(): ValidateEditCssForm(editorform, current_distribusi) return RenderDistribusiTemplate(current_distribusi) return RenderEditorTemplate(editorform, current_distribusi) def ValidateEditCssForm(editorform, current_distribusi): newcssfolder = os.path.join("themes/userthemes", current_distribusi) if os.path.exists(newcssfolder): shutil.rmtree(newcssfolder) publicfolder = os.path.join("themes/publicthemes", current_distribusi) if os.path.exists(publicfolder): shutil.rmtree(publicfolder) if editorform.public.data: MakePublicTheme(editorform, current_distribusi) if editorform.cssfile.data: SaveUploadCssFile(editorform, publicfolder) CopyPublicToUserFolder(editorform, publicfolder, newcssfolder) return else: WriteCssToFile(editorform, publicfolder) if editorform.cssfile.data: SaveUploadCssFile(editorform, newcssfolder) return if editorform.cssname.data: WriteCssToFile(editorform, newcssfolder) def SaveUploadCssFile(editorform, newcssfolder): if not os.path.exists(newcssfolder): os.mkdir(newcssfolder) cssfile = editorform.cssfile.data cssfilename = f"{secure_filename(editorform.cssname.data)}.css" cssfile.save(os.path.join(newcssfolder, cssfilename)) openfile = open(os.path.join(newcssfolder, cssfilename), "r") cleancss = bleach.clean(openfile.read(), all_styles) cleancss = cleancss.replace(">", ">") openfile.close() cleanfile = open(os.path.join(newcssfolder, cssfilename), "w") cleanfile.write(cleancss) cleanfile.close() def WriteCssToFile(editorform, newcssfolder): if not os.path.exists(newcssfolder): os.mkdir(newcssfolder) cssfilename = f"{secure_filename(editorform.cssname.data)}.css" cleancss = bleach.clean(editorform.css.data, all_styles) cleancss = cleancss.replace(">", ">") with open(os.path.join(newcssfolder, cssfilename), "w") as cssfile: cssfile.write(cleancss) cssfile.close def CopyPublicToUserFolder(editorform, publicfolder, newcssfolder): if not os.path.exists(newcssfolder): os.mkdir(newcssfolder) copycssfile = os.path.join( publicfolder, f"{secure_filename(editorform.cssname.data)}.css" ) print(f"copying file: {copycssfile}") print(f"to folder: {newcssfolder}") shutil.copy(copycssfile, newcssfolder) def MakePublicTheme(editorform, current_distribusi): try: distribusi = Distribusis.query.filter_by( distribusiname=current_distribusi ).first() distribusi.publictheme = secure_filename(editorform.cssname.data) db.session.commit() except InvalidRequestError: db.session.rollback() editorform.public.errors.append("Something went wrong!") except DataError: db.session.rollback() editorform.public.errors.append("Invalid Entry") except InterfaceError: db.session.rollback() editorform.public.errors.append("Error connecting to the database") except DatabaseError: db.session.rollback() editorform.public.errors.append("Error connecting to the database") def RenderDistribusiTemplate(current_distribusi): uploadform = UploadForm() distribusiform = DistribusiForm() themeform = ThemeForm() publicthemeform = PublicThemeForm() publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes() selectorform = SelectorForm() files_uploaded = UserHelper.is_zip_uploaded(current_distribusi) distribusi_live = UserHelper.is_distribusi_live(current_distribusi) css_selected = True selectorvisible = False 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 def RenderEditorTemplate(editorform, current_distribusi): htmlplaceholder = HtmlPlaceholder() cssplaceholder = CssPlaceholder(current_distribusi) editorform.css.data = cssplaceholder files_uploaded = UserHelper.is_zip_uploaded(current_distribusi) distribusi_live = UserHelper.is_distribusi_live(current_distribusi) template = render_template( "editor.html", files_uploaded=files_uploaded, distribusi_live=distribusi_live, editorform=editorform, htmlplaceholder=htmlplaceholder, ) return template def CssPlaceholder(current_distribusi): cssplaceholder = "Try out your CSS here" distribusi = Distribusis.query.filter_by( distribusiname=current_distribusi ).first() if distribusi is not None and distribusi.publictheme is not None: cssplaceholder = GetPublicCssFile(distribusi) else: with open("themes/editor/placeholder.css") as f: cssplaceholder = f.read() return cssplaceholder def HtmlPlaceholder(): htmlplaceholder = "Write some test HTML here" with open("themes/editor/placeholder.html") as f: htmlplaceholder = f.read() return htmlplaceholder def GetPublicCssFile(distribusi): cssplaceholder = "" publicthemefolder = os.path.join( "themes/publicthemes", distribusi.distribusiname ) for filename in os.listdir(publicthemefolder): if filename.endswith(".css"): cssfile = os.path.join(publicthemefolder, filename) with open(cssfile) as f: cssplaceholder = f.read() return cssplaceholder