From 64e1d218b10d019eb4cde113753cb18e6110a952 Mon Sep 17 00:00:00 2001 From: rix Date: Sun, 21 Jul 2024 11:31:01 +0200 Subject: [PATCH] v.20.1.3 - Refactor tampermonkey setup / external links --- feedcrawler/providers/version.py | 2 +- feedcrawler/web_interface/serve/api.py | 335 ++---------------- .../serve/tampermonkey_scripts.py | 309 ++++++++++++++++ .../vuejs_frontend/package-lock.json | 144 ++++---- .../web_interface/vuejs_frontend/package.json | 8 +- .../vuejs_frontend/src/components/Help.vue | 10 +- .../vuejs_frontend/src/components/MyJD.vue | 24 +- 7 files changed, 434 insertions(+), 398 deletions(-) create mode 100644 feedcrawler/web_interface/serve/tampermonkey_scripts.py diff --git a/feedcrawler/providers/version.py b/feedcrawler/providers/version.py index b83219f8..f3fd9a2f 100644 --- a/feedcrawler/providers/version.py +++ b/feedcrawler/providers/version.py @@ -8,7 +8,7 @@ def get_version(): - return "20.1.2" + return "20.1.3" def create_version_file(): diff --git a/feedcrawler/web_interface/serve/api.py b/feedcrawler/web_interface/serve/api.py index 432e5064..3ed1a0c2 100644 --- a/feedcrawler/web_interface/serve/api.py +++ b/feedcrawler/web_interface/serve/api.py @@ -42,6 +42,7 @@ from feedcrawler.providers.sqlite_database import FeedDb, ListDb from feedcrawler.providers.url_functions import get_url_headers, post_url_headers, get_url from feedcrawler.web_interface.serve.server import Server +from feedcrawler.web_interface.serve import tampermonkey_scripts helper_active = False already_added = [] @@ -252,6 +253,18 @@ def delete_log_entry(b64_entry): except: return abort(400, "Failed") + @app.get(prefix + "/redirect_sponsors/") + def redirect_sponsors(): + redirect("https://github.com/sponsors/rix1337") + + @app.get(prefix + "/redirect_captcha/") + def redirect_captcha(): + redirect("https://getcaptchasolution.com/zuoo67f5cq") + + @app.get(prefix + "/redirect_hoster/") + def redirect_captcha(): + redirect("https://linksnappy.com/?ref=397097") + @app.get(prefix + "/api/settings/") @auth_basic(is_authenticated_user) def get_settings(): @@ -1339,342 +1352,52 @@ def post_lists(): except: return abort(400, "Failed") - @app.get(prefix + "/sponsors_helper/feedcrawler_helper_sj.user.js") + @app.get(prefix + "/tampermonkey/feedcrawler_helper_sj.user.js") @auth_basic(is_authenticated_user) def feedcrawler_helper_sj(): try: hostnames = CrawlerConfig('Hostnames') sj = hostnames.get('sj') dj = hostnames.get('dj') - return f"""// ==UserScript== - // @name FeedCrawler Helper (SJ/DJ) - // @author rix1337 - // @description Forwards decrypted SJ/DJ Download links to FeedCrawler - // @version 0.3.0 - // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js - // @match https://{sj}/* - // @match https://{dj}/* - // @exclude https://{sj}/serie/search?q=* - // @exclude https://{dj}/serie/search?q=* - // ==/UserScript== - - document.body.addEventListener('mousedown', function (e) {{ - if (e.target.tagName != "A") return; - var anchor = e.target; - if (anchor.href.search(new RegExp('{sj}/serie//i')) != -1) {{ - anchor.href = anchor.href + '#' + anchor.text; - }} else if (anchor.href.search(new RegExp('{dj}/serie//i')) != -1) {{ - anchor.href = anchor.href + '#' + anchor.text; - }} - }}); - - var tag = window.location.hash.replace("#", "").split('|'); - var title = tag[0]; - var password = tag[1]; - if (title) {{ - $('.wrapper').prepend('

[FeedCrawler Helper] ' + title + '

'); - $(".container").hide(); - var checkExist = setInterval(async function () {{ - if ($("tr:contains('" + title + "')").length) {{ - $(".container").show(); - $("tr:contains('" + title + "')")[0].lastChild.firstChild.click(); - clearInterval(checkExist); - }} - }}, 100); - }}""" + return tampermonkey_scripts.get_feedcrawler_helper_sj(sj, dj) except: return abort(400, "Failed") - @app.get(prefix + "/sponsors_helper/feedcrawler_sponsors_helper_sj.user.js") + @app.get(prefix + "/tampermonkey/feedcrawler_sponsors_helper_sj.user.js") @auth_basic(is_authenticated_user) def feedcrawler_sponsors_helper_sj(): if not helper_active: - return abort(403, "Forbidden") + redirect_sponsors() try: hostnames = CrawlerConfig('Hostnames') sj = hostnames.get('sj') dj = hostnames.get('dj') - return f"""// ==UserScript== - // @name FeedCrawler Sponsors Helper (SJ/DJ) - // @version 0.5.2 - // @description Clicks the correct download button on SJ/DJ sub pages to speed up Click'n'Load - // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js - // @match https://{sj}/* - // @match https://{dj}/* - // @exclude https://{sj}/serie/search?q=* - // @exclude https://{dj}/serie/search?q=* - // @grant window.close - // ==/UserScript== - - // Hier muss die von außen erreichbare Adresse des FeedCrawlers stehen (nicht bspw. die Docker-interne): - const sponsorsURL = '{shared_state.values["local_address"]}'; - // Hier kann ein Wunschhoster eingetragen werden (ohne www. und .tld): - const sponsorsHoster = ''; - - $.extend($.expr[':'], {{ - 'containsi': function(elem, i, match, array) {{ - return (elem.textContent || elem.innerText || '').toLowerCase() - .indexOf((match[3] || "").toLowerCase()) >= 0; - }} - }}); - - document.body.addEventListener('mousedown', function (e) {{ - if (e.target.tagName != "A") return; - var anchor = e.target; - if (anchor.href.search(new RegExp('{sj}/serie//i')) != -1) {{ - anchor.href = anchor.href + '#' + anchor.text; - }} else if (anchor.href.search(new RegExp('{dj}/serie//i')) != -1) {{ - anchor.href = anchor.href + '#' + anchor.text; - }} - }}); - - const tag = window.location.hash.replace("#", "").split('|'); - const title = tag[0]; - const password = tag[1]; - if (title && title !== "login") {{ - $('.wrapper').prepend('

[FeedCrawler Sponsors Helper] ' + title + '

'); - $(".container").hide(); - let i = 0; - const checkExist = setInterval(function () {{ - i++; - if ($("tr:contains('" + title + "')").length) {{ - $(".container").show(); - $("tr:contains('" + title + "')")[0].lastChild.firstChild.click(); - if (i > 24) {{ - const requiresLogin = $(".alert-warning").length; - if (requiresLogin) {{ - console.log("[FeedCrawler Sponsors Helper] Login required for: " + title); - clearInterval(checkExist); - window.open("https://" + $(location).attr('hostname') + "#login|" + btoa(window.location)); - window.close(); - }} - clearInterval(checkExist); - }} else {{ - console.log("miss") - }} - }} - }}, 100); - - let j = 0; - let dl = false; - const dlExists = setInterval(function () {{ - j++; - if ($("tr:contains('Download Part')").length) {{ - const items = $("tr:contains('Download Part')").find("a"); - const links = []; - items.each(function (index) {{ - links.push(items[index].href); - }}); - console.log("[FeedCrawler Sponsors Helper] found download links: " + links); - clearInterval(dlExists); - window.open(sponsorsURL + '/sponsors_helper/to_download/' + btoa(links + '|' + title + '|' + password)); - window.close(); - }} else if (j > 24 && !dl) {{ - if (sponsorsHoster && $("button:containsi('" + sponsorsHoster + "')").length) {{ - $("button:containsi('" + sponsorsHoster + "')").click(); - }} else if ($("button:containsi('1fichier')").length) {{ - $("button:containsi('1fichier')").click(); - }} else if ($("button:containsi('ddownload')").length) {{ - $("button:containsi('ddownload')").click(); - }} else if ($("button:containsi('turbo')").length) {{ - $("button:containsi('turbo')").click(); - }} else if ($("button:containsi('filer')").length) {{ - $("button:containsi('filer')").click(); - }} else {{ - $("div.modal-body").find("button.btn.btn-secondary.btn-block").click(); - }} - console.log("[FeedCrawler Sponsors Helper] Clicked Download button to trigger reCAPTCHA"); - dl = true; - }} - }}, 100); - }}""" + return tampermonkey_scripts.get_feedcrawler_sponsors_helper_sj(sj, dj, shared_state.values["local_address"]) except: return abort(400, "Failed") - @app.get(prefix + "/sponsors_helper/feedcrawler_sponsors_helper_fc.user.js") + @app.get(prefix + "/tampermonkey/feedcrawler_sponsors_helper_fc.user.js") @auth_basic(is_authenticated_user) def feedcrawler_sponsors_helper_fc(): if not helper_active: - return abort(403, "Forbidden") - hostnames = CrawlerConfig('Hostnames') - fx = hostnames.get('fx') - sf = hostnames.get('sf') + redirect_sponsors() try: - return f"""// ==UserScript== - // @name FeedCrawler Sponsors Helper (FC) - // @author rix1337 - // @description Forwards Click'n'Load to FeedCrawler - // @version 0.7.4 - // @match *.filecrypt.cc/* - // @match *.filecrypt.co/* - // @match *.filecrypt.to/* - // @exclude http://filecrypt.cc/helper.html* - // @exclude http://filecrypt.co/helper.html* - // @exclude http://filecrypt.to/helper.html* - // @grant window.close - // ==/UserScript== - - // Hier muss die von außen erreichbare Adresse des FeedCrawlers stehen (nicht bspw. die Docker-interne): - const sponsorsURL = '{shared_state.values["local_address"]}'; - // Hier kann ein Wunschhoster eingetragen werden (ohne www. und .tld): - const sponsorsHoster = ''; - - const tag = window.location.hash.replace("#", "").split('|'); - const title = tag[0]; - const password = tag[1]; - const ids = tag[2]; - const urlParams = new URLSearchParams(window.location.search); - - function Sleep(milliseconds) {{ - return new Promise(resolve => setTimeout(resolve, milliseconds)); - }} - - let pw = ""; - - let fx = false; - try {{ - fx = (document.getElementById("customlogo").getAttribute('src') === '/css/custom/f38ed.png') - }} catch {{}} - - const checkPass = setInterval(function () {{ - if (document.getElementById("p4assw0rt")) {{ - if (password) {{ - pw = password; - }} else if (fx) {{ - pw = '{fx.split('.')[0]}'; - }} else {{ - pw = '{sf}'; - }} - }} else {{ - pw = ""; - }} - clearInterval(checkPass); - }}, 100); - - const enterPass = setInterval(function () {{ - if (pw) {{ - console.log("[FeedCrawler Sponsors Helper] entering Password: " + pw); - try {{ - document.getElementById("p4assw0rt").value = pw; - document.getElementById("p4assw0rt").parentNode.nextElementSibling.click(); - }} catch (e) {{ - console.log("[FeedCrawler Sponsors Helper] Password set Error: " + e); - }} - clearInterval(enterPass); - }} - }}, 100); - - const checkAd = setInterval(function () {{ - if (document.querySelector('#cform > div > div > div > div > ul > li:nth-child(2)') !== null) {{ - document.querySelector('#cform > div > div > div > div > ul > li:nth-child(2)').style.display = 'none'; - clearInterval(checkAd); - }} - }}, 100); - - let mirrorsAvailable = false; - try {{ - mirrorsAvailable = document.querySelector('.mirror').querySelectorAll("a"); - }} catch {{}} - let cnlAllowed = false; - - if (mirrorsAvailable && sponsorsHoster) {{ - const currentURL = window.location.href; - let desiredMirror = ""; - let i; - for (i = 0; i < mirrorsAvailable.length; i++) {{ - if (mirrorsAvailable[i].text.includes(sponsorsHoster)) {{ - let ep = ""; - const cur_ep = urlParams.get('episode'); - if (cur_ep) {{ - ep = "&episode=" + cur_ep; - }} - desiredMirror = mirrorsAvailable[i].href + ep + window.location.hash; - }} - }} - - if (desiredMirror) {{ - if (!currentURL.toLowerCase().includes(desiredMirror.toLowerCase())) {{ - console.log("[FeedCrawler Sponsors Helper] switching to desired Mirror: " + sponsorsHoster); - window.location = desiredMirror; - }} else {{ - console.log("[FeedCrawler Sponsors Helper] already at the desired Mirror: " + sponsorsHoster); - cnlAllowed = true; - }} - }} else {{ - console.log("[FeedCrawler Sponsors Helper] desired Mirror not available: " + sponsorsHoster); - cnlAllowed = true; - }} - }} else {{ - cnlAllowed = true; - }} - - const cnlExists = setInterval(async function () {{ - if (cnlAllowed && document.getElementsByClassName("cnlform").length) {{ - clearInterval(cnlExists); - document.getElementById("cnl_btn").click(); - console.log("[FeedCrawler Sponsors Helper] attempting Click'n'Load"); - await Sleep(10000); - window.close(); - }} - }}, 100);""" + hostnames = CrawlerConfig('Hostnames') + fx = hostnames.get('fx') + sf = hostnames.get('sf') + return tampermonkey_scripts.get_feedcrawler_sponsors_helper_fc(fx, sf, shared_state.values["local_address"]) except: return abort(400, "Failed") - @app.get(prefix + "/sponsors_helper/feedcrawler_sponsors_helper_nx.user.js") + @app.get(prefix + "/tampermonkey/feedcrawler_sponsors_helper_nx.user.js") @auth_basic(is_authenticated_user) def feedcrawler_sponsors_helper_nx(): if not helper_active: - return abort(403, "Forbidden") - hostnames = CrawlerConfig('Hostnames') - nx = hostnames.get('nx') + redirect_sponsors() try: - return f"""// ==UserScript== - // @name FeedCrawler Sponsors Helper (NX) - // @author rix1337 - // @description Forwards decrypted links to FeedCrawler - // @version 0.1.1 - // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js - // @match https://{nx}/release/* - // @grant window.close - // ==/UserScript== - // Hier muss die von außen erreichbare Adresse des FeedCrawlers stehen (nicht bspw. die Docker-interne): - const sponsorsURL = '{shared_state.values["local_address"]}'; - - function Sleep(milliseconds) {{ - return new Promise(resolve => setTimeout(resolve, milliseconds)); - }} - - var tag = window.location.hash.replace("#", "").split('|'); - var title = tag[0]; - var password = '{nx}'; - - if (title) {{ - await Sleep(3000); - $('h2').prepend('

[FeedCrawler Sponsors Helper] ' + title + '

'); - var dl = false; - var dlExists = setInterval(function() {{ - console.log($("tr:contains("+ title +")").find("a[href*=filer]").length) - if ($("tr:contains("+ title +")").find("a[href*=filer]").length) {{ - var link = $("tr:contains("+ title +")").find("a[href*=filer]")[0]["href"].replace("https://referer.to/?", ""); - var links = [link]; - console.log("[FeedCrawler Sponsors Helper] found download links: " + links); - clearInterval(dlExists); - window.open(sponsorsURL + '/sponsors_helper/to_download/' + btoa(links + '|' + title + '|' + password)); - window.close(); - }} - }}, 1000); - var tolinkExists = setInterval(function() {{ - console.log($("tr:contains("+ title +")").find("a[href*=tolink]").length) - if ($("tr:contains("+ title +")").find("a[href*=tolink]").length) {{ - var link = $("tr:contains("+ title +")").find("a[href*=tolink]")[0]["href"].replace("https://referer.to/?", ""); - var links = [link]; - console.log("[FeedCrawler Sponsors Helper] found encrypted download links: " + links); - clearInterval(tolinkExists); - window.open(sponsorsURL + '/sponsors_helper/replace_decrypt/' + btoa(links + '|' + title + '|' + password)); - window.close(); - }} - }}, 1000); - }}""" + hostnames = CrawlerConfig('Hostnames') + nx = hostnames.get('nx') + return tampermonkey_scripts.get_feedcrawler_sponsors_helper_nx(nx, shared_state.values["local_address"]) except: return abort(400, "Failed") diff --git a/feedcrawler/web_interface/serve/tampermonkey_scripts.py b/feedcrawler/web_interface/serve/tampermonkey_scripts.py new file mode 100644 index 00000000..1c92c8f1 --- /dev/null +++ b/feedcrawler/web_interface/serve/tampermonkey_scripts.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- +# FeedCrawler +# Projekt von https://github.com/rix1337 +# Dieses Modul stellt Tampermonkey-Scripte für die API des FeedCrawlers bereit. + +def get_feedcrawler_helper_sj(sj, dj): + return f"""// ==UserScript== + // @name FeedCrawler Helper (SJ/DJ) + // @author rix1337 + // @description Forwards decrypted SJ/DJ Download links to FeedCrawler + // @version 0.3.0 + // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js + // @match https://{sj}/* + // @match https://{dj}/* + // @exclude https://{sj}/serie/search?q=* + // @exclude https://{dj}/serie/search?q=* + // ==/UserScript== + + document.body.addEventListener('mousedown', function (e) {{ + if (e.target.tagName != "A") return; + var anchor = e.target; + if (anchor.href.search(new RegExp('{sj}/serie//i')) != -1) {{ + anchor.href = anchor.href + '#' + anchor.text; + }} else if (anchor.href.search(new RegExp('{dj}/serie//i')) != -1) {{ + anchor.href = anchor.href + '#' + anchor.text; + }} + }}); + + var tag = window.location.hash.replace("#", "").split('|'); + var title = tag[0]; + var password = tag[1]; + if (title) {{ + $('.wrapper').prepend('

