mirror of
https://github.com/freedoom/freedoom.git
synced 2025-08-30 17:16:55 -04:00
scripts: Add news-to-feed script (#1042)
Rather than maintaining feed.xml on the website manually the news-to-feed script, added by this commit, will generate it based on NEWS.adoc in this repository. Also, make target news-to-feed has been added to run the script.
This commit is contained in:
parent
13f70d1e11
commit
6a54471431
2 changed files with 215 additions and 0 deletions
5
Makefile
5
Makefile
|
@ -227,6 +227,11 @@ rebuild-nodes: $(addprefix levels/,$(addsuffix .wad,$(NODE_BUILDER_LEVELS)))
|
|||
do \
|
||||
$(NODE_BUILDER) $$level -o $$level; \
|
||||
done
|
||||
|
||||
# Update feed.mxl (RSS feed) on the website based on NEWS.adoc. This assumes
|
||||
# that the website has the same parent directory as this build.
|
||||
news-to-feed: NEWS.adoc
|
||||
scripts/news-to-feed NEWS.adoc ../freedoom.github.io/feed.xml
|
||||
|
||||
%.6:
|
||||
$(MAKE) ASCIIDOC_MAN="$(ASCIIDOC_MAN)" -C dist $@
|
||||
|
|
210
scripts/news-to-feed
Executable file
210
scripts/news-to-feed
Executable file
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# new-to-feed - Convert NEWS.adoc to feed.xml
|
||||
#
|
||||
# This script converts from "NEWS.adoc" in the main Freedoom repository to
|
||||
# "feed.xml" on the Freedoom website, which is an RSS feed.
|
||||
#
|
||||
# It's possible that there is no need for this script given that GitHub
|
||||
# generates an Atom feed based on the releases done on GitHub. It can be
|
||||
# found at:
|
||||
# https://github.com/freedoom/freedoom/releases.atom
|
||||
# Perhaps the website should link to the above in place of the current
|
||||
# "atom.xml", and "feed.xml" should be abandon.
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from xml.dom.minidom import Document
|
||||
|
||||
# Globals
|
||||
|
||||
channel = None
|
||||
leading_whitespace = " "
|
||||
date = None
|
||||
desc_lines = []
|
||||
doc = None
|
||||
pubdate = None
|
||||
ver = None
|
||||
|
||||
# Regular expressions
|
||||
|
||||
# A regular expression that matches version / date lines.
|
||||
ver_date_patt = re.compile(r'\s*==\s+((?:\d+\.)+\d+)\s+\((\d{4}-\d{2}-\d{2})\)')
|
||||
|
||||
# Initial document processing and header prior to the first version.
|
||||
def add_header():
|
||||
global channel
|
||||
global doc
|
||||
|
||||
doc = Document()
|
||||
|
||||
rss = doc.createElement('rss')
|
||||
rss.setAttribute('version', '2.0')
|
||||
doc.appendChild(rss)
|
||||
|
||||
channel = doc.createElement('channel')
|
||||
rss.appendChild(channel)
|
||||
|
||||
title = doc.createElement('title')
|
||||
title.appendChild(doc.createTextNode('Freedoom Feed'))
|
||||
channel.appendChild(title)
|
||||
|
||||
link = doc.createElement('link')
|
||||
link.appendChild(doc.createTextNode('https://freedoom.github.io'))
|
||||
channel.appendChild(link)
|
||||
|
||||
description = doc.createElement('description')
|
||||
description.appendChild(doc.createTextNode('The latest news from Freedoom'))
|
||||
channel.appendChild(description)
|
||||
|
||||
language = doc.createElement('language')
|
||||
language.appendChild(doc.createTextNode('en-us'))
|
||||
channel.appendChild(language)
|
||||
|
||||
image = doc.createElement('image')
|
||||
channel.appendChild(image)
|
||||
|
||||
url = doc.createElement('url')
|
||||
url.appendChild(doc.createTextNode('https://freedoom.github.io/favicon.ico'))
|
||||
image.appendChild(url)
|
||||
|
||||
|
||||
# Called each time we have a complete version section
|
||||
def add_version():
|
||||
item = doc.createElement('item')
|
||||
channel.appendChild(item)
|
||||
|
||||
title_elem = doc.createElement('title')
|
||||
title_elem.appendChild(doc.createTextNode(date + ": Freedoom " + ver + " released"))
|
||||
item.appendChild(title_elem)
|
||||
|
||||
pubdate_elem = doc.createElement('pubDate')
|
||||
pubdate_elem.appendChild(doc.createTextNode(pubdate))
|
||||
item.appendChild(pubdate_elem)
|
||||
|
||||
link_elem = doc.createElement('link')
|
||||
link_elem.appendChild(doc.createTextNode("https://freedoom.github.io/#freedoom-" + ver))
|
||||
item.appendChild(link_elem)
|
||||
|
||||
# Avoid join() in order to treat newlines specially.
|
||||
nl_ws = "\n" + leading_whitespace
|
||||
desc_text = "\n"
|
||||
for desc_line in desc_lines:
|
||||
if desc_line:
|
||||
desc_text += leading_whitespace + desc_line + "\n" + leading_whitespace + "<p/>\n"
|
||||
else:
|
||||
desc_text += "\n"
|
||||
desc_elem = doc.createElement('description')
|
||||
desc_elem.appendChild(doc.createTextNode(desc_text))
|
||||
item.appendChild(desc_elem)
|
||||
|
||||
|
||||
# Iterates through news_adoc in order to process each version found.
|
||||
def add_versions():
|
||||
global date
|
||||
global desc_lines
|
||||
global pubdate
|
||||
global ver
|
||||
|
||||
first_section = True
|
||||
desc_line = ""
|
||||
with open(news_adoc) as news_hand:
|
||||
line_num = 0
|
||||
for line in news_hand:
|
||||
line_num += 1
|
||||
line = line.rstrip()
|
||||
ver_date_match = ver_date_patt.match(line)
|
||||
if ver_date_match:
|
||||
ver_date_match_groups = ver_date_match.groups()
|
||||
if len(ver_date_match_groups) != 2:
|
||||
# Should not happen.
|
||||
print("Line number", line_num, "has", len(ver_date_match_groups),
|
||||
"groups.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
# With the exception of the "HEAD" each new version line indicates
|
||||
# that the previous one is complete, so output it before setting
|
||||
# "pubdate" to the new value.
|
||||
if pubdate:
|
||||
add_version()
|
||||
desc_lines = []
|
||||
ver, date = ver_date_match.groups()
|
||||
pubdate = datetime.datetime.strptime(date, '%Y-%m-%d').strftime('%d %b %Y')
|
||||
first_section = True
|
||||
else:
|
||||
# Possible description text, but only after the first version date line.
|
||||
if not pubdate:
|
||||
continue
|
||||
line = line.strip()
|
||||
if line.startswith("=== "):
|
||||
# Add the existing line, if any.
|
||||
if desc_line:
|
||||
desc_lines.append(desc_line)
|
||||
desc_line = ""
|
||||
if first_section:
|
||||
first_section = False
|
||||
else:
|
||||
desc_lines.append("")
|
||||
desc_lines.append("> " + line[4:])
|
||||
first_section = False
|
||||
elif line.startswith("*"):
|
||||
if desc_line:
|
||||
desc_lines.append(desc_line)
|
||||
desc_line = ""
|
||||
try:
|
||||
space_index = line.index(" ")
|
||||
except ValueError:
|
||||
# Should not happen.
|
||||
print("Line number", line_num, "begins with \"*\", but has no space.")
|
||||
sys.exit(1)
|
||||
desc_line = ("- " * (space_index - 1) if (space_index > 1) \
|
||||
else "") + line[space_index + 1:]
|
||||
elif line:
|
||||
# Assume it's a continuation of the previous "*" line.
|
||||
desc_line += (" " + line)
|
||||
else:
|
||||
# Blank line marking the end of a bullet.
|
||||
if desc_line:
|
||||
desc_lines.append(desc_line)
|
||||
desc_line = ""
|
||||
if not pubdate:
|
||||
print("No pubdate at the end.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if desc_line:
|
||||
desc_lines.append(desc_line)
|
||||
desc_line = ""
|
||||
add_version()
|
||||
|
||||
|
||||
# Main enty point.
|
||||
def main():
|
||||
parse_args()
|
||||
add_header()
|
||||
add_versions()
|
||||
output_feed()
|
||||
|
||||
|
||||
# Write the feed to feed_xml.
|
||||
def output_feed():
|
||||
with open(feed_xml, "w") as feed_hand:
|
||||
print(doc.toprettyxml(indent=" "), file=feed_hand)
|
||||
|
||||
|
||||
# Parse the command line arguments and store the result in 'args'.
|
||||
def parse_args():
|
||||
global news_adoc
|
||||
global feed_xml
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage:", os.path.basename(sys.argv[0]), \
|
||||
"news-file feed-xml", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
news_adoc = sys.argv[1]
|
||||
feed_xml = sys.argv[2]
|
||||
|
||||
|
||||
# So that this script may be accessed as a module.
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue