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
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)