Correctly start and stop subscriptions autochecker when it is

disabled/enabled in settings.
This commit is contained in:
James Taylor 2020-03-08 21:01:15 -07:00
parent 56e7751da7
commit 408a9c79ae
2 changed files with 71 additions and 41 deletions

View File

@ -286,6 +286,14 @@ if route_tor:
else: else:
print("Tor routing is OFF - your Youtube activity is NOT anonymous") print("Tor routing is OFF - your Youtube activity is NOT anonymous")
hooks = {}
def add_setting_changed_hook(setting, func):
'''Called right before new settings take effect'''
if setting in hooks:
hooks[setting].append(func)
else:
hooks[setting] = [func]
def settings_page(): def settings_page():
if request.method == 'GET': if request.method == 'GET':
@ -309,6 +317,13 @@ def settings_page():
assert settings_info[setting_name]['type'] is bool, missing_inputs assert settings_info[setting_name]['type'] is bool, missing_inputs
settings[setting_name] = False settings[setting_name] = False
# call setting hooks
for setting_name, value in settings.items():
old_value = globals()[setting_name]
if value != old_value and setting_name in hooks:
for func in hooks[setting_name]:
func(old_value, value)
globals().update(settings) globals().update(settings)
save_settings(settings) save_settings(settings)
return flask.redirect(util.URL_ORIGIN + '/settings', 303) return flask.redirect(util.URL_ORIGIN + '/settings', 303)

View File

@ -331,33 +331,7 @@ for i in range(0,5):
# --- Auto checking system - Spaghetti code --- # --- Auto checking system - Spaghetti code ---
def autocheck_dispatcher():
if settings.autocheck_subscriptions:
# job application format: dict with keys (channel_id, channel_name, next_check_time)
autocheck_job_application = gevent.queue.Queue() # only really meant to hold 1 item, just reusing gevent's wait and timeout machinery
autocheck_jobs = [] # list of dicts with the keys (channel_id, channel_name, next_check_time). Stores all the channels that need to be autochecked and when to check them
with open_database() as connection:
with connection as cursor:
now = time.time()
for row in cursor.execute('''SELECT yt_channel_id, channel_name, next_check_time FROM subscribed_channels WHERE muted != 1''').fetchall():
if row[2] is None:
next_check_time = 0
else:
next_check_time = row[2]
# expired, check randomly within the next hour
# note: even if it isn't scheduled in the past right now, it might end up being if it's due soon and we dont start dispatching by then, see below where time_until_earliest_job is negative
if next_check_time < now:
next_check_time = now + 3600*secrets.randbelow(60)/60
row = (row[0], row[1], next_check_time)
_schedule_checking(cursor, row[0], next_check_time)
autocheck_jobs.append({'channel_id': row[0], 'channel_name': row[1], 'next_check_time': next_check_time})
def autocheck_dispatcher():
'''Scans the auto_check_list. Sleeps until the earliest job is due, then adds that channel to the checking queue above. Can be sent a new job through autocheck_job_application''' '''Scans the auto_check_list. Sleeps until the earliest job is due, then adds that channel to the checking queue above. Can be sent a new job through autocheck_job_application'''
while True: while True:
if len(autocheck_jobs) == 0: if len(autocheck_jobs) == 0:
@ -395,8 +369,49 @@ if settings.autocheck_subscriptions:
check_channels_queue.put(earliest_job['channel_id']) check_channels_queue.put(earliest_job['channel_id'])
del autocheck_jobs[earliest_job_index] del autocheck_jobs[earliest_job_index]
dispatcher_greenlet = None
def start_autocheck_system():
global autocheck_job_application
global autocheck_jobs
global dispatcher_greenlet
gevent.spawn(autocheck_dispatcher) # job application format: dict with keys (channel_id, channel_name, next_check_time)
autocheck_job_application = gevent.queue.Queue() # only really meant to hold 1 item, just reusing gevent's wait and timeout machinery
autocheck_jobs = [] # list of dicts with the keys (channel_id, channel_name, next_check_time). Stores all the channels that need to be autochecked and when to check them
with open_database() as connection:
with connection as cursor:
now = time.time()
for row in cursor.execute('''SELECT yt_channel_id, channel_name, next_check_time FROM subscribed_channels WHERE muted != 1''').fetchall():
if row[2] is None:
next_check_time = 0
else:
next_check_time = row[2]
# expired, check randomly within the next hour
# note: even if it isn't scheduled in the past right now, it might end up being if it's due soon and we dont start dispatching by then, see below where time_until_earliest_job is negative
if next_check_time < now:
next_check_time = now + 3600*secrets.randbelow(60)/60
row = (row[0], row[1], next_check_time)
_schedule_checking(cursor, row[0], next_check_time)
autocheck_jobs.append({'channel_id': row[0], 'channel_name': row[1], 'next_check_time': next_check_time})
dispatcher_greenlet = gevent.spawn(autocheck_dispatcher)
def stop_autocheck_system():
if dispatcher_greenlet is not None:
dispatcher_greenlet.kill()
def autocheck_setting_changed(old_value, new_value):
if new_value:
start_autocheck_system()
else:
stop_autocheck_system()
settings.add_setting_changed_hook('autocheck_subscriptions',
autocheck_setting_changed)
if settings.autocheck_subscriptions:
start_autocheck_system()
# ---------------------------- # ----------------------------