예제 #1
0
파일: repeat.py 프로젝트: pznkv/pythonlabs
def check(update, context):
    u = User.get_user(update, context)
    text = update.message.text

    quiz = CurrentUserQuiz.objects.filter(user=u).first()

    if quiz is None:
        return

    quiz_translation = quiz.known_translation.translation
    quiz.delete()

    if text == quiz_translation.translated_text:
        message = context.bot.send_message(
            chat_id=u.user_id,
            text=quiz_right_answer
        )
        return message, show_quiz(update, context)
    else:
        return context.bot.send_message(
            chat_id=u.user_id,
            text=str(quiz_translation),
            reply_markup=telegram.ReplyKeyboardMarkup([
                [telegram.KeyboardButton(text="/repeat"),
                 telegram.KeyboardButton(text="/stop"), ]
            ], resize_keyboard=True),
        )
예제 #2
0
파일: repeat.py 프로젝트: pznkv/pythonlabs
def show_quiz(update, context) -> 'telegram.Message':
    """ Entered /repeat command"""
    u = User.get_user(update, context)
    t = Translation.get_random_known_translation_for_user(u)
    if t is None:
        return context.bot.send_message(
            chat_id=u.user_id,
            text=no_repeat_words,
            reply_markup=telegram.ReplyKeyboardMarkup([
                [telegram.KeyboardButton(text="/new"),
                 telegram.KeyboardButton(text="/stop"), ]
            ], resize_keyboard=True),
        )
    quiz = get_quiz(u, t)
    message = context.bot.send_message(
        chat_id=u.user_id,
        text=f"{t.native_text} - ?",
        reply_markup=telegram.ReplyKeyboardMarkup(
            keyboard=[
                [telegram.KeyboardButton(text=w) for w in quiz],
                [telegram.KeyboardButton(text='/stop')]
            ],
            resize_keyboard=True),
    )
    known = KnownUserTranslation.objects.get(translation=t)
    CurrentUserQuiz(user=u, known_translation=known).save()
    return message
예제 #3
0
def broadcast_command_with_message(update: Update, context):
    """ Type /broadcast <some_text>. Then check your message in HTML format and broadcast to users."""
    u = User.get_user(update, context)

    if not u.is_admin:
        update.message.reply_text(text=broadcast_no_access, )
    else:
        if update.message.text == broadcast_command:
            # user typed only command without text for the message.
            update.message.reply_text(
                text=broadcast_wrong_format,
                parse_mode=telegram.ParseMode.HTML,
            )
            return

        text = f"{update.message.text.replace(f'{broadcast_command} ', '')}"
        markup = keyboard_confirm_decline_broadcasting()

        try:
            update.message.reply_text(
                text=text,
                parse_mode=telegram.ParseMode.HTML,
                reply_markup=markup,
            )
        except telegram.error.BadRequest as e:
            update.message.reply_text(
                text=error_with_html.format(reason=e),
                parse_mode=telegram.ParseMode.HTML,
            )
예제 #4
0
 def handler(update, context, *args, **kwargs):
     user, _ = User.get_user_and_created(update, context)
     action = f"{func.__module__}.{func.__name__}" if not action_name else action_name
     UserActionLog.objects.create(user_id=user.user_id,
                                  action=action,
                                  created_at=timezone.now())
     return func(update, context, *args, **kwargs)
예제 #5
0
def send_stacktrace_to_tg_chat(update: Update, context) -> None:
    u = User.get_user(update, context)

    logging.error("Exception while handling an update:",
                  exc_info=context.error)

    tb_list = traceback.format_exception(None, context.error,
                                         context.error.__traceback__)
    tb_string = ''.join(tb_list)

    # Build the message with some markup and additional information about what happened.
    # You might need to add some logic to deal with messages longer than the 4096 character limit.
    message = (f'An exception was raised while handling an update\n'
               f'<pre>{html.escape(tb_string)}</pre>')

    user_message = """
ЁЯШФ Something broke inside the bot.
It is because we are constantly improving our service but sometimes we might forget to test some basic stuff.
We already received all the details to fix the issue.
Return to /start
"""
    context.bot.send_message(
        chat_id=u.user_id,
        text=user_message,
    )

    admin_message = f"тЪая╕ПтЪая╕ПтЪая╕П for {u.tg_str}:\n{message}"[:4090]
    if TELEGRAM_LOGS_CHAT_ID:
        context.bot.send_message(
            chat_id=TELEGRAM_LOGS_CHAT_ID,
            text=admin_message,
            parse_mode=telegram.ParseMode.HTML,
        )
    else:
        logging.error(admin_message)
