// ==UserScript== // @name MyDealz | Kommentar-Export über alle Seiten // @namespace violentmonkey // @version 1.5 // @description Exportiert alle Kommentare eines MyDealz-Threads über alle Seiten als TXT (inkl. Fortschritt, Copy-All, Save-TXT, Popup-Blocker-Erkennung) // @match https://www.mydealz.de/diskussion/* // @match https://www.mydealz.de/deals/* // @match https://www.mydealz.de/gutscheine/* // @icon https://www.mydealz.de/assets/img/emojis/cool_b7b27.svg // @grant none // @downloadURL none // ==/UserScript== (function () { 'use strict'; // Selektoren const SELECTORS = { REPLY_BTN: 'button[data-t="moreReplies"]:not([disabled])', NEXT_PAGE: 'button[aria-label="Nächste Seite"]:not([disabled])', FIRST_PAGE: 'button[aria-label="Erste Seite"]:not([disabled])', LAST_PAGE: 'button[aria-label="Letzte Seite"]', CURRENT_PAGE: 'button[aria-label="Aktuelle Seite"]', COMMENT_LINK: 'a[href*="#comments"].button--type-text', COMMENT_BODY: '.comment-body .userHtml-content', THREAD_TITLE: '.thread-title .text--b, title' }; // Timings const INTERVAL = { CHECK: 500, CLICK: 200, PAGE: 2000 }; let collectedComments = []; let totalComments = 0; let exportBtn = null; // Hilfsfunktionen const sleep = ms => new Promise(r => setTimeout(r, ms)); function pageNum(sel) { const el = document.querySelector(sel); if (!el) return null; const m = el.textContent.match(/\d+/); return m ? parseInt(m[0], 10) : null; } function getTotalComments() { const a = document.querySelector(SELECTORS.COMMENT_LINK); if (!a) return 0; const m = a.textContent.match(/\d+/); return m ? parseInt(m[0], 10) : 0; } async function clickAllReplies() { while (true) { const btn = document.querySelector(SELECTORS.REPLY_BTN); if (!btn || btn.disabled || btn.offsetParent === null) break; btn.click(); await sleep(INTERVAL.CLICK); } } function collectCommentsOnPage() { const nodes = document.querySelectorAll(SELECTORS.COMMENT_BODY); const texts = Array.from(nodes).map(el => el.textContent.trim()); collectedComments.push(...texts); return texts.length; } function updateProgress(pageCollected, page, last) { const pct = totalComments ? Math.round(collectedComments.length / totalComments * 100) : 0; exportBtn.textContent = `Kommentare exportieren (${collectedComments.length} von ${totalComments} | Seite ${page}/${last} | ${pct}%)`; } async function goNextPage() { const btn = document.querySelector(SELECTORS.NEXT_PAGE); if (btn) { btn.click(); await sleep(INTERVAL.PAGE); return true; } return false; } function getThreadTitle() { let title = ''; const el = document.querySelector(SELECTORS.THREAD_TITLE); if (el) { title = el.textContent.trim(); } else { title = document.title.replace(/\|.*$/, '').trim(); } // Nur erlaubte Zeichen für Dateinamen return title.replace(/[\\\/:*?"<>|]/g, '').replace(/\s+/g, ' ').trim(); } function openExportWindow(text) { const w = window.open('', 'blank', 'width=800,height=600'); if (!w) { alert('Popup blockiert! Bitte Popup-Blocker für diese Seite deaktivieren.'); return; } const filename = getThreadTitle() || 'mydealz-comments'; w.document.title = 'MyDealz Kommentar-Export'; w.document.head.innerHTML = ` `; w.document.body.innerHTML = ` Copied!
`; const pre = w.document.getElementById('exportText'); pre.textContent = text; const btnC = w.document.getElementById('copyBtn'); const btnS = w.document.getElementById('saveBtn'); const msg = w.document.getElementById('copiedMsg'); btnC.onclick = () => { w.navigator.clipboard.writeText(text).then(() => { msg.style.opacity = 1; setTimeout(() => msg.style.opacity = 0, 2000); }); }; btnS.onclick = () => { const blob = new Blob([text], { type: 'text/plain;charset=utf-8' }); const url = w.URL.createObjectURL(blob); const a = w.document.createElement('a'); a.href = url; a.download = filename + '.txt'; w.document.body.appendChild(a); a.click(); w.URL.revokeObjectURL(url); w.document.body.removeChild(a); }; } async function runExport() { totalComments = getTotalComments(); collectedComments = []; // Immer erst auf Seite 1 starten const first = document.querySelector(SELECTORS.FIRST_PAGE); if (first) { first.click(); await sleep(INTERVAL.PAGE); } while (true) { await clickAllReplies(); const pageCollected = collectCommentsOnPage(); const page = pageNum(SELECTORS.CURRENT_PAGE) || 1; const last = pageNum(SELECTORS.LAST_PAGE) || 1; updateProgress(pageCollected, page, last); if (page >= last) break; const next = await goNextPage(); if (!next) break; } openExportWindow(collectedComments.join('\n\n---\n\n')); exportBtn.textContent = 'Fertig!'; exportBtn.disabled = false; } function injectExportBtn() { exportBtn = document.createElement('button'); exportBtn.textContent = 'Kommentare exportieren'; Object.assign(exportBtn.style, { position: 'fixed', top: '20px', right: '20px', padding: '10px 16px', background: '#d32f2f', color: '#fff', border: 'none', borderRadius: '4px', fontSize: '14px', cursor: 'pointer', zIndex: 9999 }); exportBtn.onclick = () => { exportBtn.disabled = true; exportBtn.textContent = 'Lade...'; runExport(); }; document.body.appendChild(exportBtn); } function ensureStartOnPageOne() { const url = new URL(window.location.href); const isCommentPage = url.hash.includes('comments'); const pageParam = url.searchParams.get('page'); if (pageParam && pageParam !== '1' && isCommentPage) { url.searchParams.set('page', '1'); url.hash = 'comments'; window.location.href = url.toString(); } else { injectExportBtn(); } } if (document.readyState === 'complete') { ensureStartOnPageOne(); } else { window.addEventListener('load', ensureStartOnPageOne); } })();