[FeedCrawler Helper] ' + title + '

'); + $(".container").hide(); + var checkExist = setInterval(async function () {{ + if ($("tr:contains('" + title + "')").length) {{ + $(".container").show(); + $("tr:contains('" + title + "')")[0].lastChild.firstChild.click(); + clearInterval(checkExist); + }} + }}, 100); + }}""" + + +def get_feedcrawler_sponsors_helper_sj(sj, dj, local_address): + return f"""// ==UserScript== + // @name FeedCrawler Sponsors Helper (SJ/DJ) + // @version 0.5.2 + // @description Clicks the correct download button on SJ/DJ sub pages to speed up Click'n'Load + // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js + // @match https://{sj}/* + // @match https://{dj}/* + // @exclude https://{sj}/serie/search?q=* + // @exclude https://{dj}/serie/search?q=* + // @grant window.close + // ==/UserScript== + + // Hier muss die von außen erreichbare Adresse des FeedCrawlers stehen (nicht bspw. die Docker-interne): + const sponsorsURL = '{local_address}'; + // Hier kann ein Wunschhoster eingetragen werden (ohne www. und .tld): + const sponsorsHoster = ''; + + $.extend($.expr[':'], {{ + 'containsi': function(elem, i, match, array) {{ + return (elem.textContent || elem.innerText || '').toLowerCase() + .indexOf((match[3] || "").toLowerCase()) >= 0; + }} + }}); + + document.body.addEventListener('mousedown', function (e) {{ + if (e.target.tagName != "A") return; + var anchor = e.target; + if (anchor.href.search(new RegExp('{sj}/serie//i')) != -1) {{ + anchor.href = anchor.href + '#' + anchor.text; + }} else if (anchor.href.search(new RegExp('{dj}/serie//i')) != -1) {{ + anchor.href = anchor.href + '#' + anchor.text; + }} + }}); + + const tag = window.location.hash.replace("#", "").split('|'); + const title = tag[0]; + const password = tag[1]; + if (title && title !== "login") {{ + $('.wrapper').prepend('

