Example #1
0
def _get_new_entries(self, db_feed: RSS, rss_parsed) -> list:
    """
    Grabs new entries from an RSS feed

    :param db_feed: MongoEngine RSS feed object
    :param rss_parsed: parsed & checked RSS feed
    :return: list of new entries
    """
    if len(rss_parsed.entries) == 0:
        return []

    last_entry_link = rss_parsed.entries[0].link

    if last_entry_link == db_feed.last_entry_link:
        return []

    entries = []

    for entry in rss_parsed.entries:
        if entry.link == db_feed.last_entry_link:
            break

        entries.append(entry)

    db_feed.last_entry_link = last_entry_link
    db_feed.save()

    return entries
Example #2
0
def rss_compile(update, context, user, link) -> str:
    """
    Handler: fsm:2.1 -> 3

    :param user: mongoengine User object
    :param link: the extracted entity from the message
    """
    news = utility.parse_url(link)
    language = user.settings.language
    state = user.settings.fsm_state

    # check the source for possible errors, such as bozo and format
    if not utility.check_source(news):
        return txt['CALLBACK']['error_link'][language]

    # check the actual feed, i.e.:
    # stuff like title, subtitle, link and such.
    checked_feed = utility.check_parsed(
        news.feed, config['SCRAPE']['RSS']['req_feed_keys'])

    # implement the checking described above
    if not checked_feed:
        return txt['CALLBACK']['error_feed'][language]

    # all entries must be checked for certain required elements
    # this must strike a fine balance between universality and enough
    # information for a good display of the RSS feed
    checked_all_entries = all([
        utility.check_parsed(x, config['SCRAPE']['RSS']['req_entry_keys'])
        for x in news.entries
    ])

    # implement the checking above
    if not checked_all_entries:
        return txt['CALLBACK']['error_entries'][language]

    # if all the checks have so far been passed, then we create the RSS
    # feed in our database and register it - unless it already exists for the
    # user.
    try:
        db_news = RSS(
            rss_link=link,
            link=news.feed.link,
            title=news.feed.title,
            subtitle=news.feed.get('subtitle', ''),
            summary=news.feed.get('summary', ''),
        )
        db_news.subscribed.append(user.user_id)
        db_news.save()

    # if an identical RSS feed exists instead of saving, we fetch the existing
    except errors.NotUniqueError:
        db_news = RSS.get_rss(rss_link=link)

        if user.user_id in db_news.subscribed:
            return txt['CALLBACK']['repeated_rss'][language]

        db_news.subscribed.append(user.user_id)
        db_news.meta_info.fetched = True
        db_news.save()

    user.subscribed.rss_list.append(db_news.pk)
    user.subscribed.session_list.append(news.feed.title)
    user.save()

    feed_formatted = f"<a href=\"{db_news.link}\">" + \
        f"{utility.escape(db_news.title)}</a>"

    if not len(news.entries) > 0:
        return txt['CALLBACK']['empty_feed'][language]

    db_news.last_entry_link = news.entries[0].link
    db_news.save()

    # because this function is used both in the setup and post-setup, we assign
    # a special 'b' sub-state that the user never takes on, but that contains
    # the buttons required to move on to the next FSM state.
    return txt['FSM'][f'{state}b']['text'][language].format(feed_formatted)