From 94d77a42f45895d925d9259bbc96186471547226 Mon Sep 17 00:00:00 2001 From: mitsuha_s Date: Sat, 11 Jun 2022 22:51:39 +0000 Subject: [PATCH] implement update manager --- .gitignore | 1 + database.py | 10 ++++++++-- rss.py | 6 +++--- update_manager.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 update_manager.py diff --git a/.gitignore b/.gitignore index 4bb55d6..040e37d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Python /.venv +/__pycache__ # Database /*.db \ No newline at end of file diff --git a/database.py b/database.py index 6c74564..234d88e 100644 --- a/database.py +++ b/database.py @@ -1,6 +1,7 @@ import sqlite3 from exceptions import DisplayableException +from rss import FeedItem class Database: @@ -97,6 +98,11 @@ class Database: return 0 return int(row[0]) + def find_feed_subscribers(self, feed_id: int) -> list: + """Return feed subscribers""" + self.cur.execute('SELECT telegram_id FROM users WHERE id IN (SELECT user_id FROM subscriptions WHERE feed_id = ?)', [feed_id]) + return self.cur.fetchall() + def find_feeds(self) -> list: """Get a list of feeds.""" self.cur.execute('SELECT * FROM feeds') @@ -113,10 +119,10 @@ class Database: self.cur.execute('SELECT * FROM feeds_last_items WHERE feed_id = ?', [feed_id]) return self.cur.fetchall() - def update_feed_items(self, feed_id: int, new_items: list) -> None: + def update_feed_items(self, feed_id: int, new_items: list[FeedItem]) -> None: """Replace last feed items with a list items that receive.""" for i in range(len(new_items)): - new_items[i] = (feed_id,) + new_items[i] + new_items[i] = [feed_id] + list(new_items[i].__dict__.values()) self.cur.execute('DELETE FROM feeds_last_items WHERE feed_id = ?', [feed_id]) self.cur.executemany( diff --git a/rss.py b/rss.py index a6b243e..cb76d7c 100644 --- a/rss.py +++ b/rss.py @@ -1,19 +1,19 @@ import feedparser -class FeedItem(): +class FeedItem: def __init__(self, url: str, title: str, description: str, date: str) -> None: self.url = url self.title = title self.description = description self.date = date -class Feed(): +class Feed: def __init__(self, url: str, items: list[FeedItem]) -> None: self.url = url self.items = items -class RssReader(): +class RssReader: def get_feed(self, url: str) -> Feed: f = feedparser.parse(url) items = self.__get_items(f.entries) diff --git a/update_manager.py b/update_manager.py new file mode 100644 index 0000000..3cae06a --- /dev/null +++ b/update_manager.py @@ -0,0 +1,44 @@ +from rss import RssReader, FeedItem +from database import Database +from telegram import Notifier + + +class UpdateManager: + def __init__(self, database: Database, notifier: Notifier, rss_reader: RssReader) -> None: + self.database = database + self.notifier = notifier + self.rss_reader = rss_reader + + def update(self): + feeds = self.database.find_feeds() + + for feed_id, feed_url in feeds: + new_items = self.rss_reader.get_feed(feed_url).items + old_items = self.database.find_feed_items(feed_id) + + diff = self.__calculate_difference(new_items, old_items) + + if not diff: + continue + + chat_ids = self.database.find_feed_subscribers(feed_id) + chat_ids = list(map(lambda x: x[0], chat_ids)) + self.notifier.send_updates(chat_ids, diff) + self.database.update_feed_items(feed_id, new_items) + + def __calculate_difference(self, new_items: list[FeedItem], old_items: list[tuple]) -> list[FeedItem]: + if not old_items: + return new_items + + diff = [] + urls = list(map(lambda x: x[1], old_items)) + + for item in new_items: + if item.url not in urls: + diff.append(item) + + return diff + + + +