def unsubscribe(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') user_id = message.from_user.id username = message.from_user.username if db.is_subscriber(cid, user_id): db.delete_from_participants(cid, user_id) # минусуем человека, если он участвовал в голосовании # если идёт время обеда if utils.vote_time_check(cid) is None: # и сегодня кто-то голосовал if db.sql_exec(db.check_chat_vote_text, [cid])[0][0] > 0: # проверяем, что пользователь не голосовал до минуса user_vote = db.sql_exec(db.sel_user_elec_text, [cid, user_id])[0][0] if user_vote == 0: utils.dinner_minus(cid, user_id) else: # если был голос до минуса, вычитаем его и показываем новое время utils.dinner_minus(cid, user_id, user_vote) bot.reply_to(message, cfg.vote_before_minus_text.format( cfg.show_din_time[cid]), parse_mode='HTML') # иначе молча пересчитать максимумы без учёта ушедшего участника else: utils.vote_params_chat_reset(cid, user_id) bot.send_message(cid, cfg.unsubscribe_msg) # зачищаем юзера в списках, связанных с обедом if cfg.penalty[cid].get(username) is not None: del cfg.penalty[cid][username] if username in cfg.users_minus[cid]: cfg.users_minus[cid].remove(username) else: bot.send_message(cid, cfg.unsubscribe_err_msg)
def penalty(message): time_now = datetime.datetime.now() cid = message.chat.id pen = db.sql_exec(db.sel_all_penalty_time_text, [cid]) cmd = message.text.split() flg = 0 if (len(cmd) == 3) and (not cmd[1].isdigit()) and (cmd[2].isdigit()): for user in pen: if user[0] == cmd[1][1:]: flg = 1 if user[2] == message.from_user.id: bot.send_message(cid, 'Нельзя ставить штрафы самому себе!') break penalty_time = abs(int(cmd[2])) if penalty_time != 0: if penalty_time >= 25: bot.send_message( cid, 'Я не ставлю штрафы больше чем на 25 минут!') else: bot.send_message( cid, 'Поставил штраф ' + str(cmd[1]) + ' ' + str(penalty_time) + ' мин') # добавляем строку штрафа в метаданные delta = datetime.timedelta(hours=24) expire_date = time_now + delta db.sql_exec(db.ins_operation_meta_text, [ cfg.max_id_rk, 0, cid, user[2], penalty_time, str(time_now)[:-7], str(expire_date)[:-7], 1 ]) cfg.max_id_rk += 1 else: bot.send_message(cid, 'Я не ставлю штрафы 0 минут!') break if flg == 0: bot.send_message( cid, 'Я не нашёл ' + str(cmd[1]) + ' в базе...\n' + 'Проверь написание ника!\n' + 'Ну, или может быть этот этот человек ещё не подписался?') else: pen_msg = 'Штрафы на сегодня:\n' pen_msg_flg = 0 for user in pen: if int(user[1]) != 0: pen_msg += str(user[0]) + ' — ' + str(user[1]) + ' мин\n' pen_msg_flg = 1 if pen_msg_flg == 1: bot.send_message(cid, pen_msg) else: bot.send_message(cid, random.choice(cfg.penalty_empty_text))
def meme_add_processing(message, meme_type, bot): # /meme_add /https... meme_name | /meme_add meme_name cid = message.chat.id bot.send_chat_action(cid, 'typing') query = None if meme_type in ('photo', 'video'): query = message.caption.strip().split() else: query = message.text.strip().split() meme_name = query[-1].strip().lower() mem = db.sql_exec(db.sel_meme_name_text, [cid, meme_name]) if len(mem) != 0: bot.send_message(cid, cfg.meme_dict_text['add_exist_error'].format(meme_name)) return curr_max_meme_id = db.sql_exec(db.sel_max_meme_id_text, [cid]) if curr_max_meme_id == []: curr_max_meme_id = 1 else: curr_max_meme_id = int(curr_max_meme_id[0][0]) + 1 if meme_name.isdigit() is True: bot.send_message(cid, cfg.meme_dict_text['add_digital_name_error']) return res = None if meme_type == 'photo': if len(query) == 2: res = db.sql_exec(db.ins_meme_text, [curr_max_meme_id, cid, meme_name, meme_type, message.json['photo'][-1]['file_id']]) else: bot.send_message(cid, cfg.meme_dict_text['add_media_query_error']) return elif meme_type == 'video': if len(query) == 2: res = db.sql_exec(db.ins_meme_text, [curr_max_meme_id, cid, meme_name, meme_type, message.json['video']['file_id']]) else: bot.send_message(cid, cfg.meme_dict_text['add_media_query_error']) return elif meme_type == 'link': if len(query) == 3: res = db.sql_exec(db.ins_meme_text, [curr_max_meme_id, cid, meme_name, 'link', query[1].strip()]) else: bot.send_message(cid, cfg.meme_dict_text['add_link_query_error']) return if res is not None: bot.send_message(cid, cfg.meme_dict_text['add_success'].format(meme_name)) else: bot.send_message(cid, cfg.meme_dict_text['add_unknown_error'])
def dinner_minus(cid, uid, recalc_minutes=False): # уменьшаем количество голосующих в чате cfg.dinner_cnt[cid] -= 1 db.sql_exec(db.upd_minus_text, [cid, uid]) # пересчитываем макс.голос vote_max_calc(cid) # пересчитываем время обеда если пользователь проголосовал до минуса if recalc_minutes is not False: dinner_vote_sum[cid] -= recalc_minutes upd_din_time(cid)
def settings_default_time(message): cid = message.chat.id try: msg = message.text.lower().strip().split() # отображаем текущее значение настройки if len(msg) == 1: bot.send_message( cid, cfg.curr_value_info + cfg.settings_tovar_dict[msg[0]] + ': <b>' + str(utils.getSettings(cid, 'default_dinner_time'))[:-3] + '</b>.', parse_mode='HTML') # проверяем корректность ввода elif len(msg) == 2 and tp.time_checker(msg[1]): chatSettings = utils.getSettings(cid) time = [int(m) for m in msg[1].split(':')] newTime = datetime.timedelta(hours=time[0], minutes=time[1]) # проверяем, что время по умолчанию + время отклонения не превышает сутки if (newTime + chatSettings['max_deviation']).days > 0: bot.send_message(cid, cfg.err_time_limit, parse_mode='HTML') # проверяем, что время по умолчанию меньше, чем конец голосования elif chatSettings['elec_end_hour'] >= newTime.seconds // 3600: bot.send_message(cid, cfg.big_end_error, parse_mode='HTML') elif chatSettings['default_dinner_time'] == newTime: bot.send_message(cid, 'Новое время совпадает с текущим.', parse_mode='HTML') else: # пересчитываем настройку в оперативке cfg.settings[cid]['default_dinner_time'] = newTime bot.send_message( cid, 'Время обеда по умолчанию изменено, новое значение: <b>' + msg[1] + '</b>.', parse_mode='HTML') # обновление времени обеда в результате сдвига дефолтного времени utils.upd_din_time(cid) # уведомление пользователей если время обеда сдвинулось bot.send_message( cid, 'С учётом сдвига времени обеда по умолчанию, сегодня обедаем в: <b>' + cfg.show_din_time[cid] + '</b>.', parse_mode='HTML') # записываем изменения в БД db.sql_exec(db.update_time_setting_text, [time[0], time[1], cid]) else: bot.send_message(cid, cfg.err_wrong_cmd.format(msg[0] + ' HH:MM'), parse_mode='HTML') except Exception as e: print('***ERROR: Проблема с командой settings_default_time***') print('Exception text: ' + str(e))
def sqlsql(message): cid = message.chat.id user = message.from_user.id bot.send_chat_action(cid, 'typing') sqlQuery = message.text[8:] print(sqlQuery) if sqlQuery.find(';') != -1: bot.send_message(cid, 'Запрос надо писать без ";"!') else: if user == adminId.adminId: res = db.sql_exec(sqlQuery, []) # print(str(res)) resStr = '[]' if res is None: resStr = 'Ошибка в SQL запросе!' else: for i in res: resStr += str(i) + '\n' bot.send_message(cid, str(resStr)) else: bot.send_message( cid, 'Извините, онолитики, я выполняю выполняю только запросы разработчика!' )
def settings_max_deviation(message): cid = message.chat.id try: msg = message.text.lower().strip().split() # отображаем текущее значение настройки if len(msg) == 1: bot.send_message( cid, cfg.curr_value_info + cfg.settings_tovar_dict[msg[0]] + ': <b>' + str(utils.getSettings(cid, 'max_deviation').seconds // 60) + '</b> минут.', parse_mode='HTML') # проверяем корректность ввода elif len(msg) == 2 and tp.minute_checker(msg[1]): chatSettings = utils.getSettings(cid) deviation = datetime.timedelta(minutes=int(msg[1])) # проверяем, что время по умолчанию + время отклонения не превышает сутки if (deviation + chatSettings['default_dinner_time']).days > 0: bot.send_message(cid, cfg.err_time_limit, parse_mode='HTML') elif chatSettings['max_deviation'] == deviation: bot.send_message( cid, 'Ошибка: новое отклонение совпадает с текущим.', parse_mode='HTML') else: # обновляем настройку в оперативке cfg.settings[cid]['max_deviation'] = deviation bot.send_message( cid, 'Максимальное время отклонения от обеда изменено, новое значение: <b>' + msg[1] + '</b> минут.', parse_mode='HTML') # обновляем настройку в БД db.sql_exec(db.update_deviation_setting_text, [int(msg[1]), cid]) # пересчёт votemax utils.vote_max_calc(cid) else: bot.send_message(cid, cfg.err_wrong_cmd.format(msg[0] + ' MM'), parse_mode='HTML') except Exception as e: print('***ERROR: Проблема с командой settings_max_deviation***') print('Exception text: ' + str(e))
def call_all(): chatUsers = {} for cid in cfg.subscribed_chats: users = db.sql_exec(db.sel_all_text, (cid, )) call_users = 'Эй, @all: ' for i in users: call_users += '@' + str(i[4]) + ' ' chatUsers[cid] = call_users.strip() + '\n' return chatUsers
def vote_params_chat_reset(cid, uid=False): # сброс данных о голосовании в базе if uid is False: db.sql_exec(db.upd_reset_elec_chat_text, [cid]) else: db.sql_exec(db.upd_reset_elec_user_text, [cid, uid]) chat_params = db.sql_exec(db.sel_vote_params_chat_text, [cid])[0] # кол-во подписчиков в каждом чате по отдельности cfg.dinner_cnt[chat_params[0]] = chat_params[1] # сумма штрафов в каждом чате по отдельности cfg.penalty_sum[chat_params[0]] = chat_params[2] # кол-во людей со штрафами в каждом чате по отдельности cfg.users_penalty_cnt[chat_params[0]] = chat_params[3] # пересчёт макс.голоса vote_max_calc(cid) # сброс голосований в оперативке dinner_vote_sum[cid] = 0 upd_din_time(cid)
def meme_del(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') query = message.text.strip().split() if len(query) != 2: bot.send_message(cid, cfg.meme_dict_text['del_query_error']) else: meme_name = query[-1].strip().lower() if meme_name.isdigit() is True: res = db.sql_exec(db.del_meme_id_text, [cid, meme_name]) else: res = db.sql_exec(db.del_meme_name_text, [cid, meme_name]) if res is not None: bot.send_message(cid, cfg.meme_dict_text['del_success']) else: bot.send_message(cid, cfg.meme_dict_text['del_unknown_error'])
def updateChatId(e, cid): if e.args[0].find('Bad Request: group chat was upgraded to a supergroup chat') != -1: import json as js d = js.loads(str(e.args[0].split('\n')[1][3:-2])) newCid = d['parameters']['migrate_to_chat_id'] print('!!! CHAT WITH CHAT_ID {} MOVED TO CHAT_ID {} !!!'.format(cid, newCid)) cfg.bot.send_message(newCid, cfg.group_to_supergroup_text) if not(db.boolean_select(db.check_if_settings_exist_text, [cid])): db.sql_exec(db.ins_settings_copy_text, [newCid, cid]) cfg.settings[newCid] = cfg.settings[cid].copy() cfg.show_din_time[newCid] = cfg.show_din_time[cid] db.delete_from_chatID(cid) return newCid
def vote_params_reset(): vote_params_tmp = db.sql_exec(db.sel_vote_params_text, []) for chats in vote_params_tmp: # кол-во подписчиков в каждом чате по отдельности cfg.dinner_cnt[chats[0]] = chats[1] # сумма штрафов в каждом чате по отдельности cfg.penalty_sum[chats[0]] = chats[2] # кол-во людей со штрафами в каждом чате по отдельности cfg.users_penalty_cnt[chats[0]] = chats[3] # заполняем штрафы пользователей в оперативке penalty_tmp = db.sql_exec(db.sel_penalty_text, []) for users in penalty_tmp: cfg.penalty[users[0]] = cfg.penalty.get(users[0], {users[1]: users[2]}) cfg.penalty[users[0]][users[1]] = users[2] for chats in cfg.chat_voters: # считаем votemax vote_max_calc(chats)
def settings_election_end_hour(message): cid = message.chat.id try: msg = message.text.lower().strip().split() # отображаем текущее значение настройки if len(msg) == 1: bot.send_message(cid, cfg.curr_value_info + cfg.settings_tovar_dict[msg[0]] + ': <b>' + str(utils.getSettings(cid, 'elec_end_hour')) + '</b>.', parse_mode='HTML') # проверяем корректность ввода elif len(msg) == 2 and tp.hour_checker(msg[1]): chatSettings = utils.getSettings(cid) new_elec_end_hour = int(msg[1]) # проверяем, что время по умолчанию меньше, чем конец голосования if new_elec_end_hour >= chatSettings[ 'default_dinner_time'].seconds // 3600: bot.send_message(cid, cfg.big_end_error, parse_mode='HTML') elif chatSettings['elec_end_hour'] == new_elec_end_hour: bot.send_message( cid, 'Ошибка: новое время окончания голосования совпадает с текущим.', parse_mode='HTML') else: # обновляем настройку в оперативке cfg.settings[cid]['elec_end_hour'] = new_elec_end_hour bot.send_message( cid, 'Время окончания голосования изменено, новое значение: <b>' + msg[1] + '</b>.', parse_mode='HTML') # обновляем настройку в БД db.sql_exec(db.update_elec_end_hour_setting_text, [int(msg[1]), cid]) else: bot.send_message(cid, cfg.err_wrong_cmd.format(msg[0] + ' HH'), parse_mode='HTML') except Exception as e: print('***ERROR: Проблема с командой settings_election_end_hour***') print('Exception text: ' + str(e))
def settings_flg(message): cid = message.chat.id try: msg = message.text.lower().strip().split() # отображаем текущее значение настройки if len(msg) == 1: bot.send_message(cid, cfg.curr_value_info + cfg.settings_tovar_dict[msg[0]] + ': ' + cfg.flg_check[utils.getSettings( cid, cfg.settings_tovar_dict[msg[0]])], parse_mode='HTML') # проверяем корректность ввода elif len(msg) == 2 and msg[1] in cfg.flg_dict: if utils.getSettings( cid, cfg.settings_tovar_dict[msg[0]]) == cfg.flg_dict[msg[1]]: bot.send_message(cid, 'Ошибка: новое значение совпадает с текущим.', parse_mode='HTML') else: # обновляем в оперативке cfg.settings[cid][cfg.settings_tovar_dict[ msg[0]]] = cfg.flg_dict[msg[1]] bot.send_message(cid, 'Настройка ' + msg[0][10:] + cfg.flg_rus[msg[1]], parse_mode='HTML') # обновляем в БД db.sql_exec( db.update_flg_setting_text.format( cfg.settings_todb_dict[msg[0]], cfg.flg_dict[msg[1]], cid), []) else: bot.send_message(cid, cfg.err_wrong_cmd.format(msg[0] + ' on/off'), parse_mode='HTML') except Exception as e: print('***ERROR: Проблема с командой settings_flg***') print('Exception text: ' + str(e))
def voronkov_timer(bot, meta): # print(meta) user = db.sql_exec(db.sel_text, [meta[2], meta[3]]) # print(user) if user == []: users = db.sql_exec(db.sel_all_text, [meta[2]]) if users != []: # user = rnd.choice(users) user = [rnd.choice(users)] print('! НЕТ ТЕКУЩЕГО ЮЗЕРА, БЫЛ ВЫБРАН ДРУГОЙ !') else: # обновляем строку в метаданных как ошибочную db.sql_exec(db.upd_operation_meta_text, [2, meta[0]]) print('!!! ОШИБКА, НЕТ ЮЗЕРОВ В БАЗЕ ДЛЯ CHAT_ID = ' + str(meta[2]) + ' !!!') return user = '******' + user[0][0] scenario = rnd.choice(cfg.voronkov_text) print(scenario) send_msg(bot, user + scenario[0], meta[2]) time.sleep(1) send_msg(bot, scenario[1], meta[2]) time.sleep(1) send_msg(bot, scenario[2] + str(rnd.randint(10000, 19999)), meta[2]) time.sleep(1) send_msg(bot, scenario[3], meta[2]) bot.send_sticker(meta[2], cfg.stiker_voronkov) # обновляем строку в метаданных как успешно отработавшую db.sql_exec(db.upd_operation_meta_text, [0, meta[0]])
def meme_add(message): cid = message.chat.id # user = message.from_user.id bot.send_chat_action(cid, 'typing') meme_query = message.text.strip().split() mem = db.sql_exec(db.sel_meme_text, [cid, meme_query[-1].lower()]) if len(mem) != 0: bot.send_message(cid, 'Мем "{}" в вашем чате уже существует!'.format(meme_query[-1].lower())) return # /meme_add /https.... meme_name if len(meme_query) == 3: res = db.sql_exec(db.ins_meme_text, [cid, meme_query[-1].strip(), 'lnk', meme_query[1].strip()]) if res != 'ERROR!': bot.send_message(cid, 'Добавил мем "{}" в ваш чат!\nВы можете показать мем с помощью команды'.format(meme_query[-1]) + '\n/meme {}'.format(meme_query[-1])) else: bot.send_message(cid, 'Какая-то ошибка при добовлении мема... Пусть розробочик посмотит в логи!') else: bot.send_message(cid, 'Какая-то ошибка при добовлении мема.\nНужно указать только ссылку и название.')
def ping_all(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') user_id = message.from_user.id users = db.sql_exec(db.sel_all_text, [cid]) call_text = '@all: ' # бежим по всем юзерам в чате for i in users: # если юзер не тот, кто вызывал all, уведомляем его if i[1] != user_id: call_text = call_text + '@' + str(i[0]) + ' ' bot.send_message(cid, call_text.strip() + message.text[4:])
def meme(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') meme_query = message.text.strip().split() if len(meme_query) == 1: res = db.sql_exec("""SELECT name FROM MEME WHERE chat_id = ?""", [cid]) if len(res) == 0: bot.send_message(cid, 'В вашем чате нет мемов=(\nВы можете добавить их командой /meme_add!') else: resStr = 'Мемы, добавленные в ваш чат:\n' for i in res: resStr += '*' + str(i[0]) + '*\n' bot.send_message(cid, str(resStr), parse_mode='Markdown') elif len(meme_query) != 2: bot.send_message(cid, 'Мне нужно только название мема!') else: mem = db.sql_exec(db.sel_meme_text, [cid, meme_query[-1].lower()]) if len(mem) == 0: bot.send_message(cid, 'Мем "{}" не существует в вашем чате!'.format(meme_query[-1].lower())) else: bot.send_message(cid, mem[0][3])
def vote_max_calc(cid): deviation = getSettings(cid, 'max_deviation').seconds // 60 # ведём учёт пользователей которые писали минус # также проводим преобразование users_minus, чтобы обращение не падало cfg.users_minus[cid] = db.normalize_output(db.sql_exec(db.sel_minus_text, [cid])) # не допускаем деление на ноль if cfg.dinner_cnt[cid] > 1: # считаем по формуле из документации к доработке ШТРАФ 2.0, раздельно для людей со штрафами и без cfg.votemax[cid] = (deviation - (deviation * cfg.users_penalty_cnt[cid] / cfg.dinner_cnt[cid]) + cfg.penalty_sum[cid]) / (cfg.dinner_cnt[cid] - cfg.users_penalty_cnt[cid]) cfg.votemax_with_penalty[cid] = deviation / cfg.dinner_cnt[cid] else: # если подписчиков не осталось, votemax=deviation cfg.votemax[cid] = deviation cfg.votemax_with_penalty[cid] = deviation
def user_vote_check(cid, uid): if db.is_subscriber(cid, uid) is False: return cfg.err_vote_msg vote_time_check_err = vote_time_check(cid) if vote_time_check_err: return vote_time_check_err # если минусовал if db.is_minus(cid, uid): # и сегодня уже кто-то голосовал, то запретить голосовать if db.sql_exec(db.check_chat_vote_text, [cid])[0][0] > 0: return cfg.err_minus_vote_msg # иначе сбросить минусы и дать проголосовать (механизм камбека) else: vote_params_chat_reset(cid, uid)
def meme_del(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') meme_query = message.text.strip().split() if len(meme_query) != 2: bot.send_message(cid, 'Для удаления мне нужно только название!') else: res = db.sql_exec(db.del_meme_text, [cid, meme_query[-1].lower()]) if res != 'ERROR!': bot.send_message(cid, 'Если такой мем и был в вашем чате, то он удалён!') else: bot.send_message(cid, 'Какая-то ошибка при добовлении мема... Пусть розробочик посмотит в логи!')
def meme(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') query = message.text.strip().split() if len(query) == 1: res = db.sql_exec(db.sel_meme_in_chat_text, [cid]) if len(res) == 0: bot.send_message(cid, cfg.meme_dict_text['meme_no_memes']) else: resStr = 'Мемы, добавленные в ваш чат:\n' for i in res: resStr += '<b>{}. {}</b>\n'.format(str(i[0]), str(i[1])) bot.send_message(cid, str(resStr), parse_mode='HTML') elif len(query) == 2: meme_name = query[-1].strip().lower() mem = None if meme_name.isdigit() is False: mem = db.sql_exec(db.sel_meme_name_text, [cid, meme_name]) else: mem = db.sql_exec(db.sel_meme_id_text, [cid, meme_name]) if len(mem) == 0: bot.send_message( cid, cfg.meme_dict_text['meme_no_mem_in_chat'].format(meme_name)) else: if mem[0][0] == 'photo': bot.send_photo(cid, mem[0][1]) elif mem[0][0] == 'video': bot.send_video(cid, mem[0][1]) elif mem[0][0] == 'link': bot.send_message(cid, mem[0][1]) else: bot.send_message(cid, cfg.meme_dict_text['meme_query_error'])
def call_all(query=db.sel_all_text, chat_id=None): chatUsers = {} if chat_id is None: for cid in cfg.subscribed_chats: users = db.sql_exec(query, [cid]) if users == []: chatUsers[cid] = '' continue call_users = '@all: ' for i in users: call_users += '@' + str(i[0]) + ' ' chatUsers[cid] = call_users.strip() + '\n' else: users = db.sql_exec(query, [chat_id]) if users == [] or chat_id not in cfg.subscribed_chats: chatUsers[chat_id] = '' return chatUsers call_users = '@all: ' for i in users: call_users += '@' + str(i[0]) + ' ' chatUsers[chat_id] = call_users.strip() + '\n' return chatUsers
def ping_all(message): cid = message.chat.id user_id = message.from_user.id users = db.sql_exec(db.sel_all_text, [cid]) call_text = 'Эй, @all: ' # бежим по всем юзерам в чате for i in users: # если юзер не тот, кто вызывал all, уведомляем его if i[1] != user_id: call_text = call_text + '@' + str(i[4]) + ' ' # проверка на /all@ddsCrewBot if (message.text[0:15] == '/all@ddsCrewBot'): bot.send_message(cid, call_text.strip() + message.text[15:]) else: bot.send_message(cid, call_text.strip() + message.text[4:])
def subscribe(message): cid = message.chat.id bot.send_chat_action(cid, 'typing') user = message.from_user res = db.insert_into_participants(cid, user) if res == -1: bot.send_message(cid, cfg.err_subscribe_msg) else: bot.send_message(cid, cfg.subscribe_msg) # если идёт время обеда if utils.vote_time_check(cid) is None: # и сегодня кто-то голосовал, то запретить голосовать if db.sql_exec(db.check_chat_vote_text, [cid])[0][0] > 0: bot.reply_to(message, cfg.vote_after_subscribe_text) utils.dinner_minus(cid, user.id) # иначе молча пересчитать максимумы с учётом нового участника else: utils.vote_params_chat_reset(cid, user.id) # добавляем юзера в списки, связанные с обедом if cfg.penalty[cid].get(user.username) is None: cfg.penalty[cid][user.username] = 0
def minus(message): try: cid = message.chat.id uid = message.from_user.id # проверяем что пользователь может голосовать vote_today_err = utils.user_vote_check(cid, uid) if vote_today_err is None: # проверяем, что пользователь не голосовал до минуса user_vote = db.sql_exec(db.sel_user_elec_text, [cid, uid])[0][0] if user_vote == 0: bot.reply_to(message, 'Принято!', parse_mode='HTML') utils.dinner_minus(cid, uid) else: # если был голос до минуса, вычитаем его и показываем новое время utils.dinner_minus(cid, uid, user_vote) bot.reply_to(message, cfg.vote_before_minus_text.format( cfg.show_din_time[cid]), parse_mode='HTML') else: bot.reply_to(message, vote_today_err) except Exception as e: print('***ERROR: Проблема с командой minus***') print('Exception text: ' + str(e))
def vote_func(vote_chat, bot, message): cid = message.chat.id user_id = message.from_user.id dinner_vote = db.sql_exec(db.sel_election_text, [cid, user_id]) if len(dinner_vote) == 0: bot.reply_to(message, cfg.err_vote_msg) else: vote_db = dinner_vote[0][2] penalty_time = dinner_vote[0][3] final_elec_time = 0 sign = 1 if vote_chat != 0: sign = vote_chat / abs(vote_chat) final_elec_time = vote_chat - sign * penalty_time if abs(final_elec_time) > getSettings(cid, 'max_deviation').seconds // 60: final_elec_time = sign * getSettings(cid, 'max_deviation').seconds // 60 if sign * final_elec_time < 0: final_elec_time = 0 # final_elec_time = datetime.timedelta(minutes=final_elec_time) # считаем сумму голосов отдельно от времени dinner_vote_sum[cid] = dinner_vote_sum.get(cid, 0) + final_elec_time additional_msg = '' if penalty_time != 0: additional_msg = 'с учётом штрафов ' # голосование или переголосование if int(vote_db) == 0: # обновляем итоговое время обеда upd_din_time(cid) bot.reply_to( message, cfg.vote_msg + additional_msg + cfg.show_din_time[cid]) else: final_elec_time = 0 prev_vote_db = int(vote_db) sign = 1 if prev_vote_db != 0: sign = prev_vote_db / abs(prev_vote_db) final_elec_time = prev_vote_db - sign * penalty_time if abs(final_elec_time) > getSettings( cid, 'max_deviation').seconds // 60: final_elec_time = sign * getSettings( cid, 'max_deviation').seconds // 60 if sign * final_elec_time < 0: final_elec_time = 0 # final_elec_time = datetime.timedelta(minutes=final_elec_time) # считаем сумму голосов отдельно от времени обеда dinner_vote_sum[cid] -= final_elec_time # обновляем итоговое время обеда upd_din_time(cid) bot.reply_to( message, cfg.revote_msg + additional_msg + cfg.show_din_time[cid]) print('Время обеда', cfg.show_din_time[cid]) db.sql_exec(db.upd_election_elec_text, [vote_chat, cid, user_id])
def penalty(message): time_now = datetime.datetime.now() cid = message.chat.id bot.send_chat_action(cid, 'typing') pen = db.sql_exec(db.sel_all_penalty_time_text, [cid]) # pen = db.sql_exec(db.sel_all_penalty_time_text, [-282255340]) # print(pen) # print(db.sql_exec(db.sel_all_text, [-282255340])) cmd = message.text.split() flg = 0 if (len(cmd) == 3) and (cmd[1].lower() == 'cancel') and (cmd[2].isdigit()): # отмена штрафа rk = int(cmd[2]) meta = db.sql_exec(db.sel_meta_by_rk, [rk]) if len(meta) == 0: bot.send_message(cid, 'Штрафа с таким номером не существует!') else: meta = meta[0] dttm = datetime.datetime.strptime(meta[5], '%Y-%m-%d %H:%M:%S') val = int(meta[4]) sign = val / abs(val) # 1(active) = 1(positive penalty) if (dttm.date() == time_now.date()) and (meta[7] == sign): if meta[3] == message.from_user.id: bot.send_message(cid, cfg.self_penalty.format('отменять')) else: db.sql_exec(db.upd_operation_meta_text, [3, rk]) bot.send_message(cid, cfg.cancel_penalty.format(rk)) else: bot.send_message(cid, 'Данный штраф уже невозможно отменить!') elif (len(cmd) == 3) and (not cmd[1].isdigit()) and (cmd[2].isdigit()): # постановка штрафа for user in pen: if user[0] == cmd[1][1:]: flg = 1 if user[2] == message.from_user.id: bot.send_message(cid, cfg.self_penalty.format('ставить')) break penalty_time = abs(int(cmd[2])) if penalty_time != 0: # if penalty_time > 25: if penalty_time > utils.getSettings( cid, 'max_deviation').seconds // 60: bot.send_message( cid, 'Я не ставлю штрафы больше чем на максимальное отклонение!' ) else: # добавляем строку штрафа в метаданные delta = datetime.timedelta(hours=24) # delta = datetime.timedelta(seconds=10) expire_date = time_now + delta db.sql_exec(db.ins_operation_meta_text, [ cfg.max_id_rk, 0, cid, user[2], penalty_time, str(time_now)[:-7], str(expire_date)[:-7], 1 ]) cfg.max_id_rk += 1 bot.send_message( cid, cfg.set_penalty.format(str(cmd[1]), str(penalty_time), cfg.max_id_rk - 1)) # evt.check_metadata(bot) # evt.check_metadata(bot) # print(db.sql_exec("""SELECT * FROM ELECTION""", [])) else: bot.send_message(cid, 'Я не ставлю штрафы 0 минут!') break if flg == 0: bot.send_message(cid, cfg.no_member.format(str(cmd[1]))) else: # вывод списка штрафов pen_msg = 'Штрафы на сегодня:\n' pen_msg_flg = 0 for user in pen: if int(user[1]) != 0: pen_msg += str(user[0]) + ' — <b>' + str( user[1]) + '</b> мин\n' pen_msg_flg = 1 if pen_msg_flg == 1: bot.send_message(cid, pen_msg, parse_mode='HTML') else: bot.send_message(cid, random.choice(cfg.penalty_empty_text))
def check_metadata(bot): time_now = datetime.datetime.now() # выбираем все активные строки из метаданных meta = db.sql_exec( """SELECT * FROM METADATA WHERE operation in (0, 1) and is_success_flg = ?""", [1]) # meta = db.sql_exec(db.sel_operation_meta_text, [0, 1]) # meta.extend(db.sql_exec(db.sel_operation_meta_text, [1, 1])) # meta = db.sql_exec(db.sel_operation_meta_text, [(0, 1), 1]) for m in meta: # print(m) # '%Y-%m-%d %H:%M:%S' dttm = datetime.datetime.strptime(m[6], '%Y-%m-%d %H:%M:%S') if (dttm.date() == time_now.date()) and (dttm.time() >= time_now.time()): # штрафы if m[1] == 0: print(m) user = db.sql_exec(db.sel_election_text, [m[2], m[3]]) if len(user) == 0: # обновляем строку в метаданных как ошибочную db.sql_exec(db.upd_operation_meta_text, [2, m[0]]) print('!!! ОШИБКА, НЕТ ЮЗЕРА В БАЗЕ ДЛЯ ' + str(m[2]) + ' ' + str(m[3]) + ' !!!') else: if m[4] >= 0: # вычисляем дату исполнения hh = 48 if dttm.weekday() in (4, 5): hh = 96 if dttm.weekday() == 6: hh = 72 delta = datetime.timedelta(hours=hh, minutes=5) # delta = datetime.timedelta(seconds=10) expire_date = time_now + delta db.sql_exec(db.ins_operation_meta_text, [ cfg.max_id_rk, 0, m[2], m[3], -int(m[4]), str(time_now)[:-7], str(expire_date)[:-7], 1 ]) cfg.max_id_rk += 1 penalty = int(user[0][3]) + int(m[4]) if penalty < 0: penalty = 0 elif penalty > utils.getSettings( m[2], 'max_deviation').seconds // 60: penalty = utils.getSettings( m[2], 'max_deviation').seconds // 60 # ставим/убираем штраф db.sql_exec(db.upd_election_penalty_text, [penalty, m[2], m[3]]) # обновляем строку в метаданных как успешно отработавшую db.sql_exec(db.upd_operation_meta_text, [0, m[0]]) print(db.sql_exec("""SELECT * FROM METADATA""", [])) print(db.sql_exec("""SELECT * FROM ELECTION""", [])) # воронков elif m[1] == 1 and utils.getSettings(m[2], 'voronkov') == 1: dttmt = dttm.time() expire_time = datetime.timedelta(hours=dttmt.hour, minutes=dttmt.minute, seconds=dttmt.second) dttmt_now = time_now.time() time_now_delta = datetime.timedelta(hours=dttmt_now.hour, minutes=dttmt_now.minute, seconds=dttmt_now.second) delta = expire_time - time_now_delta delta = int(delta.total_seconds()) + 1 th.Timer(delta, voronkov_timer, args=( bot, m, )).start() elif dttm < time_now: # обновляем строку в метаданных как ошибочную (не выполнилась в нужную дату или время) db.sql_exec(db.upd_operation_meta_text, [2, m[0]]) print('!!! ОШИБОЧНАЯ СТРОКА В ТАБЛИЦЕ МЕТАДАННЫХ !!!') print(m) # команду штрафа надо применить в любом случае if m[1] == 0: cfg.meta_error_flg = 1 delta = datetime.timedelta(minutes=10) expire_date = time_now + delta db.sql_exec(db.ins_operation_meta_text, [ cfg.max_id_rk, 0, m[2], m[3], m[4], str(time_now)[:-7], str(expire_date)[:-7], 1 ]) cfg.max_id_rk += 1
def one_hour_timer(bot): time_now = datetime.datetime.now() # флаг, который говорит, показывать ли сообщения (показывает, когда 1) to_show = 0 # начальное время таймера (60 * 60) timer_time = 3600 # начальная дельта (0) delta = datetime.timedelta(seconds=0) if str(time_now.time().minute) in ('0'): to_show = 1 if str(time_now.time().second) <= '30': # нормальная работа timer = th.Timer(timer_time, one_hour_timer, args=(bot, )) else: # случай для возможного увеличения времени из-за расчётов программы timer_time -= 29 timer = th.Timer(timer_time, one_hour_timer, args=(bot, )) else: # рандомное время, например, при запуске бота # высчитываем время до ближайшего часа **:00:01 common_time = datetime.timedelta(minutes=60, seconds=0) cur_time = datetime.timedelta(minutes=time_now.time().minute, seconds=time_now.time().second) delta = common_time - cur_time timer_time = int(delta.total_seconds()) + 1 timer = th.Timer(timer_time, one_hour_timer, args=(bot, )) print('Секунды до таймера =', timer_time) print('Время до таймера =', delta) timer.start() if to_show == 1: # будние + непраздничные дни if time_now.weekday() not in (5, 6) and time_now not in cfg.ru_holidays: for chats in cfg.subscribed_chats: chatSettings = utils.getSettings(chats) # доброе утро + показать maxvote + вызвать pidora if str(time_now.time().hour) == '9': send_msg(bot, rnd.choice(cfg.gm_text), chats) send_msg(bot, utils.maxvote_cmd(chats), chats) if chatSettings['pidor'] == 1: send_msg(bot, '/pidor@SublimeBot', chats) # напоминание о голосовании за обед if time_now.time().hour == chatSettings['elec_end_hour'] - 1: chatUsers = call_all(db.sel_nonvoted_users_text, chats) for cid, msg in chatUsers.items(): send_msg(bot, msg + rnd.choice(cfg.vote_notif_text), cid) # обед if time_now.time().hour == chatSettings['elec_end_hour']: chatUsers = call_all(chat_id=chats) cur_time = datetime.timedelta( hours=time_now.time().hour, minutes=time_now.time().minute, seconds=time_now.time().second) for cid, msg in chatUsers.items(): send_msg( bot, '{}{}<b>{}</b>'.format(msg, rnd.choice(cfg.dinner_text), cfg.show_din_time[cid]), cid) # сохраняем историю голосования db.sql_exec(db.colect_election_hist_text, [str(time_now.date())]) # обнуляем время голосования db.sql_exec(db.reset_election_time_text, [0]) # ставим таймер за 10 минут до обеда, о напоминании об обеде delta = utils.calc_show_din_time( cid) - cur_time - datetime.timedelta(minutes=10, seconds=0) th.Timer(int(delta.total_seconds()) + 1, dinner_timer, args=( bot, cid, )).start() # # намёк поесть # if str(time_now.time().hour) == '17': # send_msg(bot, rnd.choice(cfg.eat_text)) # пора уходить с работы if str(time_now.time().hour) == '19': send_msg(bot, rnd.choice(cfg.bb_text), chats) # в определённое время намекать на попить if str(time_now.time().hour) in ('11', '15', '17', '18'): send_msg(bot, rnd.choice(cfg.pitb_text), chats) # выходные elif time_now.weekday() == 6: # напоминать про дсс if str(time_now.time().hour) == '19': chatUsers = call_all() for cid, msg in chatUsers.items(): send_msg(bot, msg + rnd.choice(cfg.dss_text), cid) # поставить таймер на воронкова if str(time_now.time().hour) == '23': for cid in cfg.subscribed_chats: # оставляем небольшой запас времени на вычисления # 1 минута и 10 секунд hh = rnd.randint(1, 119) mm = rnd.randint(1, 58) ss = rnd.randint(0, 50) # вычисляем дату исполнения delta = datetime.timedelta(hours=hh, minutes=mm, seconds=ss) expire_date = time_now + delta if utils.getSettings(cid, 'voronkov') == 1: users = db.sql_exec(db.sel_all_text, [cid]) if users != []: call_user = rnd.choice(users)[1] # добавляем строку воронкова в метаданные для каждого чата db.sql_exec(db.ins_operation_meta_text, [ cfg.max_id_rk, 1, cid, call_user, -1, str(time_now)[:-7], str(expire_date)[:-7], 1 ]) cfg.max_id_rk += 1 else: print( '! ОШИБКА, НЕТ ЮЗЕРОВ В БАЗЕ ДЛЯ CHAT_ID = ' + str(cid) + ' !') # выводим дату для лога и выполняем системные сбросы и таймеры if str(time_now.time().hour) == '0': print('New day!', time_now) # проверяем метаданные и выставляем таймеры check_metadata(bot) # если произошла ошибка с выставлением штрафа, # нужно проверить метаданные ещё раз if cfg.meta_error_flg == 1: cfg.meta_error_flg = 0 check_metadata(bot) # обнуляем время голосования в боте utils.upd_din_time() # пересчитываем ограничения на голосование utils.vote_params_reset()