From 922d194d7a2e7cd50af960bb30606d4db40c022c Mon Sep 17 00:00:00 2001 From: ArabCoders Date: Sat, 25 Jan 2025 17:25:58 +0300 Subject: [PATCH] simplify API calls. --- .vscode/launch.json | 4 ++-- README.md | 3 --- app/library/HttpAPI.py | 42 ++++++++++----------------------- app/library/HttpSocket.py | 2 +- app/library/config.py | 11 +-------- ui/components/FloatingImage.vue | 7 +++--- ui/components/GetInfo.vue | 7 +++--- ui/components/History.vue | 9 +++---- ui/components/NewDownload.vue | 3 ++- ui/components/Queue.vue | 4 ++-- ui/components/TaskForm.vue | 3 ++- ui/layouts/default.vue | 3 ++- ui/nuxt.config.ts | 20 +++++++++++++++- ui/pages/tasks.vue | 6 +++-- ui/stores/ConfigStore.js | 2 -- ui/stores/SocketStore.js | 2 +- ui/utils/index.js | 10 +++++--- 17 files changed, 66 insertions(+), 72 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e73fa56c..96b9c850 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,6 +18,7 @@ "type": "node", "cwd": "${workspaceFolder}/ui", "env": { + "NUXT_API_URL": "http://localhost:8081/api/", "NUXT_PUBLIC_WSS": ":8081/", }, "console": "internalConsole" @@ -34,13 +35,13 @@ "YTP_DOWNLOAD_PATH": "${workspaceFolder}/var/downloads", "YTP_TEMP_PATH": "${workspaceFolder}/var/tmp", "PYDEVD_DISABLE_FILE_VALIDATION": "1", - "YTP_URL_HOST": "http://localhost:8081", "YTP_MAX_WORKERS": "2", "YTP_IGNORE_UI": "true", "YTP_PIP_IGNORE_UPDATES": "true", "YTP_LOG_LEVEL": "DEBUG", "YTP_DEBUG": "true", "YTP_YTDL_DEBUG": "false", + "YTP_ACCESS_LOG": "true", } }, { @@ -54,7 +55,6 @@ "YTP_CONFIG_PATH": "${workspaceFolder}/var/config", "YTP_DOWNLOAD_PATH": "${workspaceFolder}/var/downloads", "YTP_TEMP_PATH": "${workspaceFolder}/var/tmp", - "YTP_URL_HOST": "http://localhost:8081", "YTP_LOG_LEVEL": "DEBUG", } }, diff --git a/README.md b/README.md index d7db6187..c315e925 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,6 @@ Certain values can be set via environment variables, using the `-e` parameter on * __YTP_DOWNLOAD_PATH__: path to where the downloads will be saved. Defaults to `/downloads` in the docker image, and `./var/downloads` otherwise. * __YTP_TEMP_PATH__: path where intermediary download files will be saved. Defaults to `/tmp` in the docker image, and `./var/tmp` otherwise. * __YTP_TEMP_KEEP__: Whether to keep the Individual video temp directory or remove it. Defaults to `false`. -* __YTP_URL_PREFIX__: base path for the web server (for use when hosting behind a reverse proxy). Defaults to `/`. * __YTP_OUTPUT_TEMPLATE__: the template for the filenames of the downloaded videos, formatted according to [this spec](https://github.com/yt-dlp/yt-dlp/blob/master/README.md#output-template). Defaults to `%(title)s.%(ext)s`. This will be the default for all downloads unless the request include output template. * __YTP_OUTPUT_TEMPLATE_CHAPTER__: the template for the filenames of the downloaded videos, when split into chapters via postprocessors, formatted according to [this spec](https://github.com/yt-dlp/yt-dlp/blob/master/README.md#output-template). Defaults to `%(title)s - %(section_number)s %(section_title)s.%(ext)s.` * __YTP_KEEP_ARCHIVE__: Whether to keep history of downloaded videos to prevent downloading same file multiple times. Defaults to `true`. @@ -102,8 +101,6 @@ Certain values can be set via environment variables, using the `-e` parameter on It's advisable to run YTPTube behind a reverse proxy, if authentication and/or HTTPS support are required. -When running behind a reverse proxy which remaps the URL (i.e. serves YTPTube under a subdirectory and not under root), don't forget to set the `YTP_URL_PREFIX` environment variable to the correct value. - ### NGINX ```nginx diff --git a/app/library/HttpAPI.py b/app/library/HttpAPI.py index 1368d839..863614cd 100644 --- a/app/library/HttpAPI.py +++ b/app/library/HttpAPI.py @@ -109,7 +109,7 @@ class HttpAPI(common): continue file = os.path.join(root, file) - urlPath = f"{self.config.url_prefix}{file.replace(f'{staticDir}/', '')}" + urlPath = f"/{file.replace(f'{staticDir}/', '')}" content = open(file, "rb").read() contentType = self.extToMime.get(os.path.splitext(file)[1], MIME.from_file(file)) @@ -149,10 +149,10 @@ class HttpAPI(common): method = getattr(self, attr_name) if hasattr(method, "_http_method") and hasattr(method, "_http_path"): http_path = method._http_path - if http_path.startswith("/") and self.config.url_prefix.endswith("/"): + if http_path.startswith("/"): http_path = method._http_path[1:] - self.routes.route(method._http_method, self.config.url_prefix + http_path)(method) + self.routes.route(method._http_method, f"/{http_path}")(method) async def on_prepare(request: Request, response: Response): if "Server" in response.headers: @@ -160,14 +160,10 @@ class HttpAPI(common): if "Origin" in request.headers: response.headers["Access-Control-Allow-Origin"] = request.headers["Origin"] - response.headers["Access-Control-Allow-Headers"] = "Content-Type" - response.headers["Access-Control-Allow-Methods"] = "PATCH, PUT, POST, DELETE" + response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization" + response.headers["Access-Control-Allow-Methods"] = "GET, PATCH, PUT, POST, DELETE" - if self.config.url_prefix != "/": - self.routes.route("GET", "/")(lambda _: web.HTTPFound(self.config.url_prefix)) - self.routes.get(self.config.url_prefix[:-1])(lambda _: web.HTTPFound(self.config.url_prefix)) - - self.routes.static(f"{self.config.url_prefix}api/download/", self.config.download_path) + self.routes.static("/api/download/", self.config.download_path) self.preloadStatic(app) try: @@ -215,6 +211,10 @@ class HttpAPI(common): return middleware_handler + @route("OPTIONS", "/{path:.*}") + async def add_coors(self, _: Request) -> Response: + return web.json_response(data={"status": "ok"}, status=web.HTTPOk.status_code) + @route("GET", "api/ping") async def ping(self, _) -> Response: await self.queue.test() @@ -564,9 +564,7 @@ class HttpAPI(common): raise web.HTTPBadRequest(text="file is required.") try: - text = await Playlist(url=f"{self.config.url_host}{self.config.url_prefix}").make( - download_path=self.config.download_path, file=file - ) + text = await Playlist(url="/").make(download_path=self.config.download_path, file=file) if isinstance(text, Response): return text except StreamingError as e: @@ -604,7 +602,7 @@ class HttpAPI(common): duration = float(duration) try: - cls = M3u8(f"{self.config.url_host}{self.config.url_prefix}") + cls = M3u8("/") if "subtitle" in mode: text = await cls.make_subtitle(self.config.download_path, file, duration) else: @@ -707,22 +705,6 @@ class HttpAPI(common): status=web.HTTPOk.status_code, ) - @route("OPTIONS", "api/add") - async def add_cors(self, _: Request) -> Response: - return web.json_response(data={"status": "ok"}, status=web.HTTPOk.status_code) - - @route("OPTIONS", "api/tasks") - async def cors_add_tasks(self, _: Request) -> Response: - return web.json_response(data={"status": "ok"}, status=web.HTTPOk.status_code) - - @route("OPTIONS", "api/yt-dlp/convert") - async def cors_ytdlp_convert(self, _: Request) -> Response: - return web.json_response(data={"status": "ok"}, status=web.HTTPOk.status_code) - - @route("OPTIONS", "api/delete") - async def delete_cors(self, _: Request) -> Response: - return web.json_response(data={"status": "ok"}, status=web.HTTPOk.status_code) - @route("GET", "/") async def index(self, _) -> Response: if "/index.html" not in self.staticHolder: diff --git a/app/library/HttpSocket.py b/app/library/HttpSocket.py index cbbd9e40..8340ec80 100644 --- a/app/library/HttpSocket.py +++ b/app/library/HttpSocket.py @@ -54,7 +54,7 @@ class HttpSocket(common): return wrapper def attach(self, app: web.Application): - self.sio.attach(app, socketio_path=self.config.url_prefix + "socket.io") + self.sio.attach(app, socketio_path=self.config.url_socketio) for attr_name in dir(self): method = getattr(self, attr_name) diff --git a/app/library/config.py b/app/library/config.py index 9f437531..1b2e7d94 100644 --- a/app/library/config.py +++ b/app/library/config.py @@ -29,11 +29,7 @@ class Config: temp_keep: bool = False """Keep temporary files after the download is complete.""" - url_host: str = "" - """The host to bind the server to.""" - url_prefix: str = "" - """The prefix to use for the server URL.""" - url_socketio: str = "{url_prefix}socket.io" + url_socketio: str = "/socket.io" """The URL to use for the socket.io server.""" output_template: str = "%(title)s.%(ext)s" @@ -192,9 +188,7 @@ class Config: "output_template", "ytdlp_version", "version", - "url_host", "started", - "url_prefix", "remove_files", "ui_update_title", "max_workers", @@ -275,9 +269,6 @@ class Config: if k in self._int_vars: setattr(self, k, int(v)) - if not self.url_prefix.endswith("/"): - self.url_prefix += "/" - numeric_level = getattr(logging, self.log_level.upper(), None) if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level '{self.log_level}' specified.") diff --git a/ui/components/FloatingImage.vue b/ui/components/FloatingImage.vue index 674c39e7..ad69b291 100644 --- a/ui/components/FloatingImage.vue +++ b/ui/components/FloatingImage.vue @@ -16,6 +16,8 @@