Files
Local-Booru/button_script.user.js
2026-06-06 15:07:26 +03:00

128 lines
6.1 KiB
JavaScript

// ==UserScript==
// @name gelbooru.com Button DW ADD
// @namespace nyakonya_gelbooruocdw_dev
// @match https://gelbooru.com/index.php*
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @version 1.1r
// @author https://t.me/Nyako_TW
// @downloadURL https://git.nekono.su/Nyako/Local-Booru/raw/branch/main/button_script.user.js
// @updateURL https://git.nekono.su/Nyako/Local-Booru/raw/branch/main/button_script.user.js
// @description Adds a one-click button to download the original image on Gelbooru post pages.
// ==/UserScript==
'use strict'; // Рекомендуется оставить для более строгого и безопасного выполнения кода.
// Функция безопасного запуска функций
function safeRun(fn, name) {
try {
fn();
} catch (e) {
console.error(`Ошибка в ${name}:`, e);
}
}
// Функция генерации текстовой конфигурации
function registerTextInput(key, defaultValue, title, promptMessage) {
const currentValue = GM_getValue(key, defaultValue);
const menuText = `⚙️ ${title}: ${currentValue}`;
GM_registerMenuCommand(menuText, () => {
const newValue = prompt(promptMessage, currentValue);
if (newValue !== null) {
GM_setValue(key, newValue.trim());
alert(
`Настройка изменена!\n${title}: ${newValue.trim()}\nОбновите страницу для применения настроек.`
);
location.reload();
}
});
}
// Генерация конфигураций
function config_runner() {
registerTextInput(
'nyakonya_gb_api_root',
'http://127.0.2.1',
'Адрес API',
'Введите базовый URL локального API (например, http://127.0.2.1 или https://booru.loc):'
);
}
// Запуск конфигуратора
safeRun(config_runner, "config_runner");
// 1. Находим ссылку на оригинальное изображение по тексту
const params = new URLSearchParams(window.location.search);
const imageID = params.get("id");
const xpathResult = document.evaluate(
'//a[text()="Original image"]',
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
);
const originalImageLinkElement = xpathResult.singleNodeValue;
if (originalImageLinkElement) {
const imageUrl = originalImageLinkElement.href;
const existingAnchor = document.querySelector('a[onclick*="saveTagSearch"]');
if (existingAnchor) {
const downloadSvgIcon = `
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="2em" height="2em" viewBox="0 0 122.433 122.88" enable-background="new 0 0 122.433 122.88" xml:space="preserve"><g><polygon fill-rule="evenodd" clip-rule="evenodd" points="61.216,122.88 0,59.207 39.403,59.207 39.403,0 83.033,0 83.033,59.207 122.433,59.207 61.216,122.88"/></g></svg>
`;
const newDownloadButton = document.createElement('a');
newDownloadButton.id = "nyakonya-gelbooruocdw-geter";
newDownloadButton.title = "Download original image";
newDownloadButton.innerHTML = downloadSvgIcon;
newDownloadButton.className = existingAnchor.className;
newDownloadButton.style.cssText = existingAnchor.style.cssText;
existingAnchor.parentNode.insertBefore(newDownloadButton, existingAnchor.nextSibling);
const searchBox = document.getElementById("tags-search");
if (searchBox) {
searchBox.style.width = "calc(100% - 380px)";
}
console.log('Кнопка для скачивания добавлена:', newDownloadButton);
newDownloadButton.addEventListener('click', (event) => {
event.preventDefault(); // Отменяем стандартное действие ссылки
// Получаем настроенный пользователем корневой путь
const apiRoot = GM_getValue('nyakonya_gb_api_root', 'http://127.0.2.1');
// Формируем корректный URL для запроса к dw_api
const apiUrl = apiRoot.endsWith('/') ? `${apiRoot}dw_api` : `${apiRoot}/api`;
console.log(`Отправка URL на локальный API: ${imageUrl} (Endpoint: ${apiUrl})`);
const originalOutline = newDownloadButton.style.outline;
newDownloadButton.style.outline = "2px solid yellow"; // Статус "в процессе"
GM_xmlhttpRequest({
method: "POST",
url: apiUrl,
headers: {
"Content-Type": "application/json"
},
data: JSON.stringify({ id: imageID , type: "download"}),
onload: function(response) {
console.log('Ответ от API:', response.responseText);
newDownloadButton.style.outline = "2px solid green"; // Успех
setTimeout(() => { newDownloadButton.style.outline = originalOutline; }, 2000);
},
onerror: function(response) {
console.error('Ошибка при отправке на API:', response);
newDownloadButton.style.outline = "2px solid red"; // Ошибка
alert('Не удалось отправить на локальный загрузчик. Убедитесь, что Python-скрипт запущен и вы приняли самоподписанный сертификат в браузере. Подробности в консоли (F12).');
setTimeout(() => { newDownloadButton.style.outline = originalOutline; }, 5000);
}
});
});
} else {
console.warn('Исходный элемент для вставки кнопки (saveTagSearch) не найден.');
}
}