Skip to content

Commit

Permalink
Allow adding RSS feed paths to default to the URL
Browse files Browse the repository at this point in the history
  • Loading branch information
rmartin16 committed Feb 25, 2024
1 parent a54c5bc commit 42bb8ae
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 39 deletions.
7 changes: 4 additions & 3 deletions src/qbittorrentapi/rss.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def rss_add_folder(
def rss_add_feed(
self,
url: str | None = None,
item_path: str | None = None,
item_path: str = "",
**kwargs: APIKwargsT,
) -> None:
"""
Expand All @@ -73,7 +73,8 @@ def rss_add_feed(
:raises Conflict409Error:
:param url: URL of RSS feed (e.g. https://distrowatch.com/news/torrents.xml)
:param item_path: Name and/or path for new feed (e.g. ``Folder\\Subfolder\\FeedName``)
:param item_path: Name and/or path for new feed; defaults to the URL.
(e.g. ``Folder\\Subfolder\\FeedName``)
""" # noqa: E501
data = {"path": item_path, "url": url}
self._post(_name=APINames.RSS, _method="addFeed", data=data, **kwargs)
Expand Down Expand Up @@ -344,7 +345,7 @@ def add_folder(
def add_feed(
self,
url: str | None = None,
item_path: str | None = None,
item_path: str = "",
**kwargs: APIKwargsT,
) -> None:
return self._client.rss_add_feed(url=url, item_path=item_path, **kwargs)
Expand Down
86 changes: 50 additions & 36 deletions tests/test_rss.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,56 @@
import pytest
from qbittorrentapi import APINames
from qbittorrentapi._version_support import v
from qbittorrentapi.exceptions import APIError
from qbittorrentapi.exceptions import APIError, Conflict409Error
from qbittorrentapi.rss import RSSitemsDictionary

from tests.utils import check
from tests.utils import check, retry

FOLDER_ONE = "testFolderOne"
FOLDER_TWO = "testFolderTwo"

ITEM_ONE = "RSSOne"
ITEM_TWO = "RSSTwo"
RSS_NAME = "DistroWatch - Torrents"
RSS_URL = (
"https://gist.githubusercontent.com/rmartin16/"
"d615e1066f54186b44e8018d31af18f1/raw/b59cdc878fedfaf08efe6fc4321d18e8ded01e09/rss.xml"
)


@retry(3)
def delete_feed(client, name):
with suppress(Conflict409Error):
client.rss_remove_item(item_path=name)
check(lambda: client.rss_items(), name, reverse=True, negate=True)


@pytest.fixture(scope="function", autouse=True)
def rss_feed(client, api_version):
def delete_feed(name):
try:
client.rss_remove_item(item_path=name)
check(lambda: client.rss_items(), name, reverse=True, negate=True)
except Exception:
pass

if v(api_version) >= v("2.2"):
client.app.preferences = dict(rss_auto_downloading_enabled=False)
# refreshing the feed is finicky...so try several times if necessary
done = False
for i in range(5):
delete_feed(ITEM_ONE)
client.rss.add_feed(url=RSS_URL, item_path=ITEM_ONE)
check(lambda: client.rss_items(), ITEM_ONE, reverse=True)
# wait until feed is refreshed
for j in range(20):
if client.rss.items.with_data[ITEM_ONE]["articles"]:
done = True
yield ITEM_ONE
delete_feed(ITEM_ONE)
try:
client.app.preferences = dict(rss_auto_downloading_enabled=False)
# refreshing the feed is finicky...so try several times if necessary
done = False
for i in range(5):
delete_feed(client, ITEM_ONE)
delete_feed(client, RSS_NAME)
client.rss.add_feed(url=RSS_URL, item_path=ITEM_ONE)
check(lambda: client.rss_items(), ITEM_ONE, reverse=True)
# wait until feed is refreshed
for j in range(20):
if client.rss.items.with_data[ITEM_ONE]["articles"]:
done = True
yield ITEM_ONE
break
sleep(0.25)
if done:
break
sleep(0.25)
if done:
break
else:
raise Exception("RSS Feed '%s' did not refresh..." % ITEM_ONE)
else:
raise Exception("RSS Feed '%s' did not refresh..." % ITEM_ONE)
finally:
delete_feed(client, ITEM_ONE)
delete_feed(client, RSS_NAME)
else:
yield ""

Expand Down Expand Up @@ -120,9 +125,23 @@ def test_rss_items(client, rss_feed, items_func):


@pytest.mark.skipif_before_api_version("2.2")
@pytest.mark.parametrize("items_func", ["rss_items", "rss.items"])
def test_rss_add_feed(client, rss_feed, items_func):
assert rss_feed in client.func(items_func)()
@pytest.mark.parametrize(
"add_feed_func", ["rss_add_feed", "rss_addFeed", "rss.add_feed", "rss.addFeed"]
)
@pytest.mark.parametrize("feed_url, path", [(RSS_URL, "/path/my-feed"), (RSS_URL, "")])
def test_rss_add_feed(client, add_feed_func, feed_url, path):
@retry(3)
def run_test():
delete_feed(client, ITEM_ONE)
delete_feed(client, RSS_NAME)

client.func(add_feed_func)(url=feed_url, item_path=path)
check(lambda: client.rss_items(), path or feed_url, reverse=True)

delete_feed(client, path or feed_url)
delete_feed(client, RSS_NAME)

run_test()


@pytest.mark.skipif_before_api_version("2.9.1")
Expand Down Expand Up @@ -216,11 +235,10 @@ def test_rss_mark_as_read_not_implemented(client, mark_read_func):

@pytest.mark.skipif_before_api_version("2.2")
@pytest.mark.parametrize(
"add_feed_func, set_rule_func, rules_func, rename_rule_func, "
"set_rule_func, rules_func, rename_rule_func, "
"matching_func, remove_rule_func, remove_item_func",
(
(
"rss_add_feed",
"rss_set_rule",
"rss_rules",
"rss_rename_rule",
Expand All @@ -229,7 +247,6 @@ def test_rss_mark_as_read_not_implemented(client, mark_read_func):
"rss_remove_item",
),
(
"rss_addFeed",
"rss_setRule",
"rss_rules",
"rss_renameRule",
Expand All @@ -238,7 +255,6 @@ def test_rss_mark_as_read_not_implemented(client, mark_read_func):
"rss_removeItem",
),
(
"rss.add_feed",
"rss.set_rule",
"rss.rules",
"rss.rename_rule",
Expand All @@ -247,7 +263,6 @@ def test_rss_mark_as_read_not_implemented(client, mark_read_func):
"rss.remove_item",
),
(
"rss.addFeed",
"rss.setRule",
"rss.rules",
"rss.renameRule",
Expand All @@ -260,7 +275,6 @@ def test_rss_mark_as_read_not_implemented(client, mark_read_func):
def test_rss_rules(
client,
api_version,
add_feed_func,
set_rule_func,
rules_func,
rename_rule_func,
Expand Down

0 comments on commit 42bb8ae

Please sign in to comment.