// ==UserScript==
// @name YggTorrent amélioré [Edit]
// @match https://*.ygg.re/*
// @version 1.24
// @author J.H / clemente
// @license MIT
// @description Découvrez une connexion automatique, des boutons de téléchargement dans les résultats de recherche, une fonction de prévisualisation d'image des torrents au survol, et bien d'autres améliorations.
// @run-at document-end
// @noframes
// @icon https://www.google.com/s2/favicons?sz=64&domain=ygg.re
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @namespace https://greasyfork.org/users/448067
// ==/UserScript==
(async function () {
const CONFIG = {
// DEBUT CONFIGURATION (Pour désactiver une option, il suffit de mettre false à la place de true)
BETTER_DARK_THEME: false, // Thème sombre amélioré + blocage de certaines publicités recalcitrantes malgré "uBlock Origin"
LOGIN_AUTOMATICALLY: true, // Se connecte automatiquement après avoir saisie les identifiants au moins une fois
PREVIEWS_IMAGES_ON_HOVER: true, // Affiche une prévisualisation de l'image du torrent au survol
PREVIEWS_IMAGES_SIZE: 250, // Taille des images de prévisualisation en pixels
DOWNLOAD_BUTTONS_IN_RESULTS: true, // Ajoute un bouton de téléchargement dans les résultats de recherche
HIDE_SIDEBAR: true, // Masque la barre latérale
LARGER_NFO: true, // Agrandit la fenêtre de prévisualisation du NFO
SEARCH_BY_LATEST_FIRST: true, // Affiche les résultats de recherche par date de publication (du plus récent au plus ancien)
KEEP_SEARCH_WHEN_CLICKING_ON_SUBCATEGORY_ICON: true, // Garde les critères de recherche lorsqu'on clique sur une catégorie
// FIN CONFIGURATION (Evitez de toucher au reste si vous ne savez pas ce que vous faites)
};
const SELECTORS = {
REGISTER_BUTTON: '.register',
TORRENT_NAME_LINK: 'a[id="torrent_name"]',
RESULTS_TABLE_ROW: '.results table tbody tr',
INPUT_USERNAME: 'input[name="id"]',
INPUT_PASSWORD: 'input[name="pass"]',
INPUT_SUBMIT: 'button[type="submit"]',
LOGOUT_LINK: 'a[href="https://www.ygg.re/user/logout"]',
NFO_MODAL: '#nfoModal',
SEARCH_FORM: 'form.search',
LOGIN_FORM: '.login-form',
};
const CONSTANTS = {
IMAGE_MODAL_STYLE: `min-width: ${CONFIG.PREVIEWS_IMAGES_SIZE}px; max-width: ${CONFIG.PREVIEWS_IMAGES_SIZE}px;`,
COOKIES_STORAGE_KEY: 'yggtorrent_credentials',
MOUSEENTER_DELAY: 100,
};
CONFIG.BETTER_DARK_THEME && betterDarkTheme();
CONFIG.DOWNLOAD_BUTTONS_IN_RESULTS && addDownloadButtonToTorrents();
CONFIG.HIDE_SIDEBAR && hideSidebar();
CONFIG.LARGER_NFO && displayLargerNfo();
CONFIG.SEARCH_BY_LATEST_FIRST && searchByLatestFirst();
CONFIG.KEEP_SEARCH_WHEN_CLICKING_ON_SUBCATEGORY_ICON && keepSearchWhenClickingOnSubcategoryIcon();
//CONFIG.PREVIEWS_IMAGES_ON_HOVER && displayImageHandler();
CONFIG.LOGIN_AUTOMATICALLY && await handleLogin();
async function handleLogin() {
const isNotLoggedIn = document.querySelector(SELECTORS.REGISTER_BUTTON);
const savedCredentials = await GM.getValue(CONSTANTS.COOKIES_STORAGE_KEY);
if (isNotLoggedIn && !savedCredentials) {
await getCredentials();
} else if (isNotLoggedIn && savedCredentials) {
await autoLogin(savedCredentials);
}
}
async function getCredentials() {
try {
const loginForm = document.querySelector(SELECTORS.LOGIN_FORM);
if (loginForm) {
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const usernameInput = loginForm.querySelector(SELECTORS.INPUT_USERNAME);
const passwordInput = loginForm.querySelector(SELECTORS.INPUT_PASSWORD);
await saveCredentials(usernameInput.value, passwordInput.value);
});
}
} catch (error) {
console.error('Error getting credentials:', error);
}
}
async function autoLogin(credentials) {
try {
const loginForm = document.querySelector(SELECTORS.LOGIN_FORM);
if (loginForm) {
const usernameInput = loginForm.querySelector(SELECTORS.INPUT_USERNAME);
const passwordInput = loginForm.querySelector(SELECTORS.INPUT_PASSWORD);
const submitButton = loginForm.querySelector(SELECTORS.INPUT_SUBMIT);
if (usernameInput && passwordInput && submitButton) {
usernameInput.value = credentials.username;
passwordInput.value = credentials.password;
submitButton.click();
}
}
} catch (error) {
console.error('Error during login:', error);
}
}
const logoutLink = document.querySelector(SELECTORS.LOGOUT_LINK);
if (logoutLink) {
logoutLink.addEventListener('click', deleteCredentials);
}
async function deleteCredentials() {
try {
await GM.deleteValue(CONSTANTS.COOKIES_STORAGE_KEY);
} catch (error) {
console.error('Error deleting credentials:', error);
}
}
async function saveCredentials(username, password) {
try {
await GM.setValue(CONSTANTS.COOKIES_STORAGE_KEY, { username, password });
} catch (error) {
console.error('Error saving credentials:', error);
}
}
/* function fetchImageSize(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve({ width: img.width, height: img.height, url });
img.onerror = reject;
img.src = url;
});
}
function makeGetRequest(url) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url,
onload: function (response) {
resolve(response.responseText);
},
onerror: function (error) {
reject(error);
},
});
});
}
async function getImages(url) {
const imageRet = [];
try {
const response = await makeGetRequest(url);
const parser = new DOMParser();
const doc = parser.parseFromString(response, 'text/html');
if (doc.title.includes('Just a moment...')) {
imageRet.push({
width: 250,
height: 250,
url: 'https://i.ibb.co/DQb8WVj/cflr.jpg',
});
return imageRet;
}
const imgElements = doc.getElementsByTagName('img');
for (const imgElement of imgElements) {
if (imgElement.src.includes('yggtorrent') || imgElement.src.startsWith('data:image/png;base64')) {
continue;
}
const image = await fetchImageSize(imgElement.src);
if (image.width > 250 && image.height > 250) {
imageRet.push(image);
break;
}
}
} catch (error) {
console.error('Error fetching images:', error);
}
return imageRet;
}
function displayImageHandler() {
createImageModal();
let timeout = null;
let canDisplay = false;
const torrents = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW);
if (!torrents) return;
torrents.forEach((torrent) => {
const torrentNameLink = torrent.querySelector(SELECTORS.TORRENT_NAME_LINK);
if (!torrentNameLink) return;
torrentNameLink.addEventListener('mouseenter', async (e) => {
timeout = setTimeout(async () => {
if (e.target.id !== 'torrent_name') return;
canDisplay = true;
const images = await getImages(e.target.href);
if (canDisplay) {
displayImageModal(e, images[0]);
}
}, CONSTANTS.MOUSEENTER_DELAY);
});
torrentNameLink.addEventListener('mousemove', (e) => {
const modal = document.getElementById('imageModal');
if (modal) {
const mouseY = e.clientY - 25;
const outOfScreen =
mouseY + document.getElementById('imageModalImage').offsetHeight - window.innerHeight;
modal.style.top =
outOfScreen > -25 ? mouseY - outOfScreen - 25 + 'px' : mouseY + 'px';
modal.style.left = e.clientX + 125 + 'px';
}
});
torrentNameLink.addEventListener('mouseout', () => {
document.getElementById('imageModal').style.display = 'none';
canDisplay = false;
clearTimeout(timeout);
});
});
}
function createImageModal() {
const modal = document.createElement('div');
modal.id = 'imageModal';
modal.classList.add('modal');
modal.style.display = 'none';
const modalImage = document.createElement('img');
modalImage.id = 'imageModalImage';
modalImage.classList.add('modal-content');
modalImage.style = CONSTANTS.IMAGE_MODAL_STYLE;
modal.appendChild(modalImage);
document.body.append(modal);
}
function displayImageModal(event, image) {
const modal = document.getElementById('imageModal');
if (modal) {
const mouseY = event.clientY - 25;
const modalImage = document.getElementById('imageModalImage');
modalImage.src = image.url;
modal.style.left = event.clientX + 125 + 'px';
modal.style.display = 'block';
const outOfScreen =
mouseY + modalImage.offsetHeight - window.innerHeight;
modal.style.top =
outOfScreen > -25 ? mouseY - outOfScreen - 25 + 'px' : mouseY + 'px';
}
} */
function addDownloadButtonToTorrents() {
const torrents = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW);
torrents.forEach((torrent) => {
const torrentId = torrent.querySelector('a[target]')?.target;
if (!torrentId) return;
const downloadIcon = document.createElement('span');
downloadIcon.classList.add('ico_download');
downloadIcon.classList.add('custom_ygg');
const downloadButton = document.createElement('a');
downloadButton.href = `/engine/download_torrent?id=${torrentId}`;
downloadButton.append(downloadIcon);
downloadButton.style = 'float: left; color: rgb(98, 219, 168)';
const nameLink = torrent.querySelector('td:nth-child(3) a');
if (nameLink) {
nameLink.parentNode.insertBefore(downloadButton, nameLink);
}
});
}
function hideSidebar() {
const sidebar = document.getElementById('cat');
if (sidebar && sidebar.classList.contains('active')) {
sidebar.querySelector('.open').click();
}
}
function displayLargerNfo() {
const modal = document.getElementById(SELECTORS.NFO_MODAL);
if (!modal) return;
const modalDialog = modal.querySelector('.modal-dialog');
modalDialog.classList.remove('modal-sm');
modalDialog.classList.add('modal-lg');
}
function searchByLatestFirst() {
const searchForm = document.querySelector(SELECTORS.SEARCH_FORM);
if (!searchForm) return;
const orderInput = document.createElement('input');
orderInput.name = 'order';
orderInput.value = 'desc';
orderInput.style = 'display: none';
const sortInput = document.createElement('input');
sortInput.name = 'sort';
sortInput.value = 'publish_date';
sortInput.style = 'display: none';
searchForm.append(orderInput);
searchForm.append(sortInput);
}
function keepSearchWhenClickingOnSubcategoryIcon() {
document.querySelectorAll('[class^="tag_subcat_"]').forEach((node) => {
const subcategoryId = node.className.split('tag_subcat_')[1];
node.parentNode.href = `${document.URL}&sub_category=${subcategoryId}`;
});
}
function betterDarkTheme() {
const customStyles = `
.custom_ygg{vertical-align:middle}.promo-container{display:none!important;}#over-18-notification,.misc,.donate.pulse{display:none}#middle .row .results tr:nth-child(odd) td{background:#2a313ce8;color:#cbd1da}#middle .row .results tr td:nth-child(8){color:#4caf50}#middle .row .results tr td:nth-child(9){color:#f44336}#middle .row .results td .ico_comment,#middle .row .results td{background-color:#2c343f;border:solid 1px #1b1e24;color:#cbd1da}#middle .row table td a{color:#cbd1da}.results thead th{background:#354150;color:#cbd1da}#middle .row .results tr:hover td{background:hsla(155,43%,25%,1)}#middle .row .search-criteria{background:#354150}#middle .row .search-criteria td.adv_search_option,#middle .row .search-criteria td:first-child{background:#354150;color:#cbd1da!important}#middle .row .search-criteria td{background:#354150;color:#cbd1da;border-right:1px solid #1b1e24;border-bottom:1px solid #1b1e24}#middle .search-criteria td input{background:#2a313c;color:#6c798d}#middle .search-criteria td button.solo{transition:.1s ease-in-out;background:transparent;max-width:100%;color:#5ad9a4;top:-1px;font-size:11px;font-weight:700;text-transform:uppercase;border:3px solid #5ad9a4;border-radius:25px;padding:5px 10px}#middle .search-criteria td button.solo:hover{color:#fff;background:#5ad9a4;text-decoration:none}.form-control,.select2-selection__rendered,.select2-selection__rendered{background:#2a313c;border:1px solid #1b1e24}.select2-container--bootstrap .select2-selection--single{background-color:#2a313c}.select2-container--bootstrap .select2-selection--single .select2-selection__rendered{color:#6c798d}.select2-dropdown{background-color:#2a313c;color:#6c798d}.select2-container--bootstrap .select2-dropdown{border:1px solid #1b1e24}.select2-container--bootstrap .select2-search--dropdown .select2-search__field{border:1px solid #1b1e24;background-color:#2a313c;color:#6c798d}.select2-container--bootstrap .select2-results__option[aria-selected=true]{background-color:#354150}.select2-container--bootstrap .select2-selection{background-color:#2a313c;border:1px solid #1b1e24!important}.select2-container--bootstrap .select2-selection .select2-selection__rendered{border:none}.select2-container,.select2-container--bootstrap{width:400px!important}input:focus{border-color:#6c798d!important;color:#cbd1da}#middle .pagination{background:#2a313c;color:#cbd1da}#middle .pagination li{border-left:1px solid #1b1e24}#middle .pagination li a{background:#2a313c;color:#cbd1da}#middle .pagination li a:hover{background:#6c798d}#middle .row table.infos-torrent td.adv_search_option,#middle .row table.infos-torrent td:first-child{background:#354150;color:#cbd1da}#middle .row table.infos-torrent td{background:#354150;color:#cbd1da;border-right:1px solid #1b1e24;border-bottom:1px solid #1b1e24}.description-header{background:#354150;border-bottom:1px solid #1b1e24}#middle table td .red{color:#ef5f5f}#middle .default{background:#354150!important;color:#cbd1da}#middle .default font{color:#cbd1da}#middle .default a{color:#5ad9a4}#nfoModal .modal-sm{max-width:60%!important}#nfoModal .modal-body{background-color:#354150!important;color:#cbd1da}#nfoModal .modal-header{border-color:rgba(0,0,0,.125)}#nfoModal .modal-footer{background-color:#354150!important;border-color:rgba(0,0,0,.125)}#commentary{background:#354150}#middle .comment h4,#middle #commentary h4{color:#cbd1da}#middle .add-comment,#middle .add-note{background:#354150;border-bottom:3px solid #6c798d}#commentary li{border-top:1px solid #6c798d}#commentary li .message{background:#6c798d;border:1px solid #6c798d}#commentary li .message:before{border-right:15px solid #6c798d}#commentary li .message:after{border-right:15px solid #6c798d}#commentary li .message .add{color:#cbd1da}#commentary li .message a{color:#fff}#commentary li .left{background:#6c798d;border:1px solid #1b1e24}#comment-list li img[src$="/assets/img/avatar.jpg"]{filter:invert(70%)}#comment-list li .ratio .red{color:#9c0b0b}.wysibb{background:#354150;border:1px solid #1b1e24}.wysibb .wysibb-toolbar .wysibb-toolbar-container .wysibb-toolbar-btn .fonticon{color:#6c798d;text-shadow:none}.wysibb .wysibb-toolbar{border-bottom:1px solid #1b1e24}.wysibb .wysibb-toolbar .wysibb-toolbar-container{border-right:1px solid #1b1e24}.wysibb-toolbar-btn{color:#6c798d}.wysibb-body{color:#fff}.bottom-resize-line:hover,.bottom-resize-line.drag{background:#6c798d}#middle .row table td .input-table{background:#2a313c;color:#cbd1da;border:1px solid #1b1e24;border-radius:5px}#connect{background:#2c343f}#connect h3{color:#cbd1da}#connect input{background:#2a313c;color:#6c798d;border-top:1px solid #1b1e24}#connect input:focus{color:#cbd1da}#connect a{color:#6c798d}#connect a:hover{color:#cbd1da}.form-control:focus{background:#2a313c;color:#cbd1da;border-color:#6c798d!important}.form-control,.select2-selection__rendered,.select2-selection__rendered{color:#6c798d}.field-label-responsive label{color:#6c798d}#middle .row table.detail-account{border-left:2px solid #6c798d}#middle .row table td.adv_search_option,#middle .row table td:first-child{color:#cbd1da} .card{background:#354150}.card-footer{border-top:1px solid rgba(27,30,36,.4)!important;background:#354150}#top_panel img[src$="/assets/img/avatar.jpg"]{filter:invert(70%);border-color:rgba(0,0,0,.125)}.table-bordered{border:solid 1px #1b1e24}.inbox thead th{background:#354150;color:#cbd1da}.inbox thead td{border:solid 1px #1b1e24}#middle section.content div.row div.card img[src$="/assets/img/avatar.jpg"]{filter:invert(70%)} .well{background-color:#343a40;border-color:rgba(0,0,0,.125)}.well[style^="background:#fff"]{background-color:#6c757d!important;border-color:rgba(0,0,0,.125)}.well[style^="background:#e0ffd7"]{background-color:#48a648!important}.well[style^="background:#f0f0f0"]{text-decoration:line-through;background-color:#555!important;border-color:rgba(0,0,0,.125)}.well strong[style^="color:#3b454e"]{color:#cbd1da!important}[role=button],a,area,button,input,label,select,summary,textarea{touch-action:auto}#middle .default .date,#middle #description .date{background:#2c343f;border-top:1px solid rgba(27,30,36,.4)}#middle .row .results td{background-color:#2c343f;border:solid 1px #1b1e24;color:#cbd1da}#middle .row table td{background:#354150;color:#cbd1da;border-right:1px solid #1b1e24;border-bottom:1px solid #1b1e24}#middle .row .results tr:nth-child(odd) td{background:#232a33}.results thead th{background:#354150;color:#cbd1da}::-webkit-scrollbar{background-color:#202324;color:#aba499}::-webkit-scrollbar-thumb{background-color:#454a4d}::-webkit-scrollbar-thumb:hover{background-color:#575e62}::-webkit-scrollbar-thumb:active{background-color:#484e51}::-webkit-scrollbar-corner{background-color:#181a1b}#middle .row .results tr:hover td{background:hsla(155,43%,25%,1)}.results{background:#232a33}#panel-btn strong{background-image:url(https://i.ibb.co/sw65szs/blue-rank.gif);color:#009CD6;font-weight:bold;text-shadow:#009CD6 2px 0 6px;}
`;
GM_addStyle(customStyles);
}
})();