Manage settings from a dict as a handler.

Make the inclusive/main  filter optional.
This commit is contained in:
Schimon Jehudah 2024-03-07 14:52:51 +00:00
parent aa5f45cddc
commit 5d1cb85a36
10 changed files with 343 additions and 263 deletions

View file

@ -80,14 +80,13 @@ import os
#import slixfeed.matrix #import slixfeed.matrix
import slixfeed.config as config import slixfeed.config as config
from slixfeed.config import ConfigXMPP
from slixfeed.version import __version__ from slixfeed.version import __version__
# import socks # import socks
# import socket # import socket
base = ConfigXMPP() xmpp_type = config.get_value('accounts', 'XMPP', 'type')
xmpp_type = base.setting['type']
if not xmpp_type: if not xmpp_type:
raise Exception('Key type is missing from accounts.ini.') raise Exception('Key type is missing from accounts.ini.')
@ -100,7 +99,7 @@ match xmpp_type:
from slixfeed.xmpp.component import SlixfeedComponent from slixfeed.xmpp.component import SlixfeedComponent
from slixfeed.config import ConfigComponent as ConfigAccount from slixfeed.config import ConfigComponent as ConfigAccount
account = ConfigAccount() account = ConfigAccount() # TODO Delete as soon as posible after is no longer needed
class JabberComponent: class JabberComponent:
def __init__(self, jid, secret, hostname, port, alias=None): def __init__(self, jid, secret, hostname, port, alias=None):

View file

