Rezka+

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

  1. // ==UserScript==
  2. // @name Rezka+
  3. // @namespace https://rezka.ag/
  4. // @version 1.8
  5. // @description Добавляет кнопки под постерами на HDRezka для поиска фильмов на разных торрент-трекерах или других сайтах
  6. // @author CgPT & Vladimir0202
  7. // @include /^https?:\/\/.*rezk.*\/.*$/
  8. // @icon https://static.hdrezka.ac/templates/hdrezka/images/favicon.ico
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16.  
  17. // Получаем список трекеров из хранилища Tampermonkey или создаем дефолтный
  18. const savedTrackers = GM_getValue('rezkaTrackers', [
  19. { name: 'RuTracker', urlTemplate: 'https://rutracker.org/forum/tracker.php?nm={query}', icon: 'https://rutracker.org/favicon.ico' },
  20. { name: 'Kinozal.TV', urlTemplate: 'https://kinozal.tv/browse.php?s={query}', icon: 'https://kinozal.tv/pic/favicon.ico' },
  21. { name: 'RuTor', urlTemplate: 'http://rutor.info/search/0/0/100/0/{query}', icon: 'http://rutor.info/favicon.ico'},
  22. { name: 'NNM.Club', urlTemplate: 'https://nnmclub.to/forum/tracker.php?nm={query}', icon: 'https://nnmstatic.win/favicon.ico'},
  23. { name: 'Hurtom', urlTemplate: 'https://toloka.to/tracker.php?nm={queryEng}', icon: 'https://toloka.to/favicon.ico'},
  24. { name: 'КиноПоиск', urlTemplate: 'https://www.kinopoisk.ru/index.php?kp_query={query}', icon: 'https://www.google.com/s2/favicons?sz=64&domain=kinopoisk.ru'},
  25. { name: 'Kinorium', urlTemplate: 'https://ru.kinorium.com/search/?q={query}', icon: 'https://ru.kinorium.com/favicon.ico'},
  26. { name: 'Youtube', urlTemplate: 'https://www.youtube.com/results?search_query={query}', icon: 'https://www.youtube.com/favicon.ico'},
  27. ]);
  28.  
  29. // Сохраняем трекеры в хранилище Tampermonkey
  30. function saveTrackers() {
  31. GM_setValue('rezkaTrackers', savedTrackers);
  32. }
  33.  
  34. // Добавляем кнопку для добавления сайта
  35. function addNewTrackerButton(container) {
  36. const addButton = document.createElement('button');
  37. addButton.textContent = '+';
  38. addButton.title = 'Добавить новый сайт для поиска';
  39. addButton.style.width = '12px';
  40. addButton.style.height = '12px';
  41. addButton.style.border = '1px solid #ccc';
  42. addButton.style.backgroundColor = '#f0f0f0';
  43. addButton.style.borderRadius = '5px';
  44. addButton.style.display = 'flex';
  45. addButton.style.alignItems = 'center';
  46. addButton.style.justifyContent = 'center';
  47. addButton.style.cursor = 'pointer';
  48.  
  49. addButton.addEventListener('click', async () => {
  50. const name = prompt('Введите название сайта:');
  51. const urlTemplate = prompt('Введите URL шаблон (используйте {query} или {queryEng} для поиска):');
  52.  
  53. if (name && urlTemplate) {
  54. // Извлечение домена из URL шаблона
  55. const domainMatch = urlTemplate.match(/^(https?:\/\/[^/]+)/);
  56. let icon = '';
  57. if (domainMatch) {
  58. const faviconUrl = `${domainMatch[1]}/favicon.ico`; // Основной путь к favicon
  59. try {
  60. // Проверяем доступность favicon
  61. const response = await fetch(faviconUrl, { method: 'HEAD' });
  62. if (response.ok) {
  63. icon = faviconUrl; // Если доступен, используем его
  64. } else {
  65. throw new Error('Favicon not found');
  66. }
  67. } catch (error) {
  68. // Если favicon не найден, используем Google Favicon API
  69. icon = `https://www.google.com/s2/favicons?domain=${domainMatch[1]}`;
  70. }
  71. }
  72.  
  73. // Добавляем сайт в трекеры
  74. savedTrackers.push({ name, urlTemplate, icon });
  75. saveTrackers();
  76. alert('Сайт успешно добавлен. Перезагрузите страницу, чтобы увидеть изменения.');
  77. }
  78. });
  79.  
  80. container.appendChild(addButton);
  81. }
  82.  
  83. // Основной процесс добавления кнопок
  84. const movieCards = document.querySelectorAll('.b-content__columns');
  85.  
  86. movieCards.forEach(card => {
  87. // Извлекаем название фильма
  88. const titleElement = card.querySelector('.b-post__title');
  89. if (!titleElement) return;
  90. const title = titleElement.textContent.trim();
  91.  
  92. const titleEngElement = card.querySelector('.b-post__origtitle');
  93. const titleEng = titleEngElement ? titleEngElement.textContent.trim() : '';
  94.  
  95. // Извлекаем год из ссылки внутри .b-post__info
  96. const yearLink = document.querySelector('.b-post__info a[href*="/year/"]');
  97. let year = '';
  98. if (yearLink) {
  99. year = yearLink.textContent.trim().replace('года', '').trim();
  100. }
  101.  
  102. // Создаем контейнер для кнопок
  103. const buttonContainer = document.createElement('div');
  104. buttonContainer.style.display = 'flex';
  105. buttonContainer.style.flexWrap = 'wrap';
  106. buttonContainer.style.gap = '5px';
  107. buttonContainer.style.marginTop = '10px';
  108.  
  109. // Добавляем кнопки для каждого сайта
  110. savedTrackers.forEach(tracker => {
  111. const button = document.createElement('a');
  112. const query = encodeURIComponent(`${title} ${titleEng} ${year}`);
  113. const queryEng = encodeURIComponent(`${titleEng} ${year}`);
  114. const url = tracker.urlTemplate
  115. .replace('{query}', query)
  116. .replace('{queryEng}', queryEng);
  117. button.href = url;
  118. button.target = '_blank';
  119. button.title = tracker.name;
  120. button.style.width = '12px';
  121. button.style.height = '12px';
  122. button.style.border = '1px solid #ccc';
  123. button.style.backgroundColor = '#fff';
  124. button.style.borderRadius = '5px';
  125. button.style.backgroundImage = `url(${tracker.icon})`;
  126. button.style.backgroundSize = 'contain';
  127. button.style.backgroundRepeat = 'no-repeat';
  128. button.style.backgroundPosition = 'center';
  129.  
  130. button.addEventListener('mouseover', () => {
  131. button.style.transform = 'scale(1.1)';
  132. button.style.boxShadow = '0 2px 6px rgba(0, 0, 0, 0.3)';
  133. });
  134.  
  135. button.addEventListener('mouseout', () => {
  136. button.style.transform = 'scale(1)';
  137. button.style.boxShadow = 'none';
  138. });
  139.  
  140. buttonContainer.appendChild(button);
  141. });
  142.  
  143. // Добавляем кнопку для добавления сайта
  144. addNewTrackerButton(buttonContainer);
  145.  
  146. // Вставляем контейнер под постером
  147. const posterContainer = card.querySelector('.b-post__infotable_left');
  148. if (posterContainer) {
  149. posterContainer.appendChild(buttonContainer);
  150. }
  151. });
  152.  
  153. console.log('Кнопки добавлены под постерами!');
  154. })();