def process_updating_entry_callback(job_queue: JobQueue, database: Database, finish_time: dt.datetime): """ This callback function will be called, when an Update operation will be occurred in the database. """ jobs = job_queue.jobs() entries = database.get_entries(dt.datetime.now(), finish_time) for job in jobs: if isinstance(job.context, Entry): exist = False for entry in entries: if job.context.note_id == entry.note_id: if job.context.chat_id == entry.chat_id and job.context.name == entry.name: if job.context.entry_date == entry.entry_date: exist = True break else: job.schedule_removal() if entry.entry_date <= finish_time: job_queue.run_once(callback=recall_send_callback, when=entry.entry_date, context=entry) break else: job.schedule_removal() if entry.entry_date <= finish_time: job_queue.run_once(callback=recall_send_callback, when=entry.entry_date, context=entry) break if not exist: job.schedule_removal()
def timer_message(job_queue: JobQueue, chat_id, timer, comment): job_queue.run_once(send_timer_massage, timer, dict( timer=timer, chat_id=chat_id, comment=comment, ))
def edit_message(job_queue: JobQueue, chat_id, message_id, text, parse_mode='HTML'): job_queue.run_once( lambda _: edit_message_task(chat_id, message_id, text, parse_mode), 0)
def update_round_message(job_queue: JobQueue, game_round: Round, language_code, refresh=False): job_queue.run_once( lambda _: update_round_message_task(game_round.chat_id, language_code, refresh), 0)
def _remove_message_after(message: Message, job_queue: JobQueue, seconds: int): logger.debug( "Scheduling cleanup of message %s \ in %d seconds", message, seconds, ) job_queue.run_once(lambda _: message.delete(), seconds, context=message.chat_id)
def error_message(message: telegram.Message, job_queue: JobQueue, text: str): delete_time = 15 sent = message.reply_text('<b>[ERROR]</b> {}'.format(text), parse_mode='HTML') context = dict( chat_id=message.chat_id, message_id_list=(message.message_id, sent.message_id), ) job_queue.run_once(delay_delete_messages, delete_time, context=context)
def answer_callback_query(job_queue: JobQueue, query_id, text=None, show_alert=False, cache_time=0): job_queue.run_once( lambda _: answer_callback_query_task(query_id, text, show_alert, cache_time), 0)
def delete_message(job_queue: JobQueue, chat_id, message_id, when=0): key = deletion_task_key(chat_id, message_id) delete_tasks = job_queue.get_jobs_by_name(key) for task in delete_tasks: # Deletion will be postponed task.schedule_removal() job_queue.run_once(lambda _: delete_message_task(chat_id, message_id), when, name=key)
def send_message(job_queue: JobQueue, chat_id, text, reply_to=None, parse_mode='HTML', delete_after=None): job_queue.run_once( lambda context: send_message_task(context.job_queue, chat_id, text, reply_to, parse_mode, delete_after), 0)
def handle_roll(message: telegram.Message, name: str, text: str, job_queue: JobQueue, hide=False): if text.strip() == '': text = 'd' try: result_text = roll_text(message.chat_id, text) except dice.RollError as e: return error_message(message, job_queue, e.args[0]) kind = LogKind.ROLL.value if hide: roll_id = str(uuid.uuid4()) redis.set('roll:{}'.format(roll_id), pickle.dumps({ 'text': result_text, 'chat_id': message.chat_id, })) keyboard = [[InlineKeyboardButton("GM 查看", callback_data=roll_id)]] reply_markup = InlineKeyboardMarkup(keyboard) text = '<b>{}</b> 投了一个隐形骰子'.format(name) kind = LogKind.HIDE_DICE.value else: text = '{} 🎲 {}'.format(name, result_text) reply_markup = None chat = get_chat(message.chat) if not chat.recording: text = '[未记录] ' + text sent = message.chat.send_message( text, reply_markup=reply_markup, parse_mode='HTML' ) user = message.from_user assert isinstance(user, telegram.User) if chat.recording: Log.objects.create( user_id=user.id, message_id=sent.message_id, chat=chat, content=result_text, user_fullname=user.full_name, character_name=name, gm=is_gm(message.chat_id, user.id), kind=kind, created=message.date, ) context = dict( chat_id=message.chat_id, message_id_list=[message.message_id] ) job_queue.run_once(delay_delete_messages, 10, context)
def variable_message(message: telegram.Message, job_queue: JobQueue, assignment_list: List[Assignment]): send_text = '' for assignment in assignment_list: send_text += assignment.display(message.from_user.language_code) + '\n' sent = message.chat.send_message(send_text, parse_mode='HTML') user = message.from_user assert isinstance(user, telegram.User) delete_time = 30 job_queue.run_once(delay_delete_messages, delete_time, context=dict( chat_id=message.chat_id, message_id_list=(message.message_id, sent.message_id) ))
def ping(_, update: Update, job_queue: JobQueue): msg: Message = update.effective_message sent = msg.reply_text("🏓 Pong!", quote=True) del_timeout = 4 def delete_msgs(*_): sent.delete() try: msg.delete() except: pass job_queue.run_once(delete_msgs, del_timeout, name="delete ping pong messages")
def run_entries_jobs(job_queue: JobQueue, database: Database, start_time: dt.datetime, finish_time: dt.datetime): """ Function will get entries from the database between the specific period and run new jobs that will call the function of recalling about events. :param job_queue: the JobQueue instance :param database: the Database instance :param start_time: the start time of the period :param finish_time: the end time of the period """ entries = database.get_entries(start_time, finish_time) for entry in entries: job_queue.run_once(callback=recall_send_callback, when=entry.entry_date, context=entry)
def add_notify_event(job_queue: JobQueue, job_model: Job): job_name = str(job_model.chat_id) + '_' + job_model.name if job_model.mode == JobMode.ONCE: job_queue.run_once( callback=notify_callback, name=job_name, when=create_time(job_model.time), ) elif job_model.mode == JobMode.DAILY: job_queue.run_daily( callback=notify_callback, name=job_name, time=create_time(job_model.time), days=(0, 2, 3, 4), # Monday-Friday )
def error_message(message: telegram.Message, job_queue: JobQueue, text: str): _ = partial(get_by_user, user=message.from_user) delete_time = 15 try: send_text = '<b>[{}]</b> {}'.format( _(Text.ERROR), text, ) sent = message.reply_text(send_text, parse_mode='HTML') except TelegramError: return context = dict( chat_id=message.chat_id, message_id_list=(message.message_id, sent.message_id), ) job_queue.run_once(delay_delete_messages, delete_time, context=context)
def handle_roll(message: telegram.Message, name: str, entities: Entities, job_queue: JobQueue, chat: Chat, hide=False): _ = partial(get_by_user, user=message.from_user) kind = LogKind.ROLL.value result_text = entities.to_html() if hide: hide_roll = HideRoll(message.chat_id, result_text) hide_roll.set() keyboard = [[ InlineKeyboardButton(_(Text.GM_LOOKUP), callback_data=hide_roll.key()) ]] reply_markup = InlineKeyboardMarkup(keyboard) text = '<b>{}</b> {}'.format(name, _(Text.ROLL_HIDE_DICE)) kind = LogKind.HIDE_DICE.value else: text = '{} 🎲 {}'.format(name, result_text) reply_markup = None if not chat.recording: text = '[{}] '.format(_(Text.NOT_RECORDING)) + text sent = message.chat.send_message(text, reply_markup=reply_markup, parse_mode='HTML') user = message.from_user assert isinstance(user, telegram.User) if chat.recording: Log.objects.create( user_id=user.id, message_id=sent.message_id, chat=chat, content=result_text, entities=entities.to_object(), user_fullname=user.full_name, character_name=name, gm=is_gm(message.chat_id, user.id), kind=kind, created=message.date, ) context = dict(chat_id=message.chat_id, message_id_list=[message.message_id]) job_queue.run_once(delay_delete_messages, 10, context)
def handle_list_variables(message: telegram.Message, job_queue: JobQueue, name: str, player: Player, **_): _ = partial(get_by_user, user=message.from_user) content = '' have_variable = False for variable in player.variable_set.order_by('updated').all(): have_variable = True content += '<code>${}</code> {}\n'.format(variable.name, variable.value) if not have_variable: content = _(Text.VARIABLE_LIST_EMPTY) send_text = '<b>{}</b>\n\n{}'.format(_(Text.VARIABLE_LIST_TITLE).format(character=name), content) list_message = message.chat.send_message(send_text, parse_mode='HTML') delete_message(message) delete_time = 30 job_queue.run_once(delay_delete_messages, delete_time, context=dict( chat_id=message.chat_id, message_id_list=(list_message.message_id,) ))
def test_default_tzinfo(self, _dp, tz_bot): # we're parametrizing this with two different UTC offsets to exclude the possibility # of an xpass when the test is run in a timezone with the same UTC offset jq = JobQueue() original_bot = _dp.bot _dp.bot = tz_bot jq.set_dispatcher(_dp) try: jq.start() when = dtm.datetime.now(tz_bot.defaults.tzinfo) + dtm.timedelta(seconds=0.0005) jq.run_once(self.job_run_once, when.time()) sleep(0.001) assert self.result == 1 jq.stop() finally: _dp.bot = original_bot
def try_delete_after( job_queue: JobQueue, messages: Union[List[Union[Message, int]], Union[Message, int]], delay: Union[float, int], ): if isinstance(messages, (Message, int)): _messages = [messages] else: _messages = messages @run_async def delete_messages(*args, **kwargs): # noinspection PyTypeChecker bot: BotListBot = job_queue.bot for m in _messages: bot.delete_message(m.chat_id, m.message_id, timeout=10, safe=True) job_queue.run_once(delete_messages, delay, name="try_delete_after")
def process_inserting_entry_callback(job_queue: JobQueue, database: Database, finish_time: dt.datetime): """ This callback function will be called, when an Insert operation will be occurred in the database. """ jobs = job_queue.jobs() entries = database.get_entries(dt.datetime.now(), finish_time) for entry in entries: ran = False # Check that entry wasn't ran and put into the job_queue for job in jobs: if isinstance(job.context, Entry): if job.context.chat_id == entry.chat_id and job.context.name == entry.name: ran = True break if not ran: job_queue.run_once(callback=recall_send_callback, when=entry.entry_date, context=entry)
def hint_handler(bot, update, job_queue: JobQueue): chat_id = update.message.chat_id if not util.is_group_message(update): return text = update.message.text reply_to = update.message.reply_to_message user = User.from_update(update) msg, reply_markup, hashtag = get_hint_data(text) def _send_hint(hint_text): if hint_text is None: return if reply_to: hint_text = f"{user.markdown_short} hints: {hint_text}" bot.formatter.send_message( chat_id, hint_text, reply_markup=reply_markup, reply_to_message_id=reply_to.message_id if reply_to else None, ) update.effective_message.delete() should_reply: bool = HINTS.get(hashtag)["should_reply"] if should_reply and not reply_to: del_markup = append_free_delete_button(update, InlineKeyboardMarkup([[]])) _send_hint(msg) ntfc_msg = update.effective_message.reply_text( f"Hey {user.markdown_short}, next time reply to someone 🙃", parse_mode=ParseMode.MARKDOWN, reply_markup=del_markup, quote=False, disable_web_page_preview=True, ) job_queue.run_once(lambda *_: ntfc_msg.delete(), 7, name="delete notification") else: _send_hint(msg)
def _ptbcontrib_job(self, job_queue: JobQueue) -> None: self.logger.info("Getting ptbcontrib data.") try: files = cast( List[Tuple[str, Contents]], self.repos[PTBCONTRIB_REPO_NAME].directory_contents( PTBCONTRIB_REPO_NAME), ) with self.ptbcontrib_lock: self.ptbcontribs.clear() self.ptbcontribs.update({ name: PTBContrib(name, content.html_url) for name, content in files if content.type == "dir" }) # Rerun in two hours minutes job_queue.run_once(lambda _: self._ptbcontrib_job(job_queue), 2 * 60 * 60) except GitHubException as exc: if "rate limit" in str(exc): self.logger.warning( "GH API rate limit exceeded. Retrying in 70 minutes.") job_queue.run_once(lambda _: self._ptbcontrib_job(job_queue), 60 * 70) else: self.logger.exception( "Something went wrong fetching issues. Retrying in 10s.", exc_info=exc) job_queue.run_once(lambda _: self._ptbcontrib_job(job_queue), 10)
def send_next(bot, update, job_queue: JobQueue, args=None): uid = util.uid_from_update(update) num_rows = None if args: try: num_rows = int(args[0]) except: num_rows = None reply_markup = ReplyKeyboardMarkup(_crapPy_Tr0ll_kbmarkup(num_rows), one_time_keyboard=False, per_user=True) text = "ɹoʇɐɹǝuǝb ǝɯɐuɹǝsn ɯɐɹbǝןǝʇ" util.send_md_message(bot, uid, text, reply_markup=reply_markup) if util.is_group_message(update): del_msg = bot.formatter.send_message( update.effective_chat.id, "Have fun in private ;)\n/easteregg") update.effective_message.delete() job_queue.run_once(lambda *_: del_msg.delete(safe=True), 4, name="delete easteregg hint")
def welcome(bot: Bot, update: Update, job_queue: JobQueue) -> None: user_name = update.effective_message.new_chat_members[0].name user_id = update.effective_message.new_chat_members[0].id to_welcome, chat, message = False, 0, '' if update.effective_chat.id == nmaps_chat: bot.delete_message(nmaps_chat, update.effective_message.message_id) member = update.effective_chat.get_member(update.effective_user.id) if member.status in (ChatMember.RESTRICTED, ChatMember.KICKED): return msg = bot.send_message(nmaps_chat, BOT_WELCOME_NMAPS.format(user_name), reply_markup=VERIFY_MARKUP, parse_mode='html') bot.restrict_chat_member(nmaps_chat, user_id, can_send_messages=False) job_queue.run_once(kick_and_delete_message, 300, { 'user_id': user_id, 'msg_id': msg.message_id, 'chat_id': nmaps_chat }, str(user_id)) elif update.effective_chat.id == mods_chat: to_welcome = True chat = mods_chat message = BOT_WELCOME_MODS.format(user_name) elif update.effective_chat.id == roads_chat: to_welcome = True chat = roads_chat message = BOT_WELCOME_ROADS.format(user_name) elif update.effective_chat.id == english_chat: to_welcome = True chat = english_chat message = BOT_WELCOME_ENG.format(user_name) if to_welcome: bot.send_message(chat, message, reply_to_message_id=update.message.message_id, disable_web_page_preview=True)
def run_job(queue: JobQueue, message: ScheduledMessage, chat_id: int): if message.period == 'daily': insert_job_to_jobs( chat_id, queue.run_daily( create_scheduled_message_callback(chat_id, message), message.start_day.time())) elif message.period == 'monthly': insert_job_to_jobs( chat_id, queue.run_monthly(create_scheduled_message_callback( chat_id, message), message.start_day.time(), message.start_day.date().day, day_is_strict=False)) elif message.period == 'once': insert_job_to_jobs( chat_id, queue.run_once(create_scheduled_message_callback(chat_id, message), message.start_day)) else: raise RuntimeError("Something strange happen")
def _job(self, job_queue: JobQueue) -> None: self.logger.info("Getting issues for default repo.") try: repo = self.repos[self.default_repo] if self.issue_iterator is None: self.issue_iterator = self.repos[self.default_repo].issues( state="all") else: # The GitHubIterator automatically takes care of passing the ETag # which reduces the number of API requests that count towards the rate limit cast(GitHubIterator, self.issue_iterator).refresh(True) for i, gh_issue in enumerate(self.issue_iterator): # Acquire lock so we don't add while a func (like self.search) is iterating over it # We do this for ever single issue instead of before the for-loop, because that # would block self.search during the loop which takes a while with self.issues_lock: self.issues[gh_issue.number] = Issue(gh_issue, repo) # Sleeping a moment after 100 issues to give the API some rest - we're not in a # hurry. The 100 is the max. per page number and as of 2.0.0 what github3.py # uses. sleeping doesn't block the bot, as jobs run in their own thread. # This is outside the lock! (see above commit) if (i + 1) % 100 == 0: self.logger.info("Done with %d issues. Sleeping a moment.", i + 1) time.sleep(10) # Rerun in 20 minutes job_queue.run_once(lambda _: self._job(job_queue), 60 * 20) except GitHubException as exc: if "rate limit" in str(exc): self.logger.warning( "GH API rate limit exceeded. Retrying in 70 minutes.") job_queue.run_once(lambda _: self._job(job_queue), 60 * 70) else: self.logger.exception( "Something went wrong fetching issues. Retrying in 10s.", exc_info=exc) job_queue.run_once(lambda _: self._job(job_queue), 10)
def new_member(bot: Bot, update: Update, job_queue: JobQueue): chat = update.effective_chat user = update.effective_user msg = update.effective_message should_welc, cust_welcome, welc_type = sql.get_welc_pref(chat.id) welc_mutes = sql.welcome_mutes(chat.id) human_checks = sql.get_human_checks(user.id, chat.id) new_members = update.effective_message.new_chat_members for new_mem in new_members: welcome_log = None sent = None should_mute = True welcome_bool = True if should_welc: # Give the owner a special welcome if new_mem.id == OWNER_ID: update.effective_message.reply_text( "Oh, Genos? Let's get this moving.") welcome_log = (f"{html.escape(chat.title)}\n" f"#USER_JOINED\n" f"Bot Owner just joined the chat") # Welcome Devs elif new_mem.id in DEV_USERS: update.effective_message.reply_text( "Whoa! A member of the Penguin Logistics just joined!") # Welcome Sudos elif new_mem.id in SUDO_USERS: update.effective_message.reply_text( "Huh! A S tier just joined! Stay Alert!") # Welcome Support elif new_mem.id in SUPPORT_USERS: update.effective_message.reply_text( "Huh! Someone with a Demon tier level just joined!") # Welcome Whitelisted elif new_mem.id in B_USERS: update.effective_message.reply_text( "Oof! A B tier just joined!") # Welcome B elif new_mem.id in WHITELIST_USERS: update.effective_message.reply_text( "Oof! A Wolf tier just joined!") # Welcome yourself elif new_mem.id == bot.id: update.effective_message.reply_text("Watashi ga kitta!") else: # If welcome message is media, send with appropriate function if welc_type not in (sql.Types.TEXT, sql.Types.BUTTON_TEXT): ENUM_FUNC_MAP[welc_type](chat.id, cust_welcome) continue # else, move on first_name = new_mem.first_name or "PersonWithNoName" # edge case of empty name - occurs for some bugs. if cust_welcome: if cust_welcome == sql.DEFAULT_WELCOME: cust_welcome = random.choice( sql.DEFAULT_WELCOME_MESSAGES).format( first=escape_markdown(first_name)) if new_mem.last_name: fullname = escape_markdown( f"{first_name} {new_mem.last_name}") else: fullname = escape_markdown(first_name) count = chat.get_members_count() mention = mention_markdown(new_mem.id, escape_markdown(first_name)) if new_mem.username: username = "******" + escape_markdown(new_mem.username) else: username = mention valid_format = escape_invalid_curly_brackets( cust_welcome, VALID_WELCOME_FORMATTERS) res = valid_format.format( first=escape_markdown(first_name), last=escape_markdown(new_mem.last_name or first_name), fullname=escape_markdown(fullname), username=username, mention=mention, count=count, chatname=escape_markdown(chat.title), id=new_mem.id) buttons = sql.get_welc_buttons(chat.id) keyb = build_keyboard(buttons) else: res = random.choice(sql.DEFAULT_WELCOME_MESSAGES).format( first=escape_markdown(first_name)) keyb = [] backup_message = random.choice( sql.DEFAULT_WELCOME_MESSAGES).format( first=escape_markdown(first_name)) keyboard = InlineKeyboardMarkup(keyb) else: welcome_bool = False res = None keyboard = None backup_message = None # User exceptions from welcomemutes if is_user_ban_protected(chat, new_mem.id, chat.get_member( new_mem.id)) or human_checks: should_mute = False # Join welcome: soft mute if new_mem.is_bot: should_mute = False if user.id == new_mem.id: if should_mute: if welc_mutes == "soft": bot.restrict_chat_member(chat.id, new_mem.id, can_send_messages=True, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False, until_date=(int(time.time() + 24 * 60 * 60))) if welc_mutes == "strong": welcome_bool = False VERIFIED_USER_WAITLIST.update({ new_mem.id: { "should_welc": should_welc, "status": False, "update": update, "res": res, "keyboard": keyboard, "backup_message": backup_message } }) new_join_mem = f"[{escape_markdown(new_mem.first_name)}](tg://user?id={user.id})" message = msg.reply_text( f"{new_join_mem}, click the button below to prove you're human.\nYou have 160 seconds.", reply_markup=InlineKeyboardMarkup([{ InlineKeyboardButton( text="Yes, I'm human.", callback_data=f"user_join_({new_mem.id})") }]), parse_mode=ParseMode.MARKDOWN) bot.restrict_chat_member(chat.id, new_mem.id, can_send_messages=False, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False) job_queue.run_once(partial(check_not_bot, new_mem, chat.id, message.message_id), 160, name="welcomemute") if welcome_bool: sent = send(update, res, keyboard, backup_message) prev_welc = sql.get_clean_pref(chat.id) if prev_welc: try: bot.delete_message(chat.id, prev_welc) except BadRequest: pass if sent: sql.set_clean_welcome(chat.id, sent.message_id) if welcome_log: return welcome_log return (f"{html.escape(chat.title)}\n" f"#USER_JOINED\n" f"<b>User</b>: {mention_html(user.id, user.first_name)}\n" f"<b>ID</b>: <code>{user.id}</code>") return ""
def init_ptb_contribs(self, job_queue: JobQueue) -> None: job_queue.run_once(lambda _: self._ptbcontrib_job(job_queue), 5)
class JobQueueTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.jq = JobQueue(MockBot('jobqueue_test')) self.jq.start() self.result = 0 self.job_time = 0 def tearDown(self): if self.jq is not None: self.jq.stop() def job1(self, bot, job): self.result += 1 def job2(self, bot, job): raise Exception("Test Error") def job3(self, bot, job): self.result += 1 job.schedule_removal() def job4(self, bot, job): self.result += job.context def job5(self, bot, job): self.job_time = time.time() def test_basic(self): self.jq.put(Job(self.job1, 0.1)) sleep(1.5) self.assertGreaterEqual(self.result, 10) def test_job_with_context(self): self.jq.put(Job(self.job4, 0.1, context=5)) sleep(1.5) self.assertGreaterEqual(self.result, 50) def test_noRepeat(self): self.jq.put(Job(self.job1, 0.1, repeat=False)) sleep(0.5) self.assertEqual(1, self.result) def test_nextT(self): self.jq.put(Job(self.job1, 0.1), next_t=0.5) sleep(0.45) self.assertEqual(0, self.result) sleep(0.1) self.assertEqual(1, self.result) def test_multiple(self): self.jq.put(Job(self.job1, 0.1, repeat=False)) self.jq.put(Job(self.job1, 0.2, repeat=False)) self.jq.put(Job(self.job1, 0.4)) sleep(1) self.assertEqual(4, self.result) def test_disabled(self): j0 = Job(self.job1, 0.1) j1 = Job(self.job1, 0.2) self.jq.put(j0) self.jq.put(Job(self.job1, 0.4)) self.jq.put(j1) j0.enabled = False j1.enabled = False sleep(1) self.assertEqual(2, self.result) def test_schedule_removal(self): j0 = Job(self.job1, 0.1) j1 = Job(self.job1, 0.2) self.jq.put(j0) self.jq.put(Job(self.job1, 0.4)) self.jq.put(j1) j0.schedule_removal() j1.schedule_removal() sleep(1) self.assertEqual(2, self.result) def test_schedule_removal_from_within(self): self.jq.put(Job(self.job1, 0.4)) self.jq.put(Job(self.job3, 0.2)) sleep(1) self.assertEqual(3, self.result) def test_longer_first(self): self.jq.put(Job(self.job1, 0.2, repeat=False)) self.jq.put(Job(self.job1, 0.1, repeat=False)) sleep(0.15) self.assertEqual(1, self.result) def test_error(self): self.jq.put(Job(self.job2, 0.1)) self.jq.put(Job(self.job1, 0.2)) sleep(0.5) self.assertEqual(2, self.result) def test_jobs_tuple(self): self.jq.stop() jobs = tuple(Job(self.job1, t) for t in range(5, 25)) for job in jobs: self.jq.put(job) self.assertTupleEqual(jobs, self.jq.jobs()) def test_inUpdater(self): u = Updater(bot="MockBot") u.job_queue.start() try: u.job_queue.put(Job(self.job1, 0.5)) sleep(0.75) self.assertEqual(1, self.result) u.stop() sleep(2) self.assertEqual(1, self.result) finally: u.stop() def test_time_unit_int(self): # Testing seconds in int delta = 2 expected_time = time.time() + delta self.jq.put(Job(self.job5, delta, repeat=False)) sleep(2.5) self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) def test_time_unit_dt_timedelta(self): # Testing seconds, minutes and hours as datetime.timedelta object # This is sufficient to test that it actually works. interval = datetime.timedelta(seconds=2) expected_time = time.time() + interval.total_seconds() self.jq.put(Job(self.job5, interval, repeat=False)) sleep(2.5) self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) def test_time_unit_dt_datetime(self): # Testing running at a specific datetime delta = datetime.timedelta(seconds=2) next_t = datetime.datetime.now() + delta expected_time = time.time() + delta.total_seconds() self.jq.put(Job(self.job5, repeat=False), next_t=next_t) sleep(2.5) self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) def test_time_unit_dt_time_today(self): # Testing running at a specific time today delta = 2 next_t = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() expected_time = time.time() + delta self.jq.put(Job(self.job5, repeat=False), next_t=next_t) sleep(2.5) self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) def test_time_unit_dt_time_tomorrow(self): # Testing running at a specific time that has passed today. Since we can't wait a day, we # test if the jobs next_t has been calculated correctly delta = -2 next_t = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() expected_time = time.time() + delta + 60 * 60 * 24 self.jq.put(Job(self.job5, repeat=False), next_t=next_t) self.assertAlmostEqual(self.jq.queue.get(False)[0], expected_time, delta=0.1) def test_run_once(self): delta = 2 expected_time = time.time() + delta self.jq.run_once(self.job5, delta) sleep(2.5) self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) def test_run_repeating(self): interval = 0.1 first = 1.5 self.jq.run_repeating(self.job1, interval, first=first) sleep(2.505) self.assertAlmostEqual(self.result, 10, delta=1) def test_run_daily(self): delta = 1 time_of_day = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() expected_time = time.time() + 60 * 60 * 24 + delta self.jq.run_daily(self.job1, time_of_day) sleep(2 * delta) self.assertEqual(self.result, 1) self.assertAlmostEqual(self.jq.queue.get(False)[0], expected_time, delta=0.1)
def init_issues(self, job_queue: JobQueue) -> None: job_queue.run_once(lambda _: self._job(job_queue), 10)
def new_member(bot: Bot, update: Update, job_queue: JobQueue): chat = update.effective_chat user = update.effective_user msg = update.effective_message should_welc, cust_welcome, welc_type = sql.get_welc_pref(chat.id) welc_mutes = sql.welcome_mutes(chat.id) human_checks = sql.get_human_checks(user.id, chat.id) new_members = update.effective_message.new_chat_members for new_mem in new_members: welcome_log = None res = None sent = None should_mute = True welcome_bool = True if should_welc: reply = update.message.message_id cleanserv = sql.clean_service(chat.id) # Clean service welcome if cleanserv: try: dispatcher.bot.delete_message(chat.id, update.message.message_id) except BadRequest: pass reply = False # Give the owner a special welcome if new_mem.id == OWNER_ID: update.effective_message.reply_text( "Oh, Genos? Hadi bunu hareket ettirelim.", reply_to_message_id=reply) welcome_log = (f"{html.escape(chat.title)}\n" f"#USER_JOINED\n" f"Bot Yetkilisi sohbete katıldı") # Welcome Devs elif new_mem.id in DEV_USERS: update.effective_message.reply_text( "Oha! Kahramanlar Derneği üyesi yeni katıldı!", reply_to_message_id=reply) # Welcome Sudos elif new_mem.id in SUDO_USERS: update.effective_message.reply_text( "Huh! Bir Ejderha felaketi daha yeni katıldı! Dikkatli ol!", reply_to_message_id=reply) # Welcome Support elif new_mem.id in SUPPORT_USERS: update.effective_message.reply_text( "Huh! Demon afet düzeyine sahip biri katıldı!", reply_to_message_id=reply) # Welcome Whitelisted elif new_mem.id in TIGER_USERS: update.effective_message.reply_text( "Oof! Bir Tiger felaketi daha yeni katıldı!", reply_to_message_id=reply) # Welcome Tigers elif new_mem.id in WHITELIST_USERS: update.effective_message.reply_text( "Oof! Bir kurt felaketi daha yeni katıldı!", reply_to_message_id=reply) # Welcome yourself elif new_mem.id == bot.id: update.effective_message.reply_text("Watashi ga kita!", reply_to_message_id=reply) else: # If welcome message is media, send with appropriate function if welc_type not in (sql.Types.TEXT, sql.Types.BUTTON_TEXT): ENUM_FUNC_MAP[welc_type](chat.id, cust_welcome) continue # else, move on first_name = new_mem.first_name or "PersonWithNoName" # edge case of empty name - occurs for some bugs. if cust_welcome: if cust_welcome == sql.DEFAULT_WELCOME: cust_welcome = random.choice( sql.DEFAULT_WELCOME_MESSAGES).format( first=escape_markdown(first_name)) if new_mem.last_name: fullname = escape_markdown( f"{first_name} {new_mem.last_name}") else: fullname = escape_markdown(first_name) count = chat.get_members_count() mention = mention_markdown(new_mem.id, escape_markdown(first_name)) if new_mem.username: username = "******" + escape_markdown(new_mem.username) else: username = mention valid_format = escape_invalid_curly_brackets( cust_welcome, VALID_WELCOME_FORMATTERS) res = valid_format.format( first=escape_markdown(first_name), last=escape_markdown(new_mem.last_name or first_name), fullname=escape_markdown(fullname), username=username, mention=mention, count=count, chatname=escape_markdown(chat.title), id=new_mem.id) buttons = sql.get_welc_buttons(chat.id) keyb = build_keyboard(buttons) else: res = random.choice(sql.DEFAULT_WELCOME_MESSAGES).format( first=escape_markdown(first_name)) keyb = [] backup_message = random.choice( sql.DEFAULT_WELCOME_MESSAGES).format( first=escape_markdown(first_name)) keyboard = InlineKeyboardMarkup(keyb) else: welcome_bool = False res = None keyboard = None backup_message = None reply = None # User exceptions from welcomemutes if is_user_ban_protected(chat, new_mem.id, chat.get_member( new_mem.id)) or human_checks: should_mute = False # Join welcome: soft mute if new_mem.is_bot: should_mute = False if user.id == new_mem.id: if should_mute: if welc_mutes == "soft": bot.restrict_chat_member(chat.id, new_mem.id, can_send_messages=True, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False, until_date=(int(time.time() + 24 * 60 * 60))) if welc_mutes == "strong": welcome_bool = False VERIFIED_USER_WAITLIST.update({ new_mem.id: { "should_welc": should_welc, "status": False, "update": update, "res": res, "keyboard": keyboard, "backup_message": backup_message } }) new_join_mem = f"[{escape_markdown(new_mem.first_name)}](tg://user?id={user.id})" message = msg.reply_text( f"{new_join_mem},insan olduğunuzu kanıtlamak için aşağıdaki düğmeyi tıklayın.\n120 saniyeniz var.", reply_markup=InlineKeyboardMarkup([{ InlineKeyboardButton( text="Evet ben insanım.", callback_data=f"user_join_({new_mem.id})") }]), parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply) bot.restrict_chat_member(chat.id, new_mem.id, can_send_messages=False, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False) job_queue.run_once(partial(check_not_bot, new_mem, chat.id, message.message_id), 120, name="welcomemute") if welcome_bool: sent = send(update, res, keyboard, backup_message) prev_welc = sql.get_clean_pref(chat.id) if prev_welc: try: bot.delete_message(chat.id, prev_welc) except BadRequest: pass if sent: sql.set_clean_welcome(chat.id, sent.message_id) if welcome_log: return welcome_log return (f"{html.escape(chat.title)}\n" f"#USER_JOINED\n" f"<b>Kullanıcı</b>: {mention_html(user.id, user.first_name)}\n" f"<b>ID</b>: <code>{user.id}</code>") return ""