(function () { 'use strict'; var PLUGIN_ID = 'lampa_qbit_simple'; function ready(fn) { if (window.Lampa && Lampa.Storage) fn(); else setInterval(function () { if (window.Lampa && Lampa.Storage) { clearInterval(arguments.callee); fn(); } }, 500); } function storage(name, fallback) { var v = Lampa.Storage.field(name); return (v === undefined || v === null) ? fallback : v; } function notify(text) { if (Lampa.Noty && Lampa.Noty.show) Lampa.Noty.show(text); } function requestForm(url, formData, onSuccess, onError) { var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.onreadystatechange = function () { if (xhr.readyState !== 4) return; if (xhr.status >= 200 && xhr.status < 300) onSuccess(xhr.responseText); else onError(new Error('HTTP ' + xhr.status + ': ' + xhr.responseText)); }; xhr.send(formData); } function loginDirect(baseUrl, done, fail) { var username = storage('qbit_simple_username', 'admin'); var password = storage('qbit_simple_password', ''); if (!username && !password) return done(); var form = new URLSearchParams(); form.set('username', username); form.set('password', password); requestForm(baseUrl + '/api/v2/auth/login', form, function (text) { // qBittorrent v5.x: "Ok." или пустой ответ с 204 var t = String(text).trim(); if (t === '' || t === 'Ok.' || t === 'True.') done(); else fail(new Error('qBittorrent auth: ' + t)); }, fail); } function download(element) { var baseUrl = (storage('qbit_simple_url', 'http://127.0.0.1:8080')).replace(/\/+$/, ''); var magnet = element.MagnetUri || element.magnet || element.downloadUrl || ''; if (!magnet) { notify('Нет magnet-ссылки'); return; } var category = storage('qbit_simple_category', 'lampa'); var sequential = storage('qbit_simple_sequential', true); var firstLast = storage('qbit_simple_first_last', true); loginDirect(baseUrl, function () { var form = new URLSearchParams(); form.set('urls', magnet); if (category) form.set('category', category); if (sequential) form.set('sequentialDownload', 'true'); if (firstLast) form.set('firstLastPiecePrio', 'true'); requestForm(baseUrl + '/api/v2/torrents/add', form, function () { notify('✓ Отправлено в qBittorrent: ' + (element.Title || element.title || 'torrent')); }, function (err) { notify('Ошибка: ' + err.message); }); }, function (err) { notify('Auth ошибка: ' + err.message); }); } function patchSelect() { var original = Lampa.Select.show; Lampa.Select.show = function (params) { if (params && params.items) { var modified = false; params.items.forEach(function (item) { if (item && (item.element && (item.element.MagnetUri || item.element.magnet))) { if (!item.__qbit_added) { item.__qbit_added = true; modified = true; } } }); // Добавляем пункт "Скачать в qBittorrent" в конец var hasMagnet = params.items.some(function (item) { return item && item.element && (item.element.MagnetUri || item.element.magnet); }); if (hasMagnet) { var origOnSelect = params.onSelect; params.onSelect = function (item) { if (item && item.__qbit_download) { var el = params.items.find(function (i) { return i.element && (i.element.MagnetUri || i.element.magnet); }); if (el) download(el.element); return; } if (origOnSelect) origOnSelect.apply(this, arguments); }; params.items.push({ __qbit_download: true, name: '⬇ Скачать в qBittorrent', icon: 'download' }); } } return original.call(this, params); }; } function setupSettings() { Lampa.SettingsApi.addComponent({ component: 'qbit_simple', name: 'qBittorrent', icon: '' }); var fields = [ ['qbit_simple_url', 'input', 'Адрес qBittorrent', 'http://127.0.0.1:8080'], ['qbit_simple_username', 'input', 'Логин', 'admin'], ['qbit_simple_password', 'input', 'Пароль', ''], ['qbit_simple_category', 'input', 'Категория', 'lampa'], ['qbit_simple_sequential', 'trigger', 'Sequential download', true], ['qbit_simple_first_last', 'trigger', 'Первый/последний блок', true] ]; fields.forEach(function (row) { Lampa.SettingsApi.addParam({ component: 'qbit_simple', param: { name: row[0], type: row[1], default: row[3] }, field: { name: row[2] } }); }); } ready(function () { setupSettings(); patchSelect(); console.log('[qbit-simple] Plugin loaded'); }); })();