diff --git a/sopel_SpiceBot_Core_1/SBCore/__init__.py b/sopel_SpiceBot_Core_1/SBCore/__init__.py index 023eacd..de6409f 100644 --- a/sopel_SpiceBot_Core_1/SBCore/__init__.py +++ b/sopel_SpiceBot_Core_1/SBCore/__init__.py @@ -20,7 +20,7 @@ class SpiceBotCore_OBJ(): self.logger.info("SpiceBot Logging Interface Setup Complete.") # Allow SpiceBot to interact with Sopel Scheduler - self.scheduler = Scheduler() + self.scheduler = Scheduler(self.logger) self.logger.info("SpiceBot Scheduler Interface Setup Complete.") # Allow Spicebot to mimic Sopel Config diff --git a/sopel_SpiceBot_Core_1/SBCore/interface/scheduler/__init__.py b/sopel_SpiceBot_Core_1/SBCore/interface/scheduler/__init__.py index 2924cd0..d072cc3 100644 --- a/sopel_SpiceBot_Core_1/SBCore/interface/scheduler/__init__.py +++ b/sopel_SpiceBot_Core_1/SBCore/interface/scheduler/__init__.py @@ -1,31 +1,124 @@ +import functools +import threading +import schedule +import time -from sopel.tools import jobs + +def humanized_time(countdownseconds): + time = float(countdownseconds) + if time == 0: + return "just now" + year = time // (365 * 24 * 3600) + time = time % (365 * 24 * 3600) + day = time // (24 * 3600) + time = time % (24 * 3600) + time = time % (24 * 3600) + hour = time // 3600 + time %= 3600 + minute = time // 60 + time %= 60 + second = time + displaymsg = None + timearray = ['year', 'day', 'hour', 'minute', 'second'] + for x in timearray: + currenttimevar = eval(x) + if currenttimevar >= 1: + timetype = x + if currenttimevar > 1: + timetype = str(x+"s") + if displaymsg: + displaymsg = "%s %s %s" % (displaymsg, int(currenttimevar), timetype) + else: + displaymsg = "%s %s" % (int(currenttimevar), timetype) + if not displaymsg: + return "just now" + return displaymsg + # just for ignoring a pep error + year, day, hour, minute, second class Scheduler(): + """ + SpiceBot Scheduling events system. + """ - def __init__(self): - self.scheduler = jobs.Scheduler(self) + def __init__(self, logger): + self.logger = logger - job = jobs.Job( - [5], - plugin='coretasks', - label='throttle_join', - handler=self.fart, - threaded=True, - doc=None, - ) - self.scheduler.register(job) + self.schedule = schedule - self.scheduler.start() + # This decorator can be applied to any job function + def job_wrapper(self, func): + @functools.wraps(func) + def wrapper(*args, **kwargs): - def fart(self, *args, **kwargs): - print("toots mcgoots") + job_name = func.__name__ + start_timestamp = time.time() + + self.logger.debug('Running job: %s' % job_name) + + result = func(*args, **kwargs) + + total_time = humanized_time(time.time() - start_timestamp) + self.logger.debug('Job %s completed in %s' % (job_name, total_time)) + + return result + + return wrapper + + def remove(self, remtag): + joblist = self.jobs + for job_item in joblist: + if len(list(job_item.tags)): + if remtag in list(job_item.tags): + self.schedule.cancel_job(job_item) + + def list_tags(self): + tagslist = [] + joblist = self.jobs + for job_item in joblist: + if len(list(job_item.tags)): + tagslist.extend(list(job_item.tags)) + return tagslist + + def list_jobs(self): + jobsdicts = [] + joblist = self.jobs + for job_item in joblist: + if len(list(job_item.tags)): + jobsdicts.append({ + "name": list(job_item.tags)[0], + "last_run": job_item.last_run, + "next_run": job_item.next_run + }) + return jobsdicts + + def run_from_tag(self, runtag): + joblist = self.jobs + for job_item in joblist: + if len(list(job_item.tags)): + if runtag in list(job_item.tags): + self.logger.debug("Job %s was triggered to run." % list(job_item.tags)[0]) + job_item.run() + + def run(self): + """ + Run all scheduled tasks. + """ + + # Start a thread to run the events + t = threading.Thread(target=self.thread_worker, args=()) + t.start() + + def thread_worker(self): + while True: + self.schedule.run_pending() + time.sleep(1) def __getattr__(self, name): """ Quick and dirty shortcuts. Will only get called for undefined attributes. """ - if hasattr(self.scheduler, name): - return eval("self.scheduler.%s" % name) + if hasattr(self.schedule, name): + return eval("self.schedule.%s" % name)