Add qbit-simple.js: minimal qBittorrent v5.x compatible downloader (no select, no conflict)
This commit is contained in:
parent
86d310deea
commit
908af9d53d
156
qbit-simple.js
Normal file
156
qbit-simple.js
Normal file
@ -0,0 +1,156 @@
|
||||
(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: '<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3a9 9 0 1 0 9 9h-2a7 7 0 1 1-7-7V3Zm1 0v8.59l3.3-3.3 1.4 1.42-5.7 5.7-5.7-5.7 1.4-1.42 3.3 3.3V3h2Z"/></svg>'
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
})();
|
||||
Loading…
Reference in New Issue
Block a user