From d9c33091cac067660fd34115fbdcad9da5998e89 Mon Sep 17 00:00:00 2001 From: JesterDev <105895386+jstrdev@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:38:42 +0200 Subject: [PATCH] Version 1.17.0 --- LEEME.txt | 14 +- README.md | 5 +- README_EN.txt | 8 +- app.py | 74 +++- bg.js | 71 ++++ download | 4 + engine.py | 271 ++++++++++++-- icon128.png | Bin 0 -> 11923 bytes icon16.png | Bin 0 -> 778 bytes icon32.png | Bin 0 -> 1816 bytes icon48.png | Bin 0 -> 3067 bytes index.html | 981 +++++++++++++++++++++++++++++++++++++++++++++++++ logo.svg | 30 ++ manifest.json | 11 + popup.html | 20 + popup.js | 42 +++ ps5directo.ico | Bin 0 -> 63686 bytes 17 files changed, 1484 insertions(+), 47 deletions(-) create mode 100644 bg.js create mode 100644 download create mode 100644 icon128.png create mode 100644 icon16.png create mode 100644 icon32.png create mode 100644 icon48.png create mode 100644 index.html create mode 100644 logo.svg create mode 100644 manifest.json create mode 100644 popup.html create mode 100644 popup.js create mode 100644 ps5directo.ico diff --git a/LEEME.txt b/LEEME.txt index 8dec95d..cf04d7f 100644 --- a/LEEME.txt +++ b/LEEME.txt @@ -1,4 +1,4 @@ -PS5 DIRECTO 1.16 +PS5 DIRECTO 1.17 ================ (English: see README_EN.txt) @@ -162,6 +162,15 @@ de quien es la culpa cuando va lento. Tambien hay uno solo PC -> PS5 en Ajustes. +NOVEDADES 1.17 +- Enlaces ftp:// (un NAS u otro servidor): ftp://usuario:clave@nas/ruta/archivo.rar + Funcionan como los enlaces normales, con reanudación. +- Comprimidos .tar, .tar.gz, .tar.bz2 y .tar.xz: se descomprimen en el PC + sobre la marcha (no hace falta 7-Zip ni BFpilot). +- Las carpetas se envían con varias conexiones a la vez (Ajustes > Partes a + la vez), más rápido con muchos archivos. +- Pasos propios para los envíos de carpetas: Comparar → Enviar → Listo. + NOVEDADES 1.16 - Pestaña "Archivos de la consola": explorador con tamaños, copiar, mover, renombrar, borrar, bajar al PC, permisos y subir aquí. @@ -278,7 +287,8 @@ SI ALGO FALLA ENLACES ------- -Funcionan los enlaces de descarga directa. Pixeldrain, Dropbox y algunos +Funcionan los enlaces de descarga directa, y también los ftp:// de un NAS +u otro servidor (ftp://usuario:clave@nas/ruta/archivo.rar). Pixeldrain, Dropbox y algunos de Mediafire y Google Drive se convierten solos. Las páginas que piden captcha o iniciar sesión no funcionan: copia el enlace final de descarga. diff --git a/README.md b/README.md index e366007..8e26cc0 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,13 @@ A Windows file-transfer tool for jailbroken PS5 consoles. It sends files to the console over FTP **while they download**, without storing them on your PC. It then extracts them, either on the console with BFpilot or on the PC with 7-Zip, and places apps in `/data/homebrew` so ShadowMountPlus shows them in the menu. - ✅ Streams downloads straight to the console: nothing is saved on the PC -- ✅ Joins split parts (.part1, .part2… / .001, .002…) and extracts RAR, 7z and ZIP +- ✅ Works from download links, ftp:// links (e.g. a NAS) or files on your PC +- ✅ Joins split parts (.part1, .part2… / .001, .002…) and extracts RAR, 7z, ZIP and tar (.gz/.bz2/.xz) - ✅ Extracts on the console (BFpilot) or on the PC (7-Zip, every file CRC-checked) - ✅ Fixes the file permissions that stop BFpilot-extracted content from launching (CE-107750-0) - ✅ Pause, resume and retry where it left off, even after a dropped connection - ✅ Built-in console file browser: sizes, copy, move, rename, delete, download to PC, upload -- ✅ Send whole PC folders, skipping what's already there and resuming what got cut off +- ✅ Send whole PC folders over several connections, skipping what's already there and resuming what got cut off - ✅ Watches free space so the console never fills up - ✅ Speed limit and built-in speed test - ✅ Optional browser extension: links arrive by themselves, no copy and paste diff --git a/README_EN.txt b/README_EN.txt index c2acda0..49c6f7d 100644 --- a/README_EN.txt +++ b/README_EN.txt @@ -1,4 +1,4 @@ -PS5 DIRECTO 1.16 — USER GUIDE (English) +PS5 DIRECTO 1.17 — USER GUIDE (English) ======================================= Paste links (or drag files from your PC) and the tool does the rest: @@ -201,7 +201,8 @@ IF SOMETHING GOES WRONG LINKS ----- -Direct download links work. Pixeldrain, Dropbox and some Mediafire and +Direct download links work, and so do ftp:// links to a NAS or another +server (ftp://user:password@nas/path/file.rar). Pixeldrain, Dropbox and some Mediafire and Google Drive links are converted automatically. Pages that require a captcha or a login don't work directly: copy the final download link, or use the browser extension. @@ -214,6 +215,9 @@ Settings and queue are stored in %USERPROFILE%\.ps5directo WHAT'S NEW ---------- +1.17 ftp:// links (a NAS or other server) with resume. .tar/.tar.gz/.tar.bz2/ + .tar.xz extracted on the PC (no 7-Zip needed). Folders upload over several + connections at once. Own steps for folder uploads. 1.16 "Console files" tab (file browser: sizes, copy, move, rename, delete, download to PC, permissions, upload here). Send PC folders with resume. "Choose files…/Choose folder…" buttons. "Activity" tab. diff --git a/app.py b/app.py index ce29f1f..ec1e790 100644 --- a/app.py +++ b/app.py @@ -21,7 +21,7 @@ HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HERE) import engine as E # noqa: E402 -VERSION = "1.16.0" +VERSION = "1.17.0" # Repositorio de GitHub donde se publican las versiones (usuario/nombre). Si lo rellenas, # todas las copias buscan actualizaciones ahi sin tener que configurar nada. DEFAULT_REPO = "jstrdev/ps5directo" @@ -397,7 +397,7 @@ def transfer_job(job, srcs, cancel): return folder_job(job, srcs[0], cancel) names = [s.name for s in srcs] archives = [s for s in srcs if E.is_archive(s.name)] - if archives and job_where(job) == "pc": + if archives and (job_where(job) == "pc" or any(E.is_tar(a.name) for a in archives)): return pc_extract_job(job, srcs, cancel) m = E.SPLIT_RAW_RE.match(srcs[0].name) raw_split = (not archives and len(srcs) >= 1 and m @@ -530,8 +530,10 @@ def raw_job(job, srcs, cancel): target = dest + "/" + s.name if s.kind == "folder": setj(job, phase="Enviando carpeta: %s" % s.name) - E.upload_tree(cfg, s, target, cancel, lambda m: jlog(job, m), - lambda v, rel: prog(v)) + sent, skipped, resumed = E.upload_tree(cfg, s, target, cancel, lambda m: jlog(job, m), + lambda v, rel: prog(v)) + jlog(job, "Carpeta enviada: %d archivos nuevos, %d ya estaban iguales, %d continuados" + % (sent, skipped, resumed)) else: setj(job, phase="Enviando %s" % s.name) E.upload(cfg, target, s.size, lambda off, s=s: s.stream(off, cfg, cancel, meter), @@ -1072,11 +1074,12 @@ def pc_extract_job(job, srcs, cancel): cfg = cfg_snapshot() cfg["_limit_bps"] = live_limit_bps log = lambda m: jlog(job, m) # noqa: E731 - exe = E.find_7z(cfg.get("sevenzip_path")) - if not exe: + names = [s.name for s in srcs] + tar = any(E.is_tar(n) for n in names) + exe = None if tar else E.find_7z(cfg.get("sevenzip_path")) + if not tar and not exe: raise E.PipeError("Para descomprimir en el PC hace falta 7-Zip (gratis, 7-zip.org). Instalalo, " "o pon la ruta de 7z.exe en Ajustes, o elige 'Descomprimir en la PS5'.") - names = [s.name for s in srcs] folder = os.path.join(pc_temp_root(cfg), E.safe_name(E.set_key(srcs[0].name))) dl, up = Meter(), Meter() phase = {"dl": True} @@ -1098,6 +1101,9 @@ def pc_extract_job(job, srcs, cancel): speed_label="Descarga al PC", sent_label="Bajado al PC", pc_step="bajar") local, created = fetch_to_pc(job, srcs, cfg, cancel, dl, folder) first = local[E.first_volume(names)] + if tar: + phase["dl"] = False + return pc_tar_job(job, srcs, cfg, cancel, local[names[0]], created, folder, up) # 2) Leer el indice (con contrasena si hace falta) setj(job, phase="Leyendo el contenido del comprimido", speed_label="", sent_label="", @@ -1292,6 +1298,60 @@ def ftp_place(job, info, dest, cfg): pass +def pc_tar_job(job, srcs, cfg, cancel, path, created, folder, up): + """.tar / .tar.gz / .tar.bz2 / .tar.xz: se descomprime en el PC con Python (sin 7-Zip).""" + staging = "%s/extract/%s" % (WORK_ROOT, job["id"]) + total = os.path.getsize(path) + sig = "tar|%s|%d" % (os.path.basename(path), total) + st = _pcx_state(job) + skip = int(st.get("done") or 0) if st.get("sig") == sig else 0 + bf = E.BFpilot(cfg) + if skip: + try: + if not bf.alive() or not bf.exists(staging): + skip = 0 + except Exception: + skip = 0 + free = free_space(bf) + if free is not None: + jlog(job, "Espacio libre en la PS5: %s" % human(free)) + if free < margin_bytes(): + raise E.PipeError("No hay sitio en la PS5: quedan %s libres y el margen es %s. Libera espacio " + "y pulsa Reintentar." % (human(free), human(margin_bytes()))) + jlog(job, "Descomprimiendo el .tar en el PC y enviando a la PS5") + setj(job, status="enviando", total=total, sent=0, pc_step="enviar", sent_label="Leído del comprimido", + speed_label="Velocidad (comprimido)", phase="Descomprimiendo en el PC y enviando a la PS5") + last = {"v": 0, "t": 0.0} + + def progress(v, tot, name): + if v > last["v"]: + up(v - last["v"]) + last["v"] = v + now = time.time() + if now - last["t"] > 0.5: + last["t"] = now + setj(job, sent=v, phase="Descomprimiendo en el PC y enviando: %s" % name.rsplit("/", 1)[-1][-60:]) + + def on_file(n): + _pcx_save(job, {"sig": sig, "done": n}) + watch = start_space_watch(job, bf, cancel, "el envio") + try: + nfiles, nbytes, params = E.stream_extract_tar(path, staging, cfg, cancel, lambda m: jlog(job, m), + progress, on_file, skip) + finally: + watch.set() + setj(job, sent=total) + jlog(job, "Enviado ya descomprimido: %d archivos, %s" % (nfiles, human(nbytes))) + games = [] + for pj, raw in params.items(): + root = pj[:-len("sce_sys/param.json")].rstrip("/") + if any(root == g["root"] or root.startswith(g["root"] + "/") for g in games if g["root"]): + continue + games.append({"root": root, "tid": E.title_id(raw.decode("utf-8", "replace")) or E.title_id(root)}) + return {"mode": "pcx", "staging": staging, "hint": E.display_name(srcs[0].name), "games": games, + "pc_files": created, "pc_folder": folder if created else ""} + + def finish_pc_extract(job, info, bf, dest, cancel, cfg): staging = info["staging"] setj(job, status="colocando", phase="Colocando en su sitio") diff --git a/bg.js b/bg.js new file mode 100644 index 0000000..045c53b --- /dev/null +++ b/bg.js @@ -0,0 +1,71 @@ +const EN = !(navigator.language || "es").toLowerCase().startsWith("es"); +// PS5 Directo - captura de enlaces. +// Cuando el navegador empieza a descargar un archivo comprimido o paquete (.rar, .7z, .zip, .pkg...), +// manda el enlace FINAL (despues de redirecciones) a PS5 Directo y cancela la descarga. +// Si PS5 Directo no esta abierto, no toca nada: la descarga sigue normal. + +const WANTED_FILE = /\.(part\d+\.rar|rar|r\d{2,3}|7z(\.\d{3})?|zip|z\d{2}|\d{3}|pkg|exfat|ffpkg|ffpfsc?|ufs)$/i; +const PORTS = [8777, 8778, 8779]; + +async function settings() { + return chrome.storage.local.get({ enabled: true, captured: 0 }); +} + +async function findApp() { + for (const port of PORTS) { + try { + const r = await fetch(`http://127.0.0.1:${port}/api/ext/ping`, { cache: "no-store" }); + if (r.ok) { + const j = await r.json(); + if (j.app === "PS5 Directo") return { port, version: j.version }; + } + } catch (e) { /* no esta en ese puerto */ } + } + return null; +} + +function fileName(item) { + const f = (item.filename || "").split(/[\\/]/).pop(); + if (f) return f; + try { return decodeURIComponent(new URL(item.finalUrl || item.url).pathname.split("/").pop()); } + catch (e) { return ""; } +} + +async function handle(item) { + const cfg = await settings(); + if (!cfg.enabled) return; + const url = item.finalUrl || item.url; + if (!/^https?:/i.test(url)) return; + const name = fileName(item); + const path = url.split("?")[0]; + if (!WANTED_FILE.test(name) && !WANTED_FILE.test(path)) return; // no es un archivo que nos interese + const app = await findApp(); + if (!app) { // PS5 Directo cerrado: no tocar + chrome.action.setBadgeText({ text: "off" }); + return; + } + try { + const r = await fetch(`http://127.0.0.1:${app.port}/api/ext/capture`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ url, original: item.url, name }) + }); + if (!r.ok) return; + } catch (e) { return; } + try { await chrome.downloads.cancel(item.id); } catch (e) {} + try { await chrome.downloads.erase({ id: item.id }); } catch (e) {} + const n = (cfg.captured || 0) + 1; + await chrome.storage.local.set({ captured: n, last: name }); + chrome.action.setBadgeBackgroundColor({ color: "#2563eb" }); + chrome.action.setBadgeText({ text: String(n % 1000) }); + chrome.notifications.create({ + type: "basic", iconUrl: "icon128.png", title: EN ? "Sent to PS5 Directo" : "Enviado a PS5 Directo", + message: (name || (EN ? "Link" : "Enlace")) + (EN ? " — not downloaded to the PC." : " — no se descarga en el PC.") + }); +} + +// Cuando ya se sabe el nombre del archivo y el enlace final (tras las redirecciones) +chrome.downloads.onDeterminingFilename.addListener((item, suggest) => { + suggest(); // no cambiamos el nombre + handle(item); +}); diff --git a/download b/download new file mode 100644 index 0000000..b3ddd3e --- /dev/null +++ b/download @@ -0,0 +1,4 @@ +__pycache__/ +*.pyc +.backup/ +*.nuevo diff --git a/engine.py b/engine.py index 538e763..afe6844 100644 --- a/engine.py +++ b/engine.py @@ -13,6 +13,7 @@ import ftplib import json import math import os +import posixpath import re import socket import ssl @@ -40,7 +41,12 @@ class PipeError(Exception): # --------------------------------------------------------------------------- ARCHIVE_RE = re.compile( - r"\.(part\d+\.rar|rar|r\d{2,3}|7z|7z\.\d{3}|zip|z\d{2})$", re.I) + r"\.(part\d+\.rar|rar|r\d{2,3}|7z|7z\.\d{3}|zip|z\d{2}|tar|tar\.gz|tgz|tar\.bz2|tbz2?|tar\.xz|txz)$", re.I) +TAR_RE = re.compile(r"\.(tar|tar\.gz|tgz|tar\.bz2|tbz2?|tar\.xz|txz)$", re.I) + + +def is_tar(name): + return bool(TAR_RE.search(name or "")) SPLIT_RAW_RE = re.compile(r"^(?P.+)\.(?P\d{3})$") IMAGE_EXTS = (".exfat", ".ffpkg", ".ffpfs", ".ffpfsc", ".ufs") @@ -48,6 +54,7 @@ IMAGE_EXTS = (".exfat", ".ffpkg", ".ffpfs", ".ffpfsc", ".ufs") def display_name(name): """Nombre sin la parte de volumen (conserva mayusculas).""" for pat in (r"\.part\d+\.rar$", r"\.7z\.\d{3}$", r"\.r\d{2,3}$", r"\.z\d{2}$", + r"\.tar\.(gz|bz2|xz)$", r"\.(tgz|tbz2?|txz|tar)$", r"\.rar$", r"\.7z$", r"\.zip$", r"\.\d{3}$"): new = re.sub(pat, "", name, flags=re.I) if new != name: @@ -63,7 +70,8 @@ def set_key(name): """Nombre comun de un conjunto de volumenes (para agruparlos).""" n = name for pat in (r"\.part\d+\.rar$", r"\.7z\.\d{3}$", r"\.r\d{2,3}$", - r"\.z\d{2}$", r"\.rar$", r"\.7z$", r"\.zip$"): + r"\.z\d{2}$", r"\.tar\.(gz|bz2|xz)$", r"\.(tgz|tbz2?|txz|tar)$", + r"\.rar$", r"\.7z$", r"\.zip$"): new = re.sub(pat, "", n, flags=re.I) if new != n: return new.lower() @@ -529,10 +537,94 @@ class FolderSource: return self +class FtpSource: + """Un archivo en otro servidor FTP (un NAS, por ejemplo): ftp://usuario:clave@host:puerto/ruta""" + kind = "url" + + def __init__(self, url): + self.original = url.strip() + u = urllib.parse.urlparse(self.original) + self.host = u.hostname or "" + self.port = u.port or 21 + self.user = urllib.parse.unquote(u.username or "anonymous") + self.pw = urllib.parse.unquote(u.password or "") + self.path = urllib.parse.unquote(u.path or "/") + self.name = safe_name(posixpath.basename(self.path) or "archivo") + self.size = -1 + self.ranges = True + + def _connect(self): + f = ftplib.FTP() + f.encoding = "utf-8" + f.connect(self.host, self.port, timeout=30) + f.login(self.user, self.pw) + f.set_pasv(True) + f.voidcmd("TYPE I") + return f + + def probe(self): + try: + f = self._connect() + except Exception as e: + raise PipeError("No puedo conectar con el FTP %s:%s (%s)" % (self.host, self.port, e)) + try: + s = Ftp.size(f, self.path) + if s is None: + raise PipeError("No existe en el FTP: %s" % self.path) + self.size = s + finally: + try: + f.quit() + except Exception: + pass + return self + + def stream(self, offset, cfg, cancel, meter): + tries = 0 + while True: + f = None + try: + f = self._connect() + conn = f.transfercmd("RETR " + self.path, rest=offset or None) + with conn: + while True: + if cancel.is_set(): + raise Cancelled() + data = conn.recv(MiB) + if not data: + break + offset += len(data) + tries = 0 + meter(len(data)) + yield data + try: + f.voidresp() + except Exception: + pass + if self.size >= 0 and offset < self.size: + raise PipeError("el FTP corto la descarga") + return + except (Cancelled, GeneratorExit): + raise + except Exception as e: + tries += 1 + if tries > int(cfg.get("retries", 8)): + raise PipeError("Fallo al leer del FTP %s: %s" % (self.host, e)) + time.sleep(min(30, 2 * tries)) + finally: + if f is not None: + try: + f.close() + except Exception: + pass + + def make_source(text): text = text.strip().strip('"') if re.match(r"^https?://", text, re.I): return UrlSource(text) + if re.match(r"^ftp://", text, re.I): + return FtpSource(text) if os.path.isdir(text): return FolderSource(text) return FileSource(text) @@ -577,16 +669,21 @@ def _ftp_sizes(f, path): return out -def upload_tree(cfg, src, remote_root, cancel, log, progress): +def upload_tree(cfg, src, remote_root, cancel, log, progress, workers=None): """Manda una FolderSource a remote_root. Salta los archivos que ya estan con el mismo tamano, continua los que se cortaron (mas pequenos) y vuelve a mandar los demas. - progress(bytes_hechos, ruta_actual). Devuelve (enviados, saltados, continuados).""" + Usa varias conexiones a la vez (cfg parallel_files). progress(bytes_hechos, ruta_actual). + Devuelve (enviados, saltados, continuados).""" + import queue by_dir = {} for rel, size in src.files: d, _, n = rel.rpartition("/") by_dir.setdefault(d, []).append((n, size, rel)) - done = 0 - sent = skipped = resumed = 0 + workers = max(1, min(4, int(workers or cfg.get("parallel_files", 2) or 1))) + lock = threading.Lock() + st = {"done": 0, "sent": 0, "skipped": 0, "resumed": 0, "err": None} + tasks = queue.Queue() + # 1) una sola conexion: crear carpetas y ver que hay ya en la consola w = _FtpWriter(cfg, cancel, log) try: w.mkdir(remote_root) @@ -597,40 +694,73 @@ def upload_tree(cfg, src, remote_root, cancel, log, progress): w.mkdir(rdir) have = w._retry(lambda: ftp_sizes(w.f, rdir)) or {} for name, size, rel in by_dir[d]: - if cancel.is_set(): - raise Cancelled() - rpath = rdir + "/" + name got = have.get(name) if got == size: - skipped += 1 - done += size - progress(done, rel) + st["skipped"] += 1 + st["done"] += size continue offset = got if (got is not None and 0 < got < size) else 0 - if offset: - resumed += 1 - log("Continuando %s desde %s MB" % (rel, offset // MiB)) - local = os.path.join(src.path, *rel.split("/")) - base = done - w.begin(rpath, offset) - with open(local, "rb") as fh: - fh.seek(offset) - pos = offset - while True: - if cancel.is_set(): - raise Cancelled() - chunk = fh.read(4 * MiB) - if not chunk: - break - w.write(chunk) - pos += len(chunk) - progress(base + pos, rel) - w.end(size) - done = base + size - sent += 1 - return sent, skipped, resumed + tasks.put((rdir + "/" + name, rel, size, offset)) finally: w.close() + progress(st["done"], "") + if tasks.empty(): + return 0, st["skipped"], 0 + + # 2) varias conexiones subiendo archivos a la vez + def worker(): + ww = _FtpWriter(cfg, cancel, log) + try: + while st["err"] is None: + try: + rpath, rel, size, offset = tasks.get_nowait() + except queue.Empty: + return + if cancel.is_set(): + raise Cancelled() + if offset: + with lock: + st["resumed"] += 1 + log("Continuando %s desde %s MB" % (rel, offset // MiB)) + local = os.path.join(src.path, *rel.split("/")) + ww.begin(rpath, offset) + with lock: + st["done"] += offset # lo que ya habia en la consola cuenta como hecho + pos = offset + with open(local, "rb") as fh: + fh.seek(offset) + while True: + if cancel.is_set() or st["err"] is not None: + raise Cancelled() + chunk = fh.read(2 * MiB) + if not chunk: + break + ww.write(chunk) + pos += len(chunk) + with lock: + st["done"] += len(chunk) + d = st["done"] + progress(d, rel) + ww.end(size) + with lock: + st["sent"] += 1 + except Exception as e: + with lock: + if st["err"] is None: + st["err"] = e + finally: + ww.close() + + ths = [threading.Thread(target=worker, daemon=True) for _ in range(min(workers, tasks.qsize()))] + for t in ths: + t.start() + for t in ths: + t.join() + if st["err"] is not None: + if cancel.is_set() or isinstance(st["err"], Cancelled): + raise Cancelled() + raise st["err"] + return st["sent"], st["skipped"], st["resumed"] def ftp_download(cfg, remote, local, cancel, progress, size=None): @@ -1402,3 +1532,76 @@ def stream_extract_7z(exe, archive, entries, password, remote_root, cfg, cancel, proc.kill() except Exception: pass + + +class _CountReader: + """Envuelve un archivo y cuenta lo leido (para el progreso del .tar.gz).""" + def __init__(self, f): + self.f, self.n = f, 0 + + def read(self, k=-1): + d = self.f.read(k) + self.n += len(d) + return d + + +def stream_extract_tar(path, remote_root, cfg, cancel, log, progress, on_file=None, skip=0): + """Descomprime un .tar / .tar.gz / .tar.bz2 / .tar.xz del PC sobre la marcha y sube cada + archivo a remote_root. progress(bytes_del_comprimido_leidos, total_comprimido, ruta). + skip: miembros ya subidos antes (se leen y se descartan). + Devuelve (archivos, bytes, {ruta de sce_sys/param.json: contenido}).""" + import tarfile + total = os.path.getsize(path) + nfiles = nbytes = 0 + params = {} + w = _FtpWriter(cfg, cancel, log) + try: + with open(path, "rb") as raw: + cr = _CountReader(raw) + with tarfile.open(fileobj=cr, mode="r|*") as tf: + for i, m in enumerate(tf): + if cancel.is_set(): + raise Cancelled() + parts = [x for x in m.name.replace("\\", "/").split("/") if x not in ("", ".")] + if not parts or ".." in parts: + raise PipeError("Ruta peligrosa dentro del comprimido: %s" % m.name) + remote = remote_root + "/" + "/".join(parts) + rel = "/".join(parts) + if m.isfile() and rel.lower().endswith("sce_sys/param.json") and m.size < MiB: + params[rel] = tf.extractfile(m).read() + if i < skip: + continue + w.begin(remote) + w.write(params[rel]) + w.end(m.size) + nfiles += 1 + nbytes += m.size + if on_file: + on_file(i + 1) + continue + if i < skip: + continue + if m.isdir(): + w.mkdir(remote) + elif m.isfile(): + fh = tf.extractfile(m) + w.begin(remote) + while True: + data = fh.read(4 * MiB) + if not data: + break + w.write(data) + progress(cr.n, total, m.name) + w.end(m.size) + nfiles += 1 + nbytes += m.size + else: + log("Me salto %s (enlace o archivo especial)" % m.name) + if on_file: + on_file(i + 1) + progress(cr.n, total, m.name) + except tarfile.TarError as e: + raise PipeError("El .tar esta danado o no es un tar: %s" % e) + finally: + w.close() + return nfiles, nbytes, params diff --git a/icon128.png b/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..85c4fb876599f7850c57e642ff8db4ef6f4d9047 GIT binary patch literal 11923 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 IM6N<$g2>-t-2eap literal 0 HcmV?d00001 diff --git a/icon32.png b/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..ef53dac6f73c3c55ac6243a0f5500c418848bc1b GIT binary patch literal 1816 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 + + + + +PS5 Directo + + + + +
+ +
+

