Exemplo n.º 1
0
def subscribe(update, context):
    chat_id = update.effective_chat.id

    try:
        client.query(
            q.if_(
                q.exists(q.ref(q.collection(users), chat_id)),
                q.update(q.ref(q.collection(users), chat_id),
                         {'data': {
                             'last_command': 'subscribe'
                         }}),
                q.create(
                    q.ref(q.collection(users), chat_id), {
                        'data': {
                            'name': update.message.chat.first_name,
                            'is_admin': False,
                            'last_command': 'subscribe',
                            'animes_watching': [],
                            'config': {
                                'resolution': Resolution.MEDIUM.value
                            }
                        }
                    })))

        context.bot.send_message(
            chat_id=chat_id,
            text='Enter the anime you want to get notifications for!')
    except Exception as err:
        log_error(err)
Exemplo n.º 2
0
def run_cron():
    print('running')

    def check_for_update(context: CallbackContext):
        logger.info("About to run subscription check")
        # get all anime
        all_animes = client.query(
            q.paginate(q.documents(q.collection(animes)), size=100000))

        for anime in all_animes['data']:
            # get anime_info in the function send_update...
            # if there are new episodes...
            send_update_to_subscribed_users(anime.id())

        logger.info("Subscription check finished")

    try:
        # run job every 2 hours
        # this automatically runs in a separate thread so no problem
        job_queue.run_repeating(check_for_update,
                                interval=7200,
                                first=datetime.datetime.now() +
                                datetime.timedelta(seconds=5))
    except Exception as err:
        log_error(err)
Exemplo n.º 3
0
def get_latest(update: Update, context: CallbackContext):
    chat_id = update.effective_chat.id

    try:
        client.query(
            q.if_(
                q.exists(q.ref(q.collection(users), chat_id)),
                q.update(q.ref(q.collection(users), chat_id),
                         {'data': {
                             'last_command': 'getlatest'
                         }}),
                q.create(
                    q.ref(q.collection(users), chat_id), {
                        'data': {
                            'name': update.message.chat.first_name,
                            'last_command': 'getlatest',
                            'animes_watching': [],
                            'config': {
                                'resolution': Resolution.MEDIUM.value
                            }
                        }
                    })))
        context.bot.send_message(chat_id=chat_id,
                                 text='Enter the anime you want to get!')
    except Exception as err:
        log_error(err)
Exemplo n.º 4
0
def unsubscribe(update: Update, context: CallbackContext):
    user = User(update.effective_chat.id)
    try:
        animes_watched = client.query(
            q.let({'bot_user': q.ref(q.collection(users), user.chat_id)},
                  q.if_(
                      q.exists(q.var('bot_user')),
                      q.map_(
                          q.lambda_('doc_ref', q.get(q.var('doc_ref'))),
                          q.select(['data', 'animes_watching'],
                                   q.get(q.var('bot_user')))), [])))

        for anime in animes_watched:
            markup = [[
                InlineKeyboardButton('Unsubscribe',
                                     callback_data='unsubscribe=' +
                                     anime['ref'].id())
            ]]
            context.bot.send_message(chat_id=user.chat_id,
                                     text=anime['data']['title'],
                                     reply_markup=InlineKeyboardMarkup(markup))

        # update last command
        user.last_command = ''

        if not animes_watched:
            context.bot.send_message(
                chat_id=user.chat_id,
                text='You are currently not subscribed to any anime')
    except Exception as err:
        log_error(err)
