Greasy Fork is available in English.

BgmSyncF

Fetch and process data from API

Versión del día 31/8/2023. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         BgmSyncF
// @version      0.1
// @namespace    https://jirehlov.com
// @description  Fetch and process data from API
// @include      /^https?:\/\/(bgm\.tv|chii\.in|bangumi\.tv)\/user/.+/
// @author       Jirehlov
// @grant        none
// @license      MIT
// ==/UserScript==
(function () {
	'use strict';
	// Check if the current page is under /user/username
	const isUserPage = /^\/user\/[^/]+$/.test(window.location.pathname);
	if (!isUserPage) {
		return;	// Stop script execution if not on the user page
	}
	const limit = 50;
	let guess = 1000000;
	let totalItems = 0;
	const allData = [];
	let calculateButton;
	let buttonCounter = 0;
	const [username, page = '', subpage = ''] = (() => {
		const {pathname} = window.location;
		if (/^\/user/.test(pathname)) {
			return pathname.match(/\/user\/(\w+)\/?(\w+)?\/?(\w+)?/).slice(1, 4);
		}
		if (/^\/anime\/list/.test(pathname)) {
			return pathname.match(/\/anime\/list\/(\w+)/).slice(1, 2).concat('subject');
		}
		return [
			'',
			'',
			''
		];
	})();
	if (!username) {
		throw new Error('Username is not detected');
	}
	let countBothAbove7 = 0;
	let countRateAbove7 = 0;
	let subject_type = [
		1,
		2,
		3,
		4,
		6
	];
	let subject_type_index = 0;
	async function fetchData(offset, userAgent, cookie) {
		const url = `https://api.bgm.tv/v0/users/${ username }/collections?subject_type=${ subject_type[subject_type_index] }&type=2&limit=${ limit }&offset=${ offset }`;
		const headers = {
			'Accept': 'application/json',
			'User-Agent': userAgent,
			'Cookie': cookie
		};
		const response = await fetch(url, { headers });
		const data = await response.json();
		return data;
	}
	async function fetchAllData() {
		const userAgent = window.navigator.userAgent;
		const cookie = document.cookie;
		// Update button text to indicate calculation progress
		calculateButton.textContent = '计算中...';
		for (let i = 0; i < subject_type.length; i++) {
			subject_type_index = i;
			const initialData = await fetchData(guess, userAgent, cookie);
			if ('description' in initialData && initialData.description.includes('equal to')) {
				totalItems = parseInt(initialData.description.split('equal to ')[1]);
				console.log(`Updated totalItems to: ${ totalItems }`);
			}
			for (let offset = 0; offset < totalItems; offset += limit) {
				const data = await fetchData(offset, userAgent, cookie);
				allData.push(...data.data);
				console.log(`Fetched ${ offset + 1 }-${ offset + limit } items...`);
				// Update button text with cyclic progress dots
				updateButtonText(offset);
			}
		}
		console.log('Data fetched and stored in memory');
		for (const item of allData) {
			const rate = parseFloat(item.rate || 0);
            const score = parseFloat(item.subject && item.subject.score !== undefined ? item.subject.score : 0);
			if (rate >= 7 || rate === 0) {
				countRateAbove7++;
			}
			if (rate >= 7 && score >= 7) {
				countBothAbove7++;
			}
		}
		// Update button text to indicate calculation is complete
		calculateButton.textContent = '计算全站同步率';
        // Add userSynchronize div if not present
		let synchronizeDiv = document.querySelector('.userSynchronize');
		if (!synchronizeDiv) {
			const userBoxDiv = document.querySelector('.user_box.clearit');
			if (userBoxDiv) {
				synchronizeDiv = document.createElement('div');
				synchronizeDiv.className = 'userSynchronize';
				userBoxDiv.appendChild(synchronizeDiv);
			}
		}
        // Add the percentage bar directly to the existing userSynchronize div
		if (synchronizeDiv) {
			const syncRate = countBothAbove7 / countRateAbove7 * 100;
			const percentageBar = `
                <h3>本页用户与全站的同步率</h3><small class="hot">/ ${ countBothAbove7 }个共同喜好</small><p class="bar"><span class="percent_text rr">${ syncRate.toFixed(2) }%</span> <span class="percent" style="width:${ syncRate.toFixed(2) }%"></span> </p>
            `;
			synchronizeDiv.innerHTML += percentageBar;
		}
		console.log(`Number of items with rate >= 7: ${ countRateAbove7 }`);
		console.log(`Number of items with both rate and score >= 7: ${ countBothAbove7 }`);
		console.log(`Sync rate: ${ (countBothAbove7 / countRateAbove7).toFixed(2) }`);
	}
	function updateButtonText(offset) {
		if (buttonCounter < 5) {
			calculateButton.textContent = '计算中' + '.'.repeat(buttonCounter);
			buttonCounter++;
		} else {
			calculateButton.textContent = '计算中.';
			buttonCounter = 1;
		}
	}
	function addButton() {
		const link = document.createElement('a');
		link.href = 'javascript:void(0)';
		link.textContent = '计算全站同步率';
		link.className = 'chiiBtn';
		link.addEventListener('click', fetchAllData);
		const actionsDiv = document.querySelector('.nameSingle > .inner > .actions');
		actionsDiv.appendChild(link);
		calculateButton = link;	// Store the reference to the button
	}
	addButton();
}());