From 0167d523256e33cb33fc124d2ee402e7c7a553e1 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 23 Dec 2024 10:48:51 +0100 Subject: [PATCH 01/41] update systemd-boot --- technology/linux/systemd/systemd-boot.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/technology/linux/systemd/systemd-boot.md b/technology/linux/systemd/systemd-boot.md index 9b54efa..aac4d52 100644 --- a/technology/linux/systemd/systemd-boot.md +++ b/technology/linux/systemd/systemd-boot.md @@ -10,16 +10,29 @@ systemd-boot is a simple UEFI boot manager which executes configured EFI images. It is simple to configure but can only start EFI executables such as the [Linux](../Linux.md) kernel EFISTUB, UEFI shell, GRUB, or the [Windows](../../windows/Windows.md) Boot Manager. ## Install -Install: +**Install**: ```shell -bootctl install +bootctl install [--esp-path=PATH] ``` -Update: +**Update**: ```shell bootctl update ``` +**Update seed file:** +```shell +bootctl random-seed +``` + +**See status:** +```shell +bootctl status + +# List entries +bootctl list +``` + ## Configuration The loader configuration is stored in the file `_esp_/loader/loader.conf`. From bb16b3fceb277bc4fdb4a7ca8de7a653f4eeac39 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 23 Dec 2024 11:08:19 +0100 Subject: [PATCH 02/41] update --- technology/applications/network/NetworkManager.md | 2 ++ technology/linux/systemd/Systemd-Mounts.md | 4 ++-- technology/linux/systemd/Systemd-Timers.md | 14 +++++++------- technology/linux/systemd/Systemd.md | 9 +++++++-- technology/linux/systemd/hostnamectl.md | 6 ++++++ technology/linux/systemd/journalctl.md | 6 ++++++ technology/linux/systemd/localectl.md | 7 +++++++ technology/linux/systemd/loginctl.md | 6 ++++++ technology/linux/systemd/networkctl.md | 6 ++++++ technology/linux/systemd/systemd-analyze.md | 6 ++++++ technology/linux/systemd/systemd-ask-pass.md | 6 ++++++ technology/linux/systemd/systemd-detect-virt.md | 6 ++++++ technology/linux/systemd/systemd-firstboot.md | 6 ++++++ technology/linux/systemd/systemd-inhibit.md | 6 ++++++ technology/linux/systemd/systemd-resolve.md | 6 ++++++ technology/linux/systemd/systemd-timesyncd.md | 9 +++++++++ technology/linux/systemd/userdbctl.md | 6 ++++++ 17 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 technology/linux/systemd/hostnamectl.md create mode 100644 technology/linux/systemd/journalctl.md create mode 100644 technology/linux/systemd/localectl.md create mode 100644 technology/linux/systemd/loginctl.md create mode 100644 technology/linux/systemd/networkctl.md create mode 100644 technology/linux/systemd/systemd-analyze.md create mode 100644 technology/linux/systemd/systemd-ask-pass.md create mode 100644 technology/linux/systemd/systemd-detect-virt.md create mode 100644 technology/linux/systemd/systemd-firstboot.md create mode 100644 technology/linux/systemd/systemd-inhibit.md create mode 100644 technology/linux/systemd/systemd-resolve.md create mode 100644 technology/linux/systemd/systemd-timesyncd.md create mode 100644 technology/linux/systemd/userdbctl.md diff --git a/technology/applications/network/NetworkManager.md b/technology/applications/network/NetworkManager.md index 44ed17c..7e20ae4 100644 --- a/technology/applications/network/NetworkManager.md +++ b/technology/applications/network/NetworkManager.md @@ -2,6 +2,8 @@ obj: application --- +#refactor + # NetworkManager [NetworkManager](https://networkmanager.dev/) is a program for providing detection and configuration for systems to automatically connect to networks. NetworkManager's functionality can be useful for both wireless and wired networks. For wireless networks, NetworkManager prefers known wireless networks and has the ability to switch to the most reliable network. NetworkManager-aware applications can switch from online and offline mode. NetworkManager also prefers wired connections over wireless ones, has support for modem connections and certain types of VPN. NetworkManager was originally developed by Red Hat and now is hosted by the GNOME project. diff --git a/technology/linux/systemd/Systemd-Mounts.md b/technology/linux/systemd/Systemd-Mounts.md index c645e8d..7ea58e4 100644 --- a/technology/linux/systemd/Systemd-Mounts.md +++ b/technology/linux/systemd/Systemd-Mounts.md @@ -14,7 +14,7 @@ Fields inside the mount section: - `Options` : Mount options to use when mounting. This takes a comma-separated list of options. This setting is optional. ## Example -``` +```ini [Unit] Documentation=man:fstab(5) man:systemd-fstab-generator(8) SourcePath=/etc/fstab @@ -24,4 +24,4 @@ What=/dev/sda1 Where=/mnt Type=btrfs Options=nosuid,nodev,nofail,compress=zstd,ro -``` \ No newline at end of file +``` diff --git a/technology/linux/systemd/Systemd-Timers.md b/technology/linux/systemd/Systemd-Timers.md index 5b1b1f7..55a0d60 100644 --- a/technology/linux/systemd/Systemd-Timers.md +++ b/technology/linux/systemd/Systemd-Timers.md @@ -18,11 +18,11 @@ systemctl list-timers ## Examples ### Monotonic timer - A timer which will start 15 minutes after boot and again every week while the system is running. -`/etc/systemd/system/foo.timer` -``` +```ini +# /etc/systemd/system/foo.timer + [Unit] Description=Run foo weekly and on boot @@ -35,11 +35,11 @@ WantedBy=timers.target ``` ### Realtime timer - A timer which starts once a week (at 12:00am on Monday). When activated, it triggers the service immediately if it missed the last start time (option `Persistent=true`), for example due to the system being powered off: -`/etc/systemd/system/foo.timer` -``` +```ini +# /etc/systemd/system/foo.timer + [Unit] Description=Run foo weekly @@ -59,4 +59,4 @@ An asterisk may be used to specify any value and commas may be used to list poss In the below example the service is run the first four days of each month at 12:00 PM, but _only_ if that day is a Monday or a Tuesday. -`OnCalendar=Mon,Tue *-*-01..04 12:00:00` \ No newline at end of file +`OnCalendar=Mon,Tue *-*-01..04 12:00:00` diff --git a/technology/linux/systemd/Systemd.md b/technology/linux/systemd/Systemd.md index c508346..c5251a8 100644 --- a/technology/linux/systemd/Systemd.md +++ b/technology/linux/systemd/Systemd.md @@ -65,6 +65,11 @@ systemctl mask unit systemctl unmask unit ``` +Get a list of overridden unit files: +```shell +systemd-delta +``` + ## Power Management Shut down and reboot the system `systemctl reboot` @@ -98,7 +103,7 @@ There are several different start-up types to consider when writing a custom ser - `Type=idle`: _systemd_ will delay execution of the service binary until all jobs are dispatched. Other than that behavior is very similar to `Type=simple`. #### Example -``` +```ini [Unit] Description=Description After=network.target @@ -149,4 +154,4 @@ Below are the fields the Install section has: Systemd supports other unit types than `.service`. Some include: - [Systemd-Timers](Systemd-Timers.md) -- [Systemd-Mounts](Systemd-Mounts.md) \ No newline at end of file +- [Systemd-Mounts](Systemd-Mounts.md) diff --git a/technology/linux/systemd/hostnamectl.md b/technology/linux/systemd/hostnamectl.md new file mode 100644 index 0000000..56bfaa0 --- /dev/null +++ b/technology/linux/systemd/hostnamectl.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# hostnamectl +#wip diff --git a/technology/linux/systemd/journalctl.md b/technology/linux/systemd/journalctl.md new file mode 100644 index 0000000..9e119a7 --- /dev/null +++ b/technology/linux/systemd/journalctl.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# journalctl +#wip diff --git a/technology/linux/systemd/localectl.md b/technology/linux/systemd/localectl.md new file mode 100644 index 0000000..77ca526 --- /dev/null +++ b/technology/linux/systemd/localectl.md @@ -0,0 +1,7 @@ +--- +obj: application +--- + +# localectl +#wip +https://man.archlinux.org/man/localectl.1 diff --git a/technology/linux/systemd/loginctl.md b/technology/linux/systemd/loginctl.md new file mode 100644 index 0000000..da735c9 --- /dev/null +++ b/technology/linux/systemd/loginctl.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# loginctl +#wip diff --git a/technology/linux/systemd/networkctl.md b/technology/linux/systemd/networkctl.md new file mode 100644 index 0000000..0ddbe1f --- /dev/null +++ b/technology/linux/systemd/networkctl.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# networkctl +#wip diff --git a/technology/linux/systemd/systemd-analyze.md b/technology/linux/systemd/systemd-analyze.md new file mode 100644 index 0000000..918ccba --- /dev/null +++ b/technology/linux/systemd/systemd-analyze.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# systemd-analyze +#wip diff --git a/technology/linux/systemd/systemd-ask-pass.md b/technology/linux/systemd/systemd-ask-pass.md new file mode 100644 index 0000000..c321193 --- /dev/null +++ b/technology/linux/systemd/systemd-ask-pass.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# systemd-ask-pass +#wip diff --git a/technology/linux/systemd/systemd-detect-virt.md b/technology/linux/systemd/systemd-detect-virt.md new file mode 100644 index 0000000..1adb851 --- /dev/null +++ b/technology/linux/systemd/systemd-detect-virt.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# systemd-detect-virt +#wip diff --git a/technology/linux/systemd/systemd-firstboot.md b/technology/linux/systemd/systemd-firstboot.md new file mode 100644 index 0000000..8073a62 --- /dev/null +++ b/technology/linux/systemd/systemd-firstboot.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# systemd-firstboot +#wip diff --git a/technology/linux/systemd/systemd-inhibit.md b/technology/linux/systemd/systemd-inhibit.md new file mode 100644 index 0000000..d728255 --- /dev/null +++ b/technology/linux/systemd/systemd-inhibit.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# systemd-inhibit +#wip diff --git a/technology/linux/systemd/systemd-resolve.md b/technology/linux/systemd/systemd-resolve.md new file mode 100644 index 0000000..5896281 --- /dev/null +++ b/technology/linux/systemd/systemd-resolve.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# systemd-resolve +#wip diff --git a/technology/linux/systemd/systemd-timesyncd.md b/technology/linux/systemd/systemd-timesyncd.md new file mode 100644 index 0000000..1578234 --- /dev/null +++ b/technology/linux/systemd/systemd-timesyncd.md @@ -0,0 +1,9 @@ +--- +obj: application +arch-wiki: https://wiki.archlinux.org/title/Systemd-timesyncd +--- + +# systemd-timesyncd +#wip + +timedatectl diff --git a/technology/linux/systemd/userdbctl.md b/technology/linux/systemd/userdbctl.md new file mode 100644 index 0000000..90bbd1e --- /dev/null +++ b/technology/linux/systemd/userdbctl.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# userdbctl +#wip From f4ba4007aca465fdea28578357a7975a5ac8959e Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 23 Dec 2024 11:25:13 +0100 Subject: [PATCH 03/41] update --- .../linux/systemd/systemd-detect-virt.md | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/technology/linux/systemd/systemd-detect-virt.md b/technology/linux/systemd/systemd-detect-virt.md index 1adb851..9be0c68 100644 --- a/technology/linux/systemd/systemd-detect-virt.md +++ b/technology/linux/systemd/systemd-detect-virt.md @@ -1,6 +1,52 @@ --- obj: application +rev: 2024-12-23 --- # systemd-detect-virt -#wip +systemd-detect-virt detects execution in a virtualized environment. It identifies the virtualization technology and can distinguish full machine virtualization from container virtualization. systemd-detect-virt exits with a return value of 0 (success) if a virtualization technology is detected, and non-zero (error) otherwise. By default, any type of virtualization is detected, and the options `--container` and `--vm` can be used to limit what types of virtualization are detected. + +When executed without `--quiet` will print a short identifier for the detected virtualization technology. The following technologies are currently identified: + +| **Type** | **ID** | **Product** | +| --------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| vm | `qemu` | QEMU software virtualization, without KVM | +| vm | `kvm` | Linux KVM kernel virtual machine, in combination with QEMU. Not used for other virtualizers using the KVM interfaces, such as Oracle VirtualBox or Amazon EC2 Nitro, see below. | +| vm | `amazon` | Amazon EC2 Nitro using Linux KVM | +| vm | `zvm` | s390 z/VM | +| vm | `vmware` | VMware Workstation or Server, and related products | +| vm | `microsoft` | Hyper-V, also known as Viridian or Windows Server Virtualization | +| vm | `oracle` | Oracle VM VirtualBox (historically marketed by innotek and Sun Microsystems), for legacy and KVM hypervisor | +| vm | `powervm` | IBM PowerVM hypervisor — comes as firmware with some IBM POWER servers | +| vm | `xen` | Xen hypervisor (only domU, not dom0) | +| vm | `bochs` | Bochs Emulator | +| vm | `uml` | User-mode Linux | +| vm | `parallels` | Parallels Desktop, Parallels Server | +| vm | `bhyve` | bhyve, FreeBSD hypervisor | +| vm | `qnx` | QNX hypervisor | +| vm | `acrn` | ACRN hypervisor | +| vm | `apple` | Apple virtualization framework | +| vm | `sre` | LMHS SRE hypervisor | +| vm | `google` | Google Compute Engine | +| container | `openvz` | OpenVZ/Virtuozzo | +| container | `lxc` | Linux container implementation by LXC | +| container | `lxc-libvirt` | Linux container implementation by libvirt | +| container | `systemd-nspawn` | systemd's minimal container implementation, see systemd-nspawn(1) manual page | +| container | `docker` | Docker container manager | +| container | `podman` | Podman container manager | +| container | `rkt` | rkt app container runtime | +| container | `wsl` | Windows Subsystem for Linux | +| container | `proot` | proot userspace chroot/bind mount emulation | +| container | `pouch` | Pouch Container Engine | + +If multiple virtualization solutions are used, only the "innermost" is detected and identified. That means if both machine and container virtualization are used in conjunction, only the latter will be identified (unless `--vm` is passed). + +## Options + +| Option | Description | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `-c, --container` | Only detects container virtualization (i.e. shared kernel virtualization). | +| `-v, --vm` | Only detects hardware virtualization. | +| `-r, --chroot` | Detect whether invoked in a chroot environment. In this mode, no output is written, but the return value indicates whether the process was invoked in a chroot() environment or not. | +| `-q, --quiet` | Suppress output of the virtualization technology identifier. | +| `--list` | Output all currently known and detectable container and VM environments. | From f86008079d815823690e2d2e9f98e72d3554b1c2 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 23 Dec 2024 14:46:40 +0100 Subject: [PATCH 04/41] update systemd-firstboot --- technology/linux/systemd/systemd-firstboot.md | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/technology/linux/systemd/systemd-firstboot.md b/technology/linux/systemd/systemd-firstboot.md index 8073a62..4b70000 100644 --- a/technology/linux/systemd/systemd-firstboot.md +++ b/technology/linux/systemd/systemd-firstboot.md @@ -3,4 +3,43 @@ obj: application --- # systemd-firstboot -#wip +systemd-firstboot allows for setting of basic system settings before or during the first boot of a newly created system. The tool is able of initialize the following system settings: timezone, locale, hostname, the root password, as well as automated generation of a machine ID. + +As systemd-firstboot interacts with the filesystem directly and does not make use of the related systemd services (such as timedatectl, hostnamectl or localectl), it should not be executed on an already running system. + +Settings can be specified non-interactively when externally used on filesystem images, or interactively if executed during the early boot process. + +Usage: `systemd-firstboot [OPTIONS...]` + +## Options + +| Option | Description | +| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--root=root` | Takes a directory path as an argument. All paths will be prefixed with the given alternate root path, including config search paths. This is useful to operate on a system image mounted to the specified directory instead of the host system itself. | +| `--image=path` | Takes a path to a disk image file or block device node. If specified all operations are applied to file system in the indicated disk image. This is similar to `--root=` but operates on file systems stored in disk images or block devices. The disk image should either contain just a file system or a set of file systems within a GPT partition table. | +| `--locale=LOCALE`, `--locale-messages=LOCALE` | Sets the system locale, more specifically the `LANG=` and `LC_MESSAGES` settings. The argument should be a valid locale identifier, such as `de_DE.UTF-8`. This controls the `locale.conf` configuration file. | +| `--keymap=KEYMAP` | Sets the system keyboard layout. The argument should be a valid keyboard map, such as `de-latin1`. This controls the `KEYMAP` entry in the `vconsole.conf` configuration file. | +| `--timezone=TIMEZONE` | Sets the system time zone. The argument should be a valid time zone identifier, such as `Europe/Berlin`. This controls the `localtime` symlink. | +| `--hostname=HOSTNAME` | Sets the system hostname. The argument should be a hostname, compatible with DNS. This controls the `hostname` configuration file. | +| `--setup-machine-id` | Initialize the system's machine ID to a random ID. This controls the `machine-id` file. This option only works in combination with `--root=` or `--image=`. On a running system, machine-id is written by the manager with help from `systemd-machine-id-commit.service`. | +| `--machine-id=ID` | Set the system's machine ID to the specified value. The same restrictions apply as to `--setup-machine-id`. | +| `--root-password=PASSWORD`, `--root-password-file=PATH`, `--root-password-hashed=HASHED_PASSWORD` | Sets the password of the system's root user. This creates/modifies the `passwd` and `shadow` files. This setting exists in three forms: `--root-password=` accepts the password to set directly on the command line, `--root-password-file=` reads it from a file and `--root-password-hashed=` accepts an already hashed password on the command line. | +| `--root-shell=SHELL` | Sets the shell of the system's root user. This creates/modifies the `passwd` file. | +| `--kernel-command-line=CMDLINE` | Sets the system's kernel command line. This controls the `/etc/kernel/cmdline` file which is used by kernel-install. | +| `--prompt-locale`, `--prompt-keymap`, `--prompt-timezone`, `--prompt-hostname`, `--prompt-root-password`, `--prompt-root-shell` | Prompt the user interactively for a specific basic setting. Note that any explicit configuration settings specified on the command line take precedence, and the user is not prompted for it. | +| `--prompt` | Query the user for locale, keymap, timezone, hostname, root's password, and root's shell. | +| `--copy-locale`, `--copy-keymap`, `--copy-timezone`, `--copy-root-password`, `--copy-root-shell` | Copy a specific basic setting from the host. This only works in combination with `--root=` or `--image=`. | +| `--copy` | Copy locale, keymap, time zone, root password and shell from the host. | +| `--force` | Write configuration even if the relevant files already exist. Without this option, systemd-firstboot doesn't modify or replace existing files. Note that when configuring the root account, even with this option, systemd-firstboot only modifies the entry of the "root" user, leaving other entries in `/etc/passwd` and `/etc/shadow` intact. | +| `--reset` | If specified, all existing files that are configured by systemd-firstboot are removed. Note that the files are removed regardless of whether they'll be configured with a new value or not. This operation ensures that the next boot of the image will be considered a first boot, and systemd-firstboot will prompt again to configure each of the removed files. | +| `--delete-root-password` | Removes the password of the system's root user, enabling login as root without a password unless the root account is locked. Note that this is extremely insecure and hence this option should not be used lightly. | +| `--welcome=` | Takes a boolean argument. By default when prompting the user for configuration options a brief welcome text is shown before the first question is asked. Pass false to this option to turn off the welcome text. | + +## Delete existing settings +If the following files are present, systemd-firstboot will not prompt for the setting they relate to. + +```sh +rm /etc/{machine-id,localtime,hostname,shadow,locale.conf} +``` + +Edit `/etc/passwd` and remove the root account from it, otherwise the root will be treating as configured and systemd-firstboot will not prompt for the root password. From 927a163c7f754c5025b97523e361ccbbaeee3c8f Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 23 Dec 2024 15:22:30 +0100 Subject: [PATCH 05/41] update --- technology/linux/fwupd.md | 9 +++++++++ technology/linux/smartctl.md | 6 ++++++ technology/linux/udev.md | 9 +++++++++ technology/linux/udisks.md | 9 +++++++++ 4 files changed, 33 insertions(+) create mode 100644 technology/linux/fwupd.md create mode 100644 technology/linux/smartctl.md create mode 100644 technology/linux/udev.md create mode 100644 technology/linux/udisks.md diff --git a/technology/linux/fwupd.md b/technology/linux/fwupd.md new file mode 100644 index 0000000..76891b3 --- /dev/null +++ b/technology/linux/fwupd.md @@ -0,0 +1,9 @@ +--- +obj: application +arch-wiki: https://wiki.archlinux.org/title/Fwupd +website: https://fwupd.org +repo: https://github.com/fwupd/fwupd +--- + +# fwupd +#wip diff --git a/technology/linux/smartctl.md b/technology/linux/smartctl.md new file mode 100644 index 0000000..e0c1b65 --- /dev/null +++ b/technology/linux/smartctl.md @@ -0,0 +1,6 @@ +--- +obj: application +--- + +# smartctl +#wip diff --git a/technology/linux/udev.md b/technology/linux/udev.md new file mode 100644 index 0000000..0fb4f83 --- /dev/null +++ b/technology/linux/udev.md @@ -0,0 +1,9 @@ +--- +obj: application +arch-wiki: https://wiki.archlinux.org/title/Udev +--- + +# udev +#wip +udev +udevadm diff --git a/technology/linux/udisks.md b/technology/linux/udisks.md new file mode 100644 index 0000000..fb4e585 --- /dev/null +++ b/technology/linux/udisks.md @@ -0,0 +1,9 @@ +--- +obj: application +arch-wiki: https://wiki.archlinux.org/title/Udisks +website: https://www.freedesktop.org/wiki/Software/udisks +repo: https://github.com/storaged-project/udisks +--- + +# udisks +#wip From 95e46634639c63516d5737e04f2c87512d211ace Mon Sep 17 00:00:00 2001 From: JMARyA Date: Wed, 8 Jan 2025 11:48:29 +0100 Subject: [PATCH 06/41] update pacman --- .../applications/package managers/arch-linux/Pacman.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/technology/applications/package managers/arch-linux/Pacman.md b/technology/applications/package managers/arch-linux/Pacman.md index f6d8985..bbaa46e 100644 --- a/technology/applications/package managers/arch-linux/Pacman.md +++ b/technology/applications/package managers/arch-linux/Pacman.md @@ -1,7 +1,7 @@ --- obj: application arch-wiki: https://wiki.archlinux.org/title/Pacman -rev: 2024-12-19 +rev: 2025-01-08 --- # Pacman @@ -48,6 +48,11 @@ List explicitly installed packages: pacman -Qe ``` +List of packages owning a file/dir: +```shell +pacman -Qo /path/to/file +``` + List orphan packages (installed as dependencies and not required anymore): ```shell pacman -Qdt From c1d6c28dff78582fac7496996f0534a9e03461dc Mon Sep 17 00:00:00 2001 From: JMARyA Date: Wed, 8 Jan 2025 13:11:28 +0100 Subject: [PATCH 07/41] add xdg-user-dirs --- technology/linux/XDG.md | 74 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 technology/linux/XDG.md diff --git a/technology/linux/XDG.md b/technology/linux/XDG.md new file mode 100644 index 0000000..b00eebc --- /dev/null +++ b/technology/linux/XDG.md @@ -0,0 +1,74 @@ +--- +obj: concept +arch-wiki: https://wiki.archlinux.org/title/XDG_user_directories +rev: 2025-01-08 +--- + +# XDG Directories +The XDG User Directories are a standardized way to define and access common user directories in Unix-like operating systems, primarily defined by the XDG Base Directory Specification from the FreeDesktop.org project. + +These directories provide users and applications with predefined paths for storing specific types of files, such as documents, downloads, music, and more. By using these directories, applications can integrate better with the operating system's file structure and provide a consistent experience for users. + +## Creating default directories +Creating a full suite of localized default user directories within the `$HOME` directory can be done automatically by running: + +```sh +xdg-user-dirs-update +``` + +> **Tip**: To force the creation of English-named directories, `LC_ALL=C.UTF-8 xdg-user-dirs-update --force` can be used. + +When executed, it will also automatically: +- Create a local `~/.config/user-dirs.dirs` configuration file: used by applications to find and use home directories specific to an account. +- Create a local `~/.config/user-dirs.locale` configuration file: used to set the language according to the locale in use. + +The user service `xdg-user-dirs-update.service` will also be installed and enabled by default, in order to keep your directories up to date by running this command at the beginning of each login session. + +## Creating custom directories +Both the local `~/.config/user-dirs.dirs` and global `/etc/xdg/user-dirs.defaults` configuration files use the following environmental variable format to point to user directories: `XDG_DIRNAME_DIR="$HOME/directory_name"` An example configuration file may likely look like this (these are all the template directories): + +```sh +# ~/.config/user-dirs.dirs + +XDG_DESKTOP_DIR="$HOME/Desktop" +XDG_DOCUMENTS_DIR="$HOME/Documents" +XDG_DOWNLOAD_DIR="$HOME/Downloads" +XDG_MUSIC_DIR="$HOME/Music" +XDG_PICTURES_DIR="$HOME/Pictures" +XDG_PUBLICSHARE_DIR="$HOME/Public" +XDG_TEMPLATES_DIR="$HOME/Templates" +XDG_VIDEOS_DIR="$HOME/Videos" +``` + +As xdg-user-dirs will source the local configuration file to point to the appropriate user directories, it is therefore possible to specify custom folders. For example, if a custom folder for the `XDG_DOWNLOAD_DIR` variable has named `$HOME/Internet` in `~/.config/user-dirs.dirs` any application that uses this variable will use this directory. + +> **Note**: Like with many configuration files, local settings override global settings. It will also be necessary to create any new custom directories. + +Alternatively, it is also possible to specify custom folders using the command line. For example, the following command will produce the same results as the above configuration file edit: + +```sh +xdg-user-dirs-update --set DOWNLOAD ~/Internet +``` + +## Querying configured directories +Once set, any user directory can be viewed with xdg-user-dirs. For example, the following command will show the location of the Templates directory, which of course corresponds to the `XDG_TEMPLATES_DIR` variable in the local configuration file: + +```sh +xdg-user-dir TEMPLATES +``` + +## Specification +Please read the full specification. This section will attempt to break down the essence of what it tries to achieve. + +Only `XDG_RUNTIME_DIR` is set by default through `pam_systemd`. It is up to the user to explicitly define the other variables according to the specification. + +### User directories +- `XDG_CONFIG_HOME`: Where user-specific configurations should be written (analogous to `/etc`). Should default to `$HOME/.config`. +- `XDG_CACHE_HOME`: Where user-specific non-essential (cached) data should be written (analogous to `/var/cache`). Should default to `$HOME/.cache`. +- `XDG_DATA_HOME`: Where user-specific data files should be written (analogous to `/usr/share`). Should default to `$HOME/.local/share`. +- `XDG_STATE_HOME`: Where user-specific state files should be written (analogous to `/var/lib`). Should default to `$HOME/.local/state`. +- `XDG_RUNTIME_DIR`: Used for non-essential, user-specific data files such as sockets, named pipes, etc. Not required to have a default value; warnings should be issued if not set or equivalents provided. Must be owned by the user with an access mode of `0700`. Filesystem fully featured by standards of OS. Must be on the local filesystem. May be subject to periodic cleanup. Modified every 6 hours or set sticky bit if persistence is desired. Can only exist for the duration of the user's login. Should not store large files as it may be mounted as a tmpfs.`pam_systemd` sets this to `/run/user/$UID`. + +### System directories +- `XDG_DATA_DIRS`: List of directories separated by `:` (analogous to `PATH`). Should default to `/usr/local/share:/usr/share`. +- `XDG_CONFIG_DIRS`: List of directories separated by `:` (analogous to `PATH`). Should default to `/etc/xdg`. From 323d59d281b6ae6ea5fa02d3b1a538f752fc0f9d Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 9 Jan 2025 10:52:16 +0100 Subject: [PATCH 08/41] add bwrap + age --- technology/applications/Applications.md | 4 +- .../applications/utilities/bubblewrap.md | 103 +++++++++++++++ technology/cryptography/age.md | 123 ++++++++++++++++++ 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 technology/applications/utilities/bubblewrap.md create mode 100644 technology/cryptography/age.md diff --git a/technology/applications/Applications.md b/technology/applications/Applications.md index 010685c..99fa36d 100644 --- a/technology/applications/Applications.md +++ b/technology/applications/Applications.md @@ -1,6 +1,6 @@ --- obj: meta/collection -rev: 2024-12-10 +rev: 2025-01-09 --- # Applications @@ -233,6 +233,7 @@ rev: 2024-12-10 - [yazi](./cli/yazi.md) - [GPG](../cryptography/GPG.md) - [OpenSSL](../cryptography/OpenSSL.md) +- [age](../cryptography/age.md) - [tomb](./cli/tomb.md) - [dysk](./cli/dysk.md) - [pass](./cli/pass.md) @@ -252,6 +253,7 @@ rev: 2024-12-10 - [wine](../windows/Wine.md) - [sbctl](../linux/sbctl.md) - [systemd-cryptenroll](../linux/systemd/systemd-cryptenroll.md) +- [bubblewrap](./utilities/bubblewrap.md) ## Development - [act](./development/act.md) diff --git a/technology/applications/utilities/bubblewrap.md b/technology/applications/utilities/bubblewrap.md new file mode 100644 index 0000000..0d726d9 --- /dev/null +++ b/technology/applications/utilities/bubblewrap.md @@ -0,0 +1,103 @@ +--- +obj: application +repo: https://github.com/containers/bubblewrap +arch-wiki: https://wiki.archlinux.org//title/Bubblewrap +rev: 2025-01-09 +--- + +# Bubblewrap +Bubblewrap is a lightweight sandbox application used by Flatpak and other container tools. It has a small installation footprint and minimal resource requirements. Notable features include support for cgroup/IPC/mount/network/PID/user/UTS namespaces and seccomp filtering. Note that bubblewrap drops all capabilities within a sandbox and that child tasks cannot gain greater privileges than its parent. + +## Configuration +Bubblewrap can be called directly from the command-line and/or within shell scripts as part of a complex wrapper. + +A no-op bubblewrap invocation is as follows: + +```sh +bwrap --dev-bind / / bash +``` + +This will spawn a Bash process which should behave exactly as outside a sandbox in most cases. If a sandboxed program misbehaves, you may want to start from the above no-op invocation, and work your way towards a more secure configuration step-by-step. + +### Desktop entries +Leverage Bubblewrap within desktop entries: +- Bind as read-write the entire host `/` directory to `/` in the sandbox +- Re-bind as read-only the `/var` and `/etc` directories in the sandbox +- Mount a new devtmpfs filesystem to `/dev` in the sandbox +- Create a tmpfs filesystem over the sandboxed `/run` directory +- Disable network access by creating new network namespace + +```ini +[Desktop Entry] +Name=nano Editor +Exec=bwrap --bind / / --dev /dev --tmpfs /run --unshare-net st -e nano -o . %f +Type=Application +MimeType=text/plain; +``` + +> **Note**: `--dev /dev` is required to write to `/dev/pty` + +## Options +Usage: `bwrap [optiosn] [command]` + +| Option | Description | +| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--args FD` | Parse nul-separated arguments from the given file descriptor. This option can be used multiple times to parse options from multiple sources. | +| `--argv0 VALUE` | Set `argv[0]` to the value VALUE before running the program | +| `--unshare-user` | Create a new user namespace | +| `--unshare-user-try` | Create a new user namespace if possible else skip it | +| `--unshare-ipc` | Create a new ipc namespace | +| `--unshare-pid` | Create a new pid namespace | +| `--unshare-net` | Create a new network namespace | +| `--unshare-uts` | Create a new uts namespace | +| `--unshare-cgroup` | Create a new cgroup namespace | +| `--unshare-cgroup-try` | Create a new cgroup namespace if possible else skip it | +| `--unshare-all` | Unshare all possible namespaces. Currently equivalent with: `--unshare-user-try --unshare-ipc --unshare-pid --unshare-net --unshare-uts --unshare-cgroup-try` | +| `--share-net` | Retain the network namespace, overriding an earlier `--unshare-all` or `--unshare-net` | +| `--userns FD` | Use an existing user namespace instead of creating a new one. The namespace must fulfil the permission requirements for `setns()`, which generally means that it must be a descendant of the currently active user namespace, owned by the same user. | +| `--disable-userns` | Prevent the process in the sandbox from creating further user namespaces, so that it cannot rearrange the filesystem namespace or do other more complex namespace modification. | +| `--assert-userns-disabled` | Confirm that the process in the sandbox has been prevented from creating further user namespaces, but without taking any particular action to prevent that. For example, this can be combined with --userns to check that the given user namespace has already been set up to prevent the creation of further user namespaces. | +| `--pidns FD` | Use an existing pid namespace instead of creating one. This is often used with `--userns`, because the pid namespace must be owned by the same user namespace that bwrap uses. | +| `--uid UID` | Use a custom user id in the sandbox (requires `--unshare-user`) | +| `--gid GID` | Use a custom group id in the sandbox (requires `--unshare-user`) | +| `--hostname HOSTNAME` | Use a custom hostname in the sandbox (requires `--unshare-uts`) | +| `--chdir DIR` | Change directory to DIR | +| `--setenv VAR VALUE` | Set an environment variable | +| `--unsetenv VAR` | Unset an environment variable | +| `--clearenv` | Unset all environment variables, except for PWD and any that are subsequently set by `--setenv` | +| `--lock-file DEST` | Take a lock on DEST while the sandbox is running. This option can be used multiple times to take locks on multiple files. | +| `--sync-fd FD` | Keep this file descriptor open while the sandbox is running | +| `--perms OCTAL` | This option does nothing on its own, and must be followed by one of the options that it affects. It sets the permissions for the next operation to OCTAL. Subsequent operations are not affected: for example, `--perms 0700 --tmpfs /a --tmpfs /b` will mount `/a` with permissions `0700`, then return to the default permissions for `/b`. Note that `--perms` and `--size` can be combined: `--perms 0700 --size 10485760 --tmpfs /s` will apply permissions as well as a maximum size to the created tmpfs. | +| `--size BYTES` | This option does nothing on its own, and must be followed by `--tmpfs`. It sets the size in bytes for the next tmpfs. For example, `--size 10485760 --tmpfs /tmp` will create a tmpfs at `/tmp` of size 10MiB. Subsequent operations are not affected. | +| `--bind SRC DEST` | Bind mount the host path SRC on DEST | +| `--bind-try SRC DEST` | Equal to `--bind` but ignores non-existent SRC | +| `--dev-bind SRC DEST` | Bind mount the host path SRC on DEST, allowing device access | +| `--dev-bind-try SRC DEST` | Equal to `--dev-bind` but ignores non-existent SRC | +| `--ro-bind SRC DEST` | Bind mount the host path SRC readonly on DEST | +| `--ro-bind-try SRC DEST` | Equal to `--ro-bind` but ignores non-existent SRC | +| `--remount-ro DEST` | Remount the path DEST as readonly. It works only on the specified mount point, without changing any other mount point under the specified path | +| `--overlay-src SRC` | This option does nothing on its own, and must be followed by one of the other overlay options. It specifies a host path from which files should be read if they aren't present in a higher layer. | +| `--overlay RWSRC WORKDIR DEST`, `--tmp-overlay DEST`, `--ro-overlay DEST` | Use overlayfs to mount the host paths specified by `RWSRC` and all immediately preceding `--overlay-src` on `DEST`. `DEST` will contain the union of all the files in all the layers. With `--overlay` all writes will go to `RWSRC`. Reads will come preferentially from `RWSRC`, and then from any `--overlay-src` paths. `WORKDIR` must be an empty directory on the same filesystem as `RWSRC`, and is used internally by the kernel. With `--tmp-overlay` all writes will go to the tmpfs that hosts the sandbox root, in a location not accessible from either the host or the child process. Writes will therefore not be persisted across multiple runs. With `--ro-overlay` the filesystem will be mounted read-only. This option requires at least two `--overlay-src` to precede it. | +| `--proc DEST` | Mount procfs on DEST | +| `--dev DEST` | Mount new devtmpfs on DEST | +| `--tmpfs DEST` | Mount new tmpfs on DEST. If the previous option was `--perms`, it sets the mode of the tmpfs. Otherwise, the tmpfs has mode `0755`. If the previous option was `--size`, it sets the size in bytes of the tmpfs. Otherwise, the tmpfs has the default size. | +| `--mqueue DEST` | Mount new mqueue on DEST | +| `--dir DEST` | Create a directory at DEST. If the directory already exists, its permissions are unmodified, ignoring `--perms` (use `--chmod` if the permissions of an existing directory need to be changed). If the directory is newly created and the previous option was `--perms`, it sets the mode of the directory. Otherwise, newly-created directories have mode `0755`. | +| `--file FD DEST` | Copy from the file descriptor FD to DEST. If the previous option was `--perms`, it sets the mode of the new file. Otherwise, the file has mode `0666` (note that this is not the same as `--bind-data`). | +| `--bind-data FD DEST` | Copy from the file descriptor FD to a file which is bind-mounted on DEST. If the previous option was `--perms`, it sets the mode of the new file. Otherwise, the file has mode `0600` (note that this is not the same as `--file`). | +| `--ro-bind-data FD DEST` | Copy from the file descriptor FD to a file which is bind-mounted read-only on DEST. If the previous option was `--perms`, it sets the mode of the new file. Otherwise, the file has mode `0600` (note that this is not the same as `--file`). | +| `--symlink SRC DEST` | Create a symlink at DEST with target SRC. | +| `--chmod OCTAL PATH` | Set the permissions of PATH, which must already exist, to OCTAL. | +| `--seccomp FD` | Load and use seccomp rules from FD. The rules need to be in the form of a compiled cBPF program, as generated by seccomp_export_bpf. If this option is given more than once, only the last one is used. Use `--add-seccomp-fd` if multiple seccomp programs are needed. | +| `--add-seccomp-fd FD` | Load and use seccomp rules from FD. The rules need to be in the form of a compiled cBPF program, as generated by seccomp_export_bpf. This option can be repeated, in which case all the seccomp programs will be loaded in the order given (note that the kernel will evaluate them in reverse order, so the last program on the bwrap command-line is evaluated first). All of them, except possibly the last, must allow use of the PR_SET_SECCOMP prctl. This option cannot be combined with `--seccomp`. | +| `--exec-label LABEL` | Exec Label from the sandbox. On an SELinux system you can specify the SELinux context for the sandbox process(s). | +| `--file-label LABEL` | File label for temporary sandbox content. On an SELinux system you can specify the SELinux context for the sandbox content. | +| `--block-fd FD` | Block the sandbox on reading from FD until some data is available. | +| `--userns-block-fd FD` | Do not initialize the user namespace but wait on FD until it is ready. This allow external processes (like newuidmap/newgidmap) to setup the user namespace before it is used by the sandbox process. | +| `--info-fd FD` | Write information in JSON format about the sandbox to FD. | +| `--json-status-fd FD` | Multiple JSON documents are written to FD, one per line. | +| `--new-session` | Create a new terminal session for the sandbox (calls `setsid()`). This disconnects the sandbox from the controlling terminal which means the sandbox can't for instance inject input into the terminal. Note: In a general sandbox, if you don't use `--new-session`, it is recommended to use seccomp to disallow the `TIOCSTI` ioctl, otherwise the application can feed keyboard input to the terminal which can e.g. lead to out-of-sandbox command execution. | +| `--die-with-parent` | Ensures child process (COMMAND) dies when bwrap's parent dies. Kills (SIGKILL) all bwrap sandbox processes in sequence from parent to child including COMMAND process when bwrap or bwrap's parent dies. | +| `--as-pid-1` | Do not create a process with PID=1 in the sandbox to reap child processes. | +| `--cap-add CAP` | Add the specified capability CAP, e.g. `CAP_DAC_READ_SEARCH`, when running as privileged user. It accepts the special value `ALL` to add all the permitted caps. | +| `--cap-drop CAP` | Drop the specified capability when running as privileged user. It accepts the special value `ALL` to drop all the caps. By default no caps are left in the sandboxed process. The `--cap-add` and `--cap-drop` options are processed in the order they are specified on the command line. Please be careful to the order they are specified. | diff --git a/technology/cryptography/age.md b/technology/cryptography/age.md new file mode 100644 index 0000000..d8d7a6f --- /dev/null +++ b/technology/cryptography/age.md @@ -0,0 +1,123 @@ +--- +obj: application +repo: https://github.com/FiloSottile/age +source: https://age-encryption.org/v1 +rev: 2025-01-09 +--- + +# age +age is a simple, modern and secure file encryption tool, format, and Go library. + +It features small explicit keys, no config options, and UNIX-style composability. + +```sh +$ age-keygen -o key.txt +Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p +$ PUBLIC_KEY=$(age-keygen -y key.txt) +$ tar cvz ~/data | age -r $PUBLIC_KEY > data.tar.gz.age +$ age --decrypt -i key.txt data.tar.gz.age > data.tar.gz +``` + +## Usage +For the full documentation, read [the age(1) man page](https://filippo.io/age/age.1). + +``` +Usage: + age [--encrypt] (-r RECIPIENT | -R PATH)... [--armor] [-o OUTPUT] [INPUT] + age [--encrypt] --passphrase [--armor] [-o OUTPUT] [INPUT] + age --decrypt [-i PATH]... [-o OUTPUT] [INPUT] + +Options: + -e, --encrypt Encrypt the input to the output. Default if omitted. + -d, --decrypt Decrypt the input to the output. + -o, --output OUTPUT Write the result to the file at path OUTPUT. + -a, --armor Encrypt to a PEM encoded format. + -p, --passphrase Encrypt with a passphrase. + -r, --recipient RECIPIENT Encrypt to the specified RECIPIENT. Can be repeated. + -R, --recipients-file PATH Encrypt to recipients listed at PATH. Can be repeated. + -i, --identity PATH Use the identity file at PATH. Can be repeated. + +INPUT defaults to standard input, and OUTPUT defaults to standard output. +If OUTPUT exists, it will be overwritten. + +RECIPIENT can be an age public key generated by age-keygen ("age1...") +or an SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA..."). + +Recipient files contain one or more recipients, one per line. Empty lines +and lines starting with "#" are ignored as comments. "-" may be used to +read recipients from standard input. + +Identity files contain one or more secret keys ("AGE-SECRET-KEY-1..."), +one per line, or an SSH key. Empty lines and lines starting with "#" are +ignored as comments. Passphrase encrypted age files can be used as +identity files. Multiple key files can be provided, and any unused ones +will be ignored. "-" may be used to read identities from standard input. + +When --encrypt is specified explicitly, -i can also be used to encrypt to an +identity file symmetrically, instead or in addition to normal recipients. +``` + +### Multiple recipients +Files can be encrypted to multiple recipients by repeating `-r/--recipient`. Every recipient will be able to decrypt the file. + +``` +$ age -o example.jpg.age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \ + -r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg example.jpg +``` + +#### Recipient files +Multiple recipients can also be listed one per line in one or more files passed with the `-R/--recipients-file` flag. + +``` +$ cat recipients.txt +# Alice +age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p +# Bob +age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg +$ age -R recipients.txt example.jpg > example.jpg.age +``` + +If the argument to `-R` (or `-i`) is `-`, the file is read from standard input. + +### Passphrases +Files can be encrypted with a passphrase by using `-p/--passphrase`. By default age will automatically generate a secure passphrase. Passphrase protected files are automatically detected at decrypt time. + +``` +$ age -p secrets.txt > secrets.txt.age +Enter passphrase (leave empty to autogenerate a secure one): +Using the autogenerated passphrase "release-response-step-brand-wrap-ankle-pair-unusual-sword-train". +$ age -d secrets.txt.age > secrets.txt +Enter passphrase: +``` + +### Passphrase-protected key files +If an identity file passed to `-i` is a passphrase encrypted age file, it will be automatically decrypted. + +``` +$ age-keygen | age -p > key.age +Public key: age1yhm4gctwfmrpz87tdslm550wrx6m79y9f2hdzt0lndjnehwj0ukqrjpyx5 +Enter passphrase (leave empty to autogenerate a secure one): +Using the autogenerated passphrase "hip-roast-boring-snake-mention-east-wasp-honey-input-actress". +$ age -r age1yhm4gctwfmrpz87tdslm550wrx6m79y9f2hdzt0lndjnehwj0ukqrjpyx5 secrets.txt > secrets.txt.age +$ age -d -i key.age secrets.txt.age > secrets.txt +Enter passphrase for identity file "key.age": +``` + +Passphrase-protected identity files are not necessary for most use cases, where access to the encrypted identity file implies access to the whole system. However, they can be useful if the identity file is stored remotely. + +### SSH keys +As a convenience feature, age also supports encrypting to `ssh-rsa` and `ssh-ed25519` SSH public keys, and decrypting with the respective private key file. (`ssh-agent` is not supported.) + +``` +$ age -R ~/.ssh/id_ed25519.pub example.jpg > example.jpg.age +$ age -d -i ~/.ssh/id_ed25519 example.jpg.age > example.jpg +``` + +Note that SSH key support employs more complex cryptography, and embeds a public key tag in the encrypted file, making it possible to track files that are encrypted to a specific public key. + +#### Encrypting to a GitHub user +Combining SSH key support and `-R`, you can easily encrypt a file to the SSH keys listed on a GitHub profile. + +``` +$ curl https://github.com/benjojo.keys | age -R - example.jpg > example.jpg.age +``` From 28933b6af81d01e6fb0b96cd682e015e8a34b05e Mon Sep 17 00:00:00 2001 From: JMARyA Date: Tue, 28 Jan 2025 10:31:34 +0100 Subject: [PATCH 09/41] update --- technology/applications/cli/intermodal.md | 57 +++++++++++++++----- technology/dev/programming/languages/Dart.md | 4 +- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/technology/applications/cli/intermodal.md b/technology/applications/cli/intermodal.md index 8230bb5..d322d70 100644 --- a/technology/applications/cli/intermodal.md +++ b/technology/applications/cli/intermodal.md @@ -1,38 +1,71 @@ --- obj: application repo: https://github.com/casey/intermodal +website: imdl.io +rev: 2025-01-28 --- # Intermodal -[Repo](https://github.com/casey/intermodal) Intermodal is a user-friendly and featureful command-line [BitTorrent](../../internet/BitTorrent.md) metainfo utility. The binary is called `imdl` and runs on [Linux](../../linux/Linux.md), [Windows](../../windows/Windows.md), and [macOS](../../macos/macOS.md). ## Usage ### Create torrent file: ```shell -imdl torrent create file +imdl torrent create [OPTIONS] ``` -Flags: -```shell --N, --name Set name of torrent --i, --input Torrent Files --c, --comment Torrent Comment --a, --announce Torrent Tracker -``` +| Option | Description | +| -------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `-F, --follow-symlinks` | Follow symlinks in torrent input (default: no) | +| `-f, --force` | Overwrite destination `.torrent` file if it exists | +| `--ignore` | Skip files listed in `.gitignore`, `.ignore`, `.git/info/exclude`, and `git config --get core.excludesFile` | +| `-h, --include-hidden` | Include hidden files that would otherwise be skipped | +| `-j, --include-junk` | Include junk files that would otherwise be skipped | +| `-M, --md5` | Include MD5 checksum of each file in the torrent ( warning: MD5 is broken) | +| `--no-created-by` | Do not populate `created by` key with imdl version information | +| `--no-creation-date` | Do not populate `creation date` key with current time | +| `-O, --open` | Open `.torrent` file after creation (uses platform-specific opener) | +| `--link` | Print created torrent `magnet:` URL to standard output | +| `-P, --private` | Set private flag, restricting peer discovery | +| `-S, --show` | Display information about the created torrent file | +| `-V, --version` | Print version number | +| `-A, --allow ` | Allow specific lint (e.g., `small-piece-length`, `private-trackerless`) | +| `-a, --announce ` | Use primary tracker announce URL for the torrent | +| `-t, --announce-tier ` | Add tiered tracker announce URLs to the torrent metadata, separate their announce URLs with commas. | +| `-c, --comment ` | Set comment text in the generated `.torrent` file | +| `--node ` | Add DHT bootstrap node to the torrent for peer discovery | +| `-g, --glob ` | Include or exclude files matching specific glob patterns | +| `-i, --input ` | Read contents from input source (file, dir, or standard input) | +| `-N, --name ` | Set name of the encoded magnet link to specific text | +| `-o, --output ` | Save `.torrent` file to specified target or print to output | +| `--peer ` | Add peer specification to the generated magnet link | +| `-p, --piece-length ` | Set piece length for encoding torrent metadata | +| `--sort-by ` | Determine order of files within the encoded torrent (path, size, or both) | +| `-s, --source ` | Set source field in encoded torrent metadata to specific text | +| `--update-url ` | Set URL where revised version of metainfo can be downloaded | ### Show torrent information ```shell imdl torrent show ``` +You can output the information as JSON using `--json`. + ### Verify torrent ```shell imdl torrent verify imdl torrent verify --input torr.torrent --content file ``` -### Generate magnet link +### Magnet Links ```shell -imdl torrent link -``` \ No newline at end of file +# Get magnet link from torrent file +imdl torrent link [-s, --select-only ...] +# Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`. + +# Get torrent file from magnet link +imdl torrent from-link [-o, --output ] + +# Announce a torrent +imdl torrent announce +``` diff --git a/technology/dev/programming/languages/Dart.md b/technology/dev/programming/languages/Dart.md index 45d9586..2a3a183 100644 --- a/technology/dev/programming/languages/Dart.md +++ b/technology/dev/programming/languages/Dart.md @@ -401,11 +401,11 @@ You've seen most of the remaining operators in other examples: ### Comments Dart supports single-line comments, multi-line comments, and documentation comments. -####Single-line comments +#### Single-line comments A single-line comment begins with `//`. Everything between `//` and the end of line is ignored by the Dart compiler. ```dart void main() { - // TODO: refactor into an AbstractLlamaGreetingFactory? + // refactor into an AbstractLlamaGreetingFactory? print('Welcome to my Llama farm!'); } ``` From ee55a0b016eb5c08fa18279f1ed25b7d2ee9a7a0 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 30 Jan 2025 16:17:23 +0100 Subject: [PATCH 10/41] update --- technology/applications/Applications.md | 13 +- technology/applications/cli/kondo.md | 29 ++ technology/applications/cli/mhost.md | 122 +++++ technology/applications/cli/names.md | 17 + technology/applications/cli/qrtool.md | 31 ++ technology/applications/cli/refold.md | 23 + technology/applications/cli/rexturl.md | 45 ++ technology/applications/cli/tagctl.md | 54 +++ technology/applications/cli/unionfarm.md | 54 +++ technology/applications/cli/xt.md | 22 + .../applications/utilities/retry-cli.md | 19 + technology/applications/web/bitmagnet.md | 457 ++++++++++++++++++ 12 files changed, 885 insertions(+), 1 deletion(-) create mode 100644 technology/applications/cli/kondo.md create mode 100644 technology/applications/cli/mhost.md create mode 100644 technology/applications/cli/names.md create mode 100644 technology/applications/cli/qrtool.md create mode 100644 technology/applications/cli/refold.md create mode 100644 technology/applications/cli/rexturl.md create mode 100644 technology/applications/cli/tagctl.md create mode 100644 technology/applications/cli/unionfarm.md create mode 100644 technology/applications/cli/xt.md create mode 100644 technology/applications/utilities/retry-cli.md create mode 100644 technology/applications/web/bitmagnet.md diff --git a/technology/applications/Applications.md b/technology/applications/Applications.md index 99fa36d..398209b 100644 --- a/technology/applications/Applications.md +++ b/technology/applications/Applications.md @@ -1,6 +1,6 @@ --- obj: meta/collection -rev: 2025-01-09 +rev: 2025-01-30 --- # Applications @@ -105,6 +105,7 @@ rev: 2025-01-09 - [SnapDrop](./network/SnapDrop.md) - [OnionShare](./network/OnionShare.md) - [qBittorrent](./network/qBittorrent.md) +- [bitmagnet](./web/bitmagnet.md) ## Utilities - [Bottles](./utilities/Bottles.md) @@ -239,6 +240,14 @@ rev: 2025-01-09 - [pass](./cli/pass.md) - [ocrs](./cli/ocrs.md) - [stew](./cli/stew.md) +- [names](./cli/names.md) +- [qrtool](./cli/qrtool.md) +- [tagctl](./cli/tagctl.md) +- [unionfarm](./cli/unionfarm.md) +- [xt](./cli/xt.md) +- [refold](./cli/refold.md) +- [rexturl](./cli/rexturl.md) +- [mhost](./cli/mhost.md) ## System - [Core Utils](./cli/system/Core%20Utils.md) @@ -254,6 +263,7 @@ rev: 2025-01-09 - [sbctl](../linux/sbctl.md) - [systemd-cryptenroll](../linux/systemd/systemd-cryptenroll.md) - [bubblewrap](./utilities/bubblewrap.md) +- [retry-cli](./utilities/retry-cli.md) ## Development - [act](./development/act.md) @@ -268,6 +278,7 @@ rev: 2025-01-09 - [Podman](../tools/Podman.md) - [serie](./cli/serie.md) - [usql](./cli/usql.md) +- [kondo](./cli/kondo.md) ## Media - [yt-dlp](./media/yt-dlp.md) diff --git a/technology/applications/cli/kondo.md b/technology/applications/cli/kondo.md new file mode 100644 index 0000000..0bcf5ab --- /dev/null +++ b/technology/applications/cli/kondo.md @@ -0,0 +1,29 @@ +--- +obj: application +repo: https://github.com/tbillington/kondo +rev: 2025-01-28 +--- + +# Kondo 🧹 +Cleans `node_modules`, `target`, `build`, and friends from your projects. + +Excellent if +- 💾 You want to back up your code but don't want to include GBs of dependencies +- 🧑‍🎨 You try out lots of projects but hate how much space they occupy +- ⚡️ You like keeping your disks lean and zippy + +## Usage +Kondo recursively cleans project directories. + +Supported project types: Cargo, Node, Unity, SBT, Haskell Stack, Maven, Unreal Engine, Jupyter Notebook, Python, Jupyter Notebooks, CMake, Composer, Pub, Elixir, Swift, Gradle, and .NET projects. + +Usage: `kondo [OPTIONS] [DIRS]...` + +| Option | Description | +| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-I, --ignored-dirs ` | Directories to ignore. Will also prevent recursive traversal within | +| `-q, --quiet...` | Quiet mode. Won't output to the terminal. `-qq` prevents all output | +| `-a, --all` | Clean all found projects without confirmation | +| `-L, --follow-symlinks` | Follow symbolic links | +| `-s, --same-filesystem` | Restrict directory traversal to the root filesystem | +| `-o, --older ` | Only directories with a file last modified n units of time ago will be looked at. Ex: 20d. Units are m: minutes, h: hours, d: days, w: weeks, M: months and y: years | diff --git a/technology/applications/cli/mhost.md b/technology/applications/cli/mhost.md new file mode 100644 index 0000000..a070292 --- /dev/null +++ b/technology/applications/cli/mhost.md @@ -0,0 +1,122 @@ +--- +obj: application +repo: https://github.com/lukaspustina/mhost +website: https://mhost.pustina.de +rev: 2025-01-30 +--- + +# mhost +A modern take on the classic host DNS lookup utility including an easy to use and very fast Rust lookup library. + +## Use Cases +### Just lookup an IP address +```shell +$ mhost l github.com +``` + +### Just lookup an IP address, using even more than just your local name servers +```shell +$ mhost server-lists public-dns -o servers.txt +$ mhost --limit 6000 --max-concurrent-servers 1000 --timeout 1 -f servers.txt l www.github.com +``` + +The first command downloads a list of public available name servers that are maintained by the Public DNS community. Usually only a subset of these are reachable, but it still a large set of active name servers. + +The second command uses the name servers list from before and queries all of them concurrently. These settings are very aggressive and highly stresses your internet connection. mhost default settings are set much more cautiously. + +### Just lookup an IP address, using UDP, TCP, DoT, and DoH +```shell +$ mhost -s 1.1.1.1 -s tcp:1.1.1.1 -s tls:1.1.1.1:853,tls_auth_name=cloudflare-dns.com -s https:1.1.1.1:443,tls_auth_name=cloudflare-dns.com,name=Cloudflare -p l github.com +``` + +As already mentioned before, mhost supports DNS queries over UDP, TCP, DNS over TLS (DoT), as well as DNS over HTTPS (DoH). In the above example, mhost uses all four protocols to query Cloudflare’s name servers. + +This command also shows the syntax for name server specification, which in general is `protocol::port,tls_auth_name=hostname,name=human-readable-name`. + +### Discover a domain +Sometimes you want to know which host names and subdomains a domain has. mhost offers a simple command to help you find these. Please mind, that mhost only uses DNS specific discovery methods. If you want even deeper discoveries using Google, Shodan etc. there are other tools available. + +```shell +$ mhost -p d github.com -p +``` + +This command uses the predefined name servers to discover the GitHub domain. The `-s` reduces all discovered names to real subdomains of github.com.. + +### You can go one more step and explore the autonomous systems GitHub uses. In order to discover those, you can use the following commands: + +```shell +$ mhost -p l --all -w github.com +$ mhost -p l --all 140.82.121.0/24 +``` + +### Check your name server configuration +```shell +$ mhost -p c github.com -p +``` + +## Usage +mhost has three main commands: `lookup`, `discover`, and `check`. `lookup` lookups up arbitrary DNS records of a domain name. `discover` tries various methods to discover host names and subdomains of a domain. `check` uses lints to check if all records of a domain name adhere to the DNS RFC. + +### General Options + +| Option | Description | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------- | +| `-use-system-resolv-opt` | Uses options set in `/etc/resolv.conf` | +| `-no-system-nameservers` | Ignores nameservers from `/etc/resolv.conf` | +| `-S, --no-system-lookups` | Ignores system nameservers for lookups | +| `--resolv-conf ` | Uses alternative resolv.conf file | +| `--ndots ` | Sets number of dots to qualify domain name as FQDN [default: 1] | +| `--search-domain ` | Sets the search domain to append if HOSTNAME has less than `ndots` dots | +| `--system-nameserver ...` | Adds system nameserver for system lookups; only IP addresses allowed | +| `-s, --nameserver ...` | Adds nameserver for lookups | +| `-p, --predefined` | Adds predefined nameservers for lookups | +| `--predefined-filter ` | Filters predefined nameservers by protocol [default: udp] [possible values: udp, tcp, https, tls] | +| `--list-predefined` | Lists all predefined nameservers | +| `-f, --nameservers-from-file ` | Adds nameservers from file | +| `--limit ` | Sets max. number of nameservers to query [default: 100] | +| `--max-concurrent-servers ` | Sets max. concurrent nameservers [default: 10] | +| `--max-concurrent-requests ` | Sets max. concurrent requests per nameserver [default: 5] | +| `--retries ` | Sets number of retries if first lookup to nameserver fails [default: 0] | +| `--timeout ` | Sets timeout in seconds for responses [default: 5] | +| `-m, --resolvers-mode ` | Sets resolvers lookup mode [default: multi] [possible values: multi, uni] | +| `--wait-multiple-responses` | Waits until timeout for additional responses from nameservers | +| `--no-abort-on-error` | Sets do-not-ignore errors from nameservers | +| `--no-abort-on-timeout` | Sets do-not-ignore timeouts from nameservers | +| `--no-aborts` | Sets do-not-ignore errors and timeouts from nameservers | +| `-o, --output ` | Sets the output format for result presentation [default: summary] [possible values: json, summary] | +| `--output-options ` | Sets output options | +| `--show-errors` | Shows error counts | +| `-q, --quiet` | Does not print anything but results | +| `--no-color` | Disables colorful output | +| `--ascii` | Uses only ASCII compatible characters for output | + +### Lookup Options + +| Option | Description | +| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--all` | Enables lookups for all record types | +| `-s`, `--service` | Parses ARG as service spec and set record type to SRV | +| `-w`, `--whois` | Retrieves Whois information about A, AAAA, and PTR records | +| `-h`, `--help` | Prints help information | +| `-t`, `--record-type ...` | Sets record type to lookup, will be ignored in case of IP address lookup [default: A,AAAA,CNAME,MX] [possible values: A, AAAA, ANAME, ANY, CNAME, MX, NULL, NS, PTR, SOA, SRV, TXT] | + +### Discover Options + +```markdown +| Option | Description | +| ----------------------------------- | ------------------------------------------------------------------------------------------ | +| `-p`, `--show-partial-results` | Shows results after each lookup step | +| `-w`, `--wordlist-from-file ` | Uses wordlist from file | +| `--rnd-names-number ` | Sets number of random domain names to generate for wildcard resolution check [default: 3] | +| `--rnd-names-len ` | Sets length of random domain names to generate for wildcard resolution check [default: 32] | +| `-s`, `--subdomains-only` | Shows subdomains only omitting all other discovered names | + +### Check Options + +| Option | Description | +| ----------------------------- | ------------------------------------------- | +| `--show-partial-results` | Shows results after each check step | +| `--show-intermediate-lookups` | Shows all lookups made during by all checks | +| `--no-cnames` | Does not run cname lints | +| `--no-soa` | Does not run SOA check | +| `--no-spf` | Does not run SPF check | diff --git a/technology/applications/cli/names.md b/technology/applications/cli/names.md new file mode 100644 index 0000000..9270ae2 --- /dev/null +++ b/technology/applications/cli/names.md @@ -0,0 +1,17 @@ +--- +obj: application +repo: https://github.com/fnichol/names +rev: 2025-01-28 +--- + +# names +Random name generator for Rust + +## Usage + +``` +> names +selfish-change +``` + +Usage: `names [-n, --number] ` diff --git a/technology/applications/cli/qrtool.md b/technology/applications/cli/qrtool.md new file mode 100644 index 0000000..3ed9b6f --- /dev/null +++ b/technology/applications/cli/qrtool.md @@ -0,0 +1,31 @@ +--- +obj: application +repo: https://github.com/sorairolake/qrtool +rev: 2025-01-30 +--- + +# qrtool +qrtool is a command-line utility for encoding or decoding QR code. + +## Usage +### Encode +Usage: `qrtool encode [OPTION]…​ [STRING]` + +| Option | Description | +| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-o, --output FILE` | Output the result to a file. | +| `-r, --read-from FILE` | Read input data from a file. This option conflicts with `[STRING]`. | +| `-s, --size NUMBER` | The module size in pixels. If this option is not specified, the module size is 8 when the output format is PNG or SVG, and 1 otherwise. | +| `-l, --error-correction-level LEVEL` | Error correction level. The possible values are: Level `L`. 7% of codewords can be restored. Level `M`. 15% of codewords can be restored. This is the default value. Level `Q`. 25% of codewords can be restored. Level `H`. 30% of codewords can be restored. | +| `--level LEVEL` | Alias for `-l, --error-correction-level`. | +| `-m, --margin NUMBER` | The width of margin. If this option is not specified, the margin will be 4 for normal QR code and 2 for Micro QR code. | +| `-t, --type FORMAT` | The format of the output. The possible values are: `png`, `svg`, `pic`, `ansi256`, `ansi-true-color`, `ascii`, `ascii-invert`, `unicode`, `unicode-invert` | +| `--foreground COLOR` | Foreground color. COLOR takes a CSS color string. Colored output is only available when the output format is PNG, SVG or any ANSI escape sequences. Note that lossy conversion may be performed depending on the color space supported by the method to specify a color, the color depth supported by the output format, etc. Default is black. | +| `--background COLOR` | Background color. COLOR takes a CSS color string. Colored output is only available when the output format is PNG, SVG or any ANSI escape sequences. Note that lossy conversion may be performed depending on the color space supported by the method to specify a color, the color depth supported by the output format, etc. Default is white. | + +### Decode +Usage: `qrtool decode [OPTION]…​ [IMAGE]` + +| Option | Description | +| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-t, --type FORMAT` | The format of the input. If FORMAT is not specified, the format is determined based on the extension or the magic number. The possible values are: `bmp`, `dds`, `farbfeld`, `gif`, `hdr`, `ico`, `jpeg`, `openexr`, `png`, `pnm`, `qoi`, `svg`, `tga`, `tiff`, `webp`, `xbm` | diff --git a/technology/applications/cli/refold.md b/technology/applications/cli/refold.md new file mode 100644 index 0000000..862ffaa --- /dev/null +++ b/technology/applications/cli/refold.md @@ -0,0 +1,23 @@ +--- +obj: application +repo: https://github.com/wr7/refold +rev: 2025-01-30 +--- + +# refold +refold is a commandline tool for performing text-wrapping, similar to unix `fold`. Unlike `fold`, refold will recombine lines before performing line-wrapping, and it will automatically detect line prefixes. + +## Usage +Usage: `refold [FLAGS...]` + +refold reads from stdin and writes to stdout + +### Options + +| Option | Description | +| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `--width, -w ` | Sets the width to wrap at (default 80). | +| `--prefix, -p ` | Sets the prefix for each line (default: auto detect). Set to an empty string to disable prefixing entirely. | +| `--boundaries, -b, --unicode-boundaries` | Sets the split mode to "boundaries" mode (default). In boundaries mode, line wrapping may occur in-between unicode breakable characters. | +| `--spaces, -s` | Sets the split mode to "space" mode. In space mode, line wrapping may occur in-between words separated by ASCII spaces. | +| `--characters, -c, --break-words, --break` | Sets the split mode to "character" mode. In character mode, line wrapping may occur in-between any two characters. | diff --git a/technology/applications/cli/rexturl.md b/technology/applications/cli/rexturl.md new file mode 100644 index 0000000..60112a7 --- /dev/null +++ b/technology/applications/cli/rexturl.md @@ -0,0 +1,45 @@ +--- +obj: application +repo: https://github.com/vschwaberow/rexturl +rev: 2025-01-30 +--- + +# rexturl +A versatile command-line tool for parsing and manipulating URLs. + +## Usage +Usage: `rexturl [OPTIONS] [URLS...]` + +If no URLs are provided, rexturl will read from stdin. + +### Options + +| Option | Description | +| ------------------- | --------------------------------------------------------- | +| `--urls ` | Input URLs to process | +| `--scheme` | Extract and display the URL scheme | +| `--username` | Extract and display the username from the URL | +| `--host` | Extract and display the hostname | +| `--port` | Extract and display the port number | +| `--path` | Extract and display the URL path | +| `--query` | Extract and display the query string | +| `--fragment` | Extract and display the URL fragment | +| `--sort` | Sort the output | +| `--unique` | Remove duplicate entries from the output | +| `--json` | Output results in JSON format | +| `--all` | Display all URL components | +| `--custom` | Enable custom output mode | +| `--format ` | Custom output format [default: `{scheme}://{host}{path}`] | +| '--domain' | Extract and display the domain | + + +### Custom Output Format +When using `--custom` and `--format`, you can use the following placeholders: +- `{scheme}` +- `{username}` +- `{host}` +- `{domain}` +- `{port}` +- `{path}` +- `{query}` +- `{fragment}` diff --git a/technology/applications/cli/tagctl.md b/technology/applications/cli/tagctl.md new file mode 100644 index 0000000..d18c7e4 --- /dev/null +++ b/technology/applications/cli/tagctl.md @@ -0,0 +1,54 @@ +--- +obj: application +repo: https://gitlab.com/KodyVB/tagctl +rev: 2025-01-30 +--- + +# tagctl +Tagctl is a command line program which can add or remove tags to files. +The tags can either be in the name or under `user.xdg.tags` in the extended attributes. + +## Usage +Usage: `tagctl [OPTIONS] [FILES]...` + +| Option | Description | +| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-t, --tag ` | Tag to add/remove to selected files. `%p` uses the parent directory name, `%y` uses the modified year, `%m` uses modified month, `%d` uses modified day, and `%w` uses modified weekday | +| `-d, --delimiter ` | Separator for multiple tags (default: `,`) | +| `-i, --input` | Accepts input from stdin | +| `-x, --xattr` | Adds/removes tags via xattr under `user.xdg.tags` | +| `-r, --remove` | Removes tag instead of adding | +| `-R, --remove_all` | Removes all tags | +| `-v, --verbose` | Increases verbosity of output | +| `-g, --generate_autocomplete ` | The shell to generate auto-completion for `bash`, `elvish`, `fish`, `zsh` | + + +## Examples +**Add tag `example` to current directory using file names:** +```shell +tagctl -t example "$(ls)" +ls | tagctl --input --tag example +``` + +**Remove tag `example` from current directory using file names:** +```shell +tagctl -r --tag=example "$(ls)" +ls | tagctl --remove -it example +``` + +**Add tag `example` to current directory using extended attributes:** +```shell +tagctl -xt example "$(ls)" +ls | tagctl --xattr --input --tag example +``` + +**Remove tag `example` from current directory using extended attributes:** +```shell +tagctl -xr --tag=example "$(ls)" +ls | tagctl --xattr --remove -it example +``` + +**Add tag `example` to two sets of inputs using file names:** +```shell +find /home/user/Documents | tagctl -it "example" "$(ls)" +``` diff --git a/technology/applications/cli/unionfarm.md b/technology/applications/cli/unionfarm.md new file mode 100644 index 0000000..9ec3858 --- /dev/null +++ b/technology/applications/cli/unionfarm.md @@ -0,0 +1,54 @@ +--- +obj: application +repo: https://codeberg.org/chrysn/unionfarm +rev: 2025-01-30 +--- + +# unionfarm +This is a small utility for managing symlink farms. It takes a "farm" directory and any number of "data" directories, and creates (or updates) the union (or overlay) of the data directories in the farm directory by placing symlinks to data directories. + +It is similar to +- union mounts (overlay/overlayfs) -- but works without system privileges; it is not live, but can then again err out on duplicate files rather than picking the highest ranking + +Usage: `unionfarm [DATA]...` + +## Example + +``` +$ tree my-photos +my-photos +├── 2018/ +│ └── Rome/ +│ └── ... +└── 2019/ + └── Helsinki/ + └── DSCN2305.jpg +``` + +Assume you have a collection of photos as above, and want to see them overlaid with a friend's photos: + +``` +$ tree ~friend/photos +/home/friend/photos +├── 2018/ +│ └── Amsterdam/ +│ └── ... +└── 2019/ + └── Helsinki/ + └── DSC_0815.jpg +``` + +With unionfarm, you can create a shared view on them: + +``` +$ unionfarm all-photos my-photos ~friend/photos +$ tree all-photos +all-photos +├── 2018/ +│ ├── Amsterdam -> /home/friend/photos/2018/Amsterdam/ +│ └── Rome -> ../../my-photos/2018/Rome/ +└── 2019/ + └── Helsinki/ + ├── DSC_0815.jpg -> /home/friend/photos/2019/Helsinki/DSC_0815.jpg + └── DSCN2305.jpg -> ../../../my-photos/2019/Helsinki/DSCN2305.jpg +``` diff --git a/technology/applications/cli/xt.md b/technology/applications/cli/xt.md new file mode 100644 index 0000000..f92cc07 --- /dev/null +++ b/technology/applications/cli/xt.md @@ -0,0 +1,22 @@ +--- +obj: application +repo: https://github.com/ahamlinman/xt +rev: 2025-01-30 +--- + +# xt +xt is a cross-format translator for JSON, MessagePack, TOML, and YAML. + +## Usage +Usage: `xt [-f format] [-t format] [file ...]` + +| Option | Description | +|---|---| +| `-f format` | Skip detection and convert every input from the given format | +| `-t format` | Convert to the given format (default: `json`) | + +## Formats +- `json`, `j`: +- `msgpack`, `m` +- `toml`, `t` +- `yaml`, `y` diff --git a/technology/applications/utilities/retry-cli.md b/technology/applications/utilities/retry-cli.md new file mode 100644 index 0000000..7cd9c98 --- /dev/null +++ b/technology/applications/utilities/retry-cli.md @@ -0,0 +1,19 @@ +--- +obj: application +repo: https://github.com/demoray/retry-cli +rev: 2025-01-28 +--- + +# retry-cli +retry is a command line tool written in Rust intended to automatically re-run failed commands with a user configurable delay between tries. + +## Usage +Usage: `retry [OPTIONS] ...` + +| Option | Description | +| ------------------------------- | -------------------------------------------------------------- | +| `--attempts ` | Amount of retries (default: `3`) | +| `--min-duration ` | minimum duration (default: `10ms`) | +| `--max-duration ` | maximum duration | +| `--jitter ` | amount of randomization to add to the backoff (default: `0.3`) | +| `--factor ` | backoff factor (default: `2`) | diff --git a/technology/applications/web/bitmagnet.md b/technology/applications/web/bitmagnet.md new file mode 100644 index 0000000..6787ecb --- /dev/null +++ b/technology/applications/web/bitmagnet.md @@ -0,0 +1,457 @@ +--- +obj: application +website: https://bitmagnet.io +--- + +# bitmagnet +A self-hosted BitTorrent indexer, DHT crawler, content classifier and torrent search engine with web UI, GraphQL API and Servarr stack integration. + +## Docker Compose + +```yml +services: + bitmagnet: + image: ghcr.io/bitmagnet-io/bitmagnet:latest + container_name: bitmagnet + ports: + # API and WebUI port: + - "3333:3333" + # BitTorrent ports: + - "3334:3334/tcp" + - "3334:3334/udp" + restart: unless-stopped + environment: + - POSTGRES_HOST=postgres + - POSTGRES_PASSWORD=postgres + # - TMDB_API_KEY=your_api_key + command: + - worker + - run + - --keys=http_server + - --keys=queue_server + # disable the next line to run without DHT crawler + - --keys=dht_crawler + depends_on: + postgres: + condition: service_healthy + + postgres: + image: postgres:16-alpine + container_name: bitmagnet-postgres + volumes: + - ./data/postgres:/var/lib/postgresql/data + # ports: + # - "5432:5432" Expose this port if you'd like to dig around in the database + restart: unless-stopped + environment: + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=bitmagnet + - PGUSER=postgres + shm_size: 1g + healthcheck: + test: + - CMD-SHELL + - pg_isready + start_period: 20s + interval: 10s +``` + +After running `docker compose up -d` you should be able to access the web interface at http://localhost:3333. The DHT crawler should have started and you should see items appear in the web UI within around a minute. + +To run the bitmagnet CLI, use `docker compose run bitmagnet bitmagnet command...` + +## Configuration + +- `postgres.host`, `postgres.name`, `postgres.user`, `postgres.password` (default: `localhost`, `bitmagnet`, `postgres`, `empty`): Set these values to configure connection to your Postgres database. +- `tmdb.api_key`: TMDB API Key. +- `tmdb.enabled` (default: `true`): Specify false to disable the TMDB API integration. +- `dht_crawler.save_files_threshold` (default: `100`): Some torrents contain many thousands of files, which impacts performance and uses a lot of database disk space. This parameter sets a maximum limit for the number of files saved by the crawler with each torrent. +- `dht_crawler.save_pieces` (default: `false`): If true, the DHT crawler will save the pieces bytes from the torrent metadata. The pieces take up quite a lot of space, and aren’t currently very useful, but they may be used by future features. +- `log.level` (default: `info`): Logging +- `log.json` (default: `false`): By default logs are output in a pretty format with colors; enable this flag if you’d prefer plain JSON. + +To see a full list of available configuration options using the CLI, run: + +```sh +bitmagnet config show +``` + +### Specifying configuration values +Configuration paths are delimited by dots. If you’re specifying configuration in a YAML file then each dot represents a nesting level, for example to configure `log.json`, `tmdb.api_key` and `http_server.cors.allowed_origins`: + +```yml +log: + json: true +tmdb: + api_key: my-api-key +http_server: + cors: + allowed_origins: + - https://example1.com + - https://example2.com +``` + +This is not a suggested configuration file, it’s just an example of how to specify configuration values. + +To configure these same values with environment variables, upper-case the path and replace all dots with underscores, for example: + +```sh +LOG_JSON=true \ +TMDB_API_KEY=my-api-key \ +HTTP_SERVER_CORS_ALLOWED_ORIGINS=https://example1.com,https://example2.com \ + bitmagnet config show +``` + +### Configuration precedence +In order of precedence, configuration values will be read from: +- Environment variables +- `config.yml` in the current working directory +- `config.yml` in the XDG-compliant config location for the current user (for example on MacOS this is `~/Library/Application Support/bitmagnet/config.yml`) +- Default values + +Environment variables can be used to configure simple scalar types (strings, numbers, booleans) and slice types (arrays). For more complex configuration types such as maps you’ll have to use YAML configuration. bitmagnet will exit with an error if it’s unable to parse a provided configuration value. + +### VPN configuration +It’s recommended that you run bitmagnet behind a VPN. If you’re using Docker then `gluetun` is a good solution for this, although the networking settings can be tricky. + +### Classifier +The classifier can be configured and customized to do things like: +- automatically delete torrents you don’t want in your index +- add custom tags to torrents you’re interested in +- customize the keywords and file extensions used for determining a torrent’s content type +- specify completely custom logic to classify and perform other actions on torrents + +#### Background +After a torrent is crawled or imported, some further processing must be done to gather metadata, have a guess at the torrent’s contents and finally index it in the database, allowing it to be searched and displayed in the UI/API. + +bitmagnet’s classifier is powered by a Domain Specific Language. The aim of this is to provide a high level of customisability, along with transparency into the classification process which will hopefully aid collaboration on improvements to the core classifier logic. + +The classifier is declared in YAML format. The application includes a core classifier that can be configured, extended or completely replaced with a custom classifier. This page documents the required format. + +#### Source precedence +bitmagnet will attempt to load classifier source code from all the following locations. Any discovered classifier source will be merged with other sources in the following order of precedence: + +- the core classifier +- `classifier.yml` in the XDG-compliant config location for the current user (for example on MacOS this is `~/Library/Application Support/bitmagnet/classifier.yml`) +- `classifier.yml` in the current working directory +- Classifier configuration + +Note that multiple sources will be merged, not replaced. For example, keywords added to the classifier configuration will be merged with the core keywords. + +The merged classifier source can be viewed with the CLI command `bitmagnet classifier show`. + +#### Schema +A JSON schema for the classifier is available; some editors and IDEs will be able to validate the structure of your classifier document by specifying the `$schema` attribute: + +```yml +$schema: bitmagnet.io/schemas/classifier-0.1.json +``` + +The classifier schema can also be viewed by running the cli command `bitmagnet classifier schema`. + + +The classifier declaration comprises the following components: +- **Workflows** +A workflow is a list of actions that will be executed on all torrents when they are classified. When no custom configuration is provided, the default workflow will be run. To use a different workflow instead, specify the classifier.workflow configuration option with the name of your custom workflow. + +- **Actions** +An action is a piece of workflow to be executed. All actions either return an updated classification result or an error. +For example, the following action will set the content type of the current torrent to audiobook: + +```yml +set_content_type: audiobook +``` + +The following action will return an unmatched error: +```yml +unmatched +``` + +And the following action will delete the current torrent being classified (returning a delete error): +```yml +delete +``` + +These actions aren’t much use on their own - we’d want to check some conditions are satisfied before setting a content type or deleting a torrent, and for this we’d use the if_else action. For example, the following action will set the content type to audiobook if the torrent name contains audiobook-related keywords, and will otherwise return an unmatched error: +```yml +if_else: + condition: "torrent.baseName.matches(keywords.audiobook)" + if_action: + set_content_type: audiobook + else_action: unmatched +``` + +The following action will delete a torrent if its name matches the list ofbanned keywords: +```yml +if_else: + condition: "torrent.baseName.matches(keywords.banned)" + if_action: delete +``` + +Actions may return the following types of error: +- An unmatched error indicates that the current action did not match for the current torrent +- A delete error indicates that the torrent should be deleted +- An unhandled error may occur, for example if the TMDB API was unreachable + +Whenever an error is returned, the current classification will be terminated. + +Note that a workflow should never return an unmatched error. We expect to iterate through a series of checks corresponding to each content type. If the current torrent does not match the content type being checked, we’ll proceed to the next check until we find a match; if no match can be found, the content type will be unknown. To facilitate this, we can use the find_match action. + +The find_match action is a bit like a try/catch block in some programming languages; it will try to match a particular content type, and if an unmatched error is returned, it will catch the unmatched error proceed to the next check. For example, the following action will attempt to classify a torrent as an audiobook, and then as an ebook. If both checks fail, the content type will be unknown: +```yml +find_match: + # match audiobooks: + - if_else: + condition: "torrent.baseName.matches(keywords.audiobook)" + if_action: + set_content_type: audiobook + else_action: unmatched + # match ebooks: + - if_else: + condition: "torrent.files.map(f, f.extension in extensions.ebook ? f.size : - f.size).sum() > 0" + if_action: + set_content_type: ebook + else_action: unmatched +``` + +For a full list of available actions, please refer to the JSON schema. + +#### Conditions +Conditions are used in conjunction with the `if_else` action, in order to execute an action if a particular condition is satisfied. + +The conditions in the examples above use CEL (Common Expression Language) expressions. + +##### The CEL environment +CEL is already a well-documented language, so this page won’t go into detail about the CEL syntax. In the context of the bitmagnet classifier, the CEL environment exposes a number of variables: + +- `torrent`: The current torrent being classified (protobuf type: `bitmagnet.Torrent`) +- `result`: The current classification result (protobuf type: `bitmagnet.Classification`) +- `keywords`: A map of strings to regular expressions, representing named lists of keywords +- `extensions`: A map of strings to string lists, representing named lists of extensions +- `contentType`: A map of strings to enum values representing content types (e.g. `contentType.movie`, `contentType.music`) +- `fileType`: A map of strings to enum values representing file types (e.g. `fileType.video`, `fileType.audio`) +- `flags`: A map of strings to the configured values of flags +- `kb`, `mb`, `gb`: Variables defined for convenience, equal to the number of bytes in a kilobyte, megabyte and gigabyte respectively + +For more details on the protocol buffer types, please refer to the protobuf schema. + +##### Boolean logic (`or`, `and` & `not`) +In addition to CEL expressions, conditions may be declared using the boolean logic operators or, and and not. For example, the following condition evaluates to true, if either the torrent consists mostly of file extensions very commonly used for music (e.g. `flac`), OR if the torrent both has a name that includes music-related keywords, and consists mostly of audio files: + +or: + - "torrent.files.map(f, f.extension in extensions.music ? f.size : - f.size).sum() > 0" + - and: + - "torrent.baseName.matches(keywords.music)" + - "torrent.files.map(f, f.fileType == fileType.audio ? f.size : - f.size).sum() > 0" + +> Note that we could also have specified the above condition using just one CEL expression, but breaking up complex conditions like this is more readable. + +#### Keywords +The classifier includes lists of keywords associated with different types of torrents. These aim to provide a simpler alternative to regular expressions, and the classifier will compile all keyword lists to regular expressions that can be used within CEL expressions. In order for a keyword to match, it must appear as an isolated token in the test string - that is, it must be either at the beginning or preceded by a non-word character, and either at the end or followed by a non-word character. + +Reserved characters in the syntax are: + +parentheses `(` and `)` enclose a group +`|` is an `OR` operator +`*` is a wildcard operator +`?` makes the previous character or group optional +`+` specifies one or more of the previous character +`#` specifies any number +` ` specifies any non-word or non-number character + +For example, to define some music- and audiobook-related keywords: +```yml +keywords: + music: # define music-related keywords + - music # all letters are case-insensitive, and must be defined in lowercase unless escaped + - discography + - album + - \V.?\A # escaped letters are case-sensitive; matches "VA", "V.A" and "V.A.", but not "va" + - various artists # matches "various artists" and "Various.Artists" + audiobook: # define audiobook-related keywords + - (audio)?books? + - (un)?abridged + - narrated + - novels? + - (auto)?biograph(y|ies) # matches "biography", "autobiographies" etc. +``` + +If you’d rather use plain old regular expressions, the CEL syntax supports that too, for example `torrent.baseName.matches("^myregex$")`. + +#### Extensions +The classifier includes lists of file extensions associated with different types of content. For example, to identify torrents of type comic by their file extensions, the extensions are first declared: + +```yml +extensions: + comic: + - cb7 + - cba + - cbr + - cbt + - cbz +``` + +The extensions can now be used as part of a condition within an `if_else` action: +```yml +if_else: + condition: "torrent.files.map(f, f.extension in extensions.comic ? f.size : - f.size).sum() > 0" + if_action: + set_content_type: comic + else_action: unmatched +``` + +#### Flags +Flags can be used to configure workflows. In order to use a flag in a workflow, it must first be defined. For example, the core classifier defines the following flags that are used in the default workflow: +```yml +flag_definitions: + tmdb_enabled: bool + delete_content_types: content_type_list + delete_xxx: bool +``` + +These flags can be referenced within CEL expressions, for example to delete adult content if the `delete_xxx` flag is set to true: +```yml +if_else: + condition: "flags.delete_xxx && result.contentType == contentType.xxx" + if_action: delete +``` + +#### Configuration +The classifier can be customized by providing a `classifier.yml` file in a supported location as described above. If you only want to make some minor modifications, it may be convenient to specify these using the main application configuration instead, by providing values in either `config.yml` or as environment variables. The application configuration exposes some but not all properties of the classifier. + +For example, in your `config.yml` you could specify: +```yml +classifier: + # specify a custom workflow to be used: + workflow: custom + # add to the core list of music keywords: + keywords: + music: + - my-custom-music-keyword + # add a file extension to the list of audiobook-related extensions: + extensions: + audiobook: + - abc + # auto-delete all comics + flags: + delete_content_types: + - comics +``` + +Or as environment variables you could specify: +```shell +TMDB_ENABLED=false \ # disable the TMDB API integration +CLASSIFIER_WORKFLOW=custom \ # specify a custom workflow to be used +CLASSIFIER_DELETE_XXX=true \ # auto-delete all adult content +bitmagnet worker run --all +``` + +#### Validation +The classifier source is compiled on initial load, and all structural and syntax errors should be caught at compile time. If there are errors in your classifier source, bitmagnet should exit with an error message indicating the location of the problem. + +#### Testing on individual torrents +You can test the classifier on an individual torrent or torrents using the bitmagnet process CLI command: +```shell +bitmagnet process --infoHash=aaaaaaaaaaaaaaaaaaaa --infoHash=bbbbbbbbbbbbbbbbbbbb +``` + +#### Reclassify all torrents +The classifier is being updated regularly, and to reclassify already-crawled torrents you’ll need to run the CLI and queue them for reprocessing. + +For context: after torrents are crawled or imported, they won’t show up in the UI straight away. They must first be “processed” by the job queue. This involves a few steps: +- The classifier attempts to classify the torrent (determine its content type, and match it to a known piece of content) +- The search index for the torrent is built +- The torrent content record is saved to the database + +The reprocess command will re-queue torrents to allow the latest updates to be applied to their content records. + +To reprocess all torrents in your index, simply run `bitmagnet reprocess`. If you’ve indexed a lot of torrents, this will take a while, so there are a few options available to control exactly what gets reprocessed: +- `apisDisabled`: Disable API calls during classification. This makes the classifier run a lot faster, but disables identification with external services such as TMDB (metadata already gathered from external APIs is not lost). +- `contentType`: Only reprocess torrents of a certain content type. For example, `bitmagnet reprocess --contentType movie` will only reprocess movies. Multiple content types can be comma separated, and `null` refers to torrents of unknown content type. +- `orphans`: Only reprocess torrents that have no content record. +- `classifyMode`: This controls how already matched torrents are handled. + - `default`: Only attempt to match previously unmatched torrents + - `rematch`: Ignore any pre-existing match and always classify from scratch (A torrent is “matched” if it’s associated with a specific piece of content from one of the API integrations, currently only TMDB) + +#### Practical use cases and examples +##### Auto-delete specific content types +The default workflow provides a flag that allows for automatically deleting specific content types. For example, to delete all comic, software and xxx torrents: +```yml +flags: + delete_content_types: + - comic + - software + - xxx +``` + +Auto-deleting adult content has been one of the most requested features. For convenience, this is exposed as the configuration option `classifier.delete_xxx`, and can be specified with the environment variable `CLASSIFIER_DELETE_XXX=true`. + +##### Auto-delete torrents containing specific keywords +Any torrents containing keywords in the banned list will be automatically deleted. This is primarily used for deleting CSAM content, but the list can be extended to auto-delete any other keywords: + +```yml +keywords: + banned: + - my-hated-keyword +``` + +##### Disable the TMDB API integration +The `tmdb_enabled` flag can be used to disable the TMDB API integration: +```yml +flags: + tmdb_enabled: false +``` + +For convenience, this is also exposed as the configuration option `tmdb.enabled`, and can be specified with the environment variable `$TMDB_ENABLED=false`. + +The `apis_enabled` flag has the same effect, disabling TMDB and any future API integrations: + +```yml +flags: + apis_enabled: false +``` + +API integrations can also be disabled for individual classifier runs, without disabling them globally, by passing the `--apisDisabled` flag to the reprocess command. + +##### Extend the default workflow with custom logic +Custom workflows can be added in the workflows section of the classifier document. It is possible to extend the default workflow by using the `run_workflow` action within your custom workflow, for example: +```yml +workflows: + custom: + - + - run_workflow: default + - +``` + +A concrete example of this is adding tags to torrents based on custom criteria. + +##### Use tags to create custom torrent categories +Is there a category of torrent you’re interested in that isn’t captured by one of the core content types? Torrent tags are intended to capture custom categories and content types. + +Let’s imagine you’d like to surface torrents containing interesting documents. The interesting documents have specific file extensions, and their filenames contain specific keywords. Let’s create a custom action to tag torrents containing interesting documents: + +```yml +# define file extensions for the documents we're interested in: +extensions: + interesting_documents: + - doc + - docx + - pdf +# define keywords that must be present in the filenames of the interesting documents: +keywords: + interesting_documents: + - interesting + - fascinating +# extend the default workflow with a custom workflow to tag torrents containing interesting documents: +workflows: + custom: + # first run the default workflow: + - run_workflow: default + # then add the tag to any torrents containing interesting documents: + - if_else: + condition: "torrent.files.filter(f, f.extension in extensions.interesting_documents && f.basePath.matches(keywords.interesting_documents)).size() > 0" + if_action: + add_tag: interesting-documents +``` + +To specify that the custom workflow should be used, remember to specify the `classifier.workflow` configuration option, e.g. `CLASSIFIER_WORKFLOW=custom bitmagnet worker run --all`. From 1c7eea08e30fd7295de85a4b3966fef651c00b9b Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 31 Jan 2025 20:10:15 +0100 Subject: [PATCH 11/41] update --- technology/applications/Applications.md | 3 + technology/applications/cli/csvlens.md | 80 +++++++++++++++++++ technology/applications/cli/timr-tui.md | 23 ++++++ .../applications/development/licensit.md | 66 +++++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 technology/applications/cli/csvlens.md create mode 100644 technology/applications/cli/timr-tui.md create mode 100644 technology/applications/development/licensit.md diff --git a/technology/applications/Applications.md b/technology/applications/Applications.md index 398209b..5ac52a2 100644 --- a/technology/applications/Applications.md +++ b/technology/applications/Applications.md @@ -199,6 +199,7 @@ rev: 2025-01-30 - [bat](./cli/bat.md) - [glow](./cli/glow.md) - [tailspin](./cli/tailspin.md) +- [csvlens](./cli/csvlens.md) ### Editor - [nano](./cli/nano.md) @@ -248,6 +249,7 @@ rev: 2025-01-30 - [refold](./cli/refold.md) - [rexturl](./cli/rexturl.md) - [mhost](./cli/mhost.md) +- [timr-tui](./cli/timr-tui.md) ## System - [Core Utils](./cli/system/Core%20Utils.md) @@ -279,6 +281,7 @@ rev: 2025-01-30 - [serie](./cli/serie.md) - [usql](./cli/usql.md) - [kondo](./cli/kondo.md) +- [licensit](./development/licensit.md) ## Media - [yt-dlp](./media/yt-dlp.md) diff --git a/technology/applications/cli/csvlens.md b/technology/applications/cli/csvlens.md new file mode 100644 index 0000000..4ebb5be --- /dev/null +++ b/technology/applications/cli/csvlens.md @@ -0,0 +1,80 @@ +--- +obj: application +repo: https://github.com/ys-l/csvlens +rev: 2025-01-31 +--- + +# csvlens +`csvlens` is a command line CSV file viewer. It is like `less` but made +for CSV. + +## Usage +Run `csvlens` by providing the CSV filename: + +``` +csvlens +``` + +Pipe CSV data directly to `csvlens`: + +``` + | csvlens +``` + +### Key bindings + +| Key | Action | +| ---------------------------- | ------------------------------------------------------------------ | +| `hjkl` (or `← ↓ ↑→ `) | Scroll one row or column in the given direction | +| `Ctrl + f` (or `Page Down`) | Scroll one window down | +| `Ctrl + b` (or `Page Up`) | Scroll one window up | +| `Ctrl + d` (or `d`) | Scroll half a window down | +| `Ctrl + u` (or `u`) | Scroll half a window up | +| `Ctrl + h` | Scroll one window left | +| `Ctrl + l` | Scroll one window right | +| `Ctrl + ←` | Scroll left to first column | +| `Ctrl + →` | Scroll right to last column | +| `G` (or `End`) | Go to bottom | +| `g` (or `Home`) | Go to top | +| `G` | Go to line `n` | +| `/` | Find content matching regex and highlight matches | +| `n` (in Find mode) | Jump to next result | +| `N` (in Find mode) | Jump to previous result | +| `&` | Filter rows using regex (show only matches) | +| `*` | Filter columns using regex (show only matches) | +| `TAB` | Toggle between row, column or cell selection modes | +| `>` | Increase selected column's width | +| `<` | Decrease selected column's width | +| `Shift + ↓` (or `Shift + j`) | Sort rows or toggle sort direction by the selected column | +| `#` (in Cell mode) | Find and highlight rows like the selected cell | +| `@` (in Cell mode) | Filter rows like the selected cell | +| `y` | Copy the selected row or cell to clipboard | +| `Enter` (in Cell mode) | Print the selected cell to stdout and exit | +| `-S` | Toggle line wrapping | +| `-W` | Toggle line wrapping by words | +| `r` | Reset to default view (clear all filters and custom column widths) | +| `H` (or `?`) | Display help | +| `q` | Exit | + +### Optional parameters + +* `-d `: Use this delimiter when parsing the CSV + (e.g. `csvlens file.csv -d '\t'`). + + Specify `-d auto` to auto-detect the delimiter. + +* `-t`, `--tab-separated`: Use tab as the delimiter (when specified, `-d` is ignored). + +* `-i`, `--ignore-case`: Ignore case when searching. This flag is ignored if any + uppercase letters are present in the search string. + +* `--no-headers`: Do not interpret the first row as headers. + +* `--columns `: Use this regex to select columns to display by default. + +* `--filter `: Use this regex to filter rows to display by default. + +* `--find `: Use this regex to find and highlight matches by default. + +* `--echo-column `: Print the value of this column at the selected + row to stdout on `Enter` key and then exit. diff --git a/technology/applications/cli/timr-tui.md b/technology/applications/cli/timr-tui.md new file mode 100644 index 0000000..a4d4acc --- /dev/null +++ b/technology/applications/cli/timr-tui.md @@ -0,0 +1,23 @@ +--- +obj: application +repo: https://github.com/sectore/timr-tui +rev: 2025-01-31 +--- + +# timr-tui +TUI to organize your time: Pomodoro, Countdown, Timer. + +## CLI +Usage: `timr-tui [OPTIONS]` + +| Option | Description | +| -------- | ----------------------------------------------------------------------------------------------- | +| `–c` | Countdown time to start from. Formats: 'ss', 'mm:ss', or 'hh:mm:ss' | +| `–w` | Work time to count down from. Formats: 'ss', 'm:ss', or 'h:mm:s' | +| `–p` | Pause time to count down from. Formats: 'ss', 'm:ss', or 'h:m:s' | +| `–d` | Show deciseconds | +| `–m` | Mode to start with. [possible values: countdown, timer, pomodoro] | +| `–s` | Style to display time with. [possible values: full, light, medium, dark, thick, cross, braille] | +| `--menu` | Open the menu | +| `–r` | Reset stored values to default values. | +| `–n` | Toggle desktop notifications on or off. Experimental. [possible values: on, off] | diff --git a/technology/applications/development/licensit.md b/technology/applications/development/licensit.md new file mode 100644 index 0000000..3dab595 --- /dev/null +++ b/technology/applications/development/licensit.md @@ -0,0 +1,66 @@ +--- +obj: application +repo: https://github.com/neuromeow/licensit +rev: 2025-01-31 +--- + +# licensit +`licensit` is a command-line tool to create LICENSE files. + +### Supported licenses + +- GNU Affero General Public License v3.0 (AGPL-3.0) +- Apache License 2.0 (Apache-2.0) +- BSD 2-Clause “Simplified” License (BSD-2-Clause) +- BSD 3-Clause “New” or “Revised” License (BSD-3-Clause) +- Boost Software License 1.0 (BSL-1.0) +- Creative Commons Zero v1.0 Universal (CC0-1.0) +- Eclipse Public License 2.0 (EPL-2.0) +- GNU General Public License v2.0 (GPL-2.0) +- GNU General Public License v3.0 (GPL-3.0) +- GNU Lesser General Public License v2.1 (LGPL-2.1) +- MIT License (MIT) +- Mozilla Public License 2.0 (MPL-2.0) +- The Unlicense (Unlicense) + +## Usage +`licensit` simplifies the process of creating and managing license files for your projects. + +### Listing Available Licenses +``` +licensit list +``` + +Shows all supported licenses. + +### Showing License Content +To view the content of a specific license with the author and year filled in: + +``` +licensit show [LICENSE] [--user USER] [--year YEAR] +``` + +- `[LICENSE]`: The ID of the license you want to display (for example, `mit`, `apache-2.0`) +- `--user [USER]`: Specifies the license holder's name. If not provided, `licensit` will use the following sources in order to determine the user name: + - `LICENSE_AUTHOR` environment variable + - `user.name` entry in the `$HOME/.gitconfig` file + - Username associated with the current effective user ID +- `--year [YEAR]`: Sets the year during which the license is effective. Defaults to the current year if not specified + +To display just the template of a license (without any specific user or year information): + +``` +licensit show [LICENSE] --template +``` + +- `[LICENSE]`: The ID of the license whose template you want to display (for example, `mit`, `apache-2.0`) +- `--template`: Displays the license template with placeholders for the user and year. This option cannot be used with `--user` or `--year` + +### Adding a License to Your Project +To add a license file to your current directory: + +``` +licensit add [LICENSE] [--user USER] [--year YEAR] +``` + +Creates a `LICENSE` file in the current directory with the specified details. From 9dbc181f90837a79d0207c37aebf2289b13d4660 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 7 Apr 2025 16:19:55 +0200 Subject: [PATCH 12/41] update rust crates --- technology/dev/programming/languages/Rust.md | 468 ++++++++++++++++++- 1 file changed, 453 insertions(+), 15 deletions(-) diff --git a/technology/dev/programming/languages/Rust.md b/technology/dev/programming/languages/Rust.md index 4d0e802..108a840 100644 --- a/technology/dev/programming/languages/Rust.md +++ b/technology/dev/programming/languages/Rust.md @@ -941,35 +941,147 @@ The exact assembly code syntax is target-specific and opaque to the compiler exc Currently, all supported targets follow the assembly code syntax used by LLVM's internal assembler which usually corresponds to that of the GNU assembler (GAS). On x86, the .intel_syntax noprefix mode of GAS is used by default. On ARM, the .syntax unified mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior. Further constraints on the directives used by inline assembly are indicated by Directives Support. ## [Crates](https://lib.rs) -- [itertools](https://lib.rs/crates/itertools): Extra iterator adaptors, iterator methods, free functions, and macros -- [num_enum](https://lib.rs/crates/num_enum): Procedural macros to make inter-operation between primitives and enums easier -- [cached](https://crates.io/crates/cached): Caching Crate +### Filesystem - [tempfile](https://lib.rs/crates/tempfile): Temporary files and directories +- [temp-dir](https://lib.rs/crates/temp-dir): Simple temporary directory with cleanup - [walkdir](https://crates.io/crates/walkdir): recursively scan directories +- [jwalk](https://lib.rs/crates/jwalk): Filesystem walk performed in parallel with streamed and sorted results +- [glob](https://lib.rs/crates/glob): Support for matching file paths against Unix shell style patterns - [notify](https://lib.rs/crates/notify): filesystem watcher +- [camino](https://lib.rs/crates/camino): UTF-8 paths +- [sugar_path](https://lib.rs/crates/sugar_path): Sugar functions for manipulating paths +- [path-absolutize](https://lib.rs/crates/path-absolutize): A library for extending Path and PathBuf in order to get an absolute path and remove the containing dots +- [fs_extra](https://lib.rs/crates/fs_extra): Expanding std::fs and std::io. Recursively copy folders with information about process and much more. +- [vfs](https://lib.rs/crates/vfs): A virtual filesystem for Rust +- [fuser](https://lib.rs/crates/fuser): Filesystem in Userspace (FUSE) for Rust +- [directories](https://lib.rs/crates/directories): A tiny mid-level library that provides platform-specific standard locations of directories for config, cache and other data on Linux, Windows and macOS +- [xattr](https://lib.rs/crates/xattr): unix extended filesystem attributes +- [open](https://lib.rs/crates/open): Open a path or URL using the program configured on the system +- [infer](https://lib.rs/crates/infer): Small crate to infer file type based on magic number signatures ### Error Handling - [anyhow](https://lib.rs/crates/anyhow): Flexible concrete Error type built on `std::error::Error` -- [color-eyre](https://lib.rs/crates/color-eyre): Styled error messages - [thiserror](https://lib.rs/crates/thiserror): macros for creating error types +- [user-error](https://lib.rs/crates/user-error): Pretty printed errors for your CLI application. +- [eyre](https://lib.rs/crates/eyre): Flexible concrete Error Reporting type built on `std::error::Error` with customizable Reports +- [color-eyre](https://lib.rs/crates/color-eyre): An error report handler for panics and `eyre::Reports` for colorful, consistent, and well formatted error reports for all kinds of errors -### Encoding -- [bincode](https://lib.rs/crates/bincode): A binary serialization / deserialization strategy for transforming structs into bytes and vice versa! +### Data Structures +- [hashbrown](https://lib.rs/crates/hashbrown): A Rust port of Google's SwissTable hash map +- [bitvec](https://lib.rs/crates/bitvec): Addresses memory by bits, for packed collections and bitfields +- [bitflags](https://lib.rs/crates/bitflags): A macro to generate structures which behave like bitflags +- [smallvec](https://lib.rs/crates/smallvec): 'Small vector' optimization: store up to a small number of items on the stack +- [ndarray](https://lib.rs/crates/ndarray): An n-dimensional array for general elements and for numerics. Lightweight array views and slicing; views support chunking and splitting. +- [zerovec](https://lib.rs/crates/zerovec): Zero-copy vector backed by a byte array +- [priority-queue](https://lib.rs/crates/priority-queue): A Priority Queue implemented as a heap with a function to efficiently change the priority of an item +- [histogram](https://lib.rs/crates/histogram): A collection of histogram data structures +- [fraction](https://lib.rs/crates/fraction): Lossless fractions and decimals; drop-in float replacement +- [ringbuffer](https://lib.rs/crates/ringbuffer): A fixed-size circular buffer +- [grid](https://lib.rs/crates/grid): Dynamic generic 2D data structure +- [datas](https://lib.rs/crates/datas): A library for data structures and algorithms and data analisys +- [trees](https://lib.rs/crates/trees): General purpose tree data structures +- [either](https://lib.rs/crates/either): The enum Either with variants Left and Right is a general purpose sum type with two cases +- [either_of](https://lib.rs/crates/either_of): Utilities for working with enumerated types that contain one of 2..n other types +- [petgraph](https://lib.rs/crates/petgraph): Graph data structure library. Provides graph types and graph algorithms. +- [hypergraph](https://lib.rs/crates/hypergraph): Hypergraph is data structure library to create a directed hypergraph in which an hyperedge can join any number of vertices +- [gix](https://crates.io/crates/gix): Interact with git repositories just like git would +- [git2](https://lib.rs/crates/git2): Bindings to libgit2 for interoperating with git repositories. + +### Parser +- [nom](https://lib.rs/crates/nom): A byte-oriented, zero-copy, parser combinators library +- [pest](https://lib.rs/crates/pest): pest is a general purpose parser written in Rust +- [keepass](https://lib.rs/crates/keepass): KeePass .kdbx database file parser +- [html5ever](https://lib.rs/crates/html5ever): High-performance browser-grade HTML5 parser +- [comrak](https://lib.rs/crates/comrak): A 100% CommonMark-compatible GitHub Flavored Markdown parser and formatter +- [uriparse](https://lib.rs/crates/uriparse): A URI parser including relative references +- [markdown](https://lib.rs/crates/markdown): CommonMark compliant markdown parser in Rust with ASTs and extensions +- [evalexpr](https://lib.rs/crates/evalexpr): A powerful arithmetic and boolean expression evaluator +- [uuid](https://lib.rs/crates/uuid): A library to generate and parse UUIDs +- [semver](https://lib.rs/crates/semver): Parser and evaluator for Cargo's flavor of Semantic Versioning +- [url](https://lib.rs/crates/url): URL library for Rust, based on the WHATWG URL Standard +- [httparse](https://lib.rs/crates/httparse): A tiny, safe, speedy, zero-copy HTTP/1.x parser +- [syntect](https://lib.rs/crates/syntect): library for high quality syntax highlighting and code intelligence using Sublime Text's grammars + +### Serialization - [serde](https://lib.rs/crates/serde): A generic serialization/deserialization framework +- [serde_with](https://lib.rs/crates/serde_with): Custom de/serialization functions for Rust's serde +- [bincode](https://lib.rs/crates/bincode): A binary serialization / deserialization strategy for transforming structs into bytes and vice versa! - [serde_json](https://lib.rs/crates/serde_json): A [JSON](../../../files/JSON.md) serialization file format +- [serde_jsonc](https://lib.rs/crates/serde_jsonc): A JSON serialization file format - [serde_yaml](https://lib.rs/crates/serde_yaml): [YAML](../../../files/YAML.md) data format for Serde - [bson](https://lib.rs/crates/bson): Encoding and decoding support for [BSON](../../../files/BSON.md) in Rust -- [hex](https://lib.rs/crates/hex): Encoding and decoding data into/from hexadecimal representation - [toml](https://lib.rs/crates/toml): A native Rust encoder and decoder of [TOML](../../../files/TOML.md)-formatted files and streams. +- [gray_matter](https://lib.rs/crates/gray_matter): Smart front matter parser. An implementation of gray-matter in rust. Parses YAML, JSON, TOML and support for custom parsers. +- [schemars](https://lib.rs/crates/schemars): Generate JSON Schemas from Rust code +- [jsonschema](https://lib.rs/crates/jsonschema): JSON schema validaton library +- [json-patch](https://lib.rs/crates/json-patch): RFC 6902, JavaScript Object Notation (JSON) Patch +- [rss](https://lib.rs/crates/rss): Library for serializing the RSS web content syndication format +- [postcard](https://lib.rs/crates/postcard): A no_std + serde compatible message library for Rust + +### Encoding +- [hex](https://lib.rs/crates/hex): Encoding and decoding data into/from hexadecimal representation +- [base62](https://lib.rs/crates/base62): A Base62 encoding/decoding library - [base64](https://lib.rs/crates/base64): encodes and decodes [base64](../../../files/Base64.md) as bytes or utf8 +- [base64-url](https://lib.rs/crates/base64-url): Base64 encode, decode, escape and unescape for URL applications +- [encoding_rs](https://lib.rs/crates/encoding_rs): A Gecko-oriented implementation of the Encoding Standard +- [data-encoding](https://lib.rs/crates/data-encoding): Efficient and customizable data-encoding functions like base64, base32, and hex +- [shell-quote](https://lib.rs/crates/shell-quote): A Rust library for shell-quoting strings, e.g. for interpolating into a Bash script. +- [urlencoding](https://lib.rs/crates/urlencoding): A Rust library for doing URL percentage encoding +- [bytesize](https://lib.rs/crates/bytesize): Semantic wrapper for byte count representations +- [hex-literal](https://lib.rs/crates/hex-literal): Macro for converting hexadecimal string to a byte array at compile time +- [byte-unit](https://lib.rs/crates/byte-unit): A library for interacting with units of bytes +- [bytes](https://lib.rs/crates/bytes): Types and traits for working with bytes ### Algorithms - [rand](https://lib.rs/crates/rand): Random number generators and other randomness functionality +- [bonsai-bt](https://lib.rs/crates/bonsai-bt): Behaviour trees +- [pathfinding](https://lib.rs/crates/pathfinding): Pathfinding, flow, and graph algorithms +- [treediff](https://lib.rs/crates/treediff): Find the difference between arbitrary data structures +- [raft](https://lib.rs/crates/raft): The rust language implementation of Raft algorithm + +### Crypto +- [rustls](https://lib.rs/crates/rustls): Rustls is a modern TLS library written in Rust +- [rustls-pemfile](https://lib.rs/crates/rustls-pemfile): Basic .pem file parser for keys and certificates +- [pem](https://lib.rs/crates/pem): Parse and encode PEM-encoded data +- [x509-parser](https://lib.rs/crates/x509-parser): Parser for the X.509 v3 format (RFC 5280 certificates) +- [openssl](https://lib.rs/crates/openssl): OpenSSL bindings +- [hkdf](https://lib.rs/crates/hkdf): HMAC-based Extract-and-Expand Key Derivation Function (HKDF) +- [ed25519-compact](https://lib.rs/crates/ed25519-compact): A small, self-contained, wasm-friendly Ed25519 implementation +- [snow](https://lib.rs/crates/snow): A pure-rust implementation of the Noise Protocol Framework +- [keyring](https://lib.rs/crates/keyring): Cross-platform library for managing passwords/credentials +- [scrypt](https://lib.rs/crates/scrypt): Scrypt password-based key derivation function +- [totp-rs](https://lib.rs/crates/totp-rs): RFC-compliant TOTP implementation with ease of use as a goal and additionnal QoL features +- [mnemonic](https://lib.rs/crates/mnemonic): Encode any data into a sequence of English words +- [jwt](https://lib.rs/crates/jwt): JSON Web Token library +- [secrets](https://lib.rs/crates/secrets): Protected-access memory for cryptographic secrets +- [redact](https://lib.rs/crates/redact): A simple library for keeping secrets out of logs +- [noise](https://lib.rs/crates/noise): Procedural noise generation library +- [ulid](https://lib.rs/crates/ulid): a Universally Unique Lexicographically Sortable Identifier implementation + +#### Hashes +- [digest](https://lib.rs/crates/digest): Traits for cryptographic hash functions and message authentication codes +- [seahash](https://lib.rs/crates/seahash): A blazingly fast, portable hash function with proven statistical guarantees +- [highway](https://lib.rs/crates/highway): Native Rust port of Google's HighwayHash, which makes use of SIMD instructions for a fast and strong hash function +- [md5](https://lib.rs/crates/md5): The package provides the MD5 hash function +- [crc32c](https://lib.rs/crates/crc32c): Safe implementation for hardware accelerated CRC32C instructions with software fallback +- [blake3](https://lib.rs/crates/blake3): the BLAKE3 hash function +- [siphasher](https://lib.rs/crates/siphasher): SipHash-2-4, SipHash-1-3 and 128-bit variants in pure Rust +- [bcrypt](https://lib.rs/crates/bcrypt): Easily hash and verify passwords using bcrypt +- [sha1](https://lib.rs/crates/sha1): SHA-1 hash function +- [sha2](https://lib.rs/crates/sha2): Pure Rust implementation of the SHA-2 hash function family including SHA-224, SHA-256, SHA-384, and SHA-512 +- [sha3](https://lib.rs/crates/sha3): Pure Rust implementation of SHA-3, a family of Keccak-based hash functions including the SHAKE family of eXtendable-Output Functions (XOFs), as well as the accelerated variant TurboSHAKE ### Logging - [log](https://lib.rs/crates/log): A lightweight logging facade for Rust -- [tracing](https://lib.rs/crates/tracing): advanced logger - [env_logger](https://lib.rs/crates/env_logger): A logging implementation for `log` which is configured via an environment variable +- [prometheus](https://lib.rs/crates/prometheus): Prometheus instrumentation library for Rust applications +- [opentelemetry](https://lib.rs/crates/opentelemetry): OpenTelemetry API for Rust +- [sentry-core](https://lib.rs/crates/sentry-core): Core sentry library used for instrumentation and integration development +- [logging_timer](https://lib.rs/crates/logging_timer): Simple timers that log the elapsed time when dropped +- [dioxus-logger](https://lib.rs/crates/dioxus-logger): A logging utility to provide a standard interface whether you're targeting web desktop, fullstack, and more in Dioxus +- [tracing](https://lib.rs/crates/tracing): advanced logger +- [tracing-appender](https://lib.rs/crates/tracing-appender): Provides utilities for file appenders and making non-blocking writers +- [tracing-loki](https://lib.rs/crates/tracing-loki): A tracing layer for shipping logs to Grafana Loki ### Mail - [lettre](https://lib.rs/crates/lettre): [Email](../../../internet/eMail.md) client @@ -982,24 +1094,93 @@ Currently, all supported targets follow the assembly code syntax used by LLVM's ### Templates - [maud](https://lib.rs/crates/maud): Compile-time [HTML](../../../internet/HTML.md) templates - [tera](https://lib.rs/crates/tera): Template engine based on [Jinja](../../../tools/Jinja.md) templates +- [subst](https://lib.rs/crates/subst): shell-like variable substitution +- [minijinja](https://lib.rs/crates/minijinja): a powerful template engine for Rust with minimal dependencies +- [handlebars](https://lib.rs/crates/handlebars): Handlebars templating implemented in Rust ### Media +#### Images - [image](https://lib.rs/crates/image): Imaging library. Provides basic image processing and encoders/decoders for common image formats. +- [rgb](https://lib.rs/crates/rgb): Pixel types for Rust +- [qrcode](https://lib.rs/crates/qrcode): QR code encoder in Rust +- [gif](https://lib.rs/crates/gif): GIF de- and encoder +- [opencv](https://lib.rs/crates/opencv): Rust bindings for OpenCV +- [imgref](https://lib.rs/crates/imgref): A basic 2-dimensional slice for safe and convenient handling of pixel buffers with width, height & stride +- [palette](https://lib.rs/crates/palette): Convert and manage colors with a focus on correctness, flexibility and ease of use +- [imageproc](https://lib.rs/crates/imageproc): Image processing operations +- [resvg](https://lib.rs/crates/resvg): An SVG rendering library +- [png](https://lib.rs/crates/png): PNG decoding and encoding library in pure Rust +- [webp](https://lib.rs/crates/webp): WebP conversion library +- [image_hasher](https://lib.rs/crates/image_hasher): A simple library that provides perceptual hashing and difference calculation for images +- [dify](https://lib.rs/crates/dify): A fast pixel-by-pixel image comparison tool in Rust +- [qoi](https://lib.rs/crates/qoi): VERY fast encoder/decoder for QOI (Quite Okay Image) format +- [auto-palette](https://lib.rs/crates/auto-palette): 🎨 A Rust library that extracts prominent color palettes from images automatically +- [blockhash](https://lib.rs/crates/blockhash): A perceptual hashing algorithm for detecting similar images + +#### Video +- [ffmpeg-next](https://lib.rs/crates/ffmpeg-next): Safe FFmpeg wrapper +- [video-rs](https://lib.rs/crates/video-rs): High-level video toolkit based on ffmpeg +- [ffprobe](https://lib.rs/crates/ffprobe): Typed wrapper for the ffprobe CLI + +#### Audio +- [symphonia](https://lib.rs/crates/symphonia): Pure Rust media container and audio decoding library +- [hound](https://lib.rs/crates/hound): A wav encoding and decoding library +- [id3](https://lib.rs/crates/id3): A library for reading and writing ID3 metadata +- [metaflac](https://lib.rs/crates/metaflac): A library for reading and writing FLAC metadata +- [bliss-audio](https://lib.rs/crates/bliss-audio): A song analysis library for making playlists + +### 3D +- [glam](https://lib.rs/crates/glam): A simple and fast 3D math library for games and graphics +- [tobj](https://lib.rs/crates/tobj): A lightweight OBJ loader in the spirit of tinyobjloader +- [obj-rs](https://lib.rs/crates/obj-rs): Wavefront obj parser for Rust. It handles both 'obj' and 'mtl' formats. ### CLI -- [rustyline](https://lib.rs/crates/rustyline): Rustyline, a readline implementation based on Antirez's Linenoise -- [clap](https://lib.rs/crates/clap): A simple to use, efficient, and full-featured Command Line Argument Parser -- [crossterm](https://lib.rs/crates/crossterm): A crossplatform terminal library for manipulating terminals -- [indicatif](https://lib.rs/crates/indicatif): A progress bar and cli reporting library for Rust - [argh](https://lib.rs/crates/argh): Derive-based argument parser optimized for code size -- [owo-colors](https://lib.rs/crates/owo-colors): Zero-allocation terminal colors that'll make people go owo +- [clap](https://lib.rs/crates/clap): A simple to use, efficient, and full-featured Command Line Argument Parser - [yansi](https://lib.rs/crates/yansi): A dead simple ANSI terminal color painting library +- [owo-colors](https://lib.rs/crates/owo-colors): Zero-allocation terminal colors that'll make people go owo +- [named-colour](https://lib.rs/crates/named-colour): named-colour provides Hex Codes for popular colour names +- [colored](https://lib.rs/crates/colored): The most simple way to add colors in your terminal +- [crossterm](https://lib.rs/crates/crossterm): A crossplatform terminal library for manipulating terminals +- [trauma](https://lib.rs/crates/trauma): Simplify and prettify HTTP downloads +- [comfy-table](https://lib.rs/crates/comfy-table): An easy to use library for building beautiful tables with automatic content wrapping +- [tabled](https://lib.rs/crates/tabled): An easy to use library for pretty print tables of Rust structs and enums +- [tabular](https://lib.rs/crates/tabular): Plain text tables, aligned automatically +- [rustyline](https://lib.rs/crates/rustyline): Rustyline, a readline implementation based on Antirez's Linenoise +- [rpassword](https://lib.rs/crates/rpassword): Read passwords in console applications +- [inquire](https://lib.rs/crates/inquire): inquire is a library for building interactive prompts on terminals +- [indicatif](https://lib.rs/crates/indicatif): A progress bar and cli reporting library for Rust +- [spinners](https://lib.rs/crates/spinners): Elegant terminal spinners for Rust +- [is-terminal](https://lib.rs/crates/is-terminal): Test whether a given stream is a terminal +- [bishop](https://lib.rs/crates/bishop): Library for visualizing keys and hashes using OpenSSH's Drunken Bishop algorithm +- [termimad](https://lib.rs/crates/termimad): Markdown Renderer for the Terminal +- [rust-script](https://lib.rs/crates/rust-script): Command-line tool to run Rust "scripts" which can make use of crates +- [sysinfo](https://lib.rs/crates/sysinfo): Library to get system information such as processes, CPUs, disks, components and networks +- [which](https://lib.rs/crates/which): A Rust equivalent of Unix command "which". Locate installed executable in cross platforms. +- [ctrlc](https://lib.rs/crates/ctrlc): Easy Ctrl-C handler for Rust projects +- [subprocess](https://lib.rs/crates/subprocess): Execution of child processes and pipelines, inspired by Python's subprocess module, with Rust-specific extensions +- [cmd_lib](https://lib.rs/crates/cmd_lib): Common rust commandline macros and utils, to write shell script like tasks easily ### Compression - [flate2](https://lib.rs/crates/flate2): DEFLATE compression and decompression exposed as Read/BufRead/Write streams. Supports miniz_oxide and multiple zlib implementations. Supports zlib, gzip, and raw deflate streams. - [tar](https://lib.rs/crates/tar): A Rust implementation of a [TAR](../../../applications/cli/compression/tar.md) file reader and writer. - [zstd](https://lib.rs/crates/zstd): Binding for the [zstd compression](../../../files/Zstd%20Compression.md) library - [unrar](https://lib.rs/crates/unrar): list and extract RAR archives +- [zip](https://lib.rs/crates/zip): Library to support the reading and writing of zip files +- [brotli](https://lib.rs/crates/brotli): A brotli compressor and decompressor +- [huffman-compress2](https://lib.rs/crates/huffman-compress2): Huffman compression given a probability distribution over arbitrary symbols +- [arithmetic-coding](https://lib.rs/crates/arithmetic-coding): fast and flexible arithmetic coding library + +### Cache +- [lru](https://lib.rs/crates/lru): A LRU cache implementation +- [moka](https://lib.rs/crates/moka): A fast and concurrent cache library inspired by Java Caffeine +- [ustr](https://lib.rs/crates/ustr): Fast, FFI-friendly string interning +- [cacache](https://lib.rs/crates/cacache): Content-addressable, key-value, high-performance, on-disk cache +- [cached](https://crates.io/crates/cached): Caching Crate +- [memoize](https://lib.rs/crates/memoize): Attribute macro for auto-memoizing functions with somewhat-simple signatures +- [internment](https://lib.rs/crates/internment): Easy interning of data +- [http-cache-semantics](https://lib.rs/crates/http-cache-semantics): RFC 7234. Parses HTTP headers to correctly compute cacheability of responses, even in complex cases +- [assets_manager](https://lib.rs/crates/assets_manager): Conveniently load, cache, and reload external resources ### Databases - [rusqlite](https://lib.rs/crates/rusqlite): Ergonomic wrapper for [SQLite](../SQLite.md) @@ -1008,34 +1189,291 @@ Currently, all supported targets follow the assembly code syntax used by LLVM's - [rocksdb](https://lib.rs/crates/rocksdb): embedded database - [uuid](https://lib.rs/crates/uuid): UUID Generation - [polars](https://lib.rs/crates/polars): Dataframes computation +- [surrealdb](https://crates.io/crates/surrealdb): A scalable, distributed, collaborative, document-graph database, for the realtime web +- [sql-builder](https://lib.rs/crates/sql-builder): Simple SQL code generator +- [pgvector](https://lib.rs/crates/pgvector): pgvector support for Rust +- [sea-orm](https://lib.rs/crates/sea-orm): 🐚 An async & dynamic ORM for Rust +- [sled](https://lib.rs/crates/sled): Lightweight high-performance pure-rust transactional embedded database ### Date and Time - [chrono](https://lib.rs/crates/chrono): Date and time library for Rust +- [chrono-tz](https://lib.rs/crates/chrono-tz): TimeZone implementations for chrono from the IANA database - [humantime](https://lib.rs/crates/humantime): A parser and formatter for `std::time::{Duration, SystemTime}` +- [duration-str](https://lib.rs/crates/duration-str): duration string parser +- [cron](https://lib.rs/crates/cron): A cron expression parser and schedule explorer +- [dateparser](https://lib.rs/crates/dateparser): Parse dates in string formats that are commonly used +- [icalendar](https://lib.rs/crates/icalendar): Strongly typed iCalendar builder and parser + +### Network +- [tower](https://lib.rs/crates/tower): Tower is a library of modular and reusable components for building robust clients and servers +- [tungstenite](https://lib.rs/crates/tungstenite): Lightweight stream-based WebSocket implementation +- [tokio-websockets](http://ocean.hydrar.de/s/lib.rs/crates/tokio-websockets): High performance, strict, tokio-util based WebSockets implementation +- [message-io](https://lib.rs/crates/message-io): Fast and easy-to-use event-driven network library +- [ipnet](https://lib.rs/crates/ipnet): Provides types and useful methods for working with IPv4 and IPv6 network addresses +- [object_store](https://lib.rs/crates/object_store): A generic object store interface for uniformly interacting with AWS S3, Google Cloud Storage, Azure Blob Storage and local files +- [matchit](https://lib.rs/crates/matchit): A high performance, zero-copy URL router +- [tun](https://lib.rs/crates/tun): TUN device creation and handling +- [quiche](https://lib.rs/crates/quiche): 🥧 Savoury implementation of the QUIC transport protocol and HTTP/3 +- [arti-client](https://lib.rs/crates/arti-client): Library for connecting to the Tor network as an anonymous client +- [etherparse](https://lib.rs/crates/etherparse): A library for parsing & writing a bunch of packet based protocols (EthernetII, IPv4, IPv6, UDP, TCP ...) +- [ldap3](https://lib.rs/crates/ldap3): Pure-Rust LDAP Client +- [hyperlocal](https://lib.rs/crates/hyperlocal): Hyper bindings for Unix domain sockets +- [openssh-sftp-client](https://lib.rs/crates/openssh-sftp-client): Highlevel API used to communicate with openssh sftp server +- [swarm-discovery](https://lib.rs/crates/swarm-discovery): Discovery service for IP-based swarms +- [libmdns](https://lib.rs/crates/libmdns): mDNS Responder library for building discoverable LAN services in Rust +- [networkmanager](https://lib.rs/crates/networkmanager): Bindings for the Linux NetworkManager +- [renet](https://lib.rs/crates/renet): Server/Client network library for multiplayer games with authentication and connection management +- [dhcproto](https://lib.rs/crates/dhcproto): A DHCP parser and encoder for DHCPv4/DHCPv6. dhcproto aims to be a functionally complete DHCP implementation. +- [irc](https://lib.rs/crates/irc): the irc crate – usable, async IRC for Rust +- [ssh2](https://lib.rs/crates/ssh2): Bindings to libssh2 for interacting with SSH servers and executing remote commands, forwarding local ports, etc +- [openssh](https://lib.rs/crates/openssh): SSH through OpenSSH +- [amqprs](https://lib.rs/crates/amqprs): AMQP 0-9-1 client implementation for RabbitMQ +- [wyoming](https://lib.rs/crates/wyoming): Abstractions over the Wyoming protocol ### HTTP - [hyper](https://lib.rs/crates/hyper): A fast and correct [HTTP](../../../internet/HTTP.md) library - [reqwest](https://lib.rs/crates/reqwest): higher level [HTTP](../../../internet/HTTP.md) client library +- [ureq](https://lib.rs/crates/ureq): Simple, safe HTTP client +- [curl](https://lib.rs/crates/curl): Rust bindings to libcurl for making HTTP requests - [actix-web](https://lib.rs/crates/actix-web): Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust - [rocket](https://lib.rs/crates/rocket): web server framework for Rust +- [thirtyfour](https://lib.rs/crates/thirtyfour): Thirtyfour is a Selenium / WebDriver library for Rust, for automated website UI testing +- [http-types](https://lib.rs/crates/http-types): Common types for HTTP operations +- [headers](https://lib.rs/crates/headers): typed HTTP headers +- [cookie](https://lib.rs/crates/cookie): HTTP cookie parsing and cookie jar management. Supports signed and private (encrypted, authenticated) jars. +- [http](https://lib.rs/crates/http): A set of types for representing HTTP requests and responses +- [h2](https://lib.rs/crates/h2): An HTTP/2 client and server +- [h3](https://lib.rs/crates/h3): An async HTTP/3 implementation +- [mime](https://lib.rs/crates/mime): Strongly Typed Mimes +- [scraper](https://lib.rs/crates/scraper): HTML parsing and querying with CSS selectors +- [selectors](https://lib.rs/crates/selectors): CSS Selectors matching for Rust +- [spider](https://lib.rs/crates/spider): A web crawler and scraper, building blocks for data curation workloads +- [htmlize](https://lib.rs/crates/htmlize): Encode and decode HTML entities in UTF-8 according to the standard +- [ammonia](https://lib.rs/crates/ammonia): HTML Sanitization +- [rookie](https://lib.rs/crates/rookie): Load cookie from your web browsers +- [tonic](https://lib.rs/crates/tonic): A gRPC over HTTP/2 implementation focused on high performance, interoperability, and flexibility +- [web-sys](https://lib.rs/crates/web-sys): Bindings for all Web APIs, a procedurally generated crate from WebIDL +- [jsonwebtoken](https://lib.rs/crates/jsonwebtoken): Create and decode JWTs in a strongly typed way +- [http-range-header](https://lib.rs/crates/http-range-header): No-dep range header parser + +#### Axum +- [axum](https://lib.rs/crates/axum): Web framework that focuses on ergonomics and modularity +- [axum-valid](https://crates.io/crates/axum-valid): Provides validation extractors for your Axum application, allowing you to validate data using validator, garde, validify or all of them. +- [axum-prometheus](https://crates.io/crates/axum-prometheus): A tower middleware to collect and export HTTP metrics for Axum +- [axum-htmx](https://crates.io/crates/axum-htmx): A set of htmx extractors, responders, and request guards for axum. +- [axum_session](https://crates.io/crates/axum_session): 📝 Session management layer for axum that supports HTTP and Rest. +- [axum_csrf](https://crates.io/crates/axum_csrf): Library to Provide a CSRF (Cross-Site Request Forgery) protection layer. ### Text - [regex](https://lib.rs/crates/regex): An implementation of [regular expressions](../../../tools/Regex.md) for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs. -- [comfy-table](https://lib.rs/crates/comfy-table): An easy to use library for building beautiful tables with automatic content wrapping +- [fancy-regex](https://lib.rs/crates/fancy-regex): An implementation of regexes, supporting a relatively rich set of features, including backreferences and look-around +- [pretty_regex](https://lib.rs/crates/pretty_regex): 🧶 Elegant and readable way of writing regular expressions - [similar](https://lib.rs/crates/similar): A diff library for Rust +- [dissimilar](https://lib.rs/crates/dissimilar): Diff library with semantic cleanup, based on Google's diff-match-patch +- [strsim](https://lib.rs/crates/strsim): Implementations of string similarity metrics. Includes Hamming, Levenshtein, OSA, Damerau-Levenshtein, Jaro, Jaro-Winkler, and Sørensen-Dice. +- [enquote](https://lib.rs/crates/enquote): Quotes and unquotes strings +- [emojis](https://lib.rs/crates/emojis): ✨ Lookup emoji in *O(1)* time, access metadata and GitHub shortcodes, iterate over all emoji, and more! +- [text-splitter](https://lib.rs/crates/text-splitter): Split text into semantic chunks, up to a desired chunk size. Supports calculating length by characters and tokens, and is callable from Rust and Python. +- [wildcard](https://lib.rs/crates/wildcard): Wildcard matching +- [wildmatch](https://lib.rs/crates/wildmatch): Simple string matching with single- and multi-character wildcard operator +- [textwrap](https://lib.rs/crates/textwrap): Library for word wrapping, indenting, and dedenting strings. Has optional support for Unicode and emojis as well as machine hyphenation. +- [pad](https://lib.rs/crates/pad): Library for padding strings at runtime +- [const-str](https://lib.rs/crates/const-str): compile-time string operations +- [const_format](https://lib.rs/crates/const_format): Compile-time string formatting +- [convert_case](https://lib.rs/crates/convert_case): Convert strings into any case +- [heck](https://lib.rs/crates/heck): heck is a case conversion library +- [html2md](https://lib.rs/crates/html2md): Library to convert simple html documents into markdown + +### AI +- [safetensors](https://lib.rs/crates/safetensors): Provides functions to read and write safetensors which aim to be safer than their PyTorch counterpart. +- [burn](https://lib.rs/crates/burn): Flexible and Comprehensive Deep Learning Framework in Rust +- [ollama-rs](https://lib.rs/crates/ollama-rs): A Rust library for interacting with the Ollama API +- [linfa](https://lib.rs/crates/linfa): A Machine Learning framework for Rust +- [neurons](https://lib.rs/crates/neurons): Neural networks from scratch, in Rust ### Concurrency - [parking_lot](https://lib.rs/crates/parking_lot): More compact and efficient implementations of the standard synchronization primitives - [crossbeam](https://lib.rs/crates/crossbeam): Tools for concurrent programming - [rayon](https://lib.rs/crates/rayon): Simple work-stealing parallelism for Rust - [dashmap](https://lib.rs/crates/dashmap): fast hashmap +- [spin](https://lib.rs/crates/spin): Spin-based synchronization primitives +- [flume](https://lib.rs/crates/flume): A blazingly fast multi-producer channel +- [state](https://lib.rs/crates/state): A library for safe and effortless global and thread-local state management +- [atomic](https://lib.rs/crates/atomic): Generic `Atomic` wrapper type +- [yaque](https://lib.rs/crates/yaque): Yaque is yet another disk-backed persistent queue for Rust +- [kanal](https://lib.rs/crates/kanal): The fast sync and async channel that Rust deserves + +### Memory Management +- [jemallocator](https://lib.rs/crates/jemallocator): jemalloc allocator +- [memmap2](https://lib.rs/crates/memmap2): Map something to memory +- [sharded-slab](https://lib.rs/crates/sharded-slab): lock free concurrent slab allocation +- [heapless](https://lib.rs/crates/heapless): static friendly data structures without heap allocation +- [bumpalo](https://lib.rs/crates/bumpalo): bump allocation arena +- [singlyton](https://lib.rs/crates/singlyton): [Singleton](../patterns/creational/Singleton%20Pattern.md) for Rust +- [pipe](https://lib.rs/crates/pipe): Synchronous Read/Write memory pipe +- [memory_storage](https://lib.rs/crates/memory_storage): Vec like data structure with constant index +- [effective-limits](https://lib.rs/crates/effective-limits): Estimate effective resource limits for a process +- [iter-chunks](https://lib.rs/crates/iter-chunks): Extend Iterator with chunks +- [shared_vector](https://lib.rs/crates/shared_vector): Reference counted vector data structure +- [census](https://lib.rs/crates/census): Keeps an inventory of living objects +- [static_cell](https://lib.rs/crates/static_cell): Statically allocated, initialized at runtime cell +- [arcstr](https://lib.rs/crates/arcstr): A better reference-counted string type, with zero-cost (allocation-free) support for string literals, and reference counted substrings +- [bytebuffer](https://lib.rs/crates/bytebuffer): A bytebuffer for networking and binary protocols + +### Science +- [syunit](https://lib.rs/crates/syunit): SI Units +- [uom](https://lib.rs/crates/uom): Units of measurement +- [measurements](https://lib.rs/crates/measurements): Handle metric, imperial, and other measurements with ease! Types: Length, Temperature, Weight, Volume, Pressure +- [t4t](https://lib.rs/crates/t4t): game theory toolbox + +### Hardware / Embedded +- [virt](https://lib.rs/crates/virt): Rust bindings to the libvirt C library +- [qapi](https://lib.rs/crates/qapi): QEMU QMP and Guest Agent API +- [bootloader](https://lib.rs/crates/bootloader): An experimental x86_64 bootloader that works on both BIOS and UEFI systems +- [embedded-graphics](https://lib.rs/crates/embedded-graphics): Embedded graphics library for small hardware displays +- [riscv](https://lib.rs/crates/riscv): Low level access to RISC-V processors +- [aarch64-cpu](https://lib.rs/crates/aarch64-cpu): Low level access to processors using the AArch64 execution state +- [uefi](https://lib.rs/crates/uefi): safe UEFI wrapper +- [elf](https://lib.rs/crates/elf): A pure-rust library for parsing ELF files +- [smoltcp](https://lib.rs/crates/smoltcp): A TCP/IP stack designed for bare-metal, real-time systems without a heap +- [fatfs](https://lib.rs/crates/fatfs): FAT filesystem library + +### Metrics +- [criterion2](https://lib.rs/crates/criterion2): Statistics-driven micro-benchmarking library +- [inferno](https://lib.rs/crates/inferno): Rust port of the FlameGraph performance profiling tool suite +- [divan](https://lib.rs/crates/divan): Statistically-comfy benchmarking library + +### Testing +- [test-log](https://lib.rs/crates/test-log): A replacement of the `#[test]` attribute that initializes logging and/or tracing infrastructure before running tests +- [googletest](https://lib.rs/crates/googletest): A rich assertion and matcher library inspired by GoogleTest for C++ +- [predicates](https://lib.rs/crates/predicates): An implementation of boolean-valued predicate functions +- [validator](https://lib.rs/crates/validator): Common validation functions (email, url, length, …) and trait - to be used with validator_derive +- [garde](https://lib.rs/crates/garde): Validation library +- [fake](https://lib.rs/crates/fake): An easy to use library and command line for generating fake data like name, number, address, lorem, dates, etc +- [static_assertions](https://lib.rs/crates/static_assertions): Compile-time assertions to ensure that invariants are met + +### i18n +- [iso_currency](https://lib.rs/crates/iso_currency): ISO 4217 currency codes +- [iso_country](https://lib.rs/crates/iso_country): ISO3166-1 countries +- [sys-locale](https://lib.rs/crates/sys-locale): Small and lightweight library to obtain the active system locale ### Async - [tokio](https://lib.rs/crates/tokio): An event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications - [futures](https://lib.rs/crates/futures): An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces -- [once_cell](https://lib.rs/crates/once_cell): Lazy values +- [mio](https://lib.rs/crates/mio): Lightweight non-blocking I/O +- [deadpool](https://lib.rs/crates/deadpool): Dead simple async pool +- [blocking](https://lib.rs/crates/blocking): A thread pool for isolating blocking I/O in async programs +- [pollster](https://lib.rs/crates/pollster): Synchronously block the thread until a future completes +- [smol](https://lib.rs/crates/smol): A small and fast async runtime +- [async-stream](https://lib.rs/crates/async-stream): Asynchronous streams using async & await notation +- [async-trait](https://lib.rs/crates/async-trait): Type erasure for async trait methods ### Macros +- [proc-macro2](https://lib.rs/crates/proc-macro2): A substitute implementation of the compiler’s proc_macro API to decouple token-based libraries from the procedural macro use case - [syn](https://lib.rs/crates/syn): Parse Rust syntax into AST - [quote](https://lib.rs/crates/quote): Turn Rust syntax into TokenStream - [paste](https://lib.rs/crates/paste): Concat Rust idents + +### Build Tools +- [flamegraph](https://lib.rs/crates/flamegraph): A simple cargo subcommand for generating flamegraphs, using inferno under the hood +- [cargo-hack](https://lib.rs/crates/cargo-hack): Cargo subcommand to provide various options useful for testing and continuous integration +- [cargo-outdated](https://lib.rs/crates/cargo-outdated): Cargo subcommand for displaying when dependencies are out of date +- [cargo-binstall](https://lib.rs/crates/cargo-binstall): Binary installation for rust projects +- [cargo-cache](https://lib.rs/crates/cargo-cache): Manage cargo cache, show sizes and remove directories selectively +- [cargo-watch](https://lib.rs/crates/cargo-watch): Watches over your Cargo project’s source +- [cargo-expand](https://lib.rs/crates/cargo-expand): Wrapper around `rustc -Zunpretty=expanded`. Shows the result of macro expansion and `#[derive]` expansion. +- [cargo-audit](https://lib.rs/crates/cargo-audit): Audit Cargo.lock for crates with security vulnerabilities +- [cargo-aur](https://lib.rs/crates/cargo-aur): Prepare Rust projects to be released on the Arch Linux User Repository +- [cargo-bom](https://lib.rs/crates/cargo-bom): Bill of Materials for Rust Crates +- [cc](https://lib.rs/crates/cc): A build-time dependency for Cargo build scripts to assist in invoking the native C compiler to compile native C code into a static archive to be linked into Rust code +- [cmake](https://lib.rs/crates/cmake): A build dependency for running cmake to build a native library +- [cross](https://lib.rs/crates/cross): Zero setup cross compilation and cross testing +- [wasm-bindgen](https://lib.rs/crates/wasm-bindgen): Easy support for interacting between JS and Rust + +### Math +- [num](https://lib.rs/crates/num): A collection of numeric types and traits for Rust, including bigint, complex, rational, range iterators, generic integers, and more! +- [num-format](https://lib.rs/crates/num-format): A Rust crate for producing string-representations of numbers, formatted according to international standards +- [num-rational](https://lib.rs/crates/num-rational): Rational numbers implementation for Rust +- [num-complex](https://lib.rs/crates/num-complex): Complex numbers implementation for Rust +- [statrs](https://lib.rs/crates/statrs): Statistical computing library for Rust +- [bigdecimal](https://lib.rs/crates/bigdecimal): Arbitrary precision decimal numbers +- [nalgebra](https://lib.rs/crates/nalgebra): General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices +- [euclid](https://lib.rs/crates/euclid): Geometry primitives +- [ultraviolet](https://lib.rs/crates/ultraviolet): A crate to do linear algebra, fast +- [peroxide](https://lib.rs/crates/peroxide): Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax + +### Desktop +- [notify-rust](https://lib.rs/crates/notify-rust): Show desktop notifications (linux, bsd, mac). Pure Rust dbus client and server. +- [arboard](https://lib.rs/crates/arboard): Image and text handling for the OS clipboard + +### Configuration +- [config](https://lib.rs/crates/config): Layered configuration system for Rust applications +- [envy](https://lib.rs/crates/envy): deserialize env vars into typesafe structs + +### Language Extensions +#### Enums +- [strum](https://lib.rs/crates/strum): Helpful macros for working with enums and strings +- [enum_dispatch](https://lib.rs/crates/enum_dispatch): Near drop-in replacement for dynamic-dispatched method calls with up to 10x the speed +- [num_enum](https://lib.rs/crates/num_enum): Procedural macros to make inter-operation between primitives and enums easier +- [enum-display](https://lib.rs/crates/enum-display): A macro to derive Display for enums + +#### Memory +- [smol_str](https://lib.rs/crates/smol_str): small-string optimized string type with O(1) clone +- [beef](https://lib.rs/crates/beef): More compact Cow +- [dyn-clone](https://lib.rs/crates/dyn-clone): Clone trait that is dyn-compatible +- [memoffset](https://lib.rs/crates/memoffset): offset_of functionality for Rust structs +- [az](https://lib.rs/crates/az): Casts and checked casts +- [zerocopy](https://lib.rs/crates/zerocopy): Zerocopy makes zero-cost memory manipulation effortless. We write "unsafe" so you don't have to. +- [once_cell](https://lib.rs/crates/once_cell): Single assignment cells and lazy values +- [lazy_static](https://lib.rs/crates/lazy_static): A macro for declaring lazily evaluated statics in Rust +- [globals](https://lib.rs/crates/globals): Painless global variables in Rust +- [lazy_format](https://lib.rs/crates/lazy_format): A utility crate for lazily formatting values for later +- [fragile](https://lib.rs/crates/fragile): Provides wrapper types for sending non-send values to other threads + +#### Syntax +- [tap](https://lib.rs/crates/tap): Generic extensions for tapping values in Rust +- [option_trait](https://lib.rs/crates/option_trait): Helper traits for more generalized options +- [cascade](https://lib.rs/crates/cascade): Dart-like cascade macro for Rust +- [enclose](https://lib.rs/crates/enclose): A convenient macro, for cloning values into a closure +- [extend](https://lib.rs/crates/extend): Create extensions for types you don't own with extension traits but without the boilerplate +- [hex_lit](https://lib.rs/crates/hex_lit): Hex macro literals without use of hex macros +- [replace_with](https://lib.rs/crates/replace_with): Temporarily take ownership of a value at a mutable location, and replace it with a new value based on the old one +- [scopeguard](https://lib.rs/crates/scopeguard): A RAII scope guard that will run a given closure when it goes out of scope, even if the code between panics (assuming unwinding panic). +- [backon](https://lib.rs/crates/backon): Make retry like a built-in feature provided by Rust +- [tryhard](https://lib.rs/crates/tryhard): Easily retry futures +- [retry](https://lib.rs/crates/retry): Utilities for retrying operations that can fail +- [statum](https://lib.rs/crates/statum): Compile-time state machine magic for Rust: Zero-boilerplate typestate patterns with automatic transition validation +- [formatx](https://lib.rs/crates/formatx): A macro for formatting non literal strings at runtime +- [erased](https://lib.rs/crates/erased): Erase the type of a reference or box, retaining the lifetime +- [include_dir](https://lib.rs/crates/include_dir): Embed the contents of a directory in your binary +- [stacker](https://lib.rs/crates/stacker): A stack growth library useful when implementing deeply recursive algorithms that may accidentally blow the stack +- [recursive](https://lib.rs/crates/recursive): Easy recursion without stack overflows + +#### Type Extensions +- [itertools](https://lib.rs/crates/itertools): Extra iterator adaptors, iterator methods, free functions, and macros +- [itermore](https://lib.rs/crates/itermore): 🤸‍♀️ More iterator adaptors +- [derive_more](https://lib.rs/crates/derive_more): Adds #[derive(x)] macros for more traits +- [derive_builder](https://lib.rs/crates/derive_builder): Rust macro to automatically implement the builder pattern for arbitrary structs +- [ordered-float](https://lib.rs/crates/ordered-float): Wrappers for total ordering on floats +- [stdext](https://lib.rs/crates/stdext): Extensions for the Rust standard library structures +- [bounded-integer](https://lib.rs/crates/bounded-integer): Bounded integers +- [tuples](https://lib.rs/crates/tuples): Provides many useful tools related to tuples +- [fallible-iterator](https://lib.rs/crates/fallible-iterator): Fallible iterator traits +- [sequential](https://lib.rs/crates/sequential): A configurable sequential number generator + +#### Compilation +- [cfg-if](https://lib.rs/crates/cfg-if): A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. +- [cfg_aliases](https://lib.rs/crates/cfg_aliases): A tiny utility to help save you a lot of effort with long winded #[cfg()] checks +- [nameof](https://lib.rs/crates/nameof): Provides a Rust macro to determine the string name of a binding, type, const, or function +- [tynm](https://lib.rs/crates/tynm): Returns type names in shorter form + +#### Const +- [constcat](https://lib.rs/crates/constcat): concat! with support for const variables and expressions +- [konst](https://lib.rs/crates/konst): Const equivalents of std functions, compile-time comparison, and parsing + +### Geo +- [geo](https://lib.rs/crates/geo): Geospatial primitives and algorithms +- [geojson](https://lib.rs/crates/geojson): Read and write GeoJSON vector geographic data +- [geozero](https://lib.rs/crates/geozero): Zero-Copy reading and writing of geospatial data in WKT/WKB, GeoJSON, MVT, GDAL, and other formats +- [versatiles](https://lib.rs/crates/versatiles): A toolbox for converting, checking and serving map tiles in various formats +- [ipcap](https://lib.rs/crates/ipcap): 🌍 A CLI & library for decoding IP addresses into state, postal code, country, coordinates, etc without internet access From 61b65a08296888c1aa2ab3b2d278faaa003c1ad5 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Tue, 8 Apr 2025 11:07:33 +0200 Subject: [PATCH 13/41] =?UTF-8?q?=E2=9C=A8=20add=20ulid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- technology/dev/ULID.md | 126 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 technology/dev/ULID.md diff --git a/technology/dev/ULID.md b/technology/dev/ULID.md new file mode 100644 index 0000000..259e509 --- /dev/null +++ b/technology/dev/ULID.md @@ -0,0 +1,126 @@ +--- +obj: concept +repo: https://github.com/ulid/spec +aliases: ["Universally Unique Lexicographically Sortable Identifier"] +--- + +# ULID (Universally Unique Lexicographically Sortable Identifier) +UUID can be suboptimal for many use-cases because: + +- It isn't the most character efficient way of encoding 128 bits of randomness +- UUID v1/v2 is impractical in many environments, as it requires access to a unique, stable MAC address +- UUID v3/v5 requires a unique seed and produces randomly distributed IDs, which can cause fragmentation in many data structures +- UUID v4 provides no other information than randomness which can cause fragmentation in many data structures + +Instead, herein is proposed ULID: + +```javascript +ulid() // 01ARZ3NDEKTSV4RRFFQ69G5FAV +``` + +- 128-bit compatibility with UUID +- 1.21e+24 unique ULIDs per millisecond +- Lexicographically sortable! +- Canonically encoded as a 26 character string, as opposed to the 36 character UUID +- Uses Crockford's base32 for better efficiency and readability (5 bits per character) +- Case insensitive +- No special characters (URL safe) +- Monotonic sort order (correctly detects and handles the same millisecond) + +## Specification +Below is the current specification of ULID as implemented in [ulid/javascript](https://github.com/ulid/javascript). + +*Note: the binary format has not been implemented in JavaScript as of yet.* + +``` + 01AN4Z07BY 79KA1307SR9X4MV3 + +|----------| |----------------| + Timestamp Randomness + 48bits 80bits +``` + +### Components + +**Timestamp** +- 48 bit integer +- UNIX-time in milliseconds +- Won't run out of space 'til the year 10889 AD. + +**Randomness** +- 80 bits +- Cryptographically secure source of randomness, if possible + +### Sorting +The left-most character must be sorted first, and the right-most character sorted last (lexical order). The default ASCII character set must be used. Within the same millisecond, sort order is not guaranteed + +### Canonical String Representation + +``` +ttttttttttrrrrrrrrrrrrrrrr + +where +t is Timestamp (10 characters) +r is Randomness (16 characters) +``` + +#### Encoding +Crockford's Base32 is used as shown. This alphabet excludes the letters I, L, O, and U to avoid confusion and abuse. + +``` +0123456789ABCDEFGHJKMNPQRSTVWXYZ +``` + +### Monotonicity +When generating a ULID within the same millisecond, we can provide some guarantees regarding sort order. Namely, if the same millisecond is detected, the `random` component is incremented by 1 bit in the least significant bit position (with carrying). For example: + +```javascript +import { monotonicFactory } from 'ulid' + +const ulid = monotonicFactory() + +// Assume that these calls occur within the same millisecond +ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRZ +ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0 +``` + +If, in the extremely unlikely event that, you manage to generate more than $2^{80}$ ULIDs within the same millisecond, or cause the random component to overflow with less, the generation will fail. + +```javascript +import { monotonicFactory } from 'ulid' + +const ulid = monotonicFactory() + +// Assume that these calls occur within the same millisecond +ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRY +ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRZ +ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0 +ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS1 +... +ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZX +ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZY +ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZZ +ulid() // throw new Error()! +``` + +#### Overflow Errors when Parsing Base32 Strings +Technically, a 26-character Base32 encoded string can contain 130 bits of information, whereas a ULID must only contain 128 bits. Therefore, the largest valid ULID encoded in Base32 is `7ZZZZZZZZZZZZZZZZZZZZZZZZZ`, which corresponds to an epoch time of `281474976710655` or $2^{48}-1$. + +Any attempt to decode or encode a ULID larger than this should be rejected by all implementations, to prevent overflow bugs. + +### Binary Layout and Byte Order +The components are encoded as 16 octets. Each component is encoded with the Most Significant Byte first (network byte order). + +``` +0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| 32_bit_uint_time_high | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| 16_bit_uint_time_low | 16_bit_uint_random | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| 32_bit_uint_random | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| 32_bit_uint_random | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` From 4406c980852842cdf5793c82095f70094905e89c Mon Sep 17 00:00:00 2001 From: JMARyA Date: Tue, 8 Apr 2025 11:08:57 +0200 Subject: [PATCH 14/41] =?UTF-8?q?=E2=9C=A8=20add=20rustscript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applications/development/rust-script.md | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 technology/applications/development/rust-script.md diff --git a/technology/applications/development/rust-script.md b/technology/applications/development/rust-script.md new file mode 100644 index 0000000..245b24f --- /dev/null +++ b/technology/applications/development/rust-script.md @@ -0,0 +1,127 @@ +--- +obj: application +repo: https://github.com/fornwall/rust-script +website: https://rust-script.org +--- + +# RustScript +With rust-script Rust files and expressions can be executed just like a shell or Python script. Features include: +- Caching compiled artifacts for speed. +- Reading Cargo manifests embedded in Rust scripts. +- Supporting executable Rust scripts via Unix shebangs and Windows file associations. +- Using expressions as stream filters (i.e. for use in command pipelines). +- Running unit tests and benchmarks from scripts. + +## Scripts +The primary use for rust-script is for running Rust source files as scripts. For example: + +``` +$ echo 'println!("Hello, World!");' > hello.rs +$ rust-script hello.rs +Hello, World! +``` + +Under the hood, a Cargo project will be generated and built (with the Cargo output hidden unless compilation fails or the `-c/--cargo-output` option is used). The first invocation of the script will be slower as the script is compiled - subsequent invocations of unmodified scripts will be fast as the built executable is cached. + +As seen from the above example, using a `fn main() {}` function is not required. If not present, the script file will be wrapped in a `fn main() { ... }` block. + +rust-script will look for embedded dependency and manifest information in the script as shown by the below two equivalent `now.rs` variants: + +```rust +#!/usr/bin/env rust-script +//! This is a regular crate doc comment, but it also contains a partial +//! Cargo manifest. Note the use of a *fenced* code block, and the +//! `cargo` "language". +//! +//! ```cargo +//! [dependencies] +//! time = "0.1.25" +//! ``` +fn main() { + println!("{}", time::now().rfc822z()); +} +``` + +```rust +// cargo-deps: time="0.1.25" +// You can also leave off the version number, in which case, it's assumed +// to be "*". Also, the `cargo-deps` comment *must* be a single-line +// comment, and it *must* be the first thing in the file, after the +// shebang. +// Multiple dependencies should be separated by commas: +// cargo-deps: time="0.1.25", libc="0.2.5" +fn main() { + println!("{}", time::now().rfc822z()); +} +``` + +The output from running one of the above scripts may look something like: + +``` +$ rust-script now +Wed, 28 Oct 2020 00:38:45 +0100 +``` + +## Useful command-line arguments: + +- `--bench`: Compile and run benchmarks. Requires a nightly toolchain. +- `--debug`: Build a debug executable, not an optimised one. +- `--force`: Force the script to be rebuilt. Useful if you want to force a recompile with a different toolchain. +- `--package`: Generate the Cargo package and print the path to it - but don’t compile or run it. Effectively “unpacks” the script into a Cargo package. +- `--test`: Compile and run tests. +- `--wrapper`: Add a wrapper around the executable. Can be used to run debugging with e.g. `rust-script --debug --wrapper rust-lldb my-script.rs` or benchmarking with `rust-script --wrapper "hyperfine --runs 100" my-script.rs` + +## Executable Scripts +On Unix systems, you can use `#!/usr/bin/env rust-script` as a shebang line in a Rust script. This will allow you to execute a script files (which don’t need to have the `.rs` file extension) directly. + +If you are using Windows, you can associate the `.ers` extension (executable Rust - a renamed `.rs` file) with rust-script. This allows you to execute Rust scripts simply by naming them like any other executable or script. + +This can be done using the `rust-script --install-file-association` command. Uninstall the file association with `rust-script --uninstall-file-association`. + +If you want to make a script usable across platforms, use both a shebang line and give the file a `.ers` file extension. + +## Expressions +Using the `-e/--expr` option a Rust expression can be evaluated directly, with dependencies (if any) added using `-d/--dep`: + +``` +$ rust-script -e '1+2' +3 +$ rust-script --dep time --expr "time::OffsetDateTime::now_utc().format(time::Format::Rfc3339).to_string()"` +"2020-10-28T11:42:10+00:00" +$ # Use a specific version of the time crate (instead of default latest): +$ rust-script --dep time=0.1.38 -e "time::now().rfc822z().to_string()" +"2020-10-28T11:42:10+00:00" +``` + +The code given is embedded into a block expression, evaluated, and printed out using the Debug formatter (i.e. `{:?}`). + +## Filters +You can use rust-script to write a quick filter, by specifying a closure to be called for each line read from stdin, like so: + +``` +$ cat now.ers | rust-script --loop \ + "let mut n=0; move |l| {n+=1; println!(\"{:>6}: {}\",n,l.trim_end())}" + 1: // cargo-deps: time="0.1.25" + 3: fn main() { + 4: println!("{}", time::now().rfc822z()); + 5: } +``` + +You can achieve a similar effect to the above by using the `--count` flag, which causes the line number to be passed as a second argument to your closure: + +``` +$ cat now.ers | rust-script --count --loop \ + "|l,n| println!(\"{:>6}: {}\", n, l.trim_end())" + 1: // cargo-deps: time="0.1.25" + 2: fn main() { + 3: println!("{}", time::now().rfc822z()); + 4: } +``` + +## Environment Variables +The following environment variables are provided to scripts by rust-script: + +- `$RUST_SCRIPT_BASE_PATH`: the base path used by rust-script to resolve relative dependency paths. Note that this is not necessarily the same as either the working directory, or the directory in which the script is being compiled. +- `$RUST_SCRIPT_PKG_NAME`: the generated package name of the script. +- `$RUST_SCRIPT_SAFE_NAME`: the file name of the script (sans file extension) being run. For scripts, this is derived from the script’s filename. May also be `expr` or `loop` for those invocations. +- `$RUST_SCRIPT_PATH`: absolute path to the script being run, assuming one exists. Set to the empty string for expressions. From b45b4f651985ea0ca781cb3b4bd10616cb3a4cec Mon Sep 17 00:00:00 2001 From: JMARyA Date: Tue, 8 Apr 2025 19:01:28 +0200 Subject: [PATCH 15/41] fix --- technology/applications/cli/intermodal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/technology/applications/cli/intermodal.md b/technology/applications/cli/intermodal.md index d322d70..14dc5b8 100644 --- a/technology/applications/cli/intermodal.md +++ b/technology/applications/cli/intermodal.md @@ -1,7 +1,7 @@ --- obj: application repo: https://github.com/casey/intermodal -website: imdl.io +website: https://imdl.io rev: 2025-01-28 --- From 104e3ba3f385b244de4fd2872a5161bb4025bfe8 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 24 Apr 2025 13:50:34 +0200 Subject: [PATCH 16/41] update rust --- technology/dev/programming/languages/Rust.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/technology/dev/programming/languages/Rust.md b/technology/dev/programming/languages/Rust.md index 108a840..d48ac54 100644 --- a/technology/dev/programming/languages/Rust.md +++ b/technology/dev/programming/languages/Rust.md @@ -231,6 +231,8 @@ fn do_something() { } ``` +> **Note**: If you ever need to guard your code from an overly aggressive `cargo fmt`, you can annotate it with `#[rustfmt::skip]` + ### Modules You can split your code up into multiple modules for better organization. ```rust @@ -1009,6 +1011,9 @@ Currently, all supported targets follow the assembly code syntax used by LLVM's - [serde_json](https://lib.rs/crates/serde_json): A [JSON](../../../files/JSON.md) serialization file format - [serde_jsonc](https://lib.rs/crates/serde_jsonc): A JSON serialization file format - [serde_yaml](https://lib.rs/crates/serde_yaml): [YAML](../../../files/YAML.md) data format for Serde +- [rmp_serde](https://lib.rs/crates/rmp-serde): MsgPack format for serde +- [rmpv](https://lib.rs/crates/rmpv): MsgPack value variants (`serde_json::Value` for MsgPack) +- [rmp](https://lib.rs/crates/rmp): low level msgpack implementation - [bson](https://lib.rs/crates/bson): Encoding and decoding support for [BSON](../../../files/BSON.md) in Rust - [toml](https://lib.rs/crates/toml): A native Rust encoder and decoder of [TOML](../../../files/TOML.md)-formatted files and streams. - [gray_matter](https://lib.rs/crates/gray_matter): Smart front matter parser. An implementation of gray-matter in rust. Parses YAML, JSON, TOML and support for custom parsers. From c9d9127160adc53453f891d4573a3574b2c4d222 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 24 Apr 2025 14:14:10 +0200 Subject: [PATCH 17/41] add dualsensectl --- .../applications/gaming/dualsensectl.md | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 technology/applications/gaming/dualsensectl.md diff --git a/technology/applications/gaming/dualsensectl.md b/technology/applications/gaming/dualsensectl.md new file mode 100644 index 0000000..b6ed5d8 --- /dev/null +++ b/technology/applications/gaming/dualsensectl.md @@ -0,0 +1,47 @@ +--- +obj: application +repo: https://github.com/nowrep/dualsensectl +--- + +# dualsensectl + +Linux tool for controlling Sony PlayStation 5 DualSense controller. + +## Usage + +Usage: `dualsensectl [options] command [ARGS]` + +### Options + +| Option | Description | +| ----------- | ------------------------------------------------- | +| `-l` | List available devices | +| `-d DEVICE` | Specify which device to use | +| `-w` | Wait for shell command to complete (monitor only) | + +### Commands + +Available Commands: + +- `power-off`: Turn off the controller (BT only), +- `battery`: Get the controller battery level, +- `info`: Get the controller firmware info, +- `lightbar STATE`: Enable (on) or disable (off) lightbar, +- `lightbar RED GREEN BLUE [BRIGHTNESS]`: Set lightbar color and brightness (0-255), +- `player-leds NUMBER`: Set player LEDs (1-5) or disabled (0), +- `microphone STATE`: Enable (on) or disable (off) microphone, +- `microphone-led STATE`: Enable (on) or disable (off) microphone LED, +- `speaker STATE`: Toggle to `internal` speaker, `headphone` or both, +- `volume VOLUME`: Set audio volume (0-255) of internal speaker and headphone, +- `attenuation RUMBLE TRIGGER`: Set the attenuation (0-7) of rumble/haptic motors and trigger vibration, +- `trigger TRIGGER off`: Remove all effects, +- `trigger TRIGGER feedback POSITION STRENGTH`: Set a resistance starting at position with a defined strength, +- `trigger TRIGGER weapon START STOP STRENGTH`: Emulate weapon like gun trigger, +- `trigger TRIGGER bow START STOP STRENGTH SNAPFORCE`: Emulate weapon like bow, +- `trigger TRIGGER galloping START STOP FIRST_FOOT SECOND_FOOT FREQUENCY`: Emulate a galloping, +- `trigger TRIGGER machine START STOP STRENGTH_A STRENGTH_B FREQUENCY PERIOD`: Switch vibration between two strengths at a specified period, +- `trigger TRIGGER vibration POSITION AMPLITUDE FREQUENCY`: Vibrates motor arm around specified position, +- `trigger TRIGGER feedback-raw STRENGTH[10]`: Set a resistance starting using an array of strength, +- `trigger TRIGGER vibration-raw AMPLITUDE[10] FREQUENCY`: Vibrates motor arm at position and strength specified by an array of amplitude, +- `trigger TRIGGER MODE [PARAMS]`: Set the trigger (left, right or both) mode with parameters (up to 9), +- `monitor [add COMMAND] [remove COMMAND]`: Run shell command COMMAND on add/remove events. From 915644451b3e03bfaab18706f55cb876ae3effbb Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 24 Apr 2025 14:14:45 +0200 Subject: [PATCH 18/41] update pacman --- .../applications/package managers/arch-linux/Pacman.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/technology/applications/package managers/arch-linux/Pacman.md b/technology/applications/package managers/arch-linux/Pacman.md index bbaa46e..8795451 100644 --- a/technology/applications/package managers/arch-linux/Pacman.md +++ b/technology/applications/package managers/arch-linux/Pacman.md @@ -36,6 +36,14 @@ pacman -Rcs ... Get information about package: ```shell pacman -Si ... + +# Local +pacman -Qi ... +``` + +List all packages from a reposity: +```shell +pacman -Sl ``` Install a package from local package file (.[tar](../../cli/compression/tar.md).[xz](../../../files/XZ%20Compression.md)): From 1cd71457dd7391231b65e7efa51a9da4ab1a5f56 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 24 Apr 2025 14:15:55 +0200 Subject: [PATCH 19/41] update ha --- technology/applications/web/Home Assistant.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/technology/applications/web/Home Assistant.md b/technology/applications/web/Home Assistant.md index 92eb884..bc90bec 100644 --- a/technology/applications/web/Home Assistant.md +++ b/technology/applications/web/Home Assistant.md @@ -54,3 +54,6 @@ services: restart: always network_mode: host ``` + +## Extensions +- [Mushroom Cards](https://github.com/piitaya/lovelace-mushroom) From 09ace3edede211dc73e44bcc3de59885ebecc59f Mon Sep 17 00:00:00 2001 From: JMARyA Date: Thu, 24 Apr 2025 14:16:58 +0200 Subject: [PATCH 20/41] add systeroid --- .../applications/utilities/systeroid.md | 357 ++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 technology/applications/utilities/systeroid.md diff --git a/technology/applications/utilities/systeroid.md b/technology/applications/utilities/systeroid.md new file mode 100644 index 0000000..b0d9d39 --- /dev/null +++ b/technology/applications/utilities/systeroid.md @@ -0,0 +1,357 @@ +--- +obj: application +repo: https://github.com/orhun/systeroid +rev: 2025-02-07 +--- + +# systeroid +`sysctl` is a utility on Unix-like operating systems that is used to read and modify the attributes of the kernel such as its version number, maximum limits, and security settings. **systeroid** is "_sysctl on steroids_". It can do everything that sysctl does and even more. It provides a safer, more performant, and user-friendly CLI/TUI for managing the kernel parameters at runtime. + +Although **systeroid** does not need the parameter section to be specified explicitly, it is important to know the sections and their areas of impact. Here are the available kernel sections according to the [Linux kernel documentation](https://www.kernel.org/doc/html/latest/admin-guide/sysctl/index.html): + +| Section | Path | Description | +| ---------- | ------------------- | ------------------------------------------------------------- | +| **abi** | `/proc/sys/abi/` | execution domains & personalities | +| **fs** | `/proc/sys/fs/` | filesystem settings | +| **kernel** | `/proc/sys/kernel/` | global kernel information / miscellaneous settings | +| **net** | `/proc/sys/net/` | networking settings | +| **sunrpc** | `/proc/sys/sunrpc/` | SUN Remote Procedure Call settings | +| **user** | `/proc/sys/user/` | user namespace limits | +| **vm** | `/proc/sys/vm/` | memory management tuning buffer and cache management settings | +| **dev** | `/proc/sys/dev/` | device specific information | +| **debug** | `/proc/sys/debug/` | - | + + +## Usage +``` +systeroid [options] [variable[=value] ...] --load[=] +``` + +### Options +| Option | Description | +| ---------------------- | -------------------------------------------- | +| `-a, --all` | display all variables | +| `-T, --tree` | display the variables in a tree-like format | +| `-J, --json` | display the variables in JSON format | +| `--deprecated` | include deprecated variables while listing | +| `-e, --ignore` | ignore unknown variable errors | +| `-N, --names` | print only variable names | +| `-n, --values` | print only variable values | +| `-b, --binary` | print only variable values without new line | +| `-p, --load` | read values from file | +| `-S, --system` | read values from all system directories | +| `-r, --pattern ` | use a regex for matching variable names | +| `-q, --quiet` | do not print variable after the value is set | +| `-w, --write` | only enable writing a value to variable | +| `-E, --explain` | provide a detailed explanation for variable | +| `-D, --docs ` | set the path of the kernel documentation | +| `-P, --no-pager` | do not pipe output into a pager | +| `-v, --verbose` | enable verbose logging | +| `--tui` | show terminal user interface | +| `-c, --config ` | set the path of the configuration file | + +Most of the arguments/flags are inherited from `sysctl` so they have the same functionality. + +### Examples + +#### Listing parameters + +```sh +# list all parameters +systeroid -A + +# list parameters in a tree-like format +systeroid -T + +# list parameters in JSON format +systeroid -J +``` + +#### Filtering by section + +```sh +# only list parameters in the "kernel" section +systeroid kernel + +# only list parameters in the "vm" and "user" sections +systeroid vm user +``` + +#### Displaying values + +```sh +# print the name and value of a parameter (in "name=value" format) +systeroid kernel.hostname + +# print only the value of a parameter +systeroid -n kernel.hostname + +# print the name and values of the multiple parameters +systeroid kernel.hostname user.max_user_namespaces +``` + +#### Setting values + +```sh +# set the value of a parameter +systeroid kernel.domainname="example.com" + +# set the values of multiple parameters and ignore errors +systeroid -e kernel.dmesg_restrict=0 vm.panic_on_oom=1 unknown_param="test" + +# set the values of multiple parameters and enforce the "name=value" format +systeroid -w fs.dir-notify-enable=1 net.mptcp.enabled=1 vm.oom_kill_allocating_task +``` + +#### Loading values from a file +Parameter values can be set from an [INI file](https://en.wikipedia.org/wiki/INI_file). + +`sysctl.conf`: + +```ini +# Use kernel.sysrq = 1 to allow all keys. +# See https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html for a list +# of values and keys. +kernel.sysrq = 16 + +# Append the PID to the core filename +kernel.core_uses_pid = 1 + +; Enable hard and soft link protection +; (If a line begins with a single '-', any attempts to set the value that fail will be ignored.) +-fs.protected_hardlinks = 1 +fs.protected_symlinks = 1 +``` + +To load it: + +```sh +systeroid --load sysctl.conf +``` + +If no file is given, values are loaded from `/etc/sysctl.conf` as default: + +```sh +systeroid --load +``` + +Specifying "-" as file name means reading data from standard input: + +```sh +systeroid --load - +``` + +#### Loading values from the system directories + +The list of default system directories are the following: + +- `/etc/sysctl.d` +- `/run/sysctl.d` +- `/usr/local/lib/sysctl.d` +- `/usr/lib/sysctl.d` +- `/lib/sysctl.d` +- `/etc/sysctl.conf` + +Use `--system` flag to load the files with `.conf` extension in these directories: + +```sh +systeroid --system +``` + +#### Searching parameters + +```sh +# search parameters using regex patterns +systeroid -r 'net.ipv4.conf.(eth|wlan)0.arp' +systeroid -r '^net.ipv6' +``` + +Example output of combining search with listing: + +```sh +$ systeroid --names --pattern 'kernel.*_max$' --tree + +kernel +├── ngroups_max +├── pid_max +└── sched_util_clamp_max +``` + +#### Showing information about parameters + +**systeroid** can dump the parameter information from the kernel documentation. This is useful if you don't know what a parameter is used for. + +```sh +# show information about a parameter +systeroid --explain oom_dump_tasks +``` + +Kernel documentation should be present in one of the following paths for parsing upon first launch: + +- `/usr/share/doc/linux` +- `/usr/share/doc/linux-doc` +- `/usr/share/doc/linux-docs` +- `/usr/share/doc/kernel-doc-*/Documentation` + +Then the parsed data is cached in `$HOME/.cache/systeroid-core` and used from there as long as the documentation is not updated. The caching mechanism can be disabled via setting the `NO_CACHE` environment variable. + +This is a design choice due to the fact that different versions of kernels might be installed on different systems so the documentation might be too new or old if **systeroid** was to be shipped with a fixed set of parameter descriptions bundled in. With the parsing approach, documentation is always kept up-to-date. + +However, this means you need to: + +- either install the kernel documentation package (based on your distribution) + - on Arch Linux: `pacman -S linux-docs` + - on Debian/Ubuntu: `apt-get install linux-doc` + - on Fedora: `dnf install kernel-doc` +- or explicitly specify the path of the [kernel documentation](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide). + +```sh +# specify the kernel documentation path explicitly +# (not needed if you have the kernel documentation installed as a package) +systeroid -E user.max_user_namespaces --docs /usr/share/doc/linux +``` + +To change the default pager (`less(1)`), you can use the `PAGER` environment variable. Also, you can simply use `--no-pager` flag to disable it. + +```sh +systeroid -E kernel.ctrl-alt-del --no-pager +``` + +It is also possible to retrieve information about multiple parameters: + +```sh +systeroid -E --pattern '.*ipv4.*' --no-pager +``` + +#### Verbose logging + +`--verbose` flag can be used to enable verbose logging: + +```sh +systeroid --verbose +``` + +Also, `RUST_LOG` environment variable can be set accordingly to filter based on different log levels. + +```sh +RUST_LOG=trace systeroid +``` + +## TUI + +### Usage + +``` +systeroid-tui [options] +``` + +### Key Bindings + +| Key | Action | +| ---------------------------------------------------------- | ---------------------------- | +| ?, f1 | show help | +| up/down, k/j, pgup/pgdown | scroll list | +| t/b | scroll to top/bottom | +| left/right, h/l | scroll documentation | +| tab, ` | next/previous section | +| : | command | +| / | search | +| enter | select / set parameter value | +| s | save parameter value | +| c | copy to clipboard | +| ctrl-l, f2 | show logs | +| r, f5 | refresh | +| esc | cancel / exit | +| q, ctrl-c/ctrl-d | exit | + +## Configuration +**systeroid** can be configured with a configuration file that uses the [INI format](https://en.wikipedia.org/wiki/INI_file). It can be specified via `--config` or `SYSTEROID_CONFIG` environment variable. It can also be placed in one of the following global locations: + +- `$HOME/.config/systeroid/systeroid.conf` +- `$HOME/.systeroid/systeroid.conf` + +```sh +# set the config path via argument +systeroid --config config/systeroid.conf + +# set the config path via env +SYSTEROID_CONFIG=config/systeroid.conf systeroid + +# use a global path +mkdir -p "$HOME/.config/systeroid" +cp config/systeroid.conf "$HOME/.config/systeroid" +systeroid +``` + +See the example systeroid.conf for the configuration options: + +```ini +; systeroid ~ configuration file +; https://github.com/orhun/systeroid +; +; Each line either contains a comment or a command line argument grouped under a section. +; Run "systeroid --help" or "systeroid-tui --help" to get a list of all possible configuration options. + +[general] +; display the deprecated parameters such as base_reachable_time and retrans_time while listing +; See https://bugzilla.redhat.com/show_bug.cgi?id=152435 +display_deprecated = false +; path of the Linux kernel documentation +; this is distro dependent, systeroid checks the following locations as default: +; - /usr/share/doc/linux/ +; - /usr/share/doc/linux-doc/ +; - /usr/share/doc/linux-docs/ +; - /usr/share/doc/kernel-doc-*/Documentation/ +kernel_docs = "/usr/share/doc/linux" + +[cli] +; ignore unknown variable errors +ignore_errors = true +; do not print variable after the value is set +quiet = false +; do not pipe output into a pager +; note that the default pager is less(1) and you can change it by using `PAGER` environment variable +no_pager = false +; display type for the parameter, available options are: +; - default: print the parameter name along with its value +; - name: print only the name of the parameter +; - value: print only the value of the parameter +; - binary: print only the value of the parameter without new line +display_type = "default" +; output type for the list, available options are: +; - default: print the output as is +; - tree: print the output in a tree-like format +; - json: print the output in JSON format +output_type = "default" + +[cli.colors] +; available colors are defined in https://docs.rs/owo-colors/latest/owo_colors/colored/enum.Color.html +; default color for the symbols +default_color = "bright black" +; section colors +section_abi = "red" +section_fs = "green" +section_kernel = "magenta" +section_net = "blue" +section_sunrpc = "yellow" +section_user = "cyan" +section_vm = "bright red" +section_unknown = "white" + +[tui] +; tick rate of the terminal +tick_rate = 250 +; disable showing the parameter documentation +no_docs = true +; path for saving the changed kernel parameters +save_path = "/etc/sysctl.conf" +; file to save the logs +;log_file = "systeroid.log" + +[tui.colors] +; available colors are defined in https://docs.rs/tui/latest/tui/style/enum.Color.html +; terminal foreground color +fg_color = "white" +; terminal background color +bg_color = "black" +``` From 9639ae7add6c969de043a790b3d2dc7ba06517ff Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 25 Apr 2025 14:17:09 +0200 Subject: [PATCH 21/41] add onefetch --- .../applications/development/onefetch.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 technology/applications/development/onefetch.md diff --git a/technology/applications/development/onefetch.md b/technology/applications/development/onefetch.md new file mode 100644 index 0000000..9e68d43 --- /dev/null +++ b/technology/applications/development/onefetch.md @@ -0,0 +1,52 @@ +--- +obj: application +repo: https://github.com/o2sh/onefetch +rev: 2025-02-07 +--- + +# onefetch +Onefetch is a command-line Git information tool written in Rust that displays project information and code statistics for a local Git repository directly to your terminal. The tool is completely offline - no network access is required. + +By default, the repo's information is displayed alongside the dominant language's logo, but you can further configure onefetch to instead use an image - on supported terminals -, a text input or nothing at all. + +It automatically detects open source licenses from texts and provides the user with valuable information like code distribution, pending changes, number of dependencies (by package manager), top contributors (by number of commits), size on disk, creation date, LOC (lines of code), etc. + +Onefetch can be configured via command-line flags to display exactly what you want, the way you want it to: you can customize ASCII/Text formatting, disable info lines, ignore files & directories, output in multiple formats, etc. + +## Usage +Usage: `onefetch [OPTIONS] [INPUT]` + +| Option | Description | +| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-d`, `--disabled-fields ...` | Allows you to disable FIELD(s) from appearing in the output | +| `--no-title` | Hides the title | +| `--number-of-authors ` | Maximum NUM of authors to be shown [default: 3] | +| `--number-of-languages ` | Maximum NUM of languages to be shown [default: 6] | +| `--number-of-file-churns ` | Maximum NUM of file churns to be shown [default: 3] | +| `--churn-pool-size ` | Minimum NUM of commits from HEAD used to compute the churn summary. By default, the value is non-deterministic due to time-based computation and will be displayed under the info title "Churn (NUM)" | +| `-e`, `--exclude ...` | Ignore all files & directories matching EXCLUDE | +| `--no-bots[=]` | Exclude bot commits. Use `` to override the default pattern | +| `--no-merges` | Ignores merge commits | +| `-E`, `--email` | Show the email address of each author | +| `--http-url` | Display repository URL as HTTP | +| `--hide-token` | Hide token in repository URL | +| `--include-hidden` | Count hidden files and directories | +| `-T`, `--type ...` | Filters output by language type [default: programming markup] [possible values: programming, markup, prose, data] | +| `-t`, `--text-colors ...` | Changes the text colors (X X X...). Goes in order of title, ~, underline, subtitle, colon, and info | +| `-z`, `--iso-time` | Use ISO 8601 formatted timestamps | +| `--number-separator ` | Which thousands SEPARATOR to use [default: plain] [possible values: plain, comma, space, underscore] | +| `--no-bold` | Turns off bold formatting | +| `--ascii-input ` | Takes a non-empty STRING as input to replace the ASCII logo | +| `-c`, `--ascii-colors ...` | Colors (X X X...) to print the ascii art | +| `-a`, `--ascii-language ` | Which LANGUAGE's ascii art to print | +| `--true-color ` | Specify when to use true color [default: auto] [possible values: auto, never, always] | +| `-i`, `--image ` | Path to the IMAGE file | +| `--image-protocol ` | Which image PROTOCOL to use [possible values: kitty, sixel, iterm] | +| `--color-resolution ` | VALUE of color resolution to use with SIXEL backend [default: 16] [possible values: 16, 32, 64, 128, 256] | +| `--no-color-palette` | Hides the color palette | +| `--no-art` | Hides the ascii art or image if provided | +| `--nerd-fonts` | Use Nerd Font icons. Replaces language chips with Nerd Font icons | +| `-o`, `--output ` | Outputs Onefetch in a specific format [possible values: json, yaml] | +| `--generate ` | If provided, outputs the completion file for given SHELL [possible values: bash, elvish, fish, powershell, zsh] | +| `-l`, `--languages` | Prints out supported languages | +| `-p`, `--package-managers` | Prints out supported package managers | From 8212f6595725c4786afca5afc21de048f1033e2b Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 2 May 2025 13:21:07 +0200 Subject: [PATCH 22/41] update rust crypto crates --- technology/dev/programming/languages/Rust.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/technology/dev/programming/languages/Rust.md b/technology/dev/programming/languages/Rust.md index d48ac54..27ed117 100644 --- a/technology/dev/programming/languages/Rust.md +++ b/technology/dev/programming/languages/Rust.md @@ -1062,6 +1062,8 @@ Currently, all supported targets follow the assembly code syntax used by LLVM's - [redact](https://lib.rs/crates/redact): A simple library for keeping secrets out of logs - [noise](https://lib.rs/crates/noise): Procedural noise generation library - [ulid](https://lib.rs/crates/ulid): a Universally Unique Lexicographically Sortable Identifier implementation +- [age](https://crates.io/crates/age): A simple, secure, and modern encryption library. +- [minisign](https://crates.io/crates/minisign): A crate to sign files and verify signatures. #### Hashes - [digest](https://lib.rs/crates/digest): Traits for cryptographic hash functions and message authentication codes From 8386d56c383ce2e827e098bf728c01b40f757ef0 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 2 May 2025 13:21:30 +0200 Subject: [PATCH 23/41] add minisign --- technology/cryptography/minisign.md | 139 ++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 technology/cryptography/minisign.md diff --git a/technology/cryptography/minisign.md b/technology/cryptography/minisign.md new file mode 100644 index 0000000..9d3ff90 --- /dev/null +++ b/technology/cryptography/minisign.md @@ -0,0 +1,139 @@ +--- +obj: application +website: https://jedisct1.github.io/minisign +repo: https://github.com/jedisct1/minisign +--- + +# minisign +Minisign is a dead simple tool to sign files and verify signatures. There is also an [implementation in Rust](https://github.com/jedisct1/rsign2). +It is portable, lightweight, and uses the highly secure Ed25519 public-key signature system. + +## Creating a key pair +```shell +$ minisign -G +``` + +The public key is printed and put into the `minisign.pub` file. The secret key is encrypted and saved as a file named `~/.minisign/minisign.key`. + +## Signing a file +```shell +$ minisign -Sm myfile.txt +``` + +Or to include a comment in the signature, that will be verified and displayed when verifying the file: +```shell +$ minisign -Sm myfile.txt -t 'This comment will be signed as well' +``` + +The signature is put into `myfile.txt.minisig`. + +Multiple files can also be signed at once: +```shell +$ minisign -Sm file1.txt file2.txt *.jpg +``` + +## Verifying a file +```shell +$ minisign -Vm myfile.txt -P RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3 +``` + +or + +```shell +$ minisign -Vm myfile.txt -p signature.pub +``` + +This requires the signature `myfile.txt.minisig` to be present in the same directory. + +The public key can either reside in a file (`./minisign.pub` by default) or be directly specified on the command line. + +## Usage +``` +Usage: +minisign -G [-f] [-p pubkey_file] [-s seckey_file] [-W] +minisign -R [-s seckey_file] [-p pubkey_file] +minisign -C [-s seckey_file] [-W] +minisign -S [-l] [-x sig_file] [-s seckey_file] [-c untrusted_comment] [-t trusted_comment] -m file [file ...] +minisign -V [-H] [-x sig_file] [-p pubkey_file | -P pubkey] [-o] [-q] -m file +``` + +| Option | Description | +|--------------|-----------------------------------------------------------------------| +| `-G` | Generate a new key pair | +| `-R` | Recreate a public key file from a secret key file | +| `-C` | Change/remove the password of the secret key | +| `-S` | Sign files | +| `-V` | Verify that a signature is valid for a given file | +| `-H` | Require input to be prehashed | +| `-l` | Sign using the legacy format | +| `-m ` | File to sign/verify | +| `-o` | Combined with `-V`, output the file content after verification | +| `-p ` | Public key file (default: `./minisign.pub`) | +| `-P `| Public key, as a base64 string | +| `-s ` | Secret key file (default: `~/.minisign/minisign.key`) | +| `-W` | Do not encrypt/decrypt the secret key with a password | +| `-x `| Signature file (default: `.minisig`) | +| `-c `| Add a one-line untrusted comment | +| `-t `| Add a one-line trusted comment | +| `-q` | Quiet mode, suppress output | +| `-Q` | Pretty quiet mode, only print the trusted comment | +| `-f` | Force. Combined with `-G`, overwrite a previous key pair | +| `-v` | Display version number | + +### Trusted comments +Signature files include an untrusted comment line that can be freely modified even after the signature is created. + +They also include a second comment line that cannot be modified without the secret key. + +Trusted comments can be used to add instructions or application-specific metadata such as the intended file name, timestamps, resource identifiers, or version numbers to prevent downgrade attacks. + +OpenBSD's signify is conceptually similar to Minisign. + +Minisign creates signatures that can be verified by signify; however, signatures created by signify cannot be verified with Minisign because Minisign expects a trusted comment section to be present. +Trusted comments are crucial for describing what has been signed, in addition to merely confirming that a signature exists. + +## Signature format +``` +untrusted comment: +base64( || || ) +trusted_comment: +base64() +``` + +- `signature_algorithm`: `Ed` (legacy) or `ED` (hashed) +- `key_id`: 8 random bytes, matching the public key +- `signature` (legacy): `ed25519()` +- `signature` (prehashed): `ed25519(Blake2b-512())` +- `global_signature`: `ed25519( || )` + +New implementations must use the hashed signature format; support for the legacy one is optional and should not be done by default. + +## Public key format +``` +untrusted comment: +base64( || || ) +``` + +- `signature_algorithm`: `Ed` +- `key_id`: 8 random bytes +- `public_key`: Ed25519 public key + + +## Secret key format +``` +untrusted comment: +base64( || || || + || || || ) +``` + +- `signature_algorithm`: `Ed` +- `kdf_algorithm`: `Sc` +- `cksum_algorithm`: `B2` +- `kdf_salt`: 32 random bytes +- `kdf_opslimit`: `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE` +- `kdf_memlimit`: `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE` +- `keynum_sk`: ` ^ ( || || || )`, 104 bytes +- `key_id`: 8 random bytes +- `secret_key`: Ed25519 secret key +- `public_key`: Ed25519 public key +- `checksum`: `Blake2b-256( || || || )`, 32 bytes From 9a062cbfed2ec792392f6052d1a3df273b5e16b1 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 2 May 2025 13:25:35 +0200 Subject: [PATCH 24/41] add panamax --- technology/applications/web/panamax.md | 136 +++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 technology/applications/web/panamax.md diff --git a/technology/applications/web/panamax.md b/technology/applications/web/panamax.md new file mode 100644 index 0000000..021be1e --- /dev/null +++ b/technology/applications/web/panamax.md @@ -0,0 +1,136 @@ +--- +obj: application +repo: https://github.com/panamax-rs/panamax +--- + +# Panamax +Panamax is a tool to mirror the Rust and crates.io repositories, for offline usage of `rustup` and `cargo`. + +## Usage +## Docker +Panamax is available as a docker image, so you can run: + +``` +$ docker run --rm -it -v /path/to/mirror/:/mirror --user $(id -u) panamaxrs/panamax init /mirror +(Modify /path/to/mirror/mirror.toml as needed) +$ docker run --rm -it -v /path/to/mirror/:/mirror --user $(id -u) panamaxrs/panamax sync /mirror +(Once synced, serve the mirror) +$ docker run --rm -it -v /path/to/mirror/:/mirror --user $(id -u) -p8080:8080 panamaxrs/panamax serve /mirror +``` + +Alternatively, you can run panamax in a bare-metal environment like below. + +### Init +In Panamax, mirrors consist of self-contained directories. To create a mirror directory `my-mirror`: + +``` +$ panamax init my-mirror +Successfully created mirror base at `my-mirror`. +Make any desired changes to my-mirror/mirror.toml, then run panamax sync my-mirror. +``` + +There will now be a `my-mirror` directory in your current directory. + +### Modify mirror.toml +Within the directory, you'll find a `mirror.toml` file. This file contains the full configuration of the mirror, and while it has sane defaults, you should ensure the values are set to what you want. + +The other important parameter to set is the `base_url` within the `[crates]` section. After `cargo` fetches the index, it will try to use this URL to actually download the crates. It's important this value is accurate, or `cargo` may not work with the mirror. + +You can modify `mirror.toml` at any point in time, even after the mirror is synchronized. + +### Sync +Once you have made the changes to `mirror.toml`, it is time to synchronize your mirror! + +``` +$ panamax sync my-mirror +Syncing Rustup repositories... +[1/5] Syncing rustup-init files... ██████████████████████████████████████████████████████████████ 27/27 [00:00:06] +[2/5] Syncing latest stable... ████████████████████████████████████████████████████████████ 602/602 [00:09:02] +[3/5] Syncing latest beta... ████████████████████████████████████████████████████████████ 524/524 [00:07:29] +[4/5] Syncing latest nightly... ████████████████████████████████████████████████████████████ 546/546 [00:08:56] +[5/5] Cleaning old files... ████████████████████████████████████████████████████████████ 546/546 [00:00:00] +Syncing Rustup repositories complete! +Syncing Crates repositories... +[1/3] Fetching crates.io-index... ██████████████████████████████████████████████████████████ 1615/1615 [00:00:02] +[2/3] Syncing crates files... ██████████████████████████████████████████████████████████ 6357/6357 [00:00:05] +[3/3] Syncing index and config... +Syncing Crates repositories complete! +Sync complete. +``` + +Once this is step completes (without download errors), you will now have a full, synchronized copy of all the files needed to use `rustup` and `cargo` to their full potential! + +This directory can now be copied to a USB or rsync'd somewhere else, or even used in place - perfect for long plane trips! + +Additionally, this mirror can continually by synchronized in the future - one recommendation is to run this command in a cronjob once each night, to keep the mirror reasonably up to date. + +### Sync Select Dependencies +Optionally, panamax can be told to only grab crates needed to build a singular project. +`cargo vendor` is used to create a folder with all needed dependencies, +then a panamax command can parse the created directory and only grab those crates and versions. +``` +# Only grab crates needed for panamax, as an example +$ cargo vendor +$ panamax sync my-mirror vendor +``` + +## Server +Panamax provides a warp-based HTTP(S) server that can handle serving a Rust mirror fast and at scale. This is the recommended way to serve the mirror. + +``` +$ panamax serve my-mirror +Running HTTP on [::]:8080 +``` + +The server's index page provides all the instructions needed on how to set up a Rust client that uses this mirror. + +If you would prefer having these instructions elsewhere, the rest of this README will describe the setup process in more detail. + +Additionally, if you would prefer hosting a server with nginx, there is a sample nginx configuration in the repository, at `nginx.sample.conf`. + +## Configuring `rustup` and `cargo` +Once you have a mirror server set up and running, it's time to tell your Rust components to use it. + +### Setting environment variables +In order to ensure `rustup` knows where to look for the Rust components, we need to set some environment variables. Assuming the mirror is hosted at http://panamax.internal/: + +``` +export RUSTUP_DIST_SERVER=http://panamax.internal +export RUSTUP_UPDATE_ROOT=http://panamax.internal/rustup +``` + +These need to be set whenever `rustup` is used, so these should be added to your `.bashrc` file (or equivalent). + +### Installing `rustup` +If you already have `rustup` installed, this step isn't necessary, however if you don't have access to https://rustup.rs, the mirror also contains the `rustup-init` files needed to install `rustup`. + +Assuming the mirror is hosted at http://panamax.internal/, you will find the `rustup-init` files at http://panamax.internal/rustup/dist/. The `rustup-init` file you want depends on your architecture. Assuming you're running desktop Linux on a 64-bit machine: + +``` +wget http://panamax.internal/rustup/dist/x86_64-unknown-linux-gnu/rustup-init +chmod +x rustup-init +./rustup-init +``` + +This will let you install `rustup` the similarly following the steps from https://rustup.rs. This will also let you use `rustup` to keep your Rust installation updated in the future. + +### Configuring `cargo` +`Cargo` also needs to be configured to point to the mirror. This can be done by adding the following lines to `~/.cargo/config` (creating the file if it doesn't exist): + +``` +[source.my-mirror] +registry = "http://panamax.internal/crates.io-index" +[source.crates-io] +replace-with = "my-mirror" +``` + +`Cargo` should now be pointing to the correct location to use the mirror. + +### Testing configuration +You've now set up a Rust mirror! In order to make sure everything is set up properly, you can run a simple test: + +``` +$ cargo install ripgrep +``` + +This will install the grep-like `rg` tool (which is a great tool - props to burntsushi!). If `cargo` successfully downloads and builds everything, you have yourself a working mirror. Congratulations! From 8801263318f739ef6d1a85876b01a4be04b3e3b2 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 2 May 2025 13:32:04 +0200 Subject: [PATCH 25/41] add metadata-cli --- technology/applications/media/metadata-cli.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 technology/applications/media/metadata-cli.md diff --git a/technology/applications/media/metadata-cli.md b/technology/applications/media/metadata-cli.md new file mode 100644 index 0000000..e599b26 --- /dev/null +++ b/technology/applications/media/metadata-cli.md @@ -0,0 +1,53 @@ +--- +obj: application +repo: https://github.com/zmwangx/metadata +--- + +# metadata +`metadata` is a media metadata parser and formatter designed for human consumption. Powered by FFmpeg. + +Example: + +``` +$ metadata '20160907 Apple Special Event.m4v' +Title: Apple Special Event, September 2016 (1080p) +Filename: 20160907 Apple Special Event.m4v +File size: 6825755188 (6.83GB, 6.36GiB) +Container format: MPEG-4 Part 14 (M4V) +Duration: 01:59:15.88 +Pixel dimensions: 1920x800 +Sample aspect ratio: 1:1 +Display aspect ratio: 12:5 +Scan type: Progressive scan* +Frame rate: 29.97 fps +Bit rate: 7631 kb/s + #0: Video, H.264 (High Profile level 4), yuv420p, 1920x800 (SAR 1:1, DAR 12:5), 29.97 fps, 7500 kb/s + #1: Audio (und), AAC (LC), 48000 Hz, stereo, 125 kb/s + #2: Subtitle (eng), EIA-608 closed captions + +``` + +Compare this to `ffprobe` or `mediainfo` (both great tools, just not so human-readable): + +## Usage +``` +$ metadata -h +metadata 0.1.4 +Zhiming Wang +Media file metadata for human consumption. + +USAGE: + metadata [FLAGS] ... + +FLAGS: + -A, --all-tags Print all metadata tags + -c, --checksum Include file checksum(s) + -h, --help Prints help information + -s, --scan Decode frames to determine scan type (slower, but determines interlaced more accurately; see man + page for details) + -t, --tags Print metadata tags, except mundane ones + -V, --version Prints version information + +ARGS: + ... Media file(s) +``` From 42f42773f8d63d3d29aca2db7b08a566fc0caba6 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 2 May 2025 13:48:31 +0200 Subject: [PATCH 26/41] add delta --- technology/applications/development/delta.md | 151 +++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 technology/applications/development/delta.md diff --git a/technology/applications/development/delta.md b/technology/applications/development/delta.md new file mode 100644 index 0000000..220e571 --- /dev/null +++ b/technology/applications/development/delta.md @@ -0,0 +1,151 @@ +--- +obj: application +website: https://dandavison.github.io/delta/ +repo: https://github.com/dandavison/delta +--- + +# Delta +A syntax-highlighting pager for git, diff, grep, and blame output + +## Get started +Install delta and add this to your `~/.gitconfig`: + +```ini +[core] + pager = delta + +[interactive] + diffFilter = delta --color-only + +[delta] + navigate = true # use n and N to move between diff sections + + # delta detects terminal colors automatically; set one of these to disable auto-detection + # dark = true + # light = true + +[merge] + conflictstyle = zdiff3 +``` + +### Configuration +Delta uses git config (`~/.gitconfig`) for its configuration. + +You do not even need to use git -- delta accepts git diff and unified diff formats and hence works with e.g. mercurial and jujutsu -- but you do need to use the git config format. + +Use `delta --help` to see all the available options. + +To change your delta options in a one-off git command, use `git -c`. For example + +```shell +git -c delta.line-numbers=false show +``` + +## Usage +The main way to use delta is to configure it as the pager for git. + +Delta can also be used as a shorthand for diffing two files, even if they are not in a git repo: the following two commands do the same thing: + +```shell +delta /somewhere/a.txt /somewhere/else/b.txt + +git diff /somewhere/a.txt /somewhere/else/b.txt +``` + +You can also use process substitution shell syntax with delta, e.g. + +```bash +delta <(sort file1) <(sort file2) +``` + +In addition to git output, delta handles standard unified diff format, e.g. `diff -u a.txt b.txt | delta`. + +For Mercurial, you can add delta, with its command line options, to the `[pager]` section of `.hgrc`. + +### Choosing colors (styles) +Delta detects your terminal background color automatically and chooses appropriate default colors. To override automatic detection use dark or light, e.g. + +```ini +[delta] + dark = true +``` + +This is necessary when running delta in some contexts such as lazygit or zellij. + +### Line numbers + +```ini +[delta] + line-numbers = true +``` + +The numbers are displayed in two columns and there are several configuration options: see the `LINE NUMBERS` section in `delta --help` for details. + +### Hyperlinks +Delta uses terminal hyperlinks to turn line numbers, file paths, commit hashes, etc into clickable links, as long as your terminal emulator supports it. Enable the feature with + +```ini +[delta] + hyperlinks = true +``` + +Commit hashes link to GitHub/GitLab/Bitbucket (use `hyperlinks-commit-link-format` for full control). + +The links on line numbers (in grep output, as well as diffs) are particularly interesting: with a little bit of effort, they can be made to open your editor or IDE at the correct line. Use `hyperlinks-file-link-format` to construct the correct URL for your system. For VSCode and JetBrains IDEs this is easy, since they support their own special URL protocols. Here are examples: + +```ini +[delta] + hyperlinks = true + hyperlinks-file-link-format = "vscode://file/{path}:{line}" + # hyperlinks-file-link-format = "idea://open?file={path}&line={line}" + # hyperlinks-file-link-format = "pycharm://open?file={path}&line={line}" +``` + +Zed also supports its own URL protocol, and probably others. + +If your editor does not have its own URL protocol, then there are still many possibilities, although they may be more work. + +The easiest is probably to write a toy HTTP server (e.g. in Python) that opens the links in the way that you need. Then your delta config would look something like + +```ini +[delta] +hyperlinks = true +hyperlinks-file-link-format = "http://localhost:8000/open-in-editor?path={path}&line={line}" +# Now write an HTTP server that handles those requests by opening your editor at the file and line +``` + +### Side-by-side view + +```ini +[delta] + side-by-side = true +``` + +By default, side-by-side view has line-numbers activated, and has syntax highlighting in both the left and right panels. + +### Grep +Delta applies syntax-highlighting and other enhancements to standard grep output such as from ripgrep (aka rg), git grep, grep, etc. If you don't need special features of git grep, then for best results pipe `rg --json` output to delta: this avoids parsing ambiguities that are inevitable with the output of git grep and grep. To customize the colors and syntax highlighting, see the `grep-*` options in `delta --help`. + +Note that git grep can display the "function context" for matches and that delta handles this output specially: see the `-p` and `-W` options of git grep. + +```shell +rg --json -C 2 handle | delta +``` + +With hyperlinks enabled, the line numbers in the grep output will be clickable links. See hyperlinks. + +### Navigation keybindings for large diffs +Use the `navigate` feature to activate navigation keybindings. In this mode, pressing `n` will jump forward to the next file in the diff, and `N` will jump backwards. If you are viewing multiple commits (e.g. via `git log -p`) then navigation will also visit commit boundaries. + +### Merge conflicts +Consider setting `merge.conflictStyle` to `zdiff3`: + +```ini +[merge] + conflictStyle = zdiff3 +``` + +With that setting, when a merge conflict is encountered, Git will display merge conflicts with the contents of the merge base as well. delta will then display this as two diffs, from the ancestor to each side of the conflict: + +### Git blame +Set delta as the pager for blame in the `[pager]` section of your gitconfig. If hyperlinks is enabled in the `[delta]` section then each blame commit will link to the commit on GitHub/GitLab/Bitbucket/etc. From c9491ca90e1899829c693683bbf54b524e08d991 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 2 May 2025 13:54:21 +0200 Subject: [PATCH 27/41] add lrclib --- technology/internet/websites/Links.md | 1 + technology/internet/websites/clearnet/lrclib.net.md | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 technology/internet/websites/clearnet/lrclib.net.md diff --git a/technology/internet/websites/Links.md b/technology/internet/websites/Links.md index d64b7f9..995860f 100644 --- a/technology/internet/websites/Links.md +++ b/technology/internet/websites/Links.md @@ -50,6 +50,7 @@ rev: 2024-03-07 - [SoundCloud](clearnet/SoundCloud.md) - [Nyaa](clearnet/Nyaa.md) - [BS.to](clearnet/BS.to.md) +- [lrclib](clearnet/lrclib.net.md) ## images - [SteamGridDB](clearnet/SteamGridDB.md) diff --git a/technology/internet/websites/clearnet/lrclib.net.md b/technology/internet/websites/clearnet/lrclib.net.md new file mode 100644 index 0000000..feac9bc --- /dev/null +++ b/technology/internet/websites/clearnet/lrclib.net.md @@ -0,0 +1,8 @@ +--- +obj: website +website: https://lrclib.net +category: content +--- + +# lrclib +lrclib.net is a website and API hosting `.lrc` lyric files. From 4c694d4500ea8d9d9fe0be7a37d71c6d8a898a3a Mon Sep 17 00:00:00 2001 From: JMARyA Date: Sun, 11 May 2025 08:22:39 +0200 Subject: [PATCH 28/41] add stalwart --- technology/applications/web/stalwart.md | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 technology/applications/web/stalwart.md diff --git a/technology/applications/web/stalwart.md b/technology/applications/web/stalwart.md new file mode 100644 index 0000000..51b5284 --- /dev/null +++ b/technology/applications/web/stalwart.md @@ -0,0 +1,28 @@ +--- +obj: application +website: https://stalw.art +repo: https://github.com/stalwartlabs/mail-server +--- + +# Stalwart Mail +Stalwart Mail Server is an open-source mail server solution with JMAP, IMAP4, POP3, and SMTP support and a wide range of modern features. It is written in Rust and designed to be secure, fast, robust and scalable. + +## Compose +```yml +services: + mail-server: + ports: + - 443:443 + - 9683:8080 + - 25:25 + - 587:587 + - 465:465 + - 143:143 + - 993:993 + - 4190:4190 + - 110:110 + - 995:995 + volumes: + - /nvme/docker/system/stalwart/data:/opt/stalwart-mail + image: stalwartlabs/mail-server:latest +``` From 78bec898a1a02a5823b29a972114bb4e02e7b7db Mon Sep 17 00:00:00 2001 From: JMARyA Date: Sun, 11 May 2025 09:04:59 +0200 Subject: [PATCH 29/41] add spectacle --- technology/applications/desktops/spectacle.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 technology/applications/desktops/spectacle.md diff --git a/technology/applications/desktops/spectacle.md b/technology/applications/desktops/spectacle.md new file mode 100644 index 0000000..06d8b88 --- /dev/null +++ b/technology/applications/desktops/spectacle.md @@ -0,0 +1,12 @@ +--- +obj: application +repo: https://invent.kde.org/graphics/spectacle +website: https://apps.kde.org/de/spectacle +--- + +# Spectacle +Spectacle is a screenshot taking utility for the KDE desktop. + +## Features +- Screenshot region, windows, displays +- Screenrecord From 1a66742bb4bab90f3b2ea1c2bd88826f6c48aa77 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 12 May 2025 09:17:07 +0200 Subject: [PATCH 30/41] add skate --- technology/applications/cli/skate.md | 58 ++++++++++++++++++++++++++ technology/applications/cli/skate.png | Bin 0 -> 246858 bytes 2 files changed, 58 insertions(+) create mode 100644 technology/applications/cli/skate.md create mode 100644 technology/applications/cli/skate.png diff --git a/technology/applications/cli/skate.md b/technology/applications/cli/skate.md new file mode 100644 index 0000000..5720389 --- /dev/null +++ b/technology/applications/cli/skate.md @@ -0,0 +1,58 @@ +--- +obj: application +repo: https://github.com/charmbracelet/skate +--- + +# 🛼 skate +A personal key-value store. + +![Image](./skate.png) + +## Usage +Usage: `skate [command]` + +### KeyValues +Set a value for a key with an optional `@` db. If `VALUE` is omitted, read value from the standard input: +```sh +# Usage: skate set KEY[@DB] [VALUE] [flags] + +skate set foo@mydb bar +skate set foo < ./bar.txt +``` + +Get a value for a key with an optional `@` db: +```shell +# Usage: skate get KEY[@DB] +skate get foo@mydb +``` + +Delete a key with an optional `@` db: +```shell +# Usage: skate delete KEY[@DB] +skate delete foo@mydb +``` + +List key value pairs with an optional `@` db: +```shell +# Usage: skate list [@DB] [flags] + +# Options: +# -d, --delimiter string delimiter to separate keys and values (default "\t") +# -k, --keys-only only print keys and don't fetch values from the db +# -r, --reverse list in reverse lexicographic order +# -b, --show-binary print binary values +# -v, --values-only only print values + +skate list @mydb +``` + +### Databases +List databases: +```shell +skate list-dbs +``` + +Delete a database: +```shell +skate delete-db @mydb +``` diff --git a/technology/applications/cli/skate.png b/technology/applications/cli/skate.png new file mode 100644 index 0000000000000000000000000000000000000000..04996a933134e7a0f5665ac84bbf2e7f2b64da78 GIT binary patch literal 246858 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 Date: Tue, 13 May 2025 10:13:05 +0200 Subject: [PATCH 31/41] add auto-palette --- .../applications/media/auto-palette-cli.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 technology/applications/media/auto-palette-cli.md diff --git a/technology/applications/media/auto-palette-cli.md b/technology/applications/media/auto-palette-cli.md new file mode 100644 index 0000000..5286d6f --- /dev/null +++ b/technology/applications/media/auto-palette-cli.md @@ -0,0 +1,96 @@ +--- +obj: application +repo: https://github.com/t28hub/auto-palette +--- + +# auto-palette +🎨 `auto-palette` is a library that automatically extracts prominent color palettes from images, available as Rust library, WebAssembly and CLI tool. + +## Overview +`auto-palette` is a Rust project that offers color palette extraction from images. It consists of the following components: + +* `auto-palette`: Core library for programmatic usage. +* `auto-palette-cli`: Command-line interface for easy usage. +* `auto-palette-wasm`: WebAssembly version for browser usage. + +Perfect for developers, designers and anyone needing efficient color palette extraction. + +## Features +* Automatically extracts prominent color palettes from images. +* Provides detailed color swatch information (color, position, population) +* Supports multiple extraction algorithms: `DBSCAN`, `DBSCAN++`, and `KMeans++`. +* Supports numerous color spaces: `RGB`, `HSL`, `LAB`, `LCHuv`, `ANSI256` and more. +* Theme-based swatch selection: `Colorful`, `Vivid`, `Muted`, `Light`, and `Dark`. +* Available as a Rust library, Wasm, and a CLI tool. + +## Installation +### Rust Library +To use `auto-palette` in your Rust project, add it to your `Cargo.toml`. + +```toml +[dependencies] +auto-palette = "0.8.0" +``` + +### CLI Tool +To use command-line interface, install the `auto-palette-cli` crate. + +```sh +cargo install auto-palette-cli +``` + +## Usage +### Rust Example +Here is an example of extracting the color palette from an image using the Rust library. + +```rust +use auto_palette::{ImageData, Palette}; + +fn main() { + // Load the image data from the file + let image_data = ImageData::load("tests/assets/holly-booth-hLZWGXy5akM-unsplash.jpg").unwrap(); + + // Extract the color palette from the image data + let palette: Palette = Palette::extract(&image_data).unwrap(); + println!("Extracted {} swatches", palette.len()); + + // Find the 5 dominant colors in the palette and print their information + let swatches = palette.find_swatches(5).unwrap(); + for swatch in swatches { + println!("Color: {}", swatch.color().to_hex_string()); + println!("Position: {:?}", swatch.position()); + println!("Population: {}", swatch.population()); + println!("Ratio: {}", swatch.ratio()); + } +} +``` + +### CLI Example +Here is an example of extracting the color palette from an image using the CLI tool. + +```sh +# Usage: auto-palette [OPTIONS] [PATH] +$ auto-palette path/to/your_image.jpg -n 6 -c rgb -o table ++---+--------------------+------------+------------+ +| # | Color | Position | Population | ++---+--------------------+------------+------------+ +| 1 | RGB(221, 226, 222) | (104, 96) | 6778 | +| 2 | RGB(3, 144, 149) | (114, 201) | 5476 | +| 3 | RGB(23, 37, 36) | (120, 300) | 4300 | +| 4 | RGB(36, 88, 131) | (183, 145) | 1348 | +| 5 | RGB(254, 29, 44) | (183, 190) | 779 | +| 6 | RGB(253, 213, 116) | (25, 158) | 567 | ++---+--------------------+------------+------------+ +``` + +#### Options + +| Option | Description | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-a, --algorithm ` | Algorithm for extracting the color palette.

