Compare commits

..

2 Commits

Author SHA1 Message Date
exu
9d3683268a Remove old config files for nixos, easyffmpeg 2024-10-06 21:25:44 +02:00
exu
0a705abcca Start moving config stuff into Ansible role 2024-10-06 21:24:57 +02:00
810 changed files with 154548 additions and 2262 deletions

View File

@ -56,6 +56,7 @@ fi
copy_firefox=0 copy_firefox=0
# handle arguments # handle arguments
# TODO
if [[ "$#" -eq 1 ]]; then if [[ "$#" -eq 1 ]]; then
if [[ "$1" == "-f" || "$1" == "--firefox" ]]; then if [[ "$1" == "-f" || "$1" == "--firefox" ]]; then
copy_firefox=1 copy_firefox=1
@ -166,6 +167,7 @@ cp -r "$tempdir/arch-config/.local/" ~/
cp -r "$tempdir/arch-config/.ssh" ~/ cp -r "$tempdir/arch-config/.ssh" ~/
# copy firefox only if "-f" or "--firefox" is given as argument # copy firefox only if "-f" or "--firefox" is given as argument
# TODO
if [[ copy_firefox -eq 1 ]]; then if [[ copy_firefox -eq 1 ]]; then
if [[ -d ~/.mozilla/firefox ]]; then if [[ -d ~/.mozilla/firefox ]]; then
# NOTE check if firefox default-release directory exists. 1 is good, 0 is bad # NOTE check if firefox default-release directory exists. 1 is good, 0 is bad
@ -195,6 +197,7 @@ sudo cp -r "$tempdir/arch-config/etc" /
# Copy pacman config depending on system architecture # Copy pacman config depending on system architecture
# This is required due to differences in available repos between Arch on x86_64 and ALARM for aarch64 # This is required due to differences in available repos between Arch on x86_64 and ALARM for aarch64
# TODO
if [ "$(uname --machine)" == "x86_64" ]; then if [ "$(uname --machine)" == "x86_64" ]; then
sudo cp "/etc/pacman-x86_64.conf" "/etc/pacman.conf" sudo cp "/etc/pacman-x86_64.conf" "/etc/pacman.conf"
fi fi
@ -224,6 +227,8 @@ cat <<EOF
######################################## ########################################
EOF EOF
# TODO continue here
# reload systemd user scripts # reload systemd user scripts
systemctl --user daemon-reload systemctl --user daemon-reload

View File

@ -1,186 +0,0 @@
---
- hosts: localhost
become: yes
tasks:
- name: Enable multilib repository
ansible.builtin.blockinfile:
path: /etc/pacman.conf
prepend_newline: true
block: |
[multilib]
Include = /etc/pacman.d/mirrorlist
- name: Update packages
community.general.pacman:
update_cache: true
upgrade: true
- name: Install official packages
community.general.pacman:
state: present
update_cache: true
# select the lines and use 'M-x sort-lines'
name:
#- gnome-keyring
#- hdparm
#- libaacs
#- libbluray
#- libcdio
#- libdvdcss
#- libdvdnav
#- libdvdread
#- libsecret
#- phonon-qt5-gstreamer
#- seahorse
- aardvark-dns # containers
- amd-ucode # microcode
- ansible # iac
- base-devel # devel stuff
- bind # dnsutils (nslookup, dig)
- btrfs-progs # btrfs
- buildah # containers
- clang
- cmake
- composer
- discord
- dnsmasq # virtualization
- dosfstools # fat
- e2fsprogs # ext4
- easyeffects # audio effects
- edk2-ovmf # virtualization
- emacs-wayland
- exfatprogs # exfat
- f2fs-tools # f2fs
- fd
- ffmpeg # multimedia
- firefox # browser
- firewalld # firewall
- fish # shell
- flatpak # packages
- freetype2 # fonts
- fuse-overlayfs # containers
- fwupd # firmware
- fwupd-efi # firmware
- gdb
- git # code
- git-lfs # code
- hunspell # spelling
- hunspell-de # spelling
- hunspell-en_gb # spelling
- hunspell-en_us # spelling
- hyphen # spelling
- hyphen-de # spelling
- hyphen-en # spelling
- imv # image viewer
- intel-media-driver # VAAPI
- intel-ucode # microcode
- jre-openjdk # java
- just # command runner
- kde-applications-meta # kde
- kid3 # music metadata
- krita
- languagetool
- lib32-mesa # video driver
- lib32-vulkan-intel # video driver
- lib32-vulkan-radeon # video driver
- libreoffice-fresh # office
- libreoffice-fresh-de # office
- libva-intel-driver # VAAPI
- libva-mesa-driver # VAAPI
- libva-utils # VAAPI
- libvirt # virtualization
- linux # kernel
- linux-firmware # kernel
- linux-headers # kernel
- lldb
- lldb-mi
- lutris # games
- man-db # docs
- mesa # video driver
- mesa-vdpau # VDPAU
- mosh # remote shell
- mtools # fat
- mythes-de # thesaurus
- mythes-en # thesaurus
- nerd-fonts # fonts
- nextcloud-client # cloud
- nodejs
- noto-fonts # fonts
- noto-fonts-cjk # fonts
- noto-fonts-emoji # fonts
- ntfs-3g # ntfs
- nvme-cli # nvme ssd
- obs-studio # recording
- okular # pdf
- openssh # remote shell
- opentofu # iac
- otf-font-awesome # fonts
- p7zip # compression
- packagekit-qt6
- pacman-contrib # scripts
- pandoc
- php # code
- piper # mouse
- pipewire # audio
- pipewire-alsa # audio
- pipewire-jack # audio
- pipewire-pulse # audio
- pkgstats
- podman # containers
- power-profiles-daemon # power management
- prettier # code
- pyright # code
- python-black # code
- python-debugpy # code
- python-isort # code
- python-pip # code
- python-pipenv # code
- python-pyflakes # code
- python-pytest # code
- qemu-full # virtualization
- rebuild-detector # packages
- reflector # mirrors
- restic # backup
- ripgrep # doom emacs
- rsync # file sync
- ruby-sass # code
- shellcheck # code
- shfmt # code
- smartmontools # disks
- steam # games
- stress # benchmark
- stylelint # code
- tesseract-data-deu
- tesseract-data-eng
- texlive-core
- thunderbird # email
- tidy
- traceroute # network
- transmission-remote-gtk # torrent
- ttf-fira-code # fonts
- ttf-fira-sans # fonts
- udftools # udf
- unrar # compression
- unzip # compression
- util-linux # various utils
- vdpauinfo # VDPAU
- vim # editor
- virt-manager # virtualization
- vscode-css-languageserver
- vulkan-intel # video driver
- vulkan-radeon # video driver
- wget # network
- wine # windows
- wireguard-tools # vpn
- wireplumber # audio
- xdg-desktop-portal-gtk # flatpak theming
- xdg-user-dirs # standards
- xdg-utils # standards
- xfsprogs # xfs
- yt-dlp
- name: Install config
ansible.builtin.script: ../arch-config/scripts/arch-config.sh
# - dockerfile-language-server # code
# - dockfmt
# - refind-theme-nord # bootmenu

View File

@ -1,3 +0,0 @@
# config-easyffmpeg
This script wraps the ffmpeg command I'm using often so I have to type less.
Probably not useful to anyone else, as it includes some hardcoded values for stuff I never change/want to keep constant in my media.

View File

@ -1,279 +0,0 @@
#!/usr/bin/env python3
import subprocess
import json
import os
import csv
# ffmpeg wrapper
import ffmpy
# argument parsing
import argparse
def valid_duration(filename: str, filetype: str):
"""
Check given file for presence of duration metadata
Parameters:
filename (str): Path to file
filetype (str): Should be INPUT or OUTPUT, to define if the issue appeared after encoding or before
"""
# NOTE check all files for an intact/valid duration
# Valid file example output:
# {
# "format": {
# "duration": "1425.058000"
# }
# }
# Invalid file:
# {
# "format": {
#
# }
# }
ff = ffmpy.FFprobe(
inputs={filename: None},
global_options=("-show_entries format=duration -v quiet -print_format json"),
)
proc = subprocess.Popen(
ff.cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True
)
info = json.loads(proc.stdout.read().rstrip().decode("utf8"))
# write broken files to error.csv files in current directory
if "duration" not in info["format"]:
with open("error.csv", "a", newline="") as file:
write = csv.writer(file)
write.writerow((filetype, filename))
parser = argparse.ArgumentParser(description="")
# Input file
parser.add_argument("-i", "--input-file", required=True, type=str, help="Input file")
# Media title
parser.add_argument("-t", "--title", required=True, type=str, help="Media title")
# Video stuff
parser.add_argument(
"-vc",
"--video-codec",
required=False,
type=str,
help="Output video codec. Defaults to 'copy'",
)
parser.add_argument(
"-crf",
"--crf",
required=False,
type=int,
help="Codec crf. No effect if video codec is 'copy'. Defaults to 20",
)
parser.add_argument(
"-vt", "--video-tune", required=False, type=str, help="Video codec tune"
)
parser.add_argument(
"-vp",
"--video-preset",
required=False,
type=str,
help="Video compression preset. Defaults to 'medium'",
)
# Audio stuff
parser.add_argument(
"-ac",
"--audio-codec",
required=False,
type=str,
help="Output audio codec. Defaults to 'copy'",
)
parser.add_argument(
"-ab",
"--audio-bitrate",
required=False,
type=str,
help="Output audio bitrate. No effect if audio codec is 'copy'. Defaults to '192k'",
)
parser.add_argument(
"-aj",
"--audio-japanese",
required=False,
type=str,
help="Stream identifier for japanese audio",
)
parser.add_argument(
"-ae",
"--audio-english",
required=False,
type=str,
help="Stream identifier for english audio",
)
# Subtitle stuff
parser.add_argument(
"-sn", "--subtitle-name", required=False, type=str, help="Name for subtitles"
)
parser.add_argument(
"-si",
"--subtitle-stream",
required=False,
type=str,
help="Stream identifier for subtitles",
)
"""
parser.add_argument(
"-sd",
"--set-default-subtitle",
required=False,
action="store_true",
help="If passed, set the first subtitle as default",
)
"""
# Output file
parser.add_argument("-o", "--output-file", required=True, type=str, help="Output file")
"""
# Execute or print commands
parser.add_argument(
"-e",
"--execute",
action="store_true",
help="Execute script. If not set, shows the commands that would be run.",
)
"""
args = parser.parse_args()
title = args.title
inputfile = args.input_file
# Default video codec is copy
if args.video_codec is None:
videocodec = "copy"
else:
videocodec = args.video_codec
# Default crf of 20
if args.crf is None:
crf = 20
else:
crf = args.crf
if args.video_tune is None:
tune = ""
else:
tune = "-tune " + args.video_tune
if args.video_preset is None:
preset = "medium"
else:
preset = args.video_preset
# Default audio codec is copy
if args.audio_codec is None:
audiocodec = "copy"
else:
audiocodec = args.audio_codec
# Default audio codec is copy
if args.audio_bitrate is None:
audiobitrate = "192k"
else:
audiobitrate = args.audio_bitrate
outputfile = args.output_file
# Map japanese audio, if set
if args.audio_japanese is None:
japaneseaudio = ""
else:
japaneseaudio = "-map " + args.audio_japanese
# Map english audio, if set
if args.audio_english is None:
englishaudio = ""
else:
englishaudio = "-map " + args.audio_english
# Audiometadata
if args.audio_japanese is None:
audiometa = "-metadata:s:a:0 title='English' -metadata:s:a:0 language=eng"
else:
audiometa = "-metadata:s:a:0 title='Japanese' -metadata:s:a:0 language=jpn -metadata:s:a:1 title='English' -metadata:s:a:1 language=eng"
subtitle = args.subtitle_name
subtitlestream = args.subtitle_stream
"""
if args.set_default_subtitle:
defaultsub = "-disposition:s:0 default"
else:
defaultsub = ""
"""
defaultsub = "-disposition:s:0 default"
"""
# Flag to actually execute command
execute = args.execute
"""
execute = True
# check input file for valid duration
valid_duration(inputfile, "INPUT")
# FIXME Breaks if any field (filename, title, Language) contains quotes: '
# Maps the first video stream, selected audio streams, selected subtitle streams and any attachments to the remuxed/reencoded video
ff = ffmpy.FFmpeg(
inputs={inputfile: None},
outputs={
outputfile: "-metadata title='{title}' -disposition 0 -map 0:t?"
" "
"-c:v {videocodec} -crf {crf} {tune} -preset {preset} -map 0:v:0 -metadata:s:v:0 title='Video' -disposition:v:0 default"
" "
"-c:a {audiocodec} -b:a {audiobitrate} {jpnaudiomap} {engaudiomap}"
" "
"{audiometa} -disposition:a:0 default"
" "
"-c:s copy -map {substream}? -metadata:s:s:0 title='{subtitle}' -metadata:s:s:0 language=eng {defaultsub}"
" ".format(
title=title,
videocodec=videocodec,
crf=crf,
tune=tune,
preset=preset,
audiocodec=audiocodec,
audiobitrate=audiobitrate,
jpnaudiomap=japaneseaudio,
engaudiomap=englishaudio,
audiometa=audiometa,
substream=subtitlestream,
subtitle=subtitle,
defaultsub=defaultsub,
)
},
)
if execute:
ff.run()
else:
print(ff.cmd)
# check output file for valid duration
valid_duration(outputfile, "OUTPUT")
if os.path.isfile("error.csv"):
print(
"Some media might have errors. Please check the error.csv file in this directory"
)

View File

@ -1 +0,0 @@
ffmpy

View File

@ -1 +0,0 @@
../venv/

0
galaxy.yml Normal file
View File

View File