Exemplo n.º 5
0
    def unsubscribe_from_anime(self, anime_doc_id: str):
        try:
            anime = client.query(
                q.get(q.ref(q.collection(animes), anime_doc_id)))
            client.query(
                q.let(
                    {
                        'anime_ref':
                        q.ref(q.collection(animes), anime_doc_id),
                        'bot_user':
                        q.ref(q.collection(users), self.chat_id),
                        'followers':
                        q.select(['data', 'followers'],
                                 q.get(q.var('anime_ref'))),
                    },
                    q.do(
                        q.update(
                            q.var('anime_ref'), {
                                'data': {
                                    'followers': q.subtract(
                                        q.var('followers'), 1)
                                }
                            }),
                        q.update(
                            q.var('bot_user'), {
                                'data': {
                                    'animes_watching':
                                    q.filter_(
                                        q.lambda_(
                                            'watched_anime_ref',
                                            q.not_(
                                                q.equals(
                                                    q.var('watched_anime_ref'),
                                                    q.var('anime_ref')))),
                                        q.select(['data', 'animes_watching'],
                                                 q.get(q.var('bot_user'))))
                                }
                            }),
                        q.if_(q.equals(q.var('followers'), 1),
                              q.delete(q.var('anime_ref')), 'successful!'))))

            updater.bot.send_message(chat_id=self.chat_id,
                                     text='You have stopped following ' +
                                     anime['data']['title'])
        except errors.NotFound:
            logger.info(
                'Somehow, a user {0} almost unsubscribed from an anime that did not exist'
                .format(self.chat_id))
        except Exception as err:
            log_error(err)
Exemplo n.º 6
0
def donate(update, context):
    try:
        for message in config['message']['donate']:
            context.bot.send_message(chat_id=update.effective_chat.id,
                                     text=message)
        client.query(
            q.let(
                {'user': q.ref(q.collection(users), update.effective_chat.id)},
                q.if_(
                    q.exists(q.var('user')),
                    q.update(q.var('user'), {'data': {
                        'last_command': '',
                    }}), 'Success!')))
    except Exception as err:
        log_error(err)
Exemplo n.º 7
0
def send_broadcast(args):
    print(args)
    try:
        updater.bot.send_message(chat_id=args[0], text=args[1])
    except Unauthorized:
        # user blocked bot so delete user from list
        user = client.query(q.get(q.ref(q.collection(users), args[0])))
        client.query(q.delete(user['ref'], ))
        logger.info("a user has been deleted from user list")
        return ''
    except Exception as err:
        log_error(err)
        return ''
    else:
        return 'success'
Exemplo n.º 8
0
def help_user(update, context):
    user = User(update.effective_chat.id)
    if str(user.chat_id) == str(os.getenv('ADMIN_CHAT_ID')):
        message = config['message']['help_admin']
    else:
        message = config['message']['help']
    context.bot.send_message(chat_id=user.chat_id, text=message)
    try:
        client.query(
            q.let({'user': q.ref(q.collection(users), user.chat_id)},
                  q.if_(
                      q.exists(q.var('user')),
                      q.update(q.var('user'), {'data': {
                          'last_command': '',
                      }}), 'Success!')))
    except Exception as err:
        log_error(err)
