From: Max Value Date: Tue, 2 Dec 2025 17:31:06 +0000 (+0000) Subject: rebuild for CRJ X-Git-Url: https://git.ozva.co.uk/?a=commitdiff_plain;h=e032a1c5acb52b7bbef5fc8f63fedbb5068eba6d;p=chester rebuild for CRJ --- diff --git a/Makefile b/Makefile index 5ac3925..565ee29 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ all : .venv/touchfile +test : .venv/touchfile + .venv/bin/python site/main.py + .venv/touchfile : requirements.txt python3 -m venv .venv .venv/bin/pip install -r requirements.txt diff --git a/site/__pycache__/categories.cpython-313.pyc b/site/__pycache__/categories.cpython-313.pyc new file mode 100644 index 0000000..e5f5524 Binary files /dev/null and b/site/__pycache__/categories.cpython-313.pyc differ diff --git a/site/__pycache__/media.cpython-313.pyc b/site/__pycache__/media.cpython-313.pyc new file mode 100644 index 0000000..a8ecbca Binary files /dev/null and b/site/__pycache__/media.cpython-313.pyc differ diff --git a/site/__pycache__/page.cpython-313.pyc b/site/__pycache__/page.cpython-313.pyc new file mode 100644 index 0000000..531beba Binary files /dev/null and b/site/__pycache__/page.cpython-313.pyc differ diff --git a/site/__pycache__/search.cpython-313.pyc b/site/__pycache__/search.cpython-313.pyc new file mode 100644 index 0000000..df4e86f Binary files /dev/null and b/site/__pycache__/search.cpython-313.pyc differ diff --git a/site/__pycache__/utils.cpython-313.pyc b/site/__pycache__/utils.cpython-313.pyc new file mode 100644 index 0000000..134e04e Binary files /dev/null and b/site/__pycache__/utils.cpython-313.pyc differ diff --git a/site/blog.py b/site/blog.py deleted file mode 100755 index 1f35152..0000000 --- a/site/blog.py +++ /dev/null @@ -1,228 +0,0 @@ -#! .venv/bin/python3 - -from flask import Flask, Response, request, render_template_string, redirect, send_from_directory -import markdown -from os import listdir, environ -from os.path import getmtime -from markdown.extensions.toc import TocExtension -import re -import time - -app = Flask(__name__) -md = markdown.Markdown(extensions = ['meta', 'tables', 'footnotes', TocExtension(title = "Table of contents")]) - -blog_path = environ["BLOG_PATH"] - -repo = Repo.init(blog_path) - -class Page(): - def __init__( - self, - title: str = "Unamed page", - abstract: str = "", - keywords: list = ["Undefined"], - date: str = "n.d.", - content: str = "", - template: str = "page.html", - filename: str = "" - ): - - self.title = title - self.abstract = abstract - self.keywords = keywords - self.date = date - self.content = content - self.template = template - self.filename = filename - - def from_metadata(self, metadata): - if "title" in metadata: self.title = metadata["title"].title() - if "abstract" in metadata: self.abstract = metadata["abstract"] - if "keywords" in metadata: self.keywords = [x.strip().title() for x in metadata["keywords"].split(",")] - if "date" in metadata: self.date = metadata["date"] - - def make(self): - format_keywords = " - ".join([f"{key}" for key in self.keywords]) - - template_string = open(f"{blog_path}/templates/{self.template}", "r").read() - - with open(f"{blog_path}/templates/sidebar.md", "r") as f: - sidebar = md.convert(f.read()) - - page = render_template_string( - template_string, - title = self.title, - date = self.date, - abstract = self.abstract, - keywords = format_keywords, - content = self.content, - filename = self.filename, - sidebar = sidebar - ) - - return Response(page, mimetype="text/html") - -def get_plaintext(file_name: str): - page = open(f"{blog_path}/pages/{file_name}", "r").read() - return re.sub( - r"((?[\S ]*)|(``*)", - "", - page) - -def get_metadata(file_name: str): - title = "Untitled post" - abstract = "..." - keywords = ["Undefined"] - - with open(f"{blog_path}/pages/{file_name}", "r") as f: - while keywords == ["Undefined"]: - line = f.readline().split(":") # Split metdata into [key, value] - if len(line) == 2: # len != 2 when metadata block is over - key, value = line - match key: - case "title": - title = value.strip().title() - case "abstract": - abstract = value.strip() - case "keywords": - keywords = [x.strip() for x in value.split(",")] - else: - break - - return title, abstract, keywords - -def get_recent(n): - modification_times = {file_name: getmtime(f"{blog_path}/pages/{file_name}") for file_name in listdir(f"{blog_path}/pages")} - pages = sorted(modification_times.items(), key=lambda x: x[1])[:n] - - content = "

