import random from urllib import parse import re from qutebrowser.api import interceptor from qutebrowser.extensions.interceptors import QUrl, RedirectException from qutebrowser.utils import message def fixScribePath(url: QUrl): """Fix external medium blog to scribe translation. Some paths from medium will go through a 'global identity' path which messes up the actual url path we want to go to and puts it in queries. This puts it back on the path. """ # double unquoting necessary! # I suppose we double-wrap it earlier somewhere? # unquoted = parse.unquote( # url.path(options=QUrl.ComponentFormattingOption.FullyEncoded) # ) path = parse.unquote(f"{url.path()}{url.query()}", encoding="ascii") url.setQuery(None) new_path = re.sub(r"m/global-identity-2redirectUrl=", "", path) url.setPath( parse.quote(new_path), mode=QUrl.ParsingMode.StrictMode, ) return url redirects = { "youtube": { "source": ["youtube.com"], "target": [ "yt.oelrichsgarcia.de", "invidious.weblibre.org", "invidious.dhusch.de", "iv.ggtyler.dev", "invidious.baczek.me", "yt.funami.tech", "iv.melmac.space", "invidious.silur.me", "invidious.lidarshield.cloud", "invidious.flokinet.to", "invidious.snopyta.org", "invidious.kavin.rocks", "vid.puffyan.us", "yt.artemislena.eu", "invidious.nerdvpn.de", "invidious.tiekoetter.com", "invidious.namazso.eu", "inv.vern.cc", "yewtu.be", "inv.bp.projectsegfau.lt", "invidious.epicsite.xyz", "y.com.sb", "invidious.sethforprivacy.com", ], }, "lbry": { "source": ["odysee.com"], "target": [ "lbry.bcow.xyz", "odysee.076.ne.jp", "librarian.pussthecat.org", "lbry.mutahar.rocks", "lbry.vern.cc", ], }, "reddit": { "source": ["reddit.com"], "target": [ "td.vern.cc", "teddit.artemislena.eu", "teddit.bus-hit.me", "teddit.hostux.net", "teddit.namazso.eu", "teddit.net", "teddit.pussthecat.org", "teddit.sethforprivacy.com", "teddit.zaggy.nl", ], }, "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", ], }, "imdb": { "source": ["imdb.com"], "target": [ "libremdb.iket.me", "libremdb.pussthecat.org", "ld.vern.cc", "binge.whatever.social", "libremdb.lunar.icu", ], }, "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", ], }, "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", ], }, "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", ], }, "medium": { "source": ["medium.com"], "target": [ "scribe.rip", "scribe.citizen4.eu", "scribe.bus-hit.me", "sc.vern.cc", ], "postprocess": fixScribePath, }, "google": { "source": ["google.com"], "target": [ "whoogle.dcs0.hu", ], }, "wiki-en": { "source": ["en.wikipedia.org"], "target": [ "wiki.slipfox.xyz", "wikiless.funami.tech", "wikiless.org", "wikiless.tiekoetter.com", ], }, "wiki-de": { "source": ["de.wikipedia.org"], "target": [ "wiki.adminforge.de", ], }, } def rewrite(request: interceptor.Request) -> None: # if config.get(name="content.oss_redirects") is False: # return if ( request.resource_type != interceptor.ResourceType.main_frame or request.request_url.scheme() in {"data", "blob"} ): return 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)) def _should_be_redirected(host: str, redirects: dict = redirects) -> dict | None: for service in redirects.values(): for source in service["source"]: if re.search(source, host): return service return None interceptor.register(rewrite)