GolinksPRO Download Manager
  1. Головна
  2. Довідка
  3. Архітектура

Архітектура

How GolinksPRO Download Manager's pieces fit together.

Крейтси

Шлях Крейт Роль
crates/engine mdm-engine Завантажує один файл через HTTP(S) або FTP(S): зондування, планувальник сегментів, робочі з'єднання, стан відновлення, обмеження для кожного хоста, обмежувач швидкості, контрольні суми, проксі-скрипти
crates/app mdm-app Настільна програма (misterdownloadmanager.exe, egui): список, категорії, черги, планувальник, діалоги, трей, налаштування
crates/cli mdm-cli Завантаження без інтерфейсу з прогресом (get, resume), відео, торренти та команди API автоматизації: бібліотека, яку запускає програма (misterdownloadmanager --cli …), і misterdownloadmanager-cli, невеликий запускник, який запускає її з тими ж аргументами, терміналом та кодом виходу
crates/mcp mdm-mcp Сервер MCP (misterdownloadmanager-mcp): помічники ШІ перераховують, додають та контролюють завантаження запущеної програми через API автоматизації
crates/remote mdm-remote Віддалене керування (#141): HTTPS-сервер, який використовує підключений телефон або комп'ютер у локальній мережі (його сторінка, коди сполучення, токени пристроїв, самопідписаний сертифікат); кожен запит стає командою API автоматизації, на яку відповідає програма
crates/nmhost mdm-nmhost Нативний хост обміну повідомленнями браузера: приймає перехоплені завантаження від розширення та передає їх програмі
crates/ipc mdm-ipc Одноекземплярний канал (локальний сокет, захищений токеном), папка даних та правила перехоплення, що використовуються програмою та хостом
crates/debrid mdm-debrid Облікові записи дебрид-сервісів (#44): офіційні API сервісів (Real-Debrid, AllDebrid, Premiumize) перетворюють посилання файлового хостингу на пряме посилання, яке завантажує рушій
crates/extract mdm-extract Розпакування архівів (#37): zip, tar, gz та xz у процесі; 7z та RAR за допомогою встановленого 7-Zip, запущеного як окрема програма
crates/geo mdm-geo Розташування сервера завантаження (#140): таблиця діапазонів IP-адрес за країнами, створена на основі даних DB-IP Lite (tools/geo/build.py), шукається лише на цьому комп’ютері, а також прапори країн
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 Звіти про збої та зависання: процес монітора, позапроцесні мінідампи, символізовані стеки, текст звіту та журнали випусків (crash-reports.md)
crates/torrent mdm-torrent BitTorrent та магнітні посилання через librqbit
crates/labserver mdm-labserver Сервер HTTP Range з журналом запитів та впровадженням помилок, а також сервер FTP/FTPS з власними помилками, для тестів та бенчмарків
extension/ — Розширення Chromium (MV3) та Firefox
docs/ — Посібник користувача та навчальні матеріали, цей файл, дані бенчмарків; вебсайт робить посібник своїми сторінками довідки, які відкриває Довідка
website/ — Власні сторінки misterdownloadmanager.com (головна, завантаження, функції, теми, FAQ); tools/website/build.py додає довідку з docs/ та новини з CHANGELOG 22 мовами, а GitHub Pages публікує їх

Залежності вказують всередину: app, cli, mcp, nmhost та remote використовують engine та ipc; рушій нічого не знає про інтерфейс користувача. Програма бачить рушій лише через його події (прогрес, знімки таблиці сегментів, завершено, не вдалося).

Рушій

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

Коли кожен сегмент завершено, файл частини перевіряється на відповідність очікуваному розміру та перейменовується на місце; дата файлу може відповідати даті сервера.

Перший запит на завантаження (get) переходить за перенаправленнями та сторінками, які самі ведуть до файлу (оновлення сторінки очікування). Сайти, чиї посилання не є адресою файлу, мають модуль у sites/ (Google Drive: sites/gdrive.rs): він перетворює посилання на адресу файлу, читає власні сторінки сайту (форму підтвердження, сторінку помилки) та називає його відмови (Error::Refused), за допомогою чистих функцій, протестованих без мережі. Лабораторний сервер відтворює такий сайт на його реальних хост-іменах для наскрізних тестів (labserver/src/drive.rs).

FTP та FTPS (ftp.rs) проходять через той самий планувальник, робочі процеси та стан: сегмент — це REST + RETR у сесії керування замість діапазонного GET, SIZE та MDTM замінюють заголовки, а сесії об'єднуються для кожного завантаження та повторно використовуються між сегментами.

Програма

Одне вікно egui, намальоване за фіксованими піксельними координатами, плюс один безпосередній вікно перегляду для кожного діалогового вікна. app.rs зберігає стан (завантаження, черги, налаштування, вибір у списку) і перетворює команди меню, панелі інструментів, клавіш та IPC на дії. Кожне діалогове вікно є окремим модулем і повертає Outcome (відкрите, закрите, виконане зі значенням). Виклики лише для Windows обмежені win32.rs, а їхні аналоги для Linux і macOS — unix.rs (починаючи з сесії, хоста браузерів, звуків, показу в папці, обробника збоїв); кожен інший файл є безпечним, портативним Rust. Шрифти надходять із системи: папка Fonts у Windows, системні шрифти macOS, fontconfig у Linux (theme.rs). У Windows латинський, грецький та кириличний текст малюється за допомогою DirectWrite у класичному режимі GDI (win32.rs, через хук растеризатора гліфів egui), тому підказка форми кожної літери та ширина в цілих пікселях поєднуються; інші скрипти формуються та малюються за допомогою egui.

Теми

Кожен колір і розмір, яким малюється елемент керування, походить від активної теми (#45). Тема — це світла та темна палітра, метрики, стилі елементів керування та стиль іконок (palette.rs):

  • Ролі палітри. palette.rs оголошує кожну роль зі стабільним ключем ("button.hot", "list.row", "caption"…), описом та світлими й темними значеннями класичного вигляду, записаними повністю (класичний вигляд не є похідним). Спільні художники (winui.rs, chrome.rs, list.rs, scrollbar.rs) читають їх через theme::colors() та theme::metrics() і визначають стани кожного елемента керування на їх основі; жоден код малювання не містить власного кольору.
  • Похідні палітри. derive.rs створює цілу палітру з кількох початкових значень (фон, поверхня, текст, акцент…), змішуючи всі інші ролі в OKLab та зберігаючи контраст WCAG (4.5:1 для тексту, 3:1 для країв); «Висока контрастність» посилює кожен край зверху. native.rs ініціює власну тему з системного акценту та контрасту (налаштування Windows, портал freedesktop на Linux, акцент 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).
  • Файли тем. themefile.rs читає TOML або JSON з папки даних themes (один файл, або <id>/theme.toml з іконками поруч). Файл називає лише те, що він змінює; решта походить від теми, яку він inherits (ідентифікатор вбудованої теми або інший файл, класичний вигляд за замовчуванням), по ланцюжку, в якому відхиляється цикл. Невідомі ключі є попередженнями, а не помилками. Вбудовані стильові теми також є такими файлами, що містяться в програмі (crates/app/assets/themes).
  • Набори іконок. themeicons.rs малює іконки теми (названі за призначенням: tb-add-url, cat-music…, SVG або PNG розміром 16, 24, 32 та 48 пікселів, -symbolic іконки, забарвлені в колір тексту) там, де класичний вигляд малює свої власні; якщо набір не має потрібної іконки, залишається класична іконка.

Розташування елементів керування у вікні залишається його макетом. Так само і іконки перед іменами файлів (fileicons.rs): системні списки зображень оболонки Windows, Finder macOS (NSWorkspace), тема іконок робочого столу Linux (xdgicons.rs, shared-mime-info та Icon Theme Specification). Кожен тип шукається один раз для кожного розміру пікселів у фоновому потоці. Іконки Tango (в комплекті) використовуються, доки системна іконка не буде готова, і скрізь, де система не має жодної.

Малювання

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.

Вигляд → Розмір інтерфейсу (scale.rs, #262) — це коефіцієнт масштабування egui над власним масштабом дисплея: кожне вікно розташовується в точках, тому воно відкривається настільки більшим; вікно, більше за екран, прокручується.

Дані

Список завантажень та налаштування зберігаються атомарно в папці даних (downloads.json): %APPDATA%\misterdownloadmanager\ на Windows, ~/.local/share/misterdownloadmanager на Linux, ~/Library/Application Support/misterdownloadmanager на macOS, папка data поруч із портативною копією або MDM_DATA_DIR (mdm_ipc::data_dir). Хост браузера читає той самий файл для правил перехоплення, тому зміна в Параметрах застосовується до наступного перехопленого завантаження.

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.

Розташування сервера завантаження (#140) — це країна адреси, до якої він підключився, знайдена в таблиці mdm-geo на цьому комп'ютері (countries.rs називає її мовою інтерфейсу); завдання випуску знову створює таблицю з даних за місяць (tools/geo/build.py --release).

Інтеграція з браузером

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

Розширення запитує у хоста, які типи файлів приймати, перевіряє кожне завантаження на відповідність їм і скасовує завантаження браузера лише після того, як програма його прийняла; інакше браузер зберігає його, а розширення пояснює причину.

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.

Віддалене керування

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

--headless(headless.rs, #157) запускає той самий App без eframe: цикл викликає його tick (те, що logic запускає в кожному кадрі) на голому egui::Context, розбудженому каналом команд, і ніколи його ui; команди додаються, як їх додає пульт дистанційного керування (без вікна). Dockerfile та docker/ (Compose, шаблон Unraid) запускають його на сервері (server.md).

Сервер працює на середовищі виконання Tokio програми, по одному слухачу на кожну адресу локальної мережі. Кожен запит перевіряється (Host, Origin, токен), перетворюється на mdm_ipc::Command, позначений remote (поле, яке не може бути встановлене рядком запиту), і передається програмі через той самий канал, що й командний рядок; програма відповідає на нього в наступному кадрі, як вона відповідає на API автоматизації. Його сторінка вбудована (crates/remote/web), а тексти надходять з каталогів програми (remote.rs).

Переклади

Кожен текст, який показує інтерфейс користувача, проходить через crate::i18n (каталоги craft-i18n, i18n/<locale>.tsv). tools/i18n/extract.py перебудовує i18n/en.tsv з джерела, з приміткою для перекладачів до кожного тексту (що це, де відображається, його заповнювачі). tools/i18n/translate.py заповнює те, чого бракує в інших каталогах (рядки, позначені #, machine), дотримуючись стильового посібника кожної мови (i18n/style/) та глосарію; рядок, перевірений людиною, ніколи не замінюється, а CI (reviewed_guard.py) відхиляє зміну, яка його видаляє. Вебсайт має власні каталоги (i18n/site/, tools/website/translate_site.py).

Зображення

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).

Учасники

tools/contributors.pyчитає, хто відкрив запити на витягування та проблеми, а також хто коментував, з публічного API GitHub (розробник, Клод та боти виключені) для кожного місця, де їм дякують: домашня сторінка вебсайту, /contributors.html та кожен випуск на сторінці «Новини» (build.py, у кожній збірці), примітки до кожного випуску (release.yml, люди, активні з попереднього випуску) та файл README (python tools/contributors.py readme під час підготовки кожного випуску: його круглі фотографії завантажуються в art/contributors/, оскільки GitHub не може округлити зображення у файлі README).

Тести та бенчмарки

cargo testзапускає модульні тести та наскрізні завантаження проти mdm-labserver з впровадженими помилками (повільні, відкинуті та відхилені з'єднання, сервери без діапазонів, файли, що змінюються). tools/bench запускає опубліковане порівняння швидкості; його необроблені дані знаходяться в docs/bench/.

Безкоштовно, з відкритим кодом, без реклами, без пробного періоду.

Download GolinksPRO Download Manager