🏠 Home 

Bangumi帖子收藏到日志

在Bangumi帖子页面添加收藏按钮,自动收藏到指定日志


Install this script?
// ==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();
})();