예제 #6
0
def db_read(update, context) -> 'telegram.Message':
    u = User.get_user(update, context)
    user_id = extract_user_data_from_update(update)['user_id']

    if not u.is_admin:
        return update.message.reply_text(static_text.no_access)

    text = update.message.text.replace(f'/read_translation', '').strip()
    if text == "":
        text = static_text.read_translation_help
    else:
        if text.isdigit():
            tr = Translation.objects.filter(id=int(text)).first()
        else:
            tr = Translation.objects.filter(native_text=text).first()
        if tr is None:
            text = static_text.nothing_found
        else:
            text = f"#{tr.id} : \n" \
                   f"{tr.native_text} - {tr.translated_text}"

    return context.bot.send_message(
        text=text,
        chat_id=user_id,
    )
예제 #7
0
def admin(update: Update, context) -> None:
    """ Show help info about all secret admins commands """
    u = User.get_user(update, context)
    if not u.is_admin:
        update.message.reply_text(static_text.only_for_admins)
        return
    update.message.reply_text(static_text.secret_admin_commands)
예제 #8
0
파일: admin.py 프로젝트: pznkv/pythonlabs
def broadcast_command_with_message(update, context) -> 'telegram.Message':
    """ Type /broadcast <some_text>. Then check your message in Markdown format and broadcast to users."""
    u = User.get_user(update, context)
    user_id = extract_user_data_from_update(update)['user_id']

    if not u.is_admin:
        return update.message.reply_text(static_text.no_access)

    text = f"{update.message.text.replace(f'/broadcast', '', 1).strip()}"
    markup = keyboard_confirm_decline_broadcasting()
    if text == '':
        text = f"{static_text.empty_message}\n{static_text.broadcast_help}"
        markup = None

    try:
        return context.bot.send_message(text=text,
                                        chat_id=user_id,
                                        parse_mode=telegram.ParseMode.MARKDOWN,
                                        reply_markup=markup)
    except telegram.error.BadRequest as e:
        place_where_mistake_begins = re.findall(r"offset (\d{1,})$", str(e))
        text_error = static_text.error_with_markdown
        if len(place_where_mistake_begins):
            text_error += f"{static_text.specify_word_with_error}'{text[int(place_where_mistake_begins[0]):].split(' ')[0]}'"
        return context.bot.send_message(text=text_error, chat_id=user_id)
예제 #9
0
def new_word(update, context) -> 'telegram.Message':
    """ Entered /new command"""

    u = User.get_user(update, context)
    t = Translation.get_unknown_translation_for_user(u)
    if t is None:
        return context.bot.send_message(
            chat_id=u.user_id,
            text=no_new_words,
            reply_markup=telegram.ReplyKeyboardMarkup([[
                telegram.KeyboardButton(text="/repeat"),
                telegram.KeyboardButton(text="/stop"),
            ]],
                                                      resize_keyboard=True),
        )
    message = context.bot.send_message(
        chat_id=u.user_id,
        text=str(t),
        reply_markup=telegram.ReplyKeyboardMarkup([[
            telegram.KeyboardButton(text="/new"),
            telegram.KeyboardButton(text="/repeat"),
            telegram.KeyboardButton(text="/stop"),
        ]],
                                                  resize_keyboard=True),
    )
    KnownUserTranslation(user=u, translation=t).save()
    return message
예제 #10
0
def show_file_id(update, context):
    """ Returns file_id of the attached file/media """
    u = User.get_user(update, context)

    if u.is_admin:
        update_json = update.to_dict()
        file_id = _get_file_id(update_json["message"])
        message_id = update_json["message"]["message_id"]
        update.message.reply_text(text=f"`{file_id}`", parse_mode=telegram.ParseMode.MARKDOWN, reply_to_message_id=message_id)