Recent Posts

" - - return content - -@app.route("/") -def homepage(): - with open(f"{blog_path}/templates/homepage.md", "r") as f: - homepage = md.convert(f.read()) - - page = Page( - title = "Home", - abstract = "Blog and portfolio of Will Greenwood.", - keywords = [], - date = "", - content = homepage + get_recent(10), - template = "page.html" - ) - return page.make() - -@app.route("/search") -def get_search(): - search = request.args.get("name") - - results = 0 - content = f"

Search '{search}'

No results found

" - else: - content += f"

{results} results found

" - - page = Page( - title = "Post search", - date = "", - keywords = [], - content = content - ) - return page.make() - -@app.route("/categories") -def get_categories(): - name = request.args.get("name") - index = {} - - if name == "all": - return redirect("/categories") - - for file_name in listdir(f"{blog_path}/pages"): - title, abstract, keywords = get_metadata(file_name) - - entry = {"title": title, "abstract": abstract, "path": f"/{file_name[:-3]}"} - for key in keywords: - if key in index: - index[key] += [entry] - - elif name is None: - index.update({key: [entry]}) - - elif key.lower() == name.lower(): - index.update({key: [entry]}) - - content = "" - for c in index: - content += f"

{c.title()}

" - - page = Page( - title = "Keyword search", - abstract = "Click on a keyword to see all pages tagged with that keyword.", - date = "", - keywords = [c.title() for c in index] + ["All"], - content = content - ) - return page.make() - -@app.route("/") -def generate_page(title): - title = title.replace("/", "") - try: - with open(f"{blog_path}/pages/{title}.md", "r") as f: - html = md.convert(f.read()) - metadata = {k: v[0] for k, v in md.Meta.items()} - md.reset() - - page = Page(content = html, filename = title) - page.from_metadata(metadata) - return page.make() - - except FileNotFoundError: - page = Page(title = "404", abstract = "Page not found!") - return page.make() - -@app.route("//") -def get_media(title, filename): - return send_from_directory(f"{blog_path}/media/{title}", filename) - -if __name__ == "__main__": - app.run(host='127.0.0.1', port=5000, debug=True) diff --git a/site/main.py b/site/main.py new file mode 100755 index 0000000..2db81ec --- /dev/null +++ b/site/main.py @@ -0,0 +1,200 @@ +#! .venv/bin/python3 + +from flask import Flask, Response, request, render_template_string, redirect, send_file +import markdown +from os import listdir, environ +from os.path import getmtime, basename +from markdown.extensions.toc import TocExtension +import glob +import re +import time + +app = Flask(__name__) +md = markdown.Markdown(extensions = ['meta', 'footnotes', TocExtension(title = "Table of contents")]) + +class Page(): + def __init__( + self, + title: str = "Unamed page", + keywords: list = ["Undefined"], + date: str = "n.d.", + content: str = "", + filename: str = "" + ): + + self.title = title + self.keywords = keywords + self.date = date + self.content = content + self.filename = filename + + def from_metadata(self, metadata): + if "title" in metadata: self.title = metadata["title"].title() + if "keywords" in metadata: self.keywords = [x.strip().title() for x in metadata["keywords"].split(",")] + if "date" in metadata: self.date = metadata["date"] + + def make(self): + format_keywords = " - ".join([f"{key}" for key in self.keywords]) + + template_string = open(f"{app.root_path}/templates/page.html", "r").read() + + page = render_template_string( + template_string, + title = self.title, + date = self.date, + keywords = format_keywords, + content = self.content, + filename = self.filename, + sidebar = get_categories() + ) + + return Response(page, mimetype="text/html") + +def get_files(): + data = glob.glob(f"{app.root_path}/src/**/*", recursive=True) + + data = { + basename(x): x + for x in data + } + + return data + +def get_plaintext(file_name: str): + page = open(get_files()[file_name], "r").read() + return re.sub( + r"((?[\S ]*)|(``*)", + "", + page) + +def get_metadata(file_name: str): + title = "Untitled post" + keywords = ["Undefined"] + + with open(get_files()[file_name], "r") as f: + while keywords == ["Undefined"]: + line = f.readline().split(":") # Split metdata into [key, value] + if len(line) == 2: # len != 2 when metadata block is over + key, value = line + match key: + case "title": + title = value.strip().title() + case "keywords": + keywords = [x.strip() for x in value.split(",")] + else: + break + + return title, keywords + +@app.route("/") +def homepage(): + with open(f"{app.root_path}/src/homepage.md", "r") as f: + homepage = md.convert(f.read()) + + page = Page( + title = "Home", + keywords = [], + date = "", + content = homepage, + ) + return page.make() + +@app.route("/search") +def get_search(): + search = request.args.get("name") + + results = 0 + content = f"

