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, APP from distribusikan.distribusis_info 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 css_editor_page(): editorform = EditorForm() current_distribusi = UserHelper.current_distribusi() if editorform.validate_on_submit(): validate_edit_css_form(editorform, current_distribusi) return render_distribusi_template(current_distribusi) return render_editor_template(editorform, current_distribusi) def validate_edit_css_form(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: make_public_theme(editorform, current_distribusi) if editorform.cssfile.data: save_upload_css_file(editorform, publicfolder) copy_public_to_user_folder(editorform, publicfolder, newcssfolder) return else: write_css_to_file(editorform, publicfolder) if editorform.cssfile.data: save_upload_css_file(editorform, newcssfolder) return if editorform.cssname.data: write_css_to_file(editorform, newcssfolder) def save_upload_css_file(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 write_css_to_file(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 copy_public_to_user_folder(editorform, publicfolder, newcssfolder): if not os.path.exists(newcssfolder): os.mkdir(newcssfolder) copycssfile = os.path.join( publicfolder, f"{secure_filename(editorform.cssname.data)}.css" ) APP.logger.info(f"copying file:{copycssfile} to folder:{newcssfolder}") shutil.copy(copycssfile, newcssfolder) def make_public_theme(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 render_distribusi_template(current_distribusi): uploadform = UploadForm() distribusiform = DistribusiForm() themeform = ThemeForm() publicthemeform = PublicThemeForm() publicthemeform.publicthemes.choices = DistribusisInfo.public_themes() 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 render_editor_template(editorform, current_distribusi): html_placeholder = get_html_placeholder() css_placeholder = get_css_placeholder(current_distribusi) editorform.css.data = css_placeholder 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, html_placeholder=html_placeholder, ) return template def get_css_placeholder(current_distribusi): css_placeholder = "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: css_placeholder = get_public_css_file(distribusi) else: with open("themes/editor/placeholder.css") as f: css_placeholder = f.read() return css_placeholder def get_html_placeholder(): html_placeholder = "Write some test HTML here" with open("themes/editor/placeholder.html") as f: html_placeholder = f.read() return html_placeholder def get_public_css_file(distribusi): css_placeholder = "" 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: css_placeholder = f.read() return css_placeholder