Add MUC support including bookmarks and improve filtering

This commit is contained in:
Schimon Jehudah 2023-11-27 17:22:56 +00:00
parent 071bf78e1d
commit 634b0e3ce6
5 changed files with 193 additions and 31 deletions

View file

@ -115,8 +115,9 @@ if __name__ == '__main__':
xmpp.register_plugin('xep_0045') # Multi-User Chat xmpp.register_plugin('xep_0045') # Multi-User Chat
xmpp.register_plugin('xep_0048') # Bookmarks xmpp.register_plugin('xep_0048') # Bookmarks
xmpp.register_plugin('xep_0060') # PubSub xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping xmpp.register_plugin('xep_0199', {'keepalive': True, 'frequency': 15}) # XMPP Ping
xmpp.register_plugin('xep_0249') # Multi-User Chat xmpp.register_plugin('xep_0249') # Multi-User Chat
xmpp.register_plugin('xep_0402') # PEP Native Bookmarks
# Connect to the XMPP server and start processing XMPP stanzas. # Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect() xmpp.connect()

View file

@ -18,7 +18,7 @@ TODO
import sqlitehandler import sqlitehandler
async def set_list(newwords, keywords): async def add_to_list(newwords, keywords):
""" """
Append new keywords to list. Append new keywords to list.
@ -48,6 +48,36 @@ async def set_list(newwords, keywords):
return val return val
async def remove_from_list(newwords, keywords):
"""
Remove given keywords from list.
Parameters
----------
newwords : str
List of new keywords.
keywords : str
List of current keywords.
Returns
-------
val : str
List of new keywords.
"""
try:
keywords = keywords.split(",")
except:
keywords = []
newwords = newwords.lower().split(",")
for word in newwords:
word = word.strip()
if len(word) and word in keywords:
keywords.remove(word)
keywords.sort()
val = ",".join(keywords)
return val
async def is_listed(db_file, key, string): async def is_listed(db_file, key, string):
""" """
Check keyword match. Check keyword match.

View file

@ -1128,15 +1128,21 @@ async def last_entries(db_file, num):
"LIMIT :num " "LIMIT :num "
) )
results = cur.execute(sql, (num,)) results = cur.execute(sql, (num,))
titles_list = "Recent {} titles:\n".format(num) titles_list = "Recent {} titles:\n```".format(num)
counter = 0
for result in results: for result in results:
counter += 1
titles_list += ( titles_list += (
"\n{}\n{}\n" "\n{}\n{}\n"
).format( ).format(
str(result[0]), str(result[0]),
str(result[1]) str(result[1])
) )
if counter:
titles_list += "```\n"
return titles_list return titles_list
else:
return "There are no news at the moment."
async def search_feeds(db_file, query): async def search_feeds(db_file, query):
@ -1185,7 +1191,7 @@ async def search_feeds(db_file, query):
if counter: if counter:
return results_list + "\n```\nTotal of {} feeds".format(counter) return results_list + "\n```\nTotal of {} feeds".format(counter)
else: else:
return "No feeds found for: {}".format(query) return "No feeds were found for: {}".format(query)
async def search_entries(db_file, query): async def search_entries(db_file, query):
@ -1234,7 +1240,7 @@ async def search_entries(db_file, query):
if counter: if counter:
return results_list + "```\nTotal of {} results".format(counter) return results_list + "```\nTotal of {} results".format(counter)
else: else:
return "No results found for: {}".format(query) return "No results were found for: {}".format(query)
""" """
FIXME Error due to missing date, but it appears that date is present: FIXME Error due to missing date, but it appears that date is present:

View file

@ -282,7 +282,7 @@ async def send_status(self, jid):
if unread: if unread:
status_mode = "chat" status_mode = "chat"
status_text = ( status_text = (
"📬️ You have {} news items" "📬️ There are {} news items"
).format(str(unread)) ).format(str(unread))
# status_text = ( # status_text = (
# "📰 News items: {}" # "📰 News items: {}"

View file

