Settings: Manage several class instance objects.

This commit is contained in:
Schimon Jehudah 2024-03-07 06:56:11 +00:00
parent 9969f8ded1
commit aa5f45cddc
7 changed files with 173 additions and 66 deletions

View file

@ -80,12 +80,14 @@ import os
#import slixfeed.matrix
import slixfeed.config as config
from slixfeed.config import ConfigXMPP
from slixfeed.version import __version__
import socks
import socket
# import socks
# import socket
xmpp_type = config.get_value('accounts', 'XMPP', 'type')
base = ConfigXMPP()
xmpp_type = base.setting['type']
if not xmpp_type:
raise Exception('Key type is missing from accounts.ini.')
@ -93,9 +95,12 @@ if not xmpp_type:
match xmpp_type:
case 'client':
from slixfeed.xmpp.client import Slixfeed
from slixfeed.config import ConfigClient as ConfigAccount
case 'component':
from slixfeed.xmpp.component import SlixfeedComponent
from slixfeed.config import ConfigComponent as ConfigAccount
account = ConfigAccount()
class JabberComponent:
def __init__(self, jid, secret, hostname, port, alias=None):
@ -172,10 +177,8 @@ class JabberClient:
# Connect to the XMPP server and start processing XMPP stanzas.
address = config.get_value('accounts', 'XMPP Client',
['hostname', 'port'])
if address[0] and address[1]:
xmpp.connect(tuple(address))
if account.setting['hostname'] and account.setting['port']:
xmpp.connect((account.setting['hostname'], account.setting['port']))
else:
xmpp.connect()
xmpp.process()
@ -240,13 +243,11 @@ def main():
# logwrn = logger.warning
# Try configuration file
key_list = ['alias', 'jid', 'password', 'hostname', 'port']
values = config.get_value('accounts', 'XMPP Client', key_list)
alias = values[0]
jid = values[1]
password = values[2]
hostname = values[3]
port = values[4]
alias = account.setting['alias']
jid = account.setting['jid']
password = account.setting['password']
hostname = account.setting['hostname']
port = account.setting['port']
# Use arguments if were given
if args.jid:

View file

@ -18,7 +18,10 @@ check = 120
# Work status (Value 0 to disable)
enabled = 1
# Update interval (Minimum value 10)
# Enable filters (Value 1 to enable)
filter = 0
# Update interval in minutes (Minimum value 10)
interval = 300
# Maximum length of summary (Value 0 to disable)
@ -56,7 +59,7 @@ yggdrasil =
http_proxy =
# User Agent
user-agent = Slixfeed/0.1
user_agent = Slixfeed/0.1
# Enable policed DNS system (not recommended)
# clearnet = 1

View file

