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 distribusisinfo import DistribusisInfo from forms.distribusiform import DistribusiForm from forms.editorform import EditorForm from forms.publicthemeform import PublicThemeForm from forms.selectorform import SelectorForm from forms.themeform import ThemeForm from forms.uploadform import UploadForm from models.distribusimodel 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