**Default:** `dbscan`

**Possible values:**
- `dbscan`: High accuracy but slower speed. Ideal for precision over performance.
- `dbscan++`: A balanced algorithm with faster speed and good accuracy.
- `kmeans`: Fast speed but potentially less accurate. Ideal for performance over precision. | +| `-t, --theme ` | Theme for selecting the swatches.

**Possible values:**
- `colorful`: Prioritize colorful colors.
- `vivid`: Prioritize saturated colors.
- `muted`: Prioritize desaturated colors.
- `light`: Prioritize light colors.
- `dark`: Prioritize dark colors. | +| `-n, --count ` | Number of colors to extract.

**Default:** `5` | +| `-c, --color ` | Output color format.

**Default:** `hex`

**Possible values:**
- `hex`, `rgb`, `cmyk`, `hsl`, `hsv`, `lab`, `luv`, `lchab`, `lchuv`, `oklab`, `oklch`, `xyz` | +| `-o, --output ` | Output format.

**Default:** `text`

**Possible values:**
- `json`, `text`, `table` | +| `--no-resize` | Disable image resizing before extracting the color palette. May improve accuracy by preserving original image resolution. | +| `--clipboard` | Get image from system clipboard. | From dc924e9c1dd0320f4115cbc2f656d86bffd07191 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 13:49:17 +0200 Subject: [PATCH 32/41] add lemmy --- technology/applications/web/lemmy.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 technology/applications/web/lemmy.md diff --git a/technology/applications/web/lemmy.md b/technology/applications/web/lemmy.md new file mode 100644 index 0000000..686f365 --- /dev/null +++ b/technology/applications/web/lemmy.md @@ -0,0 +1,9 @@ +--- +obj: application +repo: https://github.com/LemmyNet/lemmy +website: https://join-lemmy.org +rev: 2025-05-19 +--- + +# Lemmy +**Lemmy** is an open-source, decentralized, and federated alternative to platforms like Reddit. It allows users to create, share, and discuss content in community-based forums called *communities*. Unlike Reddit, Lemmy is part of the **Fediverse**—a network of interconnected servers (also known as *instances*) that communicate using the **ActivityPub** protocol. From 01ef9a0b18705b415a1ab49acba5889b76f7ff62 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 13:52:03 +0200 Subject: [PATCH 33/41] add stump --- technology/applications/web/stump.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 technology/applications/web/stump.md diff --git a/technology/applications/web/stump.md b/technology/applications/web/stump.md new file mode 100644 index 0000000..672ac13 --- /dev/null +++ b/technology/applications/web/stump.md @@ -0,0 +1,8 @@ +--- +obj: application +website: https://www.stumpapp.dev +repo: https://github.com/stumpapp/stump +--- + +# Stump +Stump is a free and open source comics, manga and digital book server with OPDS support. From bff33f063b5f94730c0dc2744cb8649b44585139 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 13:54:21 +0200 Subject: [PATCH 34/41] add octopi --- technology/applications/utilities/octopi.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 technology/applications/utilities/octopi.md diff --git a/technology/applications/utilities/octopi.md b/technology/applications/utilities/octopi.md new file mode 100644 index 0000000..79608ff --- /dev/null +++ b/technology/applications/utilities/octopi.md @@ -0,0 +1,8 @@ +--- +obj: application +repo: https://github.com/aarnt/octopi +--- + +# Octopi +Octopi is a graphical user interface for the Arch Linux pacman package management tool. +It consists of a package browser, sudo helper, notifier, cache cleaner and repository editor. From 1bef285a760e32e6ffd9ca44cf1f48a6d5ee9ed0 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 14:08:57 +0200 Subject: [PATCH 35/41] add material icons --- technology/dev/Material Icons.md | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 technology/dev/Material Icons.md diff --git a/technology/dev/Material Icons.md b/technology/dev/Material Icons.md new file mode 100644 index 0000000..c44bee3 --- /dev/null +++ b/technology/dev/Material Icons.md @@ -0,0 +1,74 @@ +--- +obj: concept +website: https://fonts.google.com/icons +repo: https://github.com/google/material-design-icons +--- + +# Material Icons +[Material Icons](https://fonts.google.com/icons) are a comprehensive set of visual symbols designed by Google. These icons follow the [Material Design](https://m3.material.io/) guidelines and are widely used across Android, web, and other platforms to provide a consistent, clean, and intuitive UI experience. + +## Features +* Over 2,000 icons +* Available in multiple styles (Filled, Outlined, Rounded, Sharp, Two-tone) +* Free and open-source under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) +* Easily customizable (size, color, weight) +* Supported via web fonts, SVGs, and icon components + +## Icon Styles +| Style | Description | +| -------- | ----------------------------------------- | +| Filled | Default solid icons | +| Outlined | Icons with a thin, outlined design | +| Rounded | Icons with rounded corners | +| Sharp | Icons with sharp, angular edges | +| Two-tone | Icons with dual-tone for visual hierarchy | + +## Installation + +### Web Font +Add the following `` tag to your HTML ``: + +```html + +``` + +Then use an icon like this: +```html +home +``` + +To use other styles (e.g., Outlined, Rounded), change the font family: +```html + +``` + +Use it like: +```html +home +``` + +## SVG +You can download individual icons as SVGs from [Material Icons](https://fonts.google.com/icons) or use them programmatically. + +Example: +```html +home icon +``` + +## Customization + +### Size +Use CSS to change the size: +```html +home +``` + +Or use utility classes in frameworks like Tailwind: +```html +home +``` + +### Color +```html +home +``` From a0179e824ee2abe7c4b2eb8ad6cbfbd40fd0c606 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 15:40:41 +0200 Subject: [PATCH 36/41] update rnr --- technology/applications/cli/rnr.md | 105 +++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/technology/applications/cli/rnr.md b/technology/applications/cli/rnr.md index b457b68..6b91c67 100644 --- a/technology/applications/cli/rnr.md +++ b/technology/applications/cli/rnr.md @@ -1,20 +1,101 @@ --- obj: application repo: https://github.com/ismaelgv/rnr +rev: 2025-05-19 --- # rnr -[Repo](https://github.com/ismaelgv/rnr) -**RnR** is a command-line tool to **securely rename** multiple files and directories that supports regular expressions. +RnR is a command-line tool to rename multiple files and directories that supports regular expressions. ## Usage -Flags -```shell --n, --dry-run Only show what would be done (default mode) --f, --force Make actual changes to files --x, --hidden Include hidden files and directories --D, --include-dirs Rename matching directories --r, --recursive Recursive mode --s, --silent Do not print any information ---no-dump Do not dump operations into a file -``` \ No newline at end of file +Usage: `rnr ` + +Commands: +- `regex`: Rename files and directories using a regular expression +- `from-file`: Read operations from a dump file +- `to-ascii`: Replace file name UTF-8 chars with ASCII chars representation + +### regex +``` +Rename files and directories using a regular expression + +Usage: rnr regex [OPTIONS] ... + +Arguments: + Expression to match (can be a regex) + Expression replacement (use single quotes for capture groups) + ... Target paths + +Options: + -n, --dry-run + Only show what would be done (default mode) + -f, --force + Make actual changes to files + -b, --backup + Generate file backups before renaming + -s, --silent + Do not print any information + --color + Set color output mode [default: auto] [possible values: always, never, auto] + --dump + Force dumping operations into a file even in dry-run mode + --dump-prefix + Set the dump file prefix [default: rnr-] + --no-dump + Do not dump operations into a file + -l, --replace-limit + Limit of replacements, all matches if set to 0 + -t, --replace-transform + Apply a transformation to replacements including captured groups [possible values: upper, lower, ascii] + -D, --include-dirs + Rename matching directories + -r, --recursive + Recursive mode + -d, --max-depth + Set max depth in recursive mode + -x, --hidden + Include hidden files and directories +``` + +### from-file +``` +Read operations from a dump file + +Usage: rnr from-file [OPTIONS] + +Arguments: + + +Options: + -n, --dry-run Only show what would be done (default mode) + -f, --force Make actual changes to files + -b, --backup Generate file backups before renaming + -s, --silent Do not print any information + --color Set color output mode [default: auto] [possible values: always, never, auto] + --dump Force dumping operations into a file even in dry-run mode + --dump-prefix Set the dump file prefix [default: rnr-] + --no-dump Do not dump operations into a file + -u, --undo Undo the operations from the dump file +``` + +### to-ascii +``` +Usage: rnr to-ascii [OPTIONS] ... + +Arguments: + ... Target paths + +Options: + -n, --dry-run Only show what would be done (default mode) + -f, --force Make actual changes to files + -b, --backup Generate file backups before renaming + -s, --silent Do not print any information + --color Set color output mode [default: auto] [possible values: always, never, auto] + --dump Force dumping operations into a file even in dry-run mode + --dump-prefix Set the dump file prefix [default: rnr-] + --no-dump Do not dump operations into a file + -D, --include-dirs Rename matching directories + -r, --recursive Recursive mode + -d, --max-depth Set max depth in recursive mode + -x, --hidden Include hidden files and directories +``` From a97795fd6d68de9c8cc7592c9cc881af0275425b Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 15:47:54 +0200 Subject: [PATCH 37/41] add opengist --- technology/applications/web/opengist.md | 208 ++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 technology/applications/web/opengist.md diff --git a/technology/applications/web/opengist.md b/technology/applications/web/opengist.md new file mode 100644 index 0000000..046b906 --- /dev/null +++ b/technology/applications/web/opengist.md @@ -0,0 +1,208 @@ +--- +obj: application +website: https://opengist.io +repo: https://github.com/thomiceli/opengist +rev: 2025-05-19 +--- + +# OpenGist +Opengist is a self-hosted pastebin powered by Git. All snippets are stored in a Git repository and can be read and/or modified using standard Git commands, or with the web interface. It is similiar to GitHub Gist, but open-source and could be self-hosted. + +## Features +- Create public, unlisted or private snippets +- Init / Clone / Pull / Push snippets via Git over HTTP or SSH +- Syntax highlighting ; markdown & CSV support +- Search code in snippets ; browse users snippets, likes and forks +- Add topics to snippets +- Embed snippets in other websites +- Revisions history +- Like / Fork snippets +- Editor with indentation mode & size ; drag and drop files +- Download raw files or as a ZIP archive +- Retrieve snippet data/metadata via a JSON API +- OAuth2 login with GitHub, GitLab, Gitea, and OpenID Connect +- Avatars via Gravatar or OAuth2 providers +- Light/Dark mode +- Responsive UI +- Enable or disable signups +- Restrict or unrestrict snippets visibility to anonymous users + +## Compose +```yml +services: + opengist: + image: ghcr.io/thomiceli/opengist:1 + container_name: opengist + restart: unless-stopped + ports: + - "6157:6157" # HTTP port + - "2222:2222" # SSH port, can be removed if you don't use SSH + volumes: + - "$HOME/.opengist:/opengist" + environment: + # OG_LOG_LEVEL: info + # other configuration options +``` + +## Configuration + +| YAML Config Key | Environment Variable | Default value | Description | +| --------------------- | ----------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| log-level | OG_LOG_LEVEL | `warn` | Set the log level to one of the following: `debug`, `info`, `warn`, `error`, `fatal`. | +| log-output | OG_LOG_OUTPUT | `stdout,file` | Set the log output to one or more of the following: `stdout`, `file`. | +| external-url | OG_EXTERNAL_URL | none | Public URL to access to Opengist. | +| opengist-home | OG_OPENGIST_HOME | home directory | Path to the directory where Opengist stores its data. | +| secret-key | OG_SECRET_KEY | randomized 32 bytes | Secret key used for session store & encrypt MFA data on database. | +| db-uri | OG_DB_URI | `opengist.db` | URI of the database. | +| index | OG_INDEX | `bleve` | Define the code indexer (either `bleve`, `meilisearch`, or empty for no index). | +| index.meili.host | OG_MEILI_HOST | none | Set the host for the Meiliseach server. | +| index.meili.api-key | OG_MEILI_API_KEY | none | Set the API key for the Meiliseach server. | +| git.default-branch | OG_GIT_DEFAULT_BRANCH | none | Default branch name used by Opengist when initializing Git repositories. If not set, uses the Git default branch name. More info [here](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup#_new_default_branch) | +| sqlite.journal-mode | OG_SQLITE_JOURNAL_MODE | `WAL` | Set the journal mode for SQLite. More info [here](https://www.sqlite.org/pragma.html#pragma_journal_mode) | +| http.host | OG_HTTP_HOST | `0.0.0.0` | The host on which the HTTP server should bind. | +| http.port | OG_HTTP_PORT | `6157` | The port on which the HTTP server should listen. | +| http.git-enabled | OG_HTTP_GIT_ENABLED | `true` | Enable or disable git operations (clone, pull, push) via HTTP. (`true` or `false`) | +| metrics.enabled | OG_METRICS_ENABLED | `false` | Enable or disable Prometheus metrics endpoint at `/metrics` (`true` or `false`) | +| ssh.git-enabled | OG_SSH_GIT_ENABLED | `true` | Enable or disable git operations (clone, pull, push) via SSH. (`true` or `false`) | +| ssh.host | OG_SSH_HOST | `0.0.0.0` | The host on which the SSH server should bind. | +| ssh.port | OG_SSH_PORT | `2222` | The port on which the SSH server should listen. | +| ssh.external-domain | OG_SSH_EXTERNAL_DOMAIN | none | Public domain for the Git SSH connection, if it has to be different from the HTTP one. If not set, uses the URL from the request. | +| ssh.keygen-executable | OG_SSH_KEYGEN_EXECUTABLE | `ssh-keygen` | Path to the SSH key generation executable. | +| github.client-key | OG_GITHUB_CLIENT_KEY | none | The client key for the GitHub OAuth application. | +| github.secret | OG_GITHUB_SECRET | none | The secret for the GitHub OAuth application. | +| gitlab.client-key | OG_GITLAB_CLIENT_KEY | none | The client key for the GitLab OAuth application. | +| gitlab.secret | OG_GITLAB_SECRET | none | The secret for the GitLab OAuth application. | +| gitlab.url | OG_GITLAB_URL | `https://gitlab.com/` | The URL of the GitLab instance. | +| gitlab.name | OG_GITLAB_NAME | `GitLab` | The name of the GitLab instance. It is displayed in the OAuth login button. | +| gitea.client-key | OG_GITEA_CLIENT_KEY | none | The client key for the Gitea OAuth application. | +| gitea.secret | OG_GITEA_SECRET | none | The secret for the Gitea OAuth application. | +| gitea.url | OG_GITEA_URL | `https://gitea.com/` | The URL of the Gitea instance. | +| gitea.name | OG_GITEA_NAME | `Gitea` | The name of the Gitea instance. It is displayed in the OAuth login button. | +| oidc.provider-name | OG_OIDC_PROVIDER_NAME | none | The name of the OIDC provider | +| oidc.client-key | OG_OIDC_CLIENT_KEY | none | The client key for the OpenID application. | +| oidc.secret | OG_OIDC_SECRET | none | The secret for the OpenID application. | +| oidc.discovery-url | OG_OIDC_DISCOVERY_URL | none | Discovery endpoint of the OpenID provider. | +| ldap.url | OG_LDAP_URL | none | URL of the LDAP instance; if not set, LDAP authentication is disabled | +| ldap.bind-dn | OG_LDAP_BIND_DN | none | Bind DN to authenticate against the LDAP. e.g: cn=read-only-admin,dc=example,dc=com | +| ldap.bind-credentials | OG_LDAP_BIND_CREDENTIALS | none | The password for the Bind DN. | +| ldap.search-base | OG_LDAP_SEARCH_BASE | none | The Base DN to start search from. e.g: ou=People,dc=example,dc=com | +| ldap.search-filter | OG_LDAP_SEARCH_FILTER | none | The filter to search against (the format string %s will be replaced with the username). e.g: (uid=%s) | +| custom.name | OG_CUSTOM_NAME | none | The name of your instance, to be displayed in the tab title | +| custom.logo | OG_CUSTOM_LOGO | none | Path to an image, relative to $opengist-home/custom. | +| custom.favicon | OG_CUSTOM_FAVICON | none | Path to an image, relative to $opengist-home/custom. | +| custom.static-links | OG_CUSTOM_STATIC_LINK_#_(PATH,NAME) | none | Path and name to custom links, more info [here](custom-links.md). | + +## Usage +### Init Gists via Git +Opengist allows you to create new snippets via Git over HTTP. + +Simply init a new Git repository where your file(s) is/are located: + +```shell +git init +git add . +git commit -m "My cool snippet" +``` + +Then add this Opengist special remote URL and push your changes: + +```shell +git remote add origin http://localhost:6157/init + +git push -u origin master +``` + +Log in with your Opengist account credentials, and your snippet will be created at the specified URL: + +```shell +Username for 'http://localhost:6157': thomas +Password for 'http://thomas@localhost:6157': +Enumerating objects: 3, done. +Counting objects: 100% (3/3), done. +Delta compression using up to 8 threads +Compressing objects: 100% (2/2), done. +Writing objects: 100% (3/3), 416 bytes | 416.00 KiB/s, done. +Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 +remote: +remote: Your new repository has been created here: http://localhost:6157/thomas/6051e930f140429f9a2f3bb1fa101066 +remote: +remote: If you want to keep working with your gist, you could set the remote URL via: +remote: git remote set-url origin http://localhost:6157/thomas/6051e930f140429f9a2f3bb1fa101066 +remote: +To http://localhost:6157/init + * [new branch] master -> master +``` + +### Embed a Gist to your webpage +To embed a Gist to your webpage, you can add a script tag with the URL of your gist followed by `.js` to your HTML page: + +```html + + + + +``` + +### Retrieve Gist as JSON +To retrieve a Gist as JSON, you can add `.json` to the end of the URL of your gist: + +```shell +curl http://opengist.url/thomas/my-gist.json | jq '.' +``` + +It returns a JSON object with the following structure similar to this one: +```json +{ + "created_at": "2023-04-12T13:15:20+02:00", + "description": "", + "embed": { + "css": "http://localhost:6157/assets/embed-94abc261.css", + "html": "
\n
\n \n
\n \n \n \n \n

