From 20b9d432ac5cd077702358c8a49fd424fbca7841 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Mon, 5 Feb 2024 12:09:23 +0100 Subject: [PATCH] qutebrowser: Use farside for dynamic redirects The redirector can now be fed with either a list of targets to pick from (as before) or a "farside" entry which points to a farside service redirect or multiple. The dict entry then looks like: ```python "quora": { "source": ["quora.com"], "farside": ["quetre"], } ``` It has the source service url as usual, but then instead of a "target" entry contains a "farside" entry. A redirect dict entry can take both "target" and "farside" entries, but will then always give precedence to farside choices. This should go a long way in helping keep OSS frontends up to date. It now mostly depends on farside entries in turn being updated. One potential concern is the new centralization in relying on farside as the redirect authority. --- qutebrowser/config/redirects.py | 216 ++++++++++++-------------------- 1 file changed, 83 insertions(+), 133 deletions(-) diff --git a/qutebrowser/config/redirects.py b/qutebrowser/config/redirects.py index c4f6868..218db30 100644 --- a/qutebrowser/config/redirects.py +++ b/qutebrowser/config/redirects.py @@ -1,6 +1,8 @@ import random -from urllib import parse import re +from typing import Any, Callable +from urllib import parse + from qutebrowser.api import interceptor from qutebrowser.extensions.interceptors import QUrl, RedirectException from qutebrowser.utils import message @@ -30,157 +32,81 @@ def fixScribePath(url: QUrl): redirects = { "youtube": { "source": ["youtube.com"], - "target": [ - "invidious.no-logs.com", - "inv.citw.lgbt", - "invidious.privacydev.net", - "inv.tux.pizza", - "invidious.einfachzocken.eu", - "invidious.perennialte.ch", - "invidious.fdn.fr", - "invidious.nerdvpn.de", - "inv.zzls.xyz", - "invidious.private.coffee", - "invidious.projectsegfau.lt", - "invidious.lunar.icu", - "yewtu.be", - "iv.melmac.space", - "iv.datura.network", - "piped.kavin.rocks", - ], + "farside": ["invidious"], + }, + "stackoverflow": { + "source": ["stackoverflow.com"], + "farside": ["anonymousoverflow"], }, "lbry": { "source": ["odysee.com"], - "target": [ - "lbry.bcow.xyz", - "odysee.076.ne.jp", - "librarian.pussthecat.org", - "lbry.mutahar.rocks", - "lbry.vern.cc", - ], + "farside": ["librarian"], }, "reddit": { "source": ["reddit.com"], - "target": [ - "teddit.ggc-project.de", - "teddit.kavin.rocks", - "teddit.zaggy.nl", - "teddit.namazso.eu", - "teddit.nautolan.racing", - "teddit.tinfoil-hat.net", - "teddit.domain.glass", - "libreddit.kavin.rocks", - "safereddit.com", - "reddit.invak.id", - "reddit.simo.sh", - "libreddit.strongthany.cc", - "libreddit.domain.glass", - "libreddit.pussthecat.org", - "libreddit.kylrth.com", - "libreddit.privacydev.net", - "l.opnxng.com", - "libreddit.oxymagnesium.com", - "reddit.utsav2.dev", - "libreddit.freedit.eu", - "lr.artemislena.eu", - "snoo.habedieeh.re", - ], + "farside": ["redlib"], + }, + "instagram": { + "source": ["instagram.com"], + "farside": ["proxigram"], }, "twitter": { "source": ["twitter.com"], - "target": [ - "nitter.net", - "nitter.42l.fr", - "nitter.fdn.fr", - "nitter.1d4.us", - "nitter.kavin.rocks", - "nitter.unixfox.eu", - "nitter.namazso.eu", - "nitter.moomoo.me", - "bird.trom.tf", - "nitter.it", - "twitter.censors.us", - "nitter.grimneko.de", - "twitter.076.ne.jp", - "n.l5.ca", - "unofficialbird.com", - "nitter.ungovernable.men", - ], + "farside": ["nitter"], }, "imdb": { "source": ["imdb.com"], - "target": [ - "libremdb.iket.me", - "libremdb.pussthecat.org", - "ld.vern.cc", - "binge.whatever.social", - "libremdb.lunar.icu", - ], + "farside": ["libremdb"], }, "translate": { "source": ["translate.google.com"], - "target": [ - "lingva.ml", - "translate.igna.wtf", - "translate.plausibility.cloud", - "translate.projectsegfau.lt", - "translate.dr460nf1r3.org", - "lingva.garudalinux.org", - "translate.jae.fi", - ], + "farside": ["lingva"], }, "tiktok": { "source": ["tiktok.com"], - "target": [ - "proxitok.pabloferreiro.es", - "proxitok.pussthecat.org", - "tok.habedieeh.re", - "proxitok.privacydev.net", - "proxitok.odyssey346.dev", - "tok.artemislena.eu", - "tok.adminforge.de", - "proxitok.manasiwibi.com", - "tik.hostux.net", - "tt.vern.cc", - "proxitok.mha.fi", - "proxitok.pufe.org", - "proxitok.marcopisco.com", - "cringe.whatever.social", - "proxitok.lunar.icu", - ], + "farside": ["proxitok"], }, "imgur": { "source": ["imgur.com"], - "target": [ - "imgur.artemislena.eu", - "ri.zzls.xyz", - "rimgo.bus-hit.me", - "rimgo.fascinated.cc", - "rimgo.hostux.net", - "rimgo.kling.gg", - "rimgo.lunar.icu", - "rimgo.marcopisco.com", - "rimgo.privacytools.io", - "rimgo.projectsegfau.lt", - "rimgo.pussthecat.org", - "rimgo.totaldarkness.net", - "rimgo.whateveritworks.org", - ], + "farside": ["rimgo"], }, "medium": { "source": ["medium.com"], - "target": [ - "scribe.rip", - "scribe.citizen4.eu", - "scribe.bus-hit.me", - "sc.vern.cc", - ], - "postprocess": fixScribePath, + "farside": ["scribe"], + # "postprocess": fixScribePath + }, + "fandom": { + "source": ["fandom.com"], + "farside": ["breezewiki"], + }, + "quora": { + "source": ["quora.com"], + "farside": ["quetre"], + # "postprocess": lambda url: message.info(f"CALLING QUORA WITH {url}") }, "google": { "source": ["google.com"], "target": [ + "search.albony.xyz", + "search.garudalinux.org", + "search.dr460nf1r3.org", + "s.tokhmi.xyz", + "search.sethforprivacy.com", "whoogle.dcs0.hu", + "gowogle.voring.me", + "whoogle.privacydev.net", + "wg.vern.cc", + "whoogle.hxvy0.gq", + "whoogle.hostux.net", + "whoogle.lunar.icu", + "wgl.frail.duckdns.org", + "whoogle.no-logs.com", + "whoogle.ftw.lol", + "whoogle-search--replitcomreside.repl.co", + "search.notrustverify.ch", + "whoogle.datura.network", + "whoogle.yepserver.xyz", + "search.nezumi.party", ], }, } @@ -199,18 +125,42 @@ def rewrite(request: interceptor.Request) -> None: url = request.request_url if service := _should_be_redirected(url.host()): - # TODO integrate pinging and always surf to fastest? - target = service["target"][random.randint(0, len(service["target"]) - 1)] - if target is not None and url.setHost(target) is not False: - if "postprocess" in service: - url = service["postprocess"](url) - try: - request.redirect(url) - except RedirectException as e: - message.error(str(e)) + if "farside" in service: + url = _farside_redirect(url, _pick_random(service["farside"])) + else: + srv = _pick_random(service["target"]) + url = _target_redirect(url, srv) + try: + request.redirect(url) + except RedirectException as e: + message.error(str(e)) + + if "postprocess" in service and isinstance(service["postprocess"], Callable): + url = service["postprocess"](url) -def _should_be_redirected(host: str, redirects: dict = redirects) -> dict | None: +def _farside_redirect(url: QUrl, service: str) -> QUrl: + try: + url.setHost("farside.link") + url.setPath(f"/{service}{url.path()}") + except RedirectException as e: + message.error(str(e)) + return url + + +def _target_redirect(url: QUrl, target: str) -> QUrl: + if target is not None and url.setHost(target) is not False: + return url + return url + + +def _pick_random(choices: list) -> Any: + return choices[random.randint(0, len(choices) - 1)] + + +def _should_be_redirected( + host: str, redirects: dict = redirects +) -> dict[str, list] | None: for service in redirects.values(): for source in service["source"]: if re.search(source, host):