From 78295a492c35a606af2d00cf9730eb2c0d7a5d20 Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Sun, 9 Aug 2020 11:40:46 +0200 Subject: [PATCH] Improve parsing inputs for download command * Fix overzealous regex which caused video patterns to be identified as clips by testing for videos before clips. * Allow URLs with or without `www.`. * Add tests which verify this actually works. fixes #28 --- Makefile | 3 +++ requirements-dev.txt | 8 +++----- tests/test_download.py | 45 ++++++++++++++++++++++++++++++++++++++++++ twitchdl/commands.py | 16 +++++++-------- 4 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 tests/test_download.py diff --git a/Makefile b/Makefile index a6513e3..3f6099f 100644 --- a/Makefile +++ b/Makefile @@ -19,3 +19,6 @@ deb: man: scdoc < twitch-dl.1.scd > twitch-dl.1.man + +test: + pytest diff --git a/requirements-dev.txt b/requirements-dev.txt index 330763d..49cb4e3 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,3 @@ -pytest-cov~=2.4.0 -pytest~=3.0.0 -stdeb~=0.8.5 -twine~=1.8.1 -wheel~=0.29.0 +pytest +twine +wheel diff --git a/tests/test_download.py b/tests/test_download.py new file mode 100644 index 0000000..b9989c3 --- /dev/null +++ b/tests/test_download.py @@ -0,0 +1,45 @@ +import pytest + +from unittest.mock import patch +from twitchdl.commands import download +from collections import namedtuple + +Args = namedtuple("args", ["video"]) + + +TEST_VIDEO_PATTERNS = [ + ("702689313", "702689313"), + ("702689313", "https://twitch.tv/videos/702689313"), + ("702689313", "https://www.twitch.tv/videos/702689313"), +] + +TEST_CLIP_PATTERNS = { + ("AbrasivePlayfulMangoMau5", "AbrasivePlayfulMangoMau5"), + ("AbrasivePlayfulMangoMau5", "https://clips.twitch.tv/AbrasivePlayfulMangoMau5"), + ("AbrasivePlayfulMangoMau5", "https://www.twitch.tv/dracul1nx/clip/AbrasivePlayfulMangoMau5"), + ("AbrasivePlayfulMangoMau5", "https://twitch.tv/dracul1nx/clip/AbrasivePlayfulMangoMau5"), + ("HungryProudRadicchioDoggo", "HungryProudRadicchioDoggo"), + ("HungryProudRadicchioDoggo", "https://clips.twitch.tv/HungryProudRadicchioDoggo"), + ("HungryProudRadicchioDoggo", "https://www.twitch.tv/bananasaurus_rex/clip/HungryProudRadicchioDoggo?filter=clips&range=7d&sort=time"), + ("HungryProudRadicchioDoggo", "https://twitch.tv/bananasaurus_rex/clip/HungryProudRadicchioDoggo?filter=clips&range=7d&sort=time"), +} + + +@patch("twitchdl.commands._download_clip") +@patch("twitchdl.commands._download_video") +@pytest.mark.parametrize("expected,input", TEST_VIDEO_PATTERNS) +def test_video_patterns(video_dl, clip_dl, expected, input): + args = Args(video=input) + download(args) + video_dl.assert_called_once_with(expected, args) + clip_dl.assert_not_called() + + +@patch("twitchdl.commands._download_clip") +@patch("twitchdl.commands._download_video") +@pytest.mark.parametrize("expected,input", TEST_CLIP_PATTERNS) +def test_clip_patterns(video_dl, clip_dl, expected, input): + args = Args(video=input) + download(args) + clip_dl.assert_called_once_with(expected, args) + video_dl.assert_not_called() diff --git a/twitchdl/commands.py b/twitchdl/commands.py index 174e724..5bc818a 100644 --- a/twitchdl/commands.py +++ b/twitchdl/commands.py @@ -164,29 +164,29 @@ def _crete_temp_dir(base_uri): VIDEO_PATTERNS = [ r"^(?P\d+)?$", - r"^https://www.twitch.tv/videos/(?P\d+)(\?.+)?$", + r"^https://(www.)?twitch.tv/videos/(?P\d+)(\?.+)?$", ] CLIP_PATTERNS = [ r"^(?P[A-Za-z0-9]+)$", - r"^https://www.twitch.tv/\w+/clip/(?P[A-Za-z0-9]+)(\?.+)?$", + r"^https://(www.)?twitch.tv/\w+/clip/(?P[A-Za-z0-9]+)(\?.+)?$", r"^https://clips.twitch.tv/(?P[A-Za-z0-9]+)(\?.+)?$", ] def download(args): - for pattern in CLIP_PATTERNS: - match = re.match(pattern, args.video) - if match: - clip_slug = match.group('slug') - return _download_clip(clip_slug, args) - for pattern in VIDEO_PATTERNS: match = re.match(pattern, args.video) if match: video_id = match.group('id') return _download_video(video_id, args) + for pattern in CLIP_PATTERNS: + match = re.match(pattern, args.video) + if match: + clip_slug = match.group('slug') + return _download_clip(clip_slug, args) + raise ConsoleError("Invalid video: {}".format(args.video))