@ -56,6 +56,8 @@ import slixmpp
from random import randrange from random import randrange
from slixmpp.plugins.xep_0363.http_upload import FileTooBig, HTTPError, UploadServiceNotFound from slixmpp.plugins.xep_0363.http_upload import FileTooBig, HTTPError, UploadServiceNotFound
# from slixmpp.plugins.xep_0402 import BookmarkStorage, Conference
from slixmpp.plugins.xep_0048.stanza import Bookmarks
import datahandler import datahandler
import datetimehandler import datetimehandler
@ -64,6 +66,10 @@ import listhandler
import sqlitehandler import sqlitehandler
import taskhandler import taskhandler
import xmltodict
import xml.etree.ElementTree as ET
from lxml import etree
main_task = [] main_task = []
jid_tasker = {} jid_tasker = {}
task_manager = {} task_manager = {}
@ -96,6 +102,8 @@ class Slixfeed(slixmpp.ClientXMPP):
# our roster. # our roster.
self.add_event_handler("session_start", self.start_session) self.add_event_handler("session_start", self.start_session)
self.add_event_handler("session_resumed", self.start_session) self.add_event_handler("session_resumed", self.start_session)
self.add_event_handler("session_start", self.autojoin_muc)
self.add_event_handler("session_resumed", self.autojoin_muc)
self.add_event_handler("got_offline", print("got_offline")) self.add_event_handler("got_offline", print("got_offline"))
# self.add_event_handler("got_online", self.check_readiness) # self.add_event_handler("got_online", self.check_readiness)
self.add_event_handler("changed_status", self.check_readiness) self.add_event_handler("changed_status", self.check_readiness)
@ -238,18 +246,73 @@ class Slixfeed(slixmpp.ClientXMPP):
# If a room password is needed, use: # If a room password is needed, use:
# password=the_room_password, # password=the_room_password,
) )
# self.add_event_handler(
# "muc::[room]::message",
# self.message
# )
# await self.get_bookmarks() result = await self.plugin['xep_0048'].get_bookmarks()
# bookmark = self.plugin['xep_0048'].instantiate_pep() bookmarks = result["private"]["bookmarks"]
# print(bookmark) conferences = bookmarks["conferences"]
# nick = "Slixfeed (RSS News Bot)" mucs = []
# bookmark.add_bookmark(muc_jid, nick=nick) for conference in conferences:
# await self['xep_0048'].set_bookmarks(bookmark) jid = conference["jid"]
# print(bookmark) mucs.extend([jid])
if muc_jid not in mucs:
bookmarks = Bookmarks()
mucs.extend([muc_jid])
for muc in mucs:
bookmarks.add_conference(
muc,
"Slixfeed (RSS News Bot)",
autojoin=True
)
await self.plugin['xep_0048'].set_bookmarks(bookmarks)
# bookmarks = Bookmarks()
# await self.plugin['xep_0048'].set_bookmarks(bookmarks)
# print(await self.plugin['xep_0048'].get_bookmarks())
# bm = BookmarkStorage()
# bm.conferences.append(Conference(muc_jid, autojoin=True, nick="Slixfeed (RSS News Bot)"))
# await self['xep_0402'].publish(bm)
async def remove_and_leave_muc(self, muc_jid):
result = await self.plugin['xep_0048'].get_bookmarks()
bookmarks = result["private"]["bookmarks"]
conferences = bookmarks["conferences"]
mucs = []
for conference in conferences:
jid = conference["jid"]
mucs.extend([jid])
if muc_jid in mucs:
bookmarks = Bookmarks()
mucs.remove(muc_jid)
for muc in mucs:
bookmarks.add_conference(
muc,
"Slixfeed (RSS News Bot)",
autojoin=True
)
await self.plugin['xep_0048'].set_bookmarks(bookmarks)
self.plugin['xep_0045'].leave_muc(
muc_jid,
"Slixfeed (RSS News Bot)",
"Goodbye!",
self.boundjid.bare
)
async def autojoin_muc(self, event):
result = await self.plugin['xep_0048'].get_bookmarks()
bookmarks = result["private"]["bookmarks"]
conferences = bookmarks["conferences"]
for conference in conferences:
if conference["autojoin"]:
muc = conference["jid"]
print(muc)
self.plugin['xep_0045'].join_muc(
muc,
"Slixfeed (RSS News Bot)",
# If a room password is needed, use:
# password=the_room_password,
)
async def on_session_end(self, event): async def on_session_end(self, event):
@ -562,6 +625,7 @@ class Slixfeed(slixmpp.ClientXMPP):
print(self.client_roster.keys()) print(self.client_roster.keys())
print("jid") print("jid")
print(jid) print(jid)
await self.autojoin_muc()
case _ if message_lowercase.startswith("activate"): case _ if message_lowercase.startswith("activate"):
if msg["type"] == "groupchat": if msg["type"] == "groupchat":
@ -606,16 +670,16 @@ class Slixfeed(slixmpp.ClientXMPP):
) )
else: else:
action = "Missing URL." action = "Missing URL."
case _ if message_lowercase.startswith("allow"): case _ if message_lowercase.startswith("allow +"):
key = "filter-" + message[:5] key = "filter-" + message[:5]
val = message[6:] val = message[7:]
if val: if val:
keywords = await filehandler.initdb( keywords = await filehandler.initdb(
jid, jid,
sqlitehandler.get_settings_value, sqlitehandler.get_settings_value,
key key
) )
val = await listhandler.set_list( val = await listhandler.add_to_list(
val, val,
keywords keywords
) )
@ -630,16 +694,64 @@ class Slixfeed(slixmpp.ClientXMPP):
).format(val) ).format(val)
else: else:
action = "Missing keywords." action = "Missing keywords."
case _ if message_lowercase.startswith("deny"): case _ if message_lowercase.startswith("allow -"):
key = "filter-" + message[:4] key = "filter-" + message[:5]
val = message[5:] val = message[7:]
if val: if val:
keywords = await filehandler.initdb( keywords = await filehandler.initdb(
jid, jid,
sqlitehandler.get_settings_value, sqlitehandler.get_settings_value,
key key
) )
val = await listhandler.set_list( val = await listhandler.remove_from_list(
val,
keywords
)
await filehandler.initdb(
jid,
sqlitehandler.set_settings_value,
[key, val]
)
action = (
"Approved keywords\n"
"```\n{}\n```"
).format(val)
else:
action = "Missing keywords."
case _ if message_lowercase.startswith("deny +"):
key = "filter-" + message[:4]
val = message[6:]
if val:
keywords = await filehandler.initdb(
jid,
sqlitehandler.get_settings_value,
key
)
val = await listhandler.add_to_list(
val,
keywords
)
await filehandler.initdb(
jid,
sqlitehandler.set_settings_value,
[key, val]
)
action = (
"Rejected keywords\n"
"```\n{}\n```"
).format(val)
else:
action = "Missing keywords."
case _ if message_lowercase.startswith("deny -"):
key = "filter-" + message[:4]
val = message[6:]
if val:
keywords = await filehandler.initdb(
jid,
sqlitehandler.get_settings_value,
key
)
val = await listhandler.remove_from_list(
val, val,
keywords keywords
) )
@ -705,6 +817,11 @@ class Slixfeed(slixmpp.ClientXMPP):
jid, jid,
sqlitehandler.list_feeds sqlitehandler.list_feeds
) )
case "goodbye":
if msg["type"] == "groupchat":
await self.remove_and_leave_muc(jid)
else:
action = "This command is valid for groupchat only."
case _ if message_lowercase.startswith("interval"): case _ if message_lowercase.startswith("interval"):
# FIXME # FIXME
# The following error occurs only upon first attempt to set interval. # The following error occurs only upon first attempt to set interval.
@ -746,7 +863,7 @@ class Slixfeed(slixmpp.ClientXMPP):
sqlitehandler.get_settings_value, sqlitehandler.get_settings_value,
key key
) )
val = await listhandler.set_list( val = await listhandler.add_to_list(
val, val,
names names
) )
@ -955,6 +1072,9 @@ class Slixfeed(slixmpp.ClientXMPP):
"Unknown command. " "Unknown command. "
"Press \"help\" for list of commands" "Press \"help\" for list of commands"
) )
# TODO Use message correction here
# NOTE This might not be a good idea if
# commands are sent one close to the next
if action: msg.reply(action).send() if action: msg.reply(action).send()
@ -995,11 +1115,12 @@ def print_info():
" Dimitris Tzemos (SalixOS, Greece)," " Dimitris Tzemos (SalixOS, Greece),"
"\n" "\n"
" Emmanuel Gil Peyrot (poezio, France)," " Emmanuel Gil Peyrot (poezio, France),"
" Florent Le Coz (poezio, France),"
"\n"
" George Vlahavas (SalixOS, Greece)," " George Vlahavas (SalixOS, Greece),"
"\n"
" Pierrick Le Brun (SalixOS, France)," " Pierrick Le Brun (SalixOS, France),"
" Thorsten Mühlfelder (SalixOS, Germany),"
"\n" "\n"
" Thorsten Mühlfelder (SalixOS, Germany),"
" Yann Leboulanger (Gajim, France).\n" " Yann Leboulanger (Gajim, France).\n"
"\n" "\n"
"COPYRIGHT\n" "COPYRIGHT\n"
@ -1088,10 +1209,14 @@ def print_help():
" Set new owner.\n" " Set new owner.\n"
"\n" "\n"
"FILTER OPTIONS\n" "FILTER OPTIONS\n"
" allow\n" " allow +\n"
" Keywords to allow (comma separates).\n" " Add keywords to allow (comma separates).\n"
" deny\n" " allow -\n"
" Delete keywords from allow list (comma separates).\n"
" deny +\n"
" Keywords to block (comma separates).\n" " Keywords to block (comma separates).\n"
" deny -\n"
" Delete keywords from deny list (comma separates).\n"
# " filter clear allow\n" # " filter clear allow\n"
# " Reset allow list.\n" # " Reset allow list.\n"
# " filter clear deny\n" # " filter clear deny\n"