@ -3,6 +3,12 @@
"""
FIXME
1) Use dict for ConfigDefault
2) Store ConfigJabberID in dicts
TODO
1) Website-specific filter (i.e. audiobookbay).
@ -42,15 +48,86 @@ except:
# 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.
class Config:
def __init__(self, db_file):
self.archive = get_setting_value(db_file, 'archive')
self.enabled = get_setting_value(db_file, 'enabled')
self.formatting = get_setting_value(db_file, 'formatting')
self.interval = get_setting_value(db_file, 'interval')
self.length = get_setting_value(db_file, 'length')
self.media = get_setting_value(db_file, 'media')
self.old = get_setting_value(db_file, 'old')
self.quantum = get_setting_value(db_file, 'quantum')
def __init__(self):
self.settings = {}
# initiate an empty dict and the rest would be:
# settings['account'] = {}
# settings['default'] = {}
# settings['jabber@id'] = {}
# def __init__(self, db_file):
# self.archive = get_setting_value(db_file, 'archive')
# self.enabled = get_setting_value(db_file, 'enabled')
# self.formatting = get_setting_value(db_file, 'formatting')
# self.interval = get_setting_value(db_file, 'interval')
# self.length = get_setting_value(db_file, 'length')
# self.media = get_setting_value(db_file, 'media')
# self.old = get_setting_value(db_file, 'old')
# self.quantum = get_setting_value(db_file, 'quantum')
# def default():
# archive = get_value('settings', 'Settings', 'archive')
# enabled = get_value('settings', 'Settings', 'enabled')
# formatting = get_value('settings', 'Settings', 'formatting')
# interval = get_value('settings', 'Settings', 'interval')
# length = get_value('settings', 'Settings', 'length')
# media = get_value('settings', 'Settings', 'media')
# old = get_value('settings', 'Settings', 'old')
# quantum = get_value('settings', 'Settings', 'quantum')
# def jid(db_file):
# archive = sqlite.get_setting_value(db_file, 'archive')
# enabled = sqlite.get_setting_value(db_file, 'enabled')
# formatting = sqlite.get_setting_value(db_file, 'formatting')
# interval = sqlite.get_setting_value(db_file, 'interval')
# length = sqlite.get_setting_value(db_file, 'length')
# media = sqlite.get_setting_value(db_file, 'media')
# old = sqlite.get_setting_value(db_file, 'old')
# 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:
def __init__(self):
self.setting = {}
for key in ('operator', 'reconnect_timeout', 'type'):
value = get_value('accounts', 'XMPP', key)
self.setting[key] = value
class ConfigClient:
def __init__(self):
self.setting = {}
for key in ('alias', 'jid', 'operator', 'password', 'hostname', 'port'):
value = get_value('accounts', 'XMPP Client', key)
self.setting[key] = value
class ConfigJabberID:
def __init__(self, jid_bare=None, db_file=None):
self.setting = {}
if jid_bare and db_file:
self.setting[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]
print(value)
self.setting[jid_bare][key] = value
async def set_setting_value(db_file, key, val):

View file

@ -92,7 +92,7 @@ def http_response(url):
"""
user_agent = (
config.get_value(
"settings", "Network", "user-agent")
"settings", "Network", "user_agent")
) or 'Slixfeed/0.1'
headers = {
"User-Agent": user_agent
@ -121,7 +121,7 @@ async def http(url):
msg: list or str
Document or error message.
"""
user_agent = (config.get_value("settings", "Network", "user-agent")
user_agent = (config.get_value("settings", "Network", "user_agent")
or 'Slixfeed/0.1')
headers = {'User-Agent': user_agent}
proxy = (config.get_value("settings", "Network", "http_proxy") or '')

View file

@ -59,6 +59,7 @@ import logging
import os
import slixfeed.action as action
import slixfeed.config as config
from slixfeed.config import ConfigJabberID
# from slixfeed.dt import current_time
import slixfeed.sqlite as sqlite
# from xmpp import Slixfeed
@ -143,7 +144,7 @@ async def start_tasks_xmpp(self, jid, tasks=None):
match task:
case 'check':
self.task_manager[jid]['check'] = asyncio.create_task(
check_updates(jid))
check_updates(self, jid))
case 'status':
self.task_manager[jid]['status'] = asyncio.create_task(
task_status(self, jid))
@ -169,7 +170,8 @@ async def task_status(self, jid):
async def task_send(self, jid):
jid_file = jid.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file)
update_interval = config.get_setting_value(db_file, 'interval')
setting_custom = ConfigJabberID(db_file)
update_interval = setting_custom.interval or self.default.settings_p['interval']
update_interval = 60 * int(update_interval)
last_update_time = await sqlite.get_last_update_time(db_file)
if last_update_time:
@ -227,7 +229,8 @@ async def refresh_task(self, jid, callback, key, val=None):
if not val:
jid_file = jid.replace('/', '_')
db_file = config.get_pathname_to_database(jid_file)
val = config.get_setting_value(db_file, key)
setting_custom = ConfigJabberID(db_file)
val = setting_custom.interval or self.default.settings_p[key]
# if self.task_manager[jid][key]:
if jid in self.task_manager:
try:
@ -263,7 +266,7 @@ async def wait_and_run(self, callback, jid, val):
# TODO Take this function out of
# <class 'slixmpp.clientxmpp.ClientXMPP'>
async def check_updates(jid):
async def check_updates(self, jid):
"""
Start calling for update check up.
@ -279,7 +282,7 @@ async def check_updates(jid):
urls = await sqlite.get_active_feeds_url(db_file)
for url in urls:
await action.scan(db_file, url)
val = config.get_value('settings', 'Settings', 'check')
val = self.default.setting['check']
await asyncio.sleep(60 * float(val))
# Schedule to call this function again in 90 minutes
# loop.call_at(

View file

@ -43,6 +43,9 @@ import slixfeed.task as task
# from lxml import etree
import slixfeed.config as config
from slixfeed.config import ConfigDefault
from slixfeed.config import ConfigJabberID
from slixfeed.config import ConfigXMPP
from slixfeed.log import Logger
from slixfeed.version import __version__
from slixfeed.xmpp.bookmark import XmppBookmark
@ -64,7 +67,6 @@ import logging
import os
import slixfeed.action as action
import slixfeed.config as config
from slixfeed.config import Config
import slixfeed.crawl as crawl
import slixfeed.dt as dt
import slixfeed.fetch as fetch
@ -111,12 +113,17 @@ class Slixfeed(slixmpp.ClientXMPP):
# Handler for nickname
self.alias = alias
# Handlers for tasks
# Handler for tasks
self.task_manager = {}
# Handlers for ping
# Handler for ping
self.task_ping_instance = {}
# Handlers for configuration
self.base = ConfigXMPP()
self.custom = ConfigJabberID() # The value is {} (which is empty)
self.default = ConfigDefault()
# Handlers for connection events
self.connection_attempts = 0
self.max_connection_attempts = 10
@ -261,8 +268,8 @@ class Slixfeed(slixmpp.ClientXMPP):
task.task_ping(self)
bookmarks = await self.plugin['xep_0048'].get_bookmarks()
XmppGroupchat.autojoin(self, bookmarks)
if config.get_value('accounts', 'XMPP', 'operator'):
jid_op = config.get_value('accounts', 'XMPP', 'operator')
if self.base['operator']:
jid_op = self.base['operator']
status_message = 'Slixfeed version {}'.format(__version__)
XmppPresence.send(self, jid_op, status_message)
time_end = time.time()
@ -655,7 +662,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# )
# NOTE https://codeberg.org/poezio/slixmpp/issues/3515
# if jid == config.get_value('accounts', 'XMPP', 'operator'):
# if jid == self.base['operator']:
self['xep_0050'].add_command(node='recent',
name='📰️ Browse',
handler=self._handle_recent)
@ -704,7 +711,9 @@ class Slixfeed(slixmpp.ClientXMPP):
jid_bare = session['from'].bare
jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file)
# if not self.custom.setting and jid_bare not in self.custom.setting:
if jid_bare not in self.custom.setting:
self.custom = ConfigJabberID(jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Profile')
form['instructions'] = ('Displaying information\nJabber ID {}'
.format(jid_bare))
@ -730,35 +739,43 @@ class Slixfeed(slixmpp.ClientXMPP):
value=unread)
form.add_field(ftype='fixed',
value='Options')
key_archive = str(setting.archive)
key_archive = self.custom.setting[jid_bare]['archive'] or self.default.setting['archive']
key_archive = str(key_archive)
form.add_field(label='Archive',
ftype='text-single',
value=key_archive)
key_enabled = str(setting.enabled)
key_enabled = self.custom.setting[jid_bare]['enabled'] or self.default.setting['enabled']
key_enabled = str(key_enabled)
form.add_field(label='Enabled',
ftype='text-single',
value=key_enabled)
key_interval = str(setting.interval)
key_interval = self.custom.setting[jid_bare]['interval'] or self.default.setting['interval']
key_interval = str(key_interval)
form.add_field(label='Interval',
ftype='text-single',
value=key_interval)
key_length = str(setting.length)
key_length = self.custom.setting[jid_bare]['length'] or self.default.setting['length']
key_length = str(key_length)
form.add_field(label='Length',
ftype='text-single',
value=key_length)
key_media = str(setting.media)
key_media = self.custom.setting[jid_bare]['media'] or self.default.setting['media']
key_media = str(key_media)
form.add_field(label='Media',
ftype='text-single',
value=key_media)
key_old = str(setting.old)
key_old = self.custom.setting[jid_bare]['old'] or self.default.setting['old']
key_old = str(key_old)
form.add_field(label='Old',
ftype='text-single',
value=key_old)
key_quantum = str(setting.quantum)
key_quantum = self.custom.setting[jid_bare]['quantum'] or self.default.setting['quantum']
key_quantum = str(key_quantum)
form.add_field(label='Quantum',
ftype='text-single',
value=key_quantum)
update_interval = str(setting.interval)
update_interval = self.custom.setting[jid_bare]['interval'] or self.default.setting['interval']
update_interval = str(update_interval)
update_interval = 60 * int(update_interval)
last_update_time = await sqlite.get_last_update_time(db_file)
if last_update_time:
@ -1913,7 +1930,7 @@ class Slixfeed(slixmpp.ClientXMPP):
options.addOption('Import', 'import')
options.addOption('Export', 'export')
jid = session['from'].bare
if jid == config.get_value('accounts', 'XMPP', 'operator'):
if jid == self.base['operator']:
options.addOption('Administration', 'admin')
session['payload'] = form
session['next'] = self._handle_advanced_result
@ -1940,7 +1957,7 @@ class Slixfeed(slixmpp.ClientXMPP):
# NOTE Even though this check is already conducted on previous
# form, this check is being done just in case.
jid_bare = session['from'].bare
if jid_bare == config.get_value('accounts', 'XMPP', 'operator'):
if jid_bare == self.base['operator']:
if self.is_component:
# NOTE This will be changed with XEP-0222 XEP-0223
text_info = ('Subscriber management options are '
@ -2669,10 +2686,12 @@ class Slixfeed(slixmpp.ClientXMPP):
if chat_type == 'chat' or moderator:
jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file)
if jid_bare not in self.custom.setting:
self.custom = ConfigJabberID(jid_bare, db_file)
form = self['xep_0004'].make_form('form', 'Settings')
form['instructions'] = 'Editing settings'
value = str(setting.enabled)
value = self.custom.setting[jid_bare]['enabled'] or self.default.setting['enabled']
value = str(value)
value = int(value)
if value:
value = True
@ -2683,8 +2702,8 @@ class Slixfeed(slixmpp.ClientXMPP):
label='Enabled',
desc='Enable news updates.',
value=value)
value = str(setting.media)
value = self.custom.setting[jid_bare]['media'] or self.default.setting['media']
value = str(value)
value = int(value)
if value:
value = True
@ -2695,8 +2714,8 @@ class Slixfeed(slixmpp.ClientXMPP):
desc='Send audio, images or videos if found.',
label='Display media',
value=value)
value = str(setting.old)
value = self.custom.setting[jid_bare]['old'] or self.default.setting['old']
value = str(value)
value = int(value)
if value:
value = True
@ -2708,8 +2727,8 @@ class Slixfeed(slixmpp.ClientXMPP):
# label='Send only new items',
label='Include old news',
value=value)
value = str(setting.interval)
value = self.custom.setting[jid_bare]['interval'] or self.default.setting['interval']
value = str(value)
value = int(value)
value = value/60
value = int(value)
@ -2729,8 +2748,8 @@ class Slixfeed(slixmpp.ClientXMPP):
i += 6
else:
i += 1
value = str(setting.quantum)
value = self.custom.setting[jid_bare]['quantum'] or self.default.setting['quantum']
value = str(value)
value = str(value)
options = form.add_field(var='quantum',
ftype='list-single',
@ -2744,8 +2763,8 @@ class Slixfeed(slixmpp.ClientXMPP):
x = str(i)
options.addOption(x, x)
i += 1
value = str(setting.archive)
value = self.custom.setting[jid_bare]['archive'] or self.default.setting['archive']
value = str(value)
value = str(value)
options = form.add_field(var='archive',
ftype='list-single',
@ -2779,7 +2798,8 @@ class Slixfeed(slixmpp.ClientXMPP):
form = payload
jid_file = jid_bare
db_file = config.get_pathname_to_database(jid_file)
setting = Config(db_file)
if jid_bare not in self.custom.setting:
self.custom = ConfigJabberID(jid_bare, db_file)
# In this case (as is typical), the payload is a form
values = payload['values']
for value in values:
@ -2791,8 +2811,10 @@ class Slixfeed(slixmpp.ClientXMPP):
if val < 1: val = 1
val = val * 60
is_enabled = self.custom.setting[jid_bare]['enabled'] or self.default.setting['enabled']
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))
status_type = 'available'
status_message = '📫️ Welcome back!'
@ -2803,7 +2825,7 @@ class Slixfeed(slixmpp.ClientXMPP):
await task.start_tasks_xmpp(self, jid_bare, key_list)
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))
key_list = ['interval', 'status']
task.clean_tasks_xmpp(self, jid_bare, key_list)

View file

@ -28,7 +28,7 @@ import logging
import os
import slixfeed.action as action
import slixfeed.config as config
# from slixfeed.config import Config
from slixfeed.config import ConfigJabberID
import slixfeed.dt as dt
import slixfeed.fetch as fetch
import slixfeed.sqlite as sqlite
@ -306,7 +306,8 @@ async def message(self, message):
await action.scan(db_file, url)
# setting = Config(db_file)
# old = setting.old
old = config.get_setting_value(db_file, "old")
setting_custom = ConfigJabberID(db_file)
old = setting_custom.old or self.default.settings_p['old']
if old:
# task.clean_tasks_xmpp(self, jid, ['status'])
# await send_status(jid)