lelykmaryan / AnimeGoSync

// ==UserScript==
// @name         AnimeGoSync
// @namespace    https://animego.org/anime/*
// @version      1.0
// @description  simple script for sync anime from yummyanime to shikimori!
// @author       lelykmaryan
// @match        https://animego.org/anime/*
// @icon         https://www.google.com/s2/favicons?domain=animego.org
// @grant        none
// @license MIT
// ==/UserScript==


let names = document.querySelector(".list-unstyled > li").innerText;

let response = await fetch(`https://shikimori.one/api/animes?search=${names}`); // получаем общую информацию об аниме без токена пользователя
let responseAnime = await response.json();

let anime = {};
anime.id = responseAnime[0].id; 
anime.episodes = responseAnime[0].episodes;
anime.name = responseAnime[0].name;

checkVallidToken()

if (String(localStorage.getItem('access_token')) != 'undefined' && localStorage.getItem('access_token') != null ) { // токен есть в сторадже? -Да - получаем инфу по этому аниме от пользователя, обновляем статусы, Нет - показываем форму авторизации
    getAnime();
    haveToken();

} else {
    let syncButton = document.createElement('div');
    syncButton.innerHTML = `<br><h4>Shikimori:</h4>
            <div style="color: #ff6666; font-weight: bold">Без авторизации на Shikimori, добавить аниме в свой список будет невозможно! <br><br>
                <div class="btn-primary btn" id="authAdd">Авторизоваться</div>
            </div>`;

    document.querySelector(".dropdown").after(syncButton); ;
}




async function checkVallidToken() {
    if( Date.now()/1000 > localStorage.getItem('expired_token')) { // токен устарел? => меняем на новый (refresh токен активен 28 дней, если они пройдут, наиболее вероятно будет ошибка, исправлю позже)
        const formData = new FormData();
        formData.append('grant_type', 'refresh_token');
        formData.append('client_id', 'IGtPiT4zLudryFhJMA4yPdNtZ_3T_E4GFVrma1O4KkI');
        formData.append('client_secret', 'bxTapg5D3FIoNVFwxeowYyQizqQLbN0kdITcZVOzmUo');
        formData.append('refresh_token', localStorage.getItem('refresh_token'));
    
        let response = await fetch(`https://shikimori.one/oauth/token`, {
            method: 'POST',
            body: formData
        });
        let responseJSON = await response.json();
    
        localStorage.setItem('expired_token', responseJSON.created_at+responseJSON.expires_in);
        localStorage.setItem('access_token', responseJSON.access_token);
        localStorage.setItem('refresh_token', responseJSON.refresh_token);
    }    
}


async function getAnime() { // получаем статус аниме и количество просмотреннных эпизодов
    let response = await fetch(`https://shikimori.one/api/v2/user_rates/?target_id=${anime.id}&target_type=Anime&user_id=${localStorage.getItem('shiki_id')}`, {
        headers: {
            'Authorization': `Bearer ${localStorage.getItem('access_token')}`
        }});
    let responseJSON = await response.json();
    anime.status = responseJSON[0]?.status;
    anime.myEpisodes = responseJSON[0]?.episodes != undefined ? responseJSON[0]?.episodes : 0;
    anime.rewatches = responseJSON[0]?.episodes != undefined ? responseJSON[0]?.rewatches : 0;


}
try {
    authAdd.onclick = () => { //авторизуем пользователя (oauth2.0), получаем его статус по аниме, обновляем раздел
        let paramsLink = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no, width=450,height=650`;
        let link = `https://shikimori.one/oauth/authorize?client_id=IGtPiT4zLudryFhJMA4yPdNtZ_3T_E4GFVrma1O4KkI&redirect_uri=https://animego.org/&response_type=code&scope=user_rates`;
        newWindow = open(link, 'test', paramsLink);

        let timerID = setTimeout(async function tick() {
            try {
                let tmppath = newWindow.location.href;
                let path = tmppath.slice(tmppath.indexOf('=')+1);

                const formData = new FormData();
                formData.append('grant_type', 'authorization_code');
                formData.append('client_id', 'IGtPiT4zLudryFhJMA4yPdNtZ_3T_E4GFVrma1O4KkI');
                formData.append('client_secret', 'bxTapg5D3FIoNVFwxeowYyQizqQLbN0kdITcZVOzmUo');
                formData.append('code', path);
                formData.append('redirect_uri', 'https://animego.org/');

                let responseToken = await fetch(`https://shikimori.one/oauth/token`, {
                    method: 'POST',
                    body: formData
                });
                let responseTokenJson = await responseToken.json();

                localStorage.setItem('expired_token', responseTokenJson.created_at+86400);
                localStorage.setItem('access_token', responseTokenJson.access_token);
                localStorage.setItem('refresh_token', responseTokenJson.refresh_token);

                let responseID = await fetch(`https://shikimori.one/api/users/whoami`, { 
                    headers: {
                        'Authorization': `Bearer ${localStorage.getItem('access_token')}`
                    }
                });
                let responseIdJson = await responseID.json();

                localStorage.setItem('shiki_id', responseIdJson.id);


                newWindow.close();
                getAnime();

            } catch {
                time = setTimeout(tick, 2000);
            }
        }, 2000);
    }
} catch {
    console.log(`токен шики найден, кнопки авторизации отключены`);
}


async function haveToken() {
    let timerID = setTimeout(function tick() {
        try {
            document.querySelector(".video-player-bar-series-watch").onclick = function() {
                let numSeries = (document.querySelector(`.video-player-bar-series-item.video-player__active`) != null) ? document.querySelector(`.video-player-bar-series-item.video-player__active`).getAttribute('data-episode') : 1;
                let nextSeries = document.getElementById(`video-carousel-item${+numSeries}`);
                (nextSeries != null) ? nextSeries.querySelector(`.video-player-bar-series-item`).click() : false;
                anime.status = (+numSeries === anime.episodes) ? 'completed' : 'watching';
                anime.myEpisodes = +numSeries;

                sendStatus(anime.status, numSeries);
            };
        } catch {
        time = setTimeout(tick, 1000);
    
    }}, 1000);
}

sendStatus = async function(statusAnime, numSeries) { //отправляем изменения в статусе/эпизоде аниме
    let json = {
        "user_rate": {
            "episodes": `${anime.status === 'watching' ? numSeries : anime.myEpisodes}`,
            "status": `${statusAnime}`,
            "rewatches": `${anime.rewatches}`,
            "target_id": `${anime.id}`,
            "target_type": "Anime",
            "user_id": `${localStorage.getItem('shiki_id')}`
    }};
    let responsetok = await fetch(`https://shikimori.one/api/v2/user_rates`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(json)
    });

}