[FeedCrawler Sponsors Helper] ' + title + '

'); + $(".container").hide(); + let i = 0; + const checkExist = setInterval(function () {{ + i++; + if ($("tr:contains('" + title + "')").length) {{ + $(".container").show(); + $("tr:contains('" + title + "')")[0].lastChild.firstChild.click(); + if (i > 24) {{ + const requiresLogin = $(".alert-warning").length; + if (requiresLogin) {{ + console.log("[FeedCrawler Sponsors Helper] Login required for: " + title); + clearInterval(checkExist); + window.open("https://" + $(location).attr('hostname') + "#login|" + btoa(window.location)); + window.close(); + }} + clearInterval(checkExist); + }} else {{ + console.log("miss") + }} + }} + }}, 100); + + let j = 0; + let dl = false; + const dlExists = setInterval(function () {{ + j++; + if ($("tr:contains('Download Part')").length) {{ + const items = $("tr:contains('Download Part')").find("a"); + const links = []; + items.each(function (index) {{ + links.push(items[index].href); + }}); + console.log("[FeedCrawler Sponsors Helper] found download links: " + links); + clearInterval(dlExists); + window.open(sponsorsURL + '/sponsors_helper/to_download/' + btoa(links + '|' + title + '|' + password)); + window.close(); + }} else if (j > 24 && !dl) {{ + if (sponsorsHoster && $("button:containsi('" + sponsorsHoster + "')").length) {{ + $("button:containsi('" + sponsorsHoster + "')").click(); + }} else if ($("button:containsi('1fichier')").length) {{ + $("button:containsi('1fichier')").click(); + }} else if ($("button:containsi('ddownload')").length) {{ + $("button:containsi('ddownload')").click(); + }} else if ($("button:containsi('turbo')").length) {{ + $("button:containsi('turbo')").click(); + }} else if ($("button:containsi('filer')").length) {{ + $("button:containsi('filer')").click(); + }} else {{ + $("div.modal-body").find("button.btn.btn-secondary.btn-block").click(); + }} + console.log("[FeedCrawler Sponsors Helper] Clicked Download button to trigger reCAPTCHA"); + dl = true; + }} + }}, 100); + }}""" + + +def get_feedcrawler_sponsors_helper_fc(fx, sf, local_address): + return f"""// ==UserScript== + // @name FeedCrawler Sponsors Helper (FC) + // @author rix1337 + // @description Forwards Click'n'Load to FeedCrawler + // @version 0.7.4 + // @match *.filecrypt.cc/* + // @match *.filecrypt.co/* + // @match *.filecrypt.to/* + // @exclude http://filecrypt.cc/helper.html* + // @exclude http://filecrypt.co/helper.html* + // @exclude http://filecrypt.to/helper.html* + // @grant window.close + // ==/UserScript== + + // Hier muss die von außen erreichbare Adresse des FeedCrawlers stehen (nicht bspw. die Docker-interne): + const sponsorsURL = '{local_address}'; + // Hier kann ein Wunschhoster eingetragen werden (ohne www. und .tld): + const sponsorsHoster = ''; + + const tag = window.location.hash.replace("#", "").split('|'); + const title = tag[0]; + const password = tag[1]; + const ids = tag[2]; + const urlParams = new URLSearchParams(window.location.search); + + function Sleep(milliseconds) {{ + return new Promise(resolve => setTimeout(resolve, milliseconds)); + }} + + let pw = ""; + + let fx = false; + try {{ + fx = (document.getElementById("customlogo").getAttribute('src') === '/css/custom/f38ed.png') + }} catch {{}} + + const checkPass = setInterval(function () {{ + if (document.getElementById("p4assw0rt")) {{ + if (password) {{ + pw = password; + }} else if (fx) {{ + pw = '{fx.split('.')[0]}'; + }} else {{ + pw = '{sf}'; + }} + }} else {{ + pw = ""; + }} + clearInterval(checkPass); + }}, 100); + + const enterPass = setInterval(function () {{ + if (pw) {{ + console.log("[FeedCrawler Sponsors Helper] entering Password: " + pw); + try {{ + document.getElementById("p4assw0rt").value = pw; + document.getElementById("p4assw0rt").parentNode.nextElementSibling.click(); + }} catch (e) {{ + console.log("[FeedCrawler Sponsors Helper] Password set Error: " + e); + }} + clearInterval(enterPass); + }} + }}, 100); + + const checkAd = setInterval(function () {{ + if (document.querySelector('#cform > div > div > div > div > ul > li:nth-child(2)') !== null) {{ + document.querySelector('#cform > div > div > div > div > ul > li:nth-child(2)').style.display = 'none'; + clearInterval(checkAd); + }} + }}, 100); + + let mirrorsAvailable = false; + try {{ + mirrorsAvailable = document.querySelector('.mirror').querySelectorAll("a"); + }} catch {{}} + let cnlAllowed = false; + + if (mirrorsAvailable && sponsorsHoster) {{ + const currentURL = window.location.href; + let desiredMirror = ""; + let i; + for (i = 0; i < mirrorsAvailable.length; i++) {{ + if (mirrorsAvailable[i].text.includes(sponsorsHoster)) {{ + let ep = ""; + const cur_ep = urlParams.get('episode'); + if (cur_ep) {{ + ep = "&episode=" + cur_ep; + }} + desiredMirror = mirrorsAvailable[i].href + ep + window.location.hash; + }} + }} + + if (desiredMirror) {{ + if (!currentURL.toLowerCase().includes(desiredMirror.toLowerCase())) {{ + console.log("[FeedCrawler Sponsors Helper] switching to desired Mirror: " + sponsorsHoster); + window.location = desiredMirror; + }} else {{ + console.log("[FeedCrawler Sponsors Helper] already at the desired Mirror: " + sponsorsHoster); + cnlAllowed = true; + }} + }} else {{ + console.log("[FeedCrawler Sponsors Helper] desired Mirror not available: " + sponsorsHoster); + cnlAllowed = true; + }} + }} else {{ + cnlAllowed = true; + }} + + const cnlExists = setInterval(async function () {{ + if (cnlAllowed && document.getElementsByClassName("cnlform").length) {{ + clearInterval(cnlExists); + document.getElementById("cnl_btn").click(); + console.log("[FeedCrawler Sponsors Helper] attempting Click'n'Load"); + await Sleep(10000); + window.close(); + }} + }}, 100);""" + + +def get_feedcrawler_sponsors_helper_nx(nx, local_address): + return f"""// ==UserScript== + // @name FeedCrawler Sponsors Helper (NX) + // @author rix1337 + // @description Forwards decrypted links to FeedCrawler + // @version 0.1.1 + // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js + // @match https://{nx}/release/* + // @grant window.close + // ==/UserScript== + // Hier muss die von außen erreichbare Adresse des FeedCrawlers stehen (nicht bspw. die Docker-interne): + const sponsorsURL = '{local_address}'; + + function Sleep(milliseconds) {{ + return new Promise(resolve => setTimeout(resolve, milliseconds)); + }} + + var tag = window.location.hash.replace("#", "").split('|'); + var title = tag[0]; + var password = '{nx}'; + + if (title) {{ + await Sleep(3000); + $('h2').prepend('

