- // ==UserScript==
- // @name Danbooru Copy Tags Optimized
- // @namespace http://tampermonkey.net/
- // @version 1.31
- // @description 优化后的Danbooru标签复制脚本,支持角色名、艺术家名等功能,并移除重复逗号和多余空格
- // @match https://danbooru.donmai.us/posts/*
- // @match https://aibooru.online/posts/*
- // @grant none
- // ==/UserScript==
-
- (function () {
- 'use strict';
-
- const BUTTON_STYLE = `
- position: absolute;
- right: 10px;
- z-index: 9999;
- padding: 10px;
- background-color: #28a745;
- color: #fff;
- border: none;
- border-radius: 5px;
- cursor: pointer;
- margin-right: 5px;
- `;
-
- const BUTTON_COLORS = {
- general: '#28a745',
- nonCharacter: '#dc3545',
- characterFeatures: '#17a2b8',
- clothing: '#ffc107',
- characterNames: '#007bff',
- artistNames: '#6f42c1'
- };
-
- const TAG_LISTS = {
- general: '.general-tag-list a',
- characters: '.character-tag-list a',
- artists: '.artist-tag-list a'
- };
-
- const FILTERS = {
- all: () => true,
- nonCharacter: tag => !blacklist.some(b => tag.includes(b)) && characterFeatures.every(f => !tag.includes(f)) && clothingFeatures.every(f => !tag.includes(f)),
- characterFeatures: tag => characterFeatures.some(f => tag.includes(f)) && !blacklist.some(b => tag.includes(b)),
- clothing: tag => clothingFeatures.some(f => tag.includes(f)) && !blacklist.some(b => tag.includes(b))
- };
-
- const allTagsFilter = (tag) => !blacklist.some(blacklistedTag => tag.includes(blacklistedTag));
-
- const characterFeatures = [
- 'hair', 'eyes', 'choker', 'medium hair', '1girl', 'large breasts', 'twintails', 'girl on top', 'multiple girls',
- 'hair ornament', 'animal ears', 'hairband', 'symbol-shaped pupils', 'fake animal ears', 'heart-shaped pupils',
- 'mouse ears', 'long hair', 'one eye closed', 'dark skin', 'pubic hair', 'upper teeth only', 'looking over eyewear',
- 'red-tinted eyewear', 'eyeshadow', 'v-shaped eyebrows', 'wide-eyed', 'constricted pupils', 'bloodshot eyes', 'tail',
- 'cat ears', 'cat tail', 'half-closed eyes', 'cat girl', 'eyepatch', 'empty eyes', 'medical eyepatch', 'very long hair',
- 'hair bow', 'hairclip', 'green eyes', 'rabbit ears', 'streaked hair', 'hair tie', 'adjusting hair', 'hair tie in mouth',
- 'earrings', 'ribbon', 'halo', 'braid', 'pointy ears', 'feathered wings', 'angel wings', 'single side bun', 'low twintails',
- 'alternate costume', 'closed eyes', 'long bangs', 'absurdly long hair', 'blue halo', 'mechanical halo', 'facial hair', 'ahoge',
- 'two-tone hair', 'gradient hair', 'eyelashes', 'straight hair', 'pale skin', 'black wings', 'detached wings', 'energy wings',
- 'hair flowing over', 'broken halo', 'dark halo', 'ponytail', 'round eyewear', 'pearl earrings', 'glowing eyes', 'cowgirl position',
- 'drill hair', 'horns', 'demon horns', 'shiny skin', 'crossed bangs', 'fox ears', 'necklace', 'wavy hair', 'wolf ears', 'wolf tail',
- 'extra ears', 'bead necklace', 'scar across eye', 'colored eyelashes', 'butterfly hair ornament', 'dark-skinned female', 'covering face',
- 'ringed eyes', 'frilled hair tubes', 'ear piercing', 'cow horns', 'draph', 'cow tail', 'monkey tail', 'forehead', 'red ribbon',
- 'fox tail', 'skull hair ornament', 'eyes visible through hair', 'asymmetrical hair', 'official alternate hairstyle', 'mini wings',
- 'multicolored wings', 'star halo', 'heart hair ornament', 'spiked choker', 'high ponytail', 'tentacle hair', 'choker', 'fangs',
- 'pom pom hair ornament', 'floating hair', 'forked tail', 'ribbon-trimmed skirt', 'leaf hair ornament', 'short hair with long locks',
- 'fake horns', 'blood in hair', 'diamond hair ornament', 'skin fang', 'braided ponytail', 'multicolored eyes', 'demon tail',
- 'o-ring choker', 'playboy bunny', 'bob cut', 'button eyes', 'braided bangs', 'heart choker', 'tassel hair ornament', 'asymmetrical horns',
- 'demon wings', 'butterfly wings', 'horse ears', 'horse tail', 'side ponytail', 'diamond-shaped pupils', 'dog ears', 'bandaid hair ornament',
- 'neck ribbon', 'ribbon hair ornament', 'sharp teeth', 'messy hair', 'bright pupils', 'one side up', 'bags under eyes', 'hairband',
- 'braid', 'blue wings', 'star hair ornament', 'side ponytail', 'twisted horns', 'swirling eyes', 'vampire teeth','animal ear fluff',
- ];
-
-
- const clothingFeatures = [
- 'swimsuit', 'bikini', 'strap gap', 'skirt', 'gloves', 'thighhighs', 'jacket', 'fingerless gloves', 'open jacket',
- 'sunglasses', 'leather jacket', 'long sleeves', 'bow', 'boots', 'detached sleeves', 'belt', 'wide sleeves', 'high heels',
- 'side-tie bikini bottom', 'thigh boots', 'micro bikini', 'striped bikini', 'heart brooch', 'bikini bottom aside',
- 'bikini top lift', 'black gloves', 'black footwear', 'turtleneck', 'cropped jacket', 'short sleeves', 'yellow gloves',
- 'boxing gloves', 'shirt', 'collared shirt', 'shorts', 'shoes', 'socks', 'white jacket', 'white footwear', 'bow',
- 'grey shorts', 'multicolored jacket', 'dress', 'asymmetrical legwear', 'single leg pantyhose', 'frills', 'bowtie', 'detached collar',
- 'sandals', 'toenails', 'frilled bikini', 'jewelry', 'braid', 'bell', 'shirt', 'official alternate costume', 'short shorts',
- 'shirt lift', 'track jacket', 'gym uniform', 'gym shirt', 'gym shorts', 'flowers', 'leotard', 'black leotard', 'cuffs',
- 'handcuffs', 'torn leotard', 'school uniform', 'capelet', 'scrunchie', 'wrist scrunchie', 'blue skirt', 'sweater',
- 'red shorts', 'underwear', 'panties', 'japanese clothes', 'kimono', 'pasties', 'open kimono', 'collar', 'black panties',
- 'highleg', 'highleg panties', 'black sweater', 'tentacle hair', 'vest', 'uniform', 'white socks', 'wing collar',
- 'long skirt', 'blue footwear', 'blue vest', 'serafuku', 'neckerchief', 'white skirt', 'cardigan', 'slippers',
- 'frilled collar', 'bra', 'underwear only', 'china dress', 'print dress', 'striped coat', 'beret', 'school swimsuit',
- 'one-piece swimsuit', 'shawl', 'collar', 'micro shorts', 'cow costume', 'casual one-piece swimsuit', 'green one-piece swimsuit',
- 'hood', 'scarf', 'coat', 'fur trim', 'beanie', 'white scarf', 'black dress', 'sleeveless dress', 'arm strap', 'elbow gloves',
- 'strappy heels', 'bodysuit', 'red bodysuit', 'wrist cuffs', 'no shoes', 'garter straps', 'grey thighhighs', 'thigh strap',
- 'vibrator', 'jacket on shoulders', 'pants rolled up', 'red ribbon', 'pantyhose', 'sailor collar', 'white pantyhose',
- 'thighband pantyhose', 'sun hat', 'high heel boots', 'fishnet thighhighs', 'fishnets', 'o-ring thigh strap', 'thigh belt',
- 'strapless', 'chinese clothes', 'aqua dress', 'aqua gloves', 'puffy sleeves', 'apron', 'maid headdress', 'pleated skirt',
- 'green skirt', 'black pantyhose', 'frilled dress', 'frilled apron', 'two-tone dress', 'necktie', 'sash', 'waist apron',
- 'jingle bell', 'neck bell', 'purple bow', 'pink kimono', 'sleeveless kimono', 'pink sleeves', 'hatsune miku', 'miniskirt',
- 'sleeveless shirt', 'grey shirt', 'yellow necktie', 'ascot', 'frilled bow', 'orange ascot', 'hoodie', 'bandages',
- 'black hoodie', 'bandaged neck', 'white shorts', 'animal costume', 'one-piece swimsuit', 'shawl', 'collar', 'green one-piece swimsuit',
- 'vest', 'uniform', 'highleg panties', 'tentacle hair', 'pants', 'jacket'
- ];
-
-
- const blacklist = [
- 'lowres', 'jpeg artifacts', 'signature', 'watermark', 'text', 'artist name',
- 'sample', 'resolution mismatch', 'bad anatomy', 'error', 'low quality', 'character name',
- 'name', 'censored', 'censoring', 'censor',
- ];
-
-
- const createButton = (text, color, top, callback) => {
- const button = document.createElement('button');
- button.innerText = text;
- button.style.cssText = `${BUTTON_STYLE} top: ${top}px; background-color: ${color};`;
- document.querySelector('.image-container')?.appendChild(button);
- button.addEventListener('click', callback);
- };
-
- const sanitizeTags = tags =>
- tags.filter(Boolean) // 移除空字符串
- .join(', ') // 将数组转换为字符串,用逗号连接
- .replace(/, ,+/g, ',') // 移除多余的连续逗号
- .replace(/,\s+/g, ', ') // 确保每个逗号后只有一个空格
- .trim(); // 去除首尾多余空格
-
- const copyTags = (selector, filter) => {
- setTimeout(() => {
- const tags = Array.from(document.querySelectorAll(selector)).map(el => el.innerText.replace(/\?/g, '').trim());
- const filtered = filter ? tags.filter(filter) : tags;
- const result = sanitizeTags(filtered);
- if (!result) return alert('未找到符合条件的标签。');
- navigator.clipboard.writeText(result).then(() => alert(`已复制到剪贴板: ${result}`)).catch(err => alert(`复制失败: ${err}`));
- }, 1000); // 延迟确保加载完成
- };
-
- const copyNames = (selector, type) => {
- setTimeout(() => {
- const elements = document.querySelectorAll(selector);
- const names = Array.from(elements).map(el => el.innerText.replace(/\?/g, '').trim());
- const result = sanitizeTags(names);
- if (!result) return alert(`未找到${type}。`);
- navigator.clipboard.writeText(result).then(() => alert(`已复制${type}: ${result}`)).catch(err => alert(`复制失败: ${err}`));
- }, 1000);
- };
-
- // 创建各类按钮
- createButton('复制所有标签', BUTTON_COLORS.general, 10, () => copyTags(TAG_LISTS.general, FILTERS.all));
- createButton('复制非角色特征标签', BUTTON_COLORS.nonCharacter, 50, () => copyTags(TAG_LISTS.general, FILTERS.nonCharacter));
- createButton('复制角色特征标签', BUTTON_COLORS.characterFeatures, 90, () => copyTags(TAG_LISTS.general, FILTERS.characterFeatures));
- createButton('仅复制服装标签', BUTTON_COLORS.clothing, 130, () => copyTags(TAG_LISTS.general, FILTERS.clothing));
- createButton('复制角色名字', BUTTON_COLORS.characterNames, 170, () => copyNames(TAG_LISTS.characters, '角色名字'));
- createButton('复制艺术家名字', BUTTON_COLORS.artistNames, 210, () => copyNames(TAG_LISTS.artists, '艺术家名字'));
- })();