import os import bleach from bleach_allowlist import all_styles import shutil from flask import render_template from werkzeug.utils import secure_filename from sqlalchemy.exc import ( DataError, DatabaseError, InterfaceError, InvalidRequestError, ) from app import db from distribusimodel import Distribusis from statuspengguna.helper import UserHelper from distribusisinfo import DistribusisInfo from forms.uploadform import UploadForm from forms.distribusiform import DistribusiForm from forms.themeform import ThemeForm from forms.publicthemeform import PublicThemeForm from forms.editorform import EditorForm from forms.selectorform import SelectorForm 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