您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Segna automaticamente gli episodi visualizzati su Trakt.TV
当前为
// ==UserScript== // @name AnimeWorld Scrobbling // @namespace https://www.pizidavi.altervista.org/ // @description Segna automaticamente gli episodi visualizzati su Trakt.TV // @author pizidavi // @version 1.4.1 // @copyright 2020, PIZIDAVI // @license MIT // @homepageURL https://www.pizidavi.altervista.org/AnimeWoldScrobbling/ // @require https://greasyfork.org/scripts/401626-notify-library/code/Notify%20Library.js // @include https://*.animeworld.*/play/* // @connect https://api.trakt.tv/ // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_xmlhttpRequest // ==/UserScript== (function($) { 'use strict'; // USER INFO const CLIENT_ID = ''; const ACCESS_TOKEN = ''; const EXPIRES = ''; // SETTINGS const SHOW_HELPER = true; const AUTO_NEXT_EPISODE = false; /* ----------- CODE ----------- */ const css = '#body .sidebar { float: right; width: 300px; position: relative; z-index: 1; }'; const template = '<div id="trakt" class="sidebar"><div class="widget"><div class="widget-title"><div class="title">Trakt</div></div><div class="widget-body"><div class="row" style="margin-bottom:1em;"><div class="col-sm-10" style=" padding-right: 0; "><button class="btn btn-primary btn-block" id="watched">Episodio Visto</button></div><div class="col-sm-2"><input type="checkbox" id="autoNext" style="margin-top: 8px;" title="Prossimo episodio automatico"></div></div><div class="row"><div class="col-sm-6" style=" padding-right: 0; "><input type="text" class="form-control" placeholder="Trakt Slug"><small id="helper" style="display:none;margin:0.3em 0px -5px 0.5em;"><a href="https://www.pizidavi.altervista.org/AnimeWoldScrobbling/#trakt" target="_blank" style="color:grey;">Dove lo trovo?</a></small></div><div class="col-sm-2" style=" padding-right: 0; "><input type="number" class="form-control" value="1" min="0" placeholder="Season"></div><div class="col-sm-4"><button class="btn btn-success btn-block">Salva</button></div></div></div></div></div>'; const AnimeID = getAnimeID(); var Trakt = GM_getValue(AnimeID, {}); var section = $(template); GM_addStyle(css); $('#body #body-container').append(section); if(!CLIENT_ID || !ACCESS_TOKEN || !EXPIRES) { section.find('div.widget-body').html('Dati Trakt mancanti. Segui la <a href="https://www.pizidavi.altervista.org/AnimeWoldScrobbling/" target="_blank">guida</a>'); return; } if(new Date() >= new Date(EXPIRES)) { section.find('div.widget-body').html('Access Token Trakt Scaduto. <a href="https://www.pizidavi.altervista.org/AnimeWoldScrobbling/#login" target="_blank">Aggiorna</a>'); return; } if(AnimeID == undefined) { section.find('div.widget-body').html('Errore. AnimeID non trovato'); return; } section.find('input[type="text"]').val(Trakt.slug); section.find('input[type="number"]').val((Trakt.season || '1')); if(AUTO_NEXT_EPISODE) section.find('input[type="checkbox"]').attr('checked', ''); if(SHOW_HELPER) section.find('#helper').css('display', 'block'); section.find('button.btn:not(#watched)').on('click', function() { var title = $('#main div.widget.info div.info > div.head h2').text(); var slug = $(this).parent().parent().find('input[type="text"]').val(); var season = $(this).parent().parent().find('input[type="number"]').val(); if(slug != '' && season != '') { Trakt.title = title.trim(); Trakt.slug = slug.trim(); Trakt.season = season; GM_setValue(AnimeID, Trakt); section.find('button#watched').removeAttr('disabled'); new Notify({ text: 'Dati salvati', type: 'success' }).show(); } else { new Notify({ text: 'Completa tutti i campi', type: 'warn' }).show(); } }); if(Trakt.slug == undefined || Trakt.season == undefined) { section.find('button#watched').attr('disabled', ''); } $('button#watched').on('click', function() { var _this = $(this); var episode = $('div.server ul a.active').attr('data-base'); if(Trakt.slug == undefined || Trakt.season == undefined || episode == undefined) { new Notify({ text: 'Errore', type: 'error' }).show(); return; } _this.attr('disabled', ''); var joData = { 'shows': [ { 'ids': { 'slug': Trakt.slug, }, 'seasons': [ { 'number': parseInt(Trakt.season), 'episodes': [ { 'watched_at': new Date().toJSON(), 'number': parseFloat(episode) } ] } ] } ] }; request(joData, function(data) { if(data.added.episodes > 0) { new Notify({ text: 'Episodio '+episode+' salvato', type: 'success' }).show(); if(AUTO_NEXT_EPISODE || section.find('#autoNext').prop('checked')) $('#controls > div.prevnext[data-value="next"]').click(); } else { new Notify({ text: 'Errore. Episodio non trovato', type: 'error' }).show(); } _this.removeAttr('disabled'); }); }); $(document).on('click', '#controls > div.userbookmark > ul > li:nth-child(2), #controls > div.userbookmark > ul > li:nth-child(7)', function() { var deleted = deleteOne(AnimeID); if(deleted) { section.find('input[type="text"]').val(''); section.find('input[type="number"]').val('1'); section.find('button#watched').attr('disabled', ''); Trakt = {}; new Notify({ text: 'Dati Trakt rimossi', type: 'success' }).show(); } }); // Functions function request(data, success) { var r = new XMLHttpRequest(); r.open('POST', 'https://api.trakt.tv/sync/history'); r.setRequestHeader('Content-Type', 'application/json'); r.setRequestHeader('Authorization', 'Bearer '+ACCESS_TOKEN); r.setRequestHeader('trakt-api-version', '2'); r.setRequestHeader('trakt-api-key', CLIENT_ID); r.onreadystatechange = function () { if (this.readyState === 4 && (this.status == 200 || this.status == 201)) { success(JSON.parse(this.responseText)); } else if (this.readyState === 4) { new Notify({ text: 'Errore nella richiesta. Ricarica la pagina', type: 'error' }).show(); } }; r.send(JSON.stringify(data)); } function getAnimeID() { var url = location.pathname; var start = url.indexOf('.')+1; var end = start + (url.substring(start).indexOf('/') >= 0 ? url.substring(start).indexOf('/') : url.substring(start).length); return url.substring(start, end) || undefined; } function deleteOne(key) { if(GM_listValues().includes(key)) { GM_deleteValue(key); return true; } else { return false; } } function deleteAll() { GM_listValues().forEach(function(key) { GM_deleteValue(key); }); return true; } })(jQuery);