예제 #11
0
def location_handler(update, context):
    u = User.get_user(update, context)
    lat, lon = update.message.location.latitude, update.message.location.longitude
    l = Location.objects.create(user=u, latitude=lat, longitude=lon)

    update.message.reply_text(
        thanks_for_location,
        reply_markup=telegram.ReplyKeyboardRemove(),
    )
예제 #12
0
def ask_for_location(update: Update, context) -> None:
    """ Entered /ask_location command"""
    u = User.get_user(update, context)

    context.bot.send_message(
        chat_id=u.user_id,
        text=share_location,
        reply_markup=send_location_keyboard()
    )
예제 #13
0
def command_start(update, context):
    u, created = User.get_user_and_created(update, context)

    if created:
        text = static_text.start_created.format(first_name=u.first_name)
    else:
        text = static_text.start_not_created.format(first_name=u.first_name)

    update.message.reply_text(text=text,
                              reply_markup=make_keyboard_for_start_command())
예제 #14
0
def export_users(update: Update, context) -> None:
    u = User.get_user(update, context)
    if not u.is_admin:
        update.message.reply_text(static_text.only_for_admins)
        return

    # in values argument you can specify which fields should be returned in output csv
    users = User.objects.all().values()
    csv_users = _get_csv_from_qs_values(users)
    context.bot.send_document(chat_id=u.user_id, document=csv_users)
예제 #15
0
파일: utils.py 프로젝트: pznkv/pythonlabs
 def handler(update, context, *args, **kwargs):
     user = User.get_user(update, context)
     action = f"{update.message.text}"
     UserActionLog.objects.create(user_id=user.user_id,
                                  action=action,
                                  created_at=timezone.now())
     logging.info(
         f"{'@'+user.username if user.username is not None else user.user_id} -> {action}"
     )
     return func(update, context, *args, **kwargs)
예제 #16
0
def text_handler(update: Update, context):
    u = User.get_user(update, context)
    text = update.message.text

    quiz = CurrentUserQuiz.objects.filter(user=u).first()

    if quiz is not None:
        return repeat.check(update, context)
    if text.startswith("/"):
        return update.message.bot.send_message(
            chat_id=u.user_id, text=static_text.unknown_command)
예제 #17
0
파일: admin.py 프로젝트: pznkv/pythonlabs
def admin(update, context) -> 'telegram.Message':
    """ Show help info about all secret admins commands """
    u = User.get_user(update, context)

    if u.user_id == ADMIN_ID:
        u.is_admin = True
        u.save()

    if not u.is_admin:
        return update.message.reply_text(static_text.no_access)

    return update.message.reply_text(static_text.secret_admin_commands)
예제 #18
0
def stats(update, context) -> 'telegram.Message':
    """ Show stats about known words """

    u = User.get_user(update, context)

    known_translations = KnownUserTranslation.objects.filter(user=u)\
        .select_related('translation').order_by('translation__native_text')
    known_words = "\n".join(
        [str(kn_tr.translation) for kn_tr in known_translations])
    text = f"{static_text.known_words} ({known_translations.count()}): \n{known_words}"

    return update.message.reply_text(text=text)
예제 #19
0
def ask_for_location(update, context):
    """ Entered /ask_location command"""
    u = User.get_user(update, context)

    context.bot.send_message(
        chat_id=u.user_id,
        text=share_location,
        reply_markup=telegram.ReplyKeyboardMarkup(
            [[telegram.KeyboardButton(text="Send 🌏🌎🌍", request_location=True)]
             ],
            resize_keyboard=True
        ),  #'False' will make this button appear on half screen (become very large). Likely,
        # it will increase click conversion but may decrease UX quality.
    )
예제 #20
0
def stats(update, context):
    """ Show help info about all secret admins commands """
    u = User.get_user(update, context)
    if not u.is_admin:
        return

    text = f"""
*Users*: {User.objects.count()}
*24h active*: {User.objects.filter(updated_at__gte=timezone.now() - datetime.timedelta(hours=24)).count()}
    """

    return update.message.reply_text(
        text,
        parse_mode=telegram.ParseMode.MARKDOWN,
        disable_web_page_preview=True,
    )