@ -123,8 +123,7 @@ async def xmpp_send_status(self, jid):
status_text = '📜️ Slixfeed RSS News Bot' status_text = '📜️ Slixfeed RSS News Bot'
jid_file = jid.replace('/', '_') jid_file = jid.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) enabled = self.settings[jid]['enabled'] or self.settings['default']['enabled']
enabled = setting.enabled
if not enabled: if not enabled:
status_mode = 'xa' status_mode = 'xa'
status_text = '📪️ Send "Start" to receive updates' status_text = '📪️ Send "Start" to receive updates'
@ -176,12 +175,11 @@ async def xmpp_send_update(self, jid, num=None):
logger.debug('{}: jid: {} num: {}'.format(function_name, jid, num)) logger.debug('{}: jid: {} num: {}'.format(function_name, jid, num))
jid_file = jid.replace('/', '_') jid_file = jid.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) enabled = self.settings[jid]['enabled'] or self.settings['default']['enabled']
enabled = setting.enabled
if enabled: if enabled:
show_media = setting.media show_media = self.settings[jid]['media'] or self.settings['default']['media']
if not num: if not num:
num = setting.quantum num = self.settings[jid]['quantum'] or self.settings['default']['quantum']
else: else:
num = int(num) num = int(num)
results = await sqlite.get_unread_entries(db_file, num) results = await sqlite.get_unread_entries(db_file, num)
@ -198,7 +196,7 @@ async def xmpp_send_update(self, jid, num=None):
date = result[6] date = result[6]
title_f = sqlite.get_feed_title(db_file, feed_id) title_f = sqlite.get_feed_title(db_file, feed_id)
title_f = title_f[0] title_f = title_f[0]
news_digest += list_unread_entries(result, title_f, jid_file) news_digest += list_unread_entries(self, result, title_f, jid)
# print(db_file) # print(db_file)
# print(result[0]) # print(result[0])
# breakpoint() # breakpoint()
@ -423,10 +421,10 @@ def is_feed(feed):
return value return value
def list_unread_entries(result, feed_title, jid_file): def list_unread_entries(self, result, feed_title, jid):
function_name = sys._getframe().f_code.co_name function_name = sys._getframe().f_code.co_name
logger.debug('{}: feed_title: {} jid_file: {}' logger.debug('{}: feed_title: {} jid: {}'
.format(function_name, feed_title, jid_file)) .format(function_name, feed_title, jid))
# TODO Add filtering # TODO Add filtering
# TODO Do this when entry is added to list and mark it as read # TODO Do this when entry is added to list and mark it as read
# DONE! # DONE!
@ -463,9 +461,7 @@ def list_unread_entries(result, feed_title, jid_file):
summary = summary.replace('\n', ' ') summary = summary.replace('\n', ' ')
summary = summary.replace(' ', ' ') summary = summary.replace(' ', ' ')
summary = summary.replace(' ', ' ') summary = summary.replace(' ', ' ')
db_file = config.get_pathname_to_database(jid_file) length = self.settings[jid]['length'] or self.settings['default']['length']
setting = Config(db_file)
length = setting.length
length = int(length) length = int(length)
summary = summary[:length] + " […]" summary = summary[:length] + " […]"
# summary = summary.strip().split('\n') # summary = summary.strip().split('\n')
@ -476,7 +472,7 @@ def list_unread_entries(result, feed_title, jid_file):
link = (replace_hostname(link, "link")) or link link = (replace_hostname(link, "link")) or link
# news_item = ("\n{}\n{}\n{} [{}]\n").format(str(title), str(link), # news_item = ("\n{}\n{}\n{} [{}]\n").format(str(title), str(link),
# str(feed_title), str(ix)) # str(feed_title), str(ix))
formatting = setting.formatting formatting = self.settings[jid]['formatting'] or self.settings['default']['formatting']
news_item = formatting.format(feed_title=feed_title, news_item = formatting.format(feed_title=feed_title,
title=title, title=title,
summary=summary, summary=summary,
@ -521,9 +517,52 @@ def list_feeds_by_query(db_file, query):
return message return message
async def list_options(self, jid_bare):
"""
Print options.
Parameters
----------
jid_bare : str
Jabber ID.
Returns
-------
msg : str
Options as message.
"""
function_name = sys._getframe().f_code.co_name
logger.debug('{}: jid: {}'
.format(function_name, jid_bare))
# msg = """You have {} unread news items out of {} from {} news sources.
# """.format(unread_entries, entries, feeds)
# try:
# value = cur.execute(sql, par).fetchone()[0]
# except:
# print("Error for key:", key)
# value = "Default"
# values.extend([value])
message = ("Options:"
"\n"
"```"
"\n"
"Items to archive : {}\n"
"Update interval : {}\n"
"Items per update : {}\n"
"Operation status : {}\n"
"```").format(self.settings[jid_bare]['archive'],
self.settings[jid_bare]['interval'],
self.settings[jid_bare]['quantum'],
self.settings[jid_bare]['enabled'])
return message
async def list_statistics(db_file): async def list_statistics(db_file):
""" """
Return table statistics. Print statistics.
Parameters Parameters
---------- ----------
@ -544,11 +583,6 @@ async def list_statistics(db_file):
entries_all = entries + archive entries_all = entries + archive
feeds_active = await sqlite.get_number_of_feeds_active(db_file) feeds_active = await sqlite.get_number_of_feeds_active(db_file)
feeds_all = await sqlite.get_number_of_items(db_file, 'feeds') feeds_all = await sqlite.get_number_of_items(db_file, 'feeds')
setting = Config(db_file)
key_archive = setting.archive
key_interval = setting.interval
key_quantum = setting.quantum
key_enabled = setting.enabled
# msg = """You have {} unread news items out of {} from {} news sources. # msg = """You have {} unread news items out of {} from {} news sources.
# """.format(unread_entries, entries, feeds) # """.format(unread_entries, entries, feeds)
@ -560,23 +594,16 @@ async def list_statistics(db_file):
# value = "Default" # value = "Default"
# values.extend([value]) # values.extend([value])
message = ("```" message = ("Statistics:"
"\nSTATISTICS\n" "\n"
"```"
"\n"
"News items : {}/{}\n" "News items : {}/{}\n"
"News sources : {}/{}\n" "News sources : {}/{}\n"
"\nOPTIONS\n"
"Items to archive : {}\n"
"Update interval : {}\n"
"Items per update : {}\n"
"Operation status : {}\n"
"```").format(entries_unread, "```").format(entries_unread,
entries_all, entries_all,
feeds_active, feeds_active,
feeds_all, feeds_all)
key_archive,
key_interval,
key_quantum,
key_enabled)
return message return message
@ -713,11 +740,10 @@ async def import_opml(db_file, url):
return difference return difference
async def add_feed(db_file, url): async def add_feed(self, jid_bare, db_file, url):
function_name = sys._getframe().f_code.co_name function_name = sys._getframe().f_code.co_name
logger.debug('{}: db_file: {} url: {}' logger.debug('{}: db_file: {} url: {}'
.format(function_name, db_file, url)) .format(function_name, db_file, url))
setting = Config(db_file)
while True: while True:
exist = await sqlite.get_feed_id_and_name(db_file, url) exist = await sqlite.get_feed_id_and_name(db_file, url)
if not exist: if not exist:
@ -759,8 +785,8 @@ async def add_feed(db_file, url):
language=language, language=language,
status_code=status_code, status_code=status_code,
updated=updated) updated=updated)
await scan(db_file, url) await scan(self, jid_bare, db_file, url)
old = setting.old old = self.settings[jid_bare]['old']
feed_id = await sqlite.get_feed_id(db_file, url) feed_id = await sqlite.get_feed_id(db_file, url)
feed_id = feed_id[0] feed_id = feed_id[0]
if not old: if not old:
@ -809,8 +835,8 @@ async def add_feed(db_file, url):
language=language, language=language,
status_code=status_code, status_code=status_code,
updated=updated) updated=updated)
await scan_json(db_file, url) await scan_json(self, jid_bare, db_file, url)
old = setting.old old = self.settings[jid_bare]['old']
if not old: if not old:
feed_id = await sqlite.get_feed_id(db_file, url) feed_id = await sqlite.get_feed_id(db_file, url)
feed_id = feed_id[0] feed_id = feed_id[0]
@ -872,7 +898,7 @@ async def add_feed(db_file, url):
return result_final return result_final
async def scan_json(db_file, url): async def scan_json(self, jid_bare, db_file, url):
""" """
Check feeds for new entries. Check feeds for new entries.
@ -895,8 +921,7 @@ async def scan_json(db_file, url):
if document and status == 200: if document and status == 200:
feed = json.loads(document) feed = json.loads(document)
entries = feed["items"] entries = feed["items"]
await remove_nonexistent_entries_json( await remove_nonexistent_entries_json(self, jid_bare, db_file, url, feed)
db_file, url, feed)
try: try:
feed_id = await sqlite.get_feed_id(db_file, url) feed_id = await sqlite.get_feed_id(db_file, url)
feed_id = feed_id[0] feed_id = feed_id[0]
@ -966,17 +991,20 @@ async def scan_json(db_file, url):
"{} {} {}" "{} {} {}"
).format( ).format(
title, summary, pathname) title, summary, pathname)
allow_list = config.is_include_keyword(db_file, "allow", if self.settings['default']['filter']:
string) print('Filter is now processing data.')
if not allow_list: allow_list = config.is_include_keyword(db_file,
reject_list = config.is_include_keyword(db_file, "deny", "allow", string)
string) if not allow_list:
if reject_list: reject_list = config.is_include_keyword(db_file,
read_status = 1 "deny",
logger.debug('Rejected : {}' string)
'\n' if reject_list:
'Keyword : {}' read_status = 1
.format(link, reject_list)) logger.debug('Rejected : {}'
'\n'
'Keyword : {}'
.format(link, reject_list))
if isinstance(date, int): if isinstance(date, int):
logger.error('Variable "date" is int: {}'.format(date)) logger.error('Variable "date" is int: {}'.format(date))
media_link = '' media_link = ''
@ -1156,7 +1184,7 @@ async def view_entry(url, num):
# TODO Rename function name (idea: scan_and_populate) # TODO Rename function name (idea: scan_and_populate)
async def scan(db_file, url): async def scan(self, jid_bare, db_file, url):
""" """
Check feeds for new entries. Check feeds for new entries.
@ -1184,7 +1212,7 @@ async def scan(db_file, url):
feed = parse(document) feed = parse(document)
entries = feed.entries entries = feed.entries
# length = len(entries) # length = len(entries)
await remove_nonexistent_entries(db_file, url, feed) await remove_nonexistent_entries(self, jid_bare, db_file, url, feed)
try: try:
if feed.bozo: if feed.bozo:
# bozo = ( # bozo = (
@ -1251,20 +1279,22 @@ async def scan(db_file, url):
"{} {} {}" "{} {} {}"
).format( ).format(
title, summary, pathname) title, summary, pathname)
allow_list = config.is_include_keyword(db_file, "allow", if self.settings['default']['filter']:
string) print('Filter is now processing data.')
if not allow_list: allow_list = config.is_include_keyword(db_file,
reject_list = config.is_include_keyword(db_file, "deny", "allow", string)
string) if not allow_list:
if reject_list: reject_list = config.is_include_keyword(db_file,
read_status = 1 "deny",
logger.debug('Rejected : {}' string)
'\n' if reject_list:
'Keyword : {}'.format(link, read_status = 1
reject_list)) logger.debug('Rejected : {}'
'\n'
'Keyword : {}'
.format(link, reject_list))
if isinstance(date, int): if isinstance(date, int):
logger.error('Variable "date" is int: {}' logger.error('Variable "date" is int: {}'.format(date))
.format(date))
media_link = '' media_link = ''
if entry.has_key("links"): if entry.has_key("links"):
for e_link in entry.links: for e_link in entry.links:
@ -1554,7 +1584,7 @@ async def get_magnet(link):
return torrent return torrent
async def remove_nonexistent_entries(db_file, url, feed): async def remove_nonexistent_entries(self, jid_bare, db_file, url, feed):
""" """
Remove entries that don't exist in a given parsed feed. Remove entries that don't exist in a given parsed feed.
Check the entries returned from feed and delete read non Check the entries returned from feed and delete read non
@ -1576,8 +1606,7 @@ async def remove_nonexistent_entries(db_file, url, feed):
feed_id = feed_id[0] feed_id = feed_id[0]
items = await sqlite.get_entries_of_feed(db_file, feed_id) items = await sqlite.get_entries_of_feed(db_file, feed_id)
entries = feed.entries entries = feed.entries
setting = Config(db_file) limit = self.settings[jid_bare]['archive']
limit = setting.archive
for item in items: for item in items:
ix = item[0] ix = item[0]
entry_title = item[1] entry_title = item[1]
@ -1664,7 +1693,7 @@ async def remove_nonexistent_entries(db_file, url, feed):
async def remove_nonexistent_entries_json(db_file, url, feed): async def remove_nonexistent_entries_json(self, jid_bare, db_file, url, feed):
""" """
Remove entries that don't exist in a given parsed feed. Remove entries that don't exist in a given parsed feed.
Check the entries returned from feed and delete read non Check the entries returned from feed and delete read non
@ -1686,8 +1715,7 @@ async def remove_nonexistent_entries_json(db_file, url, feed):
feed_id = feed_id[0] feed_id = feed_id[0]
items = await sqlite.get_entries_of_feed(db_file, feed_id) items = await sqlite.get_entries_of_feed(db_file, feed_id)
entries = feed["items"] entries = feed["items"]
setting = Config(db_file) limit = self.settings[jid_bare]['archive']
limit = setting.archive
for item in items: for item in items:
ix = item[0] ix = item[0]
entry_title = item[1] entry_title = item[1]

View file

