Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39a117f08b |
No files matched your search
@@ -170,6 +170,7 @@ class Api:
|
|||||||
"bitrate": payload.get("bitrate", "320K"),
|
"bitrate": payload.get("bitrate", "320K"),
|
||||||
"hq_threshold": threshold,
|
"hq_threshold": threshold,
|
||||||
"cookies_path": (payload.get("cookies_path") or "").strip(),
|
"cookies_path": (payload.get("cookies_path") or "").strip(),
|
||||||
|
"cookies_browser": (payload.get("cookies_browser") or "").strip().lower(),
|
||||||
"output_dir": (payload.get("output_dir") or "").strip(),
|
"output_dir": (payload.get("output_dir") or "").strip(),
|
||||||
"theme": payload.get("theme", "dark"),
|
"theme": payload.get("theme", "dark"),
|
||||||
})
|
})
|
||||||
|
|||||||
+2
-1
@@ -5,7 +5,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
VERSION = "v1.10.0"
|
VERSION = "v1.10.1"
|
||||||
|
|
||||||
|
|
||||||
APP_NAME = "MusicTools"
|
APP_NAME = "MusicTools"
|
||||||
@@ -68,6 +68,7 @@ DEFAULTS = {
|
|||||||
"bitrate": "320K",
|
"bitrate": "320K",
|
||||||
"hq_threshold": 310,
|
"hq_threshold": 310,
|
||||||
"cookies_path": str(_project_dir / "cookies.txt"),
|
"cookies_path": str(_project_dir / "cookies.txt"),
|
||||||
|
"cookies_browser": "", # "" | chrome | safari | firefox | edge | brave
|
||||||
"output_dir": str(_project_dir / "MUSICA"),
|
"output_dir": str(_project_dir / "MUSICA"),
|
||||||
"theme": "dark",
|
"theme": "dark",
|
||||||
# ---- Beatport ----
|
# ---- Beatport ----
|
||||||
|
|||||||
+30
-14
@@ -12,6 +12,29 @@ from typing import Callable, Optional
|
|||||||
from core.paths import find_ytdlp, find_ffmpeg_dir, subprocess_flags
|
from core.paths import find_ytdlp, find_ffmpeg_dir, subprocess_flags
|
||||||
|
|
||||||
|
|
||||||
|
_ALLOWED_BROWSERS = {"chrome", "safari", "firefox", "edge", "brave", "chromium", "opera", "vivaldi"}
|
||||||
|
|
||||||
|
|
||||||
|
def _cookie_args(cookies_path: Optional[str]) -> list:
|
||||||
|
"""Ritorna gli argomenti yt-dlp per i cookies.
|
||||||
|
|
||||||
|
Priorità: file cookies_path se esiste → altrimenti --cookies-from-browser
|
||||||
|
<name> se `cookies_browser` è settato in config → altrimenti niente.
|
||||||
|
"""
|
||||||
|
if cookies_path and Path(cookies_path).exists():
|
||||||
|
return ["--cookies", cookies_path]
|
||||||
|
# Fallback: legge il browser dalla config al volo (evita di cambiare
|
||||||
|
# firma di tutte le funzioni download_*)
|
||||||
|
try:
|
||||||
|
from core.config import load_config
|
||||||
|
browser = (load_config().get("cookies_browser") or "").strip().lower()
|
||||||
|
except Exception:
|
||||||
|
browser = ""
|
||||||
|
if browser in _ALLOWED_BROWSERS:
|
||||||
|
return ["--cookies-from-browser", browser]
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
# Flag globale per interruzione
|
# Flag globale per interruzione
|
||||||
_stop_event = threading.Event()
|
_stop_event = threading.Event()
|
||||||
_current_process: Optional[subprocess.Popen] = None
|
_current_process: Optional[subprocess.Popen] = None
|
||||||
@@ -99,8 +122,7 @@ def _search_youtube(query: str, cookies_path: Optional[str] = None) -> tuple[str
|
|||||||
"--no-warnings",
|
"--no-warnings",
|
||||||
"--flat-playlist",
|
"--flat-playlist",
|
||||||
]
|
]
|
||||||
if cookies_path and Path(cookies_path).exists():
|
cmd.extend(_cookie_args(cookies_path))
|
||||||
cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, **subprocess_flags())
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, **subprocess_flags())
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
@@ -216,8 +238,7 @@ def download_playlist(
|
|||||||
ffmpeg_dir = find_ffmpeg_dir()
|
ffmpeg_dir = find_ffmpeg_dir()
|
||||||
if ffmpeg_dir:
|
if ffmpeg_dir:
|
||||||
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
||||||
if cookies_path and Path(cookies_path).exists():
|
cmd.extend(_cookie_args(cookies_path))
|
||||||
cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with _process_lock:
|
with _process_lock:
|
||||||
@@ -300,8 +321,7 @@ def download_direct_url(
|
|||||||
"--no-warnings",
|
"--no-warnings",
|
||||||
url,
|
url,
|
||||||
]
|
]
|
||||||
if cookies_path and Path(cookies_path).exists():
|
probe_cmd.extend(_cookie_args(cookies_path))
|
||||||
probe_cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(probe_cmd, capture_output=True, text=True, timeout=60, **subprocess_flags())
|
result = subprocess.run(probe_cmd, capture_output=True, text=True, timeout=60, **subprocess_flags())
|
||||||
@@ -375,8 +395,7 @@ def download_direct_url(
|
|||||||
ffmpeg_dir = find_ffmpeg_dir()
|
ffmpeg_dir = find_ffmpeg_dir()
|
||||||
if ffmpeg_dir:
|
if ffmpeg_dir:
|
||||||
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
||||||
if cookies_path and Path(cookies_path).exists():
|
cmd.extend(_cookie_args(cookies_path))
|
||||||
cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with _process_lock:
|
with _process_lock:
|
||||||
@@ -511,8 +530,7 @@ def download_urls(
|
|||||||
ffmpeg_dir = find_ffmpeg_dir()
|
ffmpeg_dir = find_ffmpeg_dir()
|
||||||
if ffmpeg_dir:
|
if ffmpeg_dir:
|
||||||
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
||||||
if cookies_path and Path(cookies_path).exists():
|
cmd.extend(_cookie_args(cookies_path))
|
||||||
cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with _process_lock:
|
with _process_lock:
|
||||||
@@ -608,8 +626,7 @@ def download_video(
|
|||||||
probe_cmd = [
|
probe_cmd = [
|
||||||
ytdlp, "--dump-json", "--flat-playlist", "--no-download", "--no-warnings", url,
|
ytdlp, "--dump-json", "--flat-playlist", "--no-download", "--no-warnings", url,
|
||||||
]
|
]
|
||||||
if cookies_path and Path(cookies_path).exists():
|
probe_cmd.extend(_cookie_args(cookies_path))
|
||||||
probe_cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(probe_cmd, capture_output=True, text=True, timeout=60, **subprocess_flags())
|
result = subprocess.run(probe_cmd, capture_output=True, text=True, timeout=60, **subprocess_flags())
|
||||||
@@ -684,8 +701,7 @@ def download_video(
|
|||||||
ffmpeg_dir = find_ffmpeg_dir()
|
ffmpeg_dir = find_ffmpeg_dir()
|
||||||
if ffmpeg_dir:
|
if ffmpeg_dir:
|
||||||
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
cmd.extend(["--ffmpeg-location", ffmpeg_dir])
|
||||||
if cookies_path and Path(cookies_path).exists():
|
cmd.extend(_cookie_args(cookies_path))
|
||||||
cmd.extend(["--cookies", cookies_path])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with _process_lock:
|
with _process_lock:
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ def _bundle_dirs() -> list[Path]:
|
|||||||
sub_macos = frameworks / sub / "Contents" / "MacOS"
|
sub_macos = frameworks / sub / "Contents" / "MacOS"
|
||||||
if sub_macos.exists():
|
if sub_macos.exists():
|
||||||
dirs.append(sub_macos)
|
dirs.append(sub_macos)
|
||||||
|
else:
|
||||||
|
# Dev: cerca in <project_root>/bundle_bin/ così `python main.py`
|
||||||
|
# usa gli stessi binari del bundle (aggiornati via build_*.py)
|
||||||
|
# invece di Homebrew/PATH che possono essere obsoleti.
|
||||||
|
project_bundle = Path(__file__).resolve().parent.parent / "bundle_bin"
|
||||||
|
if project_bundle.exists():
|
||||||
|
dirs.append(project_bundle)
|
||||||
return dirs
|
return dirs
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -563,6 +563,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="field-label">Cookies da browser (bypass 403 YouTube)</label>
|
||||||
|
<div class="row">
|
||||||
|
<select id="cookiesBrowserSelect" class="input pill" style="max-width:220px;">
|
||||||
|
<option value="">Nessuno</option>
|
||||||
|
<option value="chrome">Chrome</option>
|
||||||
|
<option value="safari">Safari</option>
|
||||||
|
<option value="firefox">Firefox</option>
|
||||||
|
<option value="edge">Edge</option>
|
||||||
|
<option value="brave">Brave</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="hint">
|
||||||
|
<span class="hint-ico">ⓘ</span>
|
||||||
|
<div>Alcuni video YouTube (musica protetta, region-lock, età) danno HTTP 403 senza cookies autenticati. Selezionando un browser, l'app legge i cookies dal tuo profilo — richiede che tu sia loggato su YouTube in quel browser. Se hai anche cookies.txt sopra, ha priorità il file.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="field-label">Cartella output predefinita</label>
|
<label class="field-label">Cartella output predefinita</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -485,6 +485,7 @@ async function init() {
|
|||||||
$("#bitrateSelect").value = state.config.bitrate || "320K";
|
$("#bitrateSelect").value = state.config.bitrate || "320K";
|
||||||
$("#hqThresholdInput").value = state.config.hq_threshold || 310;
|
$("#hqThresholdInput").value = state.config.hq_threshold || 310;
|
||||||
$("#cookiesInput").value = state.config.cookies_path || "";
|
$("#cookiesInput").value = state.config.cookies_path || "";
|
||||||
|
if ($("#cookiesBrowserSelect")) $("#cookiesBrowserSelect").value = state.config.cookies_browser || "";
|
||||||
$("#outputInput").value = state.config.output_dir || "";
|
$("#outputInput").value = state.config.output_dir || "";
|
||||||
$("#themeSelect").value = state.config.theme || "dark";
|
$("#themeSelect").value = state.config.theme || "dark";
|
||||||
applyTheme(state.config.theme);
|
applyTheme(state.config.theme);
|
||||||
@@ -1293,6 +1294,7 @@ $("#saveBtn").addEventListener("click", async () => {
|
|||||||
bitrate: $("#bitrateSelect").value,
|
bitrate: $("#bitrateSelect").value,
|
||||||
hq_threshold: parseInt($("#hqThresholdInput").value, 10) || 310,
|
hq_threshold: parseInt($("#hqThresholdInput").value, 10) || 310,
|
||||||
cookies_path: $("#cookiesInput").value,
|
cookies_path: $("#cookiesInput").value,
|
||||||
|
cookies_browser: $("#cookiesBrowserSelect") ? $("#cookiesBrowserSelect").value : "",
|
||||||
output_dir: $("#outputInput").value,
|
output_dir: $("#outputInput").value,
|
||||||
theme: $("#themeSelect").value,
|
theme: $("#themeSelect").value,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user