'{search}'

    " + + if search != "": + for file_name in get_files(): + if file_name[-3:] != ".md": continue + page = get_plaintext(file_name) + i = page.casefold().find(search.casefold()) + + if i != -1: + results += 1 + content += f""" +
  • + + {get_metadata(file_name)[0]} + - + '... + {page[i:i+len(search)]} + {page[i+len(search):i+50]} + ...' + +
  • """ + + if results == 0: + content += "

No results found

" + else: + content += f"

{results} results found

" + + page = Page( + title = "Search", + date = "", + keywords = [], + content = content + ) + return page.make() + +def get_categories(): + name = request.args.get("name") + index = {} + + for file_name in get_files(): + if file_name[-3:] != ".md": continue + elif file_name == "homepage.md": continue + elif file_name == "example.md": continue + title, keywords = get_metadata(file_name) + + entry = {"title": title, "path": f"/{file_name[:-3]}"} + for key in keywords: + if key in index: + index[key] += [entry] + + elif name is None: + index.update({key: [entry]}) + + elif key.lower() == name.lower(): + index.update({key: [entry]}) + + content = "" + for c in index: + content += f"
{c.title()}
    " + + for post in index[c]: + content += f"
  • {post['title']}
  • " + + content += "
" + + return content + +@app.route("/") +def generate_page(title): + if "." in title: + path = get_files()[title] + return send_file(path) + + title = title.replace("/", "") + try: + with open(get_files()[f"{title}.md"], "r") as f: + html = md.convert(f.read()) + metadata = {k: v[0] for k, v in md.Meta.items()} + md.reset() + + page = Page(content = html, filename = title) + page.from_metadata(metadata) + return page.make() + + except FileNotFoundError: + page = Page(title = "404") + return page.make() + +@app.route("//") +def get_media(title, filename): + return send_from_directory(f"{app.root_path}/media/{title}", filename) + +if __name__ == "__main__": + app.run(host='127.0.0.1', port=5000, debug=True) diff --git a/site/src/bayeux.md b/site/src/bayeux.md new file mode 100644 index 0000000..d775ae1 --- /dev/null +++ b/site/src/bayeux.md @@ -0,0 +1,72 @@ +title: An Audio Bayeux Tapestry +keywords: programming,audio +date: 16/12/2024 + +# An Audio Bayeux Tapestry + +Hello! + +With the power of technology, the Bayeux tapestry is now avaiable for the blind. + +