PS5 Directo

+
Envía archivos a tu consola por la red local, sin pasar por el disco del PC
+
+
+ FTP + BFpilot + + + + + + + +
+ + +
+
+

Nueva transferencia

+ + +
Archivos de tu PC: suéltalos en esta página y los busco en tu PC, o arrástralos sobre el icono de PS5 Directo, o clic derecho → Enviar a → PS5 Directo.
+
+ + + Una carpeta se manda tal cual (si tiene sce_sys, como aplicación) y salta lo que ya esté igual en la consola. +
+
+
+ + +
+
+ + + +
+
+ + +
+
+
+ + Si pegas enlaces de varios archivos distintos, los separa solo. «En el PC» usa 7-Zip y manda el contenido ya descomprimido y comprobado (más datos por el Wi-Fi, pero sin BFpilot). +
+
+ +
+
+

Cola

+
+ +
+
+
+
+ +
+
+
+

Archivos de la consola

+
+
+
+
+ + + + + + + +
+
+ + + + + + + + + + + +
+ + + + + + + + + + + + +
NombreTamañoModificadoPermisos
+

+
+
+ +
+
+

Actividad

+

Historial de transferencias terminadas o con error (las últimas 500).

+ +
FechaNombreResultadoTamañoDuraciónDestino
+
+
+ + +

