Add commands for PubSub.

Improve joining to MUC (WIP).
Improve PubSub (WIP).
This commit is contained in:
Schimon Jehudah 2024-03-27 16:20:32 +00:00
parent 5f946fe0b6
commit d6eec41a86
8 changed files with 199 additions and 70 deletions

View file

@ -49,6 +49,7 @@ from slixfeed.url import (
) )
import slixfeed.task as task import slixfeed.task as task
from slixfeed.xmpp.bookmark import XmppBookmark from slixfeed.xmpp.bookmark import XmppBookmark
from slixfeed.xmpp.muc import XmppGroupchat
from slixfeed.xmpp.iq import XmppIQ from slixfeed.xmpp.iq import XmppIQ
from slixfeed.xmpp.message import XmppMessage from slixfeed.xmpp.message import XmppMessage
from slixfeed.xmpp.presence import XmppPresence from slixfeed.xmpp.presence import XmppPresence
@ -116,6 +117,28 @@ def export_feeds(self, jid, jid_file, ext):
return filename return filename
async def xmpp_muc_autojoin(self, bookmarks):
for bookmark in bookmarks:
if bookmark["jid"] and bookmark["autojoin"]:
if not bookmark["nick"]:
bookmark["nick"] = self.alias
logger.error('Alias (i.e. Nicknname) is missing for '
'bookmark {}'.format(bookmark['name']))
alias = bookmark["nick"]
muc_jid = bookmark["jid"]
await XmppGroupchat.join(self, muc_jid, alias)
logger.info('Autojoin groupchat\n'
'Name : {}\n'
'JID : {}\n'
'Alias : {}\n'
.format(bookmark["name"],
bookmark["jid"],
bookmark["nick"]))
elif not bookmark["jid"]:
logger.error('JID is missing for bookmark {}'
.format(bookmark['name']))
""" """
TODO TODO
@ -192,18 +215,25 @@ async def xmpp_send_status_message(self, jid):
# ) # )
async def xmpp_send_pubsub(self, jid_bare): async def xmpp_send_pubsub(self, jid_bare, num=None):
function_name = sys._getframe().f_code.co_name function_name = sys._getframe().f_code.co_name
logger.debug('{}: jid_bare: {}'.format(function_name, jid_bare)) logger.debug('{}: jid_bare: {}'.format(function_name, jid_bare))
jid_file = jid_bare.replace('/', '_') jid_file = jid_bare.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
enabled = Config.get_setting_value(self.settings, jid_bare, 'enabled') enabled = Config.get_setting_value(self.settings, jid_bare, 'enabled')
if enabled: if enabled:
if num: counter = 0
report = {}
subscriptions = sqlite.get_active_feeds_url(db_file) subscriptions = sqlite.get_active_feeds_url(db_file)
for url in subscriptions: for url in subscriptions:
url = url[0] url = url[0]
feed_id = sqlite.get_feed_id(db_file, url) feed_id = sqlite.get_feed_id(db_file, url)
feed_id = feed_id[0] feed_id = feed_id[0]
feed_title = None
feed_summary = None
if jid_bare == self.boundjid.bare:
node = 'urn:xmpp:microblog:0'
else:
feed_title = sqlite.get_feed_title(db_file, feed_id) feed_title = sqlite.get_feed_title(db_file, feed_id)
feed_title = feed_title[0] feed_title = feed_title[0]
feed_summary = None feed_summary = None
@ -216,13 +246,17 @@ async def xmpp_send_pubsub(self, jid_bare):
entries = sqlite.get_unread_entries_of_feed(db_file, feed_id) entries = sqlite.get_unread_entries_of_feed(db_file, feed_id)
feed_properties = sqlite.get_feed_properties(db_file, feed_id) feed_properties = sqlite.get_feed_properties(db_file, feed_id)
feed_version = feed_properties[2] feed_version = feed_properties[2]
print('xmpp_send_pubsub',jid_bare)
print(node)
# if num and counter < num:
report[url] = len(entries)
for entry in entries: for entry in entries:
feed_entry = {'author' : None, feed_entry = {'author' : None,
'authors' : None, 'authors' : None,
'category' : None, 'category' : None,
'content' : None, 'content' : None,
'description' : entry[3], 'description' : entry[3],
'href' : entry[2], 'link' : entry[2],
'links' : entry[4], 'links' : entry[4],
'tags' : None, 'tags' : None,
'title' : entry[1], 'title' : entry[1],
@ -233,6 +267,9 @@ async def xmpp_send_pubsub(self, jid_bare):
await XmppIQ.send(self, iq_create_entry) await XmppIQ.send(self, iq_create_entry)
ix = entry[0] ix = entry[0]
await sqlite.mark_as_read(db_file, ix) await sqlite.mark_as_read(db_file, ix)
# counter += 1
# if num and counter > num: break
return report
async def xmpp_send_message(self, jid, num=None): async def xmpp_send_message(self, jid, num=None):

View file

@ -152,10 +152,6 @@ async def start_tasks_xmpp_pubsub(self, jid_bare, tasks=None):
.format(task, jid_bare)) .format(task, jid_bare))
logging.info('Starting tasks {} for JID {}'.format(tasks, jid_bare)) logging.info('Starting tasks {} for JID {}'.format(tasks, jid_bare))
for task in tasks: for task in tasks:
# print("task:", task)
# print("tasks:")
# print(tasks)
# breakpoint()
match task: match task:
case 'publish': case 'publish':
self.task_manager[jid_bare]['publish'] = asyncio.create_task( self.task_manager[jid_bare]['publish'] = asyncio.create_task(

View file

@ -1,2 +1,2 @@
__version__ = '0.1.50' __version__ = '0.1.51'
__version_info__ = (0, 1, 50) __version_info__ = (0, 1, 51)

View file

@ -214,10 +214,9 @@ class Slixfeed(slixmpp.ClientXMPP):
function_name = sys._getframe().f_code.co_name function_name = sys._getframe().f_code.co_name
message_log = '{}: jid_full: {}' message_log = '{}: jid_full: {}'
logger.debug(message_log.format(function_name, jid_full)) logger.debug(message_log.format(function_name, jid_full))
inviter = message['from'].bare
muc_jid = message['groupchat_invite']['jid'] muc_jid = message['groupchat_invite']['jid']
await XmppBookmark.add(self, muc_jid) await XmppBookmark.add(self, muc_jid)
await XmppGroupchat.join(self, inviter, muc_jid) await XmppGroupchat.join(self, muc_jid)
message_body = ('Greetings! I am {}, the news anchor.\n' message_body = ('Greetings! I am {}, the news anchor.\n'
'My job is to bring you the latest ' 'My job is to bring you the latest '
'news from sources you provide me with.\n' 'news from sources you provide me with.\n'
@ -237,10 +236,9 @@ class Slixfeed(slixmpp.ClientXMPP):
function_name = sys._getframe().f_code.co_name function_name = sys._getframe().f_code.co_name
message_log = '{}: jid_full: {}' message_log = '{}: jid_full: {}'
logger.debug(message_log.format(function_name, jid_full)) logger.debug(message_log.format(function_name, jid_full))
inviter = message['from'].bare
muc_jid = message['groupchat_invite']['jid'] muc_jid = message['groupchat_invite']['jid']
await XmppBookmark.add(self, muc_jid) await XmppBookmark.add(self, muc_jid)
await XmppGroupchat.join(self, inviter, muc_jid) await XmppGroupchat.join(self, muc_jid)
message_body = ('Greetings! I am {}, the news anchor.\n' message_body = ('Greetings! I am {}, the news anchor.\n'
'My job is to bring you the latest ' 'My job is to bring you the latest '
'news from sources you provide me with.\n' 'news from sources you provide me with.\n'
@ -285,9 +283,10 @@ class Slixfeed(slixmpp.ClientXMPP):
await self['xep_0115'].update_caps() await self['xep_0115'].update_caps()
# self.send_presence() # self.send_presence()
await self.get_roster() await self.get_roster()
bookmarks = await self.plugin['xep_0048'].get_bookmarks() bookmarks = await XmppBookmark.get(self)
await XmppGroupchat.autojoin(self, bookmarks) await action.xmpp_muc_autojoin(self, bookmarks)
jids = await XmppPubsub.get_pubsub_services(self) jids = await XmppPubsub.get_pubsub_services(self)
print(jids)
for jid_bare in jids: for jid_bare in jids:
if jid_bare not in self.settings: if jid_bare not in self.settings:
jid_file = jid_bare jid_file = jid_bare
@ -311,8 +310,8 @@ class Slixfeed(slixmpp.ClientXMPP):
# self.send_presence() # self.send_presence()
profile.set_identity(self, 'client') profile.set_identity(self, 'client')
self['xep_0115'].update_caps() self['xep_0115'].update_caps()
bookmarks = await self.plugin['xep_0048'].get_bookmarks() bookmarks = await XmppBookmark.get(self)
await XmppGroupchat.autojoin(self, bookmarks) await action.xmpp_muc_autojoin(self, bookmarks)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{} (time: {})'.format(function_name, if difference > 1: logger.warning('{} (time: {})'.format(function_name,
@ -782,7 +781,7 @@ class Slixfeed(slixmpp.ClientXMPP):
form['instructions'] = ('Choose a PubSub Jabber ID and verify ' form['instructions'] = ('Choose a PubSub Jabber ID and verify '
'that Slixfeed has the necessary ' 'that Slixfeed has the necessary '
'permissions to publish into it.') 'permissions to publish into it.')
form.add_field(var='subscription', form.add_field(var='url',
# TODO Make it possible to add several subscriptions at once; # TODO Make it possible to add several subscriptions at once;
# Similarly to BitTorrent trackers list # Similarly to BitTorrent trackers list
# ftype='text-multi', # ftype='text-multi',
@ -833,7 +832,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# options.addOption('XEP-0060: Publish-Subscribe', '0060') # options.addOption('XEP-0060: Publish-Subscribe', '0060')
# options.addOption('XEP-0277: Microblogging over XMPP', '0277') # options.addOption('XEP-0277: Microblogging over XMPP', '0277')
# options.addOption('XEP-0472: Pubsub Social Feed', '0472') # options.addOption('XEP-0472: Pubsub Social Feed', '0472')
session['next'] = self._handle_subscription_new session['next'] = self._handle_preview
session['payload'] = form session['payload'] = form
case 'post': case 'post':
form = self['xep_0004'].make_form('form', 'Post') form = self['xep_0004'].make_form('form', 'Post')
@ -912,7 +911,7 @@ class Slixfeed(slixmpp.ClientXMPP):
return session return session
node = values['node'] node = values['node']
url = values['url'] url = values['url']
xep = values['xep'] # xep = values['xep']
if not node: if not node:
if jid == self.boundjid.bare: if jid == self.boundjid.bare:
node = 'urn:xmpp:microblog:0' node = 'urn:xmpp:microblog:0'
@ -958,6 +957,7 @@ class Slixfeed(slixmpp.ClientXMPP):
session['allow_prev'] = True session['allow_prev'] = True
session['has_next'] = True session['has_next'] = True
session['next'] = self._handle_post_complete session['next'] = self._handle_post_complete
session['notes'] = None
session['prev'] = self._handle_publish session['prev'] = self._handle_publish
session['payload'] = form session['payload'] = form
break break
@ -981,6 +981,7 @@ class Slixfeed(slixmpp.ClientXMPP):
session['allow_prev'] = True session['allow_prev'] = True
session['has_next'] = True session['has_next'] = True
session['next'] = self._handle_preview session['next'] = self._handle_preview
session['notes'] = None
session['prev'] = self._handle_publish session['prev'] = self._handle_publish
session['payload'] = form session['payload'] = form
break break
@ -1006,9 +1007,9 @@ class Slixfeed(slixmpp.ClientXMPP):
form.add_field(var='url', form.add_field(var='url',
ftype='hidden', ftype='hidden',
value=url) value=url)
form.add_field(var='xep', # form.add_field(var='xep',
ftype='hidden', # ftype='hidden',
value=xep) # value=xep)
return session return session
async def _handle_post_complete(self, payload, session): async def _handle_post_complete(self, payload, session):
@ -1021,7 +1022,8 @@ class Slixfeed(slixmpp.ClientXMPP):
node = values['node'][0] node = values['node'][0]
jid = values['jid'][0] jid = values['jid'][0]
url = values['url'][0] url = values['url'][0]
xep = values['xep'][0] # xep = values['xep'][0]
xep = None
result = await fetch.http(url) result = await fetch.http(url)
if 'content' in result: if 'content' in result:
document = result['content'] document = result['content']
@ -1054,7 +1056,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# title = "*** No title ***" # title = "*** No title ***"
# if feed.entries[entry].has_key("summary"): # if feed.entries[entry].has_key("summary"):
# summary = feed.entries[entry].summary # summary = feed.entries[entry].summary
iq_create_entry = XmppPubsub.create_entry( iq_create_entry = XmppPubsub._create_entry(
self, jid, node, feed_entry, feed_version) self, jid, node, feed_entry, feed_version)
await XmppIQ.send(self, iq_create_entry) await XmppIQ.send(self, iq_create_entry)
text_info = 'Posted {} entries.'.format(len(entries)) text_info = 'Posted {} entries.'.format(len(entries))

View file

@ -743,7 +743,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
form['instructions'] = ('Choose a PubSub Jabber ID and verify ' form['instructions'] = ('Choose a PubSub Jabber ID and verify '
'that Slixfeed has the necessary ' 'that Slixfeed has the necessary '
'permissions to publish into it.') 'permissions to publish into it.')
form.add_field(var='subscription', form.add_field(var='url',
# TODO Make it possible to add several subscriptions at once; # TODO Make it possible to add several subscriptions at once;
# Similarly to BitTorrent trackers list # Similarly to BitTorrent trackers list
# ftype='text-multi', # ftype='text-multi',
@ -794,7 +794,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
# options.addOption('XEP-0060: Publish-Subscribe', '0060') # options.addOption('XEP-0060: Publish-Subscribe', '0060')
# options.addOption('XEP-0277: Microblogging over XMPP', '0277') # options.addOption('XEP-0277: Microblogging over XMPP', '0277')
# options.addOption('XEP-0472: Pubsub Social Feed', '0472') # options.addOption('XEP-0472: Pubsub Social Feed', '0472')
session['next'] = self._handle_subscription_new session['next'] = self._handle_preview
session['payload'] = form session['payload'] = form
case 'post': case 'post':
form = self['xep_0004'].make_form('form', 'Post') form = self['xep_0004'].make_form('form', 'Post')
@ -873,7 +873,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
return session return session
node = values['node'] node = values['node']
url = values['url'] url = values['url']
xep = values['xep'] # xep = values['xep']
if not node: if not node:
if jid == self.boundjid.bare: if jid == self.boundjid.bare:
node = 'urn:xmpp:microblog:0' node = 'urn:xmpp:microblog:0'
@ -919,6 +919,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
session['allow_prev'] = True session['allow_prev'] = True
session['has_next'] = True session['has_next'] = True
session['next'] = self._handle_post_complete session['next'] = self._handle_post_complete
session['notes'] = None
session['prev'] = self._handle_publish session['prev'] = self._handle_publish
session['payload'] = form session['payload'] = form
break break
@ -942,6 +943,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
session['allow_prev'] = True session['allow_prev'] = True
session['has_next'] = True session['has_next'] = True
session['next'] = self._handle_preview session['next'] = self._handle_preview
session['notes'] = None
session['prev'] = self._handle_publish session['prev'] = self._handle_publish
session['payload'] = form session['payload'] = form
break break
@ -967,9 +969,9 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
form.add_field(var='url', form.add_field(var='url',
ftype='hidden', ftype='hidden',
value=url) value=url)
form.add_field(var='xep', # form.add_field(var='xep',
ftype='hidden', # ftype='hidden',
value=xep) # value=xep)
return session return session
async def _handle_post_complete(self, payload, session): async def _handle_post_complete(self, payload, session):
@ -982,7 +984,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
node = values['node'][0] node = values['node'][0]
jid = values['jid'][0] jid = values['jid'][0]
url = values['url'][0] url = values['url'][0]
xep = values['xep'][0] # xep = values['xep'][0]
xep = None
result = await fetch.http(url) result = await fetch.http(url)
if 'content' in result: if 'content' in result:
document = result['content'] document = result['content']
@ -1015,7 +1018,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
# title = "*** No title ***" # title = "*** No title ***"
# if feed.entries[entry].has_key("summary"): # if feed.entries[entry].has_key("summary"):
# summary = feed.entries[entry].summary # summary = feed.entries[entry].summary
iq_create_entry = XmppPubsub.create_entry( iq_create_entry = XmppPubsub._create_entry(
self, jid, node, feed_entry, feed_version) self, jid, node, feed_entry, feed_version)
await XmppIQ.send(self, iq_create_entry) await XmppIQ.send(self, iq_create_entry)
text_info = 'Posted {} entries.'.format(len(entries)) text_info = 'Posted {} entries.'.format(len(entries))

View file

@ -34,32 +34,7 @@ class XmppGroupchat:
self.join(self, inviter, jid) self.join(self, inviter, jid)
async def autojoin(self, bookmarks): async def join(self, jid, alias=None, password=None):
jid_from = str(self.boundjid) if self.is_component else None
conferences = bookmarks["private"]["bookmarks"]["conferences"]
for conference in conferences:
if conference["jid"] and conference["autojoin"]:
if not conference["nick"]:
conference["nick"] = self.alias
logging.error('Alias (i.e. Nicknname) is missing for '
'bookmark {}'.format(conference['name']))
await self.plugin['xep_0045'].join_muc_wait(conference["jid"],
conference["nick"],
presence_options = {"pfrom" : jid_from},
password=None)
logging.info('Autojoin groupchat\n'
'Name : {}\n'
'JID : {}\n'
'Alias : {}\n'
.format(conference["name"],
conference["jid"],
conference["nick"]))
elif not conference["jid"]:
logging.error('JID is missing for bookmark {}'
.format(conference['name']))
async def join(self, inviter, jid):
# token = await initdb( # token = await initdb(
# muc_jid, # muc_jid,
# sqlite.get_setting_value, # sqlite.get_setting_value,
@ -81,13 +56,13 @@ class XmppGroupchat:
# ) # )
logging.info('Joining groupchat\n' logging.info('Joining groupchat\n'
'JID : {}\n' 'JID : {}\n'
'Inviter : {}\n' .format(jid))
.format(jid, inviter))
jid_from = str(self.boundjid) if self.is_component else None jid_from = str(self.boundjid) if self.is_component else None
if alias == None: self.alias
await self.plugin['xep_0045'].join_muc_wait(jid, await self.plugin['xep_0045'].join_muc_wait(jid,
self.alias, alias,
presence_options = {"pfrom" : jid_from}, presence_options = {"pfrom" : jid_from},
password=None) password=password)
def leave(self, jid): def leave(self, jid):

View file

@ -897,7 +897,7 @@ async def message(self, message):
muc_jid = uri.check_xmpp_uri(message_text[5:]) muc_jid = uri.check_xmpp_uri(message_text[5:])
if muc_jid: if muc_jid:
# TODO probe JID and confirm it's a groupchat # TODO probe JID and confirm it's a groupchat
XmppGroupchat.join(self, jid_bare, muc_jid) XmppGroupchat.join(self, muc_jid)
# await XmppBookmark.add(self, jid=muc_jid) # await XmppBookmark.add(self, jid=muc_jid)
response = ('Joined groupchat {}' response = ('Joined groupchat {}'
.format(message_text)) .format(message_text))
@ -981,6 +981,60 @@ async def message(self, message):
db_file, key, val) db_file, key, val)
response = 'Only new items of newly added feeds be delivered.' response = 'Only new items of newly added feeds be delivered.'
XmppMessage.send_reply(self, message, response) XmppMessage.send_reply(self, message, response)
case _ if message_lowercase.startswith('pubsub delete '):
if is_operator(self, jid_bare):
info = message_text[14:]
info = info.split(' ')
jid = info[0]
nid = info[1]
if jid:
from slixfeed.xmpp.publish import XmppPubsub
XmppPubsub.delete_node(self, jid, nid)
response = 'Deleted node: ' + nid
else:
response = 'PubSub JID is missing. Enter PubSub JID.'
else:
response = ('This action is restricted. '
'Type: sending news to PubSub.')
XmppMessage.send_reply(self, message, response)
case _ if message_lowercase.startswith('pubsub purge '):
if is_operator(self, jid_bare):
info = message_text[13:]
info = info.split(' ')
jid = info[0]
nid = info[1]
if jid:
from slixfeed.xmpp.publish import XmppPubsub
XmppPubsub.purge_node(self, jid, nid)
response = 'Purged node: ' + nid
else:
response = 'PubSub JID is missing. Enter PubSub JID.'
else:
response = ('This action is restricted. '
'Type: sending news to PubSub.')
XmppMessage.send_reply(self, message, response)
case _ if message_lowercase.startswith('pubsub flash '):
if is_operator(self, jid_bare):
info = message_text[13:]
info = info.split(' ')
jid = info[0]
num = int(info[1])
if jid:
if num:
report = await action.xmpp_send_pubsub(self, jid,
num)
else:
report = await action.xmpp_send_pubsub(self, jid)
response = ''
for url in report:
if report[url]:
response += url + ' : ' + str(report[url]) + '\n'
else:
response = 'PubSub JID is missing. Enter PubSub JID.'
else:
response = ('This action is restricted. '
'Type: sending news to PubSub.')
XmppMessage.send_reply(self, message, response)
case _ if message_lowercase.startswith('next'): case _ if message_lowercase.startswith('next'):
num = message_text[5:] num = message_text[5:]
if num: if num:
@ -1398,7 +1452,7 @@ async def message(self, message):
muc_jid = uri.check_xmpp_uri(message_text) muc_jid = uri.check_xmpp_uri(message_text)
if muc_jid: if muc_jid:
# TODO probe JID and confirm it's a groupchat # TODO probe JID and confirm it's a groupchat
XmppGroupchat.join(self, jid_bare, muc_jid) XmppGroupchat.join(self, muc_jid)
# await XmppBookmark.add(self, jid=muc_jid) # await XmppBookmark.add(self, jid=muc_jid)
response = ('Joined groupchat {}' response = ('Joined groupchat {}'
.format(message_text)) .format(message_text))

View file

@ -28,8 +28,23 @@ class XmppPubsub:
return jids return jids
def delete_node(self, jid, node):
jid_from = str(self.boundjid) if self.is_component else None
self.plugin['xep_0060'].delete_node(jid, node, ifrom=jid_from)
def purge_node(self, jid, node):
jid_from = str(self.boundjid) if self.is_component else None
self.plugin['xep_0060'].purge(jid, node, ifrom=jid_from)
# iq = self.Iq(stype='set',
# sto=jid,
# sfrom=jid_from)
# iq['pubsub']['purge']['node'] = node
# return iq
# TODO Make use of var "xep" with match/case (XEP-0060, XEP-0277, XEP-0472) # TODO Make use of var "xep" with match/case (XEP-0060, XEP-0277, XEP-0472)
def create_node(self, jid, node, xep ,title, summary=None): def create_node(self, jid, node, xep ,title=None, summary=None):
jid_from = str(self.boundjid) if self.is_component else None jid_from = str(self.boundjid) if self.is_component else None
iq = self.Iq(stype='set', iq = self.Iq(stype='set',
sto=jid, sto=jid,
@ -85,7 +100,7 @@ class XmppPubsub:
# NOTE Warning: Entry might not have a link # NOTE Warning: Entry might not have a link
# TODO Handle situation error # TODO Handle situation error
url_encoded = entry.link.encode() url_encoded = entry['link'].encode()
url_hashed = hashlib.md5(url_encoded) url_hashed = hashlib.md5(url_encoded)
url_digest = url_hashed.hexdigest() url_digest = url_hashed.hexdigest()
item['id'] = url_digest item['id'] = url_digest
@ -99,6 +114,53 @@ class XmppPubsub:
updated = ET.SubElement(node_entry, "updated") updated = ET.SubElement(node_entry, "updated")
updated.text = entry['updated'] updated.text = entry['updated']
# Content
content = ET.SubElement(node_entry, "content")
content.set('type', 'text/html')
content.text = entry['description']
# Links
link = ET.SubElement(node_entry, "link")
link.set('href', entry['link'])
item['payload'] = node_entry
iq['pubsub']['publish'].append(item)
return iq
def _create_entry(self, jid, node, entry, version):
iq = self.Iq(stype="set", sto=jid)
iq['pubsub']['publish']['node'] = node
item = pubsub.Item()
# From atomtopubsub:
# character / is causing a bug in movim. replacing : and , with - in id.
# It provides nicer urls.
# Respond to atomtopubsub:
# I think it would be beneficial to use md5 checksum of Url as Id for
# cross reference, and namely - in another project to utilize PubSub as
# links sharing system (see del.icio.us) - to share node entries.
# NOTE Warning: Entry might not have a link
# TODO Handle situation error
url_encoded = entry.link.encode()
url_hashed = hashlib.md5(url_encoded)
url_digest = url_hashed.hexdigest()
item['id'] = url_digest + '_html'
node_entry = ET.Element("entry")
node_entry.set('xmlns', 'http://www.w3.org/2005/Atom')
title = ET.SubElement(node_entry, "title")
title.text = entry.title
updated = ET.SubElement(node_entry, "updated")
updated.text = entry.updated
# Content # Content
if version == 'atom3': if version == 'atom3':