GolinksPRO Download Manager
  1. Inicio
  2. Ayuda
  3. Arquitectura

Arquitectura

How GolinksPRO Download Manager's pieces fit together.

Crates

Ruta Crate Función
crates/engine mdm-engine Descarga un archivo por HTTP(S) o FTP(S): sondeo, planificador de segmentos, trabajadores de conexión, estado de reanudación, límites por host, limitador de velocidad, sumas de comprobación, scripts de proxy
crates/app mdm-app La aplicación de escritorio (misterdownloadmanager.exe, egui): lista, categorías, colas, planificador, diálogos, bandeja, ajustes
crates/cli mdm-cli Descargas sin interfaz con progreso (get, resume), vídeos, torrents y los comandos de la API de automatización: una biblioteca que ejecuta el programa de la aplicación (misterdownloadmanager --cli …), y misterdownloadmanager-cli, un pequeño lanzador que la inicia con los mismos argumentos, terminal y código de salida
crates/mcp mdm-mcp El servidor MCP (misterdownloadmanager-mcp): los asistentes de IA listan, añaden y controlan las descargas de la aplicación en ejecución a través de la API de automatización
crates/remote mdm-remote El control remoto (#141): el servidor HTTPS que usa un teléfono o un ordenador emparejado en la red local (su página, códigos de emparejamiento, tokens de dispositivo, el certificado autofirmado); cada solicitud se convierte en un comando de la API de automatización que la aplicación responde
crates/nmhost mdm-nmhost El host de mensajería nativa del navegador: toma las descargas capturadas de la extensión y las entrega a la aplicación
crates/ipc mdm-ipc El canal de instancia única (un socket local protegido por token), la carpeta de datos y las reglas de captura compartidas por la aplicación y el host
crates/debrid mdm-debrid Cuentas Debrid (#44): las API oficiales de los servicios (Real-Debrid, AllDebrid, Premiumize) convierten un enlace de un servidor de archivos en uno directo que el motor descarga
crates/extract mdm-extract Extracción de archivos (#37): zip, tar, gz y xz en proceso; 7z y RAR a través de 7-Zip instalado, ejecutado como programa independiente
crates/geo mdm-geo Ubicación del servidor de una descarga (#140): una tabla de rangos de IP a país construida a partir de los datos Lite de DB-IP (tools/geo/build.py), consultada solo en este equipo, y las banderas de los países
crates/tools mdm-tools Video pages through yt-dlp and ffmpeg, image galleries through gallery-dl (run as separate programs); while a network adapter is chosen, their connections go through a proxy of GDM's on 127.0.0.1 that binds them to it (relay.rs)
crates/crash mdm-crash Informes de fallos y bloqueos: el proceso de monitorización, minivolcados fuera de proceso, pilas simbolizadas, el texto del informe y los registros de la versión (crash-reports.md)
crates/torrent mdm-torrent Enlaces BitTorrent y magnet a través de librqbit
crates/labserver mdm-labserver Un servidor HTTP Range con un registro de solicitudes e inyección de fallos, y un servidor FTP/FTPS con sus propios fallos, para pruebas y puntos de referencia
extension/ — La extensión para Chromium (MV3) y Firefox
docs/ — La guía de usuario y los tutoriales, este archivo, los datos de referencia; el sitio web convierte la guía en sus páginas de ayuda, que se abren con Ayuda
website/ — Las propias páginas de misterdownloadmanager.com (inicio, descarga, características, temas, preguntas frecuentes); tools/website/build.py añade la ayuda de docs/ y las noticias del CHANGELOG, en 22 idiomas, y GitHub Pages las publica

Las dependencias apuntan hacia dentro: app, cli, mcp, nmhost y remote usan engine y ipc; el motor no sabe nada de la interfaz de usuario. La aplicación ve el motor solo a través de sus eventos (progreso, instantáneas de la tabla de segmentos, finalizado, fallido).

Motor

Download
 ├─ probe()              size, resumable?, validators (ETag / Last-Modified), file name
 ├─ Planner (pure)       segment table: when a connection is free, the largest remaining
 │                       part is split in half (planner.rs, tested by random simulation)
 ├─ Worker × N           one HTTP/1.1 connection each, reused across segments; slow ones
 │                       are dropped and their part re-split
 │    └─ writes at its offset into <name>.mdm.part (created sparse)
 ├─ HostLimits           learns how many connections each server accepts
 ├─ Limiter (shared)     per-download and global token buckets
 ├─ State                segment table saved atomically (craft-atomic) for crash-safe resume
 └─ events → channel     Progress, Done, Failed

Cuando cada segmento está hecho, el archivo parcial se comprueba con el tamaño esperado y se renombra en su lugar; la fecha del archivo puede seguir la del servidor.

La primera solicitud de una descarga (get) sigue las redirecciones y las páginas que conducen a un archivo por sí mismas (la actualización de una página de espera). Los sitios cuyos enlaces no son la dirección del archivo tienen un módulo en sites/ (Google Drive: sites/gdrive.rs): este convierte el enlace en la dirección del archivo, lee las propias páginas del sitio (un formulario de confirmación, una página de error) y nombra sus rechazos (Error::Refused), con funciones puras probadas sin red. El servidor de laboratorio simula dicho sitio en sus nombres de host reales para las pruebas de extremo a extremo (labserver/src/drive.rs).

FTP y FTPS (ftp.rs) pasan por el mismo planificador, trabajadores y estado: un segmento es REST + RETR en una sesión de control en lugar de un GET con rango, SIZE y MDTM sustituyen a las cabeceras, y las sesiones se agrupan por descarga y se reutilizan entre segmentos.

Aplicación

Una ventana de egui dibujada en coordenadas de píxeles fijas, más una ventana gráfica inmediata por cada diálogo. app.rs contiene el estado (descargas, colas, configuración, la selección de la lista) y convierte los comandos de menú, barra de herramientas, teclado e IPC en acciones. Cada diálogo es su propio módulo y devuelve un Outcome (abierto, cerrado, completado con un valor). Las llamadas exclusivas de Windows se limitan a win32.rs y sus equivalentes de Linux y macOS a unix.rs (a partir de la sesión, el host de los navegadores, los sonidos, mostrar en carpeta, el controlador de fallos); cualquier otro archivo es Rust seguro y portátil. Las fuentes provienen del sistema: la carpeta Fonts de Windows, las fuentes del sistema de macOS, fontconfig en Linux (theme.rs). En Windows, el texto latino, griego y cirílico se dibuja con DirectWrite en modo GDI-clásico (win32.rs, a través del gancho del rasterizador de glifos de egui), de modo que la forma sugerida y el ancho de píxel completo de cada letra se unen; otros scripts son formados y dibujados por egui.

Temas

Cada color y tamaño con el que se dibuja un control proviene del tema activo (#45). Un tema es una paleta clara y una oscura, métricas, estilos de control y un estilo de icono (palette.rs):

  • Roles de paleta. palette.rs declara cada rol con una clave estable ("button.hot", "list.row", "caption"…), una descripción y los valores claros y oscuros del aspecto clásico, escritos (el aspecto clásico no se deriva). Los pintores compartidos (winui.rs, chrome.rs, list.rs, scrollbar.rs) los leen a través de theme::colors() y theme::metrics() y deciden los estados de cada control a partir de ellos; ningún código de pintura tiene un color propio.
  • Paletas derivadas. derive.rs crea una paleta completa a partir de unas pocas semillas (fondo, superficie, texto, acento…), mezclando todos los demás roles en OKLab y manteniendo el contraste WCAG (4,5:1 para texto, 3:1 para bordes); Contraste alto refuerza cada borde. native.rs siembra el tema Nativo a partir del acento y contraste del sistema (la configuración de Windows, el portal freedesktop en Linux, el acento de macOS).
  • Control styles. palette::Controls names each control's shape (text boxes, check boxes, buttons, progress bars, scroll bars, the focus mark, the title bar); the style themes (Metro, Adwaita, Breeze, Luna, Aero, Aqua) pick theirs, and on Windows GDM then draws the title bar itself (the caption.* roles).
  • Archivos de tema. themefile.rs lee TOML o JSON de la carpeta de datos themes (un archivo, o <id>/theme.toml con iconos al lado). Un archivo nombra solo lo que cambia; el resto proviene del tema que inherits (el ID de uno integrado u otro archivo, el aspecto clásico por defecto), en una cadena en la que se rechaza un ciclo. Las claves desconocidas son advertencias, no errores. Los temas de estilo integrados también son esos archivos, incluidos en el programa (crates/app/assets/themes).
  • Conjuntos de iconos. themeicons.rs dibuja los iconos de un tema (nombrados por su función: tb-add-url, cat-music…, SVG o PNG a 16, 24, 32 y 48 px, los -symbolic entintados en el color del texto) donde el aspecto clásico dibuja los suyos; una necesidad que el conjunto no tiene mantiene el icono clásico.

La forma en que una ventana coloca sus controles mantiene su diseño. También lo hacen los iconos antes de los nombres de archivo (fileicons.rs): las listas de imágenes del sistema de la shell de Windows, las de macOS Finder (NSWorkspace), el tema de iconos del escritorio de Linux (xdgicons.rs, shared-mime-info y la Icon Theme Specification). Cada tipo se busca una vez por tamaño de píxel, en un hilo en segundo plano. Los iconos de Tango (incluidos) se usan hasta que el icono del sistema esté listo, y donde el sistema no tenga ninguno.

Dibujo

The windows are drawn with OpenGL (eframe's glow) or with the system's own graphics API through eframe's wgpu, with that one backend only: Direct3D 12 on Windows (the default there), Vulkan on Linux, Metal on macOS (choices there; OpenGL stays their default until real graphics cards have tried them, #206). View → Draw with picks one, from the next start. One code path does it on every system (crates/app/src/renderer.rs): when the chosen one can't start, the other one is tried, so the windows always open. A watched start with the system's API leaves a marker until its first frame is drawn: a start that ends before it (a crash inside the driver), one whose first frame doesn't come within 10 seconds (GDM then starts again with OpenGL), or a graphics card lost twice in 10 minutes is remembered with its reason, which the menu shows.

Ver → Tamaño de la interfaz (scale.rs, #262) es el factor de zoom de egui sobre la escala propia de la pantalla: cada ventana se diseña en puntos, por lo que se abre mucho más grande; una más grande que la pantalla se desplaza.

Datos

La lista de descargas y la configuración se guardan atómicamente en la carpeta de datos (downloads.json): %APPDATA%\misterdownloadmanager\ en Windows, ~/.local/share/misterdownloadmanager en Linux, ~/Library/Application Support/misterdownloadmanager en macOS, una carpeta data junto a una copia portátil, o MDM_DATA_DIR (mdm_ipc::data_dir). El host del navegador lee el mismo archivo para las reglas de captura, por lo que un cambio en Opciones se aplica a la siguiente descarga capturada.

Sign-in secrets (debrid accounts, Sites Logins' and the proxy's passwords) live in the system's keychain (secrets.rs, #44): Windows Credential Manager (win32.rs), the Secret Service on Linux or the macOS keychain (unix.rs). The settings keep a keychain:<service>/<scope>/<key> reference in their place, written only once the keychain has confirmed the secret; without a keychain (or with a locked one, never unlocked for GDM) the secret stays in the settings as before.

La ubicación del servidor de una descarga (#140) es el país de la dirección a la que se conectó, buscada en la tabla de mdm-geo en este equipo (countries.rs la nombra en el idioma de la interfaz); el trabajo de lanzamiento reconstruye la tabla a partir de los datos del mes (tools/geo/build.py --release).

Integración con el navegador

page ──► extension ──native messaging──► mdm-nmhost ──ipc──► app

La extensión pregunta al host qué tipos de archivo tomar, comprueba cada descarga con ellos y cancela la descarga del navegador solo después de que la aplicación la haya aceptado; de lo contrario, el navegador la mantiene y la extensión explica el motivo.

The host serves only GDM's own extension. Its IDs are in one place, mdm_ipc::extension (crates/ipc/src/extension.rs): the unpacked copy's (UNPACKED_ID, from the manifest's public key), the Chrome Web Store's (STORE_ID, signed with the store's own key: pack.ps1 leaves the manifest's key out of the store's copy), the Firefox add-on's (FIREFOX_ID) and its addons.mozilla.org page; the Edge and Opera stores' are placeholders, never served, until the extension is listed there. The host writes each browser's manifest with those IDs, and the app offers the store's copy (Add to Chrome, Add to Firefox) before the unpacked one.

Control remoto

phone ──HTTPS (paired token)──► mdm-remote ──ipc::Sink──► app (answer, remote_add)

--headless(headless.rs, #157) ejecuta el mismo App sin eframe: un bucle llama a su tick (lo que logic ejecuta en cada fotograma) en un egui::Context desnudo, activado por el canal de comandos, y nunca a su ui; los comandos se añaden a medida que el control remoto los añade (sin ventana). Los Dockerfile y docker/ (Compose, plantilla de Unraid) lo ejecutan en un servidor (server.md).

El servidor se ejecuta en el tiempo de ejecución Tokio de la aplicación, un oyente por cada dirección de red local. Cada solicitud se comprueba (Host, Origin, token), se convierte en un mdm_ipc::Command marcado remote (un campo que ninguna línea de solicitud puede establecer) y se entrega a la aplicación a través del mismo canal que la línea de comandos; la aplicación la responde en su siguiente fotograma, como responde a la API de automatización. Su página está integrada (crates/remote/web) y sus textos provienen de los catálogos de la aplicación (remote.rs).

Traducciones

Cada texto que muestra la interfaz de usuario pasa por crate::i18n (catálogos craft-i18n, i18n/<locale>.tsv). tools/i18n/extract.py reconstruye i18n/en.tsv desde la fuente, con una nota para los traductores en cada texto (qué es, dónde se muestra, sus marcadores de posición). tools/i18n/translate.py rellena lo que falta en los otros catálogos (filas marcadas #, machine), siguiendo la guía de estilo de cada idioma (i18n/style/) y el glosario; una fila revisada por una persona nunca se reemplaza, y CI (reviewed_guard.py) falla un cambio que elimina una. El sitio web tiene sus propios catálogos (i18n/site/, tools/website/translate_site.py).

Imágenes

The help pages' pictures (docs/images/help/) come from one list, tools/shots/shots.toml: tools/shots/make.py opens each window through GDM's own /show <window> command line in a test instance off the screen, crops and annotates it from the window's accessibility tree, and writes lossless WebP; make.py check (CI) keeps the list, the pages and the files in step. The published ones are taken on GitHub's Windows runner (docs-shots.yml).

Colaboradores

tools/contributors.pylee quién abrió solicitudes de extracción e incidencias, y quién comentó, de la API pública de GitHub (el encargado del mantenimiento, Claude y los bots excluidos) para cada lugar que les da las gracias: la página de inicio del sitio web, /contributors.html y cada lanzamiento en la página de Novedades (build.py, en cada compilación), las notas de cada lanzamiento (release.yml, las personas activas desde el lanzamiento anterior) y el archivo README (python tools/contributors.py readme en la preparación de cada lanzamiento: sus fotos redondas se confirman en art/contributors/, ya que GitHub no puede redondear una imagen en un README).

Pruebas y puntos de referencia

cargo testejecuta pruebas unitarias y descargas de extremo a extremo contra mdm-labserver con fallos inyectados (conexiones lentas, caídas y rechazadas, servidores sin rangos, archivos cambiantes). tools/bench ejecuta la comparación de velocidad publicada; sus datos brutos están en docs/bench/.

Gratis, código abierto, sin anuncios, sin prueba.

Download GolinksPRO Download Manager