Skip to content
Snippets Groups Projects
Commit e4960733 authored by Timuçin Boldt's avatar Timuçin Boldt :bike:
Browse files

Merge branch 'main' into 'master'

# Conflicts:
#   base-config.yaml
#   rss/bot.py
#   rss/db.py
parents f93fcb94 b3e9147b
No related branches found
No related tags found
No related merge requests found
......@@ -4,10 +4,18 @@ update_interval: 60
max_backoff: 7200
# The time to sleep between send requests when broadcasting a new feed entry.
# Set to 0 to disable sleep or -1 to run all requests asynchronously at once.
spam_sleep: 2
spam_sleep: 0
# The prefix for all commands
# It has to be prefixed with ! in matrix to be recognised
command_prefix: "rss"
# Users who can bypass room permission checks
admins:
- "@user:example.com"
# standard message template for all subscriptions
notification_template: "New post in $feed_title: [$title]($link)"
# global standard-subscriptions that get silently added at startup
# usage:
#subscription:
# '!roomID:example.com':
# - 'Rss-Feed'
subscriptions:
......@@ -41,6 +41,8 @@ class Config(BaseProxyConfig):
helper.copy("spam_sleep")
helper.copy("command_prefix")
helper.copy("admins")
helper.copy("subscriptions")
helper.copy("notification_template")
class BoolArgument(command.Argument):
......@@ -71,11 +73,25 @@ class RSSBot(Plugin):
async def start(self) -> None:
await super().start()
self.config.load_and_update()
self.db = Database(self.database)
self.db = Database(self.database, self.config)
self.http = self.client.api.session
self.power_level_cache = {}
self.poll_task = asyncio.ensure_future(self.poll_feeds(), loop=self.loop)
async def activate_predefined_subscriptions(self) -> None:
subscriptions = self.config["subscriptions"]
for room_id in subscriptions.keys():
for url in subscriptions[room_id]:
feed = self.db.get_feed_by_url(url)
if feed is None:
try:
info, entries = await self.parse_feed(url=url)
feed = self.db.create_feed(info)
self.db.add_entries(entries, override_feed_id=feed.id)
self.db.subscribe(feed.id, room_id, self.config["admins"][0])
except Exception:
self.log.warning("Can not subscribe room " + room_id + " to " + url + " . Error while parsing feed.")
async def stop(self) -> None:
await super().stop()
self.poll_task.cancel()
......@@ -153,6 +169,7 @@ class RSSBot(Plugin):
self.log.debug("Polling started")
while True:
try:
await self.activate_predefined_subscriptions()
await self._poll_once()
except asyncio.CancelledError:
self.log.debug("Polling stopped")
......@@ -238,6 +255,9 @@ class RSSBot(Plugin):
@classmethod
def _parse_rss_entry(cls, feed_id: int, entry: Any) -> Entry:
content = getattr(entry, "content", "") if hasattr(entry, "content") else getattr(entry, "description", "")
if isinstance(content, list):
content = content[0]["value"]
return Entry(
feed_id=feed_id,
id=(getattr(entry, "id", None) or
......@@ -249,6 +269,7 @@ class RSSBot(Plugin):
title=getattr(entry, "title", ""),
summary=getattr(entry, "description", ""),
link=getattr(entry, "link", ""),
content=content
)
@staticmethod
......
......@@ -24,11 +24,13 @@ from sqlalchemy.engine.base import Engine
from mautrix.types import UserID, RoomID
from mautrix.util.config import BaseProxyConfig
Subscription = NamedTuple("Subscription", feed_id=int, room_id=RoomID, user_id=UserID,
notification_template=Template, send_notice=bool)
Feed = NamedTuple("Feed", id=int, url=str, title=str, subtitle=str, link=str, next_retry=int,
error_count=int, subscriptions=List[Subscription])
Entry = NamedTuple("Entry", feed_id=int, id=str, date=datetime, title=str, summary=str, link=str)
Entry = NamedTuple("Entry", feed_id=int, id=str, date=datetime, title=str, summary=str, content=str, link=str)
class Database:
......@@ -38,8 +40,9 @@ class Database:
entry: Table
version: Table
def __init__(self, db: Engine) -> None:
def __init__(self, db: Engine, config: BaseProxyConfig) -> None:
self.db = db
self.config = config
metadata = MetaData()
self.feed = Table("feed", metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
......@@ -63,6 +66,7 @@ class Database:
Column("date", DateTime, nullable=False),
Column("title", Text, nullable=False),
Column("summary", Text, nullable=False),
Column("content", Text, nullable=False),
Column("link", Text, nullable=False))
self.version = Table("version", metadata,
Column("version", Integer, primary_key=True))
......@@ -98,6 +102,7 @@ class Database:
date DATETIME NOT NULL,
title TEXT NOT NULL,
summary TEXT NOT NULL,
content TEXT NOT NULL,
link TEXT NOT NULL,
PRIMARY KEY (feed_id, id),
FOREIGN KEY(feed_id) REFERENCES feed (id)
......@@ -211,9 +216,14 @@ class Database:
.values(error_count=error_count, next_retry=next_retry))
def subscribe(self, feed_id: int, room_id: RoomID, user_id: UserID) -> None:
notification_template = self.config["notification_template"]
sub, feed = self.get_subscription(feed_id, room_id)
if not (sub and feed):
self.db.execute(self.subscription.insert().values(
feed_id=feed_id, room_id=room_id, user_id=user_id,
notification_template="New post in $feed_title: [$title]($link)"))
feed_id=feed_id, room_id=room_id,
user_id=user_id, notification_template=notification_template))
else:
self.update_template(feed_id, room_id, notification_template)
def unsubscribe(self, feed_id: int, room_id: RoomID) -> None:
tbl = self.subscription
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment