feat: add xsl stylesheet to changelogs (#21930)

This commit is contained in:
Matt
2024-01-07 03:02:36 +00:00
committed by GitHub
parent b85a9d7688
commit 40e4d43c3b
3 changed files with 104 additions and 11 deletions

View File

@@ -14,7 +14,7 @@ jobs:
steps: steps:
- name: Install dependencies - name: Install dependencies
run: sudo apt-get install -y python3-paramiko run: sudo apt-get install -y python3-paramiko python3-lxml
- uses: actions/checkout@v3.6.0 - uses: actions/checkout@v3.6.0
with: with:

View File

@@ -10,16 +10,15 @@
# $env:CHANGELOG_RSS_KEY=[System.IO.File]::ReadAllText($(gci "key")) # $env:CHANGELOG_RSS_KEY=[System.IO.File]::ReadAllText($(gci "key"))
import os import os
import pathlib
import io import io
import paramiko
import base64 import base64
import yaml import yaml
import sys
import itertools import itertools
import html import html
import email.utils import email.utils
from typing import Optional, List, Any, Tuple from typing import List, Any, Tuple
import xml.etree.ElementTree as ET from lxml import etree as ET
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
MAX_ITEM_AGE = timedelta(days=30) MAX_ITEM_AGE = timedelta(days=30)
@@ -33,6 +32,7 @@ SSH_HOST = "centcomm.spacestation14.io"
SSH_USER = "changelog-rss" SSH_USER = "changelog-rss"
SSH_PORT = 22 SSH_PORT = 22
RSS_FILE = "changelog.xml" RSS_FILE = "changelog.xml"
XSL_FILE = "stylesheet.xsl"
HOST_KEYS = [ HOST_KEYS = [
"AAAAC3NzaC1lZDI1NTE5AAAAIEE8EhnPjb3nIaAPTXAJHbjrwdGGxHoM0f1imCK0SygD" "AAAAC3NzaC1lZDI1NTE5AAAAIEE8EhnPjb3nIaAPTXAJHbjrwdGGxHoM0f1imCK0SygD"
] ]
@@ -102,10 +102,21 @@ def main():
et = ET.ElementTree(feed) et = ET.ElementTree(feed)
with sftp.open(RSS_FILE, "wb") as f: with sftp.open(RSS_FILE, "wb") as f:
et.write(f, encoding="utf-8", xml_declaration=True) et.write(
f,
encoding="utf-8",
xml_declaration=True,
# This ensures our stylesheet is loaded
doctype="<?xml-stylesheet type='text/xsl' href='./stylesheet.xsl'?>",
)
# Copy in the stylesheet
template_path = pathlib.Path(__file__, 'changelogs', XSL_FILE)
with sftp.open(XSL_FILE, "wb") as f, open(template_path) as fh:
f.write(fh)
def create_feed(changelog: Any, previous_items: List[ET.Element]) -> Tuple[ET.Element, bool]: def create_feed(changelog: Any, previous_items: List[Any]) -> Tuple[Any, bool]:
rss = ET.Element("rss", attrib={"version": "2.0"}) rss = ET.Element("rss", attrib={"version": "2.0"})
channel = ET.SubElement(rss, "channel") channel = ET.SubElement(rss, "channel")
@@ -128,7 +139,7 @@ def create_feed(changelog: Any, previous_items: List[ET.Element]) -> Tuple[ET.El
return rss, any return rss, any
def create_new_item_since(changelog: Any, channel: ET.Element, since: int, now: datetime) -> bool: def create_new_item_since(changelog: Any, channel: Any, since: int, now: datetime) -> bool:
entries_for_item = [entry for entry in changelog["Entries"] if entry["id"] > since] entries_for_item = [entry for entry in changelog["Entries"] if entry["id"] > since]
top_entry_id = max(map(lambda e: e["id"], entries_for_item), default=0) top_entry_id = max(map(lambda e: e["id"], entries_for_item), default=0)
@@ -174,7 +185,7 @@ def generate_description_for_entries(entries: List[Any]) -> str:
return desc.getvalue() return desc.getvalue()
def copy_previous_items(channel: ET.Element, previous: List[ET.Element], now: datetime): def copy_previous_items(channel: Any, previous: List[Any], now: datetime):
# Copy in previous items, if we have them. # Copy in previous items, if we have them.
for item in previous: for item in previous:
date_elem = item.find("./pubDate") date_elem = item.find("./pubDate")
@@ -189,7 +200,7 @@ def copy_previous_items(channel: ET.Element, previous: List[ET.Element], now: da
channel.append(item) channel.append(item)
def find_last_changelog_id(items: List[ET.Element]) -> int: def find_last_changelog_id(items: List[Any]) -> int:
return max(map(lambda i: int(i.get(XML_NS_B + "to-id", "0")), items), default=0) return max(map(lambda i: int(i.get(XML_NS_B + "to-id", "0")), items), default=0)
def load_key(key_contents: str) -> paramiko.PKey: def load_key(key_contents: str) -> paramiko.PKey:
@@ -204,7 +215,7 @@ def load_host_keys(host_keys: paramiko.HostKeys):
host_keys.add(SSH_HOST, "ssh-ed25519", paramiko.Ed25519Key(data=base64.b64decode(key))) host_keys.add(SSH_HOST, "ssh-ed25519", paramiko.Ed25519Key(data=base64.b64decode(key)))
def load_last_feed_items(client: paramiko.SFTPClient) -> List[ET.Element]: def load_last_feed_items(client: paramiko.SFTPClient) -> List[Any]:
try: try:
with client.open(RSS_FILE, "rb") as f: with client.open(RSS_FILE, "rb") as f:
feed = ET.parse(f) feed = ET.parse(f)

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ss14="https://spacestation14.com/changelog_rss">
<head>
<style>
<![CDATA[
body {
font-family: Arial;
font-size: 1.6em;
background-color: rgb(32, 32, 48);
max-width: 1024px;
margin: 0 auto;
}
.title {
font-size: 1.2em;
color: rgb(155, 34, 54);
font-weight: bold;
padding: 4px;
}
.author {
font-size: 1.2em;
}
.description {
margin-left: 20px;
margin-bottom: 1em;
font-size: 10pt;
color: rgb(199, 199, 199);
}
span {
color: white;
}
.changes li {
list-style-type: none;
padding: 1px;
}
li::before {
margin-right: 6px;
}
li.Tweak::before {
content: '🔧';
}
li.Fix::before {
content: '🐛';
}
li.Add::before {
content: '';
}
li.Remove::before {
content: '';
}
]]>
</style>
</head>
<body>
<xsl:for-each select="rss/channel/item">
<div class='title'>
<xsl:copy-of select="pubDate"/>
</div>
<div class='description'>
<xsl:for-each select="*[local-name()='entry']">
<div class='author'>
<span>
<xsl:value-of select="*[local-name()='author']"/>
</span> updated
</div>
<div class='changes'>
<ul>
<xsl:for-each select="*[local-name()='change']">
<li>
<xsl:attribute name="class">
<xsl:value-of select="@*" />
</xsl:attribute>
<xsl:copy-of select="node()" />
</li>
</xsl:for-each>
</ul>
</div>
</xsl:for-each>
</div>
</xsl:for-each>
</body>
</html>