Direct Image Link E621/926 (AI-fix)

Рипалка ссылок / имён / номеров картинок

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name           Direct Image Link E621/926 (AI-fix)
// @version        2025.08.23
// @description    Рипалка ссылок / имён / номеров картинок
// @match          http*://e621.net/posts*
// @match          http*://e621.net/pool*
// @match          http*://e621.net/favorites*
// @match          http*://e926.net/posts*
// @match          http*://e926.net/pool*
// @match          http*://e926.net/favorites*
// @author         Rainbow-Spike
// @namespace      https://greasyfork.org/users/7568
// @homepage       https://greasyfork.org/ru/users/7568-rainbow-spike
// @icon           https://www.google.com/s2/favicons?domain=e621.net
// @grant          none
// @run-at         document-end
// ==/UserScript==

// Получаем список элементов
const postList = document.querySelectorAll('.thumbnail');

if (postList.length > 0) {
    // Конфигурация параметров
    const config = {
        mode: 2, // 0 - номера постов, 1 - имена файлов, 2 - полные ссылки
        filters: {
            useNegativeList: 1,
            usePositiveList: 1,
            filterDownloaded: 1,
            showTopList: 1,
            showUnderImage: 1
        },
        tags: {
            negative: /\Wcensored|gore|male\/male/,
            positive: /\Wvulva\W?|female_on_top|tribadism|camel_toe|vaginal_mastu/
        },
        styles: {
            negative: 'opacity: 0.5; border: 3px dotted red;',
            neutral: 'opacity: 0.5; border: 3px dashed gray;',
            downloaded: 'opacity: 0.5; border: 16px double green;',
            topList: 'columns: 300px; font-size: 40%; line-height: .25em; max-height: 100px;',
            underImage: 'word-wrap: anywhere;'
        },
	downloadedMD5: JSON.parse(localStorage.getItem("downloadedMD5")) || [ ], // список скачанного, ТРЕБУЕТСЯ ЮЗЕРСКРИПТ "Direct Image Link E621/926 filelist"
        domNodes: {
            topContainer: document.body,
            newContainer: document.createElement('div')
        }
    };

    // Основная функция обработки
    function processPost(postElement) {
        const { filters, tags, styles, downloadedMD5 } = config;
        
        // Извлечение данных
        const postTags = postElement.getAttribute('data-tags');
        const src = postElement.getAttribute('data-file-url');
        const name = src.split('/').pop();
        const [md5, ext] = name.split('.');
        const num = postElement.getAttribute('data-id');
        
        // Фильтрация
        let isValid = true;
        
        if (filters.useNegativeList && tags.negative.test(postTags)) {
            postElement.style = styles.negative;
            isValid = false;
        }
        
        if (isValid && filters.usePositiveList && !tags.positive.test(postTags)) {
            postElement.style = styles.neutral;
            isValid = false;
        }
        
        if (isValid && filters.filterDownloaded && downloadedMD5.includes(md5)) {
            postElement.style = styles.downloaded;
            isValid = false;
        }
        
        // Формирование вывода
        if (isValid) {
            const insertTopContent = getInsertTopContent(md5, num, src, ext);
	    const insertUnderContent = getInsertUnderContent(md5, num);
            
            if (filters.showTopList) {
                config.domNodes.newContainer.innerHTML += `<a href="${src}">${insertTopContent}</a><br>`;
            }
            
            if (filters.showUnderImage) {
                postElement.innerHTML += `<a href="${src}" style="${styles.underImage}">${insertUnderContent}</a>`;
            }
        }
    }

    // Получение содержимого для вставки
    function getInsertTopContent(md5, num, src, ext) {
        switch (config.mode) {
            case 0:
                return `${num}.${ext}`;
            case 1:
                return `${md5}.${ext}`;
            case 2:
                return src;
            default:
                return '';
        }
    }
    function getInsertUnderContent(md5, num) {
        switch (config.mode) {
            case 0:
                return num;
            case 1:
                return md5;
            case 2:
                return md5;
            default:
                return '';
        }
    }

    // Обработка всех постов
    postList.forEach(processPost);

    // Функция выделения блока
    function selectBlock(node) {
        try {
            const range = document.createRange();
            range.selectNode(node);
            const selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
        } catch (error) {
            console.error('Ошибка при выделении элемента:', error);
        }
    }

    // Добавление верхнего списка
    if (config.filters.showTopList) {
        config.domNodes.newContainer.style = config.styles.topList;
        config.domNodes.topContainer.insertBefore(
            config.domNodes.newContainer,
            config.domNodes.topContainer.firstChild
        );
        selectBlock(config.domNodes.newContainer);
    }
}