@ -1,13 +0,0 @@
# Normalize my music with ffmpeg and python
[Loudnorm Filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm)
[Filtering Guide](https://trac.ffmpeg.org/wiki/FilteringGuide)
[Two pass loudnorm](https://superuser.com/a/1312885)
`ffmpeg -y -i FalKKonE\ -\ 01\ Aria\ \(From\ \"Berserk:\ The\ Golden\ Age\ Arc\"\).flac -pass 1 -filter:a loudnorm=print_format=json -f flac /dev/null`
`ffmpeg -i FalKKonE\ -\ 01\ Aria\ \(From\ \"Berserk:\ The\ Golden\ Age\ Arc\"\).flac -pass 2 -filter:a loudnorm=I=-30.0:linear=true:measured_I=-4.52:measured_LRA=1.90:measured_thresh=-14.64 -c:a libopus -b:a 320k test441.opus`

View File

@ -1,15 +0,0 @@
gtk-theme-name="Sweet-Dark"
#gtk-icon-theme-name="Sweet-Rainbow"
gtk-font-name="Fira Sans 12"
gtk-cursor-theme-name="capitaine-cursors-light"
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_ICONS
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=1
gtk-menu-images=1
gtk-enable-event-sounds=0
gtk-enable-input-feedback-sounds=0
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle="hintslight"
gtk-xft-rgba="rgb"

View File

@ -1,16 +0,0 @@
[Settings]
gtk-theme-name=Sweet-Dark
#gtk-icon-theme-name=Sweet-Rainbow
gtk-font-name=Fira Sans 12
gtk-cursor-theme-name=capitaine-cursors-light
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_ICONS
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=1
gtk-menu-images=1
gtk-enable-event-sounds=0
gtk-enable-input-feedback-sounds=0
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle=hintslight
gtk-xft-rgba=rgb

View File

@ -1,16 +0,0 @@
[Settings]
gtk-theme-name=Sweet-Dark
#gtk-icon-theme-name=Sweet-Rainbow
gtk-font-name=Fira Sans 12
gtk-cursor-theme-name=capitaine-cursors-light
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_ICONS
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=1
gtk-menu-images=1
gtk-enable-event-sounds=0
gtk-enable-input-feedback-sounds=0
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle=hintslight
gtk-xft-rgba=rgb

View File

@ -1,19 +0,0 @@
# Don't edit this file. Set the NixOS options security.sudo.configFile
# or security.sudo.extraRules instead.
# Set editor to nvim
Defaults editor=/run/current-system/sw/bin/nvim
# Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic.
Defaults env_keep+=SSH_AUTH_SOCK
# "root" is allowed to do anything.
root ALL=(ALL:ALL) SETENV: ALL
# extraRules
%wheel ALL=(ALL:ALL) SETENV: ALL
# Keep terminfo database for root and %wheel.
Defaults:root,%wheel env_keep+=TERMINFO_DIRS
Defaults:root,%wheel env_keep+=TERMINFO

View File

@ -1,203 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running `nixos-help`).
{ config, pkgs, ... }:
let
user = "exu";
hostname = "nixos";
in
{
imports = [
./hardware-configuration.nix
./system-packages.nix
./home-manager.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader = {
systemd-boot = {
enable = true;
configurationLimit = 10;
};
efi = {
canTouchEfiVariables = true;
};
};
# Enable completions by nix
programs.fish.enable = true;
# set neovim as default
programs.neovim.enable = true;
programs.neovim.defaultEditor = true;
environment = {
shells = [ pkgs.fish ];
variables = {
EDITOR = "nvim";
VISUAL = "nvim";
SUDO_EDITOR = "nvim";
};
# remove nano from default packages
defaultPackages = [ pkgs.perl pkgs.rsync pkgs.strace ];
etc = {
# gtk theme configuration
# src: https://unix.stackexchange.com/questions/632879/how-to-set-a-system-wide-gtk-theme-in-nixos
"gtk-2.0/gtkrc".source = ./config/gtk-2.0/gtkrc;
"gtk-3.0/settings.ini".source = ./config/gtk-3.0/settings.ini;
"gtk-4.0/settings.ini".source = ./config/gtk-4.0/settings.ini;
};
};
networking.hostName = "${hostname}"; # Define your hostname.
# Pick only one of the below networking options.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
# disable global firewall for the time being
networking.firewall.enable = false;
# Set your time zone.
time.timeZone = "Europe/Zurich";
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
i18n.defaultLocale = "de_CH.UTF-8";
console = {
keyMap = "de_CH-latin1";
};
# Enable the X11 windowing system.
services.xserver = {
enable = true;
displayManager.defaultSession = "hyprland";
#displayManager.lightdm = {
# enable = true;
# greeters.gtk.enable = true;
#};
displayManager.gdm = {
enable = true;
wayland = true;
};
};
# enable gvfs service
services.gvfs.enable = true;
# Hyprland
security.polkit.enable = true;
programs.hyprland = {
enable = true;
};
# sudoers file
security.sudo.configFile = (builtins.readFile ./config/sudoers);
# Configure keymap in X11
services.xserver.layout = "ch";
# keyring
services.gnome.gnome-keyring.enable = true;
security.pam.services.${user}.enableGnomeKeyring = true;
programs.seahorse.enable = true;
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable Pipewire
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
#jack.enable = true;
};
# Enable touchpad support (enabled default in most desktopManager).
services.xserver.libinput.enable = true;
# root config
users.users.root = {
shell = pkgs.fish;
};
# User config
users.users.${user} = {
isNormalUser = true;
extraGroups = [ "wheel" "video" "audio" "networkmanager" "lp" "scanner" ];
initialPassword = "pass";
shell = pkgs.fish;
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Enable thumbnailer service
services.tumbler.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# system.copySystemConfiguration = true;
# BTRFS options
fileSystems = {
"/".options = [ "compress=zstd" ];
"/home".options = [ "compress=zstd" ];
"/nix".options = [ "compress=zstd" "noatime" ];
"/swap".options = [ "noatime" ];
};
# Swapfile
swapDevices = [ { device = "/swap/swapfile"; } ];
# Enable automatic package upgrades
#system.autoUpgrade = {
# enable = true;
# channel = "https://nixos.org/channels/nixos-unstable";
#};
# Enable automatic garbage collection
nix = {
settings.auto-optimise-store = true;
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It's perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment?
}

View File

@ -1,141 +0,0 @@
{ config, pkgs, ... }:
let
user = "exu";
hostname = "nixos";
in
{
imports = [
<home-manager/nixos>
];
# root home
home-manager.users.root = { pkgs, ... }: {
home.username = "root";
home.homeDirectory = "/root";
home.stateVersion = "22.11";
home.packages = with pkgs; [
kitty # terminfo support
];
imports = [
./home-manager/hyprland.nix
./home-manager/fish.nix
];
};
# keep everything using home manager within this block
home-manager.users.${user} = { pkgs, ... }: {
home.username = "${user}";
home.homeDirectory = "/home/${user}";
home.stateVersion = "22.11";
home.packages = with pkgs; [
firefox # browser
kitty # terminal
pciutils # lspci command
git # git
emacs # emacs editor
emacsPackages.doom # doom emacs configuration
acpilight # controlling laptop monitor backlight
networkmanagerapplet # network configuration
wofi # app launcher (wayland replacement for rofi)
fish # fish shell
libnotify # notifications
mako # notification daemon
xdg-desktop-portal-hyprland # desktop portal (hyprland fork)
#neovim # text editor
yt-dlp # video downloader
#sweet # gtk theme
waybar # status bar
playerctl # mpris
xfce.thunar # file manager
xfce.thunar-archive-plugin # manage archives in thunar
#xfce.xfce4-settings # xfce settings manager
xfce.xfconf # xfce config storage
];
imports = [
./home-manager/hyprland.nix
./home-manager/fish.nix
];
systemd.user = {
# user services
services = {
# ssh-agent user service
ssh-agent = {
Unit = {
Description = "SSH key agent";
};
Service = {
Type = "simple";
Environment = "SSH_AUTH_SOCK=%t/ssh-agent.socket";
ExecStart = "/run/current-system/sw/bin/ssh-agent -D -a $SSH_AUTH_SOCK";
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
# user environment variables
sessionVariables = {
SSH_AUTH_SOCK = "/run/user/1000/ssh-agent.socket";
};
};
# git configuration
programs.git = {
enable = true;
extraConfig = {
init = {
defaultBranch = "main";
};
user = {
name = "RealStickman";
email = "mrc@frm01.net";
};
gitlab = {
user = "RealStickman";
};
github = {
user = "RealStickman";
};
};
};
programs.waybar = {
enable = true;
settings = {
mainBar = (builtins.fromJSON (builtins.readFile ./home-manager/config/waybar/config.json));
};
style = (builtins.readFile ./home-manager/config/waybar/style.css);
};
home.file = {
# Scripts
".scripts/waybar/player-mpris-tail.py" = {
source = ./home-manager/scripts/waybar/player-mpris-tail.py;
executable = true;
};
# Thunar configuration
".config/Thunar" = {
source = ./home-manager/config/Thunar;
#recursive = true;
};
# templates
".config/Vorlagen" = {
source = ./home-manager/config/Vorlagen;
#recursive = true;
};
# xfce4 settings
".config/xfce4".source = ./home-manager/config/xfce4;
# xdg user dirs
".config/user-dirs.dirs".source = ./home-manager/config/user-dirs.dirs;
# xdg user locales
".config/user-dirs.locale".source = ./home-manager/config/user-dirs.locale;
};
services.mako.enable = true;
};
}

View File

@ -1,132 +0,0 @@
; thunar GtkAccelMap rc-file -*- scheme -*-
; this file is an automated accelerator map dump
;
; (gtk_accel_path "<Actions>/ThunarBookmarks/fab0a703c3165b9ea6d4a2e40b570272" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-type" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/134cf305a61c72f784680835c93c28fd" "")
; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-last-modified" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/cut" "<Primary>x")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-size" "")
; (gtk_accel_path "<Actions>/ThunarWindow/file-menu" "")
(gtk_accel_path "<Actions>/ThunarWindow/close-tab" "<Primary>q")
; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-size" "")
(gtk_accel_path "<Actions>/ThunarWindow/new-window" "")
; (gtk_accel_path "<Actions>/ThunarWindow/clear-directory-specific-settings" "")
(gtk_accel_path "<Actions>/ThunarWindow/close-window" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/ac3bbb1429c4180d34b90e935eaeaa7b" "")
(gtk_accel_path "<Actions>/ThunarWindow/open-parent" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-side-pane-menu" "")
; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-size-in-bytes" "")
; (gtk_accel_path "<Actions>/ThunarWindow/switch-previous-tab" "<Primary>Page_Up")
; (gtk_accel_path "<Actions>/ThunarBookmarks/3cb76eced52269e016bf542f6d20d431" "")
(gtk_accel_path "<Actions>/ThunarActionManager/open" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-ascending" "")
; (gtk_accel_path "<Actions>/ThunarWindow/toggle-split-view" "F3")
; (gtk_accel_path "<Actions>/ThunarActionManager/copy-2" "<Primary>Insert")
; (gtk_accel_path "<Actions>/ThunarActionManager/trash-delete" "Delete")
; (gtk_accel_path "<Actions>/ThunarWindow/open-recent" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-configure-toolbar" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/forward" "<Alt>Right")
; (gtk_accel_path "<Actions>/ThunarBookmarks/9f9804d3a8acb92d2796c0e9ee791891" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/restore" "")
(gtk_accel_path "<Actions>/ThunarWindow/open-location-alt" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/0d63283611773acfd219c84ae028d009" "")
(gtk_accel_path "<Actions>/ThunarStandardView/select-by-pattern" "")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-out-alt" "<Primary>minus")
; (gtk_accel_path "<Actions>/ThunarWindow/open-file-menu" "F10")
(gtk_accel_path "<Actions>/ThunarWindow/contents" "")
; (gtk_accel_path "<Actions>/ThunarWindow/show-highlight" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-descending" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-name" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/select-all-files" "<Primary>a")
; (gtk_accel_path "<Actions>/ThunarActionManager/execute" "")
(gtk_accel_path "<Actions>/ThunarStandardView/properties" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/cut-2" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-dtime" "")
; (gtk_accel_path "<Actions>/ThunarWindow/switch-next-tab" "<Primary>Page_Down")
; (gtk_accel_path "<Actions>/ThunarActionManager/paste-2" "<Shift>Insert")
; (gtk_accel_path "<Actions>/ThunarWindow/open-templates" "")
; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-filetype" "")
(gtk_accel_path "<Actions>/ThunarWindow/close-all-windows" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/create-document" "")
; (gtk_accel_path "<Actions>/ThunarWindow/detach-tab" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/310a68ed4e8d7e3153dbac6fd6f8509e" "")
; (gtk_accel_path "<Actions>/ThunarWindow/cancel-search" "Escape")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-in-alt2" "<Primary>equal")
(gtk_accel_path "<Actions>/ThunarShortcutsPane/sendto-shortcuts" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/undo" "<Primary>z")
; (gtk_accel_path "<Actions>/ThunarWindow/reload-alt" "F5")
(gtk_accel_path "<Actions>/ThunarActions/uca-action-1666515885637912-1" "<Primary>Return")
; (gtk_accel_path "<Actions>/ThunarStandardView/toggle-sort-order" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-location-selector-entry" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/paste" "<Primary>v")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-in-alt1" "<Primary>plus")
(gtk_accel_path "<Actions>/ThunarWindow/view-menubar" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/back" "<Alt>Left")
; (gtk_accel_path "<Actions>/ThunarWindow/open-desktop" "")
(gtk_accel_path "<Actions>/ThunarWindow/view-as-detailed-list" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/restore-show" "")
; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-display-name" "")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-out" "<Primary>KP_Subtract")
; (gtk_accel_path "<Actions>/ThunarBookmarks/d560a9adc56f1eaa2739d7e989051c36" "")
; (gtk_accel_path "<Actions>/ThunarWindow/sendto-menu" "")
; (gtk_accel_path "<Actions>/ThunarWindow/go-menu" "")
; (gtk_accel_path "<Actions>/ThunarWindow/remove-from-recent" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/open-with-other" "")
(gtk_accel_path "<Actions>/ThunarStandardView/invert-selection" "<Primary>i")
(gtk_accel_path "<Actions>/ThunarWindow/view-side-pane-shortcuts" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-location-selector-menu" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-mtime" "")
; (gtk_accel_path "<Actions>/ThunarWindow/edit-menu" "")
; (gtk_accel_path "<Actions>/ThunarWindow/reload" "<Primary>r")
; (gtk_accel_path "<Actions>/ThunarActionManager/copy" "<Primary>c")
; (gtk_accel_path "<Actions>/ThunarActionManager/move-to-trash" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/unselect-all-files" "Escape")
; (gtk_accel_path "<Actions>/ThunarActionManager/delete-3" "<Shift>KP_Delete")
(gtk_accel_path "<Actions>/ThunarWindow/toggle-side-pane" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/bd09eece7395e751859c8153dca05324" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/arrange-items-menu" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/ef49cad9a2b186bac59b8de045e0f5d4" "")
; (gtk_accel_path "<Actions>/ThunarWindow/open-computer" "")
; (gtk_accel_path "<Actions>/ThunarWindow/bookmarks-menu" "")
; (gtk_accel_path "<Actions>/ThunarWindow/toggle-image-preview" "")
(gtk_accel_path "<Actions>/ThunarWindow/view-as-icons" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/delete-2" "<Shift>Delete")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-in" "<Primary>KP_Add")
; (gtk_accel_path "<Actions>/ThunarStandardView/configure-columns" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/rename" "F2")
; (gtk_accel_path "<Actions>/ThunarWindow/open-location" "<Primary>l")
(gtk_accel_path "<Actions>/ThunarWindow/view-as-compact-list" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-menu" "")
; (gtk_accel_path "<Actions>/ThunarWindow/search" "<Primary>f")
; (gtk_accel_path "<Actions>/ThunarWindow/new-tab" "<Primary>t")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-reset" "<Primary>KP_0")
; (gtk_accel_path "<Actions>/ThunarWindow/contents/help-menu" "")
(gtk_accel_path "<Actions>/ThunarActionManager/open-in-new-tab" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-location-selector-buttons" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/redo" "<Primary><Shift>z")
; (gtk_accel_path "<Actions>/ThunarWindow/open-trash" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/7d2c0d8f2cb46dda0c77c334948613d9" "")
(gtk_accel_path "<Actions>/ThunarActionManager/open-in-new-window" "")
; (gtk_accel_path "<Actions>/ThunarWindow/view-statusbar" "")
; (gtk_accel_path "<Actions>/ThunarBookmarks/356c14bf86880b16a82a896aac1ea75d" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/open-location" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/duplicate" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/trash-delete-2" "KP_Delete")
; (gtk_accel_path "<Actions>/ThunarBookmarks/efbd1f6870be1a5a9ee9ba157935b388" "")
(gtk_accel_path "<Actions>/ThunarActions/uca-action-1666516933235505-2" "<Primary>f")
; (gtk_accel_path "<Actions>/ThunarStandardView/create-folder" "<Primary><Shift>n")
(gtk_accel_path "<Actions>/ThunarWindow/open-home" "")
(gtk_accel_path "<Actions>/ThunarWindow/show-hidden" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/set-default-app" "")
; (gtk_accel_path "<Actions>/ThunarWindow/empty-trash" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/back-alt" "BackSpace")
; (gtk_accel_path "<Actions>/ThunarWindow/preferences" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/delete" "")
(gtk_accel_path "<Actions>/ThunarWindow/view-side-pane-tree" "")
; (gtk_accel_path "<Actions>/ThunarWindow/open-file-system" "")
; (gtk_accel_path "<Actions>/ThunarWindow/open-network" "")
; (gtk_accel_path "<Actions>/ThunarActionManager/sendto-desktop" "")
; (gtk_accel_path "<Actions>/ThunarStandardView/make-link" "")
; (gtk_accel_path "<Actions>/ThunarWindow/zoom-reset-alt" "<Primary>0")
; (gtk_accel_path "<Actions>/ThunarWindow/about" "")

View File

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<icon>folder</icon>
<name>Als root öffnen</name>
<submenu></submenu>
<unique-id>1673031093097554-1</unique-id>
<command>gksu thunar %f</command>
<description>Verzeichnis als root-Nutzer öffnen</description>
<range>*</range>
<patterns>*</patterns>
<directories/>
</action>
<action>
<icon>utilities-terminal</icon>
<name>Terminal öffnen</name>
<submenu></submenu>
<unique-id>1666515885637912-1</unique-id>
<command>for f in %F; do if [ -d &quot;$f&quot; ]; then kitty &quot;$f&quot;; elif [ -z &quot;$default&quot; ]; then default=1; kitty; fi done</command>
<description>Terminal im gewählten Ordner öffnen</description>
<range></range>
<patterns>*</patterns>
<startup-notify/>
<directories/>
<audio-files/>
<image-files/>
<other-files/>
<text-files/>
<video-files/>
</action>
<action>
<icon>preferences-system-search</icon>
<name>Suchen</name>
<submenu></submenu>
<unique-id>1666516933235505-2</unique-id>
<command>catfish --path=%f</command>
<description>Dateien und Ordner suchen</description>
<range></range>
<patterns>*</patterns>
<startup-notify/>
<directories/>
</action>
<action>
<icon>link</icon>
<name>Symlink erstellen</name>
<submenu></submenu>
<unique-id>1676990164646243-1</unique-id>
<command>ln -Ts %f %n&quot; (symlink)&quot;</command>
<description>Symbolischen Link erstellen</description>
<range>*</range>
<patterns>*</patterns>
<directories/>
<audio-files/>
<image-files/>
<other-files/>
<text-files/>
<video-files/>
</action>
</actions>

View File

@ -1,35 +0,0 @@
#vi mode for fish
#fish_vi_key_bindings
fish_default_key_bindings
# change greeting
set fish_greeting "Good Morning! Nice day for fishing ain't it! Hu ha!"
# Info:
# https://fishshell.com/docs/current/index.html#variables-for-changing-highlighting-colors
set fish_color_normal blue
set fish_color_command blue
set fish_color_quote bryellow
set fish_color_redirection
set fish_color_end brred
set fish_color_error red
set fish_color_param brblue
set fish_color_comment white
set fish_color_selection brcyan
set fish_color_search_match magenta
set fish_color_operator blue
set fish_color_escape green
set fish_color_autosuggestion brwhite
set fish_color_host_remote brwhite
set fish_color_cancel brred
# used in prompt
set fish_color_user --bold red
set fish_color_separator --bold yellow
set fish_color_host cyan
set fish_color_cwd yellow
# environment variables
# SSH Agent
set SSH_AUTH_SOCK "$XDG_RUNTIME_DIR/ssh-agent.socket"
export SSH_AUTH_SOCK

View File

@ -1,32 +0,0 @@
set -l last_pipestatus $pipestatus
set -lx __fish_last_status $status # Export for __fish_print_pipestatus.
set -l normal (set_color normal)
# Color the prompt differently when we're root
set -l color_cwd $fish_color_cwd
set -l suffix '>'
#if functions -q fish_is_root_user; and fish_is_root_user
# if set -q fish_color_cwd_root
# set color_cwd $fish_color_cwd_root
# end
# set suffix '#'
#end
# If we're running via SSH, change the host color.
set -l color_host $fish_color_host
#if set -q SSH_TTY
# set color_host $fish_color_host_remote
#end
# Write pipestatus
# If the status was carried over (e.g. after `set`), don't bold it.
set -l bold_flag --bold
set -q __fish_prompt_status_generation; or set -g __fish_prompt_status_generation $status_generation
if test $__fish_prompt_status_generation = $status_generation
set bold_flag
end
set __fish_prompt_status_generation $status_generation
set -l prompt_status (__fish_print_pipestatus "[" "]" "|" (set_color $fish_color_status) (set_color $bold_flag $fish_color_status) $last_pipestatus)
echo -n -s (set_color $fish_color_user) "$USER" $normal (set_color $fish_color_separator) @ $normal (set_color $color_host) (prompt_hostname) $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (fish_vcs_prompt) $normal " "$prompt_status $suffix " "
#echo -n -s (set_color --bold red) "$USER" $normal (set_color --bold yellow) @ $normal (set_color cyan) (prompt_hostname) $normal ' ' (set_color yellow) (prompt_pwd) $normal (fish_vcs_prompt) $normal " "$prompt_status $suffix " "

View File

@ -1,205 +0,0 @@
#
# Please note not all available settings / options are set here.
# For a full list, see the wiki
#
# See https://wiki.hyprland.org/Configuring/Monitors/
monitor=,preferred,auto,auto
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
# Execute your favorite apps at launch
# exec-once = waybar & hyprpaper & firefox
# Source a file (multi-file configs)
# source = ~/.config/hypr/myColors.conf
# Some default env vars.
env = XCURSOR_SIZE,24
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
#kb_layout = de_CH-latin1
kb_layout = ch
kb_variant =
kb_model =
kb_options =
kb_rules =
follow_mouse = 1
touchpad {
natural_scroll = false
}
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}
general {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
gaps_in = 0
gaps_out = 0
border_size = 2
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
col.inactive_border = rgba(595959aa)
layout = dwindle
}
decoration {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
#rounding = 10
blur = yes
blur_size = 3
blur_passes = 1
blur_new_optimizations = on
drop_shadow = yes
shadow_range = 4
shadow_render_power = 3
col.shadow = rgba(1a1a1aee)
}
animations {
enabled = yes
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
animation = windows, 1, 7, myBezier
animation = windowsOut, 1, 7, default, popin 80%
animation = border, 1, 10, default
animation = borderangle, 1, 8, default
animation = fade, 1, 7, default
animation = workspaces, 1, 6, default
}
dwindle {
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = yes # you probably want this
}
master {
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
new_is_master = true
}
gestures {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
workspace_swipe = off
}
# Example per-device config
# See https://wiki.hyprland.org/Configuring/Keywords/#executing for more
#device:epic-mouse-v1 {
# sensitivity = -0.5
#}
# Example windowrule v1
# windowrule = float, ^(kitty)$
# Example windowrule v2
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
$mod = SUPER
# Startup stuff
exec-once = mako
exec-once = waybar
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = CTRL_ALT, RETURN, exec, kitty # terminal
bind = CTRL_ALT, A, exec, wofi --show drun # app launcher
bind = CTRL_ALT, f, exec, firefox # browser
bind = CTRL_ALT, e, exec, emacs # editor
bind = CTRL_ALT, t, exec, thunar # file manager
bind = $mod, Q, killactive, # close window
# logout
bind = ALT_$mod, L, exit,
# bind power management submap
bind = $mod, x, submap, | (S)hutdown, (R)eboot, (E)xit |
# power management submap
submap = | (S)hutdown, (R)eboot, (E)xit |
# lock
# TODO
# logout
bind = , e, exit,
# poweroff
bind = , s, exec, systemctl poweroff
# reboot
bind = , r, exec, systemctl reboot
# suspend
# TODO
# hibernate
# TODO
# use reset to go back to the global submap
bind=,escape,submap,reset
# will reset the submap, meaning end the current one and return to the global one
submap=reset
#bind = $mod, Q, exec, kitty
#bind = $mod, C, killactive,
#bind = $mod, M, exit,
#bind = $mod, E, exec, dolphin
#bind = $mod, V, togglefloating,
#bind = $mod, R, exec, wofi --show drun
#bind = $mod, P, pseudo, # dwindle
#bind = $mod, J, togglesplit, # dwindle
# Move focus with $mod + arrow keys
bind = $mod, left, movefocus, l
bind = $mod, right, movefocus, r
bind = $mod, up, movefocus, u
bind = $mod, down, movefocus, d
# Move focus with $mod + hjkl
bind = $mod, H, movefocus, l
bind = $mod, L, movefocus, r
bind = $mod, K, movefocus, u
bind = $mod, J, movefocus, d
# Switch workspaces with mainMod + [0-9]
bind = $mod, 1, workspace, 1
bind = $mod, 2, workspace, 2
bind = $mod, 3, workspace, 3
bind = $mod, 4, workspace, 4
bind = $mod, 5, workspace, 5
bind = $mod, 6, workspace, 6
bind = $mod, 7, workspace, 7
bind = $mod, 8, workspace, 8
bind = $mod, 9, workspace, 9
bind = $mod, 0, workspace, 10
# Move active window to a workspace with mainMod + SHIFT + [0-9]
bind = $mod SHIFT, 1, movetoworkspace, 1
bind = $mod SHIFT, 2, movetoworkspace, 2
bind = $mod SHIFT, 3, movetoworkspace, 3
bind = $mod SHIFT, 4, movetoworkspace, 4
bind = $mod SHIFT, 5, movetoworkspace, 5
bind = $mod SHIFT, 6, movetoworkspace, 6
bind = $mod SHIFT, 7, movetoworkspace, 7
bind = $mod SHIFT, 8, movetoworkspace, 8
bind = $mod SHIFT, 9, movetoworkspace, 9
bind = $mod SHIFT, 0, movetoworkspace, 10
# Scroll through existing workspaces with $mod + scroll
bind = $mod, mouse_down, workspace, e+1
bind = $mod, mouse_up, workspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mod, mouse:272, movewindow
bindm = $mod, mouse:273, resizewindow

View File

@ -1,70 +0,0 @@
{
"layer": "top",
"position": "bottom",
"height": 25,
"spacing": 10,
"modules-left": ["wlr/workspaces", "hyprland/window", "hyprland/submap"],
"modules-center": ["clock"],
"modules-right": ["mpris", "idle_inhibitor", "battery", "tray"],
"wlr/workspaces": {
"format": "{name}: {icon}",
"format-icons": {
"urgent": "",
"active": "",
"default": ""
},
"sort-by-number": true
},
"hyprland/window": {
"format": "{}",
"separate-outputs": true
},
"hyprland/submap": {
"format": "{}",
"tooltip": false
},
"mpris": {
"format": "{status_icon} {dynamic}",
"format-paused": "{status_icon} <i>{dynamic}</i>",
"status-icons": {
"playing": "▶",
"paused": "⏸"
}
},
"battery": {
"bat": "BAT0",
"states": {
"warning": 30,
"critical": 15
},
"format": "{capacity}% {icon}",
"format-charging": "{capacity}% ",
"format-plugged": "{capacity}% ",
"format-alt": "{time} {icon}",
"format-icons": ["", "", "", "", ""]
},
"clock": {
"timezone": "Europe/Zurich",
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
"format-alt": "{:%Y-%m-%d}"
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "",
"deactivated": ""
}
},
"tray": {
"icon-size": 21,
"spacing": 10
},
"custom/mpris": {
"exec": "~/.scripts/polybar/player-mpris-tail.py -f '{icon} {:artist:t10:{artist}:}{:artist: - :}{:t25:{title}:}'",
"on-click": "~/.scripts/polybar/player-mpris-tail.py play-pause &",
"on-click-middle": "~/.scripts/polybar/player-mpris-tail.py next &",
"on-click-right": "~/.scripts/polybar/player-mpris-tail.py previous &"
}
}

View File

@ -1,145 +0,0 @@
* {
/* `otf-font-awesome` is required to be installed for icons */
font-family: FontAwesome, Fira Sans, sans-serif;
font-size: 12px;
padding-left: 5px;
padding-right: 5px;
}
window#waybar {
/*background-color: rgba(43, 48, 59, 0.5);*/
background-color: rgba(51, 2, 47, 0.6);
border: 0px;
border-top: 2px solid rgba(93, 4, 86, 0.8);
/*border-bottom: 3px solid rgba(100, 114, 125, 0.5);*/
color: #f2daf0;
/*color: #ffffff;*/
transition-property: background-color;
transition-duration: 0.5s;
}
window#waybar.hidden {
opacity: 0.2;
}
/*
window#waybar.empty {
background-color: transparent;
}
window#waybar.solo {
background-color: #FFFFFF;
}
*/
button {
/* Use box-shadow instead of border so the text isn't offset */
box-shadow: inset 0 -3px transparent;
/* Avoid rounded borders under each button name */
border: none;
border-radius: 0;
}
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
button:hover {
background: inherit;
box-shadow: inset 0 -3px #ffffff;
}
#workspaces button {
padding: 0 5px;
background-color: transparent;
color: #ffffff;
}
#workspaces button:hover {
background: rgba(0, 0, 0, 0.2);
}
#workspaces button.focused {
background-color: #64727d;
box-shadow: inset 0 -3px #ffffff;
}
#workspaces button.urgent {
background-color: #eb4d4b;
}
#mode {
background-color: #64727d;
border-bottom: 3px solid #ffffff;
}
#clock,
#battery,
#tray,
#mode,
#idle_inhibitor,
#window,
#workspaces {
margin: 0 4px;
}
/* If workspaces is the leftmost module, omit left margin */
.modules-left > widget:first-child > #workspaces {
margin-left: 0;
}
/* If workspaces is the rightmost module, omit right margin */
.modules-right > widget:last-child > #workspaces {
margin-right: 0;
}
#clock {
background-color: #5d0456;
}
#battery {
background-color: #5d0456;
color: #f2daf0;
/*color: #000000;*/
}
@keyframes blink {
to {
background-color: #f2daf0;
color: #000000;
}
}
#battery.critical:not(.charging) {
background-color: #ca3232;
color: #f2daf0;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
label:focus {
background-color: #000000;
}
/*
#tray {
background-color: #2980b9;
}
#tray > .passive {
-gtk-icon-effect: dim;
}
#tray > .needs-attention {
-gtk-icon-effect: highlight;
background-color: #eb4d4b;
}
*/
#idle_inhibitor {
background-color: #5d0456;
}
#idle_inhibitor.activated {
background-color: #f2daf0;
color: #5d0456;
}

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<channel name="thunar" version="1.0">
<property name="last-view" type="string"
value="ThunarDetailsView" />
<property name="last-icon-view-zoom-level" type="string"
value="THUNAR_ZOOM_LEVEL_400_PERCENT" />
<property name="last-separator-position" type="int"
value="189" />
<property name="last-show-hidden" type="bool" value="true" />
<property name="last-window-width" type="int" value="956" />
<property name="last-window-height" type="int" value="1056" />
<property name="last-window-maximized" type="bool"
value="false" />
<property name="last-details-view-zoom-level" type="string"
value="THUNAR_ZOOM_LEVEL_38_PERCENT" />
<property name="last-details-view-column-widths" type="string"
value="50,155,155,148,150,237,50,79,370,379,50,92,50,775" />
<property name="misc-date-style" type="string"
value="THUNAR_DATE_STYLE_ISO" />
<property name="misc-single-click" type="bool" value="false" />
<property name="misc-show-delete-action" type="bool"
value="true" />
<property name="misc-full-path-in-title" type="bool"
value="true" />
<property name="last-location-bar" type="string"
value="ThunarLocationEntry" />
<property name="last-sort-column" type="string"
value="THUNAR_COLUMN_NAME" />
<property name="last-sort-order" type="string"
value="GTK_SORT_ASCENDING" />
<property name="misc-recursive-permissions" type="string"
value="THUNAR_RECURSIVE_PERMISSIONS_ALWAYS" />
<property name="last-details-view-visible-columns" type="string"
value="THUNAR_COLUMN_DATE_MODIFIED,THUNAR_COLUMN_NAME,THUNAR_COLUMN_SIZE,THUNAR_COLUMN_TYPE" />
<property name="misc-folders-first" type="bool" value="true" />
<property name="last-side-pane" type="string"
value="ThunarShortcutsPane" />
<property name="last-menubar-visible" type="bool" value="true" />
<property name="misc-confirm-close-multiple-tabs" type="bool"
value="false" />
<property name="default-view" type="string"
value="ThunarDetailsView" />
<property name="misc-middle-click-in-tab" type="bool"
value="true" />
<property name="misc-volume-management" type="bool"
value="false" />
<property name="misc-parallel-copy-mode" type="string"
value="THUNAR_PARALLEL_COPY_MODE_ONLY_LOCAL" />
<property name="misc-transfer-verify-file" type="string"
value="THUNAR_VERIFY_FILE_MODE_REMOTE" />
<property name="last-splitview-separator-position" type="int"
value="717" />
<property name="misc-folder-item-count" type="string"
value="THUNAR_FOLDER_ITEM_COUNT_ALWAYS" />
<property name="misc-transfer-use-partial" type="string"
value="THUNAR_USE_PARTIAL_MODE_REMOTE" />
</channel>

View File

@ -1,39 +0,0 @@
{ config, ... }:
{
programs.fish = {
enable = true;
interactiveShellInit = (builtins.readFile ./config/fish/conf.d/interactive.fish);
shellAliases = {
# open emacs in terminal
emacs = "emacs --no-window-system";
# colored wget output
wget = "wget -c";
# copy terminfo to remote server with kitty
sshkp = "kitty +kitten ssh use-python";
sshk = "kitty +kitten ssh";
# colored ls output
ls = "ls --color=auto";
# kill all wine processes
killwine = "ls -l /proc/*/exe 2>/dev/null | grep -E 'wine(64)?-preloader|wineserver' | perl -pe 's;^.*/proc/(\d+)/exe.*$;$1;g;' | xargs -n 1 kill";
# colored grep output
grep = "grep --color=auto";
# yt-dlp aliases
# best audio
yta-best = "yt-dlp -f bestaudio --extract-audio ";
# best video
ytv-best = "yt-dlp -f bestvideo+bestaudio ";
# download video including metadata from youtube
ytv-metadata = "yt-dlp -f bestvideo+bestaudio --add-metadata --parse-metadata \"%(title)s:%(meta_title)s\" --parse-metadata \"%(uploader)s:%(meta_artist)s\" --write-info-json --write-thumbnail --embed-thumbnail --embed-subs --sub-langs \"en.*\" --merge-output-format mkv ";
# activate venv called "venv" in the local directory
activate = "source venv/bin/activate.fish";
# lsblk including file system type
lsblkf = "lsblk -o NAME,FSTYPE,LABEL,MOUNTPOINT,SIZE,MODEL,UUID";
# color ip command
ip = "ip -c";
};
functions = {
fish_prompt = (builtins.readFile ./config/fish/functions/fish_prompt.fish);
};
};
}

View File

@ -1,20 +0,0 @@
{pkgs, ...}:
let
flake-compat = builtins.fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz";
hyprland = (import flake-compat {
src = builtins.fetchTarball "https://github.com/hyprwm/Hyprland/archive/master.tar.gz";
}).defaultNix;
in
{
imports = [
hyprland.homeManagerModules.default
];
wayland.windowManager.hyprland = {
enable = true;
extraConfig = (builtins.readFile ./config/hypr/hyprland.conf);
};
}

View File

@ -1,530 +0,0 @@
#!/usr/bin/env python3
import sys
import dbus
import os
from operator import itemgetter
import argparse
import re
from urllib.parse import unquote
import time
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
DBusGMainLoop(set_as_default=True)
FORMAT_STRING = '{icon} {artist} - {title}'
FORMAT_REGEX = re.compile(r'(\{:(?P<tag>.*?)(:(?P<format>[wt])(?P<formatlen>\d+))?:(?P<text>.*?):\})', re.I)
FORMAT_TAG_REGEX = re.compile(r'(?P<format>[wt])(?P<formatlen>\d+)')
SAFE_TAG_REGEX = re.compile(r'[{}]')
class PlayerManager:
def __init__(self, blacklist = [], connect = True):
self.blacklist = blacklist
self._connect = connect
self._session_bus = dbus.SessionBus()
self.players = {}
self.print_queue = []
self.connected = False
self.player_states = {}
self.refreshPlayerList()
if self._connect:
self.connect()
loop = GLib.MainLoop()
try:
loop.run()
except KeyboardInterrupt:
print("interrupt received, stopping…")
def connect(self):
self._session_bus.add_signal_receiver(self.onOwnerChangedName, 'NameOwnerChanged')
self._session_bus.add_signal_receiver(self.onChangedProperties, 'PropertiesChanged',
path = '/org/mpris/MediaPlayer2',
sender_keyword='sender')
def onChangedProperties(self, interface, properties, signature, sender = None):
if sender in self.players:
player = self.players[sender]
# If we know this player, but haven't been able to set up a signal handler
if 'properties_changed' not in player._signals:
# Then trigger the signal handler manually
player.onPropertiesChanged(interface, properties, signature)
else:
# If we don't know this player, get its name and add it
bus_name = self.getBusNameFromOwner(sender)
if bus_name is None:
return
self.addPlayer(bus_name, sender)
player = self.players[sender]
player.onPropertiesChanged(interface, properties, signature)
def onOwnerChangedName(self, bus_name, old_owner, new_owner):
if self.busNameIsAPlayer(bus_name):
if new_owner and not old_owner:
self.addPlayer(bus_name, new_owner)
elif old_owner and not new_owner:
self.removePlayer(old_owner)
else:
self.changePlayerOwner(bus_name, old_owner, new_owner)
def getBusNameFromOwner(self, owner):
player_bus_names = [ bus_name for bus_name in self._session_bus.list_names() if self.busNameIsAPlayer(bus_name) ]
for player_bus_name in player_bus_names:
player_bus_owner = self._session_bus.get_name_owner(player_bus_name)
if owner == player_bus_owner:
return player_bus_name
def busNameIsAPlayer(self, bus_name):
return bus_name.startswith('org.mpris.MediaPlayer2') and bus_name.split('.')[3] not in self.blacklist
def refreshPlayerList(self):
player_bus_names = [ bus_name for bus_name in self._session_bus.list_names() if self.busNameIsAPlayer(bus_name) ]
for player_bus_name in player_bus_names:
self.addPlayer(player_bus_name)
if self.connected != True:
self.connected = True
self.printQueue()
def addPlayer(self, bus_name, owner = None):
player = Player(self._session_bus, bus_name, owner = owner, connect = self._connect, _print = self.print)
self.players[player.owner] = player
def removePlayer(self, owner):
if owner in self.players:
self.players[owner].disconnect()
del self.players[owner]
# If there are no more players, clear the output
if len(self.players) == 0:
_printFlush(ICON_NONE)
# Else, print the output of the next active player
else:
players = self.getSortedPlayerOwnerList()
if len(players) > 0:
self.players[players[0]].printStatus()
def changePlayerOwner(self, bus_name, old_owner, new_owner):
player = Player(self._session_bus, bus_name, owner = new_owner, connect = self._connect, _print = self.print)
self.players[new_owner] = player
del self.players[old_owner]
# Get a list of player owners sorted by current status and age
def getSortedPlayerOwnerList(self):
players = [
{
'number': int(owner.split('.')[-1]),
'status': 2 if player.status == 'playing' else 1 if player.status == 'paused' else 0,
'owner': owner
}
for owner, player in self.players.items()
]
return [ info['owner'] for info in reversed(sorted(players, key=itemgetter('status', 'number'))) ]
# Get latest player that's currently playing
def getCurrentPlayer(self):
playing_players = [
player_owner for player_owner in self.getSortedPlayerOwnerList()
if
self.players[player_owner].status == 'playing' or
self.players[player_owner].status == 'paused'
]
return self.players[playing_players[0]] if playing_players else None
def print(self, status, player):
self.player_states[player.bus_name] = status
if self.connected:
current_player = self.getCurrentPlayer()
if current_player != None:
_printFlush(self.player_states[current_player.bus_name])
else:
_printFlush(ICON_STOPPED)
else:
self.print_queue.append([status, player])
def printQueue(self):
for args in self.print_queue:
self.print(args[0], args[1])
self.print_queue.clear()
class Player:
def __init__(self, session_bus, bus_name, owner = None, connect = True, _print = None):
self._session_bus = session_bus
self.bus_name = bus_name
self._disconnecting = False
self.__print = _print
self.metadata = {
'artist' : '',
'album' : '',
'title' : '',
'track' : 0
}
self._rate = 1.
self._positionAtLastUpdate = 0.
self._timeAtLastUpdate = time.time()
self._positionTimerRunning = False
self._metadata = None
self.status = 'stopped'
self.icon = ICON_NONE
self.icon_reversed = ICON_PLAYING
if owner is not None:
self.owner = owner
else:
self.owner = self._session_bus.get_name_owner(bus_name)
self._obj = self._session_bus.get_object(self.bus_name, '/org/mpris/MediaPlayer2')
self._properties_interface = dbus.Interface(self._obj, dbus_interface='org.freedesktop.DBus.Properties')
self._introspect_interface = dbus.Interface(self._obj, dbus_interface='org.freedesktop.DBus.Introspectable')
self._media_interface = dbus.Interface(self._obj, dbus_interface='org.mpris.MediaPlayer2')
self._player_interface = dbus.Interface(self._obj, dbus_interface='org.mpris.MediaPlayer2.Player')
self._introspect = self._introspect_interface.get_dbus_method('Introspect', dbus_interface=None)
self._getProperty = self._properties_interface.get_dbus_method('Get', dbus_interface=None)
self._playerPlay = self._player_interface.get_dbus_method('Play', dbus_interface=None)
self._playerPause = self._player_interface.get_dbus_method('Pause', dbus_interface=None)
self._playerPlayPause = self._player_interface.get_dbus_method('PlayPause', dbus_interface=None)
self._playerStop = self._player_interface.get_dbus_method('Stop', dbus_interface=None)
self._playerPrevious = self._player_interface.get_dbus_method('Previous', dbus_interface=None)
self._playerNext = self._player_interface.get_dbus_method('Next', dbus_interface=None)
self._playerRaise = self._media_interface.get_dbus_method('Raise', dbus_interface=None)
self._signals = {}
self.refreshPosition()
self.refreshStatus()
self.refreshMetadata()
if connect:
self.printStatus()
self.connect()
def play(self):
self._playerPlay()
def pause(self):
self._playerPause()
def playpause(self):
self._playerPlayPause()
def stop(self):
self._playerStop()
def previous(self):
self._playerPrevious()
def next(self):
self._playerNext()
def raisePlayer(self):
self._playerRaise()
def connect(self):
if self._disconnecting is not True:
introspect_xml = self._introspect(self.bus_name, '/')
if 'TrackMetadataChanged' in introspect_xml:
self._signals['track_metadata_changed'] = self._session_bus.add_signal_receiver(self.onMetadataChanged, 'TrackMetadataChanged', self.bus_name)
self._signals['seeked'] = self._player_interface.connect_to_signal('Seeked', self.onSeeked)
self._signals['properties_changed'] = self._properties_interface.connect_to_signal('PropertiesChanged', self.onPropertiesChanged)
def disconnect(self):
self._disconnecting = True
for signal_name, signal_handler in list(self._signals.items()):
signal_handler.remove()
del self._signals[signal_name]
def refreshStatus(self):
# Some clients (VLC) will momentarily create a new player before removing it again
# so we can't be sure the interface still exists
try:
self.status = str(self._getProperty('org.mpris.MediaPlayer2.Player', 'PlaybackStatus')).lower()
self.updateIcon()
self.checkPositionTimer()
except dbus.exceptions.DBusException:
self.disconnect()
def refreshMetadata(self):
# Some clients (VLC) will momentarily create a new player before removing it again
# so we can't be sure the interface still exists
try:
self._metadata = self._getProperty('org.mpris.MediaPlayer2.Player', 'Metadata')
self._parseMetadata()
except dbus.exceptions.DBusException:
self.disconnect()
def updateIcon(self):
self.icon = (
ICON_PLAYING if self.status == 'playing' else
ICON_PAUSED if self.status == 'paused' else
ICON_STOPPED if self.status == 'stopped' else
ICON_NONE
)
self.icon_reversed = (
ICON_PAUSED if self.status == 'playing' else
ICON_PLAYING
)
def _print(self, status):
self.__print(status, self)
def _parseMetadata(self):
if self._metadata != None:
# Obtain properties from _metadata
_artist = _getProperty(self._metadata, 'xesam:artist', [''])
_album = _getProperty(self._metadata, 'xesam:album', '')
_title = _getProperty(self._metadata, 'xesam:title', '')
_track = _getProperty(self._metadata, 'xesam:trackNumber', '')
_genre = _getProperty(self._metadata, 'xesam:genre', [''])
_disc = _getProperty(self._metadata, 'xesam:discNumber', '')
_length = _getProperty(self._metadata, 'xesam:length', 0) or _getProperty(self._metadata, 'mpris:length', 0)
_length_int = _length if type(_length) is int else int(float(_length))
_date = _getProperty(self._metadata, 'xesam:contentCreated', '')
_year = _date[0:4] if len(_date) else ''
_url = _getProperty(self._metadata, 'xesam:url', '')
_cover = _getProperty(self._metadata, 'xesam:artUrl', '') or _getProperty(self._metadata, 'mpris:artUrl', '')
_duration = _getDuration(_length_int)
# Update metadata
self.metadata['artist'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _firstIfList(_artist))
self.metadata['album'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _firstIfList(_album))
self.metadata['title'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _firstIfList(_title))
self.metadata['track'] = _track
self.metadata['genre'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _firstIfList(_genre))
self.metadata['disc'] = _disc
self.metadata['date'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _date)
self.metadata['year'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _year)
self.metadata['url'] = _url
self.metadata['filename'] = os.path.basename(_url)
self.metadata['length'] = _length_int
self.metadata['cover'] = re.sub(SAFE_TAG_REGEX, """\1\1""", _firstIfList(_cover))
self.metadata['duration'] = _duration
def onMetadataChanged(self, track_id, metadata):
self.refreshMetadata()
self.printStatus()
def onPropertiesChanged(self, interface, properties, signature):
updated = False
if dbus.String('Metadata') in properties:
_metadata = properties[dbus.String('Metadata')]
if _metadata != self._metadata:
self._metadata = _metadata
self._parseMetadata()
updated = True
if dbus.String('PlaybackStatus') in properties:
status = str(properties[dbus.String('PlaybackStatus')]).lower()
if status != self.status:
self.status = status
self.checkPositionTimer()
self.updateIcon()
updated = True
if dbus.String('Rate') in properties and dbus.String('PlaybackStatus') not in properties:
self.refreshStatus()
if NEEDS_POSITION and dbus.String('Rate') in properties:
rate = properties[dbus.String('Rate')]
if rate != self._rate:
self._rate = rate
self.refreshPosition()
if updated:
self.refreshPosition()
self.printStatus()
def checkPositionTimer(self):
if NEEDS_POSITION and self.status == 'playing' and not self._positionTimerRunning:
self._positionTimerRunning = True
GLib.timeout_add_seconds(1, self._positionTimer)
def onSeeked(self, position):
self.refreshPosition()
self.printStatus()
def _positionTimer(self):
self.printStatus()
self._positionTimerRunning = self.status == 'playing'
return self._positionTimerRunning
def refreshPosition(self):
try:
time_us = self._getProperty('org.mpris.MediaPlayer2.Player', 'Position')
except dbus.exceptions.DBusException:
time_us = 0
self._timeAtLastUpdate = time.time()
self._positionAtLastUpdate = time_us / 1000000
def _getPosition(self):
if self.status == 'playing':
return self._positionAtLastUpdate + self._rate * (time.time() - self._timeAtLastUpdate)
else:
return self._positionAtLastUpdate
def _statusReplace(self, match, metadata):
tag = match.group('tag')
format = match.group('format')
formatlen = match.group('formatlen')
text = match.group('text')
tag_found = False
reversed_tag = False
if tag.startswith('-'):
tag = tag[1:]
reversed_tag = True
if format is None:
tag_is_format_match = re.match(FORMAT_TAG_REGEX, tag)
if tag_is_format_match:
format = tag_is_format_match.group('format')
formatlen = tag_is_format_match.group('formatlen')
tag_found = True
if format is not None:
text = text.format_map(CleanSafeDict(**metadata))
if format == 'w':
formatlen = int(formatlen)
text = text[:formatlen]
elif format == 't':
formatlen = int(formatlen)
if len(text) > formatlen:
text = text[:max(formatlen - len(TRUNCATE_STRING), 0)] + TRUNCATE_STRING
if tag_found is False and tag in metadata and len(metadata[tag]):
tag_found = True
if reversed_tag:
tag_found = not tag_found
if tag_found:
return text
else:
return ''
def printStatus(self):
if self.status in [ 'playing', 'paused' ]:
metadata = { **self.metadata, 'icon': self.icon, 'icon-reversed': self.icon_reversed }
if NEEDS_POSITION:
metadata['position'] = time.strftime("%M:%S", time.gmtime(self._getPosition()))
# replace metadata tags in text
text = re.sub(FORMAT_REGEX, lambda match: self._statusReplace(match, metadata), FORMAT_STRING)
# restore polybar tag formatting and replace any remaining metadata tags after that
try:
text = re.sub(r'􏿿p􏿿(.*?)􏿿p􏿿(.*?)􏿿p􏿿(.*?)􏿿p􏿿', r'%{\1}\2%{\3}', text.format_map(CleanSafeDict(**metadata)))
except:
print("Invalid format string")
self._print(text)
else:
self._print(ICON_STOPPED)
def _dbusValueToPython(value):
if isinstance(value, dbus.Dictionary):
return {_dbusValueToPython(key): _dbusValueToPython(value) for key, value in value.items()}
elif isinstance(value, dbus.Array):
return [ _dbusValueToPython(item) for item in value ]
elif isinstance(value, dbus.Boolean):
return int(value) == 1
elif (
isinstance(value, dbus.Byte) or
isinstance(value, dbus.Int16) or
isinstance(value, dbus.UInt16) or
isinstance(value, dbus.Int32) or
isinstance(value, dbus.UInt32) or
isinstance(value, dbus.Int64) or
isinstance(value, dbus.UInt64)
):
return int(value)
elif isinstance(value, dbus.Double):
return float(value)
elif (
isinstance(value, dbus.ObjectPath) or
isinstance(value, dbus.Signature) or
isinstance(value, dbus.String)
):
return unquote(str(value))
def _getProperty(properties, property, default = None):
value = default
if not isinstance(property, dbus.String):
property = dbus.String(property)
if property in properties:
value = properties[property]
return _dbusValueToPython(value)
else:
return value
def _getDuration(t: int):
seconds = t / 1000000
return time.strftime("%M:%S", time.gmtime(seconds))
def _firstIfList(_value):
return _value[0] if type(_value) is list and len(_value) else _value
class CleanSafeDict(dict):
def __missing__(self, key):
return '{{{}}}'.format(key)
"""
Seems to assure print() actually prints when no terminal is connected
"""
_last_status = ''
def _printFlush(status, **kwargs):
global _last_status
if status != _last_status:
print(status, **kwargs)
sys.stdout.flush()
_last_status = status
parser = argparse.ArgumentParser()
parser.add_argument('command', help="send the given command to the active player",
choices=[ 'play', 'pause', 'play-pause', 'stop', 'previous', 'next', 'status', 'list', 'current', 'metadata', 'raise' ],
default=None,
nargs='?')
parser.add_argument('-b', '--blacklist', help="ignore a player by it's bus name. Can be be given multiple times (e.g. -b vlc -b audacious)",
action='append',
metavar="BUS_NAME",
default=[])
parser.add_argument('-f', '--format', default='{icon} {:artist:{artist} - :}{:title:{title}:}{:-title:{filename}:}')
parser.add_argument('--truncate-text', default='')
parser.add_argument('--icon-playing', default='')
parser.add_argument('--icon-paused', default='')
#parser.add_argument('--icon-stopped', default='⏹')
parser.add_argument('--icon-stopped', default='') # show no icon if stopped
parser.add_argument('--icon-none', default='')
args = parser.parse_args()
FORMAT_STRING = re.sub(r'%\{(.*?)\}(.*?)%\{(.*?)\}', r'􏿿p􏿿\1􏿿p􏿿\2􏿿p􏿿\3􏿿p􏿿', args.format)
NEEDS_POSITION = "{position}" in FORMAT_STRING
TRUNCATE_STRING = args.truncate_text
ICON_PLAYING = args.icon_playing
ICON_PAUSED = args.icon_paused
ICON_STOPPED = args.icon_stopped
ICON_NONE = args.icon_none
if args.command is None:
PlayerManager(blacklist = args.blacklist)
else:
player_manager = PlayerManager(blacklist = args.blacklist, connect = False)
current_player = player_manager.getCurrentPlayer()
if args.command == 'play' and current_player:
current_player.play()
elif args.command == 'pause' and current_player:
current_player.pause()
elif args.command == 'play-pause' and current_player:
current_player.playpause()
elif args.command == 'stop' and current_player:
current_player.stop()
elif args.command == 'previous' and current_player:
current_player.previous()
elif args.command == 'next' and current_player:
current_player.next()
elif args.command == 'status' and current_player:
current_player.printStatus()
elif args.command == 'list':
print("\n".join(sorted([
"{} : {}".format(player.bus_name.split('.')[3], player.status)
for player in player_manager.players.values() ])))
elif args.command == 'current' and current_player:
print("{} : {}".format(current_player.bus_name.split('.')[3], current_player.status))
elif args.command == 'metadata' and current_player:
print(_dbusValueToPython(current_player._metadata))
elif args.command == 'raise' and current_player:
current_player.raisePlayer()

View File

@ -1,32 +0,0 @@
{ pkgs, ... }:
{
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
#vim # an editor
neovim # text editor
fwupd # firmware updates
fwupd-efi # firmware updates additional EFI stuff
wget # get stuff from the net
gvfs # virtual file system support
#hyprland # window manager
wayland # wayland server
xdg-utils # xdg directories, open, etc
xdg-user-dirs # directories
sweet # gtk theme
capitaine-cursors # cursor theme
xfce.tumbler # image files thumbnail generator (+ base requirement)
ffmpegthumbnailer # video files thumbnail generator
qt6.qtwayland # wayland for qt6
libsForQt5.qt5.qtwayland # wayland for at5
polkit_gnome # graphical authentication agent for polkit
freetype # font rendering and configuration
];
fonts.fonts = with pkgs; [
fira # fira sans font
fira-code # fira code font
font-awesome # icons font
];
}

View File

@ -1,13 +0,0 @@
#!/usr/bin/env sh
set -euo pipefail
git fetch -a
git reset --hard
git clean -fd
git pull
# regenerate hardware config
nixos-generate-config
# rebuild system
nixos-rebuild switch

0
roles/config/README.md Normal file
View File

View File

View File

@ -0,0 +1,500 @@
[%General]
author=Eliver Lara
comment=A dark and modern theme for Kvantum.
x11drag=menubar_and_primary_toolbar
alt_mnemonic=true
left_tabs=true
attach_active_tab=true
mirror_doc_tabs=true
group_toolbar_buttons=false
toolbar_item_spacing=1
toolbar_interior_spacing=3
spread_progressbar=true
composite=true
menu_shadow_depth=5
menu_separator_height=6
tooltip_shadow_depth=6
splitter_width=4
scroll_width=6
scroll_arrows=false
scroll_min_extent=60
slider_width=2
slider_handle_width=18
slider_handle_length=18
center_toolbar_handle=true
check_size=14
textless_progressbar=false
progressbar_thickness=2
menubar_mouse_tracking=true
toolbutton_style=0
double_click=false
translucent_windows=false
blurring=false
popup_blurring=true
vertical_spin_indicators=false
spin_button_width=32
fill_rubberband=false
merge_menubar_with_toolbar=true
small_icon_size=16
large_icon_size=32
button_icon_size=16
toolbar_icon_size=22
combo_as_lineedit=true
animate_states=false
button_contents_shift=false
combo_menu=true
hide_combo_checkboxes=true
combo_focus_rect=true
groupbox_top_label=true
inline_spin_indicators=false
joined_inactive_tabs=false
layout_spacing=6
layout_margin=9
scrollbar_in_view=true
transient_scrollbar=true
transient_groove=false
submenu_overlap=0
tooltip_delay=-1
tree_branch_line=true
dark_titlebar=true
opaque=QMPlay2,kaffeine,kmplayer,subtitlecomposer,kdenlive,vlc,avidemux,avidemux2_qt4,avidemux3_qt4,avidemux3_qt5,kamoso,QtCreator,VirtualBox,trojita,dragon,digikam,virtualboxvm
reduce_window_opacity=18
scrollable_menu=false
submenu_delay=250
no_inactiveness=false
no_window_pattern=false
reduce_menu_opacity=0
respect_DE=true
click_behavior=0
contrast=1.00
dialog_button_layout=0
drag_from_buttons=false
intensity=1.00
menu_blur_radius=0
saturation=1.00
shadowless_popup=false
tooltip_blur_radius=0
[GeneralColors]
window.color=#161925
base.color=#181b28
alt.base.color=#252a3f78
button.color=#1e1e20
light.color=#0C0E15
mid.light.color=#0C0E15
dark.color=#0C0E15
mid.color=#0C0E15
highlight.color=#c50ed2
inactive.highlight.color=#654ea3
text.color=#aaaaac
window.text.color=#aaaaac
button.text.color=#aaaaac
disabled.text.color=#aaaaac78
tooltip.text.color=#aaaaac
highlight.text.color=#dadadc
link.color=#646464
link.visited.color=#7f8c8d
progress.indicator.text.color=#aaaaac
[Hacks]
transparent_ktitle_label=false
transparent_dolphin_view=false
transparent_pcmanfm_sidepane=false
blur_translucent=true
transparent_menutitle=false
respect_darkness=true
kcapacitybar_as_progressbar=true
force_size_grip=true
iconless_pushbutton=false
iconless_menu=false
disabled_icon_opacity=70
lxqtmainmenu_iconsize=22
normal_default_pushbutton=true
single_top_toolbar=true
tint_on_mouseover=0
transparent_pcmanfm_view=false
middle_click_scroll=false
no_selection_tint=false
opaque_colors=false
blur_only_active_window=false
centered_forms=false
kinetic_scrolling=false
noninteger_translucency=false
style_vertical_toolbars=false
[PanelButtonCommand]
frame=true
frame.element=button
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
interior=true
interior.element=button
indicator.size=8
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.press.color=#d2d2d4
text.toggle.color=#aaaaac
text.shadow=0
text.margin=1
text.iconspacing=4
indicator.element=arrow
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
min_width=+0.3font
min_height=+0.3font
frame.expansion=6
[PanelButtonTool]
inherits=PanelButtonCommand
[Dock]
inherits=PanelButtonCommand
interior.element=dock
frame.element=dock
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#aaaaac
[DockTitle]
inherits=PanelButtonCommand
frame=false
interior=false
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.bold=false
[IndicatorSpinBox]
inherits=PanelButtonCommand
frame=true
interior=true
frame.left=1
indicator.element=spin
indicator.size=10
text.normal.color=#aaaaac
[RadioButton]
inherits=PanelButtonCommand
frame=false
interior.element=radio
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
[CheckBox]
inherits=PanelButtonCommand
frame=false
interior.element=checkbox
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
[Focus]
inherits=PanelButtonCommand
frame=true
frame.element=focus
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
frame.patternsize=20
[GenericFrame]
inherits=PanelButtonCommand
frame=true
interior=false
frame.element=common
interior.element=common
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
[LineEdit]
inherits=PanelButtonCommand
frame.element=lineedit
interior.element=lineedit
text.margin.left=0
text.margin.right=0
[DropDownButton]
inherits=PanelButtonCommand
indicator.element=arrow-down
[IndicatorArrow]
indicator.element=arrow
indicator.size=8
[ToolboxTab]
inherits=PanelButtonCommand
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.press.color=#d2d2d4
[Tab]
inherits=PanelButtonCommand
interior.element=tab
text.margin.left=8
text.margin.right=8
text.margin.top=2
text.margin.bottom=2
frame.element=tab
indicator.element=tab
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.normal.color=#aaaaac
text.focus.color=#aaaaac
text.toggle.color=#aaaaac
frame.expansion=0
[TabFrame]
inherits=PanelButtonCommand
frame.element=tabframe
interior.element=tabframe
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
[TreeExpander]
inherits=PanelButtonCommand
indicator.size=12
indicator.element=tree
[HeaderSection]
inherits=PanelButtonCommand
interior.element=header
frame.element=header
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
text.bold=false
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.press.color=#d2d2d4
text.toggle.color=#d2d2d4
frame.expansion=0
[SizeGrip]
indicator.element=resize-grip
[Toolbar]
inherits=PanelButtonCommand
indicator.element=toolbar
indicator.size=5
text.margin=0
frame=true
interior.element=menubar
frame.element=menubar
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
frame.left=0
frame.right=0
frame.top=0
frame.bottom=1
frame.expansion=0
[Slider]
inherits=PanelButtonCommand
frame.element=slider
interior.element=slider
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
[SliderCursor]
inherits=PanelButtonCommand
frame=false
interior.element=slidercursor
[Progressbar]
inherits=PanelButtonCommand
frame.element=progress
interior.element=progress
text.margin=0
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.press.color=#d2d2d4
text.toggle.color=#aaaaac
text.bold=false
frame.expansion=8
[ProgressbarContents]
inherits=PanelButtonCommand
frame=true
frame.element=progress-pattern
interior.element=progress-pattern
[ItemView]
inherits=PanelButtonCommand
text.margin=0
frame.element=itemview
interior.element=itemview
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
text.margin.top=2
text.margin.bottom=2
text.margin.left=4
text.margin.right=4
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.press.color=#d2d2d4
text.toggle.color=#d2d2d4
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[Splitter]
indicator.size=48
[Scrollbar]
inherits=PanelButtonCommand
indicator.element=arrow
indicator.size=8
[ScrollbarSlider]
inherits=PanelButtonCommand
interior.element=scrollbarslider
interior=true
frame=false
frame.expansion=48
[ScrollbarGroove]
inherits=PanelButtonCommand
interior.element=scrollbargroove
interior=true
frame=false
frame.expansion=48
[MenuItem]
inherits=PanelButtonCommand
frame=true
frame.element=menuitem
interior.element=menuitem
indicator.element=menuitem
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.margin.top=1
text.margin.bottom=1
text.margin.left=4
text.margin.right=4
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
text.bold=false
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[MenuBar]
inherits=PanelButtonCommand
frame.element=menubar
interior.element=menubar
text.normal.color=#aaaaac
frame.bottom=0
frame.expansion=0
[MenuBarItem]
inherits=PanelButtonCommand
interior=true
interior.element=menubaritem
frame.element=menubaritem
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
text.margin.left=4
text.margin.right=4
text.margin.top=0
text.margin.bottom=0
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
frame.expansion=0
[TitleBar]
inherits=PanelButtonCommand
frame=false
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
interior.element=titlebar
indicator.size=16
indicator.element=mdi
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.bold=true
text.italic=false
frame.expansion=0
[ComboBox]
inherits=PanelButtonCommand
interior.element=combo
frame.element=combo
text.press.color=#d2d2d4
indicator.element=carrow
[Menu]
inherits=PanelButtonCommand
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
frame.element=menu
interior.element=menu
text.normal.color=#aaaaac
text.shadow=false
frame.expansion=0
[GroupBox]
inherits=GenericFrame
frame=false
text.shadow=0
text.margin=0
text.normal.color=#aaaaac
text.focus.color=#c8c8ca
text.bold=true
frame.expansion=0
[TabBarFrame]
inherits=GenericFrame
frame=true
frame.element=tabBarFrame
interior=false
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
[ToolTip]
inherits=GenericFrame
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
interior=true
text.shadow=0
text.margin=0
interior.element=tooltip
frame.element=tooltip
frame.expansion=0
[StatusBar]
inherits=GenericFrame
frame=false
interior=false
interior=false
[Window]
interior=true
interior.element=window

View File

@ -0,0 +1,2 @@
[General]
theme=Sweet#

View File

View File

@ -0,0 +1,71 @@
### MangoHud configuration file
### Uncomment any options you wish to enable. Default options are left uncommented
### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead
################ PERFORMANCE #################
### Limit the application FPS
# fps_limit=
### VSYNC [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
# vsync=
################### VISUAL ###################
### Display the current CPU information
cpu_stats
cpu_temp
### Display the current GPU information
gpu_name
gpu_stats
gpu_temp
gpu_power
### Display the frametime line graph
frame_timing
### Display the current system time
# time
### Change the hud font size (default is 24)
font_size=20
### Change the hud position (default is top-left)
position=top-left
### Display the current CPU load & frequency for each core
core_load
### Display system ram / vram usage
ram
vram
### Disable / hide the hud by deafult
# no_display
### Hud position offset
# offset_x=
# offset_y=
### Hud dimensions
# width=
# height=
### Hud transparency / alpha
background_alpha=0.5
### Crosshair overlay (default size is 30)
# crosshair
# crosshair_size=
# crosshair_color=RRGGBB
### Output file
output_file /home/marc/Dokumente/mangohud.log
################## INTERACTION #################
### Change toggle keybinds for the hud & logging
toggle_hud=Shift_L+F12
toggle_logging=Shift_L+F2

View File

@ -0,0 +1,8 @@
json:{
"prefer_author_sort": false,
"toc_title": null,
"mobi_toc_at_start": false,
"dont_compress": false,
"no_inline_toc": false,
"share_not_sync": false
}

View File

@ -0,0 +1,17 @@
json:{
"colors": 0,
"dont_normalize": false,
"keep_aspect_ratio": false,
"right2left": false,
"despeckle": false,
"no_sort": false,
"no_process": false,
"landscape": false,
"dont_sharpen": false,
"disable_trim": false,
"wide": false,
"output_format": "png",
"dont_grayscale": false,
"comic_image_size": null,
"dont_add_comic_pages_to_toc": false
}

View File

@ -0,0 +1,5 @@
json:{
"docx_no_cover": false,
"docx_no_pagebreaks_between_notes": false,
"docx_inline_subsup": false
}

View File

@ -0,0 +1,11 @@
json:{
"docx_page_size": "letter",
"docx_custom_page_size": null,
"docx_no_cover": false,
"docx_no_toc": false,
"docx_page_margin_left": 72.0,
"docx_page_margin_top": 72.0,
"docx_page_margin_right": 72.0,
"docx_page_margin_bottom": 72.0,
"preserve_cover_aspect_ratio": false
}

View File

@ -0,0 +1,12 @@
json:{
"dont_split_on_page_breaks": false,
"flow_size": 0,
"no_default_epub_cover": false,
"no_svg_cover": false,
"epub_inline_toc": false,
"epub_toc_at_end": false,
"toc_title": null,
"preserve_cover_aspect_ratio": true,
"epub_flatten": false,
"epub_version": "3"
}

View File

@ -0,0 +1,3 @@
json:{
"no_inline_fb2_toc": false
}

View File

@ -0,0 +1,4 @@
json:{
"sectionize": "files",
"fb2_genre": "antique"
}

View File

@ -0,0 +1,13 @@
json:{
"enable_heuristics": false,
"markup_chapter_headings": true,
"italicize_common_cases": true,
"fix_indents": true,
"html_unwrap_factor": 0.4,
"unwrap_lines": true,
"delete_blank_paragraphs": true,
"format_scene_breaks": true,
"replace_scene_breaks": "",
"dehyphenate": true,
"renumber_headings": true
}

View File

@ -0,0 +1,5 @@
json:{
"htmlz_css_type": "class",
"htmlz_class_style": "external",
"htmlz_title_filename": false
}

View File

@ -0,0 +1,3 @@
json:{
"allow_conversion_with_errors": true
}

View File

@ -0,0 +1,26 @@
json:{
"change_justification": "original",
"extra_css": null,
"base_font_size": 0.0,
"font_size_mapping": null,
"line_height": 0.0,
"minimum_line_height": 120.0,
"embed_font_family": null,
"embed_all_fonts": false,
"subset_embedded_fonts": false,
"smarten_punctuation": false,
"unsmarten_punctuation": false,
"disable_font_rescaling": false,
"insert_blank_line": false,
"remove_paragraph_spacing": false,
"remove_paragraph_spacing_indent_size": 1.5,
"insert_blank_line_size": 0.5,
"input_encoding": null,
"filter_css": "",
"expand_css": false,
"asciiize": false,
"keep_ligatures": false,
"linearize_tables": false,
"transform_css_rules": "[]",
"transform_html_rules": "[]"
}

View File

@ -0,0 +1,13 @@
json:{
"wordspace": 2.5,
"header": false,
"header_format": "%t by %a",
"minimum_indent": 0.0,
"serif_family": null,
"render_tables_as_images": false,
"sans_family": null,
"mono_family": null,
"text_size_multiplier_for_rendered_tables": 1.0,
"autorotation": false,
"header_separation": 0.0
}

View File

@ -0,0 +1,12 @@
json:{
"prefer_author_sort": false,
"toc_title": null,
"mobi_keep_original_images": false,
"mobi_ignore_margins": false,
"mobi_toc_at_start": false,
"dont_compress": false,
"no_inline_toc": false,
"share_not_sync": false,
"personal_doc": "[PDOC]",
"mobi_file_type": "old"
}

View File

@ -0,0 +1,8 @@
json:{
"margin_top": 5.0,
"margin_left": 5.0,
"margin_right": 5.0,
"margin_bottom": 5.0,
"input_profile": "default",
"output_profile": "tablet"
}

View File

@ -0,0 +1,5 @@
json:{
"format": "doc",
"inline_toc": false,
"pdb_output_encoding": "cp1252"
}

View File

@ -0,0 +1,4 @@
json:{
"no_images": false,
"unwrap_factor": 0.45
}

View File

@ -0,0 +1,26 @@
json:{
"use_profile_size": false,
"paper_size": "letter",
"custom_size": null,
"pdf_hyphenate": false,
"preserve_cover_aspect_ratio": false,
"pdf_serif_family": "Nimbus Roman",
"unit": "inch",
"pdf_sans_family": "Nimbus Sans [UKWN]",
"pdf_mono_family": "Nimbus Mono PS",
"pdf_standard_font": "serif",
"pdf_default_font_size": 20,
"pdf_mono_font_size": 16,
"pdf_page_numbers": false,
"pdf_footer_template": null,
"pdf_header_template": null,
"pdf_add_toc": false,
"toc_title": null,
"pdf_page_margin_left": 72.0,
"pdf_page_margin_top": 72.0,
"pdf_page_margin_right": 72.0,
"pdf_page_margin_bottom": 72.0,
"pdf_use_document_margins": false,
"pdf_page_number_map": null,
"pdf_odd_even_offset": 0.0
}

View File

@ -0,0 +1,5 @@
json:{
"inline_toc": false,
"full_image_depth": false,
"pml_output_encoding": "cp1252"
}

View File

@ -0,0 +1,3 @@
json:{
"inline_toc": false
}

View File

@ -0,0 +1,3 @@
json:{
"ignore_wmf": false
}

View File

@ -0,0 +1,9 @@
json:{
"search_replace": "[]",
"sr1_search": null,
"sr1_replace": null,
"sr2_search": null,
"sr2_replace": null,
"sr3_search": null,
"sr3_replace": null
}

View File

@ -0,0 +1,6 @@
json:{
"snb_insert_empty_line": false,
"snb_dont_indent_first_line": false,
"snb_hide_chapter_name": false,
"snb_full_screen": false
}

View File

@ -0,0 +1,9 @@
json:{
"chapter": "//*[((name()='h1' or name()='h2') and re:test(., '\\s*((chapter|book|section|part)\\s+)|((prolog|prologue|epilogue)(\\s+|$))', 'i')) or @class = 'chapter']",
"chapter_mark": "pagebreak",
"start_reading_at": null,
"remove_first_image": false,
"remove_fake_margins": true,
"insert_metadata": false,
"page_breaks_before": "//*[name()='h1' or name()='h2']"
}

View File

@ -0,0 +1,11 @@
json:{
"level1_toc": null,
"level2_toc": null,
"level3_toc": null,
"toc_threshold": 6,
"max_toc_links": 50,
"no_chapters_in_toc": false,
"use_auto_toc": false,
"toc_filter": null,
"duplicate_links_in_toc": false
}

View File

@ -0,0 +1,7 @@
json:{
"paragraph_type": "auto",
"formatting_type": "auto",
"markdown_extensions": "footnotes, tables, toc",
"preserve_spaces": false,
"txt_in_remove_indents": false
}

View File

@ -0,0 +1,11 @@
json:{
"newline": "system",
"max_line_length": 0,
"force_max_line_length": false,
"inline_toc": false,
"txt_output_formatting": "plain",
"keep_links": false,
"keep_image_references": false,
"keep_color": false,
"txt_output_encoding": "utf-8"
}

View File

@ -0,0 +1,11 @@
json:{
"newline": "system",
"max_line_length": 0,
"force_max_line_length": false,
"inline_toc": false,
"txt_output_formatting": "plain",
"keep_links": false,
"keep_image_references": false,
"keep_color": false,
"txt_output_encoding": "utf-8"
}

View File

@ -0,0 +1,4 @@
{
"last_used_colors": "Grass",
"last_used_style": "Banner"
}

View File

@ -0,0 +1,20 @@
{
"disabled_plugins": {
"__class__": "set",
"__value__": []
},
"enabled_plugins": {
"__class__": "set",
"__value__": [
"DeDRM"
]
},
"filetype_mapping": {},
"plugin_customization": {},
"plugins": {
"DeACSM": "/home/marc/.config/calibre/plugins/DeACSM.zip",
"DeDRM": "/home/marc/.config/calibre/plugins/DeDRM.zip",
"KFX Input": "/home/exu/.config/calibre/plugins/KFX Input.zip",
"Obok DeDRM": "/home/marc/.config/calibre/plugins/Obok DeDRM.zip"
}
}

View File

@ -0,0 +1,43 @@
{
"DeDRMexport_Kindle_for_Mac_and_PC_Key_keys": "/home/marc/Downloads/default_key.k4i",
"DeDRMimport_Adobe_Digital_Editions_Key_keys": "/home/marc/Nextcloud/backups",
"Export ADE activation files": "/home/marc/Nextcloud/backups/adobe_account_backup_uuid_2d6cfbec-33fd-43ca-bcf9-e8b281114a17.zip",
"Export ADE keys": "/home/marc/Nextcloud/backups/adobe_uuid_2d6cfbec-33fd-43ca-bcf9-e8b281114a17.der",
"add a plugin dialog": "/home/marc/Downloads/DeDRM_tools_10.0.3",
"add books dialog dir": "/home/exu/Nextcloud/Reading/books/Sanderson, Brandon/Oathbringer",
"add books dialog dir-last-used-filter-spec-all-files": false,
"choose calibre library": "/home/exu/.local/share/Calibre-Library",
"database location dialog": "/home/marc/Nextcloud/Books",
"library_delete_books_again": false,
"notified-version-updates": {
"__class__": "set",
"__value__": [
"6.0",
"5.24",
"5.25",
"5.28"
]
},
"recursive book import root dir dialog": "/home/exu/Nextcloud/Reading/books",
"save to disk dialog": "/home/exu/Downloads/newBooks",
"sort_history": [
[
"series",
true
],
[
"authors",
true
],
[
"series",
true
],
[
"timestamp",
false
]
],
"welcome_wizard_device": "default",
"welcome_wizard_was_run": true
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>lineedit_history_tweak_book_find_edit</key>
<array>
<string>font</string>
</array>
</dict>
</plist>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
{
"add_formats_to_existing": false,
"case_sensitive": false,
"check_for_dupes_on_ctl": false,
"database_path": "/home/marc/library1.db",
"filename_pattern": "(?P<title>.+) - (?P<author>[^_]+)",
"input_format_order": [
"EPUB",
"AZW3",
"MOBI",
"LIT",
"PRC",
"FB2",
"HTML",
"HTM",
"XHTM",
"SHTML",
"XHTML",
"ZIP",
"DOCX",
"ODT",
"RTF",
"PDF",
"TXT"
],
"installation_uuid": "95258752-0a69-416a-90ff-c20df0267b24",
"isbndb_com_key": "",
"language": "de",
"library_path": "/home/exu/.local/share/Calibre-Library",
"limit_search_columns": false,
"limit_search_columns_to": [
"title",
"authors",
"tags",
"series",
"publisher"
],
"manage_device_metadata": "manual",
"mark_new_books": false,
"migrated": false,
"network_timeout": 5,
"new_book_tags": [],
"numeric_collation": false,
"output_format": "epub",
"read_file_metadata": true,
"saved_searches": {},
"swap_author_names": false,
"use_primary_find_in_search": true,
"user_categories": {},
"worker_process_priority": "normal"
}

View File

@ -0,0 +1,933 @@
{
"Plugin Updater plugin:plugin updater dialog": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAHHAAABFQAABdkAAAMKAAAByQAAARcAAAXXAAADCAAAAAAAAAAAB4AAAAHJAAABFwAABdcAAAMI"
},
"action-layout-toolbar": [
"Add Books",
"Edit Metadata",
null,
"Convert Books",
"View",
null,
"Store",
"Donate",
"Fetch News",
"Help",
null,
"Remove Books",
"Choose Library",
"Save To Disk",
"Connect Share",
"Tweak ePub",
"Preferences",
"Obok DeDRM"
],
"action-layout-toolbar-device": [
"Add Books",
"Edit Metadata",
null,
"Convert Books",
"View",
"Send To Device",
null,
null,
"Location Manager",
null,
null,
"Fetch News",
"Save To Disk",
"Store",
"Connect Share",
null,
"Remove Books",
null,
"Help",
"Preferences",
"Obok DeDRM"
],
"advanced search dialog current tab": 3,
"advanced_search_template_tab_program_field": "",
"advanced_search_template_tab_test_field": "0",
"advanced_search_template_tab_value_field": "",
"ask_to_manage_device": [
"9d273cd5"
],
"basic_metadata_widget_splitter_state": {
"__class__": "bytearray",
"__value__": "AAAA/wAAAAEAAAADAAAA6wAAAdoAAAEKAf////8BAAAAAQA="
},
"book_details_splitter_horizontal_state": [
true,
448
],
"book_info_dialog_layout": [
{
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAH3AAAAJAAABYgAAAP7AAAB+QAAACYAAAWGAAAD+QAAAAAAAAAAB4AAAAH5AAAAJgAABYYAAAP5"
},
{
"__class__": "bytearray",
"__value__": "AAAA/wAAAAEAAAACAAABXgAAAV4B/////wEAAAABAA=="
}
],
"book_list_pin_splitter_state": {
"__class__": "bytearray",
"__value__": "AAAA/wAAAAEAAAACAAABAAAAAEYA/////wEAAAABAA=="
},
"bulk_metadata_window_geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAbAAAAEgAAB1gAAAQbAAAAHQAAABQAAAdWAAAEGQAAAAAAAAAAB4AAAAAdAAAAFAAAB1YAAAQZ"
},
"bulk_metadata_window_tab": 0,
"choose-merge-dialog-geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAKEAAABYgAABPsAAAK9AAAChgAAAWQAAAT5AAACuwAAAAAAAAAAB4AAAAKGAAABZAAABPkAAAK7"
},
"choose-merge-dialog-splitter-state": {
"__class__": "bytearray",
"__value__": "AAAA/wAAAAEAAAACAAABXgAAAQAA/////wEAAAABAA=="
},
"convert_bulk_dialog_geom": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAeAAAAJAAAB1sAAAP7AAAAIAAAACYAAAdZAAAD+QAAAAAAAAAAB4AAAAAgAAAAJgAAB1kAAAP5"
},
"convert_single_dialog_geom": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAA4AAAAEgAAB3UAAAPpAAAAOgAAABQAAAdzAAAD5wAAAAAAAAAAB4AAAAA6AAAAFAAAB3MAAAPn"
},
"cover_browser_splitter_vertical_state": [
false,
300
],
"custom_colors_for_color_dialog": [
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
],
[
255,
255,
255,
255
]
],
"diff_dialog_geom": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAJnAAAAJgAABv8AAAP9AAACaQAAACgAAAb9AAAD+wAAAAAAAAAAB4AAAAJpAAAAKAAABv0AAAP7"
},
"duplicates-question-dialog-geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAACOAAABTAAAA2gAAALPAAAAkAAAAU4AAANmAAACzQAAAAAAAAAAB4AAAACQAAABTgAAA2YAAALN"
},
"geometry-of-Plugin Updater plugin:plugin updater dialog": {
"frame_geometry": {
"height": 498,
"width": 1039,
"x": 0,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 498,
"width": 1039,
"x": 0,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 498,
"width": 1039,
"x": 0,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAABA4AAAHxAAAAAAAAAAAAAAQOAAAB8QAAAAAAAAAACFUAAAAAAAAAAAAABA4AAAHx"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 0,
"y": 0
},
"index_in_screens_list": 0,
"manufacturer": "Acer Technologies",
"model": "XV272U V",
"name": "DP-1",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-bulk_metadata_window_geometry": {
"frame_geometry": {
"height": 1030,
"width": 1850,
"x": 0,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 1030,
"width": 1850,
"x": 0,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 1030,
"width": 1850,
"x": 0,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAABzkAAAQFAAAAAAAAAAAAAAc5AAAEBQAAAAEAAAAACFUAAAAAAAAAAAAABzkAAAQF"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-calibre_main_window_geometry": {
"frame_geometry": {
"height": 1154,
"width": 2129,
"x": 0,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 1154,
"width": 2129,
"x": 0,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 1154,
"width": 2129,
"x": 0,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAACFAAAASBAAAAAAAAAAAAAAhQAAAEgQAAAAAAAAAACFUAAAAAAAAAAAAACFAAAASB"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 0,
"y": 0
},
"index_in_screens_list": 0,
"manufacturer": "Acer Technologies",
"model": "XV272U V",
"name": "DP-1",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-convert_single_dialog_geom": {
"frame_geometry": {
"height": 980,
"width": 1850,
"x": 2133,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 980,
"width": 1850,
"x": 2133,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 980,
"width": 1850,
"x": 2133,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAhVAAAAAAAAD44AAAPTAAAIVQAAAAAAAA+OAAAD0wAAAAEAAAAACFUAAAhVAAAAAAAAD44AAAPT"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-diff_dialog_geom": {
"frame_geometry": {
"height": 980,
"width": 1306,
"x": 0,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 980,
"width": 1306,
"x": 0,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 980,
"width": 1306,
"x": 0,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAABRkAAAPTAAAAAAAAAAAAAAUZAAAD0wAAAAAAAAAACFUAAAAAAAAAAAAABRkAAAPT"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 0,
"y": 0
},
"index_in_screens_list": 0,
"manufacturer": "Acer Technologies",
"model": "XV272U V",
"name": "DP-1",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-duplicates-question-dialog-geometry": {
"frame_geometry": {
"height": 384,
"width": 748,
"x": 2133,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 384,
"width": 748,
"x": 2133,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 384,
"width": 748,
"x": 2133,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAhVAAAAAAAAC0AAAAF/AAAIVQAAAAAAAAtAAAABfwAAAAAAAAAACFUAAAhVAAAAAAAAC0AAAAF/"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 0,
"y": 0
},
"index_in_screens_list": 0,
"manufacturer": "Acer Technologies",
"model": "XV272U V",
"name": "DP-1",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-jobs_dialog_geometry": {
"frame_geometry": {
"height": 542,
"width": 883,
"x": 2133,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 542,
"width": 883,
"x": 2133,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 542,
"width": 883,
"x": 2133,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAhVAAAAAAAAC8cAAAIdAAAIVQAAAAAAAAvHAAACHQAAAAEAAAAACFUAAAhVAAAAAAAAC8cAAAId"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-metadata_single_gui_geom": {
"frame_geometry": {
"height": 600,
"width": 850,
"x": 2133,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 600,
"width": 850,
"x": 2133,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 600,
"width": 850,
"x": 2133,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAhVAAAAAAAAC6YAAAJXAAAIVQAAAAAAAAumAAACVwAAAAEAAAAACFUAAAhVAAAAAAAAC6YAAAJX"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-metasingle_window_geometry3": {
"frame_geometry": {
"height": 1030,
"width": 1850,
"x": 2133,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 1030,
"width": 1850,
"x": 2133,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 1030,
"width": 1850,
"x": 2133,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAhVAAAAAAAAD44AAAQFAAAIVQAAAAAAAA+OAAAEBQAAAAEAAAAACFUAAAhVAAAAAAAAD44AAAQF"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-preferences dialog geometry": {
"frame_geometry": {
"height": 720,
"width": 1295,
"x": 0,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 720,
"width": 1295,
"x": 0,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 720,
"width": 1295,
"x": 0,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAABQ4AAALPAAAAAAAAAAAAAAUOAAACzwAAAAAAAAAACFUAAAAAAAAAAAAABQ4AAALP"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 0,
"y": 0
},
"index_in_screens_list": 0,
"manufacturer": "Acer Technologies",
"model": "XV272U V",
"name": "DP-1",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-single-cover-fetch-dialog-geometry": {
"frame_geometry": {
"height": 600,
"width": 850,
"x": 0,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 600,
"width": 850,
"x": 0,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 600,
"width": 850,
"x": 0,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAAA1EAAAJXAAAAAAAAAAAAAANRAAACVwAAAAEAAAAACFUAAAAAAAAAAAAAA1EAAAJX"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"geometry-of-template_editor_dialog_geometry": {
"frame_geometry": {
"height": 478,
"width": 706,
"x": 2133,
"y": 0
},
"full_screened": false,
"geometry": {
"height": 478,
"width": 706,
"x": 2133,
"y": 0
},
"maximized": false,
"normal_geometry": {
"height": 478,
"width": 706,
"x": 2133,
"y": 0
},
"qt": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAhVAAAAAAAACxYAAAHdAAAIVQAAAAAAAAsWAAAB3QAAAAEAAAAACFUAAAhVAAAAAAAACxYAAAHd"
},
"screen": {
"depth": 32,
"device_pixel_ratio": 2.0,
"geometry_in_logical_pixels": {
"height": 1200,
"width": 2133,
"x": 2133,
"y": 0
},
"index_in_screens_list": 1,
"manufacturer": "HP Inc.",
"model": "OMEN 27q",
"name": "DP-2",
"serial": "",
"size_in_logical_pixels": {
"height": 1200,
"width": 2133
},
"virtual_geometry": {
"height": 1200,
"width": 4266,
"x": 0,
"y": 0
}
}
},
"gpm_template_editor_font": "Fira Sans",
"gpm_template_editor_word_wrap_mode": true,
"grid view visible": false,
"jobs view column layout3": {
"__class__": "bytearray",
"__value__": "AAAA/wAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA04AAAAFAQEBAAAAAAAAAAAAAAAAAGT/////AAAAhAAAAAAAAAAFAAABRAAAAAEAAAAAAAAAtgAAAAEAAAAAAAAAjAAAAAEAAAAAAAAAZAAAAAEAAAAAAAAAZAAAAAEAAAAAAAAD6AAAAAAAAAAAAA=="
},
"jobs_dialog_geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAGYAAABEQAABQ4AAAMyAAABmgAAARMAAAUMAAADMAAAAAAAAAAAB4AAAAGaAAABEwAABQwAAAMw"
},
"library_usage_stats": {
"/home/exu/.local/share/Calibre-Library": 26,
"/home/marc/Calibre-Bibliothek": 200
},
"main_window_central_widget_state": {
"layout": "wide",
"narrow_desires": {
"book_details_height": 0.23066202090592333,
"cover_browser_width": 0.34992954438703616,
"quick_view_height": 0.2564459930313589,
"tag_browser_width": 0.2498825739783936
},
"narrow_visibility": {
"book_details": true,
"book_list": true,
"cover_browser": false,
"quick_view": false,
"tag_browser": true
},
"wide_desires": {
"book_details_width": 0.21042743071864725,
"cover_browser_height": 0.21367521367521367,
"quick_view_height": 0.2621082621082621,
"tag_browser_width": 0.09394081728511038
},
"wide_visibility": {
"book_details": true,
"book_list": true,
"cover_browser": false,
"quick_view": false,
"tag_browser": true
}
},
"metadata-download-identify-widget-splitter-state": {
"__class__": "bytearray",
"__value__": "AAAA/wAAAAEAAAACAAACAAAAAQAA/////wEAAAABAA=="
},
"metadata_single_gui_geom": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAIiAAAA6QAABXcAAANEAAACJAAAAOsAAAV1AAADQgAAAAAAAAAAB4AAAAIkAAAA6wAABXUAAANC"
},
"metasingle_window_geometry3": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAA+AAAAEgAAB3sAAAQbAAAAQAAAABQAAAd5AAAEGQAAAAAAAAAAB4AAAABAAAAAFAAAB3kAAAQZ"
},
"plugin config dialog:Dateityp:DeACSM": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAMkAAABRAAABKIAAAL9AAADJgAAAUYAAASgAAAC+wAAAAAAAAAAB4AAAAMmAAABRgAABKAAAAL7"
},
"plugin config dialog:Dateityp:DeDRM": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAQAAAAApAAABRoAAAKaAAAEAgAAAKYAAAUYAAACmAAAAAAAAAAAB4AAAAQCAAAApgAABRgAAAKY"
},
"preferences dialog geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAHtAAAApgAABZIAAAN5AAAB7wAAAKgAAAWQAAADdwAAAAAAAAAAB4AAAAHvAAAAqAAABZAAAAN3"
},
"previous_sort_order_BooksView": {
"authors": true,
"rating": true,
"series": true,
"timestamp": false,
"title": true
},
"quick_start_guide_added": true,
"quickview visible": false,
"qv_open_at_shutdown": false,
"recently_used_languages": [
"Englisch"
],
"replace_scene_breaks_history": [
"",
"<hr />",
" ",
"• • •",
"♦ ♦ ♦",
"† †",
"‡ ‡ ‡",
"∞ ∞ ∞",
"¤ ¤ ¤"
],
"search bar visible": true,
"show_files_after_save": false,
"single-cover-fetch-dialog-geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAIhAAAA5wAABXYAAANCAAACIwAAAOkAAAV0AAADQAAAAAAAAAAAB4AAAAIjAAAA6QAABXQAAANA"
},
"tag browser search box visible": false,
"tag_browser_splitter_horizontal_state": [
true,
200
],
"tag_editor_geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAKTAAAAyAAABRYAAANlAAAClQAAAMoAAAUUAAADYwAAAAAAAAAAB4AAAAKVAAAAygAABRQAAANj"
},
"tag_editor_last_filter": "add_tag_input",
"template_editor_table_widths": [
90,
551
]
}

View File

@ -0,0 +1,81 @@
{
"LRF_conversion_defaults": [],
"LRF_ebook_viewer_options": null,
"asked_library_thing_password": false,
"auto_download_cover": false,
"autolaunch_server": false,
"column_map": [
"title",
"ondevice",
"authors",
"size",
"timestamp",
"rating",
"publisher",
"tags",
"series",
"pubdate"
],
"confirm_delete": false,
"cover_flow_queue_length": 6,
"default_send_to_device_action": "DeviceAction:main::False:False",
"delete_news_from_library_on_upload": false,
"disable_animations": false,
"disable_tray_notification": false,
"enforce_cpu_limit": true,
"get_social_metadata": true,
"gui_layout": "wide",
"highlight_search_matches": false,
"internally_viewed_formats": [
"LRF",
"EPUB",
"LIT",
"MOBI",
"PRC",
"POBI",
"AZW",
"AZW3",
"HTML",
"FB2",
"PDB",
"RB",
"SNB",
"HTMLZ",
"KEPUB"
],
"jobs_search_history": [],
"lrf_viewer_search_history": [],
"main_search_history": [],
"main_window_geometry": {
"__class__": "bytearray",
"__value__": "AdnQywADAAAAAAAAAAAAAAAAB38AAAQjAAAAAgAAAAIAAAd9AAAEIQAAAAAAAAAAB4AAAAACAAAAAgAAB30AAAQh"
},
"match_tags_type": "any",
"new_version_notification": true,
"oldest_news": 60,
"overwrite_author_title_metadata": true,
"plugin_search_history": [],
"save_to_disk_template_history": [
"{authors} - {series}/{series} {series_index} - {title}",
"{author_sort}/{title}/{title} - {authors}"
],
"scheduler_search_history": [],
"search_as_you_type": false,
"send_to_device_template_history": [],
"send_to_storage_card_by_default": false,
"separate_cover_flow": false,
"shortcuts_search_history": [],
"show_avg_rating": true,
"sort_tags_by": "name",
"systray_icon": false,
"tag_browser_hidden_categories": {
"__class__": "set",
"__value__": []
},
"tweaks_search_history": [],
"upload_news_to_device": true,
"use_roman_numerals_for_series_number": true,
"viewer_search_history": [],
"viewer_toc_search_history": [],
"worker_limit": 6
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>lineedit_history_xpath_edit_opt_chapter</key>
<array>
<string>//*[((name()='h1' or name()='h2') and re:test(., '\s*((chapter|book|section|part)\s+)|((prolog|prologue|epilogue)(\s+|$))', 'i')) or @class = 'chapter']</string>
</array>
</dict>
</plist>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
{
"domain": "uk",
"ignore_fields": [],
"prefer_kindle_edition": true,
"server": "auto",
"use_mobi_asin": true
}

View File

@ -0,0 +1,4 @@
{
"ignore_fields": [],
"max_covers": 5
}

View File

@ -0,0 +1,3 @@
{
"ignore_fields": []
}

View File

@ -0,0 +1,3 @@
{
"ignore_fields": []
}

View File

@ -0,0 +1,3 @@
{
"ignore_fields": []
}

View File

@ -0,0 +1,11 @@
{
"cover_priorities": {
"Big Book Search": 2,
"Goodreads": 3,
"Google": 2,
"Google Images": 2
},
"fewer_tags": true,
"ignore_fields": [],
"max_tags": 10
}

View File

@ -0,0 +1,11 @@
{
"blacklist": [
"9d273cd5"
],
"history": {
"9d273cd5": [
"ONEPLUS A3003",
"2021-05-15T18:17:07.571225+00:00"
]
}
}

Binary file not shown.

View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<activationInfo xmlns="http://ns.adobe.com/adept">
<adept:activationServiceInfo xmlns:adept="http://ns.adobe.com/adept">
<adept:authURL>http://adeactivate.adobe.com/adept</adept:authURL>
<adept:userInfoURL>http://adeactivate.adobe.com/adept</adept:userInfoURL>
<adept:activationURL>http://adeactivate.adobe.com/adept</adept:activationURL>
<adept:certificate>MIIEsjCCA5qgAwIBAgIER2q5eDANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMRswGQYDVQQLExJEaWdpdGFsIFB1Ymxpc2hpbmcxMzAxBgNVBAMTKkFkb2JlIENvbnRlbnQgU2VydmVyIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wODAxMDkxODM3NDVaFw0xMzAxMDkxOTA3NDVaMH0xCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEbMBkGA1UECxMSRGlnaXRhbCBQdWJsaXNoaW5nMSwwKgYDVQQDEyNodHRwOi8vYWRlYWN0aXZhdGUuYWRvYmUuY29tL2FkZXB0LzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyXpCCWFh0Q3Bi1S7xf+CJfMd+cZz3HB0NknDScB1Cs8KdU0ygO7iqAgdiAdPliITkUTVEgUPvK+4yYCUderzBjq13/IrKlwEAyWeNgssJekpYgqNywo7Md1OApXzM47wVThNePNydhGYuNEEDDxzO+0JxucfhfArwnp7kIWA6q8CAwEAAaOCAbQwggGwMAsGA1UdDwQEAwIFoDBYBglghkgBhvprHgEESwxJVGhlIHByaXZhdGUga2V5IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBjZXJ0aWZpY2F0ZSBtYXkgaGF2ZSBiZWVuIGV4cG9ydGVkLjAUBgNVHSUEDTALBgkqhkiG9y8CAQQwgbIGA1UdIASBqjCBpzCBpAYJKoZIhvcvAQIDMIGWMIGTBggrBgEFBQcCAjCBhhqBg1lvdSBhcmUgbm90IHBlcm1pdHRlZCB0byB1c2UgdGhpcyBMaWNlbnNlIENlcnRpZmljYXRlIGV4Y2VwdCBhcyBwZXJtaXR0ZWQgYnkgdGhlIGxpY2Vuc2UgYWdyZWVtZW50IGFjY29tcGFueWluZyB0aGUgQWRvYmUgc29mdHdhcmUuMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Fkb2JlQ1MuY3JsMB8GA1UdIwQYMBaAFIvu8IFgyaLaHg5SwVgMBLBD94/oMB0GA1UdDgQWBBT9A+kXOPL6N57MN/zovbCGEx2+BTAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQBVjUalliql3VjpLdT8si7OwPU1wQODllwlgfLH7tI/Ubq5wHDlprGtbf3jZm6tXY1qmh9mz1WnTmQHU3uPk8qgpihrpx4HJTjhAhLP0CXU1rd/t5whwhgT1lYfw77RRG2lZ5BzpHb/XjnY5yc3awd6F3Dli6kTkbcPyOCNoXlW4wiF+jkL+jBImY8xo2EewiJioY/iTYZH5HF+PjHF5mffANiLK/Q43l4f0YF8UagTfAJkD3iQV9lrTOWxKBgpfdyvekGqFCDq9AKzfpllqctxsC29W5bXU0cVYzf6Bj5ALs6tyi7r5fsIPSwszH/i4ixsuD0qccIgTXCwMNbt9zQu</adept:certificate>
<adept:authenticationCertificate>MIIEYDCCA0igAwIBAgIER2q5eTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMRswGQYDVQQLExJEaWdpdGFsIFB1Ymxpc2hpbmcxMzAxBgNVBAMTKkFkb2JlIENvbnRlbnQgU2VydmVyIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wODAxMDkxODQzNDNaFw0xODAxMzEwODAwMDBaMHwxKzApBgNVBAMTImh0dHA6Ly9hZGVhY3RpdmF0ZS5hZG9iZS5jb20vYWRlcHQxGzAZBgNVBAsTEkRpZ2l0YWwgUHVibGlzaGluZzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZAxpzOZ7N38ZGlQjfMY/lfu4Ta4xK3FRm069VwdqGZIwrfTTRxnLE4A9i1X00BnNk/5z7C0pQX435ylIEQPxIFBKTH+ip5rfDNh/Iu6cIlB0N4I/t7Pac8cIDwbc9HxcGTvXg3BFqPjaGVbmVZmoUtSVOsphdA43sZc6j1iFfOQIDAQABo4IBYzCCAV8wEgYDVR0TAQH/BAgwBgEB/wIBATAUBgNVHSUEDTALBgkqhkiG9y8CAQUwgbIGA1UdIASBqjCBpzCBpAYJKoZIhvcvAQIDMIGWMIGTBggrBgEFBQcCAjCBhhqBg1lvdSBhcmUgbm90IHBlcm1pdHRlZCB0byB1c2UgdGhpcyBMaWNlbnNlIENlcnRpZmljYXRlIGV4Y2VwdCBhcyBwZXJtaXR0ZWQgYnkgdGhlIGxpY2Vuc2UgYWdyZWVtZW50IGFjY29tcGFueWluZyB0aGUgQWRvYmUgc29mdHdhcmUuMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Fkb2JlQ1MuY3JsMAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSL7vCBYMmi2h4OUsFYDASwQ/eP6DAdBgNVHQ4EFgQU9RP19K+lzF03he+0T47hCVkPhdAwDQYJKoZIhvcNAQEFBQADggEBAJoqOj+bUa+bDYyOSljs6SVzWH2BN2ylIeZKpTQYEo7jA62tRqW/rBZcNIgCudFvEYa7vH8lHhvQak1s95g+NaNidb5tpgbS8Q7/XTyEGS/4Q2HYWHD/8ydKFROGbMhfxpdJgkgn21mb7dbsfq5AZVGS3M4PP1xrMDYm50+Sip9QIm1RJuSaKivDa/piA5p8/cv6w44YBefLzGUN674Y7WS5u656MjdyJsN/7Oup+12fHGiye5QS5mToujGd6LpU80gfhNxhrphASiEBYQ/BUhWjHkSi0j4WOiGvGpT1Xvntcj0rf6XV6lNrOddOYUL+KdC1uDIe8PUI+naKI+nWgrs=</adept:authenticationCertificate>
</adept:activationServiceInfo>
<adept:credentials xmlns:adept="http://ns.adobe.com/adept">
<adept:user>urn:uuid:2d6cfbec-33fd-43ca-bcf9-e8b281114a17</adept:user>
<adept:username method="AdobeID">adobe@frm01.net</adept:username>
<adept:pkcs12>MIIICgIBAzCCB8MGCSqGSIb3DQEHAaCCB7QEggewMIIHrDCCA3AGCSqGSIb3DQEHAaCCA2EEggNdMIIDWTCCA1UGCyqGSIb3DQEMCgECoIICszCCAq8wKQYKKoZIhvcNAQwBAzAbBBQYnc0dHYbt/zeyPvEbYrhgbYyxgwIDAMNQBIICgFqwh/cekpmgYtd57bU3rUEJEohVOC1OrXVh3j9b8UE7RHwiI04O9D0TZtZv0y6IH4VotY/t0j71JAHpXQwVnyQgSB0zrqi7inwJ8p/xFCPvrS/brzZk4hGmSRMfaeyoaqZhTYHThAFw3Hyz7FqmqU5p8bfggSwQ/xOviU7Ct+nBAfkrpaiNfeTQdY63lMKHghYL4IwmZMs6omaVN0ngMuN4/Nhfp7Ij0FK8SmpMMsRJCXSAAk6VjxNBKlLHwgkA4C+qxdyK7LXLd5JO3lGWpR2x+mBHalYt07xaq6OuuNWQKv0Ho1o75Rv3Blibnj8dvcweb3/3aEP0G3p+BfU2bFKrb3pAn3ClsPO1JJnncYdOLmNdkUlmbHK2RIAgAIqE/aJy1QblRcN34drbbV7FMEHScMdaUf6HVTvEj2TkZRT56GxpI4nhIE9KVzzUrj03COLYkRsfkp1NhfBJC1W324Q9Qd4veQWgpAGzYrpN9KwfQsMvNAEijuV0ExYcDxhcp+8cPcCcyjvm8DICAHKCnHtyDHFTutXR6fMQ8Jphu7uz4Sm++YDXby5M+Kb4luK5u8+PDlqfJ5LGAJ54MlzqGUK0OK/NN9U76ga5ekpFeU5wq2DTCQIZ/M4QuHcaTXpme8YempZzcnFWLh5HD/HDQOddCPoxvinGcjiPxC7MWOMKvWPu/oETHNUWYvCz12O8EycWIi4a0dW6Sa0DlC2S0wBBP2lgvd41/M/CksFuqUjiww9CsBMwzbFlmv0ebi9ZKD7IHVz68s+DV3swIGVq7EKSlCGrHNbthnAeOIlk1lwRUTn09a8cRDo8tomY6cBxxdlyqN24mq0vFhwTfqO2CBgxgY4waQYJKoZIhvcNAQkUMVweWgB1AHIAbgA6AHUAdQBpAGQAOgAyAGQANgBjAGYAYgBlAGMALQAzADMAZgBkAC0ANAAzAGMAYQAtAGIAYwBmADkALQBlADgAYgAyADgAMQAxADEANABhADEANzAhBgkqhkiG9w0BCRUxFAQSVGltZSAxNjU4ODU5ODkzNjE4MIIENAYJKoZIhvcNAQcGoIIEJTCCBCECAQAwggQaBgkqhkiG9w0BBwEwKQYKKoZIhvcNAQwBBjAbBBS6J/ZgKvOxIDg+c1iftQoiDAEjXQIDAMNQgIID4Hvb0y7+KcU6CEWDRPRqY6v9CGWmZxT2Ih2P0azuqio0N3tOb+fl4vymhvcJzdGAG1wTX9c2BpZBM7hMVq1YZuM1/rpdXSnbizBYa+ZzcbbYoNU77yQujwQtcJG1JwZI+VCJMJ+rXCKP+0ebIuCmh7AvcfN2tj48h3TFIeRbeic+YjvqB7RifbnaoVkV56L4k2TeKy1yrTqE8K5I7lICEVJA/ouXWOHdpMcse4SGRZ6n3JmZnC6aCoZTwKydQ0HGW7EvkmK+b3DS8gf3SGLvDEz3k3H41oYvr8zAN40ID7a71wdKHIlDcSeLkzZt6YNZBMXeH8ZlNf3s2qiCX79lRHuKlH7GYjNoUoLlAKO1OSwluxr6qKsLizOrmj7pgledFGYW5iCxVUooXneou/fDJtpOZGVKugPmwT5hL4ouiDI7R7gzWaGDjK0EIorthBTOymwj+hMx5wJ+2g42a0UyD0n73G5e1zRE7hT5axOXULsYMiKTJMCEopRVV70fjAsInBmDOCjIzRsPKtVIrVpOVJIr0zULLqyPucnaeJHpr9sb9hojUqRRZy55wnb5L7JbNLWnRTGLApnmhTx5KmbBTo7UdpyhWUqsApPrhRf3pMXPPBzkEZgeSEp2un3lnPMNhKVpo9lH2Ox206UXlzCYtrK+i+bH1wJdgdoDXzF01ysad8hHAcZJSUNF/i09DaoaFkX3uuPRbiqt5hgYdXb3E3aA5E/ChA80jFjaMLRBbsXSwvn7Ok9LD+kEUOoFvMyz9HrTS3j7fKQRvu20fn3uzyIkUyva46WlNWP/3KGcq1fWarJAuhYgwZbw3o9LB09w87uISN71Wm5pnYpAiFUo48oiTO/PB6F9F8SPiqR8h40Ghjvp7dFm9HzyXjq14T0GBkyG8RaJn9umc4yz1vOt7wPCXyf92cDltlSstpoY+SKrECTMcmnY//b9fyjRiXU4KJ7idSeKmF6thz1SBZ7FzUSoeozPHs+WOmIrVRJDez7J766oJBstqycIq15UVAPGt09ND/WXmhxDyHfZPlrR49YW87CLTFY8MmiOgd/fr+1gTsZqxLLb7L303MKeOQ8Lb0s4bMqGuCLsW/WcniHFhezN7YwyyAsdFhrI/Ugro2uDFlZ3BgAsipaqyzc4kyfGxjkSuIarzxV7huswH8COHSd0Jf9wj8iCLQSw4gX627C9F9dNy0AqT8uwXa/Z78leKUfSbbUB06Veram5y0kXnWGM97WyYKezxpmUHXUagZb5v6zG3o62/ia43tr8YmmUsJ9eyrl3xA+7RkERta/vryBuse5wQhpjd8F/2IxHnSG0MD4wITAJBgUrDgMCGgUABBSD2oMtYGOzFgykxeJda8+qoJQ7BAQUdwkJW7jL0vGmUxZNCAB2k3wM828CAwGGoA==</adept:pkcs12>
<adept:licenseCertificate>MIIDGDCCAoGgAwIBAgIGAYI7wTNyMA0GCSqGSIb3DQEBBQUAMHwxKzApBgNVBAMTImh0dHA6Ly9hZGVhY3RpdmF0ZS5hZG9iZS5jb20vYWRlcHQxGzAZBgNVBAsTEkRpZ2l0YWwgUHVibGlzaGluZzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxCzAJBgNVBAYTAlVTMB4XDTIyMDcyNjE4MjQ1M1oXDTMyMDcyNjE4MjQ1M1owODE2MDQGA1UEAxMtdXJuOnV1aWQ6MmQ2Y2ZiZWMtMzNmZC00M2NhLWJjZjktZThiMjgxMTE0YTE3MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDf+bPePv4GMbGBRssk/3dXktw0nIou8bhWCXha1i+rRi3VpuhHkj02KgBjOaEWEZy3Xkjkv7JGedv2cT0ZShIC6wOvGTsKT2Y3IJpNgWoZzniaWPz1zAGKffe41vjhrVj+8Vbtmt0MhxUbM3uA47echS7Kg9Cp036ydHYX70EeVQIDAQABo4HoMIHlMIG0BgNVHSMEgawwgamAFPUT9fSvpcxdN4XvtE+O4QlZD4XQoYGKpIGHMIGEMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxGzAZBgNVBAsTEkRpZ2l0YWwgUHVibGlzaGluZzEzMDEGA1UEAxMqQWRvYmUgQ29udGVudCBTZXJ2ZXIgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggRHarl5MAkGA1UdEwQCMAAwFAYDVR0lBA0wCwYJKoZIhvcvAgEHMAsGA1UdDwQEAwIFIDANBgkqhkiG9w0BAQUFAAOBgQC0lvq2fT3XCu8dB4au2kdQQvMPSVPLet9cS5bF5YSmox4YhLjF8BzBojNinU7fmxAnr5DL4Z4JL2OSf70SL6BOZAZUP8LTf2m3ES5096GGLvGryqNmHIeyublHhAa4sp7ya51NpkAi/Cj765WxORTMY+sF9D92R23Jj+Y8QslG1A==</adept:licenseCertificate>
<adept:privateLicenseKey>MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN/5s94+/gYxsYFGyyT/d1eS3DScii7xuFYJeFrWL6tGLdWm6EeSPTYqAGM5oRYRnLdeSOS/skZ52/ZxPRlKEgLrA68ZOwpPZjcgmk2BahnOeJpY/PXMAYp997jW+OGtWP7xVu2a3QyHFRsze4Djt5yFLsqD0KnTfrJ0dhfvQR5VAgMBAAECgYBfw07xhnNsSJEBmjg/YG8xZVx7rjay7a0INFJeXFfTXlU4lX2ZJGDBqOGziy9h1TPxfwGhtIjP80hmLXKXPoFGKyTRhf1Z2QsLefX1hhpHhuWI6NxEtQiUiN4oD+igvIWQnPYkRJtth14hvOkl9wtQM6zFG1IV+8hkZf6gJ4c8gQJBAPq3K/UfSjHz1YmIo86wGU8bZHnsdo2uOX0biH3cQ20WsLv2cj6wo/DmFgVAE8hbYkW2yfrfN/ddL1skXTOHnSECQQDksj6mcZyzROW+DGC6csNEMuKVez7/DlWak4M4XwWa8wpQZPAqilNPjmrdK13Bsmxp8TrQDAJt4h/16GrWaEa1AkEAjdgQAJCBU52WVEeAFbG/v+fJgslrkWDemY94O2zgoNlTiCQ4IouhVOt3zeSgzJwXD0YJI+wiJ8sKvc/nAv5YwQJBAJVqp2gTnm+5ueh7Kc9nH5C1Nji3tybo9KDzc64m1wCvfbOc3xTMHzZBNCygIrdknVRyWRyIXCXysTL20KaYpmkCQHNYn681QtlOYC1AyMFcn/w78DmQwTDqlKIyx9oyaRJlEcq6KSeBgu1LJ0pGYq/5EGMYrp0KqMn/qXQ/1OSTY9M=</adept:privateLicenseKey>
<adept:authenticationCertificate>MIIEYDCCA0igAwIBAgIER2q5eTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMRswGQYDVQQLExJEaWdpdGFsIFB1Ymxpc2hpbmcxMzAxBgNVBAMTKkFkb2JlIENvbnRlbnQgU2VydmVyIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wODAxMDkxODQzNDNaFw0xODAxMzEwODAwMDBaMHwxKzApBgNVBAMTImh0dHA6Ly9hZGVhY3RpdmF0ZS5hZG9iZS5jb20vYWRlcHQxGzAZBgNVBAsTEkRpZ2l0YWwgUHVibGlzaGluZzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZAxpzOZ7N38ZGlQjfMY/lfu4Ta4xK3FRm069VwdqGZIwrfTTRxnLE4A9i1X00BnNk/5z7C0pQX435ylIEQPxIFBKTH+ip5rfDNh/Iu6cIlB0N4I/t7Pac8cIDwbc9HxcGTvXg3BFqPjaGVbmVZmoUtSVOsphdA43sZc6j1iFfOQIDAQABo4IBYzCCAV8wEgYDVR0TAQH/BAgwBgEB/wIBATAUBgNVHSUEDTALBgkqhkiG9y8CAQUwgbIGA1UdIASBqjCBpzCBpAYJKoZIhvcvAQIDMIGWMIGTBggrBgEFBQcCAjCBhhqBg1lvdSBhcmUgbm90IHBlcm1pdHRlZCB0byB1c2UgdGhpcyBMaWNlbnNlIENlcnRpZmljYXRlIGV4Y2VwdCBhcyBwZXJtaXR0ZWQgYnkgdGhlIGxpY2Vuc2UgYWdyZWVtZW50IGFjY29tcGFueWluZyB0aGUgQWRvYmUgc29mdHdhcmUuMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Fkb2JlQ1MuY3JsMAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSL7vCBYMmi2h4OUsFYDASwQ/eP6DAdBgNVHQ4EFgQU9RP19K+lzF03he+0T47hCVkPhdAwDQYJKoZIhvcNAQEFBQADggEBAJoqOj+bUa+bDYyOSljs6SVzWH2BN2ylIeZKpTQYEo7jA62tRqW/rBZcNIgCudFvEYa7vH8lHhvQak1s95g+NaNidb5tpgbS8Q7/XTyEGS/4Q2HYWHD/8ydKFROGbMhfxpdJgkgn21mb7dbsfq5AZVGS3M4PP1xrMDYm50+Sip9QIm1RJuSaKivDa/piA5p8/cv6w44YBefLzGUN674Y7WS5u656MjdyJsN/7Oup+12fHGiye5QS5mToujGd6LpU80gfhNxhrphASiEBYQ/BUhWjHkSi0j4WOiGvGpT1Xvntcj0rf6XV6lNrOddOYUL+KdC1uDIe8PUI+naKI+nWgrs=</adept:authenticationCertificate>
</adept:credentials>
<activationToken xmlns="http://ns.adobe.com/adept">
<device>urn:uuid:32095968-696a-46d1-95ef-e76097c33051</device>
<fingerprint>Pa7vI/H67wVERB/TsVjesFE6Kws=</fingerprint>
<deviceType>standalone</deviceType>
<activationURL>http://adeactivate.adobe.com/adept</activationURL>
<user>urn:uuid:2d6cfbec-33fd-43ca-bcf9-e8b281114a17</user>
<signature>B+Y6HxQ3o203HDb/5rSnal6Ca9tE8FEmVyiFcVpE9R7QzHo2NbpFzFHssFd2L+C7HKdFQ4pg+SFxyBLrDpLEdzILfPu+gRsDOvk/AGSisXEvdHsTFK9Yc5Cjkz8WkmWM1N6rgJ30V8AW6/d0mHj81g+Iue8VO8soBPkFwXGX1u4=</signature>
</activationToken>
<adept:operatorURLList xmlns:adept="http://ns.adobe.com/adept"><adept:user>urn:uuid:2d6cfbec-33fd-43ca-bcf9-e8b281114a17</adept:user><adept:operatorURL>https://acs4.kobo.com/fulfillment/Fulfill</adept:operatorURL></adept:operatorURLList><adept:licenseServices xmlns:adept="http://ns.adobe.com/adept"><adept:licenseServiceInfo><adept:licenseURL>https://nasigningservice.adobe.com/licensesign</adept:licenseURL><adept:certificate>MIIEvjCCA6agAwIBAgIER2q5ljANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMRswGQYDVQQLExJEaWdpdGFsIFB1Ymxpc2hpbmcxMzAxBgNVBAMTKkFkb2JlIENvbnRlbnQgU2VydmVyIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wODA4MTExNjMzNDhaFw0xMzA4MTEwNzAwMDBaMIGIMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxGzAZBgNVBAsTEkRpZ2l0YWwgUHVibGlzaGluZzE3MDUGA1UEAxMuaHR0cHM6Ly9uYXNpZ25pbmdzZXJ2aWNlLmFkb2JlLmNvbS9saWNlbnNlc2lnbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs9GRZ1f5UTRySgZ2xAL7TaDKQBfdpIS9ei9Orica0N72BB/WE+82G5lfsZ2HdeCFDZG/oz2WPLXovcuUAbFKSIXVLyc7ONOd4sczeXQYPixeAvqzGtsyMArIzaeJcriGVPRnbD/spbuHR0BHhJEakIiDtQLJz+xgVYHlicx2H/kCAwEAAaOCAbQwggGwMAsGA1UdDwQEAwIFoDBYBglghkgBhvprHgEESwxJVGhlIHByaXZhdGUga2V5IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBjZXJ0aWZpY2F0ZSBtYXkgaGF2ZSBiZWVuIGV4cG9ydGVkLjAUBgNVHSUEDTALBgkqhkiG9y8CAQIwgbIGA1UdIASBqjCBpzCBpAYJKoZIhvcvAQIDMIGWMIGTBggrBgEFBQcCAjCBhhqBg1lvdSBhcmUgbm90IHBlcm1pdHRlZCB0byB1c2UgdGhpcyBMaWNlbnNlIENlcnRpZmljYXRlIGV4Y2VwdCBhcyBwZXJtaXR0ZWQgYnkgdGhlIGxpY2Vuc2UgYWdyZWVtZW50IGFjY29tcGFueWluZyB0aGUgQWRvYmUgc29mdHdhcmUuMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Fkb2JlQ1MuY3JsMB8GA1UdIwQYMBaAFIvu8IFgyaLaHg5SwVgMBLBD94/oMB0GA1UdDgQWBBSQ5K+bvggI6Rbh2u9nPhH8bcYTITAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQC0l1L+BRCccZdb2d9zQBJ7JHkXWt1x/dUydU9I/na+QPFE5x+fGK4cRwaIfp6fNviGyvtJ6Wnxe6du/wlarC1o26UNpyWpnAltcy47LpVXsmcV5rUlhBx10l4lecuX0nx8/xF8joRz2BvvAusK+kxgKeiAjJg2W20wbJKh0Otct1ZihruQsEtGbZJ1L55xfNhrm6CKAHuGuTDYQ/S6W20dUaDUiNFhA2n2eEySLwUwgOuuhfVUPb8amQQKbF4rOQ2rdjAskEl/0CiavW6Xv0LGihThf6CjEbNSdy+vXQ7K9wFbKsE843DflpuSPfj2Aagtyrv/j1HsBjsf03e0uVu5</adept:certificate></adept:licenseServiceInfo></adept:licenseServices></activationInfo>

View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<adept:deviceInfo xmlns:adept="http://ns.adobe.com/adept">
<adept:deviceType>standalone</adept:deviceType>
<adept:deviceClass>Desktop</adept:deviceClass>
<adept:deviceSerial>84abdfab8a0837c803a405f01b2fe493ae7b8c10</adept:deviceSerial>
<adept:deviceName>lupusregina</adept:deviceName>
<adept:version name="hobbes" value="9.3.58046"/>
<adept:version name="clientOS" value="Windows Vista"/>
<adept:version name="clientLocale" value="de"/>
<adept:fingerprint>Pa7vI/H67wVERB/TsVjesFE6Kws=</adept:fingerprint>
</adept:deviceInfo>

View File

@ -0,0 +1 @@
<EFBFBD>6(8[hK4<4B><03><>w,<2C>

View File

@ -0,0 +1,13 @@
.tox/
__pycache__/
build/
dist/
tests/output/
tmp/
*.egg-info/
*.pyc
*.pyo
.python-version
.DS_Store
.coverage
coverage.xml

View File

@ -0,0 +1,19 @@
Copyright (c) 2015-2022 Will Bond <will@wbond.net>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,305 @@
Metadata-Version: 2.1
Name: asn1crypto
Version: 1.5.1
Summary: Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP
Home-page: https://github.com/wbond/asn1crypto
Author: wbond
Author-email: will@wbond.net
License: MIT
Description: # asn1crypto
A fast, pure Python library for parsing and serializing ASN.1 structures.
- [Features](#features)
- [Why Another Python ASN.1 Library?](#why-another-python-asn1-library)
- [Related Crypto Libraries](#related-crypto-libraries)
- [Current Release](#current-release)
- [Dependencies](#dependencies)
- [Installation](#installation)
- [License](#license)
- [Security Policy](#security-policy)
- [Documentation](#documentation)
- [Continuous Integration](#continuous-integration)
- [Testing](#testing)
- [Development](#development)
- [CI Tasks](#ci-tasks)
[![GitHub Actions CI](https://github.com/wbond/asn1crypto/workflows/CI/badge.svg)](https://github.com/wbond/asn1crypto/actions?workflow=CI)
[![CircleCI](https://circleci.com/gh/wbond/asn1crypto.svg?style=shield)](https://circleci.com/gh/wbond/asn1crypto)
[![PyPI](https://img.shields.io/pypi/v/asn1crypto.svg)](https://pypi.org/project/asn1crypto/)
## Features
In addition to an ASN.1 BER/DER decoder and DER serializer, the project includes
a bunch of ASN.1 structures for use with various common cryptography standards:
| Standard | Module | Source |
| ---------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| X.509 | [`asn1crypto.x509`](asn1crypto/x509.py) | [RFC 5280](https://tools.ietf.org/html/rfc5280) |
| CRL | [`asn1crypto.crl`](asn1crypto/crl.py) | [RFC 5280](https://tools.ietf.org/html/rfc5280) |
| CSR | [`asn1crypto.csr`](asn1crypto/csr.py) | [RFC 2986](https://tools.ietf.org/html/rfc2986), [RFC 2985](https://tools.ietf.org/html/rfc2985) |
| OCSP | [`asn1crypto.ocsp`](asn1crypto/ocsp.py) | [RFC 6960](https://tools.ietf.org/html/rfc6960) |
| PKCS#12 | [`asn1crypto.pkcs12`](asn1crypto/pkcs12.py) | [RFC 7292](https://tools.ietf.org/html/rfc7292) |
| PKCS#8 | [`asn1crypto.keys`](asn1crypto/keys.py) | [RFC 5208](https://tools.ietf.org/html/rfc5208) |
| PKCS#1 v2.1 (RSA keys) | [`asn1crypto.keys`](asn1crypto/keys.py) | [RFC 3447](https://tools.ietf.org/html/rfc3447) |
| DSA keys | [`asn1crypto.keys`](asn1crypto/keys.py) | [RFC 3279](https://tools.ietf.org/html/rfc3279) |
| Elliptic curve keys | [`asn1crypto.keys`](asn1crypto/keys.py) | [SECG SEC1 V2](http://www.secg.org/sec1-v2.pdf) |
| PKCS#3 v1.4 | [`asn1crypto.algos`](asn1crypto/algos.py) | [PKCS#3 v1.4](ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc) |
| PKCS#5 v2.1 | [`asn1crypto.algos`](asn1crypto/algos.py) | [PKCS#5 v2.1](http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf) |
| CMS (and PKCS#7) | [`asn1crypto.cms`](asn1crypto/cms.py) | [RFC 5652](https://tools.ietf.org/html/rfc5652), [RFC 2315](https://tools.ietf.org/html/rfc2315) |
| TSP | [`asn1crypto.tsp`](asn1crypto/tsp.py) | [RFC 3161](https://tools.ietf.org/html/rfc3161) |
| PDF signatures | [`asn1crypto.pdf`](asn1crypto/pdf.py) | [PDF 1.7](http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf) |
## Why Another Python ASN.1 Library?
Python has long had the [pyasn1](https://pypi.org/project/pyasn1/) and
[pyasn1_modules](https://pypi.org/project/pyasn1-modules/) available for
parsing and serializing ASN.1 structures. While the project does include a
comprehensive set of tools for parsing and serializing, the performance of the
library can be very poor, especially when dealing with bit fields and parsing
large structures such as CRLs.
After spending extensive time using *pyasn1*, the following issues were
identified:
1. Poor performance
2. Verbose, non-pythonic API
3. Out-dated and incomplete definitions in *pyasn1-modules*
4. No simple way to map data to native Python data structures
5. No mechanism for overridden universal ASN.1 types
The *pyasn1* API is largely method driven, and uses extensive configuration
objects and lowerCamelCase names. There were no consistent options for
converting types of native Python data structures. Since the project supports
out-dated versions of Python, many newer language features are unavailable
for use.
Time was spent trying to profile issues with the performance, however the
architecture made it hard to pin down the primary source of the poor
performance. Attempts were made to improve performance by utilizing unreleased
patches and delaying parsing using the `Any` type. Even with such changes, the
performance was still unacceptably slow.
Finally, a number of structures in the cryptographic space use universal data
types such as `BitString` and `OctetString`, but interpret the data as other
types. For instance, signatures are really byte strings, but are encoded as
`BitString`. Elliptic curve keys use both `BitString` and `OctetString` to
represent integers. Parsing these structures as the base universal types and
then re-interpreting them wastes computation.
*asn1crypto* uses the following techniques to improve performance, especially
when extracting one or two fields from large, complex structures:
- Delayed parsing of byte string values
- Persistence of original ASN.1 encoded data until a value is changed
- Lazy loading of child fields
- Utilization of high-level Python stdlib modules
While there is no extensive performance test suite, the
`CRLTests.test_parse_crl` test case was used to parse a 21MB CRL file on a
late 2013 rMBP. *asn1crypto* parsed the certificate serial numbers in just
under 8 seconds. With *pyasn1*, using definitions from *pyasn1-modules*, the
same parsing took over 4,100 seconds.
For smaller structures the performance difference can range from a few times
faster to an order of magnitude or more.
## Related Crypto Libraries
*asn1crypto* is part of the modularcrypto family of Python packages:
- [asn1crypto](https://github.com/wbond/asn1crypto)
- [oscrypto](https://github.com/wbond/oscrypto)
- [csrbuilder](https://github.com/wbond/csrbuilder)
- [certbuilder](https://github.com/wbond/certbuilder)
- [crlbuilder](https://github.com/wbond/crlbuilder)
- [ocspbuilder](https://github.com/wbond/ocspbuilder)
- [certvalidator](https://github.com/wbond/certvalidator)
## Current Release
1.5.0 - [changelog](changelog.md)
## Dependencies
Python 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10 or pypy. *No third-party
packages required.*
## Installation
```bash
pip install asn1crypto
```
## License
*asn1crypto* is licensed under the terms of the MIT license. See the
[LICENSE](LICENSE) file for the exact license text.
## Security Policy
The security policies for this project are covered in
[SECURITY.md](https://github.com/wbond/asn1crypto/blob/master/SECURITY.md).
## Documentation
The documentation for *asn1crypto* is composed of tutorials on basic usage and
links to the source for the various pre-defined type classes.
### Tutorials
- [Universal Types with BER/DER Decoder and DER Encoder](docs/universal_types.md)
- [PEM Encoder and Decoder](docs/pem.md)
### Reference
- [Universal types](asn1crypto/core.py), `asn1crypto.core`
- [Digest, HMAC, signed digest and encryption algorithms](asn1crypto/algos.py), `asn1crypto.algos`
- [Private and public keys](asn1crypto/keys.py), `asn1crypto.keys`
- [X509 certificates](asn1crypto/x509.py), `asn1crypto.x509`
- [Certificate revocation lists (CRLs)](asn1crypto/crl.py), `asn1crypto.crl`
- [Online certificate status protocol (OCSP)](asn1crypto/ocsp.py), `asn1crypto.ocsp`
- [Certificate signing requests (CSRs)](asn1crypto/csr.py), `asn1crypto.csr`
- [Private key/certificate containers (PKCS#12)](asn1crypto/pkcs12.py), `asn1crypto.pkcs12`
- [Cryptographic message syntax (CMS, PKCS#7)](asn1crypto/cms.py), `asn1crypto.cms`
- [Time stamp protocol (TSP)](asn1crypto/tsp.py), `asn1crypto.tsp`
- [PDF signatures](asn1crypto/pdf.py), `asn1crypto.pdf`
## Continuous Integration
Various combinations of platforms and versions of Python are tested via:
- [macOS, Linux, Windows](https://github.com/wbond/asn1crypto/actions/workflows/ci.yml) via GitHub Actions
- [arm64](https://circleci.com/gh/wbond/asn1crypto) via CircleCI
## Testing
Tests are written using `unittest` and require no third-party packages.
Depending on what type of source is available for the package, the following
commands can be used to run the test suite.
### Git Repository
When working within a Git working copy, or an archive of the Git repository,
the full test suite is run via:
```bash
python run.py tests
```
To run only some tests, pass a regular expression as a parameter to `tests`.
```bash
python run.py tests ocsp
```
### PyPi Source Distribution
When working within an extracted source distribution (aka `.tar.gz`) from
PyPi, the full test suite is run via:
```bash
python setup.py test
```
### Package
When the package has been installed via pip (or another method), the package
`asn1crypto_tests` may be installed and invoked to run the full test suite:
```bash
pip install asn1crypto_tests
python -m asn1crypto_tests
```
## Development
To install the package used for linting, execute:
```bash
pip install --user -r requires/lint
```
The following command will run the linter:
```bash
python run.py lint
```
Support for code coverage can be installed via:
```bash
pip install --user -r requires/coverage
```
Coverage is measured by running:
```bash
python run.py coverage
```
To change the version number of the package, run:
```bash
python run.py version {pep440_version}
```
To install the necessary packages for releasing a new version on PyPI, run:
```bash
pip install --user -r requires/release
```
Releases are created by:
- Making a git tag in [PEP 440](https://www.python.org/dev/peps/pep-0440/#examples-of-compliant-version-schemes) format
- Running the command:
```bash
python run.py release
```
Existing releases can be found at https://pypi.org/project/asn1crypto/.
## CI Tasks
A task named `deps` exists to download and stage all necessary testing
dependencies. On posix platforms, `curl` is used for downloads and on Windows
PowerShell with `Net.WebClient` is used. This configuration sidesteps issues
related to getting pip to work properly and messing with `site-packages` for
the version of Python being used.
The `ci` task runs `lint` (if flake8 is available for the version of Python) and
`coverage` (or `tests` if coverage is not available for the version of Python).
If the current directory is a clean git working copy, the coverage data is
submitted to codecov.io.
```bash
python run.py deps
python run.py ci
```
Keywords: asn1 crypto pki x509 certificate rsa dsa ec dh
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Security :: Cryptography
Description-Content-Type: text/markdown

View File

@ -0,0 +1,37 @@
# Security Policy
## How to Report
If you believe you've found an issue that has security implications, please do
not post a public issue on GitHub. Instead, email the project lead, Will Bond,
at will@wbond.net.
You should receive a response within two business days, and follow up emails
during the process of confirming the potential issue.
## Supported Versions
The asn1crypto project only provides security patches for the most recent
release. This is primarily a function of available resources.
## Disclosure Process
The following process is used when handling a potential secuirty issue:
1. The report should be emailed to will@wbond.net, and NOT posted on the
GitHub issue tracker.
2. Confirmation of receipt of the report should happen within two business
days.
3. Information will be collected and an investigation will be performed to
determine if a security issue exists.
4. If no security issue is found, the process will end.
5. A fix for the issue and announcement will be drafted.
6. A release schedule and accouncement will be negotiated between the
reporter and the project
7. The security contacts for Arch Linux, Conda, Debian, Fedora, FreeBSD,
Ubuntu, and Tidelift will be contacted to notify them of an upcoming
security release.
8. Fixes for all vulnerabilities will be performed, and new releases made,
but without mention of a security issue. These changes and releases will
be published before the announcement.
9. An announcement will be made disclosing the vulnerability and the fix.

View File

@ -0,0 +1,47 @@
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
from .version import __version__, __version_info__
__all__ = [
'__version__',
'__version_info__',
'load_order',
]
def load_order():
"""
Returns a list of the module and sub-module names for asn1crypto in
dependency load order, for the sake of live reloading code
:return:
A list of unicode strings of module names, as they would appear in
sys.modules, ordered by which module should be reloaded first
"""
return [
'asn1crypto._errors',
'asn1crypto._int',
'asn1crypto._ordereddict',
'asn1crypto._teletex_codec',
'asn1crypto._types',
'asn1crypto._inet',
'asn1crypto._iri',
'asn1crypto.version',
'asn1crypto.pem',
'asn1crypto.util',
'asn1crypto.parser',
'asn1crypto.core',
'asn1crypto.algos',
'asn1crypto.keys',
'asn1crypto.x509',
'asn1crypto.crl',
'asn1crypto.csr',
'asn1crypto.ocsp',
'asn1crypto.cms',
'asn1crypto.pdf',
'asn1crypto.pkcs12',
'asn1crypto.tsp',
'asn1crypto',
]

View File

@ -0,0 +1,54 @@
# coding: utf-8
"""
Exports the following items:
- unwrap()
- APIException()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import re
import textwrap
class APIException(Exception):
"""
An exception indicating an API has been removed from asn1crypto
"""
pass
def unwrap(string, *params):
"""
Takes a multi-line string and does the following:
- dedents
- converts newlines with text before and after into a single line
- strips leading and trailing whitespace
:param string:
The string to format
:param *params:
Params to interpolate into the string
:return:
The formatted string
"""
output = textwrap.dedent(string)
# Unwrap lines, taking into account bulleted lists, ordered lists and
# underlines consisting of = signs
if output.find('\n') != -1:
output = re.sub('(?<=\\S)\n(?=[^ \n\t\\d\\*\\-=])', ' ', output)
if params:
output = output % params
output = output.strip()
return output

View File

@ -0,0 +1,170 @@
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
import socket
import struct
from ._errors import unwrap
from ._types import byte_cls, bytes_to_list, str_cls, type_name
def inet_ntop(address_family, packed_ip):
"""
Windows compatibility shim for socket.inet_ntop().
:param address_family:
socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
:param packed_ip:
A byte string of the network form of an IP address
:return:
A unicode string of the IP address
"""
if address_family not in set([socket.AF_INET, socket.AF_INET6]):
raise ValueError(unwrap(
'''
address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),
not %s
''',
repr(socket.AF_INET),
repr(socket.AF_INET6),
repr(address_family)
))
if not isinstance(packed_ip, byte_cls):
raise TypeError(unwrap(
'''
packed_ip must be a byte string, not %s
''',
type_name(packed_ip)
))
required_len = 4 if address_family == socket.AF_INET else 16
if len(packed_ip) != required_len:
raise ValueError(unwrap(
'''
packed_ip must be %d bytes long - is %d
''',
required_len,
len(packed_ip)
))
if address_family == socket.AF_INET:
return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip))
octets = struct.unpack(b'!HHHHHHHH', packed_ip)
runs_of_zero = {}
longest_run = 0
zero_index = None
for i, octet in enumerate(octets + (-1,)):
if octet != 0:
if zero_index is not None:
length = i - zero_index
if length not in runs_of_zero:
runs_of_zero[length] = zero_index
longest_run = max(longest_run, length)
zero_index = None
elif zero_index is None:
zero_index = i
hexed = [hex(o)[2:] for o in octets]
if longest_run < 2:
return ':'.join(hexed)
zero_start = runs_of_zero[longest_run]
zero_end = zero_start + longest_run
return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:])
def inet_pton(address_family, ip_string):
"""
Windows compatibility shim for socket.inet_ntop().
:param address_family:
socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
:param ip_string:
A unicode string of an IP address
:return:
A byte string of the network form of the IP address
"""
if address_family not in set([socket.AF_INET, socket.AF_INET6]):
raise ValueError(unwrap(
'''
address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),
not %s
''',
repr(socket.AF_INET),
repr(socket.AF_INET6),
repr(address_family)
))
if not isinstance(ip_string, str_cls):
raise TypeError(unwrap(
'''
ip_string must be a unicode string, not %s
''',
type_name(ip_string)
))
if address_family == socket.AF_INET:
octets = ip_string.split('.')
error = len(octets) != 4
if not error:
ints = []
for o in octets:
o = int(o)
if o > 255 or o < 0:
error = True
break
ints.append(o)
if error:
raise ValueError(unwrap(
'''
ip_string must be a dotted string with four integers in the
range of 0 to 255, got %s
''',
repr(ip_string)
))
return struct.pack(b'!BBBB', *ints)
error = False
omitted = ip_string.count('::')
if omitted > 1:
error = True
elif omitted == 0:
octets = ip_string.split(':')
error = len(octets) != 8
else:
begin, end = ip_string.split('::')
begin_octets = begin.split(':')
end_octets = end.split(':')
missing = 8 - len(begin_octets) - len(end_octets)
octets = begin_octets + (['0'] * missing) + end_octets
if not error:
ints = []
for o in octets:
o = int(o, 16)
if o > 65535 or o < 0:
error = True
break
ints.append(o)
return struct.pack(b'!HHHHHHHH', *ints)
raise ValueError(unwrap(
'''
ip_string must be a valid ipv6 string, got %s
''',
repr(ip_string)
))

View File

@ -0,0 +1,22 @@
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
def fill_width(bytes_, width):
"""
Ensure a byte string representing a positive integer is a specific width
(in bytes)
:param bytes_:
The integer byte string
:param width:
The desired width as an integer
:return:
A byte string of the width specified
"""
while len(bytes_) < width:
bytes_ = b'\x00' + bytes_
return bytes_

View File

@ -0,0 +1,291 @@
# coding: utf-8
"""
Functions to convert unicode IRIs into ASCII byte string URIs and back. Exports
the following items:
- iri_to_uri()
- uri_to_iri()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from encodings import idna # noqa
import codecs
import re
import sys
from ._errors import unwrap
from ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types
if sys.version_info < (3,):
from urlparse import urlsplit, urlunsplit
from urllib import (
quote as urlquote,
unquote as unquote_to_bytes,
)
else:
from urllib.parse import (
quote as urlquote,
unquote_to_bytes,
urlsplit,
urlunsplit,
)
def iri_to_uri(value, normalize=False):
"""
Encodes a unicode IRI into an ASCII byte string URI
:param value:
A unicode string of an IRI
:param normalize:
A bool that controls URI normalization
:return:
A byte string of the ASCII-encoded URI
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
value must be a unicode string, not %s
''',
type_name(value)
))
scheme = None
# Python 2.6 doesn't split properly is the URL doesn't start with http:// or https://
if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'):
real_prefix = None
prefix_match = re.match('^[^:]*://', value)
if prefix_match:
real_prefix = prefix_match.group(0)
value = 'http://' + value[len(real_prefix):]
parsed = urlsplit(value)
if real_prefix:
value = real_prefix + value[7:]
scheme = _urlquote(real_prefix[:-3])
else:
parsed = urlsplit(value)
if scheme is None:
scheme = _urlquote(parsed.scheme)
hostname = parsed.hostname
if hostname is not None:
hostname = hostname.encode('idna')
# RFC 3986 allows userinfo to contain sub-delims
username = _urlquote(parsed.username, safe='!$&\'()*+,;=')
password = _urlquote(parsed.password, safe='!$&\'()*+,;=')
port = parsed.port
if port is not None:
port = str_cls(port).encode('ascii')
netloc = b''
if username is not None:
netloc += username
if password:
netloc += b':' + password
netloc += b'@'
if hostname is not None:
netloc += hostname
if port is not None:
default_http = scheme == b'http' and port == b'80'
default_https = scheme == b'https' and port == b'443'
if not normalize or (not default_http and not default_https):
netloc += b':' + port
# RFC 3986 allows a path to contain sub-delims, plus "@" and ":"
path = _urlquote(parsed.path, safe='/!$&\'()*+,;=@:')
# RFC 3986 allows the query to contain sub-delims, plus "@", ":" , "/" and "?"
query = _urlquote(parsed.query, safe='/?!$&\'()*+,;=@:')
# RFC 3986 allows the fragment to contain sub-delims, plus "@", ":" , "/" and "?"
fragment = _urlquote(parsed.fragment, safe='/?!$&\'()*+,;=@:')
if normalize and query is None and fragment is None and path == b'/':
path = None
# Python 2.7 compat
if path is None:
path = ''
output = urlunsplit((scheme, netloc, path, query, fragment))
if isinstance(output, str_cls):
output = output.encode('latin1')
return output
def uri_to_iri(value):
"""
Converts an ASCII URI byte string into a unicode IRI
:param value:
An ASCII-encoded byte string of the URI
:return:
A unicode string of the IRI
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
value must be a byte string, not %s
''',
type_name(value)
))
parsed = urlsplit(value)
scheme = parsed.scheme
if scheme is not None:
scheme = scheme.decode('ascii')
username = _urlunquote(parsed.username, remap=[':', '@'])
password = _urlunquote(parsed.password, remap=[':', '@'])
hostname = parsed.hostname
if hostname:
hostname = hostname.decode('idna')
port = parsed.port
if port and not isinstance(port, int_types):
port = port.decode('ascii')
netloc = ''
if username is not None:
netloc += username
if password:
netloc += ':' + password
netloc += '@'
if hostname is not None:
netloc += hostname
if port is not None:
netloc += ':' + str_cls(port)
path = _urlunquote(parsed.path, remap=['/'], preserve=True)
query = _urlunquote(parsed.query, remap=['&', '='], preserve=True)
fragment = _urlunquote(parsed.fragment)
return urlunsplit((scheme, netloc, path, query, fragment))
def _iri_utf8_errors_handler(exc):
"""
Error handler for decoding UTF-8 parts of a URI into an IRI. Leaves byte
sequences encoded in %XX format, but as part of a unicode string.
:param exc:
The UnicodeDecodeError exception
:return:
A 2-element tuple of (replacement unicode string, integer index to
resume at)
"""
bytes_as_ints = bytes_to_list(exc.object[exc.start:exc.end])
replacements = ['%%%02x' % num for num in bytes_as_ints]
return (''.join(replacements), exc.end)
codecs.register_error('iriutf8', _iri_utf8_errors_handler)
def _urlquote(string, safe=''):
"""
Quotes a unicode string for use in a URL
:param string:
A unicode string
:param safe:
A unicode string of character to not encode
:return:
None (if string is None) or an ASCII byte string of the quoted string
"""
if string is None or string == '':
return None
# Anything already hex quoted is pulled out of the URL and unquoted if
# possible
escapes = []
if re.search('%[0-9a-fA-F]{2}', string):
# Try to unquote any percent values, restoring them if they are not
# valid UTF-8. Also, requote any safe chars since encoded versions of
# those are functionally different than the unquoted ones.
def _try_unescape(match):
byte_string = unquote_to_bytes(match.group(0))
unicode_string = byte_string.decode('utf-8', 'iriutf8')
for safe_char in list(safe):
unicode_string = unicode_string.replace(safe_char, '%%%02x' % ord(safe_char))
return unicode_string
string = re.sub('(?:%[0-9a-fA-F]{2})+', _try_unescape, string)
# Once we have the minimal set of hex quoted values, removed them from
# the string so that they are not double quoted
def _extract_escape(match):
escapes.append(match.group(0).encode('ascii'))
return '\x00'
string = re.sub('%[0-9a-fA-F]{2}', _extract_escape, string)
output = urlquote(string.encode('utf-8'), safe=safe.encode('utf-8'))
if not isinstance(output, byte_cls):
output = output.encode('ascii')
# Restore the existing quoted values that we extracted
if len(escapes) > 0:
def _return_escape(_):
return escapes.pop(0)
output = re.sub(b'%00', _return_escape, output)
return output
def _urlunquote(byte_string, remap=None, preserve=None):
"""
Unquotes a URI portion from a byte string into unicode using UTF-8
:param byte_string:
A byte string of the data to unquote
:param remap:
A list of characters (as unicode) that should be re-mapped to a
%XX encoding. This is used when characters are not valid in part of a
URL.
:param preserve:
A bool - indicates that the chars to be remapped if they occur in
non-hex form, should be preserved. E.g. / for URL path.
:return:
A unicode string
"""
if byte_string is None:
return byte_string
if byte_string == b'':
return ''
if preserve:
replacements = ['\x1A', '\x1C', '\x1D', '\x1E', '\x1F']
preserve_unmap = {}
for char in remap:
replacement = replacements.pop(0)
preserve_unmap[replacement] = char
byte_string = byte_string.replace(char.encode('ascii'), replacement.encode('ascii'))
byte_string = unquote_to_bytes(byte_string)
if remap:
for char in remap:
byte_string = byte_string.replace(char.encode('ascii'), ('%%%02x' % ord(char)).encode('ascii'))
output = byte_string.decode('utf-8', 'iriutf8')
if preserve:
for replacement, original in preserve_unmap.items():
output = output.replace(replacement, original)
return output

Some files were not shown because too many files have changed in this diff Show More