From eacecdd006f0b1687dba4921ca53216a749e35d3 Mon Sep 17 00:00:00 2001 From: Thomas Dehaeze Date: Mon, 9 Mar 2026 09:27:31 +0100 Subject: [PATCH] Update qutebrowser config and userscripts --- qutebrowser.org | 495 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 465 insertions(+), 30 deletions(-) diff --git a/qutebrowser.org b/qutebrowser.org index 97f143c..5f32176 100644 --- a/qutebrowser.org +++ b/qutebrowser.org @@ -50,7 +50,7 @@ c.content.blocking.adblock.lists = ['https://easylist.to/easylist/easylist.txt', * Editor #+begin_src python -c.editor.command = ['/usr/bin/alacritty', '--class', 'terminal,Floating', '-e', 'nvim', '{}'] +c.editor.command = ['kitty', '--class', 'terminal,Floating', '-e', 'nvim', '{}'] #+end_src * Downloads @@ -66,9 +66,9 @@ c.downloads.remove_finished = 10000 * File Select #+begin_src python -c.fileselect.handler = "default" -# c.fileselect.single_file.command = ['termine', '-e', 'ranger', '--choosefile', '{}'] -# c.fileselect.multiple_files.command = ['alacritty', '-e', 'ranger', '--choosefiles', '{}'] +c.fileselect.handler = "external" +c.fileselect.single_file.command = ['kitty', '--class', 'floating', '-e', 'yazi', '--chooser-file', '{}'] +c.fileselect.multiple_files.command = ['kitty', '--class', 'floating', '-e', 'yazi', '--chooser-file', '{}'] #+end_src * Colors @@ -186,8 +186,8 @@ c.url.searchengines = { #+end_src #+begin_src python -c.url.start_pages = ['https://homer.tdehaeze.xyz/'] -c.url.default_page = 'https://homer.tdehaeze.xyz/' +c.url.start_pages = ['https://homepage.tdehaeze.xyz/'] +c.url.default_page = 'https://homepage.tdehaeze.xyz/' #+END_SRC * Normal Bindings @@ -259,10 +259,11 @@ Go to specific websites config.bind('gy', 'open -t https://www.youtube.com/feed/subscriptions') config.bind('gf', 'open -t https://rss.tdehaeze.xyz/') config.bind('gr', 'open -t https://www.reddit.com/') - -config.bind('gh', 'open -t https://homer.tdehaeze.xyz/') +config.bind('gh', 'open -t https://homepage.tdehaeze.xyz/') config.bind('ge', 'open -t http://intranet.esrf.fr/') config.bind('gc', 'open -t https://calendar.esrf.fr/') +config.bind('gn', 'open -t https://node-red.tdehaeze.xyz/ui/#!/1') +config.bind('gN', 'open -t https://node-red.pic05.eu/ui/#!/3') config.bind('gb', 'open -t qute://bookmarks') config.bind('gH', 'open -t qute://history') @@ -275,11 +276,6 @@ config.bind('D', 'close') #+end_src * Custom Bindings -Create a Password for the current website -#+begin_src python -c.aliases['Password_Add'] = 'spawn --userscript ~/.config/qutebrowser/userscripts/add-passowrd.sh' -config.bind(',P', 'Password_Add') -#+end_src #+begin_src python c.aliases['proxy_homelab_on'] = 'set content.proxy socks5://localhost:8080' @@ -297,12 +293,36 @@ c.aliases['Password_Fill'] = 'spawn --userscript password_fill' config.bind(',p', 'Password_Fill') #+END_SRC +Create a Password for the current website +#+begin_src python +c.aliases['Password_Add'] = 'spawn --userscript ~/.config/qutebrowser/userscripts/add-passowrd.sh' +config.bind(',P', 'Password_Add') +#+end_src + +#+begin_src python +c.aliases['Password_ESRF'] = 'spawn --userscript password_ESRF' +config.bind(',e', 'Password_ESRF') +#+end_src + +#+begin_src python +c.aliases['OTP_ESRF'] = 'spawn --userscript OTP_ESRF' +config.bind(',3', 'OTP_ESRF') +#+end_src + +#+RESULTS: + Get Two Factor Authentication number. #+begin_src python c.aliases['OTP'] = 'spawn --userscript ~/.config/qutebrowser/userscripts/get-otp.sh' config.bind(',2', 'OTP') #+END_SRC +Open current page with Firefox: +#+begin_src python +c.aliases['Firefox'] = 'spawn --detach firefox-developer-edition --new-tab {url}' +config.bind(',f', 'Firefox') +#+END_SRC + Open Youtube video using =mpv= #+begin_src python c.aliases['MPV_view'] = 'spawn --detach mpv --force-window yes {url}' @@ -457,6 +477,16 @@ choose_entry() { } #+end_src +** Password_fill_ESRF +#+begin_src bash :tangle ~/.config/qutebrowser/userscripts/password_ESRF +echo "insert-text $(pass esrf.fr/dehaeze | head -n 1) ;; cmd-later 100 fake-key " >> "$QUTE_FIFO" +#+end_src + +** OTP_fill_ESRF +#+begin_src bash :tangle ~/.config/qutebrowser/userscripts/OTP_ESRF +echo "insert-text $(pass otp totp-esrf) ;; cmd-later 100 fake-key " >> "$QUTE_FIFO" +#+end_src + ** Org-Capture #+begin_src bash :tangle ~/.config/qutebrowser/userscripts/org-capture.sh readonly CAPTURE_SCRIPT=~/.config/qutebrowser/userscripts/org-protocol-capture-html.sh @@ -684,8 +714,9 @@ fi passname=$(ls ~/.local/share/pass/totp-* | xargs -n 1 basename | sed -e 's/\..*$//' | rofi -p "TOPT" -dmenu) if [ -n "$passname" ]; then - pass otp $passname | xsel -ib && \ - dunstify 'OTP' 'copied to clipboard.' & + otpnumber=`pass otp $passname` + echo $otpnumber | xsel -ib + dunstify 'OTP' "$otpnumber" & fi #+end_src @@ -705,29 +736,433 @@ fi ** Display URL as a QRcode #+begin_src bash :tangle ~/.config/qutebrowser/userscripts/url-to-qrcode.sh -qrencode -o /tmp/qrcode.png "$1" && sxiv /tmp/qrcode.png +qrencode -o /tmp/qrcode.png "$1" && nsxiv /tmp/qrcode.png #+end_src * Greasemonkey Scripts ** Skip Youtube ads https://github.com/qutebrowser/qutebrowser/issues/6480 +https://greasyfork.org/en + #+begin_src javascript :tangle ~/.local/share/qutebrowser/greasemonkey/youtube-adblock.user.js // ==UserScript== -// @name Auto Skip YouTube Ads -// @version 1.0.0 -// @description Speed up and skip YouTube ads automatically -// @author jso8910 -// @match *://*.youtube.com/* -// @exclude *://*.youtube.com/subscribe_embed?* +// @name Disable YouTube Video Ads +// @namespace DisableYouTubeVideoAds +// @version 1.5.42 +// @license AGPLv3 +// @author jcunews +// @description Disable YouTube video & screen based ads at home page, and right before or in the middle of the main video playback. Also disable YouTube's anti-adblocker popup dialog. For new YouTube layout (Polymer) only. +// @website https://greasyfork.org/en/users/85671-jcunews +// @include https://www.youtube.com/* +// @grant unsafeWindow +// @run-at document-start // ==/UserScript== -setInterval(() => { - const btn = document.querySelector('.videoAdUiSkipButton,.ytp-ad-skip-button') - if (btn) { - btn.click() + +((window, disableAnnotations, fn) => { + //===== CONFIG BEGIN ===== + disableAnnotations = true; + //===== CONFIG END ===== + + fn = (a, ipse, haia, hca, rpo, et) => { + + if ((a = document.scripts[document.scripts.length - 1]) && (a.id === "dyvaUjs")) a.remove(); + + et = document.styleSheetSetsz ? "beforescriptexecute" : false; //Firefox workaround + + JSON.parse_dyva = JSON.parse; + JSON.parse = function(a) { + var m, z; + if (rpo) { + a = rpo; //JSON.parse_dyva(a); //from xhr/fetch + try { + if (a.forEach) { + a.forEach((p, a) => { + if (p.player && p.player.args && (p.player.args.raw_player_response || p.player.args.player_response)) { + patchPlayerResponse(a = p.player_response_); + if (p.player.args.raw_player_response) { + p.raw_player_response = JSON.stringify(a) + } else p.player_response = JSON.stringify(a) + } else if (p.playerResponse) { + patchPlayerResponse(p.playerResponse); + } + }); + } else patchPlayerResponse(a); + } catch(z) {} + rpo = null; + } else if ((a = JSON.parse_dyva(a)).playerResponse) patchPlayerResponse(a.playerResponse); + return a; + }; + + var ftc = window.fetch_dyva = window.fetch; + window.fetch = function(u) { + if (u) { + if (u.substr && /\/v1\/player\/ad_break/.test(u)) return new Promise(() => {}); + if (u.url && u.url.substr && /\/v1\/player\/ad_break/.test(u.url)) return new Promise(() => {}); + } + return ftc.apply(this, arguments); + }; + + var rj = Response.prototype.json_dyva = Response.prototype.json; + Response.prototype.json = function() { + var rs = this, p = rj.apply(this, arguments), pt = p.then; + p.then = function(fn) { + var fn_ = fn; + fn = function(j) { + if (/\/v1\/player\?/.test(rs.url)) rpo = j; + if ("function" === typeof fn_) return fn_.apply(this, arguments); + }; + return pt.apply(this, arguments); + }; + return p; + }; + var rt = Response.prototype.text; + Response.prototype.text = function() { + var rs = this, p = rt.apply(this, arguments), pt = p.then; + p.then = function(fn) { + var fn_ = fn; + fn = function(t) { + if (/\/v1\/player\?/.test(rs.url)) rpo = JSON.parse_dyva(t); + if ("function" === typeof fn_) return fn_.apply(this, arguments); + }; + return pt.apply(this, arguments); + }; + return p; + }; + + window.XMLHttpRequest.prototype.open_dyva = window.XMLHttpRequest.prototype.open; + window.XMLHttpRequest.prototype.open = function(mtd, url) { + if (!(/get_midroll_info/).test(url) && !((/^\/watch/).test(location.pathname) && (/get_video_info/).test(url))) { + this.url_dyva = url; + return this.open_dyva.apply(this, arguments); + } + }; + window.XMLHttpRequest.prototype.addEventListener_dyva = window.XMLHttpRequest.prototype.addEventListener; + window.XMLHttpRequest.prototype.addEventListener = function(typ, fn) { + if (typ === "readystatechange") { + var f = fn; + fn = function() { + var z; + if (this.readyState === 4) { + if (this.url_dyva?.includes("youtubei/v1/player")) { + rpo = JSON.parse_dyva(this.responseText); + try { + patchPlayerResponse(rpo); + } catch(z) {} + } else if ((/\/watch\?|get_video_info/).test(this.url_dyva)) { + rpo = JSON.parse_dyva(this.responseText); + try { + rpo.forEach(p => { + if (p.player && p.player.args && (p.player.args.raw_player_response || p.player.args.player_response)) { + p.playerResponse_ = JSON.parse_dyva(p.player.args.raw_player_response || p.player.args.player_response); + if (p.playerResponse_.playabilityStatus && (p.playerResponse_.playabilityStatus.status === "LOGIN_REQUIRED")) { + nav.navigate({commandMetadata: {webCommandMetadata: {url: location.href, webPageType: "WEB_PAGE_TYPE_BROWSE"}}}, false); + return; + } + patchPlayerResponse(p.playerResponse_); + if (p.player.args.raw_player_response) { + p.player.args.raw_player_response = JSON.stringify(p.playerResponse_) + } else p.player.args.player_response = JSON.stringify(p.playerResponse_) + } else if (p.playerResponse) { + patchPlayerResponse(p.playerResponse); + } + }); + } catch(z) {} + } + } + return f.apply(this, arguments); + }; + } + return this.addEventListener_dyva.apply(this, arguments); + }; + + window.Node.prototype.appendChild_dyva = window.Node.prototype.appendChild; + window.Node.prototype.appendChild = function(node) { + var a; + if (!ipse && (a = document.querySelector('ytd-watch-flexy')) && (a = a.constructor.prototype) && a.isPlaShelfEnabled_) { + a.isPlaShelfEnabled_ = () => false; + ipse = true; + } + if ((!hca || !haia) && (a = document.querySelector('ytd-watch-next-secondary-results-renderer')) && (a = a.constructor.prototype)) { + if (a.hasAllowedInstreamAd_ && !haia) { + a.hasAllowedInstreamAd_ = () => false; + haia = true; + } + if (a.hasCompanionAds_ && !hca) { + a.hasCompanionAds_ = () => false; + hca = true; + } + } + if ((node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) && Array.from(node.childNodes).some((n, i) => { + if (n.id === "masthead-ad") { + n.style.setProperty("display", "none", "important"); + //n.remove(); + return true; + } + })); //window.Node.prototype.appendChild = window.Node.prototype.appendChild_dyva; + if (node.querySelector && (a = node.querySelector('.ytp-ad-skip-button'))) a.click(); + return this.appendChild_dyva.apply(this, arguments); + }; + + var to = {createHTML: s => s, createScript: s => s}, tp = window.trustedTypes?.createPolicy ? trustedTypes.createPolicy("", to) : to; + var html = s => tp.createHTML(s), script = s => tp.createScript(s); + + function patchPlayerResponse(playerResponse, i) { + delete playerResponse.adBreakHeartbeatParams; + if (playerResponse.adPlacements) playerResponse.adPlacements = []; + if (disableAnnotations) delete playerResponse.annotations; + if (playerResponse.adSlots) playerResponse.adSlots = []; + if (playerResponse.auxiliaryUi?.messageRenderers?.bkaEnforcementMessageViewModel) { + delete playerResponse.auxiliaryUi.messageRenderers.bkaEnforcementMessageViewModel; + if (!Object.keys(playerResponse.auxiliaryUi.messageRenderers).length) { + delete playerResponse.auxiliaryUi.messageRenderers; + if (!Object.keys(playerResponse.auxiliaryUi).length) delete playerResponse.auxiliaryUi + } + var vd = playerResponse.videoDetails; + delete playerResponse.videoDetails; + Object.defineProperty(playerResponse, "videoDetails", { + get() { + return vd + }, + set(v) { + if (this.playabilityStatus?.errorScreen) { + delete this.playabilityStatus.errorScreen; + this.playabilityStatus.status = "OK" + } + return v + } + }); + } + if (playerResponse.messages) { + for (i = playerResponse.messages.length - 1; i >= 0; i--) { + if (playerResponse.messages[i].mealbarPromoRenderer) playerResponse.messages.splice(i, 1) + } + } + if (playerResponse.playerAds) playerResponse.playerAds = []; + if (playerResponse.playbackTracking) { + delete playerResponse.playbackTracking.googleRemarketingUrl; + delete playerResponse.playbackTracking.youtubeRemarketingUrl; + } } - const ad = [...document.querySelectorAll('.ad-showing')][0]; - if (ad) { - document.querySelector('video').playbackRate = 10; + + function patchPlayerArgs(args, a) { + if (args.ad_device) args.ad_device = "0"; + if (args.ad_flags) args.ad_flags = 0; + if (args.ad_logging_flag) args.ad_logging_flag = "0"; + if (args.ad_preroll) args.ad_preroll = "0"; + if (args.ad_slots) delete args.ad_slots; + if (args.ad_tag) delete args.ad_tag; + if (args.ad3_module) args.ad3_module = "0"; + if (args.adsense_video_doc_id) delete args.adsense_video_doc_id; + if (args.afv) args.afv = false; + if (args.afv_ad_tag) delete args.afv_ad_tag; + if (args.allow_html5_ads) args.allow_html5_ads = 0; + if (args.csi_page_type) args.csi_page_type = args.csi_page_type.replace(/watch7ad/, "watch7"); + if (args.enable_csi) args.enable_csi = "0"; + if (args.pyv_ad_channel) delete args.pyv_ad_channel; + if (args.show_pyv_in_related) args.show_pyv_in_related = false; + if (args.vmap) delete args.vmap; + if (args.raw_player_response) { + patchPlayerResponse(a = args.raw_player_response.charAt ? JSON.parse_dyva(args.raw_player_response) : args.raw_player_response); + if (args.raw_player_response.charAt) args.raw_player_response = JSON.stringify(a) + } else if (args.player_response) { + patchPlayerResponse(a = JSON.parse_dyva(args.player_response)); + args.player_response = JSON.stringify(a); + } } -}, 50) + + function patchSpf() { + if (window.spf && !spf.request_dyva) { + spf.request_dyva = spf.request; + spf.request = function(a, b) { + if (b && b.onDone) { + var onDone_ = b.onDone; + b.onDone = function(response) { + var a = response; + if (a && (/\/watch\?/).test(a.url) && (a = a.response) && (a = a.parts)) { + a.forEach((p, a) => { + if (p.player && p.player.args && (p.player.args.raw_player_response || p.player.args.player_response)) { + p = p.player.args; + patchPlayerResponse(a = JSON.parse_dyva(p.raw_player_response || p.player_response)); + if (p.raw_player_response) { + p.raw_player_response = JSON.stringify(a) + } else p.player_response = JSON.stringify(a) + } else if (p.playerResponse) { + patchPlayerResponse(p.playerResponse); + } + }); + } + return onDone_.apply(this, arguments); + }; + } + return this.request_dyva.apply(this, arguments); + }; + return; + } + } + + var ldh, docnt = 5 * 60; + + function do1(ev, a) { + + if ((a = document.scripts[document.scripts.length - 1]) && /"adPlacements"/.test(a.text)) { + a.text = script(a.text.replace(/"adPlacements"/, '"adPlacements":[],"zadPlacements"')); + } + if (window.loadDataHook) { + if (!window.loadDataHook.dyva) { + ldh = window.loadDataHook; + window.loadDataHook = function(ep, dt) { + if (dt.playabilityStatus && (dt.playabilityStatus === "LOGIN_REQUIRED")) { + location.href = location.href; + throw "Ain't gonna login"; + } + patchPlayerResponse(dt); + return ldh.apply(this, arguments); + }; + window.loadDataHook.dyva = true; + } + } + if (window.ytcfg && window.ytcfg.set) { + if (!window.ytcfg.set.dyva) { + var ytcfgSet = window.ytcfg.set; + window.ytcfg.set = function(ytConfig, ytValue){ + if (window.ytInitialPlayerResponse) { + if (ytInitialPlayerResponse.playabilityStatus && (ytInitialPlayerResponse.playabilityStatus === "LOGIN_REQUIRED")) { + location.href = location.href; + throw "Ain't gonna login"; + } + patchPlayerResponse(window.ytInitialPlayerResponse); + } + patchSpf(); + if (ytConfig) { + var a; + if (a = ytConfig.EXPERIMENT_FLAGS) { + if (a.enable_auto_play_param_fix_for_masthead_ad) a.enable_auto_play_param_fix_for_masthead_ad = false; + if (a.html5_check_both_ad_active_and_ad_info) a.html5_check_both_ad_active_and_ad_info = false; + if (a.web_enable_ad_signals_in_it_context) a.web_enable_ad_signals_in_it_context = false; + } + if (ytConfig.SKIP_RELATED_ADS === false) ytConfig.SKIP_RELATED_ADS = true; + if (ytConfig.TIMING_ACTION) ytConfig.TIMING_ACTION = ytConfig.TIMING_ACTION.replace(/watch7ad/, "watch7"); + if (a = ytConfig.TIMING_INFO) { + if (a.yt_ad) a.yt_ad = 0; + if (a.yt_ad_an) delete a.yt_ad_an; + if (a.yt_ad_pr) a.yt_ad_pr = 0; + } + if ( + (a = ytConfig.WEB_PLAYER_CONTEXT_CONFIGS) && (a = a.WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH) && + a.serializedExperimentFlags && a.serializedExperimentFlags.replace + ) { + a.serializedExperimentFlags = a.serializedExperimentFlags.replace( + /([a-z][^=]+)=([^&]+)/g, (s, a, b) => { + switch (a) { + case "enable_ad_break_end_time_on_pacf_tvhtml5": + case "enable_auto_play_param_fix_for_masthead_ad": + case "html5_check_both_ad_active_and_ad_info": b = false; break; + case "web_enable_ad_signals_in_it_context": + case "web_player_gvi_wexit_adunit": b = false; break; + } + return a + "=" + b; + } + ); + } + } + return ytcfgSet.apply(this, arguments); + }; + window.ytcfg.set.dyva = true; + } + } + if (window.yt) { + if (window.yt.player && window.yt.player.Application) { + if (window.yt.player.Application.create) { + if (!window.yt.player.Application.create.dyva) { + var ytPlayerApplicationCreate = window.yt.player.Application.create; + window.yt.player.Application.create = function(id, ytPlayerConfig) { + if ((id === "player-api") && ytPlayerConfig && ytPlayerConfig.args) { + if (ytPlayerConfig.args.raw_player_response) patchPlayerResponse(ytPlayerConfig.args.raw_player_response); + if (ytPlayerConfig.args.vmap) delete ytPlayerConfig.args.vmap; + } + return ytPlayerApplicationCreate.apply(this, arguments); + }; + window.yt.player.Application.create.dyva = true; + } + } + if (window.yt.player.Application.createAlternate) { + if (!window.yt.player.Application.createAlternate.dyva) { + var ytPlayerApplicationCreateAlternate = window.yt.player.Application.createAlternate; + window.yt.player.Application.createAlternate = function(id, ytPlayerConfig) { + if ((id === "player-api") && ytPlayerConfig && ytPlayerConfig.args) { + if (ytPlayerConfig.args.raw_player_response) patchPlayerResponse(ytPlayerConfig.args.raw_player_response); + if (ytPlayerConfig.args.vmap) delete ytPlayerConfig.args.vmap; + } + return ytPlayerApplicationCreateAlternate.apply(this, arguments); + }; + window.yt.player.Application.createAlternate.dyva = true; + } + } + } + if (window.yt.setConfig) { + if (!window.yt.setConfig.dyva) { + var ytSetConfig = window.yt.setConfig; + window.yt.setConfig = function(ytConfig){ + if (ytConfig && ytConfig.ADS_DATA) delete ytConfig.ADS_DATA; + return ytSetConfig.apply(this, arguments); + }; + window.yt.setConfig.dyva = true; + } + } + } + if (window.ytplayer && window.ytplayer.config && window.ytplayer.config.args) { + if (!window.ytplayer.config.args.dvya) { + patchPlayerArgs(window.ytplayer.config.args); + window.ytplayer.config.args.dvya = true; + } + } + if (document.readyState !== "complete") { + if ((et === false) && (--docnt > 0)) requestAnimationFrame(do1) + } else if (et !== false) removeEventListener(et, do1) + } + addEventListener(et, do1); + do1(); + + addEventListener("spfpartprocess", function(ev) { //old youtube + if (ev.detail && ev.detail.part && ev.detail.part.data && + ev.detail.part.data.swfcfg && ev.detail.part.data.swfcfg.args) { + patchPlayerArgs(ev.detail.part.data.swfcfg.args); + } + }, true); + + addEventListener("load", a => { + if (!(a = window.ayvp_cssOverride)) { + a = document.createElement("STYLE"); + a.id = "ayvp_cssOverride"; + a.innerHTML = html(`\ +.html5-video-player>.ytp-suggested-action, +.video-ads{display:none!important} +.ytp-ad-overlay-open .caption-window.ytp-caption-window-bottom{margin-bottom:4em} +.ytp-autohide .caption-window.ytp-caption-window-bottom, .ytp-hide-controls .caption-window.ytp-caption-window-bottom{margin-bottom:0!important}`); + document.documentElement.appendChild(a); + } + if (et === "message") { + if (document.readyState !== "complete") { + postMessage({}); + } else removeEventListener(et, do1); + } + }); + + var dce = document.createElement; + document.createElement = function(tag) { + if ((tag === "meta") && window.ytInitialPlayerResponse && ytInitialPlayerResponse.adPlacements && ytInitialPlayerResponse.adPlacements.length) { + patchPlayerResponse(window.ytInitialPlayerResponse) + } + return dce.apply(this, arguments) + }; + }; + if (("object" === typeof GM_info) && ["FireMonkey", "Greasemonkey"].includes(GM_info.scriptHandler)) { + //FireMonkey and new Greasemonkey workaround for compatibility with the original (unrestricted) Greasemonkey version. + let e = document.createElement("SCRIPT"); + e.id = "dyvaUjs"; + e.text = "(" + fn + ")()"; + document.documentElement.appendChild(e); + } else fn(); + +})(unsafeWindow); #+end_src