Rename project to XMPP Journal Publisher;

Retrieve dates of PubSub node items;
Improve CSS stylesheet;
Fix JS error.
This commit is contained in:
Schimon Jehudah, Adv. 2024-07-11 20:56:20 +03:00
parent 16bd475be2
commit e07ff6e838
5 changed files with 41 additions and 30 deletions

View file

@ -1,12 +1,14 @@
# XMPP PubSub To Atom # XMPP Journal Publisher
XMPP PubSub To Atom ("XPTA") is a simple Python script that parses XMPP Pubsub Nodes and sends them as Atom Syndication Format or OPML over HTTP. Previously, XMPP PubSub To Atom ("XPTA").
XPTA generates Atom syndication feeds ([RFC 4287](https://www.rfc-editor.org/rfc/rfc4287)) from XMPP PubSub nodes ([XEP-0060](http://xmpp.org/extensions/xep-0060.html)). XMPP Journal Publisher ("XJP") is a software that parses XMPP Pubsub Nodes and sends them as Atom Syndication Format or OPML over HTTP.
XPTA includes [XSLT ](https://www.w3.org/TR/xslt/) stylesheets that transforms PubSub nodes into static XHTML journal sites. XJP generates Atom syndication feeds ([RFC 4287](https://www.rfc-editor.org/rfc/rfc4287)) from XMPP PubSub nodes ([XEP-0060](http://xmpp.org/extensions/xep-0060.html)).
XPTA was inspired from Tigase and was motivated by Movim. XJP includes [XSLT ](https://www.w3.org/TR/xslt/) stylesheets that transforms PubSub nodes into static XHTML journal sites.
XJP was inspired from Tigase and was motivated by Movim.
## Preview ## Preview
@ -17,14 +19,14 @@ XPTA was inspired from Tigase and was motivated by Movim.
## Motivation ## Motivation
PubSub To Atom is a syndication project which makes journals and publications that are hosted on XMPP PubSub nodes, available XMPP Journal Publisher is a syndication project which makes journals and publications that are hosted on XMPP PubSub nodes, available
from HTTP to both, XML news readers and even HTML browsers. from HTTP to both, XML news readers and even HTML browsers.
This means that instead of hosting a journal or publication site in the old fashion (i.e. HTML documents hosted on an HTTP server), one only has to have an HTTP server to operate PubSub To Atom, and the rest of the content is delivered from an XMPP server (i.e. PubSub nodes). This means that instead of hosting a journal or publication site in the old fashion (i.e. HTML documents hosted on an HTTP server), one only has to have an HTTP server to operate XMPP Journal Publisher, and the rest of the content is delivered from an XMPP server (i.e. PubSub nodes).
The project also showcases the non-necessity of HTML, as it automatically generates valid XHTML pages by HTML browsers (client-side) from XSLT stylesheets. The project also showcases the non-necessity of HTML, as it automatically generates valid XHTML pages by HTML browsers (client-side) from XSLT stylesheets.
Because PubSub To Atom reads XMPP PubSub nodes, it is possible to view a complete set of node items, and even a single node item, which means, that a considered and carefully earnest use of PubSub To Atom would save bandwidth and system overhead, which includes CPU, I/O and RAM usage. Because XMPP Journal Publisher reads XMPP PubSub nodes, it is possible to view a complete set of node items, and even a single node item, which means, that a considered and carefully earnest use of XMPP Journal Publisher would save bandwidth and system overhead, which includes CPU, I/O and RAM usage.
## Requirements ## Requirements
@ -49,8 +51,8 @@ Because PubSub To Atom reads XMPP PubSub nodes, it is possible to view a complet
Extract the source package to a directory that you have permission to run software. Extract the source package to a directory that you have permission to run software.
```shell ```shell
$ git clone https://git.xmpp-it.net/sch/PubSubToAtom $ git clone https://git.xmpp-it.net/sch/XJP
$ cd PubSubToAtom/ $ cd XJP/
``` ```
### Configure ### Configure
@ -59,7 +61,7 @@ Add account credentials to file `configuration.toml`.
### Start ### Start
Execute PubSub To Atom with one of the following commands: Execute XMPP Journal Publisher with one of the following commands:
```shell ```shell
$ python -m uvicorn pubsub_to_atom:app --reload $ python -m uvicorn pubsub_to_atom:app --reload
@ -132,7 +134,7 @@ Thank you to to Mr. Timothée Jaussoin ([edhelas](https://edhelas.movim.eu/)) wh
A special thank you to the gentlemen "d3x" and "cchianel" from IRC channel #python on irc.libera.chat for initial references concerning code, servers and FastAPI. A special thank you to the gentlemen "d3x" and "cchianel" from IRC channel #python on irc.libera.chat for initial references concerning code, servers and FastAPI.
And an important thank you to Mr. Simone Canaletti ([roughnecks](https://blog.woodpeckersnest.space/)) for testing and deploying PubSub To Atom into production. And an important thank you to Mr. Simone Canaletti ([roughnecks](https://blog.woodpeckersnest.space/)) for testing and deploying XMPP Journal Publisher into production.
## Similar Projects ## Similar Projects

View file

@ -1,4 +1,4 @@
# An account to connect PubSubToAtom to the XMPP network. # An account to connect XMPP Journal Publisher to the XMPP network.
[account] [account]
xmpp = "" # Jabber ID. xmpp = "" # Jabber ID.
pass = "" # Password. pass = "" # Password.

View file

@ -42,6 +42,7 @@ h1#title, h2#subtitle, #actions, #references {
#note { #note {
line-height: 30px; line-height: 30px;
margin: auto; margin: auto;
margin-top: 0.67em;
max-width: 70%; max-width: 70%;
padding: 10px; padding: 10px;
text-align: center; text-align: center;
@ -59,7 +60,7 @@ h1#title, h2#subtitle, #actions, #references {
margin-left: 2%; margin-left: 2%;
margin-right: 2%; margin-right: 2%;
min-width: 350px; min-width: 350px;
padding-bottom: 50px; padding-bottom: 0.67em;
width: 20%; width: 20%;
} }
@ -83,7 +84,7 @@ h1#title, h2#subtitle, #actions, #references {
} }
#articles > ul > li > div.entry { #articles > ul > li > div.entry {
padding-bottom: 50px; padding-bottom: 0.67em;
} }
#articles > ul > li > div.entry h1 { #articles > ul > li > div.entry h1 {
@ -145,7 +146,6 @@ h1#title, h2#subtitle, #actions, #references {
#articles #journal { #articles #journal {
margin-left: unset; margin-left: unset;
margin-right: unset; margin-right: unset;
padding-bottom: 50px;
min-width: unset; min-width: unset;
width: unset; width: unset;
} }

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#import datetime import datetime
from fastapi import FastAPI, Request, Response from fastapi import FastAPI, Request, Response
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
@ -65,8 +65,14 @@ async def view_pubsub(request: Request):
generate_json(iq, node) generate_json(iq, node)
else: else:
operator = get_configuration('settings')['operator'] operator = get_configuration('settings')['operator']
json_data = [{'title' : 'Timeout Error: Press here to contact the operator.', json_data = [{'title' : 'Error retrieving items list.',
'link' : 'xmpp:{}?message'.format(operator)}] 'link' : ('javascript:alert("XJP: XMPP Journal Publisher has experienced an error '
'while attempting to retrieve the list of items for Node {} of PubSub {}.")')
.format(node, pubsub)},
{'title' : 'Contact the operator.',
'link' : ('xmpp:{}?message;subject=XJP: XMPP Journal Publisher;body=Greetings! '
'I am contacting you to inform you that there is an error listing '
'node items for Node {} on PubSub {}.').format(operator, node, pubsub)}]
filename = 'data/{}.json'.format(node) filename = 'data/{}.json'.format(node)
with open(filename, 'w', encoding='utf-8') as f: with open(filename, 'w', encoding='utf-8') as f:
json.dump(json_data, f, ensure_ascii=False, indent=4) json.dump(json_data, f, ensure_ascii=False, indent=4)
@ -172,12 +178,13 @@ def form_a_link(pubsub, node):
def error_message(text): def error_message(text):
"""Error message in RFC 4287: The Atom Syndication Format.""" """Error message in RFC 4287: The Atom Syndication Format."""
feed = feedgenerator.Atom1Feed( feed = feedgenerator.Atom1Feed(
description = ('This is a syndication feed generated with PubSub To ' description = ('This is a syndication feed generated with XMPP Journal '
'Atom, which conveys XEP-0060: Publish-Subscribe nodes ' 'Publisher (XJP), which conveys XEP-0060: Publish-'
'to standard RFC 4287: The Atom Syndication Format.'), 'Subscribe nodes to standard RFC 4287: The Atom '
'Syndication Format.'),
language = 'en', language = 'en',
link = '', link = '',
subtitle = 'XMPP PubSub To Atom', subtitle = 'XMPP Journal Publisher',
title = 'StreamBurner') title = 'StreamBurner')
namespace = '{http://www.w3.org/2005/Atom}' namespace = '{http://www.w3.org/2005/Atom}'
feed_url = 'gemini://schimon.i2p/' feed_url = 'gemini://schimon.i2p/'
@ -194,7 +201,7 @@ def error_message(text):
xml_atom_extended = append_element( xml_atom_extended = append_element(
xml_atom, xml_atom,
'generator', 'generator',
'XPTA: XMPP PubSub To Atom') 'XMPP Journal Publisher (XJP)')
return xml_atom_extended return xml_atom_extended
def generate_rfc_4287(iq, link): def generate_rfc_4287(iq, link):
@ -216,7 +223,9 @@ def generate_rfc_4287(iq, link):
title = None if title == None else title.text title = None if title == None else title.text
updated = item.find(namespace + 'updated') updated = item.find(namespace + 'updated')
updated = None if updated == None else updated.text updated = None if updated == None else updated.text
# if updated: updated = datetime.datetime.fromisoformat(updated) published = item.find(namespace + 'published')
published = None if published == None else published.text
if not updated and not published: updated = datetime.datetime.utcnow().isoformat()
content = item.find(namespace + 'content') content = item.find(namespace + 'content')
content = 'No content' if content == None else content.text content = 'No content' if content == None else content.text
link = item.find(namespace + 'link') link = item.find(namespace + 'link')
@ -229,14 +238,14 @@ def generate_rfc_4287(iq, link):
description = content, description = content,
# enclosure = feedgenerator.Enclosure(enclosure, enclosure_size, enclosure_type) if args.entry_enclosure else None, # enclosure = feedgenerator.Enclosure(enclosure, enclosure_size, enclosure_type) if args.entry_enclosure else None,
link = link, link = link,
# pubdate = updated, pubdate = published or updated,
title = title, title = title,
unique_id = link) unique_id = link)
xml_atom = feed.writeString('utf-8') xml_atom = feed.writeString('utf-8')
xml_atom_extended = append_element( xml_atom_extended = append_element(
xml_atom, xml_atom,
'generator', 'generator',
'XPTA: XMPP PubSub To Atom') 'XMPP Journal Publisher (XJP)')
return xml_atom_extended return xml_atom_extended
def generate_json(iq, node): def generate_json(iq, node):

View file

@ -51,11 +51,11 @@ window.onload = async function(){
let elementUl2 = document.createElement('ul'); let elementUl2 = document.createElement('ul');
elementDiv.appendChild(elementUl2); elementDiv.appendChild(elementUl2);
links = [ links = [
{'text' : 'Subscribe from an XMPP client...', {'text' : 'Subscribe from an XMPP client.',
'href' : `xmpp:${pubsub}?pubsub;action=subscribe;node=${node}`}, 'href' : `xmpp:${pubsub}?pubsub;action=subscribe;node=${node}`},
{'text' : 'Subscribe with a News Reader...', {'text' : 'Subscribe with a News Reader.',
'href' : `feed://${location.host}/atom?pubsub=${pubsub}&node=${node}`}, 'href' : `feed://${location.host}/atom?pubsub=${pubsub}&node=${node}`},
{'text' : 'Browse the journal...', {'text' : 'Browse the journal.',
'href' : `atom?pubsub=${pubsub}&node=${node}`} 'href' : `atom?pubsub=${pubsub}&node=${node}`}
] ]
for (let link of links) { for (let link of links) {