From f6bc76fdf89f70790b66df97f32454424e70eb37 Mon Sep 17 00:00:00 2001 From: Schimon Jehudah Date: Sun, 11 Feb 2024 21:31:31 +0000 Subject: [PATCH] Fix settings update. Add option to restore default settings. Reorganize code. Thank you mirux. --- slixfeed/__main__.py | 4 +- slixfeed/action.py | 271 +++++++++++++++++++++++-------- slixfeed/assets/commands.toml | 10 +- slixfeed/assets/information.toml | 5 +- slixfeed/config.py | 2 +- slixfeed/sqlite.py | 14 +- slixfeed/task.py | 199 ++++------------------- slixfeed/version.py | 4 +- slixfeed/xmpp/client.py | 55 +++++-- slixfeed/xmpp/component.py | 2 +- slixfeed/xmpp/connect.py | 15 +- slixfeed/xmpp/process.py | 25 +-- slixfeed/xmpp/utility.py | 6 +- 13 files changed, 328 insertions(+), 284 deletions(-) diff --git a/slixfeed/__main__.py b/slixfeed/__main__.py index 238ea86..c00e51c 100644 --- a/slixfeed/__main__.py +++ b/slixfeed/__main__.py @@ -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 diff --git a/slixfeed/action.py b/slixfeed/action.py index cae053c..8bc2f33 100644 --- a/slixfeed/action.py +++ b/slixfeed/action.py @@ -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,27 +556,23 @@ async def list_statistics(db_file): # value = "Default" # values.extend([value]) - message = ( - "```" - "\nSTATISTICS\n" - "News items : {}/{}\n" - "News sources : {}/{}\n" - "\nOPTIONS\n" - "Items to archive : {}\n" - "Update interval : {}\n" - "Items per update : {}\n" - "Operation status : {}\n" - "```" - ).format( - entries_unread, - entries_all, - feeds_active, - feeds_all, - key_archive, - key_interval, - key_quantum, - key_enabled - ) + message = ("```" + "\nSTATISTICS\n" + "News items : {}/{}\n" + "News sources : {}/{}\n" + "\nOPTIONS\n" + "Items to archive : {}\n" + "Update interval : {}\n" + "Items per update : {}\n" + "Operation status : {}\n" + "```").format(entries_unread, + entries_all, + feeds_active, + feeds_all, + key_archive, + key_interval, + key_quantum, + 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" - "URL : {}\n" - # "Updated : {}\n" - # "Status : {}\n" - "ID : {}\n" - "\n" - ).format( - str(result[0]), str(result[1]), str(result[2])) + message += ("Name : {}\n" + "URL : {}\n" + # "Updated : {}\n" + # "Status : {}\n" + "ID : {}\n" + "\n" + .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 diff --git a/slixfeed/assets/commands.toml b/slixfeed/assets/commands.toml index 03b315e..a8bf19b 100644 --- a/slixfeed/assets/commands.toml +++ b/slixfeed/assets/commands.toml @@ -162,9 +162,9 @@ archive = """ archive Number of news items to archive (maximum value 500). """ -remove = """ -remove -Remove feed of from subscription list by given . +default = """ +default +Restore default settings. """ disable = """ disable @@ -174,6 +174,10 @@ enable = """ enable Enable updates for feed of given . """ +remove = """ +remove +Remove feed of from subscription list by given . +""" reset = """ reset Mark all entries as read and remove all archived entries diff --git a/slixfeed/assets/information.toml b/slixfeed/assets/information.toml index 6df51ad..59cda37 100644 --- a/slixfeed/assets/information.toml +++ b/slixfeed/assets/information.toml @@ -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 (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). """ diff --git a/slixfeed/config.py b/slixfeed/config.py index 3a9fdea..31f8d82 100644 --- a/slixfeed/config.py +++ b/slixfeed/config.py @@ -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) diff --git a/slixfeed/sqlite.py b/slixfeed/sqlite.py index 6515398..1397782 100644 --- a/slixfeed/sqlite.py +++ b/slixfeed/sqlite.py @@ -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. diff --git a/slixfeed/task.py b/slixfeed/task.py index 3f1ba13..aa0b0b3 100644 --- a/slixfeed/task.py +++ b/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. diff --git a/slixfeed/version.py b/slixfeed/version.py index e88b087..e6b202e 100644 --- a/slixfeed/version.py +++ b/slixfeed/version.py @@ -1,2 +1,2 @@ -__version__ = '0.1.3' -__version_info__ = (0, 1, 3) +__version__ = '0.1.4' +__version_info__ = (0, 1, 4) diff --git a/slixfeed/xmpp/client.py b/slixfeed/xmpp/client.py index 484df5b..3e44b5c 100644 --- a/slixfeed/xmpp/client.py +++ b/slixfeed/xmpp/client.py @@ -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]) diff --git a/slixfeed/xmpp/component.py b/slixfeed/xmpp/component.py index 01565b5..a00725b 100644 --- a/slixfeed/xmpp/component.py +++ b/slixfeed/xmpp/component.py @@ -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]) diff --git a/slixfeed/xmpp/connect.py b/slixfeed/xmpp/connect.py index 949e533..35220e2 100644 --- a/slixfeed/xmpp/connect.py +++ b/slixfeed/xmpp/connect.py @@ -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) diff --git a/slixfeed/xmpp/process.py b/slixfeed/xmpp/process.py index dae73c3..15cb776 100644 --- a/slixfeed/xmpp/process.py +++ b/slixfeed/xmpp/process.py @@ -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: diff --git a/slixfeed/xmpp/utility.py b/slixfeed/xmpp/utility.py index 24754a1..83b7bc7 100644 --- a/slixfeed/xmpp/utility.py +++ b/slixfeed/xmpp/utility.py @@ -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)