Compare commits

..

No commits in common. "master" and "v0.3.2" have entirely different histories.

6 changed files with 16 additions and 49 deletions

View File

@ -9,7 +9,7 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-python@v3 - uses: actions/setup-python@v3
with: with:
python-version: "3.13" python-version: "3.10"
- uses: isort/isort-action@master - uses: isort/isort-action@master
with: with:
sortPaths: "./rss" sortPaths: "./rss"

View File

@ -1,6 +1,6 @@
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0 rev: v4.1.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
exclude_types: [markdown] exclude_types: [markdown]
@ -8,13 +8,13 @@ repos:
- id: check-yaml - id: check-yaml
- id: check-added-large-files - id: check-added-large-files
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 25.1.0 rev: 22.3.0
hooks: hooks:
- id: black - id: black
language_version: python3 language_version: python3
files: ^rss/.*\.pyi?$ files: ^rss/.*\.pyi?$
- repo: https://github.com/PyCQA/isort - repo: https://github.com/PyCQA/isort
rev: 6.0.0 rev: 5.10.1
hooks: hooks:
- id: isort - id: isort
files: ^rss/.*\.pyi?$ files: ^rss/.*\.pyi?$

View File

@ -1,30 +1,2 @@
# rss # rss
A [maubot](https://github.com/maubot/maubot) that posts RSS feed updates to Matrix. A [maubot](https://github.com/maubot/maubot) that posts RSS feed updates to Matrix.
## Usage
Basic commands:
* `!rss subscribe <url>` - Subscribe the current room to a feed.
* `!rss unsubscribe <feed ID>` - Unsubscribe the current room from a feed.
* `!rss subscriptions` - List subscriptions (and feed IDs) in the current room.
* `!rss notice <feed ID> [true/false]` - Set whether the bot should send new
posts as `m.notice` (if false, they're sent as `m.text`).
* `!rss template <feed ID> [new template]` - Change the post template for a
feed in the current room. If the new template is omitted, the bot replies
with the current template.
### Templates
The default template is `New post in $feed_title: [$title]($link)`.
Templates are interpreted as markdown with some simple variable substitution.
The following variables are available:
* `$feed_url` - The URL that was used to subscribe to the feed.
* `$feed_link` - The home page of the feed.
* `$feed_title` - The title of the feed.
* `$feed_subtitle` - The subtitle of the feed.
* `$id` - The unique ID of the entry.
* `$date` - The date of the entry.
* `$title` - The title of the entry.
* `$summary` - The summary/description of the entry.
* `$link` - The link of the entry.

View File

@ -1,6 +1,6 @@
maubot: 0.3.0 maubot: 0.3.0
id: xyz.maubot.rss id: xyz.maubot.rss
version: 0.4.1 version: 0.3.2
license: AGPL-3.0-or-later license: AGPL-3.0-or-later
modules: modules:
- rss - rss

View File

@ -8,4 +8,4 @@ line_length = 99
[tool.black] [tool.black]
line-length = 99 line-length = 99
target-version = ["py310"] target-version = ["py38"]

View File

@ -21,8 +21,6 @@ from string import Template
from time import mktime, time from time import mktime, time
import asyncio import asyncio
import hashlib import hashlib
import html
import io
import aiohttp import aiohttp
import attr import attr
@ -257,9 +255,15 @@ class RSSBot(Plugin):
async def _parse_rss( async def _parse_rss(
cls, feed: Feed, resp: aiohttp.ClientResponse cls, feed: Feed, resp: aiohttp.ClientResponse
) -> tuple[Feed, list[Entry]]: ) -> tuple[Feed, list[Entry]]:
content = await resp.read() try:
content = await resp.text()
except UnicodeDecodeError:
try:
content = await resp.text(encoding="utf-8", errors="ignore")
except UnicodeDecodeError:
content = str(await resp.read())[2:-1]
headers = {"Content-Location": feed.url, **resp.headers, "Content-Encoding": "identity"} headers = {"Content-Location": feed.url, **resp.headers, "Content-Encoding": "identity"}
parsed_data = feedparser.parse(io.BytesIO(content), response_headers=headers) parsed_data = feedparser.parse(content, response_headers=headers)
if parsed_data.bozo: if parsed_data.bozo:
if not isinstance(parsed_data.bozo_exception, feedparser.ThingsNobodyCaresAboutButMe): if not isinstance(parsed_data.bozo_exception, feedparser.ThingsNobodyCaresAboutButMe):
raise parsed_data.bozo_exception raise parsed_data.bozo_exception
@ -275,12 +279,12 @@ class RSSBot(Plugin):
feed_id=feed_id, feed_id=feed_id,
id=( id=(
getattr(entry, "id", None) getattr(entry, "id", None)
or getattr(entry, "link", None)
or hashlib.sha1( or hashlib.sha1(
" ".join( " ".join(
[ [
getattr(entry, "title", ""), getattr(entry, "title", ""),
getattr(entry, "description", ""), getattr(entry, "description", ""),
getattr(entry, "link", ""),
] ]
).encode("utf-8") ).encode("utf-8")
).hexdigest() ).hexdigest()
@ -388,7 +392,7 @@ class RSSBot(Plugin):
help="Change the notification template for a subscription in this room", help="Change the notification template for a subscription in this room",
) )
@command.argument("feed_id", "feed ID", parser=int) @command.argument("feed_id", "feed ID", parser=int)
@command.argument("template", "new template", pass_raw=True, required=False) @command.argument("template", "new template", pass_raw=True)
async def command_template(self, evt: MessageEvent, feed_id: int, template: str) -> None: async def command_template(self, evt: MessageEvent, feed_id: int, template: str) -> None:
if not await self.can_manage(evt): if not await self.can_manage(evt):
return return
@ -396,15 +400,6 @@ class RSSBot(Plugin):
if not sub: if not sub:
await evt.reply("This room is not subscribed to that feed") await evt.reply("This room is not subscribed to that feed")
return return
if not template:
await evt.reply(
'<p>Current template in this room:</p><pre><code language="markdown">'
f"{html.escape(sub.notification_template.template)}"
"</code></pre>",
allow_html=True,
markdown=False,
)
return
await self.dbm.update_template(feed.id, evt.room_id, template) await self.dbm.update_template(feed.id, evt.room_id, template)
sub = Subscription( sub = Subscription(
feed_id=feed.id, feed_id=feed.id,