Change node names;
Soft code (i.e. opposite of hard code) node names; Improve parsing of Netscape HTML boomark files; Add IQ module; Catch more exceptions; Display Jabber ID on template profile.
This commit is contained in:
parent
a3d50fe8d8
commit
2103b061a2
8 changed files with 277 additions and 214 deletions
|
@ -74,6 +74,12 @@
|
|||
This page provides a general survey of your XMPP account and
|
||||
stored bookmarks.
|
||||
</p>
|
||||
<h4 id="jid">
|
||||
Jabber ID
|
||||
</h4>
|
||||
<p>
|
||||
Your Jabber identifier is <a href="xmpp:{{jabber_id}}?message">{{jabber_id}}</a>.
|
||||
</p>
|
||||
<!--
|
||||
<h4 id="enrollment">
|
||||
Enrollment
|
||||
|
@ -471,7 +477,7 @@ retrieve items only if on a whitelist managed by the node owner.">
|
|||
to='{{jabber_id}}'
|
||||
id='delete1'>
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
|
||||
<delete node='urn:xmpp:bibliography:0'/>
|
||||
<delete node='blasta:annotation:0'/>
|
||||
</pubsub>
|
||||
</iq>
|
||||
</pre>
|
||||
|
@ -484,7 +490,7 @@ retrieve items only if on a whitelist managed by the node owner.">
|
|||
to='{{jabber_id}}'
|
||||
id='delete2'>
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
|
||||
<delete node='xmpp:bibliography:private:0'/>
|
||||
<delete node='blasta:annotation:private:0'/>
|
||||
</pubsub>
|
||||
</iq>
|
||||
</pre>
|
||||
|
@ -497,7 +503,7 @@ retrieve items only if on a whitelist managed by the node owner.">
|
|||
to='{{jabber_id}}'
|
||||
id='delete3'>
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
|
||||
<delete node='xmpp:bibliography:read:0'/>
|
||||
<delete node='blasta:annotation:read:0'/>
|
||||
</pubsub>
|
||||
</iq>
|
||||
</pre>
|
||||
|
|
|
@ -13,22 +13,24 @@ journal = ""
|
|||
pubsub = ""
|
||||
|
||||
# Bibliography
|
||||
node_id = "blasta:annotation:0"
|
||||
node_title = "Blasta"
|
||||
node_subtitle = "Annotation"
|
||||
node_public_id = "blasta:annotation:0"
|
||||
node_public_title = "Blasta (Public)"
|
||||
node_public_subtitle = "Public annotations"
|
||||
|
||||
# Private bibliography
|
||||
node_id_private = "blasta:annotation:private:0"
|
||||
node_title_private = "Blasta (Private)"
|
||||
node_subtitle_private = "Private annotation"
|
||||
node_private_id = "blasta:annotation:private:0"
|
||||
node_private_title = "Blasta (Private)"
|
||||
node_private_subtitle = "Private annotations"
|
||||
|
||||
# Reading list
|
||||
node_id_read = "blasta:annotation:read:0"
|
||||
node_title_read = "Blasta (Read)"
|
||||
node_subtitle_read = "Reading list"
|
||||
node_read_id = "blasta:annotation:read:0"
|
||||
node_read_title = "Blasta (Read)"
|
||||
node_read_subtitle = "Reading list"
|
||||
|
||||
# Settings node
|
||||
node_settings = "blasta:settings:0"
|
||||
node_settings_id = "blasta:settings:0"
|
||||
node_settings_title = "Blasta (Settings)"
|
||||
node_settings_subtitle = "Blasta Settings Node"
|
||||
|
||||
# Acceptable protocol types that would be aggregated to the Blasta database
|
||||
schemes = [
|
||||
|
|
|
@ -11,6 +11,7 @@ from blasta.utilities.http import UtilitiesHttp
|
|||
from blasta.utilities.syndication import UtilitiesSyndication
|
||||
from blasta.xmpp.form import DataForm
|
||||
from blasta.xmpp.instance import XmppInstance
|
||||
from blasta.xmpp.iq import XmppIq
|
||||
from blasta.xmpp.pubsub import XmppPubsub
|
||||
from datetime import datetime
|
||||
from fastapi import Cookie, FastAPI, File, Form, HTTPException, Request, Response, UploadFile
|
||||
|
@ -73,33 +74,37 @@ class HttpInstance:
|
|||
jabber_id_pubsub = settings['pubsub']
|
||||
journal = settings['journal']
|
||||
|
||||
node_id_public = settings['node_id']
|
||||
node_title_public = settings['node_title']
|
||||
node_subtitle_public = settings['node_subtitle']
|
||||
node_settings_id = settings['node_settings_id']
|
||||
node_settings_title = settings['node_settings_title']
|
||||
node_settings_subtitle = settings['node_settings_subtitle']
|
||||
|
||||
node_id_private = settings['node_id_private']
|
||||
node_title_private = settings['node_title_private']
|
||||
node_subtitle_private = settings['node_subtitle_private']
|
||||
node_public_id = settings['node_public_id']
|
||||
node_public_title = settings['node_public_title']
|
||||
node_public_subtitle = settings['node_public_subtitle']
|
||||
|
||||
node_id_read = settings['node_id_read']
|
||||
node_title_read = settings['node_title_read']
|
||||
node_subtitle_read = settings['node_subtitle_read']
|
||||
node_private_id = settings['node_private_id']
|
||||
node_private_title = settings['node_private_title']
|
||||
node_private_subtitle = settings['node_private_subtitle']
|
||||
|
||||
node_read_id = settings['node_read_id']
|
||||
node_read_title = settings['node_read_title']
|
||||
node_read_subtitle = settings['node_read_subtitle']
|
||||
|
||||
nodes = {
|
||||
'public' : {
|
||||
'name' : node_id_public,
|
||||
'title' : node_title_public,
|
||||
'subtitle' : node_subtitle_public,
|
||||
'name' : node_public_id,
|
||||
'title' : node_public_title,
|
||||
'subtitle' : node_public_subtitle,
|
||||
'access_model' : 'presence'},
|
||||
'private' : {
|
||||
'name' : node_id_private,
|
||||
'title' : node_title_private,
|
||||
'subtitle' : node_subtitle_private,
|
||||
'name' : node_private_id,
|
||||
'title' : node_private_title,
|
||||
'subtitle' : node_private_subtitle,
|
||||
'access_model' : 'whitelist'},
|
||||
'read' : {
|
||||
'name' : node_id_read,
|
||||
'title' : node_title_read,
|
||||
'subtitle' : node_subtitle_read,
|
||||
'name' : node_read_id,
|
||||
'title' : node_read_title,
|
||||
'subtitle' : node_read_subtitle,
|
||||
'access_model' : 'whitelist'}
|
||||
}
|
||||
|
||||
|
@ -522,7 +527,7 @@ class HttpInstance:
|
|||
result, reason = await UtilitiesData.update_cache_and_database(
|
||||
db_file, directory_cache, xmpp_instance, jabber_id, node_type, node_id)
|
||||
if result == 'error':
|
||||
message = 'XMPP system message » {}.'.format(reason)
|
||||
message = f'XMPP system message » {reason}.'
|
||||
description = 'IQ Error'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
|
@ -545,7 +550,7 @@ class HttpInstance:
|
|||
ask = invite = name = origin = start = ''
|
||||
# pubsub_jid = syndicate = jid
|
||||
# message = 'Find and share bookmarks with family and friends!'
|
||||
# description = 'Bookmarks of {}'.format(jid)
|
||||
# description = f'Bookmarks of {jid}'
|
||||
max_count = 10
|
||||
entries = None
|
||||
related_tags = None
|
||||
|
@ -585,43 +590,10 @@ class HttpInstance:
|
|||
if param_query:
|
||||
query = param_query
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
entries_cache_node = entries_cache[node_type]
|
||||
filename_cache = os.path.join(directory_cache, 'data', jid + '_query.toml')
|
||||
UtilitiesData.cache_items_and_tags_search(directory_cache, entries_cache_node, jid, query)
|
||||
if os.path.exists(filename_cache) and os.path.getsize(filename_cache):
|
||||
data = UtilitiesData.open_file_toml(filename_cache)
|
||||
item_ids_all = data['item_ids']
|
||||
related_tags = data['tags']
|
||||
if len(item_ids_all) <= index_last:
|
||||
index_last = len(item_ids_all)
|
||||
page_next = None
|
||||
item_ids_selection = []
|
||||
for item_id in item_ids_all[index_first:index_last]:
|
||||
item_ids_selection.append(item_id)
|
||||
entries = []
|
||||
for entry in entries_cache_node:
|
||||
for item_id in item_ids_selection:
|
||||
if entry['url_hash'] == item_id:
|
||||
entries.append(entry)
|
||||
for entry in entries:
|
||||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(entry['published'])
|
||||
entry['tags'] = entry['tags'][:5]
|
||||
description = 'Your {} bookmarks with "{}"'.format(node_type, query)
|
||||
message = 'Listing {} bookmarks {} - {} out of {}.'.format(node_type, index_first+1, index_last, len(item_ids_all))
|
||||
#item_id_next = entries[len(entries)-1]
|
||||
else:
|
||||
description = 'No {} bookmarks with "{}" were found for {}'.format(node_type, query, jid)
|
||||
message = 'Blasta system message » No entries.'
|
||||
page_next = None
|
||||
page_prev = None
|
||||
elif param_tags or param_tld or param_filetype or param_protocol:
|
||||
tags_list = param_tags.split('+')
|
||||
if len(tags_list) == 1:
|
||||
tag = param_tags
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
if node_type in entries_cache:
|
||||
entries_cache_node = entries_cache[node_type]
|
||||
filename_cache = os.path.join(directory_cache, 'data', jid, tag + '.toml')
|
||||
UtilitiesData.cache_items_and_tags_filter(directory_cache, entries_cache_node, jid, tag)
|
||||
filename_cache = os.path.join(directory_cache, 'data', jid + '_query.toml')
|
||||
UtilitiesData.cache_items_and_tags_search(directory_cache, entries_cache_node, jid, query)
|
||||
if os.path.exists(filename_cache) and os.path.getsize(filename_cache):
|
||||
data = UtilitiesData.open_file_toml(filename_cache)
|
||||
item_ids_all = data['item_ids']
|
||||
|
@ -640,11 +612,56 @@ class HttpInstance:
|
|||
for entry in entries:
|
||||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(entry['published'])
|
||||
entry['tags'] = entry['tags'][:5]
|
||||
description = 'Your {} bookmarks tagged with "{}"'.format(node_type, tag)
|
||||
message = 'Listing {} bookmarks {} - {} out of {}.'.format(node_type, index_first+1, index_last, len(item_ids_all))
|
||||
description = f'Your {node_type} bookmarks with "{query}"'
|
||||
message = f'Listing {node_type} bookmarks {index_first+1} - {index_last} out of {len(item_ids_all)}.'
|
||||
#item_id_next = entries[len(entries)-1]
|
||||
else:
|
||||
description = 'No {} bookmarks tagged with "{}" were found for {}'.format(node_type, tag, jid)
|
||||
description = f'No {node_type} bookmarks with "{query}" were found for {jid}'
|
||||
message = 'Blasta system message » No entries.'
|
||||
page_next = None
|
||||
page_prev = None
|
||||
else:
|
||||
description = f'No {node_type} bookmarks with "{query}" were found for {jid}'
|
||||
message = 'Blasta system message » No entries.'
|
||||
page_next = None
|
||||
page_prev = None
|
||||
elif param_tags or param_tld or param_filetype or param_protocol:
|
||||
tags_list = param_tags.split('+')
|
||||
if len(tags_list) == 1:
|
||||
tag = param_tags
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
if node_type in entries_cache:
|
||||
entries_cache_node = entries_cache[node_type]
|
||||
filename_cache = os.path.join(directory_cache, 'data', jid, tag + '.toml')
|
||||
UtilitiesData.cache_items_and_tags_filter(directory_cache, entries_cache_node, jid, tag)
|
||||
if os.path.exists(filename_cache) and os.path.getsize(filename_cache):
|
||||
data = UtilitiesData.open_file_toml(filename_cache)
|
||||
item_ids_all = data['item_ids']
|
||||
related_tags = data['tags']
|
||||
if len(item_ids_all) <= index_last:
|
||||
index_last = len(item_ids_all)
|
||||
page_next = None
|
||||
item_ids_selection = []
|
||||
for item_id in item_ids_all[index_first:index_last]:
|
||||
item_ids_selection.append(item_id)
|
||||
entries = []
|
||||
for entry in entries_cache_node:
|
||||
for item_id in item_ids_selection:
|
||||
if entry['url_hash'] == item_id:
|
||||
entries.append(entry)
|
||||
for entry in entries:
|
||||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(entry['published'])
|
||||
entry['tags'] = entry['tags'][:5]
|
||||
description = f'Your {node_type} bookmarks tagged with "{tag}"'
|
||||
message = f'Listing {node_type} bookmarks {index_first+1} - {index_last} out of {len(item_ids_all)}.'
|
||||
#item_id_next = entries[len(entries)-1]
|
||||
else:
|
||||
description = 'No {node_type} bookmarks tagged with "{tag}" were found for {jid}'
|
||||
message = 'Blasta system message » No entries.'
|
||||
page_next = None
|
||||
page_prev = None
|
||||
else:
|
||||
description = 'No {node_type} bookmarks tagged with "{tag}" were found for {jid}'
|
||||
message = 'Blasta system message » No entries.'
|
||||
page_next = None
|
||||
page_prev = None
|
||||
|
@ -654,31 +671,37 @@ class HttpInstance:
|
|||
else:
|
||||
name = jabber_id.split('@')[0]
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
entries_cache_node = entries_cache[node_type]
|
||||
filename_cache = os.path.join(directory_cache, 'data', jabber_id + '.toml')
|
||||
#if len(entries_cache_node) and not os.path.exists(filename_cache):
|
||||
UtilitiesData.cache_items_and_tags(directory_cache, entries_cache_node, jabber_id)
|
||||
if os.path.exists(filename_cache) and os.path.getsize(filename_cache):
|
||||
data = UtilitiesData.open_file_toml(filename_cache)
|
||||
item_ids_all = data['item_ids']
|
||||
related_tags = data['tags']
|
||||
if len(item_ids_all) <= index_last:
|
||||
index_last = len(item_ids_all)
|
||||
page_next = None
|
||||
item_ids_selection = []
|
||||
for item_id in item_ids_all[index_first:index_last]:
|
||||
item_ids_selection.append(item_id)
|
||||
entries = []
|
||||
for entry in entries_cache_node:
|
||||
for item_id in item_ids_selection:
|
||||
if entry['url_hash'] == item_id:
|
||||
entries.append(entry)
|
||||
for entry in entries:
|
||||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(entry['published'])
|
||||
entry['tags'] = entry['tags'][:5]
|
||||
description = 'Your {} bookmarks'.format(node_type)
|
||||
message = 'Listing {} bookmarks {} - {} out of {}.'.format(node_type, index_first+1, index_last, len(item_ids_all))
|
||||
#item_id_next = entries[len(entries)-1]
|
||||
if node_type in entries_cache:
|
||||
entries_cache_node = entries_cache[node_type]
|
||||
filename_cache = os.path.join(directory_cache, 'data', jabber_id + '.toml')
|
||||
#if len(entries_cache_node) and not os.path.exists(filename_cache):
|
||||
UtilitiesData.cache_items_and_tags(directory_cache, entries_cache_node, jabber_id)
|
||||
if os.path.exists(filename_cache) and os.path.getsize(filename_cache):
|
||||
data = UtilitiesData.open_file_toml(filename_cache)
|
||||
item_ids_all = data['item_ids']
|
||||
related_tags = data['tags']
|
||||
if len(item_ids_all) <= index_last:
|
||||
index_last = len(item_ids_all)
|
||||
page_next = None
|
||||
item_ids_selection = []
|
||||
for item_id in item_ids_all[index_first:index_last]:
|
||||
item_ids_selection.append(item_id)
|
||||
entries = []
|
||||
for entry in entries_cache_node:
|
||||
for item_id in item_ids_selection:
|
||||
if entry['url_hash'] == item_id:
|
||||
entries.append(entry)
|
||||
for entry in entries:
|
||||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(
|
||||
entry['published'])
|
||||
entry['tags'] = entry['tags'][:5]
|
||||
description = f'Your {node_type} bookmarks'
|
||||
message = f'Listing {node_type} bookmarks {index_first+1} - {index_last} out of {len(item_ids_all)}.'
|
||||
#item_id_next = entries[len(entries)-1]
|
||||
else:
|
||||
description = 'Your bookmarks directory appears to be empty'
|
||||
message = 'Blasta system message » Zero count.'
|
||||
start = True
|
||||
else:
|
||||
description = 'Your bookmarks directory appears to be empty'
|
||||
message = 'Blasta system message » Zero count.'
|
||||
|
@ -692,19 +715,19 @@ class HttpInstance:
|
|||
xmpp_instance = accounts[jabber_id]
|
||||
tags_dict = {}
|
||||
if param_query:
|
||||
description = 'Bookmarks from {} with "{}"'.format(jid, param_query)
|
||||
description = f'Bookmarks from {jid} with "{param_query}"'
|
||||
entries_database = DatabaseSQLite.get_entries_by_jid_and_query(db_file, jid, param_query, index_first)
|
||||
entries_count = DatabaseSQLite.get_entries_count_by_jid_and_query(db_file, jid, param_query)
|
||||
for tag, instances in DatabaseSQLite.get_30_tags_by_jid_and_query(db_file, jid, param_query, index_first):
|
||||
tags_dict[tag] = instances
|
||||
elif param_tags:
|
||||
description = 'Bookmarks from {} tagged with "{}"'.format(jid, param_tags)
|
||||
description = f'Bookmarks from {jid} tagged with "{param_tags}"'
|
||||
entries_database = DatabaseSQLite.get_entries_by_jid_and_tag(db_file, jid, param_tags, index_first)
|
||||
entries_count = DatabaseSQLite.get_entries_count_by_jid_and_tag(db_file, jid, param_tags)
|
||||
for tag, instances in DatabaseSQLite.get_30_tags_by_jid_and_tag(db_file, jid, param_tags, index_first):
|
||||
tags_dict[tag] = instances
|
||||
else:
|
||||
description = 'Bookmarks from {}'.format(jid)
|
||||
description = f'Bookmarks from {jid}'
|
||||
entries_database = DatabaseSQLite.get_entries_by_jid(db_file, jid, index_first)
|
||||
entries_count = DatabaseSQLite.get_entries_count_by_jid(db_file, jid)
|
||||
for tag, instances in DatabaseSQLite.get_30_tags_by_jid(db_file, jid, index_first):
|
||||
|
@ -749,10 +772,10 @@ class HttpInstance:
|
|||
if entries_count <= index_last:
|
||||
index_last = entries_count
|
||||
page_next = None
|
||||
message = 'Listing bookmarks {} - {} out of {}.'.format(index_first+1, index_last, entries_count)
|
||||
message = f'Listing bookmarks {index_first+1} - {index_last} out of {entries_count}.'
|
||||
else:
|
||||
# TODO Check permission, so there is no unintended continuing to cached data which is not authorized for.
|
||||
iq = await XmppPubsub.get_node_item_ids(xmpp_instance, jid, node_id_public)
|
||||
iq = await XmppPubsub.get_node_item_ids(xmpp_instance, jid, node_public_id)
|
||||
if isinstance(iq, Iq):
|
||||
iq_items_remote = iq['disco_items']
|
||||
|
||||
|
@ -776,19 +799,19 @@ class HttpInstance:
|
|||
for item_id in item_ids_all[index_first:index_last]:
|
||||
item_ids_selection.append(item_id)
|
||||
|
||||
iq = await XmppPubsub.get_node_items(xmpp_instance, jid, node_id_public, item_ids_selection)
|
||||
iq = await XmppPubsub.get_node_items(xmpp_instance, jid, node_public_id, item_ids_selection)
|
||||
entries = UtilitiesData.extract_iq_items_extra(db_file, iq, jid)
|
||||
if entries:
|
||||
for entry in entries:
|
||||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(entry['published'])
|
||||
message = 'Listing bookmarks {} - {} out of {}.'.format(index_first+1, index_last, len(item_ids_all))
|
||||
description = 'Bookmarks from {}'.format(jid)
|
||||
message = f'Listing bookmarks {index_first+1} - {index_last} out of {len(item_ids_all)}.'
|
||||
description = f'Bookmarks from {jid}'
|
||||
else:
|
||||
message = 'Blasta system message » Zero count.'
|
||||
description = 'Bookmarks directory appears to be empty'
|
||||
invite = True
|
||||
else:
|
||||
message = 'XMPP system message » {}.'.format(iq)
|
||||
message = f'XMPP system message » {iq}.'
|
||||
name = jid.split('@')[0]
|
||||
path = 'error'
|
||||
if not iq:
|
||||
|
@ -811,7 +834,7 @@ class HttpInstance:
|
|||
invite = True
|
||||
elif 'DNS lookup failed' in iq:
|
||||
domain = jid.split('@')[1] if '@' in jid else jid
|
||||
description = 'Blasta could not connect to server {}'.format(domain)
|
||||
description = f'Blasta could not connect to server {domain}'
|
||||
elif iq == 'Connection failed: connection refused':
|
||||
description = 'Connection with ' + name + ' has been refused'
|
||||
elif 'Timeout' in iq or 'timeout' in iq:
|
||||
|
@ -929,15 +952,15 @@ class HttpInstance:
|
|||
entries_count = DatabaseSQLite.get_entries_count_by_tag(db_file, param_tags)
|
||||
match page_type:
|
||||
case 'new':
|
||||
description = 'New bookmarks tagged with "{}"'.format(param_tags)
|
||||
description = f'New bookmarks tagged with "{param_tags}"'
|
||||
entries_database = DatabaseSQLite.get_entries_new_by_tag(db_file, param_tags, index_first)
|
||||
tags_of_entries = DatabaseSQLite.get_30_tags_by_entries_new_by_tag(db_file, param_tags, index_first)
|
||||
case 'popular':
|
||||
description = 'Popular bookmarks tagged with "{}"'.format(param_tags) # 'Most popular'
|
||||
description = f'Popular bookmarks tagged with "{param_tags}"' # 'Most popular'
|
||||
entries_database = DatabaseSQLite.get_entries_popular_by_tag(db_file, param_tags, index_first)
|
||||
tags_of_entries = DatabaseSQLite.get_30_tags_by_entries_popular_by_tag(db_file, param_tags, index_first)
|
||||
case 'recent':
|
||||
description = 'Recent bookmarks tagged with "{}"'.format(param_tags)
|
||||
description = f'Recent bookmarks tagged with "{param_tags}"'
|
||||
entries_database = DatabaseSQLite.get_entries_recent_by_tag(db_file, param_tags, index_first)
|
||||
tags_of_entries = DatabaseSQLite.get_30_tags_by_entries_recent_by_tag(db_file, param_tags, index_first)
|
||||
# TODO case 'query':
|
||||
|
@ -955,7 +978,7 @@ class HttpInstance:
|
|||
entries_count = DatabaseSQLite.get_entries_count(db_file)
|
||||
case 'query':
|
||||
node_id = syndicate = 'new'
|
||||
description = 'Posted bookmarks with "{}"'.format(param_query)
|
||||
description = f'Posted bookmarks with "{param_query}"'
|
||||
entries_database = DatabaseSQLite.get_entries_by_query(db_file, param_query, index_first)
|
||||
tags_of_entries = DatabaseSQLite.get_30_tags_by_entries_by_query_recent(db_file, param_query, index_first)
|
||||
entries_count = DatabaseSQLite.get_entries_count_by_query(db_file, param_query)
|
||||
|
@ -1010,7 +1033,7 @@ class HttpInstance:
|
|||
page_next = None
|
||||
#if page_type != 'new' or page_prev or param_tags or param_tld or param_filetype or param_protocol:
|
||||
if request.url.path != '/' or request.url.query:
|
||||
message = 'Listing bookmarks {} - {} out of {}.'.format(index_first+1, index_last, entries_count)
|
||||
message = f'Listing bookmarks {index_first+1} - {index_last} out of {entries_count}.'
|
||||
message_link = None
|
||||
else:
|
||||
message = ('Welcome to Blasta, an XMPP PubSub oriented social '
|
||||
|
@ -1052,8 +1075,8 @@ class HttpInstance:
|
|||
@self.app.get('/tag/{tag}')
|
||||
async def tag_tag_get(request: Request, tag):
|
||||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
node_id = 'tag:{}'.format(tag)
|
||||
syndicate = '?tag={}'.format(tag)
|
||||
node_id = f'tag:{tag}'
|
||||
syndicate = f'?tag={tag}'
|
||||
path = 'tag'
|
||||
# NOTE Perhaps it would be beneficial to retrieve "published" and
|
||||
# tags ("category") of viewer to override the tags of Blasta
|
||||
|
@ -1123,7 +1146,7 @@ class HttpInstance:
|
|||
|
||||
if jabber_id in accounts:
|
||||
xmpp_instance = accounts[jabber_id]
|
||||
#await xmpp_instance.plugin['xep_0060'].delete_node(jabber_id, node_id_public)
|
||||
#await xmpp_instance.plugin['xep_0060'].delete_node(jabber_id, node_public_id)
|
||||
|
||||
for node_properties in nodes:
|
||||
properties = nodes[node_properties]
|
||||
|
@ -1132,22 +1155,22 @@ class HttpInstance:
|
|||
xmpp_instance, jabber_id, properties['name'],
|
||||
properties['title'], properties['subtitle'],
|
||||
properties['access_model'])
|
||||
await iq.send(timeout=15)
|
||||
await XmppIq.send(iq, 15)
|
||||
|
||||
#await XmppPubsub.set_node_private(xmpp_instance, node_id_private)
|
||||
#await XmppPubsub.set_node_private(xmpp_instance, node_id_read)
|
||||
#await XmppPubsub.set_node_private(xmpp_instance, node_private_id)
|
||||
#await XmppPubsub.set_node_private(xmpp_instance, node_read_id)
|
||||
#configuration_form = await xmpp_instance['xep_0060'].get_node_config(jabber_id, properties['name'])
|
||||
#print(configuration_form)
|
||||
node_id = nodes['public']['name']
|
||||
result, reason = await UtilitiesData.update_cache_and_database(
|
||||
db_file, directory_cache, xmpp_instance, jabber_id, 'public', node_id)
|
||||
if result == 'error':
|
||||
message = 'XMPP system message » {}.'.format(reason)
|
||||
message = f'XMPP system message » {reason}.'
|
||||
description = 'IQ Error'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
else:
|
||||
iq = await XmppPubsub.get_node_item(xmpp_instance, jabber_id, 'xmpp:blasta:configuration:0', 'routine')
|
||||
iq = await XmppPubsub.get_node_item(xmpp_instance, jabber_id, node_settings_id, 'routine')
|
||||
routine = None
|
||||
if isinstance(iq, Iq):
|
||||
payload = iq['pubsub']['items']['item']['payload']
|
||||
|
@ -1182,7 +1205,7 @@ class HttpInstance:
|
|||
xmpp_instance = accounts[jabber_id]
|
||||
XmppMessage.send(xmpp_instance, jid, body)
|
||||
alias = jid.split('@')[0]
|
||||
message = 'Your message has been sent to {}.'.format(alias)
|
||||
message = f'Your message has been sent to {alias}.'
|
||||
description = 'Message has been sent'
|
||||
path = 'message'
|
||||
else:
|
||||
|
@ -1215,7 +1238,7 @@ class HttpInstance:
|
|||
result, reason = await UtilitiesData.update_cache_and_database(
|
||||
db_file, directory_cache, xmpp_instance, jabber_id, node_type, node_id)
|
||||
if result == 'error':
|
||||
message = 'Blasta system message » {}.'.format(reason)
|
||||
message = f'Blasta system message » {reason}.'
|
||||
description = 'Directory "private" appears to be empty'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
|
@ -1233,18 +1256,19 @@ class HttpInstance:
|
|||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
if jabber_id:
|
||||
xmpp_instance = accounts[jabber_id]
|
||||
if not await XmppPubsub.is_node_exist(xmpp_instance, 'xmpp:blasta:configuration:0'):
|
||||
iq = XmppPubsub.create_node_config(xmpp_instance, jabber_id)
|
||||
await iq.send(timeout=15)
|
||||
if not await XmppPubsub.is_node_exist(xmpp_instance, node_settings_id):
|
||||
iq = XmppPubsub.create_node_config(xmpp_instance, jabber_id, node_settings_id)
|
||||
await XmppIq.send(iq, 15)
|
||||
access_models = {}
|
||||
for node_type in nodes:
|
||||
node_id = nodes[node_type]['name']
|
||||
iq = await XmppPubsub.get_node_configuration(xmpp_instance, jabber_id, node_id)
|
||||
access_model = iq['pubsub_owner']['configure']['form']['values']['pubsub#access_model']
|
||||
access_models[node_type] = access_model
|
||||
if isinstance(iq, Iq):
|
||||
access_model = iq['pubsub_owner']['configure']['form']['values']['pubsub#access_model']
|
||||
access_models[node_type] = access_model
|
||||
settings = {}
|
||||
for setting in ['enrollment', 'routine']:
|
||||
iq = await XmppPubsub.get_node_item(xmpp_instance, jabber_id, 'xmpp:blasta:configuration:0', setting)
|
||||
iq = await XmppPubsub.get_node_item(xmpp_instance, jabber_id, node_settings_id, setting)
|
||||
if isinstance(iq, Iq):
|
||||
payload = iq['pubsub']['items']['item']['payload']
|
||||
if payload:
|
||||
|
@ -1276,16 +1300,16 @@ class HttpInstance:
|
|||
if jabber_id:
|
||||
xmpp_instance = accounts[jabber_id]
|
||||
if routine:
|
||||
message = 'The routine directory has been set to {}'.format(routine)
|
||||
message = f'The routine directory has been set to {routine}'
|
||||
payload = DataForm.create_setting_entry(xmpp_instance, 'routine', routine)
|
||||
iq = await XmppPubsub.publish_node_item( # NOTE Consider "configurations" as item ID (see Movim)
|
||||
xmpp_instance, jabber_id, 'xmpp:blasta:configuration:0', 'routine', payload)
|
||||
xmpp_instance, jabber_id, node_settings_id, 'routine', payload)
|
||||
if enroll:
|
||||
if enroll == '1': message = 'Your database is shared with the Blasta system'
|
||||
else: message = 'Your database is excluded from the Blasta system'
|
||||
payload = DataForm.create_setting_entry(xmpp_instance, 'enroll', enroll)
|
||||
iq = await XmppPubsub.publish_node_item(
|
||||
xmpp_instance, jabber_id, 'xmpp:blasta:configuration:0', 'enrollment', payload)
|
||||
xmpp_instance, jabber_id, node_settings_id, 'enrollment', payload)
|
||||
description = 'Setting has been saved'
|
||||
template_file = 'result.xhtml'
|
||||
template_dict = {
|
||||
|
@ -1318,9 +1342,9 @@ class HttpInstance:
|
|||
if entries:
|
||||
filename = os.path.join(directory_cache, 'export', jabber_id + '_' + node_type + '.' + filetype)
|
||||
#filename = 'export/' + jabber_id + '_' + node_type + '.' + filetype
|
||||
#filename = 'export/{}_{}.{}'.format(jabber_id, node_type, filetype)
|
||||
#filename = f'export/{jabber_id}_{node_type}.{filetype}'
|
||||
#filename = 'export_' + node_type + '/' + jabber_id + '_' + '.' + filetype
|
||||
#filename = 'export_{}/{}.{}'.format(node_type, jabber_id, filetype)
|
||||
#filename = f'export_{node_type}/{jabber_id}.{filetype}'
|
||||
match filetype:
|
||||
case 'json':
|
||||
UtilitiesData.save_to_json(filename, entries)
|
||||
|
@ -1360,7 +1384,7 @@ class HttpInstance:
|
|||
iq = XmppPubsub.create_node_atom(
|
||||
xmpp_instance, jabber_id, node_id, node_title,
|
||||
node_subtitle, node_access_model)
|
||||
await iq.send(timeout=15)
|
||||
await XmppIq.send(iq, 15)
|
||||
|
||||
#return {"filename": file.filename}
|
||||
content = file.file.read().decode()
|
||||
|
@ -1408,10 +1432,10 @@ class HttpInstance:
|
|||
payload = UtilitiesSyndication.create_rfc4287_entry(entry_new)
|
||||
iq = await XmppPubsub.publish_node_item(
|
||||
xmpp_instance, jabber_id, node_id, item_id, payload)
|
||||
#await iq.send(timeout=15)
|
||||
#await XmppIq.send(iq, 15)
|
||||
counter += 1
|
||||
|
||||
message = 'Blasta system message » Imported {} items.'.format(counter)
|
||||
message = f'Blasta system message » Imported {counter} items.'
|
||||
description = 'Import successful'
|
||||
path = 'profile'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
|
@ -1441,7 +1465,7 @@ class HttpInstance:
|
|||
if (isinstance(iq, Iq) and
|
||||
url_hash == iq['pubsub']['items']['item']['id']):
|
||||
return RedirectResponse(url='/url/' + url_hash + '/edit')
|
||||
iq = await XmppPubsub.get_node_item(xmpp_instance, jabber_id, 'xmpp:blasta:configuration:0', 'routine')
|
||||
iq = await XmppPubsub.get_node_item(xmpp_instance, jabber_id, node_settings_id, 'routine')
|
||||
if isinstance(iq, Iq):
|
||||
payload = iq['pubsub']['items']['item']['payload']
|
||||
if payload:
|
||||
|
@ -1541,7 +1565,7 @@ class HttpInstance:
|
|||
result, reason = await UtilitiesData.update_cache_and_database(
|
||||
db_file, directory_cache, xmpp_instance, jabber_id, node_type, node_id)
|
||||
if result == 'error':
|
||||
message = 'Blasta system message » {}.'.format(reason)
|
||||
message = f'Blasta system message » {reason}.'
|
||||
description = 'Directory "read" appears to be empty'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
|
@ -1626,7 +1650,7 @@ class HttpInstance:
|
|||
description = 'Search your own bookmarks'
|
||||
message = 'Search for bookmarks from your own directory.'
|
||||
else:
|
||||
description = 'Search bookmarks of {}'.format(jid)
|
||||
description = f'Search bookmarks of {jid}'
|
||||
message = 'Search for bookmarks of a given Jabber ID.'
|
||||
form_action = '/jid/' + jid
|
||||
input_id = input_name = label_for = 'q'
|
||||
|
@ -1712,7 +1736,7 @@ class HttpInstance:
|
|||
#if jabber_id == jid or node_type in ('private', 'read'):
|
||||
tag_list = DatabaseSQLite.get_500_tags_by_jid_sorted_by_name(db_file, jid)
|
||||
message = 'Common 500 tags sorted by name and sized by commonality.'
|
||||
description = 'Common tags of {}'.format(jid)
|
||||
description = f'Common tags of {jid}'
|
||||
template_file = 'tag.xhtml'
|
||||
template_dict = {
|
||||
'request' : request,
|
||||
|
@ -1734,7 +1758,7 @@ class HttpInstance:
|
|||
@self.app.get('/url/{url_hash}')
|
||||
async def url_hash_get(request: Request, url_hash):
|
||||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
node_id = 'hash:{}'.format(url_hash)
|
||||
node_id = f'hash:{url_hash}'
|
||||
param_hash = url_hash
|
||||
syndicate = path = 'url'
|
||||
entries = []
|
||||
|
@ -1753,7 +1777,7 @@ class HttpInstance:
|
|||
exist = True
|
||||
break
|
||||
else:
|
||||
message = 'XMPP system message » Error: {}.'.format(iq)
|
||||
message = f'XMPP system message » Error: {iq}.'
|
||||
description = 'The requested bookmark could not be retrieved'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
|
@ -1810,7 +1834,7 @@ class HttpInstance:
|
|||
'jid' : jid,
|
||||
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
||||
'instances' : instances})
|
||||
# message = 'XMPP system message » {}.'.format(iq)
|
||||
# message = f'XMPP system message » {iq}.'
|
||||
# if iq == 'Node not found':
|
||||
# description = 'An error has occurred'
|
||||
# else:
|
||||
|
@ -1853,7 +1877,7 @@ class HttpInstance:
|
|||
description = 'The requested bookmark does not exist'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
message = 'Information for URI {}'.format(entries[0]['link']) # entry[2]
|
||||
message = f'Information for URI {entries[0]["link"]}' # entry[2]
|
||||
if not instances: instances = 0
|
||||
if instances > 1:
|
||||
description = 'Discover new resources and see who shares them'
|
||||
|
@ -1904,7 +1928,7 @@ class HttpInstance:
|
|||
tags_old: str = Form(''),
|
||||
title: str = Form(...),
|
||||
url: str = Form(...)):
|
||||
node_id = 'hash:{}'.format(url_hash)
|
||||
node_id = f'hash:{url_hash}'
|
||||
param_hash = url_hash
|
||||
syndicate = path = 'url'
|
||||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
|
@ -1923,7 +1947,7 @@ class HttpInstance:
|
|||
'jid' : jabber_id,
|
||||
'name' : name,
|
||||
'instances' : instances or 1}
|
||||
message = 'Information for URL {}'.format(url)
|
||||
message = f'Information for URL {url}'
|
||||
description = 'Bookmark properties'
|
||||
xmpp_instance = accounts[jabber_id]
|
||||
payload = UtilitiesSyndication.create_rfc4287_entry(entry)
|
||||
|
@ -1938,29 +1962,29 @@ class HttpInstance:
|
|||
case 'private':
|
||||
print('Set item as private (XEP-0223)')
|
||||
#iq = await XmppPubsub.publish_node_item_private(
|
||||
# xmpp_instance, node_id_private, url_hash, iq)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_id_public, url_hash)
|
||||
# xmpp_instance, node_private_id, url_hash, iq)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_public_id, url_hash)
|
||||
UtilitiesData.remove_item_from_cache(directory_cache, jabber_id, 'public', url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_id_read, url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_read_id, url_hash)
|
||||
UtilitiesData.remove_item_from_cache(directory_cache, jabber_id, 'read', url_hash)
|
||||
case 'public':
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_id_private, url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_private_id, url_hash)
|
||||
UtilitiesData.remove_item_from_cache(directory_cache, jabber_id, 'private', url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_id_read, url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_read_id, url_hash)
|
||||
UtilitiesData.remove_item_from_cache(directory_cache, jabber_id, 'read', url_hash)
|
||||
case 'read':
|
||||
#iq = await XmppPubsub.publish_node_item_private(
|
||||
# xmpp_instance, node_id_read, url_hash, iq)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_id_public, url_hash)
|
||||
# xmpp_instance, node_read_id, url_hash, iq)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_public_id, url_hash)
|
||||
UtilitiesData.remove_item_from_cache(directory_cache, jabber_id, 'public', url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_id_private, url_hash)
|
||||
await XmppPubsub.del_node_item(xmpp_instance, jabber_id, node_private_id, url_hash)
|
||||
UtilitiesData.remove_item_from_cache(directory_cache, jabber_id, 'private', url_hash)
|
||||
if isinstance(iq, str):
|
||||
description = 'Could not save bookmark'
|
||||
message = 'XMPP system message » {}.'.format(iq)
|
||||
message = f'XMPP system message » {iq}.'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
#await iq.send(timeout=15)
|
||||
#await XmppIq.send(iq, 15)
|
||||
# Save changes to cache file
|
||||
entries_cache_filename = os.path.join(directory_cache, 'items', jabber_id + '.toml')
|
||||
entries_cache = UtilitiesData.open_file_toml(entries_cache_filename)
|
||||
|
@ -2055,7 +2079,7 @@ class HttpInstance:
|
|||
@self.app.get('/url/{url_hash}/confirm')
|
||||
async def url_hash_confirm_get(request: Request, url_hash):
|
||||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
node_id = 'hash:{}'.format(url_hash)
|
||||
node_id = f'hash:{url_hash}'
|
||||
param_hash = url_hash
|
||||
syndicate = path = 'url'
|
||||
if len(url_hash) == 32:
|
||||
|
@ -2073,7 +2097,7 @@ class HttpInstance:
|
|||
exist = True
|
||||
break
|
||||
else:
|
||||
message = 'XMPP system message » {}.'.format(iq)
|
||||
message = f'XMPP system message » {iq}.'
|
||||
if iq == 'Node not found':
|
||||
description = 'An error has occurred'
|
||||
else:
|
||||
|
@ -2093,7 +2117,7 @@ class HttpInstance:
|
|||
entry['published_mod'] = UtilitiesDate.convert_iso8601_to_readable(entry['published'])
|
||||
entries.append(entry)
|
||||
description = 'Confirm deletion of a bookmark'
|
||||
message = 'Details for bookmark {}'.format(entries[0]['link'])
|
||||
message = f'Details for bookmark {entries[0]["link"]}'
|
||||
template_file = 'browse.xhtml'
|
||||
template_dict = {
|
||||
'request' : request,
|
||||
|
@ -2127,7 +2151,7 @@ class HttpInstance:
|
|||
@self.app.get('/url/{url_hash}/delete')
|
||||
async def url_hash_delete_get(request: Request, url_hash):
|
||||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
node_id = 'hash:{}'.format(url_hash)
|
||||
node_id = f'hash:{url_hash}'
|
||||
param_hash = url_hash
|
||||
syndicate = path = 'url'
|
||||
if len(url_hash) == 32:
|
||||
|
@ -2145,7 +2169,7 @@ class HttpInstance:
|
|||
exist = True
|
||||
break
|
||||
else:
|
||||
message = 'XMPP system message » {}.'.format(iq)
|
||||
message = f'XMPP system message » {iq}.'
|
||||
if iq == 'Node not found':
|
||||
description = 'An error has occurred'
|
||||
else:
|
||||
|
@ -2168,7 +2192,7 @@ class HttpInstance:
|
|||
# Set a title
|
||||
description = 'A bookmark has been deleted'
|
||||
# Set a message
|
||||
message = 'Details for bookmark {}'.format(entry['link'])
|
||||
message = f'Details for bookmark {entry["link"]}'
|
||||
|
||||
# Create a link to restore bookmark
|
||||
link_save = ('/save?url=' + urllib.parse.quote(entry['link']) +
|
||||
|
@ -2222,7 +2246,7 @@ class HttpInstance:
|
|||
@self.app.post('/url/{url_hash}/edit')
|
||||
async def url_hash_edit_get(request: Request, url_hash):
|
||||
jabber_id = UtilitiesHttp.is_jid_matches_to_session(accounts, sessions, request)
|
||||
# node_id = 'hash:{}'.format(url_hash)
|
||||
# node_id = f'hash:{url_hash}'
|
||||
if len(url_hash) == 32:
|
||||
if jabber_id:
|
||||
xmpp_instance = accounts[jabber_id]
|
||||
|
@ -2241,7 +2265,7 @@ class HttpInstance:
|
|||
exist = True
|
||||
break
|
||||
else:
|
||||
message = 'XMPP system message » {}.'.format(iq)
|
||||
message = f'XMPP system message » {iq}.'
|
||||
if iq == 'Node not found':
|
||||
description = 'An error has occurred'
|
||||
else:
|
||||
|
@ -2281,7 +2305,7 @@ class HttpInstance:
|
|||
entry['name'] = name
|
||||
entry['url_hash'] = url_hash
|
||||
else:
|
||||
message = 'XMPP system message » {}.'.format(iq)
|
||||
message = f'XMPP system message » {iq}.'
|
||||
if iq == 'Node not found':
|
||||
description = 'An error has occurred'
|
||||
else:
|
||||
|
|
|
@ -6,8 +6,8 @@ from blasta.utilities.cryptography import UtilitiesCryptography
|
|||
from blasta.utilities.syndication import UtilitiesSyndication
|
||||
from blasta.xmpp.pubsub import XmppPubsub
|
||||
from datetime import datetime
|
||||
from lxml import etree
|
||||
import os
|
||||
import re
|
||||
from slixmpp.stanza.iq import Iq
|
||||
import time
|
||||
import tomli_w
|
||||
|
@ -116,8 +116,8 @@ class UtilitiesData:
|
|||
url_hash = UtilitiesCryptography.hash_url_to_md5(entry['link'])
|
||||
iq_item_id = iq_item['id']
|
||||
if iq_item_id != url_hash:
|
||||
logging.error('Item ID does not match MD5. id: {} hash: {}'.format(iq_item_id, url_hash))
|
||||
logging.warn('Item ID does not match MD5. id: {} hash: {}'.format(iq_item_id, url_hash))
|
||||
logging.error(f'Item ID does not match MD5. id: {iq_item_id} hash: {url_hash}')
|
||||
logging.warn(f'Item ID does not match MD5. id: {iq_item_id} hash: {url_hash}')
|
||||
instances = DatabaseSQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
||||
if entry:
|
||||
entry['instances'] = instances or 0
|
||||
|
@ -136,44 +136,53 @@ class UtilitiesData:
|
|||
def load_data_netscape(html: str) -> dict:
|
||||
bookmarks = []
|
||||
current_summary = ""
|
||||
parser = etree.XMLParser(recover=True)
|
||||
|
||||
lines = html.splitlines()
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line:
|
||||
# Parse given line
|
||||
root = etree.fromstring(line, parser)
|
||||
|
||||
# Check for <DT> tag
|
||||
if line.startswith("<DT>"):
|
||||
# Look for <A> tag within <DT>
|
||||
a_match = re.search(r'<A HREF="(.*?)" ADD_DATE="(.*?)" LAST_MODIFIED="(.*?)" PRIVATE="(.*?)" TAGS="(.*?)">(.*?)</A>', line)
|
||||
if a_match:
|
||||
link, published, updated, private, tags, title = a_match.groups()
|
||||
# Check for <DT> tag
|
||||
if line.startswith("<DT>"):
|
||||
# Look for <A> tag within <DT>
|
||||
a_element = root.find('.//A')
|
||||
if a_element is not None:
|
||||
link = a_element.get('HREF')
|
||||
add_date = a_element.get('ADD_DATE') or time.time()
|
||||
last_modified = a_element.get('LAST_MODIFIED') or time.time()
|
||||
tags = a_element.get('TAGS')
|
||||
title = a_element.text or link
|
||||
|
||||
# Convert timestamps from seconds since epoch to ISO format
|
||||
published_date = datetime.fromtimestamp(int(published)).isoformat()
|
||||
updated_date = datetime.fromtimestamp(int(updated)).isoformat()
|
||||
# Convert timestamps from seconds since epoch to ISO format
|
||||
added_date = datetime.fromtimestamp(float(add_date)).isoformat()
|
||||
modified_date = datetime.fromtimestamp(float(last_modified)).isoformat()
|
||||
|
||||
# Create bookmark dictionary
|
||||
bookmark = {
|
||||
'title': title,
|
||||
'link': link,
|
||||
'summary': current_summary,
|
||||
'published': published_date,
|
||||
'updated': updated_date,
|
||||
'tags': [tag.strip() for tag in tags.split(',')] if tags else []
|
||||
}
|
||||
# Create bookmark dictionary
|
||||
bookmark = {
|
||||
'title': title,
|
||||
'link': link,
|
||||
'summary': current_summary,
|
||||
'published': added_date,
|
||||
'updated': modified_date,
|
||||
'tags': [tag.strip() for tag in tags.split(',')] if tags else ['unclassified']
|
||||
}
|
||||
|
||||
# Append bookmark to the list
|
||||
bookmarks.append(bookmark)
|
||||
# Append bookmark to the list
|
||||
bookmarks.append(bookmark)
|
||||
|
||||
# Reset summary for the next bookmark
|
||||
current_summary = ""
|
||||
# Reset summary for the next bookmark
|
||||
current_summary = ""
|
||||
|
||||
# Check for <DD> tag
|
||||
elif line.startswith("<DD>"):
|
||||
# Extract summary from <DD>
|
||||
summary_match = re.search(r'<DD>(.*?)</DD>|<DD>(.*?)(?=s*<DT>|$)', line)
|
||||
if summary_match:
|
||||
bookmarks[len(bookmarks)-1]['summary'] = summary_match.group(2).strip()
|
||||
# Check for <DD> tag
|
||||
elif line.startswith("<DD>"):
|
||||
# Extract summary from <DD>
|
||||
bookmarks[len(bookmarks)-1]['summary'] = line[4:].strip()
|
||||
#dd_element = root.find('.//DD')
|
||||
#if dd_element:
|
||||
# bookmarks[len(bookmarks)-1]['summary'] = dd_element.text.strip()
|
||||
|
||||
return {'entries': bookmarks}
|
||||
|
||||
|
@ -195,16 +204,18 @@ class UtilitiesData:
|
|||
|
||||
def remove_item_from_cache(directory_cache, jabber_id, node, url_hash):
|
||||
filename_items = os.path.join(directory_cache, 'items', jabber_id + '.toml')
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
if node in entries_cache:
|
||||
entries_cache_node = entries_cache[node]
|
||||
for entry_cache in entries_cache_node:
|
||||
if entry_cache['url_hash'] == url_hash:
|
||||
entry_cache_index = entries_cache_node.index(entry_cache)
|
||||
del entries_cache_node[entry_cache_index]
|
||||
break
|
||||
data_items = entries_cache
|
||||
UtilitiesData.save_to_toml(filename_items, data_items)
|
||||
if os.path.exists(filename_items):
|
||||
#if os.path.exists(filename_items) and os.path.getsize(filename_items):
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
if node in entries_cache:
|
||||
entries_cache_node = entries_cache[node]
|
||||
for entry_cache in entries_cache_node:
|
||||
if entry_cache['url_hash'] == url_hash:
|
||||
entry_cache_index = entries_cache_node.index(entry_cache)
|
||||
del entries_cache_node[entry_cache_index]
|
||||
break
|
||||
data_items = entries_cache
|
||||
UtilitiesData.save_to_toml(filename_items, data_items)
|
||||
|
||||
def save_to_json(filename: str, data) -> None:
|
||||
with open(filename, 'w') as f:
|
||||
|
@ -244,7 +255,8 @@ class UtilitiesData:
|
|||
return ['error', iq]
|
||||
else:
|
||||
entries_cache = UtilitiesData.open_file_toml(filename_items)
|
||||
if not node_type in entries_cache: return ['error', 'Directory "{}" is empty'. format(node_type)]
|
||||
if not node_type in entries_cache:
|
||||
return ['error', f'Directory "{node_type}" is empty']
|
||||
entries_cache_node = entries_cache[node_type]
|
||||
|
||||
# Check whether items still exist on node
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
__version__ = '0.2'
|
||||
__version_info__ = (0, 2)
|
||||
__version__ = '0.3'
|
||||
__version_info__ = (0, 3)
|
||||
|
|
19
blasta/xmpp/iq.py
Normal file
19
blasta/xmpp/iq.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from slixmpp.exceptions import IqError, IqTimeout
|
||||
|
||||
class XmppIq:
|
||||
|
||||
async def send(iq, timeout):
|
||||
try:
|
||||
await iq.send(timeout=timeout)
|
||||
except IqError as e:
|
||||
raise Exception('IQ Error!')
|
||||
print(str(e))
|
||||
except IqTimeout as e:
|
||||
raise Exception('IQ Timeout!')
|
||||
print(str(e))
|
||||
except Exception as e:
|
||||
raise Exception('Error!')
|
||||
print(str(e))
|
|
@ -29,7 +29,7 @@ class XmppPubsub:
|
|||
value=subtitle)
|
||||
form.addField('pubsub#max_items',
|
||||
ftype='text-single',
|
||||
value='255')
|
||||
value=255)
|
||||
form.addField('pubsub#notify_retract',
|
||||
ftype='boolean',
|
||||
value=1)
|
||||
|
@ -47,12 +47,12 @@ class XmppPubsub:
|
|||
value='http://www.w3.org/2005/Atom')
|
||||
return iq
|
||||
|
||||
def create_node_config(xmpp_instance, jid):
|
||||
def create_node_config(xmpp_instance, jid, node_settings_id):
|
||||
jid_from = str(xmpp_instance.boundjid) if xmpp_instance.is_component else None
|
||||
iq = xmpp_instance.Iq(stype='set',
|
||||
sto=jid,
|
||||
sfrom=jid_from)
|
||||
iq['pubsub']['create']['node'] = 'xmpp:blasta:configuration:0'
|
||||
iq['pubsub']['create']['node'] = node_settings_id
|
||||
form = iq['pubsub']['configure']['form']
|
||||
form['type'] = 'submit'
|
||||
form.addField('pubsub#access_model',
|
||||
|
@ -63,7 +63,7 @@ class XmppPubsub:
|
|||
value=0)
|
||||
form.addField('pubsub#description',
|
||||
ftype='text-single',
|
||||
value='Settings of the Blasta PubSub bookmarks system')
|
||||
value='Settings of the Blasta PubSub annotation system')
|
||||
form.addField('pubsub#max_items',
|
||||
ftype='text-single',
|
||||
value='30')
|
||||
|
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "Blasta"
|
||||
version = "0.2"
|
||||
version = "0.3"
|
||||
description = "A collaborative annotation management system for XMPP"
|
||||
authors = [{name = "Schimon Zachary", email = "sch@fedora.email"}]
|
||||
license = {text = "AGPL-3.0"}
|
||||
|
|
Loading…
Reference in a new issue