Merge pull request #517 from arabcoders/dev
Some checks failed
native-build / build (amd64, ubuntu-latest) (push) Has been cancelled
native-build / build (amd64, windows-latest) (push) Has been cancelled
native-build / build (arm64, macos-latest) (push) Has been cancelled
native-build / build (arm64, ubuntu-latest) (push) Has been cancelled
native-build / build (arm64, windows-latest) (push) Has been cancelled
Some checks failed
native-build / build (amd64, ubuntu-latest) (push) Has been cancelled
native-build / build (amd64, windows-latest) (push) Has been cancelled
native-build / build (arm64, macos-latest) (push) Has been cancelled
native-build / build (arm64, ubuntu-latest) (push) Has been cancelled
native-build / build (arm64, windows-latest) (push) Has been cancelled
Some extractors dont work with --flat-playlist
This commit is contained in:
commit
20e6c129ba
6 changed files with 641 additions and 672 deletions
|
|
@ -373,11 +373,12 @@ class DownloadQueue(metaclass=Singleton):
|
|||
|
||||
newItem: Item = item.new_with(url=etr.get("url") or etr.get("webpage_url"), extras=extras)
|
||||
|
||||
if "formats" in etr and isinstance(etr["formats"], list) and len(etr["formats"]) > 0:
|
||||
LOG.warning(f"Unexpected formats entries in --flat-playlist for {item_name}, treating as video.")
|
||||
return await self._add_video(
|
||||
entry=merge_dict(merge_dict({"_type": "video"}, etr), entry), item=newItem, logs=[]
|
||||
)
|
||||
if ("video" == etr.get("_type") and etr.get("url")) or (
|
||||
"formats" in etr and isinstance(etr["formats"], list) and len(etr["formats"]) > 0
|
||||
):
|
||||
dct = merge_dict(merge_dict({"_type": "video"}, etr), entry)
|
||||
dct.pop("entries", None)
|
||||
return await self.add(item=newItem, entry=dct, already=already)
|
||||
|
||||
return await self.add(item=newItem, already=already)
|
||||
finally:
|
||||
|
|
@ -651,13 +652,14 @@ class DownloadQueue(metaclass=Singleton):
|
|||
|
||||
return {"status": "error", "msg": f'Unsupported event type "{event_type}".'}
|
||||
|
||||
async def add(self, item: Item, already: set | None = None):
|
||||
async def add(self, item: Item, already: set | None = None, entry: dict | None = None) -> dict[str, str]:
|
||||
"""
|
||||
Add an item to the download queue.
|
||||
|
||||
Args:
|
||||
item (Item): The item to be added to the queue.
|
||||
already (set): Set of already downloaded items.
|
||||
entry (dict): The entry associated with the item.
|
||||
|
||||
Returns:
|
||||
dict[str, str]: The status of the download.
|
||||
|
|
@ -683,7 +685,7 @@ class DownloadQueue(metaclass=Singleton):
|
|||
yt_conf = {}
|
||||
cookie_file: Path = Path(self.config.temp_path) / f"c_{uuid.uuid4().hex}.txt"
|
||||
|
||||
LOG.info(f"Adding '{item.__repr__()}'.")
|
||||
LOG.info(f"Adding '{item!r}'.")
|
||||
|
||||
already = set() if already is None else already
|
||||
|
||||
|
|
@ -709,7 +711,7 @@ class DownloadQueue(metaclass=Singleton):
|
|||
LOG.warning(f"Using external downloader '{yt_conf.get('external_downloader')}' for '{item.url}'.")
|
||||
item.extras.update({"external_downloader": True})
|
||||
|
||||
archive_id = item.get_archive_id()
|
||||
archive_id: str | None = item.get_archive_id()
|
||||
|
||||
if item.is_archived():
|
||||
if archive_id:
|
||||
|
|
@ -744,12 +746,11 @@ class DownloadQueue(metaclass=Singleton):
|
|||
return {"status": "ok"}
|
||||
|
||||
message: str = f"The URL '{item.url}' is already downloaded and recorded in archive."
|
||||
LOG.error(message)
|
||||
LOG.warning(message)
|
||||
self._notify.emit(
|
||||
Events.LOG_INFO, data={"preset": item.preset}, title="Already Downloaded", message=message
|
||||
)
|
||||
|
||||
return {"status": "error", "msg": message}
|
||||
return {"status": "error", "msg": message, "hidden": True}
|
||||
|
||||
started: float = time.perf_counter()
|
||||
|
||||
|
|
@ -761,22 +762,23 @@ class DownloadQueue(metaclass=Singleton):
|
|||
LOG.error(msg)
|
||||
return {"status": "error", "msg": msg}
|
||||
|
||||
LOG.info(f"Checking '{item.url}' with {'cookies' if yt_conf.get('cookiefile') else 'no cookies'}.")
|
||||
LOG.info(f"Extracting '{item.url}' with {'cookies' if yt_conf.get('cookiefile') else ''}.")
|
||||
|
||||
entry: dict | None = await asyncio.wait_for(
|
||||
fut=asyncio.get_running_loop().run_in_executor(
|
||||
None,
|
||||
functools.partial(
|
||||
extract_info,
|
||||
config=yt_conf,
|
||||
url=item.url,
|
||||
debug=bool(self.config.ytdlp_debug),
|
||||
no_archive=False,
|
||||
follow_redirect=True,
|
||||
if not entry:
|
||||
entry: dict | None = await asyncio.wait_for(
|
||||
fut=asyncio.get_running_loop().run_in_executor(
|
||||
None,
|
||||
functools.partial(
|
||||
extract_info,
|
||||
config=yt_conf,
|
||||
url=item.url,
|
||||
debug=bool(self.config.ytdlp_debug),
|
||||
no_archive=False,
|
||||
follow_redirect=True,
|
||||
),
|
||||
),
|
||||
),
|
||||
timeout=self.config.extract_info_timeout,
|
||||
)
|
||||
timeout=self.config.extract_info_timeout,
|
||||
)
|
||||
|
||||
if not entry:
|
||||
LOG.error(f"Unable to extract info for '{item.url}'. Logs: {logs}")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import asyncio
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from aiohttp import web
|
||||
from aiohttp.web import Request, Response
|
||||
|
|
@ -375,15 +375,18 @@ async def items_add(request: Request, queue: DownloadQueue, encoder: Encoder) ->
|
|||
except ValueError as e:
|
||||
return web.json_response(data={"error": str(e), "data": item}, status=web.HTTPBadRequest.status_code)
|
||||
|
||||
status: list = await asyncio.wait_for(
|
||||
status: list[dict] = await asyncio.wait_for(
|
||||
fut=asyncio.gather(*[queue.add(item=item) for item in items]),
|
||||
timeout=None,
|
||||
)
|
||||
|
||||
response: list = []
|
||||
response: list[dict[str, Any]] = []
|
||||
|
||||
for i, item in enumerate(items):
|
||||
response.append({"item": item, "status": "ok" == status[i].get("status"), "msg": status[i].get("msg")})
|
||||
it = {"item": item, "status": "ok" == status[i].get("status"), "msg": status[i].get("msg")}
|
||||
if status[i].get("hidden"):
|
||||
it["hidden"] = True
|
||||
response.append(it)
|
||||
|
||||
return web.json_response(data=response, status=web.HTTPOk.status_code, dumps=encoder.encode)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<span class="icon"><i class="fa-solid fa-link" /></span>
|
||||
<span class="has-tooltip" v-tooltip="'Use Shift+Enter to switch to multiline input mode.'">
|
||||
URLs separated by newlines or <span class="is-bold is-lowercase">{{ getSeparatorsName(separator)
|
||||
}}</span>
|
||||
}}</span>
|
||||
</span>
|
||||
</label>
|
||||
<div class="field is-grouped">
|
||||
|
|
@ -474,8 +474,14 @@ const addDownload = async () => {
|
|||
if (false !== item.status) {
|
||||
return
|
||||
}
|
||||
toast.error(`Error: ${item.msg || 'Failed to add download.'}`)
|
||||
|
||||
had_errors = true
|
||||
|
||||
if (item?.hidden) {
|
||||
return
|
||||
}
|
||||
|
||||
toast.error(`Error: ${item.msg || 'Failed to add download.'}`)
|
||||
})
|
||||
|
||||
if (false === had_errors) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
"@pinia/nuxt": "^0.11.3",
|
||||
"@vueuse/core": "^14.1.0",
|
||||
"@vueuse/nuxt": "^14.1.0",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"cron-parser": "^5.4.0",
|
||||
"cronstrue": "^3.9.0",
|
||||
"floating-vue": "^5.2.2",
|
||||
|
|
@ -34,8 +34,8 @@
|
|||
"moment": "^2.30.1",
|
||||
"nuxt": "^4.2.2",
|
||||
"pinia": "^3.0.4",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"vue": "^3.5.25",
|
||||
"socket.io-client": "^4.8.2",
|
||||
"vue": "^3.5.26",
|
||||
"vue-router": "^4.6.4",
|
||||
"vue-toastification": "2.0.0-rc.5"
|
||||
},
|
||||
|
|
@ -54,11 +54,11 @@
|
|||
"devDependencies": {
|
||||
"@nuxt/eslint": "^1.12.1",
|
||||
"@nuxt/eslint-config": "^1.12.1",
|
||||
"@typescript-eslint/parser": "^8.50.0",
|
||||
"@typescript-eslint/parser": "^8.50.1",
|
||||
"eslint": "^9.39.2",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.16",
|
||||
"vue-eslint-parser": "^10.2.0",
|
||||
"vue-tsc": "^3.1.8"
|
||||
"vue-tsc": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1204
ui/pnpm-lock.yaml
1204
ui/pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
24
uv.lock
24
uv.lock
|
|
@ -107,11 +107,11 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "aiosqlite"
|
||||
version = "0.22.0"
|
||||
version = "0.22.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3a/0d/449c024bdabd0678ae07d804e60ed3b9786facd3add66f51eee67a0fccea/aiosqlite-0.22.0.tar.gz", hash = "sha256:7e9e52d72b319fcdeac727668975056c49720c995176dc57370935e5ba162bb9", size = 14707 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4e/8a/64761f4005f17809769d23e518d915db74e6310474e733e3593cfc854ef1/aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650", size = 14821 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/39/b2181148075272edfbbd6d87e6cd78cc71dca243446fa3b381fd4116950b/aiosqlite-0.22.0-py3-none-any.whl", hash = "sha256:96007fac2ce70eda3ca1bba7a3008c435258a592b8fbf2ee3eeaa36d33971a09", size = 17263 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/b7/e3bf5133d697a08128598c8d0abc5e16377b51465a33756de24fa7dee953/aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb", size = 17405 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1059,15 +1059,15 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "pyinstaller-hooks-contrib"
|
||||
version = "2025.10"
|
||||
version = "2025.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/26/4f/e33132acdb8f732978e577b8a0130a412cbfe7a3414605e3fd380a975522/pyinstaller_hooks_contrib-2025.10.tar.gz", hash = "sha256:a1a737e5c0dccf1cf6f19a25e2efd109b9fec9ddd625f97f553dac16ee884881", size = 168155 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/45/2f/2c68b6722d233dae3e5243751aafc932940b836919cfaca22dd0c60d417c/pyinstaller_hooks_contrib-2025.11.tar.gz", hash = "sha256:dfe18632e06655fa88d218e0d768fd753e1886465c12a6d4bce04f1aaeec917d", size = 169183 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/86/de/a7688eed49a1d3df337cdaa4c0d64e231309a52f269850a72051975e3c4a/pyinstaller_hooks_contrib-2025.10-py3-none-any.whl", hash = "sha256:aa7a378518772846221f63a84d6306d9827299323243db890851474dfd1231a9", size = 447760 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/c4/3a096c6e701832443b957b9dac18a163103360d0c7f5842ca41695371148/pyinstaller_hooks_contrib-2025.11-py3-none-any.whl", hash = "sha256:777e163e2942474aa41a8e6d31ac1635292d63422c3646c176d584d04d971c34", size = 449478 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1216,14 +1216,14 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "python-engineio"
|
||||
version = "4.12.3"
|
||||
version = "4.13.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "simple-websocket" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c9/d8/63e5535ab21dc4998ba1cfe13690ccf122883a38f025dca24d6e56c05eba/python_engineio-4.12.3.tar.gz", hash = "sha256:35633e55ec30915e7fc8f7e34ca8d73ee0c080cec8a8cd04faf2d7396f0a7a7a", size = 91910 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/42/5a/349caac055e03ef9e56ed29fa304846063b1771ee54ab8132bf98b29491e/python_engineio-4.13.0.tar.gz", hash = "sha256:f9c51a8754d2742ba832c24b46ed425fdd3064356914edd5a1e8ffde76ab7709", size = 92194 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl", hash = "sha256:7c099abb2a27ea7ab429c04da86ab2d82698cdd6c52406cb73766fe454feb7e1", size = 59637 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/74/c655a6eda0fd188d490c14142a0f0380655ac7099604e1fbf8fa1a97f0a1/python_engineio-4.13.0-py3-none-any.whl", hash = "sha256:57b94eac094fa07b050c6da59f48b12250ab1cd920765f4849963e3d89ad9de3", size = 59676 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1246,15 +1246,15 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "python-socketio"
|
||||
version = "5.15.1"
|
||||
version = "5.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "bidict" },
|
||||
{ name = "python-engineio" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/b5/56d070ade9ae60ed90ce2cdb41da927791cdae31f1059aab4b6b60d223b3/python_socketio-5.15.1.tar.gz", hash = "sha256:54fe3e5580ea06a1b29b541e8ef32fe956846c99a76059e343e43aada754efdd", size = 127172 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b8/55/5d8af5884283b58e4405580bcd84af1d898c457173c708736e065f10ca4a/python_socketio-5.16.0.tar.gz", hash = "sha256:f79403c7f1ba8b84460aa8fe4c671414c8145b21a501b46b676f3740286356fd", size = 127120 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/47/45a805fc1e4c3104df1193a78aeb98734497e32931efd1dfe9897c19188b/python_socketio-5.15.1-py3-none-any.whl", hash = "sha256:abc3528803563ed9a2010bc76829afe21d7a308a1e5651171fdb582d12e2ace0", size = 79561 },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/d2/2ccc2b69a187b80fda3152745670cfba936704f296a9fa54c6c8ac694d12/python_socketio-5.16.0-py3-none-any.whl", hash = "sha256:d95802961e15c7bd54ecf884c6e7644f81be8460f0a02ee66b473df58088ee8a", size = 79607 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
Loading…
Reference in a new issue