diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index eead904..914ed43 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -3,16 +3,16 @@ from typing import cast # pylint: disable=C0111 from qutebrowser.config.config import ConfigContainer # noqa: F401 -from qutebrowser.config.configfiles import ConfigAPI +from qutebrowser.config.configfiles import ConfigAPI # noqa: F401 config: ConfigAPI = cast(ConfigAPI, config) # noqa: F821 pylint: disable=E0602,C0103 c: ConfigContainer = cast(ConfigContainer, c) # noqa: F821 pylint: disable=E0602,C0103 - # Autogenerated config.py # Documentation: # qute://help/configuring.html # qute://help/settings.html + # load additional settings configured via autoconfig.yml _ = config.load_autoconfig() @@ -59,7 +59,7 @@ config.source("alias.py") config.source("maps.py") config.source("content.py") config.source("searchengines.py") -config.source("fossredirect.py") +config.source("redirects.py") # Tab-Bar # have tab bar on the right, not on the top diff --git a/qutebrowser/config/content.py b/qutebrowser/config/content.py index 4f2a44c..90c84bc 100644 --- a/qutebrowser/config/content.py +++ b/qutebrowser/config/content.py @@ -32,7 +32,6 @@ js_whitelist = [ "*://news.ycombinator.com/*", "*://old.reddit.com/*", "*://translate.google.com/*", - "*://hub.docker.com/*", "chrome://*/*", "file://*", "qute://*/*", diff --git a/qutebrowser/config/fossredirect.py b/qutebrowser/config/fossredirect.py deleted file mode 100644 index b18e3f0..0000000 --- a/qutebrowser/config/fossredirect.py +++ /dev/null @@ -1,203 +0,0 @@ -import random -import re -from dataclasses import dataclass, field -from typing import Callable -from urllib import parse - -from qutebrowser.api import interceptor -from qutebrowser.extensions.interceptors import QUrl, RedirectException -from qutebrowser.utils import message - - -@dataclass -class Service: - source: list[str] = field(default_factory=lambda: []) - target: list[str] = field(default_factory=lambda: []) - custom_targets: bool = False - preprocess: Callable[[QUrl], QUrl] | None = None - postprocess: Callable[[QUrl], QUrl] | None = None - - def __contains__(self, item: str): - for source in self.source: - if re.search(source, item): - return True - return False - - -def scribe_global_identity(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. - """ - 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 - - -def breezewiki_host_to_path(url: QUrl): - host = url.host() - if wiki := host[0 : host.find(".fandom.com")]: - url.setPath(f"/{wiki}{url.path()}") - return url - - -default_services = [ - Service(source=["youtube.com"], target=["invidious"]), - Service(source=["stackoverflow.com"], target=["anonymousoverflow"]), - Service(source=["odysee.com"], target=["librarian"]), - Service(source=["reddit.com"], target=["redlib"]), - Service(source=["instagram.com"], target=["proxigram"]), - Service(source=["twitter.com"], target=["nitter"]), - Service(source=["imdb.com"], target=["libremdb"]), - Service(source=["tiktok.com"], target=["proxitok"]), - Service(source=["imgur.com"], target=["rimgo"]), - Service( - source=["medium.com"], target=["scribe"], postprocess=scribe_global_identity - ), - Service( - source=["fandom.com"], target=["breezewiki"], preprocess=breezewiki_host_to_path - ), - Service(source=["quora.com"], target=["quetre"]), - Service(source=["google.com"], target=["whoogle"]), - Service(source=["genius.com"], target=["dumb"]), - Service(source=["translate.google.com"], target=["lingva", "simplytranslate"]), - Service(source=["deepl.com"], target=["simplytranslate"]), - Service(source=["bandcamp.com"], target=["tent"]), - Service( - custom_targets=True, - source=["pinterest.com"], - target=[ - "pain.thirtysix.pw", - "pt.bloat.cat", - "painterest.gitro.xyz", - ], - ), - Service( - custom_targets=True, - source=["tumblr.com"], - target=[ - "pb.bloat.cat", - "tb.opnxng.com", - "priviblur.pussthecat.org", - "priviblur.thebunny.zone", - "priviblur.gitro.xyz", - "priviblur.canine.tools", - ], - ), - Service( - custom_targets=True, - source=["twitch.com"], - target=[ - "safetwitch.drgns.space", - "safetwitch.projectsegfau.lt", - "stream.whateveritworks.org", - "safetwitch.datura.network", - "ttv.vern.cc", - "safetwitch.frontendfriendly.xyz", - "ttv.femboy.band", - "twitch.seitan-ayoub.lol", - "twitch.sudovanilla.org", - "safetwitch.r4fo.com", - "safetwitch.ducks.party", - "safetwitch.privacyredirect.com", - "st.ngn.tf", - "safetwitch.darkness.services", - "safetwitch.adminforge.de", - ], - ), - Service( - custom_targets=True, - source=["goodreads.com"], - target=[ - "biblioreads.eu.org", - "biblioreads.vercel.app", - "biblioreads.mooo.com", - "bl.vern.cc", - "biblioreads.lunar.icu", - "read.whateveritworks.org", - "biblioreads.privacyfucking.rocks", - "read.seitan-ayoub.lol", - "read.freedit.eu", - "biblioreads.ducks.party", - "biblioreads.snine.nl", - "biblioreads.privacyredirect.com", - "reads.nezumi.party", - "br.bloat.cat", - "read.canine.tools", - ], - ), -] - - -@dataclass -class Redirects: - services: list[Service] = field(default_factory=lambda: default_services) - selector: Callable[[list[str]], str] = lambda c: c[ - random.randint(0, len(c) - 1) - ] # selection algorithm - farside_service: str = ( - "farside.link" # Contains url for farside-like redirector (e.g. 'fastsi.de') - ) - - def __post_init__(self): - interceptor.register(self.intercept) - - def intercept(self, request: interceptor.Request) -> None: - # TODO: Implement config check (maybe 'privacy.redirect = False?') - # 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 url in self: - try: - request.redirect(self.get(url)) - except RedirectException as e: - message.error(str(e)) - - def get(self, url: QUrl) -> QUrl: - service = self.get_service(url) - if not service: - return url - - foss_host = self.selector(service.target) - if service.preprocess: - url = service.preprocess(url) - - try: - if service.custom_targets: - url.setHost(foss_host) - else: - url.setHost(self.farside_service) - url.setPath(f"/{foss_host}{url.path()}") - except RedirectException as e: - message.error(str(e)) - - if service.postprocess: - url = service.postprocess(url) - return url - - def get_service(self, url: QUrl) -> Service | None: - host = url.host() - for service in self.services: - if host in service: - return service - - def __contains__(self, item: QUrl): - if self.get_service(item): - return True - return False - - -_ = Redirects() diff --git a/qutebrowser/config/redirects.py b/qutebrowser/config/redirects.py new file mode 100644 index 0000000..d6db906 --- /dev/null +++ b/qutebrowser/config/redirects.py @@ -0,0 +1,207 @@ +import random +import re +from typing import Callable +from urllib import parse + +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 + + +type Service = dict[str, list[str]] +type Redirects = dict[str, Service] + + +redirects: Redirects = { + "youtube": { + "source": ["youtube.com"], + "farside": ["invidious"], + }, + "stackoverflow": { + "source": ["stackoverflow.com", "askubuntu.com"], + "farside": ["anonymousoverflow"], + }, + "lbry": { + "source": ["odysee.com"], + "farside": ["librarian"], + }, + "reddit": { + "source": ["reddit.com"], + "farside": ["redlib"], + }, + "instagram": { + "source": ["instagram.com"], + "farside": ["proxigram"], + }, + "twitter": { + "source": ["twitter.com"], + "farside": ["nitter"], + }, + "imdb": { + "source": ["imdb.com"], + "farside": ["libremdb"], + }, + "translate": { + "source": ["translate.google.com"], + "farside": ["lingva"], + }, + "tiktok": { + "source": ["tiktok.com"], + "farside": ["proxitok"], + }, + "imgur": { + "source": ["imgur.com"], + "farside": ["rimgo"], + }, + "medium": { + "source": ["medium.com"], + "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", + ], + }, + "biblioreads": { + "source": ["goodreads.com"], + "target": [ + "biblioreads.eu.org", + "biblioreads.vercel.app", + "biblioreads.mooo.com", + "bl.vern.cc", + "biblioreads.lunar.icu", + "read.whateveritworks.org", + "biblioreads.privacyfucking.rocks", + "read.seitan-ayoub.lol", + "read.freedit.eu", + "biblioreads.ducks.party", + "biblioreads.snine.nl", + "biblioreads.privacyredirect.com", + ], + }, + "safetwitch": { + "source": ["twitch.tv"], + "target": [ + "safetwitch.drgns.space", + "safetwitch.projectsegfau.lt", + "stream.whateveritworks.org", + "safetwitch.datura.network", + "ttv.vern.cc", + "safetwitch.frontendfriendly.xyz", + "ttv.femboy.band", + "twitch.seitan-ayoub.lol", + "st.ggtyler.dev", + "safetwitch.lunar.icu", + "twitch.sudovanilla.com", + "safetwitch.r4fo.com", + "safetwitch.ducks.party", + "safetwitch.nogafam.fr", + "safetwitch.privacyredirect.com", + "st.ngn.tf", + ], + }, +} + + +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()): + url = _farside_redirect( + url, _pick_random(service["farside" if "farside" in service else "target"]) + ) + 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 _farside_redirect(url: QUrl, service: str, use_fastside: bool = True) -> QUrl: + try: + url.setHost("fastside.link" if use_fastside else "farside.link") + url.setPath(f"/{service}{url.path()}") + except RedirectException as e: + message.error(str(e)) + return url + + +def _pick_random[T](choices: list[T]) -> T: + return choices[random.randint(0, len(choices) - 1)] + + +def _should_be_redirected( + # TODO: Update to use typedefs/classes instead of this jumble + host: str, + redirects: Redirects = redirects, +) -> Service | None: + for service in redirects.values(): + for source in service["source"]: + if re.search(source, host): + return service + return None + + +interceptor.register(rewrite) diff --git a/vcs/jj/config/jj/config.toml b/vcs/jj/config/jj/config.toml index 174fd04..e3d2f2b 100644 --- a/vcs/jj/config/jj/config.toml +++ b/vcs/jj/config/jj/config.toml @@ -9,7 +9,7 @@ key = "73BA40D5AFAF49C9" [git] sign-on-push = true subprocess = true -private-commits = "description(glob:'wip:*') | description(glob:'private:*')" # refuse to push WIP commits +private-commits = "description(glob:'wip:*')" # refuse to push WIP commits [ui] diff-editor = ["nvim", "-c", "DiffEditor $left $right $output"] @@ -32,7 +32,7 @@ concat( ''' [revsets] -log = "ancestors(@, 5) | ancestors(trunk()..(visible_heads() & mine()), 2) | trunk()" +log = "@ | ancestors(trunk()..(visible_heads() & mine()), 2) | trunk()" [revset-aliases] "bases" = "dev" diff --git a/vcs/jj/config/sh/alias.d/jj.sh b/vcs/jj/config/sh/alias.d/jj.sh index d4feeb7..2e51bfa 100644 --- a/vcs/jj/config/sh/alias.d/jj.sh +++ b/vcs/jj/config/sh/alias.d/jj.sh @@ -62,6 +62,5 @@ alias jb="jj log -r 'ancestors(heads(all()), 3)'" alias jrb="jj rebase" -# remote work -alias jrv="jj git remote list" + alias jp="jj git push"