diff --git a/tubearchivist/api/urls.py b/tubearchivist/api/urls.py index 19c6e192..1af11133 100644 --- a/tubearchivist/api/urls.py +++ b/tubearchivist/api/urls.py @@ -41,6 +41,11 @@ urlpatterns = [ views.ChannelApiListView.as_view(), name="api-channel-list", ), + path( + "channel/search/", + views.ChannelApiSearchView.as_view(), + name="api-channel-search", + ), path( "channel//", views.ChannelApiView.as_view(), diff --git a/tubearchivist/api/views.py b/tubearchivist/api/views.py index 6ae35f4f..34762d29 100644 --- a/tubearchivist/api/views.py +++ b/tubearchivist/api/views.py @@ -228,6 +228,10 @@ class VideoSponsorView(ApiBaseView): # pylint: disable=unused-argument self.get_document(video_id) + if not self.response.get("data"): + message = {"message": "video not found"} + return Response(message, status=404) + sponsorblock = self.response["data"].get("sponsorblock") return Response(sponsorblock) @@ -356,6 +360,36 @@ class ChannelApiListView(ApiBaseView): ) +class ChannelApiSearchView(ApiBaseView): + """resolves to /api/channel/search/ + search for channel + """ + + search_base = "ta_channel/_doc/" + + def get(self, request): + """handle get request, search with s parameter""" + + query = request.GET.get("q") + if not query: + message = "missing expected q parameter" + return Response({"message": message, "data": False}, status=400) + + try: + parsed = Parser(query).parse()[0] + except (ValueError, IndexError, AttributeError): + message = f"channel not found: {query}" + return Response({"message": message, "data": False}, status=404) + + if not parsed["type"] == "channel": + message = "expected type channel" + return Response({"message": message, "data": False}, status=400) + + self.get_document(parsed["url"]) + + return Response(self.response, status=self.status_code) + + class ChannelApiVideoView(ApiBaseView): """resolves to /api/channel//video GET: returns a list of videos of channel diff --git a/tubearchivist/config/settings.py b/tubearchivist/config/settings.py index bdf0a6a2..4418083d 100644 --- a/tubearchivist/config/settings.py +++ b/tubearchivist/config/settings.py @@ -256,4 +256,4 @@ CORS_ALLOW_HEADERS = list(default_headers) + [ # TA application settings TA_UPSTREAM = "https://github.com/tubearchivist/tubearchivist" -TA_VERSION = "v0.4.0" +TA_VERSION = "v0.4.1-unstable" diff --git a/tubearchivist/home/src/ta/notify.py b/tubearchivist/home/src/ta/notify.py index d8821285..5b1c9c7a 100644 --- a/tubearchivist/home/src/ta/notify.py +++ b/tubearchivist/home/src/ta/notify.py @@ -8,12 +8,12 @@ from home.src.ta.task_manager import TaskManager class Notifications: """notification handler""" - def __init__(self, name, task_id, task_title): - self.name = name - self.task_id = task_id - self.task_title = task_title + def __init__(self, name: str, task_id: str, task_title: str): + self.name: str = name + self.task_id: str = task_id + self.task_title: str = task_title - def send(self): + def send(self) -> None: """send notifications""" apobj = apprise.Apprise() hooks: str | None = self.get_url() diff --git a/tubearchivist/static/script.js b/tubearchivist/static/script.js index 7d2d3cf8..990e76c9 100644 --- a/tubearchivist/static/script.js +++ b/tubearchivist/static/script.js @@ -1483,6 +1483,21 @@ function doShortcut(e) { player.muted = !player.muted; break; } + case 'f': { + e.preventDefault(); + if (document.fullscreenElement === null) { + player.requestFullscreen().catch(e => { + console.error(e); + showModal('Unable to enter fullscreen', 3000); + }); + } else { + document.exitFullscreen().catch(e => { + console.error(e); + showModal('Unable to exit fullscreen', 3000); + }); + } + break; + } case 'ArrowLeft': { e.preventDefault(); showModal('- 5 seconds', 500); @@ -1527,6 +1542,7 @@ function doShortcut(e) { +
Show help?
Toggle mutem
Toggle fullscreenf
Toggle subtitles (if available)c
Increase speed>
Decrease speed<