Exemplo n.º 9
0
def send_update_to_subscribed_users(anime: Union[Dict[str, Any], str, int],
                                    download_links=None,
                                    anime_info: Dict = None):
    """
    This function sends updates to all users subscribed to a particular anime
    """

    # download_links is a dict of Resolution -> download_link
    if download_links is None:
        download_links = {}
    download_links = download_links
    if isinstance(anime, dict):
        pass
    elif isinstance(anime, str) or isinstance(anime, int):
        anime = client.query(q.get(q.ref(q.collection(animes), str(anime))))

    if anime_info is None:
        anime_info = scraper.get_anime_info(anime['data']['link'])

    # if there is a new episode...
    if anime_info['number_of_episodes'] > anime['data']['episodes']:
        if anime_info['latest_episode_link'] != anime['data']['last_episode'][
                'link']:
            try:
                subscribed_users = get_subscribed_users_for_anime(
                    anime['ref'].id())

                # send message to subscribed users
                for user in subscribed_users:
                    try:
                        # if link for particular resolution has not been scraped yet...
                        user_resolution = Resolution(
                            user['data']['config']['resolution'])
                        if user_resolution not in download_links:
                            download_links[
                                user_resolution] = scraper.get_download_link(
                                    anime_info['latest_episode_link'],
                                    user_resolution)
                        markup = [[
                            InlineKeyboardButton(
                                text='Download',
                                url=download_links[user_resolution])
                        ]]
                        text = "Here's the latest episode for {0}:\n\n{1}".format(
                            anime['data']['title'],
                            anime_info['latest_episode_title'])
                        if anime['data']['anime_id'] == '9914':
                            text = "It's AOT Sunday!!\n\n" + text + "\n\nShinzou Wo Sasageyo!!"

                        updater.bot.send_message(
                            chat_id=int(user['ref'].id()),
                            text=text,
                            reply_markup=InlineKeyboardMarkup(markup))

                    except Unauthorized:
                        # user has blocked bot
                        # delete user from list
                        client.query(q.delete(user['ref']))
                        logger.info("A user has been deleted from user list")
                # send message to admin
                updater.bot.send_message(
                    chat_id=os.getenv('ADMIN_CHAT_ID'),
                    text=anime['data']['title'] +
                    ' just got a new episode and was updated!')
                logger.info(
                    str(len(subscribed_users)) +
                    " users were notified of an update to " +
                    anime['data']['title'])

            except CannotDownloadAnimeException as err:
                log_error(err)
                subscribed_users = get_subscribed_users_for_anime(
                    anime['ref'].id())

                # tell subscribed user episode is available but can't download
                for user in subscribed_users:
                    text = "A new episode for {0}: {1} is now out.\nSadly, I could not download it\U0001F622".format(
                        anime['data']['title'],
                        anime_info['latest_episode_title'])
                    updater.bot.send_message(chat_id=int(user['ref'].id()),
                                             text=text)
                # send message to admin
                updater.bot.send_message(chat_id=os.getenv('ADMIN_CHAT_ID'),
                                         text=anime['data']['title'] +
                                         ' just got a new '
                                         'episode but could '
                                         'not be downloaded')

            finally:
                # update anime in db after sending messages to users
                client.query(
                    q.update(
                        anime['ref'], {
                            'data': {
                                'episodes': anime_info['number_of_episodes'],
                                'last_episode': {
                                    'title':
                                    anime_info['latest_episode_title'],
                                    'link': anime_info['latest_episode_link']
                                }
                            }
                        }))

        else:
            pass
    else:
        pass
Exemplo n.º 10
0
def callback_handler_func(update: Update, context: CallbackContext):
    user = User(update.effective_chat.id)
    callback_message = update.callback_query.message.reply_markup.inline_keyboard[
        0][0].callback_data

    [command, payload] = callback_message.split(sep='=')

    if command == 'subscribe':
        user.subscribe_to_anime(payload)
    elif command == 'unsubscribe':
        user.unsubscribe_from_anime(payload)
    elif command == 'getlatest':
        try:
            anime_info = scraper.get_anime_info(payload)

            latest_episode_download_link = shorten(
                scraper.get_download_link(anime_info['latest_episode_link'],
                                          resolution=user.resolution))
            markup = [[
                InlineKeyboardButton(text='Download',
                                     url=latest_episode_download_link)
            ]]
            context.bot.send_message(chat_id=user.chat_id,
                                     text=anime_info['latest_episode_title'],
                                     reply_markup=InlineKeyboardMarkup(markup))
        except CannotDownloadAnimeException as err:
            log_error(err)
            context.bot.send_message(chat_id=user.chat_id,
                                     text="Sorry," + payload +
                                     "could not be downloaded at this "
                                     "time!")
            context.bot.send_message(chat_id=os.getenv('ADMIN_CHAT_ID'),
                                     text='A user tried to download ' +
                                     payload + "but could not due to error: " +
                                     str(err))
            return
        except Exception as err:
            log_error(err)
            return
        else:
            # check if anime is in our anime registry
            try:
                anime_from_db = client.query(
                    q.if_(
                        q.exists(
                            q.match(q.index(anime_by_id),
                                    anime_info['anime_id'])),
                        q.let(
                            {
                                'anime':
                                q.get(
                                    q.match(q.index(anime_by_id),
                                            anime_info['anime_id']))
                            },
                            q.if_(
                                q.gt(
                                    anime_info['number_of_episodes'],
                                    q.select(['data', 'episodes'],
                                             q.var('anime'))), q.var('anime'),
                                None)), None))
            except errors.NotFound:
                anime_from_db = None
            if anime_from_db is not None:
                send_update_to_subscribed_users(
                    anime_from_db,
                    download_links={
                        user.resolution: latest_episode_download_link
                    },
                    anime_info=anime_info)
    elif command == 'set_resolution':
        try:
            new_res = Resolution(payload)
            user.resolution = new_res
            context.bot.send_message(
                chat_id=user.chat_id,
                text=
                f'Your desired resolution has been set to {new_res.value}({resolutions[new_res]}).\nThis resolution will be used for your future /subscribe and /latest commands.'
            )
        except ValueError:
            context.bot.send_message(chat_id=user.chat_id,
                                     text='Unidentified resolution level!')
            context.bot.send_message(chat_id=os.getenv('ADMIN_CHAT_ID'),
                                     text='Unidentified resolution level!')
    else:
        pass
