distribusi-verse/verse/editor.py

196 lines
6.5 KiB
Python

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