diff --git a/build.sh b/build.sh index d96742c..c08232d 100755 --- a/build.sh +++ b/build.sh @@ -5,6 +5,15 @@ set -x -o pipefail tag=$1 build=$2 +cat <src/.buildinfo.json +{ + "tag": "${tag}:${build}", + "date": "$(date -I)", + "host": "$(hostname -f)", + "user": "${USER}" +} +EOF + docker build -t ${tag}:latest . if [[ $build != "" ]]; then docker build -t ${tag}:${build} . diff --git a/config/httpd.conf b/config/httpd.conf index df690f4..3728e8e 100755 --- a/config/httpd.conf +++ b/config/httpd.conf @@ -432,6 +432,14 @@ WSGIScriptAlias / /var/www/jc/projects.wsgi Require all granted +Alias "/static" "/var/www/jc/static/" + + Order allow,Deny + Allow from all + + +Alias "/robots.txt" "/var/www/jc/static/robots.txt" + Require all granted diff --git a/debug_local.sh b/debug_local.sh new file mode 100755 index 0000000..6efefde --- /dev/null +++ b/debug_local.sh @@ -0,0 +1,9 @@ +#!/bin/bash --noprofile + +run() { + python3 src/projects.wsgi || run +} + +export DISCORD_ERR_HOOK='dummy' +run +unset DISCORD_ERR_HOOK \ No newline at end of file diff --git a/src/.buildinfo.json b/src/.buildinfo.json new file mode 100755 index 0000000..6ce3573 --- /dev/null +++ b/src/.buildinfo.json @@ -0,0 +1,6 @@ +{ + "tag": "jc-ng-localtest:", + "date": "2025-06-15", + "host": "jake-e580", + "user": "jake" +} diff --git a/src/index.py b/src/index.py index 9e3d781..98057c4 100755 --- a/src/index.py +++ b/src/index.py @@ -12,6 +12,7 @@ app = Flask(__name__) # These imports need to come after our app is defined as they add routes to it. import projects # pylint: disable=wrong-import-position,unused-import import contact # pylint: disable=wrong-import-position,unused-import +import sitemap # pylint: disable=wrong-import-position,unused-import class DiscordLogger(logging.Handler): ''' Simple logging handler to send a message to Discord ''' diff --git a/src/projects.py b/src/projects.py index d6a9729..97be9c1 100755 --- a/src/projects.py +++ b/src/projects.py @@ -45,7 +45,7 @@ def to_html(content: str) -> str: ''' Jninja filter to wrap markdown ''' return markdown(content) -def get_all_posts(directory: str) -> list: +def get_all_posts(directory: str = md_directory) -> list: ''' Get all posts in the posts directory ''' abs_paths = [path.join(directory, x) for x in glob(f'{directory}/*.md')] return [frontmatter.load(x) for x in abs_paths] diff --git a/src/projects.wsgi b/src/projects.wsgi index 02fed47..62fcc3c 100755 --- a/src/projects.wsgi +++ b/src/projects.wsgi @@ -4,3 +4,6 @@ import sys sys.path.append('/var/www/jc') from index import app as application + +if __name__ == '__main__': + application.run(debug=True) \ No newline at end of file diff --git a/src/sitemap.py b/src/sitemap.py new file mode 100755 index 0000000..a43609d --- /dev/null +++ b/src/sitemap.py @@ -0,0 +1,42 @@ +#!/usr/bin/python3 + +import xml.etree.ElementTree as ET +import json +from flask import url_for, request, Response +from re import match +from index import app +from projects import get_all_posts + +def get_routes() -> list: + routes = [] + for rule in app.url_map.iter_rules(): + if 0 >= len(rule.arguments): + url = url_for(rule.endpoint, **(rule.defaults or {})) + routes.append(url) + return routes + +def get_build_date(): + try: + with open('/var/www/jc/.buildinfo.json', encoding='utf8') as build: + build_json = json.load(build) + return build_json['date'] + except: + return '1970-01-01' + +@app.route('/sitemap.xml') +def sitemap(): + date = get_build_date() + root = ET.Element('urlset', xmlns='http://www.sitemaps.org/schemas/sitemap/0.9') + base_url = match(r'^https?:\/\/.+:?\d*(?=\/)', request.base_url).group() + for route in get_routes(): + url = ET.SubElement(root, 'url') + ET.SubElement(url, 'loc').text = base_url + route + ET.SubElement(url, 'lastmod').text = date + for article in get_all_posts(): + if 'link' in article.metadata: + continue + url = ET.SubElement(root, 'url') + ET.SubElement(url, 'loc').text = f'{base_url}/projects/{article.metadata['id']}' + ET.SubElement(url, 'lastmod').text = article.metadata['date'].strftime('%Y-%m-%d') + + return Response(ET.tostring(root, encoding='utf-8'), 200, {'content-type': 'application/xml'}) \ No newline at end of file diff --git a/src/static/robots.txt b/src/static/robots.txt new file mode 100755 index 0000000..c0d0576 --- /dev/null +++ b/src/static/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://jakecharman.co.uk/sitemap.xml \ No newline at end of file