forked from sch/Slixfeed
Add support for groupchat and activation feature
This commit is contained in:
parent
31baf96430
commit
071bf78e1d
7 changed files with 296 additions and 131 deletions
|
@ -113,6 +113,7 @@ if __name__ == '__main__':
|
||||||
xmpp.register_plugin('xep_0004') # Data Forms
|
xmpp.register_plugin('xep_0004') # Data Forms
|
||||||
xmpp.register_plugin('xep_0030') # Service Discovery
|
xmpp.register_plugin('xep_0030') # Service Discovery
|
||||||
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_0060') # PubSub
|
xmpp.register_plugin('xep_0060') # PubSub
|
||||||
xmpp.register_plugin('xep_0199') # XMPP Ping
|
xmpp.register_plugin('xep_0199') # XMPP Ping
|
||||||
xmpp.register_plugin('xep_0249') # Multi-User Chat
|
xmpp.register_plugin('xep_0249') # Multi-User Chat
|
||||||
|
|
|
@ -12,6 +12,7 @@ TODO
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import filehandler
|
import filehandler
|
||||||
|
from random import randrange
|
||||||
|
|
||||||
|
|
||||||
async def get_value_default(key):
|
async def get_value_default(key):
|
||||||
|
@ -42,8 +43,10 @@ async def get_value_default(key):
|
||||||
result = 3
|
result = 3
|
||||||
case "random":
|
case "random":
|
||||||
result = 0
|
result = 0
|
||||||
case "read":
|
case "masters":
|
||||||
result = "https://www.blacklistednews.com/rss.php"
|
result = randrange(100000, 999999)
|
||||||
|
case "token":
|
||||||
|
result = "none"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import feedparser
|
||||||
import sqlitehandler
|
import sqlitehandler
|
||||||
import confighandler
|
import confighandler
|
||||||
import datetimehandler
|
import datetimehandler
|
||||||
import filterhandler
|
import listhandler
|
||||||
|
|
||||||
from asyncio.exceptions import IncompleteReadError
|
from asyncio.exceptions import IncompleteReadError
|
||||||
from http.client import IncompleteRead
|
from http.client import IncompleteRead
|
||||||
|
@ -168,15 +168,15 @@ async def download_updates(db_file, url=None):
|
||||||
summary,
|
summary,
|
||||||
pathname
|
pathname
|
||||||
)
|
)
|
||||||
allow_list = await filterhandler.is_listed(
|
allow_list = await listhandler.is_listed(
|
||||||
db_file,
|
db_file,
|
||||||
"allow",
|
"filter-allow",
|
||||||
string
|
string
|
||||||
)
|
)
|
||||||
if not allow_list:
|
if not allow_list:
|
||||||
reject_list = await filterhandler.is_listed(
|
reject_list = await listhandler.is_listed(
|
||||||
db_file,
|
db_file,
|
||||||
"deny",
|
"filter-deny",
|
||||||
string
|
string
|
||||||
)
|
)
|
||||||
if reject_list:
|
if reject_list:
|
||||||
|
@ -208,7 +208,7 @@ async def download_updates(db_file, url=None):
|
||||||
|
|
||||||
|
|
||||||
# NOTE Why (if result[0]) and (if result[1] == 200)?
|
# NOTE Why (if result[0]) and (if result[1] == 200)?
|
||||||
async def view_feed(db_file, url):
|
async def view_feed(url):
|
||||||
"""
|
"""
|
||||||
Check feeds for new entries.
|
Check feeds for new entries.
|
||||||
|
|
||||||
|
@ -235,8 +235,7 @@ async def view_feed(db_file, url):
|
||||||
# "For more information, visit "
|
# "For more information, visit "
|
||||||
# "https://pythonhosted.org/feedparser/bozo.html"
|
# "https://pythonhosted.org/feedparser/bozo.html"
|
||||||
# ).format(url)
|
# ).format(url)
|
||||||
# msg = await probe_page(view_feed, url, result[0])
|
msg = await probe_page(view_feed, url, result[0])
|
||||||
msg = await probe_page(view_feed, url, result[0], db_file)
|
|
||||||
return msg
|
return msg
|
||||||
except (
|
except (
|
||||||
IncompleteReadError,
|
IncompleteReadError,
|
||||||
|
@ -253,10 +252,7 @@ async def view_feed(db_file, url):
|
||||||
if result[1] == 200:
|
if result[1] == 200:
|
||||||
title = await get_title(url, result[0])
|
title = await get_title(url, result[0])
|
||||||
entries = feed.entries
|
entries = feed.entries
|
||||||
msg = "Extracted {} entries from {}:\n```\n".format(
|
msg = "Preview of {}:\n```\n".format(title)
|
||||||
len(entries),
|
|
||||||
title
|
|
||||||
)
|
|
||||||
count = 0
|
count = 0
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -290,13 +286,11 @@ async def view_feed(db_file, url):
|
||||||
link,
|
link,
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
if count > 4:
|
||||||
|
break
|
||||||
msg += (
|
msg += (
|
||||||
"```\n"
|
"```\nSource: {}"
|
||||||
"Source: {}\n"
|
).format(url)
|
||||||
"Enter a number from 1 - {} using command `select` "
|
|
||||||
"to view a specific item from the list."
|
|
||||||
).format(url, count)
|
|
||||||
await sqlitehandler.set_settings_value(db_file, ["read", url])
|
|
||||||
else:
|
else:
|
||||||
msg = (
|
msg = (
|
||||||
">{}\nFailed to load URL. Reason: {}"
|
">{}\nFailed to load URL. Reason: {}"
|
||||||
|
@ -304,14 +298,38 @@ async def view_feed(db_file, url):
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
async def view_entry(db_file, num):
|
# NOTE Why (if result[0]) and (if result[1] == 200)?
|
||||||
num = int(num) - 1
|
async def view_entry(url, num):
|
||||||
url = await sqlitehandler.get_settings_value(db_file, "read")
|
|
||||||
result = await download_feed(url)
|
result = await download_feed(url)
|
||||||
|
if result[0]:
|
||||||
|
try:
|
||||||
|
feed = feedparser.parse(result[0])
|
||||||
|
if feed.bozo:
|
||||||
|
# msg = (
|
||||||
|
# ">{}\n"
|
||||||
|
# "WARNING: Bozo detected!\n"
|
||||||
|
# "For more information, visit "
|
||||||
|
# "https://pythonhosted.org/feedparser/bozo.html"
|
||||||
|
# ).format(url)
|
||||||
|
msg = await probe_page(view_entry, url, result[0], num)
|
||||||
|
return msg
|
||||||
|
except (
|
||||||
|
IncompleteReadError,
|
||||||
|
IncompleteRead,
|
||||||
|
error.URLError
|
||||||
|
) as e:
|
||||||
|
# print(e)
|
||||||
|
# TODO Print error to log
|
||||||
|
msg = (
|
||||||
|
"> {}\n"
|
||||||
|
"Error: {}"
|
||||||
|
).format(url, e)
|
||||||
|
breakpoint()
|
||||||
if result[1] == 200:
|
if result[1] == 200:
|
||||||
feed = feedparser.parse(result[0])
|
feed = feedparser.parse(result[0])
|
||||||
title = await get_title(url, result[0])
|
title = await get_title(url, result[0])
|
||||||
entries = feed.entries
|
entries = feed.entries
|
||||||
|
num = int(num) - 1
|
||||||
entry = entries[num]
|
entry = entries[num]
|
||||||
if entry.has_key("title"):
|
if entry.has_key("title"):
|
||||||
title = entry.title
|
title = entry.title
|
||||||
|
@ -328,9 +346,9 @@ async def view_entry(db_file, num):
|
||||||
if entry.has_key("summary"):
|
if entry.has_key("summary"):
|
||||||
summary = entry.summary
|
summary = entry.summary
|
||||||
# Remove HTML tags
|
# Remove HTML tags
|
||||||
# summary = BeautifulSoup(summary, "lxml").text
|
summary = BeautifulSoup(summary, "lxml").text
|
||||||
# TODO Limit text length
|
# TODO Limit text length
|
||||||
# summary = summary.replace("\n\n", "\n")
|
summary = summary.replace("\n\n\n", "\n\n")
|
||||||
else:
|
else:
|
||||||
summary = "*** No summary ***"
|
summary = "*** No summary ***"
|
||||||
if entry.has_key("link"):
|
if entry.has_key("link"):
|
||||||
|
@ -346,11 +364,8 @@ async def view_entry(db_file, num):
|
||||||
"\n"
|
"\n"
|
||||||
"{}\n"
|
"{}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"{}\n"
|
|
||||||
"\n"
|
|
||||||
).format(
|
).format(
|
||||||
title,
|
title,
|
||||||
date,
|
|
||||||
summary,
|
summary,
|
||||||
link
|
link
|
||||||
)
|
)
|
||||||
|
@ -453,7 +468,7 @@ async def add_feed(db_file, url):
|
||||||
|
|
||||||
|
|
||||||
# TODO callback for use with add_feed and view_feed
|
# TODO callback for use with add_feed and view_feed
|
||||||
async def probe_page(callback, url, doc, db_file=None):
|
async def probe_page(callback, url, doc, num=None, db_file=None):
|
||||||
msg = None
|
msg = None
|
||||||
try:
|
try:
|
||||||
# tree = etree.fromstring(res[0]) # etree is for xml
|
# tree = etree.fromstring(res[0]) # etree is for xml
|
||||||
|
@ -483,6 +498,8 @@ async def probe_page(callback, url, doc, db_file=None):
|
||||||
url = msg[0]
|
url = msg[0]
|
||||||
if db_file:
|
if db_file:
|
||||||
return await callback(db_file, url)
|
return await callback(db_file, url)
|
||||||
|
elif num:
|
||||||
|
return await callback(url, num)
|
||||||
else:
|
else:
|
||||||
return await callback(url)
|
return await callback(url)
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,10 @@ TODO
|
||||||
|
|
||||||
import sqlitehandler
|
import sqlitehandler
|
||||||
|
|
||||||
async def set_filter(newwords, keywords):
|
|
||||||
|
async def set_list(newwords, keywords):
|
||||||
"""
|
"""
|
||||||
Append new keywords to filter.
|
Append new keywords to list.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -46,7 +47,8 @@ async def set_filter(newwords, keywords):
|
||||||
val = ",".join(keywords)
|
val = ",".join(keywords)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
async def is_listed(db_file, type, string):
|
|
||||||
|
async def is_listed(db_file, key, string):
|
||||||
"""
|
"""
|
||||||
Check keyword match.
|
Check keyword match.
|
||||||
|
|
||||||
|
@ -66,10 +68,9 @@ async def is_listed(db_file, type, string):
|
||||||
"""
|
"""
|
||||||
# async def reject(db_file, string):
|
# async def reject(db_file, string):
|
||||||
# async def is_blacklisted(db_file, string):
|
# async def is_blacklisted(db_file, string):
|
||||||
filter_type = "filter-" + type
|
|
||||||
list = await sqlitehandler.get_settings_value(
|
list = await sqlitehandler.get_settings_value(
|
||||||
db_file,
|
db_file,
|
||||||
filter_type
|
key
|
||||||
)
|
)
|
||||||
if list:
|
if list:
|
||||||
list = list.split(",")
|
list = list.split(",")
|
|
@ -1059,7 +1059,7 @@ async def list_feeds(db_file):
|
||||||
"FROM feeds"
|
"FROM feeds"
|
||||||
)
|
)
|
||||||
results = cur.execute(sql)
|
results = cur.execute(sql)
|
||||||
feeds_list = "\nList of subscriptions:\n```"
|
feeds_list = "\nList of subscriptions:\n```\n"
|
||||||
counter = 0
|
counter = 0
|
||||||
for result in results:
|
for result in results:
|
||||||
counter += 1
|
counter += 1
|
||||||
|
@ -1329,7 +1329,7 @@ async def set_settings_value(db_file, key_value):
|
||||||
key_value : list
|
key_value : list
|
||||||
key : str
|
key : str
|
||||||
enabled, filter-allow, filter-deny,
|
enabled, filter-allow, filter-deny,
|
||||||
interval, master, quantum, random.
|
interval, masters, quantum, random.
|
||||||
value : int
|
value : int
|
||||||
Numeric value.
|
Numeric value.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -198,11 +198,15 @@ async def send_update(self, jid, num=None):
|
||||||
if new:
|
if new:
|
||||||
# TODO Add while loop to assure delivery.
|
# TODO Add while loop to assure delivery.
|
||||||
# print(await datetimehandler.current_time(), ">>> ACT send_message",jid)
|
# print(await datetimehandler.current_time(), ">>> ACT send_message",jid)
|
||||||
|
if await xmpphandler.Slixfeed.is_muc(self, jid):
|
||||||
|
chat_type = "groupchat"
|
||||||
|
else:
|
||||||
|
chat_type = "chat"
|
||||||
xmpphandler.Slixfeed.send_message(
|
xmpphandler.Slixfeed.send_message(
|
||||||
self,
|
self,
|
||||||
mto=jid,
|
mto=jid,
|
||||||
mbody=new,
|
mbody=new,
|
||||||
mtype="chat"
|
mtype=chat_type
|
||||||
)
|
)
|
||||||
# TODO Do not refresh task before
|
# TODO Do not refresh task before
|
||||||
# verifying that it was completed.
|
# verifying that it was completed.
|
||||||
|
|
|
@ -23,6 +23,15 @@ TODO
|
||||||
4) Do not send updates when busy or away.
|
4) Do not send updates when busy or away.
|
||||||
See https://slixmpp.readthedocs.io/en/latest/event_index.html#term-changed_status
|
See https://slixmpp.readthedocs.io/en/latest/event_index.html#term-changed_status
|
||||||
|
|
||||||
|
5) XHTTML-IM
|
||||||
|
case _ if message_lowercase.startswith("html"):
|
||||||
|
message['html']="<h1>Parse me!</h1>"
|
||||||
|
self.send_message(
|
||||||
|
mto=jid,
|
||||||
|
mfrom=self.boundjid.bare,
|
||||||
|
mhtml=message
|
||||||
|
)
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
|
|
||||||
1) Self presence
|
1) Self presence
|
||||||
|
@ -51,7 +60,7 @@ from slixmpp.plugins.xep_0363.http_upload import FileTooBig, HTTPError, UploadSe
|
||||||
import datahandler
|
import datahandler
|
||||||
import datetimehandler
|
import datetimehandler
|
||||||
import filehandler
|
import filehandler
|
||||||
import filterhandler
|
import listhandler
|
||||||
import sqlitehandler
|
import sqlitehandler
|
||||||
import taskhandler
|
import taskhandler
|
||||||
|
|
||||||
|
@ -105,8 +114,8 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
self.add_event_handler("message", self.message)
|
self.add_event_handler("message", self.message)
|
||||||
self.add_event_handler("message", self.settle)
|
self.add_event_handler("message", self.settle)
|
||||||
|
|
||||||
self.add_event_handler("groupchat_invite", self.accept_muc_invite)
|
self.add_event_handler("groupchat_invite", self.process_muc_invite) # XEP_0045
|
||||||
self.add_event_handler("groupchat_direct_invite", self.accept_muc_invite)
|
self.add_event_handler("groupchat_direct_invite", self.process_muc_invite) # XEP_0249
|
||||||
# self.add_event_handler("groupchat_message", self.message)
|
# self.add_event_handler("groupchat_message", self.message)
|
||||||
|
|
||||||
# self.add_event_handler("disconnected", self.reconnect)
|
# self.add_event_handler("disconnected", self.reconnect)
|
||||||
|
@ -190,27 +199,58 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
print("reactions")
|
print("reactions")
|
||||||
print(message)
|
print(message)
|
||||||
|
|
||||||
async def accept_muc_invite(self, message):
|
# async def accept_muc_invite(self, message, ctr=None):
|
||||||
ctr = message["from"].bare
|
# # if isinstance(message, str):
|
||||||
jid = message['groupchat_invite']['jid']
|
# if not ctr:
|
||||||
tkn = randrange(10000, 99999)
|
# ctr = message["from"].bare
|
||||||
|
# jid = message['groupchat_invite']['jid']
|
||||||
|
# else:
|
||||||
|
# jid = message
|
||||||
|
async def process_muc_invite(self, message):
|
||||||
|
# operator muc_chat
|
||||||
|
inviter = message["from"].bare
|
||||||
|
muc_jid = message['groupchat_invite']['jid']
|
||||||
|
await self.join_muc(inviter, muc_jid)
|
||||||
|
|
||||||
|
|
||||||
|
async def join_muc(self, inviter, muc_jid):
|
||||||
|
token = await filehandler.initdb(
|
||||||
|
muc_jid,
|
||||||
|
sqlitehandler.get_settings_value,
|
||||||
|
"token"
|
||||||
|
)
|
||||||
|
if token != "accepted":
|
||||||
|
token = randrange(10000, 99999)
|
||||||
|
await filehandler.initdb(
|
||||||
|
muc_jid,
|
||||||
|
sqlitehandler.set_settings_value,
|
||||||
|
["token", token]
|
||||||
|
)
|
||||||
|
self.send_message(
|
||||||
|
mto=inviter,
|
||||||
|
mbody=(
|
||||||
|
"Send activation token {} to groupchat xmpp:{}?join."
|
||||||
|
).format(token, muc_jid)
|
||||||
|
)
|
||||||
self.plugin['xep_0045'].join_muc(
|
self.plugin['xep_0045'].join_muc(
|
||||||
jid,
|
muc_jid,
|
||||||
"Slixfeed (RSS News Bot)",
|
"Slixfeed (RSS News Bot)",
|
||||||
# If a room password is needed, use:
|
# If a room password is needed, use:
|
||||||
# password=the_room_password,
|
# password=the_room_password,
|
||||||
)
|
)
|
||||||
self.send_message(
|
|
||||||
mto=ctr,
|
|
||||||
mbody=(
|
|
||||||
"Send activation token {} to groupchat xmpp:{}?join."
|
|
||||||
).format(tkn, jid)
|
|
||||||
)
|
|
||||||
# self.add_event_handler(
|
# self.add_event_handler(
|
||||||
# "muc::[room]::message",
|
# "muc::[room]::message",
|
||||||
# self.message
|
# self.message
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
# await self.get_bookmarks()
|
||||||
|
# bookmark = self.plugin['xep_0048'].instantiate_pep()
|
||||||
|
# print(bookmark)
|
||||||
|
# nick = "Slixfeed (RSS News Bot)"
|
||||||
|
# bookmark.add_bookmark(muc_jid, nick=nick)
|
||||||
|
# await self['xep_0048'].set_bookmarks(bookmark)
|
||||||
|
# print(bookmark)
|
||||||
|
|
||||||
|
|
||||||
async def on_session_end(self, event):
|
async def on_session_end(self, event):
|
||||||
print(await datetimehandler.current_time(), "Session ended. Attempting to reconnect.")
|
print(await datetimehandler.current_time(), "Session ended. Attempting to reconnect.")
|
||||||
|
@ -341,6 +381,31 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
# await taskhandler.select_file()
|
# await taskhandler.select_file()
|
||||||
|
|
||||||
|
|
||||||
|
async def is_muc(self, jid):
|
||||||
|
"""
|
||||||
|
Check whether a JID is of MUC.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
jid : str
|
||||||
|
Jabber ID.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
boolean
|
||||||
|
True or False.
|
||||||
|
"""
|
||||||
|
iqresult = await self["xep_0030"].get_info(jid=jid)
|
||||||
|
features = iqresult["disco_info"]["features"]
|
||||||
|
# identity = iqresult['disco_info']['identities']
|
||||||
|
# if 'account' in indentity:
|
||||||
|
# if 'conference' in indentity:
|
||||||
|
if 'http://jabber.org/protocol/muc' in features:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
async def settle(self, msg):
|
async def settle(self, msg):
|
||||||
"""
|
"""
|
||||||
Add JID to roster and settle subscription.
|
Add JID to roster and settle subscription.
|
||||||
|
@ -355,42 +420,46 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
None.
|
None.
|
||||||
"""
|
"""
|
||||||
jid = msg["from"].bare
|
jid = msg["from"].bare
|
||||||
await self.get_roster()
|
if await self.is_muc(jid):
|
||||||
# Check whether JID is in roster; otherwise, add it.
|
# Check whether JID is in bookmarks; otherwise, add it.
|
||||||
if jid not in self.client_roster.keys():
|
print(jid, "is muc")
|
||||||
self.send_presence_subscription(
|
else:
|
||||||
pto=jid,
|
await self.get_roster()
|
||||||
ptype="subscribe",
|
# Check whether JID is in roster; otherwise, add it.
|
||||||
pnick="Slixfeed RSS News Bot"
|
if jid not in self.client_roster.keys():
|
||||||
)
|
self.send_presence_subscription(
|
||||||
self.update_roster(
|
pto=jid,
|
||||||
jid,
|
ptype="subscribe",
|
||||||
subscription="both"
|
pnick="Slixfeed RSS News Bot"
|
||||||
)
|
)
|
||||||
# Check whether JID is subscribed; otherwise, ask for presence.
|
self.update_roster(
|
||||||
if not self.client_roster[jid]["to"]:
|
jid,
|
||||||
self.send_presence_subscription(
|
subscription="both"
|
||||||
pto=jid,
|
)
|
||||||
pfrom=self.boundjid.bare,
|
# Check whether JID is subscribed; otherwise, ask for presence.
|
||||||
ptype="subscribe",
|
if not self.client_roster[jid]["to"]:
|
||||||
pnick="Slixfeed RSS News Bot"
|
self.send_presence_subscription(
|
||||||
)
|
pto=jid,
|
||||||
self.send_message(
|
pfrom=self.boundjid.bare,
|
||||||
mto=jid,
|
ptype="subscribe",
|
||||||
mtype="headline",
|
pnick="Slixfeed RSS News Bot"
|
||||||
msubject="RSS News Bot",
|
)
|
||||||
mbody=("Accept subscription request to receive updates."),
|
self.send_message(
|
||||||
mfrom=self.boundjid.bare,
|
mto=jid,
|
||||||
mnick="Slixfeed RSS News Bot"
|
# mtype="headline",
|
||||||
)
|
msubject="RSS News Bot",
|
||||||
self.send_presence(
|
mbody="Accept subscription request to receive updates.",
|
||||||
pto=jid,
|
mfrom=self.boundjid.bare,
|
||||||
pfrom=self.boundjid.bare,
|
mnick="Slixfeed RSS News Bot"
|
||||||
# Accept symbol 🉑️ 👍️ ✍
|
)
|
||||||
pstatus="✒️ Accept subscription request to receive updates",
|
self.send_presence(
|
||||||
# ptype="subscribe",
|
pto=jid,
|
||||||
pnick="Slixfeed RSS News Bot"
|
pfrom=self.boundjid.bare,
|
||||||
)
|
# Accept symbol 🉑️ 👍️ ✍
|
||||||
|
pstatus="✒️ Accept subscription request to receive updates",
|
||||||
|
# ptype="subscribe",
|
||||||
|
pnick="Slixfeed RSS News Bot"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def presence_unsubscribe(self, presence):
|
async def presence_unsubscribe(self, presence):
|
||||||
|
@ -436,14 +505,26 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
action = 0
|
action = 0
|
||||||
jid = msg["from"].bare
|
jid = msg["from"].bare
|
||||||
if msg["type"] == "groupchat":
|
if msg["type"] == "groupchat":
|
||||||
ctr = await filehandler.initdb(
|
# nick = msg["from"][msg["from"].index("/")+1:]
|
||||||
|
nick = str(msg["from"])
|
||||||
|
nick = nick[nick.index("/")+1:]
|
||||||
|
if (msg['muc']['nick'] == "Slixfeed (RSS News Bot)" or
|
||||||
|
not msg["body"].startswith("!")):
|
||||||
|
return
|
||||||
|
token = await filehandler.initdb(
|
||||||
jid,
|
jid,
|
||||||
sqlitehandler.get_settings_value,
|
sqlitehandler.get_settings_value,
|
||||||
"masters"
|
"token"
|
||||||
)
|
)
|
||||||
if (msg["from"][msg["from"].index("/")+1:] not in ctr
|
if token == "accepted":
|
||||||
or not msg["body"].startswith("!")):
|
operator = await filehandler.initdb(
|
||||||
return
|
jid,
|
||||||
|
sqlitehandler.get_settings_value,
|
||||||
|
"masters"
|
||||||
|
)
|
||||||
|
if operator:
|
||||||
|
if nick not in operator:
|
||||||
|
return
|
||||||
|
|
||||||
# # Begin processing new JID
|
# # Begin processing new JID
|
||||||
# # Deprecated in favour of event "presence_available"
|
# # Deprecated in favour of event "presence_available"
|
||||||
|
@ -451,12 +532,9 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
# os.chdir(db_dir)
|
# os.chdir(db_dir)
|
||||||
# if jid + ".db" not in os.listdir():
|
# if jid + ".db" not in os.listdir():
|
||||||
# await taskhandler.task_jid(jid)
|
# await taskhandler.task_jid(jid)
|
||||||
print(msg["body"])
|
|
||||||
print(msg["body"].split())
|
|
||||||
message = " ".join(msg["body"].split())
|
message = " ".join(msg["body"].split())
|
||||||
if msg["type"] == "groupchat":
|
if msg["type"] == "groupchat":
|
||||||
message = message[1:]
|
message = message[1:]
|
||||||
print(message)
|
|
||||||
message_lowercase = message.lower()
|
message_lowercase = message.lower()
|
||||||
|
|
||||||
print(await datetimehandler.current_time(), "ACCOUNT: " + str(msg["from"]))
|
print(await datetimehandler.current_time(), "ACCOUNT: " + str(msg["from"]))
|
||||||
|
@ -482,6 +560,33 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
print(self.client_roster)
|
print(self.client_roster)
|
||||||
print("roster 2")
|
print("roster 2")
|
||||||
print(self.client_roster.keys())
|
print(self.client_roster.keys())
|
||||||
|
print("jid")
|
||||||
|
print(jid)
|
||||||
|
|
||||||
|
case _ if message_lowercase.startswith("activate"):
|
||||||
|
if msg["type"] == "groupchat":
|
||||||
|
acode = message[9:]
|
||||||
|
token = await filehandler.initdb(
|
||||||
|
jid,
|
||||||
|
sqlitehandler.get_settings_value,
|
||||||
|
"token"
|
||||||
|
)
|
||||||
|
if int(acode) == token:
|
||||||
|
await filehandler.initdb(
|
||||||
|
jid,
|
||||||
|
sqlitehandler.set_settings_value,
|
||||||
|
["masters", nick]
|
||||||
|
)
|
||||||
|
await filehandler.initdb(
|
||||||
|
jid,
|
||||||
|
sqlitehandler.set_settings_value,
|
||||||
|
["token", "accepted"]
|
||||||
|
)
|
||||||
|
action = "{}, your are in command.".format(nick)
|
||||||
|
else:
|
||||||
|
action = "Activation code is not valid."
|
||||||
|
else:
|
||||||
|
action = "This command is valid for groupchat only."
|
||||||
case _ if message_lowercase.startswith("add"):
|
case _ if message_lowercase.startswith("add"):
|
||||||
message = message[4:]
|
message = message[4:]
|
||||||
url = message.split(" ")[0]
|
url = message.split(" ")[0]
|
||||||
|
@ -510,7 +615,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
sqlitehandler.get_settings_value,
|
sqlitehandler.get_settings_value,
|
||||||
key
|
key
|
||||||
)
|
)
|
||||||
val = await filterhandler.set_filter(
|
val = await listhandler.set_list(
|
||||||
val,
|
val,
|
||||||
keywords
|
keywords
|
||||||
)
|
)
|
||||||
|
@ -534,7 +639,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
sqlitehandler.get_settings_value,
|
sqlitehandler.get_settings_value,
|
||||||
key
|
key
|
||||||
)
|
)
|
||||||
val = await filterhandler.set_filter(
|
val = await listhandler.set_list(
|
||||||
val,
|
val,
|
||||||
keywords
|
keywords
|
||||||
)
|
)
|
||||||
|
@ -629,6 +734,33 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
).format(val)
|
).format(val)
|
||||||
else:
|
else:
|
||||||
action = "Missing value."
|
action = "Missing value."
|
||||||
|
case _ if message_lowercase.startswith("join"):
|
||||||
|
muc = message[5:]
|
||||||
|
await self.join_muc(jid, muc)
|
||||||
|
case _ if message_lowercase.startswith("mastership"):
|
||||||
|
key = message[:7]
|
||||||
|
val = message[11:]
|
||||||
|
if val:
|
||||||
|
names = await filehandler.initdb(
|
||||||
|
jid,
|
||||||
|
sqlitehandler.get_settings_value,
|
||||||
|
key
|
||||||
|
)
|
||||||
|
val = await listhandler.set_list(
|
||||||
|
val,
|
||||||
|
names
|
||||||
|
)
|
||||||
|
await filehandler.initdb(
|
||||||
|
jid,
|
||||||
|
sqlitehandler.set_settings_value,
|
||||||
|
[key, val]
|
||||||
|
)
|
||||||
|
action = (
|
||||||
|
"Operators\n"
|
||||||
|
"```\n{}\n```"
|
||||||
|
).format(val)
|
||||||
|
else:
|
||||||
|
action = "Missing value."
|
||||||
case _ if message_lowercase.startswith("next"):
|
case _ if message_lowercase.startswith("next"):
|
||||||
num = message[5:]
|
num = message[5:]
|
||||||
await taskhandler.clean_tasks_xmpp(
|
await taskhandler.clean_tasks_xmpp(
|
||||||
|
@ -675,16 +807,29 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
case "random":
|
case "random":
|
||||||
action = "Updates will be sent randomly."
|
action = "Updates will be sent randomly."
|
||||||
case _ if message_lowercase.startswith("read"):
|
case _ if message_lowercase.startswith("read"):
|
||||||
url = message[5:]
|
data = message[5:]
|
||||||
if url.startswith("http"):
|
data = data.split()
|
||||||
# action = await datahandler.view_feed(url)
|
url = data[0]
|
||||||
action = await filehandler.initdb(
|
if url.startswith("feed:"):
|
||||||
jid,
|
url = await datahandler.feed_to_http(url)
|
||||||
datahandler.view_feed,
|
match len(data):
|
||||||
url
|
case 1:
|
||||||
)
|
if url.startswith("http"):
|
||||||
else:
|
action = await datahandler.view_feed(url)
|
||||||
action = "Missing URL."
|
else:
|
||||||
|
action = "Missing URL."
|
||||||
|
case 2:
|
||||||
|
num = data[1]
|
||||||
|
if url.startswith("http"):
|
||||||
|
action = await datahandler.view_entry(url, num)
|
||||||
|
else:
|
||||||
|
action = "Missing URL."
|
||||||
|
case _:
|
||||||
|
action = (
|
||||||
|
"Enter command as follows:\n"
|
||||||
|
"`read URL` or `read URL NUMBER`\n"
|
||||||
|
"URL must not contain white space."
|
||||||
|
)
|
||||||
case _ if message_lowercase.startswith("recent"):
|
case _ if message_lowercase.startswith("recent"):
|
||||||
num = message[7:]
|
num = message[7:]
|
||||||
if num:
|
if num:
|
||||||
|
@ -759,16 +904,6 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
jid,
|
jid,
|
||||||
sqlitehandler.statistics
|
sqlitehandler.statistics
|
||||||
)
|
)
|
||||||
case _ if message_lowercase.startswith("select"):
|
|
||||||
num = message[7:]
|
|
||||||
if num:
|
|
||||||
action = await filehandler.initdb(
|
|
||||||
jid,
|
|
||||||
datahandler.view_entry,
|
|
||||||
num
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
action = "Missing number."
|
|
||||||
case _ if message_lowercase.startswith("status "):
|
case _ if message_lowercase.startswith("status "):
|
||||||
ix = message[7:]
|
ix = message[7:]
|
||||||
action = await filehandler.initdb(
|
action = await filehandler.initdb(
|
||||||
|
@ -878,8 +1013,6 @@ def print_info():
|
||||||
" GNU General Public License for more details.\n"
|
" GNU General Public License for more details.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"NOTE\n"
|
"NOTE\n"
|
||||||
" Make Slixfeed your own.\n"
|
|
||||||
"\n"
|
|
||||||
" You can run Slixfeed on your own computer, server, and\n"
|
" You can run Slixfeed on your own computer, server, and\n"
|
||||||
" even on a Linux phone (i.e. Droidian, Mobian NixOS,\n"
|
" even on a Linux phone (i.e. Droidian, Mobian NixOS,\n"
|
||||||
" postmarketOS). You can also use Termux.\n"
|
" postmarketOS). You can also use Termux.\n"
|
||||||
|
@ -919,30 +1052,34 @@ def print_help():
|
||||||
" For more information, visit https://xmpp.org/software/\n"
|
" For more information, visit https://xmpp.org/software/\n"
|
||||||
"\n"
|
"\n"
|
||||||
"BASIC USAGE\n"
|
"BASIC USAGE\n"
|
||||||
" start\n"
|
|
||||||
" Enable bot and send updates.\n"
|
|
||||||
" stop\n"
|
|
||||||
" Disable bot and stop updates.\n"
|
|
||||||
" URL\n"
|
" URL\n"
|
||||||
" Add URL to subscription list.\n"
|
" Add URL to subscription list.\n"
|
||||||
" add URL TITLE\n"
|
" add URL TITLE\n"
|
||||||
" Add URL to subscription list (without validity check).\n"
|
" Add URL to subscription list (without validity check).\n"
|
||||||
" feeds\n"
|
" join MUC\n"
|
||||||
" List subscriptions.\n"
|
" Join specified groupchat.\n"
|
||||||
|
" read URL\n"
|
||||||
|
" Display most recent 20 titles of given URL.\n"
|
||||||
|
" read URL N\n"
|
||||||
|
" Display specified entry number from given URL.\n"
|
||||||
|
"\n"
|
||||||
|
"MESSAGE OPTIONS\n"
|
||||||
|
" start\n"
|
||||||
|
" Enable bot and send updates.\n"
|
||||||
|
" stop\n"
|
||||||
|
" Disable bot and stop updates.\n"
|
||||||
" interval N\n"
|
" interval N\n"
|
||||||
" Set interval update to every N minutes.\n"
|
" Set interval update to every N minutes.\n"
|
||||||
" next N\n"
|
" next N\n"
|
||||||
" Send N next updates.\n"
|
" Send N next updates.\n"
|
||||||
" quantum N\n"
|
" quantum N\n"
|
||||||
" Set amount of updates for each interval.\n"
|
" Set N amount of updates per interval.\n"
|
||||||
" read URL\n"
|
|
||||||
" Display most recent 20 titles of given URL.\n"
|
|
||||||
" read URL NUM\n"
|
|
||||||
" Display specified entry from given URL.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"GROUPCHAT OPTIONS\n"
|
"GROUPCHAT OPTIONS\n"
|
||||||
" ! (command initiation)\n"
|
" ! (command initiation)\n"
|
||||||
" Use exclamation mark to initiate an actionable command.\n"
|
" Use exclamation mark to initiate an actionable command.\n"
|
||||||
|
" activate CODE\n"
|
||||||
|
" Activate and command bot.\n"
|
||||||
" demaster NICKNAME\n"
|
" demaster NICKNAME\n"
|
||||||
" Remove master privilege.\n"
|
" Remove master privilege.\n"
|
||||||
" mastership NICKNAME\n"
|
" mastership NICKNAME\n"
|
||||||
|
@ -967,6 +1104,8 @@ def print_help():
|
||||||
" Toggle update status of feed.\n"
|
" Toggle update status of feed.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"SEARCH OPTIONS\n"
|
"SEARCH OPTIONS\n"
|
||||||
|
" feeds\n"
|
||||||
|
" List all subscriptions.\n"
|
||||||
" feeds TEXT\n"
|
" feeds TEXT\n"
|
||||||
" Search subscriptions by given keywords.\n"
|
" Search subscriptions by given keywords.\n"
|
||||||
" search TEXT\n"
|
" search TEXT\n"
|
||||||
|
|
Loading…
Reference in a new issue