Welcome to Opengist

\n
\n \n\n
\n \n
\n
\n", + "js": "http://localhost:6157/thomas/my-gist.js", + "js_dark": "http://localhost:6157/thomas/my-gist.js?dark" + }, + "files": [ + { + "filename": "hello.md", + "size": 21, + "human_size": "21 B", + "content": "# Welcome to Opengist", + "truncated": false, + "type": "Markdown" + } + ], + "id": "my-gist", + "owner": "thomas", + "title": "hello.md", + "uuid": "8622b297bce54b408e36d546cef8019d", + "visibility": "public" +} +``` + +### Push Options +Opengist has support for a few [Git push options](https://git-scm.com/docs/git-push#Documentation/git-push.txt--oltoptiongt). + +These options are passed to `git push` command and can be used to change the metadata of a gist. + +#### Set URL +```shell +git push -o url=mygist # Will set the URL to https://opengist.example.com/user/mygist +``` + +#### Change title +```shell +git push -o title=Gist123 +git push -o title="My Gist 123" +``` + +#### Change description +```shell +git push -o description="This is my gist description" +``` + +#### Change visibility +```shell +git push -o visibility=public +git push -o visibility=unlisted +git push -o visibility=private +``` From 576421a6be2a23a111b2399a5e08d6032f45c3c1 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 19 May 2025 15:57:29 +0200 Subject: [PATCH 38/41] add ruff --- technology/applications/development/ruff.md | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 technology/applications/development/ruff.md diff --git a/technology/applications/development/ruff.md b/technology/applications/development/ruff.md new file mode 100644 index 0000000..05596c9 --- /dev/null +++ b/technology/applications/development/ruff.md @@ -0,0 +1,41 @@ +--- +obj: application +repo: https://github.com/astral-sh/ruff +website: https://docs.astral.sh/ruff +rev: 2025-05-19 +--- + +# ruff +An extremely fast Python linter and code formatter, written in Rust. + +## The Ruff Linter +The Ruff Linter is an extremely fast Python linter designed as a drop-in replacement for [Flake8](https://pypi.org/project/flake8/) (plus dozens of plugins), [isort](https://pypi.org/project/isort/), [pydocstyle](https://pypi.org/project/pydocstyle/), [pyupgrade](https://pypi.org/project/pyupgrade/), [autoflake](https://pypi.org/project/autoflake/), and more. + +### `ruff check` +`ruff check` is the primary entrypoint to the Ruff linter. It accepts a list of files or directories, and lints all discovered Python files, optionally fixing any fixable errors. When linting a directory, Ruff searches for Python files recursively in that directory and all its subdirectories: + +```console +$ ruff check # Lint files in the current directory. +$ ruff check --fix # Lint files in the current directory and fix any fixable errors. +$ ruff check --watch # Lint files in the current directory and re-lint on change. +$ ruff check path/to/code/ # Lint files in `path/to/code`. +``` + +## The Ruff Formatter +The Ruff formatter is an extremely fast Python code formatter designed as a drop-in replacement for [Black](https://pypi.org/project/black/), available as part of the `ruff` CLI via `ruff format`. + +### `ruff format` +`ruff format` is the primary entrypoint to the formatter. It accepts a list of files or directories, and formats all discovered Python files: + +```shell +ruff format # Format all files in the current directory. +ruff format path/to/code/ # Format all files in `path/to/code` (and any subdirectories). +ruff format path/to/file.py # Format a single file. +``` + +Similar to Black, running `ruff format /path/to/file.py` will format the given file or directory in-place, while `ruff format --check /path/to/file.py` will avoid writing any formatted files back, and instead exit with a non-zero status code upon detecting any unformatted files. + +For the full list of supported options, run `ruff format --help`. + +## Configuration +ruff can be configured via `ruff.toml` config file. See [here](https://docs.astral.sh/ruff/settings/) for a reference of all config parameters. From 9f6a31e8ef28d05e64037de1a780c90980b63c3a Mon Sep 17 00:00:00 2001 From: JMARyA Date: Wed, 21 May 2025 13:10:23 +0200 Subject: [PATCH 39/41] add artem --- technology/applications/media/artem.md | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 technology/applications/media/artem.md diff --git a/technology/applications/media/artem.md b/technology/applications/media/artem.md new file mode 100644 index 0000000..f258c38 --- /dev/null +++ b/technology/applications/media/artem.md @@ -0,0 +1,30 @@ +--- +obj: application +repo: https://github.com/FineFindus/artem +--- + +# artem +Artem is a small cli program, written in rust, to easily convert images to ascii art, named after the latin word for art. By default it tries to use truecolor, if the terminal does not support truecolor, it falls back to 16 Color ANSI. When the ascii image is written to a file, the image will not use colors. It supports .jpeg, .png, .gif, .webp and many more. + +## Usage +Usage: `artem [options] [image]` + +| `Option` | `Description` | +| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-c, --characters ` | Change the characters used to display the image. The first character should have the highest 'darkness' and the last should have the least (recommended to be a space ' '). A lower detail map is recommended for smaller images. | +| `-s, --size ` | Change the size of the output image. The minimum size is 20. Lower values will be ignored and changed to 20. Conflicts with `--width` and `--height`. \[default: 80] | +| `--height` | Use the terminal maximum height to display the image. Conflicts with `--size` and `--width`. | +| `-w, --width` | Use the terminal maximum width to display the image. Conflicts with `--size` and `--height`. | +| `--ratio ` | Change the ratio between height and width. The value must be between 0.1 and 1.0. It is not recommended to change this setting. \[default: 0.42] | +| `--flipX` | Flip the image along the X-Axis/horizontally. | +| `--flipY` | Flip the image along the Y-Axis/vertically. | +| `--centerX` | Center the image along the X-Axis/horizontally in the terminal. | +| `--centerY` | Center the image along the Y-Axis/vertically in the terminal. | +| `-o, --output ` | Output file for non-colored ASCII. For color, use a file with .ansi, .svg, or .html extension. .ansi files will consider environment variables when creating colored output. | +| `--invert` | Inverts the characters used for the image, so light characters will be dark. Useful if the image has a dark background. | +| `--background` | Sets the background of the ASCII as the color. Ignored if the terminal does not support truecolor. Mutually exclusive with `--no-color`. | +| `--border` | Adds a decorative border surrounding the ASCII image, making the image slightly smaller as it respects the given size. | +| `--no-color` | Do not use color when printing the image to the terminal. | +| `--outline` | Only create an outline of the image. Uses filters and may take more resources/time, especially on larger images. Best used on images with clear foreground/background distinction. | +| `--hysteresis` | When creating the outline, use the hysteresis method to remove imperfections, but might not look as good in ASCII form. Requires `--outline` to be present. | +| `--verbose ` | Choose the verbosity of the logging level. \[default: warn] Possible values: off, error, warn, info, debug, trace. | From 502dfdebdc6843b3d27692d96901bd8bd1add99e Mon Sep 17 00:00:00 2001 From: JMARyA Date: Wed, 21 May 2025 13:42:18 +0200 Subject: [PATCH 40/41] add distrobox --- .../applications/utilities/distrobox.md | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 technology/applications/utilities/distrobox.md diff --git a/technology/applications/utilities/distrobox.md b/technology/applications/utilities/distrobox.md new file mode 100644 index 0000000..346dd40 --- /dev/null +++ b/technology/applications/utilities/distrobox.md @@ -0,0 +1,112 @@ +--- +obj: application +website: https://distrobox.it +arch-wiki: https://wiki.archlinux.org/title/Distrobox +repo: https://github.com/89luca89/distrobox +--- + +# DistroBox +Use any Linux distribution inside your terminal. Enable both backward and forward compatibility with software and freedom to use whatever distribution you’re more comfortable with. Distrobox uses podman, docker or lilipod to create containers using the Linux distribution of your choice. The created container will be tightly integrated with the host, allowing sharing of the HOME directory of the user, external storage, external USB devices and graphical apps (X11/Wayland), and audio. + +## Usage +To create a new container run the following: +``` +$ distrobox create -n name +``` + +To list installed containers run the following: +``` +$ distrobox list +``` + +To interact with an installed container run the following: +``` +$ distrobox enter name +``` + +or you can send a command directly to a container with: +``` +$ distrobox enter name -- command-to-execute +``` + +To stop a running container run the following: +``` +$ distrobox stop name +``` + +To delete a container run the following: +``` +$ distrobox rm name +``` + +To install a specific distro into a container run the following (in this example it is Ubuntu): +``` +$ distrobox create --image ubuntu:22.04 +``` + +Installations can be fully customised as follows (in this example it is a container called test running Gentoo with root access): +``` +$ distrobox create -i docker.io/gentoo/stage3:latest -n test --root +``` + +If you need your container to have root access to the host then it is recommended that you use the `--root` flag over `sudo distrobox`. + +### Unsharing mode +Distrobox allows users to partially isolate certain system aspects through its unshare feature. By default, the following components are shared between host and container: + +`devsysfs`, `ipc`, `netns`, `process`, `$HOME` and Application access. + +You can choose to unshare some of these components by using the commands listed below when creating a new container: + +#### Shares + +| Share | Command | Usage | +| ---------- | -------------------- | --------------------------------------------------- | +| `devsysfs` | `--unshare-devsysfs` | Do not share host devices and sysfs dirs from host. | +| `ipc` | `--unshare-ipc` | Do not share the ipc namespace with host. | +| `netns` | `--unshare-netns` | Do not share the network namespace with host. | +| `process` | `--unshare-process` | Do not share the process namespace with host. | +| All | `--unshare-all` | Activate all unshare flags. | + +Note that unsharing `$HOME` and Application access is not possible, as these are mandatory for Distrobox's core functionality. + +> Warning: While the unsharing feature provides some isolation between container and host, it does not constitute a full security sandbox. You should not rely on it for complete security isolation. + +## Configuration +It is possible to configure Distrobox in two ways, either with a configuration file or by using environment variables. + +### Configuration file +Distrobox checks the following locations for config files, from least important to most important: + +- `/usr/share/distrobox/distrobox.conf` +- `/usr/etc/distrobox/distrobox.conf` +- `/etc/distrobox/distrobox.conf` +- `~/.config/distrobox/distrobox.conf` +- `~/.distroboxrc` + +An example config file is as follows: +``` +container_always_pull="1" +container_generate_entry=0 +container_manager="docker" +container_image_default="registry.opensuse.org/opensuse/toolbox:latest" +container_name_default="test-name-1" +container_user_custom_home="$HOME/.local/share/container-home-test" +container_init_hook="~/.local/distrobox/a_custom_default_init_hook.sh" +container_pre_init_hook="~/a_custom_default_pre_init_hook.sh" +non_interactive="1" +skip_workdir="0" +``` + +### Environment variables +The following variables are available and should be set using per user variables: +``` +DBX_CONTAINER_ALWAYS_PULL +DBX_CONTAINER_CUSTOM_HOME +DBX_CONTAINER_IMAGE +DBX_CONTAINER_MANAGER +DBX_CONTAINER_NAME +DBX_CONTAINER_ENTRY +DBX_NON_INTERACTIVE +DBX_SKIP_WORKDIR +``` From 6869f6eca58365d4a3b57412b6078217ca447985 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Wed, 21 May 2025 16:52:05 +0200 Subject: [PATCH 41/41] add mdbook --- technology/applications/office/mdbook.md | 530 +++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 technology/applications/office/mdbook.md diff --git a/technology/applications/office/mdbook.md b/technology/applications/office/mdbook.md new file mode 100644 index 0000000..421e816 --- /dev/null +++ b/technology/applications/office/mdbook.md @@ -0,0 +1,530 @@ +--- +obj: application +website: https://rust-lang.github.io/mdBook/ +repo: https://github.com/rust-lang/mdBook +rev: 2025-05-21 +--- + +# mdbook +`mdBook` is a command-line tool for creating books from Markdown files. It is designed to generate a static website based on Markdown content, perfect for creating online documentation, tutorials, and books. It is similar to GitBook but is written in Rust and is fully open-source. + +## Usage +The basic command for `mdBook` is as follows: + +```bash +mdbook [options] +``` + +### Available Commands + +* `init`: Creates a new book in the current directory. +* `build`: Builds the book (default). +* `serve`: Serves the book locally with hot reloading. +* `test`: Runs tests on the book. +* `clean`: Cleans the book’s build artifacts. +* `watch`: Watches for file changes and rebuilds the book. + +### Examples + +1. **Building the book**: + + ```bash + mdbook build + ``` + +2. **Serving the book locally**: + + ```bash + mdbook serve + ``` + +3. **Initializing a new book**: + + ```bash + mdbook init my-book + ``` + + This creates a new directory called `my-book` and sets up a template for your book. + +## Book Format +The structure of the book’s source directory typically looks like this: + +``` +my-book/ +├── src/ +│ ├── SUMMARY.md +│ ├── chapter_1.md +│ ├── chapter_2.md +│ └── ... +├── book.toml +└── README.md +``` + +### Key Files and Directories +* `src/`: Contains the Markdown files for your book. This is where the content resides. + * `SUMMARY.md`: This file defines the table of contents and chapter structure of your book. It lists all of the sections and their hierarchical order. + * Other `.md` files: The content for each chapter or section of the book. +* `book.toml`: The configuration file that defines the metadata and settings for the book (e.g., title, author, theme). +* `README.md`: This file is optional and provides a description of your book. + +### Configuration File (`book.toml`) +The `book.toml` file contains configuration settings for the book. Below is an example configuration: + +```toml +[book] +title = "Example book" +authors = ["John Doe"] +description = "The example book covers examples." + +[rust] +edition = "2018" + +[build] +build-dir = "my-example-book" +create-missing = false + +[preprocessor.index] + +[preprocessor.links] + +[output.html] +additional-css = ["custom.css"] + +[output.html.search] +limit-results = 15 +``` + +### `SUMMARY.md` file +The summary file is used by mdBook to know what chapters to include, in what order they should appear, what their hierarchy is and where the source files are. Without this file, there is no book. + +This markdown file must be named `SUMMARY.md`. Its formatting is very strict and must follow the structure outlined below to allow for easy parsing. Any element not specified below, be it formatting or textual, is likely to be ignored at best, or may cause an error when attempting to build the book. + +#### Structure +- `Title` - While optional, it’s common practice to begin with a title, generally `# Summary`. This is ignored by the parser however, and can be omitted. +```md +# Summary +``` + +- `Prefix Chapter` - Before the main numbered chapters, prefix chapters can be added that will not be numbered. This is useful for forewords, introductions, etc. There are, however, some constraints. Prefix chapters cannot be nested; they should all be on the root level. And you cannot add prefix chapters once you have added numbered chapters. +```md +[A Prefix Chapter](relative/path/to/markdown.md) + +- [First Chapter](relative/path/to/markdown2.md) +``` + +- `Part Title` - Level 1 headers can be used as a title for the following numbered chapters. This can be used to logically separate different sections of the book. The title is rendered as unclickable text. Titles are optional, and the numbered chapters can be broken into as many parts as desired. Part titles must be h1 headers (one `#`), other heading levels are ignored. +```md +# My Part Title + +- [First Chapter](relative/path/to/markdown.md) +``` + +- `Numbered Chapter` - Numbered chapters outline the main content of the book and can be nested, resulting in a nice hierarchy (chapters, sub-chapters, etc.). +```md +# Title of Part + +- [First Chapter](relative/path/to/markdown.md) +- [Second Chapter](relative/path/to/markdown2.md) + - [Sub Chapter](relative/path/to/markdown3.md) + +# Title of Another Part + +- [Another Chapter](relative/path/to/markdown4.md) +``` + +Numbered chapters can be denoted with either - or * (do not mix delimiters). + +- `Suffix Chapter` - Like prefix chapters, suffix chapters are unnumbered, but they come after numbered chapters. +```md +- [Last Chapter](relative/path/to/markdown.md) + +[Title of Suffix Chapter](relative/path/to/markdown2.md) +``` + +- `Draft chapters` - Draft chapters are chapters without a file and thus content. The purpose of a draft chapter is to signal future chapters still to be written. Or when still laying out the structure of the book to avoid creating the files while you are still changing the structure of the book a lot. Draft chapters will be rendered in the HTML renderer as disabled links in the table of contents, as you can see for the next chapter in the table of contents on the left. Draft chapters are written like normal chapters but without writing the path to the file. +```md +- [Draft Chapter]() +``` + +- `Separators` - Separators can be added before, in between, and after any other element. They result in an HTML rendered line in the built table of contents. A separator is a line containing exclusively dashes and at least three of them: ---. +```md +# My Part Title + +[A Prefix Chapter](relative/path/to/markdown.md) + +--- + +- [First Chapter](relative/path/to/markdown2.md) +``` + +#### Example +Below is a full example `SUMMARY.md`: + +```md +# Summary + +[Introduction](README.md) + +# User Guide + +- [Installation](guide/installation.md) +- [Reading Books](guide/reading.md) +- [Creating a Book](guide/creating.md) + +# Reference Guide + +- [Command Line Tool](cli/README.md) + - [init](cli/init.md) + - [build](cli/build.md) + - [watch](cli/watch.md) + - [serve](cli/serve.md) + - [test](cli/test.md) + - [clean](cli/clean.md) + - [completions](cli/completions.md) +- [Format](format/README.md) + - [SUMMARY.md](format/summary.md) + - [Draft chapter]() + - [Configuration](format/configuration/README.md) + - [General](format/configuration/general.md) + - [Preprocessors](format/configuration/preprocessors.md) + - [Renderers](format/configuration/renderers.md) + - [Environment Variables](format/configuration/environment-variables.md) + - [Theme](format/theme/README.md) + - [index.hbs](format/theme/index-hbs.md) + - [Syntax highlighting](format/theme/syntax-highlighting.md) + - [Editor](format/theme/editor.md) + - [MathJax Support](format/mathjax.md) + - [mdBook-specific features](format/mdbook.md) + - [Markdown](format/markdown.md) +- [Continuous Integration](continuous-integration.md) +- [For Developers](for_developers/README.md) + - [Preprocessors](for_developers/preprocessors.md) + - [Alternative Backends](for_developers/backends.md) + +----------- + +[Contributors](misc/contributors.md) +``` + +### Preprocessors +Preprocessors are extensions that can modify the raw Markdown source before it gets sent to the renderer. + +The following preprocessors are built-in and included by default: +- links: Expands the `{{ #playground }}`, `{{ #include }}`, and `{{ #rustdoc_include }}` handlebars helpers in a chapter to include the contents of a file. +- index: Convert all chapter files named `README.md` into `index.md`. That is to say, all `README.md` would be rendered to an index file `index.html` in the rendered book. + +The built-in preprocessors can be disabled with the `build.use-default-preprocessors` config option. + +The community has developed several preprocessors. See the [Third Party Plugins wiki page](https://github.com/rust-lang/mdBook/wiki/Third-party-plugins) for a list of available preprocessors. + +#### Custom Preprocessor Configuration +Preprocessors can be added by including a `preprocessor` table in `book.toml` with the name of the preprocessor. For example, if you have a preprocessor called `mdbook-example`, then you can include it with: +```toml +[preprocessor.example] +``` + +With this table, mdBook will execute the mdbook-example preprocessor. + +This table can include additional key-value pairs that are specific to the preprocessor. For example, if our example preprocessor needed some extra configuration options: +```toml +[preprocessor.example] +some-extra-feature = true +``` + +#### Locking a Preprocessor dependency to a renderer +You can explicitly specify that a preprocessor should run for a renderer by binding the two together. +```toml +[preprocessor.example] +renderers = ["html"] # example preprocessor only runs with the HTML renderer +``` + +#### Provide Your Own Command +By default when you add a `[preprocessor.foo]` table to your `book.toml` file, mdbook will try to invoke the `mdbook-foo` executable. If you want to use a different program name or pass in command-line arguments, this behaviour can be overridden by adding a command field. +```toml +[preprocessor.random] +command = "python random.py" +``` + +#### Require A Certain Order +The order in which preprocessors are run can be controlled with the before and after fields. For example, suppose you want your linenos preprocessor to process lines that may have been `{{#include}}`d; then you want it to run after the built-in links preprocessor, which you can require using either the before or after field: +```toml +[preprocessor.linenos] +after = [ "links" ] +``` + +or + +``` +[preprocessor.links] +before = [ "linenos" ] +``` + +It would also be possible, though redundant, to specify both of the above in the same config file. + +Preprocessors having the same priority specified through before and after are sorted by name. Any infinite loops will be detected and produce an error. + +## Features +### Hiding code lines +There is a feature in mdBook that lets you hide code lines by prepending them with a specific prefix. + +For the Rust language, you can prefix lines with `# ` (# followed by a space) to hide them like you would with Rustdoc. This prefix can be escaped with `##` to prevent the hiding of a line that should begin with the literal string `#` (see Rustdoc’s docs for more details) +``` +# fn main() { + let x = 5; + let y = 6; + + println!("{}", x + y); +# } +``` + +Will render as +``` + let x = 5; + let y = 6; + + println!("{}", x + y); +``` + +When you tap or hover the mouse over the code block, there will be an eyeball icon which will toggle the visibility of the hidden lines. + +By default, this only works for code examples that are annotated with rust. However, you can define custom prefixes for other languages by adding a new line-hiding prefix in your `book.toml` with the language name and prefix character(s): + +```toml +[output.html.code.hidelines] +python = "~" +``` + +The prefix will hide any lines that begin with the given prefix. With the python prefix shown above, this: + +``` +~hidden() +nothidden(): +~ hidden() + ~hidden() + nothidden() +``` + +will render as +```python +nothidden(): + nothidden() +``` + +This behavior can be overridden locally with a different prefix. This has the same effect as above: + +``` +\```python,hidelines=!!! +!!!hidden() +nothidden(): +!!! hidden() + !!!hidden() + nothidden() +\``` +``` + +### Rust Playground +Rust language code blocks will automatically get a play button which will execute the code and display the output just below the code block. This works by sending the code to the Rust Playground. + +If there is no main function, then the code is automatically wrapped inside one. + +If you wish to disable the play button for a code block, you can include the `noplayground` option on the code block like this: + +``` +\```rust,noplayground +let mut name = String::new(); +std::io::stdin().read_line(&mut name).expect("failed to read line"); +println!("Hello {}!", name); +\``` +``` + +Or, if you wish to disable the play button for all code blocks in your book, you can write the config to the `book.toml` like this. + +```toml +[output.html.playground] +runnable = false +``` + +### Rust code block attributes +Additional attributes can be included in Rust code blocks with comma, space, or tab-separated terms just after the language term. For example: + +``` +\```rust,ignore +# This example won't be tested. +panic!("oops!"); +\``` +``` + +These are particularly important when using mdbook test to test Rust examples. These use the same attributes as rustdoc attributes, with a few additions: + +- `editable` — Enables the editor. +- `noplayground` — Removes the play button, but will still be tested. +- `mdbook-runnable` — Forces the play button to be displayed. This is intended to be combined with the ignore attribute for examples that should not be tested, but you want to allow the reader to run. +- `ignore` — Will not be tested and no play button is shown, but it is still highlighted as Rust syntax. +- `should_panic` — When executed, it should produce a panic. +- `no_run` — The code is compiled when tested, but it is not run. The play button is also not shown. +- `compile_fail` — The code should fail to compile. +- `edition2015`, `edition2018`, `edition2021` — Forces the use of a specific Rust edition. See rust.edition to set this globally. + +### Including files +With the following syntax, you can include files into your book: +``` +{{#include file.rs}} +``` + +The path to the file has to be relative from the current source file. + +mdBook will interpret included files as Markdown. Since the include command is usually used for inserting code snippets and examples, you will often wrap the command with ``` to display the file contents without interpreting them. + +``` +\``` +{{#include file.rs}} +\``` +``` + +### Including portions of a file +Often you only need a specific part of the file, e.g. relevant lines for an example. We support four different modes of partial includes: + +``` +{{#include file.rs:2}} +{{#include file.rs::10}} +{{#include file.rs:2:}} +{{#include file.rs:2:10}} +``` + +The first command only includes the second line from file `file.rs`. The second command includes all lines up to line 10, i.e. the lines from 11 till the end of the file are omitted. The third command includes all lines from line 2, i.e. the first line is omitted. The last command includes the excerpt of `file.rs` consisting of lines 2 to 10. + +To avoid breaking your book when modifying included files, you can also include a specific section using anchors instead of line numbers. An anchor is a pair of matching lines. The line beginning an anchor must match the regex `ANCHOR:\s*[\w_-]+` and similarly the ending line must match the regex `ANCHOR_END:\s*[\w_-]+`. This allows you to put anchors in any kind of commented line. + +Consider the following file to include: + +``` +/* ANCHOR: all */ + +// ANCHOR: component +struct Paddle { + hello: f32, +} +// ANCHOR_END: component + +////////// ANCHOR: system +impl System for MySystem { ... } +////////// ANCHOR_END: system + +/* ANCHOR_END: all */ +``` + +Then in the book, all you have to do is: + +``` +Here is a component: +\```rust,no_run,noplayground +{{#include file.rs:component}} +\``` + +Here is a system: +\```rust,no_run,noplayground +{{#include file.rs:system}} +\``` + +This is the full file. +\```rust,no_run,noplayground +{{#include file.rs:all}} +\``` +``` + +Lines containing anchor patterns inside the included anchor are ignored. + +### Including a file but initially hiding all except specified lines +The `rustdoc_include` helper is for including code from external Rust files that contain complete examples, but only initially showing particular lines specified with line numbers or anchors in the same way as with include. + +The lines not in the line number range or between the anchors will still be included, but they will be prefaced with `#`. This way, a reader can expand the snippet to see the complete example, and Rustdoc will use the complete example when you run mdbook test. + +For example, consider a file named `file.rs` that contains this Rust program: + +```rust +fn main() { + let x = add_one(2); + assert_eq!(x, 3); +} + +fn add_one(num: i32) -> i32 { + num + 1 +} +``` + +We can include a snippet that initially shows only line 2 by using this syntax: + +``` +To call the `add_one` function, we pass it an `i32` and bind the returned value to `x`: + +\```rust +{{#rustdoc_include file.rs:2}} +\``` +``` + +This would have the same effect as if we had manually inserted the code and hidden all but line 2 using `#`: + +### Inserting runnable Rust files +With the following syntax, you can insert runnable Rust files into your book: +``` +{{#playground file.rs}} +``` + +The path to the Rust file has to be relative from the current source file. + +When play is clicked, the code snippet will be sent to the Rust Playground to be compiled and run. The result is sent back and displayed directly underneath the code. + +### Controlling page `` +A chapter can set a `<title>` that is different from its entry in the table of contents (sidebar) by including a `{{#title ...}}` near the top of the page. + +``` +{{#title My Title}} +``` + +### HTML classes provided by mdBook +#### class="left" and "right" +These classes are provided by default, for inline HTML to float images. + +```html +<img class="right" src="images/rust-logo-blk.svg" alt="The Rust logo"> +``` + +#### class="hidden" +HTML tags with class hidden will not be shown. + +```html +<div class="hidden">This will not be seen.</div> +``` + +#### class="warning" +To make a warning or similar note stand out, wrap it in a warning div. + +```html +<div class="warning"> +``` + +### Math Support +mdBook has optional support for math equations through MathJax. + +To enable MathJax, you need to add the `mathjax-support` key to your `book.toml` under the `output.html` section. + +```toml +[output.html] +mathjax-support = true +``` + +> **Note**: The usual delimiters MathJax uses are not yet supported. You can’t currently use `$$ ... $$` as delimiters and the `\[ ... \]` delimiters need an extra backslash to work. + +#### Inline equations +Inline equations are delimited by `\\(` and `\\)`. So for example, to render the following inline equation you would write the following: + +``` +\\( \int x dx = \frac{x^2}{2} + C \\) +``` + +#### Block equations +Block equations are delimited by `\\[` and `\\]`. To render the following equation + +``` +\\[ \mu = \frac{1}{N} \sum_{i=0} x_i \\] +```