Test de velocidad

+
+

Mide por separado la descarga desde el enlace, el envío del PC a la PS5 y las dos cosas a la vez (unos 30 segundos). Así se sabe de quién es la culpa cuando va lento. No se guarda nada: el archivo de prueba de la PS5 se borra al acabar.

+
+
+
+ + +

Ajustes

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Para incluir la descarga, usa "Test de velocidad" en una transferencia de la cola.

+

El límite se aplica al momento, sin parar nada. Si el espacio libre baja del margen, PS5 Directo para el envío o la descompresión antes de llenar la consola (0 = no vigilar). Con alojamientos que limitan conexiones usa solo 2 por archivo y baja más si el servidor protesta.

+
+ + +
+ + +
+ Descomprimir en el PC +

Alternativa a BFpilot: 7-Zip descomprime en el PC sobre la marcha y la app manda los archivos ya sueltos, comprobando cada uno con su CRC. No escribe nada descomprimido en el PC y en la PS5 solo ocupa el contenido final (sin el RAR al lado). A cambio, por el Wi-Fi viaja todo sin comprimir (puede ser 3-4 veces más) y los enlaces se bajan antes al PC (hace falta sitio para el RAR).

+
+
+
+
+
+
+
+ + + + +
+
+ Extensión para capturar enlaces (Chrome / Edge) +

