diff --git a/.git-crypt/keys/default/0/3044E71E3DEFF49B586CF5809BF4FCCB90854DA9.gpg b/.git-crypt/keys/default/0/3044E71E3DEFF49B586CF5809BF4FCCB90854DA9.gpg deleted file mode 100644 index 469ad36..0000000 Binary files a/.git-crypt/keys/default/0/3044E71E3DEFF49B586CF5809BF4FCCB90854DA9.gpg and /dev/null differ diff --git a/.git-crypt/keys/default/0/66FB54F6081375106EEBF651A222365EB448F934.gpg b/.git-crypt/keys/default/0/66FB54F6081375106EEBF651A222365EB448F934.gpg new file mode 100644 index 0000000..8dcb496 Binary files /dev/null and b/.git-crypt/keys/default/0/66FB54F6081375106EEBF651A222365EB448F934.gpg differ diff --git a/.gitattributes b/.gitattributes index eea1737..bd72c2c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,3 @@ **/secrets/** filter=git-crypt diff=git-crypt **/secrets.yaml diff=sops *.wav filter=lfs diff=lfs merge=lfs -text - -hosts/iron/services/tvproxy.nix filter=git-crypt diff=git-crypt diff --git a/.sops.yaml b/.sops.yaml index 44b3cd9..c264349 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,12 +1,11 @@ keys: - - &admin_jalr 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 + - &admin_jalr 66FB54F6081375106EEBF651A222365EB448F934 - &admin_jalr_tb FE170812543DF81393EA56BA5042B8317A10617E - &host_aluminium age1ne08hny30vrkejqhh7dcx4ql6dmkx6jw9dqkf3cz7mzvt53njy0qh59w44 - &host_hafnium age1ahnfjspcpwxxk7getcxkj3fypwt37rr6p3xsmp8n2tqqqz8jtg7q2am0et - &host_iron age1hx7fdu4mcha7kkxe7yevtvs6xgzgaafgenm3drhvr609wlj94sgqm497je - - &host_magnesium age19qkgfaq08kmyxghet48dq4gxwjuy9zpvuyxys9jkmcqa5634537qlxjcd8 + - &host_magnesium age1swv42gad884z2v75kateem6k2za6ltkq6wu90ewqp6dp7gxprawslwz0w0 - &host_weinturm_pretix_prod age1djjxl3lcvzs85nj0met6w8ujsz8pvr6ngmmdwlxfh0k9d5lkrpdqlzzehf - - &host_copper age1rrut5ntrkqmvttvmpa5jcmjhr2pfpyaqgu9dmtx6v07lgjxx5ppsl7e5v3 creation_rules: - path_regex: hosts/aluminium/secrets\.yaml$ key_groups: @@ -38,12 +37,6 @@ creation_rules: - *admin_jalr age: - *host_weinturm_pretix_prod - - path_regex: hosts/copper/secrets\.yaml$ - key_groups: - - pgp: - - *admin_jalr - age: - - *host_copper - path_regex: secrets\.yaml$ key_groups: - pgp: diff --git a/README.md b/README.md index 332bf77..15ccbb8 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,18 @@ -# jalr's NixOS Configuration +## home-manager +https://github.com/nix-community/home-manager + +For a systematic overview of Home Manager and its available options, please see +- the [Home Manager manual](https://nix-community.github.io/home-manager/index.html) and +- the [Home Manager configuration options](https://nix-community.github.io/home-manager/options.html). + ## Install a new host This installs nixos on host `somehost`: - -### NixOS Anywhere - -```bash -nix run github:nix-community/nixos-anywhere -- --flake .# root@ -``` - -### The traditional way - ```bash nix-shell -p nixUnstable --run 'nixos-install --flake https://gitlab.jalr.de/jalr/nixos-configuration#somehost --no-channel-copy' ``` -### Build a configuration - -``` -nix build .#nixosConfigurations.iron.config.system.build.toplevel -``` - ### setting up sops Get the host key and convert it. ```bash @@ -55,12 +46,4 @@ nix-repl> :lf .# ``` gpg --card-edit gpg/card> fetch -gpg --edit-key $key -gpg> trust -Your decision? 5 ``` - -## Debugging boot issues - -1. Add `rd.systemd.debug_shell` kernel parameter -2. Press CTRL+ALT+F9 to switch to root shell diff --git a/custom-utils/default.nix b/custom-utils/default.nix index 9bc4a53..66a9a15 100644 --- a/custom-utils/default.nix +++ b/custom-utils/default.nix @@ -1,5 +1,33 @@ { lib, ... }: +let + filterPort = pm: port: ( + lib.attrsets.catAttrs port ( + lib.attrsets.attrValues ( + lib.attrsets.filterAttrs (n: v: v ? "${port}") pm + ) + ) + ); + onlyUniqueItemsInList = (x: lib.lists.length x == lib.lists.length (lib.lists.unique x)); + protocols = (x: lib.lists.unique (lib.flatten (map builtins.attrNames (lib.attrValues x)))); + mkRange = (x: lib.lists.range (builtins.elemAt x 0) (builtins.elemAt x 1)); + validateList = allowed: builtins.all (x: builtins.elem x allowed); +in { - validatePortAttrset = import ./ports.nix { inherit lib; }; + validatePortAttrset = portmap: + if ! onlyUniqueItemsInList (lib.flatten (map + (x: + if lib.isInt x then x + else if lib.isList x then x + else if lib.isAttrs x then + ( + if ! validateList [ "range" ] (builtins.attrNames x) then builtins.abort "found invalid attribute name" + else if x ? "range" then if lib.lists.length x.range == 2 then mkRange x.range else builtins.abort "range needs a list with exactly two items" + else builtins.abort "found invalid attrset" + ) + else builtins.abort "found invalid entry in portmap" + ) + (filterPort portmap "udp"))) then builtins.abort "Found duplicate ports." + else if ! validateList [ "tcp" "udp" ] (protocols portmap) then builtins.abort "Found invalid protocol." + else portmap; } diff --git a/custom-utils/ports.nix b/custom-utils/ports.nix index a8d1a54..66a9a15 100644 --- a/custom-utils/ports.nix +++ b/custom-utils/ports.nix @@ -4,30 +4,30 @@ let filterPort = pm: port: ( lib.attrsets.catAttrs port ( lib.attrsets.attrValues ( - lib.attrsets.filterAttrs (_: v: v ? "${port}") pm + lib.attrsets.filterAttrs (n: v: v ? "${port}") pm ) ) ); - onlyUniqueItemsInList = x: lib.lists.length x == lib.lists.length (lib.lists.unique x); - mkRange = { from, to }: (lib.lists.range from to); + onlyUniqueItemsInList = (x: lib.lists.length x == lib.lists.length (lib.lists.unique x)); + protocols = (x: lib.lists.unique (lib.flatten (map builtins.attrNames (lib.attrValues x)))); + mkRange = (x: lib.lists.range (builtins.elemAt x 0) (builtins.elemAt x 1)); + validateList = allowed: builtins.all (x: builtins.elem x allowed); in -portmap: -if builtins.all - ( - proto: - if onlyUniqueItemsInList - ( - lib.flatten ( - map - (x: - if lib.isInt x then x - else if lib.isList x then x - else if lib.isAttrs x then mkRange x - else builtins.abort "found invalid entry in portmap" - ) - (filterPort portmap proto) - ) - ) then true else builtins.abort "Found duplicate ${proto} ports." - ) [ "tcp" "udp" ] -then portmap -else builtins.abort "Found duplicate ports." +{ + validatePortAttrset = portmap: + if ! onlyUniqueItemsInList (lib.flatten (map + (x: + if lib.isInt x then x + else if lib.isList x then x + else if lib.isAttrs x then + ( + if ! validateList [ "range" ] (builtins.attrNames x) then builtins.abort "found invalid attribute name" + else if x ? "range" then if lib.lists.length x.range == 2 then mkRange x.range else builtins.abort "range needs a list with exactly two items" + else builtins.abort "found invalid attrset" + ) + else builtins.abort "found invalid entry in portmap" + ) + (filterPort portmap "udp"))) then builtins.abort "Found duplicate ports." + else if ! validateList [ "tcp" "udp" ] (protocols portmap) then builtins.abort "Found invalid protocol." + else portmap; +} diff --git a/flake.lock b/flake.lock index 7c92712..b208caa 100644 --- a/flake.lock +++ b/flake.lock @@ -1,91 +1,13 @@ { "nodes": { - "asterisk-sounds-de": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nix-filter": [ - "nix-filter" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1748284610, - "narHash": "sha256-B3/OOZC0puXbODupPEbdMA6sJP39MzbMCl4j1HvgNfU=", - "ref": "refs/heads/main", - "rev": "6b1c484318727af78a64aee3f46903493dae8259", - "revCount": 1, - "type": "git", - "url": "https://git.jalr.de/jalr/asterisk-sounds-de" - }, - "original": { - "type": "git", - "url": "https://git.jalr.de/jalr/asterisk-sounds-de" - } - }, - "bldcSrc": { - "flake": false, - "locked": { - "lastModified": 1733324381, - "narHash": "sha256-ui9N8QSog1G5zyK7yRrD0Xl+Y2CZhvvhBkaJuQZ2qZw=", - "owner": "vedderb", - "repo": "bldc", - "rev": "a0d40e2c5a42c810888d8c379307e6b0a118a125", - "type": "github" - }, - "original": { - "owner": "vedderb", - "ref": "release_6_05", - "repo": "bldc", - "type": "github" - } - }, - "crane": { - "locked": { - "lastModified": 1731098351, - "narHash": "sha256-HQkYvKvaLQqNa10KEFGgWHfMAbWBfFp+4cAgkut+NNE=", - "owner": "ipetkov", - "repo": "crane", - "rev": "ef80ead953c1b28316cc3f8613904edc2eb90c28", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "disko": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1762276996, - "narHash": "sha256-TtcPgPmp2f0FAnc+DMEw4ardEgv1SGNR3/WFGH0N19M=", - "owner": "nix-community", - "repo": "disko", - "rev": "af087d076d3860760b3323f6b583f4d828c1ac17", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "disko", - "type": "github" - } - }, "flake-compat": { "flake": false, "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "owner": "edolstra", "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "type": "github" }, "original": { @@ -94,74 +16,16 @@ "type": "github" } }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1730504689, - "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "506278e768c2a08bec68eb62932193e341f55c90", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": [ - "nur", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733312601, - "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { @@ -170,49 +34,7 @@ "type": "github" } }, - "gg-chatmix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1748177977, - "narHash": "sha256-xC/dOrDrZoQhUfVotj/z14iTwGlE80OqSl9S5zkevdA=", - "owner": "nilathedragon", - "repo": "gg-chatmix", - "rev": "1dadaa51794042c20ddc52d52479e8a156bd235b", - "type": "github" - }, - "original": { - "owner": "nilathedragon", - "repo": "gg-chatmix", - "type": "github" - } - }, "gitignore": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "pre-commit-hooks-nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gitignore_2": { "inputs": { "nixpkgs": [ "nix-pre-commit-hooks", @@ -220,11 +42,11 @@ ] }, "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", "type": "github" }, "original": { @@ -243,11 +65,11 @@ ] }, "locked": { - "lastModified": 1759991118, - "narHash": "sha256-pDyrtUQyeP1lVTMIYqJtftzDtsXEZaJjYy9ZQ/SGhL8=", + "lastModified": 1701687253, + "narHash": "sha256-qJCMxIKWXonJODPF2oV7mCd0xu7VYVenTucrY0bizto=", "owner": "nix-community", "repo": "gomod2nix", - "rev": "7f8d7438f5870eb167abaf2c39eea3d2302019d1", + "rev": "001bbfa22e2adeb87c34c6015e5694e88721cabe", "type": "github" }, "original": { @@ -263,35 +85,20 @@ ] }, "locked": { - "lastModified": 1758463745, - "narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=", + "lastModified": 1703367386, + "narHash": "sha256-FMbm48UGrBfOWGt8+opuS+uLBLQlRfhiYXhHNcYMS5k=", "owner": "nix-community", "repo": "home-manager", - "rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3", + "rev": "d5824a76bc6bb93d1dce9ebbbcb09a9b6abcc224", "type": "github" }, "original": { "owner": "nix-community", - "ref": "release-25.05", + "ref": "release-23.11", "repo": "home-manager", "type": "github" } }, - "impermanence": { - "locked": { - "lastModified": 1737831083, - "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", - "owner": "nix-community", - "repo": "impermanence", - "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "impermanence", - "type": "github" - } - }, "krops": { "inputs": { "flake-utils": [ @@ -315,47 +122,6 @@ "type": "github" } }, - "lanzaboote": { - "inputs": { - "crane": "crane", - "flake-compat": "flake-compat", - "flake-parts": "flake-parts", - "nixpkgs": [ - "nixpkgs" - ], - "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "rust-overlay": "rust-overlay" - }, - "locked": { - "lastModified": 1737639419, - "narHash": "sha256-AEEDktApTEZ5PZXNDkry2YV2k6t0dTgLPEmAZbnigXU=", - "owner": "nix-community", - "repo": "lanzaboote", - "rev": "a65905a09e2c43ff63be8c0e86a93712361f871e", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "v0.4.2", - "repo": "lanzaboote", - "type": "github" - } - }, - "nix-filter": { - "locked": { - "lastModified": 1757882181, - "narHash": "sha256-+cCxYIh2UNalTz364p+QYmWHs0P+6wDhiWR4jDIKQIU=", - "owner": "numtide", - "repo": "nix-filter", - "rev": "59c44d1909c72441144b93cf0f054be7fe764de5", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "nix-filter", - "type": "github" - } - }, "nix-github-actions": { "inputs": { "nixpkgs": [ @@ -364,11 +130,11 @@ ] }, "locked": { - "lastModified": 1729742964, - "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=", + "lastModified": 1698974481, + "narHash": "sha256-yPncV9Ohdz1zPZxYHQf47S8S0VrnhV7nNhCawY46hDA=", "owner": "nix-community", "repo": "nix-github-actions", - "rev": "e04df33f62cdcf93d73e9a04142464753a16db67", + "rev": "4bb5e752616262457bc7ca5882192a564c0472d2", "type": "github" }, "original": { @@ -379,82 +145,84 @@ }, "nix-pre-commit-hooks": { "inputs": { - "flake-compat": "flake-compat_2", - "gitignore": "gitignore_2", - "nixpkgs": [ - "nixpkgs" - ] + "flake-compat": "flake-compat", + "flake-utils": [ + "flake-utils" + ], + "gitignore": "gitignore", + "nixpkgs": "nixpkgs", + "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1763319842, - "narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=", + "lastModified": 1703939133, + "narHash": "sha256-Gxe+mfOT6bL7wLC/tuT2F+V+Sb44jNr8YsJ3cyIl4Mo=", "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761", + "repo": "pre-commit-hooks.nix", + "rev": "9d3d7e18c6bc4473d7520200d4ddab12f8402d38", "type": "github" }, "original": { "owner": "cachix", "ref": "master", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "nixos-hardware": { - "locked": { - "lastModified": 1762847253, - "narHash": "sha256-BWWnUUT01lPwCWUvS0p6Px5UOBFeXJ8jR+ZdLX8IbrU=", - "owner": "nixos", - "repo": "nixos-hardware", - "rev": "899dc449bc6428b9ee6b3b8f771ca2b0ef945ab9", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "master", - "repo": "nixos-hardware", + "repo": "pre-commit-hooks.nix", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1763334038, - "narHash": "sha256-LBVOyaH6NFzQ3X/c6vfMZ9k4SV2ofhpxeL9YnhHNJQQ=", - "owner": "nixos", + "lastModified": 1689261696, + "narHash": "sha256-LzfUtFs9MQRvIoQ3MfgSuipBVMXslMPH/vZ+nM40LkA=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "4c8cdd5b1a630e8f72c9dd9bf582b1afb3127d2c", + "rev": "df1eee2aa65052a18121ed4971081576b25d6b5c", "type": "github" }, "original": { - "owner": "nixos", - "ref": "nixos-25.05", + "owner": "NixOS", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, "nixpkgs-stable": { "locked": { - "lastModified": 1730741070, - "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-24.05", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1703950681, + "narHash": "sha256-veU5bE4eLOmi7aOzhE7LfZXcSOONRMay0BKv01WHojo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0aad9113182747452dbfc68b93c86e168811fa6c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-23.05", "repo": "nixpkgs", "type": "github" } }, "nixpkgsMaster": { "locked": { - "lastModified": 1763473525, - "narHash": "sha256-NzmsN8hRIn/9rJvZH3vPirBrOJJfeSfvPr4+feeK7LY=", + "lastModified": 1704028587, + "narHash": "sha256-gvnPImYfQkcb1ZQXKHUfec7f+XRxRMCg++TWhAYp/XQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "15901670689a6f338ebd2a9436b947ec189463a3", + "rev": "bab500a21ac81b122bc9b573429b724eb74225e1", "type": "github" }, "original": { @@ -464,65 +232,29 @@ "type": "github" } }, - "nixpkgsOld": { - "locked": { - "lastModified": 1748037224, - "narHash": "sha256-92vihpZr6dwEMV6g98M5kHZIttrWahb9iRPBm1atcPk=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "f09dede81861f3a83f7f06641ead34f02f37597f", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_2": { "locked": { - "lastModified": 1763283776, - "narHash": "sha256-Y7TDFPK4GlqrKrivOcsHG8xSGqQx3A6c+i7novT85Uk=", + "lastModified": 1703900474, + "narHash": "sha256-Zu+chYVYG2cQ4FCbhyo6rc5Lu0ktZCjRbSPE0fDgukI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "50a96edd8d0db6cc8db57dab6bb6d6ee1f3dc49a", + "rev": "9dd7699928e26c3c00d5d46811f1358524081062", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1735554305, - "narHash": "sha256-zExSA1i/b+1NMRhGGLtNfFGXgLtgo+dcuzHzaWA6w3Q=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "0e82ab234249d8eee3e8c91437802b32c74bb3fd", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixpkgs-unstable", + "ref": "nixos-23.11", "repo": "nixpkgs", "type": "github" } }, "nur": { - "inputs": { - "flake-parts": "flake-parts_2", - "nixpkgs": "nixpkgs_2" - }, "locked": { - "lastModified": 1763471545, - "narHash": "sha256-B1ua1UtkPuMwT8o4nOR7yNP5yz10usMcNnxwHpGtLck=", + "lastModified": 1704028639, + "narHash": "sha256-fDN/0YA5EUCu1ic6NyWoie5W+VzrX0aHVvFkrY0np18=", "owner": "nix-community", "repo": "NUR", - "rev": "4c584dcedf9aa3394e9730e62693515a0e47674b", + "rev": "c1a78c7eeacb194aef527a7f41910f3866e2f14b", "type": "github" }, "original": { @@ -544,11 +276,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1743690424, - "narHash": "sha256-cX98bUuKuihOaRp8dNV1Mq7u6/CQZWTPth2IJPATBXc=", + "lastModified": 1703546497, + "narHash": "sha256-CN/7HaEmHz+akXKejkRVhsxAm6HPGOmYBWMtgMkuROA=", "owner": "nix-community", "repo": "poetry2nix", - "rev": "ce2369db77f45688172384bbeb962bc6c2ea6f94", + "rev": "528d500ea826383cc126a9be1e633fc92b19ce5d", "type": "github" }, "original": { @@ -557,88 +289,33 @@ "type": "github" } }, - "pre-commit-hooks-nix": { - "inputs": { - "flake-compat": [ - "lanzaboote", - "flake-compat" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1731363552, - "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, "root": { "inputs": { - "asterisk-sounds-de": "asterisk-sounds-de", - "disko": "disko", "flake-utils": "flake-utils", - "gg-chatmix": "gg-chatmix", "gomod2nix": "gomod2nix", "home-manager": "home-manager", - "impermanence": "impermanence", "krops": "krops", - "lanzaboote": "lanzaboote", - "nix-filter": "nix-filter", "nix-pre-commit-hooks": "nix-pre-commit-hooks", - "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs", + "nixpkgs": "nixpkgs_2", "nixpkgsMaster": "nixpkgsMaster", "nur": "nur", "poetry2nix": "poetry2nix", - "sops-nix": "sops-nix", - "vesc-tool": "vesc-tool" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1731897198, - "narHash": "sha256-Ou7vLETSKwmE/HRQz4cImXXJBr/k9gp4J4z/PF8LzTE=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "0be641045af6d8666c11c2c40e45ffc9667839b5", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" + "sops-nix": "sops-nix" } }, "sops-nix": { "inputs": { "nixpkgs": [ "nixpkgs" - ] + ], + "nixpkgs-stable": "nixpkgs-stable_2" }, "locked": { - "lastModified": 1763417348, - "narHash": "sha256-n5xDOeNN+smocQp3EMIc11IzBlR9wvvTIJZeL0g33Fs=", + "lastModified": 1703991717, + "narHash": "sha256-XfBg2dmDJXPQEB8EdNBnzybvnhswaiAkUeeDj7fa/hQ=", "owner": "Mic92", "repo": "sops-nix", - "rev": "3f66a7fb9626a9a9c077612ef10a0ce396286c7d", + "rev": "cfdbaf68d00bc2f9e071f17ae77be4b27ff72fa6", "type": "github" }, "original": { @@ -672,9 +349,8 @@ "type": "github" }, "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" + "id": "systems", + "type": "indirect" } }, "treefmt-nix": { @@ -685,11 +361,11 @@ ] }, "locked": { - "lastModified": 1730120726, - "narHash": "sha256-LqHYIxMrl/1p3/kvm2ir925tZ8DkI0KA10djk8wecSk=", + "lastModified": 1699786194, + "narHash": "sha256-3h3EH1FXQkIeAuzaWB+nK0XK54uSD46pp+dMD3gAcB4=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "9ef337e492a5555d8e17a51c911ff1f02635be15", + "rev": "e82f32aa7f06bbbd56d7b12186d555223dc399d1", "type": "github" }, "original": { @@ -697,51 +373,6 @@ "repo": "treefmt-nix", "type": "github" } - }, - "treefmt-nix_2": { - "inputs": { - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1744961264, - "narHash": "sha256-aRmUh0AMwcbdjJHnytg1e5h5ECcaWtIFQa6d9gI85AI=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "8d404a69efe76146368885110f29a2ca3700bee6", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "vesc-tool": { - "inputs": { - "bldcSrc": "bldcSrc", - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgsOld": "nixpkgsOld", - "treefmt-nix": "treefmt-nix_2" - }, - "locked": { - "lastModified": 1762968599, - "narHash": "sha256-j+AZQYOuZ0X33p76LsZu4/NZl1Ccu6kkwPKC5HpIn1Y=", - "owner": "vedderb", - "repo": "vesc_tool", - "rev": "6a75051ce9742d97f14addd5d175ac516effb3c6", - "type": "github" - }, - "original": { - "owner": "vedderb", - "ref": "master", - "repo": "vesc_tool", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index d56e73d..13dd219 100644 --- a/flake.nix +++ b/flake.nix @@ -1,88 +1,60 @@ { inputs = { - disko.inputs.nixpkgs.follows = "nixpkgs"; - disko.url = "github:nix-community/disko"; - flake-utils.url = "github:numtide/flake-utils"; - - nix-filter.url = "github:numtide/nix-filter"; - - gg-chatmix = { - url = "github:nilathedragon/gg-chatmix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - gomod2nix = { - url = "github:nix-community/gomod2nix"; - inputs.flake-utils.follows = "flake-utils"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - home-manager = { - url = "github:nix-community/home-manager/release-25.05"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - impermanence.url = "github:nix-community/impermanence"; - - krops = { - url = "github:Mic92/krops"; - inputs.flake-utils.follows = "flake-utils"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - lanzaboote = { - url = "github:nix-community/lanzaboote/v0.4.2"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - nix-pre-commit-hooks = { - url = "github:cachix/git-hooks.nix/master"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - nixos-hardware.url = "github:nixos/nixos-hardware/master"; - - nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; - + nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; nixpkgsMaster.url = "github:NixOS/nixpkgs/master"; nur.url = "github:nix-community/NUR"; - poetry2nix = { - url = "github:nix-community/poetry2nix"; - inputs.flake-utils.follows = "flake-utils"; + home-manager = { + url = "github:nix-community/home-manager/release-23.11"; inputs.nixpkgs.follows = "nixpkgs"; }; + nix-pre-commit-hooks = { + url = "github:cachix/pre-commit-hooks.nix/master"; + inputs.flake-utils.follows = "flake-utils"; + }; + sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - asterisk-sounds-de = { - url = "git+https://git.jalr.de/jalr/asterisk-sounds-de"; + krops = { + url = "github:Mic92/krops"; inputs = { flake-utils.follows = "flake-utils"; - nix-filter.follows = "nix-filter"; nixpkgs.follows = "nixpkgs"; }; }; - vesc-tool = { - url = "github:vedderb/vesc_tool/master"; - inputs.flake-utils.follows = "flake-utils"; - inputs.nixpkgs.follows = "nixpkgs"; + gomod2nix = { + url = "github:nix-community/gomod2nix"; + inputs = { + flake-utils.follows = "flake-utils"; + nixpkgs.follows = "nixpkgs"; + }; + }; + + poetry2nix = { + url = "github:nix-community/poetry2nix"; + inputs = { + flake-utils.follows = "flake-utils"; + nixpkgs.follows = "nixpkgs"; + }; }; }; outputs = { self , flake-utils + , gomod2nix , home-manager , krops , nix-pre-commit-hooks , nixpkgs , nur + , poetry2nix , ... }@inputs: flake-utils.lib.eachSystem [ "x86_64-linux" @@ -98,26 +70,20 @@ src = self; hooks = { black.enable = true; - deadnix.enable = true; nixpkgs-fmt.enable = true; shellcheck.enable = true; - statix = { - enable = true; - settings.ignore = [ ".direnv" ]; - }; }; - excludes = [ ".envrc" ]; }; }; devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ + buildInputs = (with pkgs; [ black just nixpkgs-fmt shellcheck sops ssh-to-age - ]; + ]); shellHook = '' ${self.checks.${system}.pre-commit-check.shellHook} @@ -125,7 +91,7 @@ }; apps = lib.mapAttrs - (_: program: { type = "app"; program = toString program; }) + (name: program: { type = "app"; program = toString program; }) (flake-utils.lib.flattenTree { deploy = lib.recurseIntoAttrs (lib.mapAttrs (hostname: machine: @@ -149,7 +115,6 @@ command = targetPath: '' nixos-rebuild switch --flake ${targetPath}/config -L --keep-going ''; - force = true; } ) self.nixosConfigurations); @@ -184,67 +149,42 @@ , extraModules ? [ ] , targetHost ? hostname , nixpkgs ? inputs.nixpkgs - }: nixpkgs.lib.nixosSystem { + }: nixpkgs.lib.nixosSystem rec { inherit system; specialArgs = { inherit self system; }; - modules = - let - hostDir = ./hosts + "/${hostname}"; - in - [ - (hostDir + "/configuration.nix") + modules = [ + (./hosts + "/${hostname}/configuration.nix") - ./modules + ./modules - { - _module.args = { - inherit inputs; - custom-utils = import ./custom-utils { inherit (nixpkgs) lib; }; + { + _module.args = { + inputs = inputs; + custom-utils = import ./custom-utils { lib = nixpkgs.lib; }; + }; + } + + # deployment settings + ({ lib, ... }: { + options.deployment = { + targetHost = lib.mkOption { + type = lib.types.str; + readOnly = true; + internal = true; }; - } - - # deployment settings - ({ lib, ... }: { - options.deployment = { - targetHost = lib.mkOption { - type = lib.types.str; - readOnly = true; - internal = true; - }; - }; - config.deployment = { - inherit targetHost; - }; - }) - - # sops settings - ({ lib, config, pkgs, ... }: - { - sops.defaultSopsFile = hostDir + "/secrets.yaml"; - sops.secrets = - let - secretFile = config.sops.defaultSopsFile; - getSecrets = file: builtins.fromJSON (builtins.readFile (pkgs.runCommandNoCC "secretKeys" { } ''${pkgs.yq-go}/bin/yq -o json '[del .sops | .. | select(tag != "!!seq" and tag != "!!map") | path | join("/")]' ${file} > $out'')); - secretNames = getSecrets secretFile; - secrets = - if builtins.pathExists secretFile then - lib.listToAttrs (builtins.map (name: lib.nameValuePair name { }) secretNames) - else - { }; - in - secrets; - }) - ] ++ [ - { nixpkgs.overlays = [ nur.overlays.default inputs.vesc-tool.overlays.default ]; } - home-manager.nixosModules.home-manager - inputs.asterisk-sounds-de.nixosModules.default - inputs.disko.nixosModules.disko - inputs.impermanence.nixosModules.impermanence - inputs.lanzaboote.nixosModules.lanzaboote - inputs.sops-nix.nixosModules.sops - inputs.gg-chatmix.nixosModule - ] ++ extraModules; + }; + config.deployment = { + inherit targetHost; + }; + }) + ] ++ [{ + nixpkgs.overlays = [ nur.overlay ]; + }] ++ [ + home-manager.nixosModules.home-manager + ] ++ (with inputs; [ + sops-nix.nixosModules.sops + ]) ++ extraModules; }) (import ./hosts inputs); }; diff --git a/home-manager/README.md b/home-manager/README.md new file mode 100644 index 0000000..e245e64 --- /dev/null +++ b/home-manager/README.md @@ -0,0 +1,2 @@ +# Documentation +[Home Manager Manual](https://rycee.gitlab.io/home-manager/) diff --git a/home-manager/modules/alacritty.nix b/home-manager/modules/alacritty.nix new file mode 100644 index 0000000..6974d18 --- /dev/null +++ b/home-manager/modules/alacritty.nix @@ -0,0 +1,174 @@ +{ lib, pkgs, nixosConfig, ... }: +let + solarized = import ./solarized.nix; + + #nixosConfig.jalr.terminalEmulator.command = pkgs.writeShellScriptBin "alacritty-sway-cwd" '' + # this_alacritty_pid="$(swaymsg -t get_tree | ${pkgs.jq} -e 'recurse(.nodes[]?) | select((.focused==true) and (.app_id=="Alacritty")).pid')" + + # if [ "$this_alacritty_pid" ]; then + # child_pid="$(pgrep -P "$this_alacritty_pid")" + # cwd="$(readlink /proc/$child_pid/cwd)" + # fi + # if [ -e "$cwd" ]; then + # exec ${pkgs.alacritty} --working-directory "$cwd" + # fi + + # exec alacritty + #''; + + colorschemes = { + # https://github.com/alacritty/alacritty/wiki/Color-schemes#solarized + solarized-dark = { + # Default colors + primary = { + background = solarized.base03.hex; + foreground = solarized.base0.hex; + }; + + # Cursor colors + cursor = { + text = solarized.base03.hex; + cursor = solarized.base0.hex; + }; + + # Normal colors + normal = { + black = solarized.base02.hex; + red = solarized.red.hex; + green = solarized.green.hex; + yellow = solarized.yellow.hex; + blue = solarized.blue.hex; + magenta = solarized.magenta.hex; + cyan = solarized.cyan.hex; + white = solarized.base2.hex; + }; + + # Bright colors + bright = { + black = solarized.base03.hex; + red = solarized.orange.hex; + green = solarized.base01.hex; + yellow = solarized.base00.hex; + blue = solarized.base0.hex; + magenta = solarized.violet.hex; + cyan = solarized.base1.hex; + white = solarized.base3.hex; + }; + }; + + solarized-light = { + # Default colors + primary = { + background = solarized.base3.hex; + foreground = solarized.base00.hex; + }; + + # Cursor colors + cursor = { + text = solarized.base3.hex; + cursor = solarized.base00.hex; + }; + + # Normal colors + normal = { + black = solarized.base02.hex; + red = solarized.red.hex; + green = solarized.green.hex; + yellow = solarized.yellow.hex; + blue = solarized.blue.hex; + magenta = solarized.magenta.hex; + cyan = solarized.cyan.hex; + white = solarized.base2.hex; + }; + + # Bright colors + bright = { + black = solarized.base03.hex; + red = solarized.orange.hex; + green = solarized.base01.hex; + yellow = solarized.base00.hex; + blue = solarized.base0.hex; + magenta = solarized.violet.hex; + cyan = solarized.base1.hex; + white = solarized.base3.hex; + }; + }; + }; + commonSettings = { + font = { + normal = { + family = "Inconsolata for Powerline"; + style = "Regular"; + }; + size = 12; + }; + + mouse.hide_when_typing = true; + + key_bindings = [ + { + key = "F1"; + mods = "Control"; + action = "DecreaseFontSize"; + } + { + key = "F2"; + mods = "Control"; + action = "IncreaseFontSize"; + } + ]; + + bell = { + duration = 100; + color = "#000000"; + }; + + window.dynamic_title = true; + + scrolling.history = 100000; + + window.opacity = 0.95; + }; + settings = { + dark = commonSettings // { + colors = colorschemes.solarized-dark; + }; + light = commonSettings // { + colors = colorschemes.solarized-light; + }; + }; +in +{ + + programs.alacritty = { + enable = nixosConfig.jalr.gui.enable; + }; + + # The option `home-manager.users.jalr.xdg.configFile.dark.alacritty/alacritty-dark.yml' does not exist + + /* + xdg.configFile = builtins.mapAttrs (colorScheme: cfg: { + "alacritty/alacritty-${colorScheme}.yml" = lib.replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg); + }) settings; + */ + + xdg.configFile = lib.attrsets.mapAttrs' + (colorScheme: cfg: lib.attrsets.nameValuePair "alacritty/alacritty-${colorScheme}.yml" { + text = lib.replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg); + }) + settings; + + programs.fish.functions = { + ssh = { + description = "ssh wrapper function"; + wraps = "ssh"; + body = '' + if [ "$TERM" = alacritty ] + TERM=xterm-256color command ssh $argv + else + command ssh $argv + end + ''; + }; + }; +} diff --git a/users/jalr/modules/aws.nix b/home-manager/modules/aws.nix similarity index 85% rename from users/jalr/modules/aws.nix rename to home-manager/modules/aws.nix index 2e85f92..85bbd23 100644 --- a/users/jalr/modules/aws.nix +++ b/home-manager/modules/aws.nix @@ -1,7 +1,7 @@ -{ nixosConfig, lib, config, ... }: +{ nixosConfig, lib, pkgs, config, ... }: let - inherit (config) xdg; + xdg = config.xdg; in { config = lib.mkIf nixosConfig.jalr.aws.enable { @@ -17,7 +17,7 @@ in xdg.configFile."aws/config".text = lib.generators.toINI { } ( lib.mapAttrs' (name: value: - lib.attrsets.nameValuePair "profile ${name}" value + lib.attrsets.nameValuePair ("profile ${name}") (value) ) nixosConfig.jalr.aws.accounts // diff --git a/users/jalr/modules/roomeqwizard.nix b/home-manager/modules/claws-mail.nix similarity index 86% rename from users/jalr/modules/roomeqwizard.nix rename to home-manager/modules/claws-mail.nix index 42b49aa..ff32d39 100644 --- a/users/jalr/modules/roomeqwizard.nix +++ b/home-manager/modules/claws-mail.nix @@ -1,6 +1,6 @@ { nixosConfig, lib, pkgs, ... }: lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ - roomeqwizard + claws-mail ]; } diff --git a/home-manager/modules/cli.nix b/home-manager/modules/cli.nix new file mode 100644 index 0000000..f07297b --- /dev/null +++ b/home-manager/modules/cli.nix @@ -0,0 +1,23 @@ +{ nixosConfig, lib, pkgs, ... }: +{ + home.packages = with pkgs; [ + cached-nix-shell + eza + file + htop + inetutils + jq + lsof + ncdu + ripgrep + unzip + ] ++ (if ! nixosConfig.jalr.workstation.enable then [ ] else [ + direnv + dnsutils + screen + speedtest-cli + usbutils + wget + yt-dlp + ]); +} diff --git a/home-manager/modules/communication/default.nix b/home-manager/modules/communication/default.nix new file mode 100644 index 0000000..6be079f --- /dev/null +++ b/home-manager/modules/communication/default.nix @@ -0,0 +1,10 @@ +{ nixosConfig, ... }: + +{ + imports = [ + ./ferdium.nix + ./mumble.nix + ./qtox.nix + ./telegram-desktop.nix + ]; +} diff --git a/home-manager/modules/communication/ferdium.nix b/home-manager/modules/communication/ferdium.nix new file mode 100644 index 0000000..ee8f39e --- /dev/null +++ b/home-manager/modules/communication/ferdium.nix @@ -0,0 +1,7 @@ +{ nixosConfig, lib, pkgs, ... }: + +lib.mkIf nixosConfig.jalr.tradebyte.enable { + home.packages = with pkgs; [ + master.ferdium + ]; +} diff --git a/users/jalr/modules/communication/mumble.nix b/home-manager/modules/communication/mumble.nix similarity index 100% rename from users/jalr/modules/communication/mumble.nix rename to home-manager/modules/communication/mumble.nix diff --git a/users/jalr/modules/sound/ksoloti.nix b/home-manager/modules/communication/qtox.nix similarity index 90% rename from users/jalr/modules/sound/ksoloti.nix rename to home-manager/modules/communication/qtox.nix index 3528602..85aa45b 100644 --- a/users/jalr/modules/sound/ksoloti.nix +++ b/home-manager/modules/communication/qtox.nix @@ -2,6 +2,6 @@ lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ - ksoloti + qtox ]; } diff --git a/users/jalr/modules/3d-printing.nix b/home-manager/modules/communication/telegram-desktop.nix similarity index 86% rename from users/jalr/modules/3d-printing.nix rename to home-manager/modules/communication/telegram-desktop.nix index 5107e9c..d8876cc 100644 --- a/users/jalr/modules/3d-printing.nix +++ b/home-manager/modules/communication/telegram-desktop.nix @@ -2,6 +2,6 @@ lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ - prusa-slicer + tdesktop ]; } diff --git a/users/jalr/modules/default.nix b/home-manager/modules/default.nix similarity index 54% rename from users/jalr/modules/default.nix rename to home-manager/modules/default.nix index f97916b..c8c85d8 100644 --- a/users/jalr/modules/default.nix +++ b/home-manager/modules/default.nix @@ -1,51 +1,40 @@ +{ nixosConfig, ... }: + { imports = [ - ./3d-modeling.nix - ./3d-printing.nix - ./ardour.nix + ./${nixosConfig.jalr.terminalEmulator}.nix ./aws.nix - ./cli + ./claws-mail.nix + ./cli.nix ./communication - ./dconf.nix - ./ddev.nix ./direnv.nix - ./do-not-disturb ./dynamic-colors.nix ./firefox ./fish.nix ./fpv.nix - ./freetube.nix ./git.nix ./gnuradio.nix ./graphics ./gui.nix ./jameica.nix ./kicad.nix - ./lsd - ./mixxc ./mpv.nix ./mute-indicator.nix - ./mycli - ./neovim - ./nix-index.nix + ./neo.nix + ./neovim.nix ./obs-studio - ./ots.nix - ./pace.nix + ./openscad.nix ./pass.nix - ./pomodoro.nix + ./pcmanfm.nix ./python.nix ./remarkable - ./roomeqwizard.nix - ./snapclient.nix ./sound ./sway - ./thunar.nix ./thunderbird.nix ./tmux.nix ./tor-browser.nix - ./trilium.nix ./vdirsyncer.nix - ./vesc-tool.nix - ./wezterm.nix ]; + + programs.nix-index.enable = true; } diff --git a/users/jalr/modules/direnv.nix b/home-manager/modules/direnv.nix similarity index 100% rename from users/jalr/modules/direnv.nix rename to home-manager/modules/direnv.nix diff --git a/users/jalr/modules/dynamic-colors.nix b/home-manager/modules/dynamic-colors.nix similarity index 75% rename from users/jalr/modules/dynamic-colors.nix rename to home-manager/modules/dynamic-colors.nix index c97e9ed..233497d 100644 --- a/users/jalr/modules/dynamic-colors.nix +++ b/home-manager/modules/dynamic-colors.nix @@ -1,4 +1,4 @@ -{ nixosConfig, lib, pkgs, ... }: +{ nixosConfig, lib, config, pkgs, ... }: let loadSwayTheme = pkgs.writeShellScript "load-sway-theme" '' @@ -7,6 +7,12 @@ let done < "$1" ''; applicationConfig = [ + { + dir = "~/.config/alacritty"; + light = "alacritty-light.yml"; + dark = "alacritty-dark.yml"; + target = "alacritty.yml"; + } { dir = "~/.config/wofi"; light = "color-light"; @@ -28,28 +34,11 @@ let exec = [ "${pkgs.systemd}/bin/systemctl" "--user" "restart" "waybar.service" ]; } { - dir = "~/.config/mycli"; - light = "theme-light.ini"; - dark = "theme-dark.ini"; - target = "myclirc"; - } - { - exec = + exec = ( if nixosConfig.jalr.gui.enable then [ "/usr/bin/env" "gsettings" "set" "org.gnome.desktop.interface" "color-scheme" "prefer-%scheme%" ] - else null; - } - { - exec = - if nixosConfig.jalr.gui.enable - then [ "/usr/bin/env" "gsettings" "set" "org.gnome.desktop.interface" "gtk-theme" "Adwaita-%scheme%" ] - else null; - } - { - dir = "~/.config/lsd"; - light = "colors-light.yaml"; - dark = "colors-dark.yaml"; - target = "colors.yaml"; + else null + ); } ]; dynamic-colors = pkgs.writers.writePython3Bin "dynamic-colors" { } '' @@ -90,7 +79,7 @@ let if scheme is None: if target.exists(): continue - scheme = DEFAULT_SCHEME + scheme = entry[DEFAULT_SCHEME] else: if target.exists() and target.is_symlink: os.remove(target) @@ -100,10 +89,7 @@ let 'dark': entry['dark'], }[scheme] - try: - os.symlink(src, target) - except FileNotFoundError: - pass + os.symlink(src, target) if entry.get('exec') is not None: command, *args = entry["exec"] @@ -116,13 +102,10 @@ let for arg in args ] print(command, *args) - try: - subprocess.run( - (command, *args), - cwd=directory - ) - except FileNotFoundError: - pass + subprocess.run( + (command, *args), + cwd=directory + ) if __name__ == '__main__': diff --git a/home-manager/modules/firefox/default.nix b/home-manager/modules/firefox/default.nix new file mode 100644 index 0000000..a2d4992 --- /dev/null +++ b/home-manager/modules/firefox/default.nix @@ -0,0 +1,103 @@ +{ nixosConfig, pkgs, ... }: +{ + programs.firefox = { + enable = nixosConfig.jalr.gui.enable; + package = pkgs.firefox-esr; + profiles = { + default = { + extensions = with pkgs.nur.repos.rycee.firefox-addons; [ + darkreader + tree-style-tab + ublock-origin + umatrix + violentmonkey + ]; + settings = { + #"browser.startup.homepage" = "https://nixos.org"; + #"browser.search.region" = "GB"; + #"browser.search.isUS" = false; + #"distribution.searchplugins.defaultLocale" = "en-GB"; + #"general.useragent.locale" = "en-GB"; + #"browser.bookmarks.showMobileBookmarks" = true; + "app.normandy.enabled" = false; + "app.shield.optoutstudies.enabled" = false; + "app.update.auto" = false; + "browser.ctrlTab.sortByRecentlyUsed" = true; + "browser.fixup.alternate.enabled" = false; + "browser.formfill.enable" = false; + "browser.link.open_newwindow.restriction" = 0; + "browser.newtabpage.enabled" = false; + "browser.ping-centre.telemetry" = false; + "browser.safebrowsing.downloads.enabled" = false; + "browser.safebrowsing.downloads.remote.block_dangerous" = false; + "browser.safebrowsing.downloads.remote.block_dangerous_host" = false; + "browser.safebrowsing.downloads.remote.block_potentially_unwanted" = false; + "browser.safebrowsing.downloads.remote.block_uncommon" = false; + "browser.safebrowsing.downloads.remote.enabled" = false; + "browser.safebrowsing.downloads.remote.url" = ""; + "browser.safebrowsing.malware.enabled" = false; + "browser.safebrowsing.phishing.enabled" = false; + "browser.safebrowsing.provider.google.advisoryURL" = ""; + "browser.safebrowsing.provider.google.gethashURL" = ""; + "browser.safebrowsing.provider.google.lists" = ""; + "browser.safebrowsing.provider.google.reportMalwareMistakeURL" = ""; + "browser.safebrowsing.provider.google.reportPhishMistakeURL" = ""; + "browser.safebrowsing.provider.google.reportURL" = ""; + "browser.safebrowsing.provider.google.updateURL" = ""; + "browser.safebrowsing.provider.google4.advisoryURL" = ""; + "browser.safebrowsing.provider.google4.dataSharingURL" = ""; + "browser.safebrowsing.provider.google4.gethashURL" = ""; + "browser.safebrowsing.provider.google4.lists" = ""; + "browser.safebrowsing.provider.google4.reportMalwareMistakeURL" = ""; + "browser.safebrowsing.provider.google4.reportPhishMistakeURL" = ""; + "browser.safebrowsing.provider.google4.reportURL" = ""; + "browser.safebrowsing.provider.google4.updateURL" = ""; + "browser.safebrowsing.provider.mozilla.gethashURL" = ""; + "browser.safebrowsing.provider.mozilla.lists" = ""; + "browser.safebrowsing.provider.mozilla.updateURL" = ""; + "browser.search.suggest.enabled" = false; + "browser.search.widget.inNavBar" = true; + "browser.startup.page" = 0; + "extensions.pocket.enabled" = false; + "extensions.update.enabled" = false; + "identity.fxaccounts.enabled" = false; + "keyword.enabled" = false; + "network.captive-portal-service.enabled" = false; + "network.predictor.enabled" = false; + "privacy.donottrackheader.enabled" = true; + "startup.homepage_welcome_url" = about:blank; + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.bhrPing.enabled" = false; + "toolkit.telemetry.firstShutdownPing.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; + "toolkit.telemetry.server" = http://127.0.0.1:4711; + "toolkit.telemetry.server_owner" = ""; + "toolkit.telemetry.shutdownPingSender.enabled" = false; + "toolkit.telemetry.updatePing.enabled" = false; + "urlclassifier.downloadAllowTable" = ""; + "urlclassifier.downloadBlockTable" = ""; + "urlclassifier.malwareTable" = ""; + "urlclassifier.phishTable" = ""; + "datareporting.healthreport.uploadEnabled" = ""; + "app.normandy.api_url" = ""; + "breakpad.reportURL" = ""; + "browser.region.network.url" = ""; + "browser.search.geoSpecificDefaults.url" = ""; + "browser.shell.checkDefaultBrowser" = false; + + "privacy.userContext.enabled" = true; + "privacy.userContext.ui.enabled" = true; + "network.dnsCacheExpiration" = 0; + + # disable disk cache to reduce ssd writes + "browser.cache.disk.enable" = false; + "browser.cache.memory.enable" = true; + "browser.cache.memory.capacity" = -1; + }; + userChrome = builtins.readFile ./userChrome.css; + + }; + }; + }; +} diff --git a/users/jalr/modules/firefox/userChrome.css b/home-manager/modules/firefox/userChrome.css similarity index 92% rename from users/jalr/modules/firefox/userChrome.css rename to home-manager/modules/firefox/userChrome.css index 889027a..dcc6b2b 100644 --- a/users/jalr/modules/firefox/userChrome.css +++ b/home-manager/modules/firefox/userChrome.css @@ -218,28 +218,4 @@ url(chrome://browser/content/browser.xhtml) { } /*** End of: Megabar Styler One-Offs ***/ - - /* Hide "Firefox Suggest" in location bar search results */ - .urlbarView-row[label="Firefox Suggest"]::before { - display: none !important - } - .urlbarView-row[label] { - margin-block-start: 4px !important; - } - - /* Hide search button in location bar */ - #identity-box[pageproxystate=invalid] > .identity-box-button, - .searchbar-search-button { - display: none - } - - /* Hide search placeholder in location bar */ - #urlbar-input::placeholder { - color: transparent; - } - - /* Hide back & forward buttons */ - toolbarbutton#back-button, toolbarbutton#forward-button { - display: none; - } } diff --git a/home-manager/modules/fish.nix b/home-manager/modules/fish.nix new file mode 100644 index 0000000..59e209b --- /dev/null +++ b/home-manager/modules/fish.nix @@ -0,0 +1,201 @@ +{ config, pkgs, ... }: +{ + home.packages = with pkgs; [ + fzf + ]; + programs.fish = { + enable = true; + plugins = [ + { + name = "theme-agnoster"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "theme-agnoster"; + rev = "c142e802983bd1b34b4d91efac2126fc5913126d"; + sha256 = "0PLx626BWoBp/L6wgkB4o+53q8PymiEE/rTu2mfzHhg="; + fetchSubmodules = true; + }; + } + { + name = "fzf"; + src = pkgs.fetchFromGitHub { + owner = "jethrokuan"; + repo = "fzf"; + rev = "479fa67d7439b23095e01b64987ae79a91a4e283"; + sha256 = "0k6l21j192hrhy95092dm8029p52aakvzis7jiw48wnbckyidi6v"; + fetchSubmodules = true; + }; + } + ]; + shellAliases = { + ls = "ls --color=auto"; + crontab = "crontab -i"; + }; + + shellAbbrs = { + lessr = "less -R"; + jqc = "jq -C"; + }; + + #interactiveShellInit = '' + # echo "programs.fish.interactiveShellInit" + #''; + shellInit = '' + # key bindings + bind \cr '__fzf_reverse_isearch' + + # PATH + set -U fish_user_paths $HOME/.local/bin $HOME/.local/bin/pio + + # pass + #set -x PASSWORD_STORE_ENABLE_EXTENSIONS true + set -x AWS_VAULT_BACKEND pass + set -x AWS_VAULT_PASS_PREFIX aws + complete -c pw --no-files -a '(__fish_pass_print_entries)' + + # colors + set -x GCC_COLORS 'error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + + abbr --add v vim + + #alias cal='ncal -b -M' + alias myip='dig +short myip.opendns.com @resolver1.opendns.com' + + function hm -d 'merge history and delete failed commands' + history --merge + + if test -z "$fish_private_mode" && test -e "$__fish_user_data_dir/successful_commands" && test -e "$__fish_user_data_dir/failed_commands" + while read line; + if ! grep -qFx $line "$__fish_user_data_dir/successful_commands" + set hist_command (echo $line | base64 -d) + echo "deleting command: $hist_command" + echo "." + history delete --exact --case-sensitive $hist_command + end + end < "$__fish_user_data_dir/failed_commands" + echo -n > "$__fish_user_data_dir/successful_commands" + echo -n > "$__fish_user_data_dir/failed_commands" + end + end + hm + + # fancy tools + if which eza > /dev/null 2>&1 + alias l=eza + alias ll='eza -l --time-style=long-iso --git' + alias la='eza -la --time-style=long-iso --git' + alias tree='eza --tree' + alias llt='eza -s modified -l' + else + alias l=ls + alias ll='ls -l' + alias la='ls -la' + alias llt='ls -trl' + end + + if which rg > /dev/null 2>&1 + alias g=rg + complete -c g -w rg + else if which ag > /dev/null 2>&1 + alias g=ag + complete -c g -w ag + else + alias g='grep --color=auto' + complete -c g -w grep + end + + function jqless -d 'jq -C [args] | less -R' + jq -C $argv | less -R + end + + # NixOS direnv + if which direnv > /dev/null + eval (direnv hook fish) + end + + function __cut_commandline -d 'cut commandline and paste it later' + set -g commandline_buffer (commandline) + commandline "" + end + + + + function __postexec --on-event fish_postexec + if test $status -ne 0 + if test -z "$hist_cmd" + if test -z "$fish_private_mode" + echo $argv[1] | base64 >> "$__fish_user_data_dir/failed_commands" + end + end + else + if test -z "$fish_private_mode" + echo $argv[1] | base64 >> "$__fish_user_data_dir/successful_commands" + end + commandline $commandline_buffer + set -e commandline_buffer + end + end + + function dirh-nocolor --description "Print the current directory history (the prev and next lists)" + set -l options h/help + argparse -n dirh --max-args=0 $options -- $argv + or return + + if set -q _flag_help + __fish_print_help dirh + return 0 + end + + set -l dirc (count $dirprev) + if test $dirc -gt 0 + set -l dirprev_rev $dirprev[-1..1] + # This can't be (seq $dirc -1 1) because of BSD. + set -l dirnum (seq 1 $dirc) + for i in $dirnum[-1..1] + printf '%s\n' $dirprev_rev[$i] + end + end + + echo $PWD + + set -l dirc (count $dirnext) + if test $dirc -gt 0 + set -l dirnext_rev $dirnext[-1..1] + for i in (seq $dirc) + printf '%s\n' $dirnext_rev[$i] + end + end + end + + function dirh-fzf -d 'directory history fuzzy finder' + builtin cd (dirh-nocolor | uniq | fzf) + end + + bind \ed 'dirh-fzf' + ''; + }; + + xdg.configFile."fish/completions/mycli.fish".text = '' + complete -e -c mycli + complete -c mycli -f -s h -l host -d "Host address of the database." + complete -c mycli -f -s P -l port -d "Port number to use for connection." + complete -c mycli -f -s u -l user -d "User name to connect to the database." + complete -c mycli -f -s S -l socket -d "The socket file to use for connection." + complete -c mycli -f -s p -l pass \ + -l password -d "Password to connect to the database." + complete -c mycli -f -s V -l version -d "Output mycli's version." + complete -c mycli -f -s v -l verbose -d "Verbose output." + complete -c mycli -f -s d -l dsn -d "Use DSN configured into the [alias_dsn] section of myclirc file." + complete -c mycli -f -l list-dsn -d "list of DSN configured into the [alias_dsn] section of myclirc file." + + complete -c mycli -f -s t -l table -d "Display batch output in table format." + complete -c mycli -f -l csv -d "Display batch output in CSV format." + complete -c mycli -f -l warn \ + -l no-warn -d "Warn before running a destructive query." + complete -c mycli -f -s e -l execute -d "Execute command and quit." + + + complete -c mycli -f -s h -l host -r -a '(__fish_print_hostnames)' + complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)' + ''; +} diff --git a/users/jalr/modules/fpv.nix b/home-manager/modules/fpv.nix similarity index 77% rename from users/jalr/modules/fpv.nix rename to home-manager/modules/fpv.nix index b51fb63..9cc7d27 100644 --- a/users/jalr/modules/fpv.nix +++ b/home-manager/modules/fpv.nix @@ -2,7 +2,7 @@ lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ - betaflight-configurator + master.betaflight-configurator fpvout ]; } diff --git a/users/jalr/modules/git.nix b/home-manager/modules/git.nix similarity index 68% rename from users/jalr/modules/git.nix rename to home-manager/modules/git.nix index 3cf4007..2bdf690 100644 --- a/users/jalr/modules/git.nix +++ b/home-manager/modules/git.nix @@ -1,59 +1,29 @@ -{ pkgs, ... }: -let - identity.DigitalerDienst = { - name = "Jakob Lechner"; - email = "j.lechner@digitaler-dienst.gmbh"; - }; -in +{ nixosConfig, pkgs, ... }: + { programs = { git = { enable = true; - userName = "Jakob Lechner"; - userEmail = "mail@jalr.de"; + userName = nixosConfig.jalr.git.user.name; + userEmail = nixosConfig.jalr.git.user.email; signing = { - key = "3044E71E3DEFF49B586CF5809BF4FCCB90854DA9"; - signByDefault = false; - }; - diff-so-fancy = { - enable = true; - markEmptyLines = false; + key = nixosConfig.jalr.gpg.defaultKey; + signByDefault = nixosConfig.jalr.git.signByDefault; }; extraConfig = { init.defaultBranch = "main"; + core.pager = "${pkgs.diff-so-fancy}/bin/diff-so-fancy | less --tabs=4 -RFX"; diff.sops.textconv = "${pkgs.sops}/bin/sops -d"; pull.ff = "only"; alias.find-merge = "!sh -c 'commit=$0 && branch=\${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"; alias.show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"; - color = { - ui = true; - meta = "11"; - frag = "magenta bold"; - func = "146 bold"; - commit = "yellow bold"; - old = "red bold"; - new = "green bold"; - whitespace = "red reverse"; - diff-highlight = { - oldNormal = "red bold"; - oldHighlight = "red bold 52"; - newNormal = "green bold"; - newHighlight = "green bold 22"; - }; - }; }; lfs.enable = true; }; - lazygit = { - enable = true; - settings = { - gui.scrollHeight = 8; - }; - }; fish = { shellAbbrs = { ga = "git add"; - gam = "git commit --amend --no-edit"; + gam = "git commit --amend"; gap = "git add --patch"; gb = "git branch"; gbd = "git branch --delete"; @@ -66,10 +36,12 @@ in gd = "git diff"; gdc = "git diff --cached"; gf = "git fetch"; + ginit = "git init"; gl = "git log"; - gpll = "git pull --rebase"; + gpll = "git pull"; gpsh = "git push"; grb = "git rebase --autostash"; + grbi = "git rebase --autostash --interactive --autosquash refs/remotes/origin/HEAD"; gr = "git restore"; grs = "git restore --staged"; grst = "git reset"; @@ -84,7 +56,6 @@ in gswc = "git switch -c"; gwl = "git worktree list"; gwr = "git worktree remove"; - lg = "lazygit"; }; functions = { #function gwa -d 'git worktree add' @@ -125,28 +96,19 @@ in end ''; }; - git_pick-commit = { + git_pick-commit_merge-base_origin = { description = "fuzzy find a commit hash"; body = '' - git log --decorate --oneline --color=always \ - | ${pkgs.fzf}/bin/fzf --ansi --preview='git show --color=always (echo {} | cut -d" " -f 1)' --preview-window=top:75% \ - | cut -d" " -f 1 + git log --oneline refs/remotes/origin/HEAD..HEAD | ${pkgs.fzf}/bin/fzf --preview='git show (echo {} | cut -d" " -f 1)' --preview-window=top:75% | cut -d" " -f 1 ''; }; gfix = { description = "git commit --fixup with fuzzy find commmit picker"; body = '' - set commit (git_pick-commit) + set commit (git_pick-commit_merge-base_origin) commandline "git commit --fixup=$commit" ''; }; - gi = { - description = "git interactive rebase with fuzzy find commmit picker"; - body = '' - set commit (git_pick-commit) - commandline "git rebase --autostash --interactive --autosquash $commit" - ''; - }; ".g" = { description = "change directory to repository root"; body = '' @@ -189,23 +151,10 @@ in end ''; }; - "fish_set_git_author_by_pwd" = { - description = "Set Git identity by PWD"; - body = '' - if string match -n $HOME'/digitaler-dienst/*' $PWD/ > /dev/null - if git rev-parse --git-dir >/dev/null 2>&1 - git config --local user.name >/dev/null || git config --local user.name "${identity.DigitalerDienst.name}" - git config --local user.email >/dev/null || git config --local user.email "${identity.DigitalerDienst.email}" - end - end - ''; - onVariable = "PWD"; - }; }; }; }; home.packages = with pkgs; [ git-crypt - tig ]; } diff --git a/users/jalr/modules/gnuradio.nix b/home-manager/modules/gnuradio.nix similarity index 54% rename from users/jalr/modules/gnuradio.nix rename to home-manager/modules/gnuradio.nix index 8a380a7..d3bec15 100644 --- a/users/jalr/modules/gnuradio.nix +++ b/home-manager/modules/gnuradio.nix @@ -1,13 +1,13 @@ { nixosConfig, lib, pkgs, ... }: let - gnuradioEnv = pkgs.gnuradio.override { + gnuradioEnv = pkgs.gnuradio3_8.override { extraPackages = pkgs.lib.attrVals [ "osmosdr" ] - pkgs.gnuradioPackages; + pkgs.gnuradio3_8Packages; }; in -lib.mkIf nixosConfig.jalr.gui.enable { +(lib.mkIf nixosConfig.jalr.gui.enable { home.packages = [ gnuradioEnv ]; -} +}) diff --git a/users/jalr/modules/graphics/default.nix b/home-manager/modules/graphics/default.nix similarity index 76% rename from users/jalr/modules/graphics/default.nix rename to home-manager/modules/graphics/default.nix index 3af9b75..802e665 100644 --- a/users/jalr/modules/graphics/default.nix +++ b/home-manager/modules/graphics/default.nix @@ -1,3 +1,5 @@ +{ nixosConfig, ... }: + { imports = [ ./gimp.nix diff --git a/users/jalr/modules/graphics/gimp.nix b/home-manager/modules/graphics/gimp.nix similarity index 100% rename from users/jalr/modules/graphics/gimp.nix rename to home-manager/modules/graphics/gimp.nix diff --git a/users/jalr/modules/graphics/inkscape.nix b/home-manager/modules/graphics/inkscape.nix similarity index 100% rename from users/jalr/modules/graphics/inkscape.nix rename to home-manager/modules/graphics/inkscape.nix diff --git a/users/jalr/modules/graphics/krita.nix b/home-manager/modules/graphics/krita.nix similarity index 100% rename from users/jalr/modules/graphics/krita.nix rename to home-manager/modules/graphics/krita.nix diff --git a/home-manager/modules/gui.nix b/home-manager/modules/gui.nix new file mode 100644 index 0000000..1ef15d5 --- /dev/null +++ b/home-manager/modules/gui.nix @@ -0,0 +1,15 @@ +{ nixosConfig, lib, pkgs, ... }: +lib.mkIf nixosConfig.jalr.gui.enable { + home.packages = with pkgs; [ + evince + gcr # required for pinentry-gnome + geeqie + mpv + networkmanagerapplet + pinentry-gnome + streamlink + supersonic-wayland + vlc + xdg_utils + ]; +} diff --git a/users/jalr/modules/trilium.nix b/home-manager/modules/jameica.nix similarity index 81% rename from users/jalr/modules/trilium.nix rename to home-manager/modules/jameica.nix index 91b6dfe..d9472e0 100644 --- a/users/jalr/modules/trilium.nix +++ b/home-manager/modules/jameica.nix @@ -1,6 +1,6 @@ { nixosConfig, lib, pkgs, ... }: lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ - trilium-next-desktop + jameica ]; } diff --git a/users/jalr/modules/kicad.nix b/home-manager/modules/kicad.nix similarity index 100% rename from users/jalr/modules/kicad.nix rename to home-manager/modules/kicad.nix diff --git a/users/jalr/modules/mpv.nix b/home-manager/modules/mpv.nix similarity index 100% rename from users/jalr/modules/mpv.nix rename to home-manager/modules/mpv.nix diff --git a/users/jalr/modules/mute-indicator.nix b/home-manager/modules/mute-indicator.nix similarity index 100% rename from users/jalr/modules/mute-indicator.nix rename to home-manager/modules/mute-indicator.nix diff --git a/modules/neo.nix b/home-manager/modules/neo.nix similarity index 71% rename from modules/neo.nix rename to home-manager/modules/neo.nix index b9c299c..48bbb3b 100644 --- a/modules/neo.nix +++ b/home-manager/modules/neo.nix @@ -1,5 +1,6 @@ +{ config, pkgs, ... }: { - environment.variables = { + home.sessionVariables = { XKB_DEFAULT_LAYOUT = "de,de"; XKB_DEFAULT_VARIANT = "neo,"; XKB_DEFAULT_OPTIONS = "grp:win_space_toggle"; diff --git a/home-manager/modules/neovim.nix b/home-manager/modules/neovim.nix new file mode 100644 index 0000000..09b05a3 --- /dev/null +++ b/home-manager/modules/neovim.nix @@ -0,0 +1,174 @@ +{ lib, nixosConfig, config, pkgs, ... }: +{ + home.sessionVariables = { + EDITOR = "nvim"; + }; + programs.neovim = { + enable = true; + vimAlias = true; + extraConfig = '' + " use space as leader + let mapleader = " " + + colorscheme NeoSolarized + + """"""""""""""""" + " Swap and undo " + set noswapfile + set nobackup + if has('persistent_undo') + " yay persistent undo + :silent !mkdir -p ~/.local/vim-undo + set undofile + set undodir=~/.local/vim-undo + endif + + cabbr %% expand('%:p:h') + + set listchars=trail:·,precedes:«,extends:»,eol:↲,tab:▸\ + nmap c :set list! + + set smartcase + set hlsearch + nnoremap :nohlsearch:set nolist + + " highlight whitespace + highlight ExtraWhitespace ctermbg=red guibg=red + highlight WrongIndent ctermbg=2 guibg=blue + match ExtraWhitespace /\s\+$/ + augroup highlight_extra_whitespace + autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ + autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@ gd lua vim.lsp.buf.definition() + nnoremap gi lua vim.lsp.buf.implementation() + nnoremap gr lua vim.lsp.buf.references() + nnoremap gD lua vim.lsp.buf.declaration() + nnoremap ge lua vim.lsp.diagnostic.set_loclist() + nnoremap K lua vim.lsp.buf.hover() + nnoremap f lua vim.lsp.buf.formatting() + nnoremap rn lua vim.lsp.buf.rename() + + nnoremap a lua vim.lsp.buf.code_action() + xmap a lua vim.lsp.buf.range_code_action() + + lua require('init') + ''; + + # nix-env -f '' -qaP -A vimPlugins + plugins = with pkgs.vimPlugins; [ + #Valloric/MatchTagAlways + #frankier/neovim-colors-solarized-truecolor-only + #nvie/vim-rst-tables + NeoSolarized + deoplete-nvim + editorconfig-vim + nvim-lspconfig + vim-gitgutter + vim-indent-guides + vim-nix + vim-puppet + vim-terraform + ]; + }; + + xdg.configFile."nvim/lua/init.lua".text = builtins.concatStringsSep "\n" ( + [ + '' + -- init.lua + -- this configuration applies to servers and workstations + '' + ] ++ lib.optional nixosConfig.jalr.workstation.enable ( + '' + -- this configuration applies to workstations only + -- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md + local lsp = require('lspconfig') + '' + + builtins.concatStringsSep "\n" ( + lib.mapAttrsToList + ( + lang: cfg: "lsp.${lang}.setup\n" + lib.generators.toLua { } cfg + ) + { + # C and C++ + ccls = { + cmd = [ "${pkgs.ccls}/bin/ccls" ]; + }; + + # Nix + rnix = { + cmd = [ "${pkgs.rnix-lsp}/bin/rnix-lsp" ]; + }; + + # Python + pylsp = { + cmd = [ "${pkgs.python3Packages.python-lsp-server}/bin/pylsp" ]; + settings = { + # https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md + pylsp = { + plugins = { + flake8 = { + enabled = true; + executable = "${pkgs.python3Packages.flake8}/bin/flake8"; + }; + jedi_completion = { enabled = true; }; + jedi_definition = { enabled = true; }; + jedi_hover = { enabled = true; }; + jedi_references = { enabled = true; }; + jedi_signature_help = { enabled = true; }; + jedi_symbols = { enabled = true; }; + mccabe = { enabled = true; }; + preload = { enabled = true; }; + pycodestyle = { enabled = true; }; + pyflakes = { enabled = true; }; + rope_completion = { enabled = true; }; + yapf = { enabled = true; }; + }; + }; + }; + }; + + # Ruby + solargraph = { + cmd = [ "${pkgs.solargraph}/bin/solargraph" "stdio" ]; + }; + + # Rust + rust_analyzer = { + cmd = [ "${pkgs.rust-analyzer}/bin/rust-analyzer" ]; + }; + + # Bash + bashls = { + cmd = [ "${pkgs.nodePackages.bash-language-server}/bin/bash-language-server" "start" ]; + }; + + # Terraform + terraform_lsp = { + cmd = [ "${pkgs.terraform-lsp}/bin/terraform-lsp" "serve" ]; + }; + + # YAML + yamlls = { + cmd = [ "${pkgs.nodePackages.yaml-language-server}/bin/yaml-language-server" "--stdio" ]; + settings = { + yaml = { + keyOrdering = false; + }; + }; + }; + } + ) + ) + ); +} diff --git a/users/jalr/modules/obs-studio/default.nix b/home-manager/modules/obs-studio/default.nix similarity index 75% rename from users/jalr/modules/obs-studio/default.nix rename to home-manager/modules/obs-studio/default.nix index ffd39b3..545bcbd 100644 --- a/users/jalr/modules/obs-studio/default.nix +++ b/home-manager/modules/obs-studio/default.nix @@ -2,7 +2,7 @@ { programs.obs-studio = { - inherit (nixosConfig.jalr.gui) enable; + enable = nixosConfig.jalr.gui.enable; plugins = with pkgs; [ obs-studio-plugins.wlrobs ]; diff --git a/users/jalr/modules/3d-modeling.nix b/home-manager/modules/openscad.nix similarity index 100% rename from users/jalr/modules/3d-modeling.nix rename to home-manager/modules/openscad.nix diff --git a/home-manager/modules/pass.nix b/home-manager/modules/pass.nix new file mode 100644 index 0000000..ce3e446 --- /dev/null +++ b/home-manager/modules/pass.nix @@ -0,0 +1,29 @@ +{ nixosConfig, config, pkgs, ... }: + +let + pw = pkgs.writeScriptBin "pw" '' + p="$(${pkgs.pass}/bin/pass show "$1")" + + copy_line() { + echo -n "$p" | ${pkgs.gnused}/bin/sed -n "$1"p | ${pkgs.wl-clipboard}/bin/wl-copy -o -f + } + + echo "username" + copy_line 2 + echo "password" + copy_line 1 + ''; +in +{ + home.packages = [ + pw + ] ++ + ( + if nixosConfig.jalr.gui.enable + then with pkgs; [ + qtpass + pass-wayland + ] + else [ ] + ); +} diff --git a/home-manager/modules/pcmanfm.nix b/home-manager/modules/pcmanfm.nix new file mode 100644 index 0000000..49819d8 --- /dev/null +++ b/home-manager/modules/pcmanfm.nix @@ -0,0 +1,7 @@ +{ nixosConfig, lib, pkgs, ... }: +lib.mkIf nixosConfig.jalr.gui.enable { + home.packages = with pkgs; [ + pcmanfm + ]; +} + diff --git a/users/jalr/modules/python.nix b/home-manager/modules/python.nix similarity index 55% rename from users/jalr/modules/python.nix rename to home-manager/modules/python.nix index d73b0e3..9a620b3 100644 --- a/users/jalr/modules/python.nix +++ b/home-manager/modules/python.nix @@ -1,10 +1,8 @@ { nixosConfig, lib, pkgs, ... }: lib.mkIf nixosConfig.jalr.workstation.enable { home.packages = with pkgs; [ - (python3.withPackages (pp: with pp; [ - ipython - pyyaml - virtualenv - ])) + python3 + python3Packages.virtualenv + python3Packages.ipython ]; } diff --git a/users/jalr/modules/remarkable/default.nix b/home-manager/modules/remarkable/default.nix similarity index 100% rename from users/jalr/modules/remarkable/default.nix rename to home-manager/modules/remarkable/default.nix diff --git a/users/jalr/modules/remarkable/restream.nix b/home-manager/modules/remarkable/restream.nix similarity index 62% rename from users/jalr/modules/remarkable/restream.nix rename to home-manager/modules/remarkable/restream.nix index 6dcbec5..f2725f8 100644 --- a/users/jalr/modules/remarkable/restream.nix +++ b/home-manager/modules/remarkable/restream.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ nixosConfig, lib, pkgs, ... }: { home.packages = with pkgs; [ diff --git a/users/jalr/modules/remarkable/rmview.nix b/home-manager/modules/remarkable/rmview.nix similarity index 85% rename from users/jalr/modules/remarkable/rmview.nix rename to home-manager/modules/remarkable/rmview.nix index 0bf96ed..e87366b 100644 --- a/users/jalr/modules/remarkable/rmview.nix +++ b/home-manager/modules/remarkable/rmview.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: +{ nixosConfig, lib, pkgs, ... }: let config = { @@ -16,7 +16,7 @@ in { home.packages = with pkgs; [ ( - writeShellScriptBin "rmview" '' + pkgs.writeShellScriptBin "rmview" '' export QT_QPA_PLATFORM=xcb exec ${pkgs.rmview}/bin/rmview "$@" '' diff --git a/home-manager/modules/solarized.nix b/home-manager/modules/solarized.nix new file mode 100644 index 0000000..c814420 --- /dev/null +++ b/home-manager/modules/solarized.nix @@ -0,0 +1,23 @@ +builtins.mapAttrs + (name: hex: { + inherit hex; + rgb = builtins.concatStringsSep "," (map (f: toString (builtins.fromTOML "i = 0x${f hex}").i) (map (pos: builtins.substring pos 2) [ 1 3 5 ])); + }) +{ + base00 = "#657b83"; + base01 = "#586e75"; + base02 = "#073642"; + base03 = "#002b36"; + base0 = "#839496"; + base1 = "#93a1a1"; + base2 = "#eee8d5"; + base3 = "#fdf6e3"; + blue = "#268bd2"; + cyan = "#2aa198"; + green = "#859900"; + magenta = "#d33682"; + orange = "#cb4b16"; + red = "#dc322f"; + violet = "#6c71c4"; + yellow = "#b58900"; +} diff --git a/users/jalr/modules/sound/audacity.nix b/home-manager/modules/sound/audacity.nix similarity index 100% rename from users/jalr/modules/sound/audacity.nix rename to home-manager/modules/sound/audacity.nix diff --git a/users/jalr/modules/sound/default.nix b/home-manager/modules/sound/default.nix similarity index 59% rename from users/jalr/modules/sound/default.nix rename to home-manager/modules/sound/default.nix index d5764d3..5c7de31 100644 --- a/users/jalr/modules/sound/default.nix +++ b/home-manager/modules/sound/default.nix @@ -1,8 +1,8 @@ +{ nixosConfig, ... }: + { imports = [ ./audacity.nix - ./easyeffects.nix ./pipewire.nix - #./ksoloti.nix ]; } diff --git a/home-manager/modules/sound/easyeffects.nix b/home-manager/modules/sound/easyeffects.nix new file mode 100644 index 0000000..215ba9a --- /dev/null +++ b/home-manager/modules/sound/easyeffects.nix @@ -0,0 +1,7 @@ +{ nixosConfig, lib, pkgs, ... }: + +lib.mkIf nixosConfig.jalr.gui.enable { + home.packages = with pkgs; [ + easyeffects + ]; +} diff --git a/users/jalr/modules/sound/pipewire.nix b/home-manager/modules/sound/pipewire.nix similarity index 89% rename from users/jalr/modules/sound/pipewire.nix rename to home-manager/modules/sound/pipewire.nix index 22503f8..0be3f41 100644 --- a/users/jalr/modules/sound/pipewire.nix +++ b/home-manager/modules/sound/pipewire.nix @@ -2,6 +2,7 @@ lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ + easyeffects pavucontrol qpwgraph ]; diff --git a/users/jalr/modules/sway/default.nix b/home-manager/modules/sway/default.nix similarity index 72% rename from users/jalr/modules/sway/default.nix rename to home-manager/modules/sway/default.nix index 7e4e764..3b51e61 100644 --- a/users/jalr/modules/sway/default.nix +++ b/home-manager/modules/sway/default.nix @@ -1,21 +1,24 @@ -{ nixosConfig, config, lib, pkgs, ... }: +{ nixosConfig, config, lib, pkgs, stdenv, ... }: let solarized = import ../solarized.nix; terminalEmulator = - pkgs.writeShellScript "wezterm-sway-cwd" '' - this_wezterm_pid="$(${pkgs.sway}/bin/swaymsg -t get_tree --raw | ${pkgs.jq}/bin/jq -e 'recurse(.nodes[]?) | select((.focused==true) and (.app_id=="org.wezfurlong.wezterm")).pid')" + if nixosConfig.jalr.terminalEmulator == "alacritty" + then + pkgs.writeShellScript "alacritty-sway-cwd" '' + this_alacritty_pid="$(${pkgs.sway}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq -e 'recurse(.nodes[]?) | select((.focused==true) and (.app_id=="Alacritty")).pid')" - if [ "$this_wezterm_pid" ]; then - child_pid="$(pgrep -P "$this_wezterm_pid")" - cwd="$(readlink /proc/$child_pid/cwd)" - fi - if [ -e "$cwd" ]; then - exec ${pkgs.wezterm}/bin/wezterm start --cwd "$cwd" - fi + if [ "$this_alacritty_pid" ]; then + child_pid="$(pgrep -P "$this_alacritty_pid")" + cwd="$(readlink /proc/$child_pid/cwd)" + fi + if [ -e "$cwd" ]; then + exec ${pkgs.alacritty}/bin/alacritty --working-directory "$cwd" + fi - exec ${pkgs.wezterm}/bin/wezterm - ''; + exec ${pkgs.alacritty}/bin/alacritty + '' + else nixosConfig.jalr.terminalEmulator; cfg = config.wayland.windowManager.sway.config; wallpaper = pkgs.fetchurl { url = "https://raw.githubusercontent.com/swaywm/sway/3b2bc894a5ebbcbbd6707d45a25d171779c2e874/assets/Sway_Wallpaper_Blue_1920x1080.png"; @@ -35,48 +38,20 @@ let #gsettings set $gnome_schema gtk-theme 'Dracula' ${pkgs.glib}/bin/gsettings "$@" ''; - matchHostname = hostname: lib.optionalAttrs (nixosConfig.networking.hostName == hostname); - resumeTimeTrackingNotification = pkgs.writeShellScript "resume-time-tracking-notification" '' - export PATH=${pkgs.lib.makeBinPath [pkgs.timewarrior pkgs.libnotify]} - task="$1" - date="$2" - if [ $(notify-send --action 'default=Resume time tracking' "Tracking '$task' stopped at $date, resume?") = "default" ]; then - timew continue - fi - ''; - lockScreen = pkgs.writeShellScript "lock-screen" '' - export PATH="${pkgs.lib.makeBinPath [pkgs.gnused pkgs.timewarrior pkgs.coreutils pkgs.swaylock]}" - task="$(timew | sed -n -r 's/^Tracking (.*)$/\1/p')" - date="$(date --rfc-3339=seconds)" - if [ "$task" != "" ]; then - timew stop - nohup ${resumeTimeTrackingNotification} "$task" "$date" >/dev/null 2>&1 & - fi - swaylock -f -i ${wallpaper} - ''; in { imports = lib.optionals nixosConfig.jalr.gui.enable [ ./gammastep.nix - ./mako.nix - ./screenshare.nix ./waybar.nix - ./wofi-bluetooth.nix ./wofi.nix + ./wofi-bluetooth.nix ./yubikey-touch-detector.nix ]; } // (lib.mkIf nixosConfig.jalr.gui.enable { home.packages = with pkgs; [ - gsettings - libnotify # notify-send - mako - slurp - swappy # screenshot editing sway-contrib.grimshot # screenshots - timewarrior wdisplays # graphical output manager - wl-clipboard - wl-mirror + gsettings ]; home.sessionVariables = { @@ -88,6 +63,41 @@ in _JAVA_AWT_WM_NONREPARENTING = "1"; }; + #home.sessionVariables = { + # CLUTTER_BACKEND = "wayland"; + # GDK_BACKEND = "wayland"; + # GDK_DPI_SCALE = 1; + # MOZ_ENABLE_WAYLAND = 1; + # QT_QPA_PLATFORM = "wayland-egl"; + # QT_WAYLAND_DISABLE_WINDOWDECORATION = 1; + # SDL_VIDEODRIVER = "wayland"; + # WLR_NO_HARDWARE_CURSORS = 1; + # _JAVA_AWT_WM_NONREPARENTING = 1; + # _JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=on"; + #}; + + programs.fish.loginShellInit = '' + if [ -z $WAYLAND_DISPLAY ] && [ (tty) = /dev/tty1 ] + export XDG_SESSION_TYPE="wayland" # otherwise set to tty + set -e __HM_SESS_VARS_SOURCED + set -e __NIXOS_SET_ENVIRONMENT_DONE + exec systemd-cat -t sway sway + end + ''; + + xdg.configFile."sway/light-theme".text = with solarized; '' + client.focused ${base01.hex} ${blue.hex} ${base3.hex} ${blue.hex} ${blue.hex} + client.focused_inactive ${base2.hex} ${base2.hex} ${base01.hex} ${base0.hex} ${base2.hex} + client.unfocused ${base2.hex} ${base3.hex} ${base01.hex} ${base2.hex} ${base2.hex} + client.urgent ${red.hex} ${red.hex} ${base3.hex} ${red.hex} ${red.hex} + ''; + xdg.configFile."sway/dark-theme".text = with solarized; '' + client.focused ${base1.hex} ${blue.hex} ${base03.hex} ${blue.hex} ${blue.hex} + client.focused_inactive ${base02.hex} ${base02.hex} ${base1.hex} ${base03.hex} ${base02.hex} + client.unfocused ${base02.hex} ${base03.hex} ${base1.hex} ${base02.hex} ${base02.hex} + client.urgent ${red.hex} ${red.hex} ${base03.hex} ${red.hex} ${red.hex} + ''; + wayland.windowManager.sway = { enable = true; @@ -101,17 +111,17 @@ in terminal = "${terminalEmulator}"; menu = "${pkgs.wofi}/bin/wofi --allow-images --show drun --color=$HOME/.config/wofi/color"; - input."type:keyboard" = { - xkb_layout = "de,de,us"; - xkb_variant = "neo,,"; - xkb_options = "grp:win_space_toggle"; - }; + output."*".bg = "${wallpaper} fill"; - output = { - "*".bg = "${wallpaper} fill"; - } // matchHostname "copper" { - eDP-1.scale = toString 1.5; - }; + # FIXME + #input = { + # #"type:keyboard" = { + # # xkb_layout = "neo"; + # #}; + #} // (lib.optionalAttrs (nixosConfig.networking.hostName == "mayushii") { + # "type:touchpad".events = "disabled"; + # "2:10:TPPS/2_Elan_TrackPoint".pointer_accel = "-0.15"; + #}); keybindings = { "${cfg.modifier}+Return" = "exec ${cfg.terminal}"; @@ -233,8 +243,7 @@ in "XF86AudioMute" = "exec pactl set-source-mute alsa_input.usb-BEHRINGER_UMC202HD_192k-00.HiFi__umc202hd_mono_in_U192k_0_1__source toggle"; - "${cfg.modifier}+l" = "exec ${lockScreen}"; - "${cfg.modifier}+v" = "exec GSK_RENDERER=cairo GTK_USE_PORTAL=0 ${pkgs.mixxc}/bin/mixxc -A"; + "${cfg.modifier}+l" = "exec ${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}"; }; bars = [ ]; # managed as systemd user unit @@ -272,20 +281,6 @@ in criteria = { app_id = "firefox"; title = "Firefox — Sharing Indicator"; }; command = "kill"; } - { - criteria = { - app_id = "firefox-esr"; - title = "Extension: \\\\(Tree Style Tab\\\\) - Close tabs\\\\? — Mozilla Firefox"; - }; - command = "floating enable"; - } - { - criteria = { - app_id = "yad"; - title = "Pomodoro"; - }; - command = "floating enable"; - } ]; window.border = 2; @@ -302,9 +297,7 @@ in fonts = { names = [ "monospace" ]; style = "Regular"; - - # FIXME: this is an ugly workaround until https://github.com/swaywm/sway/issues/7409 is fixed - size = 0.001; + size = 0.0; }; }; @@ -355,48 +348,35 @@ in Environment = "PATH=${pkgs.bash}/bin:${config.wayland.windowManager.sway.package}/bin"; ExecStart = '' ${pkgs.swayidle}/bin/swayidle -w \ - timeout 300 "${lockScreen}" \ - timeout 270 '${pkgs.sway}/bin/swaymsg "output * dpms off"' \ + timeout 300 "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}" \ + timeout 300 '${pkgs.sway}/bin/swaymsg "output * dpms off"' \ resume '${pkgs.sway}/bin/swaymsg "output * dpms on"' \ - before-sleep "${lockScreen}" + before-sleep "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}" ''; Restart = "on-failure"; }; }; - xdg.configFile = + xdg.configFile."swaynag/config".text = let - makeTheme = scheme: '' - client.focused ${scheme.base05} ${scheme.base0D} ${scheme.base00} ${scheme.base0D} ${scheme.base0D} - client.focused_inactive ${scheme.base01} ${scheme.base01} ${scheme.base05} ${scheme.base03} ${scheme.base01} - client.unfocused ${scheme.base01} ${scheme.base00} ${scheme.base05} ${scheme.base01} ${scheme.base01} - client.urgent ${scheme.base08} ${scheme.base08} ${scheme.base00} ${scheme.base08} ${scheme.base08} + # adding it to the header doesn’t work since the defaults overwrite it + commonConfig = /* ini */ '' + background=${lib.substring 1 6 solarized.base3.hex} + border-bottom=${lib.substring 1 6 solarized.base2.hex} + border=${lib.substring 1 6 solarized.base2.hex} + button-background=${lib.substring 1 6 solarized.base3.hex} + button-text=${lib.substring 1 6 solarized.base00.hex} ''; in - { - "sway/light-theme".text = makeTheme solarized.light.hex; - "sway/dark-theme".text = makeTheme solarized.dark.hex; - "swaynag/config".text = - let - # adding it to the header doesn’t work since the defaults overwrite it - commonConfig = /* ini */ '' - background=${lib.substring 1 6 solarized.colors.base3} - border-bottom=${lib.substring 1 6 solarized.colors.base2} - border=${lib.substring 1 6 solarized.colors.base2} - button-background=${lib.substring 1 6 solarized.colors.base3} - button-text=${lib.substring 1 6 solarized.colors.base00} - ''; - in - /* ini */ '' - font=Monospace 12 + /* ini */ '' + font=Monospace 12 - [warning] - text=${lib.substring 1 6 solarized.colors.yellow} - ${commonConfig} + [warning] + text=${lib.substring 1 6 solarized.yellow.hex} + ${commonConfig} - [error] - text=${lib.substring 1 6 solarized.colors.red} - ${commonConfig} - ''; - }; + [error] + text=${lib.substring 1 6 solarized.red.hex} + ${commonConfig} + ''; }) diff --git a/users/jalr/modules/sway/gammastep.nix b/home-manager/modules/sway/gammastep.nix similarity index 100% rename from users/jalr/modules/sway/gammastep.nix rename to home-manager/modules/sway/gammastep.nix diff --git a/users/jalr/modules/sway/move-to-output/default.nix b/home-manager/modules/sway/move-to-output/default.nix similarity index 95% rename from users/jalr/modules/sway/move-to-output/default.nix rename to home-manager/modules/sway/move-to-output/default.nix index 0daabfe..4c3fa5e 100644 --- a/users/jalr/modules/sway/move-to-output/default.nix +++ b/home-manager/modules/sway/move-to-output/default.nix @@ -1,5 +1,5 @@ -{ stdenv, pkgs, ... }: -stdenv.mkDerivation { +{ lib, stdenv, pkgs, writeShellScript, ... }: +stdenv.mkDerivation rec { name = "sway-move-to-output"; phases = "installPhase"; installPhase = '' diff --git a/home-manager/modules/sway/waybar.nix b/home-manager/modules/sway/waybar.nix new file mode 100644 index 0000000..5f9c2f5 --- /dev/null +++ b/home-manager/modules/sway/waybar.nix @@ -0,0 +1,499 @@ +{ config, lib, nixosConfig, pkgs, ... }: +let + watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" '' + ${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \ + | ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \ + | ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end' + ''; + + toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" '' + if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then + ${pkgs.systemd}/bin/systemctl --user stop ${unit} + else + ${pkgs.systemd}/bin/systemctl --user start ${unit} + fi + ''; + + # for fine-grained control over spacing + thinsp = " "; + + solarized = import ../solarized.nix; + solarizedColors = (as: lib.strings.concatLines (lib.attrsets.mapAttrsToList (name: value: let color = solarized."${value}".hex; in "@define-color ${name} ${color};") as)); +in +{ + # home-manager’s waybar module performs additional checks that are overly strict + xdg.configFile."waybar/config".text = lib.generators.toJSON { } { + layer = "top"; + position = "top"; + height = 24; + + modules-center = [ ]; + modules-left = [ + "sway/workspaces" + "sway/mode" + ]; + modules-right = [ + "tray" + "custom/screencast" + "custom/redshift" + "idle_inhibitor" + "backlight" + "mpd" + "pulseaudio" + "network" + "custom/vpn" + "memory" + "cpu" + "temperature" + "battery" + "clock" + "custom/calendar" + ]; + + "sway/workspaces" = { + disable-scroll = true; + }; + "sway/mode" = { + format = "{}"; + }; + + tray = { + spacing = 5; + }; + "custom/redshift" = { + exec = watchUserUnitState + "gammastep" + { class = "active"; } + { class = "inactive"; }; + on-click = toggleUserUnitState "gammastep"; + return-type = "json"; + format = "󰌵"; + tooltip = false; + }; + idle_inhibitor = { + format = "{icon}"; + format-icons = { + activated = "󰈈 "; + deactivated = "󰈉 "; + }; + }; + "custom/screencast" = { + exec = pkgs.writeScript "screencast-monitor" /* python */ '' + #!${pkgs.python3}/bin/python3 + import subprocess + import sys + + active_outputs = 0 + + with subprocess.Popen( + ["${pkgs.coreutils}/bin/stdbuf", "-o0", "${nixosConfig.services.pipewire.package}/bin/pw-link", "-m", "-o", "xdg-desktop-portal-wlr"], + stdout=subprocess.PIPE, + text=True, + ) as proc: + for line in proc.stdout: + action = line.split(" ")[0] + if action == "=" or action == "+": + active_outputs += 1 + elif action == "-": + active_outputs -= 1 + else: + print(f"Invalid action {action} (in line {line})", file=sys.stderr) + + if active_outputs > 0: + print("󱒃") + else: + print() + + sys.stdout.flush() + ''; + format = "{}"; + tooltip = false; + }; + backlight = { + format = "{percent}% {icon}"; + format-icons = [ "󰛩" "󱩎" "󱩏" "󱩐" "󱩑" "󱩒" "󱩓" "󱩔" "󱩕" "󱩖" "󰛨" ]; + on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -q set +5%"; + on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -q set 5%-"; + }; + mpd = { + server = config.services.mpd.network.listenAddress; + format = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} – {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 󰎈"; + format-disconnected = "Disconnected 󰎈"; + format-stopped = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 󰎈"; + unknown-tag = "N/A"; + interval = 2; + tooltip-format = "MPD (connected)"; + tooltip-format-disconnected = "MPD (disconnected)"; + on-scroll-up = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} volume +2"; + on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} volume -2"; + title-len = 48; + artist-len = 24; + consume-icons = { + on = "󰩫 "; + }; + random-icons = { + off = "󰒞 "; + on = "󰒝 "; + }; + repeat-icons = { + on = "󰑖 "; + }; + single-icons = { + on = "󰑘 "; + }; + state-icons = { + paused = "󰏤 "; + playing = "󰐊 "; + }; + }; + pulseaudio = { + format = "{volume}% {icon} {format_source}"; + format-bluetooth = "{volume}% {icon}󰗾{format_source}"; + format-bluetooth-muted = "{icon}󰗿{format_source}"; + format-muted = "󰝟 {format_source}"; + format-source = "{volume}% ${thinsp}"; + format-source-muted = "${thinsp}"; + format-icons = { + car = "󰄋 "; + default = [ "󰕿" "󰖀" "󰕾" ]; + hands-free = "󰋎"; + headphone = "󰋋"; + headset = "󰋎"; + phone = "󰏲"; + portable = "󰏲"; + }; + on-click-right = "${pkgs.pavucontrol}/bin/pavucontrol"; + }; + network = { + format-wifi = "{essid} ({signalStrength}%) 󰖩 "; + format-ethernet = "{ipaddr}/{cidr} 󰈀 "; + format-linked = "{ifname} (No IP) 󰈀 "; + format-disconnected = "Disconnected ⚠ "; + format-alt = "{ifname}: {ipaddr}/{cidr}"; + tooltip = false; + on-click-right = "${config.programs.alacritty.package}/bin/alacritty -e ${pkgs.networkmanager}/bin/nmtui"; + }; + "custom/vpn" = { + interval = 10; + exec = pkgs.writeShellScript "vpn-state" '' + ${pkgs.iproute}/bin/ip -j link \ + | ${pkgs.jq}/bin/jq --unbuffered --compact-output ' + [[.[].ifname | select(. | startswith("mullvad"))][] | split("-")[1] + " 󰌾${thinsp}"] as $conns + | { text: ($conns[0] // ""), class: (if $conns | length > 0 then "connected" else "disconnected" end) }' + ''; + return-type = "json"; + format = "{}"; + tooltip = false; + }; + memory = { + interval = 2; + format = "{:2}% 󰍛 "; + }; + cpu = { + interval = 2; + format = "{usage:2}%  "; + tooltip = false; + }; + temperature = { + critical-threshold = 80; + format = "{temperatureC}°C {icon}"; + format-icons = [ "" "" "" "" "" ]; + } // (lib.optionalAttrs (nixosConfig.networking.hostName == "mayushii") { + hwmon-path = "/sys/class/hwmon/hwmon3/temp1_input"; + }); + battery = { + interval = 5; + format = "{capacity}% {icon}"; + format-charging = "{capacity}% "; + format-plugged = "{capacity}% x"; + format-alt = "{time} {icon}"; + format-icons = [ "󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; + states = { + critical = 15; + good = 95; + warning = 30; + }; + }; + clock = { + format = "{:%H:%M %Z}"; + format-alt = "{:%Y-%m-%d (%a)}"; + tooltip-format = "{:%Y %B}\n{calendar}"; + }; + "custom/calendar" = { + interval = 300; + exec = pkgs.writeScript "calendar" /* python */ '' + #!${pkgs.python3}/bin/python3 + import json + import subprocess + + + def khal(args): + completed = subprocess.run(["${pkgs.khal}/bin/khal"] + args, capture_output=True) + assert completed.returncode == 0 + return completed.stdout.decode("utf-8") + + + events_today = khal(["list", "today", "today", "-df", "", "-f", "{title}"]).rstrip().split("\n") + events_2d = khal(["list", "today", "tomorrow", "-df", "{name}, {date}"]).rstrip() + + if len(events_today) == 1 and events_today[0] == "No events": + events_today = [] + + if len(events_today) == 0: + text = "󰃮 " + else: + text = f"{len(events_today)} 󰃶 " + + print( + json.dumps( + { + "class": "active" if len(events_today) > 0 else "", + "text": text, + "tooltip": events_2d, + } + ) + ) + ''; + return-type = "json"; + format = "{}"; + }; + }; + + xdg.configFile."waybar/theme-light.css".text = solarizedColors { + base00 = "base3"; + base01 = "base2"; + base02 = "base1"; + base03 = "base0"; + base04 = "base00"; + base05 = "base01"; + base06 = "base02"; + base07 = "base03"; + base08 = "red"; + base09 = "orange"; + base0A = "yellow"; + base0B = "green"; + base0C = "cyan"; + base0D = "blue"; + base0E = "violet"; + base0F = "magenta"; + }; + xdg.configFile."waybar/theme-dark.css".text = solarizedColors { + base00 = "base03"; + base01 = "base02"; + base02 = "base01"; + base03 = "base00"; + base04 = "base0"; + base05 = "base1"; + base06 = "base2"; + base07 = "base3"; + base08 = "red"; + base09 = "orange"; + base0A = "yellow"; + base0B = "green"; + base0C = "cyan"; + base0D = "blue"; + base0E = "violet"; + base0F = "magenta"; + }; + xdg.configFile."waybar/style.css".text = '' + @import "theme.css"; + + * { + border-radius: 0; + border: none; + font-family: "Iosevka Nerd Font"; + font-size: 14px; + min-height: 0; + transition-property: none; + } + + window#waybar { + background-color: @base00; + color: @base04; + } + + #workspaces button { + padding: 0 5px; + background-color: @base00; + color: inherit; + border-bottom: 2px solid transparent; + } + + #workspaces button:hover { + background: @base01; + box-shadow: inherit; + text-shadow: inherit; + } + + #workspaces button.focused { + border-bottom: 2px solid @base0B; + } + + #workspaces button.urgent { + background-color: @base08; + } + + #mode { + background-color: @base01; + font-style: italic; + } + + /* all modules on the right */ + #waybar > box > box:nth-child(3) > widget > label { + padding: 0 10px; + } + + #battery.charging { + color: @base01; + background-color: @base0B; + } + + @keyframes blink { + to { + background-color: @base07; + color: @base03; + } + } + + #battery.critical:not(.charging), + #temperature.critical { + background-color: @base08; + animation-name: blink; + animation-duration: 0.5s; + /* FIXME use nearest neighbor interpolation if possible */ + animation-timing-function: cubic-bezier(1, 0, 0, 1); + animation-iteration-count: infinite; + animation-direction: alternate; + } + + #cpu { + background-color: @base0C; + color: @base01 + } + + #memory { + background-color: @base0A; + color: @base01 + } + + #backlight { + background-color: @base07; + color: @base03; + } + + #network { + background-color: @base0E; + color: @base01 + } + + #custom-vpn { + background-color: @base0D; + color: @base01 + } + + #network.disconnected { + background-color: @base08; + } + + #pulseaudio { + background-color: @base07; + color: @base03; + } + + #pulseaudio.muted { + background-color: @base00; + color: @base04; + } + + #temperature { + background-color: @base0F; + color: @base01; + } + + #idle_inhibitor.activated { + background-color: @base07; + color: @base00; + } + + #mpd { + background-color: @base0B; + color: @base01; + } + + #mpd.disconnected { + background-color: @base08; + } + + #mpd.stopped { + background-color: @base09; + } + + #mpd.paused { + background-color: @base0A; + } + + #custom-redshift { + color: @base01; + } + + #custom-redshift.active { + background-color: @base08; + } + + #custom-redshift.inactive { + background-color: @base0D; + } + + #tray { + padding: 0 5px; + } + + #custom-notification_inhibitor.active { + background-color: @base07; + color: @base00; + } + + #custom-screencast { + background-color: @base08; + color: @base00; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: cubic-bezier(1, 0, 0, 1); + animation-iteration-count: infinite; + animation-direction: alternate; + } + + #custom-calendar.active { + background-color: @base07; + color: @base03; + } + ''; + + systemd.user.services.waybar = { + Unit = { + Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors."; + Documentation = "https://github.com/Alexays/Waybar/wiki/"; + PartOf = [ "sway-session.target" ]; + }; + + Install.WantedBy = [ "sway-session.target" ]; + + Service = { + # ensure sway is already started, otherwise workspaces will not work + ExecStartPre = "${config.wayland.windowManager.sway.package}/bin/swaymsg"; + ExecStart = "${pkgs.waybar}/bin/waybar"; + ExecReload = "${pkgs.utillinux}/bin/kill -SIGUSR2 $MAINPID"; + Restart = "on-failure"; + RestartSec = "1s"; + }; + }; + + # TODO: remove when https://github.com/nix-community/home-manager/issues/2064 + # is resolved + systemd.user.targets.tray = { + Unit = { + Description = "Home Manager System Tray"; + Requires = [ "graphical-session-pre.target" ]; + }; + }; +} diff --git a/users/jalr/modules/sway/wofi-bluetooth.nix b/home-manager/modules/sway/wofi-bluetooth.nix similarity index 100% rename from users/jalr/modules/sway/wofi-bluetooth.nix rename to home-manager/modules/sway/wofi-bluetooth.nix diff --git a/home-manager/modules/sway/wofi.nix b/home-manager/modules/sway/wofi.nix new file mode 100644 index 0000000..a5ed905 --- /dev/null +++ b/home-manager/modules/sway/wofi.nix @@ -0,0 +1,89 @@ +{ nixosConfig, config, lib, pkgs, ... }: + +let + solarized = import ../solarized.nix; +in +{ + xdg.configFile."wofi/color-light".text = lib.strings.concatLines (map (c: solarized."${c}".hex) [ + "base3" + "base2" + "base1" + "base0" + "base00" + "base01" + "base02" + "base03" + "red" + "orange" + "yellow" + "green" + "cyan" + "blue" + "violet" + "magenta" + ]); + xdg.configFile."wofi/color-dark".text = lib.strings.concatLines (map (c: solarized."${c}".hex) [ + "base03" + "base02" + "base01" + "base00" + "base0" + "base1" + "base2" + "base3" + "red" + "orange" + "yellow" + "green" + "cyan" + "blue" + "violet" + "magenta" + ]); + xdg.configFile."wofi/style.css".text = '' + window { + margin: 0px; + border: 3px solid --wofi-color1; + border-radius: 8px; + background-color: rgba(--wofi-rgb-color0,0.8); + } + + #input { + margin: 5px; + border: none; + color: --wofi-color4; + background-color: rgba(--wofi-rgb-color1,0.8); + } + + #inner-box { + margin: 5px; + border: none; + background: none; + } + + #outer-box { + margin: 5px; + border: none; + background: none; + } + + #scroll { + margin: 0px; + border: none; + } + + #text { + margin: 5px; + border: none; + color: --wofi-color4; + } + + #entry:selected { + background-color: rgba(--wofi-rgb-color1,0.8); + } + + #entry:selected #text{ + color: --wofi-color11; + } + ''; +} diff --git a/users/jalr/modules/sway/yubikey-touch-detector.nix b/home-manager/modules/sway/yubikey-touch-detector.nix similarity index 95% rename from users/jalr/modules/sway/yubikey-touch-detector.nix rename to home-manager/modules/sway/yubikey-touch-detector.nix index 0d01b60..658f653 100644 --- a/users/jalr/modules/sway/yubikey-touch-detector.nix +++ b/home-manager/modules/sway/yubikey-touch-detector.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ nixosConfig, config, lib, pkgs, ... }: { systemd.user.services.yubikey-touch-detector = { diff --git a/home-manager/modules/thunderbird.nix b/home-manager/modules/thunderbird.nix new file mode 100644 index 0000000..dfe8769 --- /dev/null +++ b/home-manager/modules/thunderbird.nix @@ -0,0 +1,7 @@ +{ nixosConfig, pkgs, ... }: +{ + programs.thunderbird = { + enable = nixosConfig.jalr.gui.enable; + profiles."default".isDefault = true; + }; +} diff --git a/users/jalr/modules/tmux.nix b/home-manager/modules/tmux.nix similarity index 81% rename from users/jalr/modules/tmux.nix rename to home-manager/modules/tmux.nix index c8d4c10..a0781e4 100644 --- a/users/jalr/modules/tmux.nix +++ b/home-manager/modules/tmux.nix @@ -1,3 +1,4 @@ +{ config, pkgs, ... }: { programs.tmux = { enable = true; diff --git a/users/jalr/modules/tor-browser.nix b/home-manager/modules/tor-browser.nix similarity index 100% rename from users/jalr/modules/tor-browser.nix rename to home-manager/modules/tor-browser.nix diff --git a/users/jalr/modules/vdirsyncer.nix b/home-manager/modules/vdirsyncer.nix similarity index 85% rename from users/jalr/modules/vdirsyncer.nix rename to home-manager/modules/vdirsyncer.nix index c853db1..c8c828d 100644 --- a/users/jalr/modules/vdirsyncer.nix +++ b/home-manager/modules/vdirsyncer.nix @@ -45,6 +45,27 @@ let }; }; + mkWebcalSection = { name, url ? null, urlCommand ? null }: assert url == null -> urlCommand != null; { + "pair calendar_${name}" = { + a = "calendar_${name}_local"; + b = "calendar_${name}_remote"; + collections = null; + }; + + "storage calendar_${name}_local" = { + type = "filesystem"; + path = "${calendarBasePath}/${name}/"; + fileext = ".ics"; + }; + + "storage calendar_${name}_remote" = { + type = "http"; + } // (if urlCommand != null then { + "url.fetch" = fetchCommand urlCommand; + } else { + inherit url; + }); + }; in { home.packages = with pkgs; [ diff --git a/home-manager/users/default.nix b/home-manager/users/default.nix new file mode 100644 index 0000000..26dd6aa --- /dev/null +++ b/home-manager/users/default.nix @@ -0,0 +1,28 @@ +{ lib, ... }: + +{ + options.jalr = { + git = { + user = { + name = lib.mkOption { + type = lib.types.str; + description = "name to use for git commits"; + }; + email = lib.mkOption { + type = lib.types.str; + description = "email to use for git commits"; + }; + }; + signByDefault = lib.mkEnableOption "GPG sign commits per default"; + }; + gpg.defaultKey = lib.mkOption { + type = lib.types.str; + description = "default gpg key id"; + }; + terminalEmulator = lib.mkOption { + type = lib.types.str; + description = "default Terminal emulator name"; + default = "alacritty"; + }; + }; +} diff --git a/home-manager/users/jal.nix b/home-manager/users/jal.nix new file mode 100644 index 0000000..e824fb6 --- /dev/null +++ b/home-manager/users/jal.nix @@ -0,0 +1,224 @@ +{ config, lib, pkgs, ... }: + +let + userName = "jal"; + vpn_routes = [ + "10.18.0.0/16" # OEE VPC + "10.64.0.0/16" # CPS + "10.158.128.0/23" # approval + "10.158.224.0/20" # core production + "10.158.240.0/20" # core development + #"10.96.0.0/24" # CCS infrastructure + #"10.96.8.0/24" # Boomi + #"10.96.10.0/24" # Boomi (new) + "10.96.0.0/16" + "10.170.254.30/32" # first core DNS resolver + "10.170.254.40/32" # second core DNS resolver + ]; + vpnc-script = pkgs.writeShellScript "vpnc-script-tb" '' + cisco_split_inc="$CISCO_SPLIT_INC" + export CISCO_SPLIT_INC=0 + + echo "DNS server sent by vpn: $INTERNAL_IP4_DNS" + unset INTERNAL_IP4_DNS + + route_in_whitelist() { + for route in ${builtins.toString vpn_routes}; do + [ "$1" = "$route" ] && return 0 + done + return 1 + } + + routes() { + for i in $(seq 0 $((cisco_split_inc-1))); do + addr_var="CISCO_SPLIT_INC_''${i}_ADDR" + mask_var="CISCO_SPLIT_INC_''${i}_MASK" + masklen_var="CISCO_SPLIT_INC_''${i}_MASKLEN" + addr="''${!addr_var}" + mask="''${!mask_var}" + masklen="''${!masklen_var}" + if route_in_whitelist "$addr/$masklen"; then + case "$1" in + add) + if [ -n "$NETGW" ]; then + ip route add "$addr/$masklen" metric 100 dev "$TUNDEV" via "$NETGW" + else + ip route add "$addr/$masklen" metric 100 dev "$TUNDEV" + fi + ;; + remove) + ip route del "$addr/$masklen" dev "$TUNDEV" + ;; + esac + echo "allowing route '$addr/$masklen'" + else + echo "ignoring route '$addr/$masklen'" + fi + done + } + + case "$reason" in + pre-init|reconnect|attempt-reconnect) + "${pkgs.vpnc-scripts}/bin/vpnc-script" "$@" + ;; + connect) + "${pkgs.vpnc-scripts}/bin/vpnc-script" "$@" + routes add + ;; + disconnect) + routes remove + "${pkgs.vpnc-scripts}/bin/vpnc-script" "$@" + ;; + *) + echo "reason '$reason' is not implemented" >&2 + exit 1 + ;; + esac + ''; + tradebyte-vpn = pkgs.writeShellScriptBin "tradebyte-vpn" '' + [ $UID -ne 0 ] && exec sudo -- "$0" "$@" + /run/wrappers/bin/sudo -u "$SUDO_USER" ${pkgs.pass}/bin/pass show zalando | openconnect \ + --protocol=pulse \ + -u jlechner \ + --passwd-on-stdin \ + -i pulse \ + --pfs \ + --disable-ipv6 \ + --script=${vpnc-script} \ + https://remote.tradebyte.org | grep -v '^> ' + ''; + aws_defaults = { + sso = { + start_url = "https://d-9967250383.awsapps.com/start"; + region = "eu-central-1"; + role_name = "AdministratorAccess"; + }; + region = "eu-central-1"; + }; +in +{ + imports = [ + ./default.nix + ]; + + jalr = { + git = { + user = { + name = "Jakob Lechner"; + email = "jal@tradebyte.biz"; + }; + signByDefault = false; + }; + gpg.defaultKey = "FE170812543DF81393EA56BA5042B8317A10617E"; + aws = { + enable = true; + accounts = { + ops_testing = { + sso_account_id = 134848648016; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + core-production = { + sso_account_id = 455520445575; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + tbmeta-production = { + sso_account_id = 696695470425; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + abnahme = { + sso_account_id = 837645089494; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + core-develop = { + sso_account_id = 934000686307; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + infrastructure = { + sso_account_id = 994756397773; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + tbmeta-development = { + sso_account_id = 730951147261; + sso_start_url = aws_defaults.sso.start_url; + sso_region = aws_defaults.sso.region; + sso_role_name = aws_defaults.sso.role_name; + region = aws_defaults.region; + }; + }; + }; + }; + + users.users.${userName} = { + isNormalUser = true; + extraGroups = [ + "dialout" + "podman" + "libvirtd" + "lp" + "networkmanager" + "scanner" + "video" + "wheel" + "wireshark" + ]; # Enable ‘sudo’ for the user. + shell = pkgs.fish; + }; + + home-manager = { + useUserPackages = true; + useGlobalPkgs = true; + users.${userName} = { lib, pkgs, ... }: { + imports = [ ../modules ]; + config = { + home.stateVersion = config.system.stateVersion; + + home.packages = with pkgs; [ + mycli + timetrap + tradebyte-vpn + + # common + asciinema + bat + docker-compose + envsubst + gnupg + nmap + psutils + pwgen + tig + vlc + xdg_utils + ]; + }; + }; + }; + + security.sudo.extraRules = [{ + users = [ userName ]; + commands = [ + { + command = "${tradebyte-vpn}/bin/tradebyte-vpn"; + options = [ "NOPASSWD" ]; + } + ]; + }]; +} diff --git a/home-manager/users/jalr.nix b/home-manager/users/jalr.nix new file mode 100644 index 0000000..51bd39b --- /dev/null +++ b/home-manager/users/jalr.nix @@ -0,0 +1,97 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./default.nix + ]; + + jalr = { + git = { + user = { + name = "Jakob Lechner"; + email = "mail@jalr.de"; + }; + signByDefault = true; + }; + gpg.defaultKey = "66FB54F6081375106EEBF651A222365EB448F934"; + }; + + users.users.jalr = { + isNormalUser = true; + extraGroups = [ + "adbusers" + "audio" + "dialout" + "docker" + "libvirtd" + "lp" + "networkmanager" + "scanner" + "video" + "wheel" + "wireshark" + ]; # Enable ‘sudo’ for the user. + shell = pkgs.fish; + }; + + home-manager = { + useUserPackages = true; + useGlobalPkgs = true; + users.jalr = { lib, pkgs, ... }: { + imports = [ ../modules ]; + config = { + home.stateVersion = if config.system.stateVersion == "22.11" then "22.05" else config.system.stateVersion; + + home.packages = with pkgs; [ + cutecom + ghostscript + newsboat + pdftk + platformio + ptouch-print + qrencode + sshfs + tmate + + # common + asciinema + bat + docker-compose + envsubst + gnupg + nmap + psutils + pwgen + tig + ]; + + accounts.email.accounts."jalr" = { + primary = true; + userName = "jalr@jalr.de"; + address = "jalr@jalr.de"; + realName = "Jakob Lechner"; + imap = { + host = "hha.jalr.de"; + port = 143; + tls = { + enable = true; + useStartTls = true; + }; + }; + smtp = { + host = "hha.jalr.de"; + port = 587; + tls = { + enable = true; + useStartTls = true; + }; + }; + thunderbird = { + enable = true; + profiles = [ "default" ]; + }; + }; + }; + }; + }; +} diff --git a/hosts/aluminium/configuration.nix b/hosts/aluminium/configuration.nix index 3dfd6a3..e95c861 100644 --- a/hosts/aluminium/configuration.nix +++ b/hosts/aluminium/configuration.nix @@ -1,18 +1,21 @@ -{ config, ... }: +{ config, lib, pkgs, ... }: +let + iptablesAppendIfMissing = rule: "iptables -C " + rule + " || iptables -A " + rule; + iptablesInsertIfMissing = rule: "iptables -C " + rule + " || iptables -I " + rule; +in { imports = [ ./hardware-configuration.nix - ../../users/jalr + ../../home-manager/users/jalr.nix ./services - ./ports.nix ]; + networking.hostName = "aluminium"; services.openssh.enable = true; security.sudo.wheelNeedsPassword = false; networking = { - hostName = "aluminium"; useDHCP = false; vlans = { lechner = { @@ -23,10 +26,6 @@ id = 2; interface = "enp1s0"; }; - iot = { - id = 3; - interface = "enp1s0"; - }; pv = { id = 10; interface = "enp1s0"; @@ -49,10 +48,6 @@ address = "192.168.1.1"; prefixLength = 24; }]; - iot.ipv4.addresses = [{ - address = "192.168.2.1"; - prefixLength = 24; - }]; pv.ipv4.addresses = [{ address = "192.168.10.1"; prefixLength = 30; @@ -75,22 +70,19 @@ "voice" ]; }; - firewall.extraInputRules = '' - iifname "voice" udp dport 5059 accept - ip saddr 217.10.68.150 udp dport 5060 accept - ''; - nftables.tables.pppoe = { - family = "ip"; - content = '' - chain clamp { - type filter hook forward priority mangle; - oifname "ppp0" tcp flags syn tcp option maxseg size set rt mtu comment "clamp MSS to Path MTU" - } - ''; + firewall = { + extraCommands = lib.concatStringsSep "\n" [ + (iptablesAppendIfMissing "FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu") + (iptablesInsertIfMissing "INPUT -i voice -p udp -m udp --dport 5060 -j ACCEPT") + (iptablesInsertIfMissing "INPUT -s 217.10.68.150 -p udp --dport 5060 -j ACCEPT") + ]; }; }; + sops.secrets.pap-secrets = { + sopsFile = ./secrets.yaml; + }; environment.etc."ppp/pap-secrets".source = config.sops.secrets.pap-secrets.path; services.pppd = { enable = true; diff --git a/hosts/aluminium/hardware-configuration.nix b/hosts/aluminium/hardware-configuration.nix index 6b60bb6..f146835 100644 --- a/hosts/aluminium/hardware-configuration.nix +++ b/hosts/aluminium/hardware-configuration.nix @@ -1,7 +1,7 @@ # Do not modify this file! It was generated by ‘nixos-generate-config’ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. -{ config, lib, modulesPath, ... }: +{ config, lib, pkgs, modulesPath, ... }: { imports = diff --git a/hosts/aluminium/ports.nix b/hosts/aluminium/ports.nix index f83f360..a259d6d 100644 --- a/hosts/aluminium/ports.nix +++ b/hosts/aluminium/ports.nix @@ -1,16 +1,9 @@ -{ custom-utils, ... }: +{ lib, custom-utils, ... }: -{ - config.networking.ports = custom-utils.validatePortAttrset { - asterisk-rtp.udp = { from = 10000; to = 10200; }; - doorbell-audiosocket.tcp = 9092; - doorbell-webrtc-ice.tcp = 8189; - doorbell-webrtc.tcp = 8889; - esphome.tcp = 6052; - home-assistant.tcp = 8123; - nginx-http.tcp = 80; - nginx-https.tcp = 443; - unifi-inform.tcp = 8080; - unifi-ui.tcp = 8443; - }; +custom-utils.validatePortAttrset { + asterisk-rtp = { udp.range = [ 10000 10200 ]; }; + unifi.tcp = 8443; + doorbell-audiosocket.tcp = 9092; + doorbell-webrtc.tcp = 8889; + doorbell-webrtc-ice.tcp = 8189; } diff --git a/hosts/aluminium/secrets.yaml b/hosts/aluminium/secrets.yaml index 2ecd5a3..a920ae9 100644 --- a/hosts/aluminium/secrets.yaml +++ b/hosts/aluminium/secrets.yaml @@ -4,7 +4,6 @@ myintercom-doorbell-password: ENC[AES256_GCM,data:waUUvHQ9BZFePQ==,iv:ev21SNOwzd asterisk-pjsip: ENC[AES256_GCM,data:PMgHCdo7K1a9/OitWdUonJ66gr70uwYgylCCWAO9cYOeXdPTIFuFLHlgBIUUxfln3UqhquTzoTluZJW9vaSuzZGe1kLIYrb1hRyrM0HLCCQc8m46jN898le/9ZrEivxonWkxf4FTfpENIf7iEr5KHh4vfd4tr4IbORTFdpcbsy8pd5eyvS8G2z9dynIWS19zqrzfGrW6yZICzAJz28IQCiiHgpN16bqSwlcPm1UdX+qi0+ZJ3TAr16Px1F9VFOXtEsu4EZvJSomecJDuhjo3QzBFffXDL971of8KX05BJgtpP6SzIZXKfSWaOxaguctdFr2tScvze0o3FXpDoOn0cvinOdYQt1P2TzjFnBZ4I3N1turpD4be9xJ92coV/j1hBsZHj2mWE/iCdsrzj2uP/74b4Mo1BJZ6l1gXFg3OgyDXaVoMxAOnutelCEG0lf78hsJXF56aQ1LVSUly6ugZP4rMiPFg5oa7WfrIsVVURUt7WRFrDLCYIQVynpfeUxHshPSB+/jVvYLqie5XeNt8B8mgTJYFo5hFB28sa1beqYEA27QMT3gRvWivqDnuf8soVi/r3WREfnSCBujhzXQF/uJZEwqVEn0OQo9ICfJ8hqtvDiAw6Hb4Wn+0maoYQeKjbPHeL3kr1SUE/kU913FNig4Yn66QKYevLLIkd3uQ0GqTLcgn4Ttwu3qArlXXxrI4US8yA7XGQUutVadN7ayyZBbYnw+vUTlPfhSO+ridK3huGKnQfcPAbD31L11EeQBe2820Nba9Bb4d5QAkiGsNj5y9tZ4Vl6l2JErO63fVPKQ9fPxD3yYyZpP8Hm1e7Wl1eRsNtoWqkTRtno7hIpAYFoMYTUk2x5U/qZOgtRX0JHufi6+GXvPPlBaQNfiGzNlJjdmtTT6MGLPRQjsASGi00pSjKd4psAj9Uf8rttsHhJHvIRDRsiNSjae+JGbVlyyauU1JL44Qf+U+MaJDjkLagNqUZ9xgNFmXzr7st6bRFYCJHkmQC8bgJsdpwRMz3HjNzrKZRvRhHIiwT3d+oyrd9hoSQl3JkxcrD7AfEThrBQL9BpGCDcfr5RzfNv8Fb08tR7rlIzyb6Rw3eKlY1obfZRRNTF+iYlBDz8LLI+BwWqJiefbHB2F9nOC0of5Eqm5gjn+MXSKuSIP5ltDsjfO+m6q7c+t7udKwnJVnePtOnuf4uQpKfxjpld4e8Y1N9hyuKSjqEy83UB4yXJb1OoUAOXENvdPhGFDghmSC+ZVcCZRBG2k6d6MdXY6AkdjUAteDQLsDNMwpW8a8RwOXlDoAtxu7yEYP51BrHu2spagNfXMWHThnkcuR/TvqAPmcPlzVjcX+tnuU0k+JK5e4eWc+diTcvo8fpeaKi7A4uyGWRaZsoaauxsK1dEwIgmAAYyWc0Hl+Z49/dLW8kgr/Qh9N5SRRk/SLk4GvS0uyYYClN7G/7LdMDUwWifr32oqXEINDh0NEyehEJ9dEQsIIH5gR3OdlEAuL1C7/Js3/ZCdBREXRYt4y5y4TAO/kMmGgv7Y/Z2XVD0klXVBMvVnil4LJ0H5KF+RZC4j/C6acRBdrPaI0nlE3bfAbmizQN9D7jOj5BkkRzBaYlMaBuFKRKUA6CUanhUWhIn3ZlF3Z+o4PGB2c7EFXZN+PzOSgkQYUD7KtVW/QV94mxkcqN9mKe6mAbj87neN1IHhEkNOj7KJQP60pqDjx6N+WYFpD3sYvDcJDg2WFumR8F2v+jHx09v5AB1r6AzhPJ3TCwnHN4e1+Nexxlb91iPcoSmLRF3Fimn7307260CtaA70hngWHSRaBcKTXi3WL1v9kKOou2kKs1GMy5bjREtqheBxZ1i4x56VtANF9lo9UT+97qxuAqk08Rc4z9j5M8cJK/d1syRT0z/uAuTWlRgxdE/Fj/OlDNr/SnZw9CLkQ0SVJAuJFFg9EY0ru3PC9PDNt9CJiVy0GoeK0mv7ZkTv2o456kdzMpJPBwpKLIO9tpZBbNZrMn1HpLJrfXIvmuVDFmm3EH6FVhGoI+4yB11Eo/2aEMzUOEtn55KNeESkoVel6GgYiwrg1ZlQS7XhdCTGyCOMbFTOLHgUe4vaUfPBNOyLaLWE3ZiyGCxVb+nBltcPSDHrNtbc2fuPqVom3Z1wfmako1BGcwRzbLdaUPwuu6eRa/KxppPh/PoYTttPxOArql25BWAVTI6BIhlvGgZgqDRwihHBGt1uyXjwv4ufES5zgxhMB8mNqVnCSkcLXXyvpmCiB5kEv5+V4nCJIXSNbmym+V9tEzGh+cx8up24IHrg6gG28fHfMcV7Z+JzN86jogr+sgH9wigrcYcDqTE9lHJhaZlmNraTl8viAwEXkPC/dnQuPSTX5V1qeRtKo1oFkf9xnPhdVLq51GoVU+MhQqZsbnqymgKnPWTQq3Kyiux5go/Li0BqfiV+Wwpn+f3WXJ21aMpU2FfIR26z2DULlJUYDKoewmklq8vzk5iZ/tywPFGR1G0z8IM5jwr+qz0uEccAtulCWsQjtvw0kGLnTsoB2WNL4x0Kti/cE14purKaE65wMrBoG/mxd6R7ZHE7u/Uo1MDAsgqsS8MomCqyxC/1yH9BdhpXc6VZJpborqWQjW/kK8/OBxWFjfQgwvDGeQkgv2ShV0c8U6DgnS545Im9aAxQGvu1sXMhnVNQZdZ2Ta3Gz7bTHqkxB4/X7KGHdGSmw5s/RQfo0BkBBBLLTc49pcmJTxG5LPkRebCM8ANX57qj3u/D9wYumFKclTglNdrjaxSdh3zTb1kEQ0rn/D4z7lVNUsw7srUUZeEadg3xTZSmSustbziXvp51juiJeyPjVY2AlmbVVxU0O245kbyWA8lHcEluo+dfk0Rr9hDNHz35NxQRCslPHiSKswxfuPcqyzlSiBMLsMWrJ5/RyQJgaO/XJ/x3R2o4h+MiHtUKj91epxAIpYD8JqQ4eaUkP6GJRNDSNLK3VNP69Qecc7b6AvV5udzt2up0lp7OuzEZeT88Vg8YcZvOv1UTxmkI6dem1xi4imJs+V4OZrcSt9ZTlc34rc6/lvVxVQZs/1vADB0ZVk3jp24KWuRWFGacJqUIxW8TbI8N1DtmZcf7sqoQU1QPRzkOa/UYmzWablAP4B5M5WOjyr3YSJGOzHxN+GSSs4K4jHUon+LbpKxHL5KJUSsD+kZFTfsDauFhAzpFDhR2wW/XYLr0iTvKQ6+26dIpW65P8Egv+n/CXQE0wuJ1R5z0M4FucpUo+FTUIcww8cfqfHqMlMeKEFeu8/QNdZ0uj06Q8/j6E/OUjpxTIVRQBs4qaLWxMZv3zulCUe9Czr6c28NhewIJlLUxOnCVDo5pT1OmzZPghurNyhTBFP8PfJrRXN1h2uvXfGP46dgt9jgeqqQqP9xlq+fzo9cyEZ/n4nQvY+CBuOW9Cqo41zNB0PQ3tC9SU477gQkDrg0M6/bAk+xsqVg1DpZOSuRUQnOfbTdZ1CXhESy+dcri9BeKKcTCZ6aenvW4W4J6OV8en3L4jPFsgqEWJUk1qr9ggM5NXc7RIrR0eCsiR9V1gi4HWMF1roTZ3wK9NvdATj3HWTGssfdpXht/vjedIp+InNWBWjnBfIf7XWuPgiB/ZW9uew8g8vDLULGVtww==,iv:bFKc8e+3rLAHje8UWwY2elof5xqceTTWX1f7nkE91nM=,tag:NWMiljj8urTDoka5bkF0jg==,type:str] asterisk-ari: ENC[AES256_GCM,data:HnY7d3BdScb0bmsBVlsTHAMv2k8tyyA/,iv:q+NsCHcGGOCe6gdAHbFfjKvO4dyWoW/xI5jtngJmdds=,tag:e8kuEsEokf5lAAgO/coxTQ==,type:str] asterisk-voicemail: ENC[AES256_GCM,data:uyXeBP+9WkfVot4Ot3vwv3OEZfoVDK2I+lvaPpGJTZp16YNtP+uxNiW2ynewQlORCTY59bP1jW3bQdT/ASGsErOrhInYSytTyfdZ51BF9+jz0TH6oWxsSuuawTrkC8jvJOpejt6XuGoYbbqlM/VL1xzgDkq3ztTxaHTfdTonQij2Q4cYddMRHWIEuBCK7FU2TlHAJeIFZvtE0MiyNNT3rEWSs1xcljTGfMjkoMd+FI1uZSQT4r0kAaPPkvCWcAGH6R+F0Ue++i9TuLhu+sDV+X6u3N/garDW74H0bOcLJysImtuPXh1aXuBkHQuC1Liss/IF4NDjtDDhpfc0eePR5MWv/Kj0q+VFJiUPY6XnWh6fG9I2yY22+I7eAAg/xWVZBXPWbFHRz8jm1owp4ln6/hcrJOw6Fzw8tZ6Jd9nciOeOmR1KtjEzklPP5kP1YQPtGio/LnOaAAhTHy16MbWf/Ey4S30+eHB+joD8OM93+YxxrdKNE6XXEcAhkdpHYecrvz4Co1fhY7ZoOnNvA8Juup/7PMyNEU/Fy4Pta34aT/j1s7de2vTpRNBeecWvgFA9Qd7Re/2XPqOAkpduxDniwsUdb52oL39MBoOCY8brmXn2J/mMDeOmoqvjRHsPZsajPTAqF/nqRB8VpwoZAKAx59DYBGgmHz7/7JRX9NXOAus1yLbMfVqDftk6+KTFQ9wCqei3jaI/K5AJrSEwlZG0BLoDefIGXT5f8bNNgSn865j2RP+FLa6W3/u5t+k=,iv:/phktIxMdDO5Nrum7hf3oLDmQO04lrkvFuHNw77aRks=,tag:7OUg0BG9X7nBHWiQNaSOEQ==,type:str] -esphome: ENC[AES256_GCM,data:2pFVokO8YTyKa1F7EePo6wIS3y6prL8SSkxypWZkHl3Ye6Qg0eqZ4du/iwLIXQpJoc6R3uU7D6eIQEVOGbwqYp6+F0CW17F89k9c/VLHQHRpWbA20GgLr7X4fZ8xdbp7HCLpVxRsdzDz8aoARfV8Cn6T7Uo80ah1rMDnTj10WI+Yu6xVqVwPNWrSk9NUGKMK32M2slk=,iv:Xla0c4d9rxn06upy7GTbWBQ8pzl+gLnIw+Rf6hqQlhk=,tag:S+clc2ctuOA6lsInSFm93Q==,type:str] sops: kms: [] gcp_kms: [] @@ -14,25 +13,25 @@ sops: - recipient: age1ne08hny30vrkejqhh7dcx4ql6dmkx6jw9dqkf3cz7mzvt53njy0qh59w44 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEZmNOcVlKNmZCdWN5NVBy - U3VRbXl3OUljWCtITXZCQTdrVkIxOEtDZHg4CktBNjVKRmVucjRpYXo3WXFWd1VV - MFpGdWIvTmNHRlJ4akxUQkZzWUtXVUkKLS0tIGs3NlNXREVkT1Nta2prSXk4QkV0 - NEtzRXY1Q1Njelc1YXNWVE9Jd2NnOFEKjOWHaxO5fF5l+c1Hv6QLBQajrvu1VimZ - Hqk0GYrFpfpFtbhBRyrYgmNuX/qIRMHemdXcNKDYcj0WXgsdVqH7Qw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBodUx5V25ETmJLTi9EZlRU + ZnYweXliTDl4ZUlvcmliTjhQRkpzU0pkNXlZCjFtYU5ySWFxOGlNL29SR2RJZHNu + UHJ4YWE4UWJVeEJBUXJwaHJBd292REkKLS0tIDV2WlppeUxIOWFPTHlRYTBaMzA0 + MU41eU8zeTRRUlZyUXV0U1N6U0NRNnMKZK3vfyRRr7Iu6HfpdpmDTKzUbEnCnW9l + rGjFmY9VX2q9w3j/4E5uUToQfeGMqqBTOFUB3hNgU8K5ZT7wMbOXAg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-03-17T20:41:27Z" - mac: ENC[AES256_GCM,data:f7RdcXpu9CGSZpIF8rwuIkn97EWRxJXxoC7KKbkZg4yxSxZJR/S5UXzEC56eY73IdBHap4op3l+cO7pT7p1rkspHQPH/5D225ihVQ8PQ29u2nlyyrrebB5tM1Mt+rJRlizBPxDDKySJYgdqZCWUwB8f5hQudpb0CGra7NfQreRg=,iv:vwpVqib7fyuV83FiyMT4BOeuqyrcspFyieQGWyZZzcU=,tag:zuJVSA2WqzSvM4MBWrdRlQ==,type:str] + lastmodified: "2023-11-06T23:32:51Z" + mac: ENC[AES256_GCM,data:7lW6i4ULus4348NwnV/ovcWebspBcEBzYqLtl+8xFOfe3erIFnC3iRo0ibZJ8yishZpIUxoVu08yxQoa1qEriC57WETMaR+iGUPaY75tHraBJGY26Etk7Hy2QhQ7D+srBY+CogHhHAD8HUwT4/ZiPqKe1eQAvNg/6HWnjbQkG/Q=,iv:r43odkYgQsyK5uJJ5V98kTx7enP7TRuFoTnYfHmD/8o=,tag:hR+1zCniHs1l3qSkhQhtFw==,type:str] pgp: - - created_at: "2024-01-31T01:19:14Z" + - created_at: "2022-11-02T22:14:19Z" enc: |- -----BEGIN PGP MESSAGE----- - hF4DY/xpNY5WhB0SAQdAkeQx8NatnRtZUJa/G0zaw+NL5twonTayNH8mmNBXOWgw - EWaC9Yq6yWntxxfkVaJHN5BEzxVVumrKmpKSIkvCkJqFZ5SuYH/DyE9oZZSr7iC/ - 0l4BTKZ8SdxQL8usQPSQVbs9skr7KsYfhtjTeTi823RwZLD1+wZKwqe43AJTE0Hl - b2jIihfXa7wKTfi9jXI/mpxLRpGH8kZnPoQuldkz1zWIU14YKoTKq55My8qwR4uW - =RazZ + wV4D3ylLYNOsO+0SAQdASri/Ozm8ibaE1PN8ItRanuAGU4jRQL1g4U8GbsiXWzcw + u7trrk6foY98pfVAP4Z78X4Dp79UagorlDCT6F6yWtfFODFdTVJdbzJsD5QtZ1vK + 0lEBMmTyLDw4lzTpedDhvgkWpNd33TC3WgAfRb/2LCSPmoVp83O7ja6BfuBQDkWY + gP7g815fKYigaihDH8HlNzvRoOOcGC9+6lyQkHTJyRjKsrg= + =WfhH -----END PGP MESSAGE----- - fp: 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 + fp: 66FB54F6081375106EEBF651A222365EB448F934 unencrypted_suffix: _unencrypted - version: 3.8.1 + version: 3.7.3 diff --git a/hosts/aluminium/services/asterisk/default.nix b/hosts/aluminium/services/asterisk/default.nix index 463ac5e..ccc0e79 100644 --- a/hosts/aluminium/services/asterisk/default.nix +++ b/hosts/aluminium/services/asterisk/default.nix @@ -1,15 +1,34 @@ -{ config, lib, pkgs, ... }: +args@{ config, lib, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../../ports.nix args; secretConfigFiles = [ "ari" "pjsip" "voicemail" ]; + rtp = { + start = builtins.elemAt ports.asterisk-rtp.udp.range 0; + end = builtins.elemAt ports.asterisk-rtp.udp.range 1; + }; voicemail-sounds = pkgs.callPackage ./voicemail-sounds { }; in { + systemd.services.asterisk-voicemail-sounds = { + wantedBy = [ "asterisk.service" ]; + after = [ "asterisk.service" ]; + script = '' + ln -sfn \ + ${voicemail-sounds}/unavail.wav \ + /var/spool/asterisk/voicemail/lechner/876/unavail.wav + ''; + restartTriggers = [ voicemail-sounds ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + services.asterisk = { enable = true; confFiles = { @@ -138,8 +157,8 @@ in ''; "rtp.conf" = '' [general] - rtpstart=${toString ports.asterisk-rtp.udp.from} - rtpend=${toString ports.asterisk-rtp.udp.to} + rtpstart=${toString rtp.start} + rtpend=${toString rtp.end} ''; "dnsmgr.conf" = '' [general] @@ -150,11 +169,12 @@ in useTheseDefaultConfFiles = [ ]; }; - sops.secrets = lib.listToAttrs (map + sops.secrets = (lib.listToAttrs (map (name: lib.nameValuePair "asterisk-${name}" { + sopsFile = ../../secrets.yaml; owner = config.users.users.asterisk.name; }) - secretConfigFiles); + secretConfigFiles)); environment.etc = lib.mapAttrs' (name: _: lib.nameValuePair "asterisk/${name}.conf" @@ -162,106 +182,92 @@ in (lib.listToAttrs (map (name: lib.nameValuePair name { }) secretConfigFiles)); networking.firewall = { - allowedUDPPortRanges = lib.singleton ports.asterisk-rtp.udp; - interfaces.voice = { - allowedTCPPorts = [ 5060 ]; - allowedUDPPorts = [ 5060 ]; + allowedUDPPortRanges = [ + { + from = rtp.start; + to = rtp.end; + } + ]; + }; + + systemd.services."asterisk-reload-endpoint@" = { + description = "Check if asterisk endpoint is identified and reload it when it is not."; + serviceConfig = { + Type = "oneshot"; + }; + environment = { + ENDPOINT = "%I"; + }; + script = '' + export PATH=${pkgs.lib.makeBinPath [pkgs.asterisk pkgs.gnused pkgs.gnugrep]} + if ! asterisk -r -x "pjsip show endpoint $ENDPOINT" | sed -n '/^===/,/^\s*ParameterName/{//!p}' | grep -q 'Identify:'; then + asterisk -r -x "module reload res_pjsip_endpoint_identifier_ip.so" + fi + ''; + }; + + systemd.timers.asterisk-reload-endpoint = { + description = "Check if asterisk endpoint is identified and reload it when it is not."; + after = [ "asterisk.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig = { + Persistent = true; + OnCalendar = "*-*-* *:*:00"; + Unit = "asterisk-reload-endpoint@sipgate.service"; }; }; - systemd.services = { - "asterisk-reload-endpoint@" = { - description = "Check if asterisk endpoint is identified and reload it when it is not."; - serviceConfig = { - Type = "oneshot"; - }; - environment = { - ENDPOINT = "%I"; - }; - script = '' - export PATH=${pkgs.lib.makeBinPath [pkgs.asterisk pkgs.gnused pkgs.gnugrep]} - if ! asterisk -r -x "pjsip show endpoint $ENDPOINT" | sed -n '/^===/,/^\s*ParameterName/{//!p}' | grep -q 'Identify:'; then - asterisk -r -x "module reload res_pjsip_endpoint_identifier_ip.so" - fi - ''; + systemd.services."asterisk-voicemail-call@" = { + description = "Check if voicemail exists and place a call to the voicemail application."; + serviceConfig = { + Type = "oneshot"; }; - asterisk-voicemail-sounds = { - wantedBy = [ "asterisk.service" ]; - after = [ "asterisk.service" ]; - script = '' - ln -sfn \ - ${voicemail-sounds}/unavail.wav \ - /var/spool/asterisk/voicemail/lechner/876/unavail.wav - ''; - restartTriggers = [ voicemail-sounds ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; + scriptArgs = "%I"; + script = '' + export PATH=${pkgs.lib.makeBinPath [pkgs.asterisk pkgs.coreutils pkgs.findutils]} + number="$(echo "$1" | cut -d ':' -f 1)" + user="$(echo "$1" | cut -d ':' -f 2)" + channel="PJSIP/$(echo "$1" | cut -d ':' -f 3)" + + if ! find "/var/spool/asterisk/voicemail/$user/$number/INBOX/" -mindepth 1 -maxdepth 1 | read; then + exit + fi + + callfile="$(mktemp -p /tmp XXXXXXXXXX.call)" + chmod 644 "$callfile" + + cat > "$callfile" << EOF + Channel: $channel + WaitTime: 15 + Application: VoiceMailMain + Data: $number@$user + CallerID: Voicemail + EOF + + mv "$callfile" /var/spool/asterisk/outgoing/ + ''; + }; + + systemd.timers.asterisk-voicemail-call-10 = { + description = "Check if voicemail exists and place a call to the voicemail application."; + after = [ "asterisk.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig = { + Persistent = true; + OnCalendar = "*-*-* 07..22:00,20,40:00"; + Unit = "asterisk-voicemail-call@876:lechner:10.service"; }; - "asterisk-voicemail-call@" = { - description = "Check if voicemail exists and place a call to the voicemail application."; - serviceConfig = { - Type = "oneshot"; - }; - scriptArgs = "%I"; - script = '' - export PATH=${pkgs.lib.makeBinPath [pkgs.asterisk pkgs.coreutils pkgs.findutils]} - number="$(echo "$1" | cut -d ':' -f 1)" - user="$(echo "$1" | cut -d ':' -f 2)" - channel="PJSIP/$(echo "$1" | cut -d ':' -f 3)" - - if ! find "/var/spool/asterisk/voicemail/$user/$number/INBOX/" -mindepth 1 -maxdepth 1 | read; then - exit - fi - - callfile="$(mktemp -p /tmp XXXXXXXXXX.call)" - chmod 644 "$callfile" - - cat > "$callfile" << EOF - Channel: $channel - WaitTime: 15 - Application: VoiceMailMain - Data: $number@$user - CallerID: Voicemail - EOF - - mv "$callfile" /var/spool/asterisk/outgoing/ - ''; + }; + systemd.timers.asterisk-voicemail-call-11 = { + description = "Check if voicemail exists and place a call to the voicemail application."; + after = [ "asterisk.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig = { + Persistent = true; + OnCalendar = "*-*-* 07..22:00,10,30:50"; + Unit = "asterisk-voicemail-call@876:lechner:11.service"; }; }; - systemd.timers = { - asterisk-reload-endpoint = { - description = "Check if asterisk endpoint is identified and reload it when it is not."; - after = [ "asterisk.service" ]; - wantedBy = [ "timers.target" ]; - timerConfig = { - Persistent = true; - OnCalendar = "*-*-* *:*:00"; - Unit = "asterisk-reload-endpoint@sipgate.service"; - }; - }; - - asterisk-voicemail-call-10 = { - description = "Check if voicemail exists and place a call to the voicemail application."; - after = [ "asterisk.service" ]; - wantedBy = [ "timers.target" ]; - timerConfig = { - Persistent = true; - OnCalendar = "*-*-* 07..22:00,20,40:00"; - Unit = "asterisk-voicemail-call@876:lechner:10.service"; - }; - }; - asterisk-voicemail-call-11 = { - description = "Check if voicemail exists and place a call to the voicemail application."; - after = [ "asterisk.service" ]; - wantedBy = [ "timers.target" ]; - timerConfig = { - Persistent = true; - OnCalendar = "*-*-* 07..22:00,10,30:50"; - Unit = "asterisk-voicemail-call@876:lechner:11.service"; - }; - }; - }; + #voicemailCallScript } diff --git a/hosts/aluminium/services/asterisk/voicemail-sounds/default.nix b/hosts/aluminium/services/asterisk/voicemail-sounds/default.nix index 06451f1..a4a810c 100644 --- a/hosts/aluminium/services/asterisk/voicemail-sounds/default.nix +++ b/hosts/aluminium/services/asterisk/voicemail-sounds/default.nix @@ -1,4 +1,4 @@ -{ stdenvNoCC }: +{ lib, stdenvNoCC }: stdenvNoCC.mkDerivation { name = "voicemail-sounds"; diff --git a/hosts/aluminium/services/default.nix b/hosts/aluminium/services/default.nix index 8639a37..9539fb7 100644 --- a/hosts/aluminium/services/default.nix +++ b/hosts/aluminium/services/default.nix @@ -4,10 +4,6 @@ ./dnsmasq.nix ./doorbell.nix ./dyndns.nix - ./esphome - ./home-assistant.nix - ./nginx.nix - ./ntp.nix ./unifi-controller.nix ]; } diff --git a/hosts/aluminium/services/dnsmasq.nix b/hosts/aluminium/services/dnsmasq.nix index c6ada0d..7d45fa8 100644 --- a/hosts/aluminium/services/dnsmasq.nix +++ b/hosts/aluminium/services/dnsmasq.nix @@ -1,5 +1,8 @@ -{ lib, pkgs, ... }: +{ pkgs, ... }: +let + stateDir = "/var/lib/dnsmasq"; +in { services.dnsmasq = { enable = true; @@ -7,19 +10,14 @@ listen-address = [ "192.168.0.1" "192.168.1.1" - "192.168.2.1" "192.168.10.9" ]; interface = "lo"; expand-hosts = true; - domain = [ - "lan.kbh.jalr.de" - "iot.kbh.jalr.de,192.168.2.0/24" - ]; + domain = "lan.kbh.jalr.de"; dhcp-range = [ "192.168.0.20,192.168.0.254,4h" "192.168.1.20,192.168.1.254,4h" - "192.168.2.20,192.168.2.254,4h" "192.168.10.8,static,24h" ]; dhcp-host = [ @@ -36,24 +34,11 @@ "2001:470:20::2" # ordns.he.net "74.82.42.42" # ordns.he.net ]; - dhcp-option = [ - "option:ntp-server,192.168.0.1" - ]; }; }; - networking.firewall.interfaces = lib.attrsets.genAttrs [ - "heizung" - "iot" - "lechner" - "pv" - "sprechanlage" - "voice" - ] - ( - _: { - allowedUDPPorts = [ 53 67 ]; - allowedTCPPorts = [ 53 ]; - } - ); + networking.firewall = { + allowedUDPPorts = [ 53 67 ]; + allowedTCPPorts = [ 53 ]; + }; } diff --git a/hosts/aluminium/services/doorbell.nix b/hosts/aluminium/services/doorbell.nix index 01190f4..e2b7229 100644 --- a/hosts/aluminium/services/doorbell.nix +++ b/hosts/aluminium/services/doorbell.nix @@ -1,10 +1,13 @@ -{ config, ... }: +args@{ config, lib, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; in { - sops.secrets.myintercom-doorbell-password.owner = "asterisk"; + sops.secrets.myintercom-doorbell-password = { + sopsFile = ../secrets.yaml; + owner = "asterisk"; + }; services.myintercom-doorbell = { enable = true; host = "sprechanlage.lan.kbh.jalr.de"; diff --git a/hosts/aluminium/services/dyndns.nix b/hosts/aluminium/services/dyndns.nix index 546cb07..ea0e38c 100644 --- a/hosts/aluminium/services/dyndns.nix +++ b/hosts/aluminium/services/dyndns.nix @@ -1,42 +1,16 @@ -{ config, lib, pkgs, ... }: -let - mkService = config: - lib.mapAttrs' - (name: cfg: lib.nameValuePair "godns-${name}" ( - let - config = cfg.settings // { - login_token_file = "$CREDENTIALS_DIRECTORY/login_token"; - }; - configFile = (pkgs.formats.yaml { }).generate "config.yaml" config; - in - { - description = "GoDNS service"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - serviceConfig = { - DynamicUser = true; - ExecStart = "${lib.getExe pkgs.godns} -c ${configFile}"; - LoadCredential = "login_token:${cfg.tokenPath}"; - Restart = "always"; - RestartSec = "2s"; - }; - } - )) - config; -in +{ config, ... }: { - systemd.services = mkService { - ip4 = { - tokenPath = config.sops.secrets.duckdns-secret.path; - settings = { - provider = "DuckDNS"; - domains = [{ domain_name = "www.duckdns.org"; sub_domains = [ "jalr-k" ]; }]; - resolver = "8.8.8.8"; - ip_interface = "ppp0"; - ip_urls = [ "" ]; - ip_type = "IPv4"; - interval = 60; - }; - }; + sops.secrets.duckdns-secret = { + sopsFile = ../secrets.yaml; + }; + services.ddclient = { + enable = true; + interval = "1min"; + protocol = "duckdns"; + server = "www.duckdns.org"; + username = "nouser"; + passwordFile = config.sops.secrets.duckdns-secret.path; + domains = [ "jalr-k" ]; + use = "if, if=ppp0"; }; } diff --git a/hosts/aluminium/services/esphome/default.nix b/hosts/aluminium/services/esphome/default.nix deleted file mode 100644 index 4e63710..0000000 --- a/hosts/aluminium/services/esphome/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ pkgs -, config -, ... -}: -let - inherit (config.networking) ports; -in -{ - sops.secrets.esphome.restartUnits = [ config.systemd.services.esphome.name ]; - - jalr.esphome = { - enable = true; - port = ports.esphome.tcp; - secretsFile = config.sops.secrets.esphome.path; - configDir = pkgs.stdenvNoCC.mkDerivation { - name = "esphome-config"; - src = ./devices; - dontBuild = true; - installPhase = '' - mkdir $out - cp -r * $out - ''; - }; - }; -} diff --git a/hosts/aluminium/services/esphome/devices/.env b/hosts/aluminium/services/esphome/devices/.env deleted file mode 100644 index 640bd9c..0000000 --- a/hosts/aluminium/services/esphome/devices/.env +++ /dev/null @@ -1,2 +0,0 @@ -ESPHOME_HOST="jalr-k.duckdns.org" -ESPHOME_SECRETS_FILE="esphome_${ESPHOME_HOST}_secrets.yaml" diff --git a/hosts/aluminium/services/esphome/devices/.gitignore b/hosts/aluminium/services/esphome/devices/.gitignore deleted file mode 100644 index d8b4157..0000000 --- a/hosts/aluminium/services/esphome/devices/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Gitignore settings for ESPHome -# This is an example and may include too much for your use-case. -# You can modify this file to suit your needs. -/.esphome/ -/secrets.yaml diff --git a/hosts/aluminium/services/esphome/devices/justfile b/hosts/aluminium/services/esphome/devices/justfile deleted file mode 120000 index 68d1c45..0000000 --- a/hosts/aluminium/services/esphome/devices/justfile +++ /dev/null @@ -1 +0,0 @@ -../../../../../modules/esphome/devices/justfile \ No newline at end of file diff --git a/hosts/aluminium/services/esphome/devices/wasserbett.yaml b/hosts/aluminium/services/esphome/devices/wasserbett.yaml deleted file mode 100644 index 8d0e6ab..0000000 --- a/hosts/aluminium/services/esphome/devices/wasserbett.yaml +++ /dev/null @@ -1,64 +0,0 @@ -esphome: - name: "waterbed" - friendly_name: "Wasserbett" - -esp8266: - board: d1_mini - framework: - version: recommended - -logger: - -api: - encryption: - key: !secret apikey_waterbed - -ota: - - platform: esphome - password: !secret otapass_waterbed - -wifi: - ssid: !secret wifi_ssid_kbh - password: !secret wifi_password_kbh - domain: .iot.kbh.jalr.de - enable_on_boot: true - fast_connect: true - -switch: - - platform: gpio - pin: - number: 13 - id: pump - icon: "mdi:electric-switch" - -dallas: - - pin: 12 - -sensor: - - platform: dallas - #address: 0xb7000802397ccc10 - index: 0 - name: "Temperatur" - id: temperature_waterbed - -climate: - - platform: thermostat - name: "Temperatur" - id: temperature - sensor: temperature_waterbed - heat_deadband: 0.2 - heat_overrun: 0.2 - min_heating_off_time: 300s - min_heating_run_time: 300s - min_idle_time: 30s - heat_action: - - switch.turn_on: pump - idle_action: - - switch.turn_off: pump - default_preset: heizen - on_boot_restore_from: memory - preset: - - name: heizen - default_target_temperature_low: 28.5 °C - - name: abwesend - default_target_temperature_low: 24 °C diff --git a/hosts/aluminium/services/home-assistant.nix b/hosts/aluminium/services/home-assistant.nix deleted file mode 100644 index 633b210..0000000 --- a/hosts/aluminium/services/home-assistant.nix +++ /dev/null @@ -1,141 +0,0 @@ -{ pkgs, config, ... }: -let - inherit (config.networking) ports; -in -{ - services.home-assistant = { - enable = true; - lovelaceConfig = { - title = "Home"; - views = [ - { - path = "default_view"; - title = "Home"; - cards = [ - { - title = "Heizung"; - type = "entities"; - entities = [ - { entity = "sensor.guntamaticbiostar_betrieb"; } - { entity = "sensor.guntamaticbiostar_pufferladung"; } - { entity = "sensor.guntamaticbiostar_puffer_oben"; } - { entity = "sensor.guntamaticbiostar_puffer_unten"; } - { entity = "sensor.guntamaticbiostar_kesseltemperatur"; } - { entity = "sensor.guntamaticbiostar_vorlauf_ist_1"; } - { entity = "sensor.guntamaticbiostar_aussentemperatur"; } - { entity = "sensor.guntamaticbiostar_co2_gehalt"; } - { entity = "select.guntamaticbiostar_program"; } - { entity = "sensor.guntamaticbiostar_programm"; } - { entity = "sensor.guntamaticbiostar_programm_hk1"; } - { entity = "sensor.guntamaticbiostar_rucklauftemperatur"; } - { entity = "sensor.guntamaticbiostar_servicezeit"; } - ]; - } - { - type = "grid"; - square = false; - columns = 1; - cards = [ - { - title = "Wasserbett"; - type = "entities"; - entities = [ - { - entity = "sensor.waterbed_temperatur"; - name = "Temperatur"; - } - ]; - } - { - type = "thermostat"; - entity = "climate.waterbed_temperatur"; - } - ]; - } - ]; - } - ]; - }; - extraComponents = [ - # See https://www.home-assistant.io/integrations - "esphome" - "openweathermap" - ]; - customComponents = [ - # https://github.com/a529987659852/GuntamaticBiostar - pkgs.home-assistant-custom-components.guntamatic - ]; - lovelaceConfigWritable = false; - configWritable = false; - config = { - http = { - server_host = [ "127.0.0.1" ]; - server_port = ports.home-assistant.tcp; - use_x_forwarded_for = true; - trusted_proxies = [ "127.0.0.1" ]; - }; - homeassistant = { - unit_system = "metric"; - time_zone = "Europe/Berlin"; - temperature_unit = "C"; - inherit (config.location) longitude; - inherit (config.location) latitude; - }; - default_config = { }; - "automation nix" = [ - { - alias = "Nachschüren"; - description = "Benachrichtigung auf iPad bei Wechsel auf Teillast"; - mode = "single"; - trigger = [ - { - platform = "state"; - entity_id = [ "sensor.guntamaticbiostar_betrieb" ]; - from = "VOLLLAST"; - to = "TEILLAST"; - } - ]; - condition = [ - { - condition = "numeric_state"; - entity_id = "sensor.guntamaticbiostar_pufferladung"; - below = "80"; - } - ]; - action = [ - { - device_id = "5612874405fa2ee539ad4518a1bb8e34"; - domain = "mobile_app"; - type = "notify"; - message = '' - Kessel läuft auf Teillast und Puffer ist unter 80%. Vielleicht willst du - nachschüren. - ''; - title = "Nachschüren?"; - } - ]; - } - ]; - "automation ui" = "!include automations.yaml"; - "scene nix" = [ - ]; - "scene ui" = "!include scenes.yaml"; - }; - }; - - systemd.tmpfiles.rules = [ - "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" - "f ${config.services.home-assistant.configDir}/scenes.yaml 0755 hass hass" - ]; - - services.nginx.virtualHosts."hass.kbh.jalr.de" = { - enableACME = true; - forceSSL = true; - kTLS = true; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString ports.home-assistant.tcp}/"; - recommendedProxySettings = true; - proxyWebsockets = true; - }; - }; -} diff --git a/hosts/aluminium/services/nginx.nix b/hosts/aluminium/services/nginx.nix deleted file mode 100644 index 6eb78ee..0000000 --- a/hosts/aluminium/services/nginx.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ config, ... }: - -let - inherit (config.networking) ports; -in -{ - services.nginx = { - enable = true; - defaultHTTPListenPort = ports.nginx-http.tcp; - defaultSSLListenPort = ports.nginx-https.tcp; - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - }; - networking.firewall.allowedTCPPorts = [ - 80 - 443 - ]; -} diff --git a/hosts/aluminium/services/ntp.nix b/hosts/aluminium/services/ntp.nix deleted file mode 100644 index 45917cf..0000000 --- a/hosts/aluminium/services/ntp.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ - services.chrony = { - enable = true; - extraConfig = '' - allow 192.168.0.0/24 - allow 192.168.10.0/24 - leapsectz right/UTC - ''; - }; - networking.firewall.interfaces.lechner.allowedUDPPorts = [ 123 ]; - networking.firewall.interfaces.heizung.allowedUDPPorts = [ 123 ]; -} diff --git a/hosts/aluminium/services/unifi-controller.nix b/hosts/aluminium/services/unifi-controller.nix index ae39578..8004941 100644 --- a/hosts/aluminium/services/unifi-controller.nix +++ b/hosts/aluminium/services/unifi-controller.nix @@ -1,16 +1,13 @@ -{ config, pkgs, ... }: +args@{ pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; in { services.unifi = { enable = true; + openFirewall = true; unifiPackage = pkgs.unifi; - mongodbPackage = pkgs.mongodb-7_0; }; - networking.firewall.interfaces.lechner.allowedTCPPorts = [ - ports.unifi-inform.tcp - ports.unifi-ui.tcp - ]; + networking.firewall.allowedTCPPorts = [ ports.unifi.tcp ]; } diff --git a/hosts/cadmium/configuration.nix b/hosts/cadmium/configuration.nix index 32c1151..eb39348 100644 --- a/hosts/cadmium/configuration.nix +++ b/hosts/cadmium/configuration.nix @@ -1,13 +1,16 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { imports = [ ./hardware-configuration.nix - ../../users/jalr + ../../home-manager/users/jalr.nix ]; networking = { hostName = "cadmium"; + networkmanager = { + enable = true; + }; useDHCP = false; firewall = { @@ -47,11 +50,9 @@ bootloader = "systemd-boot"; bluetooth.enable = true; uefi.enable = true; - gui = { - enable = true; - sway.enable = true; - }; + gui.enable = true; workstation.enable = true; + sdr.enable = true; libvirt.enable = true; autologin.enable = true; autologin.username = "jalr"; diff --git a/hosts/copper/configuration.nix b/hosts/copper/configuration.nix deleted file mode 100644 index 841d390..0000000 --- a/hosts/copper/configuration.nix +++ /dev/null @@ -1,77 +0,0 @@ -{ lib, ... }: - -{ - imports = [ - ./hardware-configuration.nix - ./disko.nix - ../../users/jalr - ./services - ./framework-fixes.nix - ]; - - networking = { - hostName = "copper"; - extraHosts = lib.concatStringsSep "\n" ( - lib.attrsets.mapAttrsToList - (addr: hosts: - lib.concatStringsSep " " ([ addr ] ++ hosts) - ) - { - #"192.0.2.1" = ["example.com"]; - } - ); - firewall.interfaces.virbr0.allowedTCPPorts = [ 53 64172 ]; - firewall.interfaces.virbr0.allowedUDPPorts = [ 53 67 69 4011 ]; - }; - - zramSwap = { - enable = true; - algorithm = "zstd"; - memoryPercent = 60; - priority = 1; - }; - - services = { - fstrim.enable = true; - flatpak.enable = true; - snapper.configs = { - home = { - SUBVOLUME = "/home"; - ALLOW_USERS = [ "jalr" ]; - TIMELINE_CREATE = true; - TIMELINE_CLEANUP = true; - TIMELINE_LIMIT_HOURLY = 12; - TIMELINE_LIMIT_DAILY = 7; - TIMELINE_LIMIT_WEEKLY = 4; - TIMELINE_LIMIT_MONTHLY = 3; - TIMELINE_LIMIT_YEARLY = 0; - BACKGROUND_COMPARISON = "yes"; - NUMBER_CLEANUP = "no"; - NUMBER_MIN_AGE = "1800"; - NUMBER_LIMIT = "100"; - NUMBER_LIMIT_IMPORTANT = "10"; - EMPTY_PRE_POST_CLEANUP = "yes"; - EMPTY_PRE_POST_MIN_AGE = "1800"; - }; - }; - }; - - jalr = { - bootloader = "lanzaboote"; - bluetooth.enable = true; - uefi.enable = true; - gui = { - enable = true; - sway.enable = true; - }; - workstation.enable = true; - libvirt.enable = true; - autologin = { - enable = true; - username = "jalr"; - }; - }; - - system.stateVersion = "24.05"; -} - diff --git a/hosts/copper/disko.nix b/hosts/copper/disko.nix deleted file mode 100644 index bdbbf17..0000000 --- a/hosts/copper/disko.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ - disko.devices = { - disk = { - nvme = { - type = "disk"; - device = "/dev/disk/by-id/nvme-Samsung_SSD_990_PRO_2TB_S7DNNJ0X235226N"; - content = { - type = "gpt"; - partitions = { - esp = { - type = "EF00"; - size = "1024M"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - mountOptions = [ "uid=0" "gid=0" "fmask=0077" "dmask=0077" "nodev" "nosuid" "noexec" ]; - }; - }; - luks = { - size = "100%"; - content = { - type = "luks"; - name = "copper-crypt"; - settings = { - allowDiscards = true; - }; - extraFormatArgs = [ "--hash sha512 --use-random --pbkdf argon2id --iter-time 5000 --pbkdf-memory ${builtins.toString (4*1024*1024)} --pbkdf-parallel 4" ]; - content = { - type = "btrfs"; - extraArgs = [ "-f" ]; - subvolumes = { - "/root" = { - mountpoint = "/"; - mountOptions = [ "compress-force=zstd:1" "noatime" ]; - }; - "/home" = { - mountpoint = "/home"; - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - "/home/.snapshots" = { - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - "/nix" = { - mountpoint = "/nix"; - mountOptions = [ "compress-force=zstd:1" "noatime" "noatime" "nodev" ]; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; -} - - diff --git a/hosts/copper/framework-fixes.nix b/hosts/copper/framework-fixes.nix deleted file mode 100644 index f1463d2..0000000 --- a/hosts/copper/framework-fixes.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ pkgs, ... }: - -{ - boot.extraModprobeConfig = '' - options cfg80211 ieee80211_regdom="DE" - options mt7921_common disable_clc=1 - options mt7921e disable_aspm=Y - ''; - hardware.firmware = [ pkgs.wireless-regdb ]; - - services.udev.extraRules = '' - ACTION=="add", SUBSYSTEM=="pci", ATTR{power/wakeup}="disabled" - ''; -} diff --git a/hosts/copper/hardware-configuration.nix b/hosts/copper/hardware-configuration.nix deleted file mode 100644 index aa46864..0000000 --- a/hosts/copper/hardware-configuration.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ config, lib, pkgs, modulesPath, ... }: - -{ - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; - - boot.initrd = { - availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ]; - }; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - - environment.systemPackages = with pkgs; [ - fw-ectool - ]; -} diff --git a/hosts/copper/secrets.yaml b/hosts/copper/secrets.yaml deleted file mode 100644 index 5ad148c..0000000 --- a/hosts/copper/secrets.yaml +++ /dev/null @@ -1,32 +0,0 @@ -ntfy_shiftphone: ENC[AES256_GCM,data:WG/LlELNgEh2BiyrOYLDvYk3AlObSvUYUH8v3Cq9oHOhN1+Iwg==,iv:MVwLBIQjY8Z31V9mXf7Ge/jGb9S7ceLFx2TffcsO+o4=,tag:skeQbBPLYH8D4CPDorJ0fQ==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] - age: - - recipient: age1rrut5ntrkqmvttvmpa5jcmjhr2pfpyaqgu9dmtx6v07lgjxx5ppsl7e5v3 - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzbXFqbHJFM0xxL284dWZD - TDkzcGVSRGorRWQvV3h3dkJ6UjNOeUxVcGdRCk5jTkZDeVFORVVWdm1vZm5XUHdk - S0ZBTEdEeDgramZNZm5xK3RkVkkxSDgKLS0tIFZ6dysvVm1YNlJzOVFXZXhrdXBE - dU0reGFSUmRxb0ZlUHgyYlpjU0FOQUEKuOMKvkZcynBGyMHmAYmz13Jy32YKyVK0 - ztCWcXbl9qCe6KtI0yW+t8DLk/PaRrmSrB+2ICTMFqPh7HiBoX+KgQ== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-03-12T20:36:21Z" - mac: ENC[AES256_GCM,data:BpwQmtqj8NkTNO7cJHMoOeILY4HRcb7OasiCcnXsBwIFvbeDgwj+DMZOeKbitLXwzS5frWhZWg0eBHQ4BZQFjX1K0KReVacH9CblHnSZLxjMg3x6o3upB70YjdmD3KKBisOwfMCjklwk0rKwx0w5vzac3r1nJU+PGtFw1luIiBs=,iv:bYIRVFWVGjwgmaGu6JqvpCa0TIp8idP5Bc5cYV7Bri8=,tag:D2xS1PK9a9Dd1mm8+R9RRA==,type:str] - pgp: - - created_at: "2025-03-12T20:51:07Z" - enc: |- - -----BEGIN PGP MESSAGE----- - - hF4DY/xpNY5WhB0SAQdAhB2C4sQhoL04j1RiWoeNCNSbGxDkrqXP+IffdoY8DWgw - x8aogh0b7CpTplBG/4g/WMVB4N/86uvI+mLYxJMyRb9b0f0bDr5dPpnhk//r/MDg - 0l4B9+hcSzmkwXlKh7L8Ds4cZr/z3RlqnR424KSfKbiaaigYttui5l4xgEEPZE1H - 1yfIJ5lBMgG1HTj3HX5mqM9ocA4HVzIkfPPqrFRAgjZdqeDEbLBT3lItMlvsOwy4 - =kS0b - -----END PGP MESSAGE----- - fp: 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 - unencrypted_suffix: _unencrypted - version: 3.9.4 diff --git a/hosts/copper/services/default.nix b/hosts/copper/services/default.nix deleted file mode 100644 index 663c3a8..0000000 --- a/hosts/copper/services/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ - imports = [ - ./illuminanced.nix - ./ntfy.nix - ./timelog.nix - ./webdev.nix - ]; -} diff --git a/hosts/copper/services/illuminanced.nix b/hosts/copper/services/illuminanced.nix deleted file mode 100644 index dde4c64..0000000 --- a/hosts/copper/services/illuminanced.nix +++ /dev/null @@ -1,94 +0,0 @@ -{ lib, pkgs, ... }: - -let - tomlFormat = pkgs.formats.toml { }; - cfg = { - daemonize = { - log_to = "syslog"; - pid_file = "/run/illuminanced/illuminanced.pid"; - #log_level = "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" - log_level = "ERROR"; - }; - general = { - check_period_in_seconds = 1; - light_steps = 100; - min_backlight = 20; - step_barrier = 0.1; - max_backlight_file = "/sys/class/backlight/amdgpu_bl1/max_brightness"; - backlight_file = "/sys/class/backlight/amdgpu_bl1/brightness"; - illuminance_file = "/sys/bus/iio/devices/iio:device0/in_illuminance_raw"; - #event_device_mask = "/dev/input/event*"; - #event_device_name = "Asus WMI hotkeys"; - enable_max_brightness_mode = true; - filename_for_sensor_activation = ""; - }; - kalman = { - q = 1; - r = 20; - covariance = 10; - }; - light = { - points_count = 6; - - illuminance_0 = 0; - light_0 = 0; - illuminance_1 = 20; - light_1 = 35; - illuminance_2 = 70; - light_2 = 50; - illuminance_3 = 120; - light_3 = 65; - illuminance_4 = 200; - light_4 = 75; - illuminance_5 = 255; - light_5 = 99; - }; - }; - configFile = tomlFormat.generate "illuminanced.toml" cfg; -in -{ - systemd.services.illuminanced = { - description = "Ambient Light Sensor Daemon"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "exec"; - Restart = "always"; - ExecStart = "${pkgs.illuminanced}/bin/illuminanced -c ${configFile}"; - PIDFile = cfg.daemonize.pid_file; - StandardOutput = "journal"; - BindReadOnlyPaths = [ - "/nix/store" - "/dev/log" - "/run/systemd/journal/socket" - "/run/systemd/journal/stdout" - cfg.general.max_backlight_file - (lib.strings.escape [ ":" ] cfg.general.illuminance_file) - ]; - BindPaths = [ - cfg.general.backlight_file - ]; - CapabilityBoundingSet = null; - IPAddressDeny = "any"; - LockPersonality = true; - PrivateDevices = true; - PrivateTmp = true; - PrivateUsers = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "noaccess"; - ProtectSystem = "strict"; - RestrictAddressFamilies = [ ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RootDirectory = "/run/illuminanced"; - RuntimeDirectory = "illuminanced"; - SystemCallArchitectures = "native"; - SystemCallFilter = "@system-service"; - }; - }; -} diff --git a/hosts/copper/services/ntfy.nix b/hosts/copper/services/ntfy.nix deleted file mode 100644 index e3e7665..0000000 --- a/hosts/copper/services/ntfy.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - sops.secrets.ntfy_shiftphone.owner = "jalr"; -} diff --git a/hosts/copper/services/timelog.nix b/hosts/copper/services/timelog.nix deleted file mode 100644 index 3343897..0000000 --- a/hosts/copper/services/timelog.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - powerManagement = { - powerUpCommands = '' - echo "timelog: powerUp" - ''; - powerDownCommands = '' - echo "timelog: powerDown" - ''; - }; -} diff --git a/hosts/copper/services/webdev.nix b/hosts/copper/services/webdev.nix deleted file mode 100644 index 5236f67..0000000 --- a/hosts/copper/services/webdev.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ pkgs, lib, ... }: -{ - systemd.services = lib.attrsets.mapAttrs' - ( - name: mapping: lib.attrsets.nameValuePair "redir-${name}" { - description = "Port redirection for local development web server (${name})"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - AmbientCapabilities = "CAP_NET_BIND_SERVICE"; - BindReadOnlyPaths = [ "/nix/store" ]; - CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; - DynamicUser = true; - ExecStart = "${pkgs.redir}/bin/redir -n 127.0.0.1:${toString mapping.to} 127.0.0.1:${toString mapping.from}"; - IPAddressAllow = "localhost"; - IPAddressDeny = "any"; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = lib.mkForce true; - PrivateTmp = true; - ProcSubset = "pid"; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "noaccess"; - ProtectSystem = "strict"; - ReadWritePaths = ""; - RemoveIPC = true; - RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - RootDirectory = "/run/redir-https"; - RuntimeDirectory = "redir-https"; - SystemCallArchitectures = "native"; - SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ]; - Type = "exec"; - }; - } - ) - { - http = { from = 8080; to = 80; }; - https = { from = 8443; to = 443; }; - }; -} diff --git a/hosts/default.nix b/hosts/default.nix index 357302f..322731b 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -1,10 +1,7 @@ -inputs: -let - hardware = inputs.nixos-hardware.nixosModules; -in +{ ... }@inputs: { aluminium = { - targetHost = "jalr-k.duckdns.org"; + targetHost = "192.168.0.1"; system = "x86_64-linux"; }; jalr-t520 = { @@ -13,20 +10,20 @@ in cadmium = { system = "x86_64-linux"; }; + hafnium = { + system = "x86_64-linux"; + }; + weinturm-pretix-prod = { + system = "aarch64"; + targetHost = "142.132.185.70"; + }; iron = { system = "x86_64-linux"; #targetHost = "192.168.42.1"; targetHost = "jalr-bw.duckdns.org"; }; magnesium = { - system = "x86_64-linux"; - targetHost = "magnesium.jalr.de"; - }; - copper = { - system = "x86_64-linux"; - targetHost = "copper.lan.bw.jalr.de"; - extraModules = [ - hardware.framework-16-7040-amd - ]; + system = "aarch64"; + targetHost = "162.55.35.199"; }; } diff --git a/hosts/hafnium/configuration.nix b/hosts/hafnium/configuration.nix new file mode 100644 index 0000000..31afa72 --- /dev/null +++ b/hosts/hafnium/configuration.nix @@ -0,0 +1,147 @@ +{ lib, config, pkgs, self, system, ... }: + +let + tradebyteDnsServers = [ + "10.170.254.30" + "10.170.254.40" + ]; +in +{ + imports = [ + ./hardware-configuration.nix + ../../home-manager/users/jal.nix + ]; + + networking = { + hostName = "hafnium"; + networkmanager = { + enable = true; + }; + useDHCP = false; + interfaces = { + enp2s0f0.useDHCP = false; + enp5s0.useDHCP = false; + wlp3s0.useDHCP = false; + }; + firewall = { + allowedUDPPorts = [ + 53 + ]; + allowedTCPPorts = [ + 53 + ]; + }; + extraHosts = '' + #10.10.10.10 example.com + ''; + }; + + environment.systemPackages = with pkgs; [ + brightnessctl + gnome3.adwaita-icon-theme + openconnect + redir + tcpdump + ]; + + environment.variables.EDITOR = "nvim"; + + programs.mtr.enable = true; + + + services.udisks2.enable = true; + + jalr = { + bootloader = "systemd-boot"; + bluetooth.enable = true; + uefi.enable = true; + gui.enable = true; + workstation.enable = true; + sdr.enable = false; + libvirt.enable = true; + autologin.enable = true; + autologin.username = "jal"; + tradebyte.enable = true; + }; + + + sops.secrets = ( + lib.listToAttrs (map + (name: lib.nameValuePair "wireguard_key_${name}" { + sopsFile = ./secrets.yaml; + }) + [ + "tbcore" + "ops-testing" + ] + ) + ); + + networking.wireguard.interfaces = { + tbcore = { + ips = [ "172.27.27.16/32" ]; + privateKeyFile = config.sops.secrets.wireguard_key_tbcore.path; + listenPort = 51930; + + peers = [{ + publicKey = "K5vF/yTag6NnWjZsMug63DERdCFRfHoqxVkgKH55oFE="; + endpoint = "194.33.184.175:51930"; + #endpoint = "ccs-emergency-vpn.core.tradebyte.com:51930"; + persistentKeepalive = 25; + allowedIPs = [ + "10.158.128.0/23" + "10.158.224.0/20" + "10.18.0.0/16" + "10.64.64.0/20" # CPS + "172.31.1.0/24" + ]; + }]; + }; + ops-testing = { + ips = [ "10.254.254.2/30" ]; + privateKeyFile = config.sops.secrets.wireguard_key_ops-testing.path; + peers = [{ + publicKey = "+jZETJfwaRiM+7ys5eYjgiWEAtxP47RzZSCx0w4l2nI="; + endpoint = "3.68.138.217:2048"; + persistentKeepalive = 25; + allowedIPs = [ + "10.254.254.0/30" + "10.250.0.0/16" + ]; + }]; + }; + }; + + services.dnsmasq.settings.server = lib.lists.flatten + ( + map (domain: (map (srv: "/${domain}/${srv}") tradebyteDnsServers)) [ + "vpce-0c1c169d1e33a1c2f-yugtdam1.s3.eu-central-1.vpce.amazonaws.com" + "ccs.tradebyte.com" + "instance.tradebyte.com" + ]) ++ [ + "/internal.production.core.tradebyte.com/10.158.224.2" + "/internal.development.core.tradebyte.com/10.170.254.30" + "/rds.amazonaws.com/9.9.9.9" + "/tradebyte.com/9.9.9.9" + "/tradebyte.org/9.9.9.9" + "/develop.sys.tradebyte.com/10.0.3.1" + "/corp.ad.zalando.net/10.160.19.100" + ]; + services.actkbd = { + enable = true; + bindings = [ + { keys = [ 232 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/brightnessctl s -5%"; } + { keys = [ 233 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/brightnessctl s +5%"; } + ]; + }; + + # 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 = "23.11"; # Did you read the comment? + +} + diff --git a/hosts/hafnium/hardware-configuration.nix b/hosts/hafnium/hardware-configuration.nix new file mode 100644 index 0000000..5e2c719 --- /dev/null +++ b/hosts/hafnium/hardware-configuration.nix @@ -0,0 +1,44 @@ +{ modulesPath, ... }: + +{ + imports = [ + "${modulesPath}/installer/scan/not-detected.nix" + ]; + + hardware.cpu.amd.updateMicrocode = true; + + boot = { + initrd.availableKernelModules = [ + "nvme" + "ehci_pci" + "xhci_pci" + "usb_storage" + "sd_mod" + "rtsx_pci_sdmmc" + ]; + kernelModules = [ "kvm-amd" ]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/b86310f5-fe3d-4b4d-bc02-ab0d7e9297cf"; + fsType = "btrfs"; + options = [ + "discard=async" + "noatime" + "subvol=/nixos" + "compress=zstd:6" + ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/564E-26B4"; + fsType = "vfat"; + options = [ "nodev" "nosuid" "noexec" ]; + }; + }; + + boot.initrd.luks.devices.cryptroot = { + device = "/dev/disk/by-uuid/d9b120c1-5e80-4893-92fe-497e5b44c25b"; + allowDiscards = true; + }; +} diff --git a/hosts/hafnium/secrets.yaml b/hosts/hafnium/secrets.yaml new file mode 100644 index 0000000..f2bf06a --- /dev/null +++ b/hosts/hafnium/secrets.yaml @@ -0,0 +1,42 @@ +wireguard_key_tbcore: ENC[AES256_GCM,data:/VdCVC6xciihm2suOiuNabAWPhWPGSyWSKbLKRpy8EK7aXpyxZPybnANc1E=,iv:/LxrjPLzUkHdyT45RIfbfc4Xa3vsnQNiamnbiMdubpg=,tag:N5nFx1QsH9FGiK9DrMg2hQ==,type:str] +wireguard_key_ops-testing: ENC[AES256_GCM,data:FiADGmh3GAK6LI9Y5EEErmoVCfx4So6mN3glnzUWk8zDXJbRYP1Uj1kJiss=,iv:7tEWVT6eeHpekgkO17DXtrO7meFvYo6xV4ZLpGG20PQ=,tag:Mtr2gMnCqfJP5ADyordddw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1ahnfjspcpwxxk7getcxkj3fypwt37rr6p3xsmp8n2tqqqz8jtg7q2am0et + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtWlZBSFBKNXJ4QmpDZUpT + NE91ek10QkwxSU1XTE81cGxHZXZmL1JncEY0ClZFbVd5dG14L1hqQlRWTDVkZmpx + V1EzSG9rMC80WTNIZExXOXU1VjcrMk0KLS0tIElWdkh4MzNyeTNteDJTY3RvanQx + ai9YdFdleXNNY2pXQzZMem0vdDdSMjgKvngMU5Y1/Pp+G/a9SyewkN9wr22ZcGP6 + XHHadzk6NE7BJWqquY+2B0Rh3B1Ow+rC8yJd7FhJlHw+i0Bp/d/ESw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2022-04-21T08:09:31Z" + mac: ENC[AES256_GCM,data:+TB7XQPMQCFAR/0jrUKTgjm2yJ7qJ6Jak3DMbFof7mnGE9LKT+xPKYzPwAM+4aDzngHv1fumD6JCXDoJ4DS95frAVfNVNM1bfB0iVmrtf0PX1y+Em189/hs3bt2YBkvvW9kYJMq0g9VBngX6gwGuaBAFHly1gi6SPMZN4vNRF6g=,iv:DK5OYG+BohxllorP0j9mvQ7MtqVNnBjJ3Nf378scJOA=,tag:lBwsHbY9PlJ2/eMtKcxZxA==,type:str] + pgp: + - created_at: "2022-04-20T21:27:25Z" + enc: | + -----BEGIN PGP MESSAGE----- + + hQIMA6jlFWJ+id7kARAArP1hdPwQk2XyKsXYnSj6vxK81GhfZp3tkYEqsU3Jdpwn + OR+0SnuoNWk4dN4JE4ooS5DOhS0ZaVsglLPtiLLohGWYY4OrX33JHZN4oEa5GMBK + t9b0YNb9owow0MSFN679tmiCMvzXGprT0mdWO3/X/HlKvCcTYPRqul4BVeVR/LyG + V94MSaF3BUwFb4p/Q8jcWfsfH5gmMpiFHQsmtci4LjDHvAVCFzI3AjcbRRJUfO5v + ampZ+9yUNo8Y6btrQQWvMoGpOp6U7cj6rTk+eZuW16/7WbHMz6WSpolDyy01QjzQ + szS5RuACnUTMqG4YWQk90H3Srgq/6CFBVLSTm2h8zdO9UZcgkJRYLTFczbYbyqgN + 2Vpjf0UwIv5MHvdo1QZJeBEl8TxjI5UZY2/UDOb9OZXktcAxW5U0Wy6pZIfUsJpk + GJeAb+P3pLvs62hkNSS+rGoGvLX2u0R/Xvw1btTdLLOeIOPNGF8lau32mBuErIZ9 + 2E44N1qV8uQDkDdvaKpj4ikf/0MURPW4GWXST3K/BwD1Gos2SzVD17kXGGOVdeOP + Q19LSo06h2Cq+zNcyKU4C0IdRPvFLKJbyEN3vDYXGnJK7lqGr/UDDcPgYPHVPn1Q + gTdmAk2e8lZY6O0OP5tth5cMjJZj5msvjbww9J1PA3VnBuo8+17zCJ/IYwCUlEbS + XgEWH0LKnwjG7Ufr8eT0DzeCJoD2U/2h+8/+Q2dc4YqokIPW7VuZhR+HZygVAX65 + 1yT/1z+1Hr6kLr9cDLzjyPRu5rNgZJHc8pxkbrQsT764oclvfbgIcmvko9Fsg4o= + =S5XT + -----END PGP MESSAGE----- + fp: FE170812543DF81393EA56BA5042B8317A10617E + unencrypted_suffix: _unencrypted + version: 3.7.2 diff --git a/hosts/iron/configuration.nix b/hosts/iron/configuration.nix index 57a422a..329758c 100644 --- a/hosts/iron/configuration.nix +++ b/hosts/iron/configuration.nix @@ -1,25 +1,25 @@ -{ config, pkgs, lib, ... }: +{ inputs, config, pkgs, lib, ... }: let - interfaces = import ./interfaces.nix; - disks = { - slot1 = "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R103837K"; - slot2 = "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R103838A"; - slot3 = "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R104926N"; - slot4 = "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R104934H"; - slot5 = "ata-Samsung_SSD_870_QVO_8TB_S5SSNJ0W206517Y"; - }; + zfsKernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages; + disks = [ + "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R103837K" + "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R103838A" + "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R104926N" + "ata-Samsung_SSD_870_QVO_8TB_S5SSNG0R104934H" + "ata-Samsung_SSD_870_QVO_8TB_S5SSNJ0W206517Y" + ]; removableEfi = true; devNodes = "/dev/disk/by-id/"; datasets = { "bpool/nixos/root" = "/boot"; "rpool/filebitch" = "/filebitch"; "rpool/navidrome" = "/var/lib/private/navidrome"; - "rpool/navidrome/music" = "/var/lib/navidrome/music"; + "rpool/navidrome/music" = "/var/lib/private/navidrome/music"; "rpool/nixos/home" = "/home"; "rpool/nixos/root" = "/"; "rpool/nixos/var/lib" = "/var/lib"; - "rpool/nixos/var/lib/qBittorrent" = "/var/lib/qBittorrent"; - "rpool/nixos/var/lib/qBittorrent/downloads" = "/var/lib/qBittorrent/downloads"; + "rpool/nixos/var/lib/qbittorrent" = "/var/lib/qbittorrent"; + "rpool/nixos/var/lib/qbittorrent/downloads" = "/var/lib/qbittorrent/downloads"; "rpool/nixos/var/log" = "/var/log"; }; partitionScheme = { @@ -28,16 +28,16 @@ let luksDev = "-part3"; biosBoot = "-part4"; }; - efiSystemPartitions = map (diskName: diskName + partitionScheme.efiBoot) (lib.attrValues disks); + efiSystemPartitions = (map (diskName: diskName + partitionScheme.efiBoot) disks); + iptablesAppendIfMissing = rule: "iptables -C " + rule + " || iptables -A " + rule; in with lib; { imports = [ - ../../users/jalr + ../../home-manager/users/jalr.nix ./services - ./ports.nix ]; config = { - system.stateVersion = "25.05"; + system.stateVersion = "23.11"; security.sudo.wheelNeedsPassword = false; @@ -47,19 +47,14 @@ with lib; { useDHCP = false; networkmanager.enable = false; - bridges = { - "${interfaces.lan}" = { - interfaces = [ "enp2s4" "enp3s5" ]; - }; - }; vlans = { iot = { id = 20; - interface = interfaces.lan; + interface = "enp2s4"; }; }; interfaces = { - "${interfaces.lan}".ipv4.addresses = [{ + enp2s4.ipv4.addresses = [{ address = "192.168.42.1"; prefixLength = 24; }]; @@ -67,36 +62,30 @@ with lib; { address = "10.20.0.1"; prefixLength = 20; }]; - "${interfaces.wan}" = { + enp3s5 = { useDHCP = true; }; }; nat = { enable = true; - externalInterface = interfaces.wan; + externalInterface = "enp3s5"; internalInterfaces = [ - interfaces.lan - "virbr0" + "enp2s4" ]; }; firewall = { - allowedTCPPorts = [ 5201 ]; - extraForwardRules = '' - tcp flags syn tcp option maxseg size set rt mtu - ''; - interfaces.virbr0 = { - allowedTCPPorts = [ 53 ]; - allowedUDPPorts = [ 53 67 ]; - }; + extraCommands = lib.concatStringsSep "\n" [ + (iptablesAppendIfMissing "FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu") + ]; }; }; services.radvd = { enable = true; config = '' - interface ${interfaces.lan} { + interface enp2s4 { AdvSendAdvert on; prefix ::/64 { AdvOnLink on; @@ -111,59 +100,47 @@ with lib; { noipv6rs waitip 6 - interface ${interfaces.wan} + interface enp3s5 ipv6rs ia_na 1 - ia_pd 1/::/64 ${interfaces.lan}/0/64 + ia_pd 1/::/64 enp2s4/0/64 ''; - jalr.luksUsbUnlock = { - enable = true; - devices = builtins.mapAttrs - (_: _: { - keyPath = "iron.key"; - usbDevice = "by-label/RAM_USB"; - waitForDevice = 10; - }) - disks; - }; - boot = { + kernelPackages = zfsKernelPackages; kernel.sysctl = { "net.ipv6.conf.all.forwarding" = 1; }; initrd = { - availableKernelModules = [ - "ahci" - "ehci_pci" - "sd_mod" - "sdhci_pci" - "usb_storage" - "xhci_pci" - ]; + availableKernelModules = [ "ahci" ]; systemd.enable = true; - luks.devices = builtins.mapAttrs - (_: dev: { - device = "${devNodes}${dev}${partitionScheme.luksDev}"; - allowDiscards = true; - }) - disks; + luks.devices = lib.listToAttrs ( + map + (dev: { + name = "LUKS-${dev}${partitionScheme.luksDev}"; + value = { + device = "${devNodes}${dev}${partitionScheme.luksDev}"; + allowDiscards = true; + }; + }) + disks + ); }; supportedFilesystems = [ "zfs" ]; zfs = { - inherit devNodes; + devNodes = devNodes; forceImportRoot = false; }; loader = { efi = { - canTouchEfiVariables = if removableEfi then false else true; - efiSysMountPoint = "/boot/efis/" + (head (lib.attrValues disks)) - + partitionScheme.efiBoot; + canTouchEfiVariables = (if removableEfi then false else true); + efiSysMountPoint = ("/boot/efis/" + (head disks) + + partitionScheme.efiBoot); }; generationsDir.copyKernels = true; grub = { enable = true; - devices = map (diskName: devNodes + diskName) (attrValues disks); + devices = (map (diskName: devNodes + diskName) disks); efiInstallAsRemovable = removableEfi; copyKernels = true; efiSupport = true; @@ -173,11 +150,11 @@ with lib; { terminal_input --append serial terminal_output --append serial ''; - extraInstallCommands = toString (map + extraInstallCommands = (toString (map (diskName: '' ${pkgs.coreutils-full}/bin/cp -r ${config.boot.loader.efi.efiSysMountPoint}/EFI /boot/efis/${diskName}${partitionScheme.efiBoot} '') - (tail (attrValues disks))); + (tail disks))); }; }; kernelParams = [ @@ -218,15 +195,9 @@ with lib; { }; }; - hardware = { - enableRedistributableFirmware = true; - graphics = { - enable = true; - extraPackages = [ - pkgs.intel-vaapi-driver - ]; - }; - }; + hardware.enableRedistributableFirmware = true; + + sound.enable = true; virtualisation.containers.storage.settings = { storage = { @@ -236,16 +207,5 @@ with lib; { options.zfs.fsname = "rpool/nixos/podman"; }; }; - - zramSwap = { - enable = true; - algorithm = "zstd"; - memoryPercent = 60; - priority = 1; - }; - - services.zfs = { - trim.enable = false; - }; }; } diff --git a/hosts/iron/interfaces.nix b/hosts/iron/interfaces.nix deleted file mode 100644 index dec89ae..0000000 --- a/hosts/iron/interfaces.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ - lan = "br0"; - wan = "enp0s25"; -} diff --git a/hosts/iron/luks-passfile.gpg b/hosts/iron/luks-passfile.gpg deleted file mode 100644 index 96c9903..0000000 Binary files a/hosts/iron/luks-passfile.gpg and /dev/null differ diff --git a/hosts/iron/ports.nix b/hosts/iron/ports.nix index 7a60b1f..9ec9ba2 100644 --- a/hosts/iron/ports.nix +++ b/hosts/iron/ports.nix @@ -1,35 +1,22 @@ -{ custom-utils, ... }: +{ lib, custom-utils, ... }: -{ - config.networking.ports = custom-utils.validatePortAttrset { - calibre-server.tcp = 8081; - calibre-web.tcp = 8082; - esphome.tcp = 6052; - grafana.tcp = 3001; - home-assistant.tcp = 8123; - jellyfin.tcp = 8096; - matrix-synapse.tcp = 8008; - mautrix-signal.tcp = 29319; - mautrix-whatsapp.tcp = 29318; - mqtt.tcp = 1883; - navidrome.tcp = 4533; - nginx-http.tcp = 80; - nginx-https.tcp = 443; - photoprism.tcp = 2342; - postfix-relay.tcp = 25; - postfix-submission.tcp = 465; - prometheus-vodafone-station-exporter.tcp = 9420; - qbittorrent-torrent.tcp = 59832; - qbittorrent-webui.tcp = 8099; - radicale.tcp = 5232; - rmfakecloud.tcp = 3000; - snapserver.tcp = 1704; - snapserverHttp.tcp = 1780; - snapserverTcp.tcp = 1705; - tvproxy.tcp = 64321; - unifi-http.tcp = 8080; - unifi-https.tcp = 8443; - wireguard-esphome.udp = 51001; - wireguard-public-ip-tunnel.udp = 51000; - }; +custom-utils.validatePortAttrset { + esphome.tcp = 6052; + home-assistant.tcp = 8123; + jellyfin.tcp = 8096; + matrix-synapse.tcp = 8008; + mautrix-signal.tcp = 29319; + mautrix-whatsapp.tcp = 29318; + navidrome.tcp = 4533; + nginx-http.tcp = 80; + nginx-https.tcp = 443; + postfix-relay.tcp = 25; + postfix-submission.tcp = [ 465 587 ]; + qbittorrent-torrent.tcp = 59832; + qbittorrent-webui.tcp = 8099; + radicale.tcp = 5232; + rmfakecloud.tcp = 3000; + snapserver.tcp = 1705; + unifi.tcp = 8443; + wireguard-public-ip-tunnel.udp = 51000; } diff --git a/hosts/iron/secrets.yaml b/hosts/iron/secrets.yaml index 3a51f2f..a8cddef 100644 --- a/hosts/iron/secrets.yaml +++ b/hosts/iron/secrets.yaml @@ -1,54 +1,43 @@ duckdns-secret: ENC[AES256_GCM,data:SAf/xZ28tgmvqcVKC2tMNRm838AVMMNCC3fpYLXBEIoTl7E7,iv:+KTEpNMj0+aVCGKB1dRFFslgjpBhSzBZFdee+VIAt4o=,tag:C/eSyoQjAgD7Qv4J4jsp4g==,type:str] -calibre-htpasswd: ENC[AES256_GCM,data:+WW5A3/GZIk0p5CJ8RnK/gcYpJIXXsfrCpqFUWz2PzFZwf5xOlUeTGxqZdNorKq5xip4sT3/brrG4mqGDJ7iXfXJ,iv:D7CqUlbX4XGuUhjRLKytgvLa+jF4zuTZGV1NZCehf8Y=,tag:TAjSyBCIMZC4LBm0Q/2aXQ==,type:str] -radicale-htpasswd: ENC[AES256_GCM,data:Q0WnleP9I4xozsL/H+5oV3Ag7khfalV40A6ub+DA07U8UKna3/ju533RmjWOnETzSNa6XK140nfCcfGZCiqGyF9tfuuXcKFu+j4=,iv:87PSvHyKF7QUQZmEuxM+IT0VKSGnS0MjoUmCqJ+6tzI=,tag:yrP3TgxE8aSZf0MrCF9dsQ==,type:str] sturzbach-htpasswd: ENC[AES256_GCM,data:qqBwu6mASnRqjy65knU4uIvBNXXgrfcmvWnbmOH4tVQ7vRbpEhe/GQDwAg==,iv:OQnDOzezjajGl35m/u5StQeMRR+1sNDD5u1my1wTngQ=,tag:7zjVRWI1IzZ5iS3sFHLubg==,type:str] navidrome-password-encryption-key: ENC[AES256_GCM,data:ynQsFyGDEBnlWhTlv0mF7mLiXOjijq9ixWWEa1OXsTOYAd74dU0dp3Fo532WtD4fPvIWEf8Y2dYmY7zPVLuydQ==,iv:GJqPVL5OIFPLMcCVOjWvMjyFR4iTXo3uGE8R0keTzG0=,tag:RTERQgYRxBBevlL2H1lIWA==,type:str] wireguard_key_hetzner-ha: ENC[AES256_GCM,data:ak/KpQIHBNRPriJ1IeKYXIp4CcnygRHSj5MzZNnuxQnVunmmtzGu0lBEajA=,iv:aNw3EooT6XE1zC+g37WSJasRCfnNUaKQrYCDBMTxRrg=,tag:KXc70tVFc7xDLlefk1Hzow==,type:str] -wireguard_key: - esphome: ENC[AES256_GCM,data:sMA/a0YsS/9ReJDY6gpIw+nTjkMyhs3GyEy6nA3Fiw2mvBdZCyNg0q8tdy4=,iv:WPVk4BlY7eKTjLuT/Li0oRhA9N16WFBnuuGKFjHIhLQ=,tag:0x3+3+ts2zMg2Q4eqySNnA==,type:str] +hetzner-api-key: ENC[AES256_GCM,data:7eWYncujkEytQzhRdNRItPgpz1eUvcyp2PVLJtHbqd8=,iv:AxoKJUuor32kC3ZdpkDPUEUlPRosY6cKoWx0TIGK9wA=,tag:SVtXMraGxnJnx/j3zMQnQw==,type:str] rspamd-worker-controller: ENC[AES256_GCM,data:7tS8bEr9i5F+YZoj3uPQa6Xd2SCsuC+jE531AbKEmPHNeL3qMyO0pQZ/P1ONaPHTVMOPQHYABihDJcZv0BKW,iv:pFBVi4F661fnYPcCPwuetiGL1H+RAnJiFQhTUqGNwjU=,tag:xQoHIEQpnrMOnXqsH8anxQ==,type:str] dkim-keys: jalr.de.default: ENC[AES256_GCM,data:mnApsYKXYGtUAHddccmNmU9yZQtekDkTiTXbJ0UJxC0rFxzQCtGsinQslIROJdNUxsxciR1ilNzxawzjJD7AaWJbcAq2TYObGJJOQZBif7t/XEN/rIxEmnAFmdeAyrSONmFb9DiEn59m6DpsU+/9Y+hnc/uwwbzueO34WHJnTqmmsxFVNQZfGR+cbSckHS3wZrfjZSKKzCRt+9DU/xxJ4voyowXLO77w00LHVkyU5liwONi0v2XJ+QeP/jIMmJeKjujZcH+qvUm/kukijqyWKGrZoAYPC2cBlL/UrNECuVdSLMXvr4KBDDTCRZCSMRgUPJ0TAfpQPTPitKJ/0igK7qQl9n/6hckY7VyP8KDS7J7G2Z2XVxfZrAR4X/7ya9B2kneVr2CNx3w954EdTcV1/lD7rcKRjKynyl3ddf8gxJFJ21k1ybo2RLnftGCRVq25qNwhyfjU8x5c7AEs+YTPDrcnmxZ/Ui276eLwpMj61oZzTp8QQhiBVwS/+ruRLC+78pu2gb1gBF/Oo3nuvQD1SOpCRikLVewCYDvfXj/hrjo+oCsjTOj+9tWRcRAEDVlhkXWCMuPXDYrdt3HrIWbQuP8NW1ezd1Ll0r1ujjtPJeSwdd8cVcUSBIoA5gU+eXnYjFaSx9BZ+sIfKqG//W3S+aBYDqAEK/z4N5q66sReb5mtSQYfbZuIZDmox9bwNMG3tJmQX0lJZgEIiuJ5/ef4ra0sj9JsRFldmIn9KUmjW9OlIwzQ42cNNvQSMD/6haNiYsE6TPzVylJ/B2kNu9Qh5FfpCIPtVORv2BAGoNvZlyhjyEiXBEZ4x2hx1l5cBwGOaGhoJ0p+1wqn2zDalIBaEFjbBVdIB6DPC6/lccvpqSwF7HvW2ugyYhW+u92vgic71/BsI4i0OlsJV18gU/zVg0Yj8SK69kEwm4wkJTrkM/I4+kkUIc5OiSAknRfjOFJc0etkh3nO34xpHLOkSv9DrKfXSAGmGZtCLtVL5LGdZeCd/g6EK0JJh6bd9Gu9koSJVq5vjdDJJFf+sgk39TCvHAvk8k1/FgdK5jMJ+pR8heJtP8G96ay3DFVm5hpbjuNKqfBvbf2rkyV6++ywRFnAQGPUiMn9g6Q4F5Ks7CC1D0Ubl7b3dCUk6BDi8rHjxy9QS0/25Yz9cF0bFd6XQDfblnyRLMi9aB36M9Vp38Oh5aB16MyvNUHzcxpaAak0yknE6OuuEMBPQZgFVADCITfy9eUXl2FoXrMWEnBO78GybQ+cV8nhynn5t0U+3koMy2E8ju5kiEofQxXylys3Q76iKRRUbQqFkh/ndWtJVVfGNpi1GrUr1w1YZM0hBY9FqqeBjf7ckj+9BdiwWJ0XauuR70o7odm02mydk1/T3Hfzt3OE5nHIXnVbum9KyPx8wXj9qc6JGFm558pQOcRUgGUi+EzGoGckkoLx4Onl+XeGysW5sXP9dbYgMBug0Tjmdo9xkoBti6znDnN/zh93bbzWITNvxMgVs8zSWEhlM0c7F02UeUXSekbTFue5FOaMdYObMvPeb53jAKBOYLr34GVFvucJhKajIaNzDvfiI6fGCMxcSsWk+P3co7gdbRlWYZELsKDu2scktZsHr/gRwRiDZXAWOLiWZL4jswQ1vXSFXJgdblEV//hr2DwsAtCAsyFcgO/LGq30xi3xNqHTkUZXo6cZYSb6EVaIywMCI5ySEnTLAp/xedySANHuo8yyVqyLxkDPI7CnnSS7JcnQF3K5z+NZ0KnIpc1ewGupOhS0fKj31XxUkoSsHEY/iWJPLNA8+4VsBkADnGdkYXHTvy/yAGV6w1k1qtjiWhDAGcE9/o6NOHctYm3cx8CVsLpve/WFUaCkGgjWJdC8XP92xsUQoE6PENn6ZzFaqGHs7hgQqE1kBcEj8N5WkEqkoMo82giHE33iYoVUdkjOTkV4iDGEqyjg1BoM0GedR2A832LseDkP7u4DjIAQfpIDu7PaeiDh7xWkPRwIMV0oDTakXTdPkPGdgFikzTaxkTzRlpCbQuV769eITqVT04kJDp7+0Rb6dtjeXc0Ennv68wZSiyrlmXbrJntg7g1wrebq28q9NMIZETAPugfK6wNDu/Iw1q1kZn2ELo6xaDlcIxHDcpzK7e2VAYYuP1k3sYnSLU3oeq54j3/yS2z1me5FEqWlPOCrjdnLkE3/GjbeMsYo2YTYJEUEd2ncacSCoXUaUoxpBnjRYcHLRUV+6jy7Amp0/52rAPzSeVlBzc+SdNiKLYA2UQ74WrMU596Gkhw1SD8jSM5QqSBhH9sL+oE4GjhjLhstMUPdkNgiwxXDTZLKcIyjN1cn+RSmvNA2KXMH6MoXrkqSkJ9u2s0QAhla51zR/LZwWbzwGOO0dkh3rwh2x+pcCfuzvlk3lYr/x5XOF2k1n8yvehXY5zIX8nk6djjLbvAzzSr/yalS7R0WYIc6CjzoUl3qz+PlneMfKHcaX00hkOlIub/ZFQf1RE+JzZxi0qQq4M8Nt1XRKGDeS448Z6znDpedStUH29krZcnjMtyLmPX7ETTsjr3HLpCOd7MQ2K1rfhmvh5BtJkn1KSUf94puZbkLH7X+WnWN0hsc+KbSXnYZvqwJ8G0/7ptp/Q+wGljqhjv+HhOeA3NUwANv1xWgbiymVIlxCodXtQwn8mxS+jxSvslGwOnyUkTT76IbFbv/IpW6PNvj/xqwOqey8a/4WCGcqs403Y7TKQ+xCflG6K3tL7U5UbMnMgXTeZvoK+DooS2eIepF2WB5XqTuOZJV2OQ6GHfaBMjXN9iGVNLi6XgkbpmcMLQ4TZq+dVmgleJb14IaTFD3n74OfmbcT9lmRfPRJEpFEMNeL3ghH54P2a91zJFASgE7x+Uv2cGcmKFtMbyc/rrhH1F/Ixlv/R37huFo1T2dPMEZ/1ouuPpbUQ5oz/JlOWw3NOxd0O6oG0x9Xib+9KxSFOusLWcFEgx70jrBQKj8s2Jj+W0gZYv+BJtPMPY0KAkRj1amt4Fd6ZrPOEXJ392EHSAEv5jssO5ba52OHKA+QkYvPPL04rwkxSAQiTl57scnEj2WEIP+Lz0/qsMnwF+3rWuz856doJZcXX+U9iuzBCaYQqA1P3BojAYhEHnXBPeolHOA3BmhT9E2TJsZ6P9SQ+GaqyLm0i4vRXGlArlkLwRBs9EZv/l4DT8q0YHha53O4rhRzGJZKAOO252Dpha1YN7+FubYGAZjaUT5O0R/7xSPrGyBejddtM8asW8+NClAn4Y6xvj1IgUg6VRpEy7ZIpZEQ+UyDWt0A4nsipaz2NyZKZ5Vxza2v1qZDdYODK8nm/zj7fR/JykaNVEVj7ceTSHdaQlajfeEWWTs92msIBcqPUXqlaR005hoVvXm+WCnzIMIXLGiyRKRsAPIDYh2hGCtvfXLSq5TYm3bnGAImL0KW3Yllt1qSqSbOYsvm5QfDmTrrccvtSLGRj0rOU3Z8f4WXjf+1YgxjZ9h8fKL+LKA8x1S6M8fl0JVGBIAU8Xe8c4+r2F1VcygJp7h+0v8o8GudM6in4djAdeMLWBgXid7r0q744joFucP56opwYQp3Lu0oFEo0omS6Rh9yPfOjdGBU2eUdjcCNXXuEJD9yHSyebviSAvDw/KH1AxYSWYnjMWACCfcbOlXf3ej7PuQgq5MdFwF7+QawXm0john4YusUon4/0fqd/IFLd6oHYYesxcFdm1jN6DeS4SAqRgeEPuEWDFERgXjLHBxl5Xdi5n+NOR3Vc7ziJ9j9/CA1DKdwmsFBBDcVKMnr2FibXpN5WsSdlBng0L2zhkL22wRH9xbz8Xk5shN20/EHoxHB5HJvwfOgHIC7ooWKOUUuNTZH43+gVN+wzRzlMfiF4X71Edw+lTnQRp6Lh03M2k9do6JPoX2+UU0h6mOYiAFkhHKzCmK3DY12c4Smx+qLJNbUGhoMgthu/WnXObm0Hr+myCooTYSVNTJx6vVjI3GZtMcat2o8B9k38u/Y5/FxqTYmyXhROwS4v3W5fXwTAaxBqQy6Xj5s4V37omBBh/Z9a43nc2VlT7dKR1wIvNB/gqhiYyYrVMtYMJqGLkeCbu50LUWT4qXyR8uaqbZTVjyJCQRxZd6fd3Zfe9wIeYe3N5qKIXkFD3n1U2Q/EyRfb3TpiA+eYkAtl6JGK0vpeWpN5M2LJ3/V79e3cIG7B7/p6BrRxKxHDnBZcu57KKaN8XM+v2KTz7XdF8bjgeu1V/B9WoBwnpzCM+3s5ffNceuUcb2gJgRAUpZvcSDLYy+9aluGU2Tvsm49fCzr851p3VSEJepgPpnvuq874AX/MbPvqidF8Y21Kss1RUbl5wrlq5IihKdM+xCSq6mjvtSPVHRvw==,iv:2NBiTTW9slOH9BvM+kVbMB/+8EiS/Dc/eaqrtiwn4HY=,tag:0rc2+ZWy9XZYE7RK/oSo3g==,type:str] +radicale-htpasswd: ENC[AES256_GCM,data:Q0WnleP9I4xozsL/H+5oV3Ag7khfalV40A6ub+DA07U8UKna3/ju533RmjWOnETzSNa6XK140nfCcfGZCiqGyF9tfuuXcKFu+j4=,iv:87PSvHyKF7QUQZmEuxM+IT0VKSGnS0MjoUmCqJ+6tzI=,tag:yrP3TgxE8aSZf0MrCF9dsQ==,type:str] synapse-turn-shared-secret: ENC[AES256_GCM,data:Q1XRds3Zud1kYkvD6s9WUzP+kNDNsxB5SHd6oCAaLCHhHhYENSAYTZOF+rGjCPNyKFL0e/A=,iv:zScRQrz+pXHNUh/BGOaV+TVnDR3wu1Z/UO1zXarKwtA=,tag:ckpVziE+yb0FjctcT7tAkg==,type:str] rmfakecloud: ENC[AES256_GCM,data:ktKBKb6cRv1VF8tRvXIpxIy9hPinVPKK05mgvYzz18PEdcrCLpldm5xf7ffHtY5XzDOAMXDCiz6x4xyv7071frrF0spOEPnIzVhxwG8H2Ck=,iv:qJdHjv0RziAs4G9UGeRwGQ4GE5kaObJWpIYWpRKhr9c=,tag:PXgvU1hZK/gvWGyFJaHekg==,type:str] -esphome: ENC[AES256_GCM,data:SPZ/4GqNuz3Lk0Jor815jWaw9YYiIS/u79qmdjd9eNhPUiT4PpM7gQJHLwa/KHbjYAHBICVd5dAFdBsZ5UsYww6bTZcEjM+aDcSXvrXE7NKUdYwrKfOeGdsIX/l79AlNfaPma1+3dDULj6/5ElXZJFsuurMWaWc+KLOUTBTMNRwylW1pxShywz40wqxtTQmFBLhIbk/yYLfJMuFaPnctoJnW6cutbzw/fwSitAvYEq9Ch2ZOkujOOTP/NlDAsxxBV6tFJj7UnJtGJ9lucJ7BURU0eb3Bp3K3ef1XgiyTtp0g4m2EdN/XTzzA6fI4/Vhf6giDvrbXxSM5pPTbY4fjv5cpKROaHS58il24OA0S7zccFY8XoXkl2QjiJrNnsJvNrfxn21i+LFWKCC1CMZbfEMkg+FNjzrp6nkr/kpjOlEet7umhlkxXdEUSjUBmb7luig55ICSxCH5yzRD8TwsP4fhjQgAQ8C+5fojQ/YH3VkFboY4sS5mkamDeUJ94pLy3GcfKPB5I/qipi5kUxEo7AvvxK2PHNM/0VC3S/23StQwkrH2+mrU5mo4+ngutoxyegSaqJzMJZ6KORPbDo9ETxehwWGZTuP+kpjT8Sz3J0A1LxCZwQsbXJMpABWkg2c3URJZYS/1q1o+16PocE9mbPthiayrBETss6zsYB7xYjaRMN74C1yuEL/55xRqqlrNgfk/svW4XTNRl+zkRfyxz1awWEa4zSpbqSTZT5M97uxuSHwWW64dOb7lCxfVZtpBuEMTN2iITUYWfNnyv3Ipgv2AN3vZUoYiehS8Vlv+j0SHrTAjLqUv/opTNB02PMpE9wWKsOiktDQ6VwbPkd/k9xCPqdaT4fN/yinji+91BkgeaNgyu3KRTnaQlFOxmYzQAoPHwhZSwT+s0/rOPP4wtKIUkI2IcMjEWd8nw0PEo9J/wqzZxcFZ8VKSJofrVMmo0nQF4BK0/86KXOTk2bo/5HaXE4d2s6xc3qhyGnWdWUjm1X8CLoVNx49EsVRhrJKkqrvgFH0P26qNno4m7KWtzZGt/e/e3B4+TeaVgFS5o7IY8hcnIslsbic9DW/rSAxkXdumgvumRHHtBf0WA89K84/Qhs0Ufx4z9ijZdojqTX4rRPpIpV79jaJmjS72adUjnVWMMdQWyW7Y7e0Cp0u7dcbhl1T2S8QRMsJiIOv8syiUFEy8krC7R8Lf7/kZca1MYohEud/QeNsIWq0FfpyYN/vGMoTZ0Hn5npuXap5HVlmSoPX8Bve+tgR3ZFBpTS+/uXhJ70v93IXBt0fWe5tNl518Di8k5h6xAp/8Rl9EJdUuKjVnpto8bO8LIefOQLpeTo282ykPlqxsaEimeasExNAMyi/dzX9SKuSr9D5zKzU8/0zhUA+lhKtwkUkBuxeaeqF1mlffWyjVhL/3/il9Xd7kTT461889AOKt20BH1rzqVQcUiLgoi79r4kIDs2MJE8QU+Ne3fcaP+DCvjjfiTGQ+0icZvVmgKYRpJaD7MsQWN0LvzoqbkIlXrSJprsDt9JNX4IOp6egh5bxAMwZM2V7uCF/WRDXSlHYa6XJId6fY7PMAhDsTYuD4/glFzeD121yajoeyb71AgoKy62mvgExe6nnzh6qNEAQEX8bl+L6sVtwzdYpvc3j0PXbtbEs7zwncyhphj0EOag0N3E236Ck3fW6EWIKkqg7qTBDdXrCKgv7BKl6aYIDQiaUP2hwlqpegklTRkfOrAP0tOYps9DCKGa+Bm6fK2ekG/b8OCPQdp72PtyNv5vumzaV2L6v+nc/0+5VsjL66CdJ9tvwIR9NxUC6M7pp3gMQMyxW95rj4JxZkW8f8r6EU33rQJtNeeo45Uorp3l466s//GoEmcRNO08VcFJaEdd8rocm9dsexd+0QNN9xQVDOwF+KgJAUJi+Qygvzcy+nVibow2sRUPGai6/rbNBPrVEKjfHck+s794XjVGXPAoAMk7SsNKrjSpvEHws0dnC3Faa3PA8UKZalOzmNi6A1ngK/wn5SAQ/LfXRDY/oTJa4ND/C8vJfzywR8=,iv:3nnHepX48XKuKQzO4zHcGj0VNQR2edmQ2DqvAJi5W6M=,tag:UJHGnWXrwCUgyRMGc16Ntg==,type:str] -home-assistant: ENC[AES256_GCM,data:wcFMxDdRCHf/shO9v2WaGgrsa9J2WP62xFs=,iv:9ckeIO62cFZUo8fPyQj445CrJVTooNlwLapM/oTsrkk=,tag:mlfxtXDPsB3T79P9BX9oJQ==,type:str] -mqtt-users: - home-assistant: ENC[AES256_GCM,data:oIjCw7ZnA5iOBmQdW1jcy3QQnpjT32pY,iv:5HFRkXJBdMXQbjk2ubQs3sEy5qEteiqSe2hrNc8+H40=,tag:7B6yI4oCHanE0JE/gHaKnQ==,type:str] - valetudo: ENC[AES256_GCM,data:+HRz6X+A5dhmx43G99ka0u9VozuzOFWR,iv:SPw5yoiBqN7sBH5EofevacTtu45jmuTPqToKrar0aJ0=,tag:lf+usB/eNNP1yuWW/QyTqQ==,type:str] -photoprism: - oidc-secret: ENC[AES256_GCM,data:XTAiUiGZJfSZHNbz6fePl3iMDdbxFSE7+SQH2ECRFqlo7w8TAhLyNXBxlEfGvu+8vttbKdkEm0r7132Q4ftOtA==,iv:WGsQXolbtRWIq4EDgODWNmkXdOZCsA9A3Fqoo4lJyec=,tag:5zJftwB5If/RZB3hI0Ly8A==,type:str] -prometheus: - exporters: - vodafone-station: ENC[AES256_GCM,data:eaFqYEuK3UU=,iv:BauymCkvj33TmZLyii367uVEc4Iq4GGcik4nbyT9Fpk=,tag:poB+qh5tAdv/dEt3WN6yVw==,type:str] - unpoller: ENC[AES256_GCM,data:WI1oUKHW4ef4pBk+mGM=,iv:C1LykPf1/ypUmy3ZCQzjfSjkpxhUukDNnfJnZLp2CJg=,tag:mSnZJKl9IHcx7I7GpFherw==,type:str] -tvproxy: ENC[AES256_GCM,data:MbXEmgerpUiwDgcUKF2y1+Cc+d43sKPfGGTEkvNoZFFS4rzDWw4Udg==,iv:ZDsfSb3HK008e7/J/61iqVRafIzKbtPEdhH7ixo9lSY=,tag:3JbJ+2DJKQ9G2ui6VuWbOw==,type:str] -grafana: - secret-key: ENC[AES256_GCM,data:RX0ox0r3Jwm9DMIfBnsL7ydarlrYSVBjbVXbooHR1Ms=,iv:l8Aud8VyGtz3dNARh6s8/Y6MBtc4xj1Wu/LLJv1e+KA=,tag:+7TFyRPhBS1Tvn2JLBEeAQ==,type:str] +esphome: ENC[AES256_GCM,data:u8fNhi3J2wEJ6uxYT5LfYzktnmhTuHX4Tundu8iPxstFHkk7eF4HjlZi7KWmSZSFNqZqCRQ/Kksmtylc5LxGvVUAgwr4fUu9qBns3UbwwdrOrenefrcDZDq2Z2VjNtIHK2CbmqmDoodZy7JWgezY8ZzEjqcpv+btZ/91+ApM/5Q81gxcbFWMmurOp/yl0LSaCVu4sE7L60IstZisJMtmJ/YTY6KYop6TMuwUUDwVa5kgqzxLJWc0MEDt7rSutqVd7ryGzacvcaC4HcOcbVHVNc5tCqELBxExV4zd56rK2RLfBtDJVX7S3h+deWmNg6IMnPkAtgaer0QT8x4BIhbj8r7S2lcWDF1r1V2aZQ33mXbiuMlDVdmHliMnKpY+QIVLLtC0xNofRKixD+S1zmsjqQTJaMZO76dk8dRrZ+mnDPjDdLjT6687YPOeRuIAzLYhJrgyvQdE+SBgx0B71L/Q0Jp2joO4esx0iWwa8A6h8WZMulO1CGQpRfhI5GABz/sJtSm1pkZbxHJnhKXxAV3KiAP3RH673xkdo3Wmn1Q7RsOVsogXodYd4klmSgAszvF0eBl/pazCgfErI6ReNIr7cUGYd82Ub0gveSvPzqCPGJMkxwZ51QOUKI/pvw4pywolpH1JN5edPfoepVvbrrk/TD8X0Dd6YKOWuzjZ8LsuM1znqywwGh5BGvWzSpK1JZcYJG4Na5LFHgniyOuL6y6aANXSW6TBuehNwNEHkbm2GOjpxy3Ml5nWwQLkkD2wEdSU0/MW23rr6cOVUOrYiZvxip8l5Nf5Cl/JTLGaepRJaMBkTZj4G5x+r4zqOTBsbcEG8eiPAZG5uIxxVYo=,iv:U1srWrPW11lz/UYFW7Z9apla+ShH7W/QzDiw+evfcXg=,tag:1dxPp+m2O6xSyAZEsSf0dw==,type:str] sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] age: - recipient: age1hx7fdu4mcha7kkxe7yevtvs6xgzgaafgenm3drhvr609wlj94sgqm497je enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZSnhmN0RTMDcxR3hWMWFq - TjZNNHEzM214Tm9hK2RENm9hSlRFUy9aNW5FCm1paEx2TEEzcEd6cVIzaDk1Sk92 - NXNORGlONHQ1Uk9ocGlScXFIWmlwUDAKLS0tIDhTeDQ1KzhreEpMVFVvbFdiRjVR - SU1USkxFUUY2NVhmUHBhZkdrNDR1Q0kKiXIicInELRjDR3tuyA+lnXeCcd9lYvbV - GnBRGPM7BNO/6AA7HhAei48Kt+XE6+jQX66yTXyviKhK7Lpjrlb2YQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsdnRlZktJNHQwSWdlb2l6 + aFNRS3U0UHM5UFVkTUtqMHU1Y093ZjdNMUhrCmZVMlBNSTlwYjlQaklzZENnR013 + UXFNaWp3WXhQOC81dGFFQXNwVHVYajAKLS0tIGh5ek95NnNRbWFsVkRncFJ3VUdE + TjdZRldhSzVtMkVoTzY1NjdGbCswRVUK0pi+8UuLqRmytcR2ikxOAM02iccl8P1y + ixv0PKPLd+vQ23QeeQy/TfoGx16XttaDUnUrPLZR3TUKtAcld8+m6w== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-11-04T17:52:25Z" - mac: ENC[AES256_GCM,data:/q98uwoYJsPRLlWxxDn7gJQ0jRxlAfVxEmUw8ayP8gIkWzGN1DCR0jx2LFlSlWEuaPScThw5IhGxbBlBxX2wV952MC7tEoHAAMvMJberG1a6do8zSvotDHocdXVlyj4jJZhQvjUVAmeVsYBY3oRwOHdzis0JO5IW0hxgs3x+xoQ=,iv:9BR0ws9ZzukjxLpPjvl73B3RmLA+c9e7F3AVk5l0SGc=,tag:OJ/iGy/Umlj/82EtZxjLSg==,type:str] + lastmodified: "2024-01-12T02:04:19Z" + mac: ENC[AES256_GCM,data:pXHs+ucPNr+v/x3R2Jb+1zxnHdAeSneT+6lt20eLhjvcMQIFckYXFxc0eOMnV00jTWb+vyz6g5zHsg9+kv+xm/xBHozw9sRJi01Ni+AR/ZLSbVDa6NiMyu536MrA1TeD3iZrxgmpDTuxsChdETz0mmPyEPOMT29seWYlhzI/++o=,iv:2guaerRyQj6qz9Dyo2HbC/dXUA6cuAA+yuDwbUDCcK8=,tag:HcVT4KdLCyjwtWP24JVfhg==,type:str] pgp: - - created_at: "2024-01-31T01:20:30Z" - enc: |- + - created_at: "2023-05-02T19:30:42Z" + enc: | -----BEGIN PGP MESSAGE----- - hF4DY/xpNY5WhB0SAQdAVIYE8wlQqo3HcaT37fSDHQ5i0CxUv9kyPT9BiDgwxA4w - hJlT2XPeSK6Ob1P++oGUrVhkZCuFEnV+6ZtNjwIu9EfU6azyPZEcmffmi3PdlSvW - 0l4BHCRW14iBbixIlZxloBUEEMCg5n5HNQ5vB4jRyq4af0uYxOgE3doZbb5gaVe2 - sODYeeb0u1DdJRlvfyPgqPvit4tkovzLKsO/RUpHqTuh8cXHA8ibLIXlIUbS7FoN - =aGjt + hF4D3ylLYNOsO+0SAQdA16evFPF5J4wB4iw3y6rQbjpyVKiU/M7qZmdsKOBpLQgw + CccmnhDpRDvQ2pTlHh674o0flfXTvFQ2H2a7KuVDLerdUuw+aBGD1RB+Ob0Vvfoi + 0l4BKpYchtdJQpQuL2Gy5LToty9EZUVVRvhyIfSasWCdDH9ajNWHFcKn6MX9wj46 + ly6CeFgZKAyyeQ6qWQnft7inEQk7krl53NBrbzDN3Rfz71zmpO97h/av7y7ilffa + =DpnU -----END PGP MESSAGE----- - fp: 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 + fp: 66FB54F6081375106EEBF651A222365EB448F934 unencrypted_suffix: _unencrypted - version: 3.11.0 + version: 3.8.1 diff --git a/hosts/iron/secrets/mail-users.nix b/hosts/iron/secrets/mail-users.nix index bc181b7..4caac02 100644 Binary files a/hosts/iron/secrets/mail-users.nix and b/hosts/iron/secrets/mail-users.nix differ diff --git a/hosts/iron/services/avahi.nix b/hosts/iron/services/avahi.nix deleted file mode 100644 index f15827b..0000000 --- a/hosts/iron/services/avahi.nix +++ /dev/null @@ -1,20 +0,0 @@ -let - interfaces = import ../interfaces.nix; -in -{ - services.avahi = { - enable = true; - allowInterfaces = [ interfaces.lan ]; - openFirewall = false; - publish = { - domain = true; - enable = true; - userServices = true; - workstation = true; - }; - }; - - networking.firewall.interfaces."${interfaces.lan}".allowedUDPPorts = [ - 5353 - ]; -} diff --git a/hosts/iron/services/calibre.nix b/hosts/iron/services/calibre.nix deleted file mode 100644 index 816da0b..0000000 --- a/hosts/iron/services/calibre.nix +++ /dev/null @@ -1,94 +0,0 @@ -{ lib, config, ... }: -let - inherit (config.networking) ports; -in -{ - sops.secrets.calibre-htpasswd.owner = "nginx"; - - services = { - calibre-server = { - enable = true; - port = ports.calibre-server.tcp; - host = "127.0.0.1"; - }; - - calibre-web = { - enable = true; - inherit (config.services.calibre-server) user; - inherit (config.services.calibre-server) group; - listen = { - ip = "127.0.0.1"; - port = ports.calibre-web.tcp; - }; - options = { - enableBookUploading = true; - reverseProxyAuth = { - enable = true; - header = "X-Remote-User"; - }; - }; - }; - }; - - systemd.services.calibre-web = { - serviceConfig = { - BindPaths = [ - "/var/lib/calibre-web" - "/var/lib/calibre-server" - ]; - BindReadOnlyPaths = [ - "/nix/store" - ]; - CapabilityBoundingSet = ""; - IPAddressAllow = "localhost"; - IPAddressDeny = "any"; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = lib.mkForce true; - PrivateTmp = true; - PrivateUsers = true; - ProcSubset = "pid"; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "noaccess"; - ProtectSystem = "strict"; - ReadWritePaths = ""; - RemoveIPC = true; - RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - RootDirectory = "/run/calibre-web"; - RuntimeDirectory = "calibre-web"; - StateDirectory = "calibre-web"; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service" - "~@privileged" - ]; - WorkingDirectory = "/var/lib/calibre-web"; - }; - }; - - - services.nginx.virtualHosts."books.jalr.de" = { - enableACME = true; - forceSSL = true; - kTLS = true; - basicAuthFile = config.sops.secrets.calibre-htpasswd.path; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString ports.calibre-web.tcp}/"; - recommendedProxySettings = true; - extraConfig = '' - client_max_body_size 200M; - proxy_set_header X-Remote-User $remote_user; - ''; - }; - }; -} diff --git a/hosts/iron/services/default.nix b/hosts/iron/services/default.nix index 29cd267..f5cddc8 100644 --- a/hosts/iron/services/default.nix +++ b/hosts/iron/services/default.nix @@ -1,29 +1,20 @@ { imports = [ - ./avahi.nix - ./calibre.nix ./dnsmasq.nix ./dyndns.nix ./esphome - ./grafana.nix ./home-assistant.nix - ./jellyfin + ./jellyfin.nix ./mail.nix ./matrix.nix ./navidrome.nix ./nginx.nix ./ntp.nix - ./photoprism.nix - ./prometheus.nix ./public-ip-tunnel.nix ./radicale.nix ./remarkable.nix - ./snapcast + ./snapserver.nix ./sturzbach.nix - ./tts.nix - ./tvproxy.nix - ./unifi-controller - ./whatsapp.nix - ./wireguard-esphome.nix + ./unifi-controller.nix ]; } diff --git a/hosts/iron/services/dnsmasq.nix b/hosts/iron/services/dnsmasq.nix index 72b5f61..3233865 100644 --- a/hosts/iron/services/dnsmasq.nix +++ b/hosts/iron/services/dnsmasq.nix @@ -1,13 +1,12 @@ -{ lib, pkgs, ... }: +{ pkgs, ... }: let - interfaces = import ../interfaces.nix; + stateDir = "/var/lib/dnsmasq"; in { services.dnsmasq = { enable = true; settings = { - bind-interfaces = true; listen-address = [ "192.168.42.1" "10.20.0.1" @@ -20,35 +19,24 @@ in ]; dhcp-range = [ "192.168.42.20,192.168.42.254,4h" - "10.20.1.1,10.20.3.254,12h" + "10.20.0.20,10.20.3.254,12h" ]; cache-size = 10000; dns-forward-max = 1000; no-hosts = true; addn-hosts = "${pkgs.writeText "hosts.dnsmasq" '' 192.168.42.1 aluminium unifi - 10.20.0.10 kuechentisch.iot.bw.jalr.de - 10.20.0.11 led-panel-schreibtisch.iot.bw.jalr.de ''}"; server = [ "142.250.185.78" # dns.as250.net "2001:470:20::2" # ordns.he.net "74.82.42.42" # ordns.he.net ]; - dhcp-option = [ - "option:ntp-server,192.168.42.1" - ]; }; }; - networking.firewall.interfaces = lib.attrsets.genAttrs [ - interfaces.lan - "iot" - ] - ( - _: { - allowedUDPPorts = [ 53 67 ]; - allowedTCPPorts = [ 53 ]; - } - ); + networking.firewall = { + allowedUDPPorts = [ 53 67 ]; + allowedTCPPorts = [ 53 ]; + }; } diff --git a/hosts/iron/services/dyndns.nix b/hosts/iron/services/dyndns.nix index e53e235..9b4aebf 100644 --- a/hosts/iron/services/dyndns.nix +++ b/hosts/iron/services/dyndns.nix @@ -1,56 +1,17 @@ -{ config, lib, pkgs, ... }: -let - interfaces = import ../interfaces.nix; - - mkService = config: - lib.mapAttrs' - (name: cfg: lib.nameValuePair "godns-${name}" ( - let - config = cfg.settings // { - login_token_file = "$CREDENTIALS_DIRECTORY/login_token"; - }; - configFile = (pkgs.formats.yaml { }).generate "config.yaml" config; - in - { - description = "GoDNS service"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - serviceConfig = { - DynamicUser = true; - ExecStart = "${lib.getExe pkgs.godns} -c ${configFile}"; - LoadCredential = "login_token:${cfg.tokenPath}"; - Restart = "always"; - RestartSec = "2s"; - }; - } - )) - config; -in +{ config, ... }: { - systemd.services = mkService { - ip4 = { - tokenPath = config.sops.secrets.duckdns-secret.path; - settings = { - provider = "DuckDNS"; - domains = [{ domain_name = "www.duckdns.org"; sub_domains = [ "jalr-bw" ]; }]; - resolver = "8.8.8.8"; - ip_interface = interfaces.wan; - ip_urls = [ "" ]; - ip_type = "IPv4"; - interval = 60; - }; - }; - ip6 = { - tokenPath = config.sops.secrets.duckdns-secret.path; - settings = { - provider = "DuckDNS"; - domains = [{ domain_name = "www.duckdns.org"; sub_domains = [ "jalr-bw" ]; }]; - resolver = "2001:4860:4860::8888"; - ip_interface = interfaces.lan; - ip_urls = [ "" ]; - ip_type = "IPv6"; - interval = 60; - }; - }; + sops.secrets.duckdns-secret = { + sopsFile = ../secrets.yaml; + }; + services.ddclient = { + enable = true; + interval = "1min"; + protocol = "duckdns"; + server = "www.duckdns.org"; + username = "nouser"; + passwordFile = config.sops.secrets.duckdns-secret.path; + domains = [ "jalr-bw" ]; + use = "if, if=enp3s5"; + #usev6=ifv6, ifv6=enp3s4 }; } diff --git a/hosts/iron/services/esphome/default.nix b/hosts/iron/services/esphome/default.nix index 4e63710..05b07d5 100644 --- a/hosts/iron/services/esphome/default.nix +++ b/hosts/iron/services/esphome/default.nix @@ -1,25 +1,73 @@ -{ pkgs -, config -, ... -}: +args@{ lib, pkgs, config, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../../ports.nix args; + cfg = config.services.esphome; + stateDir = "/var/lib/esphome"; + devices = [ + ./yeelight-meteorite.yaml + ]; + cfgdir = pkgs.stdenvNoCC.mkDerivation { + name = "esphome-config"; + src = ./devices; + dontBuild = true; + installPhase = '' + mkdir $out + cp -r * $out + ln -snf "${config.sops.secrets.esphome.path}" "$out/secrets.yaml" + ln -snf "${stateDir}/.esphome" "$out/.esphome" + ln -snf "${stateDir}/.gitignore" "$out/.gitignore" + ''; + }; + esphomeParams = + if cfg.enableUnixSocket + then "--socket /run/esphome/esphome.sock" + else "--address ${cfg.address} --port ${toString cfg.port}"; in { - sops.secrets.esphome.restartUnits = [ config.systemd.services.esphome.name ]; + sops.secrets.esphome = { + sopsFile = ../../secrets.yaml; + owner = "esphome"; + group = "esphome"; + mode = "0400"; + }; - jalr.esphome = { + services.esphome = { enable = true; + address = "127.0.0.1"; port = ports.esphome.tcp; - secretsFile = config.sops.secrets.esphome.path; - configDir = pkgs.stdenvNoCC.mkDerivation { - name = "esphome-config"; - src = ./devices; - dontBuild = true; - installPhase = '' - mkdir $out - cp -r * $out - ''; - }; + /* + package = pkgs.esphome.overrideAttrs (o: o // { + propagatedBuildInputs = (o.propagatedBuildInputs or []) ++ [ + pkgs.gcc + ]; + makeWrapperArgs = [ + # platformio is used in esphomeyaml/platformio_api.py + # esptool is used in esphomeyaml/__main__.py + # git is used in esphomeyaml/writer.py + "--prefix PATH : ${lib.makeBinPath (with pkgs; [ platformio esptool_3 git gcc])}" + "--set ESPHOME_USE_SUBPROCESS ''" + ]; + }); + */ + }; + + systemd.services.esphome.serviceConfig = { + WorkingDirectory = lib.mkForce cfgdir; + ExecStart = lib.mkForce "${cfg.package}/bin/esphome dashboard ${esphomeParams} ${cfgdir}"; + /* + Environment = [ + "NIX_LD=/nix/store/qn3ggz5sf3hkjs2c797xf7nan3amdxmp-glibc-2.38-27/lib/ld-linux-x86-64.so.2" + "NIX_LD_LIBRARY_PATH=/nix/store/myw67gkgayf3s2mniij7zwd79lxy8v0k-gcc-12.3.0-lib/lib" + ]; + */ + }; + + system.activationScripts.esphome-custom = { + deps = [ "users" "groups" ]; + text = '' + mkdir -p "${stateDir}/.esphome" + touch "${stateDir}/.gitignore" + chown esphome:esphome "${stateDir}/.esphome" "${stateDir}/.gitignore" + ''; }; } diff --git a/hosts/iron/services/esphome/devices/.env b/hosts/iron/services/esphome/devices/.env deleted file mode 100644 index 10c24e2..0000000 --- a/hosts/iron/services/esphome/devices/.env +++ /dev/null @@ -1,2 +0,0 @@ -ESPHOME_HOST="jalr-bw.duckdns.org" -ESPHOME_SECRETS_FILE="esphome_${ESPHOME_HOST}_secrets.yaml" diff --git a/hosts/iron/services/esphome/devices/.gitignore b/hosts/iron/services/esphome/devices/.gitignore deleted file mode 100644 index 163bec7..0000000 --- a/hosts/iron/services/esphome/devices/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.esphome/ -/secrets.yaml diff --git a/hosts/iron/services/esphome/devices/badspiegel.yaml b/hosts/iron/services/esphome/devices/badspiegel.yaml deleted file mode 100644 index 7f262ed..0000000 --- a/hosts/iron/services/esphome/devices/badspiegel.yaml +++ /dev/null @@ -1,134 +0,0 @@ -esphome: - name: "badspiegel" - friendly_name: "Badspiegel" - platformio_options: - board_build.flash_mode: dio - on_boot: - then: - - light.turn_on: - id: front_light - brightness: 30% - color_temperature: 2700 K - - light.turn_on: - id: background_light - brightness: 20% - color_temperature: 2700 K - -esp32: - board: az-delivery-devkit-v4 - framework: - type: arduino - version: recommended - platform_version: 5.4.0 - -logger: - -api: - encryption: - key: !secret apikey_badspiegel - -ota: - - platform: esphome - password: !secret otapass_badspiegel - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - power_save_mode: none - enable_on_boot: True - fast_connect: On - output_power: 8.5 - -output: - - platform: ledc - pin: GPIO33 - id: output_background_warm - - platform: ledc - pin: GPIO32 - id: output_background_cold - - platform: ledc - pin: GPIO25 - id: output_front_warm - - platform: ledc - pin: GPIO14 - id: output_front_cold - -light: - - platform: cwww - name: "Background light" - id: background_light - cold_white: output_background_cold - warm_white: output_background_warm - cold_white_color_temperature: 6500 K - warm_white_color_temperature: 2700 K - constant_brightness: true - gamma_correct: 0 - - platform: cwww - name: "Front light" - id: front_light - cold_white: output_front_cold - warm_white: output_front_warm - cold_white_color_temperature: 6500 K - warm_white_color_temperature: 2700 K - constant_brightness: true - gamma_correct: 0 - -switch: - - platform: gpio - name: "Heating" - id: heating - pin: GPIO26 - icon: "mdi:thermometer" - - platform: gpio - name: "Soundsystem" - id: soundsystem - pin: GPIO23 - icon: "mdi:speaker" - -esp32_touch: -# setup_mode: true - - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - - platform: dht - pin: GPIO22 - model: DHT22 - temperature: - name: "Temperatur" - id: temperature - humidity: - name: "Feuchtigkeit" - id: humidity - accuracy_decimals: 1 - update_interval: 30s - -binary_sensor: -# ESP32 touch pins: 4, 13, 27, 32, 33 - # Touch Pad T4 - - platform: esp32_touch - name: "touch pad GPIO13" - pin: GPIO13 - threshold: 902 - on_press: - then: - - light.toggle: - id: front_light - internal: true - filters: - settle: 1s - # Touch Pad T7 - - platform: esp32_touch - name: "touch pad GPIO27" - pin: GPIO27 - threshold: 1086 - on_press: - then: - - light.toggle: - id: background_light - internal: true - filters: - settle: 1s diff --git a/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml b/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml index 88224a9..371d9fe 100644 --- a/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml +++ b/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml @@ -5,11 +5,6 @@ esp8266: logger: -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - bp5758d: data_pin: GPIO4 clock_pin: GPIO5 @@ -19,32 +14,22 @@ output: id: output_ch1 channel: 1 current: 20 - min_power: 0.02 - zero_means_zero: true - platform: bp5758d id: output_ch2 channel: 2 current: 20 - min_power: 0.02 - zero_means_zero: true - platform: bp5758d id: output_ch3 channel: 3 current: 20 - min_power: 0.02 - zero_means_zero: true - platform: bp5758d id: output_ch4 channel: 4 - current: 80 - min_power: 0.02 - zero_means_zero: true + current: 20 - platform: bp5758d id: output_ch5 channel: 5 - current: 80 - min_power: 0.02 - zero_means_zero: true + current: 20 light: - platform: rgbww @@ -57,4 +42,3 @@ light: cold_white: output_ch5 warm_white_color_temperature: 2700 K cold_white_color_temperature: 6500 K - color_interlock: true diff --git a/hosts/iron/services/esphome/devices/eingang-deckenleuchte.yaml b/hosts/iron/services/esphome/devices/eingang-deckenleuchte.yaml index b39f719..b752069 100644 --- a/hosts/iron/services/esphome/devices/eingang-deckenleuchte.yaml +++ b/hosts/iron/services/esphome/devices/eingang-deckenleuchte.yaml @@ -16,8 +16,7 @@ api: key: !secret apikey_eingang_deckenleuchte ota: - - platform: esphome - password: !secret otapass_eingang_deckenleuchte + password: !secret otapass_eingang_deckenleuchte wifi: ssid: !secret wifi_ssid_bw diff --git a/hosts/iron/services/esphome/devices/fussbodenheizung.yaml b/hosts/iron/services/esphome/devices/fussbodenheizung.yaml deleted file mode 100644 index 0e9019a..0000000 --- a/hosts/iron/services/esphome/devices/fussbodenheizung.yaml +++ /dev/null @@ -1,195 +0,0 @@ -esphome: - name: "fussbodenheizung" - friendly_name: "Fußbodenheizung" - -esp8266: - board: d1_mini - framework: - version: recommended - -logger: - -api: - encryption: - key: !secret apikey_fussbodenheizung - -ota: - - platform: esphome - password: !secret otapass_fussbodenheizung - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - enable_on_boot: True - fast_connect: On - -switch: - - platform: gpio - pin: - number: 16 - inverted: true - id: relay_1 - icon: "mdi:electric-switch" - - platform: gpio - pin: - number: 14 - inverted: true - id: relay_2 - icon: "mdi:electric-switch" - - platform: gpio - pin: - number: 12 - inverted: true - id: relay_3 - icon: "mdi:electric-switch" - - platform: gpio - pin: - number: 13 - inverted: true - id: relay_4 - icon: "mdi:electric-switch" - - platform: gpio - pin: - number: 0 - inverted: true - id: relay_5 - icon: "mdi:electric-switch" - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - - platform: dht - model: DHT22 - pin: GPIO2 - temperature: - name: "Temperatur" - id: temperature_local - humidity: - name: "Feuchtigkeit" - id: humidity - accuracy_decimals: 1 - update_interval: 60s - - platform: homeassistant - id: temperature_kitchen - entity_id: sensor.kueche_leiste_temperatur - - platform: homeassistant - id: humidity_kitchen - entity_id: sensor.kueche_leiste_feuchtigkeit - - platform: homeassistant - id: temperature_bathroom - entity_id: sensor.badspiegel_temperatur - - platform: homeassistant - id: humidity_bathroom - entity_id: sensor.badspiegel_feuchtigkeit - - platform: homeassistant - entity_id: sensor.bthome_sensor_e8e8_temperature - id: temperature_bedroom - - platform: homeassistant - entity_id: sensor.bthome_sensor_e8e8_humidity - id: humidity_bedroom - -climate: - - platform: thermostat - name: "Bad" - sensor: temperature_bathroom - humidity_sensor: humidity_bathroom - min_heating_off_time: 1s - min_heating_run_time: 1s - min_idle_time: 30s - heat_action: - - switch.turn_on: relay_1 - idle_action: - - switch.turn_off: relay_1 - default_preset: tag - on_boot_restore_from: memory - preset: - - name: morgens - default_target_temperature_low: 23 °C - - name: tag - default_target_temperature_low: 20 °C - - name: nacht - default_target_temperature_low: 18 °C - - name: abwesend - default_target_temperature_low: 16 °C - - platform: thermostat - name: "Schlafzimmer" - sensor: temperature_bedroom - humidity_sensor: humidity_bedroom - min_heating_off_time: 1s - min_heating_run_time: 1s - min_idle_time: 30s - heat_action: - - switch.turn_on: relay_2 - idle_action: - - switch.turn_off: relay_2 - default_preset: tag - on_boot_restore_from: memory - preset: - - name: tag - default_target_temperature_low: 22 °C - - name: nacht - default_target_temperature_low: 18 °C - - name: abwesend - default_target_temperature_low: 15 °C - - platform: thermostat - name: "West" - sensor: temperature_kitchen - humidity_sensor: humidity_kitchen - min_heating_off_time: 1s - min_heating_run_time: 1s - min_idle_time: 30s - heat_action: - - switch.turn_on: relay_3 - idle_action: - - switch.turn_off: relay_3 - default_preset: tag - on_boot_restore_from: memory - preset: - - name: tag - default_target_temperature_low: 19 °C - - name: nacht - default_target_temperature_low: 17 °C - - name: abwesend - default_target_temperature_low: 16 °C - - platform: thermostat - name: "Mitte" - sensor: temperature_local - humidity_sensor: humidity - min_heating_off_time: 1s - min_heating_run_time: 1s - min_idle_time: 30s - heat_action: - - switch.turn_on: relay_4 - idle_action: - - switch.turn_off: relay_4 - default_preset: tag - on_boot_restore_from: memory - preset: - - name: tag - default_target_temperature_low: 19 °C - - name: nacht - default_target_temperature_low: 17 °C - - name: abwesend - default_target_temperature_low: 16 °C - - platform: thermostat - name: "Ost" - sensor: temperature_local # FIXME - #humidity_sensor: - min_heating_off_time: 1s - min_heating_run_time: 1s - min_idle_time: 30s - heat_action: - - switch.turn_on: relay_5 - idle_action: - - switch.turn_off: relay_5 - default_preset: tag - on_boot_restore_from: memory - preset: - - name: tag - default_target_temperature_low: 21 °C - - name: nacht - default_target_temperature_low: 19 °C - - name: abwesend - default_target_temperature_low: 16 °C diff --git a/hosts/iron/services/esphome/devices/justfile b/hosts/iron/services/esphome/devices/justfile deleted file mode 120000 index 68d1c45..0000000 --- a/hosts/iron/services/esphome/devices/justfile +++ /dev/null @@ -1 +0,0 @@ -../../../../../modules/esphome/devices/justfile \ No newline at end of file diff --git a/hosts/iron/services/esphome/devices/kueche-leiste.yaml b/hosts/iron/services/esphome/devices/kueche-leiste.yaml index 996c412..deaf92d 100644 --- a/hosts/iron/services/esphome/devices/kueche-leiste.yaml +++ b/hosts/iron/services/esphome/devices/kueche-leiste.yaml @@ -5,7 +5,7 @@ esphome: board_build.flash_mode: dio on_boot: then: - - light.control: + - light.turn_on: id: led_light brightness: 50% color_temperature: 2700 K @@ -23,24 +23,16 @@ api: key: !secret apikey_kueche_leiste ota: - - platform: esphome - password: !secret otapass_kueche_leiste + password: !secret otapass_kueche_leiste wifi: ssid: !secret wifi_ssid_bw password: !secret wifi_password_bw domain: .iot.bw.jalr.de + power_save_mode: none enable_on_boot: True fast_connect: On - -esp32_ble_tracker: - scan_parameters: - active: false - -bluetooth_proxy: - active: true - -xiaomi_ble: + output_power: 8.5 output: - platform: ledc @@ -60,57 +52,3 @@ light: warm_white_color_temperature: 2700 K constant_brightness: true gamma_correct: 0 - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - - platform: dht - model: DHT22 - pin: GPIO5 - temperature: - name: "Temperatur" - id: temperature - humidity: - name: "Feuchtigkeit" - id: humidity - accuracy_decimals: 1 - update_interval: 60s - -binary_sensor: - - platform: gpio - pin: - number: GPIO6 - mode: - input: true - pullup: true - inverted: true - name: "Physical Power Button" - on_press: - then: - - light.toggle: - id: led_light - internal: True - -spi: - - id: spi_bus_main - clk_pin: GPIO21 - mosi_pin: GPIO10 - miso_pin: GPIO20 - -pn532_spi: - spi_id: spi_bus_main - # FIXME: GPIO9 is a strapping pin - cs_pin: GPIO9 - update_interval: 1s - on_tag: - then: - - homeassistant.tag_scanned: !lambda 'return x;' - - switch.turn_on: buzzer - - delay: 250ms - - switch.turn_off: buzzer - -switch: - - platform: gpio - pin: GPIO7 - id: buzzer diff --git a/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml b/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml index ceff0b0..a58e7e5 100644 --- a/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml +++ b/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml @@ -1,8 +1,6 @@ esphome: name: "led-panel-schreibtisch" friendly_name: "LED Panel Schreibtisch" - platformio_options: - board_build.flash_mode: dio on_boot: then: - light.turn_on: @@ -16,50 +14,37 @@ api: key: !secret apikey_panel_schreibtisch ota: - - platform: esphome - password: !secret otapass_panel_schreibtisch + password: !secret otapass_panel_schreibtisch wifi: ssid: !secret wifi_ssid_bw password: !secret wifi_password_bw domain: .iot.bw.jalr.de - power_save_mode: none - enable_on_boot: True - fast_connect: true - manual_ip: - static_ip: 10.20.0.11 - gateway: 10.20.0.1 - subnet: 255.255.240.0 - output_power: 8.5 esp32: - board: esp32-c3-devkitm-1 - variant: ESP32C3 + board: wemos_d1_uno32 framework: - type: esp-idf + type: arduino + version: recommended + platform_version: 5.4.0 logger: -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - output: - platform: ledc - pin: GPIO1 + pin: GPIO16 id: output_warm power_supply: power frequency: 2kHz - platform: ledc - pin: GPIO3 + pin: GPIO17 id: output_cold power_supply: power frequency: 2kHz power_supply: - id: power - pin: GPIO0 + pin: GPIO25 enable_time: 0s keep_on_time: 0s diff --git a/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml b/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml deleted file mode 100644 index 4c7af8b..0000000 --- a/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml +++ /dev/null @@ -1,60 +0,0 @@ -esphome: - name: "pflanzenleuchte" - friendly_name: "Pflanzenleuchte" - platformio_options: - board_build.flash_mode: dio - -esp32: - board: esp32-c3-devkitm-1 - variant: ESP32C3 - framework: - type: esp-idf - -logger: - -api: - encryption: - key: !secret apikey_pflanzenleuchte - -ota: - - platform: esphome - password: !secret otapass_pflanzenleuchte - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - enable_on_boot: True - fast_connect: On - output_power: 8.5 - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - -output: - - platform: ledc - pin: GPIO0 - id: output_royal_blue - inverted: true - min_power: 0.25 - zero_means_zero: true - - platform: ledc - pin: GPIO1 - id: output_deep_red - inverted: true - min_power: 0.25 - zero_means_zero: true - -light: - - platform: monochromatic - name: "Royalblau" - id: royal_blue - output: output_royal_blue - gamma_correct: false - - platform: monochromatic - name: "Tiefrot" - id: deep_red - output: output_deep_red - gamma_correct: false diff --git a/hosts/iron/services/esphome/devices/pinspot.yaml b/hosts/iron/services/esphome/devices/pinspot.yaml deleted file mode 100644 index b7adc49..0000000 --- a/hosts/iron/services/esphome/devices/pinspot.yaml +++ /dev/null @@ -1,53 +0,0 @@ -esphome: - name: "pinspot" - friendly_name: "Pinspot" - platformio_options: - board_build.flash_mode: dio - -esp32: - board: esp32-c3-devkitm-1 - variant: ESP32C3 - framework: - type: esp-idf - -logger: - -api: - encryption: - key: !secret apikey_pinspot - -ota: - - platform: esphome - password: !secret otapass_pinspot - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - enable_on_boot: True - fast_connect: On - output_power: 8.5 - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - -output: - - platform: ledc - pin: GPIO1 - id: output_led_brightness - min_power: 0.028 - zero_means_zero: true - - platform: ledc - pin: GPIO4 - inverted: true - id: output_led_colortemp - -light: - - platform: color_temperature - name: "Pinspot" - color_temperature: output_led_colortemp - brightness: output_led_brightness - cold_white_color_temperature: 6000 K - warm_white_color_temperature: 2700 K diff --git a/hosts/iron/services/esphome/devices/shroombox.yaml b/hosts/iron/services/esphome/devices/shroombox.yaml deleted file mode 100644 index 4f4de46..0000000 --- a/hosts/iron/services/esphome/devices/shroombox.yaml +++ /dev/null @@ -1,128 +0,0 @@ -esphome: - name: "shroombox" - friendly_name: "shroombox" - -esp32: - board: esp-wrover-kit - -api: - encryption: - key: !secret apikey_shroombox - -ota: - - platform: esphome - password: !secret otapass_shroombox - -ethernet: - type: LAN8720 - mdc_pin: GPIO23 - mdio_pin: GPIO18 - clk_mode: GPIO0_IN - phy_addr: 1 - power_pin: GPIO16 - -logger: - -i2c: - sda: GPIO4 - scl: GPIO14 - scan: true - -sensor: - - platform: scd30 - id: scd30_sensor - co2: - name: "Shroombox CO2" - accuracy_decimals: 1 - temperature: - name: "Shroombox Temperature" - accuracy_decimals: 2 - humidity: - name: "Shroombox Humidity" - accuracy_decimals: 1 - id: humidity - address: 0x61 - update_interval: 5s - automatic_self_calibration: false - - - platform: hx711 - name: "Water tank weight" - dout_pin: GPIO32 - clk_pin: GPIO33 - gain: 128 - update_interval: 5s - filters: - - calibrate_linear: - - -35884 -> 0 - - 334800 -> 887 - unit_of_measurement: g - - platform: pulse_counter - pin: - number: GPIO36 - #mode: INPUT_PULLUP - mode: INPUT - unit_of_measurement: 'RPM' - id: fan_rpm - name: Fan Speed - accuracy_decimals: 0 - -output: - - platform: ledc - id: fan_duty - pin: GPIO15 - frequency: "25000 Hz" - min_power: 10% - max_power: 100% - zero_means_zero: true - -fan: - - platform: speed - output: fan_duty - name: "Fan" - id: fan1 - -switch: - - platform: gpio - pin: GPIO2 - id: humidifier - name: "Humidifier" - -number: - - platform: template - name: "CO2 calibration value" - optimistic: true - min_value: 350 - max_value: 4500 - step: 1 - id: co2_cal - icon: "mdi:molecule-co2" - entity_category: "config" - -button: - - platform: template - name: "SCD30 Force manual calibration" - entity_category: "config" - on_press: - then: - - scd30.force_recalibration_with_reference: - value: !lambda 'return id(co2_cal).state;' - -climate: - - platform: thermostat - name: "Humidistat" - sensor: humidity - min_idle_time: 20s - min_heating_off_time: 60s - min_heating_run_time: 60s - visual: - min_temperature: 0 - max_temperature: 100 - preset: - - name: default - mode: heat - default_target_temperature_low: 80 - - heat_action: - - switch.turn_on: humidifier - idle_action: - - switch.turn_off: humidifier diff --git a/hosts/iron/services/esphome/devices/tuerschloss.yaml b/hosts/iron/services/esphome/devices/tuerschloss.yaml deleted file mode 100644 index 1560071..0000000 --- a/hosts/iron/services/esphome/devices/tuerschloss.yaml +++ /dev/null @@ -1,85 +0,0 @@ -esphome: - name: "tuerschloss" - friendly_name: "Türschloss" - platformio_options: - board_build.flash_mode: dio - -esp32: - board: esp32-c3-devkitm-1 - variant: ESP32C3 - framework: - type: esp-idf - -logger: - -api: - encryption: - key: !secret apikey_tuerschloss - -ota: - - platform: esphome - password: !secret otapass_tuerschloss - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - enable_on_boot: True - fast_connect: On - output_power: 8.5 - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - -output: - - platform: gpio - pin: - number: GPIO0 - inverted: true - mode: - output: true - open_drain: true - id: btn_unlock - - platform: gpio - pin: - number: GPIO1 - inverted: true - mode: - output: true - open_drain: true - id: btn_lock - - platform: gpio - pin: - number: GPIO3 - id: btn_open - -lock: - - platform: template - name: "Türschloss" - id: tuerschloss - assumed_state: true - lock_action: - - output.turn_on: btn_lock - - delay: 250ms - - output.turn_off: btn_lock - - delay: 5s - - lambda: id(tuerschloss).publish_state(LOCK_STATE_LOCKED); - unlock_action: - - output.turn_on: btn_unlock - - delay: 250ms - - output.turn_off: btn_unlock - - delay: 5s - - lambda: id(tuerschloss).publish_state(LOCK_STATE_UNLOCKED); - -button: - - platform: template - name: "Türöffner" - id: tueroeffner - icon: mdi:lock-open - on_press: - - logger.log: "Button pressed" - - output.turn_on: btn_open - - delay: 250ms - - output.turn_off: btn_open diff --git a/hosts/iron/services/esphome/devices/tuersprechanlage.yaml b/hosts/iron/services/esphome/devices/tuersprechanlage.yaml deleted file mode 100644 index d40d2c4..0000000 --- a/hosts/iron/services/esphome/devices/tuersprechanlage.yaml +++ /dev/null @@ -1,124 +0,0 @@ -esphome: - name: "tuersprechanlage" - friendly_name: "Türsprechanlage" - -esp32: - board: lolin_s2_mini - variant: ESP32S2 - framework: - type: esp-idf - sdkconfig_options: - CONFIG_ESP_CONSOLE_USB_CDC: y - -logger: - hardware_uart: USB_CDC - -api: - encryption: - key: !secret apikey_tuersprechanlage - -ota: - - platform: esphome - password: !secret otapass_tuersprechanlage - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - enable_on_boot: True - fast_connect: True - power_save_mode: none - output_power: 10 - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - -binary_sensor: - - platform: gpio - name: Etagenklingel - id: floor_bell - pin: - number: GPIO16 - mode: - input: true - pullup: true - filters: - - delayed_off: 10s - - - platform: gpio - name: Treppenlicht - id: staircase_light - pin: - number: GPIO18 - mode: - input: true - pullup: true - filters: - - invert - - delayed_off: 10s - on_press: - then: - - output.turn_on: output_staircase_light_ssr - - delay: 200ms - - output.turn_off: output_staircase_light_ssr - -output: - - platform: gpio - pin: GPIO15 - id: output_door_opener - - platform: ledc - pin: - number: GPIO33 - inverted: true - id: output_staircase_light_ssr - frequency: 50000 - min_power: 0 - max_power: 0.12 - - platform: template - type: binary - id: output_staircase_light_permanent - write_action: - - if: - condition: - lambda: 'return state;' - then: - - script.execute: script_staircase_permanent - else: - - script.stop: script_staircase_permanent - -button: - - platform: template - name: "Türöffner" - id: btn_tueroeffner - icon: mdi:lock-open - on_press: - - output.turn_on: output_door_opener - - delay: 500ms - - output.turn_off: output_door_opener - - platform: template - name: "Treppenlicht" - id: btn_staircase_light - icon: mdi:stairs - on_press: - - output.turn_on: output_staircase_light_ssr - - delay: 200ms - - output.turn_off: output_staircase_light_ssr - -light: - - platform: binary - id: staircase_permanent - name: Treppenlicht permanent - output: output_staircase_light_permanent - -script: - - id: script_staircase_permanent - mode: restart - then: - - while: - condition: - lambda: 'return true;' - then: - - button.press: btn_staircase_light - - delay: 90s diff --git a/hosts/iron/services/esphome/devices/waschmaschine.yaml b/hosts/iron/services/esphome/devices/waschmaschine.yaml index fad1aea..8e4f376 100644 --- a/hosts/iron/services/esphome/devices/waschmaschine.yaml +++ b/hosts/iron/services/esphome/devices/waschmaschine.yaml @@ -7,8 +7,7 @@ api: key: !secret apikey_waschmaschine ota: - - platform: esphome - password: !secret otapass_waschmaschine + password: !secret otapass_waschmaschine wifi: ssid: !secret wifi_ssid_bw @@ -28,9 +27,6 @@ external_components: components: [ miele_w433 ] sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - platform: miele_w433 enable_7segment_pin: 27 clock_pin: 14 @@ -42,83 +38,4 @@ sensor: name: "in Betrieb" current_operation: name: "aktueller Vorgang" - id: current_operation -number: - - platform: template - name: "Waschmittelmenge" - id: detergent_dosing - min_value: 25.0 - max_value: 150.0 - step: 1 - unit_of_measurement: "ml" - icon: 'mdi:cup-water' - restore_value: true - initial_value: 75.0 - optimistic: true - - platform: template - name: "Waschmittelvorrat" - id: detergent_supply - min_value: 0.0 - max_value: 5000 - step: 1.0 - unit_of_measurement: "ml" - icon: 'mdi:cup-water' - restore_value: true - initial_value: 0 - optimistic: true - -stepper: - - platform: a4988 - id: detergent_stepper - step_pin: GPIO32 - sleep_pin: GPIO33 - dir_pin: GPIO25 # not used - max_speed: 600 steps/s - acceleration: 125 steps/s^2 - deceleration: 125 steps/s^2 - -globals: - - id: dosing_enabled - type: bool - restore_value: false - initial_value: 'true' - -interval: - - interval: 1s - then: - if: - condition: - and: - #- lambda: return id(current_operation).state == "Einw/Vorwäsche"; - - lambda: return id(current_operation).state == "Waschen"; - - lambda: return id(dosing_enabled); - then: - - lambda: &dosing |- - float dose = id(detergent_dosing).state; - float current_supply = id(detergent_supply).state; - if (current_supply >= dose) { - id(detergent_stepper).set_target(dose * 125); - id(detergent_stepper).report_position(0); - id(detergent_supply).publish_state(current_supply - dose); - ESP_LOGD("custom", "Waschmitteldosierung durchgeführt: %.2f ml, verbleibender Vorrat: %.2f ml", dose, current_supply - dose); - } else { - ESP_LOGW("custom", "Nicht genug Waschmittelvorrat! Aktueller Vorrat: %.2f ml, gewünschte Dosierung: %.2f ml", current_supply, dose); - } - - lambda: |- - id(dosing_enabled) = false; - - interval: 1s - then: - if: - condition: - lambda: return id(current_operation).state == "Knitterschutz/Ende"; - then: - - lambda: |- - id(dosing_enabled) = true; - -button: - - platform: template - name: "Waschmitteldosierung auslösen" - icon: "mdi:cup-water" - on_press: - - lambda: *dosing diff --git a/hosts/iron/services/esphome/devices/water-bottle.yaml b/hosts/iron/services/esphome/devices/water-bottle.yaml deleted file mode 100644 index 456b973..0000000 --- a/hosts/iron/services/esphome/devices/water-bottle.yaml +++ /dev/null @@ -1,238 +0,0 @@ -substitutions: - tolerance: "10" - minimum_sip: "20" - default_bottle_tare: "198" - -esphome: - name: "water-bottle" - friendly_name: "Water bottle" - -esp32: - board: lolin_s2_mini - variant: ESP32S2 - framework: - type: esp-idf - sdkconfig_options: - CONFIG_ESP_CONSOLE_USB_CDC: y - -logger: - hardware_uart: USB_CDC - -api: - encryption: - key: !secret apikey_water_bottle - on_client_connected: - - light.turn_on: - id: pixels - effect: "scan" - red: 0% - green: 25% - blue: 0% - - delay: 2s - - light.turn_off: - id: pixels - -ota: - - platform: esphome - password: !secret otapass_water_bottle - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - enable_on_boot: True - fast_connect: True - power_save_mode: none - output_power: 10 - -globals: - - id: volume_when_removed - type: int - restore_value: no - initial_value: "NAN" - - id: bottle_returned - type: bool - restore_value: no - initial_value: "false" - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - - platform: hx711 - internal: true - id: scale - dout_pin: GPIO16 - clk_pin: GPIO17 - gain: 128 - update_interval: 0.1s - unit_of_measurement: g - filters: - - quantile: - window_size: 10 - send_every: 5 - send_first_at: 5 - quantile: .9 - - calibrate_linear: - - 197155 -> 0 - - 246676 -> 50 - - platform: copy - name: "absolute volume" - id: volume_absolute - icon: "mdi:water" - source_id: scale - filters: - - lambda: "return x - id(bottle_tare).state;" - - clamp: - min_value: 0 - ignore_out_of_range: true - - quantile: - window_size: 5 - send_every: 5 - send_first_at: 5 - quantile: .9 - on_value: - then: - - if: - condition: - lambda: |- - if (id(bottle_returned)) { - id(bottle_returned) = false; - return true; - } - return false; - then: - - lambda: |- - ESP_LOGI("main", "Bottle returned, waiting to settle"); - ESP_LOGI("main", "Volume absolute: %f", id(volume_absolute).state); - - delay: 3s - - lambda: |- - ESP_LOGI("main", "Bottle settled"); - ESP_LOGI("main", "Volume when removed: %d", id(volume_when_removed)); - ESP_LOGI("main", "Volume absolute: %f", id(volume_absolute).state); - if (id(volume_when_removed) > id(volume_absolute).state + ${minimum_sip}) { - ESP_LOGI("main", "Volume total before: %f", id(volume_total).state); - auto call = id(volume_total).make_call(); - call.set_value(id(volume_when_removed) - id(volume_absolute).state + id(volume_total).state); - call.perform(); - ESP_LOGI("main", "Volume total now: %f", id(volume_total).state); - } - - platform: template - name: "Water consumption rate" - id: "volume_total_derivative" - unit_of_measurement: "ml/h" - icon: "mdi:water-check" - lambda: |- - static float last_value = 0; - static float last_time = 0; - float time = (float) millis(); - if (last_time == 0){ - last_value = id(volume_total).state; - last_time = time; - return {}; - } - float change = ( ( id(volume_total).state - last_value ) / ( time - last_time ) ) *1000*60*60; - last_value = id(volume_total).state; - last_time = time; - return change; - filters: - - sliding_window_moving_average: - window_size: 3 - send_every: 2 - - or: - - delta: 0.01 - - heartbeat: 120minutes - - throttle: 30s - -number: - - platform: template - name: "Bottle tare" - id: bottle_tare - icon: mdi:weight-gram - optimistic: true - initial_value: "${default_bottle_tare}" - unit_of_measurement: "g" - step: 1 - min_value: 0 - max_value: 1000 - - platform: template - name: "total volume" - id: volume_total - optimistic: true - icon: "mdi:water" - unit_of_measurement: "ml" - step: 1 - min_value: 0 - max_value: 10000 - -binary_sensor: - - platform: template - name: "Bottle present" - id: bottle_present - lambda: |- - if (id(scale).state > id(bottle_tare).state - ${tolerance}) { - return true; - } else { - return false; - } - on_release: - then: - - lambda: |- - id(volume_when_removed) = id(volume_absolute).state; - ESP_LOGI("main", "Volume absolute: %f ml", id(volume_absolute).state); - ESP_LOGI("main", "Bottle removed with %d ml", id(volume_when_removed)); - - light.turn_on: - id: pixels - effect: "normal_pulse" - red: 75% - green: 0% - blue: 0% - on_press: - then: - - globals.set: - id: bottle_returned - value: "true" - - if: - condition: - lambda: "return id(volume_absolute).state > 250;" - then: - - light.turn_on: - id: pixels - effect: "normal_pulse" - red: 0% - green: 50% - blue: 50% - else: - - light.turn_on: - id: pixels - effect: "normal_pulse" - red: 50% - green: 25% - blue: 0% - - delay: 2s - - light.turn_off: - id: pixels - -e131: - method: multicast - -light: - - platform: esp32_rmt_led_strip - id: pixels - rgb_order: GRB - pin: GPIO12 - num_leds: 8 - rmt_channel: 0 - chipset: ws2812 - effects: - - addressable_scan: - name: scan - move_interval: 20ms - scan_width: 1 - - pulse: - name: slow_pulse - transition_length: 500ms - update_interval: 10s - - pulse: - name: normal_pulse - min_brightness: 20% diff --git a/hosts/iron/services/esphome/devices/wohnungstuer.yaml b/hosts/iron/services/esphome/devices/wohnungstuer.yaml deleted file mode 100644 index 11c0675..0000000 --- a/hosts/iron/services/esphome/devices/wohnungstuer.yaml +++ /dev/null @@ -1,253 +0,0 @@ -esphome: - name: "wohnungstuer" - friendly_name: "Wohnungstür" - -api: - encryption: - key: !secret apikey_wohnungstuer - -ota: - - platform: esphome - password: !secret otapass_wohnungstuer - -wifi: - ssid: !secret wifi_ssid_bw - password: !secret wifi_password_bw - domain: .iot.bw.jalr.de - -esp32_ble_tracker: - scan_parameters: - active: false - -bluetooth_proxy: - active: true - -xiaomi_ble: - -esp32: - board: esp32doit-devkit-v1 - framework: - type: arduino - version: recommended - -logger: - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s - -globals: - - id: leaving - type: int - restore_value: no - initial_value: '0' - -binary_sensor: - - platform: template - name: "At home" - id: presence - device_class: presence - - platform: gpio - name: Tür - id: door - pin: - number: GPIO32 - mode: - input: true - pullup: true - filters: - - delayed_on_off: 1s - device_class: door - on_press: # on opening door - then: - - lambda: |- - id(leaving) |= 1; - - if: - condition: - # bowl is occupied - binary_sensor.is_on: key_bowl - then: - - light.turn_on: - id: pixels - effect: strobe_red - - script.execute: - id: beep - on_ms: 250 - off_ms: 250 - - else: - - if: - condition: - binary_sensor.is_off: presence # when away - then: - - light.turn_on: - id: pixels - effect: "None" - red: 75% - green: 25% - - on_release: # on closing door - then: - - if: - condition: - binary_sensor.is_off: presence # when away - then: - - light.turn_on: - id: pixels - effect: "scan" - red: 0% - green: 0% - blue: 100% - - script.execute: - id: beep - on_ms: 100 - off_ms: 1000 - - if: - condition: - lambda: |- - return id(leaving) == 3; - then: - - light.turn_off: - id: pixels - - script.stop: beep - - switch.turn_off: buzzer - - binary_sensor.template.publish: # set away state - id: presence - state: OFF - else: - - if: - condition: - # when keys are in the bowl - binary_sensor.is_on: key_bowl - then: - - script.stop: beep - - switch.turn_off: buzzer - - light.turn_on: - id: pixels - effect: "None" - red: 0% - green: 50% - blue: 0% - - delay: 30s - - light.turn_off: - id: pixels - transition_length: 3s - - lambda: |- - id(leaving) = 0; - - if: - condition: - binary_sensor.is_on: presence # when at home - then: - - light.turn_off: - id: pixels - - script.stop: beep - - switch.turn_off: buzzer - - - platform: gpio - name: Schlüsselschale - id: key_bowl - pin: - number: GPIO23 - mode: - input: true - pullup: true - device_class: occupancy - filters: - - invert: - - delayed_on_off: 250ms - on_press: # when keys fall in bowl - then: - - binary_sensor.template.publish: # set at home state - id: presence - state: ON - - lambda: |- - id(leaving) = 0; - - if: - condition: - # door is closed - binary_sensor.is_off: door - then: - - script.stop: beep - - switch.turn_off: buzzer - - light.turn_on: - id: pixels - effect: "None" - red: 0% - green: 50% - blue: 0% - - delay: 30s - - light.turn_off: - id: pixels - transition_length: 3s - on_release: # when keys are removed from bowl - then: - - if: - condition: - lambda: |- - return id(leaving) == 1; - then: - - light.turn_off: - id: pixels - - script.stop: beep - - switch.turn_off: buzzer - - lambda: |- - id(leaving) |= 2; - - if: - condition: - # door is closed - binary_sensor.is_off: door - then: - - light.turn_on: - id: pixels - effect: "rainbow" - -light: - - platform: esp32_rmt_led_strip - id: pixels - rgb_order: GRB - pin: GPIO12 - num_leds: 5 - rmt_channel: 0 - chipset: ws2812 - effects: - - strobe: - name: strobe_red - colors: - - state: true - brightness: 100% - red: 100% - green: 0% - blue: 0% - duration: 250ms - - state: false - duration: 250ms - - addressable_rainbow: - name: rainbow - speed: 20 - width: 10 - - addressable_scan: - name: scan - move_interval: 20ms - scan_width: 1 - -switch: - - platform: gpio - pin: GPIO22 - id: buzzer - -script: - - id: beep - mode: restart - parameters: - on_ms: int - off_ms: int - then: - - while: - condition: - lambda: 'return true;' - then: - - switch.turn_on: buzzer - - delay: !lambda return on_ms; - - switch.turn_off: buzzer - - delay: !lambda return off_ms; diff --git a/hosts/iron/services/esphome/devices/kuechentisch.yaml b/hosts/iron/services/esphome/devices/yeelight-meteorite.yaml similarity index 75% rename from hosts/iron/services/esphome/devices/kuechentisch.yaml rename to hosts/iron/services/esphome/devices/yeelight-meteorite.yaml index 5d0f27a..617aae1 100644 --- a/hosts/iron/services/esphome/devices/kuechentisch.yaml +++ b/hosts/iron/services/esphome/devices/yeelight-meteorite.yaml @@ -1,6 +1,6 @@ esphome: - name: "kuechentisch" - friendly_name: "Küchentisch" + name: "yeelight-meteorite" + friendly_name: "Yeelight Meteorite" on_boot: then: - light.turn_on: @@ -21,44 +21,29 @@ logger: api: encryption: - key: !secret apikey_kuechentisch + key: !secret apikey_yeelight_meteorite ota: - - platform: esphome - password: !secret otapass_kuechentisch + password: !secret otapass_yeelight_meteorite wifi: ssid: !secret wifi_ssid_bw password: !secret wifi_password_bw domain: .iot.bw.jalr.de - fast_connect: true - manual_ip: - static_ip: 10.20.0.10 - gateway: 10.20.0.1 - subnet: 255.255.240.0 - -sensor: - - platform: wifi_signal - name: "WiFi Signal Sensor" - update_interval: 60s output: - platform: ledc pin: GPIO19 id: output_warm power_supply: power - min_power: 0.13 - max_power: 0.77 - frequency: 1220Hz - zero_means_zero: true +# min_power: 0.13 + max_power: 0.82 - platform: ledc pin: GPIO21 id: output_cold power_supply: power - frequency: 1220Hz - zero_means_zero: true - min_power: 0.13 - max_power: 0.76 +# min_power: 0.13 + max_power: 0.82 - platform: ledc pin: GPIO23 diff --git a/hosts/iron/services/grafana.nix b/hosts/iron/services/grafana.nix deleted file mode 100644 index 15e1571..0000000 --- a/hosts/iron/services/grafana.nix +++ /dev/null @@ -1,146 +0,0 @@ -{ config -, lib -, pkgs -, ... -}: -let - inherit (config.networking) ports; - domain = "grafana.jalr.de"; - cfg = config.services.grafana; -in -{ - sops.secrets = { - "grafana/secret-key" = { - sopsFile = ../secrets.yaml; - owner = config.systemd.services.grafana.serviceConfig.User; - }; - }; - - services.grafana = { - enable = true; - settings = { - server = { - inherit domain; - root_url = "https://%(domain)s"; - http_addr = "127.0.0.1"; - http_port = ports.grafana.tcp; - }; - security = { - content_security_policy = true; - cookie_samesite = "strict"; - cookie_secure = true; - secret_key = "$__file{${config.sops.secrets."grafana/secret-key".path}}"; - strict_transport_security = true; - strict_transport_security_preload = true; - strict_transport_security_subdomains = true; - }; - analytics = { - reporting_enabled = false; - check_for_updates = false; - check_for_plugin_updates = false; - }; - }; - provision = { - datasources.settings = { - apiVersion = 1; - datasources = with config.services.prometheus; - ( - lib.lists.optional enable { - name = "Prometheus"; - type = "prometheus"; - url = "http://${listenAddress}:${toString port}"; - orgId = 1; - } - ) - ++ (with config.services.prometheus.alertmanager; ( - lib.lists.optional enable { - name = "Alertmanager"; - type = "alertmanager"; - url = "http://${listenAddress}:${toString port}"; - orgId = 1; - } - )); - deleteDatasources = [ - { - name = "Prometheus"; - orgId = 1; - } - { - name = "Alertmanager"; - orgId = 1; - } - ]; - }; - - dashboards.settings.providers = - let - # https://grafana.com/grafana/dashboards/ - fetchDashboard = - { name - , hash - , id - , version - , - }: - pkgs.fetchurl { - inherit name hash; - url = "https://grafana.com/api/dashboards/${toString id}/revisions/${toString version}/download"; - recursiveHash = true; - postFetch = '' - mv "$out" temp - mkdir -p "$out" - mv temp "$out/${name}.json"; - ''; - }; - dashboard = name: fetchArgs: { - inherit name; - options.path = fetchDashboard fetchArgs; - }; - in - [ - (dashboard "Node Exporter Full" - { - name = "node-exporter-full"; - hash = "sha256-QTHG9ioy7E8U8O8x/qFabOxK2qBjlGlzuEvwYKug0CQ="; - id = 1860; - version = 36; - }) - (dashboard "Node Exporter" - { - name = "node-exporter"; - hash = "sha256-2xgE0m3SUFiux501uCVb4aH3zGfapW/SmfxRsFC/514="; - id = 13978; - version = 2; - }) - (dashboard "AlertManager" - { - name = "alertmanager"; - hash = "sha256-Yvw0DGQJpqBYNzE4ES/x7ZAYF7iJ4SUNBKB+sJRuGBw="; - id = 9578; - version = 4; - }) - ]; - }; - }; - services.nginx.virtualHosts = { - "${domain}" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://${cfg.settings.server.http_addr}:${toString cfg.settings.server.http_port}"; - proxyWebsockets = true; - recommendedProxySettings = true; - }; - }; - }; - - environment.persistence."/persist".directories = [ - { - directory = "/var/lib/grafana"; - user = "grafana"; - group = "grafana"; - mode = "u=rwx,g=,o="; - } - ]; -} diff --git a/hosts/iron/services/home-assistant.nix b/hosts/iron/services/home-assistant.nix index d62f792..27d40ac 100644 --- a/hosts/iron/services/home-assistant.nix +++ b/hosts/iron/services/home-assistant.nix @@ -1,265 +1,115 @@ -{ lib, pkgs, config, ... }: +args@{ lib, pkgs, config, custom-utils, ... }: let - inherit (config.networking) ports; - interfaces = import ../interfaces.nix; - domain = "hass.jalr.de"; + ports = import ../ports.nix args; in { - sops.secrets.home-assistant = { - owner = "root"; - group = "hass"; - mode = "0640"; - }; - - networking.firewall.interfaces = { - "${interfaces.lan}".allowedTCPPorts = [ ports.mqtt.tcp ]; - iot.allowedTCPPorts = [ ports.mqtt.tcp ]; - }; - - services = { - home-assistant = { - enable = true; - lovelaceConfig = { - title = "Home"; - views = [ - { - path = "default_view"; - title = "Home"; - cards = [ - { - title = "Eingang"; - type = "entities"; - entities = [ - { - entity = "light.eingang_deckenleuchte_deckenleuchte"; - name = "Deckenleuchte"; - } - ]; - } - { - name = "Esstisch"; - type = "entities"; - entities = [ - { - entity = "light.yeelight_meteorite_ambient_light"; - name = "Ambient light"; - } - { - entity = "light.yeelight_meteorite_ceiling_light"; - name = "Ceiling light"; - } - { - entity = "light.yeelight_meteorite_night_light"; - name = "Night light"; - } - ]; - } - ]; - } - ]; + services.home-assistant = { + enable = true; + lovelaceConfig = { + title = "Home"; + views = [ + { + path = "default_view"; + title = "Home"; + cards = [ + { + type = "entities"; + entities = [ + "switch.circadian_lighting_circadian_lighting" + ]; + } + { + title = "Eingang"; + type = "entities"; + entities = [ + { + entity = "light.eingang_deckenleuchte_deckenleuchte"; + name = "Deckenleuchte"; + } + ]; + } + { + name = "Esstisch"; + type = "entities"; + entities = [ + { + entity = "light.yeelight_meteorite_ambient_light"; + name = "Ambient light"; + } + { + entity = "light.yeelight_meteorite_ceiling_light"; + name = "Ceiling light"; + } + { + entity = "light.yeelight_meteorite_night_light"; + name = "Night light"; + } + ]; + } + ]; + } + ]; + }; + extraComponents = [ + # See https://www.home-assistant.io/integrations + "esphome" + ]; + customComponents = [ + pkgs.home-assistant-custom-components.circadian_lighting + ]; + lovelaceConfigWritable = false; + configWritable = false; + config = { + http = { + server_host = [ "127.0.0.1" ]; + server_port = ports.home-assistant.tcp; + use_x_forwarded_for = true; + trusted_proxies = [ "127.0.0.1" ]; }; - extraComponents = [ - # See https://www.home-assistant.io/integrations - "bthome" - "caldav" - "esphome" - "local_todo" - "openweathermap" - "wyoming" - "xiaomi_ble" - "vlc_telnet" - ]; - customComponents = with pkgs.home-assistant-custom-components; [ - adaptive_lighting - ]; - customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [ - valetudo-map-card - ]; - lovelaceConfigWritable = false; - configWritable = false; - config = { - http = { - server_host = [ "127.0.0.1" ]; - server_port = ports.home-assistant.tcp; - use_x_forwarded_for = true; - trusted_proxies = [ "127.0.0.1" ]; - }; - homeassistant = { - unit_system = "metric"; - time_zone = "Europe/Berlin"; - temperature_unit = "C"; - inherit (config.location) longitude; - inherit (config.location) latitude; - external_url = "https://${domain}/"; - internal_url = "https://${domain}/"; - }; - default_config = { }; - adaptive_lighting = { - lights = [ + homeassistant = { + unit_system = "metric"; + time_zone = "Europe/Berlin"; + temperature_unit = "C"; + longitude = config.location.longitude; + latitude = config.location.latitude; + }; + default_config = { }; + circadian_lighting = { }; + switch = [ + { + platform = "circadian_lighting"; + lights_ct = [ "light.yeelight_meteorite_ceiling_light" "light.eingang_deckenleuchte_deckenleuchte" "light.led_panel_schreibtisch_panel" "light.kueche_leiste_led_light" - "light.badspiegel_background_light" - "light.badspiegel_front_light" ]; - }; - "automation nix" = [ - { - alias = "Waschmaschine fertig Benachrichtigung"; - trigger = { - platform = "state"; - entity_id = "sensor.waschmaschine_aktueller_vorgang"; - to = "Knitterschutz/Ende"; - }; - action = [ - { - service = "notify.mobile_app_shift6mq"; - data = { - message = "Die Waschmaschine hat das Programm beendet."; - title = "Wäsche fertig"; - }; - } - ]; - } - ]; - "automation ui" = "!include automations.yaml"; - "scene nix" = [ - ]; - "scene ui" = "!include scenes.yaml"; - bluetooth = { }; - device_tracker = [ - { - platform = "bluetooth_le_tracker"; - } - ]; - "script nix" = [ - { - lights_off_except = { - icon = "mdi:home-lightbulb"; - fields.exclude_lights.description = "Excluded lights as list"; - sequence = [ - { - service = "logbook.log"; - data_template = { - entity_id = "script.turn_off_lights"; - name = "Exclude log"; - message = "Turning of all lights except: {{ exclude_lights }}"; - }; - } - { - service = "light.turn_off"; - data_template.entity_id = '' - {{ states.light | rejectattr('entity_id', 'in', exclude_lights) | rejectattr('state', 'in', 'off') | join(',', attribute='entity_id') }} - ''; - } - ]; - }; - } - ]; - "script ui" = "!include scripts.yaml"; - calendar = [ - { - platform = "caldav"; - username = "jalr@jalr.de"; - password = "!secret radicale"; - url = "https://cal.jalr.de/radicale"; - } - ]; - mqtt = { }; - media_player = [ - { - platform = "mpd"; - name = "mpd@iron"; - host = "127.0.0.1"; - } - ]; - }; - }; - - mosquitto = { - enable = true; - persistence = true; - listeners = [ + min_brightness = 20; + } + ]; + automation = [ { - port = ports.mqtt.tcp; - users = { - valetudo = { - passwordFile = config.sops.secrets."mqtt-users/valetudo".path; - acl = [ - "readwrite homeassistant/+/donald/#" - "readwrite valetudo/donald/#" - ]; - }; - home-assistant = { - passwordFile = config.sops.secrets."mqtt-users/home-assistant".path; - acl = [ "readwrite #" ]; - }; + alias = "Waschmaschine fertig Benachrichtigung"; + trigger = { + platform = "state"; + entity_id = "sensor.waschmaschine_aktueller_vorgang"; + to = "Knitterschutz/Ende"; }; + action = [ + { + service = "notify.mobile_app_shift6mq"; + data = { + message = "Die Waschmaschine hat das Programm beendet."; + title = "Wäsche fertig"; + }; + } + ]; } ]; }; }; - systemd.services = { - home-assistant.serviceConfig.ExecStartPre = [ - ( - pkgs.writeShellScript "home-assistant-secrets" '' - ln -sf "${config.sops.secrets.home-assistant.path}" "${config.services.home-assistant.configDir}/secrets.yaml" - '' - ) - ]; - hass-vlc = { - script = '' - exec ${pkgs.vlc}/bin/cvlc \ - --no-video \ - -I telnet \ - --telnet-password=vlc \ - --sout='#transcode{acodec=s16le,channels=2,samplerate=48000}:std{access=file,mux=raw,dst=/run/snapserver/hass.fifo}' \ - --aout=none - ''; - wants = [ "snapserver.service" ]; - after = [ "snapserver.service" ]; - serviceConfig = { - BindPaths = [ "/run/snapserver/hass.fifo" ]; - BindReadOnlyPaths = [ "/nix/store" "/etc/ssl/certs" "/etc/static/ssl/certs" "/bin/sh" ]; - CapabilityBoundingSet = ""; - DynamicUser = "true"; - Group = "snapserver"; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = lib.mkForce true; - PrivateUsers = true; - ProcSubset = "pid"; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "noaccess"; - ProtectSystem = "strict"; - RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - RootDirectory = "/run/hass-vlc"; - RuntimeDirectory = "hass-vlc"; - SystemCallArchitectures = "native"; - SystemCallFilter = [ "@system-service" "~@privileged" ]; - }; - wantedBy = [ "multi-user.target" ]; - }; - }; - - systemd.tmpfiles.rules = [ - "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" - "f ${config.services.home-assistant.configDir}/scenes.yaml 0755 hass hass" - ]; - - services.nginx.virtualHosts."${domain}" = { + services.nginx.virtualHosts."hass.jalr.de" = { enableACME = true; forceSSL = true; kTLS = true; diff --git a/hosts/iron/services/jellyfin/default.nix b/hosts/iron/services/jellyfin.nix similarity index 76% rename from hosts/iron/services/jellyfin/default.nix rename to hosts/iron/services/jellyfin.nix index eb4e918..01aff39 100644 --- a/hosts/iron/services/jellyfin/default.nix +++ b/hosts/iron/services/jellyfin.nix @@ -1,54 +1,29 @@ -{ config, lib, pkgs, ... }: +args@{ lib, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; - logoPng = pkgs.stdenvNoCC.mkDerivation { - name = "broflix.png"; - src = ./broflix.svg; - dontBuild = true; - dontUnpack = true; - installPhase = '' - export PATH="$PATH:${pkgs.lib.makeBinPath [pkgs.imagemagick]}" - convert \ - -background transparent \ - $src \ - -resize 1302x \ - $out - ''; - }; + ports = import ../ports.nix args; in { - imports = [ - ./rar2fs.nix - ]; - services.jellyfin = { enable = true; }; - systemd.services.jellyfin = { serviceConfig = { ###MemoryDenyWriteExecute = true; BindPaths = [ - "/dev/dri/renderD128" "/var/cache/jellyfin" "/var/lib/jellyfin" ]; BindReadOnlyPaths = [ - "/etc/resolv.conf" - "/etc/ssl" - "/etc/static/ssl" + "/nix/store" "/filebitch/pub/Filme" "/filebitch/pub/Serien" - "/nix/store" - "/run/opengl-driver" - "/var/lib/qBittorrent/downloads" + "/var/lib/qbittorrent/downloads" ]; CapabilityBoundingSet = ""; - DeviceAllow = "/dev/dri/renderD128 rw"; #IPAddressAllow = "localhost"; #IPAddressDeny = "any"; LockPersonality = true; - PrivateDevices = false; + PrivateDevices = lib.mkForce true; PrivateUsers = true; ProtectClock = true; ProtectControlGroups = true; @@ -94,15 +69,6 @@ in proxy_set_header X-Forwarded-Host $http_host; proxy_buffering off; } - location = /web/broflix.svg { - alias ${./broflix.svg}; - } - location = /web/assets/img/banner-light.png { - alias ${logoPng}; - } - location = /web/assets/img/banner-dark.png { - alias ${logoPng}; - } location = /web/ { proxy_pass http://127.0.0.1:${toString ports.jellyfin.tcp}/web/index.html; proxy_set_header Host $host; diff --git a/hosts/iron/services/jellyfin/broflix.svg b/hosts/iron/services/jellyfin/broflix.svg deleted file mode 100644 index 7653de9..0000000 --- a/hosts/iron/services/jellyfin/broflix.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - unrar and chill - - diff --git a/hosts/iron/services/jellyfin/rar2fs.nix b/hosts/iron/services/jellyfin/rar2fs.nix deleted file mode 100644 index dc634cf..0000000 --- a/hosts/iron/services/jellyfin/rar2fs.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ lib, pkgs, ... }: - -let - rar2fs = pkgs.rar2fs.override { unrar = pkgs.unrar_6; }; - rar2fs_mounts = pkgs.writeScriptBin "rar2fs_mounts" (lib.strings.concatLines [ - "#!${pkgs.python3}/bin/python" - (builtins.readFile ./rar2fs_mounts.py) - ]); - rar_path = "/var/lib/qBittorrent/downloads"; - mount_path = "/run/jellyfin/rar2fs"; -in -{ - programs.fuse = { - userAllowOther = true; - mountMax = 1000; - }; - - environment.systemPackages = [ - rar2fs - ]; - - systemd.services.jellyfin-rar2fs = { - after = [ "jellyfin.service" ]; - wantedBy = [ "multi-user.target" ]; - path = [ rar2fs "/run/wrappers/bin" ]; - environment.USER = "jellyfin"; - serviceConfig = { - AmbientCapabilities = "CAP_SYS_ADMIN CAP_SETUID CAP_SETGID"; - CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_SETUID CAP_SETGID"; - DeviceAllow = "/dev/fuse rw"; - ExecStart = "${rar2fs_mounts}/bin/rar2fs_mounts ${rar_path} ${mount_path}"; - Group = "jellyfin"; - IPAddressDeny = "any"; - LockPersonality = true; - NoNewPrivileges = "no"; - PrivateDevices = false; - PrivateMounts = false; - PrivateTmp = false; - PrivateUsers = false; - ProtectClock = true; - ProtectControlGroups = false; # implies MountAPIVFS - ProtectHome = false; - ProtectHostname = true; - ProtectKernelLogs = false; - ProtectKernelModules = false; - ProtectKernelTunables = false; # implies MountAPIVFS - #ProtectProc = "noaccess"; # implies MountAPIVFS - ProtectSystem = false; - RestrictAddressFamilies = "none"; - RestrictNamespaces = true; - RestrictRealtime = true; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service" - "@mount" - "@setuid" - "umount2" - ]; - User = "jellyfin"; - }; - }; -} diff --git a/hosts/iron/services/jellyfin/rar2fs_mounts.py b/hosts/iron/services/jellyfin/rar2fs_mounts.py deleted file mode 100644 index aacbf38..0000000 --- a/hosts/iron/services/jellyfin/rar2fs_mounts.py +++ /dev/null @@ -1,112 +0,0 @@ -from pathlib import Path -import argparse -import errno -import os -import signal -import subprocess -import sys -import time - - -mounts = {} - - -class RarMount: - process = None - - @property - def mountpoint(self): - result = self.mount_root / self.rar_file.relative_to(self.rar_root).parent - return result - - def __init__(self, mount_root: str, rar_file: Path, rar_root: Path): - self.mount_root = mount_root - self.rar_file = rar_file - self.rar_root = rar_root - - os.makedirs(self.mountpoint, exist_ok=True) - - print(f"Mounting '{self.rar_file}' at '{self.mountpoint}'") - self.process = subprocess.Popen( - [ - "rar2fs", - "-f", - "-o", - "auto_unmount", - "-o", - "allow_other", - "--no-inherit-perm", - self.rar_file, - self.mountpoint, - ] - ) - - def __del__(self): - if self.process: - self.process.terminate() - self.process.communicate() - - for i in range(10): - try: - os.rmdir(self.mountpoint) - except FileNotFoundError: - pass - except OSError as ex: - # if ex.errno == errno.ENOEMPTY: - # break - if ex.errno == errno.EBUSY: - time.sleep(1) - raise - else: - break - - for dir in self.mountpoint.relative_to(self.mount_root).parents: - try: - os.rmdir(self.mount_root.joinpath(dir)) - except OSError as ex: - pass - - -def signal_handler(sig, frame): - for rar_file, mount in mounts.items(): - del mount - - sys.exit(0) - - -def parse_args(): - parser = argparse.ArgumentParser( - description="Recursively globs a path containing rar files and mounts them under a given mount path." - ) - - parser.add_argument("rar_path", type=Path, help="Path to the RAR directory") - - parser.add_argument("mount_path", type=Path, help="Path to the mount directory") - - return parser.parse_args() - - -def main(): - args = parse_args() - - if not args.rar_path.is_dir(): - parser.error(f"RAR path '{args.rar_path}' is not a valid directory.") - - signal.signal(signal.SIGINT, signal_handler) - - for rar_file in args.rar_path.rglob("*.rar"): - if rar_file in mounts: - continue - if len(rar_file.parts) >= 2 and rar_file.parts[-2].lower() in ["subs", "proof"]: - continue - - mounts[rar_file] = RarMount(args.mount_path, rar_file, args.rar_path) - - while True: - time.sleep(600) - - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/hosts/iron/services/mail.nix b/hosts/iron/services/mail.nix index c5d855e..4ed06b9 100644 --- a/hosts/iron/services/mail.nix +++ b/hosts/iron/services/mail.nix @@ -1,10 +1,17 @@ -{ config, ... }: +args@{ config, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; in { - #sops.secrets."domain_key_jalr.de".owner = "rspamd"; + sops.secrets.hetzner-api-key = { + sopsFile = ../secrets.yaml; + owner = "acme"; + }; + #sops.secrets."domain_key_jalr.de" = { + # sopsFile = ../secrets.yaml; + # owner = "rspamd"; + #}; jalr = { mailserver = { enable = true; @@ -24,18 +31,13 @@ in messageSizeLimit = 50 * 1024 * 1024; }; }; - services.postfix = { - config = { - smtp_bind_address = "159.69.103.126"; - smtp_bind_address_enforce = true; - }; - masterConfig.smtp.args = [ - "-o" - "inet_protocols=ipv4" - ]; + services.postfix.config = { + smtp_bind_address = "159.69.103.126"; + smtp_bind_address_enforce = true; }; - services.nginx.virtualHosts."hha.jalr.de" = { - enableACME = true; - forceSSL = true; + + security.acme.certs."hha.jalr.de" = { + dnsProvider = "hetzner"; + credentialsFile = pkgs.writeText "certbotCredentialsFile" "HETZNER_API_KEY_FILE=${config.sops.secrets.hetzner-api-key.path}"; }; } diff --git a/hosts/iron/services/matrix.nix b/hosts/iron/services/matrix.nix index aa050d9..02984ad 100644 --- a/hosts/iron/services/matrix.nix +++ b/hosts/iron/services/matrix.nix @@ -1,12 +1,15 @@ -{ config, pkgs, ... }: +args@{ config, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; - signalPhoneNumber = "+4915566437153"; - signalUser = "jalr"; + ports = import ../ports.nix args; in { - sops.secrets.synapse-turn-shared-secret.owner = "matrix-synapse"; + sops.secrets = { + synapse-turn-shared-secret = { + owner = "matrix-synapse"; + sopsFile = ../secrets.yaml; + }; + }; jalr.matrix = { enable = true; fqdn = "matrix.jalr.de"; @@ -16,6 +19,17 @@ in host = "turn.jalr.de"; sharedSecretFile = config.sops.secrets.synapse-turn-shared-secret.path; }; + mautrix-whatsapp = { + enable = true; + port = ports.mautrix-whatsapp.tcp; + settings.bridge.permissions = { + # Only one user since using the name from the address book does not + # work with multiple users + #"@jalr:jalr.de" = 100; + "@jalr:jalr.de" = "admin"; + "jalr.de" = "user"; + }; + }; mautrix-signal = { enable = true; port = ports.mautrix-signal.tcp; @@ -29,27 +43,4 @@ in }; }; }; - - systemd.services.signal-cli-receive = { - description = "Run signal-cli to receive messages"; - serviceConfig = { - Type = "oneshot"; - User = signalUser; - CapabilityBoundingSet = null; - RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; - RestrictNamespaces = true; - SystemCallFilter = "@system-service"; - }; - script = "${pkgs.signal-cli}/bin/signal-cli -u ${signalPhoneNumber} receive"; - }; - systemd.timers.signal-cli-receive = { - description = "Run signal-cli to receive messages"; - after = [ "network.target" ]; - wantedBy = [ "timers.target" ]; - timerConfig = { - Persistent = true; - OnCalendar = "*-*-* *:00:00"; - Unit = config.systemd.services.signal-cli-receive.name; - }; - }; } diff --git a/hosts/iron/services/navidrome.nix b/hosts/iron/services/navidrome.nix index d001dfb..4f1044a 100644 --- a/hosts/iron/services/navidrome.nix +++ b/hosts/iron/services/navidrome.nix @@ -1,13 +1,12 @@ -{ config, lib, pkgs, ... }: +args@{ config, lib, pkgs, utils, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; settings = { # https://www.navidrome.org/docs/usage/configuration-options/#available-options Address = "127.0.0.1"; Port = ports.navidrome.tcp; DevActivityPanel = false; - MusicFolder = "/var/lib/navidrome/music"; }; passwordEncryptionKeyFile = config.sops.secrets.navidrome-password-encryption-key.path; configFile = (pkgs.formats.json { }).generate "navidrome.json" settings; @@ -18,18 +17,21 @@ let if [ -e "''$password_encryption_key_file" ]; then export ND_PASSWORDENCRYPTIONKEY="$(cat "''$password_encryption_key_file")" fi - exec ${config.services.navidrome.package}/bin/navidrome --configfile ${configFile} + exec ${pkgs.navidrome}/bin/navidrome --configfile ${configFile} ''; in { services.navidrome.enable = true; systemd.services.navidrome = { serviceConfig = { - ExecStart = lib.mkForce "${pkgs.writeShellScript "navidrome-start" script} %d"; + ExecStart = lib.mkForce "${utils.systemdUtils.lib.makeJobScript "navidrome-start" script} %d"; } // lib.attrsets.optionalAttrs (passwordEncryptionKeyFile != null) { LoadCredential = "PasswordEncryptionKey:${passwordEncryptionKeyFile}"; }; }; + sops.secrets.navidrome-password-encryption-key = { + sopsFile = ../secrets.yaml; + }; services.nginx.virtualHosts."navidrome.jalr.de" = { enableACME = true; forceSSL = true; diff --git a/hosts/iron/services/nginx.nix b/hosts/iron/services/nginx.nix index 6eb78ee..71bdff2 100644 --- a/hosts/iron/services/nginx.nix +++ b/hosts/iron/services/nginx.nix @@ -1,7 +1,7 @@ -{ config, ... }: +args@{ pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; in { services.nginx = { diff --git a/hosts/iron/services/ntp.nix b/hosts/iron/services/ntp.nix index b10a245..edf7dbf 100644 --- a/hosts/iron/services/ntp.nix +++ b/hosts/iron/services/ntp.nix @@ -1,3 +1,4 @@ +{ lib, pkgs, ... }: { services.chrony = { enable = true; diff --git a/hosts/iron/services/photoprism.nix b/hosts/iron/services/photoprism.nix deleted file mode 100644 index b4dfb05..0000000 --- a/hosts/iron/services/photoprism.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ config, lib, pkgs, ... }: -let - domain = "media.weinturm-open-air.de"; - nextcloudDomain = "cloud.weinturm-open-air.de"; - inherit (config.networking) ports; - cfg = config.services.photoprism; - readSecretWrapper = pkgs.writeShellScriptBin "photoprism" '' - export PHOTOPRISM_OIDC_SECRET=$(cat "$CREDENTIALS_DIRECTORY/PHOTOPRISM_OIDC_SECRET_FILE") - - tagline[0]="Dein Blick. Unser Festival." - tagline[1]="Zeig uns das Festival durch deine Linse!" - tagline[2]="Gemeinsam festgehalten – Festivalmomente von euch für alle." - tagline[3]="Mach’s unvergesslich – lade deine Festivalfotos hoch!" - tagline[4]="Die besten Shots kommen von dir – teile sie hier." - tagline[5]="Jede Perspektive zählt – dein Foto, unser Highlight." - tagline[6]="Klick. Hochladen. Festivalgeschichte schreiben." - tagline[7]="Von der Crowd für die Crowd – Festivalfotos zum Verlieben." - tagline[8]="Dein Beitrag zum Festival-Archiv – jetzt Fotos teilen!" - tagline[9]="Weil kein Moment verloren gehen darf – deine Kamera zählt." - - size=''${#tagline[@]} - index=$(($RANDOM % $size)) - export PHOTOPRISM_SITE_CAPTION="''${tagline[$index]}" - - exec ${pkgs.photoprism}/bin/photoprism "$@" - ''; -in -{ - systemd.services.photoprism.serviceConfig.LoadCredential = lib.mkForce "PHOTOPRISM_OIDC_SECRET_FILE:${config.sops.secrets."photoprism/oidc-secret".path}"; - - services.photoprism = { - enable = true; - originalsPath = "/weinturm/photoprism"; - port = ports.photoprism.tcp; - package = readSecretWrapper; - settings = { - PHOTOPRISM_SITE_URL = "https://${domain}/"; - PHOTOPRISM_OIDC_URI = "https://${nextcloudDomain}"; - PHOTOPRISM_OIDC_CLIENT = "WnqjmaPJ5c0dY7KaWmvXVVgJYNjztqTKBZ6Wq6bjYXGOwM2Xuzx2WabFlnJVRCSE"; # Client ID from settings - PHOTOPRISM_OIDC_SCOPES = "openid profile email roles"; - PHOTOPRISM_OIDC_PROVIDER = "Nextcloud"; - PHOTOPRISM_OIDC_ICON = "https://${nextcloudDomain}/apps/theming/image/logo"; - PHOTOPRISM_OIDC_REDIRECT = "true"; - PHOTOPRISM_OIDC_REGISTER = "true"; - PHOTOPRISM_OIDC_USERNAME = "preferred_username"; - PHOTOPRISM_OIDC_WEBDAV = "true"; - PHOTOPRISM_ORIGINALS_LIMIT = toString (20 * 1024); # maximum size of media files in MB - PHOTOPRISM_INDEX_SCHEDULE = "@every 4h"; - PHOTOPRISM_DEFAULT_LOCALE = "de"; - PHOTOPRISM_DEFAULT_TIMEZONE = "Europe/Berlin"; - PHOTOPRISM_SITE_TITLE = "Weinturm Medien"; - PHOTOPRISM_SITE_CAPTION = ""; - PHOTOPRISM_SITE_AUTHOR = "Jugend- und Kultur Förderverein e.V."; - }; - }; - - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - - locations = { - "/" = { - proxyPass = "http://127.0.0.1:${toString cfg.port}"; - proxyWebsockets = true; - }; - }; - }; -} diff --git a/hosts/iron/services/prometheus.nix b/hosts/iron/services/prometheus.nix deleted file mode 100644 index 5d571bc..0000000 --- a/hosts/iron/services/prometheus.nix +++ /dev/null @@ -1,207 +0,0 @@ -{ config -, lib -, pkgs -, ... -}: -let - #domain = ""; - cfg = config.services.prometheus; - mkStaticTargets = targets: lib.singleton { inherit targets; }; - inherit (config.networking) ports; - blackboxRelabelConfig = [ - { - source_labels = [ "__address__" ]; - target_label = "__param_target"; - } - { - source_labels = [ "__param_target" ]; - target_label = "instance"; - } - { - target_label = "__address__"; - replacement = with config.services.prometheus.exporters.blackbox; "${listenAddress}:${toString port}"; - } - ]; -in -{ - #sops.secrets.prometheus-htpasswd = { - # owner = "nginx"; - # sopsFile = ../secrets.yaml; - #}; - - services.prometheus = { - enable = true; - listenAddress = "127.0.0.1"; - #webExternalUrl = "https://${domain}"; - globalConfig = { - scrape_interval = "15s"; - evaluation_interval = "15s"; - }; - extraFlags = [ - "--storage.tsdb.retention.time=90d" - "--web.enable-admin-api" - ]; - scrapeConfigs = [ - { - job_name = "node"; - static_configs = [ - { - targets = with config.services.prometheus.exporters.node; [ - "${listenAddress}:${toString port}" - ]; - } - ]; - relabel_configs = [ - { - source_labels = [ "__address__" ]; - target_label = "instance"; - replacement = config.networking.hostName; - } - ]; - } - { - job_name = "vodafone_station"; - static_configs = mkStaticTargets [ - "127.0.0.1:${toString ports.prometheus-vodafone-station-exporter.tcp}" - ]; - } - { - job_name = "unifi"; - static_configs = mkStaticTargets [ - "${cfg.exporters.unpoller.listenAddress}:${toString cfg.exporters.unpoller.port}" - ]; - } - { - job_name = "blackbox"; - metrics_path = "/probe"; - params.module = [ "http_2xx" ]; - static_configs = [ - { - targets = [ - "https://c58r0l3wtmqltl4y.myfritz.net:44919/" - ]; - } - ]; - relabel_configs = blackboxRelabelConfig; - } - { - job_name = "internet_ip4"; - static_configs = mkStaticTargets [ "1.1.1.1" "8.8.8.8" ]; - metrics_path = "/probe"; - params.module = [ "icmp_ip4" ]; - relabel_configs = blackboxRelabelConfig; - } - { - job_name = "internet_ip6"; - static_configs = mkStaticTargets [ "2606:4700:4700::1111" "2001:4860:4860::8888" ]; - metrics_path = "/probe"; - params.module = [ "icmp_ip6" ]; - relabel_configs = blackboxRelabelConfig; - } - ]; - - exporters = { - node.enable = true; - - blackbox = { - enable = true; - listenAddress = "127.0.0.1"; - - # https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md - configFile = pkgs.writeText "prometheus-blackbox-config" (builtins.toJSON { - modules = { - icmp_ip4 = { - prober = "icmp"; - timeout = "5s"; - icmp = { - ip_protocol_fallback = false; - preferred_ip_protocol = "ip4"; - }; - }; - icmp_ip6 = { - prober = "icmp"; - timeout = "5s"; - icmp = { - ip_protocol_fallback = false; - preferred_ip_protocol = "ip6"; - }; - }; - http_2xx = { - prober = "http"; - timeout = "5s"; - http = { - valid_http_versions = [ "HTTP/1.1" "HTTP/2.0" ]; - valid_status_codes = [ ]; # Defaults to 2xx - method = "GET"; - follow_redirects = true; - fail_if_ssl = false; - fail_if_not_ssl = true; - tls_config = { - insecure_skip_verify = false; - }; - preferred_ip_protocol = "ip4"; # defaults to "ip6" - ip_protocol_fallback = false; # no fallback to "ip6" - }; - }; - }; - }); - }; - }; - }; - - /* - */ - # - - systemd.services.prometheus-vodafone-station-exporter = - let - unitName = "prometheus-vodafone-station-exporter"; - in - { - enable = true; - description = "Prometheus Vodafone Station exporter"; - wants = [ "network.target" ]; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - BindReadOnlyPaths = [ - "/nix/store" - "/etc/resolv.conf" - ]; - DynamicUser = "yes"; - ExecStart = lib.strings.concatStringsSep " " [ - "${pkgs.vodafone-station-exporter}/bin/vodafone-station-exporter" - "-web.listen-address" - "127.0.0.1:${toString ports.prometheus-vodafone-station-exporter.tcp}" - "-vodafone.station-url" - "http://192.168.100.1" - "-vodafone.station-password-file" - "\${CREDENTIALS_DIRECTORY}/password" - ]; - LoadCredential = "password:${config.sops.secrets."prometheus/exporters/vodafone-station".path}"; - NoNewPrivileges = true; - PrivateTmp = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; - RestrictNamespaces = true; - RootDirectory = "%t/${unitName}"; - RuntimeDirectory = [ unitName ]; - }; - }; - - /* - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - - #basicAuthFile = config.sops.secrets.prometheus-htpasswd.path; - - locations = { - "/".proxyPass = "http://${cfg.listenAddress}:${toString cfg.port}"; - }; - }; - */ -} diff --git a/hosts/iron/services/public-ip-tunnel.nix b/hosts/iron/services/public-ip-tunnel.nix index d6b4fcc..2e1dca8 100644 --- a/hosts/iron/services/public-ip-tunnel.nix +++ b/hosts/iron/services/public-ip-tunnel.nix @@ -1,7 +1,7 @@ -{ config, lib, ... }: +args@{ config, lib, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; listenPort = ports.wireguard-public-ip-tunnel.udp; remoteHost = "magnesium.jalr.de"; remotePort = 51000; @@ -13,38 +13,46 @@ let }; in { - networking = { - iproute2 = { - enable = true; - rttablesExtraConfig = '' - ${toString rtTable.id} ${rtTable.name} + sops.secrets = ( + lib.listToAttrs (map + (name: lib.nameValuePair "wireguard_key_${name}" { + sopsFile = ../secrets.yaml; + }) + [ + "hetzner-ha" + ] + ) + ); + + networking.iproute2.enable = true; + networking.iproute2.rttablesExtraConfig = '' + ${toString rtTable.id} ${rtTable.name} + ''; + + networking.wireguard.interfaces = { + hetzner-ha = { + ips = [ "${externalIp}/32" ]; + privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path; + listenPort = listenPort; + table = rtTable.name; + postSetup = '' + ${pkgs.iproute2}/bin/ip rule add from ${externalIp} to 192.168.0.0/16 table main priority 10 + ${pkgs.iproute2}/bin/ip rule add from ${externalIp} table ${rtTable.name} priority 20 ''; - }; - firewall.allowedUDPPorts = [ listenPort ]; - wireguard.interfaces.hetzner-ha = - let - addRule = rule: "ip rule add " + rule; - deleteRule = rule: "ip rule delete " + rule; - rules = [ - "from ${externalIp} to 192.168.0.0/16 table main priority 10" - "from ${externalIp} table ${rtTable.name} priority 20" + postShutdown = '' + ${pkgs.iproute2}/bin/ip rule del from ${externalIp} to 192.168.0.0/16 table main priority 10 + ${pkgs.iproute2}/bin/ip rule del from ${externalIp} table ${rtTable.name} priority 20 + ''; + peers = [{ + publicKey = publicKey; + endpoint = "${remoteHost}:${toString remotePort}"; + persistentKeepalive = 25; + allowedIPs = [ + "0.0.0.0/0" ]; - in - { - ips = [ "${externalIp}/32" ]; - privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path; - inherit listenPort; - table = rtTable.name; - postSetup = lib.concatLines (map addRule rules); - postShutdown = lib.concatLines (map deleteRule rules); - peers = [{ - inherit publicKey; - endpoint = "${remoteHost}:${toString remotePort}"; - persistentKeepalive = 25; - allowedIPs = [ - "0.0.0.0/0" - ]; - }]; - }; + }]; + }; }; + + networking.firewall.allowedUDPPorts = [ listenPort ]; } diff --git a/hosts/iron/services/radicale.nix b/hosts/iron/services/radicale.nix index d6cb95d..bf5196d 100644 --- a/hosts/iron/services/radicale.nix +++ b/hosts/iron/services/radicale.nix @@ -1,30 +1,29 @@ -{ config, ... }: +args@{ config, lib, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; in { - sops.secrets.radicale-htpasswd.owner = "nginx"; + sops.secrets.radicale-htpasswd = { + owner = "nginx"; + sopsFile = ../secrets.yaml; + }; services.nginx.virtualHosts = { "cal.jalr.de" = { enableACME = true; forceSSL = true; basicAuthFile = config.sops.secrets.radicale-htpasswd.path; - locations = { - "/radicale/" = { - proxyPass = "http://127.0.0.1:${toString ports.radicale.tcp}/"; - recommendedProxySettings = true; - #basicAuthFile = ""; - extraConfig = '' - proxy_set_header X-Script-Name /radicale; - proxy_set_header X-Remote-User $remote_user; - ''; - # proxy_pass_request_headers = on; - # underscores_in_headers = on; - }; - "/.well-known/caldav".return = "301 $scheme://$host:$server_port/radicale"; - "/.well-known/carddav".return = "301 $scheme://$host:$server_port/radicale"; + locations."/radicale/" = { + proxyPass = "http://127.0.0.1:${toString ports.radicale.tcp}/"; + recommendedProxySettings = true; + #basicAuthFile = ""; + extraConfig = '' + proxy_set_header X-Script-Name /radicale; + proxy_set_header X-Remote-User $remote_user; + ''; + # proxy_pass_request_headers = on; + # underscores_in_headers = on; }; }; }; diff --git a/hosts/iron/services/remarkable.nix b/hosts/iron/services/remarkable.nix index dc38c83..a7b6cad 100644 --- a/hosts/iron/services/remarkable.nix +++ b/hosts/iron/services/remarkable.nix @@ -1,11 +1,11 @@ -{ lib, config, pkgs, ... }: +args@{ lib, config, pkgs, custom-utils, ... }: let - inherit (config.networking) ports; + ports = import ../ports.nix args; domain = "rmfakecloud.jalr.de"; cfg = config.services.rmfakecloud; - mkEnvironment = settings: lib.strings.concatLines ( + mkEnvironment = (settings: lib.strings.concatLines ( lib.attrsets.mapAttrsToList (name: value: "export ${name}='${value}'") settings - ); + )); managementScript = pkgs.writeShellScriptBin "rmfakecloud" '' [[ $(id -u) == "rmfakecloud" ]] || exec sudo -u rmfakecloud -- "$0" "$@" set -a @@ -16,6 +16,7 @@ let in { sops.secrets.rmfakecloud = { + sopsFile = ../secrets.yaml; owner = "root"; group = "root"; mode = "0400"; diff --git a/hosts/iron/services/snapcast/bluetooth-sink.nix b/hosts/iron/services/snapcast/bluetooth-sink.nix deleted file mode 100644 index 43db142..0000000 --- a/hosts/iron/services/snapcast/bluetooth-sink.nix +++ /dev/null @@ -1,79 +0,0 @@ -{ pkgs, ... }: -{ - environment.systemPackages = with pkgs; [ - #bluez-alsa - bluez - bluez-tools - pipewire - wireplumber - ]; - - hardware.bluetooth = { - enable = true; - settings = { - General = { - Enable = "Source,Sink,Media,Socket"; - Class = "0x00041C"; - # Pairing always on - AlwaysPairable = "true"; - # Don't disable discoverability after timeout - DiscoverableTimeout = "0"; - # Faster but uses more power - FastConnectable = "true"; - # Allow repairing of existing devices - JustWorksRepairing = "always"; - # to show battery state - Experimental = true; - }; - }; - }; - - services = { - blueman.enable = true; - ofono.enable = true; - upower.enable = true; - }; - - systemd.services = { - bluetooth-auto-pair = { - wantedBy = [ "bluetooth.service" ]; - after = [ "bluetooth.service" ]; - bindsTo = [ "bluetooth.service" ]; - serviceConfig = { - Type = "simple"; - ExecStart = pkgs.writeShellScript "exec-start" '' - ${pkgs.bluez}/bin/bluetoothctl < /dev/null; do - sleep 1 - done - - echo "Sleeping..." - sleep 5m - - echo "Shutting down Android" - adb -s "$host:$port" shell -- reboot -p - ''; - }; - }; - systemd.timers."whatsapp-${vmName}" = { - description = "Start Android VM to run WhatsApp"; - after = [ "network.target" ]; - wantedBy = [ "timers.target" ]; - timerConfig = { - Persistent = true; - OnCalendar = "*-*-* 2:00:00"; - Unit = "whatsapp@${vmName}.service"; - }; - }; -} diff --git a/hosts/iron/services/wireguard-esphome.nix b/hosts/iron/services/wireguard-esphome.nix deleted file mode 100644 index db8fca9..0000000 --- a/hosts/iron/services/wireguard-esphome.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ config, ... }: - -let - inherit (config.networking) ports; - listenPort = ports.wireguard-esphome.udp; -in -{ - networking = { - firewall.allowedUDPPorts = [ listenPort ]; - wireguard.interfaces.esphome = { - ips = [ "10.20.16.1/30" ]; - privateKeyFile = config.sops.secrets."wireguard_key/esphome".path; - inherit listenPort; - peers = [{ - publicKey = "WM5qDvEF+tInUhzzF5msUwBy8WRyQOuxYX7roNcqNRc="; - persistentKeepalive = 120; - allowedIPs = [ "10.20.16.2" ]; - }]; - }; - }; -} diff --git a/hosts/jalr-t520/configuration.nix b/hosts/jalr-t520/configuration.nix index e10957b..f34a5fc 100644 --- a/hosts/jalr-t520/configuration.nix +++ b/hosts/jalr-t520/configuration.nix @@ -1,42 +1,62 @@ -{ lib, pkgs, ... }: +{ config, pkgs, ... }: { imports = [ - ./disko.nix - ../../users/jalr + ./hardware-configuration.nix + ../../home-manager/users/jalr.nix ]; networking = { hostName = "jalr-t520"; + networkmanager.enable = true; useDHCP = false; }; - jalr = { - bootloader = "systemd-boot"; - bluetooth.enable = true; - gui = { - enable = true; - sway.enable = true; - gnome.enable = true; - }; - workstation.enable = true; - }; - - hardware = { - cpu.intel.updateMicrocode = true; - firmware = [ pkgs.linux-firmware ]; - }; - - powerManagement.cpuFreqGovernor = "performance"; - + # List packages installed in system profile. To search, run: + # $ nix search wget environment.systemPackages = with pkgs; [ - intel-media-driver - libva - libva-utils - libva1 + gnome3.adwaita-icon-theme ]; - hardware.graphics.extraPackages = lib.singleton pkgs.vaapiIntel; + environment.variables.EDITOR = "nvim"; + + programs.mtr.enable = true; + programs.wireshark.enable = true; + + hardware.sane.enable = true; + + services.udisks2.enable = true; + + services.avahi.enable = true; + services.avahi.nssmdns = true; + + services.udev.extraRules = '' + # 16C0:0442 - Axoloti Core + SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0442", MODE:="0666" + # 0483:df11 - Axoloti Core (STM32 microcontroller) in DFU mode + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666" + + # Samsung A5 + SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", ATTRS{idProduct}=="6860", GROUP="dialout", MODE="0660" + ''; + + jalr = { + bootloader = "grub2"; + bluetooth.enable = true; + gui.enable = true; + workstation.enable = true; + sdr.enable = true; + libvirt.enable = true; + autologin.enable = true; + autologin.username = "jalr"; + }; + + # 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 = "23.11"; # Did you read the comment? - system.stateVersion = "25.05"; } diff --git a/hosts/jalr-t520/disko.nix b/hosts/jalr-t520/disko.nix deleted file mode 100644 index e75beca..0000000 --- a/hosts/jalr-t520/disko.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ config, ... }: -let - cfg = config.disko; -in -{ - disko.devices = { - disk = { - system = { - type = "disk"; - device = "/dev/disk/by-id/ata-Samsung_SSD_850_EVO_120GB_S21UNSAG200527E"; - content = { - type = "gpt"; - partitions = { - esp = { - type = "EF00"; - size = "1024M"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - mountOptions = [ "uid=0" "gid=0" "fmask=0077" "dmask=0077" "nodev" "nosuid" "noexec" ]; - }; - }; - nixos = { - size = "100%"; - content = { - type = "btrfs"; - extraArgs = [ "-f" ]; - subvolumes = { - "/root" = { - mountpoint = "/"; - mountOptions = [ "compress-force=zstd:1" "noatime" ]; - }; - "/home" = { - mountpoint = "/home"; - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - "/home/.snapshots" = { - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - "/nix" = { - mountpoint = "/nix"; - mountOptions = [ "compress-force=zstd:1" "noatime" "noatime" "nodev" ]; - }; - }; - postCreateHook = - let - inherit (cfg.devices.disk.system.content.partitions.nixos) device; - in - '' - mountpoint="$(mktemp -d)" - mount "${device}" "$mountpoint" -o subvol=/ - trap 'umount "$mountpoint"; rmdir "$mountpoint"' EXIT - btrfs subvolume snapshot -r $mountpoint/root $mountpoint/root-blank - ''; - }; - }; - }; - }; - }; - }; - }; -} - - diff --git a/hosts/jalr-t520/hardware-configuration.nix b/hosts/jalr-t520/hardware-configuration.nix new file mode 100644 index 0000000..7de2199 --- /dev/null +++ b/hosts/jalr-t520/hardware-configuration.nix @@ -0,0 +1,61 @@ +{ lib, pkgs, modulesPath, ... }: + +{ + imports = [ + "${modulesPath}/installer/scan/not-detected.nix" + ]; + + boot = { + initrd = { + availableKernelModules = [ + "aes_generic" + "aesni_intel" + "ahci" + "cryptd" + "ehci_pci" + "firewire_ohci" + "i915" + "sd_mod" + "sdhci_pci" + "usb_storage" + "usbhid" + ]; + kernelModules = [ "dm-snapshot" ]; + luks.devices = { + pvcrypt = { + device = "/dev/disk/by-uuid/3a1a8fec-b028-45c0-8432-7fcbe4615f44"; + preLVM = true; + }; + }; + }; + kernelModules = [ "kvm-intel" ]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/62e31097-dc6e-4f91-a043-1a6b8a154201"; + fsType = "ext4"; + }; + "/boot" = { + device = "/dev/disk/by-uuid/c4df83d7-8985-47df-b5cd-bf18bd490a50"; + fsType = "ext2"; + options = [ "nodev" "nosuid" "noexec" ]; + }; + }; + + boot.loader.grub.devices = [ "/dev/disk/by-id/ata-INTEL_SSDSC2BB016T4_BTWD531101JM1P6HGN" ]; + + nix.settings.max-jobs = 4; + + hardware.cpu.intel.updateMicrocode = true; + + powerManagement.cpuFreqGovernor = "performance"; + + environment.systemPackages = with pkgs; [ + intel-media-driver + libva + libva-utils + libva1 + ]; + hardware.opengl.extraPackages = lib.singleton pkgs.vaapiIntel; +} diff --git a/hosts/magnesium/configuration.nix b/hosts/magnesium/configuration.nix index 626f0b8..1bbbf96 100644 --- a/hosts/magnesium/configuration.nix +++ b/hosts/magnesium/configuration.nix @@ -1,32 +1,60 @@ -{ lib, ... }: +{ config, lib, pkgs, ... }: { imports = [ - ../../modules/providers/hetzner-cloud.nix + ./hardware-configuration.nix + ../../home-manager/users/jalr.nix ./services - ../../users/jalr - ./persistence.nix - ./ports.nix ]; networking.hostName = "magnesium"; - - disko.devices.disk.virt.device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_60640534"; - + services.openssh.enable = true; security.sudo.wheelNeedsPassword = false; - systemd.network.networks."10-wan".address = [ - "2a01:4f8:c013:bab7::1/64" - ]; + networking.useDHCP = false; - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - - zramSwap = { + systemd.network = { enable = true; - algorithm = "zstd"; - memoryPercent = 60; - priority = 1; + networks."10-wan" = { + matchConfig.Name = "enp1s0"; + networkConfig.DHCP = "no"; + address = [ + "162.55.35.199/32" + "2a01:4f8:c012:21ba::/64" + ]; + routes = [ + { + routeConfig.Destination = "172.31.1.1"; + } + { + routeConfig = { + Gateway = "172.31.1.1"; + GatewayOnLink = true; + }; + } + { + routeConfig.Gateway = "fe80::1"; + } + ]; + }; }; - system.stateVersion = "24.11"; + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + jalr = { + bootloader = "systemd-boot"; + uefi.enable = true; + }; + + # 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 = "23.11"; # Did you read the comment? + } + diff --git a/hosts/magnesium/hardware-configuration.nix b/hosts/magnesium/hardware-configuration.nix new file mode 100644 index 0000000..2c6ccd7 --- /dev/null +++ b/hosts/magnesium/hardware-configuration.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/45dcac99-1f65-48ab-b5bf-8a1507f0b75a"; + fsType = "btrfs"; + options = [ + "subvol=root" + "compress=zstd" + ]; + }; + "/proc" = { + device = "/proc"; + options = [ "nosuid" "noexec" "nodev" "hidepid=2" ]; + }; + "/home" = { + device = "/dev/disk/by-uuid/45dcac99-1f65-48ab-b5bf-8a1507f0b75a"; + fsType = "btrfs"; + options = [ + "subvol=home" + "compress=zstd" + "nodev" + "nosuid" + ]; + }; + "/nix" = { + device = "/dev/disk/by-uuid/45dcac99-1f65-48ab-b5bf-8a1507f0b75a"; + fsType = "btrfs"; + options = [ + "subvol=nix" + "compress=zstd" + "noatime" + "nodev" + ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/7836-0C48"; + fsType = "vfat"; + options = [ "nodev" "nosuid" "noexec" ]; + }; + }; + + swapDevices = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; +} diff --git a/hosts/magnesium/persistence.nix b/hosts/magnesium/persistence.nix deleted file mode 100644 index 9d8ef4a..0000000 --- a/hosts/magnesium/persistence.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ config, lib, ... }: -{ - boot.initrd.postDeviceCommands = - let - inherit (config.disko.devices.disk.virt.content.partitions.linux) device; - in - lib.mkAfter '' - mkdir /mnt - mount -t btrfs "${device}" /mnt - btrfs subvolume list -o /mnt/root | cut -f9 -d' ' | while read subvolume; do - btrfs subvolume delete "/mnt/$subvolume" - done - btrfs subvolume delete /mnt/root - btrfs subvolume snapshot /mnt/root-blank /mnt/root - ''; - - services = { - openssh = { - hostKeys = lib.mkForce [{ - path = "/persist/etc/ssh/ssh_host_ed25519_key"; - type = "ed25519"; - }]; - }; - forgejo.stateDir = "/persist/var/lib/forgejo"; - postgresql.dataDir = "/persist/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}"; - }; - - fileSystems."/persist".neededForBoot = true; - environment.persistence."/persist" = { - hideMounts = true; - directories = [ - "/var/lib/acme" - "/var/lib/hedgedoc" - "/var/lib/nixos" - "/var/lib/private/mealie" - "/var/lib/private/ntfy-sh" - { - directory = "/var/lib/private/tandoor-recipes"; - user = "tandoor_recipes"; - group = "tandoor_recipes"; - mode = "u=rwx,g=rx,o="; - } - { - directory = "/var/lib/trilium"; - user = "trilium"; - group = "trilium"; - mode = "u=rwx,g=rx,o="; - } - ]; - }; -} diff --git a/hosts/magnesium/ports.nix b/hosts/magnesium/ports.nix index fd74f41..b35165c 100644 --- a/hosts/magnesium/ports.nix +++ b/hosts/magnesium/ports.nix @@ -1,19 +1,12 @@ -{ custom-utils, ... }: +{ lib, custom-utils, ... }: -{ - config.networking.ports = custom-utils.validatePortAttrset { - coturn-cli.tcp = 5766; - coturn-plain = { tcp = [ 3478 3479 ]; udp = [ 3478 3479 ]; }; - coturn-relay.udp = { from = 49160; to = 49200; }; - coturn-tls = { tcp = [ 5349 5350 ]; udp = [ 5349 5350 ]; }; - forgejo-ssh.tcp = 2022; - hedgedoc.tcp = 3000; - mealie.tcp = 9000; - nginx-http.tcp = 80; - nginx-https.tcp = 443; - ntfy.tcp = 12474; - tandoor.tcp = 9001; - trilium.tcp = 12783; - wireguard-public-ip-tunnel.udp = 51000; - }; +custom-utils.validatePortAttrset { + coturn-cli.tcp = 5766; + coturn-plain = { tcp = [ 3478 3479 ]; udp = [ 3478 3479 ]; }; + coturn-relay.udp.range = [ 49160 49200 ]; + coturn-tls = { tcp = [ 5349 5350 ]; udp = [ 5349 5350 ]; }; + mosquitto.tcp = 1883; + nginx-http.tcp = 80; + nginx-https.tcp = 443; + wireguard-public-ip-tunnel.udp = 51000; } diff --git a/hosts/magnesium/secrets.yaml b/hosts/magnesium/secrets.yaml index 92851b1..32a9318 100644 --- a/hosts/magnesium/secrets.yaml +++ b/hosts/magnesium/secrets.yaml @@ -1,39 +1,34 @@ wireguard_key_hetzner-ha: ENC[AES256_GCM,data:HEW+EalHg6/mq7pRKZkasGz0nqbkSppkf0H/uV5QMJnWwKw9a9W21Y77OSw=,iv:OA6yml1T5kVafX0RYd0Es7DHcGjJazUxP2M6a5Pwkag=,tag:lX5UPIseIQ136HLrHbzZyw==,type:str] turn-static-auth-secret: ENC[AES256_GCM,data:rzhixUemFPwKj1BcVPZd7KtUO9OA6A2R4qEQ1BZGVG0=,iv:uYHYe4Cywxovt3b/Ho1tQVHrpgVic+AKh9AjYMYSZcM=,tag:rr8RW/if06t38GpZCYQB4w==,type:str] gitlab-runner_fablab-nea-hcloud-labsync: ENC[AES256_GCM,data:+znVO8cQxjDdhch7oUALZvt84iJmWnAx6lTM0+WGkGtaRWTCTPjgnst5waSJpw/Oysrd1PkXZKmLHyHuU7K/CHQij7sWH50G3ZcUum58klJc3dCPztlrLpDVHeSwyYiLpsqkQTfjqLPfrMkxuxBgTEVXlq2ZnFuyOGbFx9hubPxLeyQKakiW3qZWGjbFXYAps7Gl61AVdKJj3y1otX2JbCjG9x2i6FHZpl5ywwQCjKNM,iv:7v+I/oJtWDap6PNIJ4Qm3Si9dGs7a79SaMhnr/tbe1A=,tag:7jgoLtdWAEKMkWoXZ10owA==,type:str] -forgejo-mail: ENC[AES256_GCM,data:eZv9dM0a06wFJaDUZjo=,iv:L32ab5k/AX8HqSACJA5w+WbzLlBijA5++Gcr2SrnYIU=,tag:ddyTXikWTMnxq86IijgyYg==,type:str] -hedgedoc-session-secret: ENC[AES256_GCM,data:AYUiUF7R+5C3F5kNRL0R95e1l3Y59tIP388uY0IYCskBhR0H0XMVvyrX/gIM33Twwkc5it+fQtNPNXsbrAnoKQ==,iv:Q6pDEdFplp845/DCHutwni/g7Ch39pTCvfNs4Eh28CQ=,tag:aqVGs3iThmepT7iJusLOMA==,type:str] -mealie: ENC[AES256_GCM,data:4LlxJjDstTPZCD7Xyb+0CRkeDafP9a9oMuYDnXznINe+LrfkJGKwQIwP0B3VpeMmZ0Rwe7Tvje0ZWySFGADireb2r7TjDyASAoXJDyNNJ8byRc5Zt77zL2dp/W4xVt8WpQvwsXosjDv3NN6we831wWUrfNtp0g34YLqSU3F/9i7AaU7nVKnQ9QtJRVg5O57nhs/ZXopKOBUdiKAmxcl0hNNdQdaQX6xkDCWrV4432IOckqyqEQyd9KeCURuWeTUgPmTmnt9Cj8KkaQ39fd0LAGRjOBsKo4C4,iv:o5BPW4Wcg4KcFkJHc/mdrO4Rh+1nifxulYkF+iM3LEw=,tag:KXwDr3VHxjeHkyo23SPJgA==,type:str] -tandoor: - secret_key: ENC[AES256_GCM,data:8aVuOBljF+vnEXOzi0r2xUtUGlZM50MuBXK70XW78Q9jNq4ZuRciGabnYwFfknb2/tA=,iv:KN7DwcMH5NN5BgWFgO/V1dfSyiHfAM2wS86atYcBdlQ=,tag:wQA7QL8VqP5d4uBSNQLsnQ==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] age: - - recipient: age19qkgfaq08kmyxghet48dq4gxwjuy9zpvuyxys9jkmcqa5634537qlxjcd8 + - recipient: age1swv42gad884z2v75kateem6k2za6ltkq6wu90ewqp6dp7gxprawslwz0w0 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHMW5lbkRNQS9Gc0VUWndk - VlJiczFVM1dHUGc2QWZnMHVIVGZzdWJKUUJzCngyNGxaR2JFNG9HbG81c1ZNSlQ3 - MlgvMlNYWVduY1diM3g2U3BiL0J3U2sKLS0tIHBscWxMTzVISkE5WW1CZTNYK1ZM - elNwdVlJS2NCWUlXcEZvZWsvZ29FRnMK/qa6Qj1yQc91PWk9tMKSyFkMfYcHIKpQ - jcPmGWbpi2NPL/F0Xz2X/zQQxWzs9uzlS1VH+y8JRe1EPMYJ78NXZw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwa0ZIdE9lc2lNZlN0UFBU + RWdxQm1oR01GemJOSE9ZU1RYc3crRGg5REF3ClUzaEhyelZNTVUxeEwvc1V3eDBt + SUx0UXU0aTdnTGlTaWJvd2R6ajZmNVkKLS0tICszejE3WVNOTHR6Rms2bjQrbzEz + Vlk3Y1luTTg3bkpqNTNPUGlNYmNtMW8K9dEUwAuzvDZZoVi8FPZQ7/h75EV0L+VM + MlTGfEt38Hi7EOw+yfXvXYHse/OKypwcrPiJDT6IT/E+O9BJCjPKCA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-04-17T23:26:44Z" - mac: ENC[AES256_GCM,data:Dl4/6wrIwOsCRK979O9lSKyi4LKAG0CfgTGS3RwNu23MvhhaBNru4P1gPWWu7/YC6ad63Ip/RuVB69A1kUmgrYimZcU6E3iPg7vsqskmTU0caMD54CHemj57EYS7r8tcloBEgkOvM6Vn/Bs1dV1/EKAv9Kr6r4x6xb3UOofDcwM=,iv:pzRSKp3EnUpgMdwLDKrExpEkm+uZbU6/pYkVLbcnjrY=,tag:Z6DIPVcNUa8QihV1lsmUMA==,type:str] + lastmodified: "2023-10-13T18:27:53Z" + mac: ENC[AES256_GCM,data:8DPq0aGtoiMOdFyD+0NKGZ9OrDi1VXXS/6y3tH4DwlkLDpDqb2QsxunTDwoHlILQBu300nB2lUeGuGlp4/0FimFdiddlu2Ljq8vLh3wt+sz660RgfeaIcgWLSHtulyNIIQJ91wzzgbRADafFRCavVFvJALnIgeE+QDQa4ybLus0=,iv:T3xwELbHbqDszIkGs8BeJn9WV0LjagF1T+HLxCR/Aeo=,tag:NAIBPTRcnRtkGKhpWpe5Pw==,type:str] pgp: - - created_at: "2025-04-08T22:53:53Z" - enc: |- + - created_at: "2023-06-22T12:44:23Z" + enc: | -----BEGIN PGP MESSAGE----- - hF4DY/xpNY5WhB0SAQdAbrDTh/Nvu8ky1ec34AAkKQcTH1G1nDlUCSfobMQsCmAw - XPI7V41rBAY2m6J1P/0oy9cHVfE/LUi4E/yCgNG7YIGdUbb9x29x7A3uoP1NAhE5 - 0l4BZQGZ+GGa69KZ2mOnWhbKfjtOVNDoaxcpgNWHxrtO35c/tNSCxJ2Uj2Q2u3Nj - +SRaHB3tsF8VL85Tn0FEXSWLzL7SfHj78wvaZ/3AxbqdF7WDJkl1hXEnrf2DjBCC - =Gi/Y + hF4D3ylLYNOsO+0SAQdAD/wwGspjkzL/xlqVxl8pixtRQGAlyuEJdTwja6e4bkAw + I+xwPhJH9FpkwArRKErtW9u6e9lM8zJOvgteseTRmQFkQ9fyTtXAx2lLg5JOFdYn + 0l4BkaozbVKjx1XEJBoBUF1YMfREKyrORk/kU2UTluQKkEp7xaojZkuhWEqEMC7N + tKVpPhef7M5escwcpQCpoI5+DCepJQDfoxyiAWx8P0a6tbV2F+X9y6kgb6iuWpf2 + =WNKv -----END PGP MESSAGE----- - fp: 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 + fp: 66FB54F6081375106EEBF651A222365EB448F934 unencrypted_suffix: _unencrypted - version: 3.9.4 + version: 3.7.3 diff --git a/hosts/magnesium/services/coturn.nix b/hosts/magnesium/services/coturn.nix index bfd6e4a..93479ad 100644 --- a/hosts/magnesium/services/coturn.nix +++ b/hosts/magnesium/services/coturn.nix @@ -1,12 +1,15 @@ -{ config, lib, pkgs, ... }: +args@{ config, lib, pkgs, custom-utils, ... }: let + ports = import ../ports.nix args; cfg = config.services.coturn; fqdn = "turn.jalr.de"; - inherit (config.networking) ports; in { - sops.secrets.turn-static-auth-secret.owner = "turnserver"; + sops.secrets.turn-static-auth-secret = { + owner = "turnserver"; + sopsFile = ../secrets.yaml; + }; services.coturn = ( if ports.coturn-plain.tcp != ports.coturn-plain.udp then builtins.abort "coturn: plain TCP and UDP ports must match." @@ -19,8 +22,8 @@ in tls-listening-port = builtins.elemAt ports.coturn-tls.tcp 0; alt-tls-listening-port = builtins.elemAt ports.coturn-tls.tcp 1; cli-port = ports.coturn-cli.tcp; - min-port = ports.coturn-relay.udp.from; - max-port = ports.coturn-relay.udp.to; + min-port = builtins.elemAt ports.coturn-relay.udp.range 0; + max-port = builtins.elemAt ports.coturn-relay.udp.range 1; } ) // { enable = true; @@ -34,6 +37,9 @@ in no-tcp-relay = true; + cert = "/run/turnserver/fullchain.pem"; + pkey = "/run/turnserver/key.pem"; + no-cli = true; extraConfig = '' @@ -74,19 +80,9 @@ in systemd.services.coturn = { after = [ "acme-finished-${fqdn}.target" ]; serviceConfig = { - Environment = [ - "CERT_FILE=%d/fullchain.pem" - "KEY_FILE=%d/key.pem" - ]; - LoadCredential = [ - "fullchain.pem:${config.security.acme.certs."${fqdn}".directory}/fullchain.pem" - "key.pem:${config.security.acme.certs."${fqdn}".directory}/key.pem" - ]; - ExecStartPre = lib.singleton "${pkgs.writeShellScript "coturn-setup-tls" '' - cat >> /run/coturn/turnserver.cfg << EOF - cert="$CERT_FILE"; - pkey="$KEY_FILE"; - EOF + ExecStartPre = lib.singleton "!${pkgs.writeShellScript "coturn-setup-tls" '' + cp ${config.security.acme.certs."${fqdn}".directory}/{fullchain,key}.pem /run/turnserver/ + chgrp turnserver /run/turnserver/{fullchain,key}.pem ''}"; }; }; @@ -105,6 +101,10 @@ in networking.firewall = { allowedTCPPorts = with cfg; [ listening-port alt-listening-port tls-listening-port alt-tls-listening-port ]; allowedUDPPorts = with cfg; [ listening-port alt-listening-port tls-listening-port alt-tls-listening-port ]; - allowedUDPPortRanges = lib.singleton ports.coturn-relay.udp; + + allowedUDPPortRanges = lib.singleton { + from = builtins.elemAt ports.coturn-relay.udp.range 0; + to = builtins.elemAt ports.coturn-relay.udp.range 1; + }; }; } diff --git a/hosts/magnesium/services/default.nix b/hosts/magnesium/services/default.nix index c257730..0fd2a7f 100644 --- a/hosts/magnesium/services/default.nix +++ b/hosts/magnesium/services/default.nix @@ -1,15 +1,9 @@ { imports = [ ./coturn.nix - ./forgejo.nix ./gitlab-runner.nix - ./hedgedoc.nix - ./it-tools.nix - ./mealie.nix - ./ntfy.nix + ./mosquitto.nix ./public-ip-tunnel.nix - ./tandoor.nix - ./trilium.nix ./webserver.nix ]; } diff --git a/hosts/magnesium/services/forgejo.nix b/hosts/magnesium/services/forgejo.nix deleted file mode 100644 index 4484e16..0000000 --- a/hosts/magnesium/services/forgejo.nix +++ /dev/null @@ -1,69 +0,0 @@ -{ config, ... }: -let - domain = "git.jalr.de"; - cfg = config.services.forgejo; - inherit (config.networking) ports; -in -{ - sops.secrets.forgejo-mail.owner = cfg.user; - services.forgejo = { - enable = true; - lfs.enable = true; - secrets.mailer.PASSWD = config.sops.secrets.forgejo-mail.path; - settings = { - DEFAULT.APP_NAME = "jalr's git"; - avatar.DISABLE_GRAVATAR = true; - mailer = { - ENABLED = true; - PROTOCOL = "smtps"; - SMTP_ADDR = "hha.jalr.de"; - FROM = "git@jalr.de"; - USER = "git@jalr.de"; - }; - server = { - DOMAIN = domain; - PROTOCOL = "http+unix"; - ROOT_URL = "https://${domain}/"; - - DISABLE_ROUTER_LOG = true; - OFFLINE_MODE = true; - - BUILTIN_SSH_SERVER_USER = "git"; - START_SSH_SERVER = true; - SSH_PORT = ports.forgejo-ssh.tcp; - SSH_SERVER_HOST_KEYS = "ssh/forgejo.ed25519"; - }; - service = { - DEFAULT_ALLOW_CREATE_ORGANIZATION = false; - DEFAULT_KEEP_EMAIL_PRIVATE = true; - ENABLE_NOTIFY_MAIL = false; - REGISTER_MANUAL_CONFIRM = true; - DISABLE_REGISTRATION = true; - }; - session = { - PROVIDER = "file"; - COOKIE_SECURE = true; - }; - log.level = "Warn"; - }; - dump = { - enable = true; - type = "tar.zst"; - }; - }; - - networking.firewall.allowedTCPPorts = [ cfg.settings.server.SSH_PORT ]; - - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://unix:/run/forgejo/forgejo.sock"; - }; - - extraConfig = '' - client_max_body_size 1G; - ''; - }; -} diff --git a/hosts/magnesium/services/gitlab-runner.nix b/hosts/magnesium/services/gitlab-runner.nix index ad17690..9f920eb 100644 --- a/hosts/magnesium/services/gitlab-runner.nix +++ b/hosts/magnesium/services/gitlab-runner.nix @@ -1,6 +1,9 @@ -{ config, pkgs, ... }: +{ config, lib, pkgs, ... }: { + sops.secrets.gitlab-runner_fablab-nea-hcloud-labsync = { + sopsFile = ../secrets.yaml; + }; services.gitlab-runner = { enable = true; extraPackages = [ @@ -14,9 +17,13 @@ description = "FabLab NEA Hetzner Cloud - labsync image builder"; limit = 5; executor = "docker+machine"; - authenticationTokenConfigFile = config.sops.secrets.gitlab-runner_fablab-nea-hcloud-labsync.path; + registrationConfigFile = config.sops.secrets.gitlab-runner_fablab-nea-hcloud-labsync.path; dockerImage = "quay.io/official-images/alpine:latest"; dockerPrivileged = true; + tagList = [ + "labsync-image" + ]; + maximumTimeout = 6 * 60 * 60; registrationFlags = [ "--docker-tlsverify" "--machine-idle-nodes 0" @@ -28,7 +35,7 @@ "--machine-machine-name gitlabrunner-%s" ] ++ (map (o: "--machine-machine-options=" + o) [ "hetzner-image=debian-12" - "hetzner-server-type=cx22" + "hetzner-server-type=cx11" "hetzner-server-location=nbg1" ]); }; diff --git a/hosts/magnesium/services/hedgedoc.nix b/hosts/magnesium/services/hedgedoc.nix deleted file mode 100644 index d9ee1b8..0000000 --- a/hosts/magnesium/services/hedgedoc.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ config, ... }: - -let - domain = "pad.jalr.de"; - cfg = config.services.hedgedoc; - inherit (config.networking) ports; -in -{ - sops.secrets.hedgedoc-session-secret.owner = config.systemd.services.hedgedoc.serviceConfig.User; - services = { - hedgedoc = { - enable = true; - settings = - let - day = 24 * 60 * 60 * 1000; - in - { - inherit domain; - protocolUseSSL = true; - csp.enable = true; - port = ports.hedgedoc.tcp; - db = { - dialect = "postgres"; - host = "/run/postgresql"; - user = "hedgedoc"; - database = "hedgedoc"; - }; - allowEmailRegister = false; - sessionSecret = config.sops.secrets.hedgedoc-session-secret.path; - sessionLife = 90 * day; - }; - }; - postgresql = { - enable = true; - ensureDatabases = [ "hedgedoc" ]; - ensureUsers = [{ - name = "hedgedoc"; - ensureDBOwnership = true; - }]; - }; - nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://${cfg.settings.host}:${toString cfg.settings.port}"; - }; - }; - }; -} diff --git a/hosts/magnesium/services/it-tools.nix b/hosts/magnesium/services/it-tools.nix deleted file mode 100644 index 4999bf0..0000000 --- a/hosts/magnesium/services/it-tools.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ pkgs, ... }: - -let - domain = "tools.jalr.de"; -in -{ - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - root = "${pkgs.it-tools}/lib"; - }; -} diff --git a/hosts/magnesium/services/mealie.nix b/hosts/magnesium/services/mealie.nix deleted file mode 100644 index a60f80e..0000000 --- a/hosts/magnesium/services/mealie.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ config, ... }: - -let - domain = "mealie.jalr.de"; - cfg = config.services.mealie; -in -{ - services.mealie = { - enable = true; - credentialsFile = config.sops.secrets.mealie.path; - port = config.networking.ports.mealie.tcp; - listenAddress = "127.0.0.1"; - settings = { - BASE_URL = "https://${domain}"; - ALLOW_SIGNUP = "false"; - SMTP_HOST = "hha.jalr.de"; - SMTP_PORT = 465; - SMTP_FROM_NAME = "mealie"; - SMTP_AUTH_STRATEGY = "TLS"; - SMTP_FROM_EMAIL = "no-reply@jalr.de"; - SMTP_USER = "mealie@jalr.de"; - }; - }; - - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://127.0.0.1:${toString cfg.port}"; - }; - }; -} diff --git a/hosts/magnesium/services/mosquitto.nix b/hosts/magnesium/services/mosquitto.nix new file mode 100644 index 0000000..e81027e --- /dev/null +++ b/hosts/magnesium/services/mosquitto.nix @@ -0,0 +1,20 @@ +args@{ config, lib, pkgs, custom-utils, ... }: + +let + ports = import ../ports.nix args; +in +{ + services.mosquitto = { + enable = true; + persistence = true; + listeners = [ + { + port = ports.mosquitto.tcp; + settings = { + allow_anonymous = true; + }; + } + ]; + }; + networking.firewall.allowedTCPPorts = [ ports.mosquitto.tcp ]; +} diff --git a/hosts/magnesium/services/ntfy.nix b/hosts/magnesium/services/ntfy.nix deleted file mode 100644 index 16f9129..0000000 --- a/hosts/magnesium/services/ntfy.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ config, ... }: -let - cfg = config.services.ntfy-sh; - domain = "ntfy.jalr.de"; - datadir = "/var/lib/ntfy-sh"; - inherit (config.networking) ports; -in -{ - # ntfy access --auth-file /var/lib/private/ntfy-sh/user.db '*' 'up*' write-only - - services.ntfy-sh = { - enable = true; - settings = { - listen-http = "127.0.0.1:${toString ports.ntfy.tcp}"; - base-url = "https://${domain}"; - behind-proxy = true; - #web-root = "disable"; - #auth-default-access = "read-only"; - attachment-cache-dir = "${datadir}/attachments"; - auth-file = "${datadir}/user.db"; - cache-file = "${datadir}/cache-file.db"; - }; - }; - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - kTLS = true; - locations."/" = { - proxyPass = "http://${cfg.settings.listen-http}/"; - recommendedProxySettings = true; - proxyWebsockets = true; - }; - }; -} diff --git a/hosts/magnesium/services/public-ip-tunnel.nix b/hosts/magnesium/services/public-ip-tunnel.nix index 1dee818..510fff8 100644 --- a/hosts/magnesium/services/public-ip-tunnel.nix +++ b/hosts/magnesium/services/public-ip-tunnel.nix @@ -1,37 +1,45 @@ -{ config, ... }: +args@{ config, lib, pkgs, custom-utils, ... }: let + ports = import ../ports.nix args; listenPort = ports.wireguard-public-ip-tunnel.udp; publicKey = "GCmQs7upvDYFueEfqD2yJkkOZg3K7YaGluWWzdjsyTo="; - inherit (config.networking) ports; in { + sops.secrets = ( + lib.listToAttrs (map + (name: lib.nameValuePair "wireguard_key_${name}" { + sopsFile = ../secrets.yaml; + }) + [ + "hetzner-ha" + ] + ) + ); + #boot.kernel.sysctl = { # "net.ipv4.conf.all.forwarding" = 1; # "net.ipv4.conf.hetzner-ha.proxy_arp" = 1; # "net.ipv4.conf.enp1s0.proxy_arp" = 1; #}; + networking.interfaces.hetzner-ha.proxyARP = true; + networking.interfaces.enp1s0.proxyARP = true; - networking = { - interfaces = { - hetzner-ha.proxyARP = true; - enp1s0.proxyARP = true; - }; - firewall.allowedUDPPorts = [ listenPort ]; - wireguard.interfaces = { - hetzner-ha = { - ips = [ ]; - privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path; - inherit listenPort; + networking.wireguard.interfaces = { + hetzner-ha = { + ips = [ ]; + privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path; + listenPort = listenPort; - peers = [{ - inherit publicKey; - persistentKeepalive = 25; - allowedIPs = [ - "159.69.103.126/32" - ]; - }]; - }; + peers = [{ + publicKey = publicKey; + persistentKeepalive = 25; + allowedIPs = [ + "159.69.103.126/32" + ]; + }]; }; }; + + networking.firewall.allowedUDPPorts = [ listenPort ]; } diff --git a/hosts/magnesium/services/tandoor.nix b/hosts/magnesium/services/tandoor.nix deleted file mode 100644 index 1127cd2..0000000 --- a/hosts/magnesium/services/tandoor.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ config, ... }: - -let - domain = "tandoor.jalr.de"; - cfg = config.services.tandoor-recipes; - #recipesDirectory = "/var/lib/private/tandoor-recipes/recipes"; - inherit (config.networking) ports; -in -{ - services.tandoor-recipes = { - enable = true; - port = ports.tandoor.tcp; - extraConfig = { - GUNICORN_MEDIA = "1"; - }; - }; - - systemd.services.tandoor-recipes = { - serviceConfig = { - LoadCredential = [ - "secret_key:${config.sops.secrets."tandoor/secret_key".path}" - ]; - Environment = [ - "SECRET_KEY_FILE=%d/secret_key" - ]; - }; - }; - - #users.groups.tandoor-recipes.members = [ "nginx" ]; - # https://tandoor.jalr.de/media/recipes/c071286f-60b3-45e9-9ac5-f4bb99703c17_11.jpg - - #systemd.services.nginx.serviceConfig.BindReadOnlyPaths = [ recipesDirectory ]; - #users.groups.tandoor-recipes.members = [ "nginx" ]; - - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - - locations = { - "/" = { - proxyPass = "http://127.0.0.1:${toString cfg.port}"; - proxyWebsockets = true; - }; - #"/media/recipes/".alias = recipesDirectory; - }; - }; -} diff --git a/hosts/magnesium/services/trilium.nix b/hosts/magnesium/services/trilium.nix deleted file mode 100644 index 9b7adbf..0000000 --- a/hosts/magnesium/services/trilium.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ config, pkgs, ... }: - -let - domain = "notes.jalr.de"; - inherit (config.networking) ports; -in -{ - services.trilium-server = { - enable = true; - package = pkgs.trilium-next-server; - host = "127.0.0.1"; - port = ports.trilium.tcp; - nginx = { - enable = true; - hostName = domain; - }; - }; - - services.nginx.virtualHosts."${domain}" = { - enableACME = true; - forceSSL = true; - }; -} diff --git a/hosts/magnesium/services/webserver.nix b/hosts/magnesium/services/webserver.nix index a30a098..9c55514 100644 --- a/hosts/magnesium/services/webserver.nix +++ b/hosts/magnesium/services/webserver.nix @@ -1,9 +1,9 @@ -{ config, lib, pkgs, ... }: +args@{ config, lib, pkgs, custom-utils, ... }: let + ports = import ../ports.nix args; domain = "jalr.de"; matrixDomain = "matrix.jalr.de"; - inherit (config.networking) ports; in { networking.firewall.allowedTCPPorts = [ ports.nginx-http.tcp ports.nginx-https.tcp ]; @@ -44,7 +44,7 @@ in add_header Content-Type application/json; return 200 '${builtins.toJSON { "m.server" = "${matrixDomain}:443"; - }}'; + }}'; ''; "=/.well-known/matrix/client".extraConfig = '' ${parentHeaders} @@ -52,7 +52,6 @@ in add_header Access-Control-Allow-Origin *; return 200 '${builtins.toJSON { "m.homeserver"."base_url" = "https://${matrixDomain}"; - "org.matrix.msc3575.proxy"."url" = "https://${matrixDomain}"; }}'; ''; }; diff --git a/hosts/weinturm-pretix-prod/configuration.nix b/hosts/weinturm-pretix-prod/configuration.nix new file mode 100644 index 0000000..b4c9ba8 --- /dev/null +++ b/hosts/weinturm-pretix-prod/configuration.nix @@ -0,0 +1,55 @@ +{ ... }: { + imports = [ + ./hardware-configuration.nix + ../../home-manager/users/jalr.nix + ./services + ]; + + networking.hostName = "weinturm-pretix-prod"; + + networking.useDHCP = false; + + systemd.network = { + enable = true; + networks."10-wan" = { + matchConfig.Name = "enp1s0"; + networkConfig.DHCP = "no"; + address = [ + "142.132.185.70/32" + "2a01:4f8:c012:edd::/64" + ]; + routes = [ + { + routeConfig.Destination = "172.31.1.1"; + } + { + routeConfig = { + Gateway = "172.31.1.1"; + GatewayOnLink = true; + }; + } + { + routeConfig.Gateway = "fe80::1"; + } + ]; + }; + }; + + zramSwap = { + enable = true; + algorithm = "zstd"; + memoryPercent = 60; + priority = 1; + }; + + security.sudo.wheelNeedsPassword = false; + + services.netdata.enable = true; + + jalr = { + bootloader = "systemd-boot"; + uefi.enable = true; + }; + + system.stateVersion = "23.11"; +} diff --git a/hosts/weinturm-pretix-prod/hardware-configuration.nix b/hosts/weinturm-pretix-prod/hardware-configuration.nix new file mode 100644 index 0000000..ba13c46 --- /dev/null +++ b/hosts/weinturm-pretix-prod/hardware-configuration.nix @@ -0,0 +1,60 @@ +{ config, lib, pkgs, modulesPath, ... }: +{ + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/766739e7-2c5c-4c28-b6ee-4bf9f91e6b1f"; + fsType = "btrfs"; + options = [ + "subvol=root" + "compress=zstd" + ]; + }; + "/proc" = { + device = "/proc"; + options = [ "nosuid" "noexec" "nodev" "hidepid=2" ]; + }; + "/home" = { + device = "/dev/disk/by-uuid/766739e7-2c5c-4c28-b6ee-4bf9f91e6b1f"; + fsType = "btrfs"; + options = [ + "subvol=home" + "compress=zstd" + "nodev" + "nosuid" + ]; + }; + "/nix" = { + device = "/dev/disk/by-uuid/766739e7-2c5c-4c28-b6ee-4bf9f91e6b1f"; + fsType = "btrfs"; + options = [ + "subvol=nix" + "compress=zstd" + "noatime" + "nodev" + ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/A586-15AC"; + fsType = "vfat"; + options = [ "nodev" "nosuid" "noexec" ]; + }; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp1s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; +} diff --git a/hosts/weinturm-pretix-prod/ports.nix b/hosts/weinturm-pretix-prod/ports.nix new file mode 100644 index 0000000..9c3e0e7 --- /dev/null +++ b/hosts/weinturm-pretix-prod/ports.nix @@ -0,0 +1,8 @@ +{ lib, custom-utils, ... }: + +custom-utils.validatePortAttrset { + nginx-http.tcp = 80; + nginx-https.tcp = 443; + ports.postfix-relay.tcp = 25; + ports.postfix-submission.tcp = [ 465 587 ]; +} diff --git a/hosts/weinturm-pretix-prod/secrets.yaml b/hosts/weinturm-pretix-prod/secrets.yaml new file mode 100644 index 0000000..bfd0f7e --- /dev/null +++ b/hosts/weinturm-pretix-prod/secrets.yaml @@ -0,0 +1,33 @@ +pretix-cfg: ENC[AES256_GCM,data:sfgKDr9aNOdwlumoltRuD7u1ksykFdEKtzt3MldjQnG0b4iAEspEhjcxqaNvPpXYm8EZKtsLBBQgdd1ifyQgs3k69c/GfzQ/jZ/yQ2OUkCO7U9A=,iv:FADYpPbGEEM/pD6EI85s9wVMv8yMrGJa+miE25XQ+t8=,tag:WJ9LHCNFHSr9RmmUi6hxnw==,type:str] +pretix-banktool-cfg: ENC[AES256_GCM,data:6tcaQwnXsA2jZYQD2BdGu7gVzlCE+cF03icOF7VIVY92+xWMw+aivJRocDQAMBslD04EoEAu74tNIcky23swtgJwbtcwSmouDqofzo/HoXrudNyvjECYd6xUzmq/OvSBSQVY3s3OxCcc0TlpPVUipDxcGaALwJdhtCB11ZrVfOoXrycZ3YLAEESK0rC4tc5E550lhxmkyOan1m9q9rI4KVhv4mIlU6nVQbDA7LcljRPAJESFmwuwx75t6uPYKH9CjaYL3XE/MmZIZ6pN3qiNyqEx8dsxWZh1KQI233TfMr6jcIXwamTFK6/yieE2nQJfyM8r8b3E3D4nJ5+nn5Cb+wxwewEPveEmFUsNXYD84fpk2fK0nvYyOi32++gfefObFVE2ejAE7iu3rIrboA/wJoSfPCDGHVtdLVXC//MjLI3JUAU+QMTwRFz53KhE+lxFsbqaX4IdLuUwMoFSW6qRWGe7/SGUChH1Wrj705MMc4dfn2qaGhDbZNkDJA==,iv:Pl8XpuGcFzLlzEVe+JQ02S2rthKz88QMZXkGEywpCTU=,tag:beSgKDPcErhJhoV59YDIsw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1djjxl3lcvzs85nj0met6w8ujsz8pvr6ngmmdwlxfh0k9d5lkrpdqlzzehf + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0RXR4RnVQNjFvZ2NSZVhj + QVZva0lKS1RxM09sYmJjZE12NTBMd3NrUlNjCkV0aklndEZDM1BaWFhxYUJ5TDBG + T24zODBSdFVWV2VCNVZoM2s3RHJ4WHMKLS0tIC9LdDFMRW13YTBHNlVOdUY0b1NX + U3pyTDB4c1FWdHBPVjVjV3VpTjFWamsKDtc9C3xy/3Zu83+jQYCnHk8vatWANt4M + +Zo5kZ5yfYVSnvMvgpWoAHk/quXSLNg2YhKUDrYP5y57Q/jZTX3YbA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-09-25T15:21:49Z" + mac: ENC[AES256_GCM,data:R3uP3tH4faLEtga0E2Gh4WrLrpV7dYvxWDEJkD5ycUc2vglY3MeswMEhNEhkD7cpYiWKB8TaBeBe/mP3hOmgs3WY1sDURZSqKKFT1FfTTL86e1BAOq7S4rG2lRQyNxxDjeJCqFQbEV3feggqPFnV8x8kBObAd29akAK5jQn1TK8=,iv:4F83RXiyLDlzlDVgMWKAOc7BTGSi4F0so9Ub/uzl+VM=,tag:2Q2BRBRR9yC6Uli5TcZhEg==,type:str] + pgp: + - created_at: "2023-07-08T09:50:21Z" + enc: | + -----BEGIN PGP MESSAGE----- + + hF4D3ylLYNOsO+0SAQdAMH1wIM+ENgeWlLsj7qUEorj8O1L5NlW9ABKB/Whmz3Ew + xm1SbZeFPPBPcT1dfVCF+W1CYDjrFau4DXhkcz5Z6x3ENg9rZujtRAZY9c+53aqD + 0l4B4zxls8vy0K/kipHn010WKhHEPMmABJf+d0rAkT6tbVzcxU3TKlZ2BWxwifM+ + BYDGZ2A6opgV8G4Q68n6CInyhMROIIzJJpWkP0YZCIzzVQ+9yelq9jZvuuxR7v9+ + =Lkul + -----END PGP MESSAGE----- + fp: 66FB54F6081375106EEBF651A222365EB448F934 + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/hosts/weinturm-pretix-prod/services/default.nix b/hosts/weinturm-pretix-prod/services/default.nix new file mode 100644 index 0000000..731194c --- /dev/null +++ b/hosts/weinturm-pretix-prod/services/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./pretix.nix + ]; +} diff --git a/hosts/weinturm-pretix-prod/services/pretix.nix b/hosts/weinturm-pretix-prod/services/pretix.nix new file mode 100644 index 0000000..191024e --- /dev/null +++ b/hosts/weinturm-pretix-prod/services/pretix.nix @@ -0,0 +1,54 @@ +args@{ config, lib, pkgs, custom-utils, ... }: + +let + ports = import ../ports.nix args; +in +{ + services.pretix = { + enable = true; + instanceName = "Weinturm Open Air"; + domain = "tickets.weinturm-open-air.de"; + extraDomains = [ + "tickets.weinturm.jalr.de" + "tickets.wasted-openair.de" + "oel.wasted-openair.de" + ]; + enableTls = true; + enableRegistration = false; + passwordReset = true; + locale = "de"; + timezone = "Europe/Berlin"; + secretsFile = ../secrets.yaml; + banktool = { + enable = true; + days = 14; + }; + mail = { + enable = true; + from = "no-reply@tickets.weinturm-open-air.de"; + admins = [ + "mail@jalr.de" + ]; + }; + }; + + jalr.mailserver = { + enable = true; + fqdn = "tickets.weinturm.jalr.de"; + relayPort = ports.postfix-relay.tcp; + domains = [ + { + domain = "tickets.weinturm-open-air.de"; + enableDKIM = false; + } + ]; + messageSizeLimit = 10 * 1024 * 1024; + users = [ ]; + spam.enable = false; + }; + + security.acme = { + acceptTerms = true; + defaults.email = lib.mkForce "helfer@weinturm-open-air.de"; + }; +} diff --git a/justfile b/justfile index d1d2a9a..b44ce6d 100644 --- a/justfile +++ b/justfile @@ -1,34 +1,14 @@ -usb_ram_disk := "/dev/disk/by-label/RAM_USB" -usb_ram_mountpoint := shell("findmnt -n -o TARGET $1 || true", usb_ram_disk) - boot: - nixos-rebuild boot --flake . --use-remote-sudo - which fwupdmgr >/dev/null 2>&1 && fwupdmgr update || true + nixos-rebuild boot --flake . --use-remote-sudo + which fwupdmgr >/dev/null 2>&1 && fwupdmgr update || true switch: - nixos-rebuild switch --flake . --use-remote-sudo - which fwupdmgr >/dev/null 2>&1 && fwupdmgr update || true + nixos-rebuild switch --flake . --use-remote-sudo + which fwupdmgr >/dev/null 2>&1 && fwupdmgr update || true build: - nixos-rebuild build --flake . + nixos-rebuild build --flake . update: - nix flake update --commit-lock-file - which fwupdmgr >/dev/null 2>&1 && fwupdmgr refresh || true - -repl: - nix repl --expr "\ - let \ - flake = builtins.getFlake \"$(git rev-parse --show-toplevel)\"; in \ - flake // (with flake; { \ - lib = inputs.nixpkgs.lib; \ - pkgs = inputs.nixpkgs.legacyPackages."\${builtins.currentSystem}".extend(import ./pkgs inputs); \ - }) \ - " - -luks-pass host: - @if [ -d "{{usb_ram_mountpoint}}" ]; then \ - gpg -d hosts/{{host}}/luks-passfile.gpg > "{{usb_ram_mountpoint}}/{{host}}.key"; \ - else \ - echo "Mount point not found. Is the usb device plugged and mounted?" >&2; \ - fi + nix flake update --commit-lock-file + which fwupdmgr >/dev/null 2>&1 && fwupdmgr refresh || true diff --git a/modules/adb.nix b/modules/adb.nix index 47198c1..1aae96c 100644 --- a/modules/adb.nix +++ b/modules/adb.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: lib.mkIf config.jalr.gui.enable { programs.adb.enable = true; diff --git a/modules/avahi.nix b/modules/avahi.nix deleted file mode 100644 index c12bd75..0000000 --- a/modules/avahi.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ config, lib, pkgs, ... }: - -lib.mkIf config.jalr.gui.enable { - services.avahi = { - enable = true; - package = - let - xmltoman = pkgs.xmltoman.overrideAttrs (_: { - nativeBuildInputs = [ - pkgs.installShellFiles - ]; - buildInputs = [ - (pkgs.perl.withPackages (pl: [ - pl.XMLParser - ])) - ]; - }); - in - pkgs.avahi.overrideAttrs (o: rec { - version = "0.9-rc2"; - src = pkgs.fetchurl { - url = "https://github.com/avahi/avahi/archive/refs/tags/v${version}.tar.gz"; - sha256 = "sha256-9k7+1qlyz5LLLfs1q/aqkXPWK4Q7FYUML0CvdqQjj4o="; - }; - patches = [ ]; - buildInputs = o.buildInputs ++ [ pkgs.systemdLibs ]; - nativeBuildInputs = o.nativeBuildInputs ++ [ xmltoman ]; - installFlags = [ - "runstatedir=${placeholder "out"}/run" - "sysconfdir=${placeholder "out"}/etc" - ]; - }); - nssmdns4 = true; - extraConfig = '' - [server] - ratelimit-interval-usec=500000 - ratelimit-burst=500 - [wide-area] - enable-wide-area=no - ''; - }; -} diff --git a/modules/aws.nix b/modules/aws.nix index 2b6eddb..f94580a 100644 --- a/modules/aws.nix +++ b/modules/aws.nix @@ -4,7 +4,7 @@ options.jalr.aws = { enable = lib.mkEnableOption "Enable AWS CLI"; accounts = with lib; mkOption { - type = with types; attrsOf (submodule (_: { + type = with types; attrsOf (submodule ({ config, name, ... }: { options = { sso_account_id = mkOption { type = int; diff --git a/modules/bluetooth.nix b/modules/bluetooth.nix index 6c478b7..dc12711 100644 --- a/modules/bluetooth.nix +++ b/modules/bluetooth.nix @@ -9,12 +9,9 @@ in }; config = lib.mkIf cfg.bluetooth.enable { hardware.bluetooth.enable = true; - services = { - blueman.enable = true; - ofono.enable = true; - upower.enable = true; - }; - hardware.bluetooth.settings.General.Experimental = true; # to show battery state + services.blueman.enable = true; + services.ofono.enable = true; + services.upower.enable = true; }; } diff --git a/modules/bootloader/default.nix b/modules/bootloader/default.nix index bcb2908..22c07a5 100644 --- a/modules/bootloader/default.nix +++ b/modules/bootloader/default.nix @@ -1,16 +1,15 @@ -{ lib, ... }: +{ config, lib, pkgs, ... }: { options.jalr = { bootloader = lib.mkOption { - type = lib.types.nullOr (lib.types.enum [ "systemd-boot" "grub2" "lanzaboote" ]); + type = lib.types.nullOr (lib.types.enum [ "systemd-boot" "grub2" ]); default = null; description = "Bootloader to install"; }; }; imports = [ - ./grub2.nix - ./lanzaboote.nix ./systemd-boot.nix + ./grub2.nix ]; } diff --git a/modules/bootloader/grub2.nix b/modules/bootloader/grub2.nix index 2037be7..a2ec2ee 100644 --- a/modules/bootloader/grub2.nix +++ b/modules/bootloader/grub2.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: lib.mkIf (config.jalr.bootloader == "grub2") { boot.loader.grub = { diff --git a/modules/bootloader/lanzaboote.nix b/modules/bootloader/lanzaboote.nix deleted file mode 100644 index 92f0820..0000000 --- a/modules/bootloader/lanzaboote.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ config, lib, ... }: - -lib.mkIf (config.jalr.bootloader == "lanzaboote") { - boot.lanzaboote = { - enable = true; - pkiBundle = "/etc/secureboot"; - }; -} diff --git a/modules/bootloader/systemd-boot.nix b/modules/bootloader/systemd-boot.nix index 995bb0b..96cab4d 100644 --- a/modules/bootloader/systemd-boot.nix +++ b/modules/bootloader/systemd-boot.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: lib.mkIf (config.jalr.bootloader == "systemd-boot") { boot = { diff --git a/modules/debug.nix b/modules/debug.nix deleted file mode 100644 index 9cc70b5..0000000 --- a/modules/debug.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.jalr.debug; -in -{ - options.jalr.debug = { - enable = lib.mkEnableOption "debugging helpers, DO NOT USE IN PRODUCTION!"; - }; - - config = lib.mkIf cfg.enable { - services.getty.autologinUser = "root"; - boot.initrd.systemd.emergencyAccess = true; - systemd.enableEmergencyMode = true; - boot.kernelParams = [ "systemd.setenv=SYSTEMD_SULOGIN_FORCE=1" ]; - }; -} diff --git a/modules/default.nix b/modules/default.nix index cd6a1cf..d43da52 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -2,11 +2,7 @@ { options.jalr = { - gui = { - enable = lib.mkEnableOption "GUI"; - sway.enable = lib.mkEnableOption "sway"; - gnome.enable = lib.mkEnableOption "gnome"; - }; + gui.enable = lib.mkEnableOption "GUI"; workstation.enable = lib.mkEnableOption "Workstation"; }; @@ -14,43 +10,39 @@ ../pkgs/modules.nix ./adb.nix ./autologin.nix - ./avahi.nix ./aws.nix ./bluetooth.nix ./bootloader - ./debug.nix - ./dns.nix - ./esphome + ./dji-goggles.nix + ./dnsmasq.nix ./fish.nix ./fonts.nix - ./gnome.nix ./journald.nix ./kdeconnect.nix ./kvm-switch-enable-screen.nix ./libvirt.nix ./localization.nix - ./luksusb.nix ./mailserver ./matrix - ./mobile-network.nix ./mute-indicator.nix - ./neo.nix - ./networking + ./network-manager.nix ./nix.nix ./obs.nix ./pipewire.nix ./podman.nix ./printers + ./qbittorrent ./remarkable.nix + ./sdr.nix ./sshd.nix - ./steelseries-nova-pro.nix ./sudo.nix ./sway.nix - ./udev.nix + ./tor.nix + ./tradebyte + ./udmx.nix ./uefi.nix ./unfree.nix - ./upgrade-diff.nix - ./wireshark + ./wireshark.nix ./yubikey-gpg.nix ]; @@ -67,7 +59,7 @@ ]; }; - programs.nano.enable = false; + security.polkit.enable = true; security.acme = { acceptTerms = true; diff --git a/modules/dji-goggles.nix b/modules/dji-goggles.nix new file mode 100644 index 0000000..00a735b --- /dev/null +++ b/modules/dji-goggles.nix @@ -0,0 +1,6 @@ +{ + services.udev.extraRules = '' + # DJI Goggles + SUBSYSTEM=="usb", ATTRS{idVendor}=="2ca3", ATTRS{idProduct}=="001f", GROUP="video", MODE="0660" + ''; +} diff --git a/modules/dns.nix b/modules/dns.nix deleted file mode 100644 index a15d066..0000000 --- a/modules/dns.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ lib, config, ... }: - -let - dnscryptListenAddress = "127.0.0.1"; - dnscryptListenPort = 9053; -in -{ - config = lib.mkIf config.jalr.workstation.enable { - services.dnscrypt-proxy2 = { - enable = true; - settings = { - ipv6_servers = true; - require_dnssec = true; - require_nolog = true; - require_nofilter = true; - dnscrypt_ephemeral_keys = true; - tls_disable_session_tickets = true; - listen_addresses = [ "${dnscryptListenAddress}:${toString dnscryptListenPort}" ]; - anonymized_dns.skip_incompatible = true; - }; - }; - services.dnsmasq = { - enable = true; - resolveLocalQueries = true; - settings = { - server = [ - "/iceportal.de/172.18.0.1" - "/lab.fablab-nea.de/192.168.94.1" - "/iot.bw.jalr.de/192.168.42.1" - "/lan.bw.jalr.de/192.168.42.1" - "/lechner.zz/192.168.0.1" - "/login.wifionice.de/172.18.0.1" - "${dnscryptListenAddress}#${toString dnscryptListenPort}" - ]; - address = [ - "/localhost/127.0.0.1" - ]; - no-resolv = true; - interface = "lo"; - listen-address = [ - "::1" - "127.0.0.1" - ]; - bind-interfaces = true; - dns-loop-detect = true; - neg-ttl = 5; - }; - }; - }; -} diff --git a/modules/dnsmasq.nix b/modules/dnsmasq.nix new file mode 100644 index 0000000..e33f50b --- /dev/null +++ b/modules/dnsmasq.nix @@ -0,0 +1,29 @@ +{ lib, config, ... }: + +{ + config = lib.mkIf config.jalr.workstation.enable { + services.dnsmasq = { + enable = true; + resolveLocalQueries = true; + settings = { + server = [ + "/iceportal.de/172.18.0.1" + "/lab.fablab-nea.de/192.168.94.1" + "/lan.bw.jalr.de/192.168.42.1" + "/lechner.zz/192.168.0.1" + "/login.wifionice.de/172.18.0.1" + "127.0.0.1#9053" + ]; + no-resolv = true; + interface = "lo"; + listen-address = [ + "::1" + "127.0.0.1" + ]; + bind-interfaces = true; + dns-loop-detect = true; + neg-ttl = 5; + }; + }; + }; +} diff --git a/modules/esphome/default.nix b/modules/esphome/default.nix deleted file mode 100644 index 4edf71e..0000000 --- a/modules/esphome/default.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ lib -, pkgs -, config -, ... -}: -let - cfg = config.jalr.esphome; - esphomeParams = - if config.services.esphome.enableUnixSocket - then "--socket /run/esphome/esphome.sock" - else "--address ${config.services.esphome.address} --port ${toString config.services.esphome.port}"; -in -{ - options.jalr.esphome = with lib; with lib.types; { - enable = mkEnableOption "ESPHome"; - port = mkOption { - description = "TCP port for esphome dashboard."; - type = port; - }; - configDir = mkOption { - type = path; - description = "Location of the device configuration"; - }; - secretsFile = mkOption { - type = path; - description = "Location of the secrets file"; - }; - }; - - config = lib.mkIf cfg.enable { - services.esphome = { - enable = true; - address = "127.0.0.1"; - inherit (cfg) port; - package = pkgs.master.esphome; - }; - - systemd.services.esphome = { - environment = { - "PLATFORMIO_CORE_DIR" = lib.mkForce "/var/cache/esphome/.platformio"; - }; - serviceConfig = { - BindReadOnlyPaths = [ - "/nix/store" - "%d/secrets.yaml:/run/esphome/config/secrets.yaml" - "/etc/resolv.conf" - "/etc/ssl" - "/etc/static/ssl" - ]; - TemporaryFileSystem = [ - "/var/lib" - ]; - ExecPaths = [ - "-+/var/cache/esphome/.platformio/packages/" - ]; - DeviceAllow = [ - "char-ttyACM rw" - "char-ttyAMA rw" - "char-ttyUSB rw" - ]; - ExecStartPre = [ - (pkgs.writeShellScript "esphome-exec-start-pre" '' - if ! [ -d "$CACHE_DIRECTORY/.platformio/packages" ]; then - mkdir -p "$CACHE_DIRECTORY/.platformio/packages" - exit 1 - fi - mkdir -p "$CACHE_DIRECTORY/.esphome" - for linked in \ - .esphome \ - .gitignore - do - ln -s "$CACHE_DIRECTORY/$linked" "/run/esphome/config/$linked" - done - ${pkgs.rsync}/bin/rsync \ - -a \ - --delete \ - --checksum \ - --exclude secrets.yaml \ - --exclude=.esphome \ - --exclude=.platformio \ - --exclude=.gitignore \ - '${cfg.configDir}/' /run/esphome/config/ - '') - ]; - ExecStart = lib.mkForce "${config.services.esphome.package}/bin/esphome dashboard ${esphomeParams} /run/esphome/config"; - LoadCredential = "secrets.yaml:${cfg.secretsFile}"; - PrivateTmp = true; - RootDirectory = "%t/esphome/chroot"; - RuntimeDirectory = [ - "esphome/chroot" - "esphome/config" - ]; - StateDirectory = lib.mkForce [ ]; - CacheDirectory = "esphome"; - SupplementaryGroups = [ "dialout" ]; - WorkingDirectory = lib.mkForce "/run/esphome/config"; - }; - }; - }; -} diff --git a/modules/esphome/devices/justfile b/modules/esphome/devices/justfile deleted file mode 100644 index 2c86b69..0000000 --- a/modules/esphome/devices/justfile +++ /dev/null @@ -1,17 +0,0 @@ -import '../../../../../justfile' -set dotenv-load - -download: - rsync \ - -r \ - --rsync-path='sudo rsync' \ - --exclude '/build' \ - --exclude '/.esphome' \ - --exclude '.gitignore' \ - --exclude 'secrets.yaml' \ - ${ESPHOME_HOST}:/var/lib/esphome/ ./ - -download-secrets: - umask 0077 && ssh ${ESPHOME_HOST} sudo cat /run/secrets/esphome > "/dev/shm/${ESPHOME_SECRETS_FILE}" - ln -sf "/dev/shm/${ESPHOME_SECRETS_FILE}" "{{justfile_directory()}}/secrets.yaml" - diff --git a/modules/fonts.nix b/modules/fonts.nix index 2225251..eb2cee0 100644 --- a/modules/fonts.nix +++ b/modules/fonts.nix @@ -3,10 +3,7 @@ { console.font = "Lat2-Terminus16"; fonts.packages = with pkgs; lib.mkIf config.jalr.gui.enable [ - nerd-fonts.fira-code - nerd-fonts.iosevka - nerd-fonts.iosevka-term - nerd-fonts.iosevka-term-slab + (nerdfonts.override { fonts = [ "Iosevka" ]; }) font-awesome powerline-fonts roboto diff --git a/modules/gnome.nix b/modules/gnome.nix deleted file mode 100644 index 1a6b784..0000000 --- a/modules/gnome.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ config, lib, ... }: - -lib.mkIf (config.jalr.gui.enable && config.jalr.gui.gnome.enable) { - services.xserver = { - enable = true; - desktopManager.gnome.enable = true; - displayManager.gdm = { - enable = true; - autoSuspend = false; - }; - exportConfiguration = true; - }; - - /* - programs.dconf = { - enable = true; - profiles = { - user.databases = [{ - settings = with lib.gvariant; { - "org/gnome/desktop/input-sources" = { - sources = [ - (mkTuple [ "xkb" "de" ]) - (mkTuple [ "xkb" "de+neo" ]) - (mkTuple [ "xkb" "us" ]) - ]; - }; - }; - }]; - }; - }; - */ -} diff --git a/modules/journald.nix b/modules/journald.nix index e527dc6..c6f1271 100644 --- a/modules/journald.nix +++ b/modules/journald.nix @@ -1,3 +1,5 @@ +{ lib, ... }: + { services.journald.extraConfig = '' MaxRetentionSec=90day diff --git a/modules/kdeconnect.nix b/modules/kdeconnect.nix index 96b3016..87cbf5d 100644 --- a/modules/kdeconnect.nix +++ b/modules/kdeconnect.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let portRange = { diff --git a/modules/localization.nix b/modules/localization.nix index 0034c23..3c3d813 100644 --- a/modules/localization.nix +++ b/modules/localization.nix @@ -1,4 +1,3 @@ -{ config, ... }: { i18n = { defaultLocale = "en_GB.UTF-8"; @@ -9,7 +8,7 @@ console.keyMap = "neo"; - time.timeZone = if config.jalr.workstation.enable then "Europe/Berlin" else "UTC"; + time.timeZone = "UTC"; location = { latitude = 49.5; diff --git a/modules/luksusb.nix b/modules/luksusb.nix deleted file mode 100644 index 315c6a0..0000000 --- a/modules/luksusb.nix +++ /dev/null @@ -1,121 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.jalr.luksUsbUnlock; -in -{ - options.jalr.luksUsbUnlock = with lib; with lib.types; { - enable = mkEnableOption "unlock LUKS volumes with a USB device on boot"; - devices = mkOption { - default = { }; - example = { - cryptroot = { - keyPath = "/path/to/the/key"; - usbDevice = "by-label/MY_USB"; - }; - }; - type = types.attrsOf (types.submodule { - options = { - keyPath = mkOption { - example = "/mykey.key"; - description = mdDoc '' - Path to the key file inside the USB device's filesystem. - `/` is relative to the device's filesystem root. - ''; - type = types.str; - }; - - usbDevice = mkOption { - example = "by-label/BOOTKEY"; - description = mdDoc '' - Path to the USB device that contains the keys. (Path relative to `/dev/disk/`) - ''; - type = types.str; - }; - - waitForDevice = mkOption { - default = 5; - example = 10; - description = mdDoc '' - How many seconds to wait for the USB device to be detected by the - kernel. - ''; - type = types.ints.unsigned; - }; - }; - }); - }; - }; - config = lib.mkIf cfg.enable ( - let - makeUsbDevPath = usbDevice: "/dev/disk/" + usbDevice; - makeMountPath = usbDevice: "/key/" + (builtins.hashString "md5" usbDevice); - usbFsType = "vfat"; - - mapAttrsNameValue = f: set: - lib.listToAttrs (map f (lib.attrsToList set)); - in - { - boot.initrd = { - kernelModules = [ "uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1" ]; - systemd.services = - let - makeService = name: { usbDevice, waitForDevice, ... }: - let - usbDevPath = makeUsbDevPath usbDevice; - usbMountPath = makeMountPath usbDevice; - in - { - description = "Mount ${name} key"; - wantedBy = [ "cryptsetup.target" ]; - before = [ "systemd-cryptsetup@${name}.service" ]; - after = [ "systemd-modules-load.service" ]; - unitConfig.DefaultDependencies = "no"; - serviceConfig.Type = "oneshot"; - - script = '' - if awk -v mountpoint="${usbMountPath}" '$2==mountpoint {f=1} END {exit !f}' /proc/mounts; then - exit 0 - fi - - attempts=0 - while [ ! -e ${lib.escapeShellArg usbDevPath} ]; do - sleep 1 - if [ $attempts -ge ${toString waitForDevice} ]; then - break; - fi - attempts=$((attempts+1)) - done - - if [ -e ${lib.escapeShellArg usbDevPath} ]; then - mkdir -m0500 -p ${lib.escapeShellArg usbMountPath} - mount \ - -n \ - -t ${lib.escapeShellArg usbFsType} \ - -o ro,fmask=0137,dmask=0027 \ - ${lib.escapeShellArg usbDevPath} \ - ${lib.escapeShellArg usbMountPath} - fi - ''; - }; - in - mapAttrsNameValue - ({ name, value }: { - name = "luksusb-${name}"; - value = makeService name value; - }) - cfg.devices; - - luks.devices = builtins.mapAttrs - (_: { keyPath, usbDevice, ... }: - let - usbMountPath = makeMountPath usbDevice; - in - { - keyFile = "${usbMountPath}/${keyPath}"; - keyFileTimeout = 1; - }) - cfg.devices; - }; - } - ); -} diff --git a/modules/mailserver/default.nix b/modules/mailserver/default.nix index 59a8e2c..93abbbf 100644 --- a/modules/mailserver/default.nix +++ b/modules/mailserver/default.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let cfg = config.jalr.mailserver; in diff --git a/modules/mailserver/dovecot.nix b/modules/mailserver/dovecot.nix index a2485a5..353474d 100644 --- a/modules/mailserver/dovecot.nix +++ b/modules/mailserver/dovecot.nix @@ -13,6 +13,8 @@ lib.mkIf cfg.enable { services.dovecot2 = { enable = true; + modules = with pkgs; [ dovecot_pigeonhole ]; + enableLmtp = true; enablePAM = false; @@ -31,24 +33,14 @@ lib.mkIf cfg.enable { Spam = { specialUse = "Junk"; auto = "subscribe"; }; }; - sieve = { - globalExtensions = [ - "fileinto" - "vnd.dovecot.pipe" - ]; - plugins = [ - "sieve_imapsieve" - "sieve_extprograms" - ]; - scripts = { - before = pkgs.writeText "spam.sieve" '' - require "fileinto"; + sieveScripts = { + before = pkgs.writeText "spam.sieve" '' + require "fileinto"; - if header :is "X-Spam" "Yes" { - fileinto "Spam"; - } - ''; - }; + if header :is "X-Spam" "Yes" { + fileinto "Spam"; + } + ''; }; extraConfig = '' @@ -108,6 +100,8 @@ lib.mkIf cfg.enable { lda_mailbox_autocreate = yes plugin { + sieve_plugins = sieve_imapsieve sieve_extprograms + ${lib.optionalString cfg.spam.enable '' imapsieve_mailbox1_name = Spam imapsieve_mailbox1_causes = COPY @@ -119,12 +113,11 @@ lib.mkIf cfg.enable { imapsieve_mailbox2_before = file:/var/lib/dovecot/sieve/learn-ham.sieve sieve_pipe_bin_dir = ${pkgs.symlinkJoin { name = "sieve-pipe-bin-dir"; paths = with pkgs; [ rspamd ]; } }/bin ''} + + sieve_global_extensions = +vnd.dovecot.pipe } ''; }; - - environment.systemPackages = [ pkgs.dovecot_pigeonhole ]; - systemd.services.dovecot2 = { wants = [ "acme-finished-${cfg.fqdn}.target" ]; after = [ "acme-finished-${cfg.fqdn}.target" ]; diff --git a/modules/mailserver/postfix.nix b/modules/mailserver/postfix.nix index e813dcb..e09a48a 100644 --- a/modules/mailserver/postfix.nix +++ b/modules/mailserver/postfix.nix @@ -5,26 +5,26 @@ let listToString = lib.concatStringsSep ","; # List of attribute sets with single key-value pair - plainAliases = lib.flatten + plainAliases = (lib.flatten (map ({ address, aliases, ... }: map (alias: { "${alias}" = address; }) (aliases ++ lib.singleton address)) - cfg.users); + cfg.users)); # Attribute set with every alias mapped to a list of receivers - mergedAliases = lib.attrsets.foldAttrs + mergedAliases = (lib.attrsets.foldAttrs (val: col: lib.singleton val ++ col) [ ] - plainAliases; + plainAliases); # Contents of the aliases file - aliasesString = lib.concatStringsSep + aliasesString = (lib.concatStringsSep "\n" (lib.mapAttrsToList (alias: addresses: "${alias} ${listToString addresses}") - mergedAliases); + mergedAliases)); valiases = pkgs.writeText "valiases" aliasesString; @@ -35,12 +35,13 @@ let cfg.cleanHeaders); in lib.mkIf cfg.enable { + security.dhparams.params.postfix = { }; services.postfix = { enable = true; - inherit (cfg) relayPort; + relayPort = cfg.relayPort; - enableSubmission = false; # plain/STARTTLS (latter is forced in submissionOptions) + enableSubmission = true; # plain/STARTTLS (latter is forced in submissionOptions) enableSubmissions = true; # submission with implicit TLS (TCP/465) hostname = cfg.fqdn; @@ -69,11 +70,13 @@ lib.mkIf cfg.enable { smtpd_recipient_restrictions = listToString [ "reject_non_fqdn_recipient" + "reject_rbl_client ix.dnsbl.manitu.net" "reject_unknown_recipient_domain" "reject_unverified_recipient" ]; smtpd_client_restrictions = listToString [ + "reject_rbl_client ix.dnsbl.manitu.net" "reject_unknown_client_hostname" ]; @@ -102,6 +105,8 @@ lib.mkIf cfg.enable { "DHE-RSA-AES256-GCM-SHA384" ]; tls_preempt_cipherlist = "no"; + + smtpd_tls_dh1024_param_file = config.security.dhparams.params.postfix.path; }; # plain/STARTTLS (forced with smtpd_tls_security_level) @@ -142,7 +147,7 @@ lib.mkIf cfg.enable { networking.firewall.allowedTCPPorts = [ 25 # SMTP - 465 # SMTPS (implicit TLS) + 587 # SMTP submission ]; systemd.services.postfix = { diff --git a/modules/mailserver/rspamd.nix b/modules/mailserver/rspamd.nix index ee205de..a7e0992 100644 --- a/modules/mailserver/rspamd.nix +++ b/modules/mailserver/rspamd.nix @@ -6,7 +6,7 @@ let # nix shell nixpkgs#rspamd -c \ # rspamadm dkim_keygen -s default -d example.com -b 4096 -k /dev/shm/dkim.key > dkim.txt - dkimEnabledDomains = lib.filter (d: d.enableDKIM) cfg.domains; + dkimEnabledDomains = (lib.filter (d: d.enableDKIM) cfg.domains); dkimSignatureDir = pkgs.stdenvNoCC.mkDerivation { name = "dkim-signatures"; dontUnpack = true; diff --git a/modules/matrix/default.nix b/modules/matrix/default.nix index 4f3c745..4c0d8bf 100644 --- a/modules/matrix/default.nix +++ b/modules/matrix/default.nix @@ -1,5 +1,7 @@ { config, lib, pkgs, ... }: - +let + cfg = config.jalr.matrix; +in { options.jalr.matrix = with lib; with lib.types; { enable = mkEnableOption "simple matrix server"; @@ -54,7 +56,7 @@ defaultText = literalExpression '' optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit ''; - description = '' + description = lib.mdDoc '' List of Systemd services to require and wait for when starting the application service. ''; }; @@ -63,7 +65,7 @@ type = port; }; settings = mkOption { - inherit ((pkgs.formats.json { })) type; + type = (pkgs.formats.json { }).type; }; }; mautrix-whatsapp = { @@ -73,7 +75,7 @@ type = port; }; settings = mkOption { - inherit ((pkgs.formats.json { })) type; + type = (pkgs.formats.json { }).type; }; }; }; diff --git a/modules/matrix/mautrix-signal.nix b/modules/matrix/mautrix-signal.nix index e4b50d1..a470546 100644 --- a/modules/matrix/mautrix-signal.nix +++ b/modules/matrix/mautrix-signal.nix @@ -1,49 +1,136 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let cfg = config.jalr.matrix; synapseCfg = config.services.matrix-synapse.settings; dataDir = "/var/lib/mautrix-signal"; + registrationFile = "${dataDir}/signal-registration.yaml"; + settings = { + homeserver = { + address = synapseCfg.public_baseurl; + domain = synapseCfg.server_name; + }; + appservice = rec { + hostname = "127.0.0.1"; + port = cfg.mautrix-signal.port; + address = "http://${hostname}:${toString port}"; + provisioning.shared_secret = "disable"; + database = "sqlite:///${dataDir}/mautrix-signal.db"; + }; + bridge = { + encryption = { + allow = true; + default = true; + }; + verification_levels = { + receive = "cross-signed-tofu"; + send = "cross-signed-tofu"; + share = "cross-signed-tofu"; + }; + }; + logging = { + version = 1; + min_level = "info"; + writers = lib.singleton { + type = "stdout"; + format = "pretty-colored"; + time_format = " "; + }; + }; + } // cfg.mautrix-signal.settings; + settingsFormat = pkgs.formats.json { }; + settingsFile = "${dataDir}/config.json"; + settingsFileUnsubstituted = + settingsFormat.generate "mautrix-signal-config.json" settings; in lib.mkIf cfg.mautrix-signal.enable { - services.mautrix-signal = { - enable = true; - registerToSynapse = true; - settings = { - homeserver = { - address = synapseCfg.public_baseurl; - domain = synapseCfg.server_name; - }; - database = { - type = "sqlite3-fk-wal"; - uri = "file:${dataDir}/mautrix-signal.db?_txlock=immediate"; - }; - appservice = rec { - hostname = "127.0.0.1"; - inherit (cfg.mautrix-signal) port; - address = "http://${hostname}:${toString port}"; - provisioning.shared_secret = "disable"; - }; - bridge = { - encryption = { - allow = true; - default = true; - }; - verification_levels = { - receive = "cross-signed-tofu"; - send = "cross-signed-tofu"; - share = "cross-signed-tofu"; - }; - }; - logging = { - version = 1; - min_level = "info"; - writers = lib.singleton { - type = "stdout"; - format = "pretty-colored"; - time_format = " "; - }; - }; - } // cfg.mautrix-signal.settings; + systemd.services.mautrix-signal = { + description = "mautrix-signal, A Matrix-Signal puppeting bridge."; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ] ++ cfg.mautrix-signal.serviceDependencies; + after = [ "network-online.target" ] ++ cfg.mautrix-signal.serviceDependencies; + + environment.HOME = dataDir; + preStart = '' + # substitute the settings file by environment variables + # in this case read from EnvironmentFile + test -f '${settingsFile}' && rm -f '${settingsFile}' + old_umask=$(umask) + umask 0177 + ${pkgs.envsubst}/bin/envsubst \ + -o '${settingsFile}' \ + -i '${settingsFileUnsubstituted}' + + cp '${settingsFile}' '${settingsFile}.tmp' + umask $old_umask + + # generate the appservice's registration file if absent + if [ ! -f '${registrationFile}' ]; then + ${pkgs.mautrix-signal}/bin/mautrix-signal \ + --generate-registration \ + --config='${settingsFile}.tmp' \ + --registration='${registrationFile}' + fi + + umask 0177 + ${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token + | .[0].appservice.hs_token = .[1].hs_token + | .[0]' '${settingsFile}' '${registrationFile}' \ + > '${settingsFile}.tmp' + mv '${settingsFile}.tmp' '${settingsFile}' + umask $old_umask + ''; + serviceConfig = { + Type = "exec"; + User = "mautrix-signal"; + #EnvironmentFile = cfg.environmentFile; + WorkingDirectory = dataDir; + StateDirectory = lib.mkIf (dataDir == "/var/lib/mautrix-signal") "mautrix-signal"; + ExecStart = '' + ${pkgs.mautrix-signal}/bin/mautrix-signal \ + --config='${settingsFile}' \ + --no-update + ''; + Restart = "on-failure"; + RestartSec = "30s"; + + ReadWritePaths = dataDir; + NoNewPrivileges = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateTmp = true; + #ProtectHome = true; + ProtectSystem = "strict"; + ProtectControlGroups = true; + RestrictSUIDSGID = true; + RestrictRealtime = true; + LockPersonality = true; + ProtectKernelLogs = true; + ProtectKernelTunables = true; + ProtectHostname = true; + ProtectKernelModules = true; + PrivateUsers = true; + ProtectClock = true; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + SystemCallFilter = "@system-service"; + }; + restartTriggers = [ settingsFileUnsubstituted ]; }; + + users.users.mautrix-signal = { + isSystemUser = true; + group = "mautrix-signal"; + home = dataDir; + description = "mautrix-signal bridge user"; + }; + + users.groups.mautrix-signal = { }; + + services.signald = { + enable = true; + group = "mautrix-signal"; + }; + + jalr.matrix.synapse.app_service_config."mautrix-signal" = "/var/lib/mautrix-signal/signal-registration.yaml"; } diff --git a/modules/matrix/mautrix-whatsapp.nix b/modules/matrix/mautrix-whatsapp.nix index 7225227..c4f851d 100644 --- a/modules/matrix/mautrix-whatsapp.nix +++ b/modules/matrix/mautrix-whatsapp.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let cfg = config.jalr.matrix; @@ -7,21 +7,20 @@ in lib.mkIf cfg.mautrix-whatsapp.enable { services.mautrix-whatsapp = { enable = true; - registerToSynapse = true; - settings = lib.mkForce ({ + settings = { homeserver = { address = synapseCfg.public_baseurl; domain = synapseCfg.server_name; }; - database = { - type = "sqlite3-fk-wal"; - uri = "file:/var/lib/mautrix-whatsapp/mautrix-whatsapp.db?_txlock=immediate"; - }; appservice = rec { hostname = "127.0.0.1"; - inherit (cfg.mautrix-whatsapp) port; + port = cfg.mautrix-whatsapp.port; address = "http://${hostname}:${toString port}"; provisioning.shared_secret = "disable"; + database = { + type = "sqlite3"; + uri = "/var/lib/mautrix-whatsapp/mautrix-whatsapp.db"; + }; id = "whatsapp"; bot = { username = "whatsappbot"; @@ -46,17 +45,11 @@ lib.mkIf cfg.mautrix-whatsapp.enable { relay.enable = false; }; logging = { - file_name_format = null; - min_level = "info"; print_level = "info"; - writers = [ - { - format = "pretty-colored"; - time_format = " "; - type = "stdout"; - } - ]; + file_name_format = null; }; - } // cfg.mautrix-whatsapp.settings); + } // cfg.mautrix-whatsapp.settings; }; + + jalr.matrix.synapse.app_service_config."mautrix-whatsapp" = "/var/lib/mautrix-whatsapp/whatsapp-registration.yaml"; } diff --git a/modules/matrix/synapse.nix b/modules/matrix/synapse.nix index ea3ecc0..11eed82 100644 --- a/modules/matrix/synapse.nix +++ b/modules/matrix/synapse.nix @@ -4,141 +4,100 @@ let cfg = config.jalr.matrix; in lib.mkIf cfg.enable { - services = { - matrix-synapse = { - enable = true; + services.matrix-synapse = { + enable = true; - settings = { - server_name = cfg.domain; - public_baseurl = "https://${cfg.fqdn}"; + settings = { + server_name = cfg.domain; + public_baseurl = "https://${cfg.fqdn}"; - database = { - name = "psycopg2"; - args.user = "matrix-synapse"; - args.database = "matrix-synapse"; + database.name = "sqlite3"; + + listeners = lib.singleton { + port = cfg.synapse.port; + bind_addresses = [ "127.0.0.1" "::1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = lib.singleton { + names = [ "client" "federation" "metrics" ]; + compress = false; }; - - listeners = lib.singleton { - inherit (cfg.synapse) port; - bind_addresses = [ "127.0.0.1" "::1" ]; - type = "http"; - tls = false; - x_forwarded = true; - resources = lib.singleton { - names = [ "client" "federation" "metrics" ]; - compress = false; - }; - }; - - turn_uris = [ - "turns:${cfg.turn.host}:5349?transport=udp" - "turns:${cfg.turn.host}:5349?transport=tcp" - "turn:${cfg.turn.host}:3478?transport=udp" - "turn:${cfg.turn.host}:3478?transport=tcp" - ]; - turn_user_lifetime = "1h"; - - enable_metrics = true; - - # adapted from https://github.com/NixOS/nixpkgs/blob/7e10bf4327491a6ebccbe1aaa8e6c6c0aca4663a/nixos/modules/services/misc/matrix-synapse-log_config.yaml - # - set root.level to WARNING instead of INFO - log_config = pkgs.writeText "log_config.yaml" (builtins.toJSON { - version = 1; - - formatters.journal_fmt.format = "%(name)s: [%(request)s] %(message)s"; - - filters.context = { - "()" = "synapse.util.logcontext.LoggingContextFilter"; - request = ""; - }; - - handlers.journal = { - class = "systemd.journal.JournalHandler"; - formatter = "journal_fmt"; - filters = [ "context" ]; - SYSLOG_IDENTIFIER = "synapse"; - }; - - root = { - level = "WARNING"; - handlers = [ "journal" ]; - }; - - disable_existing_loggers = false; - }); - - max_upload_size = "50M"; - - # I’m okay with using matrix.org as trusted key server - suppress_key_server_warning = true; - - # For mautrix-whatsapp backfilling - experimental_features.msc2716_enabled = true; }; - extraConfigFiles = [ - cfg.turn.sharedSecretFile + turn_uris = [ + "turns:${cfg.turn.host}:5349?transport=udp" + "turns:${cfg.turn.host}:5349?transport=tcp" + "turn:${cfg.turn.host}:3478?transport=udp" + "turn:${cfg.turn.host}:3478?transport=tcp" ]; + turn_user_lifetime = "1h"; + + enable_metrics = true; + + # adapted from https://github.com/NixOS/nixpkgs/blob/7e10bf4327491a6ebccbe1aaa8e6c6c0aca4663a/nixos/modules/services/misc/matrix-synapse-log_config.yaml + # - set root.level to WARNING instead of INFO + log_config = pkgs.writeText "log_config.yaml" (builtins.toJSON { + version = 1; + + formatters.journal_fmt.format = "%(name)s: [%(request)s] %(message)s"; + + filters.context = { + "()" = "synapse.util.logcontext.LoggingContextFilter"; + request = ""; + }; + + handlers.journal = { + class = "systemd.journal.JournalHandler"; + formatter = "journal_fmt"; + filters = [ "context" ]; + SYSLOG_IDENTIFIER = "synapse"; + }; + + root = { + level = "WARNING"; + handlers = [ "journal" ]; + }; + + disable_existing_loggers = false; + }); + + max_upload_size = "50M"; + + # I’m okay with using matrix.org as trusted key server + suppress_key_server_warning = true; + + # For mautrix-whatsapp backfilling + experimental_features.msc2716_enabled = true; }; - matrix-synapse.settings.app_service_config_files = lib.attrsets.mapAttrsToList - ( - name: _: - "/run/matrix-synapse/app_service_config/${name}.yaml" - ) - cfg.synapse.app_service_config; - - nginx.virtualHosts = { - "${cfg.fqdn}" = { - enableACME = true; - forceSSL = true; - - locations."/_matrix" = - let - listenerCfg = lib.elemAt config.services.matrix-synapse.settings.listeners 0; - in - { - proxyPass = "http://${lib.elemAt listenerCfg.bind_addresses 0}:${toString listenerCfg.port}"; - - extraConfig = '' - client_max_body_size ${config.services.matrix-synapse.settings.max_upload_size}; - ''; - }; - }; - - }; - - postgresql = { - enable = true; - ensureDatabases = [ - config.services.matrix-synapse.settings.database.args.database - ]; - ensureUsers = [{ - name = config.services.matrix-synapse.settings.database.args.user; - ensureDBOwnership = true; - }]; - }; + extraConfigFiles = [ + cfg.turn.sharedSecretFile + ]; }; + services.matrix-synapse.settings.app_service_config_files = lib.attrsets.mapAttrsToList + ( + name: value: + "/run/matrix-synapse/app_service_config/${name}.yaml" + ) + cfg.synapse.app_service_config; systemd.services.matrix-synapse = { restartTriggers = lib.attrsets.mapAttrsToList ( - _: value: "${value}" + name: value: + "${value}" ) cfg.synapse.app_service_config; serviceConfig = { - RuntimeDirectory = lib.mkForce [ - "matrix-synapse" - "matrix-synapse/app_service_config" - ]; - RuntimeDirectoryPreserve = lib.mkForce false; + RuntimeDirectory = "matrix-synapse/app_service_config"; ExecStartPre = lib.attrsets.mapAttrsToList (name: value: let script = pkgs.writeShellScript "app_service_config-${name}" '' - cp "${value}" "/run/matrix-synapse/app_service_config/${name}.yaml" - chown matrix-synapse: "/run/matrix-synapse/app_service_config/${name}.yaml" + cp "${value}" "$RUNTIME_DIRECTORY/${name}.yaml" + chown matrix-synapse: "$RUNTIME_DIRECTORY/${name}.yaml" ''; in "+${script}" @@ -146,4 +105,24 @@ lib.mkIf cfg.enable { cfg.synapse.app_service_config; }; }; + + services.nginx.virtualHosts = { + "${cfg.fqdn}" = { + enableACME = true; + forceSSL = true; + + locations."/_matrix" = + let + listenerCfg = (lib.elemAt config.services.matrix-synapse.settings.listeners 0); + in + { + proxyPass = "http://${lib.elemAt listenerCfg.bind_addresses 0}:${toString listenerCfg.port}"; + + extraConfig = '' + client_max_body_size ${config.services.matrix-synapse.settings.max_upload_size}; + ''; + }; + }; + + }; } diff --git a/modules/mobile-network.nix b/modules/mobile-network.nix deleted file mode 100644 index fb7efdb..0000000 --- a/modules/mobile-network.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ config, lib, pkgs, ... }: - -lib.mkIf config.jalr.gui.enable { - environment.systemPackages = with pkgs; [ - usb-modeswitch - ]; -} diff --git a/modules/network-manager.nix b/modules/network-manager.nix new file mode 100644 index 0000000..2c75c57 --- /dev/null +++ b/modules/network-manager.nix @@ -0,0 +1,8 @@ +{ config, lib, pkgs, ... }: + +lib.mkIf config.jalr.gui.enable { + programs.nm-applet = { + enable = true; + indicator = true; + }; +} diff --git a/modules/networking/default.nix b/modules/networking/default.nix deleted file mode 100644 index 80cdff2..0000000 --- a/modules/networking/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ lib -, ... -}: - -{ - imports = [ - ./network-manager.nix - ./ports.nix - ]; - - networking.firewall.logRefusedConnections = lib.mkDefault false; - - networking.nftables.enable = true; -} diff --git a/modules/networking/network-manager.nix b/modules/networking/network-manager.nix deleted file mode 100644 index d70a218..0000000 --- a/modules/networking/network-manager.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ config, lib, ... }: - -lib.mkIf config.jalr.gui.enable { - programs.nm-applet = { - enable = true; - indicator = true; - }; - - networking.networkmanager = { - enable = true; - ensureProfiles.profiles = { - "38C3" = { - connection = { - id = "38C3"; - type = "wifi"; - }; - wifi = { - mode = "infrastructure"; - ssid = "38C3"; - }; - wifi-security = { - auth-alg = "open"; - key-mgmt = "wpa-eap"; - }; - "802-1x" = { - anonymous-identity = "38C3"; - eap = "ttls;"; - identity = "38C3"; - password = "38C3"; - phase2-auth = "pap"; - altsubject-matches = "DNS:radius.c3noc.net"; - ca-cert = "${builtins.fetchurl { - url = "https://letsencrypt.org/certs/isrgrootx1.pem"; - sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92"; - }}"; - }; - ipv4 = { - method = "auto"; - }; - ipv6 = { - addr-gen-mode = "default"; - method = "auto"; - }; - }; - }; - }; -} diff --git a/modules/networking/ports.nix b/modules/networking/ports.nix deleted file mode 100644 index 3e656aa..0000000 --- a/modules/networking/ports.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ lib, ... }: - -{ - options.networking.ports = with lib; with lib.types; mkOption { - type = attrsOf (types.submodule { - options = { - tcp = mkOption { - type = oneOf [ port (listOf port) (attrsOf port) ]; - description = "TCP ports"; - default = [ ]; - }; - udp = mkOption { - type = oneOf [ port (listOf port) (attrsOf port) ]; - description = "UDP ports"; - default = [ ]; - }; - }; - }); - }; -} diff --git a/modules/nix.nix b/modules/nix.nix index eb8f9b4..5d48e97 100644 --- a/modules/nix.nix +++ b/modules/nix.nix @@ -1,7 +1,12 @@ -{ lib, pkgs, inputs, system, ... }: +{ config, lib, pkgs, inputs, system, ... }: { nix = { + package = pkgs.nixFlakes; + extraOptions = '' + experimental-features = nix-command flakes + ''; + daemonCPUSchedPolicy = "idle"; daemonIOSchedClass = "idle"; daemonIOSchedPriority = 7; @@ -11,47 +16,37 @@ ]; settings = { - experimental-features = [ - "nix-command" - "flakes" - ]; trusted-users = [ "@wheel" ]; auto-optimise-store = true; allowed-users = [ "@wheel" ]; - - log-lines = lib.mkDefault 25; - - # Avoid disk full issues - max-free = lib.mkDefault (3000 * 1024 * 1024); - min-free = lib.mkDefault (512 * 1024 * 10); - - download-buffer-size = lib.mkDefault (512 * 1024 * 1024); - }; - gc = { - automatic = true; - options = "--delete-older-than 30d"; - randomizedDelaySec = "60 min"; }; }; - systemd.services.nix-daemon.serviceConfig.OOMScoreAdjust = 250; - - nixpkgs.config.permittedInsecurePackages = [ - "olm-3.2.16" - ]; - - nixpkgs.overlays = [ - inputs.self.overlays.default - (_: prev: { + nixpkgs.overlays = with inputs; [ + self.overlays.default + (final: prev: { master = import inputs.nixpkgsMaster { inherit system; - inherit (prev) config; + config = prev.config; }; }) - ]; + ] + # Tradebyte access points use legacy crypto + ++ lib.optional config.jalr.tradebyte.enable ( + final: prev: + let + inherit (prev) callPackage; + in + { + wpa_supplicant = prev.wpa_supplicant.overrideAttrs (attrs: { + patches = attrs.patches ++ [ + ./wpa_supplicant/SSL_CTX_set_options-SSL_OP_LEGACY_SERVER_CONNECT.patch + ]; + }); + } + ); environment.systemPackages = with pkgs; [ cached-nix-shell - git ]; } diff --git a/modules/obs.nix b/modules/obs.nix index e8bcf9f..7f66004 100644 --- a/modules/obs.nix +++ b/modules/obs.nix @@ -11,4 +11,8 @@ lib.mkIf config.jalr.gui.enable { environment.systemPackages = with pkgs; [ v4l-utils ]; + + services.udev.extraRules = '' + SUBSYSTEM=="video4linux", ATTR{idVendor}=="2109", ATTR{idProduct}=="2813", SYMLINK+="video_c922" + ''; } diff --git a/modules/pipewire.nix b/modules/pipewire.nix index ea97fb6..cb4cf02 100644 --- a/modules/pipewire.nix +++ b/modules/pipewire.nix @@ -1,14 +1,14 @@ { config, lib, pkgs, ... }: lib.mkIf config.jalr.gui.enable { - services.pulseaudio.enable = false; + sound.enable = true; + hardware.pulseaudio.enable = false; # FIXME #hardware.pulseaudio.extraModules = [ pkgs.pulseaudio-modules-bt ]; services.pipewire = { enable = true; - package = pkgs.master.pipewire; pulse = { enable = true; }; @@ -19,33 +19,6 @@ lib.mkIf config.jalr.gui.enable { enable = true; support32Bit = true; }; - extraConfig = { - pipewire-pulse."10-snapcast-discover" = { - "context.modules" = [ - { - name = "libpipewire-module-snapcast-discover"; - args = { - stream.rules = [{ - matches = [{ - snapcast.ip = "~.*"; - }]; - actions = { - create-stream = { }; - }; - }]; - }; - } - ]; - }; - /* - pipewire."raop-sink" = { - "context.modules" = [ - { name = "libpipewire-module-raop-discover"; args = { }; } - ]; - }; - */ - }; - raopOpenFirewall = true; }; environment.systemPackages = with pkgs; [ @@ -62,7 +35,4 @@ lib.mkIf config.jalr.gui.enable { value = "unlimited"; } ]; - - security.rtkit.enable = true; - } diff --git a/modules/podman.nix b/modules/podman.nix index 79486f1..d7453a9 100644 --- a/modules/podman.nix +++ b/modules/podman.nix @@ -1,11 +1,7 @@ -{ pkgs, ... }: { virtualisation.podman = { enable = true; dockerCompat = true; dockerSocket.enable = true; }; - environment.systemPackages = with pkgs; [ - podman-compose - ]; } diff --git a/modules/printers/default.nix b/modules/printers/default.nix index b207377..8692599 100644 --- a/modules/printers/default.nix +++ b/modules/printers/default.nix @@ -3,6 +3,7 @@ { imports = [ ./hl3172cdw.nix + ./p-touch_p700.nix ]; config = lib.mkIf config.jalr.gui.enable { # install virtual pdf printer diff --git a/modules/printers/p-touch_p700.nix b/modules/printers/p-touch_p700.nix new file mode 100644 index 0000000..627ad56 --- /dev/null +++ b/modules/printers/p-touch_p700.nix @@ -0,0 +1,7 @@ +{ config, lib, ... }: + +{ + services.udev.extraRules = '' + SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="04f9", ATTR{idProduct}=="2061", OWNER="root", GROUP="users", MODE="660" + ''; +} diff --git a/modules/providers/hetzner-cloud.nix b/modules/providers/hetzner-cloud.nix deleted file mode 100644 index c1e0b16..0000000 --- a/modules/providers/hetzner-cloud.nix +++ /dev/null @@ -1,108 +0,0 @@ -{ config -, pkgs -, modulesPath -, ... -}: -let - cfg = config.disko; -in -{ - imports = [ - (modulesPath + "/profiles/qemu-guest.nix") - ]; - - config = { - networking.useDHCP = false; - - systemd.network = { - enable = true; - networks."10-wan" = { - matchConfig.Name = "enp1s0"; - networkConfig.DHCP = "ipv4"; - routes = [ - { Gateway = "fe80::1"; } - ]; - }; - }; - - boot = { - loader = { - grub.enable = pkgs.hostPlatform.system == "x86_64-linux"; - systemd-boot = { - enable = pkgs.hostPlatform.system == "aarch64-linux"; - configurationLimit = 10; - }; - efi = { - efiSysMountPoint = "/boot"; - canTouchEfiVariables = true; - }; - }; - }; - disko.devices = { - disk = { - virt = { - type = "disk"; - content = { - type = "gpt"; - partitions = { - boot = { - size = "1M"; - type = "EF02"; # for grub MBR - priority = 1; # Needs to be first partition - }; - esp = { - type = "EF00"; - size = "1024M"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - mountOptions = [ "uid=0" "gid=0" "fmask=0077" "dmask=0077" "nodev" "nosuid" "noexec" ]; - }; - }; - linux = { - size = "100%"; - content = { - type = "btrfs"; - extraArgs = [ "-f" ]; - postCreateHook = - let - inherit (cfg.devices.disk.virt.content.partitions.linux) device; - in - '' - mountpoint="$(mktemp -d)" - mount "${device}" "$mountpoint" -o subvol=/ - trap 'umount "$mountpoint"; rmdir "$mountpoint"' EXIT - btrfs subvolume snapshot -r $mountpoint/root $mountpoint/root-blank - ''; - subvolumes = { - "/root" = { - mountpoint = "/"; - mountOptions = [ "compress-force=zstd:1" "noatime" ]; - }; - "/home" = { - mountpoint = "/home"; - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - "/nix" = { - mountpoint = "/nix"; - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" ]; - }; - "/log" = { - mountpoint = "/var/log"; - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - "/persist" = { - mountpoint = "/persist"; - mountOptions = [ "compress-force=zstd:1" "noatime" "nodev" "nosuid" ]; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/modules/qbittorrent/default.nix b/modules/qbittorrent/default.nix new file mode 100644 index 0000000..810685b --- /dev/null +++ b/modules/qbittorrent/default.nix @@ -0,0 +1,94 @@ +{ config, inputs, lib, pkgs, ... }: +let + cfg = config.jalr.qbittorrent; +in +{ + options.jalr.qbittorrent = { + enable = lib.mkEnableOption "the qbittorrent service"; + homeDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/qbittorrent"; + }; + configDir = lib.mkOption { + type = lib.types.path; + default = "${cfg.homeDir}/config"; + }; + downloadDir = lib.mkOption { + type = lib.types.path; + default = "${cfg.homeDir}/download"; + }; + webuiPort = lib.mkOption { + type = lib.types.int; + default = 8099; + }; + sopsFile = lib.mkOption { + type = lib.types.path; + default = ../../hosts/${config.networking.hostName}/secrets.yaml; + description = '' + The sops secret file that includes the htpasswd file. + ''; + }; + fqdn = lib.mkOption { + type = lib.types.str; + description = "The fqdn nginx should listen on. It must not be used for anything else."; + }; + }; + + config = lib.mkIf cfg.enable + { + users.users.qbittorrent = { + group = "qbittorrent"; + home = cfg.homeDir; + isSystemUser = true; + }; + users.groups.qbittorrent = { }; + + systemd.tmpfiles.rules = [ + "d '${cfg.downloadDir}' 0775 qbittorrent users - -" + "d '${cfg.homeDir}' 0771 qbittorrent qbittorrent - -" + ]; + + sops.secrets.sturzbach-htpasswd = { + sopsFile = cfg.sopsFile; + owner = "nginx"; + }; + + systemd.services.qbittorrent = { + description = "qBittorrent Service"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Restart = "always"; + ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox --profile=${cfg.configDir} --webui-port=${toString cfg.webuiPort}"; + User = "qbittorrent"; + Group = "qbittorrent"; + + # Increase number of open file descriptors (default: 1024) + LimitNOFILE = 65536; + + # systemd-analyze --no-pager security qbittorrent.service + CapabilityBoundingSet = null; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectHome = true; + RestrictNamespaces = true; + SystemCallFilter = "@system-service"; + }; + }; + + services.nginx.virtualHosts."${cfg.fqdn}" = { + enableACME = lib.mkDefault true; + forceSSL = lib.mkDefault true; + + basicAuthFile = config.sops.secrets.sturzbach-htpasswd.path; + + locations = { + "/" = { + proxyPass = "http://127.0.0.1:${toString cfg.webuiPort}"; + proxyWebsockets = true; + }; + }; + }; + }; +} diff --git a/modules/sdr.nix b/modules/sdr.nix new file mode 100644 index 0000000..a0b7686 --- /dev/null +++ b/modules/sdr.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.jalr; +in +{ + options.jalr = { + sdr = { + enable = pkgs.lib.mkEnableOption "Enable software defined radio"; + }; + }; + config = lib.mkIf cfg.sdr.enable { + services.udev.extraRules = '' + # rad10 + SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="cc15", GROUP="users", MODE="0660" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6089", GROUP="users", MODE="0660" + ''; + }; +} diff --git a/modules/sshd.nix b/modules/sshd.nix index 040ed09..3ad95f3 100644 --- a/modules/sshd.nix +++ b/modules/sshd.nix @@ -1,61 +1,6 @@ -{ lib -, config -, ... -}: - { services.openssh = { enable = true; - settings = { - KbdInteractiveAuthentication = false; - Ciphers = [ - "aes256-gcm@openssh.com" - ]; - # Use key exchange algorithms recommended by `nixpkgs#ssh-audit` - KexAlgorithms = [ - "curve25519-sha256" - "curve25519-sha256@libssh.org" - "diffie-hellman-group16-sha512" - "diffie-hellman-group18-sha512" - "sntrup761x25519-sha512@openssh.com" - ]; - PasswordAuthentication = false; - StreamLocalBindUnlink = true; # unbind gnupg sockets if they exists - UseDns = false; - X11Forwarding = false; - }; - hostKeys = [ - { - path = "/etc/ssh/ssh_host_ed25519_key"; - type = "ed25519"; - } - ]; - authorizedKeysFiles = lib.mkForce [ "/etc/ssh/authorized_keys.d/%u" ]; + settings.PasswordAuthentication = false; }; - - networking.nftables.tables."nixos-fw".content = lib.mkOrder 20 '' - set ssh-ratelimit-v4 { - type ipv4_addr - timeout 60s - flags dynamic - } - - set ssh-ratelimit-v6 { - type ipv6_addr - timeout 60s - flags dynamic - } - ''; - - # Implement connection rate limit - services.openssh.openFirewall = false; - networking.firewall.extraInputRules = lib.mkOrder 5 ( - let - ports = builtins.concatStringsSep ", " (map builtins.toString config.services.openssh.ports); - in - '' - tcp dport { ${ports} } update @ssh-ratelimit-v4 { ip saddr limit rate 1/second burst 10 packets } accept - tcp dport { ${ports} } update @ssh-ratelimit-v6 { ip6 saddr limit rate 1/second burst 10 packets } accept - '' - ); } diff --git a/modules/steelseries-nova-pro.nix b/modules/steelseries-nova-pro.nix deleted file mode 100644 index d432dca..0000000 --- a/modules/steelseries-nova-pro.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ lib, config, ... }: - -lib.mkIf config.jalr.gui.enable { - services.gg-chatmix = { - enable = true; - }; -} diff --git a/modules/sudo.nix b/modules/sudo.nix index da6577a..d47d889 100644 --- a/modules/sudo.nix +++ b/modules/sudo.nix @@ -1,3 +1,4 @@ +{ pkgs, inputs, ... }: let commandsWithoutPassword = [ "/run/current-system/sw/bin/systemctl restart tor.service" diff --git a/modules/sway.nix b/modules/sway.nix index dbd37fe..b234c37 100644 --- a/modules/sway.nix +++ b/modules/sway.nix @@ -1,65 +1,36 @@ { config, lib, pkgs, ... }: -lib.mkIf (config.jalr.gui.enable && config.jalr.gui.sway.enable) { - services.displayManager.sessionPackages = [ pkgs.sway ]; - - programs = { - wshowkeys.enable = true; - dconf.enable = true; - sway = { - enable = true; - xwayland.enable = true; - wrapperFeatures.gtk = true; - }; +lib.mkIf config.jalr.gui.enable { + programs.sway = { + enable = true; + # FIXME: move to home manager + extraPackages = with pkgs; [ + grim + mako + gammastep + slurp + wl-clipboard + xwayland + ]; + extraSessionCommands = '' + export XKB_DEFAULT_LAYOUT=de # TODO: test if we need it + export XKB_DEFAULT_VARIANT=neo # TODO: test if we need it + export QT_QPA_PLATFORM=wayland + export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 + export ELM_ENGINE=wayland_shm + export GDK_BACKEND=wayland + export _JAVA_AWT_WM_NONREPARENTING=1 + ''; }; - services.greetd = { - enable = !config.jalr.gui.gnome.enable; - settings = - let - command = pkgs.writeShellScript "sway-init" '' - systemctl --user import-environment PATH - #systemctl --user restart xdg-desktop-portal.service - exec ${pkgs.sway}/bin/sway - ''; - user = "jalr"; - in - { - default_session = { - inherit command; - inherit user; - }; - initial_session = { - inherit command; - inherit user; - }; - }; - }; - - hardware.graphics.enable = true; - - security.polkit.enable = true; - - security.pam.loginLimits = [{ - domain = "@users"; - item = "rtprio"; - type = "-"; - value = 1; - }]; - xdg = { - icons.enable = true; portal = { enable = true; - wlr.enable = true; - extraPortals = [ - pkgs.xdg-desktop-portal-gtk + extraPortals = with pkgs; [ + xdg-desktop-portal-wlr + xdg-desktop-portal-gtk ]; - xdgOpenUsePortal = true; }; + icons.enable = true; }; - - environment.systemPackages = with pkgs; [ - adwaita-icon-theme - ]; } diff --git a/modules/tor.nix b/modules/tor.nix new file mode 100644 index 0000000..c33b3c5 --- /dev/null +++ b/modules/tor.nix @@ -0,0 +1,17 @@ +{ lib, config, ... }: + +{ + config = lib.mkIf config.jalr.workstation.enable { + services.tor = { + enable = true; + settings = { + DNSPort = 9053; + AutomapHostsOnResolve = true; + AutomapHostsSuffixes = [ + ".exit" + ".onion" + ]; + }; + }; + }; +} diff --git a/modules/tradebyte/default.nix b/modules/tradebyte/default.nix new file mode 100644 index 0000000..de83fba --- /dev/null +++ b/modules/tradebyte/default.nix @@ -0,0 +1,8 @@ +{ lib, ... }: + +{ + options.jalr = { + tradebyte.enable = lib.mkEnableOption "TB.config"; + }; +} + diff --git a/modules/udev.nix b/modules/udev.nix deleted file mode 100644 index 908a711..0000000 --- a/modules/udev.nix +++ /dev/null @@ -1,31 +0,0 @@ -let - usbDeviceRules = [ - # rad10 - { vendor = "1d50"; product = "cc15"; group = "users"; mode = "0660"; } - { vendor = "1d50"; product = "6089"; group = "users"; mode = "0660"; } - - # DJI Goggles - { vendor = "2ca3"; product = "001f"; group = "plugdev"; mode = "0660"; } - - # uDMX - { vendor = "16c0"; product = "05dc"; group = "users"; mode = "0660"; } - - # Brother P-touch P700 - { vendor = "04f9"; product = "2061"; group = "users"; mode = "0660"; } - - # RP2040 in BOOTSEL mode - { vendor = "2e8a"; product = "0003"; group = "users"; mode = "0660"; } - - # RP2350 in BOOTSEL mode - { vendor = "2e8a"; product = "000f"; group = "users"; mode = "0660"; } - - # WCH Link (CMSIS-DAP compatible adapter) - { vendor = "1a86"; product = "8010"; group = "plugdev"; mode = "0660"; } - ]; - - mkUsbRule = rule: - ''SUBSYSTEM=="usb", ATTR{idVendor}=="${rule.vendor}", ATTR{idProduct}=="${rule.product}", GROUP="${rule.group}", MODE="${rule.mode}"''; -in -{ - services.udev.extraRules = builtins.concatStringsSep "\n" (map mkUsbRule usbDeviceRules); -} diff --git a/pkgs/ksoloti/module.nix b/modules/udmx.nix similarity index 58% rename from pkgs/ksoloti/module.nix rename to modules/udmx.nix index 2948be5..da8df93 100644 --- a/pkgs/ksoloti/module.nix +++ b/modules/udmx.nix @@ -1,5 +1,8 @@ +{ config, lib, pkgs, ... }: + { services.udev.extraRules = '' - SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="0442", OWNER="jalr", GROUP="users" + # uDMX + SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="05dc", GROUP="users", MODE="0660" ''; } diff --git a/modules/unfree.nix b/modules/unfree.nix index a24df1c..3394261 100644 --- a/modules/unfree.nix +++ b/modules/unfree.nix @@ -1,11 +1,8 @@ { lib, ... }: { - nixpkgs.config.allowUnfreePredicate = pkg: lib.elem (lib.getName pkg) [ - "mongodb" - "rar2fs" - "roomeqwizard" + nixpkgs.config.allowUnfreePredicate = (pkg: lib.elem (lib.getName pkg) [ "unifi-controller" - "unrar" - ]; + "mongodb" + ]); } diff --git a/modules/upgrade-diff.nix b/modules/upgrade-diff.nix deleted file mode 100644 index ccdbe4c..0000000 --- a/modules/upgrade-diff.nix +++ /dev/null @@ -1,14 +0,0 @@ -# MIT Jörg Thalheim - https://github.com/Mic92/dotfiles/blob/c6cad4e57016945c4816c8ec6f0a94daaa0c3203/nixos/modules/upgrade-diff.nix -{ config, pkgs, ... }: -{ - system.activationScripts.diff = { - supportsDryActivation = true; - text = '' - if [[ -e /run/current-system ]]; then - echo "--- diff to current-system" - ${pkgs.nvd}/bin/nvd --nix-bin-dir=${config.nix.package}/bin diff /run/current-system "$systemConfig" - echo "---" - fi - ''; - }; -} diff --git a/modules/wireshark.nix b/modules/wireshark.nix new file mode 100644 index 0000000..878f649 --- /dev/null +++ b/modules/wireshark.nix @@ -0,0 +1,7 @@ +{ config, lib, pkgs, ... }: +lib.mkIf config.jalr.gui.enable { + programs.wireshark = { + enable = true; + package = pkgs.wireshark; + }; +} diff --git a/modules/wireshark/default.nix b/modules/wireshark/default.nix deleted file mode 100644 index 6c1b0c0..0000000 --- a/modules/wireshark/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ config, lib, pkgs, ... }: -let - extcap = ./extcap; - pythonWithPackages = pkgs.python3.withPackages (pp: with pp; [ - pyserial - psutil - ]); - nrf_sniffer_ble = pkgs.writeShellScript "nrf_sniffer_ble" '' - script_path=$(dirname `which $0`) - - exec ${pythonWithPackages}/bin/python3 $script_path/nrf_sniffer_ble.py "$@" - ''; -in -lib.mkIf config.jalr.gui.enable { - programs.wireshark = { - enable = true; - package = pkgs.wireshark.overrideAttrs (o: { - postInstall = '' - cp -r ${extcap}/* ${nrf_sniffer_ble} $out/lib/wireshark/extcap - '' + o.postInstall; - }); - }; -} diff --git a/modules/wireshark/extcap/SnifferAPI/CaptureFiles.py b/modules/wireshark/extcap/SnifferAPI/CaptureFiles.py deleted file mode 100644 index 8c218e5..0000000 --- a/modules/wireshark/extcap/SnifferAPI/CaptureFiles.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import time, os, logging -from . import Logger -from . import Pcap - - -DEFAULT_CAPTURE_FILE_DIR = Logger.DEFAULT_LOG_FILE_DIR -DEFAULT_CAPTURE_FILE_NAME = "capture.pcap" - - -def get_capture_file_path(capture_file_path=None): - default_path = os.path.join(DEFAULT_CAPTURE_FILE_DIR, DEFAULT_CAPTURE_FILE_NAME) - if capture_file_path is None: - return default_path - if os.path.splitext(capture_file_path)[1] != ".pcap": - return default_path - return os.path.abspath(capture_file_path) - - -class CaptureFileHandler: - def __init__(self, capture_file_path=None, clear=False): - filename = get_capture_file_path(capture_file_path) - if not os.path.isdir(os.path.dirname(filename)): - os.makedirs(os.path.dirname(filename)) - self.filename = filename - self.backupFilename = self.filename + ".1" - if not os.path.isfile(self.filename): - self.startNewFile() - elif os.path.getsize(self.filename) > 20000000: - self.doRollover() - if clear: - # clear file - self.startNewFile() - - def startNewFile(self): - with open(self.filename, "wb") as f: - f.write(Pcap.get_global_header()) - - def doRollover(self): - try: - os.remove(self.backupFilename) - except: - logging.exception("capture file rollover remove backup failed") - try: - os.rename(self.filename, self.backupFilename) - self.startNewFile() - except: - logging.exception("capture file rollover failed") - - def writePacket(self, packet): - with open(self.filename, "ab") as f: - packet = Pcap.create_packet( - bytes([packet.boardId] + packet.getList()), packet.time - ) - f.write(packet) diff --git a/modules/wireshark/extcap/SnifferAPI/Devices.py b/modules/wireshark/extcap/SnifferAPI/Devices.py deleted file mode 100644 index 61ac961..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Devices.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright (c) 2017, Nordic Semiconductor ASA -# -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from . import Notifications -import logging, threading - - -class DeviceList(Notifications.Notifier): - def __init__(self, *args, **kwargs): - Notifications.Notifier.__init__(self, *args, **kwargs) - logging.info("args: " + str(args)) - logging.info("kwargs: " + str(kwargs)) - self._deviceListLock = threading.RLock() - with self._deviceListLock: - self.devices = [] - - def __len__(self): - return len(self.devices) - - def __repr__(self): - return "Sniffer Device List: " + str(self.asList()) - - def clear(self): - logging.info("Clearing") - with self._deviceListLock: - self.devices = [] - self.notify("DEVICES_CLEARED") - - def appendOrUpdate(self, newDevice): - with self._deviceListLock: - existingDevice = self.find(newDevice) - - # Add device to the list of devices being displayed, but only if CRC is OK - if existingDevice == None: - self.append(newDevice) - else: - updated = False - if (newDevice.name != '""') and (existingDevice.name == '""'): - existingDevice.name = newDevice.name - updated = True - - if ( - newDevice.RSSI != 0 - and (existingDevice.RSSI < (newDevice.RSSI - 5)) - or (existingDevice.RSSI > (newDevice.RSSI + 2)) - ): - existingDevice.RSSI = newDevice.RSSI - updated = True - - if updated: - self.notify("DEVICE_UPDATED", existingDevice) - - def append(self, device): - self.devices.append(device) - self.notify("DEVICE_ADDED", device) - - def find(self, id): - if type(id) == list: - for dev in self.devices: - if dev.address == id: - return dev - elif type(id) == int: - return self.devices[id] - elif type(id) == str: - for dev in self.devices: - if dev.name in [id, '"' + id + '"']: - return dev - elif id.__class__.__name__ == "Device": - return self.find(id.address) - return None - - def remove(self, id): - if type(id) == list: # address - device = self.devices.pop(self.devices.index(self.find(id))) - elif type(id) == int: - device = self.devices.pop(id) - elif type(id) == Device: - device = self.devices.pop(self.devices.index(self.find(id.address))) - self.notify("DEVICE_REMOVED", device) - - def index(self, device): - index = 0 - for dev in self.devices: - if dev.address == device.address: - return index - index += 1 - return None - - def setFollowed(self, device): - if device in self.devices: - for dev in self.devices: - dev.followed = False - device.followed = True - self.notify("DEVICE_FOLLOWED", device) - - def asList(self): - return self.devices[:] - - -class Device: - def __init__(self, address, name, RSSI): - self.address = address - self.name = name - self.RSSI = RSSI - self.followed = False - - def __repr__(self): - return 'Bluetooth LE device "' + self.name + '" (' + str(self.address) + ")" - - -def listToString(list): - str = "" - for i in list: - str += chr(i) - return str diff --git a/modules/wireshark/extcap/SnifferAPI/Exceptions.py b/modules/wireshark/extcap/SnifferAPI/Exceptions.py deleted file mode 100644 index 86f356a..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Exceptions.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -class SnifferTimeout(Exception): - pass - - -class UARTPacketError(Exception): - pass - - -class LockedException(Exception): - def __init__(self, message): - self.message = message - - -class InvalidPacketException(Exception): - pass - - -class InvalidAdvChannel(Exception): - pass - - -# Internal Use -class SnifferWatchDogTimeout(SnifferTimeout): - pass - - -# Internal Use -class ExitCodeException(Exception): - pass diff --git a/modules/wireshark/extcap/SnifferAPI/Filelock.py b/modules/wireshark/extcap/SnifferAPI/Filelock.py deleted file mode 100644 index 7bf21b5..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Filelock.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -import logging -from sys import platform - -if platform == "linux": - import psutil - -from . import Exceptions - -# Lock file management. -# ref: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s09.html -# -# Stored in /var/lock: -# The naming convention which must be used is "LCK.." followed by the base name of the device. -# For example, to lock /dev/ttyS0 the file "LCK..ttyS0" would be created. -# HDB UUCP lock file format: -# process identifier (PID) as a ten byte ASCII decimal number, with a trailing newline - - -def lockpid(lockfile): - if os.path.isfile(lockfile): - with open(lockfile) as fd: - lockpid = fd.read() - - try: - return int(lockpid) - except: - logging.info("Lockfile is invalid. Overriding it..") - os.remove(lockfile) - return 0 - - return 0 - - -def lock(port): - if platform != "linux": - return - - tty = os.path.basename(port) - lockfile = os.path.join("/run", "user", f"{os.getuid()}", f"{tty}.lock") - - lockedpid = lockpid(lockfile) - if lockedpid: - if lockedpid == os.getpid(): - return - - if psutil.pid_exists(lockedpid): - raise Exceptions.LockedException(f"Device {port} is locked") - else: - logging.info("Lockfile is stale. Overriding it..") - os.remove(lockfile) - - fd = open(lockfile, "w") - with open(lockfile, "w") as fd: - fd.write(f"{os.getpid():10}") - - -def unlock(port): - if platform != "linux": - return - - tty = os.path.basename(port) - lockfile = f"/var/lock/LCK..{tty}" - - lockedpid = lockpid(lockfile) - if lockedpid == os.getpid(): - os.remove(lockfile) diff --git a/modules/wireshark/extcap/SnifferAPI/Logger.py b/modules/wireshark/extcap/SnifferAPI/Logger.py deleted file mode 100644 index 228a0f1..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Logger.py +++ /dev/null @@ -1,214 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import time, os, logging, traceback, threading -import logging.handlers as logHandlers - -################################################################# -# This file contains the logger. To log a line, simply write # -# 'logging.[level]("whatever you want to log")' # -# [level] is one of {info, debug, warning, error, critical, # -# exception} # -# See python logging documentation # -# As long as Logger.initLogger has been called beforehand, this # -# will result in the line being appended to the log file # -################################################################# - -appdata = os.getenv("appdata") -if appdata: - DEFAULT_LOG_FILE_DIR = os.path.join( - appdata, "Nordic Semiconductor", "Sniffer", "logs" - ) -else: - DEFAULT_LOG_FILE_DIR = "/tmp/logs" - -DEFAULT_LOG_FILE_NAME = "log.txt" - -logFileName = None -logHandler = None -logHandlerArray = [] -logFlusher = None - -myMaxBytes = 1000000 - - -def setLogFileName(log_file_path): - global logFileName - logFileName = os.path.abspath(log_file_path) - - -# Ensure that the directory we are writing the log file to exists. -# Create our logfile, and write the timestamp in the first line. -def initLogger(): - try: - global logFileName - if logFileName is None: - logFileName = os.path.join(DEFAULT_LOG_FILE_DIR, DEFAULT_LOG_FILE_NAME) - - # First, make sure that the directory exists - if not os.path.isdir(os.path.dirname(logFileName)): - os.makedirs(os.path.dirname(logFileName)) - - # If the file does not exist, create it, and save the timestamp - if not os.path.isfile(logFileName): - with open(logFileName, "w") as f: - f.write(str(time.time()) + str(os.linesep)) - - global logFlusher - global logHandlerArray - - logHandler = MyRotatingFileHandler( - logFileName, mode="a", maxBytes=myMaxBytes, backupCount=3 - ) - logFormatter = logging.Formatter( - "%(asctime)s %(levelname)s: %(message)s", datefmt="%d-%b-%Y %H:%M:%S (%z)" - ) - logHandler.setFormatter(logFormatter) - logger = logging.getLogger() - logger.addHandler(logHandler) - logger.setLevel(logging.INFO) - logFlusher = LogFlusher(logHandler) - logHandlerArray.append(logHandler) - except: - print("LOGGING FAILED") - print(traceback.format_exc()) - raise - - -def shutdownLogger(): - if logFlusher is not None: - logFlusher.stop() - logging.shutdown() - - -# Clear the log (typically after it has been sent on email) -def clearLog(): - try: - logHandler.doRollover() - except: - print("LOGGING FAILED") - raise - - -# Returns the timestamp residing on the first line of the logfile. Used for checking the time of creation -def getTimestamp(): - try: - with open(logFileName, "r") as f: - f.seek(0) - return f.readline() - except: - print("LOGGING FAILED") - - -def addTimestamp(): - try: - with open(logFileName, "a") as f: - f.write(str(time.time()) + os.linesep) - except: - print("LOGGING FAILED") - - -# Returns the entire content of the logfile. Used when sending emails -def readAll(): - try: - text = "" - with open(logFileName, "r") as f: - text = f.read() - return text - except: - print("LOGGING FAILED") - - -def addLogHandler(logHandler): - global logHandlerArray - logger = logging.getLogger() - logger.addHandler(logHandler) - logger.setLevel(logging.INFO) - logHandlerArray.append(logHandler) - - -def removeLogHandler(logHandler): - global logHandlerArray - logger = logging.getLogger() - logger.removeHandler(logHandler) - logHandlerArray.remove(logHandler) - - -class MyRotatingFileHandler(logHandlers.RotatingFileHandler): - def doRollover(self): - try: - logHandlers.RotatingFileHandler.doRollover(self) - addTimestamp() - self.maxBytes = myMaxBytes - except: - # There have been permissions issues with the log files. - self.maxBytes += int(myMaxBytes / 2) - - -class LogFlusher(threading.Thread): - def __init__(self, logHandler): - threading.Thread.__init__(self) - - self.daemon = True - self.handler = logHandler - self.exit = threading.Event() - - self.start() - - def run(self): - while True: - if self.exit.wait(10): - try: - self.doFlush() - except AttributeError as e: - print(e) - break - self.doFlush() - - def doFlush(self): - self.handler.flush() - os.fsync(self.handler.stream.fileno()) - - def stop(self): - self.exit.set() - - -if __name__ == "__main__": - initLogger() - for i in range(50): - logging.info("test log no. " + str(i)) - print("test log no. ", i) diff --git a/modules/wireshark/extcap/SnifferAPI/Notifications.py b/modules/wireshark/extcap/SnifferAPI/Notifications.py deleted file mode 100644 index b7cba37..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Notifications.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import threading, logging - - -class Notification: - def __init__(self, key, msg=None): - if type(key) is not str: - raise TypeError("Invalid notification key: " + str(key)) - self.key = key - self.msg = msg - - def __repr__(self): - return "Notification (key: %s, msg: %s)" % (str(self.key), str(self.msg)) - - -class Notifier: - def __init__(self, callbacks=[], **kwargs): - self.callbacks = {} - self.callbackLock = threading.RLock() - - for callback in callbacks: - self.subscribe(*callback) - - def clearCallbacks(self): - with self.callbackLock: - self.callbacks.clear() - - def subscribe(self, key, callback): - with self.callbackLock: - if callback not in self.getCallbacks(key): - self.getCallbacks(key).append(callback) - - def unSubscribe(self, key, callback): - with self.callbackLock: - if callback in self.getCallbacks(key): - self.getCallbacks(key).remove(callback) - - def getCallbacks(self, key): - with self.callbackLock: - if key not in self.callbacks: - self.callbacks[key] = [] - return self.callbacks[key] - - def notify(self, key=None, msg=None, notification=None): - with self.callbackLock: - if notification == None: - notification = Notification(key, msg) - - for callback in self.getCallbacks(notification.key): - callback(notification) - - for callback in self.getCallbacks("*"): - callback(notification) - - def passOnNotification(self, notification): - self.notify(notification=notification) diff --git a/modules/wireshark/extcap/SnifferAPI/Packet.py b/modules/wireshark/extcap/SnifferAPI/Packet.py deleted file mode 100644 index bc4abd9..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Packet.py +++ /dev/null @@ -1,651 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from . import UART, Exceptions, Notifications -import time, logging, os, sys, serial -from .Types import * - -ADV_ACCESS_ADDRESS = [0xD6, 0xBE, 0x89, 0x8E] - -SYNCWORD_POS = 0 -PAYLOAD_LEN_POS_V1 = 1 -PAYLOAD_LEN_POS = 0 -PROTOVER_POS = PAYLOAD_LEN_POS + 2 -PACKETCOUNTER_POS = PROTOVER_POS + 1 -ID_POS = PACKETCOUNTER_POS + 2 - -BLE_HEADER_LEN_POS = ID_POS + 1 -FLAGS_POS = BLE_HEADER_LEN_POS + 1 -CHANNEL_POS = FLAGS_POS + 1 -RSSI_POS = CHANNEL_POS + 1 -EVENTCOUNTER_POS = RSSI_POS + 1 -TIMESTAMP_POS = EVENTCOUNTER_POS + 2 -BLEPACKET_POS = TIMESTAMP_POS + 4 -TXADD_POS = BLEPACKET_POS + 4 -TXADD_MSK = 0x40 -PAYLOAD_POS = BLE_HEADER_LEN_POS - -HEADER_LENGTH = 6 -BLE_HEADER_LENGTH = 10 - -VALID_ADV_CHANS = [37, 38, 39] - -PACKET_COUNTER_CAP = 2**16 - - -class PacketReader(Notifications.Notifier): - def __init__(self, portnum=None, callbacks=[], baudrate=None): - Notifications.Notifier.__init__(self, callbacks) - self.portnum = portnum - try: - self.uart = UART.Uart(portnum, baudrate) - except serial.SerialException as e: - logging.exception("Error opening UART %s" % str(e)) - self.uart = UART.Uart() - self.packetCounter = 0 - self.lastReceivedPacketCounter = 0 - self.lastReceivedPacket = None - self.lastReceivedTimestampPacket = None - self.supportedProtocolVersion = PROTOVER_V3 - - def setup(self): - pass - - def doExit(self): - # This method will always join the Uart worker thread - self.uart.close() - # Clear method references to avoid uncollectable cyclic references - self.clearCallbacks() - - # This function takes a byte list, encode it in SLIP protocol and return the encoded byte list - def encodeToSLIP(self, byteList): - tempSLIPBuffer = [] - tempSLIPBuffer.append(SLIP_START) - for i in byteList: - if i == SLIP_START: - tempSLIPBuffer.append(SLIP_ESC) - tempSLIPBuffer.append(SLIP_ESC_START) - elif i == SLIP_END: - tempSLIPBuffer.append(SLIP_ESC) - tempSLIPBuffer.append(SLIP_ESC_END) - elif i == SLIP_ESC: - tempSLIPBuffer.append(SLIP_ESC) - tempSLIPBuffer.append(SLIP_ESC_ESC) - else: - tempSLIPBuffer.append(i) - tempSLIPBuffer.append(SLIP_END) - return tempSLIPBuffer - - # This function uses getSerialByte() function to get SLIP encoded bytes from the serial port and return a decoded byte list - # Based on https://github.com/mehdix/pyslip/ - def decodeFromSLIP(self, timeout=None, complete_timeout=None): - dataBuffer = [] - startOfPacket = False - endOfPacket = False - - if complete_timeout is not None: - time_start = time.time() - - while not startOfPacket and ( - complete_timeout is None or (time.time() - time_start < complete_timeout) - ): - res = self.getSerialByte(timeout) - startOfPacket = res == SLIP_START - - while not endOfPacket and ( - complete_timeout is None or (time.time() - time_start < complete_timeout) - ): - serialByte = self.getSerialByte(timeout) - if serialByte == SLIP_END: - endOfPacket = True - elif serialByte == SLIP_ESC: - serialByte = self.getSerialByte(timeout) - if serialByte == SLIP_ESC_START: - dataBuffer.append(SLIP_START) - elif serialByte == SLIP_ESC_END: - dataBuffer.append(SLIP_END) - elif serialByte == SLIP_ESC_ESC: - dataBuffer.append(SLIP_ESC) - else: - dataBuffer.append(SLIP_END) - else: - dataBuffer.append(serialByte) - if not endOfPacket: - raise Exceptions.UARTPacketError( - "Exceeded max timeout of %f seconds." % complete_timeout - ) - return dataBuffer - - # This function read byte chuncks from the serial port and return one byte at a time - # Based on https://github.com/mehdix/pyslip/ - def getSerialByte(self, timeout=None): - serialByte = self.uart.readByte(timeout) - if serialByte is None: - raise Exceptions.SnifferTimeout("Packet read timed out.") - return serialByte - - def handlePacketHistory(self, packet): - # Reads and validates packet counter - if ( - self.lastReceivedPacket is not None - and packet.packetCounter - != (self.lastReceivedPacket.packetCounter + 1) % PACKET_COUNTER_CAP - and self.lastReceivedPacket.packetCounter != 0 - ): - - logging.info( - "gap in packets, between " - + str(self.lastReceivedPacket.packetCounter) - + " and " - + str(packet.packetCounter) - + " packet before: " - + str(self.lastReceivedPacket.packetList) - + " packet after: " - + str(packet.packetList) - ) - - self.lastReceivedPacket = packet - if packet.id in [EVENT_PACKET_DATA_PDU, EVENT_PACKET_ADV_PDU]: - self.lastReceivedTimestampPacket = packet - - def getPacketTime(self, packet): - ble_payload_length = self.lastReceivedPacket.payloadLength - BLE_HEADER_LENGTH - - if packet.phy == PHY_1M: - return 8 * (1 + ble_payload_length) - elif packet.phy == PHY_2M: - return 4 * (2 + ble_payload_length) - elif packet.phy == PHY_CODED: - # blePacket is not assigned if not packet is "OK" (CRC error) - ci = packet.packetList[BLEPACKET_POS + 4] - fec2_block_len = ble_payload_length - 4 - 1 - fec1_block_us = 80 + 256 + 16 + 24 - if ci == PHY_CODED_CI_S8: - return fec1_block_us + 64 * fec2_block_len + 24 - elif ci == PHY_CODED_CI_S2: - return fec1_block_us + 16 * fec2_block_len + 6 - # Unknown PHY or Coding Indicator - return 0 - - def convertPacketListProtoVer2(self, packet): - # Convert to version 2 - packet.packetList[PROTOVER_POS] = 2 - - # Convert to common packet ID - if packet.packetList[ID_POS] == EVENT_PACKET_ADV_PDU: - packet.packetList[ID_POS] = EVENT_PACKET_DATA_PDU - - if packet.packetList[ID_POS] != EVENT_PACKET_DATA_PDU: - # These types do not have a timestamp - return - - # Convert time-stamp to End to Start delta - time_delta = 0 - if ( - self.lastReceivedTimestampPacket is not None - and self.lastReceivedTimestampPacket.valid - ): - time_delta = packet.timestamp - ( - self.lastReceivedTimestampPacket.timestamp - + self.getPacketTime(self.lastReceivedTimestampPacket) - ) - - time_delta = toLittleEndian(time_delta, 4) - packet.packetList[TIMESTAMP_POS] = time_delta[0] - packet.packetList[TIMESTAMP_POS + 1] = time_delta[1] - packet.packetList[TIMESTAMP_POS + 2] = time_delta[2] - packet.packetList[TIMESTAMP_POS + 3] = time_delta[3] - - def handlePacketCompatibility(self, packet): - if ( - self.supportedProtocolVersion == PROTOVER_V2 - and packet.packetList[PROTOVER_POS] > PROTOVER_V2 - ): - self.convertPacketListProtoVer2(packet) - - def setSupportedProtocolVersion(self, supportedProtocolVersion): - if supportedProtocolVersion != PROTOVER_V3: - logging.info( - "Using packet compatibility, converting packets to protocol version %d", - supportedProtocolVersion, - ) - self.supportedProtocolVersion = supportedProtocolVersion - - def getPacket(self, timeout=None): - packetList = [] - try: - packetList = self.decodeFromSLIP(timeout) - except Exceptions.UARTPacketError: # FIXME: This is never thrown... - logging.exception("") - return None - else: - packet = Packet(packetList) - if packet.valid: - self.handlePacketCompatibility(packet) - self.handlePacketHistory(packet) - return packet - - def sendPacket(self, id, payload): - packetList = ( - [HEADER_LENGTH] - + [len(payload)] - + [PROTOVER_V1] - + toLittleEndian(self.packetCounter, 2) - + [id] - + payload - ) - packetList = self.encodeToSLIP(packetList) - self.packetCounter += 1 - self.uart.writeList(packetList) - - def sendScan(self, findScanRsp=False, findAux=False, scanCoded=False): - flags0 = findScanRsp | (findAux << 1) | (scanCoded << 2) - self.sendPacket(REQ_SCAN_CONT, [flags0]) - logging.info("Scan flags: %s" % bin(flags0)) - - def sendFollow( - self, - addr, - followOnlyAdvertisements=False, - followOnlyLegacy=False, - followCoded=False, - ): - flags0 = followOnlyAdvertisements | (followOnlyLegacy << 1) | (followCoded << 2) - logging.info("Follow flags: %s" % bin(flags0)) - self.sendPacket(REQ_FOLLOW, addr + [flags0]) - - def sendPingReq(self): - self.sendPacket(PING_REQ, []) - - def getBytes(self, value, size): - if len(value) < size: - value = [0] * (size - len(value)) + value - else: - value = value[:size] - - return value - - def sendTK(self, TK): - TK = self.getBytes(TK, 16) - self.sendPacket(SET_TEMPORARY_KEY, TK) - logging.info("Sent TK to sniffer: " + str(TK)) - - def sendPrivateKey(self, pk): - pk = self.getBytes(pk, 32) - self.sendPacket(SET_PRIVATE_KEY, pk) - logging.info("Sent private key to sniffer: " + str(pk)) - - def sendLegacyLTK(self, ltk): - ltk = self.getBytes(ltk, 16) - self.sendPacket(SET_LEGACY_LONG_TERM_KEY, ltk) - logging.info("Sent Legacy LTK to sniffer: " + str(ltk)) - - def sendSCLTK(self, ltk): - ltk = self.getBytes(ltk, 16) - self.sendPacket(SET_SC_LONG_TERM_KEY, ltk) - logging.info("Sent SC LTK to sniffer: " + str(ltk)) - - def sendIRK(self, irk): - irk = self.getBytes(irk, 16) - self.sendPacket(SET_IDENTITY_RESOLVING_KEY, irk) - logging.info("Sent IRK to sniffer: " + str(irk)) - - def sendSwitchBaudRate(self, newBaudRate): - self.sendPacket(SWITCH_BAUD_RATE_REQ, toLittleEndian(newBaudRate, 4)) - - def switchBaudRate(self, newBaudRate): - self.uart.switchBaudRate(newBaudRate) - - def sendHopSequence(self, hopSequence): - for chan in hopSequence: - if chan not in VALID_ADV_CHANS: - raise Exceptions.InvalidAdvChannel( - "%s is not an adv channel" % str(chan) - ) - payload = [len(hopSequence)] + hopSequence + [37] * (3 - len(hopSequence)) - self.sendPacket(SET_ADV_CHANNEL_HOP_SEQ, payload) - self.notify("NEW_ADV_HOP_SEQ", {"hopSequence": hopSequence}) - - def sendVersionReq(self): - self.sendPacket(REQ_VERSION, []) - - def sendTimestampReq(self): - self.sendPacket(REQ_TIMESTAMP, []) - - def sendGoIdle(self): - self.sendPacket(GO_IDLE, []) - - -class Packet: - def __init__(self, packetList): - try: - if not packetList: - raise Exceptions.InvalidPacketException( - "packet list not valid: %s" % str(packetList) - ) - - self.protover = packetList[PROTOVER_POS] - - if self.protover > PROTOVER_V3: - logging.exception( - "Unsupported protocol version %s" % str(self.protover) - ) - raise RuntimeError( - "Unsupported protocol version %s" % str(self.protover) - ) - - self.packetCounter = parseLittleEndian( - packetList[PACKETCOUNTER_POS : PACKETCOUNTER_POS + 2] - ) - self.id = packetList[ID_POS] - - if int(self.protover) == PROTOVER_V1: - self.payloadLength = packetList[PAYLOAD_LEN_POS_V1] - else: - self.payloadLength = parseLittleEndian( - packetList[PAYLOAD_LEN_POS : PAYLOAD_LEN_POS + 2] - ) - - self.packetList = packetList - self.readPayload(packetList) - - except Exceptions.InvalidPacketException as e: - logging.error("Invalid packet: %s" % str(e)) - self.OK = False - self.valid = False - except Exception as e: - logging.exception("packet creation error %s" % str(e)) - logging.info("packetList: " + str(packetList)) - self.OK = False - self.valid = False - - def __repr__(self): - return "UART packet, type: " + str(self.id) + ", PC: " + str(self.packetCounter) - - def readPayload(self, packetList): - self.blePacket = None - self.OK = False - - if not self.validatePacketList(packetList): - raise Exceptions.InvalidPacketException( - "packet list not valid: %s" % str(packetList) - ) - else: - self.valid = True - - self.payload = packetList[PAYLOAD_POS : PAYLOAD_POS + self.payloadLength] - - if self.id == EVENT_PACKET_ADV_PDU or self.id == EVENT_PACKET_DATA_PDU: - try: - self.bleHeaderLength = packetList[BLE_HEADER_LEN_POS] - if self.bleHeaderLength == BLE_HEADER_LENGTH: - self.flags = packetList[FLAGS_POS] - self.readFlags() - self.channel = packetList[CHANNEL_POS] - self.rawRSSI = packetList[RSSI_POS] - self.RSSI = -self.rawRSSI - self.eventCounter = parseLittleEndian( - packetList[EVENTCOUNTER_POS : EVENTCOUNTER_POS + 2] - ) - - self.timestamp = parseLittleEndian( - packetList[TIMESTAMP_POS : TIMESTAMP_POS + 4] - ) - - # The hardware adds a padding byte which isn't sent on air. - # We remove it, and update the payload length in the packet list. - if self.phy == PHY_CODED: - self.packetList.pop(BLEPACKET_POS + 6 + 1) - else: - self.packetList.pop(BLEPACKET_POS + 6) - self.payloadLength -= 1 - if self.protover >= PROTOVER_V2: - # Write updated payload length back to the packet list. - payloadLength = toLittleEndian(self.payloadLength, 2) - packetList[PAYLOAD_LEN_POS] = payloadLength[0] - packetList[PAYLOAD_LEN_POS + 1] = payloadLength[1] - else: # PROTOVER_V1 - packetList[PAYLOAD_LEN_POS_V1] = self.payloadLength - else: - logging.info("Invalid BLE Header Length " + str(packetList)) - self.valid = False - - if self.OK: - try: - if self.protover >= PROTOVER_V3: - packet_type = ( - PACKET_TYPE_ADVERTISING - if self.id == EVENT_PACKET_ADV_PDU - else PACKET_TYPE_DATA - ) - else: - packet_type = ( - PACKET_TYPE_ADVERTISING - if packetList[BLEPACKET_POS : BLEPACKET_POS + 4] - == ADV_ACCESS_ADDRESS - else PACKET_TYPE_DATA - ) - - self.blePacket = BlePacket( - packet_type, packetList[BLEPACKET_POS:], self.phy - ) - except Exception as e: - logging.exception("blePacket error %s" % str(e)) - except Exception as e: - # malformed packet - logging.exception("packet error %s" % str(e)) - self.OK = False - elif self.id == PING_RESP: - if self.protover < PROTOVER_V3: - self.version = parseLittleEndian( - packetList[PAYLOAD_POS : PAYLOAD_POS + 2] - ) - elif self.id == RESP_VERSION: - self.version = "".join([chr(i) for i in packetList[PAYLOAD_POS:]]) - elif self.id == RESP_TIMESTAMP: - self.timestamp = parseLittleEndian( - packetList[PAYLOAD_POS : PAYLOAD_POS + 4] - ) - elif self.id == SWITCH_BAUD_RATE_RESP or self.id == SWITCH_BAUD_RATE_REQ: - self.baudRate = parseLittleEndian(packetList[PAYLOAD_POS : PAYLOAD_POS + 4]) - else: - logging.info("Unknown packet ID") - - def readFlags(self): - self.crcOK = not not (self.flags & 1) - self.direction = not not (self.flags & 2) - self.encrypted = not not (self.flags & 4) - self.micOK = not not (self.flags & 8) - self.phy = (self.flags >> 4) & 7 - self.OK = self.crcOK and (self.micOK or not self.encrypted) - - def getList(self): - return self.packetList - - def validatePacketList(self, packetList): - try: - if (self.payloadLength + HEADER_LENGTH) == len(packetList): - return True - else: - return False - except: - logging.exception("Invalid packet: %s" % str(packetList)) - return False - - -class BlePacket: - def __init__(self, type, packetList, phy): - self.type = type - - offset = 0 - offset = self.extractAccessAddress(packetList, offset) - offset = self.extractFormat(packetList, phy, offset) - - if self.type == PACKET_TYPE_ADVERTISING: - offset = self.extractAdvHeader(packetList, offset) - else: - offset = self.extractConnHeader(packetList, offset) - - offset = self.extractLength(packetList, offset) - self.payload = packetList[offset:] - - if self.type == PACKET_TYPE_ADVERTISING: - offset = self.extractAddresses(packetList, offset) - self.extractName(packetList, offset) - - def __repr__(self): - return "BLE packet, AAddr: " + str(self.accessAddress) - - def extractAccessAddress(self, packetList, offset): - self.accessAddress = packetList[offset : offset + 4] - return offset + 4 - - def extractFormat(self, packetList, phy, offset): - self.coded = phy == PHY_CODED - if self.coded: - self.codingIndicator = packetList[offset] & 3 - return offset + 1 - - return offset - - def extractAdvHeader(self, packetList, offset): - self.advType = packetList[offset] & 15 - self.txAddrType = (packetList[offset] >> 6) & 1 - if self.advType in [1, 3, 5]: - self.rxAddrType = (packetList[offset] << 7) & 1 - elif self.advType == 7: - flags = packetList[offset + 2] - if flags & 0x02: - self.rxAddrType = (packetList[offset] << 7) & 1 - return offset + 1 - - def extractConnHeader(self, packetList, offset): - self.llid = packetList[offset] & 3 - self.sn = (packetList[offset] >> 2) & 1 - self.nesn = (packetList[offset] >> 3) & 1 - self.md = (packetList[offset] >> 4) & 1 - return offset + 1 - - def extractAddresses(self, packetList, offset): - addr = None - scanAddr = None - - if self.advType in [0, 1, 2, 4, 6]: - addr = packetList[offset : offset + 6] - addr.reverse() - addr += [self.txAddrType] - offset += 6 - - if self.advType in [3, 5]: - scanAddr = packetList[offset : offset + 6] - scanAddr.reverse() - scanAddr += [self.txAddrType] - offset += 6 - addr = packetList[offset : offset + 6] - addr.reverse() - addr += [self.rxAddrType] - offset += 6 - - if self.advType == 1: - scanAddr = packetList[offset : offset + 6] - scanAddr.reverse() - scanAddr += [self.rxAddrType] - offset += 6 - - if self.advType == 7: - ext_header_len = packetList[offset] & 0x3F - offset += 1 - - ext_header_offset = offset - flags = packetList[offset] - ext_header_offset += 1 - - if flags & 0x01: - addr = packetList[ext_header_offset : ext_header_offset + 6] - addr.reverse() - addr += [self.txAddrType] - ext_header_offset += 6 - - if flags & 0x02: - scanAddr = packetList[ext_header_offset : ext_header_offset + 6] - scanAddr.reverse() - scanAddr += [self.rxAddrType] - ext_header_offset += 6 - - offset += ext_header_len - - self.advAddress = addr - self.scanAddress = scanAddr - return offset - - def extractName(self, packetList, offset): - name = "" - if self.advType in [0, 2, 4, 6, 7]: - i = offset - while i < len(packetList): - length = packetList[i] - if (i + length + 1) > len(packetList) or length == 0: - break - type = packetList[i + 1] - if type == 8 or type == 9: - nameList = packetList[i + 2 : i + length + 1] - name = "" - for j in nameList: - name += chr(j) - i += length + 1 - name = '"' + name + '"' - elif self.advType == 1: - name = "[ADV_DIRECT_IND]" - - self.name = name - - def extractLength(self, packetList, offset): - self.length = packetList[offset] - return offset + 1 - - -def parseLittleEndian(list): - total = 0 - for i in range(len(list)): - total += list[i] << (8 * i) - return total - - -def toLittleEndian(value, size): - list = [0] * size - for i in range(size): - list[i] = (value >> (i * 8)) % 256 - return list diff --git a/modules/wireshark/extcap/SnifferAPI/Pcap.py b/modules/wireshark/extcap/SnifferAPI/Pcap.py deleted file mode 100644 index 8b0445a..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Pcap.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import struct - - -# See: -# - https://github.com/pcapng/pcapng -# - https://www.tcpdump.org/linktypes/LINKTYPE_NORDIC_BLE.html -PACKET_HEADER = struct.Struct("= PROTOVER_V3: - if self._last_time is None: - # Timestamp from Host - packet.time = time.time() - else: - # Timestamp using reference and packet timestamp diff - if packet.timestamp < self._last_timestamp: - time_diff = (1 << 32) - (self._last_timestamp - packet.timestamp) - else: - time_diff = packet.timestamp - self._last_timestamp - - packet.time = self._last_time + (time_diff / 1_000_000) - - self._last_time = packet.time - self._last_timestamp = packet.timestamp - else: - # Timestamp from Host - packet.time = time.time() - - self._appendPacket(packet) - - self.notify("NEW_BLE_PACKET", {"packet": packet}) - self._captureHandler.writePacket(packet) - - self._nProcessedPackets += 1 - if packet.OK: - try: - if packet.blePacket.type == PACKET_TYPE_ADVERTISING: - - if self.state == STATE_FOLLOWING and packet.blePacket.advType == 5: - self._connectionAccessAddress = packet.blePacket.accessAddress - - if self.state == STATE_FOLLOWING and packet.blePacket.advType == 4: - newDevice = Devices.Device( - address=packet.blePacket.advAddress, - name=packet.blePacket.name, - RSSI=packet.RSSI, - ) - self._devices.appendOrUpdate(newDevice) - - if self.state == STATE_SCANNING: - if ( - packet.blePacket.advType in [0, 1, 2, 4, 6, 7] - and packet.blePacket.advAddress != None - and packet.crcOK - and not packet.direction - ): - newDevice = Devices.Device( - address=packet.blePacket.advAddress, - name=packet.blePacket.name, - RSSI=packet.RSSI, - ) - self._devices.appendOrUpdate(newDevice) - - except Exception as e: - logging.exception("packet processing error %s" % str(e)) - self.notify("PACKET_PROCESSING_ERROR", {"errorString": str(e)}) - - def _continuouslyPipe(self): - while not self._exit: - try: - packet = self._packetReader.getPacket(timeout=12) - if packet == None or not packet.valid: - raise Exceptions.InvalidPacketException("") - except Exceptions.SnifferTimeout as e: - logging.info(str(e)) - packet = None - except (SerialException, ValueError): - logging.exception("UART read error") - logging.error("Lost contact with sniffer hardware.") - self._doExit() - except Exceptions.InvalidPacketException: - pass - else: - if ( - packet.id == EVENT_PACKET_DATA_PDU - or packet.id == EVENT_PACKET_ADV_PDU - ): - self._processBLEPacket(packet) - elif packet.id == EVENT_FOLLOW: - # This packet has no value for the user. - pass - elif packet.id == EVENT_CONNECT: - self._connectEventPacketCounterValue = packet.packetCounter - self._inConnection = True - # copy it because packets are eventually deleted - self._currentConnectRequest = copy.copy( - self._findPacketByPacketCounter( - self._connectEventPacketCounterValue - 1 - ) - ) - elif packet.id == EVENT_DISCONNECT: - if self._inConnection: - self._packetsInLastConnection = ( - packet.packetCounter - self._connectEventPacketCounterValue - ) - self._inConnection = False - elif packet.id == SWITCH_BAUD_RATE_RESP and self._switchingBaudRate: - self._switchingBaudRate = False - if packet.baudRate == self._proposedBaudRate: - self._packetReader.switchBaudRate(self._proposedBaudRate) - else: - self._switchBaudRate(packet.baudRate) - elif packet.id == PING_RESP: - if hasattr(packet, "version"): - versions = { - 1116: "3.1.0", - 1115: "3.0.0", - 1114: "2.0.0", - 1113: "2.0.0-beta-3", - 1112: "2.0.0-beta-1", - } - self._fwversion = versions.get( - packet.version, "SVN rev: %d" % packet.version - ) - logging.info("Firmware version %s" % self._fwversion) - elif packet.id == RESP_VERSION: - self._fwversion = packet.version - logging.info("Firmware version %s" % self._fwversion) - elif packet.id == RESP_TIMESTAMP: - # Use current time as timestamp reference - self._last_time = time.time() - self._last_timestamp = packet.timestamp - - lt = time.localtime(self._last_time) - usecs = int((self._last_time - int(self._last_time)) * 1_000_000) - logging.info( - f"Firmware timestamp {self._last_timestamp} reference: " - f'{time.strftime("%b %d %Y %X", lt)}.{usecs} {time.strftime("%Z", lt)}' - ) - else: - logging.info("Unknown packet ID") - - def _findPacketByPacketCounter(self, packetCounterValue): - with self._packetListLock: - for i in range(-1, -1 - len(self._packets), -1): - # iterate backwards through packets - if self._packets[i].packetCounter == packetCounterValue: - return self._packets[i] - return None - - def _startScanning(self, findScanRsp=False, findAux=False, scanCoded=False): - logging.info("starting scan") - - if self.state == STATE_FOLLOWING: - logging.info("Stopped sniffing device") - - self._setState(STATE_SCANNING) - self._packetReader.sendScan(findScanRsp, findAux, scanCoded) - self._packetReader.sendTK([0]) - - def _doExit(self): - self._exit = True - self.notify("APP_EXIT") - self._packetReader.doExit() - # Clear method references to avoid uncollectable cyclic references - self.clearCallbacks() - self._devices.clearCallbacks() - - def _startFollowing( - self, - device, - followOnlyAdvertisements=False, - followOnlyLegacy=False, - followCoded=False, - ): - self._devices.setFollowed(device) - logging.info( - "Sniffing device " - + str(self._devices.index(device)) - + ' - "' - + device.name - + '"' - ) - self._packetReader.sendFollow( - device.address, followOnlyAdvertisements, followOnlyLegacy, followCoded - ) - self._setState(STATE_FOLLOWING) - - def _clearDevices(self): - self._devices.clear() - - def _appendPacket(self, packet): - with self._packetListLock: - if len(self._packets) > 100000: - self._packets = self._packets[20000:] - self._packets.append(packet) - - def _getPackets(self, number=-1): - with self._packetListLock: - returnList = self._packets[0:number] - self._packets = self._packets[number:] - return returnList - - def _clearPackets(self): - with self._packetListLock: - del self._packets[:] diff --git a/modules/wireshark/extcap/SnifferAPI/Types.py b/modules/wireshark/extcap/SnifferAPI/Types.py deleted file mode 100644 index eac7609..0000000 --- a/modules/wireshark/extcap/SnifferAPI/Types.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -SLIP_START = 0xAB -SLIP_END = 0xBC -SLIP_ESC = 0xCD -SLIP_ESC_START = SLIP_START + 1 -SLIP_ESC_END = SLIP_END + 1 -SLIP_ESC_ESC = SLIP_ESC + 1 - -PROTOVER_V3 = 3 -PROTOVER_V2 = 2 -PROTOVER_V1 = 1 - -# UART protocol packet codes (see sniffer_uart_protocol.pdf) -REQ_FOLLOW = 0x00 -EVENT_FOLLOW = 0x01 -EVENT_PACKET_ADV_PDU = 0x02 -EVENT_CONNECT = 0x05 -EVENT_PACKET_DATA_PDU = 0x06 -REQ_SCAN_CONT = 0x07 -EVENT_DISCONNECT = 0x09 -SET_TEMPORARY_KEY = 0x0C -PING_REQ = 0x0D -PING_RESP = 0x0E -SWITCH_BAUD_RATE_REQ = 0x13 -SWITCH_BAUD_RATE_RESP = 0x14 -SET_ADV_CHANNEL_HOP_SEQ = 0x17 -SET_PRIVATE_KEY = 0x18 -SET_LEGACY_LONG_TERM_KEY = 0x19 -SET_SC_LONG_TERM_KEY = 0x1A -REQ_VERSION = 0x1B -RESP_VERSION = 0x1C -REQ_TIMESTAMP = 0x1D -RESP_TIMESTAMP = 0x1E -SET_IDENTITY_RESOLVING_KEY = 0x1F -GO_IDLE = 0xFE - -PACKET_TYPE_UNKNOWN = 0x00 -PACKET_TYPE_ADVERTISING = 0x01 -PACKET_TYPE_DATA = 0x02 - -ADV_TYPE_ADV_IND = 0x0 -ADV_TYPE_ADV_DIRECT_IND = 0x1 -ADV_TYPE_ADV_NONCONN_IND = 0x2 -ADV_TYPE_ADV_SCAN_IND = 0x6 -ADV_TYPE_SCAN_REQ = 0x3 -ADV_TYPE_SCAN_RSP = 0x4 -ADV_TYPE_CONNECT_REQ = 0x5 -ADV_TYPE_ADV_EXT_IND = 0x7 - -PHY_1M = 0 -PHY_2M = 1 -PHY_CODED = 2 - -PHY_CODED_CI_S8 = 0 -PHY_CODED_CI_S2 = 1 diff --git a/modules/wireshark/extcap/SnifferAPI/UART.py b/modules/wireshark/extcap/SnifferAPI/UART.py deleted file mode 100644 index ecd16d2..0000000 --- a/modules/wireshark/extcap/SnifferAPI/UART.py +++ /dev/null @@ -1,238 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import collections -import logging -import serial -from threading import Thread, Event - -import serial.tools.list_ports as list_ports - -from . import Exceptions -from . import Packet -from . import Filelock - -import os - -if os.name == "posix": - import termios - -SNIFFER_OLD_DEFAULT_BAUDRATE = 460800 -# Baudrates that should be tried (add more if required) -SNIFFER_BAUDRATES = [1000000, 460800] - - -def find_sniffer(write_data=False): - open_ports = list_ports.comports() - - sniffers = [] - for port in [x.device for x in open_ports]: - for rate in SNIFFER_BAUDRATES: - reader = None - l_errors = [ - serial.SerialException, - ValueError, - Exceptions.LockedException, - OSError, - ] - if os.name == "posix": - l_errors.append(termios.error) - try: - reader = Packet.PacketReader(portnum=port, baudrate=rate) - try: - if write_data: - reader.sendPingReq() - _ = reader.decodeFromSLIP(0.1, complete_timeout=0.1) - else: - _ = reader.decodeFromSLIP(0.3, complete_timeout=0.3) - - # FIXME: Should add the baud rate here, but that will be a breaking change - sniffers.append(port) - break - except (Exceptions.SnifferTimeout, Exceptions.UARTPacketError): - pass - except tuple(l_errors): - continue - finally: - if reader is not None: - reader.doExit() - return sniffers - - -def find_sniffer_baudrates(port, write_data=False): - for rate in SNIFFER_BAUDRATES: - reader = None - try: - reader = Packet.PacketReader(portnum=port, baudrate=rate) - try: - if write_data: - reader.sendPingReq() - _ = reader.decodeFromSLIP(0.1, complete_timeout=0.1) - else: - _ = reader.decodeFromSLIP(0.3, complete_timeout=0.3) - - # TODO: possibly include additional rates based on protocol version - return {"default": rate, "other": []} - except (Exceptions.SnifferTimeout, Exceptions.UARTPacketError): - pass - finally: - if reader is not None: - reader.doExit() - return None - - -class Uart: - def __init__(self, portnum=None, baudrate=None): - self.ser = None - try: - if baudrate is not None and baudrate not in SNIFFER_BAUDRATES: - raise Exception("Invalid baudrate: " + str(baudrate)) - - logging.info("Opening serial port {}".format(portnum)) - - self.portnum = portnum - if self.portnum: - Filelock.lock(portnum) - - self.ser = serial.Serial( - port=portnum, baudrate=9600, rtscts=True, exclusive=True - ) - self.ser.baudrate = baudrate - - except Exception: - if self.ser: - self.ser.close() - self.ser = None - raise - - self.read_queue = collections.deque() - self.read_queue_has_data = Event() - - self.worker_thread = Thread(target=self._read_worker) - self.reading = True - self.worker_thread.setDaemon(True) - self.worker_thread.start() - - def _read_worker(self): - self.ser.reset_input_buffer() - while self.reading: - try: - # Read any data available, or wait for at least one byte - data_read = self.ser.read(self.ser.in_waiting or 1) - # logging.info('type: {}'.format(data_read.__class__)) - self._read_queue_extend(data_read) - except serial.SerialException as e: - logging.info("Unable to read UART: %s" % e) - self.reading = False - return - - def close(self): - if self.ser: - logging.info("closing UART") - self.reading = False - # Wake any threads waiting on the queue - self.read_queue_has_data.set() - if hasattr(self.ser, "cancel_read"): - self.ser.cancel_read() - self.worker_thread.join() - self.ser.close() - else: - self.ser.close() - self.worker_thread.join() - self.ser = None - - if self.portnum: - Filelock.unlock(self.portnum) - - def __del__(self): - self.close() - - def switchBaudRate(self, newBaudRate): - self.ser.baudrate = newBaudRate - - def readByte(self, timeout=None): - r = self._read_queue_get(timeout) - return r - - def writeList(self, array): - try: - self.ser.write(array) - except serial.SerialTimeoutException: - logging.info("Got write timeout, ignoring error") - - except serial.SerialException as e: - self.ser.close() - raise e - - def _read_queue_extend(self, data): - if len(data) > 0: - self.read_queue.extend(data) - self.read_queue_has_data.set() - - def _read_queue_get(self, timeout=None): - data = None - if self.read_queue_has_data.wait(timeout): - self.read_queue_has_data.clear() - try: - data = self.read_queue.popleft() - except IndexError: - # This will happen when the class is destroyed - return None - if len(self.read_queue) > 0: - self.read_queue_has_data.set() - return data - - -def list_serial_ports(): - # Scan for available ports. - return list_ports.comports() - - -if __name__ == "__main__": - import time - - t_start = time.time() - s = find_sniffer() - tn = time.time() - print(s) - print("find_sniffer took %f seconds" % (tn - t_start)) - for p in s: - t = time.time() - print(find_sniffer_baudrates(p)) - tn = time.time() - print("find_sniffer_baudrate took %f seconds" % (tn - t)) - tn = time.time() - print("total runtime %f" % (tn - t_start)) diff --git a/modules/wireshark/extcap/SnifferAPI/__init__.py b/modules/wireshark/extcap/SnifferAPI/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/modules/wireshark/extcap/SnifferAPI/version.py b/modules/wireshark/extcap/SnifferAPI/version.py deleted file mode 100644 index 5b94c32..0000000 --- a/modules/wireshark/extcap/SnifferAPI/version.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -VERSION_STRING = "4.1.1" diff --git a/modules/wireshark/extcap/nrf_sniffer_ble.py b/modules/wireshark/extcap/nrf_sniffer_ble.py deleted file mode 100644 index 1aa1380..0000000 --- a/modules/wireshark/extcap/nrf_sniffer_ble.py +++ /dev/null @@ -1,991 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) Nordic Semiconductor ASA -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form, except as embedded into a Nordic -# Semiconductor ASA integrated circuit in a product or a software update for -# such product, must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of Nordic Semiconductor ASA nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# 4. This software, with or without modification, must only be used with a -# Nordic Semiconductor ASA integrated circuit. -# -# 5. Any software provided in binary form under this license must not be reverse -# engineered, decompiled, modified and/or disassembled. -# -# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -""" -Wireshark extcap wrapper for the nRF Sniffer for Bluetooth LE by Nordic Semiconductor. -""" - -import os -import sys -import argparse -import re -import time -import struct -import logging - -from SnifferAPI import Logger - -try: - import serial -except ImportError: - Logger.initLogger() - logging.error( - f'pyserial not found, please run: "{sys.executable} -m pip install -r requirements.txt" and retry' - ) - sys.exit( - f'pyserial not found, please run: "{sys.executable} -m pip install -r requirements.txt" and retry' - ) - -from SnifferAPI import Sniffer, UART, Devices, Pcap, Exceptions - -ERROR_USAGE = 0 -ERROR_ARG = 1 -ERROR_INTERFACE = 2 -ERROR_FIFO = 3 -ERROR_INTERNAL = 4 - -CTRL_CMD_INIT = 0 -CTRL_CMD_SET = 1 -CTRL_CMD_ADD = 2 -CTRL_CMD_REMOVE = 3 -CTRL_CMD_ENABLE = 4 -CTRL_CMD_DISABLE = 5 -CTRL_CMD_STATUSBAR = 6 -CTRL_CMD_INFO_MSG = 7 -CTRL_CMD_WARN_MSG = 8 -CTRL_CMD_ERROR_MSG = 9 - -CTRL_ARG_DEVICE = 0 -CTRL_ARG_KEY_TYPE = 1 -CTRL_ARG_KEY_VAL = 2 -CTRL_ARG_ADVHOP = 3 -CTRL_ARG_HELP = 4 -CTRL_ARG_RESTORE = 5 -CTRL_ARG_LOG = 6 -CTRL_ARG_DEVICE_CLEAR = 7 -CTRL_ARG_NONE = 255 - -CTRL_KEY_TYPE_PASSKEY = 0 -CTRL_KEY_TYPE_OOB = 1 -CTRL_KEY_TYPE_LEGACY_LTK = 2 -CTRL_KEY_TYPE_SC_LTK = 3 -CTRL_KEY_TYPE_DH_PRIVATE_KEY = 4 -CTRL_KEY_TYPE_IRK = 5 -CTRL_KEY_TYPE_ADD_ADDR = 6 -CTRL_KEY_TYPE_FOLLOW_ADDR = 7 - -fn_capture = None -fn_ctrl_in = None -fn_ctrl_out = None - -extcap_log_handler = None -extcap_version = None - -# Wireshark nRF Sniffer for Bluetooth LE Toolbar will always cache the last used key and adv hop and send -# this when starting a capture. To ensure that the key and adv hop is always shown correctly -# in the Toolbar, even if the user has changed it but not applied it, we send the last used -# key and adv hop back as a default value. -last_used_key_type = CTRL_KEY_TYPE_PASSKEY -last_used_key_val = "" -last_used_advhop = "37,38,39" - -zero_addr = "[00,00,00,00,00,00,0]" - -# While searching for a selected Device we must not write packets to the pipe until -# the device is found to avoid getting advertising packets from other devices. -write_new_packets = False - -# The RSSI capture filter value given from Wireshark. -rssi_filter = 0 - -# The RSSI filtering is not on when in follow mode. -in_follow_mode = False - -# nRF Sniffer for Bluetooth LE interface option to only capture advertising packets -capture_only_advertising = False -capture_only_legacy_advertising = False -capture_scan_response = True -capture_scan_aux_pointer = True -capture_coded = False - - -def extcap_config(interface): - """List configuration for the given interface""" - print( - "arg {number=0}{call=--only-advertising}{display=Only advertising packets}" - "{tooltip=The sniffer will only capture advertising packets from the selected device}{type=boolflag}{save=true}" - ) - print( - "arg {number=1}{call=--only-legacy-advertising}{display=Only legacy advertising packets}" - "{tooltip=The sniffer will only capture legacy advertising packets from the selected device}{type=boolflag}{save=true}" - ) - print( - "arg {number=2}{call=--scan-follow-rsp}{display=Find scan response data}" - "{tooltip=The sniffer will follow scan requests and scan responses in scan mode}{type=boolflag}{default=true}{save=true}" - ) - print( - "arg {number=3}{call=--scan-follow-aux}{display=Find auxiliary pointer data}" - "{tooltip=The sniffer will follow aux pointers in scan mode}{type=boolflag}{default=true}{save=true}" - ) - print( - "arg {number=3}{call=--coded}{display=Scan and follow devices on LE Coded PHY}" - "{tooltip=Scan for devices and follow advertiser on LE Coded PHY}{type=boolflag}{default=false}{save=true}" - ) - - -def extcap_dlts(interface): - """List DLTs for the given interface""" - print("dlt {number=272}{name=NORDIC_BLE}{display=nRF Sniffer for Bluetooth LE}") - - -def get_baud_rates(interface): - if not hasattr(serial, "__version__") or not serial.__version__.startswith("3."): - raise RuntimeError( - "Too old version of python 'serial' Library. Version 3 required." - ) - return UART.find_sniffer_baudrates(interface) - - -def get_interfaces(): - if not hasattr(serial, "__version__") or not serial.__version__.startswith("3."): - raise RuntimeError( - "Too old version of python 'serial' Library. Version 3 required." - ) - - devices = UART.find_sniffer() - return devices - - -def extcap_interfaces(): - """List available interfaces to capture from""" - print( - "extcap {version=%s}{display=nRF Sniffer for Bluetooth LE}" - "{help=https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Sniffer-for-Bluetooth-LE}" - % Sniffer.VERSION_STRING - ) - - for interface_port in get_interfaces(): - if sys.platform == "win32": - print( - "interface {value=%s-%s}{display=nRF Sniffer for Bluetooth LE %s}" - % (interface_port, extcap_version, interface_port) - ) - else: - print( - "interface {value=%s-%s}{display=nRF Sniffer for Bluetooth LE}" - % (interface_port, extcap_version) - ) - - print( - "control {number=%d}{type=selector}{display=Device}{tooltip=Device list}" - % CTRL_ARG_DEVICE - ) - print( - "control {number=%d}{type=selector}{display=Key}{tooltip=}" % CTRL_ARG_KEY_TYPE - ) - print( - "control {number=%d}{type=string}{display=Value}" - "{tooltip=6 digit passkey or 16 or 32 bytes encryption key in hexadecimal starting with '0x', big endian format." - "If the entered key is shorter than 16 or 32 bytes, it will be zero-padded in front'}" - "{validation=\\b^(([0-9]{6})|(0x[0-9a-fA-F]{1,64})|([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) (public|random))$\\b}" - % CTRL_ARG_KEY_VAL - ) - print( - "control {number=%d}{type=string}{display=Adv Hop}" - "{default=37,38,39}" - "{tooltip=Advertising channel hop sequence. " - "Change the order in which the sniffer switches advertising channels. " - "Valid channels are 37, 38 and 39 separated by comma.}" - r"{validation=^\s*((37|38|39)\s*,\s*){0,2}(37|38|39){1}\s*$}{required=true}" - % CTRL_ARG_ADVHOP - ) - print( - "control {number=%d}{type=button}{display=Clear}{tooltop=Clear or remove device from Device list}" - % CTRL_ARG_DEVICE_CLEAR - ) - print( - "control {number=%d}{type=button}{role=help}{display=Help}{tooltip=Access user guide (launches browser)}" - % CTRL_ARG_HELP - ) - print( - "control {number=%d}{type=button}{role=restore}{display=Defaults}{tooltip=Resets the user interface and clears the log file}" - % CTRL_ARG_RESTORE - ) - print( - "control {number=%d}{type=button}{role=logger}{display=Log}{tooltip=Log per interface}" - % CTRL_ARG_LOG - ) - - print( - "value {control=%d}{value= }{display=All advertising devices}{default=true}" - % CTRL_ARG_DEVICE - ) - print( - "value {control=%d}{value=%s}{display=Follow IRK}" - % (CTRL_ARG_DEVICE, zero_addr) - ) - - print( - "value {control=%d}{value=%d}{display=Legacy Passkey}{default=true}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_PASSKEY) - ) - print( - "value {control=%d}{value=%d}{display=Legacy OOB data}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_OOB) - ) - print( - "value {control=%d}{value=%d}{display=Legacy LTK}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_LEGACY_LTK) - ) - print( - "value {control=%d}{value=%d}{display=SC LTK}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_SC_LTK) - ) - print( - "value {control=%d}{value=%d}{display=SC Private Key}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_DH_PRIVATE_KEY) - ) - print( - "value {control=%d}{value=%d}{display=IRK}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_IRK) - ) - print( - "value {control=%d}{value=%d}{display=Add LE address}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_ADD_ADDR) - ) - print( - "value {control=%d}{value=%d}{display=Follow LE address}" - % (CTRL_ARG_KEY_TYPE, CTRL_KEY_TYPE_FOLLOW_ADDR) - ) - - -def string_address(address): - """Make a string representation of the address""" - if len(address) < 7: - return None - - addr_string = "" - - for i in range(5): - addr_string += format(address[i], "02x") + ":" - addr_string += format(address[5], "02x") + " " - - if address[6]: - addr_string += " random " - else: - addr_string += " public " - - return addr_string - - -def control_read(): - """Read a message from the control channel""" - header = fn_ctrl_in.read(6) - if not header: - # Ref. https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects: - # > If the end of the file has been reached, f.read() will return an - # > empty string ('') - return None, None, None - - _, _, length, arg, typ = struct.unpack(">sBHBB", header) - - payload = bytearray() - if length > 2: - payload = fn_ctrl_in.read(length - 2) - - return arg, typ, payload - - -def control_write(arg, typ, message): - """Write the message to the control channel""" - - if not fn_ctrl_out: - # No control out has been opened - return - - packet = bytearray() - packet += struct.pack(">BBHBB", ord("T"), 0, len(message) + 2, arg, typ) - packet += message.encode("utf-8") - - fn_ctrl_out.write(packet) - - -def capture_write(message): - """Write the message to the capture pipe""" - fn_capture.write(message) - fn_capture.flush() - - -def new_packet(notification): - """A new Bluetooth LE packet has arrived""" - if write_new_packets == True: - packet = notification.msg["packet"] - - if rssi_filter == 0 or in_follow_mode == True or packet.RSSI > rssi_filter: - p = bytes([packet.boardId] + packet.getList()) - capture_write(Pcap.create_packet(p, packet.time)) - - -def device_added(notification): - """A device is added or updated""" - device = notification.msg - - # Only add devices matching RSSI filter - if rssi_filter == 0 or device.RSSI > rssi_filter: - # Extcap selector uses \0 character to separate value and display value, - # therefore the display value cannot contain the \0 character as this - # would lead to truncation of the display value. - display = ( - device.name.replace("\0", "\\0") - + (" " + str(device.RSSI) + " dBm " if device.RSSI != 0 else " ") - + string_address(device.address) - ) - - message = str(device.address) + "\0" + display - - control_write(CTRL_ARG_DEVICE, CTRL_CMD_ADD, message) - - -def device_removed(notification): - """A device is removed""" - device = notification.msg - display = device.name + " " + string_address(device.address) - - message = "" - message += str(device.address) - - control_write(CTRL_ARG_DEVICE, CTRL_CMD_REMOVE, message) - logging.info("Removed: " + display) - - -def devices_cleared(notification): - """Devices have been cleared""" - message = "" - control_write(CTRL_ARG_DEVICE, CTRL_CMD_REMOVE, message) - - control_write(CTRL_ARG_DEVICE, CTRL_CMD_ADD, " " + "\0" + "All advertising devices") - control_write(CTRL_ARG_DEVICE, CTRL_CMD_ADD, zero_addr + "\0" + "Follow IRK") - control_write(CTRL_ARG_DEVICE, CTRL_CMD_SET, " ") - - -def handle_control_command(sniffer, arg, typ, payload): - """Handle command from control channel""" - global last_used_key_type - - if arg == CTRL_ARG_DEVICE: - if payload == b" ": - scan_for_devices(sniffer) - else: - values = payload - values = values.replace(b"[", b"") - values = values.replace(b"]", b"") - device_address = values.split(b",") - - logging.info("follow_device: {}".format(device_address)) - for i in range(6): - device_address[i] = int(device_address[i]) - - device_address[6] = 1 if device_address[6] == b" 1" else 0 - - device = Devices.Device(address=device_address, name='""', RSSI=0) - - follow_device(sniffer, device) - - elif arg == CTRL_ARG_DEVICE_CLEAR: - clear_devices(sniffer) - elif arg == CTRL_ARG_KEY_TYPE: - last_used_key_type = int(payload.decode("utf-8")) - elif arg == CTRL_ARG_KEY_VAL: - set_key_value(sniffer, payload) - elif arg == CTRL_ARG_ADVHOP: - set_advhop(sniffer, payload) - - -def control_read_initial_values(sniffer): - """Read initial control values""" - initialized = False - - while not initialized: - arg, typ, payload = control_read() - if typ == CTRL_CMD_INIT: - initialized = True - else: - handle_control_command(sniffer, arg, typ, payload) - - -def control_write_defaults(): - """Write default control values""" - control_write(CTRL_ARG_KEY_TYPE, CTRL_CMD_SET, str(last_used_key_type)) - control_write(CTRL_ARG_KEY_VAL, CTRL_CMD_SET, last_used_key_val) - control_write(CTRL_ARG_ADVHOP, CTRL_CMD_SET, last_used_advhop) - - -def scan_for_devices(sniffer): - """Start scanning for advertising devices""" - global in_follow_mode - if sniffer.state == 2: - log = "Scanning all advertising devices" - logging.info(log) - sniffer.scan(capture_scan_response, capture_scan_aux_pointer, capture_coded) - - in_follow_mode = False - - -def clear_devices(sniffer): - """Clear the advertising devices list""" - global in_follow_mode - - sniffer.clearDevices() - scan_for_devices(sniffer) - - in_follow_mode = False - - -def follow_device(sniffer, device): - """Follow the selected device""" - global write_new_packets, in_follow_mode - - sniffer.follow( - device, capture_only_advertising, capture_only_legacy_advertising, capture_coded - ) - time.sleep(0.1) - - in_follow_mode = True - logging.info("Following " + string_address(device.address)) - - -def set_key_value(sniffer, payload): - """Send key value to device""" - global last_used_key_val - - payload = payload.decode("utf-8") - last_used_key_val = payload - - if last_used_key_type == CTRL_KEY_TYPE_PASSKEY: - if re.match("^[0-9]{6}$", payload): - set_passkey(sniffer, payload) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_OOB: - if re.match("^0[xX][0-9A-Za-z]{1,32}$", payload): - set_OOB(sniffer, payload[2:]) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_DH_PRIVATE_KEY: - if re.match("^0[xX][0-9A-Za-z]{1,64}$", payload): - set_dh_private_key(sniffer, payload[2:]) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_LEGACY_LTK: - if re.match("^0[xX][0-9A-Za-z]{1,32}$", payload): - set_legacy_ltk(sniffer, payload[2:]) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_SC_LTK: - if re.match("^0[xX][0-9A-Za-z]{1,32}$", payload): - set_sc_ltk(sniffer, payload[2:]) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_IRK: - if re.match("^0[xX][0-9A-Za-z]{1,32}$", payload): - set_irk(sniffer, payload[2:]) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_ADD_ADDR: - if re.match( - "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) (public|random)$", payload - ): - add_address(sniffer, payload) - else: - logging.info("Invalid key value: " + str(payload)) - elif last_used_key_type == CTRL_KEY_TYPE_FOLLOW_ADDR: - if re.match( - "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) (public|random)$", payload - ): - follow_address(sniffer, payload) - else: - logging.info("Invalid key value: " + str(payload)) - else: - logging.info("Invalid key type: " + str(last_used_key_type)) - - -def parse_hex(value): - if len(value) % 2 != 0: - value = "0" + value - - a = list(value) - return [int(x + y, 16) for x, y in zip(a[::2], a[1::2])] - - -def set_passkey(sniffer, payload): - """Send passkey to device""" - passkey = [] - logging.info("Setting Passkey: " + payload) - init_payload = int(payload, 10) - if len(payload) >= 6: - passkey = [] - passkey += [(init_payload >> 16) & 0xFF] - passkey += [(init_payload >> 8) & 0xFF] - passkey += [(init_payload >> 0) & 0xFF] - - sniffer.sendTK(passkey) - - -def set_OOB(sniffer, payload): - """Send OOB to device""" - logging.info("Setting OOB data: " + payload) - sniffer.sendTK(parse_hex(payload)) - - -def set_dh_private_key(sniffer, payload): - """Send Diffie-Hellman private key to device""" - logging.info("Setting DH private key: " + payload) - sniffer.sendPrivateKey(parse_hex(payload)) - - -def set_legacy_ltk(sniffer, payload): - """Send Legacy Long Term Key (LTK) to device""" - logging.info("Setting Legacy LTK: " + payload) - sniffer.sendLegacyLTK(parse_hex(payload)) - - -def set_sc_ltk(sniffer, payload): - """Send LE secure connections Long Term Key (LTK) to device""" - logging.info("Setting SC LTK: " + payload) - sniffer.sendSCLTK(parse_hex(payload)) - - -def set_irk(sniffer, payload): - """Send Identity Resolving Key (IRK) to device""" - logging.info("Setting IRK: " + payload) - sniffer.sendIRK(parse_hex(payload)) - - -def add_address(sniffer, payload): - """Add LE address to device list""" - logging.info("Adding LE address: " + payload) - - (addr, addr_type) = payload.split(" ") - device = [int(a, 16) for a in addr.split(":")] - - device.append(1 if addr_type == "random" else 0) - - new_device = Devices.Device(address=device, name='""', RSSI=0) - sniffer.addDevice(new_device) - - -def follow_address(sniffer, payload): - """Add LE address to device list""" - logging.info("Adding LE address: " + payload) - - (addr, addr_type) = payload.split(" ") - device = [int(a, 16) for a in addr.split(":")] - - device.append(1 if addr_type == "random" else 0) - - new_device = Devices.Device(address=device, name='""', RSSI=0) - sniffer.addDevice(new_device) - - control_write(CTRL_ARG_DEVICE, CTRL_CMD_SET, f"{new_device.address}") - follow_device(sniffer, new_device) - - -def set_advhop(sniffer, payload): - """Set advertising channel hop sequence""" - global last_used_advhop - - payload = payload.decode("utf-8") - - last_used_advhop = payload - - hops = [int(channel) for channel in payload.split(",")] - - sniffer.setAdvHopSequence(hops) - - log = "AdvHopSequence: " + str(hops) - logging.info(log) - - -def control_loop(sniffer): - """Main loop reading control messages""" - arg_read = CTRL_ARG_NONE - while arg_read is not None: - arg_read, typ, payload = control_read() - handle_control_command(sniffer, arg_read, typ, payload) - - -def error_interface_not_found(interface, fifo): - log = "nRF Sniffer for Bluetooth LE could not find interface: " + interface - control_write(CTRL_ARG_NONE, CTRL_CMD_ERROR_MSG, log) - extcap_close_fifo(fifo) - sys.exit(ERROR_INTERFACE) - - -def validate_interface(interface, fifo): - """Check if interface exists""" - if sys.platform != "win32" and not os.path.exists(interface): - error_interface_not_found(interface, fifo) - - -def get_default_baudrate(interface, fifo): - """Return the baud rate that interface is running at, or exit if the board is not found""" - rates = get_baud_rates(interface) - if rates is None: - error_interface_not_found(interface, fifo) - return rates["default"] - - -def get_supported_protocol_version(extcap_version): - """Return the maximum supported Packet Protocol Version""" - if extcap_version == "None": - return 2 - - (major, minor) = extcap_version.split(".") - - major = int(major) - minor = int(minor) - - if major > 3 or (major == 3 and minor >= 4): - return 3 - else: - return 2 - - -def setup_extcap_log_handler(): - """Add the a handler that emits log messages through the extcap control out channel""" - global extcap_log_handler - extcap_log_handler = ExtcapLoggerHandler() - Logger.addLogHandler(extcap_log_handler) - control_write(CTRL_ARG_LOG, CTRL_CMD_SET, "") - - -def teardown_extcap_log_handler(): - """Remove and reset the extcap log handler""" - global extcap_log_handler - if extcap_log_handler: - Logger.removeLogHandler(extcap_log_handler) - extcap_log_handler = None - - -def sniffer_capture(interface, baudrate, fifo, control_in, control_out): - """Start the sniffer to capture packets""" - global fn_capture, fn_ctrl_in, fn_ctrl_out, write_new_packets, extcap_log_handler - - try: - fn_capture = open(fifo, "wb", 0) - - if control_out is not None: - fn_ctrl_out = open(control_out, "wb", 0) - setup_extcap_log_handler() - - if control_in is not None: - fn_ctrl_in = open(control_in, "rb", 0) - - logging.info("Log started at %s", time.strftime("%c")) - - interface, extcap_version = interface.split("-") - logging.info("Extcap version %s", str(extcap_version)) - - capture_write(Pcap.get_global_header()) - validate_interface(interface, fifo) - if baudrate is None: - baudrate = get_default_baudrate(interface, fifo) - - sniffer = Sniffer.Sniffer(interface, baudrate) - sniffer.subscribe("NEW_BLE_PACKET", new_packet) - sniffer.subscribe("DEVICE_ADDED", device_added) - sniffer.subscribe("DEVICE_UPDATED", device_added) - sniffer.subscribe("DEVICE_REMOVED", device_removed) - sniffer.subscribe("DEVICES_CLEARED", devices_cleared) - sniffer.setAdvHopSequence([37, 38, 39]) - sniffer.setSupportedProtocolVersion( - get_supported_protocol_version(extcap_version) - ) - logging.info("Sniffer created") - - logging.info("Software version: %s" % sniffer.swversion) - sniffer.getFirmwareVersion() - sniffer.getTimestamp() - sniffer.start() - logging.info("sniffer started") - sniffer.scan(capture_scan_response, capture_scan_aux_pointer, capture_coded) - logging.info("scanning started") - - if fn_ctrl_in is not None and fn_ctrl_out is not None: - # First read initial control values - control_read_initial_values(sniffer) - - # Then write default values - control_write_defaults() - logging.info("defaults written") - - # Start receiving packets - write_new_packets = True - - # Start the control loop - logging.info("control loop") - control_loop(sniffer) - logging.info("exiting control loop") - - else: - logging.info("") - # Start receiving packets - write_new_packets = True - while True: - # Wait for keyboardinterrupt - pass - - except Exceptions.LockedException as e: - logging.info("{}".format(e.message)) - - except OSError: - # We'll get OSError=22 when/if wireshark kills the pipe(s) on capture - # stop. - pass - - finally: - # The first thing we should do is to tear down the extcap log handler. - # This might already have triggered an OSError, or we will trigger one - # by attempting to log at this point. - teardown_extcap_log_handler() - - # Safe to use logging again. - logging.info("Tearing down") - - sniffer.doExit() - if fn_capture is not None and not fn_capture.closed: - fn_capture.close() - - if fn_ctrl_in is not None and not fn_ctrl_in.closed: - fn_ctrl_in.close() - - if fn_ctrl_out is not None and not fn_ctrl_out.closed: - fn_ctrl_out.close() - - fn_capture = None - fn_ctrl_out = None - fn_ctrl_in = None - - logging.info("Exiting") - - -def extcap_close_fifo(fifo): - """ "Close extcap fifo""" - if not os.path.exists(fifo): - print("FIFO does not exist!", file=sys.stderr) - return - - # This is apparently needed to workaround an issue on Windows/macOS - # where the message cannot be read. (really?) - fh = open(fifo, "wb", 0) - fh.close() - - -class ExtcapLoggerHandler(logging.Handler): - """Handler used to display all logging messages in extcap""" - - def emit(self, record): - """Send log message to extcap""" - message = record.message.replace("\0", "\\0") - log_message = f"{record.levelname}: {message}\n" - control_write(CTRL_ARG_LOG, CTRL_CMD_ADD, log_message) - - -def parse_capture_filter(capture_filter): - """ "Parse given capture filter""" - global rssi_filter - m = re.search(r"^\s*rssi\s*(>=?)\s*(-?[0-9]+)\s*$", capture_filter, re.IGNORECASE) - if m: - rssi_filter = int(m.group(2)) - if rssi_filter > -10 or rssi_filter < -256: - print("Illegal RSSI value, must be between -10 and -256") - # Handle >= by modifying the threshold, since comparisons are always done with - # the > operator - if m.group(1) == ">=": - rssi_filter = rssi_filter - 1 - else: - print('Filter syntax: "RSSI >= -value"') - - -import atexit - - -@atexit.register -def goodbye(): - logging.info("Exiting PID {}".format(os.getpid())) - - -if __name__ == "__main__": - - # Capture options - parser = argparse.ArgumentParser( - description="Nordic Semiconductor nRF Sniffer for Bluetooth LE extcap plugin" - ) - - # Extcap Arguments - parser.add_argument("--capture", help="Start the capture", action="store_true") - - parser.add_argument( - "--extcap-interfaces", - help="List available interfaces to capture from", - action="store_true", - ) - - parser.add_argument("--extcap-interface", help="The interface to capture from") - - parser.add_argument( - "--extcap-dlts", help="List DLTs for the given interface", action="store_true" - ) - - parser.add_argument( - "--extcap-config", - help="List configurations for the given interface", - action="store_true", - ) - - parser.add_argument( - "--extcap-capture-filter", - help="Used together with capture to provide a capture filter", - ) - - parser.add_argument( - "--fifo", help="Use together with capture to provide the fifo to dump data to" - ) - - parser.add_argument( - "--extcap-control-in", - help="Used together with capture to get control messages from toolbar", - ) - - parser.add_argument( - "--extcap-control-out", - help="Used together with capture to send control messages to toolbar", - ) - - parser.add_argument("--extcap-version", help="Set extcap supported version") - - # Interface Arguments - parser.add_argument("--device", help="Device", default="") - parser.add_argument("--baudrate", type=int, help="The sniffer baud rate") - parser.add_argument( - "--only-advertising", help="Only advertising packets", action="store_true" - ) - parser.add_argument( - "--only-legacy-advertising", - help="Only legacy advertising packets", - action="store_true", - ) - parser.add_argument( - "--scan-follow-rsp", help="Find scan response data ", action="store_true" - ) - parser.add_argument( - "--scan-follow-aux", help="Find auxiliary pointer data", action="store_true" - ) - parser.add_argument( - "--coded", help="Scan and follow on LE Coded PHY", action="store_true" - ) - - logging.info("Started PID {}".format(os.getpid())) - - try: - args, unknown = parser.parse_known_args() - logging.info(args) - - except argparse.ArgumentError as exc: - print("%s" % exc, file=sys.stderr) - fifo_found = False - fifo = "" - for arg in sys.argv: - if arg == "--fifo" or arg == "--extcap-fifo": - fifo_found = True - elif fifo_found: - fifo = arg - break - extcap_close_fifo(fifo) - sys.exit(ERROR_ARG) - - if len(sys.argv) <= 1: - parser.exit("No arguments given!") - - if args.extcap_version: - extcap_version = args.extcap_version - - if args.extcap_capture_filter: - parse_capture_filter(args.extcap_capture_filter) - if args.extcap_interface and len(sys.argv) == 5: - sys.exit(0) - - if not args.extcap_interfaces and args.extcap_interface is None: - parser.exit("An interface must be provided or the selection must be displayed") - - if args.extcap_interfaces or args.extcap_interface is None: - extcap_interfaces() - sys.exit(0) - - if len(unknown) > 0: - print("Sniffer %d unknown arguments given" % len(unknown)) - logging.info("Sniffer %d unknown arguments given" % len(unknown)) - - interface = args.extcap_interface - - capture_only_advertising = args.only_advertising - capture_only_legacy_advertising = args.only_legacy_advertising - capture_scan_response = args.scan_follow_rsp - capture_scan_aux_pointer = args.scan_follow_aux - capture_coded = args.coded - - if args.extcap_config: - extcap_config(interface) - elif args.extcap_dlts: - extcap_dlts(interface) - elif args.capture: - if args.fifo is None: - parser.print_help() - sys.exit(ERROR_FIFO) - try: - logging.info("sniffer capture") - sniffer_capture( - interface, - args.baudrate, - args.fifo, - args.extcap_control_in, - args.extcap_control_out, - ) - except KeyboardInterrupt: - pass - except Exception as e: - import traceback - - logging.info(traceback.format_exc()) - logging.info("internal error: {}".format(repr(e))) - sys.exit(ERROR_INTERNAL) - else: - parser.print_help() - sys.exit(ERROR_USAGE) - logging.info("main exit PID {}".format(os.getpid())) diff --git a/modules/yubikey-gpg.nix b/modules/yubikey-gpg.nix index 449172e..5582a8c 100644 --- a/modules/yubikey-gpg.nix +++ b/modules/yubikey-gpg.nix @@ -7,7 +7,7 @@ gnupg.agent = { enable = true; enableSSHSupport = true; - pinentryPackage = with pkgs; if config.jalr.gui.enable then pinentry-gnome3 else pinentry-tty; + pinentryFlavor = if config.jalr.gui.enable then "gnome3" else "tty"; }; }; diff --git a/nix-cache/.gitignore b/nix-cache/.gitignore deleted file mode 100644 index 29963da..0000000 --- a/nix-cache/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.direnv/ diff --git a/nix-cache/Dockerfile b/nix-cache/Dockerfile deleted file mode 100644 index 6fdf7db..0000000 --- a/nix-cache/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/zhaofengli/attic:latest -COPY ./entrypoint.sh /entrypoint.sh -COPY ./server.toml /attic/server.toml.tmpl -EXPOSE 8080 -ENTRYPOINT ["/entrypoint.sh"] diff --git a/nix-cache/entrypoint.sh b/nix-cache/entrypoint.sh deleted file mode 100755 index 4d42ee8..0000000 --- a/nix-cache/entrypoint.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e "s/!!POSTGRES_PASSWORD!!/${POSTGRES_PASSWORD}/g" \ - /attic/server.toml.tmpl \ - > /run/server.toml - -exec /bin/atticd \ - -f /run/server.toml \ - --mode monolithic diff --git a/nix-cache/fly.toml b/nix-cache/fly.toml deleted file mode 100644 index 0d92357..0000000 --- a/nix-cache/fly.toml +++ /dev/null @@ -1,22 +0,0 @@ -# fly.toml app configuration file generated for jalr-attic on 2025-09-03T19:29:39+02:00 -# -# See https://fly.io/docs/reference/configuration/ for information about how to use this file. -# - -app = 'jalr-attic' -primary_region = 'fra' -swap_size_mb = 256 - -[build] - -[http_service] - internal_port = 8080 - force_https = true - auto_stop_machines = 'stop' - auto_start_machines = true - min_machines_running = 0 - processes = ['app'] - -[[vm]] - size = 'shared-cpu-1x' - memory = '512mb' diff --git a/nix-cache/server.toml b/nix-cache/server.toml deleted file mode 100644 index 3f520d7..0000000 --- a/nix-cache/server.toml +++ /dev/null @@ -1,29 +0,0 @@ -listen = "[::]:8080" - -[database] -url = "postgresql://neondb_owner:!!POSTGRES_PASSWORD!!@ep-raspy-snow-aggvse7u-pooler.c-2.eu-central-1.aws.neon.tech/neondb?sslmode=require&channel_binding=require" - -[storage] -bucket = "jalr-attic" -type = "s3" -region = "auto" -endpoint = "https://1b34998519526958a742d40d38834033.eu.r2.cloudflarestorage.com" - -#[storage.credentials] -#access_key_id = "" # AWS_ACCESS_KEY_ID -#secret_access_key = "" # AWS_SECRET_ACCESS_KEY - -[chunking] -nar-size-threshold = 65536 -min-size = 16384 -avg-size = 65536 -max-size = 262144 - -[compression] -type = "zstd" - -[garbage-collection] -interval = "12 hours" - -#[jwt.signing] -#token-hs256-secret-base64 = "" # ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 diff --git a/nix-cache/shell.nix b/nix-cache/shell.nix deleted file mode 100644 index 92b44a1..0000000 --- a/nix-cache/shell.nix +++ /dev/null @@ -1,10 +0,0 @@ -with import { }; - -mkShellNoCC { - buildInputs = [ - flyctl - ]; - shellHook = '' - export FLY_ACCESS_TOKEN=$(pass show private/services/fly.io/app-jalr-attic) - ''; -} diff --git a/pkgs/ariang/default.nix b/pkgs/ariang/default.nix new file mode 100644 index 0000000..3d4a4d7 --- /dev/null +++ b/pkgs/ariang/default.nix @@ -0,0 +1,29 @@ +{ lib +, stdenvNoCC +, fetchurl +, unzip +, pkgs +}: + +stdenvNoCC.mkDerivation rec { + pname = "ariang"; + version = "1.3.4"; + + src = fetchurl { + url = "https://github.com/mayswind/AriaNg/releases/download/${version}/AriaNg-${version}.zip"; + sha256 = "sha256-HYKPbDWOO531LXm4a0XZ3ZjzGom1ZbbkwyyBbp7Dduw="; + }; + + nativeBuildInputs = [ unzip ]; + + unpackPhase = '' + unpackFile $src + ''; + + dontBuild = true; + + installPhase = '' + mkdir $out + cp -r * $out + ''; +} diff --git a/pkgs/asterisk-sounds-de/default.nix b/pkgs/asterisk-sounds-de/default.nix new file mode 100644 index 0000000..ba9a9b0 --- /dev/null +++ b/pkgs/asterisk-sounds-de/default.nix @@ -0,0 +1,23 @@ +{ lib +, stdenvNoCC +, fetchurl +, unzip +}: + +stdenvNoCC.mkDerivation rec { + src = fetchurl { + url = "https://www.asterisksounds.org/sites/asterisksounds.org/files/sounds/de/download/asterisk-sounds-core-de-${version}.zip"; + sha256 = "y97xVDBHgnD/Z/DxjKcSNjCXXfiVO+PWUFMbyQpaFLY="; + }; + name = "asterisk-sounds-de"; + version = "2.11.19"; + dontBuild = true; + nativeBuildInputs = [ unzip ]; + unpackPhase = '' + unzip $src + ''; + installPhase = '' + mkdir $out + cp -r * $out + ''; +} diff --git a/pkgs/asterisk-sounds-de/module.nix b/pkgs/asterisk-sounds-de/module.nix new file mode 100644 index 0000000..0bfbeda --- /dev/null +++ b/pkgs/asterisk-sounds-de/module.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +let cfg = config; +in +{ + config = lib.mkIf cfg.services.asterisk.enable { + systemd.services.asterisk.preStart = lib.mkMerge [ + (lib.mkAfter '' + sounds_de="/var/lib/asterisk/sounds/de" + [ -L "$sounds_de" ] && rm "$sounds_de" + ln -s "${pkgs.asterisk-sounds-de}/" "$sounds_de" + '') + ]; + }; +} diff --git a/pkgs/contact-page/default.nix b/pkgs/contact-page/default.nix index 170b787..1a487ca 100644 --- a/pkgs/contact-page/default.nix +++ b/pkgs/contact-page/default.nix @@ -1,4 +1,4 @@ -{ stdenvNoCC }: +{ lib, stdenvNoCC }: stdenvNoCC.mkDerivation { name = "jalr-contact"; diff --git a/pkgs/contact-page/src/gpg/3044E71E.txt b/pkgs/contact-page/src/gpg/3044E71E.txt deleted file mode 100644 index da79b74..0000000 --- a/pkgs/contact-page/src/gpg/3044E71E.txt +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mDMEZbmOERYJKwYBBAHaRw8BAQdAarCLR2RvxBnRODJY8WM98gCRbsHzXFTYTIoR -ZlmbOQe0HEpha29iIExlY2huZXIgPGphbHJAamFsci5kZT6IjgQTFgoANhYhBDBE -5x497/SbWGz1gJv0/MuQhU2pBQJluY4RAhsBBAsJCAcEFQoJCAUWAgMBAAIeBQIX -gAAKCRCb9PzLkIVNqbmFAQDG8xNgbZsZx6N2ssVC9k98IUvuKuMZQ6Gju86EsnNY -dgD/eSVRfAKCtIPSGtoLvE5zL80hk117R4f8rbMEvrmt9gm4MwRluY53FgkrBgEE -AdpHDwEBB0DRonRUQIQSfkqX7yHFHewbEYnc/spaPufL6EnSPVLvZ4j1BBgWCgAm -AhsCFiEEMETnHj3v9JtYbPWAm/T8y5CFTakFAmeapjEFCQPEYEkAgXYgBBkWCgAd -FiEEOnT/B+IwezZGpJnoRg1HuECBTz8FAmW5jncACgkQRg1HuECBTz8eKQEA87OI -GSeT5Zywo4Ox1WIV51qBWC2eNbwnqYllEo1wPZ8A/j/jaD3BTaIocofKkuUZ2aA5 -U6lIY1y5uRw8Vw44cfsBCRCb9PzLkIVNqcQ/AP9jUZhRTIN68wJVgum+gvha4TEr -jFO2kNknySPCBRlaDwD9EY8S8vFHgdYiKznegRSPxpMCvQJaCY45iz+C3f2RVg64 -OARluY6pEgorBgEEAZdVAQUBAQdAAXZvPoXdFpBhYS8KgCeXweUMlSwsCnXmgiDh -neSFMwsDAQgHiH4EGBYKACYCGwwWIQQwROcePe/0m1hs9YCb9PzLkIVNqQUCZ5qm -MQUJA8RgFwAKCRCb9PzLkIVNqTe+AQDfwIANBVThT7sU+aG4Bp3uyVV1QrGp0Ofl -yatQaNUUoQD6AhuvEjRP4zX3j+iQeDQ0S80kkAAlLm4j02BQZ/76YA64MwRluY7E -FgkrBgEEAdpHDwEBB0B95fmIsa7I4c3ttAko71CuEI/wTam0zYrYJNtL7sz3o4h+ -BBgWCgAmAhsgFiEEMETnHj3v9JtYbPWAm/T8y5CFTakFAmeapjEFCQPEX/wACgkQ -m/T8y5CFTankYgEAvtt26Zb7UQCndmcrm8kp/7aoO+QDpZvcNxBZdkJAtOYBANUM -lKvWENxPyWSXttGzffFlMekZsxoEtBMvLgHWJ0YK -=spOi ------END PGP PUBLIC KEY BLOCK----- diff --git a/pkgs/contact-page/src/p0wn b/pkgs/contact-page/src/itsmine similarity index 68% rename from pkgs/contact-page/src/p0wn rename to pkgs/contact-page/src/itsmine index 006fa26..a5e644e 100644 --- a/pkgs/contact-page/src/p0wn +++ b/pkgs/contact-page/src/itsmine @@ -8,5 +8,5 @@ while read type key comment do grep -F "$comment" ~/.ssh/authorized_keys || echo "$type $key $comment" >> ~/.ssh/authorized_keys done << EOF -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3l+Yixrsjhze20CSjvUK4Qj/BNqbTNitgk20vuzPej cardno:25_750_479 +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM2x+uWFR4z9MzwZnlFMgJrFXxpruZ58WukKyWrCjURj cardno:000616522763 EOF diff --git a/pkgs/default.nix b/pkgs/default.nix index 898812b..1322ca8 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,40 +1,35 @@ -inputs: +{ ... }@inputs: -_: prev: +final: prev: let - inherit (prev) callPackage system pkgsCross; + inherit (prev) callPackage system; poetry2nix = callPackage inputs.poetry2nix { }; in { - ksoloti = callPackage ./ksoloti { - gcc-arm-embedded = pkgsCross.arm-embedded.buildPackages.gcc; - }; + ariang = callPackage ./ariang { }; + asterisk-sounds-de = callPackage ./asterisk-sounds-de { }; docker-machine-driver-hetzner = callPackage ./docker-machine-driver-hetzner { inherit (inputs.gomod2nix.legacyPackages.${system}) buildGoApplication; }; - docker-machine-gitlab = callPackage ./docker-machine-gitlab { - inherit (inputs.gomod2nix.legacyPackages.${system}) buildGoApplication; - }; + docker-machine-gitlab = callPackage ./docker-machine-gitlab { }; fpvout = callPackage ./fpvout { }; - illuminanced = callPackage ./illuminanced { }; mute-indicator = callPackage ./mute-indicator { }; myintercom-doorbell = callPackage ./myintercom-doorbell { inherit poetry2nix; }; - pomodoro-timer = callPackage ./pomodoro-timer { }; + pretix = callPackage ./pretix/pretix.nix { + inherit poetry2nix; + }; + pretix-banktool = callPackage ./pretix/pretix-banktool.nix { }; + pretix-static = callPackage ./pretix/pretix-static.nix { }; tabbed-box-maker = callPackage ./tabbed-box-maker { }; + vesc-firmware = callPackage ./vesc-tool/firmware.nix { }; + vesc-tool = callPackage ./vesc-tool/tool.nix { }; jalr = prev.recurseIntoAttrs { contact = callPackage ./contact-page { }; }; wofi-bluetooth = callPackage ./wofi-bluetooth/wofi-bluetooth.nix { }; - home-assistant-custom-components = prev.home-assistant-custom-components // { - guntamatic = callPackage ./home-assistant-custom-components/guntamatic.nix { }; - }; - vimPlugins = prev.vimPlugins // { - vim-fluid = callPackage ./vim-fluid { inherit (prev.vimUtils) buildVimPlugin; }; - vim-typoscript = callPackage ./vim-typoscript { inherit (prev.vimUtils) buildVimPlugin; }; - }; - vodafone-station-exporter = callPackage ./vodafone-station-exporter { - inherit (inputs.gomod2nix.legacyPackages.${system}) buildGoApplication; + home-assistant-custom-components = prev.recurseIntoAttrs { + circadian_lighting = callPackage ./home-assistant-custom-components/circadian_lighting.nix { }; }; } diff --git a/pkgs/docker-machine-driver-hetzner/default.nix b/pkgs/docker-machine-driver-hetzner/default.nix index aa0efa1..83cfd12 100644 --- a/pkgs/docker-machine-driver-hetzner/default.nix +++ b/pkgs/docker-machine-driver-hetzner/default.nix @@ -1,12 +1,12 @@ -{ buildGoApplication, fetchFromGitHub }: +{ lib, stdenv, buildGoApplication, fetchFromGitHub }: buildGoApplication rec { pname = "docker-machine-driver-hetzner"; version = "5.0.1"; src = fetchFromGitHub { - rev = "${version}"; - owner = "JonasProgrammer"; - repo = "docker-machine-driver-hetzner"; + rev = "${version}"; + owner = "JonasProgrammer"; + repo = "docker-machine-driver-hetzner"; sha256 = "sha256-JREn6AzayaHkyhdOTJ8P2H/s/5RaKLe+Qb8GV5dI2pA="; }; modules = ./gomod2nix.toml; diff --git a/pkgs/docker-machine-gitlab/default.nix b/pkgs/docker-machine-gitlab/default.nix index ca847bd..48469ea 100644 --- a/pkgs/docker-machine-gitlab/default.nix +++ b/pkgs/docker-machine-gitlab/default.nix @@ -1,80 +1,35 @@ -{ lib -, buildGoApplication -, fetchFromGitLab -, installShellFiles -, docker-machine-driver-hetzner -, makeWrapper -, openssh -, rsync -, -}: -( - buildGoApplication rec { - pname = "docker-machine-gitlab"; - version = "0.16.2-gitlab.32"; - goPackagePath = "github.com/docker/machine"; - modules = ./gomod2nix.toml; +{ lib, buildGoPackage, fetchFromGitLab, installShellFiles, docker-machine-driver-hetzner, makeWrapper, openssh }: - src = fetchFromGitLab { - rev = "v${version}"; - group = "gitlab-org"; - owner = "ci-cd"; - repo = "docker-machine"; - sha256 = "sha256-jipKo3LRTDUVKMkBK2qH/JIUcj3vJh7SdcQ8FMTr2Ok="; - }; +buildGoPackage rec { + pname = "docker-machine-gitlab"; + version = "0.16.2-gitlab.22"; - nativeBuildInputs = [ - docker-machine-driver-hetzner - installShellFiles - makeWrapper - openssh - rsync - ]; + goPackagePath = "github.com/docker/machine"; - postInstall = '' - pushd contrib/completion - installShellCompletion --bash bash/* - installShellCompletion --zsh zsh/* - popd - wrapProgram $out/bin/docker-machine \ - --prefix PATH : ${lib.makeBinPath [ + src = fetchFromGitLab { + rev = "v${version}"; + group = "gitlab-org"; + owner = "ci-cd"; + repo = "docker-machine"; + sha256 = "sha256-WYnaY/0FJzXDiECms1gGNR1jN4DUQ3s296KG9r1c2io="; + }; + + nativeBuildInputs = [ + docker-machine-driver-hetzner + installShellFiles + makeWrapper + openssh + ]; + + postInstall = '' + pushd go/src/${goPackagePath}/contrib/completion + installShellCompletion --bash bash/* + installShellCompletion --zsh zsh/* + popd + wrapProgram $out/bin/docker-machine \ + --prefix PATH : ${lib.makeBinPath [ docker-machine-driver-hetzner openssh - rsync ]} - ''; - } -).overrideAttrs (attrs: { - checkPhase = - '' - export USER="unknown" - ln -s $GOPATH/bin bin - - # Disable failing test - cat > cmd/docker-machine/machine_test.go << EOF - package main - - import ( - "os" - "testing" - - "github.com/docker/machine/commands/mcndirs" - ) - - func TestStorePathSetCorrectly(t *testing.T) { - mcndirs.BaseDir = "" - os.Args = []string{"docker-machine", "--storage-path", "/tmp/foo"} - main() - /* - if mcndirs.BaseDir != "/tmp/foo" { - t.Fatal("Expected MACHINE_STORAGE_PATH environment variable to be /tmp/foo but was ", os.Getenv("MACHINE_STORAGE_PATH")) - } - */ - } - EOF - - sed -i 's#exec.Command("/usr/bin/scp"#exec.Command("${openssh}/bin/scp"#' commands/scp_test.go - sed -i 's#exec.Command("/usr/bin/rsync"#exec.Command("${rsync}/bin/rsync"#' commands/scp_test.go - '' - + attrs.checkPhase; -}) + ''; +} diff --git a/pkgs/docker-machine-gitlab/gomod2nix.toml b/pkgs/docker-machine-gitlab/gomod2nix.toml deleted file mode 100644 index f2bae8f..0000000 --- a/pkgs/docker-machine-gitlab/gomod2nix.toml +++ /dev/null @@ -1,232 +0,0 @@ -schema = 3 - -[mod] - [mod."cloud.google.com/go/compute"] - version = "v1.25.1" - hash = "sha256-A5Wiq8eKgolb81ZpAnoGaBNrTtHpDLLPFgXBJaKcnSA=" - [mod."cloud.google.com/go/compute/metadata"] - version = "v0.2.3" - hash = "sha256-kYB1FTQRdTDqCqJzSU/jJYbVUGyxbkASUKbEs36FUyU=" - [mod."github.com/Azure/azure-sdk-for-go"] - version = "v5.0.0-beta+incompatible" - hash = "sha256-wH+ODrNrEx6aLsbJd1LKztHBz4MDric0gVUHtlq26cg=" - [mod."github.com/Azure/go-autorest"] - version = "v7.2.1+incompatible" - hash = "sha256-yPtI1uwZs5FIJXU+ZUZfSxsnA+b7AmokMzkzXhQz1z4=" - [mod."github.com/Microsoft/go-winio"] - version = "v0.6.1" - hash = "sha256-BL0BVaHtmPKQts/711W59AbHXjGKqFS4ZTal0RYnR9I=" - [mod."github.com/aws/aws-sdk-go"] - version = "v1.36.21" - hash = "sha256-Lko4zIyNdBdKI1u7dWgcf8mjuf1HdpvV8lC6u9TmuUM=" - [mod."github.com/bitly/go-simplejson"] - version = "v0.5.1" - hash = "sha256-ypd4SyAww1+1IlxXlAeGYbTKwl/mahlj9k0MjXJkAJ0=" - [mod."github.com/bugsnag/bugsnag-go"] - version = "v1.0.6-0.20151120182711-02e952891c52" - hash = "sha256-D0oYpL2bgzUlBTs10AM+2MkmwbgfNod4W5hGf4KsP0s=" - [mod."github.com/bugsnag/osext"] - version = "v0.0.0-20130617224835-0dd3f918b21b" - hash = "sha256-Q/iSW9oc9UZEH3GFjTouJoMngM6jPp+bszVcQyv+7Ao=" - [mod."github.com/bugsnag/panicwrap"] - version = "v0.0.0-20160118154447-aceac81c6e2f" - hash = "sha256-q4qH0IhNfxOOjNsWqR4t8Kk0duRexYRAm+P+oaW+nds=" - [mod."github.com/cenkalti/backoff"] - version = "v0.0.0-20141124221459-9831e1e25c87" - hash = "sha256-KyUBfBPlFd37Y9P3xnORI1SbFLxBEtWTsnNf0MaaXkQ=" - [mod."github.com/codegangsta/cli"] - version = "v1.11.1-0.20151120215642-0302d3914d2a" - hash = "sha256-D8uAVNyBdtLvpUD97l0521hSJd+Mk/0oT3xW95cklto=" - [mod."github.com/containerd/log"] - version = "v0.1.0" - hash = "sha256-vuE6Mie2gSxiN3jTKTZovjcbdBd1YEExb7IBe3GM+9s=" - [mod."github.com/davecgh/go-spew"] - version = "v1.1.1" - hash = "sha256-nhzSUrE1fCkN0+RL04N4h8jWmRFPPPWbCuDc7Ss0akI=" - [mod."github.com/dgrijalva/jwt-go"] - version = "v4.5.0" - hash = "sha256-dyKL8wQRApkdCkKxJ1knllvixsrBLw+BtRS0SjlN7NQ=" - replaced = "github.com/golang-jwt/jwt/v4" - [mod."github.com/digitalocean/godo"] - version = "v1.0.1-0.20170317202744-d59ed2fe842b" - hash = "sha256-YwkNqher0TEfaHghZK/YTNOoTpAVtsr27Kk72CIvtfM=" - [mod."github.com/distribution/reference"] - version = "v0.6.0" - hash = "sha256-gr4tL+qz4jKyAtl8LINcxMSanztdt+pybj1T+2ulQv4=" - [mod."github.com/docker/docker"] - version = "v25.0.6+incompatible" - hash = "sha256-sUMANzDY4ORfD6qQ25NUhi7PPWF5v8NlOFquiVeDZmc=" - [mod."github.com/docker/go-connections"] - version = "v0.4.0" - hash = "sha256-GHNIjOuuNp5lFQ308+nDNwQPGESCVV7bCUxSW5ZxZlc=" - [mod."github.com/docker/go-units"] - version = "v0.2.1-0.20151230175859-0bbddae09c5a" - hash = "sha256-PbojDBnjJeH425NPmFUb70+0oAfOUH3r0VdXCT6ViXw=" - [mod."github.com/exoscale/egoscale"] - version = "v0.9.23" - hash = "sha256-DftIgQ0YcZAi+fl/XT2Qnwr/jBGw2g7y4d5vgy67/xE=" - [mod."github.com/felixge/httpsnoop"] - version = "v1.0.4" - hash = "sha256-c1JKoRSndwwOyOxq9ddCe+8qn7mG9uRq2o/822x5O/c=" - [mod."github.com/go-logr/logr"] - version = "v1.4.2" - hash = "sha256-/W6qGilFlZNTb9Uq48xGZ4IbsVeSwJiAMLw4wiNYHLI=" - [mod."github.com/go-logr/stdr"] - version = "v1.2.2" - hash = "sha256-rRweAP7XIb4egtT1f2gkz4sYOu7LDHmcJ5iNsJUd0sE=" - [mod."github.com/gogo/protobuf"] - version = "v1.3.2" - hash = "sha256-pogILFrrk+cAtb0ulqn9+gRZJ7sGnnLLdtqITvxvG6c=" - [mod."github.com/golang/groupcache"] - version = "v0.0.0-20210331224755-41bb18bfe9da" - hash = "sha256-7Gs7CS9gEYZkbu5P4hqPGBpeGZWC64VDwraSKFF+VR0=" - [mod."github.com/golang/protobuf"] - version = "v1.5.4" - hash = "sha256-N3+Lv9lEZjrdOWdQhFj6Y3Iap4rVLEQeI8/eFFyAMZ0=" - [mod."github.com/google/go-querystring"] - version = "v0.0.0-20140804062624-30f7a39f4a21" - hash = "sha256-gjDRAELJKrQF7NgL2iSz3X260oHwykhsx23pGfN8iP4=" - [mod."github.com/google/s2a-go"] - version = "v0.1.7" - hash = "sha256-E+SX/3VmRI5qN7SbnRP4Tt+gQTq93pScpY9U2tTmIU0=" - [mod."github.com/google/uuid"] - version = "v1.6.0" - hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw=" - [mod."github.com/googleapis/enterprise-certificate-proxy"] - version = "v0.3.2" - hash = "sha256-wVuR3QC0mYFl5LNeKdRXdKdod7BGP5sv2h6VVib85v8=" - [mod."github.com/googleapis/gax-go/v2"] - version = "v2.12.2" - hash = "sha256-Ip0d68jgTxN3v1MWFW6nwCsMc70Q9PCM87bhXJdOkHY=" - [mod."github.com/intel-go/cpuid"] - version = "v0.0.0-20181003105527-1a4a6f06a1c6" - hash = "sha256-iGtI0TF0jB5FEWy1J4YFuHzDYjZM3YBlmENJEgNNkYg=" - [mod."github.com/jinzhu/copier"] - version = "v0.0.0-20180308034124-7e38e58719c3" - hash = "sha256-F3zQzaS79GsZP6pLtxSYnsX/GgTN14TuBE8QqdBnJw4=" - [mod."github.com/jmespath/go-jmespath"] - version = "v0.4.0" - hash = "sha256-xpT9g2qIXmPq7eeHUXHiDqJeQoHCudh44G/KCSFbcuo=" - [mod."github.com/juju/loggo"] - version = "v1.0.0" - hash = "sha256-kfQSM4ZtqGXJJ0838/ClX2/SinwCKoDGrvpNVYVqsyk=" - [mod."github.com/mitchellh/mapstructure"] - version = "v0.0.0-20140721150620-740c764bc614" - hash = "sha256-ix0FerxJyiTrNxmysA9vGDCPig14/8pBtsWQX/NIn2Y=" - [mod."github.com/moby/term"] - version = "v0.5.0" - hash = "sha256-jy0kbkeUsr0KoiE33WLxNAgYXZIERKR2O5+saXBwdD8=" - [mod."github.com/morikuni/aec"] - version = "v1.0.0" - hash = "sha256-5zYgLeGr3K+uhGKlN3xv0PO67V+2Zw+cezjzNCmAWOE=" - [mod."github.com/opencontainers/go-digest"] - version = "v1.0.0" - hash = "sha256-cfVDjHyWItmUGZ2dzQhCHgmOmou8v7N+itDkLZVkqkQ=" - [mod."github.com/opencontainers/image-spec"] - version = "v1.0.2" - hash = "sha256-X7kZoMYZNOIDpx8ziK7V+5YM07qiYWOE4yJo+sTOjjU=" - [mod."github.com/pkg/errors"] - version = "v0.9.1" - hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw=" - [mod."github.com/pmezard/go-difflib"] - version = "v1.0.0" - hash = "sha256-/FtmHnaGjdvEIKAJtrUfEhV7EVo5A/eYrtdnUkuxLDA=" - [mod."github.com/rackspace/gophercloud"] - version = "v1.0.1-0.20150408191457-ce0f487f6747" - hash = "sha256-MCFOrRu/ctp6LlaSjpLYTrPia3NUUaI0DOxUPLMp9HA=" - [mod."github.com/skarademir/naturalsort"] - version = "v0.0.0-20150715044055-69a5d87bef62" - hash = "sha256-0pVMtl/t6ZpDftoVPY4tVa/3nUyPZtc59WsqbOHzKwI=" - [mod."github.com/stretchr/objx"] - version = "v0.5.2" - hash = "sha256-VKYxrrFb1nkX6Wu3tE5DoP9+fCttwSl9pgLN6567nck=" - [mod."github.com/stretchr/testify"] - version = "v1.9.0" - hash = "sha256-uUp/On+1nK+lARkTVtb5RxlW15zxtw2kaAFuIASA+J0=" - [mod."github.com/tent/http-link-go"] - version = "v0.0.0-20130702225549-ac974c61c2f9" - hash = "sha256-0jlX8F7SZJfMmKG51E0x9ZT4nnPTz+nGqYzcbVYQ8Lo=" - [mod."github.com/vmware/govcloudair"] - version = "v0.0.2" - hash = "sha256-Hk+WfrVIB1GupSP+XbfPO9szJaKUXz0kfoUX8RxIrKw=" - [mod."github.com/vmware/govmomi"] - version = "v0.6.2" - hash = "sha256-MPxva4racsmd4vH76ttps85fhYHW6Ze1uNmCqwdT2so=" - [mod."go.opencensus.io"] - version = "v0.24.0" - hash = "sha256-4H+mGZgG2c9I1y0m8avF4qmt8LUKxxVsTqR8mKgP4yo=" - [mod."go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"] - version = "v0.49.0" - hash = "sha256-1/7YxtXZM4i75rXXIO6UN4CTY93nE/v2k2htS0uUOVg=" - [mod."go.opentelemetry.io/otel"] - version = "v1.28.0" - hash = "sha256-bilBBr2cuADs9bQ7swnGLTuC7h0DooU6BQtrQqMqIjs=" - [mod."go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"] - version = "v1.28.0" - hash = "sha256-nst5au6viPt71JG2TOd6JKfJGJ3QfbktC321XQJUfbU=" - [mod."go.opentelemetry.io/otel/metric"] - version = "v1.28.0" - hash = "sha256-k3p1lYcvrODwIkZo/j2jvCoDFUelz4yVJEEVdUKUmGU=" - [mod."go.opentelemetry.io/otel/sdk"] - version = "v1.28.0" - hash = "sha256-X48fV4A9vgxfjBpmUIQumod2nyI+tUc5lnhFkeKBRsc=" - [mod."go.opentelemetry.io/otel/trace"] - version = "v1.28.0" - hash = "sha256-8uxmlm0/5VGoWegxwy0q8NgeY+pyicSoV08RkvD9Q98=" - [mod."golang.org/x/crypto"] - version = "v0.31.0" - hash = "sha256-ZBjoG7ZOuTEmjaXPP9txAvjAjC46DeaLs0zrNzi8EQw=" - [mod."golang.org/x/mod"] - version = "v0.17.0" - hash = "sha256-CLaPeF6uTFuRDv4oHwOQE6MCMvrzkUjWN3NuyywZjKU=" - [mod."golang.org/x/net"] - version = "v0.33.0" - hash = "sha256-9swkU9vp6IflUUqAzK+y8PytSmrKLuryidP3RmRfe0w=" - [mod."golang.org/x/oauth2"] - version = "v0.18.0" - hash = "sha256-TX4CvtvHU+SGSmqlxaQqlgJjlJiOtLGYAZa0zeBfZak=" - [mod."golang.org/x/sync"] - version = "v0.10.0" - hash = "sha256-HWruKClrdoBKVdxKCyoazxeQV4dIYLdkHekQvx275/o=" - [mod."golang.org/x/sys"] - version = "v0.28.0" - hash = "sha256-kzSlDo5FKsQU9cLefIt2dueGUfz9XuEW+mGSGlPATGc=" - [mod."golang.org/x/term"] - version = "v0.27.0" - hash = "sha256-cb5p/yOlVL7dbkxugUVfqESTVpZ2LtrUWPnx9yue3r0=" - [mod."golang.org/x/text"] - version = "v0.21.0" - hash = "sha256-QaMwddBRnoS2mv9Y86eVC2x2wx/GZ7kr2zAJvwDeCPc=" - [mod."golang.org/x/tools"] - version = "v0.21.1-0.20240508182429-e35e4ccd0d2d" - hash = "sha256-KfnS+3fREPAWQUBoUedPupQp9yLrugxMmmEoHvyzKNE=" - [mod."google.golang.org/api"] - version = "v0.169.0" - hash = "sha256-7+EAvbTTnUutkXpQBbxPSmZTS5P0mrKTiFooMI81w0k=" - [mod."google.golang.org/appengine"] - version = "v1.6.8" - hash = "sha256-decMa0MiWfW/Bzr8QPPzzpeya0YWGHhZAt4Cr/bD1wQ=" - [mod."google.golang.org/genproto/googleapis/api"] - version = "v0.0.0-20240701130421-f6361c86f094" - hash = "sha256-uDvld45ensSUweUJYFdUfVt/0mNRrexpuQ3Jas3GMv4=" - [mod."google.golang.org/genproto/googleapis/rpc"] - version = "v0.0.0-20240701130421-f6361c86f094" - hash = "sha256-ass/74EkCljwk7DaASDtK2zipn2cZv6tCLKvwONUWgY=" - [mod."google.golang.org/grpc"] - version = "v1.64.1" - hash = "sha256-A1+kiePmeqRIdigryUGNJWZiILLacDPtMTEyO6CqDpY=" - [mod."google.golang.org/protobuf"] - version = "v1.34.2" - hash = "sha256-nMTlrDEE2dbpWz50eQMPBQXCyQh4IdjrTIccaU0F3m0=" - [mod."gopkg.in/check.v1"] - version = "v1.0.0-20160105164936-4f90aeace3a2" - hash = "sha256-2+om0xBiwyEtUZRY78rYvWU8ECLVhEipNngXz9ttiVE=" - [mod."gopkg.in/yaml.v3"] - version = "v3.0.1" - hash = "sha256-FqL9TKYJ0XkNwJFnq9j0VvJ5ZUU1RvH/52h/f5bkYAU=" - [mod."gotest.tools/v3"] - version = "v3.5.1" - hash = "sha256-ps2GEc3P2xvlrU4TCtXz+nLTxyP0RrF7SScz5jUqE5E=" - [mod."launchpad.net/gocheck"] - version = "v0.0.0-20140225173054-000000000087" - hash = "sha256-gDJ3emyS6+PruKHOf9BvukVENNUxzXhfKC4Gs6tQLvk=" diff --git a/pkgs/fpvout/default.nix b/pkgs/fpvout/default.nix index 7664f9c..97ecad7 100644 --- a/pkgs/fpvout/default.nix +++ b/pkgs/fpvout/default.nix @@ -1,4 +1,5 @@ -{ stdenv +{ lib +, stdenv , fetchFromGitHub , pkgs }: @@ -18,7 +19,7 @@ stdenv.mkDerivation rec { nativeBuildInputs = with pkgs; [ cmake pkg-config - libusb1 + libusb ]; installPhase = '' diff --git a/pkgs/home-assistant-custom-components/circadian_lighting.nix b/pkgs/home-assistant-custom-components/circadian_lighting.nix new file mode 100644 index 0000000..54316f7 --- /dev/null +++ b/pkgs/home-assistant-custom-components/circadian_lighting.nix @@ -0,0 +1,19 @@ +{ lib +, fetchFromGitHub +, buildHomeAssistantComponent +}: + +buildHomeAssistantComponent rec { + owner = "claytonjn"; + domain = "circadian_lighting"; + version = "2.1.4"; + + src = fetchFromGitHub { + owner = "claytonjn"; + repo = "hass-circadian_lighting"; + rev = "refs/tags/${version}"; + hash = "sha256-F67JP5PzMblWpI4CvrHyutPenzVd9KyKeHcHx8rcezA="; + }; + + dontBuild = true; +} diff --git a/pkgs/home-assistant-custom-components/guntamatic.nix b/pkgs/home-assistant-custom-components/guntamatic.nix deleted file mode 100644 index 8ddb7cd..0000000 --- a/pkgs/home-assistant-custom-components/guntamatic.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ fetchFromGitHub -, buildHomeAssistantComponent -}: - -buildHomeAssistantComponent rec { - owner = "a529987659852"; - domain = "GuntamaticBiostar"; - version = "0.2.8"; - - src = fetchFromGitHub { - owner = "a529987659852"; - repo = "GuntamaticBiostar"; - rev = "refs/tags/v${version}"; - hash = "sha256-edKt2LQzxaMXAIeJcBag85ksKPXOfgCENO4jBw9hkCQ="; - }; - - dontBuild = true; -} diff --git a/pkgs/illuminanced/default.nix b/pkgs/illuminanced/default.nix deleted file mode 100644 index 3ab99e2..0000000 --- a/pkgs/illuminanced/default.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ rustPlatform -, fetchFromGitHub -}: - -let - version = "1.0.2"; -in -rustPlatform.buildRustPackage { - pname = "illuminanced"; - inherit version; - - src = fetchFromGitHub { - owner = "mikhail-m1"; - repo = "illuminanced"; - rev = version; - sha256 = "sha256-ZEVma0uj9rsWB+vfUL7w3dHxI/ppBCG23TirGE+RREk="; - }; - - cargoHash = "sha256-kPWoQ6rE4wBjmqQLNPY4UWJt/AOgr+eVKY0ZK7B4K1A="; -} diff --git a/pkgs/ksoloti/default.nix b/pkgs/ksoloti/default.nix deleted file mode 100644 index 54cdb30..0000000 --- a/pkgs/ksoloti/default.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ lib -, pkgs -, stdenv -, fetchFromGitHub -, gnumake -, gcc-arm-embedded -, jdk -, libfaketime -, ant -, makeWrapper -, dfu-util -}: - -stdenv.mkDerivation rec { - version = "1.1.0beta"; - pname = "ksoloti"; - - src = fetchFromGitHub { - owner = "ksoloti"; - repo = "ksoloti"; - rev = version; - sha256 = "sha256-RRwar0X2gI0LyM/pNhnlLet06MzrG4z4lm3kCmzWwBc="; - }; - - buildInputs = [ jdk libfaketime ]; - - nativeBuildInputs = [ - ant - gcc-arm-embedded - gnumake - makeWrapper - ]; - - propagatedBuildInputs = [ - dfu-util - gcc-arm-embedded - ]; - - /* - # Hardcode dfu-util path - substituteInPlace "platform_linux/upload_fw_dfu.sh" \ - --replace-fail "/bin/dfu-util" "" - substituteInPlace "platform_linux/upload_fw_dfu.sh" \ - --replace-fail "./dfu-util" "${dfu-util-ksoloti}/bin/dfu-util" - - */ - patchPhase = '' - # Hardcode path to "make" - for f in "firmware/compile_firmware_linux.sh" \ - "firmware/compile_patch_linux.sh"; do - substituteInPlace "$f" \ - --replace "make" "${gnumake}/bin/make" - done - - # Fix build version - substituteInPlace "build.xml" \ - --replace-fail "(git missing)" "${version}" - # Remove build time - substituteInPlace "build.xml" \ - --replace-fail "" "" - substituteInPlace "build.xml" \ - --replace-fail \ - '' \ - '' - substituteInPlace "build.xml" \ - --replace-fail "" "" - substituteInPlace "build.xml" \ - --replace-fail \ - '{line.separator}' \ - '{line.separator} ' - ''; - - buildPhase = '' - ( - find . -exec touch -d '1970-01-01 00:00' {} \; - (cd platform_linux; PATH="${pkgs.gcc-arm-embedded}/bin:$PATH" sh compile_firmware.sh BOARD_AXOLOTI_CORE) - faketime "1970-01-01 00:00:00" ant -Dbuild.runtime=true - ) - ''; - - installPhase = '' - mkdir -p $out/bin $out/share/ksoloti - - cp -r doc firmware chibios platform_linux CMSIS *.txt $out/share/ksoloti/ - install -vD dist/Ksoloti.jar $out/share/ksoloti/ - - patchShebangs $out/share/ksoloti/platform_linux/*.sh - - rm $out/share/ksoloti/platform_linux/bin/dfu-util - ln -s ${dfu-util}/bin/dfu-util $out/share/ksoloti/platform_linux/bin/dfu-util - - makeWrapper ${jdk}/bin/java $out/bin/ksoloti --add-flags "-Dksoloti_release=$out/share/ksoloti -Dksoloti_runtime=$out/share/ksoloti -jar $out/share/ksoloti/Ksoloti.jar" --prefix PATH : ${ - lib.makeBinPath [ - pkgs.gcc-arm-embedded - ] - } - ''; - - meta = with lib; { - homepage = "http://ksoloti.github.io"; - description = '' - Sketching embedded digital audio algorithms. - - To fix permissions of the Ksoloti USB device node, add a similar udev rule to services.udev.extraRules: - SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="0442", OWNER="someuser", GROUP="somegroup" - ''; - license = licenses.gpl3; - maintainers = with maintainers; [ ]; - }; -} diff --git a/pkgs/modules.nix b/pkgs/modules.nix index 195958b..f61aa63 100644 --- a/pkgs/modules.nix +++ b/pkgs/modules.nix @@ -1,6 +1,9 @@ +{ pkgs, ... }: + { imports = [ - ./ksoloti/module.nix + ./asterisk-sounds-de/module.nix ./myintercom-doorbell/module.nix + ./pretix/module.nix ]; } diff --git a/pkgs/myintercom-doorbell/default.nix b/pkgs/myintercom-doorbell/default.nix index 37b3711..9d7fd58 100644 --- a/pkgs/myintercom-doorbell/default.nix +++ b/pkgs/myintercom-doorbell/default.nix @@ -1,7 +1,12 @@ -{ poetry2nix }: +{ lib, python3, poetry2nix }: -poetry2nix.mkPoetryApplication { +poetry2nix.mkPoetryApplication rec { pname = "myintercom-audiosocket"; version = "0.0.1"; projectDir = ./.; + overrides = poetry2nix.overrides.withDefaults (final: prev: { + urllib3 = prev.urllib3.override { + preferWheel = true; + }; + }); } diff --git a/pkgs/myintercom-doorbell/module.nix b/pkgs/myintercom-doorbell/module.nix index cddb862..066b9ca 100644 --- a/pkgs/myintercom-doorbell/module.nix +++ b/pkgs/myintercom-doorbell/module.nix @@ -84,73 +84,73 @@ in config = lib.mkIf cfg.enable { environment.etc."myintercom-doorbell/settings.json".text = builtins.toJSON { - inherit (cfg) host; - inherit (cfg) username; - inherit (cfg) passwordFile; + host = cfg.host; + username = cfg.username; + passwordFile = cfg.passwordFile; audiosocket = { - inherit (cfg.audiosocket) address; - inherit (cfg.audiosocket) port; - inherit (cfg.audiosocket) uuid; + address = cfg.audiosocket.address; + port = cfg.audiosocket.port; + uuid = cfg.audiosocket.uuid; }; - inherit (cfg) callerId; - inherit (cfg) dialTime; + callerId = cfg.callerId; + dialTime = cfg.dialTime; }; - systemd.services = { - myintercom-doorbell-poll = { - inherit (cfg) enable; - description = "Polls myintercom doorbell ring button status."; - after = [ "asterisk.service" "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "simple"; - User = "asterisk"; - # @TODO: Use unstable only until 23.11 is released - ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-poll"; - }; + systemd.services.myintercom-doorbell-poll = { + enable = cfg.enable; + description = "Polls myintercom doorbell ring button status."; + after = [ "asterisk.service" "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + User = "asterisk"; + # @TODO: Use unstable only until 23.11 is released + ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-poll"; }; - myintercom-doorbell-audiosocket = { - inherit (cfg) enable; - description = "myintercom doorbell AudioSocket for Asterisk"; - requires = [ "asterisk.service" ]; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "simple"; - DynamicUser = true; - CapabilityBoundingSet = null; - PrivateUsers = true; - ProtectHome = true; - RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; - RestrictNamespaces = true; - SystemCallFilter = "@system-service"; - LoadCredential = "password:${cfg.passwordFile}"; - Environment = [ - "LISTEN_ADDRESS=${cfg.audiosocket.address}" - "LISTEN_PORT=${toString cfg.audiosocket.port}" - "HOST=${cfg.host}" - "USERNAME=${cfg.username}" - "PASSWORD_FILE=%d/password" - ]; - ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-audiosocket"; - }; + }; + + systemd.services.myintercom-doorbell-audiosocket = { + enable = cfg.enable; + description = "myintercom doorbell AudioSocket for Asterisk"; + requires = [ "asterisk.service" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + DynamicUser = true; + CapabilityBoundingSet = null; + PrivateUsers = true; + ProtectHome = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + SystemCallFilter = "@system-service"; + LoadCredential = "password:${cfg.passwordFile}"; + Environment = [ + "LISTEN_ADDRESS=${cfg.audiosocket.address}" + "LISTEN_PORT=${toString cfg.audiosocket.port}" + "HOST=${cfg.host}" + "USERNAME=${cfg.username}" + "PASSWORD_FILE=%d/password" + ]; + ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-audiosocket"; }; - myintercom-doorbell-cam-proxy = { - inherit (cfg.cam) enable; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - description = "Proxies the videostream of myintercom doorbell."; - script = '' - sed "s:__PASSWORD__:$(cat "$PASSWORD_FILE"):" "${mediamtxConfig}" | ${pkgs.mediamtx}/bin/mediamtx /dev/stdin - ''; - serviceConfig = { - Type = "simple"; - DynamicUser = true; - LoadCredential = "password:${cfg.passwordFile}"; - Environment = [ - "PASSWORD_FILE=%d/password" - ]; - }; + }; + + systemd.services.myintercom-doorbell-cam-proxy = { + enable = cfg.cam.enable; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + description = "Proxies the videostream of myintercom doorbell."; + script = '' + sed "s:__PASSWORD__:$(cat "$PASSWORD_FILE"):" "${mediamtxConfig}" | ${pkgs.master.mediamtx}/bin/mediamtx /dev/stdin + ''; + serviceConfig = { + Type = "simple"; + DynamicUser = true; + LoadCredential = "password:${cfg.passwordFile}"; + Environment = [ + "PASSWORD_FILE=%d/password" + ]; }; }; }; diff --git a/pkgs/myintercom-doorbell/myintercom_doorbell/connection.py b/pkgs/myintercom-doorbell/myintercom_doorbell/connection.py index a5e968e..12767ea 100644 --- a/pkgs/myintercom-doorbell/myintercom_doorbell/connection.py +++ b/pkgs/myintercom-doorbell/myintercom_doorbell/connection.py @@ -13,15 +13,9 @@ from time import sleep @dataclass(frozen=True) class types_struct: uuid: bytes = b"\x01" # Message payload contains UUID set in Asterisk Dialplan - audio: bytes = ( - b"\x10" # * Message payload contains 8Khz 16-bit mono LE PCM audio (* See Github readme) - ) - silence: bytes = ( - b"\x02" # Message payload contains silence (I've never seen this occur personally) - ) - hangup: bytes = ( - b"\x00" # Tell Asterisk to hangup the call (This doesn't appear to ever be sent from Asterisk to us) - ) + audio: bytes = b"\x10" # * Message payload contains 8Khz 16-bit mono LE PCM audio (* See Github readme) + silence: bytes = b"\x02" # Message payload contains silence (I've never seen this occur personally) + hangup: bytes = b"\x00" # Tell Asterisk to hangup the call (This doesn't appear to ever be sent from Asterisk to us) error: bytes = b"\xff" # Message payload contains an error from Asterisk diff --git a/pkgs/myintercom-doorbell/myintercom_doorbell/service.py b/pkgs/myintercom-doorbell/myintercom_doorbell/service.py index 3def826..641c3f6 100644 --- a/pkgs/myintercom-doorbell/myintercom_doorbell/service.py +++ b/pkgs/myintercom-doorbell/myintercom_doorbell/service.py @@ -8,12 +8,7 @@ import time def send_open_door_request(host, username, password): - urllib3.PoolManager( - timeout=urllib3.Timeout( - connect=3.0, - read=300, - ) - ).request( + urllib3.PoolManager().request( "GET", f"http://{host}/local/Doorcom/door.cgi?r=1", headers=urllib3.make_headers(basic_auth=f"{username}:{password}"), @@ -21,12 +16,10 @@ def send_open_door_request(host, username, password): def get_ring_status(host, username, password): - url = f"http://{host}/local/Doorcom/monitor.cgi?ring=1" - print(f"sending request to {url}", flush=True) try: response = urllib3.PoolManager().request( "GET", - url, + f"http://{host}/local/Doorcom/monitor.cgi?ring=1", headers=urllib3.make_headers(basic_auth=f"{username}:{password}"), preload_content=False, decode_content=True, @@ -50,7 +43,6 @@ def get_ring_status(host, username, password): data.append(line.decode().rstrip()) else: if data: - print(f"received: {data}", flush=True) yield data break diff --git a/pkgs/myintercom-doorbell/poetry.lock b/pkgs/myintercom-doorbell/poetry.lock index 0ce0d9b..818c966 100644 --- a/pkgs/myintercom-doorbell/poetry.lock +++ b/pkgs/myintercom-doorbell/poetry.lock @@ -1,24 +1,24 @@ -# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "urllib3" -version = "2.5.0" +version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false -python-versions = ">=3.9" -groups = ["main"] +python-versions = ">=3.7" files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, ] [package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [metadata] -lock-version = "2.1" -python-versions = "^3.12" -content-hash = "a2502d4bca34c8c9ddc7579666a62dc15d3573a0240075cb566922a1d031831e" +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "cb8f26af67979881c24e243af0719b405141855256ced72c73b222b6c03d2bb8" diff --git a/pkgs/myintercom-doorbell/pyproject.toml b/pkgs/myintercom-doorbell/pyproject.toml index 3a57dc6..6a7878f 100644 --- a/pkgs/myintercom-doorbell/pyproject.toml +++ b/pkgs/myintercom-doorbell/pyproject.toml @@ -7,8 +7,8 @@ readme = "README.md" packages = [{include = "myintercom_doorbell"}] [tool.poetry.dependencies] -python = "^3.12" -urllib3 = "^2.5.0" +python = "^3.10" +urllib3 = "^2.0.7" [tool.poetry.scripts] myintercom-doorbell-audiosocket = "myintercom_doorbell.myintercom_audiosocket:main" diff --git a/pkgs/pomodoro-timer/default.nix b/pkgs/pomodoro-timer/default.nix deleted file mode 100644 index a3638f8..0000000 --- a/pkgs/pomodoro-timer/default.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ lib -, stdenv -, yad -, uair -, writeShellScript -, makeDesktopItem -, imagemagick -}: - -let - pomodoroTimer = writeShellScript "pomodoro-timer" '' - export PATH=${lib.makeBinPath [yad uair]} - uairctl listen -o yad \ - | yad \ - --title="Pomodoro" \ - --geometry="300x50" \ - --scale \ - --progress \ - --no-buttons \ - --css="* { font-size: 60px;} progress { min-height: 1200px; margin: -100px -8px -6px;}" - ''; -in -stdenv.mkDerivation rec { - pname = "pomodoro-timer"; - version = "1.0.0"; - src = ./pomodorotimer.svg; - dontUnpack = true; - - installPhase = '' - icon_size=64x64 - dir=$out/share/icons/hicolor/scalable/apps/ - mkdir -p \ - $out/share/icons/hicolor/scalable/apps/ \ - $out/share/icons/hicolor/$icon_size/apps/ - - cp $src $dir/pomodorotimer.svg - mkdir $out/bin - cp "${pomodoroTimer}" $out/bin/pomodoro-timer - ln -s "${desktopItem}/share/applications" $out/share/ - - ${imagemagick}/bin/convert \ - -size $icon_size \ - $src \ - $out/share/icons/hicolor/$icon_size/apps/pomodorotimer.png - ''; - - desktopItem = makeDesktopItem { - name = pname; - exec = pname; - icon = "pomodorotimer"; - desktopName = pname; - comment = meta.description; - categories = [ "Utility" ]; - }; - - meta = with lib; { - description = "Pomodoro timer (GUI for uair)"; - maintainers = with maintainers; [ jalr ]; - platforms = platforms.linux; - }; -} diff --git a/pkgs/pomodoro-timer/pomodorotimer.svg b/pkgs/pomodoro-timer/pomodorotimer.svg deleted file mode 100644 index b771a33..0000000 --- a/pkgs/pomodoro-timer/pomodorotimer.svg +++ /dev/null @@ -1,274 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - Pomodoro Timer - - - - - - - image/svg+xml - - - - - Openclipart - - - Pomodoro Timer - 2011-05-03T21:58:11 - The Pomodoro Technique® is a way to get the most out of time management. Develop by Francesco Cirillo. - https://openclipart.org/detail/135631/pomodoro-timer-by-fairhonanth - - - fairhonanth - - - - - management - pomodoro - productivity - techinique - timer - - - - - - - - - - - diff --git a/nix-cache/.envrc b/pkgs/pretix/.envrc similarity index 100% rename from nix-cache/.envrc rename to pkgs/pretix/.envrc diff --git a/pkgs/pretix/module.nix b/pkgs/pretix/module.nix new file mode 100644 index 0000000..da43907 --- /dev/null +++ b/pkgs/pretix/module.nix @@ -0,0 +1,313 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.pretix; + name = "pretix"; + user = "pretix"; + group = "pretix"; + bind = { + host = "127.0.0.1"; + port = 8000; + }; + postgresql = { + database = "pretix"; + user = "pretix"; + password = "pretix"; + }; + redisPort = 6379; + urlScheme = if cfg.enableTls then "https" else "http"; + url = "${urlScheme}://${cfg.domain}"; + toBool = x: if x then "on" else "off"; + hstsHeader = if cfg.enableTls then "add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\" always;" else ""; + pythonPackages = pkgs.pretix.passthru.pythonModule.passthru.pkgs; + python = pkgs.pretix.passthru.python; + runCommandArgs = { + # Sets PYTHONPATH in derivation + buildInputs = [ + pkgs.pretix + pythonPackages.gunicorn + pythonPackages.celery + ]; + }; + staticRoot = pkgs.pretix-static; + environmentFile = pkgs.runCommand "pretix-environ" runCommandArgs ('' + cat > $out <=4.0,<5.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns", "brotlicffi"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "amqp" +version = "5.2.0" +description = "Low-level AMQP client for Python (fork of amqplib)." +optional = false +python-versions = ">=3.6" +files = [ + {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, + {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, +] + +[package.dependencies] +vine = ">=5.0.0,<6.0.0" + +[[package]] +name = "arabic-reshaper" +version = "3.0.0" +description = "Reconstruct Arabic sentences to be used in applications that do not support Arabic" +optional = false +python-versions = "*" +files = [ + {file = "arabic_reshaper-3.0.0-py3-none-any.whl", hash = "sha256:3f71d5034bb694204a239a6f1ebcf323ac3c5b059de02259235e2016a1a5e2dc"}, + {file = "arabic_reshaper-3.0.0.tar.gz", hash = "sha256:ffcd13ba5ec007db71c072f5b23f420da92ac7f268512065d49e790e62237099"}, +] + +[package.extras] +with-fonttools = ["fonttools (>=4.0)"] + +[[package]] +name = "asgiref" +version = "3.7.2" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[[package]] +name = "babel" +version = "2.13.1" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, +] + +[package.dependencies] +setuptools = {version = "*", markers = "python_version >= \"3.12\""} + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.2" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "billiard" +version = "4.2.0" +description = "Python multiprocessing fork with improvements and bugfixes" +optional = false +python-versions = ">=3.7" +files = [ + {file = "billiard-4.2.0-py3-none-any.whl", hash = "sha256:07aa978b308f334ff8282bd4a746e681b3513db5c9a514cbdd810cbbdc19714d"}, + {file = "billiard-4.2.0.tar.gz", hash = "sha256:9a3c3184cb275aa17a732f93f65b20c525d3d9f253722d26a82194803ade5a2c"}, +] + +[[package]] +name = "bleach" +version = "5.0.1" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.7" +files = [ + {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, + {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, +] + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.2)"] +dev = ["Sphinx (==4.3.2)", "black (==22.3.0)", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"] + +[[package]] +name = "cbor2" +version = "5.5.1" +description = "CBOR (de)serializer with extensive tag support" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cbor2-5.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:37ba4f719384bd4ea317e92a8763ea343e205f3112c8241778fd9dbc64ae1498"}, + {file = "cbor2-5.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:425ae919120b9d05b4794b3e5faf6584fc47a9d61db059d4f00ce16ae93a3f63"}, + {file = "cbor2-5.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c511ff6356d6f4292ced856d5048a24ee61a85634816f29dadf1f089e8cb4f9"}, + {file = "cbor2-5.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6ab54a9282dd99a3a70d0f64706d3b3592e7920564a93101caa74dec322346c"}, + {file = "cbor2-5.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:39d94852dd61bda5b3d2bfe74e7b194a7199937d270f90099beec3e7584f0c9b"}, + {file = "cbor2-5.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:65532ba929beebe1c63317ad00c79d4936b60a5c29a3c329d2aa7df4e72ad907"}, + {file = "cbor2-5.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:1206180f66a9ad23e692cf457610c877f186ad303a1264b6c5335015b7bee83e"}, + {file = "cbor2-5.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:42155a20be46312fad2ceb85a408e2d90da059c2d36a65e0b99abca57c5357fd"}, + {file = "cbor2-5.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6f3827ae14c009df9b37790f1da5cd1f9d64f7ffec472a49ebf865c0af6b77e9"}, + {file = "cbor2-5.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bfa417dbb8b4581ad3c2312469899518596551cfb0fe5bdaf8a6921cff69d7e"}, + {file = "cbor2-5.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3317e7dfb4f3180be90bcd853204558d89f119b624c2168153b53dea305e79d"}, + {file = "cbor2-5.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a5770bdf4340de55679efe6c38fc6d64529fda547e7a85eb0217a82717a8235"}, + {file = "cbor2-5.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b5d53826ad0c92fcb004b2a475896610b51e0ca010f6c37d762aae44ab0807b2"}, + {file = "cbor2-5.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:dc77cac985f7f7a20f2d8b1957d1e79393d7df823f61c7c6173d3a0011c1d770"}, + {file = "cbor2-5.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9e45d5aa8e484b4bf57240d8e7949389f1c9d4073758abb30954386321b55c9d"}, + {file = "cbor2-5.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93b949a66bec40dd0ca87a6d026136fea2cf1660120f921199a47ac8027af253"}, + {file = "cbor2-5.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93d601ca92d917f769370a5e6c3ead62dca6451b2b603915e4fcf300083b9fcd"}, + {file = "cbor2-5.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a11876abd50b9f70d114fcdbb0b5a3249ccd7d321465f0350028fd6d2317e114"}, + {file = "cbor2-5.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fd77c558decdba2a2a7a463e6346d53781d2163bacf205f77b999f561ba4ac73"}, + {file = "cbor2-5.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efb81920d80410b8e80a4a6a8b06ec9b766be0ae7f3029af8ae4b30914edcfa3"}, + {file = "cbor2-5.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:4bb35f3b1ebd4b7b37628f0cd5c839f3008dec669194a2a4a33d91bab7f8663b"}, + {file = "cbor2-5.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f41e4a439f642954ed728dc18915098b5f2ebec7029eaebe52c06c52b6a9a63a"}, + {file = "cbor2-5.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4eae4d56314f22920a28bf7affefdfc918646877ce3b16220dc6cf38a584aa41"}, + {file = "cbor2-5.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559a0c1ec8dcedd6142b81727403e0f5a2e8f4c18e8bb3c548107ec39af4e9cb"}, + {file = "cbor2-5.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:537da7bfee97ee44a11b300c034c18e674af6a5dc4718a6fba141037f099c7ec"}, + {file = "cbor2-5.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5c99fd8bbc6bbf3bf4d6b2996594ae633b778b27b0531559487950762c4e1e3f"}, + {file = "cbor2-5.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ee46e6dbc8e2cf302a022fec513d57dba65e9d5ec495bcd1ad97a5dbdbab249"}, + {file = "cbor2-5.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:67e2be461320197495fff55f250b111d4125a0a2d02e6256e41f8598adc3ad3f"}, + {file = "cbor2-5.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4384a56afef0b908b61c8ea3cca3e257a316427ace3411308f51ee301b23adf9"}, + {file = "cbor2-5.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8cc64acc606b7f2a4b673a1d6cde5a9cb1860a6ce27b353e269c9535efbd62c"}, + {file = "cbor2-5.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50019fea3cb07fa9b2b53772a52b4243e87de232591570c4c272b3ebdb419493"}, + {file = "cbor2-5.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a18be0af9241883bc67a036c1f33e3f9956d31337ccd412194bf759bc1095e03"}, + {file = "cbor2-5.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:60e7e0073291096605de27de3ce006148cf9a095199160439555f14f93d044d5"}, + {file = "cbor2-5.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:41f7501338228b27dac88c1197928cf8985f6fc775f59be89c6fdaddb4e69658"}, + {file = "cbor2-5.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:c85ab7697252af2240e939707c935ea18081ccb580d4b5b9a94b04148ab2c32b"}, + {file = "cbor2-5.5.1-py3-none-any.whl", hash = "sha256:dca639c8ff81b9f0c92faf97324adfdbfb5c2a5bb97f249606c6f5b94c77cc0d"}, + {file = "cbor2-5.5.1.tar.gz", hash = "sha256:f9e192f461a9f8f6082df28c035b006d153904213dc8640bed8a72d72bbc9475"}, +] + +[package.extras] +benchmarks = ["pytest-benchmark (==4.0.0)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.3.0)", "typing-extensions"] +test = ["coverage (>=7)", "hypothesis", "pytest"] + +[[package]] +name = "celery" +version = "5.3.6" +description = "Distributed Task Queue." +optional = false +python-versions = ">=3.8" +files = [ + {file = "celery-5.3.6-py3-none-any.whl", hash = "sha256:9da4ea0118d232ce97dff5ed4974587fb1c0ff5c10042eb15278487cdd27d1af"}, + {file = "celery-5.3.6.tar.gz", hash = "sha256:870cc71d737c0200c397290d730344cc991d13a057534353d124c9380267aab9"}, +] + +[package.dependencies] +billiard = ">=4.2.0,<5.0" +click = ">=8.1.2,<9.0" +click-didyoumean = ">=0.3.0" +click-plugins = ">=1.1.1" +click-repl = ">=0.2.0" +kombu = ">=5.3.4,<6.0" +python-dateutil = ">=2.8.2" +tzdata = ">=2022.7" +vine = ">=5.1.0,<6.0" + +[package.extras] +arangodb = ["pyArango (>=2.0.2)"] +auth = ["cryptography (==41.0.5)"] +azureblockblob = ["azure-storage-blob (>=12.15.0)"] +brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] +cassandra = ["cassandra-driver (>=3.25.0,<4)"] +consul = ["python-consul2 (==0.1.5)"] +cosmosdbsql = ["pydocumentdb (==2.3.5)"] +couchbase = ["couchbase (>=3.0.0)"] +couchdb = ["pycouchdb (==1.14.2)"] +django = ["Django (>=2.2.28)"] +dynamodb = ["boto3 (>=1.26.143)"] +elasticsearch = ["elastic-transport (<=8.10.0)", "elasticsearch (<=8.11.0)"] +eventlet = ["eventlet (>=0.32.0)"] +gevent = ["gevent (>=1.5.0)"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +memcache = ["pylibmc (==1.6.3)"] +mongodb = ["pymongo[srv] (>=4.0.2)"] +msgpack = ["msgpack (==1.0.7)"] +pymemcache = ["python-memcached (==1.59)"] +pyro = ["pyro4 (==4.82)"] +pytest = ["pytest-celery (==0.0.0)"] +redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"] +s3 = ["boto3 (>=1.26.143)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +solar = ["ephem (==4.1.5)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=1.3.1)"] +zstd = ["zstandard (==0.22.0)"] + +[[package]] +name = "certifi" +version = "2023.11.17" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, +] + +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "chardet" +version = "5.1.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"}, + {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-didyoumean" +version = "0.3.0" +description = "Enables git-like *did-you-mean* feature in click" +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"}, + {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"}, +] + +[package.dependencies] +click = ">=7" + +[[package]] +name = "click-plugins" +version = "1.1.1" +description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +optional = false +python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] + +[[package]] +name = "click-repl" +version = "0.3.0" +description = "REPL plugin for Click" +optional = false +python-versions = ">=3.6" +files = [ + {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, + {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, +] + +[package.dependencies] +click = ">=7.0" +prompt-toolkit = ">=3.0.36" + +[package.extras] +testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "cryptography" +version = "41.0.7" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"}, + {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"}, + {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"}, + {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"}, + {file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"}, + {file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"}, + {file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "css-inline" +version = "0.8.7" +description = "Fast CSS inlining written in Rust" +optional = false +python-versions = ">=3.7" +files = [ + {file = "css_inline-0.8.7-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3604d7af3df90681a5a31d2a1438bd237ae1ba171f2ea1cb62824f4909238a63"}, + {file = "css_inline-0.8.7-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:6e0afb35e17888b2ddd8efee738f1f68ae569615cb32b66427381372cab2d6b2"}, + {file = "css_inline-0.8.7-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:84e2b2c5c7c16b5ff546f9fae53e7f0d24bc63e9de6a2a655809c3698ad9f9e2"}, + {file = "css_inline-0.8.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773a150ba085d73ea8a4f27f562dcf90a7bc8dcecf0d1867b660f22d036c6a6a"}, + {file = "css_inline-0.8.7-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:39a90bd53272ee68a4d7909dc9b03240b296c50249b964cb253faf361c90e9dd"}, + {file = "css_inline-0.8.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ee0894e7a72434750799fced0c7404fed19f3d0538c7fb3ff61d4efacd473d"}, + {file = "css_inline-0.8.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5b08837acd1fe60a8f8cbd44dfce88dda1676aca47eeb51bf512c02e90803b77"}, + {file = "css_inline-0.8.7-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:6c0f02ddc5b694520d0fb8db7961e703120a373e516a74cfa6c8303b1c131e42"}, + {file = "css_inline-0.8.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:51cc996cfce5fd10aa5e41569c664cded198f30f4706e699e97942893aa9e7f9"}, + {file = "css_inline-0.8.7-cp37-abi3-win32.whl", hash = "sha256:c5910202e7583f0d1b6aea34d63cd378e28808f8bcf210a9c961cb26ccc5ed25"}, + {file = "css_inline-0.8.7-cp37-abi3-win_amd64.whl", hash = "sha256:6803c2fb2064330de1761a44ae86ab6c9b78d1761c36ebdd8919346e595d702d"}, + {file = "css_inline-0.8.7-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:36a392ed87f840621838e63937e151d236a62cfdba2760f503273330691ea3d8"}, + {file = "css_inline-0.8.7-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0757b71ae23d4131d7ca274bb35d41f5faa41b88eed9090df3ab409689d055d"}, + {file = "css_inline-0.8.7-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6579c9ea5e288e644bd78dbfd3d2bae9c33eb11e3f02d2c61cf4b5683c8f97da"}, + {file = "css_inline-0.8.7-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:819bf4c331e59da07d824529027c00ec618c2f0b1d498f43e5281988339ac082"}, + {file = "css_inline-0.8.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e87293717865bca00bbc2046864e33a421468129a8a8fe938abf2397c4a8e26"}, + {file = "css_inline-0.8.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7d4313eed1de7def6d2e9c4780f11e1faed3800f2e2ad4de47dc15ba7a40da"}, + {file = "css_inline-0.8.7-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:7e5d5aebf87bcacc6bd3f548e0648f4e1b26d4b50e7239df234a42cb1374c039"}, + {file = "css_inline-0.8.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3b5dc09f6de78fa9f7152e701fdfa2ed827a7c0543a6746ba9879e8731c6da5"}, + {file = "css_inline-0.8.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf6053352d053d32a2294510416c704e5b62325a8214dca5c764455e318948c"}, + {file = "css_inline-0.8.7.tar.gz", hash = "sha256:68dac7010c27624627f7df9be12888b9129fd658804f52f8feac25f7d4766050"}, +] + +[[package]] +name = "defusedcsv" +version = "2.0.0" +description = "Drop-in replacement for Python's CSV library that tries to mitigate CSV injection attacks" +optional = false +python-versions = "*" +files = [ + {file = "defusedcsv-2.0.0-py3-none-any.whl", hash = "sha256:a7bc3b1ac1ce4f8c6c1e8740466b1b5789b51ca18d918b0099313dc0cdf2cef4"}, + {file = "defusedcsv-2.0.0.tar.gz", hash = "sha256:7612228e54ef1690a19f7aef526709010608e987f9998c89588ef05d9ecfe4d6"}, +] + +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + +[[package]] +name = "dj-static" +version = "0.0.6" +description = "Serve production static files with Django." +optional = false +python-versions = "*" +files = [ + {file = "dj-static-0.0.6.tar.gz", hash = "sha256:032ec1c532617922e6e3e956d504a6fb1acce4fc1c7c94612d0fda21828ce8ef"}, +] + +[package.dependencies] +static3 = "*" + +[[package]] +name = "django" +version = "4.2.8" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Django-4.2.8-py3-none-any.whl", hash = "sha256:6cb5dcea9e3d12c47834d32156b8841f533a4493c688e2718cafd51aa430ba6d"}, + {file = "Django-4.2.8.tar.gz", hash = "sha256:d69d5e36cc5d9f4eb4872be36c622878afcdce94062716cf3e25bcedcb168b62"}, +] + +[package.dependencies] +asgiref = ">=3.6.0,<4" +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "django-appconf" +version = "1.0.6" +description = "A helper class for handling configuration defaults of packaged apps gracefully." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-appconf-1.0.6.tar.gz", hash = "sha256:cfe87ea827c4ee04b9a70fab90b86d704cb02f2981f89da8423cb0fabf88efbf"}, + {file = "django_appconf-1.0.6-py3-none-any.whl", hash = "sha256:c3ae442fba1ff7ec830412c5184b17169a7a1e71cf0864a4c3f93cf4c98a1993"}, +] + +[package.dependencies] +django = "*" + +[[package]] +name = "django-bootstrap3" +version = "23.1" +description = "Bootstrap 3 support for Django projects" +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-bootstrap3-23.1.tar.gz", hash = "sha256:7095b7c66a89f3baeb78ea028799ebd795d29739fc8602460422e7c2a194ad30"}, + {file = "django_bootstrap3-23.1-py3-none-any.whl", hash = "sha256:044ff0d34cd6a3928e0b7dc104a06b2f73e71bea237da5e9a477cc047a5d8e21"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "django-compressor" +version = "4.3.1" +description = "('Compresses linked and inline JavaScript or CSS into single cached files.',)" +optional = false +python-versions = "*" +files = [ + {file = "django_compressor-4.3.1-py2.py3-none-any.whl", hash = "sha256:2c451174acb6f083054af7c8089376599b22d6380bd60311f78ec3fed79acc8e"}, + {file = "django_compressor-4.3.1.tar.gz", hash = "sha256:68858c0da6cc099cc29a022d86c3ba8aed114da9d709eeceb0d7b8181b5f8942"}, +] + +[package.dependencies] +django-appconf = ">=1.0.3" +rcssmin = "1.1.1" +rjsmin = "1.2.1" + +[[package]] +name = "django-countries" +version = "7.5.1" +description = "Provides a country field for Django models." +optional = false +python-versions = "*" +files = [ + {file = "django-countries-7.5.1.tar.gz", hash = "sha256:22915d9b9403932b731622619940a54894a3eb0da9a374e7249c8fc453c122d7"}, + {file = "django_countries-7.5.1-py3-none-any.whl", hash = "sha256:2df707aca7a5e677254bed116cf6021a136ebaccd5c2f46860abd6452bb45521"}, +] + +[package.dependencies] +asgiref = "*" +typing-extensions = "*" + +[package.extras] +dev = ["black", "django", "djangorestframework", "graphene-django", "pytest", "pytest-django", "tox"] +maintainer = ["django", "transifex-client", "zest.releaser[recommended]"] +pyuca = ["pyuca"] +test = ["djangorestframework", "graphene-django", "pytest", "pytest-cov", "pytest-django"] + +[[package]] +name = "django-filter" +version = "23.2" +description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-filter-23.2.tar.gz", hash = "sha256:2fe15f78108475eda525692813205fa6f9e8c1caf1ae65daa5862d403c6dbf00"}, + {file = "django_filter-23.2-py3-none-any.whl", hash = "sha256:d12d8e0fc6d3eb26641e553e5d53b191eb8cec611427d4bdce0becb1f7c172b5"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "django-formset-js-improved" +version = "0.5.0.3" +description = "Extend Django formsets with JavaScript" +optional = false +python-versions = "*" +files = [ + {file = "django-formset-js-improved-0.5.0.3.tar.gz", hash = "sha256:6c5a0ffec4fc25ad5f502b914fa6414fb0e43ec5f116a88a2da0090a72f32a4c"}, + {file = "django_formset_js_improved-0.5.0.3-py3-none-any.whl", hash = "sha256:99ff030c427fe412a8a54c6fadc3809f3d65683470b67f68d1d421ce7a09bb94"}, +] + +[package.dependencies] +Django = "*" +django-jquery-js = "*" + +[[package]] +name = "django-formtools" +version = "2.4.1" +description = "A set of high-level abstractions for Django forms" +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-formtools-2.4.1.tar.gz", hash = "sha256:21f8d5dac737f1e636fa8a0a10969c1c32f525a6dfa27c29592827ba70d9643a"}, + {file = "django_formtools-2.4.1-py3-none-any.whl", hash = "sha256:49ea8a64ddef4728a558bf5f8f622c0f4053b979edcf193bf00dd80432ab2f12"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "django-hierarkey" +version = "1.1.0" +description = "Hierarchical key-value store for django" +optional = false +python-versions = "*" +files = [ + {file = "django-hierarkey-1.1.0.tar.gz", hash = "sha256:b0963b760b5bb4b97fe7abc6b7a0f3d2dd23e4741ac4585252af1d47f5ae771a"}, + {file = "django_hierarkey-1.1.0-py3-none-any.whl", hash = "sha256:2be56a6ae79bec1b356e2df22d2781fb6a48bd4bc55635a74a3e468fc0e2046f"}, +] + +[package.dependencies] +python-dateutil = "*" + +[[package]] +name = "django-hijack" +version = "3.3.0" +description = "django-hijack allows superusers to hijack (=login as) and work on behalf of another user." +optional = false +python-versions = "*" +files = [ + {file = "django-hijack-3.3.0.tar.gz", hash = "sha256:795cd0087596a21c9bf641fa5cf1787f4edf144e16a423014afbcf2838e8e124"}, + {file = "django_hijack-3.3.0-py3-none-any.whl", hash = "sha256:976ae3bc7e9db0bcb5f5b85a58fba98f5ff1d7a6e92e1b65854289cc79a351d4"}, +] + +[package.dependencies] +django = ">=2.2" + +[package.extras] +test = ["pytest", "pytest-cov", "pytest-django"] + +[[package]] +name = "django-i18nfield" +version = "1.9.4" +description = "Store internationalized strings in Django models" +optional = false +python-versions = "*" +files = [ + {file = "django-i18nfield-1.9.4.tar.gz", hash = "sha256:f24c209f4fcbf407ec1ebf749b6c182bf4089ef46c3cd0e60fa547955d575d2e"}, + {file = "django_i18nfield-1.9.4-py3-none-any.whl", hash = "sha256:d31bf725b43d6fa0d67a403efb45abf54fc6013ee9135ad55679626df9d0c8ca"}, +] + +[[package]] +name = "django-jquery-js" +version = "3.1.1" +description = "jQuery, bundled up so apps can depend upon it" +optional = false +python-versions = "*" +files = [ + {file = "django-jquery-js-3.1.1.tar.gz", hash = "sha256:308e6472801f89be7c02fa3d06bea6470cfbcab8287db80c64b1093717b8eea9"}, +] + +[package.dependencies] +Django = ">=1.4" + +[[package]] +name = "django-libsass" +version = "0.9" +description = "A django-compressor filter to compile SASS files using libsass" +optional = false +python-versions = "*" +files = [ + {file = "django-libsass-0.9.tar.gz", hash = "sha256:bfbbb55a8950bb40fa04dd416605f92da34ad1f303b10a41abc3232386ec27b5"}, + {file = "django_libsass-0.9-py3-none-any.whl", hash = "sha256:5234d29100889cac79e36a0f44207ec6d275adfd2da1acb6a94b55c89fe2bd97"}, +] + +[package.dependencies] +django-compressor = ">=1.3" +libsass = ">=0.7.0,<1" + +[[package]] +name = "django-localflavor" +version = "4.0" +description = "Country-specific Django helpers" +optional = false +python-versions = "*" +files = [ + {file = "django-localflavor-4.0.tar.gz", hash = "sha256:11859e522dba74aa6dde5a659242b1fbc5efb4dea08e9b77315402bdeca5194e"}, + {file = "django_localflavor-4.0-py3-none-any.whl", hash = "sha256:7a5b1df03ca8e10df9d1b3c2e4314e43383067868183cdf41ab4e7a973694a8b"}, +] + +[package.dependencies] +django = ">=3.2" +python-stdnum = ">=1.6" + +[[package]] +name = "django-markup" +version = "1.8.1" +description = "A generic Django application to convert text with specific markup to html." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-markup-1.8.1.tar.gz", hash = "sha256:04824880a7afbd19e7b3cdaf0005e759f818b2cc4e3b4f1dd97182b7038a72c9"}, + {file = "django_markup-1.8.1-py2.py3-none-any.whl", hash = "sha256:bf0dabcfc288eac76b6e501357b02383ff7012b48e4005cab58e3c68b5474e07"}, + {file = "django_markup-1.8.1-py3-none-any.whl", hash = "sha256:ab0bbdcb721ec92a2848dd93f47e4a0d01760677ca78789230432298cf82a7c8"}, +] + +[package.dependencies] +django = ">=3.2" + +[package.extras] +all-filter-dependencies = ["bleach (>=3.0)", "docutils (>=0.14)", "markdown (>=2.6.9)", "pygments (>=2.10.0)", "pygments (>=2.2.0)", "python-creole (>=1.3.1)", "smartypants (>=2.0.0)", "textile (>=2.3.16)"] + +[[package]] +name = "django-oauth-toolkit" +version = "2.2.0" +description = "OAuth2 Provider for Django" +optional = false +python-versions = "*" +files = [ + {file = "django-oauth-toolkit-2.2.0.tar.gz", hash = "sha256:46890decb24a34e2a5382debeaf7752e50d90b7a11716cf2a9fd067097ec0963"}, + {file = "django_oauth_toolkit-2.2.0-py3-none-any.whl", hash = "sha256:abd85c74af525a62365ec2049113e73a2ff8b46ef906e7104a7ba968ef02a11d"}, +] + +[package.dependencies] +django = ">=2.2,<4.0.0 || >4.0.0" +jwcrypto = ">=0.8.0" +oauthlib = ">=3.1.0" +requests = ">=2.13.0" + +[[package]] +name = "django-otp" +version = "1.2.4" +description = "A pluggable framework for adding two-factor authentication to Django using one-time passwords." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django_otp-1.2.4-py3-none-any.whl", hash = "sha256:5ddd1aaf455db47fac3ce0d8b518e68e9a57db55e30ad68eafad377e4fa741f5"}, + {file = "django_otp-1.2.4.tar.gz", hash = "sha256:7e805cc196cbac93edbbbbf5078d7c5156fec2dba1b2589361ddbf74c4557e39"}, +] + +[package.dependencies] +django = ">=3.2" + +[package.extras] +qrcode = ["qrcode"] + +[[package]] +name = "django-phonenumber-field" +version = "7.1.0" +description = "An international phone number field for django models." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-phonenumber-field-7.1.0.tar.gz", hash = "sha256:63721dbdc7424cd594a08d80f550e790cf6e7c903cbc0fb4dd9d86baac8b8c51"}, + {file = "django_phonenumber_field-7.1.0-py3-none-any.whl", hash = "sha256:4eaab35fe9a163046dc3a47188771385c56a788e0e11b7bbcc662e1e6b7b9104"}, +] + +[package.dependencies] +Django = ">=3.2" + +[package.extras] +phonenumbers = ["phonenumbers (>=7.0.2)"] +phonenumberslite = ["phonenumberslite (>=7.0.2)"] + +[[package]] +name = "django-redis" +version = "5.2.0" +description = "Full featured redis cache backend for Django." +optional = false +python-versions = ">=3.6" +files = [ + {file = "django-redis-5.2.0.tar.gz", hash = "sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de"}, + {file = "django_redis-5.2.0-py3-none-any.whl", hash = "sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026"}, +] + +[package.dependencies] +Django = ">=2.2" +redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1" + +[package.extras] +hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] + +[[package]] +name = "django-scopes" +version = "2.0.0" +description = "Scope querys in multi-tenant django applications" +optional = false +python-versions = "*" +files = [ + {file = "django-scopes-2.0.0.tar.gz", hash = "sha256:d190d9a2462bce812bc6fdd254e47ba031f6fba3279c8ac7397c671df0a4e54f"}, + {file = "django_scopes-2.0.0-py3-none-any.whl", hash = "sha256:9cf521b4d543ffa2ff6369fb5a1dda03567e862ba89626c01405f3d93ca04724"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "django-statici18n" +version = "2.3.1" +description = "A Django app that compiles i18n JavaScript catalogs to static files." +optional = false +python-versions = "*" +files = [ + {file = "django-statici18n-2.3.1.tar.gz", hash = "sha256:00079579035d5b45320830191e2c047f8643b7906307eff9833f0fa95068a603"}, + {file = "django_statici18n-2.3.1-py2.py3-none-any.whl", hash = "sha256:5f4bb3d58670def2df490babe338524927cfb2ebe2e5e20538b98d9424e83d0e"}, +] + +[package.dependencies] +Django = ">=2.2" +django-appconf = ">=1.0" + +[[package]] +name = "djangorestframework" +version = "3.14.0" +description = "Web APIs for Django, made easy." +optional = false +python-versions = ">=3.6" +files = [ + {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"}, + {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"}, +] + +[package.dependencies] +django = ">=3.0" +pytz = "*" + +[[package]] +name = "dnspython" +version = "2.3.0" +description = "DNS toolkit" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "dnspython-2.3.0-py3-none-any.whl", hash = "sha256:89141536394f909066cabd112e3e1a37e4e654db00a25308b0f130bc3152eb46"}, + {file = "dnspython-2.3.0.tar.gz", hash = "sha256:224e32b03eb46be70e12ef6d64e0be123a64e621ab4c0822ff6d450d52a540b9"}, +] + +[package.extras] +curio = ["curio (>=1.2,<2.0)", "sniffio (>=1.1,<2.0)"] +dnssec = ["cryptography (>=2.6,<40.0)"] +doh = ["h2 (>=4.1.0)", "httpx (>=0.21.1)", "requests (>=2.23.0,<3.0.0)", "requests-toolbelt (>=0.9.1,<0.11.0)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1,<4.0)"] +trio = ["trio (>=0.14,<0.23)"] +wmi = ["wmi (>=1.5.1,<2.0.0)"] + +[[package]] +name = "drf-ujson2" +version = "1.7.2" +description = "Django Rest Framework UJSON Renderer" +optional = false +python-versions = ">=3.6" +files = [ + {file = "drf_ujson2-1.7.2-py3-none-any.whl", hash = "sha256:5fead7ee1cccafd08137a845ddb1f153415519519ddfd9de5bcadfacb70ceb0b"}, + {file = "drf_ujson2-1.7.2.tar.gz", hash = "sha256:ae550e861280e7166232ccbfcb4e950059d88f7123abb02019bed48f8e2dbdbb"}, +] + +[package.dependencies] +django = "*" +djangorestframework = "*" +ujson = ">=2.0.1" + +[package.extras] +dev = ["pytest", "pytest-cov", "pytest-django", "pytest-mock", "pytest-runner"] + +[[package]] +name = "elementpath" +version = "4.1.5" +description = "XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml" +optional = false +python-versions = ">=3.7" +files = [ + {file = "elementpath-4.1.5-py3-none-any.whl", hash = "sha256:2ac1a2fb31eb22bbbf817f8cf6752f844513216263f0e3892c8e79782fe4bb55"}, + {file = "elementpath-4.1.5.tar.gz", hash = "sha256:c2d6dc524b29ef751ecfc416b0627668119d8812441c555d7471da41d4bacb8d"}, +] + +[package.extras] +dev = ["Sphinx", "coverage", "flake8", "lxml", "lxml-stubs", "memory-profiler", "memray", "mypy", "tox", "xmlschema (>=2.0.0)"] + +[[package]] +name = "enum34" +version = "1.1.10" +description = "Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4" +optional = false +python-versions = "*" +files = [ + {file = "enum34-1.1.10-py2-none-any.whl", hash = "sha256:a98a201d6de3f2ab3db284e70a33b0f896fbf35f8086594e8c9e74b909058d53"}, + {file = "enum34-1.1.10-py3-none-any.whl", hash = "sha256:c3858660960c984d6ab0ebad691265180da2b43f07e061c0f8dca9ef3cffd328"}, + {file = "enum34-1.1.10.tar.gz", hash = "sha256:cce6a7477ed816bd2542d03d53db9f0db935dd013b70f336a95c73979289f248"}, +] + +[[package]] +name = "et-xmlfile" +version = "1.1.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, + {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, +] + +[[package]] +name = "frozenlist" +version = "1.4.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"}, + {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"}, + {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"}, + {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"}, + {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"}, + {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"}, + {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"}, + {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"}, + {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"}, + {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"}, + {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"}, + {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, +] + +[[package]] +name = "future" +version = "0.18.3" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, +] + +[[package]] +name = "geoip2" +version = "4.8.0" +description = "MaxMind GeoIP2 API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "geoip2-4.8.0-py2.py3-none-any.whl", hash = "sha256:39b38ec703575355d10475c0e6aa981827a2b4b5471d308c4ecb5e79cbe366ce"}, + {file = "geoip2-4.8.0.tar.gz", hash = "sha256:dd9cc180b7d41724240ea481d5d539149e65b234f64282b231b9170794a9ac35"}, +] + +[package.dependencies] +aiohttp = ">=3.6.2,<4.0.0" +maxminddb = ">=2.5.1,<3.0.0" +requests = ">=2.24.0,<3.0.0" +setuptools = ">=60.0.0" + +[package.extras] +test = ["mocket (>=3.11.1)"] + +[[package]] +name = "idna" +version = "3.6" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "importlib-metadata" +version = "6.11.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.11.0-py3-none-any.whl", hash = "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b"}, + {file = "importlib_metadata-6.11.0.tar.gz", hash = "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "isoweek" +version = "1.3.3" +description = "Objects representing a week" +optional = false +python-versions = "*" +files = [ + {file = "isoweek-1.3.3-py2.py3-none-any.whl", hash = "sha256:d3324c497d97f1534669de225ec877964222e4cc773a4a99063086f7a4e342b6"}, + {file = "isoweek-1.3.3.tar.gz", hash = "sha256:73f3f7bac443e05a3ab45c32a72048b0c4f26d53d81462ec4b142c7581d3ffe8"}, +] + +[[package]] +name = "jsonschema" +version = "4.20.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.20.0-py3-none-any.whl", hash = "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3"}, + {file = "jsonschema-4.20.0.tar.gz", hash = "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.11.2" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.11.2-py3-none-any.whl", hash = "sha256:e74ba7c0a65e8cb49dc26837d6cfe576557084a8b423ed16a420984228104f93"}, + {file = "jsonschema_specifications-2023.11.2.tar.gz", hash = "sha256:9472fc4fea474cd74bea4a2b190daeccb5a9e4db2ea80efcf7a1b582fc9a81b8"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "jwcrypto" +version = "1.5.0" +description = "Implementation of JOSE Web standards" +optional = false +python-versions = ">= 3.6" +files = [ + {file = "jwcrypto-1.5.0.tar.gz", hash = "sha256:2c1dc51cf8e38ddf324795dfe9426dee9dd46caf47f535ccbc18781fba810b8d"}, +] + +[package.dependencies] +cryptography = ">=3.4" +deprecated = "*" + +[[package]] +name = "kombu" +version = "5.3.4" +description = "Messaging library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "kombu-5.3.4-py3-none-any.whl", hash = "sha256:63bb093fc9bb80cfb3a0972336a5cec1fa7ac5f9ef7e8237c6bf8dda9469313e"}, + {file = "kombu-5.3.4.tar.gz", hash = "sha256:0bb2e278644d11dea6272c17974a3dbb9688a949f3bb60aeb5b791329c44fadc"}, +] + +[package.dependencies] +amqp = ">=5.1.1,<6.0.0" +vine = "*" + +[package.extras] +azureservicebus = ["azure-servicebus (>=7.10.0)"] +azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] +confluentkafka = ["confluent-kafka (>=2.2.0)"] +consul = ["python-consul2"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +mongodb = ["pymongo (>=4.1.1)"] +msgpack = ["msgpack"] +pyro = ["pyro4"] +qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] +redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=2.8.0)"] + +[[package]] +name = "libsass" +version = "0.22.0" +description = "Sass for Python: A straightforward binding of libsass for Python." +optional = false +python-versions = ">=3.6" +files = [ + {file = "libsass-0.22.0-cp36-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f1efc1b612299c88aec9e39d6ca0c266d360daa5b19d9430bdeaffffa86993f9"}, + {file = "libsass-0.22.0-cp37-abi3-macosx_10_15_x86_64.whl", hash = "sha256:081e256ab3c5f3f09c7b8dea3bf3bf5e64a97c6995fd9eea880639b3f93a9f9a"}, + {file = "libsass-0.22.0-cp37-abi3-win32.whl", hash = "sha256:89c5ce497fcf3aba1dd1b19aae93b99f68257e5f2026b731b00a872f13324c7f"}, + {file = "libsass-0.22.0-cp37-abi3-win_amd64.whl", hash = "sha256:65455a2728b696b62100eb5932604aa13a29f4ac9a305d95773c14aaa7200aaf"}, + {file = "libsass-0.22.0.tar.gz", hash = "sha256:3ab5ad18e47db560f4f0c09e3d28cf3bb1a44711257488ac2adad69f4f7f8425"}, +] + +[[package]] +name = "lxml" +version = "4.9.3" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, + {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, + {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, + {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, + {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, + {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, + {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, + {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, + {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, + {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, + {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, + {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, + {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, + {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, + {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, + {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, + {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, + {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, + {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, + {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, + {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, + {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, + {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=0.29.35)"] + +[[package]] +name = "markdown" +version = "3.4.3" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Markdown-3.4.3-py3-none-any.whl", hash = "sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2"}, + {file = "Markdown-3.4.3.tar.gz", hash = "sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520"}, +] + +[package.extras] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "maxminddb" +version = "2.5.1" +description = "Reader for the MaxMind DB format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "maxminddb-2.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:62e93a8e99937bf4307eeece3ca37e1161325ebf9363c4ce195410fb5daf64a0"}, + {file = "maxminddb-2.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea2e27a507b53dfbf2ba2ba85c98682a1ad2dac3f9941a7bffa5cb86150d0c47"}, + {file = "maxminddb-2.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a01b0341bd6bee431bb8c07c7ac0ed221250c7390b125c025b7d57578e78e8a3"}, + {file = "maxminddb-2.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:607344b1079ea647629bf962dcea7580ec864faaad3f5aae650e2e8652121d89"}, + {file = "maxminddb-2.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c2901daebd7c8a702302315e7a58cdc38e626406ad4a05b4d48634897d5f5a3"}, + {file = "maxminddb-2.5.1-cp310-cp310-win32.whl", hash = "sha256:7805ae8c9de433c38939ada2e376706a9f6740239f61fd445927b88f5b42c267"}, + {file = "maxminddb-2.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:f1e5bd58b71f322dc6c16a95a129433b1bc229d4b714f870a61c2367425396ee"}, + {file = "maxminddb-2.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0bbbd58b300aaddf985f763720bdebba9f7a73168ff9f57168117f630ad1c06"}, + {file = "maxminddb-2.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a6751e2e89d62d53217870bcc2a8c887dc56ae370ba1b74e52e880761916e54"}, + {file = "maxminddb-2.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ecb1be961f1969be047d07743093f0dcf2f6d4ec3a06a4555587f380a96f6e7"}, + {file = "maxminddb-2.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1e091c2b44673c218ee2df23adbc0b6d04fd5c646cfcb6c6fe26fb849434812a"}, + {file = "maxminddb-2.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09b295c401c104ae0e30f66c1a3f3c2aa4ba2cbe12a787576499356a5a4d6c1"}, + {file = "maxminddb-2.5.1-cp311-cp311-win32.whl", hash = "sha256:3d52c693baf07bba897d109b0ecb067f21fd0cc0fb266d67db456e85b80d699e"}, + {file = "maxminddb-2.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:4c67621e842c415ce336ab019a9f087305dfcf24c095b68b8e9d27848f6f6d91"}, + {file = "maxminddb-2.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17ea454f61631b9815d420d48d00663f8718fc7de30be53ffcec0f73989475eb"}, + {file = "maxminddb-2.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef4d508c899ce0f37de731340759c68bfd1102a39a873675c71fae2c8d71ad97"}, + {file = "maxminddb-2.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e5ca423b1e310f0327536f5ed1a2c6e08d83289a7f909e021590b0b477cae2"}, + {file = "maxminddb-2.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0a21abd85e10e5e0f60244b49c3db17e7e48befd4972e62a62833d91e2acbb49"}, + {file = "maxminddb-2.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:85a302d79577efe5bc308647394ffdc535dd5f062644c41103604ccf24931a05"}, + {file = "maxminddb-2.5.1-cp312-cp312-win32.whl", hash = "sha256:dd28c434fb44f825dde6a75df2c338d44645791b03480af66a4d993f93801e10"}, + {file = "maxminddb-2.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:b477852cf1741d9187b021e23723e64b063794bbf946a9b5b84cc222f3caf58a"}, + {file = "maxminddb-2.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a1e1a19f9740f586362f47862d0095b54d50b9d465babcaa8a563746132fe5be"}, + {file = "maxminddb-2.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d654895b546a47e85f2e071b98e377a60bb03cd643b9423017fa66fcd5adedce"}, + {file = "maxminddb-2.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0702da59b9670a72761b65cb1a52bc3032d8f6799bdab641cb8350ad5740580b"}, + {file = "maxminddb-2.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2e20a70c1545d6626dcd4ce2d7ecf3d566d978ea64cb37e7952f93baff66b812"}, + {file = "maxminddb-2.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0cbd272db3202e948c9088e48dec62add071a47971d84ceb11d2cb2880f83e5a"}, + {file = "maxminddb-2.5.1-cp38-cp38-win32.whl", hash = "sha256:fbd01fc7d7b5b2befe914e8cdb5ed3a1c5476e57b765197cceff8d897f33d012"}, + {file = "maxminddb-2.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:fe0af3ba9e1a78ed5f2ad32fc18d18b78ef233e7d0c627e1a77a525a7eb0c241"}, + {file = "maxminddb-2.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d772be68cce812f7c4b15ae8c68e624c8b88ff83071e3903ca5b5f55e343c25"}, + {file = "maxminddb-2.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e7b3ad87d5352ed3f496bd42bffbf9f896245278b0d8e76afa1382e42a7ae"}, + {file = "maxminddb-2.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:892c11a8694394e97d3ac0f8d5974ea588c732d14e721f22095c58b4f584c144"}, + {file = "maxminddb-2.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3ce1f42bdfce7b86cb5a56cba730fed611fb879d867e6024f0d520257bef6891"}, + {file = "maxminddb-2.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6667948e7501a513caef90edda2d367865097239d4c2381eb3998e9905af7209"}, + {file = "maxminddb-2.5.1-cp39-cp39-win32.whl", hash = "sha256:500d321bdefe4dcd351e4390a79b7786aab49b0536bedfa0788e5ffb0e91e421"}, + {file = "maxminddb-2.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:93f7055779caf7753810f1e2c6444af6d727393fd116ffa0767fbd54fb8c9bbf"}, + {file = "maxminddb-2.5.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8cee4315da7cdd3f2a18f1ab1418953a7a9eda65e63095b01f03c7d3645d633e"}, + {file = "maxminddb-2.5.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97eac5af102cede4b5f57cecb25e8f949fa4e4a8d812bed575539951c60ecaf"}, + {file = "maxminddb-2.5.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:526744b12075051fa20979090c111cc3a42a3b55e2714818270c7b84a41a8cfe"}, + {file = "maxminddb-2.5.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:fad45cd2f2e3c5fbebacb8d172a60fb22443222e549bf740a0bc7eeb849e5ce7"}, + {file = "maxminddb-2.5.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8b98ed5c34955c48e72d35daed713ba4a6833a8a6d1204e79d2c85e644049792"}, + {file = "maxminddb-2.5.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:639aee8abd63a95baa12b94b6f3a842d51877d631879c7d08c98c68dc44a84c3"}, + {file = "maxminddb-2.5.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a7a73ab4bbc16b81983531c99fa102a0c7dae459db958c17fea48c981f5e764"}, + {file = "maxminddb-2.5.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:aae262da1940a67c3ba765c49e2308947ce68ff647f87630002c306433a98ca1"}, + {file = "maxminddb-2.5.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b223c53077a736c304b63cf5afceb928975fbd12ddae5afd6b71370bab7b4700"}, + {file = "maxminddb-2.5.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:969d0057ea5472e0b574c5293c4f3ecf49585362351c543e8ea55dc48b60f1eb"}, + {file = "maxminddb-2.5.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4d36cf3d390f02d2bdf53d9efefb92be7bd70e07a5a86cdb79020c48c2d81b7"}, + {file = "maxminddb-2.5.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:188173c07dce0692fd5660a6eb7ea8c126d7b3a4b61496c8a8ee9e8b10186ff5"}, + {file = "maxminddb-2.5.1.tar.gz", hash = "sha256:4807d374e645bd68334e4f487ba85a27189dbc1267a98e644aa686a7927e0559"}, +] + +[package.dependencies] +setuptools = ">=68.2.2" + +[[package]] +name = "mt-940" +version = "4.30.0" +description = "A library to parse MT940 files and returns smart Python collections for statistics and manipulation." +optional = false +python-versions = "*" +files = [ + {file = "mt-940-4.30.0.tar.gz", hash = "sha256:da14e2ec84d6c6e85604d2a6b8a800b08ec6000351acde501c41eb662819295c"}, + {file = "mt_940-4.30.0-py2.py3-none-any.whl", hash = "sha256:66fa0c1e942478fd7970b791be017b1ca46556f54d44115008f3982e97ae0a9b"}, +] + +[package.extras] +docs = ["GitPython (>=2.1.9)", "sphinx (>=1.7.2)", "sphinx2rst"] +tests = ["flake8", "pytest", "pytest-cache", "pytest-cover", "pytest-flake8", "pyyaml"] + +[[package]] +name = "multidict" +version = "6.0.4" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, + {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, + {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, + {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, + {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, + {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, + {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, + {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, + {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, + {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, + {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, + {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, + {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, +] + +[[package]] +name = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + +[[package]] +name = "openpyxl" +version = "3.1.2" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.6" +files = [ + {file = "openpyxl-3.1.2-py2.py3-none-any.whl", hash = "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"}, + {file = "openpyxl-3.1.2.tar.gz", hash = "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "paypal-checkout-serversdk" +version = "1.0.3" +description = "Deprecated" +optional = false +python-versions = "*" +files = [ + {file = "paypal-checkout-serversdk-1.0.3.tar.gz", hash = "sha256:880c7fab12955d65aff29baeb90c182307307d2676edbd41072f3f540a2934b4"}, + {file = "paypal_checkout_serversdk-1.0.3-py3-none-any.whl", hash = "sha256:48a00ec6c52450583e2265dbbdf700b025f38f40ddc597b24b6aa4d8f0cb0257"}, +] + +[package.dependencies] +paypalhttp = "*" + +[[package]] +name = "paypalhttp" +version = "1.0.1" +description = "" +optional = false +python-versions = "*" +files = [ + {file = "paypalhttp-1.0.1-py3-none-any.whl", hash = "sha256:251a6e72e2c5140c5372ee6351b64f7af61b5aad9c554618db5782a06205989a"}, + {file = "paypalhttp-1.0.1.tar.gz", hash = "sha256:20e00f95ea052f59145b65bc2baf3b8720f449460c96bf7d32f191c8e293d16d"}, +] + +[package.dependencies] +pyopenssl = ">=0.15" +requests = ">=2.0.0" +six = ">=1.0.0" + +[[package]] +name = "paypalrestsdk" +version = "1.13.3" +description = "Deprecated" +optional = false +python-versions = "*" +files = [ + {file = "paypalrestsdk-1.13.3-py3-none-any.whl", hash = "sha256:a3f51616ee8f6d975a5a5a8c2049db63653c843479c8fdd71c9d588a31e14560"}, + {file = "paypalrestsdk-1.13.3.tar.gz", hash = "sha256:dac236492a9ac1260a760014a2e56ab38b09d8143295b5e896545359b61fedd6"}, +] + +[package.dependencies] +pyopenssl = ">=0.15" +requests = ">=1.0.0" +six = ">=1.0.0" + +[[package]] +name = "phonenumberslite" +version = "8.13.26" +description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers." +optional = false +python-versions = "*" +files = [ + {file = "phonenumberslite-8.13.26-py2.py3-none-any.whl", hash = "sha256:305736b1b489e2bc6831710a2f34a9324f2bf96a1e77c8e0b3136dfaf9ca7753"}, + {file = "phonenumberslite-8.13.26.tar.gz", hash = "sha256:6356f2728fa1d2c2bc9e79c3bfcfedc91a36537df7a134f150731a821a469a96"}, +] + +[[package]] +name = "pillow" +version = "9.5.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, + {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, + {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, + {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, + {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, + {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, + {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, + {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, + {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, + {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, + {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, + {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, + {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, + {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, + {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, + {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, + {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, + {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, + {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, + {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, + {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, + {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, + {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, + {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, + {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, + {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, + {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, + {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, + {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, + {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, + {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "platformdirs" +version = "4.1.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +optional = false +python-versions = "*" +files = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] + +[[package]] +name = "pretix" +version = "2023.10.0" +description = "Reinventing presales, one ticket at a time" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pretix-2023.10.0-py3-none-any.whl", hash = "sha256:74dd9742b102db8d71262590d4a75e9fce69861fd25f874cec0c2b8c106478c6"}, + {file = "pretix-2023.10.0.tar.gz", hash = "sha256:d0fe505e2e82841db2b69ebdb80d4d7e165260e232eb8e27c787e499edbd6a9f"}, +] + +[package.dependencies] +arabic-reshaper = "3.0.0" +babel = "*" +BeautifulSoup4 = "==4.12.*" +bleach = "==5.0.*" +celery = "==5.3.*" +chardet = "==5.1.*" +cryptography = ">=3.4.2" +css-inline = "==0.8.*" +defusedcsv = ">=1.1.0" +dj-static = "*" +Django = "==4.2.*" +django-bootstrap3 = "==23.1.*" +django-compressor = "==4.3.*" +django-countries = "==7.5.*" +django-filter = "23.2" +django-formset-js-improved = "0.5.0.3" +django-formtools = "2.4.1" +django-hierarkey = "==1.1.*" +django-hijack = "==3.3.*" +django-i18nfield = ">=1.9.4,<1.10.dev0" +django-libsass = "0.9" +django-localflavor = "4.0" +django-markup = "*" +django-oauth-toolkit = "==2.2.*" +django-otp = "==1.2.*" +django-phonenumber-field = "==7.1.*" +django-redis = "==5.2.*" +django-scopes = "==2.0.*" +django-statici18n = "==2.3.*" +djangorestframework = "==3.14.*" +dnspython = "==2.3.*" +drf-ujson2 = "==1.7.*" +geoip2 = "==4.*" +importlib-metadata = "==6.*" +isoweek = "*" +jsonschema = "*" +kombu = "==5.3.*" +libsass = "==0.22.*" +lxml = "*" +markdown = "3.4.3" +mt-940 = "==4.30.*" +oauthlib = "==3.2.*" +openpyxl = "==3.1.*" +packaging = "*" +paypal-checkout-serversdk = "==1.0.*" +paypalrestsdk = "==1.13.*" +phonenumberslite = "==8.13.*" +Pillow = "==9.5.*" +pretix-plugin-build = "*" +protobuf = "==4.23.*" +psycopg2-binary = "*" +pycountry = "*" +pycparser = "2.21" +pycryptodome = "==3.18.*" +PyJWT = "==2.7.*" +pypdf = "==3.9.*" +python-bidi = "==0.4.*" +python-dateutil = "==2.8.*" +python-u2flib-server = "==4.*" +pytz = "*" +pytz-deprecation-shim = "==0.1.*" +pyuca = "*" +qrcode = "==7.4.*" +redis = "==4.6.*" +reportlab = "==4.0.*" +requests = "==2.31.*" +sentry-sdk = "==1.15.*" +sepaxml = "==2.6.*" +slimit = "*" +static3 = "==0.7.*" +stripe = "==5.4.*" +text-unidecode = "==1.*" +tlds = ">=2020041600" +tqdm = "==4.*" +vat-moss-forked = "2020.3.20.0.11.0" +vobject = "==0.9.*" +webauthn = "==0.4.*" +zeep = "==4.2.*" + +[package.extras] +dev = ["aiohttp (==3.8.*)", "coverage", "coveralls", "fakeredis (==2.18.*)", "flake8 (==6.0.*)", "freezegun", "isort (==5.12.*)", "pep8-naming (==0.13.*)", "potypo", "pycodestyle (==2.10.*)", "pyflakes (==3.0.*)", "pytest (==7.3.*)", "pytest-asyncio", "pytest-cache", "pytest-cov", "pytest-django (==4.*)", "pytest-mock (==3.10.*)", "pytest-rerunfailures (==11.*)", "pytest-sugar", "pytest-xdist (==3.3.*)", "responses"] +memcached = ["pylibmc"] + +[[package]] +name = "pretix-plugin-build" +version = "1.0.1" +description = "Build toolchain for pretix plugins" +optional = false +python-versions = "*" +files = [ + {file = "pretix-plugin-build-1.0.1.tar.gz", hash = "sha256:88b6ea70201b78ae0fc8b5e279ba5d136eebb7a6ce3fb797733206d9b76fbd8a"}, + {file = "pretix_plugin_build-1.0.1-py3-none-any.whl", hash = "sha256:9a7be6b373471a274069f021148f918ab2b91bf5addca0e871f63c0451c57fc4"}, +] + +[package.dependencies] +django = "*" + +[[package]] +name = "prompt-toolkit" +version = "3.0.41" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.41-py3-none-any.whl", hash = "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2"}, + {file = "prompt_toolkit-3.0.41.tar.gz", hash = "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "protobuf" +version = "4.23.4" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "protobuf-4.23.4-cp310-abi3-win32.whl", hash = "sha256:5fea3c64d41ea5ecf5697b83e41d09b9589e6f20b677ab3c48e5f242d9b7897b"}, + {file = "protobuf-4.23.4-cp310-abi3-win_amd64.whl", hash = "sha256:7b19b6266d92ca6a2a87effa88ecc4af73ebc5cfde194dc737cf8ef23a9a3b12"}, + {file = "protobuf-4.23.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8547bf44fe8cec3c69e3042f5c4fb3e36eb2a7a013bb0a44c018fc1e427aafbd"}, + {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fee88269a090ada09ca63551bf2f573eb2424035bcf2cb1b121895b01a46594a"}, + {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:effeac51ab79332d44fba74660d40ae79985901ac21bca408f8dc335a81aa597"}, + {file = "protobuf-4.23.4-cp37-cp37m-win32.whl", hash = "sha256:c3e0939433c40796ca4cfc0fac08af50b00eb66a40bbbc5dee711998fb0bbc1e"}, + {file = "protobuf-4.23.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9053df6df8e5a76c84339ee4a9f5a2661ceee4a0dab019e8663c50ba324208b0"}, + {file = "protobuf-4.23.4-cp38-cp38-win32.whl", hash = "sha256:e1c915778d8ced71e26fcf43c0866d7499891bca14c4368448a82edc61fdbc70"}, + {file = "protobuf-4.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:351cc90f7d10839c480aeb9b870a211e322bf05f6ab3f55fcb2f51331f80a7d2"}, + {file = "protobuf-4.23.4-cp39-cp39-win32.whl", hash = "sha256:6dd9b9940e3f17077e820b75851126615ee38643c2c5332aa7a359988820c720"}, + {file = "protobuf-4.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:0a5759f5696895de8cc913f084e27fd4125e8fb0914bb729a17816a33819f474"}, + {file = "protobuf-4.23.4-py3-none-any.whl", hash = "sha256:e9d0be5bf34b275b9f87ba7407796556abeeba635455d036c7351f7c183ef8ff"}, + {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, +] + +[[package]] +name = "psycopg2-binary" +version = "2.9.9" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957"}, +] + +[[package]] +name = "pycountry" +version = "22.3.5" +description = "ISO country, subdivision, language, currency and script definitions and their translations" +optional = false +python-versions = ">=3.6, <4" +files = [ + {file = "pycountry-22.3.5.tar.gz", hash = "sha256:b2163a246c585894d808f18783e19137cb70a0c18fb36748dc01fc6f109c1646"}, +] + +[package.dependencies] +setuptools = "*" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[[package]] +name = "pycryptodome" +version = "3.18.0" +description = "Cryptographic library for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodome-3.18.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:d1497a8cd4728db0e0da3c304856cb37c0c4e3d0b36fcbabcc1600f18504fc54"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:928078c530da78ff08e10eb6cada6e0dff386bf3d9fa9871b4bbc9fbc1efe024"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:157c9b5ba5e21b375f052ca78152dd309a09ed04703fd3721dce3ff8ecced148"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:d20082bdac9218649f6abe0b885927be25a917e29ae0502eaf2b53f1233ce0c2"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:e8ad74044e5f5d2456c11ed4cfd3e34b8d4898c0cb201c4038fe41458a82ea27"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-win32.whl", hash = "sha256:62a1e8847fabb5213ccde38915563140a5b338f0d0a0d363f996b51e4a6165cf"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-win_amd64.whl", hash = "sha256:16bfd98dbe472c263ed2821284118d899c76968db1a6665ade0c46805e6b29a4"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:7a3d22c8ee63de22336679e021c7f2386f7fc465477d59675caa0e5706387944"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:78d863476e6bad2a592645072cc489bb90320972115d8995bcfbee2f8b209918"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:b6a610f8bfe67eab980d6236fdc73bfcdae23c9ed5548192bb2d530e8a92780e"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:422c89fd8df8a3bee09fb8d52aaa1e996120eafa565437392b781abec2a56e14"}, + {file = "pycryptodome-3.18.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:9ad6f09f670c466aac94a40798e0e8d1ef2aa04589c29faa5b9b97566611d1d1"}, + {file = "pycryptodome-3.18.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:53aee6be8b9b6da25ccd9028caf17dcdce3604f2c7862f5167777b707fbfb6cb"}, + {file = "pycryptodome-3.18.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:10da29526a2a927c7d64b8f34592f461d92ae55fc97981aab5bbcde8cb465bb6"}, + {file = "pycryptodome-3.18.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f21efb8438971aa16924790e1c3dba3a33164eb4000106a55baaed522c261acf"}, + {file = "pycryptodome-3.18.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4944defabe2ace4803f99543445c27dd1edbe86d7d4edb87b256476a91e9ffa4"}, + {file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:51eae079ddb9c5f10376b4131be9589a6554f6fd84f7f655180937f611cd99a2"}, + {file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:83c75952dcf4a4cebaa850fa257d7a860644c70a7cd54262c237c9f2be26f76e"}, + {file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:957b221d062d5752716923d14e0926f47670e95fead9d240fa4d4862214b9b2f"}, + {file = "pycryptodome-3.18.0-cp35-abi3-win32.whl", hash = "sha256:795bd1e4258a2c689c0b1f13ce9684fa0dd4c0e08680dcf597cf9516ed6bc0f3"}, + {file = "pycryptodome-3.18.0-cp35-abi3-win_amd64.whl", hash = "sha256:b1d9701d10303eec8d0bd33fa54d44e67b8be74ab449052a8372f12a66f93fb9"}, + {file = "pycryptodome-3.18.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:cb1be4d5af7f355e7d41d36d8eec156ef1382a88638e8032215c215b82a4b8ec"}, + {file = "pycryptodome-3.18.0-pp27-pypy_73-win32.whl", hash = "sha256:fc0a73f4db1e31d4a6d71b672a48f3af458f548059aa05e83022d5f61aac9c08"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f022a4fd2a5263a5c483a2bb165f9cb27f2be06f2f477113783efe3fe2ad887b"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:363dd6f21f848301c2dcdeb3c8ae5f0dee2286a5e952a0f04954b82076f23825"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12600268763e6fec3cefe4c2dcdf79bde08d0b6dc1813887e789e495cb9f3403"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4604816adebd4faf8810782f137f8426bf45fee97d8427fa8e1e49ea78a52e2c"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:01489bbdf709d993f3058e2996f8f40fee3f0ea4d995002e5968965fa2fe89fb"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3811e31e1ac3069988f7a1c9ee7331b942e605dfc0f27330a9ea5997e965efb2"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4b967bb11baea9128ec88c3d02f55a3e338361f5e4934f5240afcb667fdaec"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9c8eda4f260072f7dbe42f473906c659dcbadd5ae6159dfb49af4da1293ae380"}, + {file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"}, +] + +[[package]] +name = "pyjwt" +version = "2.7.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyJWT-2.7.0-py3-none-any.whl", hash = "sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1"}, + {file = "PyJWT-2.7.0.tar.gz", hash = "sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pyopenssl" +version = "23.3.0" +description = "Python wrapper module around the OpenSSL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyOpenSSL-23.3.0-py3-none-any.whl", hash = "sha256:6756834481d9ed5470f4a9393455154bc92fe7a64b7bc6ee2c804e78c52099b2"}, + {file = "pyOpenSSL-23.3.0.tar.gz", hash = "sha256:6b2cba5cc46e822750ec3e5a81ee12819850b11303630d575e98108a079c2b12"}, +] + +[package.dependencies] +cryptography = ">=41.0.5,<42" + +[package.extras] +docs = ["sphinx (!=5.2.0,!=5.2.0.post0,!=7.2.5)", "sphinx-rtd-theme"] +test = ["flaky", "pretend", "pytest (>=3.0.1)"] + +[[package]] +name = "pypdf" +version = "3.9.1" +description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pypdf-3.9.1-py3-none-any.whl", hash = "sha256:5f4abdb4691a8d7631e7f2db09f66cfe3a388a072882d8375c6b1bdc28027c0a"}, + {file = "pypdf-3.9.1.tar.gz", hash = "sha256:c2b7fcfe25fbd04e8da600cb2700267ecee7e8781dc798cce3a4f567143a4df1"}, +] + +[package.extras] +crypto = ["PyCryptodome"] +dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "wheel"] +docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"] +full = ["Pillow", "PyCryptodome"] +image = ["Pillow"] + +[[package]] +name = "pypng" +version = "0.20220715.0" +description = "Pure Python library for saving and loading PNG images" +optional = false +python-versions = "*" +files = [ + {file = "pypng-0.20220715.0-py3-none-any.whl", hash = "sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c"}, + {file = "pypng-0.20220715.0.tar.gz", hash = "sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1"}, +] + +[[package]] +name = "python-bidi" +version = "0.4.2" +description = "Pure python implementation of the BiDi layout algorithm" +optional = false +python-versions = "*" +files = [ + {file = "python-bidi-0.4.2.tar.gz", hash = "sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e"}, + {file = "python_bidi-0.4.2-py2.py3-none-any.whl", hash = "sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-stdnum" +version = "1.19" +description = "Python module to handle standardized numbers and codes" +optional = false +python-versions = "*" +files = [ + {file = "python-stdnum-1.19.tar.gz", hash = "sha256:133ec82f56390ea74c190569e98f2fb14b869808b1d54785708f22d0fead8b3f"}, + {file = "python_stdnum-1.19-py2.py3-none-any.whl", hash = "sha256:1b5b401ad3f45b798b0317313b781a433f5d7a5ff2c9feb8054664f76f78644e"}, +] + +[package.extras] +soap = ["zeep"] +soap-alt = ["suds"] +soap-fallback = ["PySimpleSOAP"] + +[[package]] +name = "python-u2flib-server" +version = "4.0.1" +description = "Python based U2F server library" +optional = false +python-versions = "*" +files = [ + {file = "python-u2flib-server-4.0.1.tar.gz", hash = "sha256:160425fe00407b06ce261a7d3c455a6a529ed73f71cfea1b436b573e1dff000b"}, +] + +[package.dependencies] +cryptography = ">=1.2" +enum34 = "*" + +[package.extras] +u2f-server = ["WebOb", "argparse"] +yubiauth-server = ["WebOb", "yubiauth"] + +[[package]] +name = "pytz" +version = "2023.3.post1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, + {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, +] + +[[package]] +name = "pytz-deprecation-shim" +version = "0.1.0.post0" +description = "Shims to make deprecation of pytz easier" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, + {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"}, +] + +[package.dependencies] +tzdata = {version = "*", markers = "python_version >= \"3.6\""} + +[[package]] +name = "pyuca" +version = "1.2" +description = "a Python implementation of the Unicode Collation Algorithm" +optional = false +python-versions = "*" +files = [ + {file = "pyuca-1.2-py2.py3-none-any.whl", hash = "sha256:abaa12e1bd2c7c68ca8396ff8383bc0654a739cef3ae68fd7af58bf29af0a91e"}, + {file = "pyuca-1.2.tar.gz", hash = "sha256:8a382fe74627f08c0d18908c0713ca4a20aad5385f077579e56208beea2893b2"}, +] + +[[package]] +name = "qrcode" +version = "7.4.2" +description = "QR Code image generator" +optional = false +python-versions = ">=3.7" +files = [ + {file = "qrcode-7.4.2-py3-none-any.whl", hash = "sha256:581dca7a029bcb2deef5d01068e39093e80ef00b4a61098a2182eac59d01643a"}, + {file = "qrcode-7.4.2.tar.gz", hash = "sha256:9dd969454827e127dbd93696b20747239e6d540e082937c90f14ac95b30f5845"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +pypng = "*" +typing-extensions = "*" + +[package.extras] +all = ["pillow (>=9.1.0)", "pytest", "pytest-cov", "tox", "zest.releaser[recommended]"] +dev = ["pytest", "pytest-cov", "tox"] +maintainer = ["zest.releaser[recommended]"] +pil = ["pillow (>=9.1.0)"] +test = ["coverage", "pytest"] + +[[package]] +name = "rcssmin" +version = "1.1.1" +description = "CSS Minifier" +optional = false +python-versions = "*" +files = [ + {file = "rcssmin-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:d4e263fa9428704fd94c2cb565c7519ca1d225217943f71caffe6741ab5b9df1"}, + {file = "rcssmin-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c7278c1c25bb90d8e554df92cfb3b6a1195004ead50f764653d3093933ee0877"}, + {file = "rcssmin-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f15673e97f0a68b4c378c4d15b088fe96d60bc106d278c88829923118833c20f"}, + {file = "rcssmin-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d0afc6e7b64ef30d6dcde88830ec1a237b9f16a39f920a8fd159928684ccf8db"}, + {file = "rcssmin-1.1.1-cp310-cp310-manylinux1_i686.whl", hash = "sha256:705c9112d0ed54ea40aecf97e7fd29bdf0f1c46d278a32d8f957f31dde90778a"}, + {file = "rcssmin-1.1.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:f7a1fcdbafaacac0530da04edca4a44303baab430ea42e7d59aece4b3f3e9a51"}, + {file = "rcssmin-1.1.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:cf74d7ea5e191f0f344b354eed8b7c83eeafbd9a97bec3a579c3d26edf11b005"}, + {file = "rcssmin-1.1.1-cp311-cp311-manylinux1_i686.whl", hash = "sha256:908fe072efd2432fb0975a61124609a8e05021367f6a3463d45f5e3e74c4fdda"}, + {file = "rcssmin-1.1.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:35da6a6999e9e2c5b0e691b42ed56cc479373e0ecab33ef5277dfecce625e44a"}, + {file = "rcssmin-1.1.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:e923c105100ab70abde1c01d3196ddd6b07255e32073685542be4e3a60870c8e"}, + {file = "rcssmin-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:868215e1fd0e92a6122e0ed5973dfc7bb8330fe1e92274d05b2585253b38c0ca"}, + {file = "rcssmin-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c7728e3b546b1b6ea08cab721e8e21409dbcc11b881d0b87d10b0be8930af2a2"}, + {file = "rcssmin-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:271e3d2f8614a6d4637ed8fff3d90007f03e2a654cd9444f37d888797662ba72"}, + {file = "rcssmin-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:42576d95dfad53d77df2e68dfdec95b89b10fad320f241f1af3ca1438578254a"}, + {file = "rcssmin-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:79421230dd67c37ec61ed9892813d2b839b68f2f48ef55c75f976e81701d60b4"}, + {file = "rcssmin-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:8fcfd10ae2a1c4ce231a33013f2539e07c3836bf17cc945cc25cc30bf8e68e45"}, + {file = "rcssmin-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c30f8bc839747b6da59274e0c6e4361915d66532e26448d589cb2b1846d7bf11"}, + {file = "rcssmin-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ee386bec6d62f8c814d65c011d604a7c82d24aa3f718facd66e850eea8d6a5a1"}, + {file = "rcssmin-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8a26fec3c1e6b7a3765ccbaccc20fbb5c0ed3422cc381e01a2607f08d7621c44"}, + {file = "rcssmin-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a04d58a2a21e9a089306d3f99c4b12bf5b656a79c198ef2321e80f8fd9afab06"}, + {file = "rcssmin-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:914e589f40573035006913861ed2adc28fbe70082a8b6bff5be7ee430b7b5c2e"}, + {file = "rcssmin-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a417735d4023d47d048a6288c88dbceadd20abaaf65a11bb4fda1e8458057019"}, + {file = "rcssmin-1.1.1.tar.gz", hash = "sha256:4f9400b4366d29f5f5446f58e78549afa8338e6a59740c73115e9f6ac413dc64"}, +] + +[[package]] +name = "redis" +version = "4.6.0" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.7" +files = [ + {file = "redis-4.6.0-py3-none-any.whl", hash = "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c"}, + {file = "redis-4.6.0.tar.gz", hash = "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} + +[package.extras] +hiredis = ["hiredis (>=1.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] + +[[package]] +name = "referencing" +version = "0.32.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.32.0-py3-none-any.whl", hash = "sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99"}, + {file = "referencing-0.32.0.tar.gz", hash = "sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "reportlab" +version = "4.0.7" +description = "The Reportlab Toolkit" +optional = false +python-versions = ">=3.7,<4" +files = [ + {file = "reportlab-4.0.7-py3-none-any.whl", hash = "sha256:956d5874ee56e88753cf4c49452d6a7fa54a64e049a0382bd0c0b2013a26ef9a"}, + {file = "reportlab-4.0.7.tar.gz", hash = "sha256:967c77f00efd918cc231cf8b6d8f4e477dc973b5c16557e3bd18dfaeb5a70234"}, +] + +[package.dependencies] +pillow = ">=9.0.0" + +[package.extras] +accel = ["rl-accel (>=0.9.0,<1.1)"] +pycairo = ["freetype-py (>=2.3.0,<2.4)", "rlPyCairo (>=0.2.0,<1)"] +renderpm = ["rl-renderPM (>=4.0.3,<4.1)"] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-file" +version = "1.5.1" +description = "File transport adapter for Requests" +optional = false +python-versions = "*" +files = [ + {file = "requests-file-1.5.1.tar.gz", hash = "sha256:07d74208d3389d01c38ab89ef403af0cfec63957d53a0081d8eca738d0247d8e"}, + {file = "requests_file-1.5.1-py2.py3-none-any.whl", hash = "sha256:dfe5dae75c12481f68ba353183c53a65e6044c923e64c24b2209f6c7570ca953"}, +] + +[package.dependencies] +requests = ">=1.0.0" +six = "*" + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "rjsmin" +version = "1.2.1" +description = "Javascript Minifier" +optional = false +python-versions = "*" +files = [ + {file = "rjsmin-1.2.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:35827844d2085bd59d34214dfba6f1fc42a215c455887437b07dbf9c73019cc1"}, + {file = "rjsmin-1.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:812af25c08d6a5ae98019a2e1b47ebb47f7469abd351670c353d619eaeae4064"}, + {file = "rjsmin-1.2.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:b8464629a18fe69f70677854c93a3707976024b226a0ce62707c618f923e1346"}, + {file = "rjsmin-1.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bd1faedc425006d9e86b23837d164f01d105b7a8b66b767a9766d0014773db2a"}, + {file = "rjsmin-1.2.1-cp310-cp310-manylinux1_i686.whl", hash = "sha256:99c074cd6a8302ff47118a9c3d086f89328dc8e5c4b105aa1f348fb85c765a30"}, + {file = "rjsmin-1.2.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:bc5bc2f94e59bc81562c572b7f1bdd6bcec4f61168dc68a2993bad2d355b6e19"}, + {file = "rjsmin-1.2.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:35f21046504544e2941e04190ce24161255479133751550e36ddb3f4af0ecdca"}, + {file = "rjsmin-1.2.1-cp311-cp311-manylinux1_i686.whl", hash = "sha256:ca90630b84fe94bb07739c3e3793e87d30c6ee450dde08653121f0d9153c8d0d"}, + {file = "rjsmin-1.2.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:7dd58b5ed88233bc61dc80b0ed87b93a1786031d9977c70d335221ef1ac5581a"}, + {file = "rjsmin-1.2.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:f0895b360dccf7e2d6af8762a52985e3fbaa56778de1bf6b20dbc96134253807"}, + {file = "rjsmin-1.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:747bc9d3bc8a220f40858e6aad50b2ae2eb7f69c924d4fa3803b81be1c1ddd02"}, + {file = "rjsmin-1.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f7cd33602ec0f393a0058e883284496bb4dbbdd34e0bbe23b594c8933ddf9b65"}, + {file = "rjsmin-1.2.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:3453ee6d5e7a2723ec45c2909e2382371783400e8d51952b692884c6d850a3d0"}, + {file = "rjsmin-1.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8c340e251619c97571a5ade20f147f1f7e8664f66a2d6d7319e05e3ef6a4423c"}, + {file = "rjsmin-1.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:145c6af8df42d8af102d0d39a6de2e5fa66aef9e38947cfb9d65377d1b9940b2"}, + {file = "rjsmin-1.2.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bbd7a0abaa394afd951f5d4e05249d306fec1c9674bfee179787674dddd0bdb7"}, + {file = "rjsmin-1.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:eb770aaf637919b0011c4eb87b9ac6317079fb9800eb17c90dda05fc9de4ebc3"}, + {file = "rjsmin-1.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5d67ec09da46a492186e35cabca02a0d092eda5ef5b408a419b99ee4acf28d5c"}, + {file = "rjsmin-1.2.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d332e44a1b21ad63401cc7eebc81157e3d982d5fb503bb4faaea5028068d71e9"}, + {file = "rjsmin-1.2.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:113132a40ce7d03b2ced4fac215f0297338ed1c207394b739266efab7831988b"}, + {file = "rjsmin-1.2.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:122aa52bcf7ad9f12728d309012d1308c6ecfe4d6b09ea867a110dcad7b7728c"}, + {file = "rjsmin-1.2.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:8a6710e358c661dcdcfd027e67de3afd72a6af4c88101dcf110de39e9bbded39"}, + {file = "rjsmin-1.2.1.tar.gz", hash = "sha256:1f982be8e011438777a94307279b40134a3935fc0f079312ee299725b8af5411"}, +] + +[[package]] +name = "rpds-py" +version = "0.13.2" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.13.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:1ceebd0ae4f3e9b2b6b553b51971921853ae4eebf3f54086be0565d59291e53d"}, + {file = "rpds_py-0.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46e1ed994a0920f350a4547a38471217eb86f57377e9314fbaaa329b71b7dfe3"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee353bb51f648924926ed05e0122b6a0b1ae709396a80eb583449d5d477fcdf7"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:530190eb0cd778363bbb7596612ded0bb9fef662daa98e9d92a0419ab27ae914"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d311e44dd16d2434d5506d57ef4d7036544fc3c25c14b6992ef41f541b10fb"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e72f750048b32d39e87fc85c225c50b2a6715034848dbb196bf3348aa761fa1"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db09b98c7540df69d4b47218da3fbd7cb466db0fb932e971c321f1c76f155266"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2ac26f50736324beb0282c819668328d53fc38543fa61eeea2c32ea8ea6eab8d"}, + {file = "rpds_py-0.13.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12ecf89bd54734c3c2c79898ae2021dca42750c7bcfb67f8fb3315453738ac8f"}, + {file = "rpds_py-0.13.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a44c8440183b43167fd1a0819e8356692bf5db1ad14ce140dbd40a1485f2dea"}, + {file = "rpds_py-0.13.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcef4f2d3dc603150421de85c916da19471f24d838c3c62a4f04c1eb511642c1"}, + {file = "rpds_py-0.13.2-cp310-none-win32.whl", hash = "sha256:ee6faebb265e28920a6f23a7d4c362414b3f4bb30607141d718b991669e49ddc"}, + {file = "rpds_py-0.13.2-cp310-none-win_amd64.whl", hash = "sha256:ac96d67b37f28e4b6ecf507c3405f52a40658c0a806dffde624a8fcb0314d5fd"}, + {file = "rpds_py-0.13.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:b5f6328e8e2ae8238fc767703ab7b95785521c42bb2b8790984e3477d7fa71ad"}, + {file = "rpds_py-0.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:729408136ef8d45a28ee9a7411917c9e3459cf266c7e23c2f7d4bb8ef9e0da42"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65cfed9c807c27dee76407e8bb29e6f4e391e436774bcc769a037ff25ad8646e"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aefbdc934115d2f9278f153952003ac52cd2650e7313750390b334518c589568"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48db29bd47814671afdd76c7652aefacc25cf96aad6daefa82d738ee87461e2"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c55d7f2d817183d43220738270efd3ce4e7a7b7cbdaefa6d551ed3d6ed89190"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6aadae3042f8e6db3376d9e91f194c606c9a45273c170621d46128f35aef7cd0"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5feae2f9aa7270e2c071f488fab256d768e88e01b958f123a690f1cc3061a09c"}, + {file = "rpds_py-0.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51967a67ea0d7b9b5cd86036878e2d82c0b6183616961c26d825b8c994d4f2c8"}, + {file = "rpds_py-0.13.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d0c10d803549427f427085ed7aebc39832f6e818a011dcd8785e9c6a1ba9b3e"}, + {file = "rpds_py-0.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:603d5868f7419081d616dab7ac3cfa285296735e7350f7b1e4f548f6f953ee7d"}, + {file = "rpds_py-0.13.2-cp311-none-win32.whl", hash = "sha256:b8996ffb60c69f677245f5abdbcc623e9442bcc91ed81b6cd6187129ad1fa3e7"}, + {file = "rpds_py-0.13.2-cp311-none-win_amd64.whl", hash = "sha256:5379e49d7e80dca9811b36894493d1c1ecb4c57de05c36f5d0dd09982af20211"}, + {file = "rpds_py-0.13.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:8a776a29b77fe0cc28fedfd87277b0d0f7aa930174b7e504d764e0b43a05f381"}, + {file = "rpds_py-0.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2a1472956c5bcc49fb0252b965239bffe801acc9394f8b7c1014ae9258e4572b"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f252dfb4852a527987a9156cbcae3022a30f86c9d26f4f17b8c967d7580d65d2"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f0d320e70b6b2300ff6029e234e79fe44e9dbbfc7b98597ba28e054bd6606a57"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ade2ccb937060c299ab0dfb2dea3d2ddf7e098ed63ee3d651ebfc2c8d1e8632a"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9d121be0217787a7d59a5c6195b0842d3f701007333426e5154bf72346aa658"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fa6bd071ec6d90f6e7baa66ae25820d57a8ab1b0a3c6d3edf1834d4b26fafa2"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c918621ee0a3d1fe61c313f2489464f2ae3d13633e60f520a8002a5e910982ee"}, + {file = "rpds_py-0.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:25b28b3d33ec0a78e944aaaed7e5e2a94ac811bcd68b557ca48a0c30f87497d2"}, + {file = "rpds_py-0.13.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:31e220a040b89a01505128c2f8a59ee74732f666439a03e65ccbf3824cdddae7"}, + {file = "rpds_py-0.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:15253fff410873ebf3cfba1cc686a37711efcd9b8cb30ea21bb14a973e393f60"}, + {file = "rpds_py-0.13.2-cp312-none-win32.whl", hash = "sha256:b981a370f8f41c4024c170b42fbe9e691ae2dbc19d1d99151a69e2c84a0d194d"}, + {file = "rpds_py-0.13.2-cp312-none-win_amd64.whl", hash = "sha256:4c4e314d36d4f31236a545696a480aa04ea170a0b021e9a59ab1ed94d4c3ef27"}, + {file = "rpds_py-0.13.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:80e5acb81cb49fd9f2d5c08f8b74ffff14ee73b10ca88297ab4619e946bcb1e1"}, + {file = "rpds_py-0.13.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:efe093acc43e869348f6f2224df7f452eab63a2c60a6c6cd6b50fd35c4e075ba"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c2a61c0e4811012b0ba9f6cdcb4437865df5d29eab5d6018ba13cee1c3064a0"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:751758d9dd04d548ec679224cc00e3591f5ebf1ff159ed0d4aba6a0746352452"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba8858933f0c1a979781272a5f65646fca8c18c93c99c6ddb5513ad96fa54b1"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bfdfbe6a36bc3059fff845d64c42f2644cf875c65f5005db54f90cdfdf1df815"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0379c1935c44053c98826bc99ac95f3a5355675a297ac9ce0dfad0ce2d50ca"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5593855b5b2b73dd8413c3fdfa5d95b99d657658f947ba2c4318591e745d083"}, + {file = "rpds_py-0.13.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2a7bef6977043673750a88da064fd513f89505111014b4e00fbdd13329cd4e9a"}, + {file = "rpds_py-0.13.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:3ab96754d23372009638a402a1ed12a27711598dd49d8316a22597141962fe66"}, + {file = "rpds_py-0.13.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e06cfea0ece444571d24c18ed465bc93afb8c8d8d74422eb7026662f3d3f779b"}, + {file = "rpds_py-0.13.2-cp38-none-win32.whl", hash = "sha256:5493569f861fb7b05af6d048d00d773c6162415ae521b7010197c98810a14cab"}, + {file = "rpds_py-0.13.2-cp38-none-win_amd64.whl", hash = "sha256:b07501b720cf060c5856f7b5626e75b8e353b5f98b9b354a21eb4bfa47e421b1"}, + {file = "rpds_py-0.13.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:881df98f0a8404d32b6de0fd33e91c1b90ed1516a80d4d6dc69d414b8850474c"}, + {file = "rpds_py-0.13.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d79c159adea0f1f4617f54aa156568ac69968f9ef4d1e5fefffc0a180830308e"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38d4f822ee2f338febcc85aaa2547eb5ba31ba6ff68d10b8ec988929d23bb6b4"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5d75d6d220d55cdced2f32cc22f599475dbe881229aeddba6c79c2e9df35a2b3"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d97e9ae94fb96df1ee3cb09ca376c34e8a122f36927230f4c8a97f469994bff"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67a429520e97621a763cf9b3ba27574779c4e96e49a27ff8a1aa99ee70beb28a"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:188435794405c7f0573311747c85a96b63c954a5f2111b1df8018979eca0f2f0"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:38f9bf2ad754b4a45b8210a6c732fe876b8a14e14d5992a8c4b7c1ef78740f53"}, + {file = "rpds_py-0.13.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6ba2cb7d676e9415b9e9ac7e2aae401dc1b1e666943d1f7bc66223d3d73467b"}, + {file = "rpds_py-0.13.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:eaffbd8814bb1b5dc3ea156a4c5928081ba50419f9175f4fc95269e040eff8f0"}, + {file = "rpds_py-0.13.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4c1058cdae6237d97af272b326e5f78ee7ee3bbffa6b24b09db4d828810468"}, + {file = "rpds_py-0.13.2-cp39-none-win32.whl", hash = "sha256:b5267feb19070bef34b8dea27e2b504ebd9d31748e3ecacb3a4101da6fcb255c"}, + {file = "rpds_py-0.13.2-cp39-none-win_amd64.whl", hash = "sha256:ddf23960cb42b69bce13045d5bc66f18c7d53774c66c13f24cf1b9c144ba3141"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:97163a1ab265a1073a6372eca9f4eeb9f8c6327457a0b22ddfc4a17dcd613e74"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:25ea41635d22b2eb6326f58e608550e55d01df51b8a580ea7e75396bafbb28e9"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d59d4d451ba77f08cb4cd9268dec07be5bc65f73666302dbb5061989b17198"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7c564c58cf8f248fe859a4f0fe501b050663f3d7fbc342172f259124fb59933"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61dbc1e01dc0c5875da2f7ae36d6e918dc1b8d2ce04e871793976594aad8a57a"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdb82eb60d31b0c033a8e8ee9f3fc7dfbaa042211131c29da29aea8531b4f18f"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d204957169f0b3511fb95395a9da7d4490fb361763a9f8b32b345a7fe119cb45"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c45008ca79bad237cbc03c72bc5205e8c6f66403773929b1b50f7d84ef9e4d07"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:79bf58c08f0756adba691d480b5a20e4ad23f33e1ae121584cf3a21717c36dfa"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e86593bf8637659e6a6ed58854b6c87ec4e9e45ee8a4adfd936831cef55c2d21"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:d329896c40d9e1e5c7715c98529e4a188a1f2df51212fd65102b32465612b5dc"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4a5375c5fff13f209527cd886dc75394f040c7d1ecad0a2cb0627f13ebe78a12"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:06d218e4464d31301e943b65b2c6919318ea6f69703a351961e1baaf60347276"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1f41d32a2ddc5a94df4b829b395916a4b7f103350fa76ba6de625fcb9e773ac"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6bc568b05e02cd612be53900c88aaa55012e744930ba2eeb56279db4c6676eb3"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d94d78418203904730585efa71002286ac4c8ac0689d0eb61e3c465f9e608ff"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bed0252c85e21cf73d2d033643c945b460d6a02fc4a7d644e3b2d6f5f2956c64"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244e173bb6d8f3b2f0c4d7370a1aa341f35da3e57ffd1798e5b2917b91731fd3"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7f55cd9cf1564b7b03f238e4c017ca4794c05b01a783e9291065cb2858d86ce4"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:f03a1b3a4c03e3e0161642ac5367f08479ab29972ea0ffcd4fa18f729cd2be0a"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:f5f4424cb87a20b016bfdc157ff48757b89d2cc426256961643d443c6c277007"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c82bbf7e03748417c3a88c1b0b291288ce3e4887a795a3addaa7a1cfd9e7153e"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c0095b8aa3e432e32d372e9a7737e65b58d5ed23b9620fea7cb81f17672f1fa1"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4c2d26aa03d877c9730bf005621c92da263523a1e99247590abbbe252ccb7824"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96f2975fb14f39c5fe75203f33dd3010fe37d1c4e33177feef1107b5ced750e3"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4dcc5ee1d0275cb78d443fdebd0241e58772a354a6d518b1d7af1580bbd2c4e8"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61d42d2b08430854485135504f672c14d4fc644dd243a9c17e7c4e0faf5ed07e"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d3a61e928feddc458a55110f42f626a2a20bea942ccedb6fb4cee70b4830ed41"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7de12b69d95072394998c622cfd7e8cea8f560db5fca6a62a148f902a1029f8b"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87a90f5545fd61f6964e65eebde4dc3fa8660bb7d87adb01d4cf17e0a2b484ad"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:9c95a1a290f9acf7a8f2ebbdd183e99215d491beea52d61aa2a7a7d2c618ddc6"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:35f53c76a712e323c779ca39b9a81b13f219a8e3bc15f106ed1e1462d56fcfe9"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:96fb0899bb2ab353f42e5374c8f0789f54e0a94ef2f02b9ac7149c56622eaf31"}, + {file = "rpds_py-0.13.2.tar.gz", hash = "sha256:f8eae66a1304de7368932b42d801c67969fd090ddb1a7a24f27b435ed4bed68f"}, +] + +[[package]] +name = "sentry-sdk" +version = "1.15.0" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = "*" +files = [ + {file = "sentry-sdk-1.15.0.tar.gz", hash = "sha256:69ecbb2e1ff4db02a06c4f20f6f69cb5dfe3ebfbc06d023e40d77cf78e9c37e7"}, + {file = "sentry_sdk-1.15.0-py2.py3-none-any.whl", hash = "sha256:7ad4d37dd093f4a7cb5ad804c6efe9e8fab8873f7ffc06042dc3f3fd700a93ec"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""} + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +chalice = ["chalice (>=1.16.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +pure-eval = ["asttokens", "executing", "pure-eval"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +tornado = ["tornado (>=5)"] + +[[package]] +name = "sepaxml" +version = "2.6.1" +description = "Python SEPA XML implementations" +optional = false +python-versions = "*" +files = [ + {file = "sepaxml-2.6.1-py3-none-any.whl", hash = "sha256:f110e4a11322c1ea46f86550d703468b109343b4cece1d5b792d394f03d86110"}, + {file = "sepaxml-2.6.1.tar.gz", hash = "sha256:939c12236779e6a3d7221d3557921abd6e30b0bfd369e67815ea55bccaacd688"}, +] + +[package.dependencies] +text-unidecode = "*" +xmlschema = "*" + +[[package]] +name = "setuptools" +version = "69.0.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, + {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "slimit" +version = "0.8.1" +description = "SlimIt - JavaScript minifier" +optional = false +python-versions = "*" +files = [ + {file = "slimit-0.8.1.zip", hash = "sha256:f433dcef899f166b207b67d91d3f7344659cb33b8259818f084167244e17720b"}, +] + +[package.dependencies] +ply = ">=3.4" + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "sqlparse" +version = "0.4.4" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"}, + {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"}, +] + +[package.extras] +dev = ["build", "flake8"] +doc = ["sphinx"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "static3" +version = "0.7.0" +description = "A really simple WSGI way to serve static (or mixed) content." +optional = false +python-versions = "*" +files = [ + {file = "static3-0.7.0.tar.gz", hash = "sha256:674641c64bc75507af2eb20bef7e7e3593dca993dec6674be108fa15b42f47c8"}, +] + +[package.extras] +genshimagic = ["Genshi"] +kidmagic = ["kid"] + +[[package]] +name = "stripe" +version = "5.4.0" +description = "Python bindings for the Stripe API" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "stripe-5.4.0-py2.py3-none-any.whl", hash = "sha256:57c0da7e3b889b69ff1dbf23ac1ec5e00f665cfba069fdf0f328b83ddf4225df"}, + {file = "stripe-5.4.0.tar.gz", hash = "sha256:72bda7bf9be7528e1b97a5bbacb0716cdf6a0c9597b13fdbfa364cec3c130713"}, +] + +[package.dependencies] +requests = {version = ">=2.20", markers = "python_version >= \"3.0\""} + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + +[[package]] +name = "tlds" +version = "2023112100" +description = "Automatically updated list of valid TLDs taken directly from IANA" +optional = false +python-versions = "*" +files = [ + {file = "tlds-2023112100-py2.py3-none-any.whl", hash = "sha256:17341dd4c20efefecc349c3112443d217dcc405df9c33f8bcdd60e56f61b29d0"}, + {file = "tlds-2023112100.tar.gz", hash = "sha256:3adbb9e991e804e160e7b4ff09bcfe61c6a7662f5ba0bb27d78e6a2022ed8d18"}, +] + +[[package]] +name = "tqdm" +version = "4.66.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, + {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, +] + +[[package]] +name = "tzdata" +version = "2023.3" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, +] + +[[package]] +name = "ujson" +version = "5.8.0" +description = "Ultra fast JSON encoder and decoder for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ujson-5.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4511560d75b15ecb367eef561554959b9d49b6ec3b8d5634212f9fed74a6df1"}, + {file = "ujson-5.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9399eaa5d1931a0ead49dce3ffacbea63f3177978588b956036bfe53cdf6af75"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4e7bb7eba0e1963f8b768f9c458ecb193e5bf6977090182e2b4f4408f35ac76"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40931d7c08c4ce99adc4b409ddb1bbb01635a950e81239c2382cfe24251b127a"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d53039d39de65360e924b511c7ca1a67b0975c34c015dd468fca492b11caa8f7"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bdf04c6af3852161be9613e458a1fb67327910391de8ffedb8332e60800147a2"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a70f776bda2e5072a086c02792c7863ba5833d565189e09fabbd04c8b4c3abba"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f26629ac531d712f93192c233a74888bc8b8212558bd7d04c349125f10199fcf"}, + {file = "ujson-5.8.0-cp310-cp310-win32.whl", hash = "sha256:7ecc33b107ae88405aebdb8d82c13d6944be2331ebb04399134c03171509371a"}, + {file = "ujson-5.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:3b27a8da7a080add559a3b73ec9ebd52e82cc4419f7c6fb7266e62439a055ed0"}, + {file = "ujson-5.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:193349a998cd821483a25f5df30b44e8f495423840ee11b3b28df092ddfd0f7f"}, + {file = "ujson-5.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ddeabbc78b2aed531f167d1e70387b151900bc856d61e9325fcdfefb2a51ad8"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ce24909a9c25062e60653073dd6d5e6ec9d6ad7ed6e0069450d5b673c854405"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27a2a3c7620ebe43641e926a1062bc04e92dbe90d3501687957d71b4bdddaec4"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b852bdf920fe9f84e2a2c210cc45f1b64f763b4f7d01468b33f7791698e455e"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:20768961a6a706170497129960762ded9c89fb1c10db2989c56956b162e2a8a3"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e0147d41e9fb5cd174207c4a2895c5e24813204499fd0839951d4c8784a23bf5"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e3673053b036fd161ae7a5a33358ccae6793ee89fd499000204676baafd7b3aa"}, + {file = "ujson-5.8.0-cp311-cp311-win32.whl", hash = "sha256:a89cf3cd8bf33a37600431b7024a7ccf499db25f9f0b332947fbc79043aad879"}, + {file = "ujson-5.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3659deec9ab9eb19e8646932bfe6fe22730757c4addbe9d7d5544e879dc1b721"}, + {file = "ujson-5.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:102bf31c56f59538cccdfec45649780ae00657e86247c07edac434cb14d5388c"}, + {file = "ujson-5.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:299a312c3e85edee1178cb6453645217ba23b4e3186412677fa48e9a7f986de6"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2e385a7679b9088d7bc43a64811a7713cc7c33d032d020f757c54e7d41931ae"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad24ec130855d4430a682c7a60ca0bc158f8253ec81feed4073801f6b6cb681b"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16fde596d5e45bdf0d7de615346a102510ac8c405098e5595625015b0d4b5296"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6d230d870d1ce03df915e694dcfa3f4e8714369cce2346686dbe0bc8e3f135e7"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9571de0c53db5cbc265945e08f093f093af2c5a11e14772c72d8e37fceeedd08"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7cba16b26efe774c096a5e822e4f27097b7c81ed6fb5264a2b3f5fd8784bab30"}, + {file = "ujson-5.8.0-cp312-cp312-win32.whl", hash = "sha256:48c7d373ff22366eecfa36a52b9b55b0ee5bd44c2b50e16084aa88b9de038916"}, + {file = "ujson-5.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:5ac97b1e182d81cf395ded620528c59f4177eee024b4b39a50cdd7b720fdeec6"}, + {file = "ujson-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2a64cc32bb4a436e5813b83f5aab0889927e5ea1788bf99b930fad853c5625cb"}, + {file = "ujson-5.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e54578fa8838ddc722539a752adfce9372474114f8c127bb316db5392d942f8b"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9721cd112b5e4687cb4ade12a7b8af8b048d4991227ae8066d9c4b3a6642a582"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d9707e5aacf63fb919f6237d6490c4e0244c7f8d3dc2a0f84d7dec5db7cb54c"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0be81bae295f65a6896b0c9030b55a106fb2dec69ef877253a87bc7c9c5308f7"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae7f4725c344bf437e9b881019c558416fe84ad9c6b67426416c131ad577df67"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9ab282d67ef3097105552bf151438b551cc4bedb3f24d80fada830f2e132aeb9"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94c7bd9880fa33fcf7f6d7f4cc032e2371adee3c5dba2922b918987141d1bf07"}, + {file = "ujson-5.8.0-cp38-cp38-win32.whl", hash = "sha256:bf5737dbcfe0fa0ac8fa599eceafae86b376492c8f1e4b84e3adf765f03fb564"}, + {file = "ujson-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:11da6bed916f9bfacf13f4fc6a9594abd62b2bb115acfb17a77b0f03bee4cfd5"}, + {file = "ujson-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:69b3104a2603bab510497ceabc186ba40fef38ec731c0ccaa662e01ff94a985c"}, + {file = "ujson-5.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9249fdefeb021e00b46025e77feed89cd91ffe9b3a49415239103fc1d5d9c29a"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2873d196725a8193f56dde527b322c4bc79ed97cd60f1d087826ac3290cf9207"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a4dafa9010c366589f55afb0fd67084acd8added1a51251008f9ff2c3e44042"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a42baa647a50fa8bed53d4e242be61023bd37b93577f27f90ffe521ac9dc7a3"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f3554eaadffe416c6f543af442066afa6549edbc34fe6a7719818c3e72ebfe95"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fb87decf38cc82bcdea1d7511e73629e651bdec3a43ab40985167ab8449b769c"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:407d60eb942c318482bbfb1e66be093308bb11617d41c613e33b4ce5be789adc"}, + {file = "ujson-5.8.0-cp39-cp39-win32.whl", hash = "sha256:0fe1b7edaf560ca6ab023f81cbeaf9946a240876a993b8c5a21a1c539171d903"}, + {file = "ujson-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f9b63530a5392eb687baff3989d0fb5f45194ae5b1ca8276282fb647f8dcdb3"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:efeddf950fb15a832376c0c01d8d7713479fbeceaed1eaecb2665aa62c305aec"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d8283ac5d03e65f488530c43d6610134309085b71db4f675e9cf5dff96a8282"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb0142f6f10f57598655340a3b2c70ed4646cbe674191da195eb0985a9813b83"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07d459aca895eb17eb463b00441986b021b9312c6c8cc1d06880925c7f51009c"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d524a8c15cfc863705991d70bbec998456a42c405c291d0f84a74ad7f35c5109"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d6f84a7a175c75beecde53a624881ff618e9433045a69fcfb5e154b73cdaa377"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b748797131ac7b29826d1524db1cc366d2722ab7afacc2ce1287cdafccddbf1f"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e72ba76313d48a1a3a42e7dc9d1db32ea93fac782ad8dde6f8b13e35c229130"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f504117a39cb98abba4153bf0b46b4954cc5d62f6351a14660201500ba31fe7f"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8c91b6f4bf23f274af9002b128d133b735141e867109487d17e344d38b87d94"}, + {file = "ujson-5.8.0.tar.gz", hash = "sha256:78e318def4ade898a461b3d92a79f9441e7e0e4d2ad5419abed4336d702c7425"}, +] + +[[package]] +name = "urllib3" +version = "2.1.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, + {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "vat-moss-forked" +version = "2020.3.20.0.11.0" +description = "Tools for VAT MOSS and Norway VAT on digital services." +optional = false +python-versions = "*" +files = [ + {file = "vat_moss_forked-2020.3.20.0.11.0-py3-none-any.whl", hash = "sha256:80f489da56836f5d3ad8e5b29621238a18888fa8669ebf9dd975c3666174471f"}, + {file = "vat_moss_forked-2020.3.20.0.11.0.tar.gz", hash = "sha256:d46836079687a20375cae0336946015060c71a30faa30642c8ea726daf638095"}, +] + +[[package]] +name = "vine" +version = "5.1.0" +description = "Python promises." +optional = false +python-versions = ">=3.6" +files = [ + {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, + {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, +] + +[[package]] +name = "vobject" +version = "0.9.6.1" +description = "A full-featured Python package for parsing and creating iCalendar and vCard files" +optional = false +python-versions = "*" +files = [ + {file = "vobject-0.9.6.1.tar.gz", hash = "sha256:96512aec74b90abb71f6b53898dd7fe47300cc940104c4f79148f0671f790101"}, +] + +[package.dependencies] +python-dateutil = ">=2.4.0" + +[[package]] +name = "wcwidth" +version = "0.2.12" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.12-py2.py3-none-any.whl", hash = "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c"}, + {file = "wcwidth-0.2.12.tar.gz", hash = "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02"}, +] + +[[package]] +name = "webauthn" +version = "0.4.7" +description = "A WebAuthn Python module." +optional = false +python-versions = "*" +files = [ + {file = "webauthn-0.4.7-py2.py3-none-any.whl", hash = "sha256:238391b2e2cc60fb51a2cd2d2d6be149920b9af6184651353d9f95856617a9e7"}, + {file = "webauthn-0.4.7.tar.gz", hash = "sha256:8ad9072ff1d6169f3be30d4dc8733ea563dd266962397bc58b40f674a6af74ac"}, +] + +[package.dependencies] +cbor2 = ">=4.0.1" +cryptography = ">=2.3.1" +future = ">=0.17.1" +pyOpenSSL = ">=16.0.0" +six = ">=1.11.0" + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "xmlschema" +version = "2.5.0" +description = "An XML Schema validator and decoder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "xmlschema-2.5.0-py3-none-any.whl", hash = "sha256:f2b29c45485fac414cc1fdb38d18a220c5987d7d3aa996e6df6ff35ee94d5a63"}, + {file = "xmlschema-2.5.0.tar.gz", hash = "sha256:276a03e0fd3c94c148d528bff4d9482f9b99bf8c7b4056a2e8e703d28149d454"}, +] + +[package.dependencies] +elementpath = ">=4.1.5,<5.0.0" + +[package.extras] +codegen = ["elementpath (>=4.1.5,<5.0.0)", "jinja2"] +dev = ["Sphinx", "coverage", "elementpath (>=4.1.5,<5.0.0)", "flake8", "jinja2", "lxml", "lxml-stubs", "memory-profiler", "mypy", "sphinx-rtd-theme", "tox"] +docs = ["Sphinx", "elementpath (>=4.1.5,<5.0.0)", "jinja2", "sphinx-rtd-theme"] + +[[package]] +name = "yarl" +version = "1.9.4" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "zeep" +version = "4.2.1" +description = "A Python SOAP client" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zeep-4.2.1-py3-none-any.whl", hash = "sha256:6754feb4c34a4b6d65fbc359252bf6654dcce3937bf1d95aae4402a60a8f5939"}, + {file = "zeep-4.2.1.tar.gz", hash = "sha256:72093acfdb1d8360ed400869b73fbf1882b95c4287f798084c42ee0c1ff0e425"}, +] + +[package.dependencies] +attrs = ">=17.2.0" +isodate = ">=0.5.4" +lxml = ">=4.6.0" +platformdirs = ">=1.4.0" +pytz = "*" +requests = ">=2.7.0" +requests-file = ">=1.5.1" +requests-toolbelt = ">=0.7.1" + +[package.extras] +async = ["httpx (>=0.15.0)"] +docs = ["sphinx (>=1.4.0)"] +test = ["coverage[toml] (==5.2.1)", "flake8 (==3.8.3)", "flake8-blind-except (==0.1.1)", "flake8-debugger (==3.2.1)", "flake8-imports (==0.1.1)", "freezegun (==0.3.15)", "isort (==5.3.2)", "pretend (==1.0.9)", "pytest (==6.2.5)", "pytest-asyncio", "pytest-cov (==2.8.1)", "pytest-httpx", "requests-mock (>=0.7.0)"] +xmlsec = ["xmlsec (>=0.6.1)"] + +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "6f50be70b30ae90c359a54d1847544a3c9156822b917add7008dafc89d3d3b4e" diff --git a/pkgs/pretix/pretix-banktool-requirements.patch b/pkgs/pretix/pretix-banktool-requirements.patch new file mode 100644 index 0000000..cb78385 --- /dev/null +++ b/pkgs/pretix/pretix-banktool-requirements.patch @@ -0,0 +1,18 @@ +diff --git a/setup.py b/setup.py +index 2eba88a..7041acd 100644 +--- a/setup.py ++++ b/setup.py +@@ -19,8 +19,8 @@ setup( + author_email='mail@raphaelmichel.de', + + install_requires=[ +- 'click==6.*', +- 'fints>=3.0.*', ++ 'click>=6,<8.2', ++ 'fints>=3,<4.1', + 'requests', +- 'mt-940>=4.12*', ++ 'mt-940==4.30.0', + ], +-- +2.38.3 diff --git a/pkgs/pretix/pretix-banktool.nix b/pkgs/pretix/pretix-banktool.nix new file mode 100644 index 0000000..f53f6f7 --- /dev/null +++ b/pkgs/pretix/pretix-banktool.nix @@ -0,0 +1,27 @@ +{ python3Packages, fetchFromGitHub }: +python3Packages.buildPythonApplication rec { + name = "pretix-banktool"; + version = "1.0.0"; + + src = fetchFromGitHub { + owner = "pretix"; + repo = "pretix-banktool"; + rev = "v${version}"; + sha256 = "vYHjotx1RujPV53Ei7bXAc3kL/3cwbWQB1T3sQ15MFA="; + }; + + patches = [ + ./pretix-banktool-requirements.patch + ]; + + buildInputs = with python3Packages; [ + pip + ]; + + propagatedBuildInputs = with python3Packages; [ + click + fints + mt-940 + requests + ]; +} diff --git a/pkgs/pretix/pretix-static.nix b/pkgs/pretix/pretix-static.nix new file mode 100644 index 0000000..f97399c --- /dev/null +++ b/pkgs/pretix/pretix-static.nix @@ -0,0 +1,48 @@ +{ stdenvNoCC +, pretix +, buildNpmPackage +, makeWrapper +}: + +let + nodeEnv = buildNpmPackage rec { + name = "pretix-nodejs"; + src = "${pretix.passthru.pythonModule.pkgs.pretix}/lib/${pretix.python.libPrefix}/site-packages/pretix/static/npm_dir"; + npmDepsHash = "sha256-lf7GTXjvz4df1GeQ6uibwwGm+gKRU/RdNEHiCJ+zF1Y="; + dontNpmBuild = true; + installPhase = '' + mkdir -p $out + cp -r node_modules $out/ + mkdir -p $out/bin + ln -s $out/node_modules/rollup/dist/bin/rollup $out/bin/rollup + ''; + postFixup = '' + wrapProgram $out/bin/rollup --prefix NODE_PATH : $out + ''; + nativeBuildInputs = [ + makeWrapper + ]; + }; +in +stdenvNoCC.mkDerivation { + name = "pretix-static"; + src = ./.; + buildPhase = '' + mkdir $out + export PRETIX_STATIC_ROOT=$out + export DJANGO_SETTINGS_MODULE=pretix_wrapper.settings + ${pretix}/bin/pretix collectstatic --noinput + mkdir -p $PRETIX_STATIC_ROOT/node_prefix + ln -s ${nodeEnv}/node_modules $PRETIX_STATIC_ROOT/node_prefix/node_modules + echo ${nodeEnv}/bin/rollup + ${pretix}/bin/pretix compress + ''; + installPhase = '' + runHook preInstall + runHook postInstall + ''; + nativeBuildInputs = [ + nodeEnv + ]; +} + diff --git a/pkgs/pretix/pretix.nix b/pkgs/pretix/pretix.nix new file mode 100644 index 0000000..697f2c3 --- /dev/null +++ b/pkgs/pretix/pretix.nix @@ -0,0 +1,60 @@ +{ lib +, poetry2nix +, pkgs +, gettext +, tlds-alpha-by-domain ? ./tlds-alpha-by-domain.txt +}: + +let + tlds = pkgs.fetchurl { + url = "https://data.iana.org/TLD/tlds-alpha-by-domain.txt"; + sha256 = "0153py77ll759jacq41dp2z2ksr08pdcfic0rwjd6pr84dk89y9v"; + }; + pkgsRequiringSetuptools = [ + "dj-static" + "django-jquery-js" + "paypal-checkout-serversdk" + "python-u2flib-server" + "slimit" + "static3" + ]; +in +poetry2nix.mkPoetryApplication rec { + projectDir = ./.; + #python = pkgs.python310; + preferWheels = true; + overrides = poetry2nix.defaultPoetryOverrides.extend + ( + self: super: lib.attrsets.genAttrs pkgsRequiringSetuptools + ( + pythonPackage: + super."${pythonPackage}".overridePythonAttrs ( + old: { + buildInputs = (old.buildInputs or [ ]) ++ [ super.setuptools ]; + } + ) + ) // { + tlds = super.tlds.overridePythonAttrs ( + old: { + buildInputs = (old.buildInputs or [ ]) ++ [ super.setuptools ]; + } + ); + pretix = super.pretix.overridePythonAttrs ( + old: { + buildInputs = (old.buildInputs or [ ]) ++ [ + gettext + ]; + preFixup = '' + python -m pretix compilemessages + python -m pretix compilejsi18n + ''; + } + ); + reportlab = super.reportlab.overridePythonAttrs ( + old: { + postPatch = ""; + } + ); + } + ); +} diff --git a/pkgs/pretix/pretix_wrapper/__main__.py b/pkgs/pretix/pretix_wrapper/__main__.py new file mode 100644 index 0000000..57fdb08 --- /dev/null +++ b/pkgs/pretix/pretix_wrapper/__main__.py @@ -0,0 +1,9 @@ +import sys +import os + +module_name = "pretix" + + +def main(): + os.environ["PYTHONPATH"] = ":".join(sys.path) + os.execv(sys.executable, [sys.executable, "-m", module_name, *sys.argv[1:]]) diff --git a/pkgs/pretix/pretix_wrapper/settings.py b/pkgs/pretix/pretix_wrapper/settings.py new file mode 100644 index 0000000..e0c5620 --- /dev/null +++ b/pkgs/pretix/pretix_wrapper/settings.py @@ -0,0 +1,4 @@ +import os +from pretix.settings import * + +STATIC_ROOT = os.getenv("PRETIX_STATIC_ROOT") diff --git a/pkgs/pretix/pyproject.toml b/pkgs/pretix/pyproject.toml new file mode 100644 index 0000000..541b36e --- /dev/null +++ b/pkgs/pretix/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "pretix_wrapper" +version = "1.0.0" +description = "" +authors = ["Jakob Lechner "] +license = "MIT" + +[tool.poetry.dependencies] +python = "^3.10" +pretix = "^2023.10.0" + +[tool.poetry.dev-dependencies] + +[tool.poetry.scripts] +pretix = "pretix_wrapper.__main__:main" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/pkgs/pretix/shell.nix b/pkgs/pretix/shell.nix new file mode 100644 index 0000000..cd52c53 --- /dev/null +++ b/pkgs/pretix/shell.nix @@ -0,0 +1,8 @@ +with import { }; + +mkShell { + buildInputs = [ + poetry + ]; + +} diff --git a/pkgs/tabbed-box-maker/default.nix b/pkgs/tabbed-box-maker/default.nix index dee949e..d30e534 100644 --- a/pkgs/tabbed-box-maker/default.nix +++ b/pkgs/tabbed-box-maker/default.nix @@ -14,7 +14,7 @@ stdenvNoCC.mkDerivation { sha256 = "8TNNVMSwbvcEwkvMHecHtGLEpiX3F0g0EGsgO1YKBGQ="; }; - dontBuild = true; + dontBild = true; installPhase = '' mkdir $out cp * $out diff --git a/pkgs/vesc-tool/firmware.nix b/pkgs/vesc-tool/firmware.nix new file mode 100644 index 0000000..cb16051 --- /dev/null +++ b/pkgs/vesc-tool/firmware.nix @@ -0,0 +1,46 @@ +{ lib +, stdenv +, fetchFromGitHub +, gcc-arm-embedded-7 +, python311 +, git +}: + +stdenv.mkDerivation rec { + pname = "vesc-firmware"; + version = "master"; + + src = fetchFromGitHub { + owner = "vedderb"; + repo = "bldc"; + rev = "6.00"; + sha256 = "XeIS+3SOKeTkbsx/aCy0FRw/LVXBbLpAqz6upN5HJUY="; + #rev = "5b6cc075d3cfa62bd52a05fad0195fae114d914c"; + #sha256 = "SB/mQEYY2Bi2xl5qniKdShMQ0vdrVuLtiWWH4D1U0tw="; + fetchSubmodules = true; + }; + + nativeBuildInputs = [ + gcc-arm-embedded-7 + python311 + git + # bash + # libsForQt5.qmake + # libsForQt5.qtconnectivity + # libsForQt5.qtgamepad + # libsForQt5.qtlocation + # libsForQt5.qtquickcontrols2 + # libsForQt5.qtserialport + ]; + + buildCommand = '' + cp -r $src bldc + ( + cd bldc + chmod +w . + #make all_fw_package + make fw_410 + ) + cp -r bldc/build/* $out + ''; +} diff --git a/pkgs/vesc-tool/tool.nix b/pkgs/vesc-tool/tool.nix new file mode 100644 index 0000000..2a23fa3 --- /dev/null +++ b/pkgs/vesc-tool/tool.nix @@ -0,0 +1,70 @@ +{ lib +, stdenv +, fetchFromGitHub +, libsForQt5 +, vesc-firmware +, writeText +, qt5 +}: + +let + qresource = writeText "res_fw.qrc" + '' + + + 410.bin + + + ''; +in +stdenv.mkDerivation rec { + pname = "vesc_tool"; + version = "master"; + + src = fetchFromGitHub { + owner = "vedderb"; + repo = "vesc_tool"; + rev = "6d9d6d7f17c8756a272c267659849ea9c9404efa"; + sha256 = "EXXWAwX3yPirhe83wz5/vEectieHeUAkIla7ICxzMow="; + fetchSubmodules = true; + }; + + nativeBuildInputs = [ + libsForQt5.qmake + qt5.wrapQtAppsHook + ]; + + buildInputs = [ + vesc-firmware + ]; + + propagatedBuildInputs = with qt5; [ + qtconnectivity + qtgamepad + qtlocation + qtquickcontrols2 + qtserialport + ]; + + buildPhase = '' + tempdir="$(mktemp -d)" + cp -r "$src/." "$tempdir/" + chmod -R +w "$tempdir" + cd "$tempdir" + + mkdir -p res/firmwares/ + cp ${qresource} res/firmwares/res_fw.qrc + cp ${vesc-firmware}/*.bin res/firmwares + + qmake -config release "CONFIG += release_lin build_platinum" + make clean + make -j8 + rm -rf build/lin/obj + mkdir -p $out/bin + cp build/lin/* $out/bin + ''; + + postFixup = '' + wrapQtApp $out/bin/vesc_tool_6.02 + ''; +} diff --git a/pkgs/vim-fluid/default.nix b/pkgs/vim-fluid/default.nix deleted file mode 100644 index 35f232f..0000000 --- a/pkgs/vim-fluid/default.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ buildVimPlugin, fetchFromGitHub }: -buildVimPlugin { - pname = "vim-fluid"; - version = "0.0.1"; - src = fetchFromGitHub { - owner = "mipmip"; - repo = "vim-fluid"; - rev = "cedc4ad871941e8f7134d1d71f9434f1bc3d93d5"; - sha256 = "sha256-LiS2Dqw1K1Fu5VfHQnxIBDxDzEarmSAUUavQcwHRDsQ="; - }; - meta.homepage = "https://github.com/mipmip/vim-fluid"; -} diff --git a/pkgs/vim-typoscript/default.nix b/pkgs/vim-typoscript/default.nix deleted file mode 100644 index ab85d79..0000000 --- a/pkgs/vim-typoscript/default.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ buildVimPlugin, fetchFromGitHub }: -buildVimPlugin rec { - pname = "vim-typoscript"; - version = "2.0.0"; - src = fetchFromGitHub { - owner = "DanielSiepmann"; - repo = "mirror-vim.typoscript"; - rev = "v${version}"; - sha256 = "sha256-fCB+ikDmkfEP/W0pFYGrsZiH30vT0g3z6GZpRGk0Rhc="; - }; - meta.homepage = "https://git.daniel-siepmann.de/danielsiepmann/vim-syntax-typoscript"; -} - diff --git a/pkgs/vodafone-station-exporter/default.nix b/pkgs/vodafone-station-exporter/default.nix deleted file mode 100644 index 9a80e97..0000000 --- a/pkgs/vodafone-station-exporter/default.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ buildGoApplication, fetchgit }: - -buildGoApplication { - pname = "vodafone-station-exporter"; - version = "0.0.1"; - src = fetchgit { - url = "https://git.jalr.de/jalr/vodafone-station-exporter"; - rev = "808564b940c3570e3b32ce60657bf83fda75ec3c"; - hash = "sha256-A3Behy8Q7bhYXoGUsZXzIAQd/dTXH4d4wd+FDYuD7tE="; - }; - modules = ./gomod2nix.toml; -} diff --git a/pkgs/vodafone-station-exporter/gomod2nix.toml b/pkgs/vodafone-station-exporter/gomod2nix.toml deleted file mode 100644 index 293cd7e..0000000 --- a/pkgs/vodafone-station-exporter/gomod2nix.toml +++ /dev/null @@ -1,42 +0,0 @@ -schema = 3 - -[mod] - [mod."github.com/beorn7/perks"] - version = "v1.0.1" - hash = "sha256-h75GUqfwJKngCJQVE5Ao5wnO3cfKD9lSIteoLp/3xJ4=" - [mod."github.com/cespare/xxhash/v2"] - version = "v2.3.0" - hash = "sha256-7hRlwSR+fos1kx4VZmJ/7snR7zHh8ZFKX+qqqqGcQpY=" - [mod."github.com/kr/text"] - version = "v0.2.0" - hash = "sha256-fadcWxZOORv44oak3jTxm6YcITcFxdGt4bpn869HxUE=" - [mod."github.com/munnerz/goautoneg"] - version = "v0.0.0-20191010083416-a7dc8b61c822" - hash = "sha256-79URDDFenmGc9JZu+5AXHToMrtTREHb3BC84b/gym9Q=" - [mod."github.com/prometheus/client_golang"] - version = "v1.23.2" - hash = "sha256-3GD4fBFa1tJu8MS4TNP6r2re2eViUE+kWUaieIOQXCg=" - [mod."github.com/prometheus/client_model"] - version = "v0.6.2" - hash = "sha256-q6Fh6v8iNJN9ypD47LjWmx66YITa3FyRjZMRsuRTFeQ=" - [mod."github.com/prometheus/common"] - version = "v0.66.1" - hash = "sha256-bqHPaV9IV70itx63wqwgy2PtxMN0sn5ThVxDmiD7+Tk=" - [mod."github.com/prometheus/procfs"] - version = "v0.16.1" - hash = "sha256-OBCvKlLW2obct35p0L9Q+1ZrxZjpTmbgHMP2rng9hpo=" - [mod."go.yaml.in/yaml/v2"] - version = "v2.4.2" - hash = "sha256-oC8RWdf1zbMYCtmR0ATy/kCkhIwPR9UqFZSMOKLVF/A=" - [mod."golang.org/x/crypto"] - version = "v0.42.0" - hash = "sha256-qa6cGxZUhVnbkpVzfvLGQQsl/NCqNceJp9SIx5vkyiI=" - [mod."golang.org/x/exp"] - version = "v0.0.0-20250911091902-df9299821621" - hash = "sha256-cSDirFex900mrckzB3fe18hW2Vk4/y4xKvlUWq3yoDA=" - [mod."golang.org/x/sys"] - version = "v0.36.0" - hash = "sha256-9h4SHGnlJzmTENUp6226hC8fQ73QrQC3D85NNMxLuXg=" - [mod."google.golang.org/protobuf"] - version = "v1.36.8" - hash = "sha256-yZN8ZON0b5HjUNUSubHst7zbvnMsOzd81tDPYQRtPgM=" diff --git a/pkgs/wofi-bluetooth/wofi-bluetooth.nix b/pkgs/wofi-bluetooth/wofi-bluetooth.nix index 5f6e408..1b1cad6 100644 --- a/pkgs/wofi-bluetooth/wofi-bluetooth.nix +++ b/pkgs/wofi-bluetooth/wofi-bluetooth.nix @@ -8,8 +8,8 @@ stdenv.mkDerivation rec { pname = "wofi-bluetooth"; - inherit (rofi-bluetooth) version; - inherit (rofi-bluetooth) src; + version = rofi-bluetooth.version; + src = rofi-bluetooth.src; patches = [ ./wofi-bluetooth.patch ]; diff --git a/users/README.md b/users/README.md deleted file mode 100644 index 50675ba..0000000 --- a/users/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Home Manager -The user configuration is managed by [Home Manager](https://github.com/nix-community/home-manager) - -For a systematic overview of Home Manager and its available options, please see -- the [Home Manager manual](https://nix-community.github.io/home-manager/index.html) and -- the [Home Manager configuration options](https://nix-community.github.io/home-manager/options.html). - diff --git a/users/jalr/default.nix b/users/jalr/default.nix deleted file mode 100644 index ac85cd2..0000000 --- a/users/jalr/default.nix +++ /dev/null @@ -1,206 +0,0 @@ -{ config, pkgs, ... }: - -let - sshKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3l+Yixrsjhze20CSjvUK4Qj/BNqbTNitgk20vuzPej cardno:25_750_479" - ]; -in -{ - users.users.jalr = { - isNormalUser = true; - extraGroups = [ - "adbusers" - "audio" - "dialout" - "docker" - "libvirtd" - "lp" - "networkmanager" - "plugdev" - "scanner" - "video" - "wheel" - "wireshark" - ]; # Enable ‘sudo’ for the user. - shell = pkgs.fish; - openssh.authorizedKeys.keys = sshKeys; - }; - - users.users.root.openssh.authorizedKeys.keys = sshKeys; - - home-manager = { - useUserPackages = true; - useGlobalPkgs = true; - backupFileExtension = "hm.bak"; - users.jalr = { pkgs, ... }: { - imports = [ ./modules ]; - config = { - home.stateVersion = config.system.stateVersion; - - home.packages = with pkgs; [ - cutecom - ghostscript - newsboat - pdftk - platformio - ptouch-print - qrencode - sshfs - tmate - - # common - asciinema - bat - envsubst - gnupg - nmap - psutils - pwgen - ]; - - xdg.mimeApps = { - enable = true; - defaultApplications = { - "application/pdf" = "org.gnome.Evince.desktop"; - - "image/svg+xml" = "org.inkscape.Inkscape.desktop"; - - "x-scheme-handler/http" = "firefox-esr.desktop"; - "x-scheme-handler/https" = "firefox-esr.desktop"; - - "x-scheme-handler/mailto" = "thunderbird.desktop"; - }; - }; - - accounts.email.accounts = { - "jalr" = { - primary = true; - userName = "jalr@jalr.de"; - address = "jalr@jalr.de"; - realName = "Jakob Lechner"; - imap = { - host = "hha.jalr.de"; - port = 143; - tls = { - enable = true; - useStartTls = true; - }; - }; - smtp = { - host = "hha.jalr.de"; - port = 465; - tls = { - enable = true; - useStartTls = false; - }; - }; - thunderbird = { - enable = true; - profiles = [ "default" ]; - }; - }; - "Digitaler Dienst" = { - userName = "j.lechner@digitaler-dienst.gmbh"; - address = "j.lechner@digitaler-dienst.gmbh"; - realName = "Jakob Lechner"; - imap = { - host = "mail.agenturserver.de"; - port = 143; - tls = { - enable = true; - useStartTls = true; - }; - }; - smtp = { - host = "mail.agenturserver.de"; - port = 465; - tls = { - enable = true; - useStartTls = false; - }; - }; - thunderbird = { - enable = true; - profiles = [ "default" ]; - }; - }; - "Digitaler Dienst info" = { - userName = "info@digitaler-dienst.gmbh"; - address = "info@digitaler-dienst.gmbh"; - realName = "Digitaler Dienst"; - imap = { - host = "mail.agenturserver.de"; - port = 143; - tls = { - enable = true; - useStartTls = true; - }; - }; - smtp = { - host = "mail.agenturserver.de"; - port = 587; - tls = { - enable = true; - useStartTls = true; - }; - }; - thunderbird = { - enable = true; - profiles = [ "default" ]; - }; - }; - "FabLab NEA" = { - userName = "kontakt@fablab-nea.de"; - address = "kontakt@fablab-nea.de"; - realName = "FabLab NEA"; - imap = { - host = "hha.jalr.de"; - port = 143; - tls = { - enable = true; - useStartTls = true; - }; - }; - smtp = { - host = "hha.jalr.de"; - port = 465; - tls = { - enable = true; - useStartTls = false; - }; - }; - thunderbird = { - enable = true; - profiles = [ "default" ]; - }; - }; - "Weinturm Open Air - IT" = { - userName = "it@weinturm-open-air.de"; - address = "it@weinturm-open-air.de"; - realName = "Weinturm Open Air IT"; - imap = { - host = "mail.agenturserver.de"; - port = 143; - tls = { - enable = true; - useStartTls = true; - }; - }; - smtp = { - host = "mail.agenturserver.de"; - port = 587; - tls = { - enable = true; - useStartTls = true; - }; - }; - thunderbird = { - enable = true; - profiles = [ "default" ]; - }; - }; - }; - }; - }; - }; -} diff --git a/users/jalr/modules/ardour.nix b/users/jalr/modules/ardour.nix deleted file mode 100644 index 4d3d5ac..0000000 --- a/users/jalr/modules/ardour.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - ardour - x42-plugins - ]; - home.sessionVariables.LV2_PATH = "${pkgs.x42-plugins}/lib/lv2/"; -} diff --git a/users/jalr/modules/cli/default.nix b/users/jalr/modules/cli/default.nix deleted file mode 100644 index 5ab60f5..0000000 --- a/users/jalr/modules/cli/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ nixosConfig, pkgs, ... }: -{ - imports = [ - ./htop.nix - ]; - - config = { - home.packages = with pkgs; [ - cached-nix-shell - fd - file - inetutils - jq - lsof - ncdu - ripgrep - tio - unzip - ] ++ (if ! nixosConfig.jalr.workstation.enable then [ ] else [ - dnsutils - screen - speedtest-cli - usbutils - wget - yt-dlp - ]); - }; -} diff --git a/users/jalr/modules/cli/htop.nix b/users/jalr/modules/cli/htop.nix deleted file mode 100644 index cc0b753..0000000 --- a/users/jalr/modules/cli/htop.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ nixosConfig -, config -, lib -, ... -}: - -{ - programs.htop = { - enable = true; - settings = { - color_scheme = 6; - } // (with config.lib.htop; leftMeters ([ - (bar "LeftCPUs") - (bar "Memory") - ] ++ lib.lists.optional nixosConfig.zramSwap.enable (bar "Zram") ++ lib.lists.optional (nixosConfig.swapDevices != [ ]) (bar "Swap") ++ [ - (bar "DiskIO") - ])) // (with config.lib.htop; rightMeters [ - (bar "RightCPUs") - (text "Tasks") - (text "LoadAverage") - (text "NetworkIO") - ]); - }; -} diff --git a/users/jalr/modules/communication/default.nix b/users/jalr/modules/communication/default.nix deleted file mode 100644 index f461097..0000000 --- a/users/jalr/modules/communication/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - imports = [ - ./ferdium.nix - ./mumble.nix - ]; -} diff --git a/users/jalr/modules/communication/ferdium.nix b/users/jalr/modules/communication/ferdium.nix deleted file mode 100644 index 1d0b4d5..0000000 --- a/users/jalr/modules/communication/ferdium.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ nixosConfig, lib, ... }: - -lib.mkIf nixosConfig.jalr.gui.enable { - xdg.desktopEntries.Ferdium = { - name = "Ferdium"; - exec = "flatpak run --branch=stable --arch=x86_64 --command=ferdium --file-forwarding org.ferdium.Ferdium @@u %U @@"; - terminal = false; - type = "Application"; - icon = "org.ferdium.Ferdium"; - comment = "Desktop app bringing all your messaging services into one installable"; - mimeType = [ "x-scheme-handler/ferdium" ]; - categories = [ "Network" "InstantMessaging" ]; - }; -} diff --git a/users/jalr/modules/dconf.nix b/users/jalr/modules/dconf.nix deleted file mode 100644 index eed759c..0000000 --- a/users/jalr/modules/dconf.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ lib, nixosConfig, ... }: - -lib.mkIf nixosConfig.jalr.gui.enable { - dconf.settings = { - "org/gnome/desktop/input-sources" = { - xkb-options = [ "grp:win_space_toggle" ]; - show-all-sources = true; - sources = [ - (lib.hm.gvariant.mkTuple [ "xkb" "de" ]) - (lib.hm.gvariant.mkTuple [ "xkb" "de+neo" ]) - (lib.hm.gvariant.mkTuple [ "xkb" "us" ]) - ]; - }; - }; -} diff --git a/users/jalr/modules/ddev.nix b/users/jalr/modules/ddev.nix deleted file mode 100644 index 2e154d2..0000000 --- a/users/jalr/modules/ddev.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = [ - pkgs.master.ddev - ]; -} diff --git a/users/jalr/modules/do-not-disturb/android-set-dnd.py b/users/jalr/modules/do-not-disturb/android-set-dnd.py deleted file mode 100755 index 13a7eba..0000000 --- a/users/jalr/modules/do-not-disturb/android-set-dnd.py +++ /dev/null @@ -1,28 +0,0 @@ -import os -import sys -from urllib import request - - -def read_url(): - try: - with open(os.getenv("NTFY_URL_FILE")) as f: - return f.read() - except FileNotFoundError: - return None - - -def set_android_dnd(active: bool): - url = read_url() - if url is not None: - request.urlopen( - request.Request( - read_url(), - method="POST", - data=("DND on" if active else "DND off").encode(), - ) - ) - - -if __name__ == "__main__": - _, state = sys.argv - set_android_dnd(state == "on") diff --git a/users/jalr/modules/do-not-disturb/default.nix b/users/jalr/modules/do-not-disturb/default.nix deleted file mode 100644 index 29b0c2f..0000000 --- a/users/jalr/modules/do-not-disturb/default.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: - -let - androidSetDnd = pkgs.writeScript "android-set-dnd" '' - #!${pkgs.python3}/bin/python3 - ${builtins.readFile ./android-set-dnd.py} - ''; - do-not-disturb = pkgs.writeShellScriptBin "dnd" '' - export PATH=${pkgs.lib.makeBinPath [pkgs.mako]} - - if [[ "$1" != off && "$1" != on ]]; then - echo "USAGE: $0 [on|off]" >&2 - exit 1 - fi - - export NTFY_URL_FILE=/run/secrets/ntfy_shiftphone - ${androidSetDnd} $1 - - if [[ $1 == on ]]; then - makoctl mode -a dnd > /dev/null - else - makoctl mode -r dnd > /dev/null - fi - ''; - -in -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = [ do-not-disturb ]; -} diff --git a/users/jalr/modules/firefox/default.nix b/users/jalr/modules/firefox/default.nix deleted file mode 100644 index 62b3eb5..0000000 --- a/users/jalr/modules/firefox/default.nix +++ /dev/null @@ -1,385 +0,0 @@ -{ nixosConfig, pkgs, ... }: -{ - programs.firefox = { - inherit (nixosConfig.jalr.gui) enable; - package = pkgs.firefox-esr.override { - nativeMessagingHosts = [ - pkgs.browserpass - ]; - }; - policies = { - AllowedDomainsForApps = ""; - CaptivePortal = false; - DNSOverHTTPS.Enabled = false; - DisableAppUpdate = true; - DisableFeedbackCommands = true; - DisableFirefoxAccounts = true; - DisableFirefoxScreenshots = true; - DisableFirefoxStudies = true; - DisablePocket = true; - DisableTelemetry = true; - DisplayBookmarksToolbar = "newtab"; - DisplayMenuBar = "never"; - EncryptedMediaExtensions = { Enabled = false; Locked = true; }; - NoDefaultBookmarks = true; - OfferToSaveLogins = false; - StartDownloadsInTempDirectory = true; - UserMessaging = { - WhatsNew = false; - ExtensionRecommendations = false; - FeatureRecommendations = false; - UrlbarInterventions = false; - SkipOnboarding = true; - MoreFromMozilla = false; - Locked = false; - }; - Permissions = { - Camera = { - /* - Allow = ["https://example.org" "https://example.org:1234"]; - Block = ["https://example.edu"]; - BlockNewRequests = true | false; - Locked = true | false; - */ - }; - Microphone = { }; - Location = { }; - Notifications = { }; - Autoplay = { }; - }; - PopupBlocking = { - /* Allow = ["http://example.org/" "http://example.edu/"]; */ - Default = false; - Locked = false; - }; - Bookmarks = ( - builtins.map - (b: b // { - Folder = "Nix"; - Placement = "toolbar"; - }) [ - { - Title = "NixOS Manual"; - URL = "https://nixos.org/manual/nixos/stable/"; - } - { - Title = "Nix manual"; - URL = "https://nix.dev/manual/nix/2.18/stable"; - } - { - Title = "Nixpkgs manual"; - URL = "https://nixos.org/manual/nixpkgs/stable/"; - } - { - Title = "Noogle"; - URL = "https://noogle.dev/"; - } - { - Title = "Home Manager Configuration Options"; - URL = "https://nix-community.github.io/home-manager/options.xhtml"; - } - { - Title = "Home Manager Option Search"; - URL = "https://mipmip.github.io/home-manager-option-search/"; - } - { - Title = "NixOS Status"; - URL = "https://status.nixos.org/"; - } - { - Title = "krops"; - URL = "https://cgit.krebsco.de/krops/about/"; - } - { - Title = "Awesome Nix"; - URL = "https://github.com/nix-community/awesome-nix"; - } - ] - ) ++ ( - builtins.map - (b: b // { - Folder = "Digitaler Dienst"; - Placement = "toolbar"; - }) [ - { - Title = "GitLab"; - URL = "https://gitlab.digitaler-dienst.net/"; - } - { - Title = "Moco"; - URL = "https://digitaler-dienst.mocoapp.com/activities"; - } - { - Title = "Leantime"; - URL = "https://todo.digitaler-dienst.gmbh/"; - } - { - Title = "Nextcloud"; - URL = "https://nx52865.your-storageshare.de/"; - } - { - Title = "FreeScout"; - URL = "https://tickets.digitaler-dienst.gmbh/"; - } - { - Title = "Personio"; - URL = "https://laemmermann.personio.de/"; - } - ] - ) ++ [ - { - Title = "Fefes Blog"; - URL = "https://blog.fefe.de"; - Placement = "toolbar"; - #Placement = "menu"; - #Favicon = "https://example.com/favicon.ico"; - } - ]; - /* - ManagedBookmarks = [ - { - toplevel_name = "My managed bookmarks folder"; - } - { - url = "example.com"; - name = "Example"; - } - { - name = "Mozilla links"; - children = [ - { - url = "https://mozilla.org"; - name = "Mozilla.org"; - } - { - url = "https://support.mozilla.org/"; - name = "SUMO"; - } - ]; - } - ]; - */ - SearchEngines = { - Default = "DuckDuckGo"; - Remove = [ - "Google" - "Wikipedia (en)" - ]; - Add = [ - { - Name = "Startpage"; - URLTemplate = "https://www.startpage.com/sp/search"; - Method = "POST"; - PostData = "qadf=none&query={searchTerms}"; - IconURL = "https://www.startpage.com/sp/cdn/favicons/mobile/android-icon-192x192.png"; - Alias = "sp"; - } - { - Name = "DuckDuckGo"; - URLTemplate = "https://duckduckgo.com/?q={searchTerms}"; - Method = "GET"; - IconURL = "https://duckduckgo.com/favicon.ico"; - Alias = "ddg"; - } - - # Wikipedia - { - Name = "Wikipedia en"; - URLTemplate = "https://en.wikipedia.org/wiki/Special:Search?search={searchTerms}"; - Method = "GET"; - IconURL = "https://en.wikipedia.org/static/images/icons/wikipedia.png"; - Alias = "wen"; - } - { - Name = "Wikipedia de"; - URLTemplate = "https://de.wikipedia.org/w/index.php?search={searchTerms}"; - Method = "GET"; - IconURL = "https://www.wikipedia.de/img/wikipedia.png"; - Alias = "wde"; - } - { - Name = "Nix Packages"; - URLTemplate = "https://search.nixos.org/packages?query={searchTerms}"; - Method = "GET"; - IconURL = "https://nixos.org/favicon.png"; - Alias = "pkg"; - } - { - Name = "NixOS Options"; - URLTemplate = "https://search.nixos.org/options?query={searchTerms}"; - Method = "GET"; - IconURL = "https://nixos.org/favicon.png"; - Alias = "opt"; - } - { - Name = "Docker images"; - URLTemplate = "https://hub.docker.com/search/?q={searchTerms}"; - Method = "GET"; - IconURL = "https://hub.docker.com/favicon.ico"; - Alias = "docker"; - } - { - Name = "GitHub"; - URLTemplate = "https://github.com/search?q={searchTerms}"; - Method = "GET"; - IconURL = "https://github.githubassets.com/favicons/favicon.svg"; - Alias = "gh"; - } - - # Shopping - { - Name = "Amazon de"; - URLTemplate = "https://www.amazon.de/s?k={searchTerms}"; - Method = "GET"; - IconURL = "https://www.amazon.de/favicon.ico"; - Alias = "amde"; - } - { - Name = "Ebay de"; - URLTemplate = "https://www.ebay.de/sch/i.html?_nkw={searchTerms}"; - Method = "GET"; - IconURL = "https://pages.ebay.com/favicon.ico"; - Alias = "ebde"; - } - - # Dictionary - { - Name = "dict.cc"; - URLTemplate = "https://www.dict.cc/?s={searchTerms}"; - Method = "GET"; - IconURL = "https://www4.dict.cc/img/favicons/favicon4.png"; - Alias = "dcc"; - } - { - Name = "Duden"; - URLTemplate = "https://www.duden.de/suchen/dudenonline/{searchTerms}"; - Method = "GET"; - IconURL = "https://www.duden.de/sites/default/res/apple-touch-icon/180x180.png"; - Alias = "duden"; - } - - # Map - { - Name = "OpenStreetMap"; - URLTemplate = "https://www.openstreetmap.org/search?query={searchTerms}"; - Method = "GET"; - IconURL = "https://www.openstreetmap.org/assets/favicon-194x194-79d3fb0152c735866e64b1d7535d504483cd13c2fad0131a6142bd9629d30de2.png"; - Alias = "osm"; - } - ]; - }; - }; - profiles.default = { - id = 0; - isDefault = true; - extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [ - browserpass - darkreader - sponsorblock - (tree-style-tab.override { - version = "4.1.6"; - url = "https://addons.mozilla.org/firefox/downloads/file/4488104/tree_style_tab-4.1.6.xpi"; - sha256 = "sha256-X0HC6jzytjBsM+8HmbK48DUihtdN9oCsqLUJqp29csQ="; - }) - ublock-origin - umatrix - violentmonkey - xdebug-helper-for-firefox - youtube-shorts-block - ]; - settings = { - #"browser.startup.homepage" = "https://nixos.org"; - #"browser.search.region" = "GB"; - #"browser.search.isUS" = false; - #"distribution.searchplugins.defaultLocale" = "en-GB"; - #"general.useragent.locale" = "en-GB"; - #"browser.bookmarks.showMobileBookmarks" = true; - "app.normandy.enabled" = false; - "app.shield.optoutstudies.enabled" = false; - "app.update.auto" = false; - "browser.bookmarks.addedImportButton" = false; - "browser.ctrlTab.sortByRecentlyUsed" = true; - "browser.fixup.alternate.enabled" = false; - "browser.formfill.enable" = false; - "browser.link.open_newwindow.restriction" = 0; - "browser.newtabpage.enabled" = false; - "browser.ping-centre.telemetry" = false; - "browser.safebrowsing.downloads.enabled" = false; - "browser.safebrowsing.downloads.remote.block_dangerous" = false; - "browser.safebrowsing.downloads.remote.block_dangerous_host" = false; - "browser.safebrowsing.downloads.remote.block_potentially_unwanted" = false; - "browser.safebrowsing.downloads.remote.block_uncommon" = false; - "browser.safebrowsing.downloads.remote.enabled" = false; - "browser.safebrowsing.downloads.remote.url" = ""; - "browser.safebrowsing.malware.enabled" = false; - "browser.safebrowsing.phishing.enabled" = false; - "browser.safebrowsing.provider.google.advisoryURL" = ""; - "browser.safebrowsing.provider.google.gethashURL" = ""; - "browser.safebrowsing.provider.google.lists" = ""; - "browser.safebrowsing.provider.google.reportMalwareMistakeURL" = ""; - "browser.safebrowsing.provider.google.reportPhishMistakeURL" = ""; - "browser.safebrowsing.provider.google.reportURL" = ""; - "browser.safebrowsing.provider.google.updateURL" = ""; - "browser.safebrowsing.provider.google4.advisoryURL" = ""; - "browser.safebrowsing.provider.google4.dataSharingURL" = ""; - "browser.safebrowsing.provider.google4.gethashURL" = ""; - "browser.safebrowsing.provider.google4.lists" = ""; - "browser.safebrowsing.provider.google4.reportMalwareMistakeURL" = ""; - "browser.safebrowsing.provider.google4.reportPhishMistakeURL" = ""; - "browser.safebrowsing.provider.google4.reportURL" = ""; - "browser.safebrowsing.provider.google4.updateURL" = ""; - "browser.safebrowsing.provider.mozilla.gethashURL" = ""; - "browser.safebrowsing.provider.mozilla.lists" = ""; - "browser.safebrowsing.provider.mozilla.updateURL" = ""; - "browser.search.suggest.enabled" = false; - "browser.search.widget.inNavBar" = true; - "browser.startup.page" = 0; - "extensions.pocket.enabled" = false; - "extensions.update.enabled" = false; - "identity.fxaccounts.enabled" = false; - "keyword.enabled" = false; - "network.captive-portal-service.enabled" = false; - "network.predictor.enabled" = false; - "privacy.donottrackheader.enabled" = true; - "startup.homepage_welcome_url" = "about:blank"; - "toolkit.legacyUserProfileCustomizations.stylesheets" = true; - "toolkit.telemetry.archive.enabled" = false; - "toolkit.telemetry.bhrPing.enabled" = false; - "toolkit.telemetry.firstShutdownPing.enabled" = false; - "toolkit.telemetry.newProfilePing.enabled" = false; - "toolkit.telemetry.server" = "http://127.0.0.1:4711"; - "toolkit.telemetry.server_owner" = ""; - "toolkit.telemetry.shutdownPingSender.enabled" = false; - "toolkit.telemetry.updatePing.enabled" = false; - "urlclassifier.downloadAllowTable" = ""; - "urlclassifier.downloadBlockTable" = ""; - "urlclassifier.malwareTable" = ""; - "urlclassifier.phishTable" = ""; - "datareporting.healthreport.uploadEnabled" = ""; - "app.normandy.api_url" = ""; - "breakpad.reportURL" = ""; - "browser.region.network.url" = ""; - "browser.search.geoSpecificDefaults.url" = ""; - "browser.shell.checkDefaultBrowser" = false; - - "privacy.userContext.enabled" = true; - "privacy.userContext.ui.enabled" = true; - "network.dnsCacheExpiration" = 0; - - # disable disk cache to reduce ssd writes - "browser.cache.disk.enable" = false; - "browser.cache.memory.enable" = true; - "browser.cache.memory.capacity" = -1; - }; - - userChrome = builtins.readFile ./userChrome.css; - }; - }; - - programs.browserpass = { - enable = true; - browsers = [ "firefox" ]; - }; - - xdg.configFile."treestyletab.css".source = ./treestyletab.css; -} diff --git a/users/jalr/modules/firefox/treestyletab.css b/users/jalr/modules/firefox/treestyletab.css deleted file mode 100644 index b5b430a..0000000 --- a/users/jalr/modules/firefox/treestyletab.css +++ /dev/null @@ -1,17 +0,0 @@ -@media (prefers-color-scheme: light) { - tab-item:not(.active):not(.bundled-active):not(.highlighted), - #background { - --toolbar-non-lwt-bgcolor: ThreeDShadow; - --toolbar-non-lwt-textcolor: ButtonText; - } -} - -@media (prefers-color-scheme: dark) { - #tabbar { - background-color: var(--in-content-page-background); - } -} - -tab-item.coloredTabsHue0 tab-item-substance { - background: transparent; -} diff --git a/users/jalr/modules/fish.nix b/users/jalr/modules/fish.nix deleted file mode 100644 index f929e20..0000000 --- a/users/jalr/modules/fish.nix +++ /dev/null @@ -1,206 +0,0 @@ -{ config, pkgs, ... }: -{ - home.packages = with pkgs; [ - fzf - ]; - programs.fish = { - enable = true; - plugins = [ - { - name = "theme-agnoster"; - src = pkgs.fetchFromGitHub { - owner = "oh-my-fish"; - repo = "theme-agnoster"; - rev = "4c5518c89ebcef393ef154c9f576a52651400d27"; - sha256 = "OFESuesnfqhXM0aij+79kdxjp4xgCt28YwTrcwQhFMU="; - fetchSubmodules = true; - }; - } - { - name = "fzf"; - src = pkgs.fetchFromGitHub { - owner = "jethrokuan"; - repo = "fzf"; - rev = "479fa67d7439b23095e01b64987ae79a91a4e283"; - sha256 = "0k6l21j192hrhy95092dm8029p52aakvzis7jiw48wnbckyidi6v"; - fetchSubmodules = true; - }; - } - ]; - shellAliases = { - ls = if config.programs.lsd.enable then "lsd" else "ls --color=auto"; - crontab = "crontab -i"; - }; - - shellAbbrs = { - lessr = "less -R"; - jqc = "jq -C"; - }; - - #interactiveShellInit = '' - # echo "programs.fish.interactiveShellInit" - #''; - shellInit = '' - # key bindings - bind \cr '__fzf_reverse_isearch' - - # PATH - set -U fish_user_paths $HOME/.local/bin $HOME/.local/bin/pio - - # pass - #set -x PASSWORD_STORE_ENABLE_EXTENSIONS true - set -x AWS_VAULT_BACKEND pass - set -x AWS_VAULT_PASS_PREFIX aws - complete -c pw --no-files -a '(__fish_pass_print_entries)' - - # colors - set -x GCC_COLORS 'error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' - - abbr --add v vim - - #alias cal='ncal -b -M' - alias myip='dig +short myip.opendns.com @resolver1.opendns.com' - - history --merge >/dev/null 2>&1 - - # fancy tools - if which lsd > /dev/null 2>&1 - abbr --add l "lsd" - abbr --add ll "lsd -l --date +'%Y-%m-%d %H:%M:%S'" - abbr --add la "lsd -la --date +'%Y-%m-%d %H:%M:%S'" - abbr --add tree "lsd --tree" - abbr --add llt "lsd -l --timesort --date relative -r" - else - abbr --add l ls - abbr --add ll 'ls -l' - abbr --add la 'ls -la' - abbr --add llt 'ls -trl' - end - - if which rg > /dev/null 2>&1 - abbr --add g rg - complete -c g -w rg - else if which ag > /dev/null 2>&1 - abbr --add g ag - complete -c g -w ag - else - abbr --add g 'grep --color=auto' - complete -c g -w grep - end - - - # NixOS direnv - if which direnv > /dev/null - eval (direnv hook fish) - end - - bind \ed 'dirh-fzf' - - # fix too dark color on solarized theme - set -g fish_color_autosuggestion brgreen - - if type -q fish_set_git_author_by_pwd - fish_set_git_author_by_pwd - end - ''; - - functions = { - jqless = { - body = '' - jq -C $argv | less -R - ''; - }; - __cut_commandline = { - description = "cut commandline and paste it later"; - body = '' - set -g commandline_buffer (commandline) - commandline "" - ''; - }; - __postexec = { - onEvent = "fish_postexec"; - body = '' - if test $status -ne 0; and test -z "$hist_cmd"; and test -z "$fish_private_mode" - #$SHELL -c " - history delete --exact --case-sensitive -- $argv[1] - #" & - end - ''; - }; - dirh-nocolor = { - description = "Print the current directory history (the prev and next lists)"; - body = '' - set -l options h/help - argparse -n dirh --max-args=0 $options -- $argv - or return - - if set -q _flag_help - __fish_print_help dirh - return 0 - end - - set -l dirc (count $dirprev) - if test $dirc -gt 0 - set -l dirprev_rev $dirprev[-1..1] - # This can't be (seq $dirc -1 1) because of BSD. - set -l dirnum (seq 1 $dirc) - for i in $dirnum[-1..1] - printf '%s\n' $dirprev_rev[$i] - end - end - - echo $PWD - - set -l dirc (count $dirnext) - if test $dirc -gt 0 - set -l dirnext_rev $dirnext[-1..1] - for i in (seq $dirc) - printf '%s\n' $dirnext_rev[$i] - end - end - ''; - }; - dirh-fzf = { - description = "directory history fuzzy finder"; - body = '' - builtin cd (dirh-nocolor | uniq | fzf) - ''; - }; - }; - }; - - xdg.configFile = { - "fish/completions/mycli.fish".text = '' - complete -e -c mycli - complete -c mycli -f - complete -c mycli -f -s h -l host -d "Host address of the database." - complete -c mycli -f -s P -l port -d "Port number to use for connection." - complete -c mycli -f -s u -l user -d "User name to connect to the database." - complete -c mycli -f -s S -l socket -d "The socket file to use for connection." - complete -c mycli -f -s p -l pass \ - -l password -d "Password to connect to the database." - complete -c mycli -f -s V -l version -d "Output mycli's version." - complete -c mycli -f -s v -l verbose -d "Verbose output." - complete -c mycli -f -s d -l dsn -d "Use DSN configured into the [alias_dsn] section of myclirc file." - complete -c mycli -f -l list-dsn -d "list of DSN configured into the [alias_dsn] section of myclirc file." - - complete -c mycli -f -s t -l table -d "Display batch output in table format." - complete -c mycli -f -l csv -d "Display batch output in CSV format." - complete -c mycli -f -l warn \ - -l no-warn -d "Warn before running a destructive query." - complete -c mycli -f -s e -l execute -d "Execute command and quit." - - - complete -c mycli -f -s h -l host -r -a '(__fish_print_hostnames)' - complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)' - ''; - - "fish/completions/myssh.fish".text = '' - complete -c myssh -f -a '(myssh --list)' - ''; - - "fish/completions/just.fish".source = pkgs.runCommand "just-fish-completions" { } '' - ${pkgs.just}/bin/just --completions fish > $out - ''; - }; -} diff --git a/users/jalr/modules/freetube.nix b/users/jalr/modules/freetube.nix deleted file mode 100644 index 3c45d96..0000000 --- a/users/jalr/modules/freetube.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ nixosConfig, ... }: - -{ - programs.freetube = { - inherit (nixosConfig.jalr.gui) enable; - }; -} diff --git a/users/jalr/modules/gui.nix b/users/jalr/modules/gui.nix deleted file mode 100644 index 4bc6762..0000000 --- a/users/jalr/modules/gui.nix +++ /dev/null @@ -1,72 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: -lib.mkIf nixosConfig.jalr.gui.enable { - home.pointerCursor = { - package = pkgs.gnome-themes-extra; - name = "Adwaita"; - size = lib.mkDefault 16; - }; - - home.packages = with pkgs; [ - evince - exiftool - geeqie - libreoffice-qt6-fresh - mpv - networkmanagerapplet - streamlink - supersonic-wayland - vlc - xdg-utils - xfce.mousepad - ]; - - services.kanshi = - let - internalDisplay = { - criteria = "BOE 0x0BC9 Unknown"; - status = "enable"; - mode = "2560x1600"; - }; - in - { - enable = true; - settings = [ - { - profile.name = "laemmermann"; - profile.outputs = [ - { - criteria = "ViewSonic Corporation VX3276-QHD VSX2403A0490"; - status = "enable"; - mode = "2560x1440@59.951Hz"; - position = "0,0"; - } - { - criteria = "ViewSonic Corporation VX3276-QHD VSX2351A0801"; - status = "enable"; - mode = "2560x1440@59.951Hz"; - position = "2560,0"; - } - (internalDisplay // { position = "5120,0"; }) - ]; - } - { - profile.name = "digitaler-dienst"; - profile.outputs = [ - { - criteria = "Lenovo Group Limited L27q-35 URB5T16W"; - status = "enable"; - mode = "2560x1440@59.951Hz"; - position = "0,0"; - } - { - criteria = "Lenovo Group Limited L27q-35 URB5T174"; - status = "enable"; - mode = "2560x1440@59.951Hz"; - position = "2560,0"; - } - (internalDisplay // { position = "5120,0"; }) - ]; - } - ]; - }; -} diff --git a/users/jalr/modules/jameica.nix b/users/jalr/modules/jameica.nix deleted file mode 100644 index e50c86e..0000000 --- a/users/jalr/modules/jameica.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = [ - ( - pkgs.jameica.overrideAttrs (_: { - version = "2.11.0-nightly"; - src = pkgs.fetchFromGitHub { - owner = "willuhn"; - repo = "jameica"; - rev = "e51bffc0e42907cbd802a644ab52810e0a36fff8"; - hash = "sha256-0KcT52dh/tJSX6q+uKkRybz33jKnYRTNDo1BftwJLAc="; - }; - }) - ) - ]; -} diff --git a/users/jalr/modules/lsd/colors-dark.yaml b/users/jalr/modules/lsd/colors-dark.yaml deleted file mode 100644 index 40165eb..0000000 --- a/users/jalr/modules/lsd/colors-dark.yaml +++ /dev/null @@ -1,27 +0,0 @@ -user: 125 -group: 136 -permission: - read: 166 - write: 64 - exec: 160 - exec-sticky: 125 - no-access: 245 - octal: 37 - acl: 37 - context: 245 -date: - hour-old: 64 - day-old: 136 - older: 240 -size: - none: 160 - small: 61 - medium: 37 - large: 33 -inode: - valid: 64 - invalid: 160 -links: - valid: 61 - invalid: 240 -tree-edge: 245 diff --git a/users/jalr/modules/lsd/colors-light.yaml b/users/jalr/modules/lsd/colors-light.yaml deleted file mode 100644 index bbbbe59..0000000 --- a/users/jalr/modules/lsd/colors-light.yaml +++ /dev/null @@ -1,27 +0,0 @@ -user: 125 -group: 136 -permission: - read: 166 - write: 64 - exec: 160 - exec-sticky: 125 - no-access: 234 - octal: 37 - acl: 37 - context: 235 -date: - hour-old: 64 - day-old: 136 - older: 240 -size: - none: 160 - small: 61 - medium: 37 - large: 33 -inode: - valid: 61 - invalid: 160 -links: - valid: 61 - invalid: 235 -tree-edge: 235 diff --git a/users/jalr/modules/lsd/default.nix b/users/jalr/modules/lsd/default.nix deleted file mode 100644 index 5547aee..0000000 --- a/users/jalr/modules/lsd/default.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ lib, nixosConfig, ... }: - -lib.mkIf nixosConfig.jalr.workstation.enable { - programs.lsd = { - enable = true; - enableFishIntegration = false; - settings = { - color.theme = "custom"; - }; - icons = { - extension = { - dxf = "📏"; - flac = "🎶"; - json = "🄹"; - md = "📝"; - mp3 = "🎶"; - opus = "🎶"; - scad = "🔩"; - wav = "🎶"; - yaml = "🅈"; - yml = "🅈"; - zip = "📦"; - }; - name = { - ".envrc" = ""; - Justfile = ""; - justfile = ""; - public = "📢"; - }; - }; - }; - xdg.configFile."lsd/colors-light.yaml".source = ./colors-light.yaml; - xdg.configFile."lsd/colors-dark.yaml".source = ./colors-dark.yaml; -} diff --git a/users/jalr/modules/mixxc/default.nix b/users/jalr/modules/mixxc/default.nix deleted file mode 100644 index efde8d1..0000000 --- a/users/jalr/modules/mixxc/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: - -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - mixxc - ]; - xdg.configFile = { - "mixxc/style.css".source = ./style.css; - }; -} diff --git a/users/jalr/modules/mixxc/style.css b/users/jalr/modules/mixxc/style.css deleted file mode 100644 index 33dbf39..0000000 --- a/users/jalr/modules/mixxc/style.css +++ /dev/null @@ -1,224 +0,0 @@ -.side { - $hide: false; - - .output { - transition: background 750ms; - padding: 5px; - - &.master { - transition: background 0ms; - } - - &.master:hover { - } - - .icon { - -gtk-icon-style: symbolic; - -gtk-icon-size: 16px; - } - } - - @if $hide { - min-height: 0; - min-width: 0; - - .output { - padding: 0; - - .icon { - -gtk-icon-style: symbolic; - -gtk-icon-size: 0; - } - } - } -} - -.main { - margin: 20px; -} - -.client { - $hide-name: false; - $hide-description: false; - - font-family: 'Iosevka Nerd Font'; - font-size: 1.2em; - - .icon { - -gtk-icon-style: symbolic; - } - - @if $hide-name { - .name { - font-size: 0; - } - } - - @if $hide-description { - .description { - font-size: 0; - } - } - - scale { - trough { - /* Slider Bar */ - border-radius: 10px; - - slider { - /* Slider Knob */ - padding: 0; - - border: none; - border-radius: 2px; - - transition-duration: 400ms; - } - - highlight { - /* Slider Bar Filled */ - border: none; - border-radius: 10px; - - margin: 2px; - - transition: background-image 300ms; - } - - fill { - /* Slider Peak */ - background: none; - - border-radius: 10px; - - margin: 0px; - } - } - } - - scale:active { - trough slider { - /* Slider Knob */ - transform: scale(1.1); - } - } -} - -.client.horizontal { - &.new { - animation: client-add-horizontal 300ms ease; - } - - &.removed { - animation: client-remove-horizontal 300ms ease; - } - - .icon { - padding-right: 13px; - - -gtk-icon-size: 16px; - } - - .volume { - /* Numeric Volume Level */ - padding-left: 22px; - padding-bottom: 3px; - } - - scale { - trough { - /* Slider Bar */ - min-height: 6px; - - slider { - /* Slider Knob */ - min-height: 21px; - min-width: 9px; - - margin-top: -7px; - margin-bottom: -7px; - } - } - } - -} - -@keyframes client-add-horizontal { - from { - transform: translateX(-200px); - opacity: 0; - } - to { - opacity: 1; - } -} - -@keyframes client-remove-horizontal { - from { - opacity: 1; - } - to { - transform: translateX(-200px); - opacity: 0; - } -} - -.client.vertical { - &.new { - animation: client-add-vertical 300ms ease; - } - - &.removed { - animation: client-remove-vertical 300ms ease; - } - - .icon { - padding-bottom: 5px; - - -gtk-icon-size: 20px; - } - - .volume { - /* Numeric Volume Level */ - padding-top: 10px; - } - - scale { - trough { - /* Slider Bar */ - min-width: 4px; - - margin-top: 10px; - - slider { - /* Slider Knob */ - margin-left: -7px; - margin-right: -7px; - - min-height: 6px; - min-width: 14px; - } - } - } -} - -@keyframes client-add-vertical { - from { - transform: translateY(200px); - opacity: 0; - } - to { - opacity: 1; - } -} - -@keyframes client-remove-vertical { - from { - opacity: 1; - } - to { - transform: translateY(200px); - opacity: 0; - } -} - diff --git a/users/jalr/modules/mycli/default.nix b/users/jalr/modules/mycli/default.nix deleted file mode 100644 index 844102b..0000000 --- a/users/jalr/modules/mycli/default.nix +++ /dev/null @@ -1,173 +0,0 @@ -{ lib, pkgs, ... }: -let - quoteValues = ini: lib.mapAttrs - (_: attrs: - lib.mapAttrs (_: value: if builtins.isString value then ''"${value}"'' else value) attrs - ) - ini; - - solarized = import ../solarized.nix; - - config = { - main = { - # Enables context sensitive auto-completion. If this is disabled the all - # possible completions will be listed. - smart_completion = true; - - # Multi-line mode allows breaking up the sql statements into multiple lines. If - # this is set to True, then the end of the statements must have a semi-colon. - # If this is set to False then sql statements can't be split into multiple - # lines. End of line (return) is considered as the end of the statement. - multi_line = false; - - # Destructive warning mode will alert you before executing a sql statement - # that may cause harm to the database such as "drop table", "drop database" - # or "shutdown". - destructive_warning = true; - - # log_file location. - log_file = "~/.mycli.log"; - - # Default log level. Possible values: "CRITICAL", "ERROR", "WARNING", "INFO" - # and "DEBUG". "NONE" disables logging. - log_level = "INFO"; - - # Log every query and its results to a file. Enable this by uncommenting the - # line below. - # audit_log = "~/.mycli-audit.log"; - - # Timing of sql statments and table rendering. - timing = true; - - # Table format. Possible values: ascii, double, github, - # psql, plain, simple, grid, fancy_grid, pipe, orgtbl, rst, mediawiki, html, - # latex, latex_booktabs, textile, moinmoin, jira, vertical, tsv, csv. - # Recommended: ascii - table_format = "pipe"; - - # Syntax coloring style. Possible values (many support the "-dark" suffix): - # manni, igor, xcode, vim, autumn, vs, rrt, native, perldoc, borland, tango, emacs, - # friendly, monokai, paraiso, colorful, murphy, bw, pastie, paraiso, trac, default, - # fruity. - # Screenshots at http://mycli.net/syntax - # Can be further modified in [colors] - syntax_style = "native"; - - # Keybindings: Possible values: emacs, vi. - # Emacs mode: Ctrl-A is home, Ctrl-E is end. All emacs keybindings are available in the REPL. - # When Vi mode is enabled you can use modal editing features offered by Vi in the REPL. - key_bindings = "emacs"; - - # Enabling this option will show the suggestions in a wider menu. Thus more items are suggested. - wider_completion_menu = false; - - # MySQL prompt - # \D - The full current date - # \d - Database name - # \h - Hostname of the server - # \m - Minutes of the current time - # \n - Newline - # \P - AM/PM - # \p - Port - # \R - The current time, in 24-hour military time (0–23) - # \r - The current time, standard 12-hour time (1–12) - # \s - Seconds of the current time - # \t - Product type (Percona, MySQL, MariaDB) - # \A - DSN alias name (from the [alias_dsn] section) - # \u - Username - # \x1b[...m - insert ANSI escape sequence - prompt = "\\u@\\A:\\d> "; - prompt_continuation = "-> "; - - # Skip intro info on startup and outro info on exit - less_chatty = false; - - # Use alias from --login-path instead of host name in prompt - login_path_as_host = false; - - # Cause result sets to be displayed vertically if they are too wide for the current window, - # and using normal tabular format otherwise. (This applies to statements terminated by ; or \G.) - auto_vertical_output = false; - - # keyword casing preference. Possible values "lower", "upper", "auto" - keyword_casing = "upper"; - - # disabled pager on startup - enable_pager = true; - }; - # Favorite queries. - favorite_queries = { }; - - # Use the -d option to reference a DSN. - # Special characters in passwords and other strings can be escaped with URL encoding. - alias_dsn = { - # example_dsn = "mysql://[user[:password]@][host][:port][/dbname]"; - }; - }; - - colors = - let - c = solarized.colors; - in - { - common = { - "output.header" = "bold ${c.green}"; - "sql.datatype" = "nobold ${c.yellow}"; - "sql.function" = "bold ${c.violet}"; - "sql.keyword" = c.green; - "sql.literal" = c.green; - "sql.number" = c.cyan; - "sql.string" = c.cyan; - "sql.variable" = c.red; - "sql.quoted-schema-object" = c.blue; - }; - light = { - "prompt" = "bg:${c.blue} ${c.base02}"; - "selected" = "bg:${c.base2} ${c.base00}"; - "output.odd-row" = "${c.base01}"; - "output.even-row" = "${c.base01} bg:${c.base2}"; - "sql.comment" = "italic ${c.base1}"; - "sql.operator" = "bold ${c.base02}"; - "sql.punctuation" = "bold ${c.base01}"; - "sql.symbol" = "${c.base01}"; - }; - dark = { - "prompt" = "bg:${c.blue} ${c.base2}"; - "selected" = "bg:${c.base02} ${c.base0}"; - "output.odd-row" = "${c.base1}"; - "output.even-row" = "${c.base1} bg:${c.base02}"; - "sql.comment" = "italic ${c.base01}"; - "sql.operator" = "bold ${c.base2}"; - "sql.punctuation" = "bold ${c.base1}"; - "sql.symbol" = "${c.base1}"; - }; - }; -in -{ - home.packages = [ - (pkgs.mycli.overridePythonAttrs (old: { - dependencies = old.dependencies ++ [ pkgs.python3Packages.sshtunnel ]; - })) - (pkgs.stdenv.mkDerivation { - name = "myssh"; - propagatedBuildInputs = [ - (pkgs.python3.withPackages (pp: with pp; [ - pyyaml - ])) - ]; - dontUnpack = true; - installPhase = "install -Dm755 ${./myssh.py} $out/bin/myssh"; - }) - ]; - - xdg.configFile = lib.attrsets.mapAttrs' - ( - name: value: lib.attrsets.nameValuePair "mycli/theme-${name}.ini" { - text = lib.generators.toINI { } (quoteValues (config // { colors = value; })); - } - ) - { - light = colors.common // colors.light; - dark = colors.common // colors.dark; - }; -} diff --git a/users/jalr/modules/mycli/myssh.py b/users/jalr/modules/mycli/myssh.py deleted file mode 100755 index c79b430..0000000 --- a/users/jalr/modules/mycli/myssh.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python - -import argparse -import json -import os -import subprocess -import sys -import yaml - - -def get_db_connecition_from_typo3_config(ssh_host, ssh_user, config_file): - php_code = """ - 1 - } - - -def connect(connection_name, connection): - if "t3_config" in connection: - db = get_db_connecition_from_typo3_config( - connection["ssh_host"], connection["ssh_user"], connection["t3_config"] - ) - db_host = db["host"] - db_user = db["user"] - db_password = db["password"] - db_name = db["dbname"] - elif "staging_level" in connection: - env = get_db_connection_from_env_file( - connection["ssh_host"], connection["ssh_user"], connection["staging_level"] - ) - db_host = env["TYPO3_DB_HOST"] - db_user = env["TYPO3_DB_USER"] - db_password = env["TYPO3_DB_PASSWORD"] - db_name = env["TYPO3_DB_DATABASE"] - - os.execl( - "/usr/bin/env", - "env", - "mycli", - "--prompt", - f"{connection_name}>", - "--ssh-user", - connection["ssh_user"], - "--ssh-host", - connection["ssh_host"], - "-h", - db_host, - "-u", - db_user, - "-p", - db_password, - db_name, - ) - - -def read_config(path): - with open(path, "r") as fh: - config = yaml.safe_load(fh.read()) - - return config - - -def main(): - connections = read_config(os.path.expanduser("~/.config/mycli/connections.yaml")) - - parser = argparse.ArgumentParser() - parser.add_argument("--list", action="store_true") - parser.add_argument("connection", type=str, nargs="?") - - args = vars(parser.parse_args()) - - if args["list"]: - print("\n".join(connections.keys())) - - if args["connection"] is not None: - connect(args["connection"], connections[args["connection"]]) - - -if __name__ == "__main__": - main() diff --git a/users/jalr/modules/neovim/default.nix b/users/jalr/modules/neovim/default.nix deleted file mode 100644 index 03b8b0b..0000000 --- a/users/jalr/modules/neovim/default.nix +++ /dev/null @@ -1,305 +0,0 @@ -{ lib, nixosConfig, config, pkgs, ... }: - -let - fakePlugin = pkgs.runCommand "neovim-fake-plugin" { } "mkdir $out"; -in -{ - programs.neovim = { - enable = true; - vimAlias = true; - defaultEditor = true; - extraConfig = '' - """"""""""""""""" - " Swap and undo " - set noswapfile - set nobackup - if has('persistent_undo') - " yay persistent undo - :silent !mkdir -p ~/.local/vim-undo - set undofile - set undodir=~/.local/vim-undo - endif - - cabbr %% expand('%:p:h') - - set listchars=trail:·,precedes:«,extends:»,eol:↲,tab:▸\ - nmap c :set list! - - set smartcase - set hlsearch - nnoremap :nohlsearch:set nolist - - " highlight whitespace - highlight ExtraWhitespace ctermbg=red guibg=red - highlight WrongIndent ctermbg=2 guibg=blue - match ExtraWhitespace /\s\+$/ - augroup highlight_extra_whitespace - autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ - autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@ e lua vim.diagnostic.enable(not vim.diagnostic.is_enabled()) - nnoremap i lua vim.diagnostic.open_float() - nnoremap gd lua vim.lsp.buf.definition() - nnoremap gi lua vim.lsp.buf.implementation() - nnoremap gr lua vim.lsp.buf.references() - nnoremap gD lua vim.lsp.buf.declaration() - nnoremap ge lua vim.lsp.diagnostic.set_loclist() - nnoremap K lua vim.lsp.buf.hover() - nnoremap f lua vim.lsp.buf.formatting() - nnoremap rn lua vim.lsp.buf.rename() - - nnoremap dh lua require('dap.ui.widgets').hover() - nnoremap dp lua require('dap.ui.widgets').preview() - nnoremap dc lua require('dap').continue() - nnoremap do lua require('dap').step_over() - nnoremap di lua require('dap').step_into() - nnoremap dn lua require('dap').step_out() - nnoremap b lua require('dap').toggle_breakpoint() - - nnoremap a lua vim.lsp.buf.code_action() - xmap a lua vim.lsp.buf.range_code_action() - - lua require('init') - ''; - - plugins = [ - { - plugin = fakePlugin; - config = '' - " use space as leader - let mapleader = " " - ''; - } - ] ++ - # nix-env -f '' -qaP -A vimPlugins - (with pkgs.vimPlugins; [ - { - plugin = NeoSolarized; - config = '' - colorscheme NeoSolarized - ''; - } - { - plugin = nvim-dap; - type = "lua"; - config = '' - local dap = require('dap') - dap.adapters.php = { - type = "executable", - command = "${pkgs.nodejs}/bin/node", - args = { "${pkgs.vscode-extensions.xdebug.php-debug}/share/vscode/extensions/xdebug.php-debug/out/phpDebug.js" } - } - - dap.configurations.php = { - { - type = "php", - request = "launch", - name = "Listen for Xdebug", - port = 9003, - --stopOnEntry = true, - pathMappings = { - ["/app/"] = vim.fn.getcwd().."/", - }, - log = true, - hostname = "0.0.0.0", - } - } - - vim.api.nvim_create_autocmd( - "FileType", { - pattern = "dap-float", - callback = function() - vim.api.nvim_buf_set_keymap(0, "n", "q", "close!", { noremap = true, silent = true }) - end - } - ) - ''; - } - deoplete-nvim - editorconfig-vim - jinja-vim - nvim-lspconfig - { - plugin = telescope-nvim; - type = "lua"; - config = '' - require('telescope').setup() - vim.keymap.set('n', '', 'Telescope find_files') - vim.keymap.set('n', '', 'Telescope live_grep') - vim.keymap.set('n', '', 'Telescope buffers') - ''; - } - { - plugin = telescope-ultisnips-nvim; - type = "lua"; - config = '' - require('telescope').load_extension('ultisnips') - ''; - } - nvim-treesitter-parsers.twig - { - plugin = nvim-treesitter; - type = "lua"; - config = '' - require'nvim-treesitter.configs'.setup { highlight = { enable = true, }, } - ''; - } - { - plugin = ultisnips; - config = ''; - let g:UltiSnipsSnippetDirectories = [ "UltiSnips" ] - inoremap :Telescope ultisnips - ''; - } - { - plugin = vim-fluid; - config = '' - au BufRead *.html if join(getline(1,3), "\n") =~ 'data-namespace-typo3-fluid="true"' | setlocal filetype=fluid | endif - ''; - } - vim-gitgutter - vim-indent-guides - vim-nix - vim-terraform - vim-typoscript - ( - lib.mkIf nixosConfig.jalr.workstation.enable { - plugin = lsp_signature-nvim; - type = "lua"; - config = "require('lsp_signature').setup()"; - } - ) - ]); - }; - - xdg.configFile = { - "nvim/ftplugin/gitcommit.vim".text = '' - setlocal spell - setlocal colorcolumn=73 - ''; - "nvim/ftplugin/markdown.vim".text = '' - setlocal spell - setlocal colorcolumn=81 - ''; - "nvim/ftplugin/sshconfig.vim".text = '' - setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab - ''; - "nvim/lua/init.lua".text = builtins.concatStringsSep "\n" ( - [ - '' - -- init.lua - -- this configuration applies to servers and workstations - '' - ] ++ lib.optional nixosConfig.jalr.workstation.enable ( - '' - -- this configuration applies to workstations only - -- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md - local lsp = require('lspconfig') - - -- show linter messages - vim.diagnostic.config({ virtual_text = true }) - '' + - builtins.concatStringsSep "\n" ( - lib.mapAttrsToList - ( - lang: cfg: "lsp.${lang}.setup\n" + lib.generators.toLua { } cfg - ) - { - # C and C++ - ccls = { - cmd = [ "${pkgs.ccls}/bin/ccls" ]; - }; - - # Nix - nixd = { - cmd = [ "${pkgs.nixd}/bin/nixd" ]; - }; - - # PHP - phpactor = { - cmd = [ "${pkgs.phpactor}/bin/phpactor" "language-server" ]; - init_options = { - "language_server.diagnostic_ignore_codes" = [ - "worse.docblock_missing_param" - "worse.docblock_missing_return_type" - ]; - }; - }; - - # Python - pylsp = { - cmd = [ "${pkgs.python3Packages.python-lsp-server}/bin/pylsp" ]; - settings = { - # https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md - pylsp = { - plugins = { - flake8 = { - enabled = true; - executable = "${pkgs.python3Packages.flake8}/bin/flake8"; - }; - jedi_completion = { enabled = true; }; - jedi_definition = { enabled = true; }; - jedi_hover = { enabled = true; }; - jedi_references = { enabled = true; }; - jedi_signature_help = { enabled = true; }; - jedi_symbols = { enabled = true; }; - mccabe = { enabled = true; }; - lsp_signature-nvim = { enabled = true; }; - preload = { enabled = true; }; - pycodestyle = { enabled = true; }; - pyflakes = { enabled = true; }; - rope_completion = { enabled = true; }; - yapf = { enabled = true; }; - }; - }; - }; - }; - - # Ruby - solargraph = { - cmd = [ "${pkgs.solargraph}/bin/solargraph" "stdio" ]; - }; - - # Rust - rust_analyzer = { - cmd = [ "${pkgs.rust-analyzer}/bin/rust-analyzer" ]; - }; - - # Bash - bashls = { - cmd = [ "${pkgs.nodePackages.bash-language-server}/bin/bash-language-server" "start" ]; - }; - - # Terraform - terraformls = { - cmd = [ "${pkgs.terraform-ls}/bin/terraform-ls" "serve" ]; - }; - - # YAML - yamlls = { - cmd = [ "${pkgs.nodePackages.yaml-language-server}/bin/yaml-language-server" "--stdio" ]; - settings = { - yaml = { - keyOrdering = false; - }; - }; - }; - } - ) - ) - ); - }; -} diff --git a/users/jalr/modules/nix-index.nix b/users/jalr/modules/nix-index.nix deleted file mode 100644 index c753a5e..0000000 --- a/users/jalr/modules/nix-index.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - programs.nix-index = { - enable = true; - }; -} diff --git a/users/jalr/modules/ots.nix b/users/jalr/modules/ots.nix deleted file mode 100644 index 4f3e85c..0000000 --- a/users/jalr/modules/ots.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ pkgs, ... }: - -{ - home.packages = [ - ( - pkgs.writeShellScriptBin "ots" '' - set -e - set -o nounset - - args=() - region="" - new="" - while [[ $# -gt 0 ]]; do - case "$1" in - new) - new=1 - args+=("$1"); shift - ;; - --region|--region=*) - region=1 - args+=("$1"); shift - ;; - *) - args+=("$1"); shift - ;; - esac - done - - if [[ $new && ! $region ]]; then - args+=("--region" "eu-central-1") - fi - - exec ${pkgs.ots}/bin/ots "''${args[@]}" - '' - ) - ]; - - /* - xdg.configFile."${configFile}".text = lib.generators.toJSON {} ( - let - region = "eu-central-1"; - in - { - apiUrl = "https://ots.${region}.api.sniptt.com/secrets"; - apiKey = ""; - } - ); - */ -} diff --git a/users/jalr/modules/pace.nix b/users/jalr/modules/pace.nix deleted file mode 100644 index 0a0b43f..0000000 --- a/users/jalr/modules/pace.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ config, nixosConfig, lib, pkgs, ... }: - - -let - tomlFormat = pkgs.formats.toml { }; -in -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - pace - ]; - - home.sessionVariables.PACE_HOME = "${config.xdg.configHome}/pace"; - - xdg.configFile."pace/pace.toml".source = tomlFormat.generate "pace.toml" { - general = { - path = "${config.home.homeDirectory}/.local/share/pace/activities/activities.pace.toml"; - storage-kind = "file"; - category-separator = "::"; - default-priority = "medium"; - most-recent-count = 9; - default-time-zone = "${nixosConfig.time.timeZone}"; - }; - }; - - programs.fish.interactiveShellInit = lib.mkAfter '' - ${pkgs.pace}/bin/pace setup completions fish | source - ''; -} diff --git a/users/jalr/modules/pass.nix b/users/jalr/modules/pass.nix deleted file mode 100644 index e77fdb9..0000000 --- a/users/jalr/modules/pass.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ nixosConfig, lib, config, pkgs, ... }: - -{ - programs.password-store = { - enable = true; - package = - if nixosConfig.jalr.gui.enable - then pkgs.pass-wayland.withExtensions (exts: [ exts.pass-otp ]) - else pkgs.pass.withExtensions (exts: [ exts.pass-otp ]); - }; - home.packages = lib.optionals nixosConfig.jalr.gui.enable [ - pkgs.qtpass - ]; - xdg.dataFile.password-store = { - source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/.password-store"; - target = "password-store"; - }; -} diff --git a/users/jalr/modules/pomodoro.nix b/users/jalr/modules/pomodoro.nix deleted file mode 100644 index 6df182a..0000000 --- a/users/jalr/modules/pomodoro.nix +++ /dev/null @@ -1,70 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: - -let - tomlFormat = pkgs.formats.toml { }; -in -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - uair - pomodoro-timer - ]; - - xdg.configFile."uair/uair.toml".source = tomlFormat.generate "uair.toml" { - defaults = { - loop_on_end = true; - paused_state_text = "paused"; - resumed_state_text = "resumed"; - overrides = { - yad = { - format = "{percent}\n#{time}\n"; - }; - json = { - format = ''{"name": "{name}", "percent": {percent}", "time": "{time}", "running": {state}, "total": "{total}"} - ''; - paused_state_text = "false"; - resumed_state_text = "true"; - }; - waybar = { - format = ''{"text": "{name}: {time}", "class": "{state}"} - ''; - paused_state_text = "paused"; - resumed_state_text = "resumed"; - }; - }; - }; - sessions = - let - notify-send = "notify-send --app-name='Pomodoro timer' --icon='pomodorotimer'"; - work-finished = "${notify-send} 'Pomodoro done! Enjoy your break.'; dnd off"; - break-finished = "${notify-send} 'Get back to work!'; dnd on"; - in - [ - { name = "Work 1"; duration = "25m"; command = work-finished; } - { name = "Break 1"; duration = "5m"; command = break-finished; } - { name = "Work 2"; duration = "25m"; command = work-finished; } - { name = "Break 2"; duration = "5m"; command = break-finished; } - { name = "Work 3"; duration = "25m"; command = work-finished; } - { name = "Break 3"; duration = "5m"; command = break-finished; } - { name = "Work 4"; duration = "25m"; command = work-finished; } - { name = "Long Break"; duration = "20m"; command = break-finished; } - ]; - }; - - systemd.user.services.uair = { - Unit.Description = "Pomodoro timer"; - Service = { - ExecStart = "${pkgs.uair}/bin/uair"; - NoNewPrivileges = true; - ProtectControlGroups = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; - RestrictNamespaces = true; - Type = "simple"; - Environment = [ - "PATH=/etc/profiles/per-user/jalr/bin:/run/current-system/sw/bin/" - ]; - }; - Install.WantedBy = [ "default.target" ]; - }; -} diff --git a/users/jalr/modules/snapclient.nix b/users/jalr/modules/snapclient.nix deleted file mode 100644 index c391bfb..0000000 --- a/users/jalr/modules/snapclient.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: - -lib.mkIf nixosConfig.jalr.gui.enable { - systemd.user.services.snapclient = { - Unit.Description = "Snapcast client"; - Service = { - BindPaths = [ "/run/user/1000/pulse" ]; - ExecStart = "${pkgs.snapcast}/bin/snapclient --player pulse"; - NoNewPrivileges = true; - ProtectControlGroups = true; - ProtectHome = "tmpfs"; - ProtectKernelModules = true; - ProtectKernelTunables = true; - RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; - RestrictNamespaces = true; - Type = "simple"; - }; - Install.WantedBy = [ "default.target" ]; - }; -} diff --git a/users/jalr/modules/solarized.nix b/users/jalr/modules/solarized.nix deleted file mode 100644 index baa2547..0000000 --- a/users/jalr/modules/solarized.nix +++ /dev/null @@ -1,68 +0,0 @@ -let - colors = { - base00 = "#657b83"; - base01 = "#586e75"; - base02 = "#073642"; - base03 = "#002b36"; - base0 = "#839496"; - base1 = "#93a1a1"; - base2 = "#eee8d5"; - base3 = "#fdf6e3"; - blue = "#268bd2"; - cyan = "#2aa198"; - green = "#859900"; - magenta = "#d33682"; - orange = "#cb4b16"; - red = "#dc322f"; - violet = "#6c71c4"; - yellow = "#b58900"; - }; - common = { - base08 = colors.red; - base09 = colors.orange; - base0A = colors.yellow; - base0B = colors.green; - base0C = colors.cyan; - base0D = colors.blue; - base0E = colors.violet; - base0F = colors.magenta; - }; - light = common // { - base00 = colors.base3; - base01 = colors.base2; - base02 = colors.base1; - base03 = colors.base0; - base04 = colors.base00; - base05 = colors.base01; - base06 = colors.base02; - base07 = colors.base03; - }; - dark = common // { - base00 = colors.base03; - base01 = colors.base02; - base02 = colors.base01; - base03 = colors.base00; - base04 = colors.base0; - base05 = colors.base1; - base06 = colors.base2; - base07 = colors.base3; - }; - toRgb = hex: builtins.concatStringsSep "," ( - map - ( - f: toString (builtins.fromTOML "i = 0x${f hex}").i - ) - ( - map (pos: builtins.substring pos 2) [ 1 3 5 ] - ) - ); - makeScheme = colors: { - hex = colors; - rgb = builtins.mapAttrs (_: hex: (toRgb hex)) colors; - }; -in -{ - inherit colors; - light = makeScheme light; - dark = makeScheme dark; -} diff --git a/users/jalr/modules/sound/easyeffects.nix b/users/jalr/modules/sound/easyeffects.nix deleted file mode 100644 index eaad63c..0000000 --- a/users/jalr/modules/sound/easyeffects.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: - -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - easyeffects - ]; - - services.easyeffects.enable = true; - - xdg.configFile."easyeffects/output/framework-16.json".source = pkgs.fetchurl { - url = "https://gist.githubusercontent.com/amesb/cc5d717472d7e322b5f551b643ff03f4/raw/85029e48072ab3802615b2824dce7df204f0d8ab/amesb%2520fw16%2520EE%2520profile.json"; - sha256 = "sha256-Te8S9DsG5P/NuNk5WE6mSB/DjHS+rKjOFRN7mDEVg8g="; - }; -} diff --git a/users/jalr/modules/sway/mako.nix b/users/jalr/modules/sway/mako.nix deleted file mode 100644 index 767e6b5..0000000 --- a/users/jalr/modules/sway/mako.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ pkgs, ... }: - -{ - xdg.configFile."mako/config".text = '' - [mode=dnd] - invisible=1 - - [mode=screencast] - icons=0 - format=%a - - [app-name="Pomodoro timer"] - invisible=0 - icon-path="${pkgs.pomodoro-timer}/share/icons/hicolor" - ''; -} diff --git a/users/jalr/modules/sway/screenshare.nix b/users/jalr/modules/sway/screenshare.nix deleted file mode 100644 index c5a21d6..0000000 --- a/users/jalr/modules/sway/screenshare.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ pkgs, ... }: -{ - home.packages = [ - ( - pkgs.writeShellScriptBin "screenshare" '' - # https://github.com/emersion/xdg-desktop-portal-wlr/issues/107 - - case "$1" in - start) - # Step 1: Create a new output - swaymsg create_output - - # Step 2: Find the name of the newly created output - NEW_OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.name | startswith("HEADLESS-")) | .name' | sort | tail -n 1) - - # Check if the output was successfully created - if [ -z "$NEW_OUTPUT" ]; then - echo "Failed to create a new output." - exit 1 - fi - - # Step 3: Assign a workspace to the new output - swaymsg workspace sshr output "$NEW_OUTPUT" - - # Step 4: Set the resolution for the new output - swaymsg output "$NEW_OUTPUT" resolution 1280x720 - - # Step 5: Set the background color for the new output - swaymsg output "$NEW_OUTPUT" bg "#220900" solid_color - - # Step 6: Switch to workspace sshr and then back to the previous workspace - CURRENT_WORKSPACE=$(swaymsg -t get_workspaces | jq -r '.[] | select(.focused) | .name') - swaymsg workspace sshr - swaymsg workspace "$CURRENT_WORKSPACE" - ;; - stop) - headless_outputs=$(swaymsg -t get_outputs | jq -r '.[] | select(.name | startswith("HEADLESS-")) | .name') - - # Check if there are any HEADLESS outputs - if [ -z "$headless_outputs" ]; then - echo "No HEADLESS outputs found." - exit 0 - fi - - # Unplug each HEADLESS output - for output in $headless_outputs; do - echo "Unplugging $output..." - swaymsg output "$output" unplug - done - ;; - esac - '' - ) - ]; -} diff --git a/users/jalr/modules/sway/waybar.nix b/users/jalr/modules/sway/waybar.nix deleted file mode 100644 index c507ce9..0000000 --- a/users/jalr/modules/sway/waybar.nix +++ /dev/null @@ -1,447 +0,0 @@ -{ config, lib, nixosConfig, pkgs, ... }: -let - watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" '' - ${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \ - | ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \ - | ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end' - ''; - - toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" '' - if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then - ${pkgs.systemd}/bin/systemctl --user stop ${unit} - else - ${pkgs.systemd}/bin/systemctl --user start ${unit} - fi - ''; - - # for fine-grained control over spacing - thinsp = " "; - - solarized = import ../solarized.nix; - solarizedColors = lib.attrsets.mapAttrsToList (name: color: "@define-color ${name} ${color};"); - themeCss = { - light = lib.strings.concatLines (solarizedColors solarized.light.hex); - dark = lib.strings.concatLines (solarizedColors solarized.dark.hex); - }; -in -{ - # home-manager’s waybar module performs additional checks that are overly strict - xdg.configFile."waybar/config".text = - let - makoctl = "${pkgs.mako}/bin/makoctl"; - sendSignal = signal: "${pkgs.procps}/bin/pkill -f -SIGRTMIN+${toString signal} waybar"; - in - lib.generators.toJSON { } { - layer = "top"; - output = [ - "!HEADLESS-1" - "*" - ]; - position = "top"; - height = 24; - - modules-center = [ ]; - modules-left = [ - "sway/workspaces" - "sway/mode" - ]; - modules-right = [ - "tray" - "custom/screencast" - "custom/redshift" - "idle_inhibitor" - "custom/pomodoro" - "backlight" - "pulseaudio" - "network" - "memory" - "cpu" - "temperature" - "battery" - "clock" - "custom/dnd" - ]; - - "sway/workspaces" = { - disable-scroll = true; - }; - "sway/mode" = { - format = "{}"; - }; - - tray = { - spacing = 5; - }; - "custom/redshift" = { - exec = watchUserUnitState - "gammastep" - { class = "active"; } - { class = "inactive"; }; - on-click = toggleUserUnitState "gammastep"; - return-type = "json"; - format = "󰌵"; - tooltip = false; - }; - "custom/pomodoro" = let uairctl = "${pkgs.uair}/bin/uairctl"; in { - # We need to remove nul-characters - # See https://github.com/metent/uair/issues/15 - exec = pkgs.writeShellScript "uairctl-without-null-characters" '' - ${uairctl} listen -o waybar | ${pkgs.gnused}/bin/sed --unbuffered 's/\x0//g' - ''; - - on-click = "${uairctl} toggle"; - on-scroll-up = "${uairctl} next"; - on-scroll-down = "${uairctl} prev"; - on-click-middle = "${uairctl} finish"; - menu = "on-click-right"; - /* - menu-actions = { - "work 1" = "${uairctl} jump 0"; - "break 1" = "${uairctl} jump 1"; - "work 2" = "${uairctl} jump 2"; - "break 2" = "${uairctl} jump 3"; - "work 3" = "${uairctl} jump 4"; - "break 3" = "${uairctl} jump 5"; - "work 4" = "${uairctl} jump 6"; - "long break" = "${uairctl} jump 7"; - }; - */ - return-type = "json"; - }; - idle_inhibitor = { - format = "{icon}"; - format-icons = { - activated = "󰈈 "; - deactivated = "󰈉 "; - }; - }; - "custom/screencast" = { - exec = pkgs.writeScript "screencast-monitor" /* python */ '' - #!${pkgs.python3}/bin/python3 - import subprocess - import sys - - active_outputs = 0 - - with subprocess.Popen( - ["${pkgs.coreutils}/bin/stdbuf", "-o0", "${nixosConfig.services.pipewire.package}/bin/pw-link", "-m", "-o", "xdg-desktop-portal-wlr"], - stdout=subprocess.PIPE, - text=True, - ) as proc: - for line in proc.stdout: - action = line.split(" ")[0] - if action == "=" or action == "+": - active_outputs += 1 - elif action == "-": - active_outputs -= 1 - else: - print(f"Invalid action {action} (in line {line})", file=sys.stderr) - - if active_outputs > 0: - print("󱒃") - subprocess.run(["${makoctl}", "mode", "-a" "screencast"], stdout=subprocess.DEVNULL) - else: - print() - subprocess.run(["${makoctl}", "mode", "-r" "screencast"], stdout=subprocess.DEVNULL) - - sys.stdout.flush() - ''; - format = "{}"; - tooltip = false; - }; - backlight = { - format = "{percent}% {icon}"; - format-icons = [ "󰛩" "󱩎" "󱩏" "󱩐" "󱩑" "󱩒" "󱩓" "󱩔" "󱩕" "󱩖" "󰛨" ]; - on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -q set +1%"; - on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -q set 1%-"; - }; - pulseaudio = { - format = "{volume}% {icon} {format_source}"; - format-bluetooth = "{volume}% {icon}󰗾{format_source}"; - format-bluetooth-muted = "{icon}󰗿{format_source}"; - format-muted = "󰝟 {format_source}"; - format-source = "{volume}% ${thinsp}"; - format-source-muted = "${thinsp}"; - format-icons = { - car = "󰄋 "; - default = [ "󰕿" "󰖀" "󰕾" ]; - hands-free = "󰋎"; - headphone = "󰋋"; - headset = "󰋎"; - phone = "󰏲"; - portable = "󰏲"; - }; - on-click-right = "GSK_RENDERER=cairo GTK_USE_PORTAL=0 ${pkgs.mixxc}/bin/mixxc -A -a t -a r"; - }; - network = { - format-wifi = "{essid} ({signalStrength}%) 󰖩 "; - format-ethernet = "{ipaddr}/{cidr} 󰈀 "; - format-linked = "{ifname} (No IP) 󰈀 "; - format-disconnected = "Disconnected ⚠ "; - format-alt = "{ifname}: {ipaddr}/{cidr}"; - tooltip = false; - on-click-right = "${config.programs.wezterm.package}/bin/wezterm start -e ${pkgs.networkmanager}/bin/nmtui"; - }; - memory = { - interval = 2; - format = "{:2}% 󰍛 "; - }; - cpu = { - interval = 2; - format = "{usage:2}%  "; - tooltip = false; - }; - temperature = { - critical-threshold = 80; - format = "{temperatureC}°C {icon}"; - format-icons = [ "" "" "" "" "" ]; - } // (lib.optionalAttrs (nixosConfig.networking.hostName == "mayushii") { - hwmon-path = "/sys/class/hwmon/hwmon3/temp1_input"; - }); - battery = { - interval = 5; - format = "{capacity}% {icon}"; - format-charging = "{capacity}% "; - format-plugged = "{capacity}% x"; - format-alt = "{time} {icon}"; - format-icons = [ "󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; - states = { - critical = 15; - good = 95; - warning = 30; - }; - }; - clock = { - format = "{:%H:%M %Z}"; - format-alt = "{:%Y-%m-%d (%a)}"; - tooltip-format = "{:%Y %B}\n{calendar}"; - }; - "custom/dnd" = - let - signal = 1; - dndScript = "/etc/profiles/per-user/jalr/bin/dnd"; - in - { - inherit signal; - exec = pkgs.writeScript "waybar-dnd-widget" '' - #!${pkgs.python3}/bin/python3 - - import subprocess - import sys - import time - import json - - while True: - proc = subprocess.Popen(["${makoctl}", "mode"], stdout=subprocess.PIPE, text=True) - modes = [line.rstrip() for line in proc.stdout.readlines()] - - text, class_name = ("󰂛", "active") if 'dnd' in modes else ("󰂚", "inactive") - - print(json.dumps({ - "text": text, - "tooltip": "", - "class": class_name, - "percentage": 0 - })) - - sys.stdout.flush() - - time.sleep(30) - ''; - on-click = "${dndScript} on; ${sendSignal signal}"; - on-click-right = "${dndScript} off; ${sendSignal signal}"; - exec-on-event = true; - return-type = "json"; - restart-interval = 10; - }; - }; - - xdg.configFile = { - "waybar/theme-light.css".text = themeCss.light; - "waybar/theme-dark.css".text = themeCss.dark; - "waybar/style.css".text = '' - @import "theme.css"; - - * { - border-radius: 0; - border: none; - font-family: "Iosevka Nerd Font"; - font-size: 14px; - min-height: 0; - transition-property: none; - } - - window#waybar { - background-color: @base00; - color: @base04; - } - - #workspaces button { - padding: 0 5px; - background-color: @base00; - color: inherit; - border-bottom: 2px solid transparent; - } - - #workspaces button:hover { - background: @base01; - box-shadow: inherit; - text-shadow: inherit; - } - - #workspaces button.focused { - border-bottom: 2px solid @base0B; - } - - #workspaces button.urgent { - background-color: @base08; - } - - #mode { - background-color: @base01; - font-style: italic; - } - - /* all modules on the right */ - #waybar > box > box:nth-child(3) > widget > label { - padding: 0 10px; - } - - #battery.charging { - color: @base01; - background-color: @base0B; - } - - @keyframes blink { - to { - background-color: @base07; - color: @base03; - } - } - - #battery.critical:not(.charging), - #temperature.critical { - background-color: @base08; - animation-name: blink; - animation-duration: 0.5s; - /* FIXME use nearest neighbor interpolation if possible */ - animation-timing-function: cubic-bezier(1, 0, 0, 1); - animation-iteration-count: infinite; - animation-direction: alternate; - } - - #cpu { - background-color: @base0C; - color: @base01 - } - - #memory { - background-color: @base0A; - color: @base01 - } - - #backlight { - background-color: @base07; - color: @base03; - } - - #network { - background-color: @base0E; - color: @base01 - } - - #network.disconnected { - background-color: @base08; - } - - #pulseaudio { - background-color: @base07; - color: @base03; - } - - #pulseaudio.muted { - background-color: @base00; - color: @base04; - } - - #temperature { - background-color: @base0F; - color: @base01; - } - - #idle_inhibitor.activated { - background-color: @base07; - color: @base00; - } - - #custom-redshift { - color: @base01; - } - - #custom-redshift.active { - background-color: @base08; - } - - #custom-redshift.inactive { - background-color: @base0D; - } - - #tray { - padding: 0 5px; - } - - #custom-notification_inhibitor.active { - background-color: @base07; - color: @base00; - } - - #custom-screencast { - background-color: @base08; - color: @base00; - animation-name: blink; - animation-duration: 1s; - animation-timing-function: ease-in-out; - animation-iteration-count: infinite; - animation-direction: alternate; - } - - #custom-pomodoro.resumed { - color: @base01; - background-color: @base0B; - } - - #custom-dnd.active { - color: @base01; - background-color: @base0B; - } - ''; - }; - - systemd.user.services.waybar = { - Unit = { - Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors."; - Documentation = "https://github.com/Alexays/Waybar/wiki/"; - PartOf = [ "sway-session.target" ]; - }; - - Install.WantedBy = [ "sway-session.target" ]; - - Service = { - # ensure sway is already started, otherwise workspaces will not work - ExecStartPre = "${config.wayland.windowManager.sway.package}/bin/swaymsg"; - ExecStart = "${pkgs.waybar}/bin/waybar"; - ExecReload = "${pkgs.utillinux}/bin/kill -SIGUSR2 $MAINPID"; - Restart = "on-failure"; - RestartSec = "1s"; - }; - }; - - # TODO: remove when https://github.com/nix-community/home-manager/issues/2064 - # is resolved - systemd.user.targets.tray = { - Unit = { - Description = "Home Manager System Tray"; - Requires = [ "graphical-session-pre.target" ]; - }; - }; -} diff --git a/users/jalr/modules/sway/wofi.nix b/users/jalr/modules/sway/wofi.nix deleted file mode 100644 index 44d2914..0000000 --- a/users/jalr/modules/sway/wofi.nix +++ /dev/null @@ -1,92 +0,0 @@ -{ lib, ... }: - -let - inherit (import ../solarized.nix) colors; -in -{ - xdg.configFile = - let - commonColors = with colors; [ - red - orange - yellow - green - cyan - blue - violet - magenta - ]; - in - { - "wofi/color-light".text = with colors; lib.strings.concatLines ( - [ - base3 - base2 - base1 - base0 - base00 - base01 - base02 - base03 - ] ++ commonColors - ); - "wofi/color-dark".text = with colors; lib.strings.concatLines ( - with colors; [ - base03 - base02 - base01 - base00 - base0 - base1 - base2 - base3 - ] ++ commonColors - ); - "wofi/style.css".text = '' - window { - margin: 0px; - border: 3px solid --wofi-color1; - border-radius: 8px; - background-color: rgba(--wofi-rgb-color0,0.8); - } - - #input { - margin: 5px; - border: none; - color: --wofi-color4; - background-color: rgba(--wofi-rgb-color1,0.8); - } - - #inner-box { - margin: 5px; - border: none; - background: none; - } - - #outer-box { - margin: 5px; - border: none; - background: none; - } - - #scroll { - margin: 0px; - border: none; - } - - #text { - margin: 5px; - border: none; - color: --wofi-color4; - } - - #entry:selected { - background-color: rgba(--wofi-rgb-color1,0.8); - } - - #entry:selected #text{ - color: --wofi-color11; - } - ''; - }; -} diff --git a/users/jalr/modules/thunar.nix b/users/jalr/modules/thunar.nix deleted file mode 100644 index 28b5b0b..0000000 --- a/users/jalr/modules/thunar.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: -lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - xfce.thunar - xfce.thunar-volman - ]; -} - diff --git a/users/jalr/modules/thunderbird.nix b/users/jalr/modules/thunderbird.nix deleted file mode 100644 index e8cd892..0000000 --- a/users/jalr/modules/thunderbird.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ nixosConfig, pkgs, ... }: -{ - programs.thunderbird = { - inherit (nixosConfig.jalr.gui) enable; - package = pkgs.thunderbird-esr; - profiles."default" = { - isDefault = true; - withExternalGnupg = true; - }; - settings = { - "mail.chat.enabled" = false; - }; - }; -} diff --git a/users/jalr/modules/vesc-tool.nix b/users/jalr/modules/vesc-tool.nix deleted file mode 100644 index 3b5d90b..0000000 --- a/users/jalr/modules/vesc-tool.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ nixosConfig, lib, pkgs, ... }: - -lib.mkIf (nixosConfig.jalr.gui.enable && nixosConfig.networking.hostName == "copper") { - home.packages = with pkgs; [ vesc-tool ]; - xdg.dataFile."VESC/firmware".source = pkgs.bldc-fw.override { - fwBoards = [ - "410" - "60" - "60_mk3" - ]; - }; -} diff --git a/users/jalr/modules/wezterm.nix b/users/jalr/modules/wezterm.nix deleted file mode 100644 index be238eb..0000000 --- a/users/jalr/modules/wezterm.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ config, lib, nixosConfig, ... }: - -let - weztermConfig = { - hide_tab_bar_if_only_one_tab = true; - #color_scheme = "Solarized (dark) (terminal.sexy)"; - #color_scheme = "Solarized (light) (terminal.sexy)"; - font = "FiraCode Nerd Font Mono"; - font_size = 12; - }; -in -{ - programs.wezterm = { - inherit (nixosConfig.jalr.gui) enable; - extraConfig = '' - local wezterm = require 'wezterm' - ${lib.generators.toLua {asBindings=true;} {config=weztermConfig;}} - config.font = wezterm.font(config.font) - - function get_appearance() - if wezterm.gui then - return wezterm.gui.get_appearance() - end - return 'Light' - end - - function scheme_for_appearance(appearance) - if appearance:find 'Dark' then - return 'Builtin Solarized Dark' - else - return 'Builtin Solarized Light' - end - end - - config.color_scheme = scheme_for_appearance(get_appearance()) - - return config - ''; - }; - /* - file = io.open("${config.xdg.configHome}/wezterm/color_scheme.txt", "r") - io.input(file) - config.color_scheme = io.read() - io.close(file) - */ -}