Improve display of comments of discussion nodes;
Add a list of instances (Thank you roughnecks).
This commit is contained in:
parent
b26958acae
commit
028fdacc39
3 changed files with 154 additions and 6 deletions
|
@ -10,6 +10,10 @@ Rivista includes [XSLT ](https://www.w3.org/TR/xslt/) stylesheets that transform
|
|||
|
||||
Rivista was inspired from Tigase and was motivated by Movim.
|
||||
|
||||
## Instances
|
||||
|
||||
* https://rivista.woodpeckersnest.eu/
|
||||
|
||||
## Preview
|
||||
|
||||
[<img alt="berlin-xmpp-meetup" src="screenshot/berlin-xmpp-meetup.png" width="200px"/>](screenshot/berlin-xmpp-meetup.png)
|
||||
|
|
|
@ -108,7 +108,7 @@ async def view_node_items(request: Request):
|
|||
iq = await get_node_item(pubsub, node, item_id)
|
||||
if iq:
|
||||
link = form_an_item_link(pubsub, node, item_id)
|
||||
xml_atom = generate_atom(iq, link)
|
||||
xml_atom = generate_atom_comment(iq, link) if 'urn:xmpp:microblog:0:comments/' in node else generate_atom_post(iq, link)
|
||||
iq = await get_node_items(pubsub, node)
|
||||
if not '/' in node:
|
||||
if iq:
|
||||
|
@ -146,7 +146,7 @@ async def view_node_items(request: Request):
|
|||
iq = await get_node_items(pubsub, node)
|
||||
if iq:
|
||||
link = form_a_node_link(pubsub, node)
|
||||
xml_atom = generate_atom(iq, link)
|
||||
xml_atom = generate_atom_comment(iq, link) if 'urn:xmpp:microblog:0:comments/' in node else generate_atom_post(iq, link)
|
||||
else:
|
||||
text = 'Please ensure that PubSub node "{}" is valid and accessible.'.format(node)
|
||||
xml_atom = error_message(text)
|
||||
|
@ -177,7 +177,7 @@ async def view_node_items(request: Request):
|
|||
iq = await get_node_items(pubsub, node)
|
||||
if iq:
|
||||
link = form_a_node_link(pubsub, node)
|
||||
xml_atom = generate_atom(iq, link)
|
||||
xml_atom = generate_atom_post(iq, link)
|
||||
else:
|
||||
text = 'Please ensure that PubSub node "{}" is valid and accessible.'.format(node)
|
||||
xml_atom = error_message(text)
|
||||
|
@ -187,7 +187,7 @@ async def view_node_items(request: Request):
|
|||
iq = await get_node_items(pubsub, node)
|
||||
if iq:
|
||||
link = form_a_node_link(pubsub, node)
|
||||
xml_atom = generate_atom(iq, link)
|
||||
xml_atom = generate_atom_post(iq, link)
|
||||
else:
|
||||
text = 'Please ensure that PubSub node "{}" is valid and accessible.'.format(node)
|
||||
xml_atom = error_message(text)
|
||||
|
@ -263,7 +263,7 @@ def error_message(text):
|
|||
return ET.tostring(feed, encoding='unicode')
|
||||
|
||||
# generate_rfc_4287
|
||||
def generate_atom(iq, link):
|
||||
def generate_atom_post(iq, link):
|
||||
"""Generate an Atom Syndication Format (RFC 4287) from a Publish-Subscribe (XEP-0060) node items."""
|
||||
pubsub = iq['from'].bare
|
||||
node = iq['pubsub']['items']['node']
|
||||
|
@ -295,8 +295,8 @@ def generate_atom(iq, link):
|
|||
links = item_payload.find(namespace + 'link')
|
||||
if (not isinstance(title, ET.Element) and
|
||||
not isinstance(links, ET.Element)): continue
|
||||
title_text = None if title == None else title.text
|
||||
e_entry = ET.SubElement(e_feed, 'entry')
|
||||
title_text = None if title == None else title.text
|
||||
ET.SubElement(e_entry, 'title').text = title_text
|
||||
if isinstance(links, ET.Element):
|
||||
for link in item_payload.findall(namespace + 'link'):
|
||||
|
@ -372,6 +372,139 @@ def generate_atom(iq, link):
|
|||
# ET.SubElement(e_entry, 'summary', {'type': summary_type_text}).text = summary_text
|
||||
return ET.tostring(e_feed, encoding='unicode')
|
||||
|
||||
# generate_rfc_4287
|
||||
def generate_atom_comment(iq, link):
|
||||
"""Generate an Atom Syndication Format (RFC 4287) from a Publish-Subscribe (XEP-0060) node items."""
|
||||
pubsub = iq['from'].bare
|
||||
node = iq['pubsub']['items']['node']
|
||||
title = node
|
||||
link = link
|
||||
# link = form_a_node_link(pubsub, node)
|
||||
# subtitle = 'XMPP PubSub Syndication Feed'
|
||||
subtitle = pubsub
|
||||
description = ('This is a syndication feed generated with Rivista, an XMPP '
|
||||
'Journal Publisher, which conveys XEP-0060: Publish-'
|
||||
'Subscribe nodes to standard RFC 4287: The Atom Syndication '
|
||||
'Format.')
|
||||
language = iq['pubsub']['items']['lang']
|
||||
items = iq['pubsub']['items']
|
||||
e_feed = ET.Element("feed")
|
||||
e_feed.set('xmlns', 'http://www.w3.org/2005/Atom')
|
||||
ET.SubElement(e_feed, 'title', {'type': 'text'}).text = title
|
||||
ET.SubElement(e_feed, 'subtitle', {'type': 'text'}).text = subtitle
|
||||
ET.SubElement(e_feed, 'link', {'rel': 'self', 'href': link})
|
||||
ET.SubElement(e_feed, 'generator', {
|
||||
'uri': 'https://git.xmpp-it.net/sch/Rivista',
|
||||
'version': '0.1'}).text = 'Rivista XJP'
|
||||
ET.SubElement(e_feed, 'updated').text = datetime.datetime.now(datetime.UTC).isoformat()
|
||||
for item in list(items)[::-1]:
|
||||
item_id = item['id']
|
||||
item_payload = item['payload']
|
||||
namespace = '{http://www.w3.org/2005/Atom}'
|
||||
authors = item_payload.find(namespace + 'author')
|
||||
links = item_payload.find(namespace + 'link')
|
||||
if (not isinstance(authors, ET.Element) and
|
||||
not isinstance(links, ET.Element)): continue
|
||||
e_entry = ET.SubElement(e_feed, 'entry')
|
||||
author_text = None
|
||||
for author in item_payload.findall(namespace + 'author'):
|
||||
author_email = author.find(namespace + 'email')
|
||||
if author_email is not None:
|
||||
author_text = author_email.text
|
||||
if not author_text:
|
||||
author_uri = author.find(namespace + 'uri')
|
||||
if author_uri is not None:
|
||||
author_text = author_uri.text
|
||||
if not author_text:
|
||||
author_name = author.find(namespace + 'name')
|
||||
if author_name is not None and author_name.text:
|
||||
author_text = author_name.text
|
||||
if not author_text:
|
||||
for uri in item_payload.iter(namespace + 'author'):
|
||||
author_text = uri.text
|
||||
if author_text:
|
||||
ET.SubElement(e_entry, 'title').text = author_text
|
||||
break
|
||||
if isinstance(links, ET.Element):
|
||||
for link in item_payload.findall(namespace + 'link'):
|
||||
link_href = link.attrib['href'] if 'href' in link.attrib else ''
|
||||
link_type = link.attrib['type'] if 'type' in link.attrib else ''
|
||||
link_rel = link.attrib['rel'] if 'rel' in link.attrib else ''
|
||||
ET.SubElement(e_entry, 'link', {'href': link_href, 'rel': link_rel, 'type': link_type})
|
||||
else:
|
||||
ET.SubElement(e_entry, 'content', {'href': ''})
|
||||
link_xmpp = form_an_item_link(pubsub, node, item_id)
|
||||
ET.SubElement(e_entry, 'link', {'href': link_xmpp, 'rel': 'alternate', 'type': 'x-scheme-handler/xmpp'})
|
||||
contents = item_payload.find(namespace + 'content')
|
||||
if isinstance(contents, ET.Element):
|
||||
for content in item_payload.findall(namespace + 'content'):
|
||||
if not content.text: continue
|
||||
content_text = content.text
|
||||
content_type = content.attrib['type'] if 'type' in content.attrib else 'html'
|
||||
content_type_text = 'html' if 'html' in content_type else 'text'
|
||||
ET.SubElement(e_entry, 'content', {'type': content_type_text}).text = content_text
|
||||
else:
|
||||
summary = item_payload.find(namespace + 'summary')
|
||||
summary_text = summary.text if summary else None
|
||||
if summary_text:
|
||||
summary_type = summary.attrib['type'] if 'type' in summary.attrib else 'html'
|
||||
summary_type_text = 'html' if 'html' in summary_type else 'text'
|
||||
ET.SubElement(e_entry, 'content', {'type': summary_type_text}).text = summary_text
|
||||
else:
|
||||
title = item_payload.find(namespace + 'title')
|
||||
title_text = None if title == None else title.text
|
||||
if title_text:
|
||||
ET.SubElement(e_entry, 'content').text = title_text
|
||||
else:
|
||||
ET.SubElement(e_entry, 'content').text = 'No content.'
|
||||
published = item_payload.find(namespace + 'published')
|
||||
published_text = None if published == None else published.text
|
||||
ET.SubElement(e_entry, 'published').text = published_text
|
||||
updated = item_payload.find(namespace + 'updated')
|
||||
updated_text = None if updated == None else updated.text
|
||||
ET.SubElement(e_entry, 'updated').text = updated_text
|
||||
authors = item_payload.find(namespace + 'author')
|
||||
if isinstance(authors, ET.Element):
|
||||
contact_text = None
|
||||
for author in item_payload.findall(namespace + 'author'):
|
||||
author_email = author.find(namespace + 'email')
|
||||
if author_email is not None:
|
||||
contact_text = author_email.text
|
||||
if not contact_text:
|
||||
author_uri = author.find(namespace + 'uri')
|
||||
if author_uri is not None:
|
||||
contact_text = author_uri.text
|
||||
if not contact_text:
|
||||
for uri in item_payload.iter(namespace + 'author'):
|
||||
contact_text = uri.text
|
||||
if contact_text:
|
||||
if contact_text.startswith('xmpp:'):
|
||||
contact_type = 'x-scheme-handler/xmpp'
|
||||
elif contact_text.startswith('mailto:'):
|
||||
contact_type = 'x-scheme-handler/mailto'
|
||||
else:
|
||||
contact_type = None
|
||||
if contact_type:
|
||||
ET.SubElement(e_entry, 'link', {'href': contact_text, 'rel': 'contact', 'type': contact_type})
|
||||
else:
|
||||
ET.SubElement(e_entry, 'link', {'href': contact_text, 'rel': 'contact'})
|
||||
break
|
||||
categories = item_payload.find(namespace + 'category')
|
||||
if isinstance(categories, ET.Element):
|
||||
for category in item_payload.findall(namespace + 'category'):
|
||||
if 'term' in category.attrib and category.attrib['term']:
|
||||
category_term = category.attrib['term']
|
||||
ET.SubElement(e_entry, 'category', {'term': category_term})
|
||||
|
||||
|
||||
identifier = item_payload.find(namespace + 'id')
|
||||
if identifier and identifier.attrib: print(identifier.attrib)
|
||||
|
||||
identifier_text = None if identifier == None else identifier.text
|
||||
ET.SubElement(e_entry, 'id').text = identifier_text
|
||||
# ET.SubElement(e_entry, 'summary', {'type': summary_type_text}).text = summary_text
|
||||
return ET.tostring(e_feed, encoding='unicode')
|
||||
|
||||
def generate_json(iq):
|
||||
"""Create a JSON file from node items."""
|
||||
json_data = []
|
||||
|
|
|
@ -299,6 +299,17 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
|||
(XMPP)
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
<xsl:if test='atom:link[@rel="contact"]'>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:value-of select='atom:link[@rel="contact"]/@href'/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='class'>
|
||||
<xsl:text>contact-uri</xsl:text>
|
||||
</xsl:attribute>
|
||||
🪪️ Contact
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
<xsl:if test='atom:link[@rel="replies"]'>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
|
|
Loading…
Reference in a new issue