[FeedCrawler Sponsors Helper] ' + title + '

'); + var dl = false; + var dlExists = setInterval(function() {{ + console.log($("tr:contains("+ title +")").find("a[href*=filer]").length) + if ($("tr:contains("+ title +")").find("a[href*=filer]").length) {{ + var link = $("tr:contains("+ title +")").find("a[href*=filer]")[0]["href"].replace("https://referer.to/?", ""); + var links = [link]; + console.log("[FeedCrawler Sponsors Helper] found download links: " + links); + clearInterval(dlExists); + window.open(sponsorsURL + '/sponsors_helper/to_download/' + btoa(links + '|' + title + '|' + password)); + window.close(); + }} + }}, 1000); + var tolinkExists = setInterval(function() {{ + console.log($("tr:contains("+ title +")").find("a[href*=tolink]").length) + if ($("tr:contains("+ title +")").find("a[href*=tolink]").length) {{ + var link = $("tr:contains("+ title +")").find("a[href*=tolink]")[0]["href"].replace("https://referer.to/?", ""); + var links = [link]; + console.log("[FeedCrawler Sponsors Helper] found encrypted download links: " + links); + clearInterval(tolinkExists); + window.open(sponsorsURL + '/sponsors_helper/replace_decrypt/' + btoa(links + '|' + title + '|' + password)); + window.close(); + }} + }}, 1000); + }}""" diff --git a/feedcrawler/web_interface/vuejs_frontend/package-lock.json b/feedcrawler/web_interface/vuejs_frontend/package-lock.json index e01785a9..3d9fb220 100644 --- a/feedcrawler/web_interface/vuejs_frontend/package-lock.json +++ b/feedcrawler/web_interface/vuejs_frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "feedcrawler-web", - "version": "20.1.2", + "version": "20.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "feedcrawler-web", - "version": "20.1.2", + "version": "20.1.3", "dependencies": { "@formkit/i18n": "^1.6.5", "@formkit/vue": "^1.6.5", @@ -15,20 +15,20 @@ "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", "pinia": "^2.1.7", - "sass": "^1.77.6", - "vue": "^3.4.31", + "sass": "^1.77.8", + "vue": "^3.4.33", "vue-tippy": "^6.4.4", "vuejs-paginate-next": "^1.0.2" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.5", - "vite": "^5.3.3" + "vite": "^5.3.4" } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "bin": { "parser": "bin/babel-parser.js" }, @@ -534,9 +534,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@meforma/vue-toaster": { "version": "1.3.0", @@ -798,49 +798,49 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz", - "integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", + "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.31", + "@vue/shared": "3.4.33", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz", - "integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", + "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", "dependencies": { - "@vue/compiler-core": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-core": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz", - "integrity": "sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", + "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.31", - "@vue/compiler-dom": "3.4.31", - "@vue/compiler-ssr": "3.4.31", - "@vue/shared": "3.4.31", + "@vue/compiler-core": "3.4.33", + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", - "postcss": "^8.4.38", + "postcss": "^8.4.39", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz", - "integrity": "sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", + "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", "dependencies": { - "@vue/compiler-dom": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-dom": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/devtools-api": { @@ -849,49 +849,49 @@ "integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==" }, "node_modules/@vue/reactivity": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.31.tgz", - "integrity": "sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.33.tgz", + "integrity": "sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==", "dependencies": { - "@vue/shared": "3.4.31" + "@vue/shared": "3.4.33" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.31.tgz", - "integrity": "sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.33.tgz", + "integrity": "sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==", "dependencies": { - "@vue/reactivity": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/reactivity": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.31.tgz", - "integrity": "sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.33.tgz", + "integrity": "sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==", "dependencies": { - "@vue/reactivity": "3.4.31", - "@vue/runtime-core": "3.4.31", - "@vue/shared": "3.4.31", + "@vue/reactivity": "3.4.33", + "@vue/runtime-core": "3.4.33", + "@vue/shared": "3.4.33", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.31.tgz", - "integrity": "sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.33.tgz", + "integrity": "sha512-jTH0d6gQcaYideFP/k0WdEu8PpRS9MF8d0b6SfZzNi+ap972pZ0TNIeTaESwdOtdY0XPVj54XEJ6K0wXxir4fw==", "dependencies": { - "@vue/compiler-ssr": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33" }, "peerDependencies": { - "vue": "3.4.31" + "vue": "3.4.33" } }, "node_modules/@vue/shared": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz", - "integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==" + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", + "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==" }, "node_modules/@vue/test-utils": { "version": "2.4.6", @@ -1933,9 +1933,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.77.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", - "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -2174,9 +2174,9 @@ "deprecated": "Please see https://github.com/lydell/urix#deprecated" }, "node_modules/vite": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", - "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", @@ -2229,15 +2229,15 @@ } }, "node_modules/vue": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.31.tgz", - "integrity": "sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==", - "dependencies": { - "@vue/compiler-dom": "3.4.31", - "@vue/compiler-sfc": "3.4.31", - "@vue/runtime-dom": "3.4.31", - "@vue/server-renderer": "3.4.31", - "@vue/shared": "3.4.31" + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.33.tgz", + "integrity": "sha512-VdMCWQOummbhctl4QFMcW6eNtXHsFyDlX60O/tsSQuCcuDOnJ1qPOhhVla65Niece7xq/P2zyZReIO5mP+LGTQ==", + "dependencies": { + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-sfc": "3.4.33", + "@vue/runtime-dom": "3.4.33", + "@vue/server-renderer": "3.4.33", + "@vue/shared": "3.4.33" }, "peerDependencies": { "typescript": "*" diff --git a/feedcrawler/web_interface/vuejs_frontend/package.json b/feedcrawler/web_interface/vuejs_frontend/package.json index a212f631..8117a312 100644 --- a/feedcrawler/web_interface/vuejs_frontend/package.json +++ b/feedcrawler/web_interface/vuejs_frontend/package.json @@ -1,6 +1,6 @@ { "name": "feedcrawler-web", - "version": "20.1.2", + "version": "20.1.3", "type": "module", "scripts": { "dev": "vite", @@ -15,13 +15,13 @@ "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", "pinia": "^2.1.7", - "sass": "^1.77.6", - "vue": "^3.4.31", + "sass": "^1.77.8", + "vue": "^3.4.33", "vue-tippy": "^6.4.4", "vuejs-paginate-next": "^1.0.2" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.5", - "vite": "^5.3.3" + "vite": "^5.3.4" } } diff --git a/feedcrawler/web_interface/vuejs_frontend/src/components/Help.vue b/feedcrawler/web_interface/vuejs_frontend/src/components/Help.vue index 4d027286..9eadad57 100644 --- a/feedcrawler/web_interface/vuejs_frontend/src/components/Help.vue +++ b/feedcrawler/web_interface/vuejs_frontend/src/components/Help.vue @@ -11,12 +11,16 @@ function showCaptchasHelp() { }) } +function openSponsorsLink() { + window.open('/redirect_sponsors/', '_blank') +} + function openCaptchaLink() { - window.open('http://getcaptchasolution.com/zuoo67f5cq', '_blank') + window.open('/redirect_captcha/', '_blank') } function openHosterLink() { - window.open('http://linksnappy.com/?ref=397097', '_blank') + window.open('/redirect_hoster/', '_blank') } function getTimestamp(ms) { @@ -323,7 +327,7 @@ const waitTimeActive = computed(() => {