Exemplo n.º 11
0
def plain_message(update: Update, context: CallbackContext):
    print(update.effective_message)
    try:
        bot_user = client.query(
            q.get(q.ref(q.collection('users'), update.effective_chat.id)))
    except errors.NotFound:
        context.bot.send_message(
            chat_id=update.effective_chat.id,
            text=
            'Sorry, I do not understand what you mean.\nPlease use the /help command to '
            'discover what I can help you with.')
        return
    user = User(update.effective_chat.id)
    last_command = bot_user['data']['last_command']
    message = update.message.text

    print(last_command)

    if last_command == 'subscribe':
        try:
            search_results = scraper.get_anime(message, limit=15)
            if len(search_results) == 0:
                context.bot.send_message(
                    chat_id=user.chat_id,
                    text=
                    'Sorry but no search results were available for this anime'
                )
            else:
                context.bot.send_message(
                    chat_id=user.chat_id,
                    text='Here are the search results for ' + message)
                for result in search_results:
                    markup = [[
                        InlineKeyboardButton('Select',
                                             callback_data='subscribe=' +
                                             shorten(result['link']))
                    ]]
                    context.bot.send_photo(
                        chat_id=user.chat_id,
                        photo=result['thumbnail'],
                        caption=result['title'],
                        timeout=5,
                        reply_markup=InlineKeyboardMarkup(markup))

            # update last command
            user.last_command = ''

        except Exception as err:
            log_error(err)

    elif last_command == 'getlatest':
        try:
            search_results = scraper.get_anime(message, limit=15)

            if len(search_results) == 0:
                context.bot.send_message(
                    chat_id=user.chat_id,
                    text=
                    'Sorry but no search results were available for this anime'
                )
            else:
                context.bot.send_message(
                    chat_id=user.chat_id,
                    text='Here are the search results for ' + message)
                for result in search_results:
                    markup = [[
                        InlineKeyboardButton('Select',
                                             callback_data='getlatest=' +
                                             shorten(result['link']))
                    ]]
                    context.bot.send_photo(
                        chat_id=user.chat_id,
                        photo=result['thumbnail'],
                        caption=result['title'],
                        timeout=5,
                        reply_markup=InlineKeyboardMarkup(markup))
                    # update last command
            user.last_command = ''
        except Exception as err:
            log_error(err)

    elif last_command == 'broadcast':
        if user.is_admin():
            context.bot.send_message(chat_id=user.chat_id,
                                     text='Broadcasting message...')
            try:
                results = client.query(
                    q.paginate(q.documents(q.collection(users)), size=100000))
                results = results['data']

                # spin 5 processes
                with Pool(5) as p:
                    res = p.map(send_broadcast, [[int(user_ref.id()), message]
                                                 for user_ref in results])
                    successful_broadcast = []
                    for i in res:
                        if i == 'success':
                            successful_broadcast.append(i)
                    logger.info('Message broadcast to ' +
                                str(len(successful_broadcast)) + ' users')
                    print(res)
                # update user last command
                user.last_command = ''
            except Exception as err:
                log_error(err)
        else:
            context.bot.send_message(chat_id=user.chat_id,
                                     text="Only admins can use this command!")
    else:
        context.bot.send_message(
            chat_id=user.chat_id,
            text=
            "Sorry, I do not understand what you mean.\nPlease use the /help command to "
            "discover what I can help you with.")
