diff --git a/.bashrc b/.bashrc index ca89e07..44e49cf 100644 --- a/.bashrc +++ b/.bashrc @@ -12,7 +12,6 @@ shopt -s expand_aliases [ -f $BASH_DOTFILES/.bash_sdkman ] && . $BASH_DOTFILES/.bash_sdkman [ -f $BASH_DOTFILES/.bash_nvm ] && . $BASH_DOTFILES/.bash_nvm export NODE_COMPILE_CACHE=~/.cache/nodejs-compile-cache # https://nolanlawson.com/2024/10/20/why-im-skeptical-of-rewriting-javascript-tools-in-faster-languages/ -export PATH="$HOME/.local/bin:$PATH" eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" [ -f $BASH_DOTFILES/.bash_completions ] && . $BASH_DOTFILES/.bash_completions # for Vim diff --git a/.config/github-releases/config.json b/.config/github-releases/config.json index 22d06ea..c50f2fc 100644 --- a/.config/github-releases/config.json +++ b/.config/github-releases/config.json @@ -148,9 +148,9 @@ "group": "ai", "file_name": "ollama", "exec": "yes", - "last_update": "2025-08-25T18:04:05Z", + "last_update": "2025-09-04T17:27:40Z", "downloads": "/home/jaandrle/bin/ollama", - "version": "v0.11.7", + "version": "v0.11.10", "glare": "linux-amd64" }, { @@ -173,8 +173,8 @@ "file_name": "vim", "exec": "yes", "downloads": "/home/jaandrle/bin/vim", - "version": "v9.1.1696", - "last_update": "2025-08-27T01:22:07Z", + "version": "v9.1.1744", + "last_update": "2025-09-09T01:22:24Z", "glare": "GVim.*x86_64.*.AppImage" }, { @@ -184,9 +184,9 @@ "group": "dev", "file_name": "escrcpy.appimage", "exec": "yes", - "last_update": "2025-07-15T10:25:01Z", + "last_update": "2025-09-08T03:15:03Z", "downloads": "/home/jaandrle/bin/escrcpy.appimage", - "version": "v1.30.2", + "version": "v1.32.0", "glare": ".*x86_64.*.AppImage" }, { @@ -208,9 +208,9 @@ "group": "ai", "file_name": "jan", "exec": "yes", - "last_update": "2025-08-14T09:29:09Z", + "last_update": "2025-08-28T10:22:10Z", "downloads": "/home/jaandrle/bin/jan", - "version": "v0.6.8", + "version": "v0.6.9", "glare": ".*x86_64.*.AppImage" }, { diff --git a/bin/README.md b/.local/bin/README.md similarity index 100% rename from bin/README.md rename to .local/bin/README.md diff --git a/bin/bw-ftp.js b/.local/bin/bw-ftp.js similarity index 100% rename from bin/bw-ftp.js rename to .local/bin/bw-ftp.js diff --git a/bin/chrome-autoinspect.mjs b/.local/bin/chrome-autoinspect.mjs similarity index 100% rename from bin/chrome-autoinspect.mjs rename to .local/bin/chrome-autoinspect.mjs diff --git a/bin/git-identity b/.local/bin/git-identity similarity index 100% rename from bin/git-identity rename to .local/bin/git-identity diff --git a/bin/github-releases.mjs b/.local/bin/github-releases.mjs similarity index 100% rename from bin/github-releases.mjs rename to .local/bin/github-releases.mjs diff --git a/bin/jsconfig.json b/.local/bin/jsconfig.json similarity index 100% rename from bin/jsconfig.json rename to .local/bin/jsconfig.json diff --git a/bin/kde6-workarounds.mjs b/.local/bin/kde6-workarounds.mjs similarity index 100% rename from bin/kde6-workarounds.mjs rename to .local/bin/kde6-workarounds.mjs diff --git a/.local/bin/kde6-workarounds.sh b/.local/bin/kde6-workarounds.sh new file mode 100755 index 0000000..83af082 --- /dev/null +++ b/.local/bin/kde6-workarounds.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -eou pipefail +dbus-monitor "interface=org.kde.KWin.VirtualDesktopManager" "member=currentChanged" | xargs -e -I {} kde6-workarounds.mjs desktops-last-save {} diff --git a/bin/nocodb.mjs b/.local/bin/nocodb.mjs similarity index 100% rename from bin/nocodb.mjs rename to .local/bin/nocodb.mjs diff --git a/bin/piper.mjs b/.local/bin/piper.mjs similarity index 100% rename from bin/piper.mjs rename to .local/bin/piper.mjs diff --git a/.local/bin/ra-aid b/.local/bin/ra-aid new file mode 120000 index 0000000..81b9f6c --- /dev/null +++ b/.local/bin/ra-aid @@ -0,0 +1 @@ +/home/jaandrle/.local/share/pipx/venvs/ra-aid/bin/ra-aid \ No newline at end of file diff --git a/bin/socky.mjs b/.local/bin/socky.mjs similarity index 100% rename from bin/socky.mjs rename to .local/bin/socky.mjs diff --git a/bin/uu b/.local/bin/uu similarity index 100% rename from bin/uu rename to .local/bin/uu diff --git a/bin/§ai-commit.mjs b/.local/bin/§ai-commit.mjs similarity index 100% rename from bin/§ai-commit.mjs rename to .local/bin/§ai-commit.mjs diff --git a/bin/§awk b/.local/bin/§awk similarity index 100% rename from bin/§awk rename to .local/bin/§awk diff --git a/bin/§battery b/.local/bin/§battery similarity index 100% rename from bin/§battery rename to .local/bin/§battery diff --git a/bin/§bluetooth-toggle.sh b/.local/bin/§bluetooth-toggle.sh similarity index 100% rename from bin/§bluetooth-toggle.sh rename to .local/bin/§bluetooth-toggle.sh diff --git a/bin/§calc b/.local/bin/§calc similarity index 100% rename from bin/§calc rename to .local/bin/§calc diff --git a/bin/§cordova-release.mjs b/.local/bin/§cordova-release.mjs similarity index 100% rename from bin/§cordova-release.mjs rename to .local/bin/§cordova-release.mjs diff --git a/bin/§extract b/.local/bin/§extract similarity index 100% rename from bin/§extract rename to .local/bin/§extract diff --git a/bin/§kwallet.mjs b/.local/bin/§kwallet.mjs similarity index 100% rename from bin/§kwallet.mjs rename to .local/bin/§kwallet.mjs diff --git a/bin/§mail.mjs b/.local/bin/§mail.mjs similarity index 100% rename from bin/§mail.mjs rename to .local/bin/§mail.mjs diff --git a/.local/bin/§openai b/.local/bin/§openai new file mode 100755 index 0000000..cfc2968 --- /dev/null +++ b/.local/bin/§openai @@ -0,0 +1,8 @@ +#!/bin/bash + +curl \ + -sSL \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer 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 ' \ + -d '{"prompt":"//'"$1"'","max_tokens":500,"stop":"//","n":3}' \ + https://api.openai.com/v1/engines/code-davinci-002/completions diff --git a/.local/bin/§pandoc.mjs b/.local/bin/§pandoc.mjs new file mode 100755 index 0000000..754ac92 --- /dev/null +++ b/.local/bin/§pandoc.mjs @@ -0,0 +1,131 @@ +#!/usr/bin/env nodejsscript +/* jshint esversion: 11,-W097, -W040, module: true, node: true, expr: true, undef: true *//* global echo, $, pipe, s, fetch, cyclicLoop */ +if(!s.which("pandoc")) throw new Error("pandoc not found. Use your package manager to install it (e.g. `sudo apt install pandoc`)."); +const pdftk= "§pdftk-data.mjs"; +if(!s.which(pdftk)) throw new Error(`${pdftk} user script not found.`); + +$.api() + .version("2025-09-04") + .describe([ + "Small wrapper around `pandoc` mainly to convert markdown to pdf.", + "The reason is to use modern CSS than rely on cli implementation to converting to pdf." + ]) + .option("--debug", "Debug mode") + .option("--force", "Overwrite output file.") + + .command("to-html [name-output]", "Convert markdown to html.") + .alias("tohtml") + .action(function tohtmlCMD(input, output, options){ + tohtml(input, output, options); + $.exit(0); + }) + + .command("to-pdf [name-output]", "Convert markdown to pdf.") + .alias("topdf") + .action(async function topdfCMD(input, output, options){ + const { force: isForced, debug: isDebug }= options; + testInput(input); + output= normalizeOutput(input, ".pdf", output, isForced); + const tempFile= tempFileGenerator(input); + + echo("1. step: convert to html"); + const output_html= tempFile(".html"); + const input_data= tohtml(input, output_html, options); + + echo("2. step: convert to pdf"); + echo(" …use print to pdf in your browser"); + s.run`open ${output_html}`; + await s.read({ "-p": "Press enter to continue" }).catch(()=> echo("Aborted")); + if(!isDebug) s.rm(output_html); + if(!s.test("-f", output)) + $.error("Output file not found"); + + echo("3. step: update pdf metadata"); + const output_data_file= tempFile(".json"); + echo(` ${pdftk} extract \${pdf}`); + s.run`${pdftk} extract ${output} ${output_data_file}`; + const output_data= s.cat(output_data_file).xargs(JSON.parse); + const { Creator }= output_data.Info; + input_data.Creator= [ + s.$().run`pandoc --version`.head({ "-n": 1 }).trim(), + "&", + Creator, + ].join(" "); + Object.assign(output_data.Info, input_data); + s.echo(JSON.stringify(output_data, null, "\t")).to(output_data_file); + echo(` ${pdftk} update \${pdf}`); + s.run`${pdftk} update ${output} ${output_data_file}`; + if(!isDebug) s.rm(output_data_file); + + $.exit(0); + }) + .parse(); + +/** + * @param {string} input + * @param {string} [output] + * @param {object} options + * @returns {Record} + * */ +function tohtml( + input, output, + { force: isForced, debug: isDebug } +){ + testInput(input); + output= normalizeOutput(input, ".html", output, isForced); + const tempFile= tempFileGenerator(input); + + const { input_tmp, input_data }= prepareInput(input, tempFile); + echo(" pandoc ${markdown} --standalone -o ${html}"); + s.run`pandoc ${input_tmp} --standalone -o ${output}`; + if(!isDebug) s.rm(input_tmp); + return input_data; +} +/** @param {string} orig */ +function tempFileGenerator(orig){ + const basepath= orig.includes("/") ? orig.slice(0, orig.lastIndexOf("/")+1) : ""; + const basename= orig.slice(basepath.length, orig.lastIndexOf(".")); + return ext=> basepath+"."+basename+"-"+nameHash()+ext; +} +/** + * @param {string} input + * @param {(ext: string)=> string} tempFile + * @returns {{ input_tmp: string, input_data: Record }} + * */ +function prepareInput(input, tempFile){ + const input_tmp= tempFile(".md"); + const content= s.cat(input).trim(); + let input_data= {}; + echo(" extract input metadata and eval `~` to $HOME (CSS)"); + if(content.startsWith("---")) + for(const line_raw of content.split("\n").slice(1)){ + const line= line_raw.trim(); + if(!line) continue; + if(line==="---") break; + const [key_raw, value]= line.split(/: */); + let key= key_raw.replace(/^-+/, ""); + key= key[0].toUpperCase()+key.slice(1); + input_data[key]= value; + } + s.echo(content.replaceAll("file:///~", "file:///"+process.env.HOME)).to(input_tmp); + return { input_tmp, input_data }; +} +/** + * @param {string} input Input file + * @param {string} ext Output file extension + * @param {string} [output] Output file + * @param {boolean} [isForced] Overwrite output file + * @returns {string} + * @throws {Error} When output file already exists (unless `--force`) + * */ +function normalizeOutput(input, ext, output, isForced){ + if(!output) output= input.slice(0, input.lastIndexOf("."))+ext; + if(s.test("-f", output)) { + if(!isForced) $.error("Output file already exists, choose another name or `--force`"); + s.rm(output); + } + return output; +} +/** @param {string} input @throws {Error} If input file not found */ +function testInput(input){ if(!s.test("-f", input)) $.error("Input file not found"); } +function nameHash(){ return Math.random().toString(36).slice(2); } diff --git a/bin/§pdftk-data.mjs b/.local/bin/§pdftk-data.mjs similarity index 76% rename from bin/§pdftk-data.mjs rename to .local/bin/§pdftk-data.mjs index 427e22a..9a38728 100755 --- a/bin/§pdftk-data.mjs +++ b/.local/bin/§pdftk-data.mjs @@ -12,14 +12,11 @@ $.api() ]) .option("--debug", "Debug mode") .command("extract [file_info]", "Extract data from PDF.") -.action(function extract(file_pdf, file_info, { debug }){ +.action(function extractCMD(file_pdf, file_info, { debug }){ if(!s.test("-f", file_pdf)) $.error("PDF File not found"); if(!file_info) file_info= filename(file_pdf) + ".json"; - const temp= `${tmp}${tmpname(file_pdf)}.info` ; - s.run`pdftk ${file_pdf} dump_data_utf8 output ${temp}`; - const info= infoToJSON(temp); - if(!debug) s.rm(temp); + const info= extract(file_pdf); s.echo(info).to(file_info); $.exit(0); }) @@ -28,8 +25,10 @@ $.api() if(!s.test("-f", file_pdf)) $.error("PDF File not found"); if(!file_info) file_info= filename(file_pdf) + ".json"; if(!s.test("-f", file_info)) $.error("Info File not found"); + + const infoIsHtml= file_info.endsWith(".html"); - const info= infoFromJSON(file_info); + const info= infoIsHtml ? infoFromHTML(file_info, file_pdf, debug) : infoFromJSON(file_info); const temp= `${tmp}${tmpname(file_pdf)}.info`; s.echo(info).to(temp); const tmp_pdf= `${tmp}${tmpname(file_pdf)}.pdf`; @@ -51,13 +50,52 @@ $.api() }) .parse(); +function extract(file_pdf, debug){ + const temp= `${tmp}${tmpname(file_pdf)}.info` ; + s.run`pdftk ${file_pdf} dump_data_utf8 output ${temp}`; + const out= infoToJSON(temp); + if(!debug) s.rm(temp); + return out; +} function filename(path){ return path.slice(path.lastIndexOf("/")+1, path.lastIndexOf(".")); } function tmpname(path){ return filename(path) + "-" + Date.now(); } +function infoFromHTML(file_info, file_pdf, debug){ + const info_orig= JSON.parse(extract(file_pdf, debug)); + const info= s.cat(file_info).trim(); + let isInside= false; + for(const line_raw of info.split("\n")){ + const line= line_raw.trim(); + if(line.startsWith("")){ + const title= line.slice(7).replace("", "").trim(); + info_orig.Info.Title= title; + continue; + } + if(line.startsWith("")){ + break; + } + } + const tmp_json= `${tmp}${tmpname(file_pdf)}.json`; + s.echo(JSON.stringify(info_orig, null, "\t")).to(tmp_json); + const out= infoFromJSON(tmp_json); + if(!debug) s.rm(tmp_json); + return out; +} function infoFromJSON(file_info){ const info= s.cat(file_info).xargs(JSON.parse); const output= []; info.Bookmark= Object.entries(info.Bookmark) .map(/** @param {[string, string]} _ */([PageNumber, Title])=> { + PageNumber= Number.parseInt(PageNumber); const level= Title.search(/[^ ]/); return { PageNumber, @@ -134,7 +172,7 @@ function infoToJSON(file_info){ output.set(key, value); } output.set("Bookmark", pipe( - items=> items.map(({ PageNumber, Title, Level })=> ([PageNumber, " ".repeat(Number(Level)-1) + Title])), + items=> items.map(({ PageNumber, Title, Level }, i)=> ([PageNumber+"-"+i, " ".repeat(Number(Level)-1) + Title])), Object.fromEntries, )(output.get("Bookmark") || [])); return pipe( diff --git a/bin/§psw-text.mjs b/.local/bin/§psw-text.mjs similarity index 100% rename from bin/§psw-text.mjs rename to .local/bin/§psw-text.mjs diff --git a/bin/§software b/.local/bin/§software similarity index 100% rename from bin/§software rename to .local/bin/§software diff --git a/bin/§time.mjs b/.local/bin/§time.mjs similarity index 100% rename from bin/§time.mjs rename to .local/bin/§time.mjs diff --git a/bin/§trans.mjs b/.local/bin/§trans.mjs similarity index 100% rename from bin/§trans.mjs rename to .local/bin/§trans.mjs diff --git a/bin/§ubuntu-info b/.local/bin/§ubuntu-info similarity index 100% rename from bin/§ubuntu-info rename to .local/bin/§ubuntu-info diff --git a/bin/§ultisnips.mjs b/.local/bin/§ultisnips.mjs similarity index 100% rename from bin/§ultisnips.mjs rename to .local/bin/§ultisnips.mjs diff --git a/bin/§versions.mjs b/.local/bin/§versions.mjs similarity index 100% rename from bin/§versions.mjs rename to .local/bin/§versions.mjs diff --git a/bin/§vim_cache_clean b/.local/bin/§vim_cache_clean similarity index 100% rename from bin/§vim_cache_clean rename to .local/bin/§vim_cache_clean diff --git a/bin/§vim_plugins.mjs b/.local/bin/§vim_plugins.mjs similarity index 100% rename from bin/§vim_plugins.mjs rename to .local/bin/§vim_plugins.mjs diff --git a/bin/§wallpaper_BIOTD b/.local/bin/§wallpaper_BIOTD similarity index 100% rename from bin/§wallpaper_BIOTD rename to .local/bin/§wallpaper_BIOTD diff --git a/bin/§wallpaper_BIOTD.mjs b/.local/bin/§wallpaper_BIOTD.mjs similarity index 100% rename from bin/§wallpaper_BIOTD.mjs rename to .local/bin/§wallpaper_BIOTD.mjs diff --git a/bin/§wallpaper_WCPOTD.mjs b/.local/bin/§wallpaper_WCPOTD.mjs similarity index 100% rename from bin/§wallpaper_WCPOTD.mjs rename to .local/bin/§wallpaper_WCPOTD.mjs diff --git a/bin/§wolframalpha.mjs b/.local/bin/§wolframalpha.mjs similarity index 100% rename from bin/§wolframalpha.mjs rename to .local/bin/§wolframalpha.mjs diff --git a/.local/bin/§§centrum_mail b/.local/bin/§§centrum_mail new file mode 100755 index 0000000..188ce2d --- /dev/null +++ b/.local/bin/§§centrum_mail @@ -0,0 +1,2 @@ +#!/bin/bash +kioclient5 exec https://mail.centrum.cz/?fld=-666 diff --git a/README.md b/README.md index 75f17fa..a96e4e8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ see for example [How to Store Dotfiles - A Bare Git Repository \| Atlassian Git - [git](./.config/git/config), [gh](./.config/gh/config.yml) - [KDE Neon](#kde-neon) - [Mozilla Firefox](./.mozilla/firefox/README.md) -- [Bin – scripts and executables](./bin/README.md) +- [Bin – scripts and executables](./.local/bin/README.md) ## On a new machine 1. install git