(function() { 'use strict'; var network = new Lampa.Reguest(); function getRandomKinopoiskTechKey() { const keys = ['8c8e1a50-6322-4135-8875-5d40a5420d86', 'f1d94351-2911-4485-b037-97817098724e', '8c8e1a50-6322-4135-8875-5d40a5420d86']; const randomIndex = Math.floor(Math.random() * keys.length); return keys[randomIndex]; } function calculateProgress(total, current) { if(total == current) { Lampa.Noty.show('Обновление списка фильмов Кинопоиска завершено (' + String(total) + ')'); if(Lampa.Storage.get('kinopoisk_launched_before', false) == false) { Lampa.Storage.set('kinopoisk_launched_before', true); Lampa.Activity.push({ url: '', title: 'Кинопоиск', component: 'kinopoisk', page: 1 }); } } } function processKinopoiskData(data) { // use cache if(data && data.data.userProfile && data.data.userProfile.userData && data.data.userProfile.userData.plannedToWatch) { var kinopoiskMovies = Lampa.Storage.get('kinopoisk_movies', []); var receivedMovies = data.data.userProfile.userData.plannedToWatch.movies.items; var receivedMoviesCount = receivedMovies.length; var moviesCount = data.data.userProfile.userData.plannedToWatch.movies.total; console.log('Kinopoisk', "Total planned to watch movies found: " + String(moviesCount)); console.log('Kinopoisk', "Movies received count: " + String(receivedMoviesCount)); if(receivedMoviesCount == 0) { Lampa.Noty.show('В списке "Буду смотреть" Кинопоиска нет фильмов'); } const receivedMovieIds = new Set(receivedMovies.map(m => String(m.movie.id))); // filter out movies that are no longer present in receivedMovies kinopoiskMovies = kinopoiskMovies.filter(movie => receivedMovieIds.has(String(movie.kinopoisk_id))); Lampa.Storage.set('kinopoisk_movies', JSON.stringify(kinopoiskMovies)); let processedItems = 1; receivedMovies.forEach(m => { const existsInLocalStorage = kinopoiskMovies.some(km => km.kinopoisk_id === String(m.movie.id)); if (!existsInLocalStorage) { // get movie data var title = m.movie.title.localized || m.movie.title.original; console.log('Kinopoisk', 'Getting details for movie: ' + String(m.movie.id) + ', movie title: ' + title); // getting imdb id based on kinopoisk id // network.silent('https://kinopoiskapiunofficial.tech/api/v2.2/films/' + String(m.movie.id), function(data) { network.silent('https://api.alloha.tv/?token=04941a9a3ca3ac16e2b4327347bbc1&kp=' + String(m.movie.id), function(data) { if (data && data.data) { var movieIMDBid = data.data.id_imdb; var movieTMDBid = data.data.id_tmdb ? data.data.id_tmdb : null; var movieTitle = data.data.original_name ? data.data.original_name : data.data.name; if (data.data.category == 1) { var movieType = 'movie'; } else { // 2 var movieType = 'tv'; } var movieYear = data.data.year; if (movieTMDBid) { console.log('Kinopoisk', 'TMDB movie id found: ' + String(movieTMDBid) + ' for kinopoisk id: ' + String(m.movie.id)); var url = Lampa.Utils.protocol() + 'tmdb.'+ Lampa.Manifest.cub_domain +'/3/' + movieType + '/' + String(movieTMDBid) + '?api_key=4ef0d7355d9ffb5151e987764708ce96&language=ru'; } else { if (movieType === 'movie') { console.log('Kinopoisk', 'No IMDB movie id found for kinopoisk id: ' + String(m.movie.id) + ', will search by movie title: ' + movieTitle); var url = Lampa.Utils.protocol() + 'tmdb.'+ Lampa.Manifest.cub_domain +'/3/search/movie?query=' + encodeURIComponent(movieTitle) + '&api_key=4ef0d7355d9ffb5151e987764708ce96&year=' + String(movieYear) + '&language=ru'; } else { // TV_SERIES console.log('Kinopoisk', 'No IMDB movie id found for kinopoisk id: ' + String(m.movie.id) + ', will search by tv series title: ' + movieTitle); var url = Lampa.Utils.protocol() + 'tmdb.'+ Lampa.Manifest.cub_domain +'/3/search/tv?query=' + encodeURIComponent(movieTitle) + '&api_key=4ef0d7355d9ffb5151e987764708ce96&year=' + String(movieYear) + '&language=ru'; } } // getting movie details network.silent(url, function(data) { if(data) { if (movieTMDBid) { var movieItem = data; } else { if (data.movie_results && data.movie_results[0]) { var movieItem = data.movie_results[0]; } else if(data.tv_results && data.tv_results[0]) { var movieItem = data.tv_results[0]; } else if(data.results && data.results[0]) { var movieItem = data.results[0]; } } if(movieItem) { // console.log('Kinopoisk', 'Movie details received: ' + JSON.stringify(movieItem)); console.log('Kinopoisk', 'TMDB id found: ' + movieItem.id + ' for IMDB movie id: ' + movieIMDBid + ', kinopoisk id: ' + String(m.movie.id)); var movieDateStr = movieItem.release_date || movieItem.first_air_date; // film or tv series var movieDate = new Date(movieDateStr); if (movieDate <= new Date()) { movieItem.kinopoisk_id = String(m.movie.id); movieItem.source = "tmdb"; kinopoiskMovies = Lampa.Storage.get('kinopoisk_movies', []); // re-read data if another process modified it kinopoiskMovies.unshift(movieItem); Lampa.Storage.set('kinopoisk_movies', JSON.stringify(kinopoiskMovies)); } else { console.log('Kinopoisk', 'Movie or TV with kinopoisk id ' + String(m.movie.id) + ' not released yet, release date:', movieDate); if (Lampa.Storage.get('kinopoisk_add_to_favorites', false)) { // add to favorites Lampa.Favorite.add('wath', movieItem, 100); } } } else { console.log('Kinopoisk', 'No result found for ' + movieTitle + ', ' + movieYear, data); } } else { console.log('Kinopoisk', 'No movie found by IMDB id: ' + String(movieIMDBid)); } calculateProgress(receivedMoviesCount, processedItems++); }, function(data) { console.log('Kinopoisk', 'apitmdb.cub.red error, data: ' + String(data)); calculateProgress(receivedMoviesCount, processedItems++); }); } else { console.log('Kinopoisk', 'No movie found for kinopoisk id: ' + String(m.movie.id) + ', movie: ' + title); calculateProgress(receivedMoviesCount, processedItems++); } }, function(data) { console.log('Kinopoisk', 'kinopoiskapiunofficial error, data: ' + String(data)); calculateProgress(receivedMoviesCount, processedItems++); }, false, { type: 'get' //, // headers: { // 'X-API-KEY': getRandomKinopoiskTechKey() // } }); } else { console.log('Kinopoisk', 'Reading data from local storage for movie: ' + String(m.movie.id)) calculateProgress(receivedMoviesCount, processedItems++); } }) } else { Lampa.Noty.show('Невозможно обработать данные, полученные от Кинопоиска'); console.log('Kinopoisk', 'processKinopoiskData - '); console.log('Kinopoisk', data); } } function getKinopoiskData() { console.log('Kinopoisk', 'Starting to get Kinopoisk data...'); var oauth = Lampa.Storage.get('kinopoisk_access_token'); // google script is used to act as CORS proxy network.silent('https://script.google.com/macros/s/AKfycbwQhxl9xQPv46uChWJ1UDg6BjSmefbSlTRUoSZz5f1rZDRvdhAGTi6RHyXwcSeyBtPr/exec?oauth=' + oauth, function(data) { // on success processKinopoiskData(data); }, function(data) { // on error console.log('Kinopoisk', 'Error, google script', data); }); } function full(params, oncomplete, onerror) { // https://github.com/yumata/lampa-source/blob/main/src/utils/reguest.js // https://github.com/yumata/lampa-source/blob/main/plugins/collections/api.js var oauth = Lampa.Storage.get('kinopoisk_access_token'); if(oauth) { getKinopoiskData(); } oncomplete({ "secuses": true, "page": 1, "results": Lampa.Storage.get('kinopoisk_movies', []) }); } function clear() { network.clear(); } var Api = { full: full, clear: clear }; function component(object) { var comp = new Lampa.InteractionCategory(object); comp.create = function() { Api.full(object, this.build.bind(this), this.empty.bind(this)); }; comp.nextPageReuest = function(object, resolve, reject) { Api.full(object, resolve.bind(comp), reject.bind(comp)); }; return comp; } // getting/refreshing oauth kinopoisk token function getToken(device_code, refresh) { var client_id = 'b8b9c7a09b79452094e12f6990009934'; if(!refresh) { var token_data = { 'grant_type': 'device_code', 'code': device_code, 'client_id': client_id, 'client_secret': '0e7001e272944c05ae5a0df16e3ea8bd' } } else { // refresh token var token_data = { 'grant_type': 'refresh_token', 'refresh_token': device_code, // pass refresh token as device_code 'client_id': client_id, 'client_secret': '0e7001e272944c05ae5a0df16e3ea8bd' } } network.silent('https://oauth.yandex.ru/token', function(data) { // on token success if(data.access_token) { Lampa.Storage.set('kinopoisk_access_token', data.access_token); Lampa.Storage.set('kinopoisk_refresh_token', data.refresh_token); Lampa.Storage.set('kinopoisk_token_expires', data.expires_in * 1000 + Date.now()); Lampa.Modal.close(); getUserEmail(); getKinopoiskData(); } else { Lampa.Noty.show('Не удалось получить token'); console.log('Kinopoisk', 'Error during OAuth', data.error); } }, function(data) { // on token error Lampa.Noty.show(data.responseJSON.error_description); console.log('Kinopoisk', 'Token error', data); }, token_data); } // getting oauth user_code // https://yandex.ru/dev/id/doc/ru/codes/screen-code-oauth function getDeviceCode() { // generating unique device id const uuid4 = () => { const ho = (n, p) => n.toString(16).padStart(p, 0); const data = crypto.getRandomValues(new Uint8Array(16)); data[6] = (data[6] & 0xf) | 0x40; data[8] = (data[8] & 0x3f) | 0x80; const view = new DataView(data.buffer); return `${ho(view.getUint32(0), 8)}${ho(view.getUint16(4), 4)}${ho(view.getUint16(6), 4)}${ho(view.getUint16(8), 4)}${ho(view.getUint32(10), 8)}${ho(view.getUint16(14), 4)}`; /// Compile the canonical textual form from the array data }; Lampa.Storage.set('kinopoisk_deviceid', uuid4()); var client_id = 'b8b9c7a09b79452094e12f6990009934'; var device_code_data = { 'client_id': client_id, 'device_id': Lampa.Storage.get('kinopoisk_deviceid', '') } network.silent('https://oauth.yandex.ru/device/code', function(data) { // on device code success if(data.user_code && data.device_code) { // Lampa.Utils.copyTextToClipboard(data.user_code, ()=>{}); // ask user to authorize let modal = $('