Exemplo n.º 12
0
def error_handler(update: Update, context: CallbackContext):
    try:
        raise context.error
    except BadRequest as err:
        # handle malformed requests
        log_error(err)
    except TimedOut as err:
        # handle slow connection problems
        log_error(err)
    except NetworkError as err:
        # handle other connection problems
        log_error(err)
    except ChatMigrated as err:
        # the chat_id of a group has changed, use e.new_chat_id instead
        log_error(err)
    except TelegramError as err:
        # handle all other telegram related errors
        log_error(err)
    except Exception as err:
        log_error(err)
Exemplo n.º 13
0
    def subscribe_to_anime(self, anime_link: str):
        try:
            # create a new anime document
            anime_info = anime_alarm.utils.GGAScraper().get_anime_info(
                anime_link)

            print(anime_info['anime_id'])

            result = client.query(
                q.let(
                    {
                        'user_anime_list':
                        q.select(['data', 'animes_watching'],
                                 q.get(q.ref(q.collection(users),
                                             self.chat_id))),
                    },
                    q.if_(
                        # check if this anime exists in the db
                        q.exists(
                            q.match(q.index(anime_by_id),
                                    anime_info['anime_id'])),

                        # if it exists...
                        q.let(
                            {
                                'anime_ref':
                                q.select(
                                    'ref',
                                    q.get(
                                        q.match(q.index(anime_by_id),
                                                anime_info['anime_id'])))
                            },
                            q.if_(
                                # check if user has subscribed to this anime already
                                q.contains_value(q.var('anime_ref'),
                                                 q.var('user_anime_list')),
                                'This anime is already on your watch list!',
                                q.do(
                                    q.update(
                                        q.ref(q.collection(users),
                                              self.chat_id),
                                        {
                                            'data': {
                                                'animes_watching':
                                                q.append(
                                                    q.var('user_anime_list'),
                                                    [q.var('anime_ref')])
                                            }
                                        }),
                                    q.update(
                                        q.var('anime_ref'), {
                                            'data': {
                                                'followers':
                                                q.add(
                                                    q.select([
                                                        'data', 'followers'
                                                    ], q.get(
                                                        q.var('anime_ref'))),
                                                    1)
                                            }
                                        }),
                                ))),
                        q.let(
                            {'new_anime_id': q.new_id()},
                            q.do(
                                # create new anime document
                                q.create(
                                    q.ref(q.collection(animes),
                                          q.var('new_anime_id')),
                                    {
                                        'data': {
                                            'title':
                                            anime_info['title'],
                                            'followers':
                                            1,
                                            'link':
                                            anime_link,
                                            'anime_id':
                                            anime_info['anime_id'],
                                            'anime_alias':
                                            anime_info['anime_alias'],
                                            'episodes':
                                            anime_info['number_of_episodes'],
                                            'last_episode': {
                                                'link':
                                                anime_info[
                                                    'latest_episode_link'],
                                                'title':
                                                anime_info[
                                                    'latest_episode_title'],
                                            },
                                        }
                                    }),
                                # add to user's list of subscribed animes
                                q.update(
                                    q.ref(q.collection(users), self.chat_id), {
                                        'data': {
                                            'animes_watching':
                                            q.append(
                                                q.var('user_anime_list'), [
                                                    q.ref(
                                                        q.collection(animes),
                                                        q.var('new_anime_id'))
                                                ])
                                        }
                                    }),
                            )))))

            if isinstance(result, str):
                updater.bot.send_message(chat_id=self.chat_id, text=result)
            else:
                updater.bot.send_message(
                    chat_id=self.chat_id,
                    text='You are now listening for updates on ' +
                    anime_info['title'])
        except Exception as err:
            log_error(err)