mirror of
https://github.com/alexta69/metube.git
synced 2026-06-13 16:40:05 +00:00
Merge pull request #944 from jacinli/codex/fix-subscription-enabled-parsing
Fix string boolean parsing for subscription enabled updates
This commit is contained in:
+14
-1
@@ -231,6 +231,19 @@ def _subscription_from_record(record: Any) -> Optional[SubscriptionInfo]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _coerce_bool(value: Any) -> bool:
|
||||||
|
"""Accept JSON booleans and common string forms used by API clients."""
|
||||||
|
if isinstance(value, bool):
|
||||||
|
return value
|
||||||
|
if isinstance(value, str):
|
||||||
|
lowered = value.strip().lower()
|
||||||
|
if lowered in {"true", "1", "on"}:
|
||||||
|
return True
|
||||||
|
if lowered in {"false", "0", "off"}:
|
||||||
|
return False
|
||||||
|
raise ValueError("enabled must be a boolean")
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionNotifier:
|
class SubscriptionNotifier:
|
||||||
"""Hook for Socket.IO / UI updates."""
|
"""Hook for Socket.IO / UI updates."""
|
||||||
|
|
||||||
@@ -546,7 +559,7 @@ class SubscriptionManager:
|
|||||||
old_enabled = sub.enabled
|
old_enabled = sub.enabled
|
||||||
|
|
||||||
if "enabled" in changes:
|
if "enabled" in changes:
|
||||||
sub.enabled = bool(changes["enabled"])
|
sub.enabled = _coerce_bool(changes["enabled"])
|
||||||
if "check_interval_minutes" in changes:
|
if "check_interval_minutes" in changes:
|
||||||
sub.check_interval_minutes = max(1, int(changes["check_interval_minutes"]))
|
sub.check_interval_minutes = max(1, int(changes["check_interval_minutes"]))
|
||||||
if "name" in changes and changes["name"]:
|
if "name" in changes and changes["name"]:
|
||||||
|
|||||||
@@ -386,6 +386,73 @@ class SubscriptionPersistenceTests(unittest.IsolatedAsyncioTestCase):
|
|||||||
self.assertEqual(sub.seen_ids[:2], ["v2", "v1"])
|
self.assertEqual(sub.seen_ids[:2], ["v2", "v1"])
|
||||||
self.assertEqual([entry["webpage_url"] for entry, _, _ in queue.entries], ["https://example.com/v2"])
|
self.assertEqual([entry["webpage_url"] for entry, _, _ in queue.entries], ["https://example.com/v2"])
|
||||||
|
|
||||||
|
async def test_update_subscription_parses_string_false_enabled(self):
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
queue = _Queue()
|
||||||
|
mgr = SubscriptionManager(_Config(tmp), queue, _Notifier())
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"subscriptions.extract_flat_playlist",
|
||||||
|
return_value=(
|
||||||
|
{"_type": "channel", "title": "Channel"},
|
||||||
|
[{"id": "v1", "title": "One", "webpage_url": "https://example.com/v1"}],
|
||||||
|
),
|
||||||
|
):
|
||||||
|
result = await mgr.add_subscription(
|
||||||
|
"https://example.com/channel",
|
||||||
|
check_interval_minutes=60,
|
||||||
|
download_type="video",
|
||||||
|
codec="auto",
|
||||||
|
format="any",
|
||||||
|
quality="best",
|
||||||
|
folder="",
|
||||||
|
custom_name_prefix="",
|
||||||
|
auto_start=True,
|
||||||
|
playlist_item_limit=0,
|
||||||
|
split_by_chapters=False,
|
||||||
|
chapter_template="",
|
||||||
|
subtitle_language="en",
|
||||||
|
subtitle_mode="prefer_manual",
|
||||||
|
)
|
||||||
|
|
||||||
|
sub_id = result["subscription"]["id"]
|
||||||
|
update = await mgr.update_subscription(sub_id, {"enabled": "false"})
|
||||||
|
self.assertEqual(update["status"], "ok")
|
||||||
|
self.assertFalse(mgr.list_all()[0].enabled)
|
||||||
|
|
||||||
|
async def test_update_subscription_rejects_invalid_enabled_value(self):
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
queue = _Queue()
|
||||||
|
mgr = SubscriptionManager(_Config(tmp), queue, _Notifier())
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"subscriptions.extract_flat_playlist",
|
||||||
|
return_value=(
|
||||||
|
{"_type": "channel", "title": "Channel"},
|
||||||
|
[{"id": "v1", "title": "One", "webpage_url": "https://example.com/v1"}],
|
||||||
|
),
|
||||||
|
):
|
||||||
|
result = await mgr.add_subscription(
|
||||||
|
"https://example.com/channel",
|
||||||
|
check_interval_minutes=60,
|
||||||
|
download_type="video",
|
||||||
|
codec="auto",
|
||||||
|
format="any",
|
||||||
|
quality="best",
|
||||||
|
folder="",
|
||||||
|
custom_name_prefix="",
|
||||||
|
auto_start=True,
|
||||||
|
playlist_item_limit=0,
|
||||||
|
split_by_chapters=False,
|
||||||
|
chapter_template="",
|
||||||
|
subtitle_language="en",
|
||||||
|
subtitle_mode="prefer_manual",
|
||||||
|
)
|
||||||
|
|
||||||
|
sub_id = result["subscription"]["id"]
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
await mgr.update_subscription(sub_id, {"enabled": "maybe"})
|
||||||
|
|
||||||
class ExtractFlatPlaylistTests(unittest.TestCase):
|
class ExtractFlatPlaylistTests(unittest.TestCase):
|
||||||
def test_descends_one_level_when_root_entries_are_nested_collections(self):
|
def test_descends_one_level_when_root_entries_are_nested_collections(self):
|
||||||
responses = iter(
|
responses = iter(
|
||||||
|
|||||||
Reference in New Issue
Block a user