Der FeedCrawler Sponsors Helper ist ein Docker-Image, das alle derzeit bekannten CAPTCHAs vollautomatisch löst, und dem FeedCrawler entschlüsselt übergibt.

-

Das Image steht ausschließlich aktiven Das Image steht ausschließlich aktiven Sponsoren zur Verfügung (daher der Name).
diff --git a/feedcrawler/web_interface/vuejs_frontend/src/components/MyJD.vue b/feedcrawler/web_interface/vuejs_frontend/src/components/MyJD.vue index 5b562bc0..b762211c 100644 --- a/feedcrawler/web_interface/vuejs_frontend/src/components/MyJD.vue +++ b/feedcrawler/web_interface/vuejs_frontend/src/components/MyJD.vue @@ -682,25 +682,25 @@ function showSponsorsHelp() { Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (SJ) installieren! Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (DJ) installieren! Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (FC) installieren! Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (NX) installieren!

@@ -717,13 +717,13 @@ function showSponsorsHelp() {
Bitte zuerst Tampermonkey und dann - FeedCrawler Helper (SJ) installieren!

Bitte zuerst Tampermonkey und dann - FeedCrawler Helper (DJ) installieren!

@@ -774,25 +774,25 @@ function showSponsorsHelp() { Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (SJ) installieren! Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (DJ) installieren! Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (FC) installieren! Bitte zuerst Tampermonkey und dann - FeedCrawler Sponsors Helper (NX) installieren!
@@ -809,13 +809,13 @@ function showSponsorsHelp() {
Bitte zuerst Tampermonkey und dann - FeedCrawler Helper (SJ) installieren!

Bitte zuerst Tampermonkey und dann - FeedCrawler Helper (DJ) installieren!