Редирект-кнопка для Шикимори, которая перенаправляет на Anime365
当前为
// ==UserScript==
// @name ShikiToAnime365
// @description Редирект-кнопка для Шикимори, которая перенаправляет на Anime365
// @description:en Redirect button for Shikimori that redirects to Anime 365
// @namespace https://shikimori.one/animes
// @include /^https?://shikimori\.o(?:ne|rg)/(.*)$/
// @connect smotret-anime.online
// @grant GM_xmlhttpRequest
// @compatible chrome
// @icon https://www.google.com/s2/favicons?domain=shikimori.one
// @author Jogeer
// @license MIT
// @version 1.4.3
// @contributionURL https://paypal.me/Jogeer
// @contributionAmount 5
// ==/UserScript==
const debug = true
const regexUrl = new RegExp(/^https?:\/\/shikimori\.o(?:ne|rg)\/animes\/[A-z]?(\d*)-(.*)$/mg)
const A365Url = 'https://smotret-anime.online/'
const api365 = `${A365Url}api/`
const apiShiki = 'https://shikimori.one/api/'
function log(message) {
if (!debug) {
return null
}
console.log('App: ' + message)
}
function getUserData() {
return JSON.parse(document.querySelector('body').getAttribute('data-user'))
}
function makeRequest(titleId, episodes, userData) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
headers: { "Content-type": "application/json" },
url: `${apiShiki}v2/user_rates?user_id=${userData.id}&target_id=${titleId}&target_type=Anime`,
onload: (e) => { console.log('shiki api:', e); resolve(JSON.parse(e.response == "[]" ? '[{"episodes":0, "status": null}]' : e.response)[0]) }
})
})
}
async function getNextEpisodeData(titleId, episodes) {
let userData = getUserData()
if (!userData.id) {
return null
} else {
let response = await makeRequest(titleId, episodes, userData)
let maxEpisodes = parseInt(document.querySelector('.b-entry-info .line-container:nth-child(2) .line .value').textContent)
console.log(response)
if (!response | response == [] | response.episodes >= maxEpisodes | ['completed'].includes(response.status)) { return null }
return { episodeId: episodes[response.episodes].id, episode: response.episodes + 1 }
}
}
async function addEpisodesData(titleId, episodes) {
let data = await getNextEpisodeData(titleId, episodes)
if (!data) { return null }
var dom = document.querySelector('.user-script-buttons')
let elem = `<a class=\"b-link_button dark next-episode\" href=\"${A365Url}episodes/${data.episodeId}\" target=\"_blank\" style=\"min-width:auto;margin-left:8px;\">${data.episode}</a>`
dom.insertAdjacentHTML('beforeend', elem)
}
function addElement(siteLink, kindData = '') { // user-script-buttons
var dom = document.querySelector('.c-info-right')
let elem = `<div class=\"watch-online\" id=\"anime365-inject\">
<div class=\"line user-script-buttons\">
<a class=\"b-link_button dark\" href=\"${siteLink}\" target=\"_blank\">Смотреть онлайн</a>
</div>
<div class=\"kind\">Anime 365 ${kindData}</div>
</div>`
dom.insertAdjacentHTML('beforeend', elem)
}
async function getApiData(shikimoriLink) {
let matches = regexUrl.exec(shikimoriLink)
await GM_xmlhttpRequest({
method: 'GET',
headers: { "Content-type": "application/json" },
url: `${api365}series?myAnimeListId=${matches[1]}`,
onload: (e) => {
let obj = JSON.parse(e.response).data[0]
console.log('365 api:', e)
if (!obj | !obj.episodes) { return null }
let totalEpisodesA365 = 0
obj.episodes.forEach(el => { el.episodeType === obj.type && el.isFirstUploaded ? totalEpisodesA365++ : null })
addElement(obj.url, `[Eps:${totalEpisodesA365}]`)
addEpisodesData(matches[1], obj.episodes)
}
})
}
async function main() {
var currentUrl = window.location.href
if (!currentUrl.match(regexUrl)) { return null }
await getApiData(currentUrl)
}
function ready(func) {
document.addEventListener('page:load', func)
document.addEventListener('turbolinks:load', func)
if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
func()
} else {
document.addEventListener('DOMContentLoaded', func)
}
}
ready(main)