@ -48,8 +48,29 @@ except:
# also initiated at same level or at least at event call, then check whether # also initiated at same level or at least at event call, then check whether
# setting_jid.setting_key has value, otherwise resort to setting_default.setting_key. # setting_jid.setting_key has value, otherwise resort to setting_default.setting_key.
class Config: class Config:
def __init__(self):
self.settings = {} def add_settings_default(settings):
settings['default'] = {}
for key in ('archive', 'check', 'enabled', 'filter', 'formatting',
'interval', 'length', 'media', 'old', 'quantum'):
value = get_value('settings', 'Settings', key)
settings['default'][key] = value
def add_settings_jid(settings, jid_bare, db_file):
settings[jid_bare] = {}
for key in ('archive', 'enabled', 'filter', 'formatting', 'interval',
'length', 'media', 'old', 'quantum'):
value = sqlite.get_setting_value(db_file, key)
if value: value = value[0]
settings[jid_bare][key] = value
def add_settings_xmpp(settings):
settings['xmpp'] = {}
for key in ('operator', 'reconnect_timeout', 'type'):
value = get_value('accounts', 'XMPP', key)
settings['xmpp'][key] = value
# self.settings = {}
# initiate an empty dict and the rest would be: # initiate an empty dict and the rest would be:
# settings['account'] = {} # settings['account'] = {}
# settings['default'] = {} # settings['default'] = {}
@ -85,22 +106,6 @@ class Config:
# quantum = sqlite.get_setting_value(db_file, 'quantum') # quantum = sqlite.get_setting_value(db_file, 'quantum')
class ConfigDefault:
def __init__(self):
self.setting = {}
for key in ('archive', 'check', 'enabled', 'filter', 'formatting',
'interval', 'length', 'media', 'old', 'quantum'):
value = get_value('settings', 'Settings', key)
self.setting[key] = value
class ConfigNetwork:
def __init__(self):
self.setting = {}
for key in ('http_proxy', 'user_agent'):
value = get_value('settings', 'Network', key)
self.setting[key] = value
class ConfigXMPP: class ConfigXMPP:
def __init__(self): def __init__(self):
self.setting = {} self.setting = {}
@ -117,17 +122,31 @@ class ConfigClient:
self.setting[key] = value self.setting[key] = value
class ConfigDefault:
def __init__(self, settings):
settings['default'] = {}
for key in ('archive', 'check', 'enabled', 'filter', 'formatting',
'interval', 'length', 'media', 'old', 'quantum'):
value = get_value('settings', 'Settings', key)
settings['default'][key] = value
class ConfigNetwork:
def __init__(self, settings):
settings['network'] = {}
for key in ('http_proxy', 'user_agent'):
value = get_value('settings', 'Network', key)
settings['network'][key] = value
class ConfigJabberID: class ConfigJabberID:
def __init__(self, jid_bare=None, db_file=None): def __init__(self, settings, jid_bare, db_file):
self.setting = {} settings[jid_bare] = {}
if jid_bare and db_file: for key in ('archive', 'enabled', 'filter', 'formatting', 'interval',
self.setting[jid_bare] = {} 'length', 'media', 'old', 'quantum'):
for key in ('archive', 'enabled', 'filter', 'formatting', 'interval', value = sqlite.get_setting_value(db_file, key)
'length', 'media', 'old', 'quantum'): if value: value = value[0]
value = sqlite.get_setting_value(db_file, key) print(value)
if value: value = value[0] settings[jid_bare][key] = value
print(value)
self.setting[jid_bare][key] = value
async def set_setting_value(db_file, key, val): async def set_setting_value(db_file, key, val):

View file

@ -1378,10 +1378,8 @@ async def archive_entry(db_file, ix):
try: try:
cur.execute(sql, par) cur.execute(sql, par)
except: except:
print( print('ERROR DB deleting items from table entries at index {} '
"ERROR DB deleting items from " 'for DB {}', ix, db_file)
"table entries at index", ix
)
def get_feed_title(db_file, ix): def get_feed_title(db_file, ix):

View file

@ -59,7 +59,7 @@ import logging
import os import os
import slixfeed.action as action import slixfeed.action as action
import slixfeed.config as config import slixfeed.config as config
from slixfeed.config import ConfigJabberID from slixfeed.config import Config
# from slixfeed.dt import current_time # from slixfeed.dt import current_time
import slixfeed.sqlite as sqlite import slixfeed.sqlite as sqlite
# from xmpp import Slixfeed # from xmpp import Slixfeed
@ -109,7 +109,7 @@ await taskhandler.start_tasks(
) )
""" """
async def start_tasks_xmpp(self, jid, tasks=None): async def start_tasks_xmpp(self, jid_bare, tasks=None):
""" """
NOTE NOTE
@ -117,25 +117,25 @@ async def start_tasks_xmpp(self, jid, tasks=None):
to place task 'interval' as the last to start due to await asyncio.sleep() to place task 'interval' as the last to start due to await asyncio.sleep()
which otherwise would postpone tasks that would be set after task 'interval' which otherwise would postpone tasks that would be set after task 'interval'
""" """
if jid == self.boundjid.bare: if jid_bare == self.boundjid.bare:
return return
try: try:
self.task_manager[jid] self.task_manager[jid_bare]
except KeyError as e: except KeyError as e:
self.task_manager[jid] = {} self.task_manager[jid_bare] = {}
logging.debug('KeyError:', str(e)) logging.debug('KeyError:', str(e))
logging.info('Creating new task manager for JID {}'.format(jid)) logging.info('Creating new task manager for JID {}'.format(jid_bare))
if not tasks: if not tasks:
tasks = ['status', 'check', 'interval'] tasks = ['status', 'check', 'interval']
logging.info('Stopping tasks {} for JID {}'.format(tasks, jid)) logging.info('Stopping tasks {} for JID {}'.format(tasks, jid_bare))
for task in tasks: for task in tasks:
# if self.task_manager[jid][task]: # if self.task_manager[jid][task]:
try: try:
self.task_manager[jid][task].cancel() self.task_manager[jid_bare][task].cancel()
except: except:
logging.info('No task {} for JID {} (start_tasks_xmpp)' logging.info('No task {} for JID {} (start_tasks_xmpp)'
.format(task, jid)) .format(task, jid_bare))
logging.info('Starting tasks {} for JID {}'.format(tasks, jid)) logging.info('Starting tasks {} for JID {}'.format(tasks, jid_bare))
for task in tasks: for task in tasks:
# print("task:", task) # print("task:", task)
# print("tasks:") # print("tasks:")
@ -143,14 +143,14 @@ async def start_tasks_xmpp(self, jid, tasks=None):
# breakpoint() # breakpoint()
match task: match task:
case 'check': case 'check':
self.task_manager[jid]['check'] = asyncio.create_task( self.task_manager[jid_bare]['check'] = asyncio.create_task(
check_updates(self, jid)) check_updates(self, jid_bare))
case 'status': case 'status':
self.task_manager[jid]['status'] = asyncio.create_task( self.task_manager[jid_bare]['status'] = asyncio.create_task(
task_status(self, jid)) task_status(self, jid_bare))
case 'interval': case 'interval':
self.task_manager[jid]['interval'] = asyncio.create_task( self.task_manager[jid_bare]['interval'] = asyncio.create_task(
task_send(self, jid)) task_send(self, jid_bare))
# for task in self.task_manager[jid].values(): # for task in self.task_manager[jid].values():
# print("task_manager[jid].values()") # print("task_manager[jid].values()")
# print(self.task_manager[jid].values()) # print(self.task_manager[jid].values())
@ -167,11 +167,12 @@ async def task_status(self, jid):
await refresh_task(self, jid, task_status, 'status', '90') await refresh_task(self, jid, task_status, 'status', '90')
async def task_send(self, jid): async def task_send(self, jid_bare):
jid_file = jid.replace('/', '_') jid_file = jid_bare.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting_custom = ConfigJabberID(db_file) if jid_bare not in self.settings:
update_interval = setting_custom.interval or self.default.settings_p['interval'] Config.add_settings_jid(self.settings, jid_bare, db_file)
update_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
update_interval = 60 * int(update_interval) update_interval = 60 * int(update_interval)
last_update_time = await sqlite.get_last_update_time(db_file) last_update_time = await sqlite.get_last_update_time(db_file)
if last_update_time: if last_update_time:
@ -194,9 +195,9 @@ async def task_send(self, jid):
await sqlite.update_last_update_time(db_file) await sqlite.update_last_update_time(db_file)
else: else:
await sqlite.set_last_update_time(db_file) await sqlite.set_last_update_time(db_file)
await action.xmpp_send_update(self, jid) await action.xmpp_send_update(self, jid_bare)
await refresh_task(self, jid, task_send, 'interval') await refresh_task(self, jid_bare, task_send, 'interval')
await start_tasks_xmpp(self, jid, ['status']) await start_tasks_xmpp(self, jid_bare, ['status'])
def clean_tasks_xmpp(self, jid, tasks=None): def clean_tasks_xmpp(self, jid, tasks=None):
@ -212,7 +213,7 @@ def clean_tasks_xmpp(self, jid, tasks=None):
.format(task, jid)) .format(task, jid))
async def refresh_task(self, jid, callback, key, val=None): async def refresh_task(self, jid_bare, callback, key, val=None):
""" """
Apply new setting at runtime. Apply new setting at runtime.
@ -225,27 +226,28 @@ async def refresh_task(self, jid, callback, key, val=None):
val : str, optional val : str, optional
Value. The default is None. Value. The default is None.
""" """
logging.info('Refreshing task {} for JID {}'.format(callback, jid)) logging.info('Refreshing task {} for JID {}'.format(callback, jid_bare))
if not val: if not val:
jid_file = jid.replace('/', '_') jid_file = jid_bare.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting_custom = ConfigJabberID(db_file) if jid_bare not in self.settings:
val = setting_custom.interval or self.default.settings_p[key] Config.add_settings_jid(self.settings, jid_bare, db_file)
val = self.settings[jid_bare][key] or self.settings['default'][key]
# if self.task_manager[jid][key]: # if self.task_manager[jid][key]:
if jid in self.task_manager: if jid_bare in self.task_manager:
try: try:
self.task_manager[jid][key].cancel() self.task_manager[jid_bare][key].cancel()
except: except:
logging.info('No task of type {} to cancel for ' logging.info('No task of type {} to cancel for '
'JID {} (refresh_task)'.format(key, jid)) 'JID {} (refresh_task)'.format(key, jid_bare))
# self.task_manager[jid][key] = loop.call_at( # self.task_manager[jid][key] = loop.call_at(
# loop.time() + 60 * float(val), # loop.time() + 60 * float(val),
# loop.create_task, # loop.create_task,
# (callback(self, jid)) # (callback(self, jid))
# # send_update(jid) # # send_update(jid)
# ) # )
self.task_manager[jid][key] = loop.create_task( self.task_manager[jid_bare][key] = loop.create_task(
wait_and_run(self, callback, jid, val) wait_and_run(self, callback, jid_bare, val)
) )
# self.task_manager[jid][key] = loop.call_later( # self.task_manager[jid][key] = loop.call_later(
# 60 * float(val), # 60 * float(val),
@ -259,9 +261,9 @@ async def refresh_task(self, jid, callback, key, val=None):
# ) # )
async def wait_and_run(self, callback, jid, val): async def wait_and_run(self, callback, jid_bare, val):
await asyncio.sleep(60 * float(val)) await asyncio.sleep(60 * float(val))
await callback(self, jid) await callback(self, jid_bare)
# TODO Take this function out of # TODO Take this function out of
@ -281,7 +283,7 @@ async def check_updates(self, jid):
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
urls = await sqlite.get_active_feeds_url(db_file) urls = await sqlite.get_active_feeds_url(db_file)
for url in urls: for url in urls:
await action.scan(db_file, url) await action.scan(self, jid, db_file, url)
val = self.default.setting['check'] val = self.default.setting['check']
await asyncio.sleep(60 * float(val)) await asyncio.sleep(60 * float(val))
# Schedule to call this function again in 90 minutes # Schedule to call this function again in 90 minutes

