Kinorium +

Добавляет кнопки под постерами фильмов на Kinorium для поиска на трекерах и других сайтах

目前为 2025-04-09 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Kinorium +
  3. // @namespace https://kinorium.com/
  4. // @version 1.7.3
  5. // @description Добавляет кнопки под постерами фильмов на Kinorium для поиска на трекерах и других сайтах
  6. // @author CgPT & Vladimir0202
  7. // @include /^https?:\/\/.*kinorium.*\/.*$/
  8. // @icon https://ru.kinorium.com/favicon.ico
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16.  
  17. // Проверка: находимся ли мы на главной странице фильма (например: https://kinorium.com/247921/)
  18. const path = window.location.pathname;
  19. const isMainFilmPage = /^\/\d+\/?$/.test(path);
  20.  
  21. if (!isMainFilmPage) {
  22. console.log('Not the main page of the film, the button will not be added.');
  23. return;
  24. }
  25.  
  26. console.log('Kinorium+ Search script started');
  27.  
  28. const savedTrackers = GM_getValue('kinoriumTrackers', [
  29. { name: 'RuTracker', urlTemplate: 'https://rutracker.org/forum/tracker.php?nm={query}', icon: 'https://rutracker.org/favicon.ico' },
  30. { name: 'Kinozal.TV', urlTemplate: 'https://kinozal.tv/browse.php?s={query}', icon: 'https://kinozal.tv/pic/favicon.ico' },
  31. { name: 'RuTor', urlTemplate: 'http://rutor.info/search/0/0/100/0/{query}', icon: 'http://rutor.info/favicon.ico' },
  32. { name: 'NNM.Club', urlTemplate: 'https://nnmclub.to/forum/tracker.php?nm={query}', icon: 'https://nnmstatic.win/favicon.ico' },
  33. { name: 'HDRezka', urlTemplate: 'https://hdrezka.ag/search/?do=search&subaction=search&q={query}', icon: 'https://statichdrezka.ac/templates/hdrezka/images/favicon.ico' },
  34. { name: 'Kinopoisk', urlTemplate: 'https://www.kinopoisk.ru/index.php?kp_query={query}', icon: 'https://www.kinopoisk.ru/favicon.ico' },
  35. ]);
  36.  
  37. function saveTrackers() {
  38. GM_setValue('kinoriumTrackers', savedTrackers);
  39. }
  40.  
  41. function extractMovieData() {
  42. const titleElement = document.querySelector('.film-page__title-text.film-page__itemprop');
  43. const title = titleElement ? titleElement.textContent.trim() : '';
  44.  
  45. const titleEngElement = document.querySelector('.film-page__orig_with_comment');
  46. const titleEng = titleEngElement ? titleEngElement.textContent.trim() : '';
  47.  
  48. const yearElement = document.querySelector('.film-page__date a[href*="years_min="]');
  49. const year = yearElement ? yearElement.textContent.trim() : '';
  50.  
  51. console.log(`Extracted movie data: Title: "${title}", Original Title: "${titleEng}", Year: "${year}"`);
  52.  
  53. return { title, titleEng, year };
  54. }
  55.  
  56. function addNewTrackerButton(container) {
  57. const addButton = document.createElement('button');
  58. addButton.textContent = '+';
  59. addButton.title = 'Добавить новый сайт для поиска';
  60. addButton.style.width = '19px';
  61. addButton.style.height = '19px';
  62. addButton.style.fontWeight = 'bold';
  63. addButton.style.fontSize = '15px';
  64. addButton.style.border = '1px solid #ccc';
  65. addButton.style.backgroundColor = '#f0f0f0';
  66. addButton.style.borderRadius = '5px';
  67. addButton.style.display = 'flex';
  68. addButton.style.alignItems = 'center';
  69. addButton.style.justifyContent = 'center';
  70. addButton.style.cursor = 'pointer';
  71.  
  72. addButton.addEventListener('click', async () => {
  73. const name = prompt('Введите название сайта:');
  74. const urlTemplate = prompt('Введите URL шаблон (используйте {query} или {queryEng} для поиска):');
  75.  
  76. if (name && urlTemplate) {
  77. const domainMatch = urlTemplate.match(/^(https?:\/\/[^/]+)/);
  78. let icon = domainMatch ? `${domainMatch[1]}/favicon.ico` : '';
  79. savedTrackers.push({ name, urlTemplate, icon });
  80. saveTrackers();
  81. alert('Сайт успешно добавлен. Перезагрузите страницу, чтобы увидеть изменения.');
  82. }
  83. });
  84.  
  85. container.appendChild(addButton);
  86. }
  87.  
  88. function addSearchButtons() {
  89. const { title, titleEng, year } = extractMovieData();
  90. if (!title) {
  91. console.warn('Title not found, skipping button creation');
  92. return;
  93. }
  94.  
  95. const buttonContainer = document.createElement('div');
  96. buttonContainer.style.display = 'flex';
  97. buttonContainer.style.flexWrap = 'wrap';
  98. buttonContainer.style.gap = '5px';
  99. buttonContainer.style.marginTop = '10px';
  100. buttonContainer.style.marginBottom = '10px';
  101.  
  102. savedTrackers.forEach(tracker => {
  103. const button = document.createElement('a');
  104. const query = encodeURIComponent(`${title} ${titleEng} ${year}`);
  105. const queryEng = encodeURIComponent(`${titleEng} ${year}`);
  106. const url = tracker.urlTemplate
  107. .replace('{query}', query)
  108. .replace('{queryEng}', queryEng);
  109.  
  110. button.href = url;
  111. button.target = '_blank';
  112. button.title = tracker.name;
  113. button.style.width = '20px';
  114. button.style.height = '20px';
  115. button.style.borderRadius = '5px';
  116. button.style.backgroundImage = `url(${tracker.icon})`;
  117. button.style.backgroundSize = 'contain';
  118. button.style.backgroundRepeat = 'no-repeat';
  119. button.style.backgroundPosition = 'center';
  120.  
  121. buttonContainer.appendChild(button);
  122. });
  123.  
  124. addNewTrackerButton(buttonContainer);
  125.  
  126. const targetElement = document.querySelector('.collectionWidget.collectionWidgetData.withFavourites');
  127. if (targetElement) {
  128. targetElement.after(buttonContainer);
  129. console.log('Search buttons added successfully');
  130. } else {
  131. console.warn('Target element for buttons not found');
  132. }
  133. }
  134.  
  135. addSearchButtons();
  136. })();