Initial commit.
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
# AGPL 3 or any later version
|
||||
# (C) J.Y.Amihud ( Blender Dumbass )
|
||||
|
||||
import os
|
||||
import json
|
||||
|
||||
from modules import Set
|
||||
from modules import Render
|
||||
from modules import markdown
|
||||
from modules.Common import *
|
||||
|
||||
def themes():
|
||||
|
||||
# Returns the metadata of all themes.
|
||||
|
||||
folder = Set.Folder()+"/themes/"
|
||||
|
||||
themes = {}
|
||||
|
||||
for theme in list(os.walk(folder))[0][1]:
|
||||
try:
|
||||
with open(folder+theme+"/theme.json") as o:
|
||||
data = json.load(o)
|
||||
data["id"] = theme
|
||||
themes[theme] = data
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
return themes
|
||||
|
||||
def load(ID):
|
||||
|
||||
# Load the raw CSS of a specific ID.
|
||||
|
||||
folder = Set.Folder()+"/themes/"+ID
|
||||
CSS = ""
|
||||
CSS = open(folder+"/theme.css", "r").read()
|
||||
|
||||
return CSS
|
||||
|
||||
def get_theme(server, config, user, author={}):
|
||||
|
||||
# Load a theme for a specific user
|
||||
|
||||
# Getting the server defaults
|
||||
default = config.get("css", "default.css")
|
||||
posts = author.get("css_posts")
|
||||
personal = user.get("css_personal")
|
||||
|
||||
if user.get("css_user_global_priority") or not posts:
|
||||
theme = personal
|
||||
|
||||
elif posts:
|
||||
theme = posts
|
||||
|
||||
try:
|
||||
cssfile = load(theme)
|
||||
except Exception as e:
|
||||
if theme:
|
||||
print(e)
|
||||
cssfile = open(default, "r").read()
|
||||
|
||||
return cssfile
|
||||
|
||||
|
||||
def Preview(server, ID, user={}, download=True, set_website=False, set_personal=False, set_posts=False):
|
||||
|
||||
if not user:
|
||||
user = Render.validate(server.cookie)
|
||||
|
||||
|
||||
html = '<!-- Themes.Preview -->'
|
||||
html = html + '<div class="dark_box" style="min-height:180px;"><br>'
|
||||
|
||||
metadata = themes().get(ID, {})
|
||||
|
||||
thumbnail = metadata.get("thumbnail", "")
|
||||
if thumbnail:
|
||||
html = html + '<img alt="[avatar]" style="height:150px;float:left;margin-right:20px;margin-bottom:20px" src="'+thumbnail+'">'
|
||||
|
||||
name = Safe(metadata.get("name", "Theme"))
|
||||
html = html + '<b>' + name + '</b>\n'
|
||||
|
||||
author = Safe(metadata.get("author", ""))
|
||||
if author:
|
||||
html = html + "<br><br>" + Render.User(author)
|
||||
|
||||
description = Safe(metadata.get("description", ""))
|
||||
html = html + '<small>'+markdown.convert(description, False)+"</small><br>"
|
||||
|
||||
html = html + "<br><br><br>"
|
||||
|
||||
# Doing things with themes
|
||||
|
||||
if download:
|
||||
html = html + Render.Button("View", "/themes/"+ID, "view", newpage=True)
|
||||
|
||||
# Editing
|
||||
|
||||
edits = Render.editsIn(user.get("username", ""), "Themes_CSS")
|
||||
|
||||
if edits and metadata.get("author") == user.get("username"):
|
||||
|
||||
html = html + Render.Button("Edit", "/theme_editor?id="+ID, "edit")
|
||||
|
||||
if edits:
|
||||
|
||||
html = html + Render.Button("Fork", "/theme_editor?id="+ID+"&fork=True", "checklist_new")
|
||||
|
||||
if set_personal:
|
||||
|
||||
icon = "unchecked"
|
||||
if user.get("css_personal") == ID:
|
||||
icon = "checked"
|
||||
|
||||
html = html + Render.Button("Personal", "/settings?set_personal_theme="+ID+"#css", icon)
|
||||
|
||||
if set_posts:
|
||||
|
||||
icon = "unchecked"
|
||||
if user.get("css_posts") == ID:
|
||||
icon = "checked"
|
||||
|
||||
html = html + Render.Button("Posts", "/settings?set_posts_theme="+ID+"#css", icon)
|
||||
|
||||
html = html + '</div><!-- /Themes.Preview -->'
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def ViewPage(server, ID):
|
||||
|
||||
metadata = themes().get(ID, {})
|
||||
cssfile = load(ID)
|
||||
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
html = Render.head(server,
|
||||
title = metadata.get("name", "Theme"),
|
||||
description = metadata.get("description", ""),
|
||||
image = metadata.get("thumbnail", ""),
|
||||
config = config,
|
||||
author = metadata.get("author")
|
||||
)
|
||||
|
||||
html = html + Render.Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
|
||||
html = html + Render.Button("Themes", "/themes", "theme")
|
||||
|
||||
html = html + '<!-- Themes.ViewPage -->'
|
||||
|
||||
html = html + '<div class="middle_box">'
|
||||
|
||||
html = html + Preview(server, ID, download=False)
|
||||
|
||||
html = html + "<br><br>"
|
||||
|
||||
html = html + "<pre>" + markdown.code_highlight(cssfile) + "</pre><br><br>"
|
||||
|
||||
html = html + '</div>'
|
||||
|
||||
html = html + Render.LoginButton(server)
|
||||
|
||||
Render.send(server, html, 200)
|
||||
|
||||
|
||||
def Editor(server):
|
||||
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
html = Render.head(server,
|
||||
title = "Theme Editor",
|
||||
description = "Theme Editor",
|
||||
config = config
|
||||
)
|
||||
|
||||
html = html + Render.Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
|
||||
|
||||
html = html + '<!-- Themes.Editor -->'
|
||||
|
||||
ID = server.parsed.get("id", [""])[0]
|
||||
FORK = server.parsed.get("fork", [""])[0]
|
||||
|
||||
if ID:
|
||||
metadata = themes().get(ID, {})
|
||||
text = load(ID)
|
||||
else:
|
||||
metadata = {}
|
||||
text = open("default.css", "r").read()
|
||||
|
||||
html = html + """
|
||||
|
||||
<div class="middle_section_article">
|
||||
|
||||
<div class="dark_box">
|
||||
|
||||
<form action="do_theme_edit" method="post">"""
|
||||
|
||||
if FORK:
|
||||
metadata["name"] = "Fork of "+metadata.get("name", "Theme")
|
||||
|
||||
if ID and not FORK:
|
||||
html = html + '<input type="hidden" name="id" value="'+ID.replace("'", "'")+'">'
|
||||
|
||||
html = html + """
|
||||
|
||||
<img style="vertical-align: middle" src="/icon/theme">
|
||||
<input class="button" style="width:90%" required="" name="name" placeholder="Name" value='"""+metadata.get("name", "").replace("'", "'")+"""'>
|
||||
|
||||
<img style="vertical-align: middle" src="/icon/image_link">
|
||||
<input class="button" style="width:90%" name="thumbnail"
|
||||
placeholder="Screenshot"
|
||||
title="A link to the image which will be rendered alongside the title. A visual representation of the theme."
|
||||
value='"""+metadata.get("thumbnail", "").replace("'", "'")+"""'>
|
||||
|
||||
<center>
|
||||
<textarea class="toot" rows="5" style="width:95%" name="description" placeholder="Description">"""+metadata.get("description", "")+"""</textarea>
|
||||
|
||||
<br>
|
||||
|
||||
<textarea class="pre" rows="30" style="width:95%" required="" name="text" placeholder="Text of your post">"""+Safe(text)+"""</textarea>
|
||||
|
||||
</center>
|
||||
|
||||
<br>
|
||||
<button class="button" type="submit">
|
||||
<img class="icon" style="vertical-align: middle" src="/icon/ok">
|
||||
Publish
|
||||
</button>
|
||||
|
||||
|
||||
</div>
|
||||
"""
|
||||
|
||||
|
||||
|
||||
html = html + '</div>'
|
||||
|
||||
html = html + '<div class="checklist_section_article">'
|
||||
html = html + Render.Button("+ Image", "/upload_image", "image_new", newpage=True)+'<br><br>'
|
||||
html = html + '</div>'
|
||||
|
||||
html = html + Render.LoginButton(server)
|
||||
|
||||
Render.send(server, html, 200)
|
||||
|
||||
|
||||
def DoThemeEdit(server):
|
||||
|
||||
user = Render.validate(server.cookie)
|
||||
|
||||
if not user or not Render.editsIn(user.get("username", ""), "Themes_CSS"):
|
||||
Render.AccessDenied(server)
|
||||
return
|
||||
|
||||
ID = server.parsed.get("id", [""])[0]
|
||||
name = server.parsed.get("name", [""])[0]
|
||||
thumbnail = server.parsed.get("thumbnail", [""])[0]
|
||||
description = server.parsed.get("description", [""])[0]
|
||||
text = server.parsed.get("text", [""])[0]
|
||||
|
||||
if ID:
|
||||
metadata = themes().get(ID, {})
|
||||
|
||||
if user.get("username") != metadata.get("author"):
|
||||
Render.AccessDenied(server)
|
||||
return
|
||||
|
||||
else:
|
||||
|
||||
ID = RandString()
|
||||
metadata = {"author":user.get("username", "")}
|
||||
|
||||
metadata["name"] = name
|
||||
metadata["thumbnail"] = thumbnail
|
||||
metadata["description"] = description
|
||||
|
||||
folder = Set.Folder()+"/themes/"+ID
|
||||
|
||||
# Making the folders
|
||||
try: os.makedirs(folder)
|
||||
except: pass
|
||||
|
||||
# Saving the CSS file
|
||||
filename = folder+"/theme.css"
|
||||
with ThreadLock(filename):
|
||||
with open(filename, "w") as save:
|
||||
save.write(text)
|
||||
|
||||
# Saving the metadata
|
||||
filename = folder+"/theme.json"
|
||||
with ThreadLock(filename):
|
||||
with open(filename, "w") as save:
|
||||
json.dump(metadata, save, indent=4)
|
||||
|
||||
Render.Redirect(server, "themes/"+ID)
|
||||
|
||||
|
||||
def ListPage(server):
|
||||
|
||||
user = Render.validate(server.cookie)
|
||||
config = Set.Load()
|
||||
|
||||
html = Render.head(server,
|
||||
title = "Themes",
|
||||
description = "Themes",
|
||||
config = config
|
||||
)
|
||||
|
||||
html = html + Render.Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
|
||||
|
||||
html = html + '<!-- Themes.ListPage -->'
|
||||
html = html + '<div class="middle_box">'
|
||||
|
||||
allThemes = themes()
|
||||
for theme in allThemes:
|
||||
html = html + Preview(server, theme, user)
|
||||
|
||||
html = html + '</div>'
|
||||
|
||||
html = html + Render.Footer(server)
|
||||
html = html + Render.LoginButton(server)
|
||||
|
||||
Render.send(server, html, 200)
|
||||
Reference in New Issue
Block a user