Fix settings update.
Add option to restore default settings. Reorganize code. Thank you mirux.
This commit is contained in:
parent
065311d0d8
commit
f6bc76fdf8
13 changed files with 328 additions and 284 deletions
|
@ -111,7 +111,7 @@ class JabberComponent:
|
|||
xmpp.register_plugin('xep_0066') # Out of Band Data
|
||||
xmpp.register_plugin('xep_0071') # XHTML-IM
|
||||
xmpp.register_plugin('xep_0084') # User Avatar
|
||||
# xmpp.register_plugin('xep_0085') # Chat State Notifications
|
||||
xmpp.register_plugin('xep_0085') # Chat State Notifications
|
||||
xmpp.register_plugin('xep_0115') # Entity Capabilities
|
||||
xmpp.register_plugin('xep_0153') # vCard-Based Avatars
|
||||
xmpp.register_plugin('xep_0199', {'keepalive': True}) # XMPP Ping
|
||||
|
@ -137,7 +137,7 @@ class JabberClient:
|
|||
xmpp.register_plugin('xep_0066') # Out of Band Data
|
||||
xmpp.register_plugin('xep_0071') # XHTML-IM
|
||||
xmpp.register_plugin('xep_0084') # User Avatar
|
||||
# xmpp.register_plugin('xep_0085') # Chat State Notifications
|
||||
xmpp.register_plugin('xep_0085') # Chat State Notifications
|
||||
xmpp.register_plugin('xep_0115') # Entity Capabilities
|
||||
xmpp.register_plugin('xep_0153') # vCard-Based Avatars
|
||||
xmpp.register_plugin('xep_0199', {'keepalive': True}) # XMPP Ping
|
||||
|
|
|
@ -87,6 +87,163 @@ except ImportError:
|
|||
"Arc90 Lab algorithm is disabled.")
|
||||
|
||||
|
||||
async def xmpp_send_status(self, jid):
|
||||
"""
|
||||
Send status message.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jid : str
|
||||
Jabber ID.
|
||||
"""
|
||||
logging.info('Sending a status message to JID {}'.format(jid))
|
||||
status_text = '📜️ Slixfeed RSS News Bot'
|
||||
jid_file = jid.replace('/', '_')
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
enabled = await config.get_setting_value(db_file, 'enabled')
|
||||
if not enabled:
|
||||
status_mode = 'xa'
|
||||
status_text = '📪️ Send "Start" to receive updates'
|
||||
else:
|
||||
feeds = await sqlite.get_number_of_items(db_file, 'feeds')
|
||||
# print(await current_time(), jid, "has", feeds, "feeds")
|
||||
if not feeds:
|
||||
status_mode = 'available'
|
||||
status_text = '📪️ Send a URL from a blog or a news website'
|
||||
else:
|
||||
unread = await sqlite.get_number_of_entries_unread(db_file)
|
||||
if unread:
|
||||
status_mode = 'chat'
|
||||
status_text = '📬️ There are {} news items'.format(str(unread))
|
||||
# status_text = (
|
||||
# "📰 News items: {}"
|
||||
# ).format(str(unread))
|
||||
# status_text = (
|
||||
# "📰 You have {} news items"
|
||||
# ).format(str(unread))
|
||||
else:
|
||||
status_mode = 'available'
|
||||
status_text = '📭️ No news'
|
||||
|
||||
# breakpoint()
|
||||
# print(await current_time(), status_text, "for", jid)
|
||||
XmppPresence.send(self, jid, status_text, status_type=status_mode)
|
||||
# await asyncio.sleep(60 * 20)
|
||||
# await refresh_task(self, jid, send_status, 'status', '90')
|
||||
# loop.call_at(
|
||||
# loop.time() + 60 * 20,
|
||||
# loop.create_task,
|
||||
# send_status(jid)
|
||||
# )
|
||||
|
||||
|
||||
async def xmpp_send_update(self, jid, num=None):
|
||||
"""
|
||||
Send news items as messages.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jid : str
|
||||
Jabber ID.
|
||||
num : str, optional
|
||||
Number. The default is None.
|
||||
"""
|
||||
jid_file = jid.replace('/', '_')
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
enabled = await config.get_setting_value(db_file, 'enabled')
|
||||
if enabled:
|
||||
show_media = await config.get_setting_value(db_file, 'media')
|
||||
if not num:
|
||||
num = await config.get_setting_value(db_file, 'quantum')
|
||||
else:
|
||||
num = int(num)
|
||||
results = await sqlite.get_unread_entries(db_file, num)
|
||||
news_digest = ''
|
||||
media = None
|
||||
chat_type = await get_chat_type(self, jid)
|
||||
for result in results:
|
||||
ix = result[0]
|
||||
title_e = result[1]
|
||||
url = result[2]
|
||||
enclosure = result[3]
|
||||
feed_id = result[4]
|
||||
date = result[5]
|
||||
title_f = sqlite.get_feed_title(db_file, feed_id)
|
||||
title_f = title_f[0]
|
||||
news_digest += list_unread_entries(result, title_f)
|
||||
# print(db_file)
|
||||
# print(result[0])
|
||||
# breakpoint()
|
||||
await sqlite.mark_as_read(db_file, ix)
|
||||
|
||||
# Find media
|
||||
# if url.startswith("magnet:"):
|
||||
# media = action.get_magnet(url)
|
||||
# elif enclosure.startswith("magnet:"):
|
||||
# media = action.get_magnet(enclosure)
|
||||
# elif enclosure:
|
||||
if show_media:
|
||||
if enclosure:
|
||||
media = enclosure
|
||||
else:
|
||||
media = await extract_image_from_html(url)
|
||||
|
||||
if media and news_digest:
|
||||
# Send textual message
|
||||
XmppMessage.send(self, jid, news_digest, chat_type)
|
||||
news_digest = ''
|
||||
# Send media
|
||||
XmppMessage.send_oob(self, jid, media, chat_type)
|
||||
media = None
|
||||
|
||||
if news_digest:
|
||||
XmppMessage.send(self, jid, news_digest, chat_type)
|
||||
# TODO Add while loop to assure delivery.
|
||||
# print(await current_time(), ">>> ACT send_message",jid)
|
||||
# NOTE Do we need "if statement"? See NOTE at is_muc.
|
||||
# if chat_type in ('chat', 'groupchat'):
|
||||
# # TODO Provide a choice (with or without images)
|
||||
# XmppMessage.send(self, jid, news_digest, chat_type)
|
||||
# See XEP-0367
|
||||
# if media:
|
||||
# # message = xmpp.Slixfeed.make_message(
|
||||
# # self, mto=jid, mbody=new, mtype=chat_type)
|
||||
# message = xmpp.Slixfeed.make_message(
|
||||
# self, mto=jid, mbody=media, mtype=chat_type)
|
||||
# message['oob']['url'] = media
|
||||
# message.send()
|
||||
|
||||
# TODO Do not refresh task before
|
||||
# verifying that it was completed.
|
||||
|
||||
# await start_tasks_xmpp(self, jid, ['status'])
|
||||
# await refresh_task(self, jid, send_update, 'interval')
|
||||
|
||||
# interval = await initdb(
|
||||
# jid,
|
||||
# sqlite.get_settings_value,
|
||||
# "interval"
|
||||
# )
|
||||
# self.task_manager[jid]["interval"] = loop.call_at(
|
||||
# loop.time() + 60 * interval,
|
||||
# loop.create_task,
|
||||
# send_update(jid)
|
||||
# )
|
||||
|
||||
# print(await current_time(), "asyncio.get_event_loop().time()")
|
||||
# print(await current_time(), asyncio.get_event_loop().time())
|
||||
# await asyncio.sleep(60 * interval)
|
||||
|
||||
# loop.call_later(
|
||||
# 60 * interval,
|
||||
# loop.create_task,
|
||||
# send_update(jid)
|
||||
# )
|
||||
|
||||
# print
|
||||
# await handle_event()
|
||||
|
||||
|
||||
def manual(filename, section=None, command=None):
|
||||
config_dir = config.get_default_config_directory()
|
||||
with open(config_dir + '/' + filename, mode="rb") as commands:
|
||||
|
@ -119,7 +276,7 @@ async def xmpp_change_interval(self, key, val, jid, jid_file, message=None,
|
|||
# 'Updates will be sent every {} minutes.'
|
||||
# ).format(response)
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -140,7 +297,7 @@ async def xmpp_start_updates(self, message, jid, jid_file):
|
|||
key = 'enabled'
|
||||
val = 1
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -157,7 +314,7 @@ async def xmpp_stop_updates(self, message, jid, jid_file):
|
|||
key = 'enabled'
|
||||
val = 0
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -399,8 +556,7 @@ async def list_statistics(db_file):
|
|||
# value = "Default"
|
||||
# values.extend([value])
|
||||
|
||||
message = (
|
||||
"```"
|
||||
message = ("```"
|
||||
"\nSTATISTICS\n"
|
||||
"News items : {}/{}\n"
|
||||
"News sources : {}/{}\n"
|
||||
|
@ -409,17 +565,14 @@ async def list_statistics(db_file):
|
|||
"Update interval : {}\n"
|
||||
"Items per update : {}\n"
|
||||
"Operation status : {}\n"
|
||||
"```"
|
||||
).format(
|
||||
entries_unread,
|
||||
"```").format(entries_unread,
|
||||
entries_all,
|
||||
feeds_active,
|
||||
feeds_all,
|
||||
key_archive,
|
||||
key_interval,
|
||||
key_quantum,
|
||||
key_enabled
|
||||
)
|
||||
key_enabled)
|
||||
return message
|
||||
|
||||
|
||||
|
@ -427,10 +580,8 @@ async def list_statistics(db_file):
|
|||
def list_last_entries(results, num):
|
||||
message = "Recent {} titles:\n\n```".format(num)
|
||||
for result in results:
|
||||
message += (
|
||||
"\n{}\n{}\n"
|
||||
).format(
|
||||
str(result[0]), str(result[1]))
|
||||
message += ("\n{}\n{}\n"
|
||||
.format(str(result[0]), str(result[1])))
|
||||
if len(results):
|
||||
message += "```\n"
|
||||
else:
|
||||
|
@ -441,59 +592,45 @@ def list_last_entries(results, num):
|
|||
def list_feeds(results):
|
||||
message = "\nList of subscriptions:\n\n```\n"
|
||||
for result in results:
|
||||
message += (
|
||||
"Name : {}\n"
|
||||
message += ("Name : {}\n"
|
||||
"URL : {}\n"
|
||||
# "Updated : {}\n"
|
||||
# "Status : {}\n"
|
||||
"ID : {}\n"
|
||||
"\n"
|
||||
).format(
|
||||
str(result[0]), str(result[1]), str(result[2]))
|
||||
.format(str(result[0]), str(result[1]), str(result[2])))
|
||||
if len(results):
|
||||
message += (
|
||||
"```\nTotal of {} subscriptions.\n"
|
||||
).format(len(results))
|
||||
message += ('```\nTotal of {} subscriptions.\n'
|
||||
.format(len(results)))
|
||||
else:
|
||||
message = (
|
||||
"List of subscriptions is empty.\n"
|
||||
"To add feed, send a URL\n"
|
||||
"Try these:\n"
|
||||
# TODO Pick random from featured/recommended
|
||||
"https://reclaimthenet.org/feed/"
|
||||
)
|
||||
message = ('List of subscriptions is empty.\n'
|
||||
'To add feed, send a URL\n'
|
||||
'Featured feed: '
|
||||
'https://reclaimthenet.org/feed/')
|
||||
return message
|
||||
|
||||
|
||||
async def list_bookmarks(self):
|
||||
conferences = await XmppBookmark.get(self)
|
||||
message = "\nList of groupchats:\n\n```\n"
|
||||
message = '\nList of groupchats:\n\n```\n'
|
||||
for conference in conferences:
|
||||
message += (
|
||||
"{}\n"
|
||||
"\n"
|
||||
).format(
|
||||
conference["jid"]
|
||||
)
|
||||
message += (
|
||||
"```\nTotal of {} groupchats.\n"
|
||||
).format(len(conferences))
|
||||
message += ('{}\n'
|
||||
'\n'
|
||||
.format(conference['jid']))
|
||||
message += ('```\nTotal of {} groupchats.\n'
|
||||
.format(len(conferences)))
|
||||
return message
|
||||
|
||||
|
||||
def export_to_markdown(jid, filename, results):
|
||||
with open(filename, 'w') as file:
|
||||
file.write(
|
||||
'# Subscriptions for {}\n'.format(jid))
|
||||
file.write(
|
||||
'## Set of feeds exported with Slixfeed\n')
|
||||
file.write('# Subscriptions for {}\n'.format(jid))
|
||||
file.write('## Set of feeds exported with Slixfeed\n')
|
||||
for result in results:
|
||||
file.write(
|
||||
'- [{}]({})\n'.format(result[0], result[1]))
|
||||
file.write(
|
||||
'\n\n* * *\n\nThis list was saved on {} from xmpp:{} using '
|
||||
'[Slixfeed](https://gitgud.io/sjehuda/slixfeed)\n'.format(
|
||||
dt.current_date(), jid))
|
||||
file.write('- [{}]({})\n'.format(result[0], result[1]))
|
||||
file.write('\n\n* * *\n\nThis list was saved on {} from xmpp:{} using '
|
||||
'[Slixfeed](https://gitgud.io/sjehuda/slixfeed)\n'
|
||||
.format(dt.current_date(), jid))
|
||||
|
||||
|
||||
# TODO Consider adding element jid as a pointer of import
|
||||
|
|
|
@ -162,9 +162,9 @@ archive = """
|
|||
archive <number>
|
||||
Number of news items to archive (maximum value 500).
|
||||
"""
|
||||
remove = """
|
||||
remove <id>
|
||||
Remove feed of from subscription list by given <id>.
|
||||
default = """
|
||||
default
|
||||
Restore default settings.
|
||||
"""
|
||||
disable = """
|
||||
disable <id>
|
||||
|
@ -174,6 +174,10 @@ enable = """
|
|||
enable <id>
|
||||
Enable updates for feed of given <id>.
|
||||
"""
|
||||
remove = """
|
||||
remove <id>
|
||||
Remove feed of from subscription list by given <id>.
|
||||
"""
|
||||
reset = """
|
||||
reset
|
||||
Mark all entries as read and remove all archived entries
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
about = """
|
||||
Slixfeed
|
||||
|
||||
A Syndication bot for the XMPP communication network.
|
||||
|
||||
Slixfeed is a news broker which aims to be an easy to use and fully-\
|
||||
featured news aggregator bot. It provides a convenient access to \
|
||||
Blogs, News websites and even Fediverse instances, along with \
|
||||
filtering functionality.
|
||||
|
||||
Slixfeed is primarily designed for XMPP (aka Jabber). \
|
||||
Visit https://xmpp.org/software/ for more information.
|
||||
"""
|
||||
|
@ -133,8 +131,9 @@ Simone "roughnecks" Canaletti <woodpeckersnest.space> (Italy), \
|
|||
Richard Lapointe (SalixOS, Connecticut), \
|
||||
Strix from Loqi, \
|
||||
Thibaud Guerin (SalixOS), \
|
||||
Tim Beech (SalixOS, Brazil), \
|
||||
Thorsten Fröhlich (France), \
|
||||
Thorsten Mühlfelder (SalixOS, Germany), \
|
||||
Tim Beech (SalixOS, Brazil), \
|
||||
Yann Leboulanger (Gajim, France).
|
||||
"""
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ import tomllib
|
|||
|
||||
async def get_setting_value(db_file, key):
|
||||
value = (
|
||||
await sqlite.get_settings_value(db_file, key) or
|
||||
sqlite.get_settings_value(db_file, key) or
|
||||
get_value("settings", "Settings", key)
|
||||
)
|
||||
value = int(value)
|
||||
|
|
|
@ -1808,7 +1808,19 @@ async def update_settings_value(db_file, key_value):
|
|||
# )
|
||||
|
||||
|
||||
async def get_settings_value(db_file, key):
|
||||
async def delete_settings(db_file):
|
||||
async with DBLOCK:
|
||||
with create_connection(db_file) as conn:
|
||||
cur = conn.cursor()
|
||||
sql = (
|
||||
"""
|
||||
DELETE
|
||||
FROM settings
|
||||
"""
|
||||
)
|
||||
cur.execute(sql)
|
||||
|
||||
def get_settings_value(db_file, key):
|
||||
"""
|
||||
Get settings value.
|
||||
|
||||
|
|
199
slixfeed/task.py
199
slixfeed/task.py
|
@ -3,16 +3,6 @@
|
|||
|
||||
"""
|
||||
|
||||
FIXME
|
||||
|
||||
0) URGENT!!! Place "await asyncio.sleep(next_update_time)" ***inside*** the
|
||||
task, and not outside as it is now!
|
||||
|
||||
|
||||
1) Function check_readiness or event "changed_status" is causing for
|
||||
triple status messages and also false ones that indicate of lack
|
||||
of feeds.
|
||||
|
||||
TODO
|
||||
|
||||
0) Move functions send_status and send_update to module action
|
||||
|
@ -45,6 +35,29 @@ NOTE
|
|||
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
TIMEOUT
|
||||
|
||||
import signal
|
||||
|
||||
def handler(signum, frame):
|
||||
print("Timeout!")
|
||||
raise Exception("end of time")
|
||||
|
||||
# This line will set the alarm for 5 seconds
|
||||
|
||||
signal.signal(signal.SIGALRM, handler)
|
||||
signal.alarm(5)
|
||||
|
||||
try:
|
||||
# Your command here
|
||||
pass
|
||||
except Exception as exc:
|
||||
print(exc)
|
||||
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
|
@ -137,7 +150,7 @@ async def start_tasks_xmpp(self, jid, tasks=None):
|
|||
check_updates(jid))
|
||||
case 'status':
|
||||
self.task_manager[jid]['status'] = asyncio.create_task(
|
||||
send_status(self, jid))
|
||||
task_status(self, jid))
|
||||
case 'interval':
|
||||
self.task_manager[jid]['interval'] = asyncio.create_task(
|
||||
task_send(self, jid))
|
||||
|
@ -152,6 +165,11 @@ async def start_tasks_xmpp(self, jid, tasks=None):
|
|||
# await task
|
||||
|
||||
|
||||
async def task_status(self, jid):
|
||||
await action.xmpp_send_status(self, jid)
|
||||
await refresh_task(self, jid, task_status, 'status', '90')
|
||||
|
||||
|
||||
async def task_send(self, jid):
|
||||
jid_file = jid.replace('/', '_')
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
|
@ -178,118 +196,11 @@ async def task_send(self, jid):
|
|||
await sqlite.update_last_update_time(db_file)
|
||||
else:
|
||||
await sqlite.set_last_update_time(db_file)
|
||||
await xmpp_send_update(self, jid)
|
||||
await action.xmpp_send_update(self, jid)
|
||||
await refresh_task(self, jid, task_send, 'interval')
|
||||
await start_tasks_xmpp(self, jid, ['status'])
|
||||
|
||||
|
||||
async def xmpp_send_update(self, jid, num=None):
|
||||
"""
|
||||
Send news items as messages.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jid : str
|
||||
Jabber ID.
|
||||
num : str, optional
|
||||
Number. The default is None.
|
||||
"""
|
||||
jid_file = jid.replace('/', '_')
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
enabled = await config.get_setting_value(db_file, 'enabled')
|
||||
if enabled:
|
||||
show_media = await config.get_setting_value(db_file, 'media')
|
||||
if not num:
|
||||
num = await config.get_setting_value(db_file, 'quantum')
|
||||
else:
|
||||
num = int(num)
|
||||
results = await sqlite.get_unread_entries(db_file, num)
|
||||
news_digest = ''
|
||||
media = None
|
||||
chat_type = await get_chat_type(self, jid)
|
||||
for result in results:
|
||||
ix = result[0]
|
||||
title_e = result[1]
|
||||
url = result[2]
|
||||
enclosure = result[3]
|
||||
feed_id = result[4]
|
||||
date = result[5]
|
||||
title_f = sqlite.get_feed_title(db_file, feed_id)
|
||||
title_f = title_f[0]
|
||||
news_digest += action.list_unread_entries(result, title_f)
|
||||
# print(db_file)
|
||||
# print(result[0])
|
||||
# breakpoint()
|
||||
await sqlite.mark_as_read(db_file, ix)
|
||||
|
||||
# Find media
|
||||
# if url.startswith("magnet:"):
|
||||
# media = action.get_magnet(url)
|
||||
# elif enclosure.startswith("magnet:"):
|
||||
# media = action.get_magnet(enclosure)
|
||||
# elif enclosure:
|
||||
if show_media:
|
||||
if enclosure:
|
||||
media = enclosure
|
||||
else:
|
||||
media = await action.extract_image_from_html(url)
|
||||
|
||||
if media and news_digest:
|
||||
# Send textual message
|
||||
XmppMessage.send(self, jid, news_digest, chat_type)
|
||||
news_digest = ''
|
||||
# Send media
|
||||
XmppMessage.send_oob(self, jid, media, chat_type)
|
||||
media = None
|
||||
|
||||
if news_digest:
|
||||
XmppMessage.send(self, jid, news_digest, chat_type)
|
||||
# TODO Add while loop to assure delivery.
|
||||
# print(await current_time(), ">>> ACT send_message",jid)
|
||||
# NOTE Do we need "if statement"? See NOTE at is_muc.
|
||||
# if chat_type in ('chat', 'groupchat'):
|
||||
# # TODO Provide a choice (with or without images)
|
||||
# XmppMessage.send(self, jid, news_digest, chat_type)
|
||||
# See XEP-0367
|
||||
# if media:
|
||||
# # message = xmpp.Slixfeed.make_message(
|
||||
# # self, mto=jid, mbody=new, mtype=chat_type)
|
||||
# message = xmpp.Slixfeed.make_message(
|
||||
# self, mto=jid, mbody=media, mtype=chat_type)
|
||||
# message['oob']['url'] = media
|
||||
# message.send()
|
||||
|
||||
# TODO Do not refresh task before
|
||||
# verifying that it was completed.
|
||||
|
||||
# await start_tasks_xmpp(self, jid, ['status'])
|
||||
# await refresh_task(self, jid, send_update, 'interval')
|
||||
|
||||
# interval = await initdb(
|
||||
# jid,
|
||||
# sqlite.get_settings_value,
|
||||
# "interval"
|
||||
# )
|
||||
# self.task_manager[jid]["interval"] = loop.call_at(
|
||||
# loop.time() + 60 * interval,
|
||||
# loop.create_task,
|
||||
# send_update(jid)
|
||||
# )
|
||||
|
||||
# print(await current_time(), "asyncio.get_event_loop().time()")
|
||||
# print(await current_time(), asyncio.get_event_loop().time())
|
||||
# await asyncio.sleep(60 * interval)
|
||||
|
||||
# loop.call_later(
|
||||
# 60 * interval,
|
||||
# loop.create_task,
|
||||
# send_update(jid)
|
||||
# )
|
||||
|
||||
# print
|
||||
# await handle_event()
|
||||
|
||||
|
||||
def clean_tasks_xmpp(self, jid, tasks=None):
|
||||
if not tasks:
|
||||
tasks = ['interval', 'status', 'check']
|
||||
|
@ -303,56 +214,6 @@ def clean_tasks_xmpp(self, jid, tasks=None):
|
|||
.format(task, jid))
|
||||
|
||||
|
||||
async def send_status(self, jid):
|
||||
"""
|
||||
Send status message.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jid : str
|
||||
Jabber ID.
|
||||
"""
|
||||
logging.info('Sending a status message to JID {}'.format(jid))
|
||||
status_text = '📜️ Slixfeed RSS News Bot'
|
||||
jid_file = jid.replace('/', '_')
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
enabled = await config.get_setting_value(db_file, 'enabled')
|
||||
if not enabled:
|
||||
status_mode = 'xa'
|
||||
status_text = '📪️ Send "Start" to receive updates'
|
||||
else:
|
||||
feeds = await sqlite.get_number_of_items(db_file, 'feeds')
|
||||
# print(await current_time(), jid, "has", feeds, "feeds")
|
||||
if not feeds:
|
||||
status_mode = 'available'
|
||||
status_text = '📪️ Send a URL from a blog or a news website'
|
||||
else:
|
||||
unread = await sqlite.get_number_of_entries_unread(db_file)
|
||||
if unread:
|
||||
status_mode = 'chat'
|
||||
status_text = '📬️ There are {} news items'.format(str(unread))
|
||||
# status_text = (
|
||||
# "📰 News items: {}"
|
||||
# ).format(str(unread))
|
||||
# status_text = (
|
||||
# "📰 You have {} news items"
|
||||
# ).format(str(unread))
|
||||
else:
|
||||
status_mode = 'available'
|
||||
status_text = '📭️ No news'
|
||||
|
||||
# breakpoint()
|
||||
# print(await current_time(), status_text, "for", jid)
|
||||
XmppPresence.send(self, jid, status_text, status_type=status_mode)
|
||||
# await asyncio.sleep(60 * 20)
|
||||
await refresh_task(self, jid, send_status, 'status', '90')
|
||||
# loop.call_at(
|
||||
# loop.time() + 60 * 20,
|
||||
# loop.create_task,
|
||||
# send_status(jid)
|
||||
# )
|
||||
|
||||
|
||||
async def refresh_task(self, jid, callback, key, val=None):
|
||||
"""
|
||||
Apply new setting at runtime.
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
__version__ = '0.1.3'
|
||||
__version_info__ = (0, 1, 3)
|
||||
__version__ = '0.1.4'
|
||||
__version_info__ = (0, 1, 4)
|
||||
|
|
|
@ -303,7 +303,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
jid = presence['from'].bare
|
||||
if jid in self.boundjid.bare:
|
||||
return
|
||||
print('JID available:', jid)
|
||||
logging.info('JID {} is available'.format(jid))
|
||||
# FIXME TODO Find out what is the source responsible for a couple presences with empty message
|
||||
# NOTE This is a temporary solution
|
||||
await asyncio.sleep(10)
|
||||
|
@ -326,7 +326,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
|
||||
def on_presence_unavailable(self, presence):
|
||||
jid = presence['from'].bare
|
||||
print('JID unavailable:', jid)
|
||||
logging.info('JID {} is unavailable'.format(jid))
|
||||
# await task.stop_tasks(self, jid)
|
||||
task.clean_tasks_xmpp(self, jid)
|
||||
|
||||
|
@ -346,7 +346,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
# If bookmarks, remove groupchat JID into file
|
||||
def on_presence_error(self, presence):
|
||||
jid = presence["from"].bare
|
||||
print('JID error:', jid)
|
||||
logging.info('JID {} (error)'.format(jid))
|
||||
task.clean_tasks_xmpp(self, jid)
|
||||
|
||||
|
||||
|
@ -482,7 +482,9 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscriptions(self, iq, session):
|
||||
form = self['xep_0004'].make_form('form', 'Subscriptions')
|
||||
jid = session['from'].bare
|
||||
form = self['xep_0004'].make_form('form',
|
||||
'Subscriptions for {}'.format(jid))
|
||||
form['instructions'] = '📰️ Manage subscriptions.'
|
||||
# form.addField(var='interval',
|
||||
# ftype='text-single',
|
||||
|
@ -491,7 +493,6 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
ftype='list-multi',
|
||||
label='Select subscriptions',
|
||||
desc='Select subscription(s) to edit.')
|
||||
jid = session['from'].bare
|
||||
jid_file = jid
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
subscriptions = await sqlite.get_feeds(db_file)
|
||||
|
@ -523,7 +524,9 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
# single: Delete, Disable, Reset and Rename
|
||||
# several: Delete, Disable, Reset
|
||||
async def _handle_subscription_editor(self, iq, session):
|
||||
form = self['xep_0004'].make_form('form', 'Subscriptions')
|
||||
jid = session['from'].bare
|
||||
form = self['xep_0004'].make_form('form',
|
||||
'Subscriptions for {}'.format(jid))
|
||||
form['instructions'] = '🗞️ Edit subscriptions.'
|
||||
options = form.add_field(var='enable',
|
||||
ftype='boolean',
|
||||
|
@ -542,7 +545,9 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_bookmarks(self, iq, session):
|
||||
form = self['xep_0004'].make_form('form', 'Bookmarks')
|
||||
jid = session['from'].bare
|
||||
form = self['xep_0004'].make_form('form',
|
||||
'Bookmarks for {}'.format(jid))
|
||||
form['instructions'] = '📑️ Organize bookmarks.'
|
||||
options = form.add_field(var='bookmarks',
|
||||
# ftype='list-multi'
|
||||
|
@ -559,7 +564,9 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_bookmarks_editor(self, iq, session):
|
||||
form = self['xep_0004'].make_form('form', 'Bookmarks')
|
||||
jid = session['from'].bare
|
||||
form = self['xep_0004'].make_form('form',
|
||||
'Bookmarks for {}'.format(jid))
|
||||
form['instructions'] = '📝️ Edit bookmarks.'
|
||||
form.addField(var='name',
|
||||
ftype='text-single',
|
||||
|
@ -605,11 +612,13 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
session. Additional, custom data may be saved
|
||||
here to persist across handler callbacks.
|
||||
"""
|
||||
form = self['xep_0004'].make_form('form', 'Settings')
|
||||
form['instructions'] = ('📮️ Customize news updates.')
|
||||
jid = session['from'].bare
|
||||
jid_file = jid
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
form = self['xep_0004'].make_form('form',
|
||||
'Settings for {}'.format(jid))
|
||||
form['instructions'] = ('📮️ Customize news updates.')
|
||||
|
||||
value = await config.get_setting_value(db_file, 'enabled')
|
||||
value = int(value)
|
||||
if value:
|
||||
|
@ -621,6 +630,19 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
label='Enable',
|
||||
desc='Enable news updates.',
|
||||
value=value)
|
||||
|
||||
value = await config.get_setting_value(db_file, 'media')
|
||||
value = int(value)
|
||||
if value:
|
||||
value = True
|
||||
else:
|
||||
value = False
|
||||
form.add_field(var='media',
|
||||
ftype='boolean',
|
||||
desc='Send audio, images or videos if found.',
|
||||
label='Display media',
|
||||
value=value)
|
||||
|
||||
value = await config.get_setting_value(db_file, 'old')
|
||||
value = int(value)
|
||||
if value:
|
||||
|
@ -629,11 +651,11 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
value = True
|
||||
form.add_field(var='old',
|
||||
ftype='boolean',
|
||||
desc='Do not mark items of newly added subscriptions '
|
||||
'as read.',
|
||||
desc='Send old items of newly added subscriptions.',
|
||||
# label='Send only new items',
|
||||
label='Include old news',
|
||||
value=value)
|
||||
|
||||
value = await config.get_setting_value(db_file, 'interval')
|
||||
value = str(int(value/60))
|
||||
options = form.add_field(var='interval',
|
||||
|
@ -647,6 +669,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
lab = str(int(i/60))
|
||||
options.addOption(lab, var)
|
||||
i += 60
|
||||
|
||||
value = await config.get_setting_value(db_file, 'archive')
|
||||
value = str(value)
|
||||
options = form.add_field(var='archive',
|
||||
|
@ -658,7 +681,8 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
while i <= 500:
|
||||
x = str(i)
|
||||
options.addOption(x, x)
|
||||
i += 1
|
||||
i += 50
|
||||
|
||||
value = await config.get_setting_value(db_file, 'quantum')
|
||||
value = str(value)
|
||||
options = form.add_field(var='quantum',
|
||||
|
@ -667,10 +691,11 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
desc='Set amount of updates per update.',
|
||||
value='3')
|
||||
i = 1
|
||||
while i <= 10:
|
||||
while i <= 5:
|
||||
x = str(i)
|
||||
options.addOption(x, x)
|
||||
i += 1
|
||||
|
||||
session['payload'] = form
|
||||
session['next'] = self._handle_settings_complete
|
||||
session['has_next'] = False
|
||||
|
@ -701,7 +726,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
for value in values:
|
||||
key = value
|
||||
val = values[value]
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
|
|
@ -621,7 +621,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
|
|||
for value in values:
|
||||
key = value
|
||||
val = values[value]
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
|
|
@ -44,31 +44,32 @@ class XmppConnect:
|
|||
rtt = None
|
||||
try:
|
||||
rtt = await self['xep_0199'].ping(jid, timeout=10)
|
||||
logging.info("Success! RTT: %s", rtt)
|
||||
logging.info('Success! RTT: %s', rtt)
|
||||
except IqError as e:
|
||||
logging.info("Error pinging %s: %s",
|
||||
logging.info('Error pinging %s: %s',
|
||||
jid,
|
||||
e.iq['error']['condition'])
|
||||
except IqTimeout:
|
||||
logging.info("No response from %s", jid)
|
||||
logging.info('No response from %s', jid)
|
||||
if not rtt:
|
||||
logging.info('Disconnecting...')
|
||||
self.disconnect()
|
||||
await asyncio.sleep(60 * 1)
|
||||
|
||||
|
||||
async def recover(self, message):
|
||||
logging.warning(message)
|
||||
print(current_time(), message, "Attempting to reconnect.")
|
||||
print(current_time(), message, 'Attempting to reconnect.')
|
||||
self.connection_attempts += 1
|
||||
# if self.connection_attempts <= self.max_connection_attempts:
|
||||
# self.reconnect(wait=5.0) # wait a bit before attempting to reconnect
|
||||
# else:
|
||||
# print(current_time(),"Maximum connection attempts exceeded.")
|
||||
# logging.error("Maximum connection attempts exceeded.")
|
||||
print(current_time(), "Attempt number", self.connection_attempts)
|
||||
seconds = (get_value("accounts", "XMPP", "reconnect_timeout")) or 30
|
||||
print(current_time(), 'Attempt number', self.connection_attempts)
|
||||
seconds = (get_value('accounts', 'XMPP', 'reconnect_timeout')) or 30
|
||||
seconds = int(seconds)
|
||||
print(current_time(), "Next attempt within", seconds, "seconds")
|
||||
print(current_time(), 'Next attempt within', seconds, 'seconds')
|
||||
# NOTE asyncio.sleep doesn't interval as expected
|
||||
# await asyncio.sleep(seconds)
|
||||
sleep(seconds)
|
||||
|
|
|
@ -363,11 +363,12 @@ async def message(self, message):
|
|||
response = 'Value may not be greater than 500.'
|
||||
else:
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
if await sqlite.get_settings_value(db_file,
|
||||
[key, val]):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
print('update archive')
|
||||
await sqlite.update_settings_value(db_file,
|
||||
[key, val])
|
||||
else:
|
||||
print('set archive')
|
||||
await sqlite.set_settings_value(db_file,
|
||||
[key, val])
|
||||
response = ('Maximum archived items has '
|
||||
|
@ -389,6 +390,11 @@ async def message(self, message):
|
|||
response = ('This action is restricted. '
|
||||
'Type: removing bookmarks.')
|
||||
XmppMessage.send_reply(self, message, response)
|
||||
case 'default':
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
await sqlite.delete_settings(db_file)
|
||||
response = ('Default settings have been restored.')
|
||||
XmppMessage.send_reply(self, message, response)
|
||||
case 'bookmarks':
|
||||
if jid == config.get_value('accounts', 'XMPP', 'operator'):
|
||||
response = await action.list_bookmarks(self)
|
||||
|
@ -573,8 +579,7 @@ async def message(self, message):
|
|||
try:
|
||||
val = int(val)
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
if await sqlite.get_settings_value(db_file,
|
||||
[key, val]):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file,
|
||||
[key, val])
|
||||
else:
|
||||
|
@ -619,7 +624,7 @@ async def message(self, message):
|
|||
db_file = config.get_pathname_to_database(jid_file)
|
||||
key = 'media'
|
||||
val = 0
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -629,7 +634,7 @@ async def message(self, message):
|
|||
db_file = config.get_pathname_to_database(jid_file)
|
||||
key = 'media'
|
||||
val = 1
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -639,7 +644,7 @@ async def message(self, message):
|
|||
db_file = config.get_pathname_to_database(jid_file)
|
||||
key = 'old'
|
||||
val = 0
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -650,7 +655,7 @@ async def message(self, message):
|
|||
# num = message_text[5:]
|
||||
# await task.send_update(self, jid, num)
|
||||
|
||||
await task.xmpp_send_update(self, jid)
|
||||
await action.xmpp_send_update(self, jid)
|
||||
|
||||
# task.clean_tasks_xmpp(self, jid, ['interval', 'status'])
|
||||
# await task.start_tasks_xmpp(self, jid, ['status', 'interval'])
|
||||
|
@ -662,7 +667,7 @@ async def message(self, message):
|
|||
db_file = config.get_pathname_to_database(jid_file)
|
||||
key = 'old'
|
||||
val = 1
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file, [key, val])
|
||||
else:
|
||||
await sqlite.set_settings_value(db_file, [key, val])
|
||||
|
@ -678,7 +683,7 @@ async def message(self, message):
|
|||
# 'Every update will contain {} news items.'
|
||||
# ).format(response)
|
||||
db_file = config.get_pathname_to_database(jid_file)
|
||||
if await sqlite.get_settings_value(db_file, key):
|
||||
if sqlite.get_settings_value(db_file, key):
|
||||
await sqlite.update_settings_value(db_file,
|
||||
[key, val])
|
||||
else:
|
||||
|
|
|
@ -12,12 +12,12 @@ async def get_chat_type(self, jid):
|
|||
Check whether a JID is of MUC.
|
||||
|
||||
If iqresult["disco_info"]["features"] contains XML namespace
|
||||
of 'http://jabber.org/protocol/muc', then it is a "groupchat".
|
||||
of 'http://jabber.org/protocol/muc', then it is a 'groupchat'.
|
||||
|
||||
Unless it has forward slash, which would indicate that it is
|
||||
a chat which is conducted through a groupchat.
|
||||
|
||||
Otherwise, determine type "chat".
|
||||
Otherwise, determine type 'chat'.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -27,7 +27,7 @@ async def get_chat_type(self, jid):
|
|||
Returns
|
||||
-------
|
||||
chat_type : str
|
||||
"chat" or "groupchat.
|
||||
'chat' or 'groupchat'.
|
||||
"""
|
||||
try:
|
||||
iqresult = await self["xep_0030"].get_info(jid=jid)
|
||||
|
|
Loading…
Reference in a new issue