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": [ "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", ], }, "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": [ "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", ], }, "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)