View file

@ -1,2 +1,2 @@
__version__ = '0.1.28' __version__ = '0.1.29'
__version_info__ = (0, 1, 28) __version_info__ = (0, 1, 29)

View file

@ -43,9 +43,7 @@ import slixfeed.task as task
# from lxml import etree # from lxml import etree
import slixfeed.config as config import slixfeed.config as config
from slixfeed.config import ConfigDefault from slixfeed.config import Config
from slixfeed.config import ConfigJabberID
from slixfeed.config import ConfigXMPP
from slixfeed.log import Logger from slixfeed.log import Logger
from slixfeed.version import __version__ from slixfeed.version import __version__
from slixfeed.xmpp.bookmark import XmppBookmark from slixfeed.xmpp.bookmark import XmppBookmark
@ -119,10 +117,11 @@ class Slixfeed(slixmpp.ClientXMPP):
# Handler for ping # Handler for ping
self.task_ping_instance = {} self.task_ping_instance = {}
# Handlers for configuration # Handler for configuration
self.base = ConfigXMPP() self.settings = {}
self.custom = ConfigJabberID() # The value is {} (which is empty) # Populate handler
self.default = ConfigDefault() Config.add_settings_default(self.settings)
Config.add_settings_xmpp(self.settings)
# Handlers for connection events # Handlers for connection events
self.connection_attempts = 0 self.connection_attempts = 0
@ -268,10 +267,10 @@ class Slixfeed(slixmpp.ClientXMPP):
task.task_ping(self) task.task_ping(self)
bookmarks = await self.plugin['xep_0048'].get_bookmarks() bookmarks = await self.plugin['xep_0048'].get_bookmarks()
XmppGroupchat.autojoin(self, bookmarks) XmppGroupchat.autojoin(self, bookmarks)
if self.base['operator']: jid_operator = config.get_value('accounts', 'XMPP', 'operator')
jid_op = self.base['operator'] if jid_operator:
status_message = 'Slixfeed version {}'.format(__version__) status_message = 'Slixfeed version {}'.format(__version__)
XmppPresence.send(self, jid_op, status_message) XmppPresence.send(self, jid_operator, status_message)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{} (time: {})'.format(function_name, if difference > 1: logger.warning('{} (time: {})'.format(function_name,
@ -315,6 +314,10 @@ class Slixfeed(slixmpp.ClientXMPP):
message_log = '{}: jid_full: {}' message_log = '{}: jid_full: {}'
logger.debug(message_log.format(function_name, jid_full)) logger.debug(message_log.format(function_name, jid_full))
jid_bare = message['from'].bare jid_bare = message['from'].bare
jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file)
if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
if jid_bare == self.boundjid.bare: if jid_bare == self.boundjid.bare:
status_type = 'dnd' status_type = 'dnd'
status_message = ('Slixfeed is not designed to receive messages ' status_message = ('Slixfeed is not designed to receive messages '
@ -432,9 +435,9 @@ class Slixfeed(slixmpp.ClientXMPP):
self.on_presence_unavailable) self.on_presence_unavailable)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{}: jid_full: {} (time: {})' if difference > 15: logger.warning('{}: jid_full: {} (time: {})'
.format(function_name, jid_full, .format(function_name, jid_full,
difference)) difference))
def on_presence_unsubscribed(self, presence): def on_presence_unsubscribed(self, presence):
@ -524,8 +527,8 @@ class Slixfeed(slixmpp.ClientXMPP):
await task.start_tasks_xmpp(self, jid_bare, key_list) await task.start_tasks_xmpp(self, jid_bare, key_list)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{} (time: {})'.format(function_name, if difference > 10: logger.warning('{} (time: {})'.format(function_name,
difference)) difference))
async def on_chatstate_composing(self, message): async def on_chatstate_composing(self, message):
@ -662,7 +665,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# ) # )
# NOTE https://codeberg.org/poezio/slixmpp/issues/3515 # NOTE https://codeberg.org/poezio/slixmpp/issues/3515
# if jid == self.base['operator']: # if jid == self.settings['xmpp']['operator']:
self['xep_0050'].add_command(node='recent', self['xep_0050'].add_command(node='recent',
name='📰️ Browse', name='📰️ Browse',
handler=self._handle_recent) handler=self._handle_recent)
@ -711,9 +714,8 @@ class Slixfeed(slixmpp.ClientXMPP):
jid_bare = session['from'].bare jid_bare = session['from'].bare
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
# if not self.custom.setting and jid_bare not in self.custom.setting: if jid_bare not in self.settings:
if jid_bare not in self.custom.setting: Config.add_settings_jid(self.settings, jid_bare, db_file)
self.custom = ConfigJabberID(jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Profile') form = self['xep_0004'].make_form('form', 'Profile')
form['instructions'] = ('Displaying information\nJabber ID {}' form['instructions'] = ('Displaying information\nJabber ID {}'
.format(jid_bare)) .format(jid_bare))
@ -739,42 +741,42 @@ class Slixfeed(slixmpp.ClientXMPP):
value=unread) value=unread)
form.add_field(ftype='fixed', form.add_field(ftype='fixed',
value='Options') value='Options')
key_archive = self.custom.setting[jid_bare]['archive'] or self.default.setting['archive'] key_archive = self.settings[jid_bare]['archive'] or self.settings['default']['archive']
key_archive = str(key_archive) key_archive = str(key_archive)
form.add_field(label='Archive', form.add_field(label='Archive',
ftype='text-single', ftype='text-single',
value=key_archive) value=key_archive)
key_enabled = self.custom.setting[jid_bare]['enabled'] or self.default.setting['enabled'] key_enabled = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
key_enabled = str(key_enabled) key_enabled = str(key_enabled)
form.add_field(label='Enabled', form.add_field(label='Enabled',
ftype='text-single', ftype='text-single',
value=key_enabled) value=key_enabled)
key_interval = self.custom.setting[jid_bare]['interval'] or self.default.setting['interval'] key_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
key_interval = str(key_interval) key_interval = str(key_interval)
form.add_field(label='Interval', form.add_field(label='Interval',
ftype='text-single', ftype='text-single',
value=key_interval) value=key_interval)
key_length = self.custom.setting[jid_bare]['length'] or self.default.setting['length'] key_length = self.settings[jid_bare]['length'] or self.settings['default']['length']
key_length = str(key_length) key_length = str(key_length)
form.add_field(label='Length', form.add_field(label='Length',
ftype='text-single', ftype='text-single',
value=key_length) value=key_length)
key_media = self.custom.setting[jid_bare]['media'] or self.default.setting['media'] key_media = self.settings[jid_bare]['media'] or self.settings['default']['media']
key_media = str(key_media) key_media = str(key_media)
form.add_field(label='Media', form.add_field(label='Media',
ftype='text-single', ftype='text-single',
value=key_media) value=key_media)
key_old = self.custom.setting[jid_bare]['old'] or self.default.setting['old'] key_old = self.settings[jid_bare]['old'] or self.settings['default']['old']
key_old = str(key_old) key_old = str(key_old)
form.add_field(label='Old', form.add_field(label='Old',
ftype='text-single', ftype='text-single',
value=key_old) value=key_old)
key_quantum = self.custom.setting[jid_bare]['quantum'] or self.default.setting['quantum'] key_quantum = self.settings[jid_bare]['quantum'] or self.settings['default']['quantum']
key_quantum = str(key_quantum) key_quantum = str(key_quantum)
form.add_field(label='Quantum', form.add_field(label='Quantum',
ftype='text-single', ftype='text-single',
value=key_quantum) value=key_quantum)
update_interval = self.custom.setting[jid_bare]['interval'] or self.default.setting['interval'] update_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
update_interval = str(update_interval) update_interval = str(update_interval)
update_interval = 60 * int(update_interval) update_interval = 60 * int(update_interval)
last_update_time = await sqlite.get_last_update_time(db_file) last_update_time = await sqlite.get_last_update_time(db_file)
@ -1930,7 +1932,7 @@ class Slixfeed(slixmpp.ClientXMPP):
options.addOption('Import', 'import') options.addOption('Import', 'import')
options.addOption('Export', 'export') options.addOption('Export', 'export')
jid = session['from'].bare jid = session['from'].bare
if jid == self.base['operator']: if jid == self.settings['xmpp']['operator']:
options.addOption('Administration', 'admin') options.addOption('Administration', 'admin')
session['payload'] = form session['payload'] = form
session['next'] = self._handle_advanced_result session['next'] = self._handle_advanced_result
@ -1957,7 +1959,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# NOTE Even though this check is already conducted on previous # NOTE Even though this check is already conducted on previous
# form, this check is being done just in case. # form, this check is being done just in case.
jid_bare = session['from'].bare jid_bare = session['from'].bare
if jid_bare == self.base['operator']: if jid_bare == self.settings['xmpp']['operator']:
if self.is_component: if self.is_component:
# NOTE This will be changed with XEP-0222 XEP-0223 # NOTE This will be changed with XEP-0222 XEP-0223
text_info = ('Subscriber management options are ' text_info = ('Subscriber management options are '
@ -2686,11 +2688,11 @@ class Slixfeed(slixmpp.ClientXMPP):
if chat_type == 'chat' or moderator: if chat_type == 'chat' or moderator:
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
if jid_bare not in self.custom.setting: if jid_bare not in self.settings:
self.custom = ConfigJabberID(jid_bare, db_file) Config.add_settings_jid(self.settings, jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Settings') form = self['xep_0004'].make_form('form', 'Settings')
form['instructions'] = 'Editing settings' form['instructions'] = 'Editing settings'
value = self.custom.setting[jid_bare]['enabled'] or self.default.setting['enabled'] value = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
value = str(value) value = str(value)
value = int(value) value = int(value)
if value: if value:
@ -2702,7 +2704,7 @@ class Slixfeed(slixmpp.ClientXMPP):
label='Enabled', label='Enabled',
desc='Enable news updates.', desc='Enable news updates.',
value=value) value=value)
value = self.custom.setting[jid_bare]['media'] or self.default.setting['media'] value = self.settings[jid_bare]['media'] or self.settings['default']['media']
value = str(value) value = str(value)
value = int(value) value = int(value)
if value: if value:
@ -2714,7 +2716,7 @@ class Slixfeed(slixmpp.ClientXMPP):
desc='Send audio, images or videos if found.', desc='Send audio, images or videos if found.',
label='Display media', label='Display media',
value=value) value=value)
value = self.custom.setting[jid_bare]['old'] or self.default.setting['old'] value = self.settings[jid_bare]['old'] or self.settings['default']['old']
value = str(value) value = str(value)
value = int(value) value = int(value)
if value: if value:
@ -2727,7 +2729,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# label='Send only new items', # label='Send only new items',
label='Include old news', label='Include old news',
value=value) value=value)
value = self.custom.setting[jid_bare]['interval'] or self.default.setting['interval'] value = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
value = str(value) value = str(value)
value = int(value) value = int(value)
value = value/60 value = value/60
@ -2748,7 +2750,7 @@ class Slixfeed(slixmpp.ClientXMPP):
i += 6 i += 6
else: else:
i += 1 i += 1
value = self.custom.setting[jid_bare]['quantum'] or self.default.setting['quantum'] value = self.settings[jid_bare]['quantum'] or self.settings['default']['quantum']
value = str(value) value = str(value)
value = str(value) value = str(value)
options = form.add_field(var='quantum', options = form.add_field(var='quantum',
@ -2763,7 +2765,7 @@ class Slixfeed(slixmpp.ClientXMPP):
x = str(i) x = str(i)
options.addOption(x, x) options.addOption(x, x)
i += 1 i += 1
value = self.custom.setting[jid_bare]['archive'] or self.default.setting['archive'] value = self.settings[jid_bare]['archive'] or self.settings['default']['archive']
value = str(value) value = str(value)
value = str(value) value = str(value)
options = form.add_field(var='archive', options = form.add_field(var='archive',
@ -2798,8 +2800,8 @@ class Slixfeed(slixmpp.ClientXMPP):
form = payload form = payload
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
if jid_bare not in self.custom.setting: if jid_bare not in self.settings:
self.custom = ConfigJabberID(jid_bare, db_file) Config.add_settings_jid(self.settings, jid_bare, db_file)
# In this case (as is typical), the payload is a form # In this case (as is typical), the payload is a form
values = payload['values'] values = payload['values']
for value in values: for value in values:
@ -2811,7 +2813,7 @@ class Slixfeed(slixmpp.ClientXMPP):
if val < 1: val = 1 if val < 1: val = 1
val = val * 60 val = val * 60
is_enabled = self.custom.setting[jid_bare]['enabled'] or self.default.setting['enabled'] is_enabled = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
if (key == 'enabled' and val == 1 and if (key == 'enabled' and val == 1 and
str(is_enabled) == 0): str(is_enabled) == 0):

View file

@ -40,7 +40,7 @@ class XmppCommand:
# ) # )
# NOTE https://codeberg.org/poezio/slixmpp/issues/3515 # NOTE https://codeberg.org/poezio/slixmpp/issues/3515
# if jid == config.get_value('accounts', 'XMPP', 'operator'): # if jid == self.settings['xmpp']['operator']:
self['xep_0050'].add_command(node='recent', self['xep_0050'].add_command(node='recent',
name='📰️ Browse', name='📰️ Browse',
handler=self._handle_recent) handler=self._handle_recent)
@ -89,7 +89,8 @@ class XmppCommand:
jid_bare = session['from'].bare jid_bare = session['from'].bare
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Profile') form = self['xep_0004'].make_form('form', 'Profile')
form['instructions'] = ('Displaying information\nJabber ID {}' form['instructions'] = ('Displaying information\nJabber ID {}'
.format(jid_bare)) .format(jid_bare))
@ -115,35 +116,43 @@ class XmppCommand:
value=unread) value=unread)
form.add_field(ftype='fixed', form.add_field(ftype='fixed',
value='Options') value='Options')
key_archive = str(setting.archive) key_archive = self.settings[jid_bare]['archive'] or self.settings['default']['archive']
key_archive = str(key_archive)
form.add_field(label='Archive', form.add_field(label='Archive',
ftype='text-single', ftype='text-single',
value=key_archive) value=key_archive)
key_enabled = str(setting.enabled) key_enabled = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
key_enabled = str(key_enabled)
form.add_field(label='Enabled', form.add_field(label='Enabled',
ftype='text-single', ftype='text-single',
value=key_enabled) value=key_enabled)
key_interval = str(setting.interval) key_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
key_interval = str(key_interval)
form.add_field(label='Interval', form.add_field(label='Interval',
ftype='text-single', ftype='text-single',
value=key_interval) value=key_interval)
key_length = str(setting.length) key_length = self.settings[jid_bare]['length'] or self.settings['default']['length']
key_length = str(key_length)
form.add_field(label='Length', form.add_field(label='Length',
ftype='text-single', ftype='text-single',
value=key_length) value=key_length)
key_media = str(setting.media) key_media = self.settings[jid_bare]['media'] or self.settings['default']['media']
key_media = str(key_media)
form.add_field(label='Media', form.add_field(label='Media',
ftype='text-single', ftype='text-single',
value=key_media) value=key_media)
key_old = str(setting.old) key_old = self.settings[jid_bare]['old'] or self.settings['default']['old']
key_old = str(key_old)
form.add_field(label='Old', form.add_field(label='Old',
ftype='text-single', ftype='text-single',
value=key_old) value=key_old)
key_quantum = str(setting.quantum) key_quantum = self.settings[jid_bare]['quantum'] or self.settings['default']['quantum']
key_quantum = str(key_quantum)
form.add_field(label='Quantum', form.add_field(label='Quantum',
ftype='text-single', ftype='text-single',
value=key_quantum) value=key_quantum)
update_interval = str(setting.interval) update_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
update_interval = str(update_interval)
update_interval = 60 * int(update_interval) update_interval = 60 * int(update_interval)
last_update_time = await sqlite.get_last_update_time(db_file) last_update_time = await sqlite.get_last_update_time(db_file)
if last_update_time: if last_update_time:
@ -1298,7 +1307,7 @@ class XmppCommand:
options.addOption('Import', 'import') options.addOption('Import', 'import')
options.addOption('Export', 'export') options.addOption('Export', 'export')
jid = session['from'].bare jid = session['from'].bare
if jid == config.get_value('accounts', 'XMPP', 'operator'): if jid == self.settings['xmpp']['operator']:
options.addOption('Administration', 'admin') options.addOption('Administration', 'admin')
session['payload'] = form session['payload'] = form
session['next'] = self._handle_advanced_result session['next'] = self._handle_advanced_result
@ -1325,7 +1334,7 @@ class XmppCommand:
# NOTE Even though this check is already conducted on previous # NOTE Even though this check is already conducted on previous
# form, this check is being done just in case. # form, this check is being done just in case.
jid_bare = session['from'].bare jid_bare = session['from'].bare
if jid_bare == config.get_value('accounts', 'XMPP', 'operator'): if jid_bare == self.settings['xmpp']['operator']:
if self.is_component: if self.is_component:
# NOTE This will be changed with XEP-0222 XEP-0223 # NOTE This will be changed with XEP-0222 XEP-0223
text_info = ('Subscriber management options are ' text_info = ('Subscriber management options are '
@ -1726,10 +1735,6 @@ class XmppCommand:
.format(function_name, jid_full)) .format(function_name, jid_full))
jid_bare = session['from'].bare jid_bare = session['from'].bare
jid_file = jid_bare jid_file = jid_bare
logger.debug('{}: jid_full: {}'
.format(function_name, jid_full))
jid_bare = session['from'].bare
jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
subscriptions = await sqlite.get_feeds(db_file) subscriptions = await sqlite.get_feeds(db_file)
subscriptions = sorted(subscriptions, key=lambda x: x[0]) subscriptions = sorted(subscriptions, key=lambda x: x[0])
@ -2058,10 +2063,12 @@ class XmppCommand:
if chat_type == 'chat' or moderator: if chat_type == 'chat' or moderator:
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Settings') form = self['xep_0004'].make_form('form', 'Settings')
form['instructions'] = 'Editing settings' form['instructions'] = 'Editing settings'
value = str(setting.enabled) value = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
value = str(value)
value = int(value) value = int(value)
if value: if value:
value = True value = True
@ -2072,8 +2079,8 @@ class XmppCommand:
label='Enabled', label='Enabled',
desc='Enable news updates.', desc='Enable news updates.',
value=value) value=value)
value = self.settings[jid_bare]['media'] or self.settings['default']['media']
value = str(setting.media) value = str(value)
value = int(value) value = int(value)
if value: if value:
value = True value = True
@ -2084,8 +2091,8 @@ class XmppCommand:
desc='Send audio, images or videos if found.', desc='Send audio, images or videos if found.',
label='Display media', label='Display media',
value=value) value=value)
value = self.settings[jid_bare]['old'] or self.settings['default']['old']
value = str(setting.old) value = str(value)
value = int(value) value = int(value)
if value: if value:
value = True value = True
@ -2097,8 +2104,8 @@ class XmppCommand:
# label='Send only new items', # label='Send only new items',
label='Include old news', label='Include old news',
value=value) value=value)
value = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
value = str(setting.interval) value = str(value)
value = int(value) value = int(value)
value = value/60 value = value/60
value = int(value) value = int(value)
@ -2118,8 +2125,8 @@ class XmppCommand:
i += 6 i += 6
else: else:
i += 1 i += 1
value = self.settings[jid_bare]['quantum'] or self.settings['default']['quantum']
value = str(setting.quantum) value = str(value)
value = str(value) value = str(value)
options = form.add_field(var='quantum', options = form.add_field(var='quantum',
ftype='list-single', ftype='list-single',
@ -2133,8 +2140,8 @@ class XmppCommand:
x = str(i) x = str(i)
options.addOption(x, x) options.addOption(x, x)
i += 1 i += 1
value = self.settings[jid_bare]['archive'] or self.settings['default']['archive']
value = str(setting.archive) value = str(value)
value = str(value) value = str(value)
options = form.add_field(var='archive', options = form.add_field(var='archive',
ftype='list-single', ftype='list-single',
@ -2168,7 +2175,8 @@ class XmppCommand:
form = payload form = payload
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
# In this case (as is typical), the payload is a form # In this case (as is typical), the payload is a form
values = payload['values'] values = payload['values']
for value in values: for value in values:
@ -2180,8 +2188,10 @@ class XmppCommand:
if val < 1: val = 1 if val < 1: val = 1
val = val * 60 val = val * 60
is_enabled = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
if (key == 'enabled' and val == 1 and if (key == 'enabled' and val == 1 and
str(setting.enabled) == 0): str(is_enabled) == 0):
logger.info('Slixfeed has been enabled for {}'.format(jid_bare)) logger.info('Slixfeed has been enabled for {}'.format(jid_bare))
status_type = 'available' status_type = 'available'
status_message = '📫️ Welcome back!' status_message = '📫️ Welcome back!'
@ -2192,7 +2202,7 @@ class XmppCommand:
await task.start_tasks_xmpp(self, jid_bare, key_list) await task.start_tasks_xmpp(self, jid_bare, key_list)
if (key == 'enabled' and val == 0 and if (key == 'enabled' and val == 0 and
str(setting.enabled) == 1): str(is_enabled) == 1):
logger.info('Slixfeed has been disabled for {}'.format(jid_bare)) logger.info('Slixfeed has been disabled for {}'.format(jid_bare))
key_list = ['interval', 'status'] key_list = ['interval', 'status']
task.clean_tasks_xmpp(self, jid_bare, key_list) task.clean_tasks_xmpp(self, jid_bare, key_list)

View file

@ -102,12 +102,18 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
# Handler for nickname # Handler for nickname
self.alias = alias self.alias = alias
# Handlers for tasks # Handler for tasks
self.task_manager = {} self.task_manager = {}
# Handlers for ping # Handler for ping
self.task_ping_instance = {} self.task_ping_instance = {}
# Handler for configuration
self.settings = {}
# Populate handler
Config.add_settings_default(self.settings)
Config.add_settings_xmpp(self.settings)
# Handlers for connection events # Handlers for connection events
self.connection_attempts = 0 self.connection_attempts = 0
self.max_connection_attempts = 10 self.max_connection_attempts = 10
@ -222,10 +228,10 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
task.task_ping(self) task.task_ping(self)
# bookmarks = await self.plugin['xep_0048'].get_bookmarks() # bookmarks = await self.plugin['xep_0048'].get_bookmarks()
# XmppGroupchat.autojoin(self, bookmarks) # XmppGroupchat.autojoin(self, bookmarks)
if config.get_value('accounts', 'XMPP', 'operator'): jid_operator = config.get_value('accounts', 'XMPP', 'operator')
jid_op = config.get_value('accounts', 'XMPP', 'operator') if jid_operator:
status_message = 'Slixfeed version {}'.format(__version__) status_message = 'Slixfeed version {}'.format(__version__)
XmppPresence.send(self, jid_op, status_message) XmppPresence.send(self, jid_operator, status_message)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{} (time: {})'.format(function_name, if difference > 1: logger.warning('{} (time: {})'.format(function_name,
@ -269,6 +275,10 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
message_log = '{}: jid_full: {}' message_log = '{}: jid_full: {}'
logger.debug(message_log.format(function_name, jid_full)) logger.debug(message_log.format(function_name, jid_full))
jid_bare = message['from'].bare jid_bare = message['from'].bare
jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file)
if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
if jid_bare == self.boundjid.bare: if jid_bare == self.boundjid.bare:
status_type = 'dnd' status_type = 'dnd'
status_message = ('Slixfeed is not designed to receive messages ' status_message = ('Slixfeed is not designed to receive messages '
@ -377,7 +387,6 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
jid_bare = presence['from'].bare jid_bare = presence['from'].bare
if jid_bare in self.boundjid.bare: if jid_bare in self.boundjid.bare:
return return
logging.info('JID {} is available'.format(jid))
# FIXME TODO Find out what is the source responsible for a couple presences with empty message # FIXME TODO Find out what is the source responsible for a couple presences with empty message
# NOTE This is a temporary solution # NOTE This is a temporary solution
await asyncio.sleep(10) await asyncio.sleep(10)
@ -386,9 +395,9 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
self.on_presence_unavailable) self.on_presence_unavailable)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{}: jid_full: {} (time: {})' if difference > 15: logger.warning('{}: jid_full: {} (time: {})'
.format(function_name, jid_full, .format(function_name, jid_full,
difference)) difference))
def on_presence_unsubscribed(self, presence): def on_presence_unsubscribed(self, presence):
@ -478,8 +487,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
await task.start_tasks_xmpp(self, jid_bare, key_list) await task.start_tasks_xmpp(self, jid_bare, key_list)
time_end = time.time() time_end = time.time()
difference = time_end - time_begin difference = time_end - time_begin
if difference > 1: logger.warning('{} (time: {})'.format(function_name, if difference > 10: logger.warning('{} (time: {})'.format(function_name,
difference)) difference))
async def on_chatstate_composing(self, message): async def on_chatstate_composing(self, message):
@ -616,7 +625,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
# ) # )
# NOTE https://codeberg.org/poezio/slixmpp/issues/3515 # NOTE https://codeberg.org/poezio/slixmpp/issues/3515
# if jid == config.get_value('accounts', 'XMPP', 'operator'): # if jid == self.settings['xmpp']['operator']:
self['xep_0050'].add_command(node='recent', self['xep_0050'].add_command(node='recent',
name='📰️ Browse', name='📰️ Browse',
handler=self._handle_recent) handler=self._handle_recent)
@ -665,7 +674,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
jid_bare = session['from'].bare jid_bare = session['from'].bare
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Profile') form = self['xep_0004'].make_form('form', 'Profile')
form['instructions'] = ('Displaying information\nJabber ID {}' form['instructions'] = ('Displaying information\nJabber ID {}'
.format(jid_bare)) .format(jid_bare))
@ -691,35 +701,43 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
value=unread) value=unread)
form.add_field(ftype='fixed', form.add_field(ftype='fixed',
value='Options') value='Options')
key_archive = str(setting.archive) key_archive = self.settings[jid_bare]['archive'] or self.settings['default']['archive']
key_archive = str(key_archive)
form.add_field(label='Archive', form.add_field(label='Archive',
ftype='text-single', ftype='text-single',
value=key_archive) value=key_archive)
key_enabled = str(setting.enabled) key_enabled = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
key_enabled = str(key_enabled)
form.add_field(label='Enabled', form.add_field(label='Enabled',
ftype='text-single', ftype='text-single',
value=key_enabled) value=key_enabled)
key_interval = str(setting.interval) key_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
key_interval = str(key_interval)
form.add_field(label='Interval', form.add_field(label='Interval',
ftype='text-single', ftype='text-single',
value=key_interval) value=key_interval)
key_length = str(setting.length) key_length = self.settings[jid_bare]['length'] or self.settings['default']['length']
key_length = str(key_length)
form.add_field(label='Length', form.add_field(label='Length',
ftype='text-single', ftype='text-single',
value=key_length) value=key_length)
key_media = str(setting.media) key_media = self.settings[jid_bare]['media'] or self.settings['default']['media']
key_media = str(key_media)
form.add_field(label='Media', form.add_field(label='Media',
ftype='text-single', ftype='text-single',
value=key_media) value=key_media)
key_old = str(setting.old) key_old = self.settings[jid_bare]['old'] or self.settings['default']['old']
key_old = str(key_old)
form.add_field(label='Old', form.add_field(label='Old',
ftype='text-single', ftype='text-single',
value=key_old) value=key_old)
key_quantum = str(setting.quantum) key_quantum = self.settings[jid_bare]['quantum'] or self.settings['default']['quantum']
key_quantum = str(key_quantum)
form.add_field(label='Quantum', form.add_field(label='Quantum',
ftype='text-single', ftype='text-single',
value=key_quantum) value=key_quantum)
update_interval = str(setting.interval) update_interval = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
update_interval = str(update_interval)
update_interval = 60 * int(update_interval) update_interval = 60 * int(update_interval)
last_update_time = await sqlite.get_last_update_time(db_file) last_update_time = await sqlite.get_last_update_time(db_file)
if last_update_time: if last_update_time:
@ -1874,7 +1892,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
options.addOption('Import', 'import') options.addOption('Import', 'import')
options.addOption('Export', 'export') options.addOption('Export', 'export')
jid = session['from'].bare jid = session['from'].bare
if jid == config.get_value('accounts', 'XMPP', 'operator'): if jid == self.settings['xmpp']['operator']:
options.addOption('Administration', 'admin') options.addOption('Administration', 'admin')
session['payload'] = form session['payload'] = form
session['next'] = self._handle_advanced_result session['next'] = self._handle_advanced_result
@ -1901,7 +1919,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
# NOTE Even though this check is already conducted on previous # NOTE Even though this check is already conducted on previous
# form, this check is being done just in case. # form, this check is being done just in case.
jid_bare = session['from'].bare jid_bare = session['from'].bare
if jid_bare == config.get_value('accounts', 'XMPP', 'operator'): if jid_bare == self.settings['xmpp']['operator']:
if self.is_component: if self.is_component:
# NOTE This will be changed with XEP-0222 XEP-0223 # NOTE This will be changed with XEP-0222 XEP-0223
text_info = ('Subscriber management options are ' text_info = ('Subscriber management options are '
@ -2630,10 +2648,12 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
if chat_type == 'chat' or moderator: if chat_type == 'chat' or moderator:
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Settings') form = self['xep_0004'].make_form('form', 'Settings')
form['instructions'] = 'Editing settings' form['instructions'] = 'Editing settings'
value = str(setting.enabled) value = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
value = str(value)
value = int(value) value = int(value)
if value: if value:
value = True value = True
@ -2644,8 +2664,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
label='Enabled', label='Enabled',
desc='Enable news updates.', desc='Enable news updates.',
value=value) value=value)
value = self.settings[jid_bare]['media'] or self.settings['default']['media']
value = str(setting.media) value = str(value)
value = int(value) value = int(value)
if value: if value:
value = True value = True
@ -2656,8 +2676,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
desc='Send audio, images or videos if found.', desc='Send audio, images or videos if found.',
label='Display media', label='Display media',
value=value) value=value)
value = self.settings[jid_bare]['old'] or self.settings['default']['old']
value = str(setting.old) value = str(value)
value = int(value) value = int(value)
if value: if value:
value = True value = True
@ -2669,8 +2689,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
# label='Send only new items', # label='Send only new items',
label='Include old news', label='Include old news',
value=value) value=value)
value = self.settings[jid_bare]['interval'] or self.settings['default']['interval']
value = str(setting.interval) value = str(value)
value = int(value) value = int(value)
value = value/60 value = value/60
value = int(value) value = int(value)
@ -2690,8 +2710,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
i += 6 i += 6
else: else:
i += 1 i += 1
value = self.settings[jid_bare]['quantum'] or self.settings['default']['quantum']
value = str(setting.quantum) value = str(value)
value = str(value) value = str(value)
options = form.add_field(var='quantum', options = form.add_field(var='quantum',
ftype='list-single', ftype='list-single',
@ -2705,8 +2725,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
x = str(i) x = str(i)
options.addOption(x, x) options.addOption(x, x)
i += 1 i += 1
value = self.settings[jid_bare]['archive'] or self.settings['default']['archive']
value = str(setting.archive) value = str(value)
value = str(value) value = str(value)
options = form.add_field(var='archive', options = form.add_field(var='archive',
ftype='list-single', ftype='list-single',
@ -2740,7 +2760,8 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
form = payload form = payload
jid_file = jid_bare jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file) if jid_bare not in self.settings:
Config.add_settings_jid(self.settings, jid_bare, db_file)
# In this case (as is typical), the payload is a form # In this case (as is typical), the payload is a form
values = payload['values'] values = payload['values']
for value in values: for value in values:
@ -2752,8 +2773,10 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
if val < 1: val = 1 if val < 1: val = 1
val = val * 60 val = val * 60
is_enabled = self.settings[jid_bare]['enabled'] or self.settings['default']['enabled']
if (key == 'enabled' and val == 1 and if (key == 'enabled' and val == 1 and
str(setting.enabled) == 0): str(is_enabled) == 0):
logger.info('Slixfeed has been enabled for {}'.format(jid_bare)) logger.info('Slixfeed has been enabled for {}'.format(jid_bare))
status_type = 'available' status_type = 'available'
status_message = '📫️ Welcome back!' status_message = '📫️ Welcome back!'
@ -2764,7 +2787,7 @@ class SlixfeedComponent(slixmpp.ComponentXMPP):
await task.start_tasks_xmpp(self, jid_bare, key_list) await task.start_tasks_xmpp(self, jid_bare, key_list)
if (key == 'enabled' and val == 0 and if (key == 'enabled' and val == 0 and
str(setting.enabled) == 1): str(is_enabled) == 1):
logger.info('Slixfeed has been disabled for {}'.format(jid_bare)) logger.info('Slixfeed has been disabled for {}'.format(jid_bare))
key_list = ['interval', 'status'] key_list = ['interval', 'status']
task.clean_tasks_xmpp(self, jid_bare, key_list) task.clean_tasks_xmpp(self, jid_bare, key_list)

View file

@ -28,7 +28,7 @@ import logging
import os import os
import slixfeed.action as action import slixfeed.action as action
import slixfeed.config as config import slixfeed.config as config
from slixfeed.config import ConfigJabberID from slixfeed.config import Config
import slixfeed.dt as dt import slixfeed.dt as dt
import slixfeed.fetch as fetch import slixfeed.fetch as fetch
import slixfeed.sqlite as sqlite import slixfeed.sqlite as sqlite
@ -303,11 +303,10 @@ async def message(self, message):
exist = await sqlite.get_feed_id_and_name(db_file, url) exist = await sqlite.get_feed_id_and_name(db_file, url)
if not exist: if not exist:
await sqlite.insert_feed(db_file, url, title) await sqlite.insert_feed(db_file, url, title)
await action.scan(db_file, url) await action.scan(self, jid_bare, db_file, url)
# setting = Config(db_file) if jid_bare not in self.settings:
# old = setting.old Config.add_settings_jid(self.settings, jid_bare, db_file)
setting_custom = ConfigJabberID(db_file) old = self.settings[jid_bare]['old'] or self.settings['default']['old']
old = setting_custom.old or self.default.settings_p['old']
if old: if old:
# task.clean_tasks_xmpp(self, jid, ['status']) # task.clean_tasks_xmpp(self, jid, ['status'])
# await send_status(jid) # await send_status(jid)
@ -633,7 +632,7 @@ async def message(self, message):
url = (uri.replace_hostname(url, 'feed')) or url url = (uri.replace_hostname(url, 'feed')) or url
db_file = config.get_pathname_to_database(jid_file) db_file = config.get_pathname_to_database(jid_file)
# try: # try:
result = await action.add_feed(db_file, url) result = await action.add_feed(self, jid_bare, db_file, url)
if isinstance(result, list): if isinstance(result, list):
results = result results = result
response = ("Web feeds found for {}\n\n```\n" response = ("Web feeds found for {}\n\n```\n"