diff --git a/css/stylesheet.css b/css/stylesheet.css
index 9b99627..dbc74f1 100644
--- a/css/stylesheet.css
+++ b/css/stylesheet.css
@@ -409,7 +409,7 @@ h3, h4, h5 {
text-shadow: 1px 1px #000;
}
-#message {
+#xmpp-message {
background: #000;
font-weight: bold;
opacity: 10%;
@@ -421,11 +421,11 @@ h3, h4, h5 {
right: 0;
}
-#message {
+#xmpp-message {
color: #fff;
}
-#message:hover {
+#xmpp-message:hover {
opacity: unset;
}
@@ -538,7 +538,7 @@ h3, h4, h5 {
width: unset;
}
- #message {
+ #xmpp-message {
display: none;
}
@@ -551,6 +551,10 @@ h3, h4, h5 {
margin-bottom: 2.5em;
}
+ #notice {
+ padding-bottom: 1.5em;
+ }
+
#profile #qrcode {
margin-bottom: 1em;
outline: solid;
diff --git a/details/README b/details/README
new file mode 100644
index 0000000..8d3aed9
--- /dev/null
+++ b/details/README
@@ -0,0 +1 @@
+This directory caches textual data of Jabber IDs.
diff --git a/fasi.py b/fasi.py
index 1bb6c71..ac670ea 100644
--- a/fasi.py
+++ b/fasi.py
@@ -8,6 +8,7 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
+import glob
#import logging
#from os import mkdir
#from os.path import getsize, exists
@@ -80,7 +81,7 @@ class HttpInstance:
@self.app.get('/v/{jid}')
async def view_jid(request: Request, jid):
- """View messages of jabber id"""
+ """View recent messages of a conference"""
jid_path = urlsplit(jid).path
if parseaddr(jid_path)[1] == jid_path:
jid_bare = jid_path.lower()
@@ -88,205 +89,70 @@ class HttpInstance:
jid_bare = jid
note = 'Jabber ID appears to be malformed'
- try:
- exception = node_title = note = number_of_pages = page_number = previous = selection = services_sorted = None
+ #try:
+ if True:
+ exception = jid_detail = messages_10 = note = node_title = \
+ node_note = number_of_pages = page_number = previous = \
+ selection = services_sorted = subject = None
node_name = 'urn:xmpp:microblog:0'
link_href = 'xmpp:{}?join'.format(jid_bare)
link_text = 'Join'
xmpp_uri = '{}'.format(jid_bare)
- # Start an XMPP instance and retrieve information
- xmpp_instance = XmppInstance(jabber_id, password, jid_bare)
- xmpp_instance.connect()
-
- # JID kind
- instance = message = node_id = None
- jid_info = await XmppXep0030.get_jid_info(xmpp_instance, jid_bare)
- jid_info_iq = jid_info['iq']
- jid_kind = jid_info['kind']
- links = []
- if jid_info['error']:
- message = '{}: {} (XEP-0030)'.format(jid_info['text'], jid_info['condition'])
- action = 'Connect with'
- link_href = 'xmpp:{}'.format(jid_bare)
- links.append({'name' : 'Connect',
- 'href' : link_href,
- 'iden' : 'connect'})
- xmpp_uri = jid_bare
- elif jid_kind in ('conference', 'server'):
- action = 'Discover'
- if jid_kind == 'conference':
- instance = 'conferences'
- elif jid_kind == 'server':
- instance = 'services'
- link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
- links.append({'name' : 'Discover',
- 'href' : link_href,
- 'iden' : 'discover'})
- view_href = '/d/' + jid_bare
- xmpp_uri = jid_bare
- elif jid_kind in ('mix', 'muc'):
- #title = 'Group Chat ' + title
- # TODO Set group chat subject as description.
- action = 'Join'
- instance = 'participants'
- link_href = 'xmpp:{}?join'.format(jid_bare)
- links.append({'name' : 'Join',
- 'href' : link_href,
- 'iden' : 'join'})
- view_href = '/v/' + jid_bare
- xmpp_uri = jid_bare
- # room_info = await XmppXep0045.get_room_data(xmpp_instance, jid_bare)
- # breakpoint()
- elif jid_kind == 'pubsub':
- #node_name = request.query_params.get('node', '')
- if node_name:
- action = 'Subscribe'
- instance = 'articles'
- link_href = 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name)
- view_href = '/d/{}/{}'.format(jid_bare, node_name)
- xmpp_uri = '{}?;node={}'.format(jid_bare, node_name)
+ filename = 'details/{}.toml'.format(jid_bare)
+ if os.path.exists(filename) and os.path.getsize(filename) > 0:
+ jid_details = Data.open_file_toml(filename)
+ action = jid_details['action']
+ count = jid_details['count']
+ instance = jid_details['instance']
+ jid_info = {
+ 'error' : jid_details['error'],
+ 'text' : jid_details['error_text'],
+ 'condition' : jid_details['error_condition']}
+ jid_kind = jid_details['kind']
+ link_href = jid_details['link_href']
+ messages = jid_details['messages']
+ nodes = jid_details['nodes']
+ note = jid_details['note']
+ title = jid_details['name']
+ xmpp_uri = jid_details['uri']
+ view_href = jid_details['view_href']
+ else:
+ jid_data = await FileUtilities.cache_jid_data(jabber_id, password, jid_bare, node_name, alias=alias)
+ count = jid_data['count']
+ jid_detail = jid_data['jid_detail']
+ jid_info = jid_data['jid_info']
+ jid_kind = jid_data['jid_kind']
+ jid_details = jid_data['jid_details']
+ note = jid_data['note']
+ title = jid_data['title']
+
+ # Group chat messages
+ # NOTE TODO
+ page_number = request.query_params.get('page', '')
+ if page_number:
+ try:
+ page_number = int(page_number)
+ ix = (page_number -1) * 10
+ except:
+ ix = 0
+ page_number = 1
else:
- action = 'Browse'
- instance = 'nodes'
- link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
- links.append({'name' : 'Browse',
- 'href' : link_href,
- 'iden' : 'browse'})
- view_href = '/d/' + jid_bare
- xmpp_uri = jid_bare
- else:
- action = 'Message'
- instance = 'articles'
- link_href = 'xmpp:{}?message'.format(jid_bare)
- links.append({'name' : 'Add',
- 'href' : 'xmpp:{}?roster'.format(jid_bare),
- 'id' : 'add'})
- links.append({'name' : 'Message',
- 'href' : link_href,
- 'iden' : 'message'})
- node_name = 'urn:xmpp:microblog:0'
- view_href = '/d/{}/{}'.format(jid_bare, node_name)
- xmpp_uri = jid_bare
- links.append({'name' : 'Subscribe',
- 'href' : 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name),
- 'iden' : 'subscribe'})
- links.append({'name' : 'View',
- 'href' : 'xmpp:{}?pubsub;node={}'.format(jid_bare, node_name),
- 'iden' : 'view'})
- links.append({'name' : 'vCard',
- 'href' : 'xmpp:{}?vcard'.format(jid_bare),
- 'iden' : 'vcard'})
-
- # JID info
- # NOTE Group chat of Psi+ Project at jabber.ru has a note in its vCard.
- # TODO Retrieve group chat title (try also with xep_0045
- vcard_data = await XmppXep0054.get_vcard_data(xmpp_instance, jid_bare)
- if vcard_data['error']:
- jid_detail = {}
- #jid_detail['note'] = '{}: {}'.format(vcard_data['text'], vcard_data['condition'])
- jid_detail['name'] = jid_detail['note'] = jid_detail['note'] = jid_detail['type'] = jid_detail['bin'] = None
- else:
- conference_title = None
- if jid_kind in ('mix', 'muc'):
- for identity in jid_info_iq['disco_info']['identities']:
- if identity[3]:
- conference_title = identity[3]
- break
- vcard_temp = vcard_data['iq']['vcard_temp']
- jid_detail = {
- 'name' : vcard_temp['FN'] or conference_title,
- 'note' : vcard_temp['notes'] or node_id,
- 'type' : vcard_temp['PHOTO']['TYPE'],
- 'bin' : vcard_temp['PHOTO']['BINVAL']
- }
-
- # Group chat messages
- action = 'Join'
- messages = []
- # TODO Create configurations for group chat preview
- room_info_muc = await XmppXep0045.get_room_information(xmpp_instance, jid_bare, alias, maxstanzas=50)
- messages = room_info_muc['iq'][3]
- messages.reverse()
- subject = room_info_muc['iq'][1]['subject']
- page_number = request.query_params.get('page', '')
- if page_number:
- try:
- page_number = int(page_number)
- ix = (page_number -1) * 10
- except:
ix = 0
page_number = 1
- else:
- ix = 0
- page_number = 1
- messages_10 = messages[ix:][:10]
- number_of_pages = int(len(messages) / 10)
- if number_of_pages < len(messages) / 10: number_of_pages += 1
- if not room_info_muc:
- action = 'Warning'
- node_title = jid_info['condition']
- node_note = jid_info['text']
- services = services_sorted = None
- elif isinstance(room_info_muc, IqTimeout):
- action = 'Warning'
- node_title = 'Timeout'
- node_note = 'Timeout error'
- services = services_sorted = None
- elif isinstance(room_info_muc, IqError):
- action = 'Warning'
- breakpoint()
- node_title = room_info_muc['condition']
- node_note = room_info_muc['text']
- services = services_sorted = None
- else:
- #title = title or node_name
- if not node_title: node_title = node_name
- node_note = jid_bare
+ messages_10 = messages[ix:][:10]
+ number_of_pages = int(len(messages) / 10)
+ if number_of_pages < len(messages) / 10: number_of_pages += 1
- xmpp_instance.disconnect()
+ # Query URI links
+ action, instance, link_href, links, node_name, view_href, xmpp_uri = XmppUtilities.set_query_uri_link(
+ jid_bare, jid_info, jid_kind, node_name)
- # Notes
- jid_detail_note = jid_detail['note']
- if isinstance(jid_detail_note, list) and len(jid_detail_note):
- note = jid_detail_note[0]['NOTE']
- else:
- note = jid_detail_note
- #if not note and jid_detail['name'] and not 'undefined' in jid_detail['name'] and title != jid_detail['name']:
- # note = jid_detail['name']
+ # Graphic files
+ filename, filepath, filetype, selection = FileUtilities.handle_photo(jid_bare, jid_detail)
- # File type
- mimetype = filename = filepath = None
- if jid_detail['type']:
- mimetype = jid_detail['type']
- if mimetype:
- filetype = mimetype.split('/')[1]
- if filetype == 'svg+xml': filetype = 'svg'
- filename = '{}.{}'.format(jid_bare, filetype)
- filepath = 'photo/{}.{}'.format(jid_bare, filetype)
- #img.save(filename)
-
- # Write the decoded bytes to a file
- with open(filepath, 'wb') as file:
- file.write(jid_detail['bin'])
-
- #from PIL import Image
- #img = Image.open(filepath)
- #rgb_im = im.convert("RGB")
- #rgb_im.save('{}_mod.jpg'.format(jid_bare))
-
- # Default photo. Utilized, if there is no image file.
- if not filepath or not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
- filename = 'default.svg'
- elif filetype == 'svg':
- selection = Graphics.extract_colours_from_vector(filepath)
- else:
- selection = Graphics.extract_colours_from_raster(filepath)
-
- # QR code
- Graphics.generate_qr_code_graphics_from_string(link_href, jid_bare)
-
- except Exception as e:
+ #except Exception as e:
+ else:
exception = str(e)
action = 'Error'
title = 'Slixmpp error'
@@ -302,8 +168,8 @@ class HttpInstance:
'exception' : exception,
'filename' : filename,
'jid_bare' : jid,
- 'jid_note' : jid_detail['note'],
- 'jid_title' : jid_detail['name'],
+ 'jid_note' : note,
+ 'jid_title' : title,
'links' : links,
'messages' : messages_10,
'node_title' : node_title,
@@ -314,7 +180,7 @@ class HttpInstance:
'previous' : previous,
'request' : request,
'subject' : subject,
- 'title' : jid_detail['name'],
+ 'title' : title,
'url' : request.url._url,
'xmpp_uri' : xmpp_uri}
response = templates.TemplateResponse(template_file, template_dict)
@@ -333,245 +199,121 @@ class HttpInstance:
jid_bare = jid
note = 'Jabber ID appears to be malformed'
- try:
- exception = note = number_of_pages = page_number = previous = selection = services_sorted = None
+ #try:
+ if True:
+ entries = exception = jid_detail = note = node_note = \
+ number_of_pages = page_number = previous = selection = \
+ services_sorted = None
node_title = node_name
link_href = 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name)
link_text = 'Subscribe'
xmpp_uri = '{}?;node={}'.format(jid_bare, node_name)
- # Start an XMPP instance and retrieve information
- xmpp_instance = XmppInstance(jabber_id, password, jid_bare)
- xmpp_instance.connect()
-
- # JID kind
- instance = message = node_id = None
- jid_info = await XmppXep0030.get_jid_info(xmpp_instance, jid_bare)
- jid_info_iq = jid_info['iq']
- jid_kind = jid_info['kind']
- links = []
- if jid_info['error']:
- message = '{}: {} (XEP-0030)'.format(jid_info['text'], jid_info['condition'])
- action = 'Connect with'
- link_href = 'xmpp:{}'.format(jid_bare)
- links.append({'name' : 'Connect',
- 'href' : link_href,
- 'iden' : 'connect'})
- xmpp_uri = jid_bare
- elif jid_kind in ('conference', 'server'):
- action = 'Discover'
- if jid_kind == 'conference':
- instance = 'conferences'
- elif jid_kind == 'server':
- instance = 'services'
- link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
- links.append({'name' : 'Discover',
- 'href' : link_href,
- 'iden' : 'discover'})
- view_href = '/d/' + jid_bare
- xmpp_uri = jid_bare
- elif jid_kind in ('mix', 'muc'):
- #title = 'Group Chat ' + title
- # TODO Set group chat subject as description.
- action = 'Join'
- instance = 'participants'
- link_href = 'xmpp:{}?join'.format(jid_bare)
- links.append({'name' : 'Join',
- 'href' : link_href,
- 'iden' : 'join'})
- view_href = '/v/' + jid_bare
- xmpp_uri = jid_bare
- # room_info = await XmppXep0045.get_room_data(xmpp_instance, jid_bare)
- # breakpoint()
- elif jid_kind == 'pubsub':
- #node_name = request.query_params.get('node', '')
- if node_name:
- action = 'Subscribe'
- instance = 'articles'
- link_href = 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name)
- view_href = '/d/{}/{}'.format(jid_bare, node_name)
- xmpp_uri = '{}?;node={}'.format(jid_bare, node_name)
- else:
- action = 'Browse'
- instance = 'nodes'
- link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
- links.append({'name' : 'Browse',
- 'href' : link_href,
- 'iden' : 'browse'})
- view_href = '/d/' + jid_bare
- xmpp_uri = jid_bare
+ filename = 'details/{}.toml'.format(jid_bare)
+ if os.path.exists(filename) and os.path.getsize(filename) > 0:
+ jid_details = Data.open_file_toml(filename)
+ action = jid_details['action']
+ count = jid_details['count']
+ instance = jid_details['instance']
+ jid_info = {
+ 'error' : jid_details['error'],
+ 'text' : jid_details['error_text'],
+ 'condition' : jid_details['error_condition']}
+ jid_kind = jid_details['kind']
+ link_href = jid_details['link_href']
+ messages = jid_details['messages']
+ nodes = jid_details['nodes']
+ note = jid_details['note']
+ title = jid_details['name']
+ xmpp_uri = jid_details['uri']
+ view_href = jid_details['view_href']
+ if node_name not in nodes:
+ node_item_ids = await XmppXep0060.get_node_item_ids(xmpp_instance, jid_bare, node_name)
+ if isinstance(node_item_ids, stanza.iq.Iq):
+ nodes[node_name] = node_item_ids['disco_items']['items']
else:
- action = 'Message'
- instance = 'articles'
- link_href = 'xmpp:{}?message'.format(jid_bare)
- links.append({'name' : 'Add',
- 'href' : 'xmpp:{}?roster'.format(jid_bare),
- 'iden' : 'add'})
- links.append({'name' : 'Add',
- 'href' : link_href,
- 'iden' : 'message'})
- node_name = 'urn:xmpp:microblog:0'
- view_href = '/d/{}/{}'.format(jid_bare, node_name)
- xmpp_uri = jid_bare
- if item_id:
- links.append({'name' : 'Subscribe',
- 'href' : 'xmpp:{}?pubsub;node={};item={};action=subscribe'.format(jid_bare, node_name, item_id),
- 'iden' : 'subscribe'})
- links.append({'name' : 'View',
- 'href' : 'xmpp:{}?pubsub;node={};item={}'.format(jid_bare, node_name, item_id),
- 'iden' : 'view'})
- else:
- links.append({'name' : 'Subscribe',
- 'href' : 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name),
- 'iden' : 'subscribe'})
- links.append({'name' : 'View',
- 'href' : 'xmpp:{}?pubsub;node={}'.format(jid_bare, node_name),
- 'iden' : 'view'})
- links.append({'name' : 'vCard',
- 'href' : 'xmpp:{}?vcard'.format(jid_bare),
- 'iden' : 'vcard'})
+ jid_data = await FileUtilities.cache_jid_data(jabber_id, password, jid_bare, node_name, item_id)
+ count = jid_data['count']
+ jid_detail = jid_data['jid_detail']
+ jid_info = jid_data['jid_info']
+ jid_kind = jid_data['jid_kind']
+ jid_details = jid_data['jid_details']
+ note = jid_data['note']
+ title = jid_data['title']
- # JID info
- # NOTE Group chat of Psi+ Project at jabber.ru has a note in its vCard.
- vcard_data = await XmppXep0054.get_vcard_data(xmpp_instance, jid_bare)
- if vcard_data['error']:
- jid_detail = {}
- #jid_detail['note'] = '{}: {}'.format(vcard_data['text'], vcard_data['condition'])
- jid_detail['name'] = jid_detail['note'] = jid_detail['note'] = jid_detail['type'] = jid_detail['bin'] = None
- else:
- conference_title = None
- if jid_kind in ('mix', 'muc'):
- for identity in jid_info_iq['disco_info']['identities']:
- if identity[3]:
- conference_title = identity[3]
- break
- vcard_temp = vcard_data['iq']['vcard_temp']
- jid_detail = {
- 'name' : vcard_temp['FN'] or conference_title,
- 'note' : vcard_temp['notes'] or node_id,
- 'type' : vcard_temp['PHOTO']['TYPE'],
- 'bin' : vcard_temp['PHOTO']['BINVAL']
- }
+ # Node items
+ # NOTE TODO
+ # page_number = request.query_params.get('page', '')
+ # if page_number:
+ # try:
+ # page_number = int(page_number)
+ # ix = (page_number -1) * 10
+ # except:
+ # ix = 0
+ # page_number = 1
+ # else:
+ # ix = 0
+ # page_number = 1
+ # item_ids_10 = item_ids[ix:][:10]
- # Title
- # TODO /d/pubsub.nicoco.fr/blog/urn-uuid-53e43061-1962-3112-bb8a-1473dca61719
- if '@' in jid_bare and node_name == 'urn:xmpp:microblog:0':
- node_title = 'Journal'
- else:
- jid_items = await XmppXep0030.get_jid_items(xmpp_instance, jid_bare)
- iq = jid_items['iq']
- iq_disco_items = iq['disco_items']
- iq_disco_items_items = iq_disco_items['items']
- category = 'unsorted'
- for item in iq_disco_items_items:
- if item[2] and item[1] == node_name:
- node_title = item[2]
- break
+ # if item_id:
+ # previous = True
+ # node_items = await XmppXep0060.get_node_items(xmpp_instance, jid_bare, node_name, item_ids=[item_id])
+ # else:
+ # node_items = await XmppXep0060.get_node_items(xmpp_instance, jid_bare, node_name, item_ids=item_ids_10)
+ # number_of_pages = int(len(item_ids) / 10)
+ # if number_of_pages < len(item_ids) / 10: number_of_pages += 1
- # Node items
- action = 'Browse'
- entries = []
- if item_id:
- previous = True
- node_items = await XmppXep0060.get_node_items(xmpp_instance, jid_bare, node_name, item_ids=[item_id])
- else:
- item_ids = []
- node_item_ids = await XmppXep0060.get_node_item_ids(xmpp_instance, jid_bare, node_name)
- for item_id in node_item_ids['disco_items']['items']:
- item_ids.append(item_id[2])
- # NOTE Consider to skip the reversal of order, because, then, items can be found at the same page.
- item_ids.reverse()
- page_number = request.query_params.get('page', '')
- if page_number:
- try:
- page_number = int(page_number)
- ix = (page_number -1) * 10
- except:
- ix = 0
- page_number = 1
- else:
- ix = 0
- page_number = 1
- item_ids_10 = item_ids[ix:][:10]
- node_items = await XmppXep0060.get_node_items(xmpp_instance, jid_bare, node_name, item_ids=item_ids_10)
- number_of_pages = int(len(item_ids) / 10)
- if number_of_pages < len(item_ids) / 10: number_of_pages += 1
- if not node_items:
- action = 'Warning'
- node_title = jid_info['condition']
- node_note = jid_info['text']
- services = services_sorted = None
- elif isinstance(node_items, IqTimeout):
- action = 'Warning'
- node_title = 'Timeout'
- node_note = 'Timeout error'
- services = services_sorted = None
- elif isinstance(node_items, IqError):
- action = 'Warning'
- breakpoint()
- node_title = node_items['condition']
- node_note = node_items['text']
- services = services_sorted = None
- else:
- #title = title or node_name
- if not node_title: node_title = node_name
- node_note = jid_bare
- for item in node_items['pubsub']['items']:
- item_payload = item['payload']
- entry = Syndication.extract_items(item_payload)
- if entry: entry['id'] = item['id']
- entries.append(entry)
- #if len(entries) > 10: break
- if entries: entries.reverse()
+ # if not node_items:
+ # action = 'Warning'
+ # node_title = jid_info['condition']
+ # node_note = jid_info['text']
+ # services = services_sorted = None
+ # elif isinstance(node_items, IqTimeout):
+ # action = 'Warning'
+ # node_title = 'Timeout'
+ # node_note = 'Timeout error'
+ # services = services_sorted = None
+ # elif isinstance(node_items, IqError):
+ # action = 'Warning'
+ # breakpoint()
+ # node_title = node_items['condition']
+ # node_note = node_items['text']
+ # services = services_sorted = None
+ # else:
+ # if 'items' in node_item_ids['disco_items']:
+ # for item_id in node_item_ids['disco_items']['items']:
+ # item_ids.append(item_id[2])
+ # # NOTE Consider to skip the reversal of order, because, then, items can be found at the same page.
+ # item_ids.reverse()
+ # nodes[node_name] = item_ids
+ #title = title or node_name
+ # if not node_title: node_title = node_name
+ # node_note = jid_bare
+ # for item in node_items['pubsub']['items']:
+ # item_payload = item['payload']
+ # entry = Syndication.extract_items(item_payload)
+ # if entry: entry['id'] = item['id']
+ # entries.append(entry)
+ # #if len(entries) > 10: break
+ # if entries: entries.reverse()
- xmpp_instance.disconnect()
+ # Query URI links
+ action, instance, link_href, links, node_name, view_href, xmpp_uri = XmppUtilities.set_query_uri_link(
+ jid_bare, jid_info, jid_kind, node_name, item_id)
- # Notes
- jid_detail_note = jid_detail['note']
- if isinstance(jid_detail_note, list) and len(jid_detail_note):
- note = jid_detail_note[0]['NOTE']
- else:
- note = jid_detail_note
- #if not note and jid_detail['name'] and not 'undefined' in jid_detail['name'] and title != jid_detail['name']:
- # note = jid_detail['name']
+ # Graphic files
+ filename, filepath, filetype, selection = FileUtilities.handle_photo(jid_bare, jid_detail)
- # File type
- mimetype = filename = filepath = None
- if jid_detail['type']:
- mimetype = jid_detail['type']
- if mimetype:
- filetype = mimetype.split('/')[1]
- if filetype == 'svg+xml': filetype = 'svg'
- filename = '{}.{}'.format(jid_bare, filetype)
- filepath = 'photo/{}.{}'.format(jid_bare, filetype)
- #img.save(filename)
-
- # Write the decoded bytes to a file
- with open(filepath, 'wb') as file:
- file.write(jid_detail['bin'])
-
- #from PIL import Image
- #img = Image.open(filepath)
- #rgb_im = im.convert("RGB")
- #rgb_im.save('{}_mod.jpg'.format(jid_bare))
-
- # Default photo. Utilized, if there is no image file.
- if not filepath or not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
- filename = 'default.svg'
- elif filetype == 'svg':
- selection = Graphics.extract_colours_from_vector(filepath)
- else:
- selection = Graphics.extract_colours_from_raster(filepath)
-
- # QR code
- Graphics.generate_qr_code_graphics_from_string(link_href, jid_bare)
-
- except Exception as e:
+ #except Exception as e:
+ else:
exception = str(e)
action = 'Error'
title = 'Slixmpp error'
xmpp_uri = note = jid
- filename = jid_bare = link_href = link_tex = node_note = node_title = number_of_pages = page_number = previous = selection = services = services_sorted = url = None
+ filename = jid_bare = link_href = link_tex = node_note = \
+ node_title = number_of_pages = page_number = previous = \
+ selection = services = services_sorted = url = None
#if title == 'remote-server-timeout':
# raise HTTPException(status_code=408, detail='remote-server-timeout')
@@ -583,8 +325,8 @@ class HttpInstance:
'exception' : exception,
'filename' : filename,
'jid_bare' : jid,
- 'jid_note' : jid_detail['note'],
- 'jid_title' : jid_detail['name'],
+ 'jid_note' : note,
+ 'jid_title' : title,
'links' : links,
'node_title' : node_title,
'node_note' : node_note,
@@ -611,7 +353,8 @@ class HttpInstance:
jid_bare = jid
note = 'Jabber ID appears to be malformed'
- try:
+ #try:
+ if True:
exception = note = selection = services_sorted = None
title = 'Services'
link_href = xmpp_uri = jid_bare
@@ -681,7 +424,8 @@ class HttpInstance:
xmpp_instance.disconnect()
- except Exception as e:
+ #except Exception as e:
+ else:
exception = str(e)
action = 'Error'
title = 'Slixmpp error'
@@ -709,21 +453,16 @@ class HttpInstance:
response.headers['Content-Type'] = 'application/xhtml+xml'
return response
- @self.app.get('/v/{jid}')
- async def view_jid_get(request: Request, jid):
- """View recent messages of a conference"""
- pass #TODO
-
- @self.app.get('/{jid}/{node_name}')
+ @self.app.get('/j/{jid}/{node_name}')
async def jid_node_get(request: Request, jid, node_name):
response = await main_jid_node_get(request, jid, node_name)
return response
- @self.app.get('/{jid}')
+ @self.app.get('/j/{jid}')
async def jid_get(request: Request, jid):
node_name = request.query_params.get('node', '')
if node_name:
- response = RedirectResponse(url='/{}/{}'.format(jid, node_name))
+ response = RedirectResponse(url='/j/{}/{}'.format(jid, node_name))
else:
response = await main_jid_node_get(request, jid)
return response
@@ -738,180 +477,57 @@ class HttpInstance:
jid_bare = jid
note = 'Jabber ID appears to be malformed'
- try:
- exception = note = selection = title = view_href = None
+ #try:
+ if True:
+ action = count = exception = instance = jid_detail = \
+ jid_info = link_href = message = note = selection = title = \
+ view_href = xmpp_uri = None
+ #node_name = 'urn:xmpp:microblog:0'
- # Start an XMPP instance and retrieve information
- xmpp_instance = XmppInstance(jabber_id, password, jid_bare)
- xmpp_instance.connect()
-
- # JID kind
- instance = message = node_id = None
- jid_info = await XmppXep0030.get_jid_info(xmpp_instance, jid_bare)
- jid_info_iq = jid_info['iq']
- jid_kind = jid_info['kind']
- links = []
- if jid_info['error']:
- message = '{}: {} (XEP-0030)'.format(jid_info['text'], jid_info['condition'])
- action = 'Connect with'
- link_href = 'xmpp:{}'.format(jid_bare)
- links.append(['Connect', link_href])
- xmpp_uri = jid_bare
- elif jid_kind in ('conference', 'server'):
- action = 'Discover'
- if jid_kind == 'conference':
- instance = 'conferences'
- elif jid_kind == 'server':
- instance = 'services'
- link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
- links.append(['Discover', link_href])
- view_href = '/d/' + jid_bare
- xmpp_uri = jid_bare
- elif jid_kind in ('mix', 'muc'):
- #title = 'Group Chat ' + title
- # TODO Set group chat subject as description.
- action = 'Join'
- instance = 'participants'
- link_href = 'xmpp:{}?join'.format(jid_bare)
- links.append(['Join', link_href])
- view_href = '/v/' + jid_bare
- xmpp_uri = jid_bare
- # room_info = await XmppXep0045.get_room_data(xmpp_instance, jid_bare)
- # breakpoint()
- elif jid_kind == 'pubsub':
- #node_name = request.query_params.get('node', '')
- if node_name:
- action = 'Subscribe'
- instance = 'articles'
- link_href = 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name)
- links.append(['Subscribe', link_href])
- links.append(['View', 'xmpp:{}?pubsub;node={}'.format(jid_bare, node_name)])
- view_href = '/d/{}/{}'.format(jid_bare, node_name)
- xmpp_uri = '{}?;node={}'.format(jid_bare, node_name)
- else:
- action = 'Browse'
- instance = 'nodes'
- link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
- links.append(['Browse', link_href])
- view_href = '/d/' + jid_bare
- xmpp_uri = jid_bare
+ filename = 'details/{}.toml'.format(jid_bare)
+ if os.path.exists(filename) and os.path.getsize(filename) > 0:
+ jid_details = Data.open_file_toml(filename)
+ action = jid_details['action']
+ count = jid_details['count']
+ instance = jid_details['instance']
+ jid_info = {
+ 'error' : jid_details['error'],
+ 'text' : jid_details['error_text'],
+ 'condition' : jid_details['error_condition']}
+ jid_kind = jid_details['kind']
+ link_href = jid_details['link_href']
+ messages = jid_details['messages']
+ nodes = jid_details['nodes']
+ note = jid_details['note']
+ title = jid_details['name']
+ xmpp_uri = jid_details['uri']
+ view_href = jid_details['view_href']
else:
- action = 'Message'
- instance = 'articles'
- link_href = 'xmpp:{}?message'.format(jid_bare)
- links.append(['Add', 'xmpp:{}?roster'.format(jid_bare)])
- links.append(['Message', link_href])
- node_name = 'urn:xmpp:microblog:0'
- view_href = '/d/{}/{}'.format(jid_bare, node_name)
- xmpp_uri = jid_bare
- links.append(['vCard', 'xmpp:{}?vcard'.format(jid_bare)])
+ jid_data = await FileUtilities.cache_jid_data(jabber_id, password, jid_bare, node_name, alias=alias)
+ count = jid_data['count']
+ jid_detail = jid_data['jid_detail']
+ jid_info = jid_data['jid_info']
+ jid_kind = jid_data['jid_kind']
+ jid_details = jid_data['jid_details']
+ note = jid_data['note']
+ title = jid_data['title']
- # JID item count
- count = None
- if jid_kind in ('mix', 'muc', 'conference', 'server'):
- jid_items = await XmppXep0030.get_jid_items(xmpp_instance, jid_bare)
- count = len(jid_items['iq']['disco_items']['items'])
- elif jid_kind in ('account', 'pubsub'):
- node_items = await XmppXep0060.get_node_item_ids(xmpp_instance, jid_bare, node_name)
- if isinstance(node_items, stanza.iq.Iq):
- count = len(node_items['disco_items']['items'])
+ # Query URI links
+ action, instance, link_href, links, node_name, view_href, xmpp_uri = XmppUtilities.set_query_uri_link(
+ jid_bare, jid_info, jid_kind, node_name)
- # JID info
- # NOTE Group chat of Psi+ Project at jabber.ru has a note in its vCard.
- vcard_data = await XmppXep0054.get_vcard_data(xmpp_instance, jid_bare)
- if vcard_data['error']:
- jid_detail = {}
- #jid_detail['note'] = '{}: {}'.format(vcard_data['text'], vcard_data['condition'])
- jid_detail['name'] = jid_detail['note'] = jid_detail['note'] = jid_detail['type'] = jid_detail['bin'] = None
- else:
- conference_title = None
- if jid_kind in ('mix', 'muc'):
- for identity in jid_info_iq['disco_info']['identities']:
- if identity[3]:
- conference_title = identity[3]
- break
- vcard_temp = vcard_data['iq']['vcard_temp']
- jid_detail = {
- 'name' : vcard_temp['FN'] or conference_title,
- 'note' : vcard_temp['notes'] or node_id,
- 'type' : vcard_temp['PHOTO']['TYPE'],
- 'bin' : vcard_temp['PHOTO']['BINVAL']
- }
+ # Graphic files
+ filename, filepath, filetype, selection = FileUtilities.handle_photo(jid_bare, jid_detail)
- # Title
- if jid_kind == 'pubsub':
- jid_items = await XmppXep0030.get_jid_items(xmpp_instance, jid_bare)
- iq = jid_items['iq']
- iq_disco_items = iq['disco_items']
- iq_disco_items_items = iq_disco_items['items']
- for item in iq_disco_items_items:
- if item[2] and item[1] == node_name:
- title = item[2]
- break
- if jid_kind == 'server':
- if jid_info_iq:
- for identity in jid_info_iq['disco_info']['identities']:
- if jid_kind == identity[0] and identity[1] == 'im' and identity[3]:
- title = identity[3]
- print(jid_bare)
- print(identity)
- print(jid_info)
- # String 'undefined' is sourced from JID discuss@conference.conversejs.org
- if not title:
- if jid_detail['name'] and not 'undefined' in jid_detail['name']:
- title = jid_detail['name']
- else:
- title = jid_bare.split('@')[0]
-
- xmpp_instance.disconnect()
-
- # Notes
- jid_detail_note = jid_detail['note']
- if isinstance(jid_detail_note, list) and len(jid_detail_note):
- note = jid_detail_note[0]['NOTE']
- else:
- note = jid_detail_note
- #if not note and jid_detail['name'] and not 'undefined' in jid_detail['name'] and title != jid_detail['name']:
- # note = jid_detail['name']
-
- # File type
- mimetype = filename = filepath = None
- if jid_detail['type']:
- mimetype = jid_detail['type']
- if mimetype:
- filetype = mimetype.split('/')[1]
- if filetype == 'svg+xml': filetype = 'svg'
- filename = '{}.{}'.format(jid_bare, filetype)
- filepath = 'photo/{}.{}'.format(jid_bare, filetype)
- #img.save(filename)
-
- # Write the decoded bytes to a file
- with open(filepath, 'wb') as file:
- file.write(jid_detail['bin'])
-
- #from PIL import Image
- #img = Image.open(filepath)
- #rgb_im = im.convert("RGB")
- #rgb_im.save('{}_mod.jpg'.format(jid_bare))
-
- # Default photo. Utilized, if there is no image file.
- if not filepath or not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
- filename = 'default.svg'
- elif filetype == 'svg':
- selection = Graphics.extract_colours_from_vector(filepath)
- else:
- selection = Graphics.extract_colours_from_raster(filepath)
-
- # QR code
- Graphics.generate_qr_code_graphics_from_string(link_href, jid_bare)
-
- except Exception as e:
+ #except Exception as e:
+ else:
exception = str(e)
print(exception)
action = 'Error'
title = 'Slixmpp error'
xmpp_uri = jid
- count = filename = jid_bare = jid_kind = links = message = selection = url = None
+ count = filename = jid_bare = jid_detail = jid_kind = links = \
+ message = selection = url = None
template_file = 'jid.xhtml'
template_dict = {
@@ -984,6 +600,247 @@ class Data:
data_as_string = tomli_w.dumps(data)
fn.write(data_as_string)
+class FileUtilities:
+
+ async def cache_jid_data(jabber_id, password, jid_bare, node_name=None, item_id=None, alias=None):
+
+ count = title = ''
+ jid_detail = {
+ 'name' : '',
+ 'note' : '',
+ 'type' : '',
+ 'bin' : ''}
+
+ #filename = 'details/{}.toml'.format(jid_bare)
+ #if os.path.exists(filename): jid_details = Data.open_file_toml(filename)
+
+ # Start an XMPP instance and retrieve information
+ xmpp_instance = XmppInstance(jabber_id, password, jid_bare)
+ xmpp_instance.connect()
+
+ # JID kind
+ print('JID kind')
+ instance = message = node_id = None
+ jid_info = await XmppXep0030.get_jid_info(xmpp_instance, jid_bare)
+ jid_info_iq = jid_info['iq']
+ jid_kind = jid_info['kind']
+
+ # Query URI links
+ print('Query URI links')
+ action, instance, link_href, links, node_name, view_href, xmpp_uri = XmppUtilities.set_query_uri_link(
+ jid_bare, jid_info, jid_kind, node_name)
+
+ # JID info
+ print('JID info')
+ # NOTE Group chat of Psi+ Project at jabber.ru has a note in its vCard.
+ vcard_data = await XmppXep0054.get_vcard_data(xmpp_instance, jid_bare)
+ if not vcard_data['error']:
+ conference_title = None
+ if jid_kind in ('mix', 'muc'):
+ for identity in jid_info_iq['disco_info']['identities']:
+ if identity[3]:
+ conference_title = identity[3]
+ break
+ vcard_temp = vcard_data['iq']['vcard_temp']
+ jid_detail = {
+ 'name' : vcard_temp['FN'] or conference_title or '',
+ 'note' : vcard_temp['notes'] or node_id or '',
+ 'type' : vcard_temp['PHOTO']['TYPE'] or '',
+ 'bin' : vcard_temp['PHOTO']['BINVAL'] or ''
+ }
+
+ # TODO /d/pubsub.nicoco.fr/blog/urn-uuid-53e43061-1962-3112-bb8a-1473dca61719
+ jid_items = await XmppXep0030.get_jid_items(xmpp_instance, jid_bare)
+ iq = jid_items['iq']
+ iq_disco_items = iq['disco_items']
+ iq_disco_items_items = iq_disco_items['items']
+ iq_disco_items_set = {''}
+ #iq_disco_items_list = []
+ iq_disco_items_items_list = []
+ for item in iq_disco_items_items:
+ if jid_kind == 'muc':
+ iq_disco_items_set.update([item[2]])
+ # iq_disco_items_list.append(item[1])
+ else:
+ iq_disco_items_set.update([item[1]])
+ iq_disco_items_items_list.append(
+ [item[0] or '', item[1] or '', item[2] or ''])
+ count = len(iq_disco_items_set)
+
+ # Title
+ print('Title')
+ if jid_kind not in ('conference', 'mix', 'muc') and '@' in jid_bare:
+ node_name = 'urn:xmpp:microblog:0'
+ title = node_title = 'Journal'
+ elif jid_kind == 'pubsub':
+ category = 'unsorted'
+ for item in iq_disco_items_items:
+ if item[2] and item[1] == node_name:
+ #title = item[2]
+ title = node_title = item[2]
+ break
+ else:
+ jid_items = None
+
+ if jid_kind == 'server':
+ if jid_info_iq:
+ for identity in jid_info_iq['disco_info']['identities']:
+ if jid_kind == identity[0] and identity[1] == 'im' and identity[3]:
+ title = identity[3]
+ print(jid_bare)
+ print(identity)
+ print(jid_info)
+ # String 'undefined' is sourced from JID discuss@conference.conversejs.org
+ if not title:
+ if jid_detail['name'] and not 'undefined' in jid_detail['name']:
+ title = jid_detail['name']
+ else:
+ title = jid_bare.split('@')[0]
+
+ # JID item count
+ #count = await XmppUtilities.count_jid_items(xmpp_instance, jid_bare, node_name, jid_kind)
+ #if jid_kind in ('mix', 'muc', 'conference', 'server'):
+ # jid_items = await XmppXep0030.get_jid_items(xmpp_instance, jid_bare)
+ # if isinstance(jid_items['iq'], stanza.iq.Iq):
+ # count = len(jid_items['iq']['disco_items']['items'])
+ #elif jid_kind in ('account', 'pubsub'):
+ # node_item_ids = await XmppXep0060.get_node_item_ids(xmpp_instance, jid_bare, node_name)
+ # if isinstance(node_item_ids, stanza.iq.Iq):
+ # count = len(node_item_ids['disco_items']['items'])
+
+ # Group chat messages
+ print('Group chat messages')
+ messages = []
+ if jid_kind == 'muc muc': #FIXME
+ print(jid_bare)
+ print(jid_kind)
+ print(alias)
+ action = 'Join'
+ # TODO Create configurations for group chat preview
+ room_info_muc = await XmppXep0045.get_room_information(xmpp_instance, jid_bare, alias) # maxstanzas=50
+ breakpoint()
+ if not room_info_muc:
+ action = 'Warning'
+ node_title = jid_info['condition']
+ node_note = jid_info['text']
+ services = services_sorted = None
+ elif isinstance(room_info_muc, IqTimeout):
+ action = 'Warning'
+ node_title = 'Timeout'
+ node_note = 'Timeout error'
+ services = services_sorted = None
+ elif isinstance(room_info_muc, IqError):
+ action = 'Warning'
+ breakpoint()
+ node_title = room_info_muc['condition']
+ node_note = room_info_muc['text']
+ services = services_sorted = None
+ else:
+ messages = room_info_muc['iq'][3]
+ messages.reverse()
+ subject = room_info_muc['iq'][1]['subject']
+ #title = title or node_name
+ if not node_title: node_title = node_name
+ node_note = jid_bare
+
+ # Node items
+ print('Node items')
+ nodes = {}
+ nodes[node_name] = {}
+ if node_name and node_name in iq_disco_items_set:
+ #if node_name and node_name in iq_disco_items_list:
+ action = 'Browse'
+ node_item_ids = await XmppXep0060.get_node_item_ids(xmpp_instance, jid_bare, node_name)
+ if isinstance(node_item_ids, stanza.iq.Iq):
+ nodes[node_name]['count'] = len(node_item_ids['disco_items']['items'])
+ nodes[node_name]['item_ids'] = []
+ for item_id in node_item_ids['disco_items']['items']:
+ nodes[node_name]['item_ids'].append(
+ [item_id[0] or '', item_id[1] or '', item_id[2] or ''])
+
+ xmpp_instance.disconnect()
+
+ # Notes
+ print('Notes')
+ jid_detail_note = jid_detail['note']
+ if isinstance(jid_detail_note, list) and len(jid_detail_note):
+ note = jid_detail_note[0]['NOTE']
+ else:
+ note = jid_detail_note
+ #if not note and jid_detail['name'] and not 'undefined' in jid_detail['name'] and title != jid_detail['name']:
+ # note = jid_detail['name']
+
+ jid_details = {
+ 'action' : action or '',
+ 'count' : count or '',
+ 'error' : jid_info['error'],
+ 'error_text' : jid_info['text'] or '',
+ 'error_condition' : jid_info['condition'] or '',
+ 'items' : iq_disco_items_items_list,
+ 'link_href' : link_href,
+ 'instance' : instance or '',
+ 'kind' : jid_kind or '',
+ 'messages' : messages or '',
+ 'name' : title,
+ 'nodes' : nodes,
+ 'note' : note or '',
+ 'uri' : xmpp_uri or '',
+ 'view_href' : view_href}
+
+ print(jid_details)
+
+ filename = 'details/{}.toml'.format(jid_bare)
+ Data.save_to_toml(filename, jid_details)
+
+ result = {
+ 'count' : nodes[node_name]['count'] if node_name else count or '',
+ 'jid_detail' : jid_detail,
+ 'jid_info' : jid_info,
+ 'jid_items' : jid_items,
+ 'jid_kind' : jid_kind,
+ 'jid_details' : jid_details,
+ 'note' : note,
+ 'title' : title}
+
+ return result
+
+ def handle_photo(jid_bare, jid_detail):
+ filetype = selection = None
+ filecirca = 'photo/{}.*'.format(jid_bare)
+ filepath = glob.glob(filecirca)
+ if filepath:
+ filepath = filepath[0]
+ filetype = filepath.split('.').pop()
+ filename = '{}.{}'.format(jid_bare, filetype)
+ elif jid_detail:
+ mimetype = filename = filepath = None
+ if jid_detail['type']:
+ mimetype = jid_detail['type']
+ if mimetype:
+ filetype = mimetype.split('/')[1]
+ if filetype == 'svg+xml': filetype = 'svg'
+ filename = '{}.{}'.format(jid_bare, filetype)
+ filepath = 'photo/{}.{}'.format(jid_bare, filetype)
+ #img.save(filename)
+
+ # Write the decoded bytes to a file
+ with open(filepath, 'wb') as file:
+ file.write(jid_detail['bin'])
+
+ if not filepath or not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
+ filename = 'default.svg'
+ elif filetype == 'svg':
+ selection = Graphics.extract_colours_from_vector(filepath)
+ else:
+ selection = Graphics.extract_colours_from_raster(filepath)
+
+ # QR code
+ filepath_qrcode = 'qr/{}.png'.format(jid_bare)
+ if not os.path.exists(filepath_qrcode) or os.path.getsize(filepath_qrcode) == 0:
+ Graphics.generate_qr_code_graphics_from_string(link_href, jid_bare)
+
+ return filename, filepath, filetype, selection
+
class Graphics:
@@ -1162,6 +1019,104 @@ class Syndication:
'updated' : published_text} # TODO "Updated" is missing
return entry
+class XmppUtilities:
+
+ async def count_jid_items(xmpp_instance, jid_bare, node_name, jid_kind):
+ if jid_kind in ('mix', 'muc', 'conference', 'server'):
+ jid_items = await XmppXep0030.get_jid_items(xmpp_instance, jid_bare)
+ if isinstance(jid_items['iq'], stanza.iq.Iq):
+ count = len(jid_items['iq']['disco_items']['items'])
+ elif jid_kind in ('account', 'pubsub'):
+ node_item_ids = await XmppXep0060.get_node_item_ids(xmpp_instance, jid_bare, node_name)
+ if isinstance(node_item_ids, stanza.iq.Iq):
+ count = len(node_item_ids['disco_items']['items'])
+ return count
+
+ def set_query_uri_link(jid_bare, jid_info, jid_kind, node_name=None, item_id=None):
+ links = []
+ if jid_info['error']:
+ message = '{}: {} (XEP-0030)'.format(jid_info['text'], jid_info['condition'])
+ action = 'Connect with'
+ link_href = 'xmpp:{}'.format(jid_bare)
+ links.append({'name' : 'Connect',
+ 'href' : link_href,
+ 'iden' : 'connect'})
+ xmpp_uri = jid_bare
+ instance = view_href = ''
+ elif jid_kind in ('conference', 'server'):
+ action = 'Discover'
+ if jid_kind == 'conference':
+ instance = 'conferences'
+ elif jid_kind == 'server':
+ instance = 'services'
+ link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
+ links.append({'name' : 'Discover',
+ 'href' : link_href,
+ 'iden' : 'discover'})
+ view_href = '/d/' + jid_bare
+ xmpp_uri = jid_bare
+ elif jid_kind in ('mix', 'muc'):
+ #title = 'Group Chat ' + title
+ # TODO Set group chat subject as description.
+ action = 'Join'
+ instance = 'participants'
+ link_href = 'xmpp:{}?join'.format(jid_bare)
+ links.append({'name' : 'Join',
+ 'href' : link_href,
+ 'iden' : 'join'})
+ view_href = '/v/' + jid_bare
+ xmpp_uri = jid_bare
+ # room_info = await XmppXep0045.get_room_data(xmpp_instance, jid_bare)
+ # breakpoint()
+ elif jid_kind == 'pubsub':
+ #node_name = request.query_params.get('node', '')
+ if node_name:
+ action = 'Subscribe'
+ instance = 'articles'
+ link_href = 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name)
+ view_href = '/d/{}/{}'.format(jid_bare, node_name)
+ xmpp_uri = '{}?;node={}'.format(jid_bare, node_name)
+ else:
+ action = 'Browse'
+ instance = 'nodes'
+ link_href = 'xmpp:{}?disco;type=get;request=items'.format(jid_bare)
+ links.append({'name' : 'Browse',
+ 'href' : link_href,
+ 'iden' : 'browse'})
+ view_href = '/d/' + jid_bare
+ xmpp_uri = jid_bare
+ else:
+ action = 'Message'
+ instance = 'articles'
+ link_href = 'xmpp:{}?message'.format(jid_bare)
+ links.append({'name' : 'Add',
+ 'href' : 'xmpp:{}?roster'.format(jid_bare),
+ 'iden' : 'add'})
+ links.append({'name' : 'Message',
+ 'href' : link_href,
+ 'iden' : 'message'})
+ #node_name = 'urn:xmpp:microblog:0'
+ view_href = '/d/{}/{}'.format(jid_bare, node_name)
+ xmpp_uri = jid_bare
+ if item_id:
+ links.append({'name' : 'Subscribe',
+ 'href' : 'xmpp:{}?pubsub;node={};item={};action=subscribe'.format(jid_bare, node_name, item_id),
+ 'iden' : 'subscribe'})
+ links.append({'name' : 'View',
+ 'href' : 'xmpp:{}?pubsub;node={};item={}'.format(jid_bare, node_name, item_id),
+ 'iden' : 'view'})
+ elif node_name:
+ links.append({'name' : 'Subscribe',
+ 'href' : 'xmpp:{}?pubsub;node={};action=subscribe'.format(jid_bare, node_name),
+ 'iden' : 'subscribe'})
+ links.append({'name' : 'View',
+ 'href' : 'xmpp:{}?pubsub;node={}'.format(jid_bare, node_name),
+ 'iden' : 'view'})
+ links.append({'name' : 'vCard',
+ 'href' : 'xmpp:{}?vcard'.format(jid_bare),
+ 'iden' : 'vcard'})
+ return action, instance, link_href, links, node_name, view_href, xmpp_uri
+
class XmppXep0030:
async def get_jid_items(self, jid_bare):
diff --git a/vcard/README b/vcard/README
deleted file mode 100644
index 918d546..0000000
--- a/vcard/README
+++ /dev/null
@@ -1 +0,0 @@
-This directory caches vcard files.
diff --git a/xhtml/conference.xhtml b/xhtml/conference.xhtml
index b87c361..acb663b 100644
--- a/xhtml/conference.xhtml
+++ b/xhtml/conference.xhtml
@@ -48,7 +48,7 @@
{% endif %}
{% if jid_title %}{{jid_title}}{% else %}Group Chat{% endif %}
-
+
{% if jid_note %}{{jid_note}}{% else %}{{jid_bare}}{% endif %}
@@ -131,7 +131,7 @@
{% if message %}
-