# AGPL 3 or any later version
# (C) J.Y.Amihud ( Blender Dumbass )
import os
import json
from datetime import datetime
from modules import Set
from modules import markdown
from modules.Common import *
def guess_type(path):
if "/json/" in path or ".json" in path:
return "application/json"
if "/css" in path or ".css" in path:
return "text/css"
if "/icon" in path or path.endswith(".png"):
return "image/png"
if path.endswith("jpg"):
return "image/jpg"
return "text/html"
def headers(server, code):
# Basic cookie for logins to work
cookie = False
if "Cookie" not in str(server.headers):
cookie = True
server.send_response(code)
server.send_header("Content-type", guess_type(server.path))
if cookie:
server.send_header("Set-Cookie", RandString())
server.end_headers()
def head(title="", description="", image="", config={}):
if image.startswith("/"): image = config.get("url","")+image
favicon = config.get("favicon", "/icon/internet")
html = """
"""+title+"""
"""
return html
def send(server, html, code):
# Add headers
headers(server, code)
server.wfile.write(html.encode("utf-8"))
def tabs():
folder = Set.Folder()+"/tabs"
tabs = {}
for tab in sorted(list(os.walk(folder))[0][1]):
try:
with open(folder+"/"+tab+"/config.json") as o:
data = json.load(o)
tabs[tab] = data
except Exception as e:
print(e)
pass
return tabs
def articles(tab):
folder = Set.Folder()+"/tabs/"+tab
articles = {}
for article in list(os.walk(folder))[0][1]:
try:
with open(folder+"/"+article+"/metadata.json") as o:
data = json.load(o)
articles[article] = data
except Exception as e:
print(e)
pass
# Sorting articles based on timestamp
articles = {k:articles[k] for k in sorted(articles, key=lambda y: articles[y]["timestamp"], reverse=True)}
return articles
###
def MainPage(server):
# Reading config
config = Set.Load()
# Generating
html = head(title = config.get("title", "Website"),
description = config.get("description", "Description"),
config = config
)
html = html + """
"""+config.get("title", "My Website")+"""
"""+config.get("tagline", "")+"""
"""
Tabs = tabs()
for tab in Tabs:
html = html + Button(Tabs[tab].get("title", tab),
"/"+tab,
Tabs[tab].get("icon", "folder"))
html = html + "
"
for i in range(50): html = html + " "
html = html + Footer()
send(server, html, 200)
def ListPage(server, tab):
Tabs = tabs()
Articles = articles(tab)
config = Set.Load()
try: page = int(server.parsed.get("page", ["0"])[0])
except Exception as e:
print(e)
page = 0
Buffer = 16
From = Buffer*page
To = From+Buffer
# Generating
html = head(title = Tabs.get(tab, {}).get("title", tab),
description = "",
config = config
)
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
# Scroll thingie
if len(Articles) > Buffer:
if page > 0:
html = html + Button(str(page-1), tab+"?page="+str(page-1), "left")
html = html + '
'+str(page)+'
'
if To < len(Articles)-1:
html = html + Button(str(page+1), tab+"?page="+str(page+1), "right")
html = html + """
"""
print(page)
rendered = 0
for n, article in enumerate(Articles):
if n < From: continue
if n >= To: break
html = html + ArticlePreview(Articles[article],
tab+"/"+article,
tab, Tabs)
rendered += 1
html = html + '
'
# Bottom pannel for large dialogs
if rendered >= Buffer/2:
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
# Scroll thingie
if len(Articles) > Buffer:
if page > 0:
html = html + Button(str(page-1), tab+"?page="+str(page-1), "left")
html = html + '
'+str(page)+'
'
if To < len(Articles)-1:
html = html + Button(str(page+1), tab+"?page="+str(page+1), "right")
send(server, html, 200)
def ArticlePage(server, url):
if url.endswith(".md"):
url = url.replace(".md", "")
config = Set.Load()
tab, article = url.split("/")
Tabs = tabs()
Articles = articles(tab)
# Generating
html = head(title = Tabs.get(tab, {}).get("title", tab),
description = "",
config = config
)
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
html = html + Button(Tabs.get(tab, {}).get("title", tab), "/"+tab, Tabs.get(tab, {}).get("icon", "folder"))
# The article itself
html = html + '
"
# Page author
author = Articles.get(article, {}).get("author", "")
if author:
html = html + '
'+User( author )+'
'
# Page views
# Views are calculated using an iframe which only loads when the page is
# rendered in a browser. It is also looking at whether the same cookie renders
# the same page, to avoid double counting from the same person.
# The iframe itself shows a graph of views.
views = str(Articles.get(article, {}).get("views", {}).get("amount", 0))
html = html + '
👁 '+views+''
html = html + """
"""
html = html + '
'
# Audio recording of the article
recording = Articles.get(article, {}).get("recording", "")
if recording:
html = html + ''
html = html + '
'
html = html + markdown.convert(Set.Folder()+"/tabs/"+tab+"/"+article+"/text.md")
html = html + '