def restore_configs(json): for config in json: Config(key=config["key"], value=config["value"], config_type=config["type"]) arr = Config.select()[:] print("===RESTORED {0} {1}===".format(len(arr), "Configs"))
def write_state(name): # if not auth.username() != name: # print(auth.username(), name) # return '', 401 st = Config(data=request.get_data(), cluster=get_cluster(name)) if st.save(): return jsonify(json.loads(st.data))
def save_settings(self): try: chromepath = self.lineEdit_chromepath.text() timeout = self.spinBox_timeout.value() timeout_confirm = self.spinBox_timeout_confirm.value() sheduled = self.checkBox_sheduled.isChecked() stop_datetime = self.dateTime_stop.dateTime().toPyDateTime() start_datetime = self.dateTime_start.dateTime().toPyDateTime() refresh_count = self.spinBox_refresh_count.value() config = Config.select().get() config.chrome_path = chromepath config.timeout = timeout config.timeout_confirm = timeout_confirm config.sheduled = sheduled config.start_data_time = start_datetime config.stop_data_time = stop_datetime config.refresh_count = refresh_count config.save() except peewee.DoesNotExist: config = Config(chrome_path=chromepath, timeout=timeout, sheduled=sheduled, start_data_time=start_datetime, stop_data_time=stop_datetime, timeout_confirm=timeout_confirm, refresh_count=refresh_count) config.save()
def __init__(self): # Это здесь нужно для доступа к переменным, методам # и т.д. в файле design.py super().__init__() if not os.path.exists(REPORTS_DIRECTORY_NAME): os.makedirs(REPORTS_DIRECTORY_NAME) self.setupUi(self) self.setWindowTitle('Instagram auto follow confirm v.1.5') self.pushButton_start.clicked.connect(self.btn_start) self.pushButton_stop.clicked.connect(self.btn_stop) self.pushButton_config.clicked.connect(self.btn_settings) self.pushButton_pause.clicked.connect(self.btn_pause) finish = QAction("Quit", self) finish.triggered.connect(self.closeEvent) # таймер для вывода времени работы self.timer = QTimer() self.timer.timeout.connect(self.handleTimer) self.timer.setInterval(1000) # таймер для старта планировщика self.timer_start = QTimer() self.timer_start.timeout.connect(self.handleTimerstart) self.is_startet_sheduler = False self.lg = logging.getLogger('insta') self.threadpool = QThreadPool() self.stop_thread = False self.pause_thread = False self.is_sheduled = False # программа запустилась по расписанию try: config = Config.select().get() if config.start_data_time: # если врямя запуска уже прошло - устанавливаем насильно ручной режим if datetime.datetime.now() > config.start_data_time: config.sheduled = False config.save() # настраиваем внешний вид в зависимости от config.sheduled if config.sheduled: # запуск по планировщику self.set_shedule_mode(config) else: # запуск в ручном режиме self.set_manual_mode(config) except peewee.DoesNotExist: self.log.append('Внимание! необходимо настроить путь к браузеру') config = Config(chrome_path='', timeout=10, timeout_confirm=3, refresh_count=5, auto_start=False) config.save() self.update_ui()
def run(self): var = self.store.find(Config, Config.varname == unicode(self.options.name)).one() if var: var.value = unicode(self.options.value) print "Updating %s=%s" % (var.varname, var.value) else: var = Config() var.varname = unicode(self.options.name) var.value = unicode(self.options.value) self.store.add(var) print "Setting %s=%s" % (var.varname, var.value) self.store.commit()
def load_stored_data(self): try: config = Config.select().get() self.lineEdit_chromepath.setText(config.chrome_path) self.spinBox_timeout.setValue(config.timeout) self.spinBox_timeout_confirm.setValue(config.timeout_confirm) if config.refresh_count: self.spinBox_refresh_count.setValue(config.refresh_count) if config.sheduled: self.checkBox_sheduled.setChecked(config.sheduled) else: self.checkBox_sheduled.setChecked(False) if config.stop_data_time: self.dateTime_stop.setDateTime(config.stop_data_time) if config.start_data_time: self.dateTime_start.setDateTime(config.start_data_time) except peewee.DoesNotExist: # загружаем значения по умолчанию self.lineEdit_chromepath.setText('') self.spinBox_timeout.setValue(30) self.spinBox_timeout_confirm.setValue(5) self.spinBox_refresh_count.setValue(5) self.checkBox_autostart.setChecked(False) self.dateTime_stop.setDateTime(datetime.datetime.now() + datetime.timedelta(days=1))
def __init__(self): ''' Constructor ''' self.config_ = Config.Config() self.chasmDB_ = self.config_.getWDefault("chasmDB", "SNVBox") self.conn = self._connect(self.chasmDB_)
def __init__(self): try: self.aliases = eval(Config.byName("ALIASES").value) except SQLObjectNotFound: self.aliases = {} except Exception, e: tui.error("Aliases syntax error. Ignored") self.aliases = {}
def do_a_add(self, line): """Add an alias on a command Ex. create an alias 'la' for 't_list -a': a_add la t_list -a""" tokens = line.split() if len(tokens)<2: raise YokadiException("You should provide an alias name and a command") name=tokens[0] command=" ".join(tokens[1:]) self.aliases.update({ name : command}) try: aliases = Config.selectBy(name="ALIASES")[0] except IndexError: # Config entry does not exist. Create it. aliases = Config(name="ALIASES", value="{}", system=True, desc="User command aliases") aliases.value = repr(self.aliases)
def do_a_remove(self, line): """Remove an alias""" if line in self.aliases: del self.aliases[line] aliases = Config.selectBy(name="ALIASES")[0] aliases.value = repr(self.aliases) else: tui.error("No alias with that name. Use a_list to display all aliases")
def parser_t_purge(self): parser = YokadiOptionParser() parser.set_usage("t_purge [options]") parser.set_description("Remove old done tasks from all projects.") parser.add_option("-f", "--force", dest="force", default=False, action="store_true", help="Skip confirmation prompt") delay = int(Config.byName("PURGE_DELAY").value) parser.add_option("-d", "--delay", dest="delay", default=delay, type="int", help="Delay (in days) after which done tasks are destroyed. Default is %d." % delay) return parser
def get_state(name): # if not auth.username() != name: # print(auth.username(), name) # return '', 401 cl = get_cluster(name) it = Config.select().join(Cluster).where(Cluster.name == name).order_by( Config.date_create.desc()) r = [i for i in it] if not r: return '' return jsonify(json.loads(r[0].data))
def get_configs(): arr = [] configs = Config.select() for config in configs: arr.append({ "key": config.key, "value": config.value, "type": config.config_type.type }) print("===SAVING {0} {1}===".format(len(arr), "Configs")) return arr
def btn_stop(self): self.log.append('Нажали Стоп, ждем закрытя браузера') self.stop_thread = True self.timer.stop() if self.is_sheduled: # сбрасываем настроку автозапуска self.is_sheduled = False config = Config.select().get() config.sheduled = self.is_sheduled config.save() self.timer_start.stop() self.set_manual_mode(config)
def do_c_get(self, line): parser = self.parser_c_get() options, args = parser.parse_args(line) line = u" ".join(args) if not line: line="%" k=Config.select(AND(LIKE(Config.q.name, line), Config.q.system==options.system)) fields=[(x.name, "%s (%s)" % (x.value, x.desc)) for x in k] if fields: tui.renderFields(fields) else: raise YokadiException("Configuration key %s does not exist" % line)
def btn_settings(self): dialog = QDialogClass() dialog.exec_() # тут проверяем каждый раз установлен ли запуск по времени config = Config.select().get() # если врямя запуска уже прошло - устанавливаем насильно ручной режим if datetime.datetime.now() > config.start_data_time: config.sheduled = False config.save() if config.sheduled: self.set_shedule_mode(config) else: self.set_manual_mode(config)
def update_ui(self): history_all = Historys.select().count() self.label_countAll.setText(str(history_all)) curr_datetime = datetime.datetime.now() td = datetime.timedelta(days=1) last_24 = curr_datetime - td history_24 = Historys.select().where( Historys.date_time > last_24).count() self.label_count24hour.setText(str(history_24)) config = Config.select().get() history_last_start = Historys.select().where( Historys.date_time > config.last_start_dt).count() self.label_countLaststart.setText(str(history_last_start))
def eventLoop(): """Main event loop""" delta=timedelta(hours=float(Config.byName("ALARM_DELAY").value)) suspend=timedelta(hours=float(Config.byName("ALARM_SUSPEND").value)) cmdDelayTemplate=Config.byName("ALARM_DELAY_CMD").value cmdDueTemplate=Config.byName("ALARM_DUE_CMD").value # For the two following dict, task id is key, and value is (duedate, triggerdate) triggeredDelayTasks={} triggeredDueTasks={} activeTaskFilter=[Task.q.status!="done", Task.q.projectID == Project.q.id, Project.q.active == True] while event[0]: time.sleep(DELAY) now=datetime.today().replace(microsecond=0) delayTasks=Task.select(AND(Task.q.dueDate < now+delta, Task.q.dueDate > now, *activeTaskFilter)) dueTasks=Task.select(AND(Task.q.dueDate < now, *activeTaskFilter)) processTasks(delayTasks, triggeredDelayTasks, cmdDelayTemplate, suspend) processTasks(dueTasks, triggeredDueTasks, cmdDueTemplate, suspend)
def dump(): # if not auth.username() in ['egeneralov']: # return '{}', 401 r = {} for i in Cluster.select(): try: data = Config.select().join(Cluster).where( Cluster.name == i.name).order_by( Config.date_create.desc()).limit(1).get().data r[i.name] = json.loads(data) except: if i.name != 'favicon.ico': r[i.name] = '' return jsonify(r)
def btn_start(self): # обрабатываем паузу if self.pause_thread: self.pause_thread = False self.pushButton_start.setDisabled(True) self.pushButton_pause.setDisabled(False) return else: #запускам таймер если нажимаем страт вне паузы self.curren_time = datetime.datetime.now() self.timer.start() # загружаем настройки config = Config.select().get() chromepath = config.chrome_path if chromepath == '': QMessageBox.warning(self, 'Внимание', 'Путь к браузеру не указан в настройках!', QMessageBox.Ok) return timeout = config.timeout timeout_confirm = config.timeout_confirm refresh_count = config.refresh_count #self.stop_data_time = config.stop_data_time # сохраняем дату время страта config.last_start_dt = datetime.datetime.now() config.save() self.pushButton_start.setDisabled(True) if self.is_sheduled: self.pushButton_pause.setDisabled(True) else: self.pushButton_pause.setDisabled(False) self.pushButton_stop.setDisabled(False) self.pushButton_config.setDisabled(True) print('Start') worker = Worker(self.insat_monitor, kwargs={ 'chromepath': chromepath, 'timeout': timeout, 'timeout_confirm': timeout_confirm, 'refresh_count': refresh_count }) worker.signals.result.connect(self.print_output) worker.signals.finished.connect(self.thread_complete) worker.signals.progress.connect(self.loging_thread) # Execute self.threadpool.start(worker)
def accept_option(bot: Bot, update: Update): new_value = update.effective_message.text config = Config.get() option = OPTIONS_CACHE[update.effective_user.id] if option == "max_busy_time": config.set_max_busy_time(int(new_value)) elif option == "dispatcher_chat_id": config.set_dispatcher_chat_id(int(new_value)) elif option == "check_drivers_interval": config.set_check_drivers_interval(int(new_value)) elif option == "lunch_timeout": config.set_lunch_timeout(int(new_value)) update.effective_chat.send_message( f"Опции {option} установлено новое значение: {new_value}.") return ConversationHandler.END
def show_config(bot: Bot, update: Update): if not Taxopark.is_admin(update.effective_user.id): return conf = Config.get() options = [(key, getattr(conf, key)) for key in conf if key in Config.translation_map] keyboard = [[ InlineKeyboardButton( f"{Config.translation_map[key]}: {val}", callback_data=key) ] for key, val in options] reply_markup = InlineKeyboardMarkup(keyboard) update.effective_chat.send_message( "Выберите опцию:", reply_markup=reply_markup) return STATE_CHOOSE_OPTION
def do_c_set(self, line): """Set a configuration key to value : c_set <key> <value>""" line=line.split() if len(line)<2: raise YokadiException("You should provide two arguments : the parameter key and the value") name=line[0] value=" ".join(line[1:]) p=Config.select(AND(Config.q.name==name, Config.q.system==False)) if p.count()==0: tui.error("Sorry, no parameter match") else: if self.checkParameterValue(name, value): p[0].value=value tui.info("Parameter updated") else: tui.error("Parameter value is incorrect")
def process_supervision(bot: Bot, job: Job): logger.info("checking drivers") start = monotonic() drivers = Taxopark.get_all_drivers_from_map() for driver in drivers: punisher = Punisher(bot) punisher.punish_driver(driver) config = Config.get() interval = config.check_drivers_interval * 60 end = monotonic() extra_time = interval - (end - start) if extra_time > 0: logger.info("supervisor will sleep for %i seconds", extra_time) sleep(extra_time)
def punish_driver(self, driver: Driver): conf = Config.get() name, surname, status = driver.name, driver.surname, driver.status.value if not driver.busy: logger.info('driver %s %s not busy, his status is - "%s"', name, surname, status) return busy_minutes = round( (datetime.utcnow() - driver.status.set_at).total_seconds() / 60) if busy_minutes <= conf.max_busy_time: logger.info( "skip driver %s %s - he is busy for only %i minutes. " "it is acceptable", name, surname, busy_minutes, ) return if not Taxopark.is_registered(driver): logger.info("skip unregistered driver %s %s", name, surname) return payload = Taxopark.get_payload(driver) payload.update_timeout() if payload.timeout or payload.timeout > 1: logger.info("skip driver %s %s which has timeout %i", name, surname, payload.timeout) return payload.increment_penalties() punishment = Punishment(payload.penalty) if punishment.is_warning: # Taxopark.call_driver(driver.name, punishment.message) self._send_warning(punishment.message, driver, reply_markup=punishment.button) elif punishment.is_call_dispatcher: self._call_dispatcher(punishment.message, driver) Taxopark.add_timeout(driver, int(punishment.update_timeout))
def main(): #TODO: check that yokadid is not already running for this database ? Not very harmful... #TODO: change unix process name to "yokadid" # Make the event list global to allow communication with main event loop global event (options, args) = parseOptions() if options.kill: killYokadid(options.filename) sys.exit(0) signal(SIGTERM, sigTermHandler) signal(SIGHUP, sigHupHandler) if not options.foreground: doubleFork() if not options.filename: options.filename = os.path.join(os.path.expandvars("$HOME"), ".yokadi.db") print "Using default database (%s)" % options.filename connectDatabase(options.filename, createIfNeeded=False) # Basic tests : if not (Task.tableExists() and Config.tableExists()): print "Your database seems broken or not initialised properly. Start yokadi command line tool to do it" sys.exit(1) # Start ical http handler if options.icalserver: yokadiIcalServer = YokadiIcalServer(options.tcpPort, options.tcpListen) yokadiIcalServer.start() # Start the main event Loop try: while event[1] != "SIGTERM": eventLoop() event[0] = True except KeyboardInterrupt: print "\nExiting..."
def lunch_request(bot: Bot, update: Update): driver = Taxopark.get_driver(tg_id=update.effective_user.id) conf = Config.get() last_lunch_request_time = driver.last_lunch_request_time if not last_lunch_request_time or driver.lunch_count < 2: update.effective_chat.send_message("Обед одобрен.") Taxopark.add_timeout(driver, conf.lunch_timeout) driver.lunch_count += 1 driver.last_lunch_request_time = datetime.now() driver.save() elif datetime.now().day - driver.last_lunch_request_time.day >= 1: driver.lunch_count = 0 driver.last_lunch_request_time = datetime.now() driver.save() else: update.effective_chat.send_message( "Вы уже взяли два обеда. Это максимум в сутки.")
def let_go_for_lunch(bot: Bot, update: Update): if update.effective_user.id != Taxopark.get_dispatcher_chat_id(): return query = update.callback_query data = query.data answer = {'+': 'Yes', '-': 'No'}[data[0]] driver_id = data[1:] driver = Taxopark.get_driver(driver_id=driver_id) conf = Config.get() tout = conf.lunch_timeout if answer == 'Yes': Taxopark.add_timeout(driver, tout) bot.send_message( driver.tg.id, f"Обед одобрен. Добавлено {tout} минут свободного времени.") else: bot.send_message(driver.tg.id, "Ваш запрос на обед отклонен.") update.callback_query.answer("Ваше решение передано водителю.")
def save_report(self): try: curr_datetime = datetime.datetime.now() td = datetime.timedelta(days=1) last_24 = curr_datetime - td history_24 = Historys.select().where( Historys.date_time > last_24).count() config = Config.select().get() history_last_start = Historys.select().where( Historys.date_time > config.last_start_dt).count() file_name = f'{REPORTS_DIRECTORY_NAME}/report_{datetime.datetime.now().strftime("%H%M%S_%m%d%Y")}.txt' with open(file_name, 'w') as file: file.write( f'Окончание работы: {datetime.datetime.now().strftime("%H:%M:%S %m.%d.%Y")}' + '\n') file.write(f'За сутки было принято: {history_24}' + '\n') file.write( f'За время работы было принято: {history_last_start}' + '\n') except: self.lg.exception('save_report')
def handleTimerstart(self): if datetime.datetime.now() > self.start_data_time: # запускаем скрипт if not self.is_sheduled: self.is_sheduled = True self.log.append('Запускаем по расписанию') self.pushButton_stop.setDisabled(False) self.btn_start() # меняем надписи self.label_timer_text.setText('Время работы:') else: #выводим время работы time = datetime.datetime.now() - self.start_data_time self.label_timer.setText(str(time).split('.', 2)[0]) self.label_timer_text_2.setText('Работать осталось:') time = self.stop_data_time - datetime.datetime.now() self.label_timer_2.setText(str(time).split('.', 2)[0]) else: # выводим время до старта time = self.start_data_time - datetime.datetime.now() self.label_timer.setText(str(time).split('.', 2)[0]) self.label_timer_2.setText('0:00:00') if datetime.datetime.now() > self.stop_data_time: # останавливаем скрипт self.log.append('Останавливаем по расписанию') if self.is_sheduled: # останавливаем таймер self.timer_start.stop() # останавливаем процесс self.btn_stop() # сбрасываем настроку автозапуска self.is_sheduled = False config = Config.select().get() config.sheduled = self.is_sheduled config.save() self.set_manual_mode(config)
def testAdd(self): self.cmd.do_a_add("l t_list") alias = Config.selectBy(name="ALIASES")[0] self.assertEqual(eval(alias.value)["l"], "t_list")
def setup_general_config(): ''' Is used to populate the database if it has been reset. :return: ''' long_string = ConfigType.get(type="long_string") long_string = ConfigType( type="long_string") if long_string is None else long_string string = ConfigType.get(type="string") string = ConfigType(type="string") if string is None else string number = ConfigType.get(type="number") number = ConfigType(type="number") if number is None else number config_list = [{ "key": "frontend_url", "value": "localhost:3001", "config_type": string, "description": "The url to this frontend page (used for links in the emails)" }, { "key": "archive_base_url", "value": "localhost:3001/api/archive/download", "config_type": string, "description": "The base url to download archives from (used in emails to the board)" }, { "key": "document_template_url", "value": "https://www.overleaf.com/read/ddjdhxnkxttj", "config_type": string, "description": "The template overleaf document for the different reports (used in the emails)" }, { "key": "gotify_url", "value": "http://*****:*****@chalmers.it", "config_type": string, "description": "The email to the secretary" }, { "key": "board_email", "value": "*****@*****.**", "config_type": string, "description": "The email to the board" }, { "key": "group_email_domain", "value": "@chalmers.it", "config_type": string, "description": "The domain to send emails to" }, { "key": "from_email_address", "value": "*****@*****.**", "config_type": string, "description": "The email to send from" }, { "key": "mail_to_groups_subject", "value": "Dokument till sektionsmöte den {day}/{month}", "config_type": string, "description": """ The subject for "regular" email sendout (that goes out to all active groups that have documents to turn in for the meeting). \n Description of the formatting values: \n - {group_name} = The display name of the group \n - {meeting_day} = The day of month for the meeting \n - {meeting_month} = The month (number) of the meeting \n - {deadline_time} = The deadline time (hh:mm) \n - {deadline_date} = The deadline date (dd/mm) \n - {task_list} = A list of the tasks that the group should upload \n - {frontend_url} = The url to the website \n - {group_code} = Their unique code \n - {template_url} = The document (overleaf) template url \n - {secretary_email} = The email to the secretary \n - {board_display_name} = The display name of the board \n - {board_email} = The email to the board """ }, { "key": "mail_to_groups_message", "value": "\nHej {group_name}!\n\nDen {meeting_day}/{meeting_month} är det dags för sektionsmöte och senast {deadline_time} den {deadline_date} behöver ni lämna in " "följande dokument: {task_list}\nDetta görs på sidan: {frontend_url}\nAnge koden: {group_code}\n\nMall för vissa " "dokument finns här: {template_url}\nGör en kopia av projektet (Menu -> Copy Project) och fyll i.\n\nOm ni har " "några frågor eller stöter på några problem kan kan ni kontakta mig på {secretary_email} eller hela {board_display_name} på {board_email} " ": ).", "config_type": long_string, "description": """ The body of the "regular" emails (the ones that are sent to all the active groups that should turn in documents for the meeting). \n Description of the formatting values: \n - {group_name} = The display name of the group \n - {meeting_day} = The day of month for the meeting \n - {meeting_month} = The month (number) of the meeting \n - {deadline_time} = The deadline time (hh:mm) \n - {deadline_date} = The deadline date (dd/mm) \n - {task_list} = A list of the tasks that the group should upload \n - {frontend_url} = The url to the website \n - {group_code} = Their unique code \n - {template_url} = The document (overleaf) template url \n - {secretary_email} = The email to the secretary \n - {board_display_name} = The display name of the board \n - {board_email} = The email to the board """ }, { "key": "mail_to_board_subject", "value": "Dokument för sektionsmöte {meeting_number} lp {meeting_lp}", "config_type": string, "description": """ The subject of the email that is sent to the board upon reaching the deadline. \n Description of the formatting values: \n - {board_name} = The display name of the board \n - {meeting_number} = The number of the meeting (usually 0) \n - {meeting_lp} = The study period of the meeting \n - {meeting_archive_url} = A link to the archive download \n - {secretary_email} = The email to the secretary """ }, { "key": "mail_to_board_message", "value": "\nHej {board_name}!\n\nDeadlinen för dokumentinsamling till sektionsmöte {meeting_number} i lp {meeting_lp} är nu nådd.\nFör " "nedladdning av dessa dokument klicka på denna länk: {meeting_archive_url}\n\nVid frågor, kontakta sekreteraren på {secretary_email}", "config_type": long_string, "description": """ The contents of the email that is sent out to the board upon reaching the deadline. \n Description of the formatting values: \n - {board_name} = The display name of the board \n - {meeting_number} = The number of the meeting (usually 0) \n - {meeting_lp} = The study period of the meeting \n - {meeting_archive_url} = A link to the archive download \n - {secretary_email} = The email to the secretary """ }, { "key": "mail_for_stories_subject", "value": "Dokument för sektionsmöte {meeting_number} lp {meeting_lp}", "config_type": string, "description": """ The subject of the email that is sent to the "story groups" (i.e. the groups that needs to turn in eberattelser / vberattelser. \n Description of the formatting values: \n - {group_name_year} = Display name of the group. \n - {meeting_day} = The day of month that the meeting will take place \n - {meeting_month} = The month (number) of the meeting \n - {deadline_time} = The deadline time \n - {deadline_date} = The deadline date \n - {task_list} = A list of the tasks that the group will have to turn in. \n - {frontend_url} = A url to the frontend (upload page) \n - {group_code} = Their unique code \n - {template_url} = A link the overleaf template for the documents. \n - {secretary_email} = The email to the secretary \n - {board_display_name} = The display name of the board \n - {board_email} = The email to the board \n - {meeting_number} = The number of the meeting that study period (usually 0) \n - {meeting_lp} = The study period """ }, { "key": "mail_for_stories", "value": "\nHej {group_name_year}!\n\nDen {meeting_day}/{meeting_month} är det dags för sektionsmöte och senast {deadline_time} den {deadline_date} behöver ni lämna in " "följande dokument: {task_list}\nDetta görs på sidan: {frontend_url}\nAnge koden: {group_code}\n\nMall för vissa " "dokument finns här: {template_url}\nGör en kopia av projektet (Menu -> Copy Project) och fyll i.\n " "Kontakta revisorerna på [email protected] för mer information om vad som behövs göras innan ni " "kan bli rekomenderade att bli ansvarsbefriade.\n\nOm ni har " "några frågor eller stöter på några problem kan kan ni kontakta mig på {secretary_email} eller hela {board_display_name} på {board_email} " ": ).", "config_type": long_string, "description": """ The body of the email that is sent to the "story groups" (i.e. the groups that needs to turn in eberattelser / vberattelser) \n Description of the formatting values: \n - {group_name_year} = Display name of the group. \n - {meeting_day} = The day of month that the meeting will take place \n - {meeting_month} = The month (number) of the meeting \n - {deadline_time} = The deadline time \n - {deadline_date} = The deadline date \n - {task_list} = A list of the tasks that the group will have to turn in. \n - {frontend_url} = A url to the frontend (upload page) \n - {group_code} = Their unique code \n - {template_url} = A link the overleaf template for the documents. \n - {secretary_email} = The email to the secretary \n - {board_display_name} = The display name of the board \n - {board_email} = The email to the board \n - {meeting_number} = The number of the meeting that study period (usually 0) \n - {meeting_lp} = The study period """ }, { "key": "board_display_name", "value": "styrIT", "config_type": string, "description": "The display name of the board" }, { "key": "minutes_after_deadline_to_mail", "value": "5", "config_type": number, "description": "The amount of minutes to wait extra after the deadline before sending the email to the board" }, { "key": "check_for_deadline_frequency", "value": "5", "config_type": number, "description": "The frequence (in minutes) to check if any deadlines have been reached" }, { "key": "possible_years_back_for_stories", "value": "5", "config_type": number, "description": "The number of years back that one should be able to select story groups for (usually 5 due to tax reasons)" }] for config in config_list: conf = Config.get(key=config["key"]) if conf is None: Config(key=config["key"], value=config["value"], config_type=config["config_type"], description=config["description"]) else: # Since the only way to change the description is here, # we always want the db version to be up to date with this list on application restart. conf.description = config["description"] # Setup groups and tasks groups = [{ "codeName": "armit", "displayName": "ArmIT" }, { "codeName": "digit", "displayName": "digIT" }, { "codeName": "fanbarerit", "displayName": "FanbärerIT" }, { "codeName": "fritid", "displayName": "frITid" }, { "codeName": "mrcit", "displayName": "MRCIT" }, { "codeName": "nollkit", "displayName": "NollKIT" }, { "codeName": "prit", "displayName": "P.R.I.T." }, { "codeName": "sexit", "displayName": "sexIT" }, { "codeName": "snit", "displayName": "snIT" }, { "codeName": "styrit", "displayName": "styrIT" }, { "codeName": "equalit", "displayName": "EqualIT" }, { "codeName": "flashit", "displayName": "FlashIT" }] tasks = [{ "codeName": "vplan", "displayName": "Verksamhetsplan / Operational plan" }, { "codeName": "budget", "displayName": "Budget" }, { "codeName": "vrapport", "displayName": "Verksamhetsrapport / Operational report" }, { "codeName": "vberattelse", "displayName": "Verksamhetsberättelse / Operational story" }, { "codeName": "eberattelse", "displayName": "Ekonomisk Berättelse / Economic story" }] for group in groups: if Group.get(name=group["codeName"]) is None: new_group = Group(name=group["codeName"], display_name=group["displayName"]) if GroupYear.get(group=new_group, year="active") is None: GroupYear(group=new_group, year="active", finished=False) for task in tasks: if Task.get(name=task["codeName"]) is None: Task(name=task["codeName"], display_name=task["displayName"]) commit() print("Finished loading database data from general config file.")
def get_dispatcher_chat_id(cls) -> int: conf = Config.get() return conf.dispatcher_chat_id
def get_config(key: str) -> Optional[Config]: return Config.get(key=key)
def get_config_value(config_key: str) -> str: config = Config.get(key=config_key) if config is None: raise Exception("No config found with key {0}".format(config_key)) return config.value