Files
prodik 257b42f518 Каталог плагинов: полный локальный mirror в ./plugins (один directory-mount в wwwroot/plugins), доки и вычистка неиспользуемых модулей
- plugins/: скачаны все 30 плагинов store локально (sources.json - карта исходных URL);
  патчи: showy.js (абсолютный хост подгрузки), pubtorr/td/torrentmanager - тела вместо лоадеров,
  modss.js - local-patched копия (из каталога исключена, upstream мёртв)
- extensions.json: 32 позиции, все ссылки {localhost}/plugins/<файл>.js, удалены мёртвые
  (Skaz TV x3, export.js, hotkeys/gold_theme/select_weapon/want/mult, MODS's, o.js, др.)
- compose: ./plugins:/lampac/wwwroot/plugins (один маунт вместо 30 file-mount)
- вычистка: удалены неиспользуемые mods (DatabaseEditor, ExternalBind, LogUserRequest-Lite,
  Telemetry, Transcoding, WatchTogether) и дубль каталога modules/
- config/init.conf: секции Tracks/AdminPanel/Music, customPlugins без gst.js
- mods/Tracks: правки Controller.cs/plugin.js
- README.md / AGENT.md: mirror, кеш static, правила mount
2026-10-02 16:37:30 +03:00

326 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function () {
'use strict';
function startsWith(str, searchString) {
return str.lastIndexOf(searchString, 0) === 0;
}
function endsWith(str, searchString) {
var start = str.length - searchString.length;
if (start < 0) return false;
return str.indexOf(searchString, start) === start;
}
function salt(input) {
var str = (input || '') + '';
var hash = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
hash = ((hash << 5) - hash) + c;
hash = hash & hash;
}
var result = '';
for (var _i = 0, j = 32 - 3; j >= 0; _i +=3, j -= 3) {
var x = (((hash >>> _i) & 7) << 3) + ((hash >>> j) & 7);
result += String.fromCharCode(x < 26 ? 97 + x : x < 52 ? 39 + x : x - 4);
}
return result;
}
function decodeSecret(input, password) {
var result = '';
password = (password || '') + '';
if (input && password) {
var hash = salt('123456789' + password);
while (hash.length < input.length) {
hash += hash;
}
var i = 0;
while (i < input.length) {
result += String.fromCharCode(input[i] ^ hash.charCodeAt(i));
i++;
}
}
return result;
}
function isDebug() {
var res = false;
var origin = window.location.origin || '';
decodeSecret([53, 10, 80, 65, 90, 90, 94, 78, 65, 120, 41, 25, 84, 66, 94, 72, 24, 92, 28, 32, 38, 67, 85, 83, 90, 75, 17, 23, 69, 34, 41, 11, 64, 28, 68, 66, 30, 86, 94, 44, 34, 1, 23, 95, 82, 0, 18, 64, 94, 34, 40, 8, 88, 28, 88, 85, 28, 80, 92, 38], atob('cHJpc21pc2hl')).split(';').forEach(function (s) {
res |= endsWith(origin, s);
});
return res;
}
function rating_kp_imdb(card) {
var network = new Lampa.Reguest();
var clean_title = kpCleanTitle(card.title);
var search_date = card.release_date || card.first_air_date || card.last_air_date || '0000';
var search_year = parseInt((search_date + '').slice(0, 4));
var orig = card.original_title || card.original_name;
var kp_prox = '';
var params = {
id: card.id,
url: kp_prox + 'https://kinopoiskapiunofficial.tech/',
rating_url: kp_prox + 'https://rating.kinopoisk.ru/',
headers: {
'X-API-KEY': decodeSecret([85, 4, 115, 118, 107, 125, 10, 70, 85, 67, 82, 14, 32, 110, 102, 43, 9, 19, 85, 73, 4, 83, 33, 110, 52, 44, 92, 21, 72, 22, 87, 1, 118, 32, 100, 127], atob('X0tQM3Bhc3N3b3Jk'))
},
cache_time: 60 * 60 * 24 * 1000 //86400000 сек = 1день Время кэша в секундах
};
getRating();
function getRating() {
var movieRating = _getCache(params.id);
if (movieRating) {
return _showRating(movieRating[params.id]);
} else {
searchFilm();
}
}
function searchFilm() {
var url = params.url;
var url_by_title = Lampa.Utils.addUrlComponent(url + 'api/v2.1/films/search-by-keyword', 'keyword=' + encodeURIComponent(clean_title));
if (card.imdb_id) url = Lampa.Utils.addUrlComponent(url + 'api/v2.2/films', 'imdbId=' + encodeURIComponent(card.imdb_id));
else url = url_by_title;
network.clear();
network.timeout(15000);
network.silent(url, function (json) {
if (json.items && json.items.length) chooseFilm(json.items);
else if (json.films && json.films.length) chooseFilm(json.films);
else if (url !== url_by_title) {
network.clear();
network.timeout(15000);
network.silent(url_by_title, function (json) {
if (json.items && json.items.length) chooseFilm(json.items);
else if (json.films && json.films.length) chooseFilm(json.films);
else chooseFilm([]);
}, function (a, c) {
showError(network.errorDecode(a, c));
}, false, {
headers: params.headers
});
} else chooseFilm([]);
}, function (a, c) {
showError(network.errorDecode(a, c));
}, false, {
headers: params.headers
});
}
function chooseFilm(items) {
if (items && items.length) {
var is_sure = false;
var is_imdb = false;
items.forEach(function (c) {
var year = c.start_date || c.year || '0000';
c.tmp_year = parseInt((year + '').slice(0, 4));
});
if (card.imdb_id) {
var tmp = items.filter(function (elem) {
return (elem.imdb_id || elem.imdbId) == card.imdb_id;
});
if (tmp.length) {
items = tmp;
is_sure = true;
is_imdb = true;
}
}
var cards = items;
if (cards.length) {
if (orig) {
var _tmp = cards.filter(function (elem) {
return containsTitle(elem.orig_title || elem.nameOriginal, orig) || containsTitle(elem.en_title || elem.nameEn, orig) || containsTitle(elem.title || elem.ru_title || elem.nameRu, orig);
});
if (_tmp.length) {
cards = _tmp;
is_sure = true;
}
}
if (card.title) {
var _tmp2 = cards.filter(function (elem) {
return containsTitle(elem.title || elem.ru_title || elem.nameRu, card.title) || containsTitle(elem.en_title || elem.nameEn, card.title) || containsTitle(elem.orig_title || elem.nameOriginal, card.title);
});
if (_tmp2.length) {
cards = _tmp2;
is_sure = true;
}
}
if (cards.length > 1 && search_year) {
var _tmp3 = cards.filter(function (c) {
return c.tmp_year == search_year;
});
if (!_tmp3.length) _tmp3 = cards.filter(function (c) {
return c.tmp_year && c.tmp_year > search_year - 2 && c.tmp_year < search_year + 2;
});
if (_tmp3.length) cards = _tmp3;
}
}
if (cards.length == 1 && is_sure && !is_imdb) {
if (search_year && cards[0].tmp_year) {
is_sure = cards[0].tmp_year > search_year - 2 && cards[0].tmp_year < search_year + 2;
}
if (is_sure) {
is_sure = false;
if (orig) {
is_sure |= equalTitle(cards[0].orig_title || cards[0].nameOriginal, orig) || equalTitle(cards[0].en_title || cards[0].nameEn, orig) || equalTitle(cards[0].title || cards[0].ru_title || cards[0].nameRu, orig);
}
if (card.title) {
is_sure |= equalTitle(cards[0].title || cards[0].ru_title || cards[0].nameRu, card.title) || equalTitle(cards[0].en_title || cards[0].nameEn, card.title) || equalTitle(cards[0].orig_title || cards[0].nameOriginal, card.title);
}
}
}
if (cards.length == 1 && is_sure) {
var id = cards[0].kp_id || cards[0].kinopoisk_id || cards[0].kinopoiskId || cards[0].filmId;
var base_search = function base_search() {
network.clear();
network.timeout(15000);
network.silent(params.url + 'api/v2.2/films/' + id, function (data) {
var movieRating = _setCache(params.id, {
kp: data.ratingKinopoisk,
imdb: data.ratingImdb,
timestamp: new Date().getTime()
}); // Кешируем данные
return _showRating(movieRating);
}, function (a, c) {
showError(network.errorDecode(a, c));
}, false, {
headers: params.headers
});
};
network.clear();
network.timeout(5000);
network["native"](params.rating_url + id + '.xml', function (str) {
if (str.indexOf('<rating>') >= 0) {
try {
var ratingKinopoisk = 0;
var ratingImdb = 0;
var xml = $($.parseXML(str));
var kp_rating = xml.find('kp_rating');
if (kp_rating.length) {
ratingKinopoisk = parseFloat(kp_rating.text());
}
var imdb_rating = xml.find('imdb_rating');
if (imdb_rating.length) {
ratingImdb = parseFloat(imdb_rating.text());
}
var movieRating = _setCache(params.id, {
kp: ratingKinopoisk,
imdb: ratingImdb,
timestamp: new Date().getTime()
}); // Кешируем данные
return _showRating(movieRating);
} catch (ex) {
}
}
base_search();
}, function (a, c) {
base_search();
}, false, {
dataType: 'text'
});
} else {
var movieRating = _setCache(params.id, {
kp: 0,
imdb: 0,
timestamp: new Date().getTime()
}); // Кешируем данные
return _showRating(movieRating);
}
} else {
var _movieRating = _setCache(params.id, {
kp: 0,
imdb: 0,
timestamp: new Date().getTime()
}); // Кешируем данные
return _showRating(_movieRating);
}
}
function cleanTitle(str){
return str.replace(/[\s.,:;’'`!?]+/g, ' ').trim();
}
function kpCleanTitle(str){
return cleanTitle(str).replace(/^[ \/\\]+/, '').replace(/[ \/\\]+$/, '').replace(/\+( *[+\/\\])+/g, '+').replace(/([+\/\\] *)+\+/g, '+').replace(/( *[\/\\]+ *)+/g, '+');
}
function normalizeTitle(str){
return cleanTitle(str.toLowerCase().replace(/[\-\u2010-\u2015\u2E3A\u2E3B\uFE58\uFE63\uFF0D]+/g, '-').replace(/ё/g, 'е'));
}
function equalTitle(t1, t2){
return typeof t1 === 'string' && typeof t2 === 'string' && normalizeTitle(t1) === normalizeTitle(t2);
}
function containsTitle(str, title){
return typeof str === 'string' && typeof title === 'string' && normalizeTitle(str).indexOf(normalizeTitle(title)) !== -1;
}
function showError(error) {
Lampa.Noty.show('Рейтинг KP: ' + error);
}
function _getCache(movie) {
var timestamp = new Date().getTime();
var cache = Lampa.Storage.cache('kp_rating', 500, {}); //500 это лимит ключей
if (cache[movie]) {
if ((timestamp - cache[movie].timestamp) > params.cache_time) {
// Если кеш истёк, чистим его
delete cache[movie];
Lampa.Storage.set('kp_rating', cache);
return false;
}
} else return false;
return cache;
}
function _setCache(movie, data) {
var timestamp = new Date().getTime();
var cache = Lampa.Storage.cache('kp_rating', 500, {}); //500 это лимит ключей
if (!cache[movie]) {
cache[movie] = data;
Lampa.Storage.set('kp_rating', cache);
} else {
if ((timestamp - cache[movie].timestamp) > params.cache_time) {
data.timestamp = timestamp;
cache[movie] = data;
Lampa.Storage.set('kp_rating', cache);
} else data = cache[movie];
}
return data;
}
function _showRating(data) {
if (data) {
var kp_rating = !isNaN(data.kp) && data.kp !== null ? parseFloat(data.kp).toFixed(1) : '0.0';
var imdb_rating = !isNaN(data.imdb) && data.imdb !== null ? parseFloat(data.imdb).toFixed(1) : '0.0';
var render = Lampa.Activity.active().activity.render();
$('.wait_rating', render).remove();
$('.rate--imdb', render).removeClass('hide').find('> div').eq(0).text(imdb_rating);
$('.rate--kp', render).removeClass('hide').find('> div').eq(0).text(kp_rating);
}
}
}
function startPlugin() {
window.rating_plugin = true;
if (isDebug()) return;
Lampa.Listener.follow('full', function (e) {
if (e.type == 'complite') {
var render = e.object.activity.render();
if ($('.rate--kp', render).hasClass('hide') && !$('.wait_rating', render).length) {
$('.info__rate', render).after('<div style="width:2em;margin-top:1em;margin-right:1em" class="wait_rating"><div class="broadcast__scan"><div></div></div><div>');
rating_kp_imdb(e.data.movie);
}
}
});
}
if (!window.rating_plugin) startPlugin();
})();