def test3(): """定时执行任务,暂停,恢复""" start_time = time.time() scheduler = BackgroundScheduler() scheduler.add_job( my_job, 'interval', args=('123', ), seconds=1, id='my_job_id') # 每隔1秒执行一次my_job函数,args为函数my_job的输入参数;id:可省略; scheduler.start() # 程序运行到这里,任务没有运行完也会往后执行,既执行后面的任务,又执行这个任务。 print('运行到了这里1') while (scheduler.state): if time.time() - start_time > 5: print('暂停作业') scheduler.pause() # 暂停作业: break print('恢复作业') if time.time() - start_time > 5: scheduler.resume() # time.sleep(4) print('当前任务列表:{}'.format( scheduler.get_jobs())) # 获得调度作业的列表,可以使用 get_jobs() 来完成,它会返回所有的job实例 scheduler.get_job('my_job_id') # 获取id为my_job_id的作业实例 scheduler.print_jobs() # 输出所有格式化的作业列表。 print('移除作业') # scheduler.remove_job('my_job_id') # 移除id为my_job_id的作业 scheduler.remove_all_jobs() # 移除所有的作业
class Camera: def __init__(self, queue_len=10): #初始化对象 self.q_edit = Queue(maxsize=queue_len) self.q_show = Queue(maxsize=queue_len) self.camera = cv2.VideoCapture(0) self.classifier = Detector() self.sch = BackgroundScheduler() self.sch.add_job(self.work_once, 'interval', seconds=0.5) def work_once(self): try: if self.camera.isOpened(): ok, img = self.camera.read() if not ok: print('camera cannot be read!') exit(2) face_edit, face_show = self.classifier.get_face_by_array(img) if face_edit is None: return None if self.q_edit.full(): self.q_edit.get() self.q_show.get() self.q_edit.put(face_edit) self.q_show.put(face_show) else: print('camera cannot open!') exit(3) except Exception as e: print(e) pass #让相机开始工作 def start(self): self.sch.start() def pause(self): self.sch.pause() def resume(self): self.sch.resume() def end(self): self.sch.shutdown() self.camera.release() cv2.destroyAllWindows() def get_image(self): #从队列弹出图片 #如果队列为空,则返回None if self.q_edit.empty(): return [None, None] #否则返回队首的已经处理过的面部图片的文件名 else: rst = [self.q_edit.get(), self.q_show.get()] return rst def clear(self): self.q_edit.queue.clear() self.q_show.queue.clear()
class SerialReader: scheduler = None job = None def __init__(self, serial, callback, interval=0.1): self.active = True self.interval = interval self.serial = serial self.data = None self.callback = callback def start(self): self.scheduler = BackgroundScheduler() self.job = self.scheduler.add_job(self.test, 'interval', seconds=self.interval) self.scheduler.start() def pause(self): self.scheduler.pause() def resume(self): self.scheduler.resume() def test(self): n_in = self.serial.in_waiting if n_in > 0: self.data = self.serial.read() if self.data is not None and len(self.data) > 0: self.callback(self.data) def stop(self): self.scheduler.remove_all_jobs() self.scheduler.shutdown()
class GatedScraper: def __init__(self, cookie, uid, interval=15): if (cookie == None): raise Exception('Cookie is required to be set') if (uid == None): raise Exception('Tadpoles UID is required to be set') self.cookie = cookie self.uid = uid self.requests = [] self.sched = BackgroundScheduler() self.sched.start() self.sched.add_job(self.fire_job, 'interval', seconds=interval, jitter=5) def fire_job(self): if (len(self.requests) == 0): return currentItem = self.requests.pop(0) if currentItem['url'] == None: currentItem['callback'](None, currentItem['params']) return curReq = urllib.request.Request(currentItem['url']) curReq.add_header('cookie', self.cookie) curReq.add_header('x-tadpoles-uid', self.uid) resp = urllib.request.urlopen(curReq) if (resp.getcode() >= 500): self.requests.insert(0, currentItem) self.sched.pause() time.sleep(10) self.sched.resume() else: currentItem['callback'](resp, currentItem['params']) def add_job(self, url, callback, **params): to_append = {} to_append['url'] = url to_append['callback'] = callback to_append['params'] = params self.requests.append(to_append) def pause(self): self.sched.pause() def start(self): self.sched.start()
class Scheduler(object): def __init__(self): self._scheduler = BackgroundScheduler(executors=executors, job_defaults=job_defaults) self._scheduler.add_jobstore('redis', jobs_key='crontpy.jobs', run_times_key='crontpy.run_times') @property def running(self): return self._scheduler.running def start(self): self._scheduler.start() def shutdown(self, wait=True): self._scheduler.shutdown(wait) def pause(self): self._scheduler.pause() def resume(self): self._scheduler.resume() def get_jobs(self): return self._scheduler.get_jobs() def get_job(self, jid): return self._scheduler.get_job(job_id=jid) def run_job(self, jid): job = self.get_job(jid) if not job: raise Exception('job id:{0} not found'.format(jid)) job.func(*job.args, **job.kwargs) def resume_job(self, jid): self._scheduler.resume_job(job_id=jid) def pause_job(self, jid): self._scheduler.pause_job(job_id=jid) def modify_job(self, jid, **changes): return self._scheduler.modify_job(job_id=jid, **changes) def delete_job(self, jid): self._scheduler.remove_job(job_id=jid)
def test2(): """定时执行任务,暂停,恢复""" start_time = time.time() scheduler = BackgroundScheduler(daemonic = False) # daemonic = False, scheduler.add_job(my_job, 'interval', args=('123',),seconds=1, id='my_job_id') # 每隔1秒执行一次my_job函数,args为函数my_job的输入参数;id:可省略; scheduler.start() # 程序运行到这里,任务没有运行完也会往后执行,既执行后面的任务,又执行这个任务。 print('运行到了这里1') while (scheduler.state): if time.time() - start_time >5: print('暂停作业') scheduler.pause() # 暂停作业: break print('恢复作业') if time.time() - start_time >5: scheduler.resume() # 恢复作业 time.sleep(4) print('再次暂停作业')
def begin(): scheduler = BackgroundScheduler() scheduler.add_job(update, 'interval', minutes=1) scheduler.add_job(update_aroon, 'interval', minutes=1) scheduler.add_job(update_atr, 'interval', minutes=1) scheduler.add_job(update_chaikin, 'interval', minutes=1) scheduler.add_job(update_sma, 'interval', minutes=1) scheduler.add_job(update_ssl, 'interval', minutes=1) scheduler.start() date = datetime.now() if date.isocalendar()[2] == 5 and date.hour >= 13: print("closed") scheduler.pause() if date.isocalendar()[2] == 7 and date.hour >= 14: print("open") scheduler.resume()
class Repeat: def __init__(self, toDo, repeatTime): self.isQuit = False self.scheduler = BackgroundScheduler() self.job = None self.i = 1 self.addJob(toDo, repeatTime) def addJob(self, toDo, repeatTime=1800): print("Job added every " + str(repeatTime)) self.job = self.scheduler.add_job(toDo, 'interval', seconds=repeatTime, max_instances=3) def startJobs(self): print("Started job") self.scheduler.start() def quitJob(self): self.scheduler.remove_all_jobs() self.scheduler.shutdown(wait=False) def sayHi(self): print("Hi") self.i += 1 if self.i == 3: self.pauseJob() self.resumeJob() def resumeJob(self): self.scheduler.resume() def pauseJob(self): self.scheduler.pause() print("paused") # ------------------ usage: ---------------------- # s = Repeat() # try: # s.startJobs() # except (KeyboardInterrupt, SystemExit): # s.quitJob()
class Routine: def __init__(self, config, routine_id, desc, num_cmd, cmd_list=[], crontab_list=[]): self.main_conf = config self.num_cmd = num_cmd self.routine_id = routine_id self.cmd_list, self.crontab_list = cmd_list, crontab_list self.sched = BackgroundScheduler() for i in range(len(cmd_list)): self.sched.add_job(self.sendCommand, CronTrigger.from_crontab(crontab_list[i]), kwargs={'cmd': cmd_list[i]}) def sendCommand(self, cmd): logger.info("Routine #" + str(self.routine_id + 1) + ": sending command " + cmd) address = "http://localhost/cgi-bin/picmd" try: r = requests.post(address, data={'code': cmd}) except: return -1 finally: return 1 def run(self): global routine_status self.sched.start() status = 1 while True: if routine_status[self.routine_id] == 0 and status == 1: self.sched.pause() logger.info("Routine #" + str(self.routine_id + 1) + " paused") status = 0 elif routine_status[self.routine_id] == 1 and status == 0: self.sched.resume() logger.info("Routine #" + str(self.routine_id + 1) + " resumed") status = 1 time.sleep(10)
def test2(): """定时执行任务,暂停,恢复""" start_time = time.time() scheduler = BackgroundScheduler(daemonic=False) # daemonic = False, scheduler.add_job( my_job, 'interval', args=('123', ), seconds=1, id='my_job_id') # 每隔1秒执行一次my_job函数,args为函数my_job的输入参数;id:可省略; scheduler.start() # 程序运行到这里,任务没有运行完也会往后执行,既执行后面的任务,又执行这个任务。 print('运行到了这里1') while (scheduler.state): if time.time() - start_time > 5: print('暂停作业') scheduler.pause() # 暂停作业: break print('恢复作业') if time.time() - start_time > 5: scheduler.resume() # 恢复作业 time.sleep(4) print('再次暂停作业')
def test3(): """定时执行任务,暂停,恢复""" start_time = time.time() scheduler = BackgroundScheduler() scheduler.add_job(my_job, 'interval', args=('123',),seconds=1, id='my_job_id') # 每隔1秒执行一次my_job函数,args为函数my_job的输入参数;id:可省略; scheduler.start() # 程序运行到这里,任务没有运行完也会往后执行,既执行后面的任务,又执行这个任务。 print('运行到了这里1') while (scheduler.state): if time.time() - start_time >5: print('暂停作业') scheduler.pause() # 暂停作业: break print('恢复作业') if time.time() - start_time >5: scheduler.resume() # time.sleep(4) print('当前任务列表:{}'.format(scheduler.get_jobs())) # 获得调度作业的列表,可以使用 get_jobs() 来完成,它会返回所有的job实例 scheduler.get_job('my_job_id') # 获取id为my_job_id的作业实例 scheduler.print_jobs() # 输出所有格式化的作业列表。 print('移除作业') # scheduler.remove_job('my_job_id') # 移除id为my_job_id的作业 scheduler.remove_all_jobs() # 移除所有的作业
class Dummy(object): def __init__(self): self.is_ping = False self.pinger = None self.master_id = None self.thread_num = None pass def main(self): def has_thread_num(fn): def wrapped(bot, update): if self.thread_num: fn(bot, update) else: bot.sendMessage(update.message.chat_id, 'Please, set thread number!') return wrapped def set_thread_number(bot, update, args): chat_id = update.message.chat_id if self.master_id is not None and chat_id != self.master_id: bot.sendMessage(chat_id, 'You are not my master!') return self.thread_num = args[0] with open('data/bot.txt', 'w') as bot_data: bot_data.write(json.dumps(dict(thread_num=self.thread_num))) bot.sendMessage(chat_id, 'Thread number set =^-^=') def start_ping(bot, update): chat_id = update.message.chat_id if self.master_id is not None and chat_id != self.master_id: bot.sendMessage(chat_id, 'You are not my master!') return if self.is_ping: self.pinger.pause() else: if not self.pinger: def tick(): if getters.ThreadData(self.thread_num).get_page_num() > 6: status(bot, update) self.master_id = update.message.chat_id self.pinger = BackgroundScheduler() self.pinger.add_job(tick, 'interval', minutes=60) self.pinger.start() self.pinger.resume() self.is_ping = not self.is_ping bot.sendMessage(update.message.chat_id, 'ping {}'.format(self.is_ping and 'started' or 'ended')) @has_thread_num def page(bot, update): getter = getters.ThreadData(self.thread_num) page_num = getter.get_page_num() bot.sendMessage(update.message.chat_id, page_num) @has_thread_num def status(bot, update): bot.sendChatAction(update.message.chat_id, 'typing') getter = getters.ThreadData(self.thread_num) bot.sendMessage(update.message.chat_id, templating.make_msg(getter.get_page_num(), getter.get_thread_stats()), parse_mode='HTML') @has_thread_num @show_typing def last_post(bot, update): posts = getters.ThreadData(self.thread_num).get_posts() if len(posts): post = posts[-1] _show_post(bot, update, post) else: bot.sendMessage(update.message.chat_id, "No posts found for thread:{}".format(self.thread_num)) @show_typing def _show_post(bot, update, post): post_num = "Post № {}".format(post['no']) chat_id = update.message.chat_id try: bot.sendMessage(chat_id, post_num) # FIXME no progress indication while acquiring image if post['ext'] in ['.gif', '.webm']: bot.sendDocument(chat_id, document="https://i.4cdn.org/c/{0}{1}".format(post['tim'], post['ext'])) else: bot.sendPhoto(chat_id, photo="https://i.4cdn.org/c/{0}{1}".format(post['tim'], post['ext'])) bot.sendMessage(chat_id, "{0}{1}".format(post['filename'], post['ext'])) except KeyError: pass try: data = _prepare_post_text(post['com']) bot.sendMessage(chat_id, data['text'], parse_mode='HTML', reply_markup=data['markup']) except Exception as e: print('e:', e) pass def _prepare_post_text(text): keyboard = [] markup = None result = text.replace('<br>', '\r\n') links = re.findall('#p(\d+)', result) result = re.sub('<a.+#p(\d+).+</a>', '>>\g<1>', result) for one in links: keyboard.append([InlineKeyboardButton(">>{}".format(one), callback_data=one)]) if len(keyboard): markup = InlineKeyboardMarkup(keyboard) return dict(text=result, markup=markup) # Create the EventHandler and pass it your bot's token. updater = Updater(TOKEN) # Get the dispatcher to register handlers dp = updater.dispatcher # on different commands - answer in Telegram dp.add_handler(CommandHandler("start", start)) dp.add_handler(CommandHandler("set", set_thread_number, pass_args=True)) dp.add_handler(CommandHandler("help", bot_help)) dp.add_handler(CommandHandler("page", page)) dp.add_handler(CommandHandler("status", status)) dp.add_handler(CommandHandler("ping", start_ping)) dp.add_handler(CommandHandler("last", last_post)) # on noncommand i.e message - echo the message on Telegram dp.add_handler(MessageHandler([Filters.text], echo)) # log all errors dp.add_error_handler(error) # Start the Bot updater.start_polling() path = 'data/bot.txt' if os.path.isfile(path): self.thread_num = json.loads(open(path, 'r').read())['thread_num'] # Run the bot until the you presses Ctrl-C or the process receives SIGINT, # SIGTERM or SIGABRT. This should be used most of the time, since # start_polling() is non-blocking and will stop the bot gracefully. updater.idle()
lcd.message = "Next pump in:\n" + str(deltaTime) else: lcd.clear() lcd.message = "PH: " + str(senPH) + "\n" + "EC: " + str(senEC) if sysError: print("System Paused!") lcd.clear() lcd.message = "System Paused!\nPress Select to Start" time.sleep(slp) scheduler.pause() while sysError: if lcd.select_button: sysError = False else: scheduler.resume() #------------------------------------------- # Read Ultrasonic senUltra = readSenUltra() senPH = readSenPH() senEC = readSenEC() AutoLevelData() AutoLevelTest() # Error Checking, pause apscheduler before enterError. scheduler.pause() if senUltra < 22: sendEmail("Water is Low, Fill Up Soon!")
class CronManager: def __init__(self, use_mongo_db=True): self.scheduler = BackgroundScheduler( timezone=timezone('Asia/Shanghai')) self.scheduler.configure() if use_mongo_db: self.job_store = MongoDBJobStore(database='apscheduler', collection='cronJob', client=db) self.scheduler.add_jobstore(self.job_store) self.is_replace_existing = True else: self.is_replace_existing = False def add_cron(self, cron_instance): try: if not isinstance(cron_instance, Cron): raise TypeError('please add correct cron!') if cron_instance.trigger_type == 'interval': seconds = cron_instance.trigger_args.get('seconds') if not isinstance( seconds, int) and not common.can_convert_to_int(seconds): raise TypeError('please set correct time interval') seconds = int(seconds) if seconds <= 0: raise ValueError('please set interval > 0') job = self.scheduler.add_job( func=cron_instance.cron_mission, trigger=cron_instance.trigger_type, seconds=seconds, replace_existing=self.is_replace_existing, coalesce=True, id=cron_instance.get_cron_job_id(), max_instances=5, jitter=0) elif cron_instance.trigger_type == 'date': run_date = cron_instance.trigger_args.get('run_date') # TODO 判断run_date类型 job = self.scheduler.add_job( func=cron_instance.cron_mission, trigger=cron_instance.trigger_type, run_date=run_date, replace_existing=self.is_replace_existing, coalesce=True, id=cron_instance.get_cron_job_id()) elif cron_instance.trigger_type == 'cron': raise TypeError('暂时不支持 trigger_type 等于 \'cron\'') return cron_instance.get_cron_job_id() except BaseException as e: with app.app_context(): current_app.logger.error("add_cron failed. - %s" % str(e)) def start(self, paused=False): self.scheduler.start(paused=paused) def pause_cron(self, cron_id=None, pause_all=False): if pause_all: self.scheduler.pause() elif cron_id: self.scheduler.pause_job(job_id=cron_id) def resume_cron(self, cron_id=None, resume_all=False): if resume_all: self.scheduler.resume() elif cron_id: self.scheduler.resume_job(job_id=cron_id) def del_cron(self, cron_id=None, del_all=False): if del_all: self.scheduler.remove_all_jobs() elif cron_id: self.scheduler.remove_job(job_id=cron_id) def update_cron(self, cron_job_id, project_id, cron_info): try: if not isinstance(cron_job_id, str): raise TypeError('cron_id must be str') if not isinstance(project_id, str): raise TypeError('project_id must be str') if not isinstance(cron_info, dict): raise TypeError('cron_info must be dict') trigger_type = cron_info.get('triggerType') interval = cron_info.get('interval') run_date = cron_info.get('runDate') test_suite_id_list = cron_info.get('testSuiteIdList') include_forbidden = cron_info.get('includeForbidden') test_env_id = cron_info.get('testEnvId') always_send_mail = cron_info.get('alwaysSendMail') alarm_mail_group_list = cron_info.get('alarmMailGroupList') enable_wxwork_notify = cron_info.get('enableWXWorkNotify') wxwork_api_key = cron_info.get('WXWorkAPIKey') wxwork_mention_mobile_list = cron_info.get( 'WXWorkMentionMobileList') always_wxwork_notify = cron_info.get('alwaysWXWorkNotify') enable_ding_talk_notify = cron_info.get('enableDingTalkNotify') ding_talk_access_token = cron_info.get('DingTalkAccessToken') ding_talk_at_mobiles = cron_info.get('DingTalkAtMobiles') ding_talk_secret = cron_info.get('DingTalkSecret') always_ding_talk_notify = cron_info.get('alwaysDingTalkNotify') if trigger_type == 'interval' and int(interval) > 0: self.scheduler.modify_job( job_id=cron_job_id, trigger=IntervalTrigger(seconds=interval)) elif trigger_type == 'date': self.scheduler.modify_job( job_id=cron_job_id, trigger=DateTrigger(run_date=run_date)) else: raise TypeError('更新定时任务触发器失败!') if run_date: cron = Cron( cron_job_id=cron_job_id, test_suite_id_list=test_suite_id_list, project_id=project_id, test_env_id=test_env_id, include_forbidden=include_forbidden, enable_wxwork_notify=enable_wxwork_notify, wxwork_api_key=wxwork_api_key, wxwork_mention_mobile_list=wxwork_mention_mobile_list, always_wxwork_notify=always_wxwork_notify, enable_ding_talk_notify=enable_ding_talk_notify, ding_talk_access_token=ding_talk_access_token, ding_talk_at_mobiles=ding_talk_at_mobiles, ding_talk_secret=ding_talk_secret, always_ding_talk_notify=always_ding_talk_notify, always_send_mail=always_send_mail, alarm_mail_group_list=alarm_mail_group_list, trigger_type=trigger_type, # 更新定时器时,此参数并没有真正起到作用, 仅修改展示字段 run_date=run_date) # 更新定时器时,此参数并没有起到作用, 仅修改展示字段 else: cron = Cron( cron_job_id=cron_job_id, test_suite_id_list=test_suite_id_list, project_id=project_id, include_forbidden=include_forbidden, enable_wxwork_notify=enable_wxwork_notify, wxwork_api_key=wxwork_api_key, wxwork_mention_mobile_list=wxwork_mention_mobile_list, always_wxwork_notify=always_wxwork_notify, enable_ding_talk_notify=enable_ding_talk_notify, ding_talk_access_token=ding_talk_access_token, ding_talk_at_mobiles=ding_talk_at_mobiles, ding_talk_secret=ding_talk_secret, always_ding_talk_notify=always_ding_talk_notify, test_env_id=test_env_id, always_send_mail=always_send_mail, alarm_mail_group_list=alarm_mail_group_list, trigger_type=trigger_type, # 更新定时器时,此参数并没有起到作用, 仅修改展示字段 seconds=interval) # 更新定时器时,此参数并没有起到作用, 仅修改展示字段 # 玄学,更改job的时候必须改args,不能改func self.scheduler.modify_job(job_id=cron_job_id, coalesce=True, args=[cron]) except BaseException as e: with app.app_context(): current_app.logger.error("update_cron failed. - %s" % str(e)) def shutdown(self, force_shutdown=False): if force_shutdown: self.scheduler.shutdown(wait=False) else: self.scheduler.shutdown(wait=True) def get_jobs(self): return self.scheduler.get_jobs()
class SellItem: """ SellItem class docs """ def __init__(self, owner, title, itemtype, description, auction_type, starting, minbid=1.0, image=None): self.lock = th.Lock() self.owner = owner self.owner.add_item(self) self.title = title self.itemtype = itemtype self.description = description self.auction_type = auction_type self.minbid = minbid self.image = image self.state = "onhold" self.auction_started = False self.bid_records = [] self.creation_time = time.time() self.current_value = starting self.current_bidder = None self.auction_start_timestamp = None self.auction_end_timestamp = None self.obs = NotificationModule() #self.bid_operator = 1 if self.bidtype == "increment" else -1 self.obs.notify(self.itemtype, "Object Created") # {"itemtype": [callback1,calback2,..]} self.callbacks = {} #self.stopbid = None if auction_type[0] == "decrement": self.scheduler = BackgroundScheduler() self.decrement_job = self.scheduler.add_job( self.__decrement_periodic, 'interval', minutes=self.auction_type[1]) self.scheduler.start(paused=True) elif auction_type[0] == "instantincrement": self.overall_bids = {} def __decrement_periodic(self): with self.lock: self.current_value -= self.auction_type[2] self.notify_user("Price dropped! Current:{}".format( self.current_value)) if self.current_value <= self.auction_type[3]: self.auction_started = False self.current_bidder = False self.scheduler.pause() self.notify_user("Price<=STOP stop:{}".format( self.auction_type[3])) self.state = "onhold" def startauction(self, owner=None): if owner != self.owner: raise Exception("User is not owner, can not sell") #if not (type(stopbid) is float or type(stopbid) is int): # raise ValueError("amount is invalid") if self.auction_started: raise Exception("Auction is already started at {}".format( utilities.dateformatter(self.auction_start_timestamp))) #if stopbid: # self.stopbid = stopbid self.state = "active" self.auction_started = True self.auction_start_timestamp = time.time() self.notify_user("Auction is started!") self.obs.notify(self.itemtype, "Auction Started!") if self.auction_type[0] == "decrement": self.scheduler.resume() def bid(self, user, amount): if user == self.owner: raise Exception("Owner cannot bid!") with self.lock: if not (type(amount) is float or type(amount) is int): raise ValueError("amount is invalid") if not type(user) is User: raise ValueError("invalid user") if not self.auction_started: raise Exception("Auction is not started") if amount <= 0: raise ValueError("Bid cannot be <= zero!") if amount < self.minbid: raise ValueError( " Bid amount is lower than minimum bid amount({})".format( self.minbid)) if self.auction_type[0] == "increment": if amount < self.current_value + self.auction_type[1]: raise ValueError(" Bid amount is lower than current value+delta(current:{},delta:{})."\ .format(self.current_value,self.auction_type[1])) if (user.reserve_amount(amount)): if self.current_bidder: self.current_bidder.release_amount(self.current_value) self.current_value = amount self.current_bidder = user self.bid_records.append({ "bidder": user, "amount": amount, "timestamp": time.time() }) if self.auction_type[2] <= self.current_value: print("Satiyorum... Sattim!") self.bid_records.append({ "bidder": user, "amount": amount, "timestamp": time.time() }) self.auction_started = False self.auction_end_timestamp = time.time() self.current_bidder.checkout(amount, self, self.owner) self.owner = self.current_bidder self.state = "sold" else: raise Exception( "User does not have this much unreserved amount.") elif self.auction_type[0] == "decrement": if amount < self.current_value: raise Exception( "Auction type decrement. Value is lower than current({})" .format(self.current_value)) if (user.reserve_amount(amount)): print("Satiyorum... Sattim!") self.auction_started = False self.auction_end_timestamp = time.time() self.current_bidder = user self.current_bidder.checkout(amount, self, self.owner) self.bid_records.append({ "bidder": user, "amount": amount, "timestamp": time.time() }) self.owner = self.current_bidder self.scheduler.pause() self.state = "sold" else: raise Exception( "User does not have this much unreserved amount.") else: if (amount < self.auction_type[1]): raise Exception( "Bid amount is lower than minbid({})".format( self.auction_type[1])) if (user.reserve_amount(amount)): self.current_value += amount self.bid_records.append({ "bidder": user, "amount": amount, "timestamp": time.time() }) if not user in self.overall_bids: self.overall_bids[user] = amount else: self.overall_bids[user] += amount max_user = user for u in self.overall_bids: if self.overall_bids[u] > self.overall_bids[max_user]: max_user = u if self.current_value >= self.auction_type[2]: print("Satiyorum... Sattim!") self.auction_started = False self.auction_end_timestamp = time.time() max_user.checkout(0, self, self.owner, self.overall_bids) self.owner = max_user self.state = "sold" else: raise Exception( "User does not have this much unreserved amount.!") self.notify_user() def sell(self, owner=None): with self.lock: if owner != self.owner: raise Exception("User is not owner, can not sell") if not self.auction_started: raise Exception("Auction is not started yet!") # OWNER SHOULD BE CHECKED, only owner can call sell() if self.auction_type[0] == "decrement": self.state = "onhold" self.notify_user("Item Auction Stopped") return if self.auction_type[0] == "instantincrement": if self.overall_bids: self.state = "sold" self.auction_started = False self.auction_end_timestamp = time.time() max_user = None for u in self.overall_bids: if not max_user: max_user = u elif self.overall_bids[u] > self.overall_bids[max_user]: max_user = u max_user.checkout(0, self, self.owner, self.overall_bids) self.owner = max_user return else: self.state = "onhold" self.auction_started = False self.state = "onhold" self.notify_user() if self.current_value != 0 and self.current_bidder: self.current_bidder.checkout(self.current_value, self, self.owner) self.owner = self.current_bidder self.state = "sold" def view(self): bids = [(i["bidder"].email, i["amount"]) for i in self.bid_records] return { "title": self.title, "description": self.description, "auction_start": utilities.dateformatter(self.auction_start_timestamp) or "Auction is not started yet", "auction_end": utilities.dateformatter(self.auction_end_timestamp) or "Auction is not end", "bids": bids, "current_value": self.current_value, "current_bidder": self.current_bidder.email, "owner": self.owner.email } def watch(self, user, watchmethod): if not isinstance(user, User): raise ValueError("invalid user") with self.lock: if user in self.callbacks: raise Exception("User is already add watch_list") self.callbacks[user] = watchmethod def history(self): return { "creation": utilities.dateformatter(self.creation_time), "auction_start": utilities.dateformatter(self.auction_start_timestamp), "bids": self.bid_records, "current_value": self.current_value } def notify_user(self, descr="Item state is changed"): for user in self.callbacks: try: self.callbacks[user](descr) except: pass
class CronManager: def __init__(self, use_mongo_db=True): self.scheduler = BackgroundScheduler(timezone=shanghai_tz) self.scheduler.configure() if use_mongo_db: self.job_store = MongoDBJobStore(database='apscheduler', collection='cronTab', client=db) self.scheduler.add_jobstore(self.job_store) self.is_replace_existing = True else: self.is_replace_existing = False def add_cron(self, cron_instance): if not isinstance(cron_instance, Cron): raise TypeError('please add correct cron!') if cron_instance.trigger_type == 'interval': seconds = cron_instance.trigger_args.get('seconds') if not isinstance(seconds, int) and not common.can_convert_to_int(seconds): raise TypeError('请输入合法的时间间隔!') seconds = int(seconds) if seconds <= 0: raise TypeError('请输入大于0的时间间隔!') job = self.scheduler.add_job( func=cron_instance.cron_mission, trigger=cron_instance.trigger_type, seconds=seconds, replace_existing=self.is_replace_existing, coalesce=True, id=cron_instance.get_id(), max_instances=5, jitter=0) # 玄学,新增job的时候不用加args,直接加对象调用的func elif cron_instance.trigger_type == 'date': run_date = cron_instance.trigger_args.get('run_date') # TODO 判断run_date类型 job = self.scheduler.add_job( func=cron_instance.cron_mission, trigger=cron_instance.trigger_type, run_date=run_date, replace_existing=self.is_replace_existing, coalesce=True, id=cron_instance.get_id()) # 玄学,新增job的时候不用加args,直接加对象调用的func elif cron_instance.trigger_type == 'cron': raise TypeError('暂时不支持 trigger_type 等于 \'cron\'') return cron_instance.get_id() def start(self, paused=False): self.scheduler.start(paused=paused) def pause_cron(self, cron_id=None, pause_all=False): if pause_all: self.scheduler.pause() elif cron_id: self.scheduler.pause_job(job_id=cron_id) def resume_cron(self, cron_id=None, resume_all=False): if resume_all: self.scheduler.resume() elif cron_id: self.scheduler.resume_job(job_id=cron_id) def del_cron(self, cron_id=None, del_all=False): if del_all: self.scheduler.remove_all_jobs() elif cron_id: self.scheduler.remove_job(job_id=cron_id) def update_cron(self, cron_id, cron_info): if not isinstance(cron_id, str): raise TypeError('cron_id must be str') if not isinstance(cron_info, dict): raise TypeError('cron_info must be dict') trigger_type = cron_info.get('triggerType') interval = cron_info.get('interval') run_date = cron_info.get('runDate') test_case_suite_id_list = cron_info.get('testCaseSuiteIdList') is_execute_forbiddened_case = cron_info.get('isExecuteForbiddenedCase') test_case_id_list = cron_info.get('testCaseIdList') test_domain = cron_info.get('testDomain') global_vars_id = cron_info.get('globalVarsId') alarm_mail_list = cron_info.get('alarmMailList') is_ding_ding_notify = cron_info.get('isDingDingNotify') ding_ding_access_token = cron_info.get('dingdingAccessToken') ding_ding_notify_strategy = cron_info.get('dingdingNotifyStrategy') is_enterprise_wechat_notify = cron_info.get('isEnterpriseWechatNotify') enterprise_wechat_access_token = cron_info.get( 'enterpriseWechatAccessToken') enterprise_wechat_notify_strategy = cron_info.get( 'enterpriseWechatNotifyStrategy') cron_name = cron_info.get('name') try: if trigger_type == 'interval' and int(interval) > 0: self.scheduler.modify_job( job_id=cron_id, trigger=IntervalTrigger(seconds=interval)) elif trigger_type == 'date': # TODO 判断run_date类型 self.scheduler.modify_job( job_id=cron_id, trigger=DateTrigger(run_date=run_date)) else: raise TypeError('更新定时任务触发器失败!') if run_date: cron = Cron( test_case_suite_id_list=test_case_suite_id_list, is_execute_forbiddened_case=is_execute_forbiddened_case, test_domain=test_domain, global_vars_id=global_vars_id, alarm_mail_list=alarm_mail_list, is_ding_ding_notify=is_ding_ding_notify, ding_ding_access_token=ding_ding_access_token, ding_ding_notify_strategy=ding_ding_notify_strategy, is_enterprise_wechat_notify=is_enterprise_wechat_notify, enterprise_wechat_access_token= enterprise_wechat_access_token, enterprise_wechat_notify_strategy= enterprise_wechat_notify_strategy, trigger_type=trigger_type, # 更新定时器时,此参数并没有真正起到作用, 仅修改展示字段 test_case_id_list=test_case_id_list, run_date=run_date, cron_name=cron_name) # 更新定时器时,此参数并没有起到作用, 仅修改展示字段 else: cron = Cron( test_case_suite_id_list=test_case_suite_id_list, is_execute_forbiddened_case=is_execute_forbiddened_case, test_domain=test_domain, global_vars_id=global_vars_id, alarm_mail_list=alarm_mail_list, is_ding_ding_notify=is_ding_ding_notify, ding_ding_access_token=ding_ding_access_token, ding_ding_notify_strategy=ding_ding_notify_strategy, is_enterprise_wechat_notify=is_enterprise_wechat_notify, enterprise_wechat_access_token= enterprise_wechat_access_token, enterprise_wechat_notify_strategy= enterprise_wechat_notify_strategy, trigger_type=trigger_type, # 更新定时器时,此参数并没有起到作用, 仅修改展示字段 test_case_id_list=test_case_id_list, seconds=interval, # 更新定时器时,此参数并没有起到作用, 仅修改展示字段 cron_name=cron_name) # 玄学,更改job的时候必须改args,不能改func self.scheduler.modify_job(job_id=cron_id, coalesce=True, args=[cron]) except BaseException as e: raise TypeError('更新定时任务失败: %s' % e) def shutdown(self, force_shutdown=False): if force_shutdown: self.scheduler.shutdown(wait=False) else: self.scheduler.shutdown(wait=True) def get_crons(self): return self.scheduler.get_jobs()
class APS_Schedule(object): """docstring for APS_Schedule""" def __init__(self): executors = { 'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5) } # jobstores = { # 'mongo': MongoDBJobStore(collection='SchedularJobs', database='chatdb', # host=db_name, port=27017, # username=mongouser, password=mongopass), # } job_defaults = { 'coalesce': True, 'max_instances': 5, 'misfire_grace_time': 1000 } self.scheduler = BackgroundScheduler(executors=executors, job_defaults=job_defaults) self.scheduler.start() print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) # Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed. def add_execution_reminder(self, msg_title, msg_body, execution_time, user_id, notif_type, type_id): try: self.scheduler.add_job( _send_notification, 'date', run_date=execution_time, args=[msg_title, msg_body, user_id, notif_type, type_id], id=str(type_id), replace_existing=True) return True except Exception as e: print(str(e)) logger.critical( "couldnt add the job from schedular with exception : {}". format(str(e))) def remove_execution_reminder(self, job_id, job_type): try: print('before deleting the job.') job_del = self.scheduler.remove_job(str(job_id)) print(job_del, 'after delete') return True except Exception as e: logger.critical( "couldnt remove the job from schedular with exception : {}". format(str(e))) def pause_jobs(self): try: self.scheduler.pause() return True except Exception as e: logger.error( "couldnt pause the schedular with exception : {}".format( str(e))) def resume_jobs(self): try: self.scheduler.resume() return True except Exception as e: logger.error( "couldnt resume the schedular with exception : {}".format( str(e))) def shutdown_schedular(self): try: sch = self.scheduler.shutdown() return sch except Exception as e: logger.error( "couldnt shutdown the schedular with exception : {}".format( str(e)))
class Jobs: def _listener(self, event): if event.code == EVENT_JOB_SUBMITTED: logger.debug(_("The job %s started"), event.job_id) self._job_set.add(event.job_id) else: if event.job_id in self._job_set: self._job_set.remove(event.job_id) else: logger.error(_("Job %s not found in job_set"), event.job_id) # pragma: no cover if event.exception: logger.error(_("The job %s crashed"), event.job_id) # pragma: no cover else: logger.debug(_("The job %s worked"), event.job_id) logger.debug(_("Job set: %s"), self._job_set) def __init__(self, url="sqlite:///jobs.sqlite", nb_executors=1): """Initialize class. Parameters ---------- url: str SQLalchemy URL for persistent jobstore. nb_executors : int Number of concurrent executor processes. """ self._job_set = set() logger.info( _("Creating scheduler, %s executors, storing in %s"), nb_executors, str(url)[0:str(url).find(":")], ) jobstores = { "once": MemoryJobStore(), "default": SQLAlchemyJobStore(url=url) } executors = {"default": ProcessPoolExecutor(nb_executors)} job_defaults = { "coalesce": True, "max_instances": 1, "misfire_grace_time": 3600, } self._scheduler = BackgroundScheduler( jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc, ) self._scheduler.add_listener( self._listener, EVENT_JOB_SUBMITTED | EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): logger.info( _("Shutting down scheduler in __atexit__, if still running")) try: self._scheduler.shutdown(wait=False) except Exception: pass def shutdown(self): logger.info(_("Shutting down scheduler")) try: self._scheduler.shutdown() except SchedulerNotRunningError: # pragma: no cover pass def _handler(self, signum, frame): # pragma: no cover logger.error(_("Signal handler called with signal %s"), signum) try: self._scheduler.shutdown(wait=False) except SchedulerNotRunningError: pass try: parent_id = os.getpid() for child in psutil.Process(parent_id).children(recursive=True): child.kill() except Exception: pass sys.exit(1) def start(self, paused=False): logger.debug(_("Starting scheduler, paused=%s"), paused) self._scheduler.start(paused) signal.signal(signal.SIGINT, self._handler) # signal.signal(signal.SIGTERM, self._handler) # def pause(self): # logger.debug(_("Pausing scheduler")) # self._scheduler.pause() def resume(self): logger.debug(_("Resuming scheduler")) self._scheduler.resume() def remove_all_jobs(self): logger.debug(_("Removing all scheduled jobs")) self._scheduler.remove_all_jobs() def add_job_once(self, job_fn, args=None, kwargs=None): logger.debug(_("Adding immediate job %s"), args[0].__name__ + "_" + args[2].site) self._scheduler.add_job( job_fn, args=args, kwargs=kwargs, id=args[0].__name__ + "_" + args[2].site, jobstore="once", ) def add_job_schedule( self, job_fn, args=None, kwargs=None, year=None, month=None, day=None, week=None, day_of_week=None, hour=None, minute=None, second=None, ): logger.debug(_("Adding scheduled job %s"), args[0].__name__ + "_" + args[2].site) self._scheduler.add_job( job_fn, args=args, kwargs=kwargs, id=args[0].__name__ + "_" + args[2].site, jobstore="default", trigger="cron", year=year, month=month, day=day, week=week, day_of_week=day_of_week, hour=hour, minute=minute, second=second, replace_existing=True, ) def count_jobs(self): # self._scheduler.print_jobs() jobs = self._scheduler.get_jobs() logger.debug(_("Number of jobs scheduled, %s"), len(jobs)) for j in jobs: logger.debug( _("Job %s, scheduled in: %s"), j.id, j.next_run_time - datetime.now(timezone.utc), ) logger.debug(_("Number of jobs running, %s"), len(self._job_set)) return len(self._job_set) def print_jobs(self): jobs = self._scheduler.get_jobs() logger.info(_("Number of jobs scheduled, %s"), len(jobs)) for j in jobs: logger.info(_("Job %s, scheduled: %s"), j.id, j.trigger)
# time.sleep(2) # 其他任务是独立的线程执行 # print('sleep!') bb = raw_input("aaaaa:") if bb == '1': # schedmy2.start() if schedmy.state == 0: pass else: schedmy.pause() print schedmy.state # schedmy.pause_job() elif bb == '2': if schedmy.state == 0: schedmy.start() else: schedmy.resume() print schedmy.state # schedmy.resume_job() elif bb == '3': # schedmy.remove_job('autotest') schedmy.shutdown() print schedmy.state except(KeyboardInterrupt,SystemExit): print 111 # schedmy.remove_job('autotest') # schedmy.remove_job('autotest2') # schedmy.add_job(job,trigger='cron',second = '*/5',id ='autotest')
class ScheduleManager(IScheduleManager): def __init__(self, config=None, event_listener=None): self.__config = config self.__event_listener = event_listener jobstores, executors, job_defaults, timezone = self.__get_apscheduler_settings( ) # initial apscheduler self.__scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=timezone) if self.__event_listener: self.__scheduler.add_listener(self.__event_listener.event_start, EVENT_SCHEDULER_STARTED) self.__scheduler.add_listener(self.__event_listener.event_shutdown, EVENT_SCHEDULER_SHUTDOWN) self.__scheduler.add_listener(self.__event_listener.event_pause, EVENT_SCHEDULER_PAUSED) self.__scheduler.add_listener(self.__event_listener.event_resume, EVENT_SCHEDULER_RESUMED) self.__scheduler.add_listener( self.__event_listener.event_job_submit, EVENT_JOB_SUBMITTED) self.__scheduler.add_listener( self.__event_listener.event_job_max_instances, EVENT_JOB_MAX_INSTANCES) self.__scheduler.add_listener( self.__event_listener.event_job_execute, EVENT_JOB_EXECUTED) self.__scheduler.add_listener( self.__event_listener.event_job_error, EVENT_JOB_ERROR) self.__scheduler.add_listener(self.__event_listener.event_job_miss, EVENT_JOB_MISSED) def __get_apscheduler_settings(self): try: jobstore_url = "oracle+cx_oracle://{username}:{password}${host}:{port}/{dbname}".format( username=self.__config.db_user, password=self.__config.db_pwd, host=self.__config.db_host, port=self.__config.db_port, dbname=self.__config.db_name, ) jobstores = { "default": SQLAlchemyJobStore(url=jobstore_url, tablename=self.__config.tablename) } executors = { "default": ThreadPoolExecutor(self.__config.max_workers), "processpool": ProcessPoolExecutor(2) } job_defaults = { "coalesce": True, "max_instances": 10, "misfire_grace_time": 30 } timezone = self.__config.timezone return jobstores, executors, job_defaults, timezone except Exception as e: raise e def start(self, paused=False) -> bool: try: if self.__scheduler.state == STATE_RUNNING: return True self.__scheduler.start(paused=paused) except Exception as e: logging.error(f"scheduler start error...... {str(e)}") raise e def shutdown(self, wait=False) -> bool: try: self.__scheduler.shutdown(wait=wait) if self.__scheduler.state == STATE_STOPPED: return True return False except Exception as e: logging.error(f"scheduler shutdown error...... {str(e)}") raise e def pause(self) -> bool: try: self.__scheduler.pause() if self.__scheduler.state == STATE_PAUSED: return True return False except Exception as e: logging.error(f"scheduler pause error...... {str(e)}") raise e def resume(self) -> bool: try: self.__scheduler.resume() if self.__scheduler.state == STATE_RUNNING: return True return False except Exception as e: logging.error(f"scheduler resume error...... {str(e)}") raise e def get_state(self) -> str: try: if self.__scheduler.state == STATE_RUNNING: return "RUNNING" if self.__scheduler.state == STATE_PAUSED: return "PAUSED" return "STOPPED" except Exception as e: logging.error(f"scheduler get_state error...... {str(e)}") raise e def get_job(self, id="") -> object: try: job = self.__scheduler.get_job(id) return job except Exception as e: logging.error(f"scheduler get_job error...... {str(e)}") raise e def add_job(self, task_id="", trigger=None, task=None) -> bool: try: settings = {} settings["id"] = task_id if task_id else str(uuid4()) settings["func"] = task.run settings["coalesce"] = True settings["replace_existing"] = True settings = {**settings, **(trigger.get_settings())} job = self.__scheduler.add_job(**settings) return True if self.get_job(job.id) else False except Exception as e: logging.error(f"scheduler add_job error...... {str(e)}") raise e def remove_job(self, id: str) -> bool: try: self.__scheduler.remove_job(id) return True if not self.get_job(id) else False except JobLookupError as e: return False except Exception as e: logging.error(f"scheduler remove_job error...... {str(e)}") raise e def pause_job(self, id: str) -> bool: try: job = self.__scheduler.pause_job(id) return True if job else False except Exception as e: logging.error(f"scheduler pause_job error...... {str(e)}") raise e def resume_job(self, id: str) -> bool: try: job = self.__scheduler.resume_job(id) return True if job else False except Exception as e: logging.error(f"scheduler resume_job error...... {str(e)}") raise e
class Thunderboard: def __init__(self, addr, addrType): self.addr = addr self.addrType = addrType self.char = dict() self.session = '' self.coinCell = False self.bleService = None self.senseData = dict() self.motionData = dict() self.thunderboardData = dict() self.bleService = Peripheral() self.schedulers = BackgroundScheduler() self.bleService.connect(self.addr, self.addrType) self.delegate = MyDelegate(self) self.bleService.setDelegate(self.delegate) self.enableNotification() self.characteristics = self.bleService.getCharacteristics() for k in self.characteristics: if k.uuid == '2a6e': self.char['temperature'] = k elif k.uuid == '2a6f': self.char['humidity'] = k elif k.uuid == '2a19': self.char['batterylevel'] = k elif k.uuid == 'ec61a454-ed01-a5e8-b8f9-de9ec026ec51': self.char['powertype'] = k self.job0 = self.schedulers.add_job(self.senseDataUpdate, replace_existing=True, trigger='interval', seconds=( 300 / 1000)) self.job1 = self.schedulers.add_job(self.motionDataUpdate, replace_existing=True, trigger='interval', seconds=( 300 / 1000)) self.schedulers.start() self.job0.pause() self.job1.pause() def jobInit(self, sense_interval, sense_interval_unit, motion_interval, motion_interval_unit): self.schedulers.pause() self.job0.remove() self.job1.remove() if sense_interval_unit == "seconds": self.job0 = self.schedulers.add_job( self.senseDataUpdate, replace_existing=True, trigger='interval', seconds=sense_interval) elif sense_interval_unit == "minutes": self.job0 = self.schedulers.add_job( self.senseDataUpdate, replace_existing=True, trigger='interval', minutes=sense_interval) elif sense_interval_unit == "days": self.job0 = self.schedulers.add_job( self.senseDataUpdate, replace_existing=True, trigger='interval', days=sense_interval) elif sense_interval_unit == "weeks": self.job0 = self.schedulers.add_job( self.senseDataUpdate, replace_existing=True, trigger='interval', weeks=sense_interval) if motion_interval_unit == "seconds": self.job1 = self.schedulers.add_job( self.motionDataUpdate, replace_existing=True, trigger='interval', seconds=motion_interval) elif motion_interval_unit == "minutes": self.job1 = self.schedulers.add_job( self.motionDataUpdate, replace_existing=True, trigger='interval', minutes=motion_interval) elif motion_interval_unit == "days": self.job1 = self.schedulers.add_job( self.motionDataUpdate, replace_existing=True, trigger='interval', days=motion_interval) elif motion_interval_unit == "weeks": self.job1 = self.schedulers.add_job( self.motionDataUpdate, replace_existing=True, trigger='interval', weeks=motion_interval) self.schedulers.resume() def senseDataUpdate(self): self.senseUpdate() self.thunderboardData['powertype'] = self.senseData['powertype'] self.thunderboardData['batterylevel'] = self.senseData['batterylevel'] self.thunderboardData['temperature'] = self.senseData['temperature'] self.thunderboardData['humidity'] = self.senseData['humidity'] # self.disconnect() def motionDataUpdate(self): self.thunderboardData['Orientation_x'] = self.motionData['Orientation']['x'] self.thunderboardData['Orientation_y'] = self.motionData['Orientation']['y'] self.thunderboardData['Orientation_z'] = self.motionData['Orientation']['z'] self.thunderboardData['Acceleration_x'] = self.motionData['Acceleration']['x'] self.thunderboardData['Acceleration_y'] = self.motionData['Acceleration']['y'] self.thunderboardData['Acceleration_z'] = self.motionData['Acceleration']['z'] # self.disconnect() def readTemperature(self): value = self.char['temperature'].read() value = struct.unpack('<H', value) value = value[0] / 100 return value def readHumidity(self): value = self.char['humidity'].read() value = struct.unpack('<H', value) value = value[0] / 100 return value def readBatteryLevel(self): value = self.char['batterylevel'].read() value = struct.unpack('B', value) value = value[0] return value def waitForNotification(self): if self.bleService.waitForNotifications(1.0): print("Waiting...") def enableNotification(self): self.bleService.writeCharacteristic( 79, (1).to_bytes(2, byteorder='little')) self.bleService.writeCharacteristic( 82, (1).to_bytes(2, byteorder='little')) def disableNotification(self): self.bleService.writeCharacteristic( 79, (0).to_bytes(2, byteorder='little')) self.bleService.writeCharacteristic( 82, (0).to_bytes(2, byteorder='little')) def connect(self): self.bleService.connect(self.addr, self.addrType) self.delegate = MyDelegate(self) self.bleService.setDelegate(self.delegate) self.enableNotification() self.job0.resume() self.job1.resume() def disconnect(self): self.job0.pause() self.job1.pause() sleep(0.5) del self.delegate self.bleService.disconnect() def senseUpdate(self): value = self.char['powertype'].read() if ord(value) == 0x04: self.coinCell = "coinCell" else: self.coinCell = "externalPower" self.senseData['powertype'] = self.coinCell for key in self.char.keys(): if key == 'batterylevel': self.senseData['batterylevel'] = self.readBatteryLevel() elif key == 'temperature': self.senseData['temperature'] = self.readTemperature() elif key == 'humidity': self.senseData['humidity'] = self.readHumidity()
class MainWindow(QtWidgets.QMainWindow, MainWindow.Ui_MainWindow): def __init__(self, *args, obj=None, **kwargs): """ Initializing the MainWindow """ ## Setting up the MainWindow super(MainWindow, self).__init__(*args, **kwargs) self.setupUi(self) self.setWindowTitle("TABFYE!") self.setWindowIcon(QIcon('appUi/icons8-eye-64.png')) ## Creating objects for classes imported from modules # ConfigParser for saving configuration self.config = ConfigParser() # BackgroundScheduler does the scheduling job of # showing the notification every @self.time_interval seconds/minutes self.scheduler = BackgroundScheduler() ## Variables # These variables determine the time in which # the reminder needs to be disabled self.disable_reminder_starthour = self.timeEdit.time().hour() self.disable_reminder_endhour = self.timeEdit_2.time().hour() self.disable_reminder_startmin = self.timeEdit.time().minute() self.disable_reminder_endmin = self.timeEdit_2.time().minute() # disable_reminder = True, if disable option is checked self.disable_reminder = False # do_not_start = True, if today's day name (e.g.Monday) # is checked self.do_not_start = False self.time_interval_in_seconds = True self.time_interval = 5 self.s5.setChecked(True) ## Connecting the time interval options with a function self.s5.toggled.connect(self.select_time_interval) self.s10.toggled.connect(self.select_time_interval) self.m10.toggled.connect(self.select_time_interval) self.m20.toggled.connect(self.select_time_interval) self.m30.toggled.connect(self.select_time_interval) self.m40.toggled.connect(self.select_time_interval) self.h1.toggled.connect(self.select_time_interval) if self.time_interval_in_seconds == True: self.scheduler.add_job(self.break_remind_notifier, 'interval', seconds=self.time_interval, id='reminder_job') else: self.scheduler.add_job(self.break_remind_notifier, 'interval', minutes=self.time_interval, id='reminder_job') ## Open/create config file if not os.path.exists('config.ini'): print("Config file not found") self.config.add_section('day') self.config.set('day', 'Monday', 'False') self.config.set('day', 'Tuesday', 'False') self.config.set('day', 'Wednesday', 'False') self.config.set('day', 'Thursday', 'False') self.config.set('day', 'Friday', 'False') self.config.set('day', 'Saturday', 'False') self.config.set('day', 'Sunday', 'False') with open('config.ini', 'w') as file: self.config.write(file) else: print("Config file found") self.config.read('config.ini') # Determine today's day name now = datetime.datetime.now() self.today = now.strftime("%A") # print(self.today) # Restore the previous checkstates from the config file if self.config.get('day', 'Monday') == 'True': self.checkMonday.setChecked(True) if self.today == 'Monday': do_not_start = True if self.config.get('day', 'Tuesday') == 'True': self.checkTuesday.setChecked(True) if self.today == 'Tuesday': do_not_start = True if self.config.get('day', 'Wednesday') == 'True': self.checkWednesday.setChecked(True) if self.today == 'Wednesday': do_not_start = True if self.config.get('day', 'Thursday') == 'True': self.checkThursday.setChecked(True) if self.today == 'Thursday': do_not_start = True if self.config.get('day', 'Friday') == 'True': self.checkFriday.setChecked(True) if self.today == 'Friday': do_not_start = True if self.config.get('day', 'Saturday') == 'True': self.checkSaturday.setChecked(True) if self.today == 'Saturday': do_not_start = True if self.config.get('day', 'Sunday') == 'True': self.checkSunday.setChecked(True) if self.today == 'Sunday': do_not_start = True # Start the reminders only if today was not checked if self.do_not_start == False: self.scheduler.start() else: print("Disabled for today") ## Connecting the GUI objects with their functions self.enableReminder.setChecked(True) self.enableReminder.stateChanged.connect(self.reminder_function) self.disableReminder.stateChanged.connect(self.reminder_function) self.checkMonday.stateChanged.connect(self.check_day_of_the_week) self.checkTuesday.stateChanged.connect(self.check_day_of_the_week) self.checkWednesday.stateChanged.connect(self.check_day_of_the_week) self.checkThursday.stateChanged.connect(self.check_day_of_the_week) self.checkFriday.stateChanged.connect(self.check_day_of_the_week) self.checkSaturday.stateChanged.connect(self.check_day_of_the_week) self.checkSunday.stateChanged.connect(self.check_day_of_the_week) self.helpButton.clicked.connect(self.help_dialog) time = self.timeEdit.time() self.timeEdit.dateTimeChanged.connect(self.displayDT) self.timeEdit_2.dateTimeChanged.connect(self.displayDT) def select_time_interval(self): """ Change the time interval in which the reminders are displayed :return: Nothing """ if self.s5.isChecked(): self.time_interval_in_seconds = True self.time_interval = 5 elif self.s10.isChecked(): self.time_interval_in_seconds = True self.time_interval = 10 elif self.m10.isChecked(): self.time_interval_in_seconds = False self.time_interval = 10 elif self.m20.isChecked(): self.time_interval_in_seconds = False self.time_interval = 20 elif self.m30.isChecked(): self.time_interval_in_seconds = False self.time_interval = 30 elif self.m40.isChecked(): self.time_interval_in_seconds = False self.time_interval = 40 elif self.h1.isChecked(): self.time_interval_in_seconds = False self.time_interval = 60 if self.time_interval_in_seconds == True: print("Time interval : " + str(self.time_interval) + " seconds") # self.scheduler.shutdown() self.scheduler.remove_all_jobs() self.scheduler = BackgroundScheduler() self.scheduler.add_job(self.break_remind_notifier, 'interval', seconds=self.time_interval) else: print("Time interval : " + str(self.time_interval) + " minutes") # self.scheduler.shutdown() self.scheduler.remove_all_jobs() self.scheduler = BackgroundScheduler() self.scheduler.add_job(self.break_remind_notifier, 'interval', minutes=self.time_interval) self.enableReminder.setChecked(True) self.disableReminder.setChecked(False) if self.do_not_start == False: self.scheduler.start() def help_dialog(self): """ Open the GUI help dialog :return: Nothing """ self.window = QtWidgets.QMainWindow() self.ui = help.Ui_Dialog() self.ui.setupUi(self.window) self.ui.closeButton.clicked.connect(self.window.close) # self.window.resize(500, 440) self.window.setWindowIcon(QIcon('appUi/question.png')) self.window.show() def disable_reminder_in_timerange(self): """ Set @self.disable_reminder = True, when @self.disableReminder is checked :return: """ self.disable_reminder = True # self.scheduler.pause() def reminder_function(self): """ When the states of @self.enableReminder or @self.disableReminder are changed, turn on/off the reminding schedule to reflect the change :return: Nothing """ # Get current time to compare with disalbe timings currentHour = QTime.currentTime().hour() currentMin = QTime.currentTime().minute() print("CurrentHour " + str(currentHour) + " CurrentMin " + str(currentMin)) # Start/Resume/Pause reminding schedule according to # whether it is enabled and if the current time falls # into the disable time range if self.enableReminder.isChecked() == True: print("EnableReminder " + str(self.enableReminder.isChecked())) if self.disableReminder.isChecked() == True: print("DisableReminder " + str(self.disableReminder.isChecked())) if not (currentHour >= self.disable_reminder_starthour and currentMin >= self.disable_reminder_startmin and ((currentHour < self.disable_reminder_endhour) or (currentHour == self.disable_reminder_endhour and currentMin < self.disable_reminder_endmin))): self.scheduler.resume() else: print("DisableReminder " + str(self.disableReminder.isChecked())) print("Pausing...") self.scheduler.pause() else: self.scheduler.resume() else: print("EnableReminder " + str(self.enableReminder.isChecked())) self.scheduler.pause() def break_remind_notifier(self): """ Show notification when the job is called for :return: Nothing """ print("Look away for a while!") self.reminder_label.setText('Take a break!') # Windows 10 notifications need .ico files # but Linux needs .png # So check the OS for appropriate icons if os.name == 'nt': app_icon = 'appUi/icons8-eye-64.ico' elif os.name == 'posix': app_icon = 'appUi/icons8-eye-64.png' # Show the notification notification.notify( title='Take a break for your eyes!', message='Look at an object 20ft away for 20s', app_icon=app_icon, # e.g. 'C:\\icon_32x32.ico' timeout=10, # seconds ) time.sleep(1) self.reminder_label.clear() print("Break over!") def displayDT(self): """ Get the disable timings input when it is changed :return: Nothing """ self.disable_reminder_starthour = self.timeEdit.time().hour() self.disable_reminder_endhour = self.timeEdit_2.time().hour() self.disable_reminder_startmin = self.timeEdit.time().minute() self.disable_reminder_endmin = self.timeEdit_2.time().minute() print("disable_reminder_starthour " + str(self.disable_reminder_starthour) + " disable_reminder_startmin " + str(self.disable_reminder_startmin)) print("disable_reminder_endhour " + str(self.disable_reminder_endhour) + " disable_reminder_endmin " + str(self.disable_reminder_endmin)) time = self.timeEdit.time().hour() time2 = self.timeEdit_2.time() currentTime = QTime.currentTime().hour() # if currentTime == time: # print("Yeah, they are equal indeed") def check_day_of_the_week(self): """ If today is checked, then disable the reminder for today, Resume otherwise :return: Nothing """ if (self.checkMonday.isChecked() == True and self.today == 'Monday' or self.checkTuesday.isChecked() == True and self.today == 'Tuesday' or self.checkWednesday.isChecked() == True and self.today == 'Wednesdasy' or self.checkThursday.isChecked() == True and self.today == 'Thursday' or self.checkFriday.isChecked() == True and self.today == 'Friday' or self.checkSaturday.isChecked() == True and self.today == 'Saturday' or self.checkSunday.isChecked() == True and self.today == 'Sunday'): print("Today is checked") self.scheduler.pause() else: self.scheduler.resume() def __del__(self): """ Destructor function :return: Nothing """ print("Exiting app...") self.scheduler.shutdown() config = ConfigParser() config.read('config.ini') config.set('day', 'Monday', str(self.checkMonday.isChecked())) config.set('day', 'Tuesday', str(self.checkTuesday.isChecked())) config.set('day', 'Wednesday', str(self.checkWednesday.isChecked())) config.set('day', 'Thursday', str(self.checkThursday.isChecked())) config.set('day', 'Friday', str(self.checkFriday.isChecked())) config.set('day', 'Saturday', str(self.checkSaturday.isChecked())) config.set('day', 'Sunday', str(self.checkSunday.isChecked())) with open('config.ini', 'w') as file: config.write(file)
class SchedulerManager(object): global _mongoclient def __init__(self): self._jobs = {} self._jobhandlers = {} # format, key: jobid, value: jobhandler self.create_scheduler() self.start() def create_scheduler(self): self.jobstores = { 'mongo': MongoDBJobStore(collection='job1', database='saasjob', client=_mongoclient), 'default': MemoryJobStore() } self.executors = { 'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5) } self.job_defaults = { 'coalesce': False, 'misfire_grace_time': 1, 'max_instances': 1 } self._sched = BackgroundScheduler(jobstores=self.jobstores, executors=self.executors, job_defaults=self.job_defaults) # 添加 任务提交 事件监听 self._sched.add_listener(self.when_job_submitted, EVENT_JOB_SUBMITTED) # # 添加 任务执行完成 事件监听 # self._sched.add_listener(self.when_job_executed, EVENT_JOB_EXECUTED) # 添加 任务退出 事件监听 self._sched.add_listener(self.when_job_crashed, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) def when_job_submitted(self, event): try: job_id = event.job_id if job_id not in self._jobhandlers and job_id in self._jobhandlers: self._jobhandlers.setdefault(job_id, JobHandler(self._jobs[job_id])) jobhandler = self._jobhandlers[event.job_id] jobhandler.when_job_submitted() print("%s submitted at %s" % (event.job_id, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))) except: import traceback print(traceback.print_exc()) def when_job_executed(self, event): try: if event.exception: job_id = event.job_id if job_id not in self._jobhandlers: self._jobhandlers.setdefault( job_id, JobHandler(self._jobs[job_id])) jobhandler = self._jobhandlers[event.job_id] jobhandler.when_job_crashed() print("%s crashed at %s" % (event.job_id, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))) else: job_id = event.job_id if job_id not in self._jobhandlers: self._jobhandlers.setdefault( job_id, JobHandler(self._jobs[job_id])) jobhandler = self._jobhandlers[event.job_id] jobhandler.when_job_executed() print("%s executed at %s" % (event.job_id, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))) except: import traceback print(traceback.print_exc()) def when_job_crashed(self, event): try: if event.exception: job_id = event.job_id if job_id not in self._jobhandlers: self._jobhandlers.setdefault( job_id, JobHandler(self._jobs[job_id])) jobhandler = self._jobhandlers[event.job_id] jobhandler.when_job_crashed() print("%s crashed at %s" % (event.job_id, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))) except: import traceback print(traceback.print_exc()) def fresh_jobs(self): self._sched.pause() for _job in self._sched.get_jobs(): job_id = self._get_job_attr(_job, "id") self._jobs.setdefault(job_id, _job) self._sched.resume() def sync_jobs(self, job_ids=set()): job_ids = (set(self._jobhandlers.keys()) | set(self._jobs.keys())) if len(job_ids) == 0 else job_ids for job_id in job_ids: if job_id in self._jobhandlers and job_id not in self._jobs: self._jobs[job_id] = self._jobhandlers[job_id] elif job_id not in self._jobhandlers and job_id in self._jobs: self._jobhandlers[job_id] = self._jobs[job_id] job_ids = set() return True def start(self): try: self._sched.start(paused=True) self.fresh_jobs() return True except: import traceback print(traceback.print_exc()) return False
class Scheduler(object): def __init__(self): self._scheduler = BackgroundScheduler(executors=config.EXECUTORS, job_defaults=config.JOB_DEFAULTS, timezone=config.TIME_ZONE) # self._all_jobs = {} self._scheduler.add_listener(self._on_job_add, EVENT_JOB_ADDED) self._scheduler.add_listener(self._on_job_remove, EVENT_JOB_REMOVED) self._scheduler.add_listener(self._on_job_modify, EVENT_JOB_MODIFIED) self._scheduler.add_listener(self._on_job_execute, EVENT_JOB_EXECUTED) self._scheduler.add_listener(self._on_job_error, EVENT_JOB_ERROR) self._scheduler.add_listener(self._on_scheduler_start, EVENT_SCHEDULER_STARTED) self._scheduler.add_listener(self._on_scheduler_stop, EVENT_SCHEDULER_SHUTDOWN) self._scheduler.add_listener(self._on_scheduler_pause, EVENT_SCHEDULER_PAUSED) self._scheduler.add_listener(self._on_scheduler_resume, EVENT_SCHEDULER_RESUMED) def start(self): if self.status() != STOPPED: raise ServiceException(ErrorCode.FAIL, '无法启动调度器,调度器不在停止状态') self._scheduler.start() def shutdown(self, waited=False): """ :param waited: 等待所有任务执行结束后再停止 :return: """ if self.status() != RUNNING: raise ServiceException(ErrorCode.FAIL, '无法停止调度器,调度器不在运行状态') self._scheduler.remove_all_jobs() self._scheduler.shutdown(wait=waited) def pause(self): if self.status() != RUNNING: raise ServiceException(ErrorCode.FAIL, '无法暂停调度器,调度器不在运行状态') self._scheduler.pause() def resume(self): if self.status() != PAUSED: raise ServiceException(ErrorCode.FAIL, '无法重启调度器,调度器不在暂停状态') self._scheduler.resume() def status(self): """ 获取当前调度器状态 0 停止,1 运行,2暂停 :return: """ return self._scheduler.state def add_job(self, task): if self.status() != RUNNING: raise ServiceException(ErrorCode.FAIL, '启动任务%s失败,调度器没有运行' % task.job_id) # 判断是否已经加入了调度器 if self._scheduler.get_job(task.job_id) is None: # 动态导入脚本 script = importlib.import_module('job.' + task.job_id) if script is None or not hasattr(script, 'run'): raise ServiceException(ErrorCode.FAIL, ("%s任务没有run方法" % task.job_id)) try: cron_dict = eval(task.cron) except Exception as e: raise ServiceException(ErrorCode.FAIL, ("%s任务cron规则错误" % task.job_id), str(e)) try: if task.type == Job.Type.INTERVAL.value: self._scheduler.add_job(script.run, 'interval', **cron_dict, id=task.job_id, max_instances=task.instance_cnt) elif task.type == Job.Type.CRON.value: self._scheduler.add_job(script.run, 'cron', **cron_dict, id=task.job_id, max_instances=task.instance_cnt) except Exception as e: raise ServiceException(ErrorCode.INTERNAL_ERROR, ("加入任务%s失败" % task.job_id), str(e)) else: raise ServiceException(ErrorCode.FAIL, ("任务%s已存在" % task.job_id)) def pause_job(self, task): current_job = self._scheduler.get_job(task.job_id) if current_job is not None: # 如果不在运行中 if current_job.next_run_time is None: raise ServiceException(ErrorCode.FAIL, '无法暂停任务%s, 该任务现在已经停止' % (task.job_id)) else: self._scheduler.pause_job(task.job_id) else: raise ServiceException(ErrorCode.FAIL, ("任务%s不存在" % task.job_id)) def resume_job(self, task): current_job = self._scheduler.get_job(task.job_id) if current_job is not None: # 如果在运行中 if current_job.next_run_time is not None: raise ServiceException(ErrorCode.FAIL, '无法重启任务%s, 该任务的现在已经在运行' % (task.job_id)) else: self._scheduler.resume_job(task.job_id) else: raise ServiceException(ErrorCode.FAIL, ("任务%s不存在" % task.job_id)) # def modify_job(self, task): # current_job = self._scheduler.get_job(task.job_id) # if current_job is not None: # try: # cron_dict = eval(task.cron) # except Exception as e: # raise ServiceException(ErrorCode.FAIL, ("%s任务cron规则错误" % task.job_id), str(e)) # # try: # if task.type == Job.Type.INTERVAL.value: # self._scheduler.reschedule_job(task.job_id, trigger='interval', **cron_dict, # max_instances=task.instance_cnt) # elif task.type == Job.Type.CRON.value: # self._scheduler.reschedule_job(task.job_id, trigger='cron', **cron_dict, # max_instances=task.instance_cnt) # except Exception as e: # raise ServiceException(ErrorCode.INTERNAL_ERROR, ("修改任务%s失败" % task.job_id), str(e)) # else: # raise ServiceException(ErrorCode.FAIL, ("任务%s不存在" % task.job_id)) def remove_job(self, task): current_job = self._scheduler.get_job(task.job_id) if current_job is not None: self._scheduler.remove_job(task.job_id) else: raise ServiceException(ErrorCode.FAIL, ("任务%s不存在" % task.job_id)) ###### Listener ###### def _on_job_add(self, event): from service.job_service import JobService job_id = event.job_id job = JobService.get_job(job_id) # 有自动加入的情况 if job.status != job.Status.RUNNING.value: JobService.change_job_status(job_id, job.Status.RUNNING) job.status = job.Status.RUNNING.value logger.info('定时任务%s加入了调度器,信息:%s' % (job_id, str(job))) def _on_job_remove(self, event): from service.job_service import JobService job_id = event.job_id job = JobService.get_job(job_id) # 有自动删除的情况 if job.status != job.Status.STOPPED.value: JobService.change_job_status(job_id, job.Status.STOPPED) logger.info('定时任务%s被移除了调度器,信息:%s' % (job_id, str(job))) def _on_job_modify(self, event): from service.job_service import JobService job_id = event.job_id job = self._scheduler.get_job(job_id) if job.next_run_time is None: job = JobService.get_job(job_id) logger.info('定时任务%s已暂停,信息:%s' % (job_id, str(job))) if job.status != job.Status.SUSPENDED.value: JobService.change_job_status(job_id, job.Status.SUSPENDED) else: logger.info('定时任务%s被修改或重启了并正在运行中,信息:%s' % (job_id, str(job))) def _on_job_error(self, event): from service.job_service import JobService e = event.exception job_id = event.job_id logger.warn('定时任务%s发生错误,将被移除调度器' % job_id) logger.error(str(e)) task = JobService.get_job(job_id) self.remove_job(task) def _on_job_execute(self, event): from service.job_service import JobService job_id = event.job_id logger.info('定时任务%s开始执行' % job_id) JobService.add_executed_times(job_id, 1) def _on_scheduler_start(self, event): logger.info('调度器开始执行') def _on_scheduler_pause(self, event): logger.info('调度器暂停') def _on_scheduler_resume(self, event): logger.info('调度器重启') def _on_scheduler_stop(self, event): logger.info('调度器停止') def next_run_time(self, job_id): return self._scheduler.get_job(job_id).next_run_time
class PeriodicReporter(object): """ This class is used to periodically get real-time market data from Yahoo finance database, the accessed data will not be saved at local, please use this with my Stock Data Reader class """ def __init__(self, function): """ :param function: function of the arranged job, in this case, it should be the getCurrentMarketData function """ self._scheduler = None self.function = function self.existingJob = False self.start() def start(self): """ method to start the reporter :return: None """ self._scheduler = BackgroundScheduler() self._scheduler.start() def addJob(self, interval, *args): """ add a reporter :param interval: the interval between two reports, 20 means 20 seconds, etc... :param args: tickerList,like:["AAPL","IBM","JPM"] :return: None """ if not self.existingJob: self._scheduler.add_job(self.function, trigger='interval', seconds=interval, args=args) self.existingJob = True else: warnings.warn("Existing job will be removed!") self._scheduler.remove_all_jobs() self._scheduler.add_job(self.function, trigger='interval', seconds=interval, args=args) def removeJob(self): """ remove the current reporter :return: None """ self._scheduler.remove_all_jobs() self.existingJob = False def pause(self): """ pause the current reporter :return: None """ self._scheduler.pause() def resume(self): """ resume the paused reporter :return: None """ self._scheduler.resume() def getJob(self): """ print the details of the current reporter :return: None """ self._scheduler.print_jobs() def shutDown(self): """ shut down the reporter :return: None """ self._scheduler.shutdown()
class SpecificTimeReporter(object): """ This class is used to get the real-time market data at specific time everyday from yahoo finance database, the accessed data will not be saved at local, please use this with my Stock Data Reader class """ def __init__(self, function): """ :param function: function of the arranged job, in this case, it should be the getCurrentMarketData function """ self._scheduler = None self.function = function self.count = 1 self._all_job = {} self.start() def start(self): """ start the reporter :return: None """ self._scheduler = BackgroundScheduler() self._scheduler.start() def convertInt2Time(self, hour, minute, second): """ You do not need to call this method, you can treat this as a private method :param hour: integer ranging from 0 to 23 :param minute: integer ranging from 0 to 59 :param second: integer ranging from 0 to 59 :return: string format of time """ ans = "" if hour < 10: ans = ans + "0" + str(hour) else: ans = ans + str(hour) if minute < 10: ans = ans + "0" + str(minute) else: ans = ans + str(minute) if second < 10: ans = ans + "0" + str(second) else: ans = ans + str(second) return ans def addJob(self, hour, minute, second, *args): """ add a reporter :param hour: integer ranging from 0 to 23 :param minute: integer ranging from 0 to 59 :param second: integer ranging from 0 to 59 :param args: tickerList,like:["AAPL","IBM","JPM"] :return: None """ timeString = self.convertInt2Time(hour, minute, second) if timeString not in self._all_job: self._all_job[timeString] = str(self.count) self._scheduler.add_job(self.function, trigger='cron', hour=hour, minute=minute, second=second, args=args, id=str(self.count)) self.count = self.count + 1 else: self._scheduler.reschedule_job(self._all_job[timeString], trigger='cron', hour=hour, minute=minute, second=second) def removeJob(self, hour, minute, second): """ remove a reporter :param hour: integer ranging from 0 to 23 :param minute: integer ranging from 0 to 59 :param second: integer ranging from 0 to 59 :return: None """ timeString = self.convertInt2Time(hour, minute, second) if timeString not in self._all_job: warnings.warn("Job not found!") else: self._scheduler.remove_job(self._all_job[timeString]) def removeAllJobs(self): """ remove all reporters :return: None """ self._scheduler.remove_all_jobs() def pause(self): """ pause all reporters :return: None """ self._scheduler.pause() def resume(self): """ resume the paused reporters :return: None """ self._scheduler.resume() def getAllJobs(self): """ print the information of all reporters :return: None """ self._scheduler.print_jobs() def shutDown(self): """ shut down all reporters :return: None """ self._scheduler.shutdown()
class DataCollector: def __init__(self): self.logger = get_logger('data-collector') self.scheduler = BackgroundScheduler(timezone="Asia/Seoul") self.scheduler.start() self.templates = dict() self.__global_store = dict() self.job_broker = Celery('routine-jobs', broker=BROKER_URL, backend=CELERY_RESULT_BACKEND) # ========================================================================= def add_job_schedules(self, schedule_templates: list): for schedule_template in schedule_templates: schedule_name, trigger = operator.itemgetter( 'schedule_name', 'trigger')(schedule_template) # schedule name can't be duplicated. schedule_names = [ x['schedule_name'] for x in self.get_schedule_jobs() ] if schedule_name in schedule_names: msg = f'The schedule name \'{schedule_name}\' is already assigned.' self.logger.error(msg) raise ExceptionScheduleReduplicated(msg) self._add_job_schedule(schedule_name, trigger_type=trigger['type'], trigger_setting=trigger['setting']) # store the schedule template self.templates[schedule_name] = schedule_template self.__global_store[schedule_name] = {'_gv': dict()} # ========================================================================= def _add_job_schedule(self, key, trigger_type, trigger_setting): if trigger_type == 'crontab' and 'crontab' in trigger_setting: crontab = self.crontab_add_second(trigger_setting['crontab']) trigger_type = 'cron' trigger_setting = {**trigger_setting, **crontab} del trigger_setting['crontab'] arguments = dict(func=self.request_data, args=(key, ), id=key, trigger=trigger_type) arguments = {**arguments, **trigger_setting} self.scheduler.pause() try: self.scheduler.add_job(**arguments) finally: self.scheduler.resume() # ========================================================================= def remove_job_schedule(self, schedule_name: str): self.get_schedule_job(schedule_name) self.scheduler.remove_job(schedule_name) try: del self.templates[schedule_name] del self.__global_store[schedule_name] except KeyError: # it should be failing to collect data. such as not connecting. pass return # ========================================================================= def modify_job_schedule(self, schedule_name, trigger_type, trigger_args): if trigger_type == 'crontab' and 'crontab' in trigger_args: crontab = self.crontab_add_second(trigger_args['crontab']) trigger = 'cron' setting = {**trigger_args, **crontab} del setting['crontab'] else: trigger = trigger_type setting = trigger_args job = self.scheduler.get_job(schedule_name) job.reschedule(trigger, **setting) self.templates[schedule_name]['trigger'] = dict(type=trigger_type, setting=trigger_args) # ========================================================================= @staticmethod def get_python_module(code, name): module = types.ModuleType(name) exec(code, module.__dict__) return module # ========================================================================= @staticmethod def insert_number_each_line(data: str): result = list() data = data.split('\n') for (number, line) in enumerate(data): result.append(f'{number+1:04} {line}') return '\n'.join(result) # ========================================================================= @staticmethod def filter_dict(dict_to_filter, thing_with_kwargs): sig = inspect.signature(thing_with_kwargs) filter_keys = [ param.name for param in sig.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD ] filtered_dict = { filter_key: dict_to_filter[filter_key] for filter_key in filter_keys } return filtered_dict # ========================================================================= def _source(self, name, setting): source_type, code, arguments = operator.itemgetter( 'type', 'code', 'arguments')(setting) module = DataCollector.get_python_module(code, name) try: _gv = self.__global_store[name] arguments = {**arguments, **_gv} filterd_arguments = DataCollector.filter_dict( arguments, module.main) data = module.main(**filterd_arguments) except Exception as e: code = DataCollector.insert_number_each_line(code) self.logger.error(f'{e}\ncode: \n{code}') raise return data # ========================================================================= def request_data(self, schedule_name): schedule = self.templates[schedule_name] if schedule_name not in self.templates: msg = f'The template "{schedule_name}" ' \ f'is not in the main template store' self.logger.error(msg) raise KeyError(msg) # checking use flag if not schedule['use']: self.logger.info(f'{schedule_name} is disabled.') return # source data = self._source(schedule_name, schedule['source']) if data is None: message = f'[{schedule_name}] The user function returned None.' self.logger.warning(message) # works # calling function for each works with arguments via celery for work in schedule['works']: work_type, arguments = operator.itemgetter('type', 'arguments')(work) self.job_broker.send_task(work_type, args=(data, ), kwargs=arguments) # sending events to the event # PING # event emitting data = json.dumps(data) event = { 'name': schedule_name, 'event': { 'type': 'data-collector', 'schedule_name': schedule_name }, 'data': data } try: self.emit_event(schedule_name, event) except (urllib3.exceptions.MaxRetryError, requests.exceptions.ConnectionError) as e: self.logger.error(f'Connection Error: Failed to emit events.') except Exception as e: import traceback traceback.print_exc() return # ========================================================================= def emit_event(self, name: str, event: dict): with requests.Session() as s: api = EVENT_COLLECTOR_URL + '/api/v1/events/emit' response = s.post(api, json=event) if response.status_code != 200: raise Exception(f'code: {response.status_code}\n' f'messages: [{name}] - {response.reason}') data = json.loads(response.text) self.logger.info(f'[{name}] emitted a event.') # ========================================================================= def remove_job_schedule(self, _id: str): self.scheduler.remove_job(_id) del self.data[_id] return # ========================================================================= def modify_job_schedule(self, _id, seconds): self.scheduler.reschedule_job(_id, trigger='interval', seconds=seconds) # ========================================================================= def get_schedule_jobs(self): jobs = self.scheduler.get_jobs() if not jobs: return jobs result = list() for job in jobs: schedule_name = job.id next_run_time = job.next_run_time template_data = self.templates[schedule_name] template_data['next_run_time'] = next_run_time result.append(template_data) return result
class TradingService: __config = configparser.ConfigParser() __config.read(Paths.CONFIG) __commission = 0.0015 def __init__(self): self.__currency = None self.__budget = 0 self.__num_coin = 0.0 self.__criteria = 0.0 self.__agent = CoinAgent(self.__commission) self.__scheduler = BackgroundScheduler() self.__portfolio = None def start(self, currency, budget, criteria=-50.0, mins=60): self.__currency = currency self.__budget = budget self.__criteria = criteria self.__portfolio = { 'principal': budget, 'daily': budget, 'time': time.localtime() } self.__scheduler.add_job(self.do_trading, 'interval', minutes=mins, id='do_trading') self.__scheduler.start() SlackNotification.notify( 'Coin Bot', 'good', 'Server started!', fields=[{ 'title': '지갑', 'value': 'KRW {budget:,}\n'.format(budget=self.__budget), 'short': True }]) self.do_trading() def pause(self): self.__scheduler.pause() SlackNotification.notify('Coin Bot', 'good', 'Server paused!') def resume(self): self.__scheduler.resume() SlackNotification.notify('Coin Bot', 'good', 'Server resumed!') def stop(self): self.__scheduler.shutdown(False) SlackNotification.notify('Coin Bot', 'good', 'Server Stopped!') def result_notify(self, color, prediction, dist, latest_price, qty, msg, portfolio, daily, total): SlackNotification.notify( title=self.__currency, color=color, msg='[{action}] {dist}\n' '가격 {price:,} 거래량 {qty:,.4f}\n' '*{msg}*'.format(action=prediction, dist=dist, price=latest_price, qty=qty, msg=msg), fields=[{ 'title': '지갑', 'value': 'KRW {budget:,}\n' 'Coin {coin:,.4f}\n' '자산 {portfolio:,.4f}'.format(budget=self.__budget, coin=self.__num_coin, portfolio=portfolio), 'short': True }, { 'title': '수익률', 'value': '일일 {daily:,.4f}% 기준 {daily_budget:,.4f}\n' '전체 {total:,.4f}% 기준 {total_budget:,.4f}'.format( daily=daily, total=total, daily_budget=self.__portfolio['daily'], total_budget=self.__portfolio['principal']), 'short': True }], ) def do_trading(self): prediction_debug = self.__config['debug'].getboolean('prediction') payment_debug = self.__config['debug'].getboolean('payment') logger.info('Debug: prediction %s, payment %s', prediction_debug, payment_debug) trades = CoinTrader.get_trades(self.__currency) prediction, dist = self.__agent.predict(trades, debug=prediction_debug) ticker = CoinTrader.ticker(self.__currency) latest_price = int(ticker['last']) qty = 0.0 color = 'good' msg = 'Success' if prediction == CoinAgent.Action.BUY: if self.__budget > 10: qty = self.__budget / latest_price status_code, error_code = CoinTrader.limit_buy( latest_price, self.__currency, qty, debug=payment_debug) if status_code == 200 and error_code == 0: self.__budget -= latest_price * qty self.__num_coin += qty * (1.0 - self.__commission) else: color = 'danger' msg = 'error: status_code: {}, error_code: {}'.format( status_code, error_code) else: color = 'warning' msg = 'Not enough budget' elif prediction == CoinAgent.Action.SELL: if self.__num_coin > 0.0001: qty = self.__num_coin status_code, error_code = CoinTrader.limit_sell( latest_price, self.__currency, qty, debug=payment_debug) if status_code == 200 and error_code == 0: self.__budget += latest_price * qty * (1.0 - self.__commission) self.__num_coin -= qty else: color = 'danger' msg = 'error: status_code: {}, error_code: {}'.format( status_code, error_code) else: color = 'warning' msg = 'Not enough coins' portfolio = self.__budget + self.__num_coin * latest_price cur_time = time.localtime() if cur_time.tm_mday != self.__portfolio['time'].tm_mday: self.__portfolio['daily'] = portfolio self.__portfolio['time'] = cur_time daily = 100.0 * ((portfolio / self.__portfolio['daily']) - 1.0) total = 100.0 * ((portfolio / self.__portfolio['principal']) - 1.0) logger.debug( '[{}] {} {} portfolio {:,} latest price {:,}, qty {:,}'.format( self.__currency, prediction, dist, portfolio, latest_price, qty)) self.result_notify(color=color, prediction=prediction, dist=dist, latest_price=latest_price, qty=qty, msg=msg, portfolio=portfolio, daily=daily, total=total) if total < self.__criteria: SlackNotification.notify( 'Coin Bot', 'danger', '전체 수익률이 {}% 이하로 떨어져 강제 종료 합니다.'.format(self.__criteria)) self.stop()
class Timer_handler: ############################### constructor ############################### def __init__(self, state_handler, logger, path): self.boInit = True self._open_time = None self._close_time = None self._auto_open = None self._auto_close = None self.state_handler = state_handler self.scheduler = BackgroundScheduler() self.observers = [] self.log = logger self.settings_file = path + "timer_data.pkl" #read most recent settings saved to file, if available try: #with open(os.environ['HOME'] + #"/hendroid/client-raspi/timer_data.pkl", "rb") as input: with open(self.settings_file, "rb") as input: self.open_time = pickle.load(input) self.log.info("internal: read <open_time> from file: " + str(self.open_time)) self.close_time = pickle.load(input) self.log.info("internal: read <close_time> from file: " + str(self.close_time)) self.auto_open = pickle.load(input) self.log.info("internal: read <auto_open> from file: " + str(self.auto_open)) self.auto_close = pickle.load(input) self.log.info("internal: read <auto_close> from file: " + str(self.auto_close)) self.boInit = False except Exception as e: self.log.error("internal error: timer state read from file: ", exc_info=True) self.open_time = time(hour = 7, minute = 0) self.close_time = time(hour = 18, minute = 30) self.auto_open = False self.boInit = False self.auto_close = False self.log.info("internal: set timer to default settings") self.scheduler.start() ########################### property definition ########################### #Attrinutes are defined as properties as changing them requires some effort # (i.e. changing the Scheduler settings accordingly) rather than changing # them directly. @property def open_time(self): return self._open_time @property def close_time(self): return self._close_time @property def auto_open(self): return self._auto_open @property def auto_close(self): return self._auto_close @auto_open.setter def auto_open(self, value): if (isinstance(value, bool) and value != None and (self.auto_open == None or value != self.auto_open)): self._auto_open = value if(self.scheduler.running): self.scheduler.pause() if(self.auto_open): self.scheduler.resume_job(job_id=self.open_job.id) else: self.scheduler.pause_job(job_id=self.open_job.id) self.log.info("internal: set <auto_open> to " + str(self.auto_open)) if(self.scheduler.running): self.scheduler.resume() self.save_state() self.notify_observers("auto-open") @auto_close.setter def auto_close(self, value): if (isinstance(value, bool) and value != None and (self.auto_close == None or value != self.auto_close)): self._auto_close = value if(self.scheduler.running): self.scheduler.pause() if(self.auto_close): self.scheduler.resume_job(job_id=self.close_job.id) else: self.scheduler.pause_job(job_id=self.close_job.id) self.log.info("internal: set <auto_close> to " + str(self.auto_close)) if(self.scheduler.running): self.scheduler.resume() self.save_state() self.notify_observers("auto-close") @open_time.setter def open_time(self, value): if (isinstance(value, time) and value != None and (self.open_time == None or value != self.open_time)): self._open_time = value if(self.scheduler.running): self.scheduler.pause() self.open_job = self.scheduler.add_job(self.exec_motion ,trigger="cron" ,args=["opening"] ,id="jopen" ,name="open_job" ,max_instances=1 ,replace_existing=True ,hour = self.open_time.hour ,minute = self.open_time.minute ) self.log.info("internal: set <open_time> to " + str(self.open_time)) if(self.scheduler.running): self.scheduler.resume() self.save_state() self.notify_observers("time-open") @close_time.setter def close_time(self, value): if (isinstance(value, time) and value != None and (self.close_time == None or value != self.close_time)): self._close_time = value if(self.scheduler.running): self.scheduler.pause() self.close_job = self.scheduler.add_job(self.exec_motion ,trigger="cron" ,args=["closing"] ,id="jclose" ,name="close_job" ,max_instances=1 ,replace_existing=True ,hour = self.close_time.hour ,minute = self.close_time.minute ) self.log.info("internal: set <close_time> to " + str(self.close_time)) if(self.scheduler.running): self.scheduler.resume() self.save_state() self.notify_observers("time-close") ############################## other methods ############################## def register_observer(self, callback): self.log.info("internal: registering timer observer") self.observers.append(callback) self.update_observer(callback) #Update all observers of the object, i.e. notify them about values # of all properties of the object. def update_all_observers(self): [ self.update_observer(callback) for callback in self.observers ] #Update observer defined by callback parameter, i.e. notify it about values # of all properties of the object. def update_observer(self, callback): self.notify_observers("auto-open", [callback]) self.notify_observers("auto-close", [callback]) self.notify_observers("time-open", [callback]) self.notify_observers("time-close", [callback]) # notify given observers about changes encoded in update parameter # update parameter must have the form: "<cat>-<subcat>" with # cat in {"auto", "time"} and subcat in {"open", "close"}. # If observers parameter is omittet, then all registered observers of the # object are notified. def notify_observers(self, update, observers=None): if(self.boInit == False): update_vals = {"time-open": [self.open_time.hour ,self.open_time.minute] ,"time-close": [self.close_time.hour ,self.close_time.minute] ,"auto-close": [self.auto_close] ,"auto-open": [self.auto_open] } val_str = "" for val in update_vals[update]: val_str = val_str + ":" + str(val) update = update + "-" + val_str[1:] if(observers == None): observers = self.observers self.log.info("internal: Calling " + str(len(observers)) + " timer observers") [ callback(update) for callback in observers ] def exec_motion(self, arg): self.log.info("internal: scheduled event - " + arg) self.state_handler.handle_event(arg) def save_state(self): if(self.boInit == False): try: #with open(os.environ['HOME'] + "/hendroid/client-raspi/" # + "timer_data.pkl", "wb") as output: with open(self.settings_file, "wb") as output: pickle.dump(self.open_time, output) pickle.dump(self.close_time, output) pickle.dump(self.auto_open, output) pickle.dump(self.auto_close, output) self.log.info("internal: successfully saved timer setting" + " to file") except Exception as e: self.log.error("internal error: write timer setting to file: ", exec_info=True) def __del__(self): self.scheduler.shutdown()
class Manager: timezone = pytz.timezone('America/New_York') def __init__(self, data): self.data = data self.algos = [] self.broker = None self.logger = Logger() self.datetime = None self.scheduler = BackgroundScheduler() self.scheduler.configure(timezone=Manager.timezone) self.jobs = {} def init_broker(self, backtest=False, **kwargs): if backtest: self.broker = BacktestBroker(**kwargs) else: self.broker = AlpacaBroker(**kwargs) for algo in self.algos: algo.set_broker(self.broker) def add_algo(self, algo, live=False): if algo.data is None: algo.set_data_source(self.data) if algo.broker is None: algo.set_broker(self.broker) self.algos.append(algo) if live: trigger = convert_trigger_timezone(algo.trigger, Manager.timezone) job = self.scheduler.add_job(self.run_algo_live, trigger, kwargs={'algo': algo}) self.jobs[algo] = job def stop_algo(self, algo): job = self.jobs[algo] job.remove() def remove_algo(self, algo): self.stop_algo(algo) del self.algos[algo] def log_state(self): value = self.broker.get_value(self.datetime)['value'] benchmark_value = self.data.quote("SPY", self.datetime) self.logger.append(value, self.datetime) self.logger.append(benchmark_value, self.datetime, benchmark=True) def run_algo_live(self, algo): self.datetime = datetime.datetime.now().astimezone(Manager.timezone) # print("{time}: Running {algo}".format(time=self.datetime, algo=algo.__class__.__name__)) algo.run_wrapper(time=self.datetime, update=True) def backtest(self, start=datetime.datetime(2021, 3, 1), end=datetime.datetime.now(), log_schedule=[{ "minute": "30", "hour": "9", "day_of_week": "mon-fri" }]): self.init_broker(backtest=True, data=self.data) log_trigger = build_trigger(log_schedule) algo_trigger = OrTrigger([algo.trigger for algo in self.algos]) trigger = OrTrigger([algo_trigger, log_trigger]) logging = isinstance(log_schedule, dict) or len(log_schedule) > 0 if isinstance(start, int) and not isinstance(end, int): start = trading_day_offset(end, -start) if not isinstance(start, int) and isinstance(end, int): end = trading_day_offset(start, end) self.datetime = start while self.datetime < end: for algo in self.algos: if equals_runtime(algo.trigger, self.datetime): print(self.datetime) time = Manager.timezone.localize(self.datetime) self.broker.check_limit_orders(time=time) algo.run_wrapper(time=time, update=False) if logging and equals_runtime(log_trigger, self.datetime): self.log_state() self.datetime = next_runtime(trigger, self.datetime) metrics = self.logger.metrics() for metric, value in metrics.items(): print("{metric}: {value:.3f}".format(metric=metric, value=value)) self.logger.report() return metrics def run(self, paper=False, log_schedule=[{ "minute": "30", "hour": "9", "day_of_week": "mon-fri" }]): self.init_broker(backtest=False, paper=paper) self.datetime = datetime.datetime.now().astimezone(Manager.timezone) for algo in self.algos: trigger = convert_trigger_timezone(algo.trigger, Manager.timezone) job = self.scheduler.add_job(self.run_algo_live, trigger, kwargs={'algo': algo}) self.jobs[algo] = job log_trigger = convert_trigger_timezone(build_trigger(log_schedule), Manager.timezone) job = self.scheduler.add_job(self.log_state, log_trigger) self.jobs['logger'] = job self.start() self.interact() def start(self): self.scheduler.start() def stop(self): for algo in self.jobs.keys(): self.stop_algo(algo) self.scheduler.shutdown(wait=True) def pause(self): self.scheduler.pause() def resume(self): self.scheduler.resume() def interact(self): code.interact(local=locals())
def main(): global subs global player global bridge global SRT_FILENAME, AUDIO_FILENAME, MAX_BRIGHTNESS, TICK_TIME, HUE_IP_ADDRESS parser = argparse.ArgumentParser(description="LushRoom sound and light command-line player") # group = parser.add_mutually_exclusive_group() # group.add_argument("-v", "--verbose", action="store_true") # group.add_argument("-q", "--quiet", action="store_true") parser.add_argument("-s","--srt", default=SRT_FILENAME, help=".srt file name for lighting events") parser.add_argument("-a","--audio", default=AUDIO_FILENAME, help="audio file for sound stream") parser.add_argument("-b","--brightness", default=MAX_BRIGHTNESS, help="maximum brightness") parser.add_argument("-t","--time", default=TICK_TIME, help="time between events") parser.add_argument("--hue", default=HUE_IP_ADDRESS, help="Philips Hue bridge IP address") args = parser.parse_args() print(args) if PLAY_AUDIO: player = vlc.MediaPlayer(AUDIO_FILENAME) event_manager = player.event_manager() event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, end_callback) if PLAY_HUE: # b = Bridge('lushroom-hue.local') bridge = Bridge(HUE_IP_ADDRESS, config_file_path="/media/usb/python_hue") # If the app is not registered and the button is not pressed, press the button and call connect() (this only needs to be run a single time) bridge.connect() # Get the bridge state (This returns the full dictionary that you can explore) bridge.get_api() lights = bridge.lights # Print light names for l in lights: print(l.name) #print(dir(l)) # Set brightness of each light to 10 for l in lights: l.brightness = 1 # Get a dictionary with the light name as the key light_names = bridge.get_light_objects('name') print("Light names:", light_names) subs = srtopen(SRT_FILENAME) print("Number of lighting events",len(subs)) scheduler = BackgroundScheduler() scheduler.add_job(tick, 'interval', seconds=TICK_TIME) # scheduler.start(paused=True) if PLAY_AUDIO: player.play() scheduler.start(paused=False) try: # This is here to simulate application activity (which keeps the main thread alive). while True: sleep(0.01) try: if keyboard.is_pressed('p'): # pause scheduler.pause() player.pause() elif keyboard.is_pressed('r'): # resume scheduler.resume() player.play() # elif keyboard.is_pressed('s'): # stop # scheduler.shutdown() # player.stop() # exit(0) except: pass except (KeyboardInterrupt, SystemExit): # Not strictly necessary if daemonic mode is enabled but should be done if possible scheduler.shutdown() player.stop()
print(sched) if sched == None: print('Starting Proces ...') sched = BackgroundScheduler(daemon=True) sched.add_job(sensor, 'interval', seconds=int(get_current_interval()), id='my_job_id') sched.start() sched.pause() #sched.resume() #MONITOR_BUTTON = 'Start' if get_monitor_status() == 'stop': sched.resume() else: print('Process already created ...') @app.route("/on_off") def on_off(): global MONITOR_BUTTON if get_monitor_status() == 'start': start() update_monitor_status('stop') else: stop()
class Controller(object): def __init__(self, name="defaultController"): self.name = name self.workflows = {} self.instances = {} self.tree = None self.eventlog = [] self.schedulerStatusListener = SchedulerStatusListener(self.eventlog) self.jobStatusListener = JobStatusListener(self.eventlog) self.jobExecutionListener = JobExecutionListener(self.eventlog) self.scheduler = BackgroundScheduler() self.scheduler.add_listener( self.schedulerStatusListener.callback(self), EVENT_SCHEDULER_START | EVENT_SCHEDULER_SHUTDOWN | EVENT_SCHEDULER_PAUSED | EVENT_SCHEDULER_RESUMED) self.scheduler.add_listener(self.jobStatusListener.callback(self), EVENT_JOB_ADDED | EVENT_JOB_REMOVED) self.scheduler.add_listener(self.jobExecutionListener.callback(self), EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) self.ancestry = [self.name] def loadWorkflowsFromFile(self, path): self.tree = et.ElementTree(file=path) for workflow in self.tree.iter(tag="workflow"): name = workflow.get("name") self.workflows[name] = wf.Workflow(name=name, workflowConfig=workflow, parent_name=self.name) self.addChildWorkflows() self.addWorkflowScheduledJobs() def addChildWorkflows(self): for workflow in self.workflows: children = self.workflows[workflow].options.children for child in children: if child in self.workflows: children[child] = self.workflows[child] def addWorkflowScheduledJobs(self): for workflow in self.workflows: if (self.workflows[workflow].options.enabled and self.workflows[workflow].options.scheduler["autorun"] == "true"): schedule_type = self.workflows[workflow].options.scheduler[ "type"] schedule = self.workflows[workflow].options.scheduler["args"] self.scheduler.add_job(self.workflows[workflow].execute, trigger=schedule_type, replace_existing=True, **schedule) def createWorkflowFromTemplate(self, name="emptyWorkflow"): self.loadWorkflowsFromFile(path=config.templatesPath + sep + name + ".workflow") def removeWorkflow(self, name=""): if name in self.workflows: del self.workflows[name] return True return False def updateWorkflowName(self, oldName="", newName=""): self.workflows[newName] = self.workflows.pop(oldName) self.workflows[newName].name = newName def executeWorkflow(self, name, start="start", data=None): steps, instances = self.workflows[name].execute(start=start, data=data) self.jobExecutionListener.execute_event_code(self, 'JobExecuted') return steps, instances # Starts active execution def start(self): self.scheduler.start() # Stops active execution def stop(self, wait=True): self.scheduler.shutdown(wait=wait) # Pauses active execution def pause(self): self.scheduler.pause() # Resumes active execution def resume(self): self.scheduler.resume() # Pauses active execution of specific job def pauseJob(self, job_id): self.scheduler.pause_job(job_id=job_id) # Resumes active execution of specific job def resumeJob(self, job_id): self.scheduler.resume_job(job_id=job_id) # Returns jobs scheduled for active execution def getScheduledJobs(self): self.scheduler.get_jobs()