Con ella, al pulsar Descargar en cualquier web (después del captcha), el enlace de un .rar/.7z/.zip/.pkg va directo aquí y el navegador no descarga nada. Si PS5 Directo está cerrado, la descarga sigue normal.
+ Instalarla (una vez): 1) Abre chrome://extensions (o edge://extensions) · 2) Activa Modo de desarrollador · 3) Cargar descomprimida y elige la carpeta extension de PS5 Directo.

+ +
+
+ Actualizar PS5 Directo +

Elige el .zip de la versión nueva y se instala solo (guarda una copia de la versión actual en la carpeta .backup). Se reinicia y se abre una ventana nueva.

+ + +
+ +
+
+
+ Permisos de las aplicaciones +

Lo que descomprimió BFpilot puede haber quedado sin permiso de ejecución y la PS5 no lo abre (error CE-107750-0). Esto pone permisos 777 a todas las aplicaciones en carpeta. No toca el contenido.

+ +
+
+
+ Limpieza de la PS5 +

Busca en /data/ps5directo restos que ya no usa ninguna transferencia de la cola (partes de trabajos quitados, descompresiones a medias...). Te enseña cuánto ocupa cada cosa antes de borrar.

+ +
+
+
+

Necesitas en la PS5: el servidor FTP (puerto 2121) y BFpilot cargado desde Payload Manager (puerto 5905). Para ir más rápido, con Wi-Fi baja “Trozo” a 2–4 MB.

