在Bangumi帖子页面添加收藏按钮,自动收藏到指定日志
// ==UserScript== // @name Bangumi帖子收藏到日志 // @version 1.2.1 // @description 在Bangumi帖子页面添加收藏按钮,自动收藏到指定日志 // @author age_anime // @match https://bgm.tv/group/topic/* // @match https://chii.in/group/topic/* // @match https://bangumi.tv/group/topic/* // @match https://bgm.tv/blog/* // @match https://chii.in/blog/* // @match https://bangumi.tv/blog/* // @license MIT // @namespace https://greasyfork.org/users/1426310 // ==/UserScript== (function() { 'use strict'; const BASE_URL = window.location.hostname; const path = window.location.pathname; if (path.startsWith('/blog/')) { handleBlogPage(); return; } let TARGET_BLOG_ID = localStorage.getItem('UserTargetBlogID') || '填纯数字!'; const UserConIDT = JSON.parse(localStorage.getItem('UserConIDT') || '{}'); function addCollectButton() { const header = document.querySelector('#pageHeader h1'); if (!header) return; const btnContainer = document.createElement('div'); btnContainer.style.display = 'inline-flex'; btnContainer.style.alignItems = 'center'; btnContainer.style.gap = '8px'; btnContainer.style.marginLeft = '10px'; const collectBtn = createButton(UserConIDT[getPostIdFromUrl()] ? '🔴 再次收藏' : '⭐ 收藏本帖', handleCollect); const modifyLogBtn = createButton('修改日志地址', handleModifyLog); const openLogBtn = createButton('打开收藏地址', handleOpenLog); btnContainer.appendChild(collectBtn); btnContainer.appendChild(modifyLogBtn); btnContainer.appendChild(openLogBtn); header.parentNode.insertBefore(btnContainer, header.nextSibling); } function createButton(text, onClick) { const button = document.createElement('button'); button.innerHTML = text; button.style.cssText = 'padding: 2px 6px; font-size: 12px; background: transparent; border: 1px solid #ccc; border-radius: 3px; cursor: pointer;'; button.addEventListener('click', onClick); // 根据当前模式设置按钮文字颜色 setButtonColor(button); return button; } function setButtonColor(button) { const theme = document.documentElement.getAttribute('data-theme'); if (theme === 'dark') { button.style.color = '#cccccc'; // 深色模式 } else { button.style.color = 'black'; // 浅色模式 } } function handleCollect() { try { const postId = getPostIdFromUrl(); if (!UserConIDT[postId]) { UserConIDT[postId] = true; localStorage.setItem('UserConIDT', JSON.stringify(UserConIDT)); } else { alert('再次收藏成功!'); } const postUrl = window.location.href; const postTitle = document.title.replace(' - Bangumi', ''); const groupName = document.querySelector('#pageHeader h1 a')?.textContent.trim() || '未知小组'; const postAuthorScript = document.querySelector('.post_actions .dropdown ul li a'); const authorNameMatch = postAuthorScript?.getAttribute('onclick')?.match(/ignoreUser\('([^']+)'/); const authorUsername = authorNameMatch ? authorNameMatch[1] : '未知用户'; const authorDisplayName = document.querySelector('.postTopic .inner strong a')?.textContent.trim() || '未知用户'; // 获取目标日志的formhash getBlogFormData().then(formData => { const postUrlLink = `https://${BASE_URL}/group/topic/${window.location.pathname.split('/')[3]}`; const authorLink = `https://${BASE_URL}/user/${authorUsername}`; const bbcode = `[url=${postUrlLink}]${postTitle}[/url]\n${groupName}\n${authorDisplayName}(${authorLink});`; submitComment(formData, bbcode).then(success => { if (success) { console.log('收藏成功'); } else { throw new Error('提交失败'); } }).catch(err => console.error('错误:', err.message || '操作失败')); }); } catch (err) { console.error('错误:', err.message || '操作失败'); } } function handleModifyLog() { const newBlogId = prompt('请输入新的日志ID:', TARGET_BLOG_ID); if (newBlogId) { TARGET_BLOG_ID = newBlogId; localStorage.setItem('UserTargetBlogID', TARGET_BLOG_ID); alert('日志地址已修改为: ' + TARGET_BLOG_ID); } } function handleOpenLog() { window.open(`https://${BASE_URL}/blog/${TARGET_BLOG_ID}`, '_blank'); } function getPostIdFromUrl() { const urlParts = window.location.pathname.split('/'); return urlParts[urlParts.length - 1]; } async function getBlogFormData() { try { const response = await fetch(`https://${BASE_URL}/blog/${TARGET_BLOG_ID}`); if (!response.ok) throw new Error('无法获取日志'); const text = await response.text(); const doc = new DOMParser().parseFromString(text, 'text/html'); const formhash = doc.querySelector('input[name="formhash"]')?.value; const lastview = doc.querySelector('input[name="lastview"]')?.value; if (!formhash || !lastview) throw new Error('找不到日志信息'); return { formhash, lastview }; } catch (error) { console.error('获取日志失败:', error.message); throw error; } } async function submitComment(formData, content) { try { const response = await fetch(`https://${BASE_URL}/blog/entry/${TARGET_BLOG_ID}/new_reply`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ formhash: formData.formhash, lastview: formData.lastview, content: content, submit: '加上去' }) }); return response.ok || response.status === 302; } catch (error) { console.error('提交失败:', error.message); return false; } } function handleBlogPage() { const TARGET_BLOG_ID = localStorage.getItem('UserTargetBlogID'); const currentBlogId = path.split('/')[2]; if (currentBlogId === TARGET_BLOG_ID) { extractTopicIDs(); } function extractTopicIDs() { const extractedIDs = {}; const comments = document.querySelectorAll('.light_even.row.row_reply.clearit, .light_odd.row.row_reply.clearit'); comments.forEach(comment => { const links = comment.querySelectorAll('.message a[href*="/group/topic/"]'); links.forEach(link => { const href = link.href; const topicID = href.match(/group\/topic\/(\d+)/)?.[1]; if (topicID) { extractedIDs[topicID] = true; } }); }); localStorage.setItem('UserConIDT', JSON.stringify(extractedIDs)); const notice = document.createElement('div'); notice.textContent = `已提取 ${Object.keys(extractedIDs).length} 个主题帖`; notice.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 10px; background: #40E0D0; color: white; border-radius: 5px; z-index: 9999; box-shadow: 0 2px 5px rgba(0,0,0,0.2); `; document.body.appendChild(notice); setTimeout(() => { notice.style.transition = 'opacity 1s'; notice.style.opacity = '0'; setTimeout(() => notice.remove(), 1000); }, 3000); } } // 初始化 addCollectButton(); })();