xuejianxianzun / PixivBatchDownloader

Chrome 扩展,批量下载 Pixiv 的插画和小说。过滤作品、下载时重命名、转换动态图片等。Powerful Pixiv batch downloader. Batch download artworks and novels, filter works, rename when downloading, convert animated images, and more.
https://pixiv.download/
GNU General Public License v3.0
3.48k stars 208 forks source link

Translate post title and description function #398

Closed bropines closed 2 months ago

bropines commented 2 months ago

I wrote a script for Tampermonkey that translates description and title in JS. It wouldn't be a bad idea to add it to the expansion. Here I am using my serverles api for deepl but I think it will be possible to add translator parameters.

// ==UserScript==
// @name         Pixiv Post Title and Description Translator with Single Button and No Duplicates
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Translate Pixiv post titles and descriptions
// @author       Pinus
// @match        https://www.pixiv.net/en/artworks/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    const sourceLang = 'JA';
    const targetLang = 'RU';

    const styleForButton = `
        background-color: #2c2f33;
        color: #00bfff;
        padding: 5px 10px;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 0.875rem;
        font-family: Arial, sans-serif;
        text-align: center;
        display: inline-block;
        margin-top: 8px;
        transition: background-color 0.2s;
    `;

    const styleForTranslatedTitle = `
        margin-top: 10px;
        font-weight: normal;
        color: #C0C0C0;
    `;

    const styleForTranslatedDescription = `
        margin-top: 10px;
        color: #C0C0C0;
    `;

function insertTranslatedText(translatedText, targetElement, isTitle) {
    let translationElement = targetElement.nextElementSibling;
    if (!translationElement || translationElement.className !== "translated-text") {
        translationElement = document.createElement(isTitle ? 'h1' : 'div');
        translationElement.className = "translated-text";
        translationElement.textContent = translatedText;
        if (isTitle) {
            translationElement.style.margin = '0px 0px 8px';
            translationElement.style.color = 'rgb(245, 245, 245)';
            translationElement.style.fontSize = '20px';
            translationElement.style.lineHeight = '24px';
            translationElement.style.fontWeight = 'bold';
        } else {
            translationElement.style = styleForTranslatedDescription;
        }
        targetElement.parentNode.insertBefore(translationElement, targetElement.nextSibling);
    } else {
        translationElement.textContent = translatedText;
    }
}

    function translateText(text, targetElement, isTitle) {
        const apiUrl = 'https://deeplx-vercel-phi.vercel.app/api/translate';
        GM_xmlhttpRequest({
            method: "POST",
            url: apiUrl,
            data: JSON.stringify({ text: text, source_lang: sourceLang, target_lang: targetLang }),
            headers: { "Content-Type": "application/json" },
            onload: function(response) {
                const jsonResponse = JSON.parse(response.responseText);
                if (jsonResponse && jsonResponse.data) {
                    insertTranslatedText(jsonResponse.data, targetElement, isTitle);
                }
            },
            onerror: function(error) {
                console.error("Translation API error:", error);
            }
        });
    }

    function addTranslateButton() {
        const titleElement = document.querySelector('h1.sc-1u8nu73-3.eASOvo');
        const descriptionElement = document.querySelector('p[id^="expandable-paragraph-"]');

        if (titleElement && descriptionElement) {
            const translateButton = document.createElement('button');
            translateButton.textContent = 'Translate';
            translateButton.style = styleForButton;
            translateButton.onclick = function() {
                translateText(titleElement.textContent, titleElement, true);
                translateText(descriptionElement.textContent, descriptionElement, false);
            };

            descriptionElement.parentNode.insertBefore(translateButton, descriptionElement.nextSibling);
        }
    }

    new MutationObserver(function(mutations, observer) {
        if (document.querySelector('p[id^="expandable-paragraph-"]')) {
            addTranslateButton();
            observer.disconnect(); 
        }
    }).observe(document, { childList: true, subtree: true });
})();
bropines commented 2 months ago

It looks something like this image

xuejianxianzun commented 2 months ago

No users have mentioned this requirement, so I have no plans to add this feature now. While this is a useful feature, users may not actually need translation very frequently. There are many works that are not described, or that do not require translation. And users don’t need to translate the description of every open work—sometimes we don’t care what the description says. For me, I installed the Google Translate extension, and when I need to translate, I can select text and translate it. And Chrome also has a translation function in the context menu. There is no advantage if the downloader adds a translation feature - and requires clicking the translate button. image

bropines commented 2 months ago

Well, that’s the fact. I have a lot of translation software, but I’m tired of running it, and it’s also ugly). Then I will close this issue for now. Maybe someday it will be very convenient)

xuejianxianzun commented 2 months ago

ok~