+
+
+ +
+ + + + + + + + + + + diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..7bc157e --- /dev/null +++ b/logo.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..ed55e58 --- /dev/null +++ b/manifest.json @@ -0,0 +1,11 @@ +{ + "manifest_version": 3, + "name": "PS5 Directo - Capturar enlaces", + "version": "1.0.0", + "description": "Cuando descargas un .rar/.7z/.zip/.pkg, manda el enlace a PS5 Directo en vez de bajarlo al PC.", + "permissions": ["downloads", "storage", "notifications"], + "host_permissions": ["http://127.0.0.1/*"], + "background": { "service_worker": "bg.js" }, + "action": { "default_popup": "popup.html", "default_title": "PS5 Directo", "default_icon": { "16": "icon16.png", "32": "icon32.png" } }, + "icons": { "16": "icon16.png", "48": "icon48.png", "128": "icon128.png" } +} diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..d6b9114 --- /dev/null +++ b/popup.html @@ -0,0 +1,20 @@ + + + + +

PS5 Directo

+
+
Comprobando…
+
+
+Pasa el captcha y pulsa Descargar como siempre: si es un .rar, .7z, .zip, .pkg… y PS5 Directo está abierto, el enlace va a su cuadro de enlaces y el navegador no descarga nada. Si PS5 Directo está cerrado, la descarga sigue normal. + + diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..273579c --- /dev/null +++ b/popup.js @@ -0,0 +1,42 @@ +const EN = !(navigator.language || "es").toLowerCase().startsWith("es"); +const T = EN ? { + capture: "Capture links", checking: "Checking…", reset: "Reset counter", + help: "Pass the captcha and click Download as usual: if it's a .rar, .7z, .zip, .pkg… and PS5 Directo is open, the link goes to its link box and the browser downloads nothing. If PS5 Directo is closed, the download goes ahead normally.", + sent: "Sent", last: "last", connected: "● Connected", to: "to PS5 Directo", closed: "● PS5 Directo is not open", normal: "(downloads will work normally)" +} : { + capture: "Capturar enlaces", checking: "Comprobando…", reset: "Poner contador a 0", + help: null, sent: "Enviados", last: "último", connected: "● Conectado", to: "a PS5 Directo", closed: "● PS5 Directo no está abierto", normal: "(las descargas seguirán normales)" +}; +if (EN) { + document.documentElement.lang = "en"; + document.getElementById("lblEn").textContent = T.capture; + document.getElementById("st").textContent = T.checking; + document.getElementById("reset").textContent = T.reset; + document.getElementById("help").textContent = T.help; +} +async function findApp() { + for (const port of [8777, 8778, 8779]) { + try { + const r = await fetch(`http://127.0.0.1:${port}/api/ext/ping`, { cache: "no-store" }); + if (r.ok) { const j = await r.json(); if (j.app === "PS5 Directo") return j; } + } catch (e) {} + } + return null; +} +(async () => { + const cfg = await chrome.storage.local.get({ enabled: true, captured: 0, last: "" }); + const en = document.getElementById("en"); + en.checked = cfg.enabled; + en.onchange = () => chrome.storage.local.set({ enabled: en.checked }); + document.getElementById("cnt").textContent = + cfg.captured ? `${T.sent}: ${cfg.captured}${cfg.last ? " (" + T.last + ": " + cfg.last + ")" : ""}` : ""; + document.getElementById("reset").onclick = async () => { + await chrome.storage.local.set({ captured: 0, last: "" }); + chrome.action.setBadgeText({ text: "" }); + document.getElementById("cnt").textContent = ""; + }; + const app = await findApp(); + const st = document.getElementById("st"); + if (app) { st.innerHTML = `${T.connected} ${T.to} v${app.version}`; chrome.action.setBadgeText({ text: "" }); } + else st.innerHTML = `${T.closed} ${T.normal}`; +})(); diff --git a/ps5directo.ico b/ps5directo.ico new file mode 100644 index 0000000000000000000000000000000000000000..04a48ee2ba919e119d7de15c57b395706f326b21 GIT binary patch literal 63686 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 KYnH29hx|W6`N*9B literal 0 HcmV?d00001