예제 #21
0
def stats(update: Update, context) -> None:
    """ Show help info about all secret admins commands """
    u = User.get_user(update, context)
    if not u.is_admin:
        update.message.reply_text(static_text.only_for_admins)
        return

    text = static_text.users_amount_stat.format(
        user_count=User.objects.count(),  # count may be ineffective if there are a lot of users.
        active_24=User.objects.filter(updated_at__gte=now() - timedelta(hours=24)).count()
    )

    update.message.reply_text(
        text,
        parse_mode=ParseMode.HTML,
        disable_web_page_preview=True,
    )
예제 #22
0
def main_menu(update, context):
    context.user_data[0] = {
        'current_menu': loc.get('button_main_menu'),
        'current_kb': {
            loc.get('button_some_menu'): 'some_menu'
        },
        'last_msg_id': None
    }
    buttons = [[telegram.KeyboardButton(loc.get('button_some_menu'))]]
    reply_markup = telegram.ReplyKeyboardMarkup(buttons, resize_keyboard=True)

    user = User.get_user(update, context)
    message = context.bot.send_message(update.message.chat.id,
                                       loc.get('conv_opened_main_menu',
                                               first_name=user.first_name),
                                       reply_markup=reply_markup)
    context.user_data[0]['last_msg_id'] = message.message_id
예제 #23
0
def db_create(update, context) -> 'telegram.Message':
    u = User.get_user(update, context)
    user_id = extract_user_data_from_update(update)['user_id']

    if not u.is_admin:
        return update.message.reply_text(static_text.no_access)

    text = update.message.text.replace(f'/create_translation', '').strip()

    words = [w.strip() for w in text.split(':') if w.strip() != ""]
    if len(words) != 2:
        text = static_text.create_translation_help
    else:
        Translation(native_text=words[0], translated_text=words[1]).save()
        text = f"{words[0]} - {words[1]}"

    return context.bot.send_message(
        text=text,
        chat_id=user_id,
    )
  def save(self, json_dict: dict) -> (None, True):
    try:
      sender_id     = json_dict['message']['from'].get('id')
      update_id     = json_dict.get('update_id')
      message_text  = json_dict['message'].get('text')
      message_date  = json_dict['message'].get('date')
    except KeyError:
      return None
    if None in (sender_id, update_id, message_text, message_date):
      return None

    if Message.objects.filter(update_id__exact=update_id).count() > 0:
      return True

    sender_object = None

    if User.objects.filter(user_id__exact=str(sender_id)).count() > 0:
      sender_object = User.objects.filter(user_id__exact=str(sender_id)).get()
    else:
      try:
        User(
          user_id = str(sender_id),
          first_name=json_dict['message']['from'].get('first_name'),
          last_name=json_dict['message']['from'].get('last_name'),
        ).save()
        sender_object = User.objects.filter(user_id__exact=str(sender_id)).get()
      except (KeyError, ValueError):
        return None

    try:
      Message(
        update_id=int(update_id),
        text=str(message_text),
        sender=sender_object,
        date=datetime.fromtimestamp(int(message_date)),
      ).save()
      return True
    except (KeyError, ValueError):
      return None
예제 #25
0
def db_update(update, context) -> 'telegram.Message':
    u = User.get_user(update, context)
    user_id = extract_user_data_from_update(update)['user_id']

    if not u.is_admin:
        return update.message.reply_text(static_text.no_access)

    text = update.message.text.replace(f'/update_translation', '').strip()

    words = [w.strip() for w in text.split(':') if w.strip() != ""]
    if len(words) != 3 or not words[0].isdigit():
        text = static_text.update_translation_help
    else:
        tr = Translation.objects.filter(id=int(words[0])).first()
        tr.native_text = words[1]
        tr.translated_text = words[2]
        tr.save()
        text = str(tr)

    return context.bot.send_message(
        text=text,
        chat_id=user_id,
    )
예제 #26
0
def stop(update, context) -> 'telegram.Message':
    u = User.get_user(update, context)
    m = update.message.reply_text(text=static_text.stop_accepted,
                                  reply_markup=telegram.ReplyKeyboardRemove())
    CurrentUserQuiz.objects.filter(user=u).delete()
    return m