diff options
67 files changed, 1840 insertions, 1658 deletions
diff --git a/_sources/generated.json b/_sources/generated.json index d98f141f..62c68113 100644 --- a/_sources/generated.json +++ b/_sources/generated.json | |||
@@ -22,7 +22,7 @@ | |||
22 | }, | 22 | }, |
23 | "bpf-examples": { | 23 | "bpf-examples": { |
24 | "cargoLocks": null, | 24 | "cargoLocks": null, |
25 | "date": "2025-03-06", | 25 | "date": "2025-08-18", |
26 | "extract": null, | 26 | "extract": null, |
27 | "name": "bpf-examples", | 27 | "name": "bpf-examples", |
28 | "passthru": null, | 28 | "passthru": null, |
@@ -34,12 +34,12 @@ | |||
34 | "name": null, | 34 | "name": null, |
35 | "owner": "xdp-project", | 35 | "owner": "xdp-project", |
36 | "repo": "bpf-examples", | 36 | "repo": "bpf-examples", |
37 | "rev": "64e7da048b14822bef06f3971189c4c0985422e7", | 37 | "rev": "f19bc1a9402b6fb014e3b7114f06ffba5abdf5cc", |
38 | "sha256": "sha256-cyyRNvU35ujxkLraOqw2oiZwUblBpJaEncPl2++VHL4=", | 38 | "sha256": "sha256-syYoC3XOJTUaL/Db0T10mSUak83qAl6Tx2fE6k4XLpI=", |
39 | "sparseCheckout": [], | 39 | "sparseCheckout": [], |
40 | "type": "github" | 40 | "type": "github" |
41 | }, | 41 | }, |
42 | "version": "64e7da048b14822bef06f3971189c4c0985422e7" | 42 | "version": "f19bc1a9402b6fb014e3b7114f06ffba5abdf5cc" |
43 | }, | 43 | }, |
44 | "emacs-scratch_el": { | 44 | "emacs-scratch_el": { |
45 | "cargoLocks": null, | 45 | "cargoLocks": null, |
@@ -91,11 +91,11 @@ | |||
91 | "passthru": null, | 91 | "passthru": null, |
92 | "pinned": false, | 92 | "pinned": false, |
93 | "src": { | 93 | "src": { |
94 | "sha256": "sha256-afJuTByGUMU6kFqGGa3pbPaFVdYGcJYiR0RfDNYNgDk=", | 94 | "sha256": "sha256-V+fB5KkbBRhVSDgB/e7oVEyMKQ7HbR82XQYlqxcLZyQ=", |
95 | "type": "tarball", | 95 | "type": "tarball", |
96 | "url": "https://github.com/wofr06/lesspipe/archive/refs/tags/v2.17.tar.gz" | 96 | "url": "https://github.com/wofr06/lesspipe/archive/refs/tags/v2.19.tar.gz" |
97 | }, | 97 | }, |
98 | "version": "2.17" | 98 | "version": "2.19" |
99 | }, | 99 | }, |
100 | "mako": { | 100 | "mako": { |
101 | "cargoLocks": null, | 101 | "cargoLocks": null, |
@@ -270,11 +270,11 @@ | |||
270 | "pinned": false, | 270 | "pinned": false, |
271 | "src": { | 271 | "src": { |
272 | "name": null, | 272 | "name": null, |
273 | "sha256": "sha256-8kd17ChqLuVH5/OdPc2rVDKEDWHl9ZWLh8k+EBrCGH8=", | 273 | "sha256": "sha256-ipbZJ0mPCuwzb/TDtXXUBTuWOcSsKGAJ1GEGIgB2G7E=", |
274 | "type": "url", | 274 | "type": "url", |
275 | "url": "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.87/netboot.xyz.efi" | 275 | "url": "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.88/netboot.xyz.efi" |
276 | }, | 276 | }, |
277 | "version": "2.0.87" | 277 | "version": "2.0.88" |
278 | }, | 278 | }, |
279 | "netbootxyz-lkrn": { | 279 | "netbootxyz-lkrn": { |
280 | "cargoLocks": null, | 280 | "cargoLocks": null, |
@@ -285,11 +285,11 @@ | |||
285 | "pinned": false, | 285 | "pinned": false, |
286 | "src": { | 286 | "src": { |
287 | "name": null, | 287 | "name": null, |
288 | "sha256": "sha256-/qY3NdRC0SghQ4kamrkm9EFumrKlirqDCJ+XY+jHWLA=", | 288 | "sha256": "sha256-igy3O30noS25dU7ZnHuKrWqLLkjjd/L46IdCTd038dI=", |
289 | "type": "url", | 289 | "type": "url", |
290 | "url": "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.87/netboot.xyz.lkrn" | 290 | "url": "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.88/netboot.xyz.lkrn" |
291 | }, | 291 | }, |
292 | "version": "2.0.87" | 292 | "version": "2.0.88" |
293 | }, | 293 | }, |
294 | "postfix-mta-sts-resolver": { | 294 | "postfix-mta-sts-resolver": { |
295 | "cargoLocks": null, | 295 | "cargoLocks": null, |
@@ -327,11 +327,11 @@ | |||
327 | "passthru": null, | 327 | "passthru": null, |
328 | "pinned": false, | 328 | "pinned": false, |
329 | "src": { | 329 | "src": { |
330 | "sha256": "sha256-Nz/lBhQbzWSnOKN4n0OUdJzDTpf3mfY0+FXoCqF03TU=", | 330 | "sha256": "sha256-JDKt+MzxxyaFWnzuq/7FfT/JPUknH/RRw4Cb8XDOtlk=", |
331 | "type": "tarball", | 331 | "type": "tarball", |
332 | "url": "https://github.com/hansmi/prometheus-lvm-exporter/archive/refs/tags/v0.4.0.tar.gz" | 332 | "url": "https://github.com/hansmi/prometheus-lvm-exporter/archive/refs/tags/v0.6.0.tar.gz" |
333 | }, | 333 | }, |
334 | "version": "0.4.0" | 334 | "version": "0.6.0" |
335 | }, | 335 | }, |
336 | "psql-versioning": { | 336 | "psql-versioning": { |
337 | "cargoLocks": null, | 337 | "cargoLocks": null, |
@@ -397,7 +397,7 @@ | |||
397 | }, | 397 | }, |
398 | "swayosd": { | 398 | "swayosd": { |
399 | "cargoLocks": null, | 399 | "cargoLocks": null, |
400 | "date": "2025-04-20", | 400 | "date": "2025-07-07", |
401 | "extract": null, | 401 | "extract": null, |
402 | "name": "swayosd", | 402 | "name": "swayosd", |
403 | "passthru": null, | 403 | "passthru": null, |
@@ -407,13 +407,13 @@ | |||
407 | "fetchSubmodules": false, | 407 | "fetchSubmodules": false, |
408 | "leaveDotGit": false, | 408 | "leaveDotGit": false, |
409 | "name": null, | 409 | "name": null, |
410 | "rev": "ce1f34d80a7f8b4393a5551ea0535bd8beabb28c", | 410 | "rev": "73aed75146b81aaf67c4301353790ff5a17aed1f", |
411 | "sha256": "sha256-Z9c/5jKxs5ctUuVu7g+BXA1Wy4lyZLpGATtj2jd84jI=", | 411 | "sha256": "sha256-p31HNelptAw7Sk0NmYP4FkoUCdA5uAsrXC20JJp24Vw=", |
412 | "sparseCheckout": [], | 412 | "sparseCheckout": [], |
413 | "type": "git", | 413 | "type": "git", |
414 | "url": "https://github.com/ErikReider/SwayOSD" | 414 | "url": "https://github.com/ErikReider/SwayOSD" |
415 | }, | 415 | }, |
416 | "version": "ce1f34d80a7f8b4393a5551ea0535bd8beabb28c" | 416 | "version": "73aed75146b81aaf67c4301353790ff5a17aed1f" |
417 | }, | 417 | }, |
418 | "tomorrow-night-paradise-theme": { | 418 | "tomorrow-night-paradise-theme": { |
419 | "cargoLocks": null, | 419 | "cargoLocks": null, |
@@ -437,7 +437,7 @@ | |||
437 | }, | 437 | }, |
438 | "v4l2loopback": { | 438 | "v4l2loopback": { |
439 | "cargoLocks": null, | 439 | "cargoLocks": null, |
440 | "date": "2025-04-29", | 440 | "date": "2025-08-18", |
441 | "extract": null, | 441 | "extract": null, |
442 | "name": "v4l2loopback", | 442 | "name": "v4l2loopback", |
443 | "passthru": null, | 443 | "passthru": null, |
@@ -449,16 +449,16 @@ | |||
449 | "name": null, | 449 | "name": null, |
450 | "owner": "umlaeute", | 450 | "owner": "umlaeute", |
451 | "repo": "v4l2loopback", | 451 | "repo": "v4l2loopback", |
452 | "rev": "8d806ad688961d8840081a609c39d1a82d296b24", | 452 | "rev": "5eaa59e7c41d0e6f35a6c14c3b756d94d25f58ed", |
453 | "sha256": "sha256-zuE/qFI8QCWCePmHWjTIPTh2KzmDkwQ2uj5C1dAwo1c=", | 453 | "sha256": "sha256-YcSpNfItvUdPVirlDyGdYuCnVvxHhh780x+OI5VNZmE=", |
454 | "sparseCheckout": [], | 454 | "sparseCheckout": [], |
455 | "type": "github" | 455 | "type": "github" |
456 | }, | 456 | }, |
457 | "version": "8d806ad688961d8840081a609c39d1a82d296b24" | 457 | "version": "5eaa59e7c41d0e6f35a6c14c3b756d94d25f58ed" |
458 | }, | 458 | }, |
459 | "xcompose": { | 459 | "xcompose": { |
460 | "cargoLocks": null, | 460 | "cargoLocks": null, |
461 | "date": "2025-03-11", | 461 | "date": "2025-06-05", |
462 | "extract": null, | 462 | "extract": null, |
463 | "name": "xcompose", | 463 | "name": "xcompose", |
464 | "passthru": null, | 464 | "passthru": null, |
@@ -470,12 +470,12 @@ | |||
470 | "name": null, | 470 | "name": null, |
471 | "owner": "kragen", | 471 | "owner": "kragen", |
472 | "repo": "xcompose", | 472 | "repo": "xcompose", |
473 | "rev": "8b5a6a0c788fd0a4b921d9d3737174defb863873", | 473 | "rev": "4d8eab4d05a19537ce79294ae0459fdae78ffb20", |
474 | "sha256": "sha256-6EjQErdBOd5hqcrdaf88E1UZVYIc3FOfv34hvUwOWdA=", | 474 | "sha256": "sha256-vKY4u5Z2IL111orLLkkF4AoVzqluKG/VQhNUUCqO/k8=", |
475 | "sparseCheckout": [], | 475 | "sparseCheckout": [], |
476 | "type": "github" | 476 | "type": "github" |
477 | }, | 477 | }, |
478 | "version": "8b5a6a0c788fd0a4b921d9d3737174defb863873" | 478 | "version": "4d8eab4d05a19537ce79294ae0459fdae78ffb20" |
479 | }, | 479 | }, |
480 | "yt-dlp": { | 480 | "yt-dlp": { |
481 | "cargoLocks": null, | 481 | "cargoLocks": null, |
@@ -486,10 +486,10 @@ | |||
486 | "pinned": false, | 486 | "pinned": false, |
487 | "src": { | 487 | "src": { |
488 | "name": null, | 488 | "name": null, |
489 | "sha256": "sha256-6nOFTF2rwSTymjWo+um8XUIu8yMb6+6ivfqCrBkanCk=", | 489 | "sha256": "sha256-2oc7z0JBd6tcO3AfqU6kzawXvzrsXvN7kfUwyQ3ve88=", |
490 | "type": "url", | 490 | "type": "url", |
491 | "url": "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.5.22.tar.gz" | 491 | "url": "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.8.20.tar.gz" |
492 | }, | 492 | }, |
493 | "version": "2025.5.22" | 493 | "version": "2025.8.20" |
494 | } | 494 | } |
495 | } \ No newline at end of file | 495 | } \ No newline at end of file |
diff --git a/_sources/generated.nix b/_sources/generated.nix index 3bf73fed..4368c98a 100644 --- a/_sources/generated.nix +++ b/_sources/generated.nix | |||
@@ -18,15 +18,15 @@ | |||
18 | }; | 18 | }; |
19 | bpf-examples = { | 19 | bpf-examples = { |
20 | pname = "bpf-examples"; | 20 | pname = "bpf-examples"; |
21 | version = "64e7da048b14822bef06f3971189c4c0985422e7"; | 21 | version = "f19bc1a9402b6fb014e3b7114f06ffba5abdf5cc"; |
22 | src = fetchFromGitHub { | 22 | src = fetchFromGitHub { |
23 | owner = "xdp-project"; | 23 | owner = "xdp-project"; |
24 | repo = "bpf-examples"; | 24 | repo = "bpf-examples"; |
25 | rev = "64e7da048b14822bef06f3971189c4c0985422e7"; | 25 | rev = "f19bc1a9402b6fb014e3b7114f06ffba5abdf5cc"; |
26 | fetchSubmodules = true; | 26 | fetchSubmodules = true; |
27 | sha256 = "sha256-cyyRNvU35ujxkLraOqw2oiZwUblBpJaEncPl2++VHL4="; | 27 | sha256 = "sha256-syYoC3XOJTUaL/Db0T10mSUak83qAl6Tx2fE6k4XLpI="; |
28 | }; | 28 | }; |
29 | date = "2025-03-06"; | 29 | date = "2025-08-18"; |
30 | }; | 30 | }; |
31 | emacs-scratch_el = { | 31 | emacs-scratch_el = { |
32 | pname = "emacs-scratch_el"; | 32 | pname = "emacs-scratch_el"; |
@@ -53,10 +53,10 @@ | |||
53 | }; | 53 | }; |
54 | lesspipe = { | 54 | lesspipe = { |
55 | pname = "lesspipe"; | 55 | pname = "lesspipe"; |
56 | version = "2.17"; | 56 | version = "2.19"; |
57 | src = fetchTarball { | 57 | src = fetchTarball { |
58 | url = "https://github.com/wofr06/lesspipe/archive/refs/tags/v2.17.tar.gz"; | 58 | url = "https://github.com/wofr06/lesspipe/archive/refs/tags/v2.19.tar.gz"; |
59 | sha256 = "sha256-afJuTByGUMU6kFqGGa3pbPaFVdYGcJYiR0RfDNYNgDk="; | 59 | sha256 = "sha256-V+fB5KkbBRhVSDgB/e7oVEyMKQ7HbR82XQYlqxcLZyQ="; |
60 | }; | 60 | }; |
61 | }; | 61 | }; |
62 | mako = { | 62 | mako = { |
@@ -164,18 +164,18 @@ | |||
164 | }; | 164 | }; |
165 | netbootxyz-efi = { | 165 | netbootxyz-efi = { |
166 | pname = "netbootxyz-efi"; | 166 | pname = "netbootxyz-efi"; |
167 | version = "2.0.87"; | 167 | version = "2.0.88"; |
168 | src = fetchurl { | 168 | src = fetchurl { |
169 | url = "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.87/netboot.xyz.efi"; | 169 | url = "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.88/netboot.xyz.efi"; |
170 | sha256 = "sha256-8kd17ChqLuVH5/OdPc2rVDKEDWHl9ZWLh8k+EBrCGH8="; | 170 | sha256 = "sha256-ipbZJ0mPCuwzb/TDtXXUBTuWOcSsKGAJ1GEGIgB2G7E="; |
171 | }; | 171 | }; |
172 | }; | 172 | }; |
173 | netbootxyz-lkrn = { | 173 | netbootxyz-lkrn = { |
174 | pname = "netbootxyz-lkrn"; | 174 | pname = "netbootxyz-lkrn"; |
175 | version = "2.0.87"; | 175 | version = "2.0.88"; |
176 | src = fetchurl { | 176 | src = fetchurl { |
177 | url = "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.87/netboot.xyz.lkrn"; | 177 | url = "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.88/netboot.xyz.lkrn"; |
178 | sha256 = "sha256-/qY3NdRC0SghQ4kamrkm9EFumrKlirqDCJ+XY+jHWLA="; | 178 | sha256 = "sha256-igy3O30noS25dU7ZnHuKrWqLLkjjd/L46IdCTd038dI="; |
179 | }; | 179 | }; |
180 | }; | 180 | }; |
181 | postfix-mta-sts-resolver = { | 181 | postfix-mta-sts-resolver = { |
@@ -196,10 +196,10 @@ | |||
196 | }; | 196 | }; |
197 | prometheus-lvm-exporter = { | 197 | prometheus-lvm-exporter = { |
198 | pname = "prometheus-lvm-exporter"; | 198 | pname = "prometheus-lvm-exporter"; |
199 | version = "0.4.0"; | 199 | version = "0.6.0"; |
200 | src = fetchTarball { | 200 | src = fetchTarball { |
201 | url = "https://github.com/hansmi/prometheus-lvm-exporter/archive/refs/tags/v0.4.0.tar.gz"; | 201 | url = "https://github.com/hansmi/prometheus-lvm-exporter/archive/refs/tags/v0.6.0.tar.gz"; |
202 | sha256 = "sha256-Nz/lBhQbzWSnOKN4n0OUdJzDTpf3mfY0+FXoCqF03TU="; | 202 | sha256 = "sha256-JDKt+MzxxyaFWnzuq/7FfT/JPUknH/RRw4Cb8XDOtlk="; |
203 | }; | 203 | }; |
204 | }; | 204 | }; |
205 | psql-versioning = { | 205 | psql-versioning = { |
@@ -242,17 +242,17 @@ | |||
242 | }; | 242 | }; |
243 | swayosd = { | 243 | swayosd = { |
244 | pname = "swayosd"; | 244 | pname = "swayosd"; |
245 | version = "ce1f34d80a7f8b4393a5551ea0535bd8beabb28c"; | 245 | version = "73aed75146b81aaf67c4301353790ff5a17aed1f"; |
246 | src = fetchgit { | 246 | src = fetchgit { |
247 | url = "https://github.com/ErikReider/SwayOSD"; | 247 | url = "https://github.com/ErikReider/SwayOSD"; |
248 | rev = "ce1f34d80a7f8b4393a5551ea0535bd8beabb28c"; | 248 | rev = "73aed75146b81aaf67c4301353790ff5a17aed1f"; |
249 | fetchSubmodules = false; | 249 | fetchSubmodules = false; |
250 | deepClone = false; | 250 | deepClone = false; |
251 | leaveDotGit = false; | 251 | leaveDotGit = false; |
252 | sparseCheckout = [ ]; | 252 | sparseCheckout = [ ]; |
253 | sha256 = "sha256-Z9c/5jKxs5ctUuVu7g+BXA1Wy4lyZLpGATtj2jd84jI="; | 253 | sha256 = "sha256-p31HNelptAw7Sk0NmYP4FkoUCdA5uAsrXC20JJp24Vw="; |
254 | }; | 254 | }; |
255 | date = "2025-04-20"; | 255 | date = "2025-07-07"; |
256 | }; | 256 | }; |
257 | tomorrow-night-paradise-theme = { | 257 | tomorrow-night-paradise-theme = { |
258 | pname = "tomorrow-night-paradise-theme"; | 258 | pname = "tomorrow-night-paradise-theme"; |
@@ -270,34 +270,34 @@ | |||
270 | }; | 270 | }; |
271 | v4l2loopback = { | 271 | v4l2loopback = { |
272 | pname = "v4l2loopback"; | 272 | pname = "v4l2loopback"; |
273 | version = "8d806ad688961d8840081a609c39d1a82d296b24"; | 273 | version = "5eaa59e7c41d0e6f35a6c14c3b756d94d25f58ed"; |
274 | src = fetchFromGitHub { | 274 | src = fetchFromGitHub { |
275 | owner = "umlaeute"; | 275 | owner = "umlaeute"; |
276 | repo = "v4l2loopback"; | 276 | repo = "v4l2loopback"; |
277 | rev = "8d806ad688961d8840081a609c39d1a82d296b24"; | 277 | rev = "5eaa59e7c41d0e6f35a6c14c3b756d94d25f58ed"; |
278 | fetchSubmodules = true; | 278 | fetchSubmodules = true; |
279 | sha256 = "sha256-zuE/qFI8QCWCePmHWjTIPTh2KzmDkwQ2uj5C1dAwo1c="; | 279 | sha256 = "sha256-YcSpNfItvUdPVirlDyGdYuCnVvxHhh780x+OI5VNZmE="; |
280 | }; | 280 | }; |
281 | date = "2025-04-29"; | 281 | date = "2025-08-18"; |
282 | }; | 282 | }; |
283 | xcompose = { | 283 | xcompose = { |
284 | pname = "xcompose"; | 284 | pname = "xcompose"; |
285 | version = "8b5a6a0c788fd0a4b921d9d3737174defb863873"; | 285 | version = "4d8eab4d05a19537ce79294ae0459fdae78ffb20"; |
286 | src = fetchFromGitHub { | 286 | src = fetchFromGitHub { |
287 | owner = "kragen"; | 287 | owner = "kragen"; |
288 | repo = "xcompose"; | 288 | repo = "xcompose"; |
289 | rev = "8b5a6a0c788fd0a4b921d9d3737174defb863873"; | 289 | rev = "4d8eab4d05a19537ce79294ae0459fdae78ffb20"; |
290 | fetchSubmodules = false; | 290 | fetchSubmodules = false; |
291 | sha256 = "sha256-6EjQErdBOd5hqcrdaf88E1UZVYIc3FOfv34hvUwOWdA="; | 291 | sha256 = "sha256-vKY4u5Z2IL111orLLkkF4AoVzqluKG/VQhNUUCqO/k8="; |
292 | }; | 292 | }; |
293 | date = "2025-03-11"; | 293 | date = "2025-06-05"; |
294 | }; | 294 | }; |
295 | yt-dlp = { | 295 | yt-dlp = { |
296 | pname = "yt-dlp"; | 296 | pname = "yt-dlp"; |
297 | version = "2025.5.22"; | 297 | version = "2025.8.20"; |
298 | src = fetchurl { | 298 | src = fetchurl { |
299 | url = "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.5.22.tar.gz"; | 299 | url = "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.8.20.tar.gz"; |
300 | sha256 = "sha256-6nOFTF2rwSTymjWo+um8XUIu8yMb6+6ivfqCrBkanCk="; | 300 | sha256 = "sha256-2oc7z0JBd6tcO3AfqU6kzawXvzrsXvN7kfUwyQ3ve88="; |
301 | }; | 301 | }; |
302 | }; | 302 | }; |
303 | } | 303 | } |
diff --git a/accounts/gkleen@sif/default.nix b/accounts/gkleen@sif/default.nix index 051427bd..64434bb8 100644 --- a/accounts/gkleen@sif/default.nix +++ b/accounts/gkleen@sif/default.nix | |||
@@ -72,7 +72,7 @@ in { | |||
72 | ./libvirt | 72 | ./libvirt |
73 | ./niri | 73 | ./niri |
74 | ./synadm | 74 | ./synadm |
75 | flakeInputs.nix-index-database.hmModules.nix-index | 75 | flakeInputs.nix-index-database.homeModules.nix-index |
76 | flakeInputs.impermanence.nixosModules.home-manager.impermanence | 76 | flakeInputs.impermanence.nixosModules.home-manager.impermanence |
77 | ]; | 77 | ]; |
78 | 78 | ||
@@ -172,6 +172,7 @@ in { | |||
172 | }; | 172 | }; |
173 | }; | 173 | }; |
174 | }; | 174 | }; |
175 | chromium.enable = true; | ||
175 | 176 | ||
176 | zathura = { | 177 | zathura = { |
177 | enable = true; | 178 | enable = true; |
@@ -233,6 +234,7 @@ in { | |||
233 | config.programs.ssh.package | 234 | config.programs.ssh.package |
234 | gnused | 235 | gnused |
235 | miniserve | 236 | miniserve |
237 | p7zip | ||
236 | ]; | 238 | ]; |
237 | execer = with pkgs; [ | 239 | execer = with pkgs; [ |
238 | "cannot:${lib.getExe' rpm "rpm2cpio"}" | 240 | "cannot:${lib.getExe' rpm "rpm2cpio"}" |
@@ -245,6 +247,7 @@ in { | |||
245 | "cannot:${lib.getExe less}" | 247 | "cannot:${lib.getExe less}" |
246 | "cannot:${lib.getExe' config.systemd.package "systemctl"}" | 248 | "cannot:${lib.getExe' config.systemd.package "systemctl"}" |
247 | "cannot:${lib.getExe config.programs.ssh.package}" | 249 | "cannot:${lib.getExe config.programs.ssh.package}" |
250 | "cannot:${lib.getExe' p7zip "7z"}" | ||
248 | ]; | 251 | ]; |
249 | wrapper = with pkgs; [ | 252 | wrapper = with pkgs; [ |
250 | "${lib.getExe' magickWrapped "magick"}:${lib.getExe' imagemagick "magick"}" | 253 | "${lib.getExe' magickWrapped "magick"}:${lib.getExe' imagemagick "magick"}" |
@@ -344,7 +347,7 @@ in { | |||
344 | font = "Fira Sans"; | 347 | font = "Fira Sans"; |
345 | }; | 348 | }; |
346 | colors = { | 349 | colors = { |
347 | background = "000000aa"; | 350 | background = "000000cc"; |
348 | text = "cdd6f4ff"; | 351 | text = "cdd6f4ff"; |
349 | match = "94e2d5ff"; | 352 | match = "94e2d5ff"; |
350 | selection = "585b70ff"; | 353 | selection = "585b70ff"; |
@@ -509,15 +512,15 @@ in { | |||
509 | wrappedYTMDesktop libsForQt5.qt5ct playerctl evince papers | 512 | wrappedYTMDesktop libsForQt5.qt5ct playerctl evince papers |
510 | thunderbird zoom-us xdg-desktop-portal steam steam-run | 513 | thunderbird zoom-us xdg-desktop-portal steam steam-run |
511 | wireshark virt-manager rclone cached-nix-shell worktime | 514 | wireshark virt-manager rclone cached-nix-shell worktime |
512 | fira-code-symbols libreoffice xournalpp google-chrome | 515 | fira-code-symbols libreoffice xournalpp |
513 | nixos-shell virt-viewer freerdp gnome-icon-theme | 516 | nixos-shell virt-viewer freerdp gnome-icon-theme |
514 | paper-icon-theme sshpassSecret weechat element-desktop | 517 | paper-icon-theme sshpassSecret weechat element-desktop |
515 | sieve-connect gimp3 inkscape udiskie glab nitrokey-app | 518 | sieve-connect gimp3 inkscape udiskie glab nitrokey-app |
516 | pynitrokey gtklock wlrctl remmina openscad spice-record | 519 | pynitrokey gtklock wlrctl remmina openscad spice-record |
517 | libguestfs-with-appliance nerd-fonts.fira-mono | 520 | nerd-fonts.fira-mono |
518 | nerd-fonts.symbols-only nerd-fonts.fira-code powerline-fonts | 521 | nerd-fonts.symbols-only nerd-fonts.fira-code powerline-fonts |
519 | swtpm (hunspellWithDicts (with hunspellDicts; [en_GB-large de_DE])) | 522 | swtpm (hunspell.withDicts (dicts: with dicts; [en_GB-large de_DE])) |
520 | libation | 523 | libation libqalculate |
521 | ] ++ mapAttrsToList (_name: pkg: pkgs.callPackage pkg {}) (customUtils.nixImport { dir = ./utils; }); | 524 | ] ++ mapAttrsToList (_name: pkg: pkgs.callPackage pkg {}) (customUtils.nixImport { dir = ./utils; }); |
522 | 525 | ||
523 | file = { | 526 | file = { |
@@ -577,6 +580,9 @@ in { | |||
577 | General = { | 580 | General = { |
578 | dot_as_separator = 0; | 581 | dot_as_separator = 0; |
579 | }; | 582 | }; |
583 | Mode = { | ||
584 | calculate_as_you_type = 1; | ||
585 | }; | ||
580 | }; | 586 | }; |
581 | }; | 587 | }; |
582 | "emacs/init.el".source = pkgs.substitute { | 588 | "emacs/init.el".source = pkgs.substitute { |
@@ -691,11 +697,11 @@ in { | |||
691 | exec -- \ | 697 | exec -- \ |
692 | ${lib.getExe' config.systemd.package "systemd-run"} --wait --user --slice-inherit \ | 698 | ${lib.getExe' config.systemd.package "systemd-run"} --wait --user --slice-inherit \ |
693 | --property 'CPUAccounting=yes' --property 'CPUQuotaPeriodSec=50ms' \ | 699 | --property 'CPUAccounting=yes' --property 'CPUQuotaPeriodSec=50ms' \ |
694 | --property 'Environment=DSCP=46' \ | 700 | -E DSCP=46 -E NIXOS_OZONE_WL \ |
695 | -- ${lib.getExe pkgs.dscp} ${lib.getExe' pkgs.google-chrome "google-chrome-stable"} \ | 701 | -- ${lib.getExe pkgs.dscp} ${lib.getExe cfg.programs.chromium.package} \ |
696 | --class=Rainbow \ | 702 | --class=Rainbow \ |
697 | --app="https://web.openrainbow.com" \ | 703 | --app="https://web.openrainbow.com" \ |
698 | --user-data-dir=''${HOME}/.config/google-chrome-rainbow | 704 | --user-data-dir=''${HOME}/.config/chromium-rainbow |
699 | ''); | 705 | ''); |
700 | icon = pkgs.fetchurl { | 706 | icon = pkgs.fetchurl { |
701 | url = "https://web.openrainbow.com/rb/2.139.17/assets/skins/rainbow/images/homepage/logo__rainbow.svg"; | 707 | url = "https://web.openrainbow.com/rb/2.139.17/assets/skins/rainbow/images/homepage/logo__rainbow.svg"; |
@@ -709,10 +715,10 @@ in { | |||
709 | name = "Kimai"; | 715 | name = "Kimai"; |
710 | exec = toString (pkgs.writeShellScript "kimai" '' | 716 | exec = toString (pkgs.writeShellScript "kimai" '' |
711 | exec -- \ | 717 | exec -- \ |
712 | ${lib.getExe' pkgs.google-chrome "google-chrome-stable"} \ | 718 | ${lib.getExe cfg.programs.chromium.package} \ |
713 | --class=Kimai \ | 719 | --class=Kimai \ |
714 | --app="https://kimai.yggdrasil.li" \ | 720 | --app="https://kimai.yggdrasil.li" \ |
715 | --user-data-dir=''${HOME}/.config/google-chrome-kimai | 721 | --user-data-dir=''${HOME}/.config/chromium-kimai |
716 | ''); | 722 | ''); |
717 | icon = pkgs.fetchurl { | 723 | icon = pkgs.fetchurl { |
718 | url = "https://www.kimai.org/images/kimai_logo.png"; | 724 | url = "https://www.kimai.org/images/kimai_logo.png"; |
@@ -720,6 +726,25 @@ in { | |||
720 | }; | 726 | }; |
721 | settings = { | 727 | settings = { |
722 | StartupWMClass = "Kimai"; | 728 | StartupWMClass = "Kimai"; |
729 | StartupNotify = "true"; | ||
730 | }; | ||
731 | }; | ||
732 | audiobookshelf = { | ||
733 | name = "Audiobookshelf"; | ||
734 | exec = toString (pkgs.writeShellScript "audiobookshelf" '' | ||
735 | exec -- \ | ||
736 | ${lib.getExe cfg.programs.chromium.package} \ | ||
737 | --class=Audiobookshelf \ | ||
738 | --app="https://audiobookshelf.yggdrasil.li" \ | ||
739 | --user-data-dir=''${HOME}/.config/chromium-audiobookshelf | ||
740 | ''); | ||
741 | icon = pkgs.fetchurl { | ||
742 | url = "https://www.audiobookshelf.org/Logo.png"; | ||
743 | hash = "sha256-JGPk+WNT1C4DC4lSMb0K0YmAMT5LvmSOeO0QRzkc7Lk="; | ||
744 | }; | ||
745 | settings = { | ||
746 | StartupWMClass = "Audiobookshelf"; | ||
747 | StartupNotify = "true"; | ||
723 | }; | 748 | }; |
724 | }; | 749 | }; |
725 | thunderbird-lmu = { | 750 | thunderbird-lmu = { |
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix index bf997b7d..35a3d799 100644 --- a/accounts/gkleen@sif/niri/default.nix +++ b/accounts/gkleen@sif/niri/default.nix | |||
@@ -3,6 +3,7 @@ let | |||
3 | cfg = config.programs.niri; | 3 | cfg = config.programs.niri; |
4 | 4 | ||
5 | kdl = flakeInputs.niri-flake.lib.kdl; | 5 | kdl = flakeInputs.niri-flake.lib.kdl; |
6 | sleaf = name: arg: kdl.node name [arg] []; | ||
6 | 7 | ||
7 | niri = cfg.package; | 8 | niri = cfg.package; |
8 | terminal = lib.getExe config.programs.kitty.package; | 9 | terminal = lib.getExe config.programs.kitty.package; |
@@ -134,7 +135,7 @@ let | |||
134 | 135 | ||
135 | windows_json="$(niri msg -j windows)" | 136 | windows_json="$(niri msg -j windows)" |
136 | active_workspace="$(jq -r '.[] | select(.is_focused) | .workspace_id' <<<"$windows_json")" | 137 | active_workspace="$(jq -r '.[] | select(.is_focused) | .workspace_id' <<<"$windows_json")" |
137 | window_ix="$(gojq -r --arg active_workspace "$active_workspace" '.[] | select('"$window_select"') | "\(.title)\u0000icon\u001f\(.app_id)"' <<<"$windows_json" | fuzzel --log-level=warning --dmenu --index)" | 138 | window_ix="$(gojq -r --arg active_workspace "$active_workspace" '.[] | select('"$window_select"') | "\(.title)\u0000icon\u001f\(.app_id)"' <<<"$windows_json" | fuzzel --width=60 --log-level=warning --dmenu --index)" |
138 | # shellcheck disable=SC2016 | 139 | # shellcheck disable=SC2016 |
139 | window_json="$(gojq -rc --arg active_workspace "$active_workspace" --arg window_ix "$window_ix" 'map(select('"$window_select"')) | .[($window_ix | tonumber)]' <<<"$windows_json")" | 140 | window_json="$(gojq -rc --arg active_workspace "$active_workspace" --arg window_ix "$window_ix" 'map(select('"$window_select"')) | .[($window_ix | tonumber)]' <<<"$windows_json")" |
140 | 141 | ||
@@ -449,8 +450,8 @@ in { | |||
449 | { title = "^Access Request.*"; } | 450 | { title = "^Access Request.*"; } |
450 | { title = ".*Passkey credentials$"; } | 451 | { title = ".*Passkey credentials$"; } |
451 | ]; | 452 | ]; |
452 | windowRuleExtra = [ | 453 | windowRuleExtra = with kdl; [ |
453 | (kdl.leaf "open-focused" false) | 454 | (sleaf "open-focused" false) |
454 | ]; | 455 | ]; |
455 | key = "Mod+Control+P"; | 456 | key = "Mod+Control+P"; |
456 | app-id = "org.keepassxc.KeePassXC"; | 457 | app-id = "org.keepassxc.KeePassXC"; |
@@ -477,6 +478,20 @@ in { | |||
477 | app-id = "com.github.wwmm.easyeffects"; | 478 | app-id = "com.github.wwmm.easyeffects"; |
478 | spawn = [ "easyeffects" ]; | 479 | spawn = [ "easyeffects" ]; |
479 | } | 480 | } |
481 | { name = "time"; | ||
482 | key = "Mod+Control+K"; | ||
483 | app-id = "chrome-kimai.yggdrasil.li__-Default"; | ||
484 | spawn = [ (toString (pkgs.resholve.writeScript "kimai" { | ||
485 | interpreter = pkgs.runtimeShell; | ||
486 | inputs = [ pkgs.dex ]; | ||
487 | execer = [ "cannot:${lib.getExe pkgs.dex}" ]; | ||
488 | } '' | ||
489 | exec dex $HOME/.local/state/nix/profile/share/applications/kimai.desktop | ||
490 | '')) ]; | ||
491 | windowRuleExtra = with kdl; [ | ||
492 | (sleaf "block-out-from" "screencast") | ||
493 | ]; | ||
494 | } | ||
480 | ]; | 495 | ]; |
481 | programs.niri.config = | 496 | programs.niri.config = |
482 | let | 497 | let |
@@ -486,10 +501,12 @@ in { | |||
486 | then v | 501 | then v |
487 | else null; | 502 | else null; |
488 | opt-props = lib.filterAttrs (lib.const (value: value != null)); | 503 | opt-props = lib.filterAttrs (lib.const (value: value != null)); |
504 | normalize-nodes = nodes: lib.remove null (lib.flatten nodes); | ||
489 | in | 505 | in |
490 | [ (flag "prefer-no-csd") | 506 | normalize-nodes [ |
507 | (flag "prefer-no-csd") | ||
491 | 508 | ||
492 | (leaf "screenshot-path" "~/screenshots/%Y-%m-%dT%H:%M:%S.png") | 509 | (sleaf "screenshot-path" "~/screenshots/%Y-%m-%dT%H:%M:%S.png") |
493 | 510 | ||
494 | (plain "hotkey-overlay" [ | 511 | (plain "hotkey-overlay" [ |
495 | (flag "skip-at-startup") | 512 | (flag "skip-at-startup") |
@@ -497,27 +514,27 @@ in { | |||
497 | 514 | ||
498 | (plain "input" [ | 515 | (plain "input" [ |
499 | (plain "keyboard" [ | 516 | (plain "keyboard" [ |
500 | (leaf "repeat-delay" 300) | 517 | (sleaf "repeat-delay" 300) |
501 | (leaf "repeat-rate" 50) | 518 | (sleaf "repeat-rate" 50) |
502 | 519 | ||
503 | (plain "xkb" [ | 520 | (plain "xkb" [ |
504 | (leaf "layout" "us,us") | 521 | (sleaf "layout" "us,us") |
505 | (leaf "variant" "dvp,") | 522 | (sleaf "variant" "dvp,") |
506 | (leaf "options" "compose:caps,grp:win_space_toggle") | 523 | (sleaf "options" "compose:caps,grp:win_space_toggle") |
507 | ]) | 524 | ]) |
508 | ]) | 525 | ]) |
509 | 526 | ||
510 | (flag "workspace-auto-back-and-forth") | 527 | (flag "workspace-auto-back-and-forth") |
511 | # (leaf "focus-follows-mouse" {}) | 528 | # (sleaf "focus-follows-mouse" {}) |
512 | # (flag "warp-mouse-to-focus") | 529 | # (flag "warp-mouse-to-focus") |
513 | 530 | ||
514 | # (plain "touchpad" [ (flag "off") ]) | 531 | # (plain "touchpad" [ (flag "off") ]) |
515 | (plain "trackball" [ | 532 | (plain "trackball" [ |
516 | (leaf "scroll-method" "on-button-down") | 533 | (sleaf "scroll-method" "on-button-down") |
517 | (leaf "scroll-button" 278) | 534 | (sleaf "scroll-button" 278) |
518 | ]) | 535 | ]) |
519 | (plain "touch" [ | 536 | (plain "touch" [ |
520 | (leaf "map-to-output" "eDP-1") | 537 | (sleaf "map-to-output" "eDP-1") |
521 | ]) | 538 | ]) |
522 | ]) | 539 | ]) |
523 | 540 | ||
@@ -525,7 +542,7 @@ in { | |||
525 | (plain "hot-corners" [(flag "off")]) | 542 | (plain "hot-corners" [(flag "off")]) |
526 | ]) | 543 | ]) |
527 | 544 | ||
528 | (plain "environment" (lib.mapAttrsToList leaf { | 545 | (plain "environment" (lib.mapAttrsToList sleaf { |
529 | NIXOS_OZONE_WL = "1"; | 546 | NIXOS_OZONE_WL = "1"; |
530 | QT_QPA_PLATFORM = "wayland"; | 547 | QT_QPA_PLATFORM = "wayland"; |
531 | QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; | 548 | QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; |
@@ -538,47 +555,47 @@ in { | |||
538 | SUDO_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass; | 555 | SUDO_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass; |
539 | })) | 556 | })) |
540 | 557 | ||
541 | (node "output" "eDP-1" [ | 558 | (node "output" ["eDP-1"] [ |
542 | (leaf "scale" 1.5) | 559 | (sleaf "scale" 1.5) |
543 | (leaf "position" { x = 0; y = 0; }) | 560 | (sleaf "position" { x = 0; y = 0; }) |
544 | ]) | 561 | ]) |
545 | (node "output" "Ancor Communications Inc ASUS PB287Q 0x0000DD9B" [ | 562 | (node "output" ["Ancor Communications Inc ASUS PB287Q 0x0000DD9B"] [ |
546 | (leaf "scale" 1.5) | 563 | (sleaf "scale" 1.5) |
547 | (leaf "position" { x = 2560; y = 0; }) | 564 | (sleaf "position" { x = 2560; y = 0; }) |
548 | ]) | 565 | ]) |
549 | (node "output" "HP Inc. HP 727pu CN4417143K" [ | 566 | (node "output" ["HP Inc. HP 727pu CN4417143K"] [ |
550 | (leaf "mode" "2560x1440@119.998") | 567 | (sleaf "mode" "2560x1440@119.998") |
551 | (leaf "scale" 1) | 568 | (sleaf "scale" 1) |
552 | (leaf "position" { x = 2560; y = 0; }) | 569 | (sleaf "position" { x = 2560; y = 0; }) |
553 | (flag "variable-refresh-rate") | 570 | (flag "variable-refresh-rate") |
554 | ]) | 571 | ]) |
555 | 572 | ||
556 | (plain "debug" [ | 573 | (plain "debug" [ |
557 | (leaf "render-drm-device" "/dev/dri/by-path/pci-0000:00:02.0-render") | 574 | (sleaf "render-drm-device" "/dev/dri/by-path/pci-0000:00:02.0-render") |
558 | ]) | 575 | ]) |
559 | 576 | ||
560 | (plain "animations" [ | 577 | (plain "animations" [ |
561 | (leaf "slowdown" 0.5) | 578 | (sleaf "slowdown" 0.5) |
562 | (plain "workspace-switch" [(flag "off")]) | 579 | (plain "workspace-switch" [(flag "off")]) |
563 | ]) | 580 | ]) |
564 | 581 | ||
565 | (plain "layout" [ | 582 | (plain "layout" [ |
566 | (leaf "gaps" 8) | 583 | (sleaf "gaps" 8) |
567 | (plain "struts" [ | 584 | (plain "struts" [ |
568 | (leaf "left" 26) | 585 | (sleaf "left" 26) |
569 | (leaf "right" 26) | 586 | (sleaf "right" 26) |
570 | (leaf "top" 0) | 587 | (sleaf "top" 0) |
571 | (leaf "bottom" 0) | 588 | (sleaf "bottom" 0) |
572 | ]) | 589 | ]) |
573 | (plain "border" [ | 590 | (plain "border" [ |
574 | (leaf "width" 2) | 591 | (sleaf "width" 2) |
575 | (leaf "active-gradient" { | 592 | (sleaf "active-gradient" { |
576 | from = "hsla(195 100% 45% 1)"; | 593 | from = "hsla(195 100% 45% 1)"; |
577 | to = "hsla(155 100% 37.5% 1)"; | 594 | to = "hsla(155 100% 37.5% 1)"; |
578 | angle = 29; | 595 | angle = 29; |
579 | relative-to = "workspace-view"; | 596 | relative-to = "workspace-view"; |
580 | }) | 597 | }) |
581 | (leaf "inactive-gradient" { | 598 | (sleaf "inactive-gradient" { |
582 | from = "hsla(0 0% 27.7% 1)"; | 599 | from = "hsla(0 0% 27.7% 1)"; |
583 | to = "hsla(0 0% 23% 1)"; | 600 | to = "hsla(0 0% 23% 1)"; |
584 | angle = 29; | 601 | angle = 29; |
@@ -589,29 +606,29 @@ in { | |||
589 | (flag "off") | 606 | (flag "off") |
590 | ]) | 607 | ]) |
591 | 608 | ||
592 | (plain "preset-column-widths" (map (prop: leaf "proportion" prop) [ | 609 | (plain "preset-column-widths" (map (prop: sleaf "proportion" prop) [ |
593 | (1. / 4.) (1. / 3.) (1. / 2.) (2. / 3.) (3. / 4.) (1.) | 610 | (1. / 4.) (1. / 3.) (1. / 2.) (2. / 3.) (3. / 4.) (1.) |
594 | ])) | 611 | ])) |
595 | (plain "default-column-width" [ (leaf "proportion" (1. / 2.)) ]) | 612 | (plain "default-column-width" [ (sleaf "proportion" (1. / 2.)) ]) |
596 | (plain "preset-window-heights" (map (prop: leaf "proportion" prop) [ | 613 | (plain "preset-window-heights" (map (prop: sleaf "proportion" prop) [ |
597 | (1. / 3.) (1. / 2.) (2. / 3.) (1.) | 614 | (1. / 3.) (1. / 2.) (2. / 3.) (1.) |
598 | ])) | 615 | ])) |
599 | 616 | ||
600 | (flag "always-center-single-column") | 617 | (flag "always-center-single-column") |
601 | 618 | ||
602 | (plain "tab-indicator" [ | 619 | (plain "tab-indicator" [ |
603 | (leaf "gap" 4) | 620 | (sleaf "gap" 4) |
604 | (leaf "width" 8) | 621 | (sleaf "width" 8) |
605 | (leaf "gaps-between-tabs" 4) | 622 | (sleaf "gaps-between-tabs" 4) |
606 | (flag "place-within-column") | 623 | (flag "place-within-column") |
607 | (leaf "length" { total-proportion = 1.; }) | 624 | (sleaf "length" { total-proportion = 1.; }) |
608 | (leaf "active-gradient" { | 625 | (sleaf "active-gradient" { |
609 | from = "hsla(195 100% 60% 0.75)"; | 626 | from = "hsla(195 100% 60% 0.75)"; |
610 | to = "hsla(155 100% 50% 0.75)"; | 627 | to = "hsla(155 100% 50% 0.75)"; |
611 | angle = 29; | 628 | angle = 29; |
612 | relative-to = "workspace-view"; | 629 | relative-to = "workspace-view"; |
613 | }) | 630 | }) |
614 | (leaf "inactive-gradient" { | 631 | (sleaf "inactive-gradient" { |
615 | from = "hsla(0 0% 42% 0.66)"; | 632 | from = "hsla(0 0% 42% 0.66)"; |
616 | to = "hsla(0 0% 35% 0.66)"; | 633 | to = "hsla(0 0% 35% 0.66)"; |
617 | angle = 29; | 634 | angle = 29; |
@@ -625,130 +642,121 @@ in { | |||
625 | ]) | 642 | ]) |
626 | 643 | ||
627 | (map (name: | 644 | (map (name: |
628 | (node "workspace" name [ | 645 | (node "workspace" [name] [ |
629 | (leaf "open-on-output" "eDP-1") | 646 | (sleaf "open-on-output" "eDP-1") |
630 | ]) | 647 | ]) |
631 | ) (map ({name, ...}: name) cfg.scratchspaces)) | 648 | ) (map ({name, ...}: name) cfg.scratchspaces)) |
632 | (map (name: | 649 | (map (name: |
633 | (leaf "workspace" name) | 650 | (sleaf "workspace" name) |
634 | ) ["comm" "web" "vid" "bmr"]) | 651 | ) ["comm" "web" "vid" "bmr"]) |
635 | 652 | ||
636 | (plain "window-rule" [ | 653 | (plain "window-rule" [ |
637 | (leaf "clip-to-geometry" true) | 654 | (sleaf "clip-to-geometry" true) |
638 | ]) | 655 | ]) |
639 | 656 | ||
640 | (plain "window-rule" [ | 657 | (plain "window-rule" [ |
641 | (leaf "match" { is-floating = true; }) | 658 | (sleaf "match" { is-floating = true; }) |
642 | (leaf "geometry-corner-radius" 8) | 659 | (sleaf "geometry-corner-radius" 8) |
643 | (plain "shadow" [ (flag "on") ]) | 660 | (plain "shadow" [ (flag "on") ]) |
644 | ]) | 661 | ]) |
645 | 662 | ||
646 | (plain "window-rule" [ | 663 | (plain "window-rule" [ |
647 | (leaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; }) | 664 | (sleaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; }) |
648 | (leaf "block-out-from" "screencast") | 665 | (sleaf "block-out-from" "screencast") |
649 | ]) | 666 | ]) |
650 | (plain "window-rule" [ | 667 | (plain "window-rule" (normalize-nodes [ |
651 | (map (title: | 668 | (map (title: |
652 | (leaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; }) | 669 | (sleaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; }) |
653 | ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$"]) | 670 | ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$" "Browser Access Request$"]) |
654 | (leaf "open-focused" true) | 671 | (sleaf "open-focused" true) |
655 | (leaf "open-floating" true) | 672 | (sleaf "open-floating" true) |
656 | ]) | 673 | ])) |
657 | 674 | ||
658 | (map ({ name, match, exclude, windowRuleExtra, ... }: | 675 | (map ({ name, match, exclude, windowRuleExtra, ... }: |
659 | (optional-node (match != []) (plain "window-rule" [ | 676 | (optional-node (match != []) (plain "window-rule" (normalize-nodes [ |
660 | (map (leaf "match") match) | 677 | (map (sleaf "match") match) |
661 | (map (leaf "exclude") exclude) | 678 | (map (sleaf "exclude") exclude) |
662 | (leaf "open-on-workspace" name) | 679 | (sleaf "open-on-workspace" name) |
663 | (leaf "open-maximized" true) | 680 | (sleaf "open-maximized" true) |
664 | windowRuleExtra | 681 | windowRuleExtra |
665 | ])) | 682 | ]))) |
666 | ) cfg.scratchspaces) | 683 | ) cfg.scratchspaces) |
667 | 684 | ||
668 | (plain "window-rule" [ | 685 | (plain "window-rule" [ |
669 | (leaf "match" { app-id = "^emacs$"; }) | 686 | (sleaf "match" { app-id = "^emacs$"; }) |
670 | (leaf "match" { app-id = "^firefox$"; }) | 687 | (sleaf "match" { app-id = "^firefox$"; }) |
671 | (plain "default-column-width" [(leaf "proportion" (2. / 3.))]) | 688 | (plain "default-column-width" [(sleaf "proportion" (2. / 3.))]) |
672 | ]) | 689 | ]) |
673 | (plain "window-rule" [ | 690 | (plain "window-rule" [ |
674 | (leaf "match" { app-id = "^kitty$"; }) | 691 | (sleaf "match" { app-id = "^kitty$"; }) |
675 | (leaf "match" { app-id = "^kitty-play$"; }) | 692 | (sleaf "match" { app-id = "^kitty-play$"; }) |
676 | (plain "default-column-width" [(leaf "proportion" (1. / 3.))]) | 693 | (plain "default-column-width" [(sleaf "proportion" (1. / 3.))]) |
677 | ]) | 694 | ]) |
678 | 695 | ||
679 | (plain "window-rule" [ | 696 | (plain "window-rule" [ |
680 | (leaf "match" { app-id = "^thunderbird$"; }) | 697 | (sleaf "match" { app-id = "^thunderbird$"; }) |
681 | (leaf "match" { app-id = "^Element$"; }) | 698 | (sleaf "match" { app-id = "^Element$"; }) |
682 | (leaf "match" { app-id = "^Rainbow$"; }) | 699 | (sleaf "match" { app-id = "^chrome-web\.openrainbow\.com__-Default$"; }) |
683 | (leaf "open-on-workspace" "comm") | 700 | (sleaf "open-on-workspace" "comm") |
684 | ]) | 701 | ]) |
685 | (plain "window-rule" [ | 702 | (plain "window-rule" [ |
686 | (leaf "match" { app-id = "^Kimai$"; }) | 703 | (sleaf "match" { app-id = "^firefox$"; }) |
687 | (leaf "open-on-workspace" "comm") | 704 | (sleaf "open-on-workspace" "web") |
688 | (leaf "open-fullscreen" false) | 705 | (sleaf "open-maximized" true) |
689 | (plain "default-column-width" [(leaf "proportion" (2. / 3.))]) | ||
690 | ]) | 706 | ]) |
691 | (plain "window-rule" [ | 707 | (plain "window-rule" [ |
692 | (leaf "match" { app-id = "^firefox$"; }) | 708 | (sleaf "match" { app-id = "^mpv$"; }) |
693 | (leaf "open-on-workspace" "web") | 709 | (sleaf "open-on-workspace" "vid") |
694 | (leaf "open-maximized" true) | 710 | (plain "default-column-width" [(sleaf "proportion" 1.)]) |
695 | ]) | 711 | ]) |
696 | (plain "window-rule" [ | 712 | (plain "window-rule" [ |
697 | (leaf "match" { app-id = "^mpv$"; }) | 713 | (sleaf "match" { app-id = "^kitty-play$"; }) |
698 | (leaf "open-on-workspace" "vid") | 714 | (sleaf "open-on-workspace" "vid") |
699 | (plain "default-column-width" [(leaf "proportion" 1.)]) | 715 | (sleaf "open-focused" false) |
700 | ]) | 716 | ]) |
701 | (plain "window-rule" [ | 717 | (plain "window-rule" [ |
702 | (leaf "match" { app-id = "^kitty-play$"; }) | 718 | (sleaf "match" { app-id = "^chrome-audiobookshelf\.yggdrasil\.li__-Default$"; }) |
703 | (leaf "open-on-workspace" "vid") | 719 | (sleaf "match" { app-id = "^YouTube Music Desktop App$"; }) |
704 | (leaf "open-focused" false) | 720 | (sleaf "open-on-workspace" "vid") |
705 | ]) | 721 | ]) |
706 | (plain "window-rule" [ | 722 | (plain "window-rule" [ |
707 | (leaf "match" { app-id = "^pdfpc$"; }) | 723 | (sleaf "match" { app-id = "^pdfpc$"; }) |
708 | (plain "default-column-width" [(leaf "proportion" 1.)]) | 724 | (plain "default-column-width" [(sleaf "proportion" 1.)]) |
709 | ]) | 725 | ]) |
710 | (plain "window-rule" [ | 726 | (plain "window-rule" [ |
711 | (leaf "match" { app-id = "^pdfpc$"; title = "^.*presentation.*$"; }) | 727 | (sleaf "match" { app-id = "^pdfpc$"; title = "^.*presentation.*$"; }) |
712 | (plain "default-column-width" [(leaf "proportion" 1.)]) | 728 | (plain "default-column-width" [(sleaf "proportion" 1.)]) |
713 | (leaf "open-fullscreen" true) | 729 | (sleaf "open-fullscreen" true) |
714 | (leaf "open-on-workspace" "bmr") | 730 | (sleaf "open-on-workspace" "bmr") |
715 | (leaf "open-focused" false) | 731 | (sleaf "open-focused" false) |
716 | ]) | 732 | ]) |
717 | (plain "window-rule" [ | 733 | (plain "window-rule" (normalize-nodes [ |
718 | (map (leaf "match") [ | 734 | (map (sleaf "match") [ |
719 | { app-id = "^Gimp-"; title = "^Quit GIMP$"; } | 735 | { app-id = "^Gimp-"; title = "^Quit GIMP$"; } |
720 | { app-id = "^org\\.kde\\.polkit-kde-authentication-agent-1$"; } | 736 | { app-id = "^org\\.kde\\.polkit-kde-authentication-agent-1$"; } |
721 | { app-id = "^xdg-desktop-portal-gtk$"; } | 737 | { app-id = "^xdg-desktop-portal-gtk$"; } |
722 | ]) | 738 | ]) |
723 | (leaf "open-floating" true) | 739 | (sleaf "open-floating" true) |
724 | ]) | 740 | ])) |
725 | (plain "window-rule" [ | 741 | (plain "window-rule" [ |
726 | (leaf "match" { app-id = "^org\\.pwmt\\.zathura$"; }) | 742 | (sleaf "match" { app-id = "^org\\.pwmt\\.zathura$"; }) |
727 | (leaf "match" { app-id = "^evince$"; }) | 743 | (sleaf "match" { app-id = "^evince$"; }) |
728 | (leaf "match" { app-id = "^org\\.gnome\\.Papers$"; }) | 744 | (sleaf "match" { app-id = "^org\\.gnome\\.Papers$"; }) |
729 | (leaf "default-column-display" "tabbed") | 745 | (sleaf "default-column-display" "tabbed") |
730 | ]) | 746 | ]) |
731 | 747 | ||
732 | (plain "layer-rule" [ | 748 | (plain "layer-rule" [ |
733 | (leaf "match" { namespace = "^notifications$"; }) | 749 | (sleaf "match" { namespace = "^notifications$"; }) |
734 | (leaf "match" { namespace = "^waybar$"; }) | 750 | (sleaf "match" { namespace = "^waybar$"; }) |
735 | (leaf "match" { namespace = "^launcher$"; }) | 751 | (sleaf "match" { namespace = "^launcher$"; }) |
736 | (leaf "block-out-from" "screencast") | 752 | (sleaf "block-out-from" "screencast") |
737 | ]) | 753 | ]) |
738 | 754 | ||
739 | (plain "binds" | 755 | (plain "binds" |
740 | (let | 756 | (let |
741 | bind = name: cfg: node name (opt-props { | 757 | bind = name: cfg: node name [(lib.removeAttrs cfg ["action"])] (lib.mapAttrsToList leaf (lib.removeAttrs cfg.action ["__functor"])); |
742 | cooldown-ms = cfg.cooldown-ms or null; | ||
743 | } | ||
744 | // (lib.optionalAttrs (!(cfg.repeat or true)) { | ||
745 | repeat = false; | ||
746 | }) | ||
747 | // (lib.optionalAttrs (cfg.allow-when-locked or false) { | ||
748 | allow-when-locked = true; | ||
749 | })) (lib.mapAttrsToList leaf (lib.removeAttrs cfg.action ["__functor"])); | ||
750 | in | 758 | in |
751 | [ | 759 | normalize-nodes [ |
752 | (lib.mapAttrsToList bind (with config.lib.niri.actions; { | 760 | (lib.mapAttrsToList bind (with config.lib.niri.actions; { |
753 | "Mod+Slash".action = show-hotkey-overlay; | 761 | "Mod+Slash".action = show-hotkey-overlay; |
754 | 762 | ||
@@ -803,12 +811,12 @@ in { | |||
803 | done < <(export LC_ALL=C.UTF-8; echo; find "$RESULTS_DIR" -type f -printf $'%T@ %p\n' | sort -n | cut -d' ' -f2- | xargs -r cat) | 811 | done < <(export LC_ALL=C.UTF-8; echo; find "$RESULTS_DIR" -type f -printf $'%T@ %p\n' | sort -n | cut -d' ' -f2- | xargs -r cat) |
804 | $FOUND || echo | 812 | $FOUND || echo |
805 | } | 813 | } |
806 | FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> ") || exit $? | 814 | FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> " --width=60) || exit $? |
807 | if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then | 815 | if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then |
808 | QALC_RES="$FUZZEL_RES" | 816 | QALC_RES="$FUZZEL_RES" |
809 | QALC_RET=0 | 817 | QALC_RET=0 |
810 | else | 818 | else |
811 | QALC_RES=$(qalc "$FUZZEL_RES" 2>&1) | 819 | QALC_RES=$(qalc -set "autocalc off" "$FUZZEL_RES" 2>&1) |
812 | QALC_RET=$? | 820 | QALC_RET=$? |
813 | fi | 821 | fi |
814 | [[ -n "$QALC_RES" ]] || exit 1 | 822 | [[ -n "$QALC_RES" ]] || exit 1 |
@@ -828,11 +836,26 @@ in { | |||
828 | notify-send "$QALC_RES" | 836 | notify-send "$QALC_RES" |
829 | ''; | 837 | ''; |
830 | })); | 838 | })); |
839 | "Mod+Shift+U".action = | ||
840 | let | ||
841 | qalcKitty = pkgs.symlinkJoin { | ||
842 | name = "qalc-kitty"; | ||
843 | paths = [ config.programs.kitty.package ]; | ||
844 | buildInputs = [ pkgs.makeWrapper ]; | ||
845 | postBuild = '' | ||
846 | wrapProgram $out/bin/kitty \ | ||
847 | --add-flags "--config ${pkgs.writeText "kitty.conf" '' | ||
848 | include $HOME/${config.xdg.configFile."kitty/kitty.conf".target} | ||
849 | shell ${lib.getExe pkgs.libqalculate} | ||
850 | ''}" | ||
851 | ''; | ||
852 | }; | ||
853 | in spawn (lib.getExe' qalcKitty "kitty"); | ||
831 | "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication { | 854 | "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication { |
832 | name = "emoji-fuzzel"; | 855 | name = "emoji-fuzzel"; |
833 | runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ]; | 856 | runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ]; |
834 | text = '' | 857 | text = '' |
835 | FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " <"$HOME"/.local/share/emoji-data/list.txt) || exit $? | 858 | FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " --cache "$HOME"/.cache/fuzzel-emoji --width=60 <"$HOME"/.local/share/emoji-data/list.txt) || exit $? |
836 | [[ -n "$FUZZEL_RES" ]] || exit 1 | 859 | [[ -n "$FUZZEL_RES" ]] || exit 1 |
837 | wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste | 860 | wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste |
838 | ''; | 861 | ''; |
@@ -973,6 +996,9 @@ in { | |||
973 | 996 | ||
974 | "Mod+D".action = with-urgent-window-action "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | 997 | "Mod+D".action = with-urgent-window-action "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; |
975 | "Mod+Shift+D".action = with-focused-window-action "{\"Action\":{\"UnsetUrgent\":{\"id\": .id}}}"; | 998 | "Mod+Shift+D".action = with-focused-window-action "{\"Action\":{\"UnsetUrgent\":{\"id\": .id}}}"; |
999 | |||
1000 | "Mod+K".action = spawn (lib.getExe' pkgs.worktime "worktime-ui"); | ||
1001 | "Mod+Shift+K".action = spawn (lib.getExe' pkgs.worktime "worktime-stop"); | ||
976 | })) | 1002 | })) |
977 | (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) | 1003 | (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) |
978 | (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces) | 1004 | (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces) |
diff --git a/accounts/gkleen@sif/niri/mako.nix b/accounts/gkleen@sif/niri/mako.nix index 810bff89..703d5f7b 100644 --- a/accounts/gkleen@sif/niri/mako.nix +++ b/accounts/gkleen@sif/niri/mako.nix | |||
@@ -14,8 +14,7 @@ | |||
14 | outer-margin = 1; | 14 | outer-margin = 1; |
15 | max-history = 100; | 15 | max-history = 100; |
16 | max-icon-size = 48; | 16 | max-icon-size = 48; |
17 | }; | 17 | |
18 | criteria = { | ||
19 | grouped.format = "<b>(%g)</b> <i>%s</i>\\n%b"; | 18 | grouped.format = "<b>(%g)</b> <i>%s</i>\\n%b"; |
20 | "urgency=low".text-color = "#999999ff"; | 19 | "urgency=low".text-color = "#999999ff"; |
21 | "urgency=critical".background-color = "#900000dd"; | 20 | "urgency=critical".background-color = "#900000dd"; |
@@ -25,6 +24,7 @@ | |||
25 | ignore-timeout = true; | 24 | ignore-timeout = true; |
26 | default-timeout = 2000; | 25 | default-timeout = 2000; |
27 | }; | 26 | }; |
27 | "app-name=worktime".history = false; | ||
28 | "mode=silent".invisible = true; | 28 | "mode=silent".invisible = true; |
29 | }; | 29 | }; |
30 | package = pkgs.symlinkJoin { | 30 | package = pkgs.symlinkJoin { |
diff --git a/accounts/gkleen@sif/systemd.nix b/accounts/gkleen@sif/systemd.nix index 90cccc58..18c2315f 100644 --- a/accounts/gkleen@sif/systemd.nix +++ b/accounts/gkleen@sif/systemd.nix | |||
@@ -385,6 +385,8 @@ in { | |||
385 | }; | 385 | }; |
386 | Service = { | 386 | Service = { |
387 | ExecStart = "${config.systemd.package}/lib/systemd/systemd-socket-proxyd --exit-idle-time=60s 127.0.0.1:${toString (port + 1)}"; | 387 | ExecStart = "${config.systemd.package}/lib/systemd/systemd-socket-proxyd --exit-idle-time=60s 127.0.0.1:${toString (port + 1)}"; |
388 | Restart = "always"; | ||
389 | RestartSec = "23s"; | ||
388 | }; | 390 | }; |
389 | }) [{ host = "proxy.ssh.math.lmu.de"; port = 8118; } { host = "proxy.vidhar"; port = 8120; } { host = "proxy.mathw0h"; port = 8122; } { host = "proxy.mathw0e"; port = 8124; }]); | 391 | }) [{ host = "proxy.ssh.math.lmu.de"; port = 8118; } { host = "proxy.vidhar"; port = 8120; } { host = "proxy.mathw0h"; port = 8122; } { host = "proxy.mathw0e"; port = 8124; }]); |
390 | sockets = listToAttrs (map (port: nameValuePair "proxy-to-autossh-socks@${toString port}" { | 392 | sockets = listToAttrs (map (port: nameValuePair "proxy-to-autossh-socks@${toString port}" { |
diff --git a/accounts/gkleen@sif/utils/pdf2pdf.nix b/accounts/gkleen@sif/utils/pdf2pdf.nix new file mode 100644 index 00000000..9f4cbc3e --- /dev/null +++ b/accounts/gkleen@sif/utils/pdf2pdf.nix | |||
@@ -0,0 +1,8 @@ | |||
1 | pkgs@{ lib, resholve, zsh, ghostscript_headless, ... }: | ||
2 | |||
3 | resholve.writeScriptBin "pdf2pdf" { | ||
4 | inputs = with pkgs; [ghostscript_headless]; | ||
5 | interpreter = lib.getExe zsh; | ||
6 | } '' | ||
7 | exec gs -dPDFSETTINGS=/prepress -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER -dPreserveAnnots=false "-sOutputFile=''${2}" "''${1}" | ||
8 | '' | ||
diff --git a/accounts/gkleen@sif/zshrc b/accounts/gkleen@sif/zshrc index abc200c6..702990c3 100644 --- a/accounts/gkleen@sif/zshrc +++ b/accounts/gkleen@sif/zshrc | |||
@@ -93,7 +93,7 @@ dir() { | |||
93 | if [[ $curlArchive = "true" ]]; then | 93 | if [[ $curlArchive = "true" ]]; then |
94 | archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}") | 94 | archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}") |
95 | 95 | ||
96 | curl -L -o ${archiveFile} ${templateArchive} | 96 | curl -SfL -o ${archiveFile} ${templateArchive} |
97 | 97 | ||
98 | templateArchive=${archiveFile} | 98 | templateArchive=${archiveFile} |
99 | fi | 99 | fi |
@@ -132,6 +132,10 @@ dir() { | |||
132 | unpack=false | 132 | unpack=false |
133 | fi | 133 | fi |
134 | ;; | 134 | ;; |
135 | application/x-iso9660-image) | ||
136 | 7z x ${templateArchive} | ||
137 | unpack=false | ||
138 | ;; | ||
135 | *) | 139 | *) |
136 | tar -xvaf ${templateArchive} | 140 | tar -xvaf ${templateArchive} |
137 | unpack=false | 141 | unpack=false |
@@ -231,7 +235,7 @@ clock() { | |||
231 | } | 235 | } |
232 | 236 | ||
233 | public-ip() { | 237 | public-ip() { |
234 | curl -s -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip' | 238 | curl -sSf -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip' |
235 | } | 239 | } |
236 | 240 | ||
237 | swap() { | 241 | swap() { |
@@ -6,22 +6,28 @@ | |||
6 | "nixpkgs": [ | 6 | "nixpkgs": [ |
7 | "nixpkgs" | 7 | "nixpkgs" |
8 | ], | 8 | ], |
9 | "poetry2nix": [ | 9 | "pre-commit-hooks-nix": "pre-commit-hooks-nix", |
10 | "poetry2nix" | 10 | "pyproject-build-systems": [ |
11 | "pyproject-build-systems" | ||
12 | ], | ||
13 | "pyproject-nix": [ | ||
14 | "pyproject-nix" | ||
11 | ], | 15 | ], |
12 | "pre-commit-hooks-nix": "pre-commit-hooks-nix" | 16 | "uv2nix": [ |
17 | "uv2nix" | ||
18 | ] | ||
13 | }, | 19 | }, |
14 | "locked": { | 20 | "locked": { |
15 | "lastModified": 1723124245, | 21 | "lastModified": 1749560907, |
16 | "narHash": "sha256-ThDq7vOXo6G4+C5FHqUc64CeX2c5n36tln4ZlDao6s4=", | 22 | "narHash": "sha256-zvAxxnJ5dcnjbuog0W6UvlthD1dLm5t4ZQI25jzNDW4=", |
17 | "owner": "gkleen", | 23 | "owner": "gkleen", |
18 | "repo": "backup-utils", | 24 | "repo": "backup-utils", |
19 | "rev": "74e65090de63fc99f056098677cc490754e2708f", | 25 | "rev": "8ed6a1d7c2e337cb2e35ed68f6d852f0d1049908", |
20 | "type": "gitlab" | 26 | "type": "gitlab" |
21 | }, | 27 | }, |
22 | "original": { | 28 | "original": { |
23 | "owner": "gkleen", | 29 | "owner": "gkleen", |
24 | "ref": "v0.1.6", | 30 | "ref": "v0.1.7", |
25 | "repo": "backup-utils", | 31 | "repo": "backup-utils", |
26 | "type": "gitlab" | 32 | "type": "gitlab" |
27 | } | 33 | } |
@@ -33,26 +39,45 @@ | |||
33 | "nixpkgs": [ | 39 | "nixpkgs": [ |
34 | "nixpkgs" | 40 | "nixpkgs" |
35 | ], | 41 | ], |
36 | "poetry2nix": [ | 42 | "pre-commit-hooks-nix": "pre-commit-hooks-nix_2", |
37 | "poetry2nix" | 43 | "pyproject-build-systems": "pyproject-build-systems", |
44 | "pyproject-nix": [ | ||
45 | "pyproject-nix" | ||
38 | ], | 46 | ], |
39 | "pre-commit-hooks-nix": "pre-commit-hooks-nix_2" | 47 | "uv2nix": [ |
48 | "uv2nix" | ||
49 | ] | ||
40 | }, | 50 | }, |
41 | "locked": { | 51 | "locked": { |
42 | "lastModified": 1734281899, | 52 | "lastModified": 1750599403, |
43 | "narHash": "sha256-9QdIl3sjHY4Xij9KrBUkW1KpLB+jyxlI12UHPitlawI=", | 53 | "narHash": "sha256-MLQ7CISl00w1xq88TL2wukNq3ukzID4u7BVT4okbUik=", |
44 | "owner": "gkleen", | 54 | "owner": "gkleen", |
45 | "repo": "ca", | 55 | "repo": "ca", |
46 | "rev": "1e4ee9d25a5282ef7bc6774072229784fa0036f3", | 56 | "rev": "505a29233ada969b2eca76d616b0d7a8767dfb71", |
47 | "type": "gitlab" | 57 | "type": "gitlab" |
48 | }, | 58 | }, |
49 | "original": { | 59 | "original": { |
50 | "owner": "gkleen", | 60 | "owner": "gkleen", |
51 | "ref": "v3.1.3", | 61 | "ref": "v3.1.5", |
52 | "repo": "ca", | 62 | "repo": "ca", |
53 | "type": "gitlab" | 63 | "type": "gitlab" |
54 | } | 64 | } |
55 | }, | 65 | }, |
66 | "crane": { | ||
67 | "locked": { | ||
68 | "lastModified": 1731098351, | ||
69 | "narHash": "sha256-HQkYvKvaLQqNa10KEFGgWHfMAbWBfFp+4cAgkut+NNE=", | ||
70 | "owner": "ipetkov", | ||
71 | "repo": "crane", | ||
72 | "rev": "ef80ead953c1b28316cc3f8613904edc2eb90c28", | ||
73 | "type": "github" | ||
74 | }, | ||
75 | "original": { | ||
76 | "owner": "ipetkov", | ||
77 | "repo": "crane", | ||
78 | "type": "github" | ||
79 | } | ||
80 | }, | ||
56 | "deploy-rs": { | 81 | "deploy-rs": { |
57 | "inputs": { | 82 | "inputs": { |
58 | "flake-compat": [ | 83 | "flake-compat": [ |
@@ -66,11 +91,11 @@ | |||
66 | ] | 91 | ] |
67 | }, | 92 | }, |
68 | "locked": { | 93 | "locked": { |
69 | "lastModified": 1727447169, | 94 | "lastModified": 1749105467, |
70 | "narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", | 95 | "narHash": "sha256-hXh76y/wDl15almBcqvjryB50B0BaiXJKk20f314RoE=", |
71 | "owner": "serokell", | 96 | "owner": "serokell", |
72 | "repo": "deploy-rs", | 97 | "repo": "deploy-rs", |
73 | "rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", | 98 | "rev": "6bc76b872374845ba9d645a2f012b764fecd765f", |
74 | "type": "github" | 99 | "type": "github" |
75 | }, | 100 | }, |
76 | "original": { | 101 | "original": { |
@@ -132,6 +157,22 @@ | |||
132 | "flake-compat_4": { | 157 | "flake-compat_4": { |
133 | "flake": false, | 158 | "flake": false, |
134 | "locked": { | 159 | "locked": { |
160 | "lastModified": 1696426674, | ||
161 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", | ||
162 | "owner": "edolstra", | ||
163 | "repo": "flake-compat", | ||
164 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", | ||
165 | "type": "github" | ||
166 | }, | ||
167 | "original": { | ||
168 | "owner": "edolstra", | ||
169 | "repo": "flake-compat", | ||
170 | "type": "github" | ||
171 | } | ||
172 | }, | ||
173 | "flake-compat_5": { | ||
174 | "flake": false, | ||
175 | "locked": { | ||
135 | "lastModified": 1673956053, | 176 | "lastModified": 1673956053, |
136 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", | 177 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", |
137 | "owner": "edolstra", | 178 | "owner": "edolstra", |
@@ -168,11 +209,11 @@ | |||
168 | "nixpkgs-lib": "nixpkgs-lib_2" | 209 | "nixpkgs-lib": "nixpkgs-lib_2" |
169 | }, | 210 | }, |
170 | "locked": { | 211 | "locked": { |
171 | "lastModified": 1733312601, | 212 | "lastModified": 1749398372, |
172 | "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", | 213 | "narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=", |
173 | "owner": "hercules-ci", | 214 | "owner": "hercules-ci", |
174 | "repo": "flake-parts", | 215 | "repo": "flake-parts", |
175 | "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", | 216 | "rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569", |
176 | "type": "github" | 217 | "type": "github" |
177 | }, | 218 | }, |
178 | "original": { | 219 | "original": { |
@@ -183,6 +224,27 @@ | |||
183 | }, | 224 | }, |
184 | "flake-parts_3": { | 225 | "flake-parts_3": { |
185 | "inputs": { | 226 | "inputs": { |
227 | "nixpkgs-lib": [ | ||
228 | "lanzaboote", | ||
229 | "nixpkgs" | ||
230 | ] | ||
231 | }, | ||
232 | "locked": { | ||
233 | "lastModified": 1730504689, | ||
234 | "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", | ||
235 | "owner": "hercules-ci", | ||
236 | "repo": "flake-parts", | ||
237 | "rev": "506278e768c2a08bec68eb62932193e341f55c90", | ||
238 | "type": "github" | ||
239 | }, | ||
240 | "original": { | ||
241 | "owner": "hercules-ci", | ||
242 | "repo": "flake-parts", | ||
243 | "type": "github" | ||
244 | } | ||
245 | }, | ||
246 | "flake-parts_4": { | ||
247 | "inputs": { | ||
186 | "nixpkgs-lib": "nixpkgs-lib_3" | 248 | "nixpkgs-lib": "nixpkgs-lib_3" |
187 | }, | 249 | }, |
188 | "locked": { | 250 | "locked": { |
@@ -296,6 +358,28 @@ | |||
296 | "gitignore_3": { | 358 | "gitignore_3": { |
297 | "inputs": { | 359 | "inputs": { |
298 | "nixpkgs": [ | 360 | "nixpkgs": [ |
361 | "lanzaboote", | ||
362 | "pre-commit-hooks-nix", | ||
363 | "nixpkgs" | ||
364 | ] | ||
365 | }, | ||
366 | "locked": { | ||
367 | "lastModified": 1709087332, | ||
368 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", | ||
369 | "owner": "hercules-ci", | ||
370 | "repo": "gitignore.nix", | ||
371 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", | ||
372 | "type": "github" | ||
373 | }, | ||
374 | "original": { | ||
375 | "owner": "hercules-ci", | ||
376 | "repo": "gitignore.nix", | ||
377 | "type": "github" | ||
378 | } | ||
379 | }, | ||
380 | "gitignore_4": { | ||
381 | "inputs": { | ||
382 | "nixpkgs": [ | ||
299 | "prometheus-borg-exporter", | 383 | "prometheus-borg-exporter", |
300 | "pre-commit-hooks-nix", | 384 | "pre-commit-hooks-nix", |
301 | "nixpkgs" | 385 | "nixpkgs" |
@@ -322,11 +406,11 @@ | |||
322 | ] | 406 | ] |
323 | }, | 407 | }, |
324 | "locked": { | 408 | "locked": { |
325 | "lastModified": 1746904907, | 409 | "lastModified": 1753177987, |
326 | "narHash": "sha256-XYo6bwc7xwo4lO6a/D2ttYRN4yDmsAjyt5O1E0vOLDg=", | 410 | "narHash": "sha256-PkCc+YTrl0A/H6EV09DCr5yZpvQZ9DkuFXj/NNaEvHs=", |
327 | "owner": "gkleen", | 411 | "owner": "gkleen", |
328 | "repo": "home-manager", | 412 | "repo": "home-manager", |
329 | "rev": "696495266c65b76f08d8196b87aa7bd835906570", | 413 | "rev": "b493410fc6e427129a1caee8f50970d152a27daa", |
330 | "type": "github" | 414 | "type": "github" |
331 | }, | 415 | }, |
332 | "original": { | 416 | "original": { |
@@ -343,16 +427,16 @@ | |||
343 | ] | 427 | ] |
344 | }, | 428 | }, |
345 | "locked": { | 429 | "locked": { |
346 | "lastModified": 1747139300, | 430 | "lastModified": 1749562430, |
347 | "narHash": "sha256-V+YnIIM2wMprHGgzOU0HzyeWQEjP6EhG8kc4IffWFeg=", | 431 | "narHash": "sha256-M5MqsIsf+o7yngakVUW4poBGZaghB6sUpw7SsWA55kU=", |
348 | "owner": "gkleen", | 432 | "owner": "gkleen", |
349 | "repo": "home-manager", | 433 | "repo": "home-manager", |
350 | "rev": "50182497604587a24bdbe97d6400b1696eac57b1", | 434 | "rev": "dca5a2df9f8a00cc34bea6ead249a8446f5f069e", |
351 | "type": "github" | 435 | "type": "github" |
352 | }, | 436 | }, |
353 | "original": { | 437 | "original": { |
354 | "owner": "gkleen", | 438 | "owner": "gkleen", |
355 | "ref": "nixos-late-start-23.11", | 439 | "ref": "nixos-late-start-25.05", |
356 | "repo": "home-manager", | 440 | "repo": "home-manager", |
357 | "type": "github" | 441 | "type": "github" |
358 | } | 442 | } |
@@ -373,10 +457,36 @@ | |||
373 | "type": "github" | 457 | "type": "github" |
374 | } | 458 | } |
375 | }, | 459 | }, |
460 | "lanzaboote": { | ||
461 | "inputs": { | ||
462 | "crane": "crane", | ||
463 | "flake-compat": "flake-compat_4", | ||
464 | "flake-parts": "flake-parts_3", | ||
465 | "nixpkgs": [ | ||
466 | "nixpkgs" | ||
467 | ], | ||
468 | "pre-commit-hooks-nix": "pre-commit-hooks-nix_3", | ||
469 | "rust-overlay": "rust-overlay" | ||
470 | }, | ||
471 | "locked": { | ||
472 | "lastModified": 1737639419, | ||
473 | "narHash": "sha256-AEEDktApTEZ5PZXNDkry2YV2k6t0dTgLPEmAZbnigXU=", | ||
474 | "owner": "nix-community", | ||
475 | "repo": "lanzaboote", | ||
476 | "rev": "a65905a09e2c43ff63be8c0e86a93712361f871e", | ||
477 | "type": "github" | ||
478 | }, | ||
479 | "original": { | ||
480 | "owner": "nix-community", | ||
481 | "ref": "v0.4.2", | ||
482 | "repo": "lanzaboote", | ||
483 | "type": "github" | ||
484 | } | ||
485 | }, | ||
376 | "leapseconds": { | 486 | "leapseconds": { |
377 | "flake": false, | 487 | "flake": false, |
378 | "locked": { | 488 | "locked": { |
379 | "narHash": "sha256-5ZaoY/bScQS7EGJRHu6vj9XWhbObmxNEaGugaGU7+lg=", | 489 | "narHash": "sha256-FJgbafPB48+5sT+7ZB8pajSsfJoISEOoaJ0d/2Ya7o8=", |
380 | "type": "file", | 490 | "type": "file", |
381 | "url": "https://data.iana.org/time-zones/tzdb/leap-seconds.list" | 491 | "url": "https://data.iana.org/time-zones/tzdb/leap-seconds.list" |
382 | }, | 492 | }, |
@@ -392,16 +502,16 @@ | |||
392 | "nixpkgs": [ | 502 | "nixpkgs": [ |
393 | "nixpkgs" | 503 | "nixpkgs" |
394 | ], | 504 | ], |
395 | "nixpkgs-stable": "nixpkgs-stable_2", | 505 | "nixpkgs-stable": "nixpkgs-stable_3", |
396 | "xwayland-satellite-stable": "xwayland-satellite-stable", | 506 | "xwayland-satellite-stable": "xwayland-satellite-stable", |
397 | "xwayland-satellite-unstable": "xwayland-satellite-unstable" | 507 | "xwayland-satellite-unstable": "xwayland-satellite-unstable" |
398 | }, | 508 | }, |
399 | "locked": { | 509 | "locked": { |
400 | "lastModified": 1747638609, | 510 | "lastModified": 1755424351, |
401 | "narHash": "sha256-rPTN667tMqC1IQYgsnotVfXbVNbOzScxn0ontMkkSPk=", | 511 | "narHash": "sha256-xcorYLNdtLpb0wH5CPlUcpmYQUxeK95j1X855xQw+DY=", |
402 | "owner": "sodiboo", | 512 | "owner": "sodiboo", |
403 | "repo": "niri-flake", | 513 | "repo": "niri-flake", |
404 | "rev": "af697f3a8665c8d0770485a2e659ddde88430e3b", | 514 | "rev": "9aa137af01f05386e5bb5050e983750017007a66", |
405 | "type": "github" | 515 | "type": "github" |
406 | }, | 516 | }, |
407 | "original": { | 517 | "original": { |
@@ -414,16 +524,16 @@ | |||
414 | "niri-stable": { | 524 | "niri-stable": { |
415 | "flake": false, | 525 | "flake": false, |
416 | "locked": { | 526 | "locked": { |
417 | "lastModified": 1740117926, | 527 | "lastModified": 1748151941, |
418 | "narHash": "sha256-mTTHA0RAaQcdYe+9A3Jx77cmmyLFHmRoZdd8RpWa+m8=", | 528 | "narHash": "sha256-z4viQZLgC2bIJ3VrzQnR+q2F3gAOEQpU1H5xHtX/2fs=", |
419 | "owner": "YaLTeR", | 529 | "owner": "YaLTeR", |
420 | "repo": "niri", | 530 | "repo": "niri", |
421 | "rev": "b94a5db8790339cf9134873d8b490be69e02ac71", | 531 | "rev": "8ba57fcf25d2fc9565131684a839d58703f1dae7", |
422 | "type": "github" | 532 | "type": "github" |
423 | }, | 533 | }, |
424 | "original": { | 534 | "original": { |
425 | "owner": "YaLTeR", | 535 | "owner": "YaLTeR", |
426 | "ref": "v25.02", | 536 | "ref": "v25.05.1", |
427 | "repo": "niri", | 537 | "repo": "niri", |
428 | "type": "github" | 538 | "type": "github" |
429 | } | 539 | } |
@@ -431,11 +541,11 @@ | |||
431 | "niri-unstable": { | 541 | "niri-unstable": { |
432 | "flake": false, | 542 | "flake": false, |
433 | "locked": { | 543 | "locked": { |
434 | "lastModified": 1747635487, | 544 | "lastModified": 1755419373, |
435 | "narHash": "sha256-za7ctGh4MaW1h5Drm1WtwNZxiXvQK9yXZAeeIyY9b2Q=", | 545 | "narHash": "sha256-EFH3zbpyLYjEboNV2Lmkxf9joEuFCmeYX+MMLRPStpg=", |
436 | "owner": "YaLTeR", | 546 | "owner": "YaLTeR", |
437 | "repo": "niri", | 547 | "repo": "niri", |
438 | "rev": "3f2b7e63ba15cf33475116d32e8b7d22208a8438", | 548 | "rev": "a6febb86aa5af0df7bf2792ca027ef95a503d599", |
439 | "type": "github" | 549 | "type": "github" |
440 | }, | 550 | }, |
441 | "original": { | 551 | "original": { |
@@ -472,11 +582,11 @@ | |||
472 | ] | 582 | ] |
473 | }, | 583 | }, |
474 | "locked": { | 584 | "locked": { |
475 | "lastModified": 1747540584, | 585 | "lastModified": 1755404379, |
476 | "narHash": "sha256-cxCQ413JTUuRv9Ygd8DABJ1D6kuB/nTfQqC0Lu9C0ls=", | 586 | "narHash": "sha256-Q6ZxZDBmD/B988Jjbx7/NchxOKIpOKBBrx9Yb0zMzpQ=", |
477 | "owner": "Mic92", | 587 | "owner": "Mic92", |
478 | "repo": "nix-index-database", | 588 | "repo": "nix-index-database", |
479 | "rev": "ec179dd13fb7b4c6844f55be91436f7857226dce", | 589 | "rev": "ebbc1c05f786ae39bb5e04e57bf2c10c44a649e3", |
480 | "type": "github" | 590 | "type": "github" |
481 | }, | 591 | }, |
482 | "original": { | 592 | "original": { |
@@ -514,11 +624,11 @@ | |||
514 | ] | 624 | ] |
515 | }, | 625 | }, |
516 | "locked": { | 626 | "locked": { |
517 | "lastModified": 1747637556, | 627 | "lastModified": 1748140003, |
518 | "narHash": "sha256-AYd1nE+BLWTZS8J0eFQ7kuNiuE+XjhhndoXinj7en/M=", | 628 | "narHash": "sha256-DNBZmuk1YRM2PmwbHzVdXumRjCUzQkMarg4iI/37rOQ=", |
519 | "owner": "AshleyYakeley", | 629 | "owner": "AshleyYakeley", |
520 | "repo": "NixVirt", | 630 | "repo": "NixVirt", |
521 | "rev": "a7d3d3ae8b9a0cf3ec3cf504bb593df0618a6dbc", | 631 | "rev": "5dfe108fd859b122f9a96981cb6bc12297653d6c", |
522 | "type": "github" | 632 | "type": "github" |
523 | }, | 633 | }, |
524 | "original": { | 634 | "original": { |
@@ -529,11 +639,11 @@ | |||
529 | }, | 639 | }, |
530 | "nixos-hardware": { | 640 | "nixos-hardware": { |
531 | "locked": { | 641 | "locked": { |
532 | "lastModified": 1747129300, | 642 | "lastModified": 1755330281, |
533 | "narHash": "sha256-L3clA5YGeYCF47ghsI7Tcex+DnaaN/BbQ4dR2wzoiKg=", | 643 | "narHash": "sha256-aJHFJWP9AuI8jUGzI77LYcSlkA9wJnOIg4ZqftwNGXA=", |
534 | "owner": "NixOS", | 644 | "owner": "NixOS", |
535 | "repo": "nixos-hardware", | 645 | "repo": "nixos-hardware", |
536 | "rev": "e81fd167b33121269149c57806599045fd33eeed", | 646 | "rev": "3dac8a872557e0ca8c083cdcfc2f218d18e113b0", |
537 | "type": "github" | 647 | "type": "github" |
538 | }, | 648 | }, |
539 | "original": { | 649 | "original": { |
@@ -561,16 +671,16 @@ | |||
561 | }, | 671 | }, |
562 | "nixpkgs-eostre": { | 672 | "nixpkgs-eostre": { |
563 | "locked": { | 673 | "locked": { |
564 | "lastModified": 1701282334, | 674 | "lastModified": 1748026580, |
565 | "narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=", | 675 | "narHash": "sha256-rWtXrcIzU5wm/C8F9LWvUfBGu5U5E7cFzPYT1pHIJaQ=", |
566 | "owner": "NixOS", | 676 | "owner": "NixOS", |
567 | "repo": "nixpkgs", | 677 | "repo": "nixpkgs", |
568 | "rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e", | 678 | "rev": "11cb3517b3af6af300dd6c055aeda73c9bf52c48", |
569 | "type": "github" | 679 | "type": "github" |
570 | }, | 680 | }, |
571 | "original": { | 681 | "original": { |
572 | "owner": "NixOS", | 682 | "owner": "NixOS", |
573 | "ref": "23.11", | 683 | "ref": "25.05", |
574 | "repo": "nixpkgs", | 684 | "repo": "nixpkgs", |
575 | "type": "github" | 685 | "type": "github" |
576 | } | 686 | } |
@@ -589,14 +699,17 @@ | |||
589 | }, | 699 | }, |
590 | "nixpkgs-lib_2": { | 700 | "nixpkgs-lib_2": { |
591 | "locked": { | 701 | "locked": { |
592 | "lastModified": 1733096140, | 702 | "lastModified": 1748740939, |
593 | "narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=", | 703 | "narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=", |
594 | "type": "tarball", | 704 | "owner": "nix-community", |
595 | "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz" | 705 | "repo": "nixpkgs.lib", |
706 | "rev": "656a64127e9d791a334452c6b6606d17539476e2", | ||
707 | "type": "github" | ||
596 | }, | 708 | }, |
597 | "original": { | 709 | "original": { |
598 | "type": "tarball", | 710 | "owner": "nix-community", |
599 | "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz" | 711 | "repo": "nixpkgs.lib", |
712 | "type": "github" | ||
600 | } | 713 | } |
601 | }, | 714 | }, |
602 | "nixpkgs-lib_3": { | 715 | "nixpkgs-lib_3": { |
@@ -651,38 +764,54 @@ | |||
651 | }, | 764 | }, |
652 | "nixpkgs-stable_2": { | 765 | "nixpkgs-stable_2": { |
653 | "locked": { | 766 | "locked": { |
654 | "lastModified": 1747485343, | 767 | "lastModified": 1730741070, |
655 | "narHash": "sha256-YbsZyuRE1tobO9sv0PUwg81QryYo3L1F3R3rF9bcG38=", | 768 | "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", |
656 | "owner": "NixOS", | 769 | "owner": "NixOS", |
657 | "repo": "nixpkgs", | 770 | "repo": "nixpkgs", |
658 | "rev": "9b5ac7ad45298d58640540d0323ca217f32a6762", | 771 | "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", |
659 | "type": "github" | 772 | "type": "github" |
660 | }, | 773 | }, |
661 | "original": { | 774 | "original": { |
662 | "owner": "NixOS", | 775 | "owner": "NixOS", |
663 | "ref": "nixos-24.11", | 776 | "ref": "nixos-24.05", |
664 | "repo": "nixpkgs", | 777 | "repo": "nixpkgs", |
665 | "type": "github" | 778 | "type": "github" |
666 | } | 779 | } |
667 | }, | 780 | }, |
668 | "nixpkgs-stable_3": { | 781 | "nixpkgs-stable_3": { |
669 | "locked": { | 782 | "locked": { |
670 | "lastModified": 1717179513, | 783 | "lastModified": 1755274400, |
671 | "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=", | 784 | "narHash": "sha256-rTInmnp/xYrfcMZyFMH3kc8oko5zYfxsowaLv1LVobY=", |
672 | "owner": "NixOS", | 785 | "owner": "NixOS", |
673 | "repo": "nixpkgs", | 786 | "repo": "nixpkgs", |
674 | "rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0", | 787 | "rev": "ad7196ae55c295f53a7d1ec39e4a06d922f3b899", |
675 | "type": "github" | 788 | "type": "github" |
676 | }, | 789 | }, |
677 | "original": { | 790 | "original": { |
678 | "owner": "NixOS", | 791 | "owner": "NixOS", |
679 | "ref": "24.05", | 792 | "ref": "nixos-25.05", |
680 | "repo": "nixpkgs", | 793 | "repo": "nixpkgs", |
681 | "type": "github" | 794 | "type": "github" |
682 | } | 795 | } |
683 | }, | 796 | }, |
684 | "nixpkgs-stable_4": { | 797 | "nixpkgs-stable_4": { |
685 | "locked": { | 798 | "locked": { |
799 | "lastModified": 1748026580, | ||
800 | "narHash": "sha256-rWtXrcIzU5wm/C8F9LWvUfBGu5U5E7cFzPYT1pHIJaQ=", | ||
801 | "owner": "NixOS", | ||
802 | "repo": "nixpkgs", | ||
803 | "rev": "11cb3517b3af6af300dd6c055aeda73c9bf52c48", | ||
804 | "type": "github" | ||
805 | }, | ||
806 | "original": { | ||
807 | "owner": "NixOS", | ||
808 | "ref": "25.05", | ||
809 | "repo": "nixpkgs", | ||
810 | "type": "github" | ||
811 | } | ||
812 | }, | ||
813 | "nixpkgs-stable_5": { | ||
814 | "locked": { | ||
686 | "lastModified": 1678872516, | 815 | "lastModified": 1678872516, |
687 | "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=", | 816 | "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=", |
688 | "owner": "NixOS", | 817 | "owner": "NixOS", |
@@ -699,11 +828,11 @@ | |||
699 | }, | 828 | }, |
700 | "nixpkgs_2": { | 829 | "nixpkgs_2": { |
701 | "locked": { | 830 | "locked": { |
702 | "lastModified": 1747542820, | 831 | "lastModified": 1755615617, |
703 | "narHash": "sha256-GaOZntlJ6gPPbbkTLjbd8BMWaDYafhuuYRNrxCGnPJw=", | 832 | "narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=", |
704 | "owner": "NixOS", | 833 | "owner": "NixOS", |
705 | "repo": "nixpkgs", | 834 | "repo": "nixpkgs", |
706 | "rev": "292fa7d4f6519c074f0a50394dbbe69859bb6043", | 835 | "rev": "20075955deac2583bb12f07151c2df830ef346b4", |
707 | "type": "github" | 836 | "type": "github" |
708 | }, | 837 | }, |
709 | "original": { | 838 | "original": { |
@@ -811,18 +940,14 @@ | |||
811 | "nixpkgs": [ | 940 | "nixpkgs": [ |
812 | "ca-util", | 941 | "ca-util", |
813 | "nixpkgs" | 942 | "nixpkgs" |
814 | ], | ||
815 | "nixpkgs-stable": [ | ||
816 | "ca-util", | ||
817 | "nixpkgs" | ||
818 | ] | 943 | ] |
819 | }, | 944 | }, |
820 | "locked": { | 945 | "locked": { |
821 | "lastModified": 1734261738, | 946 | "lastModified": 1749636823, |
822 | "narHash": "sha256-3Lzk+7QyX8v60+km26D3dln7NMSA13vW+KYTkMkds6Q=", | 947 | "narHash": "sha256-WUaIlOlPLyPgz9be7fqWJA5iG6rHcGRtLERSCfUDne4=", |
823 | "owner": "cachix", | 948 | "owner": "cachix", |
824 | "repo": "pre-commit-hooks.nix", | 949 | "repo": "pre-commit-hooks.nix", |
825 | "rev": "4c8e75efbbdcc6f9203f64b1f21f8a55d2285264", | 950 | "rev": "623c56286de5a3193aa38891a6991b28f9bab056", |
826 | "type": "github" | 951 | "type": "github" |
827 | }, | 952 | }, |
828 | "original": { | 953 | "original": { |
@@ -833,11 +958,38 @@ | |||
833 | }, | 958 | }, |
834 | "pre-commit-hooks-nix_3": { | 959 | "pre-commit-hooks-nix_3": { |
835 | "inputs": { | 960 | "inputs": { |
836 | "flake-compat": "flake-compat_4", | 961 | "flake-compat": [ |
837 | "flake-utils": "flake-utils_2", | 962 | "lanzaboote", |
963 | "flake-compat" | ||
964 | ], | ||
838 | "gitignore": "gitignore_3", | 965 | "gitignore": "gitignore_3", |
966 | "nixpkgs": [ | ||
967 | "lanzaboote", | ||
968 | "nixpkgs" | ||
969 | ], | ||
970 | "nixpkgs-stable": "nixpkgs-stable_2" | ||
971 | }, | ||
972 | "locked": { | ||
973 | "lastModified": 1731363552, | ||
974 | "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=", | ||
975 | "owner": "cachix", | ||
976 | "repo": "pre-commit-hooks.nix", | ||
977 | "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0", | ||
978 | "type": "github" | ||
979 | }, | ||
980 | "original": { | ||
981 | "owner": "cachix", | ||
982 | "repo": "pre-commit-hooks.nix", | ||
983 | "type": "github" | ||
984 | } | ||
985 | }, | ||
986 | "pre-commit-hooks-nix_4": { | ||
987 | "inputs": { | ||
988 | "flake-compat": "flake-compat_5", | ||
989 | "flake-utils": "flake-utils_2", | ||
990 | "gitignore": "gitignore_4", | ||
839 | "nixpkgs": "nixpkgs_3", | 991 | "nixpkgs": "nixpkgs_3", |
840 | "nixpkgs-stable": "nixpkgs-stable_4" | 992 | "nixpkgs-stable": "nixpkgs-stable_5" |
841 | }, | 993 | }, |
842 | "locked": { | 994 | "locked": { |
843 | "lastModified": 1685361114, | 995 | "lastModified": 1685361114, |
@@ -855,14 +1007,14 @@ | |||
855 | }, | 1007 | }, |
856 | "prometheus-borg-exporter": { | 1008 | "prometheus-borg-exporter": { |
857 | "inputs": { | 1009 | "inputs": { |
858 | "flake-parts": "flake-parts_3", | 1010 | "flake-parts": "flake-parts_4", |
859 | "nixpkgs": [ | 1011 | "nixpkgs": [ |
860 | "nixpkgs" | 1012 | "nixpkgs" |
861 | ], | 1013 | ], |
862 | "poetry2nix": [ | 1014 | "poetry2nix": [ |
863 | "poetry2nix" | 1015 | "poetry2nix" |
864 | ], | 1016 | ], |
865 | "pre-commit-hooks-nix": "pre-commit-hooks-nix_3" | 1017 | "pre-commit-hooks-nix": "pre-commit-hooks-nix_4" |
866 | }, | 1018 | }, |
867 | "locked": { | 1019 | "locked": { |
868 | "lastModified": 1722088088, | 1020 | "lastModified": 1722088088, |
@@ -882,21 +1034,50 @@ | |||
882 | "pyproject-build-systems": { | 1034 | "pyproject-build-systems": { |
883 | "inputs": { | 1035 | "inputs": { |
884 | "nixpkgs": [ | 1036 | "nixpkgs": [ |
1037 | "ca-util", | ||
885 | "nixpkgs" | 1038 | "nixpkgs" |
886 | ], | 1039 | ], |
887 | "pyproject-nix": [ | 1040 | "pyproject-nix": [ |
1041 | "ca-util", | ||
888 | "pyproject-nix" | 1042 | "pyproject-nix" |
889 | ], | 1043 | ], |
890 | "uv2nix": [ | 1044 | "uv2nix": [ |
1045 | "ca-util", | ||
891 | "uv2nix" | 1046 | "uv2nix" |
892 | ] | 1047 | ] |
893 | }, | 1048 | }, |
894 | "locked": { | 1049 | "locked": { |
895 | "lastModified": 1744599653, | 1050 | "lastModified": 1749519371, |
896 | "narHash": "sha256-nysSwVVjG4hKoOjhjvE6U5lIKA8sEr1d1QzEfZsannU=", | 1051 | "narHash": "sha256-UJONN7mA2stweZCoRcry2aa1XTTBL0AfUOY84Lmqhos=", |
897 | "owner": "pyproject-nix", | 1052 | "owner": "pyproject-nix", |
898 | "repo": "build-system-pkgs", | 1053 | "repo": "build-system-pkgs", |
899 | "rev": "7dba6dbc73120e15b558754c26024f6c93015dd7", | 1054 | "rev": "7c06967eca687f3482624250428cc12f43c92523", |
1055 | "type": "github" | ||
1056 | }, | ||
1057 | "original": { | ||
1058 | "owner": "pyproject-nix", | ||
1059 | "repo": "build-system-pkgs", | ||
1060 | "type": "github" | ||
1061 | } | ||
1062 | }, | ||
1063 | "pyproject-build-systems_2": { | ||
1064 | "inputs": { | ||
1065 | "nixpkgs": [ | ||
1066 | "nixpkgs" | ||
1067 | ], | ||
1068 | "pyproject-nix": [ | ||
1069 | "pyproject-nix" | ||
1070 | ], | ||
1071 | "uv2nix": [ | ||
1072 | "uv2nix" | ||
1073 | ] | ||
1074 | }, | ||
1075 | "locked": { | ||
1076 | "lastModified": 1755484659, | ||
1077 | "narHash": "sha256-2FfbqsaHVQd12XFFUAinIMAuGO3853LONmva1gT3vKw=", | ||
1078 | "owner": "pyproject-nix", | ||
1079 | "repo": "build-system-pkgs", | ||
1080 | "rev": "9778e87c2361810ff15e287ca5895c9da4a0e900", | ||
900 | "type": "github" | 1081 | "type": "github" |
901 | }, | 1082 | }, |
902 | "original": { | 1083 | "original": { |
@@ -912,11 +1093,11 @@ | |||
912 | ] | 1093 | ] |
913 | }, | 1094 | }, |
914 | "locked": { | 1095 | "locked": { |
915 | "lastModified": 1746540146, | 1096 | "lastModified": 1754923840, |
916 | "narHash": "sha256-QxdHGNpbicIrw5t6U3x+ZxeY/7IEJ6lYbvsjXmcxFIM=", | 1097 | "narHash": "sha256-QSKpYg+Ts9HYF155ltlj40iBex39c05cpOF8gjoE2EM=", |
917 | "owner": "pyproject-nix", | 1098 | "owner": "pyproject-nix", |
918 | "repo": "pyproject.nix", | 1099 | "repo": "pyproject.nix", |
919 | "rev": "e09c10c24ebb955125fda449939bfba664c467fd", | 1100 | "rev": "023cd4be230eacae52635be09eef100c37ef78da", |
920 | "type": "github" | 1101 | "type": "github" |
921 | }, | 1102 | }, |
922 | "original": { | 1103 | "original": { |
@@ -936,6 +1117,7 @@ | |||
936 | "home-manager": "home-manager", | 1117 | "home-manager": "home-manager", |
937 | "home-manager-eostre": "home-manager-eostre", | 1118 | "home-manager-eostre": "home-manager-eostre", |
938 | "impermanence": "impermanence", | 1119 | "impermanence": "impermanence", |
1120 | "lanzaboote": "lanzaboote", | ||
939 | "niri-flake": "niri-flake", | 1121 | "niri-flake": "niri-flake", |
940 | "nix-index-database": "nix-index-database", | 1122 | "nix-index-database": "nix-index-database", |
941 | "nix-monitored": "nix-monitored", | 1123 | "nix-monitored": "nix-monitored", |
@@ -944,17 +1126,38 @@ | |||
944 | "nixpkgs": "nixpkgs_2", | 1126 | "nixpkgs": "nixpkgs_2", |
945 | "nixpkgs-eostre": "nixpkgs-eostre", | 1127 | "nixpkgs-eostre": "nixpkgs-eostre", |
946 | "nixpkgs-pgbackrest": "nixpkgs-pgbackrest", | 1128 | "nixpkgs-pgbackrest": "nixpkgs-pgbackrest", |
947 | "nixpkgs-stable": "nixpkgs-stable_3", | 1129 | "nixpkgs-stable": "nixpkgs-stable_4", |
948 | "nvfetcher": "nvfetcher", | 1130 | "nvfetcher": "nvfetcher", |
949 | "poetry2nix": "poetry2nix", | 1131 | "poetry2nix": "poetry2nix", |
950 | "prometheus-borg-exporter": "prometheus-borg-exporter", | 1132 | "prometheus-borg-exporter": "prometheus-borg-exporter", |
951 | "pyproject-build-systems": "pyproject-build-systems", | 1133 | "pyproject-build-systems": "pyproject-build-systems_2", |
952 | "pyproject-nix": "pyproject-nix", | 1134 | "pyproject-nix": "pyproject-nix", |
953 | "sops-nix": "sops-nix", | 1135 | "sops-nix": "sops-nix", |
954 | "uv2nix": "uv2nix", | 1136 | "uv2nix": "uv2nix", |
955 | "waybar": "waybar" | 1137 | "waybar": "waybar" |
956 | } | 1138 | } |
957 | }, | 1139 | }, |
1140 | "rust-overlay": { | ||
1141 | "inputs": { | ||
1142 | "nixpkgs": [ | ||
1143 | "lanzaboote", | ||
1144 | "nixpkgs" | ||
1145 | ] | ||
1146 | }, | ||
1147 | "locked": { | ||
1148 | "lastModified": 1731897198, | ||
1149 | "narHash": "sha256-Ou7vLETSKwmE/HRQz4cImXXJBr/k9gp4J4z/PF8LzTE=", | ||
1150 | "owner": "oxalica", | ||
1151 | "repo": "rust-overlay", | ||
1152 | "rev": "0be641045af6d8666c11c2c40e45ffc9667839b5", | ||
1153 | "type": "github" | ||
1154 | }, | ||
1155 | "original": { | ||
1156 | "owner": "oxalica", | ||
1157 | "repo": "rust-overlay", | ||
1158 | "type": "github" | ||
1159 | } | ||
1160 | }, | ||
958 | "sops-nix": { | 1161 | "sops-nix": { |
959 | "inputs": { | 1162 | "inputs": { |
960 | "nixpkgs": [ | 1163 | "nixpkgs": [ |
@@ -962,11 +1165,11 @@ | |||
962 | ] | 1165 | ] |
963 | }, | 1166 | }, |
964 | "locked": { | 1167 | "locked": { |
965 | "lastModified": 1747603214, | 1168 | "lastModified": 1754988908, |
966 | "narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=", | 1169 | "narHash": "sha256-t+voe2961vCgrzPFtZxha0/kmFSHFobzF00sT8p9h0U=", |
967 | "owner": "Mic92", | 1170 | "owner": "Mic92", |
968 | "repo": "sops-nix", | 1171 | "repo": "sops-nix", |
969 | "rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd", | 1172 | "rev": "3223c7a92724b5d804e9988c6b447a0d09017d48", |
970 | "type": "github" | 1173 | "type": "github" |
971 | }, | 1174 | }, |
972 | "original": { | 1175 | "original": { |
@@ -1037,11 +1240,11 @@ | |||
1037 | ] | 1240 | ] |
1038 | }, | 1241 | }, |
1039 | "locked": { | 1242 | "locked": { |
1040 | "lastModified": 1747441483, | 1243 | "lastModified": 1755485731, |
1041 | "narHash": "sha256-W8BFXk5R0TuJcjIhcGoMpSOaIufGXpizK0pm+uTqynA=", | 1244 | "narHash": "sha256-k8kxwVs8Oze6q/jAaRa3RvZbb50I/K0b5uptlsh0HXI=", |
1042 | "owner": "pyproject-nix", | 1245 | "owner": "pyproject-nix", |
1043 | "repo": "uv2nix", | 1246 | "repo": "uv2nix", |
1044 | "rev": "582024dc64663e9f88d467c2f7f7b20d278349de", | 1247 | "rev": "bebbd80bf56110fcd20b425589814af28f1939eb", |
1045 | "type": "github" | 1248 | "type": "github" |
1046 | }, | 1249 | }, |
1047 | "original": { | 1250 | "original": { |
@@ -1060,11 +1263,11 @@ | |||
1060 | ] | 1263 | ] |
1061 | }, | 1264 | }, |
1062 | "locked": { | 1265 | "locked": { |
1063 | "lastModified": 1747383113, | 1266 | "lastModified": 1752562190, |
1064 | "narHash": "sha256-/YW7eOKU3gsNplxvUDpEj1LiXtcCENSFpS1c8kXSDWw=", | 1267 | "narHash": "sha256-zWOMCNe56H2PHUd3rJZ6tklZUZBLgRo85jd9IlK1g9o=", |
1065 | "owner": "gkleen", | 1268 | "owner": "gkleen", |
1066 | "repo": "Waybar", | 1269 | "repo": "Waybar", |
1067 | "rev": "919036587381595f15010ac95644992fe6d7343d", | 1270 | "rev": "d008cd998369c40f2344a856caf39cdbbd7bd068", |
1068 | "type": "github" | 1271 | "type": "github" |
1069 | }, | 1272 | }, |
1070 | "original": { | 1273 | "original": { |
@@ -1077,16 +1280,16 @@ | |||
1077 | "xwayland-satellite-stable": { | 1280 | "xwayland-satellite-stable": { |
1078 | "flake": false, | 1281 | "flake": false, |
1079 | "locked": { | 1282 | "locked": { |
1080 | "lastModified": 1739246919, | 1283 | "lastModified": 1748488455, |
1081 | "narHash": "sha256-/hBM43/Gd0/tW+egrhlWgOIISeJxEs2uAOIYVpfDKeU=", | 1284 | "narHash": "sha256-IiLr1alzKFIy5tGGpDlabQbe6LV1c9ABvkH6T5WmyRI=", |
1082 | "owner": "Supreeeme", | 1285 | "owner": "Supreeeme", |
1083 | "repo": "xwayland-satellite", | 1286 | "repo": "xwayland-satellite", |
1084 | "rev": "44590a416d4a3e8220e19e29e0b6efe64a80315d", | 1287 | "rev": "3ba30b149f9eb2bbf42cf4758d2158ca8cceef73", |
1085 | "type": "github" | 1288 | "type": "github" |
1086 | }, | 1289 | }, |
1087 | "original": { | 1290 | "original": { |
1088 | "owner": "Supreeeme", | 1291 | "owner": "Supreeeme", |
1089 | "ref": "v0.5.1", | 1292 | "ref": "v0.6", |
1090 | "repo": "xwayland-satellite", | 1293 | "repo": "xwayland-satellite", |
1091 | "type": "github" | 1294 | "type": "github" |
1092 | } | 1295 | } |
@@ -1094,11 +1297,11 @@ | |||
1094 | "xwayland-satellite-unstable": { | 1297 | "xwayland-satellite-unstable": { |
1095 | "flake": false, | 1298 | "flake": false, |
1096 | "locked": { | 1299 | "locked": { |
1097 | "lastModified": 1747111562, | 1300 | "lastModified": 1755219541, |
1098 | "narHash": "sha256-GAqhWoxaBIk0tgoecZPa8gTHDHxNc0JtlwWHZN2iOOo=", | 1301 | "narHash": "sha256-yKV6xHaPbEbh5RPxAJnb9yTs1wypr7do86hFFGQm1w8=", |
1099 | "owner": "Supreeeme", | 1302 | "owner": "Supreeeme", |
1100 | "repo": "xwayland-satellite", | 1303 | "repo": "xwayland-satellite", |
1101 | "rev": "ec9ff64c1e0cbec42710b580b7c0f759b1694e72", | 1304 | "rev": "5a184d435927c3423f0ad189ea2b490578450fb7", |
1102 | "type": "github" | 1305 | "type": "github" |
1103 | }, | 1306 | }, |
1104 | "original": { | 1307 | "original": { |
@@ -29,13 +29,13 @@ | |||
29 | type = "github"; | 29 | type = "github"; |
30 | owner = "NixOS"; | 30 | owner = "NixOS"; |
31 | repo = "nixpkgs"; | 31 | repo = "nixpkgs"; |
32 | ref = "24.05"; | 32 | ref = "25.05"; |
33 | }; | 33 | }; |
34 | nixpkgs-eostre = { | 34 | nixpkgs-eostre = { |
35 | type = "github"; | 35 | type = "github"; |
36 | owner = "NixOS"; | 36 | owner = "NixOS"; |
37 | repo = "nixpkgs"; | 37 | repo = "nixpkgs"; |
38 | ref = "23.11"; | 38 | ref = "25.05"; |
39 | }; | 39 | }; |
40 | home-manager = { | 40 | home-manager = { |
41 | type = "github"; | 41 | type = "github"; |
@@ -53,7 +53,7 @@ | |||
53 | type = "github"; | 53 | type = "github"; |
54 | owner = "gkleen"; | 54 | owner = "gkleen"; |
55 | repo = "home-manager"; | 55 | repo = "home-manager"; |
56 | ref = "nixos-late-start-23.11"; | 56 | ref = "nixos-late-start-25.05"; |
57 | inputs = { | 57 | inputs = { |
58 | nixpkgs.follows = "nixpkgs-eostre"; | 58 | nixpkgs.follows = "nixpkgs-eostre"; |
59 | }; | 59 | }; |
@@ -145,20 +145,23 @@ | |||
145 | type = "gitlab"; | 145 | type = "gitlab"; |
146 | owner = "gkleen"; | 146 | owner = "gkleen"; |
147 | repo = "ca"; | 147 | repo = "ca"; |
148 | ref = "v3.1.3"; | 148 | ref = "v3.1.5"; |
149 | inputs = { | 149 | inputs = { |
150 | pyproject-nix.follows = "pyproject-nix"; | ||
151 | uv2nix.follows = "uv2nix"; | ||
150 | nixpkgs.follows = "nixpkgs"; | 152 | nixpkgs.follows = "nixpkgs"; |
151 | poetry2nix.follows = "poetry2nix"; | ||
152 | }; | 153 | }; |
153 | }; | 154 | }; |
154 | backup-utils = { | 155 | backup-utils = { |
155 | type = "gitlab"; | 156 | type = "gitlab"; |
156 | owner = "gkleen"; | 157 | owner = "gkleen"; |
157 | repo = "backup-utils"; | 158 | repo = "backup-utils"; |
158 | ref = "v0.1.6"; | 159 | ref = "v0.1.7"; |
159 | inputs = { | 160 | inputs = { |
160 | nixpkgs.follows = "nixpkgs"; | 161 | nixpkgs.follows = "nixpkgs"; |
161 | poetry2nix.follows = "poetry2nix"; | 162 | pyproject-nix.follows = "pyproject-nix"; |
163 | uv2nix.follows = "uv2nix"; | ||
164 | pyproject-build-systems.follows = "pyproject-build-systems"; | ||
162 | }; | 165 | }; |
163 | }; | 166 | }; |
164 | prometheus-borg-exporter = { | 167 | prometheus-borg-exporter = { |
@@ -218,6 +221,14 @@ | |||
218 | nixpkgs.follows = "nixpkgs"; | 221 | nixpkgs.follows = "nixpkgs"; |
219 | }; | 222 | }; |
220 | }; | 223 | }; |
224 | lanzaboote = { | ||
225 | type = "github"; | ||
226 | owner = "nix-community"; | ||
227 | repo = "lanzaboote"; | ||
228 | ref = "v0.4.2"; | ||
229 | |||
230 | inputs.nixpkgs.follows = "nixpkgs"; | ||
231 | }; | ||
221 | }; | 232 | }; |
222 | 233 | ||
223 | outputs = { self, nixpkgs, home-manager, sops-nix, deploy-rs, nvfetcher, niri-flake, ... }@inputs: | 234 | outputs = { self, nixpkgs, home-manager, sops-nix, deploy-rs, nvfetcher, niri-flake, ... }@inputs: |
diff --git a/hosts/eostre/default.nix b/hosts/eostre/default.nix index fd4b15f2..d4113024 100644 --- a/hosts/eostre/default.nix +++ b/hosts/eostre/default.nix | |||
@@ -37,14 +37,10 @@ with lib; | |||
37 | powerManagement.enable = true; | 37 | powerManagement.enable = true; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | opengl.enable = true; | 40 | graphics.enable = true; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | environment.etc."machine-id".text = "f457b21333f1491e916521151ff5d468"; | ||
44 | |||
45 | networking = { | 43 | networking = { |
46 | hostId = "f457b213"; | ||
47 | |||
48 | domain = "lan.yggdrasil"; | 44 | domain = "lan.yggdrasil"; |
49 | search = [ "lan.yggdrasil" "yggdrasil" ]; | 45 | search = [ "lan.yggdrasil" "yggdrasil" ]; |
50 | 46 | ||
@@ -83,19 +79,14 @@ with lib; | |||
83 | ]; | 79 | ]; |
84 | }; | 80 | }; |
85 | 81 | ||
86 | 82 | services.displayManager.sddm = { | |
87 | services.xserver = { | ||
88 | enable = true; | 83 | enable = true; |
89 | displayManager.sddm = { | 84 | wayland.enable = true; |
90 | enable = true; | 85 | settings = { |
91 | settings = { | 86 | Users.HideUsers = "gkleen"; |
92 | Users.HideUsers = "gkleen"; | ||
93 | }; | ||
94 | }; | 87 | }; |
95 | desktopManager.plasma5.enable = true; | ||
96 | |||
97 | videoDrivers = [ "nvidia" ]; | ||
98 | }; | 88 | }; |
89 | services.desktopManager.plasma6.enable = true; | ||
99 | 90 | ||
100 | 91 | ||
101 | services.openssh = { | 92 | services.openssh = { |
diff --git a/hosts/sif/default.nix b/hosts/sif/default.nix index b50cad60..ed85ca17 100644 --- a/hosts/sif/default.nix +++ b/hosts/sif/default.nix | |||
@@ -12,10 +12,9 @@ let | |||
12 | in { | 12 | in { |
13 | imports = with flake.nixosModules.systemProfiles; [ | 13 | imports = with flake.nixosModules.systemProfiles; [ |
14 | ./hw.nix | 14 | ./hw.nix |
15 | ./mail ./libvirt ./greetd | 15 | ./email ./libvirt ./greetd |
16 | tmpfs-root bcachefs initrd-all-crypto-modules default-locale openssh rebuild-machines niri-unstable networkmanager | 16 | tmpfs-root bcachefs initrd-all-crypto-modules default-locale openssh rebuild-machines niri-unstable networkmanager lanzaboote |
17 | flakeInputs.nixos-hardware.nixosModules.lenovo-thinkpad-p1 | 17 | flakeInputs.nixos-hardware.nixosModules.lenovo-thinkpad-p1 |
18 | flakeInputs.impermanence.nixosModules.impermanence | ||
19 | flakeInputs.nixVirt.nixosModules.default | 18 | flakeInputs.nixVirt.nixosModules.default |
20 | ]; | 19 | ]; |
21 | 20 | ||
@@ -34,6 +33,10 @@ in { | |||
34 | initrd = { | 33 | initrd = { |
35 | systemd = { | 34 | systemd = { |
36 | emergencyAccess = config.users.users.root.hashedPassword; | 35 | emergencyAccess = config.users.users.root.hashedPassword; |
36 | extraBin = { | ||
37 | "vim" = lib.getExe pkgs.vim; | ||
38 | "grep" = lib.getExe pkgs.gnugrep; | ||
39 | }; | ||
37 | }; | 40 | }; |
38 | luks.devices = { | 41 | luks.devices = { |
39 | nvm0 = { device = "/dev/disk/by-uuid/bef17e86-d929-4a60-97cb-6bfa133face7"; bypassWorkqueues = true; }; | 42 | nvm0 = { device = "/dev/disk/by-uuid/bef17e86-d929-4a60-97cb-6bfa133face7"; bypassWorkqueues = true; }; |
@@ -47,13 +50,8 @@ in { | |||
47 | 50 | ||
48 | blacklistedKernelModules = [ "nouveau" ]; | 51 | blacklistedKernelModules = [ "nouveau" ]; |
49 | 52 | ||
50 | # Use the systemd-boot EFI boot loader. | 53 | lanzaboote.configurationLimit = 15; |
51 | loader = { | 54 | loader = { |
52 | systemd-boot = { | ||
53 | enable = true; | ||
54 | configurationLimit = 15; | ||
55 | netbootxyz.enable = true; | ||
56 | }; | ||
57 | efi.canTouchEfiVariables = true; | 55 | efi.canTouchEfiVariables = true; |
58 | timeout = null; | 56 | timeout = null; |
59 | }; | 57 | }; |
@@ -64,19 +62,27 @@ in { | |||
64 | kernelPatches = [ | 62 | kernelPatches = [ |
65 | { name = "edac-config"; | 63 | { name = "edac-config"; |
66 | patch = null; | 64 | patch = null; |
67 | extraStructuredConfig = with lib.kernel; { | 65 | structuredExtraConfig = with lib.kernel; { |
68 | EDAC = yes; | 66 | EDAC = yes; |
69 | EDAC_IE31200 = yes; | 67 | EDAC_IE31200 = yes; |
70 | }; | 68 | }; |
71 | } | 69 | } |
72 | { name = "zswap-default"; | 70 | { name = "zswap-default"; |
73 | patch = null; | 71 | patch = null; |
74 | extraStructuredConfig = with lib.kernel; { | 72 | structuredExtraConfig = with lib.kernel; { |
75 | ZSWAP_DEFAULT_ON = yes; | 73 | ZSWAP_DEFAULT_ON = yes; |
76 | ZSWAP_SHRINKER_DEFAULT_ON = yes; | 74 | ZSWAP_SHRINKER_DEFAULT_ON = yes; |
77 | }; | 75 | }; |
78 | } | 76 | } |
79 | ]; | 77 | ]; |
78 | consoleLogLevel = 3; | ||
79 | kernelParams = [ | ||
80 | "quiet" | ||
81 | "boot.shell_on_fail" | ||
82 | "udev.log_priority=3" | ||
83 | "rd.systemd.show_status=auto" | ||
84 | "plymouth.use-simpledrm" | ||
85 | ]; | ||
80 | 86 | ||
81 | tmp.useTmpfs = true; | 87 | tmp.useTmpfs = true; |
82 | 88 | ||
@@ -98,6 +104,8 @@ in { | |||
98 | server ptbtime2.ptb.de prefer iburst nts | 104 | server ptbtime2.ptb.de prefer iburst nts |
99 | server ptbtime3.ptb.de prefer iburst nts | 105 | server ptbtime3.ptb.de prefer iburst nts |
100 | server ptbtime4.ptb.de prefer iburst nts | 106 | server ptbtime4.ptb.de prefer iburst nts |
107 | pool ntppool1.time.nl prefer iburst nts | ||
108 | pool ntppool2.time.nl prefer iburst nts | ||
101 | 109 | ||
102 | authselectmode require | 110 | authselectmode require |
103 | minsources 3 | 111 | minsources 3 |
@@ -130,6 +138,12 @@ in { | |||
130 | useNetworkd = true; | 138 | useNetworkd = true; |
131 | }; | 139 | }; |
132 | 140 | ||
141 | environment.etc."NetworkManager/dnsmasq.d/dnssec.conf" = { | ||
142 | text = '' | ||
143 | conf-file=${pkgs.dnsmasq}/share/dnsmasq/trust-anchors.conf | ||
144 | dnssec | ||
145 | ''; | ||
146 | }; | ||
133 | environment.etc."NetworkManager/dnsmasq.d/libvirt_dnsmasq.conf" = { | 147 | environment.etc."NetworkManager/dnsmasq.d/libvirt_dnsmasq.conf" = { |
134 | text = '' | 148 | text = '' |
135 | except-interface=virbr0 | 149 | except-interface=virbr0 |
@@ -372,19 +386,6 @@ in { | |||
372 | ]; | 386 | ]; |
373 | 387 | ||
374 | services = { | 388 | services = { |
375 | uucp = { | ||
376 | enable = true; | ||
377 | nodeName = "sif"; | ||
378 | remoteNodes = { | ||
379 | "ymir" = { | ||
380 | publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG6KNtsCOl5fsZ4rV7udTulGMphJweLBoKapzerWNoLY root@ymir"]; | ||
381 | hostnames = ["ymir.yggdrasil.li" "ymir.niflheim.yggdrasil"]; | ||
382 | }; | ||
383 | }; | ||
384 | |||
385 | defaultCommands = lib.mkForce []; | ||
386 | }; | ||
387 | |||
388 | avahi.enable = true; | 389 | avahi.enable = true; |
389 | 390 | ||
390 | fwupd.enable = true; | 391 | fwupd.enable = true; |
@@ -446,11 +447,6 @@ in { | |||
446 | 447 | ||
447 | systemd.tmpfiles.settings = { | 448 | systemd.tmpfiles.settings = { |
448 | "10-localtime"."/etc/localtime".L.argument = "/.bcachefs/etc/localtime"; | 449 | "10-localtime"."/etc/localtime".L.argument = "/.bcachefs/etc/localtime"; |
449 | |||
450 | # "10-regreet"."/var/cache/regreet/cache.toml".C.argument = toString ((pkgs.formats.toml {}).generate "cache.toml" { | ||
451 | # last_user = "gkleen"; | ||
452 | # user_to_last_sess.gkleen = "Niri"; | ||
453 | # }); | ||
454 | }; | 450 | }; |
455 | 451 | ||
456 | users = { | 452 | users = { |
@@ -679,25 +675,15 @@ in { | |||
679 | "/var/lib/bluetooth" | 675 | "/var/lib/bluetooth" |
680 | "/var/lib/upower" | 676 | "/var/lib/upower" |
681 | "/var/lib/postfix" | 677 | "/var/lib/postfix" |
678 | "/var/lib/regreet" | ||
682 | "/etc/NetworkManager/system-connections" | 679 | "/etc/NetworkManager/system-connections" |
683 | { directory = "/var/uucp"; user = "uucp"; group = "uucp"; mode = "0700"; } | 680 | config.boot.lanzaboote.pkiBundle |
684 | { directory = "/var/spool/uucp"; user = "uucp"; group = "uucp"; mode = "0750"; } | ||
685 | ]; | 681 | ]; |
686 | files = [ | 682 | files = [ |
687 | ]; | 683 | ]; |
684 | timezone = true; | ||
688 | }; | 685 | }; |
689 | 686 | ||
690 | systemd.services.timezone = { | ||
691 | wantedBy = [ "multi-user.target" ]; | ||
692 | serviceConfig = { | ||
693 | Type = "oneshot"; | ||
694 | RemainAfterExit = true; | ||
695 | ExecStart = "${pkgs.coreutils}/bin/cp -vP /.bcachefs/etc/localtime /etc/localtime"; | ||
696 | ExecStop = "${pkgs.coreutils}/bin/cp -vP /etc/localtime /.bcachefs/etc/localtime"; | ||
697 | }; | ||
698 | }; | ||
699 | services.tzupdate.enable = true; | ||
700 | |||
701 | security.pam.services.gtklock = {}; | 687 | security.pam.services.gtklock = {}; |
702 | 688 | ||
703 | home-manager.sharedModules = [ flakeInputs.nixVirt.homeModules.default ]; | 689 | home-manager.sharedModules = [ flakeInputs.nixVirt.homeModules.default ]; |
diff --git a/hosts/sif/email/default.nix b/hosts/sif/email/default.nix new file mode 100644 index 00000000..bebf7980 --- /dev/null +++ b/hosts/sif/email/default.nix | |||
@@ -0,0 +1,111 @@ | |||
1 | { config, lib, pkgs, ... }: | ||
2 | { | ||
3 | services.postfix = { | ||
4 | enable = true; | ||
5 | enableSmtp = false; | ||
6 | enableSubmission = false; | ||
7 | setSendmail = true; | ||
8 | # networksStyle = "host"; | ||
9 | settings.main = { | ||
10 | recpipient_delimiter = "+"; | ||
11 | mydestination = []; | ||
12 | myhostname = "sif.midgard.yggdrasil"; | ||
13 | |||
14 | mydomain = "yggdrasil.li"; | ||
15 | |||
16 | local_transport = "error:5.1.1 No local delivery"; | ||
17 | alias_database = []; | ||
18 | alias_maps = []; | ||
19 | local_recipient_maps = []; | ||
20 | |||
21 | inet_interfaces = "loopback-only"; | ||
22 | |||
23 | message_size_limit = 0; | ||
24 | |||
25 | authorized_submit_users = "inline:{ gkleen= }"; | ||
26 | authorized_flush_users = "inline:{ gkleen= }"; | ||
27 | authorized_mailq_users = "inline:{ gkleen= }"; | ||
28 | |||
29 | smtp_generic_maps = "inline:{ root=root+sif }"; | ||
30 | |||
31 | mynetworks = ["127.0.0.0/8" "[::1]/128"]; | ||
32 | smtpd_client_restrictions = ["permit_mynetworks" "reject"]; | ||
33 | smtpd_relay_restrictions = ["permit_mynetworks" "reject"]; | ||
34 | |||
35 | sender_dependent_default_transport_maps = ''regexp:${pkgs.writeText "sender_relay" '' | ||
36 | /@(cip|stud)\.ifi\.(lmu|uni-muenchen)\.de$/ smtp:smtp.ifi.lmu.de | ||
37 | /@ifi\.(lmu|uni-muenchen)\.de$/ smtp:smtpin1.ifi.lmu.de:587 | ||
38 | /@math(ematik)?\.(lmu|uni-muenchen)\.de$/ smtps:smtp.math.lmu.de:465 | ||
39 | /@(campus\.)?lmu\.de$/ smtp:postout.lrz.de | ||
40 | ''}''; | ||
41 | sender_bcc_maps = ''regexp:${pkgs.writeText "sender_bcc" '' | ||
42 | /^uni2work(-[^@]*)?@ifi\.lmu\.de$/ uni2work@ifi.lmu.de | ||
43 | /@ifi\.lmu\.de$/ gregor.kleen@ifi.lmu.de | ||
44 | ''}''; | ||
45 | relayhost = ["[surtr.yggdrasil.li]:465"]; | ||
46 | default_transport = "relay"; | ||
47 | |||
48 | smtp_sasl_auth_enable = true; | ||
49 | smtp_sender_dependent_authentication = true; | ||
50 | smtp_sasl_tls_security_options = "noanonymous"; | ||
51 | smtp_sasl_mechanism_filter = ["plain"]; | ||
52 | smtp_sasl_password_maps = "regexp:/run/credentials/postfix.service/sasl_passwd"; | ||
53 | smtp_cname_overrides_servername = false; | ||
54 | smtp_always_send_ehlo = true; | ||
55 | smtp_tls_security_level = "dane"; | ||
56 | |||
57 | smtp_tls_loglevel = "1"; | ||
58 | smtp_dns_support_level = "dnssec"; | ||
59 | }; | ||
60 | settings.master = { | ||
61 | submission = { | ||
62 | type = "inet"; | ||
63 | private = false; | ||
64 | command = "smtpd"; | ||
65 | args = [ | ||
66 | "-o" "syslog_name=postfix/$service_name" | ||
67 | ]; | ||
68 | }; | ||
69 | smtp = { }; | ||
70 | smtps = { | ||
71 | type = "unix"; | ||
72 | private = true; | ||
73 | privileged = true; | ||
74 | chroot = false; | ||
75 | command = "smtp"; | ||
76 | args = [ | ||
77 | "-o" "smtp_tls_wrappermode=yes" | ||
78 | "-o" "smtp_tls_security_level=encrypt" | ||
79 | ]; | ||
80 | }; | ||
81 | relay = { | ||
82 | command = "smtp"; | ||
83 | args = [ | ||
84 | "-o" "smtp_fallback_relay=" | ||
85 | "-o" "smtp_tls_security_level=verify" | ||
86 | "-o" "smtp_tls_wrappermode=yes" | ||
87 | "-o" "smtp_tls_cert_file=${./relay.crt}" | ||
88 | "-o" "smtp_tls_key_file=/run/credentials/postfix.service/relay.key" | ||
89 | ]; | ||
90 | }; | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | systemd.services.postfix = { | ||
95 | serviceConfig.LoadCredential = [ | ||
96 | "sasl_passwd:${config.sops.secrets."postfix-sasl-passwd".path}" | ||
97 | "relay.key:${config.sops.secrets."relay-key".path}" | ||
98 | ]; | ||
99 | }; | ||
100 | |||
101 | sops.secrets = { | ||
102 | postfix-sasl-passwd = { | ||
103 | key = "sasl-passwd"; | ||
104 | sopsFile = ./secrets.yaml; | ||
105 | }; | ||
106 | relay-key = { | ||
107 | format = "binary"; | ||
108 | sopsFile = ./relay.key; | ||
109 | }; | ||
110 | }; | ||
111 | } | ||
diff --git a/hosts/sif/email/relay.crt b/hosts/sif/email/relay.crt new file mode 100644 index 00000000..ac13e7cb --- /dev/null +++ b/hosts/sif/email/relay.crt | |||
@@ -0,0 +1,11 @@ | |||
1 | -----BEGIN CERTIFICATE----- | ||
2 | MIIBjDCCAQygAwIBAgIPQAAAAGgLfNoL/PSMAsutMAUGAytlcTAXMRUwEwYDVQQD | ||
3 | DAx5Z2dkcmFzaWwubGkwHhcNMjUwNDI1MTIwOTQ1WhcNMzUwNDI2MTIxNDQ1WjAR | ||
4 | MQ8wDQYDVQQDDAZna2xlZW4wKjAFBgMrZXADIQB3outi3/3F4YO7Q97WAAaMHW0a | ||
5 | m+Blldrgee+EZnWnD6N1MHMwHwYDVR0jBBgwFoAUTtn+VjMw6Ge1f68KD8dT1CWn | ||
6 | l3YwHQYDVR0OBBYEFFOa4rYZYMbXUVdKv98NB504GUhjMA4GA1UdDwEB/wQEAwID | ||
7 | 6DAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAUGAytlcQNzABC0 | ||
8 | 0UgIt7gLZrU1TmzGoqPBris8R1DbKOJacicF5CU0MIIjHcX7mPFW8KtB4qm6KcPq | ||
9 | kF6IaEPmgKpX3Nubk8HJik9vhIy9ysfINcVTvzXx8pO1bxbvREJRyA/apj10nzav | ||
10 | yauId0cXHvN6g5RLAMsMAA== | ||
11 | -----END CERTIFICATE----- | ||
diff --git a/hosts/sif/email/relay.key b/hosts/sif/email/relay.key new file mode 100644 index 00000000..412a44e0 --- /dev/null +++ b/hosts/sif/email/relay.key | |||
@@ -0,0 +1,19 @@ | |||
1 | { | ||
2 | "data": "ENC[AES256_GCM,data:lBlTuzOS75pvRmcTKT4KhHMH44RlE2SvCFAUP+GfsXws1Uai7DZ1MmbhvxxCa+pcLW19+sQYxrXLRNZWby1yOeKBJ2UQeYV5LOk9LSL/WIE3FZkCo5Dv0O0gSFKjjb61WN22a4JnHbLWADf/mLT3GZv91XfvFDo=,iv:ho8wQH3UNzX9JPW5gVcUGtxZzdVwsMFus0Z4KYe5t48=,tag:dAgZyHOva2xVVhE1nTl+lg==,type:str]", | ||
3 | "sops": { | ||
4 | "age": [ | ||
5 | { | ||
6 | "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866", | ||
7 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6eTVRSUdFNUZGZmcxSUlT\nWmlsOGNyWXIzMGNTZjlKbXlhcEdZUXFRVkR3Cll0T0RMd0h2UW16QkR3SHlhYmNZ\nNDFrYXh3Rkp5NWsvcWc3UFJJaHVwT1UKLS0tIHhXVEI0VHBZVkpDQ1FzWENjMmJH\nb1FQWXVUUTBiZ1pKWG00MTNqVEo2SjAKK3VOU+QgRuxWYWEcrJiVMRFCprBICz4F\ngD+9zuPUzPezyJkYwTs+M+wX5GYkXppqm5W58yQLS2UDD38sr+SRjg==\n-----END AGE ENCRYPTED FILE-----\n" | ||
8 | }, | ||
9 | { | ||
10 | "recipient": "age1fj65apkhfkrwyv5tx6zcs9nkjg8267fy733qph30sc7zfn7vapjqkd5kne", | ||
11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzWmJmZDVFazN2bDY1TkNG\nNXpJN2twMFFjZUxMTVdSNzJwQTFiYktrcGdrCjk4eFVHTko0bFVMSlFFWm9tbjMr\nbWNHMEQ1Rm1qUVhodlB1RGw2aDc4TUEKLS0tIERBK0J5NkN4OXJEZ1ZOZXhNc1Jm\naWNnUmZGbTIxdmNkYi9TZ2h2bGs3MVEKPQGaEf7M/5/xvSOfawpIp50fB3QfFSuz\nPgkrPMneaBeUx+uBYMyEFX4rpzLIBR3pnYMjAfoc+bjWaOtGQuEqyQ==\n-----END AGE ENCRYPTED FILE-----\n" | ||
12 | } | ||
13 | ], | ||
14 | "lastmodified": "2025-04-25T12:14:44Z", | ||
15 | "mac": "ENC[AES256_GCM,data:pObl2bJA93az9E3Ya+hA3ekI8TKKZ9NNTi0KzmWZBOiQwi9FuQYtpnmmT80L1KXWyOKJV6wGdAri3mNe/ue2S0TziSbQ/4+Dj4ubFKgkH7thb5q2dFyxw5FzhYzRQiXFqD/pxcNN9uL0lQI2Al0Eci0zX8Kcd1rAQ6RzLEoSmco=,iv:zo/3QFKTUEDxLy1k5yyU7Z1JMZ7cKdYUc6GHjaTTZKQ=,tag:f63Eja3lBfwJCYAOyEt56g==,type:str]", | ||
16 | "unencrypted_suffix": "_unencrypted", | ||
17 | "version": "3.10.2" | ||
18 | } | ||
19 | } | ||
diff --git a/hosts/sif/mail/secrets.yaml b/hosts/sif/email/secrets.yaml index 3c74b710..3c74b710 100644 --- a/hosts/sif/mail/secrets.yaml +++ b/hosts/sif/email/secrets.yaml | |||
diff --git a/hosts/sif/hw.nix b/hosts/sif/hw.nix index 1bcf0261..e567c37d 100644 --- a/hosts/sif/hw.nix +++ b/hosts/sif/hw.nix | |||
@@ -25,7 +25,7 @@ | |||
25 | # system.etc.overlay.enable = false; | 25 | # system.etc.overlay.enable = false; |
26 | 26 | ||
27 | boot.initrd.systemd.packages = [ | 27 | boot.initrd.systemd.packages = [ |
28 | (pkgs.writeTextDir "/etc/systemd/system/\\x2ebcachefs.mount.d/block_scan.conf" '' | 28 | (pkgs.writeTextDir "/etc/systemd/system/sysroot-.bcachefs.mount.d/block_scan.conf" '' |
29 | [Mount] | 29 | [Mount] |
30 | Environment=BCACHEFS_BLOCK_SCAN=1 | 30 | Environment=BCACHEFS_BLOCK_SCAN=1 |
31 | '') | 31 | '') |
diff --git a/hosts/sif/mail/default.nix b/hosts/sif/mail/default.nix deleted file mode 100644 index 8d6cd705..00000000 --- a/hosts/sif/mail/default.nix +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | { config, lib, pkgs, ... }: | ||
2 | { | ||
3 | services.postfix = { | ||
4 | enable = true; | ||
5 | enableSmtp = true; | ||
6 | enableSubmission = false; | ||
7 | setSendmail = true; | ||
8 | networksStyle = "host"; | ||
9 | hostname = "sif.midgard.yggdrasil"; | ||
10 | destination = []; | ||
11 | relayHost = "uucp:ymir"; | ||
12 | recipientDelimiter = "+"; | ||
13 | masterConfig = { | ||
14 | uucp = { | ||
15 | type = "unix"; | ||
16 | private = true; | ||
17 | privileged = true; | ||
18 | chroot = false; | ||
19 | command = "pipe"; | ||
20 | args = [ "flags=Fqhu" "user=uucp" ''argv=${config.security.wrapperDir}/uux -z -a $sender - $nexthop!rmail ($recipient)'' ]; | ||
21 | }; | ||
22 | smtps = { | ||
23 | type = "unix"; | ||
24 | private = true; | ||
25 | privileged = true; | ||
26 | chroot = false; | ||
27 | command = "smtp"; | ||
28 | args = [ "-o" "smtp_tls_wrappermode=yes" "-o" "smtp_tls_security_level=encrypt" ]; | ||
29 | }; | ||
30 | }; | ||
31 | config = { | ||
32 | default_transport = "uucp:ymir"; | ||
33 | |||
34 | inet_interfaces = "loopback-only"; | ||
35 | |||
36 | authorized_submit_users = ["!uucp" "static:anyone"]; | ||
37 | message_size_limit = "0"; | ||
38 | |||
39 | sender_dependent_default_transport_maps = ''regexp:${pkgs.writeText "sender_relay" '' | ||
40 | /@(cip|stud)\.ifi\.(lmu|uni-muenchen)\.de$/ smtp:smtp.ifi.lmu.de | ||
41 | /@ifi\.(lmu|uni-muenchen)\.de$/ smtp:smtpin1.ifi.lmu.de:587 | ||
42 | /@math(ematik)?\.(lmu|uni-muenchen)\.de$/ smtps:smtp.math.lmu.de:465 | ||
43 | /@(campus\.)?lmu\.de$/ smtp:postout.lrz.de | ||
44 | ''}''; | ||
45 | sender_bcc_maps = ''regexp:${pkgs.writeText "sender_bcc" '' | ||
46 | /^uni2work(-[^@]*)?@ifi\.lmu\.de$/ uni2work@ifi.lmu.de | ||
47 | /@ifi\.lmu\.de$/ gregor.kleen@ifi.lmu.de | ||
48 | ''}''; | ||
49 | |||
50 | smtp_sasl_auth_enable = true; | ||
51 | smtp_sender_dependent_authentication = true; | ||
52 | smtp_sasl_tls_security_options = "noanonymous"; | ||
53 | smtp_sasl_mechanism_filter = ["plain"]; | ||
54 | smtp_sasl_password_maps = "regexp:/var/db/postfix/sasl_passwd"; | ||
55 | smtp_cname_overrides_servername = false; | ||
56 | smtp_always_send_ehlo = true; | ||
57 | smtp_tls_security_level = "dane"; | ||
58 | |||
59 | smtp_tls_loglevel = "1"; | ||
60 | smtp_dns_support_level = "dnssec"; | ||
61 | }; | ||
62 | }; | ||
63 | |||
64 | sops.secrets.postfix-sasl-passwd = { | ||
65 | key = "sasl-passwd"; | ||
66 | path = "/var/db/postfix/sasl_passwd"; | ||
67 | owner = "postfix"; | ||
68 | sopsFile = ./secrets.yaml; | ||
69 | }; | ||
70 | } | ||
diff --git a/hosts/surtr/default.nix b/hosts/surtr/default.nix index 9d3101c0..1c66df2b 100644 --- a/hosts/surtr/default.nix +++ b/hosts/surtr/default.nix | |||
@@ -22,7 +22,6 @@ with lib; | |||
22 | device = "/dev/vda"; | 22 | device = "/dev/vda"; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | |||
26 | tmp.useTmpfs = true; | 25 | tmp.useTmpfs = true; |
27 | 26 | ||
28 | zfs.devNodes = "/dev"; # /dev/vda2 does not show up in /dev/disk/by-id | 27 | zfs.devNodes = "/dev"; # /dev/vda2 does not show up in /dev/disk/by-id |
@@ -31,7 +30,7 @@ with lib; | |||
31 | kernelPatches = [ | 30 | kernelPatches = [ |
32 | { name = "zswap-default"; | 31 | { name = "zswap-default"; |
33 | patch = null; | 32 | patch = null; |
34 | extraStructuredConfig = with lib.kernel; { | 33 | structuredExtraConfig = with lib.kernel; { |
35 | ZSWAP_DEFAULT_ON = yes; | 34 | ZSWAP_DEFAULT_ON = yes; |
36 | ZSWAP_SHRINKER_DEFAULT_ON = yes; | 35 | ZSWAP_SHRINKER_DEFAULT_ON = yes; |
37 | }; | 36 | }; |
diff --git a/hosts/surtr/dns/zones/email.nights.soa b/hosts/surtr/dns/zones/email.nights.soa index 913a88d4..34209a99 100644 --- a/hosts/surtr/dns/zones/email.nights.soa +++ b/hosts/surtr/dns/zones/email.nights.soa | |||
@@ -1,7 +1,7 @@ | |||
1 | $ORIGIN nights.email. | 1 | $ORIGIN nights.email. |
2 | $TTL 3600 | 2 | $TTL 3600 |
3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( | 3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( |
4 | 2023013000 ; serial | 4 | 2025060700 ; serial |
5 | 10800 ; refresh | 5 | 10800 ; refresh |
6 | 3600 ; retry | 6 | 3600 ; retry |
7 | 604800 ; expire | 7 | 604800 ; expire |
@@ -27,11 +27,7 @@ $TTL 3600 | |||
27 | 27 | ||
28 | _acme-challenge IN NS ns.yggdrasil.li. | 28 | _acme-challenge IN NS ns.yggdrasil.li. |
29 | 29 | ||
30 | ymir._domainkey IN TXT ( | 30 | ymir._domainkey IN CNAME ymir._domainkey.yggdrasil.li. |
31 | "v=DKIM1;k=rsa;p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq3cCKlk+VPhyAanLZTM0BCzUT/+fmxHioZcFk0uJk1akBYj7BRofR7eVNcLKpm3rwYMQgE+9vJH9p8SV6tws9EcWc8SMCqqGZlREYM7PmLDiTSK/vjCzkygfgFCb0EBNsY2A/fpP4rTeoxrbcBSvMkq97iY5rwyw4wXZVZXLiDaCj23s8POoxTk1ClqUJZJQ5x2" | ||
32 | "qzrC0RfN5kLZ9A7Gq2jB09vNxpXHYqABA0bJv88JiZM7hfkp9IafJZ+yCVMaBcJs4DAxnTjNAuFD9gm+qSFVY8+yeXqL6Qjo5PbruhyZRBW8RgRYT8t5n07XRglMGKKGMwOGLanrltcyXqB+GsDZBD36RAAwjFadnxdpDyRv4SgRP7ff2tKRrORYpmpN+mKdqw5j3J/nP6bXV1oAkyh9XQkPEIDi81WT87EZziTElDzVp6A2qFOxqucAovoRk24" | ||
33 | "7vlsns1FApFRsp9mja0UZNObyKD1M6tP9Ep7lS76tFGMk+WDvXRJH5LEsyCpu7sSyl1r/O0M4K+KldRCqLlZd7rf8F5P8T0dn1azk05g7F4p0N/y9GNdzXbPZ9u0eZdI7SEdh8ZoOZp7NVZiBFfbWLSS5ZtyA2kbBa4i7GJ/cuAbEKOmqAkeQPiu96TGIcyjkXjS6mTPI+9UmKZYZC+OM8XdJ02y5KRoonCc19ZS8CAwEAAQ==" | ||
34 | ) | ||
35 | 31 | ||
36 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. | 32 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. |
37 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. | 33 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. |
diff --git a/hosts/surtr/dns/zones/li.141.soa b/hosts/surtr/dns/zones/li.141.soa index ab117f09..78d137bb 100644 --- a/hosts/surtr/dns/zones/li.141.soa +++ b/hosts/surtr/dns/zones/li.141.soa | |||
@@ -1,7 +1,7 @@ | |||
1 | $ORIGIN 141.li. | 1 | $ORIGIN 141.li. |
2 | $TTL 3600 | 2 | $TTL 3600 |
3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( | 3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( |
4 | 2025020900 ; serial | 4 | 2025060701 ; serial |
5 | 10800 ; refresh | 5 | 10800 ; refresh |
6 | 3600 ; retry | 6 | 3600 ; retry |
7 | 604800 ; expire | 7 | 604800 ; expire |
@@ -45,11 +45,8 @@ ymir IN AAAA 2a03:4000:6:d004:: | |||
45 | ymir IN MX 0 ymir.yggdrasil.li | 45 | ymir IN MX 0 ymir.yggdrasil.li |
46 | ymir IN TXT "v=spf1 redirect=ymir.yggdrasil.li" | 46 | ymir IN TXT "v=spf1 redirect=ymir.yggdrasil.li" |
47 | 47 | ||
48 | ymir._domainkey IN TXT ( | 48 | ymir._domainkey IN CNAME ymir._domainkey.yggdrasil.li. |
49 | "v=DKIM1;k=rsa;p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq3cCKlk+VPhyAanLZTM0BCzUT/+fmxHioZcFk0uJk1akBYj7BRofR7eVNcLKpm3rwYMQgE+9vJH9p8SV6tws9EcWc8SMCqqGZlREYM7PmLDiTSK/vjCzkygfgFCb0EBNsY2A/fpP4rTeoxrbcBSvMkq97iY5rwyw4wXZVZXLiDaCj23s8POoxTk1ClqUJZJQ5x2" | 49 | surtr._domainkey IN CNAME surtr._domainkey.yggdrasil.li. |
50 | "qzrC0RfN5kLZ9A7Gq2jB09vNxpXHYqABA0bJv88JiZM7hfkp9IafJZ+yCVMaBcJs4DAxnTjNAuFD9gm+qSFVY8+yeXqL6Qjo5PbruhyZRBW8RgRYT8t5n07XRglMGKKGMwOGLanrltcyXqB+GsDZBD36RAAwjFadnxdpDyRv4SgRP7ff2tKRrORYpmpN+mKdqw5j3J/nP6bXV1oAkyh9XQkPEIDi81WT87EZziTElDzVp6A2qFOxqucAovoRk24" | ||
51 | "7vlsns1FApFRsp9mja0UZNObyKD1M6tP9Ep7lS76tFGMk+WDvXRJH5LEsyCpu7sSyl1r/O0M4K+KldRCqLlZd7rf8F5P8T0dn1azk05g7F4p0N/y9GNdzXbPZ9u0eZdI7SEdh8ZoOZp7NVZiBFfbWLSS5ZtyA2kbBa4i7GJ/cuAbEKOmqAkeQPiu96TGIcyjkXjS6mTPI+9UmKZYZC+OM8XdJ02y5KRoonCc19ZS8CAwEAAQ==" | ||
52 | ) | ||
53 | 50 | ||
54 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. | 51 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. |
55 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. | 52 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. |
diff --git a/hosts/surtr/dns/zones/li.kleen.soa b/hosts/surtr/dns/zones/li.kleen.soa index a1c7d35a..5dd3e697 100644 --- a/hosts/surtr/dns/zones/li.kleen.soa +++ b/hosts/surtr/dns/zones/li.kleen.soa | |||
@@ -1,7 +1,7 @@ | |||
1 | $ORIGIN kleen.li. | 1 | $ORIGIN kleen.li. |
2 | $TTL 3600 | 2 | $TTL 3600 |
3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( | 3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( |
4 | 2023013000 ; serial | 4 | 2025060701 ; serial |
5 | 10800 ; refresh | 5 | 10800 ; refresh |
6 | 3600 ; retry | 6 | 3600 ; retry |
7 | 604800 ; expire | 7 | 604800 ; expire |
@@ -27,11 +27,8 @@ $TTL 3600 | |||
27 | 27 | ||
28 | _acme-challenge IN NS ns.yggdrasil.li. | 28 | _acme-challenge IN NS ns.yggdrasil.li. |
29 | 29 | ||
30 | ymir._domainkey IN TXT ( | 30 | ymir._domainkey IN CNAME ymir._domainkey.yggdrasil.li. |
31 | "v=DKIM1;k=rsa;p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq3cCKlk+VPhyAanLZTM0BCzUT/+fmxHioZcFk0uJk1akBYj7BRofR7eVNcLKpm3rwYMQgE+9vJH9p8SV6tws9EcWc8SMCqqGZlREYM7PmLDiTSK/vjCzkygfgFCb0EBNsY2A/fpP4rTeoxrbcBSvMkq97iY5rwyw4wXZVZXLiDaCj23s8POoxTk1ClqUJZJQ5x2" | 31 | surtr._domainkey IN CNAME surtr._domainkey.yggdrasil.li. |
32 | "qzrC0RfN5kLZ9A7Gq2jB09vNxpXHYqABA0bJv88JiZM7hfkp9IafJZ+yCVMaBcJs4DAxnTjNAuFD9gm+qSFVY8+yeXqL6Qjo5PbruhyZRBW8RgRYT8t5n07XRglMGKKGMwOGLanrltcyXqB+GsDZBD36RAAwjFadnxdpDyRv4SgRP7ff2tKRrORYpmpN+mKdqw5j3J/nP6bXV1oAkyh9XQkPEIDi81WT87EZziTElDzVp6A2qFOxqucAovoRk24" | ||
33 | "7vlsns1FApFRsp9mja0UZNObyKD1M6tP9Ep7lS76tFGMk+WDvXRJH5LEsyCpu7sSyl1r/O0M4K+KldRCqLlZd7rf8F5P8T0dn1azk05g7F4p0N/y9GNdzXbPZ9u0eZdI7SEdh8ZoOZp7NVZiBFfbWLSS5ZtyA2kbBa4i7GJ/cuAbEKOmqAkeQPiu96TGIcyjkXjS6mTPI+9UmKZYZC+OM8XdJ02y5KRoonCc19ZS8CAwEAAQ==" | ||
34 | ) | ||
35 | 32 | ||
36 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. | 33 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. |
37 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. | 34 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. |
diff --git a/hosts/surtr/dns/zones/li.synapse.soa b/hosts/surtr/dns/zones/li.synapse.soa index 086d4a85..247cf025 100644 --- a/hosts/surtr/dns/zones/li.synapse.soa +++ b/hosts/surtr/dns/zones/li.synapse.soa | |||
@@ -1,7 +1,7 @@ | |||
1 | $ORIGIN synapse.li. | 1 | $ORIGIN synapse.li. |
2 | $TTL 3600 | 2 | $TTL 3600 |
3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( | 3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( |
4 | 2023092100 ; serial | 4 | 2025060701 ; serial |
5 | 10800 ; refresh | 5 | 10800 ; refresh |
6 | 3600 ; retry | 6 | 3600 ; retry |
7 | 604800 ; expire | 7 | 604800 ; expire |
diff --git a/hosts/surtr/dns/zones/li.yggdrasil.soa b/hosts/surtr/dns/zones/li.yggdrasil.soa index ebb298b4..500194ae 100644 --- a/hosts/surtr/dns/zones/li.yggdrasil.soa +++ b/hosts/surtr/dns/zones/li.yggdrasil.soa | |||
@@ -1,7 +1,7 @@ | |||
1 | $ORIGIN yggdrasil.li. | 1 | $ORIGIN yggdrasil.li. |
2 | $TTL 3600 | 2 | $TTL 3600 |
3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( | 3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( |
4 | 2025052400 ; serial | 4 | 2025060700 ; serial |
5 | 10800 ; refresh | 5 | 10800 ; refresh |
6 | 3600 ; retry | 6 | 3600 ; retry |
7 | 604800 ; expire | 7 | 604800 ; expire |
@@ -115,6 +115,8 @@ vidhar IN TXT "v=spf1 redirect=yggdrasil.li" | |||
115 | 115 | ||
116 | mailout IN A 188.68.51.254 | 116 | mailout IN A 188.68.51.254 |
117 | mailout IN AAAA 2a03:4000:6:d004:: | 117 | mailout IN AAAA 2a03:4000:6:d004:: |
118 | mailout IN A 202.61.241.61 | ||
119 | mailout IN AAAA 2a03:4000:52:ada:: | ||
118 | mailout IN MX 0 ymir.yggdrasil.li | 120 | mailout IN MX 0 ymir.yggdrasil.li |
119 | mailout IN TXT "v=spf1 redirect=yggdrasil.li" | 121 | mailout IN TXT "v=spf1 redirect=yggdrasil.li" |
120 | 122 | ||
diff --git a/hosts/surtr/dns/zones/org.praseodym.soa b/hosts/surtr/dns/zones/org.praseodym.soa index df505b4c..2b97ca19 100644 --- a/hosts/surtr/dns/zones/org.praseodym.soa +++ b/hosts/surtr/dns/zones/org.praseodym.soa | |||
@@ -1,7 +1,7 @@ | |||
1 | $ORIGIN praseodym.org. | 1 | $ORIGIN praseodym.org. |
2 | $TTL 3600 | 2 | $TTL 3600 |
3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( | 3 | @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( |
4 | 2023013000 ; serial | 4 | 2025060701 ; serial |
5 | 10800 ; refresh | 5 | 10800 ; refresh |
6 | 3600 ; retry | 6 | 3600 ; retry |
7 | 604800 ; expire | 7 | 604800 ; expire |
@@ -32,11 +32,8 @@ surtr IN AAAA 2a03:4000:52:ada:: | |||
32 | surtr IN MX 0 ymir.yggdrasil.li | 32 | surtr IN MX 0 ymir.yggdrasil.li |
33 | surtr IN TXT "v=spf1 redirect=yggdrasil.li" | 33 | surtr IN TXT "v=spf1 redirect=yggdrasil.li" |
34 | 34 | ||
35 | ymir._domainkey IN TXT ( | 35 | ymir._domainkey IN CNAME ymir._domainkey.yggdrasil.li. |
36 | "v=DKIM1;k=rsa;p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq3cCKlk+VPhyAanLZTM0BCzUT/+fmxHioZcFk0uJk1akBYj7BRofR7eVNcLKpm3rwYMQgE+9vJH9p8SV6tws9EcWc8SMCqqGZlREYM7PmLDiTSK/vjCzkygfgFCb0EBNsY2A/fpP4rTeoxrbcBSvMkq97iY5rwyw4wXZVZXLiDaCj23s8POoxTk1ClqUJZJQ5x2" | 36 | surtr._domainkey IN CNAME surtr._domainkey.yggdrasil.li. |
37 | "qzrC0RfN5kLZ9A7Gq2jB09vNxpXHYqABA0bJv88JiZM7hfkp9IafJZ+yCVMaBcJs4DAxnTjNAuFD9gm+qSFVY8+yeXqL6Qjo5PbruhyZRBW8RgRYT8t5n07XRglMGKKGMwOGLanrltcyXqB+GsDZBD36RAAwjFadnxdpDyRv4SgRP7ff2tKRrORYpmpN+mKdqw5j3J/nP6bXV1oAkyh9XQkPEIDi81WT87EZziTElDzVp6A2qFOxqucAovoRk24" | ||
38 | "7vlsns1FApFRsp9mja0UZNObyKD1M6tP9Ep7lS76tFGMk+WDvXRJH5LEsyCpu7sSyl1r/O0M4K+KldRCqLlZd7rf8F5P8T0dn1azk05g7F4p0N/y9GNdzXbPZ9u0eZdI7SEdh8ZoOZp7NVZiBFfbWLSS5ZtyA2kbBa4i7GJ/cuAbEKOmqAkeQPiu96TGIcyjkXjS6mTPI+9UmKZYZC+OM8XdJ02y5KRoonCc19ZS8CAwEAAQ==" | ||
39 | ) | ||
40 | 37 | ||
41 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. | 38 | _xmpp-client._tcp IN SRV 5 0 5222 ymir.yggdrasil.li. |
42 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. | 39 | _xmpp-server._tcp IN SRV 5 0 5269 ymir.yggdrasil.li. |
diff --git a/hosts/surtr/email/ccert-policy-server/ccert_policy_server/__main__.py b/hosts/surtr/email/ccert-policy-server/ccert_policy_server/__main__.py index 7117eb63..7c931559 100644 --- a/hosts/surtr/email/ccert-policy-server/ccert_policy_server/__main__.py +++ b/hosts/surtr/email/ccert-policy-server/ccert_policy_server/__main__.py | |||
@@ -28,10 +28,12 @@ class PolicyHandler(StreamRequestHandler): | |||
28 | 28 | ||
29 | allowed = False | 29 | allowed = False |
30 | user = None | 30 | user = None |
31 | relay_eligible = False | ||
31 | if self.args['sasl_username']: | 32 | if self.args['sasl_username']: |
32 | user = self.args['sasl_username'] | 33 | user = self.args['sasl_username'] |
33 | if self.args['ccert_subject']: | 34 | if self.args['ccert_subject']: |
34 | user = self.args['ccert_subject'] | 35 | user = self.args['ccert_subject'] |
36 | relay_eligible = True | ||
35 | 37 | ||
36 | if user: | 38 | if user: |
37 | with self.server.db_pool.connection() as conn: | 39 | with self.server.db_pool.connection() as conn: |
@@ -44,9 +46,16 @@ class PolicyHandler(StreamRequestHandler): | |||
44 | 46 | ||
45 | with conn.cursor() as cur: | 47 | with conn.cursor() as cur: |
46 | cur.row_factory = namedtuple_row | 48 | cur.row_factory = namedtuple_row |
47 | cur.execute('SELECT EXISTS(SELECT true FROM "mailbox" INNER JOIN "mailbox_mapping" ON "mailbox".id = "mailbox_mapping"."mailbox" WHERE "mailbox"."mailbox" = %(user)s AND ("local" = %(local)s OR "local" IS NULL) AND ("extension" = %(extension)s OR "extension" IS NULL) AND "domain" = %(domain)s) as "exists"', params = {'user': user, 'local': local, 'extension': extension if extension is not None else '', 'domain': domain}, prepare=True) | 49 | |
48 | if (row := cur.fetchone()) is not None: | 50 | if relay_eligible: |
49 | allowed = row.exists | 51 | cur.execute('SELECT EXISTS(SELECT true FROM "mailbox" INNER JOIN "relay_access" ON "mailbox".id = "relay_access"."mailbox" WHERE "mailbox"."mailbox" = %(user)s AND ("domain" = %(domain)s OR %(domain)s ilike CONCAT(\'%%_.\', "domain"))) as "exists"', params = {'user': user, 'domain': domain}) |
52 | if (row := cur.fetchone()) is not None: | ||
53 | allowed = row.exists | ||
54 | |||
55 | if not allowed: | ||
56 | cur.execute('SELECT EXISTS(SELECT true FROM "mailbox" INNER JOIN "mailbox_mapping" ON "mailbox".id = "mailbox_mapping"."mailbox" WHERE "mailbox"."mailbox" = %(user)s AND ("local" = %(local)s OR "local" IS NULL) AND ("extension" = %(extension)s OR "extension" IS NULL) AND "domain" = %(domain)s) as "exists"', params = {'user': user, 'local': local, 'extension': extension if extension is not None else '', 'domain': domain}, prepare=True) | ||
57 | if (row := cur.fetchone()) is not None: | ||
58 | allowed = row.exists | ||
50 | 59 | ||
51 | action = '550 5.7.0 Sender address not authorized for current user' | 60 | action = '550 5.7.0 Sender address not authorized for current user' |
52 | if allowed: | 61 | if allowed: |
diff --git a/hosts/surtr/email/default.nix b/hosts/surtr/email/default.nix index c6253e4c..a3e06ca6 100644 --- a/hosts/surtr/email/default.nix +++ b/hosts/surtr/email/default.nix | |||
@@ -124,19 +124,20 @@ in { | |||
124 | services.postfix = { | 124 | services.postfix = { |
125 | enable = true; | 125 | enable = true; |
126 | enableSmtp = false; | 126 | enableSmtp = false; |
127 | hostname = "surtr.yggdrasil.li"; | ||
128 | recipientDelimiter = ""; | ||
129 | setSendmail = true; | 127 | setSendmail = true; |
130 | postmasterAlias = ""; rootAlias = ""; extraAliases = ""; | 128 | postmasterAlias = ""; rootAlias = ""; extraAliases = ""; |
131 | destination = []; | 129 | settings.main = { |
132 | sslCert = "/run/credentials/postfix.service/surtr.yggdrasil.li.pem"; | 130 | recpipient_delimiter = ""; |
133 | sslKey = "/run/credentials/postfix.service/surtr.yggdrasil.li.key.pem"; | 131 | mydestination = []; |
134 | networks = []; | 132 | mynetworks = []; |
135 | config = let | 133 | myhostname = "surtr.yggdrasil.li"; |
136 | relay_ccert = "texthash:${pkgs.writeText "relay_ccert" ""}"; | 134 | |
137 | in { | ||
138 | smtpd_tls_security_level = "may"; | 135 | smtpd_tls_security_level = "may"; |
139 | 136 | ||
137 | smtpd_tls_chain_files = [ | ||
138 | "/run/credentials/postfix.service/surtr.yggdrasil.li.full.pem" | ||
139 | ]; | ||
140 | |||
140 | #the dh params | 141 | #the dh params |
141 | smtpd_tls_dh1024_param_file = toString config.security.dhparams.params."postfix-1024".path; | 142 | smtpd_tls_dh1024_param_file = toString config.security.dhparams.params."postfix-1024".path; |
142 | smtpd_tls_dh512_param_file = toString config.security.dhparams.params."postfix-512".path; | 143 | smtpd_tls_dh512_param_file = toString config.security.dhparams.params."postfix-512".path; |
@@ -171,21 +172,14 @@ in { | |||
171 | 172 | ||
172 | smtp_tls_connection_reuse = true; | 173 | smtp_tls_connection_reuse = true; |
173 | 174 | ||
174 | tls_server_sni_maps = ''texthash:${pkgs.writeText "sni" ( | 175 | tls_server_sni_maps = "inline:{${concatMapStringsSep ", " (domain: "{ ${domain} = /run/credentials/postfix.service/${removePrefix "." domain}.full.pem }") (concatMap (domain: [domain "mailin.${domain}" "mailsub.${domain}" ".${domain}"]) emailDomains)}}"; |
175 | concatMapStringsSep "\n\n" (domain: | ||
176 | concatMapStringsSep "\n" (subdomain: "${subdomain} /run/credentials/postfix.service/${removePrefix "." subdomain}.full.pem") | ||
177 | [domain "mailin.${domain}" "mailsub.${domain}" ".${domain}"] | ||
178 | ) emailDomains | ||
179 | )}''; | ||
180 | 176 | ||
181 | smtp_tls_policy_maps = "socketmap:unix:${config.services.postfix-mta-sts-resolver.settings.path}:postfix"; | 177 | smtp_tls_policy_maps = "socketmap:unix:${config.services.postfix-mta-sts-resolver.settings.path}:postfix"; |
182 | 178 | ||
183 | local_recipient_maps = ""; | 179 | local_recipient_maps = ""; |
184 | 180 | ||
185 | # 10 GiB | 181 | message_size_limit = 10 * 1024 * 1024 * 1024; |
186 | message_size_limit = "10737418240"; | 182 | mailbox_size_limit = 10 * 1024 * 1024 * 1024; |
187 | # 10 GiB | ||
188 | mailbox_size_limit = "10737418240"; | ||
189 | 183 | ||
190 | smtpd_delay_reject = true; | 184 | smtpd_delay_reject = true; |
191 | smtpd_helo_required = true; | 185 | smtpd_helo_required = true; |
@@ -200,7 +194,6 @@ in { | |||
200 | dbname = email | 194 | dbname = email |
201 | query = SELECT action FROM virtual_mailbox_access WHERE lookup = '%s' | 195 | query = SELECT action FROM virtual_mailbox_access WHERE lookup = '%s' |
202 | ''}" | 196 | ''}" |
203 | "check_ccert_access ${relay_ccert}" | ||
204 | "reject_non_fqdn_helo_hostname" | 197 | "reject_non_fqdn_helo_hostname" |
205 | "reject_invalid_helo_hostname" | 198 | "reject_invalid_helo_hostname" |
206 | "reject_unauth_destination" | 199 | "reject_unauth_destination" |
@@ -221,7 +214,6 @@ in { | |||
221 | address_verify_sender_ttl = "30045s"; | 214 | address_verify_sender_ttl = "30045s"; |
222 | 215 | ||
223 | smtpd_relay_restrictions = [ | 216 | smtpd_relay_restrictions = [ |
224 | "check_ccert_access ${relay_ccert}" | ||
225 | "reject_unauth_destination" | 217 | "reject_unauth_destination" |
226 | ]; | 218 | ]; |
227 | 219 | ||
@@ -268,13 +260,26 @@ in { | |||
268 | virtual_transport = "dvlmtp:unix:/run/dovecot-lmtp"; | 260 | virtual_transport = "dvlmtp:unix:/run/dovecot-lmtp"; |
269 | smtputf8_enable = false; | 261 | smtputf8_enable = false; |
270 | 262 | ||
271 | authorized_submit_users = "inline:{ root= postfwd= dovecot2= }"; | 263 | authorized_submit_users = "inline:{ root= postfwd= ${config.services.dovecot2.user}= }"; |
264 | authorized_flush_users = "inline:{ root= }"; | ||
265 | authorized_mailq_users = "inline:{ root= }"; | ||
272 | 266 | ||
273 | postscreen_access_list = ""; | 267 | postscreen_access_list = ""; |
274 | postscreen_denylist_action = "drop"; | 268 | postscreen_denylist_action = "drop"; |
275 | postscreen_greet_action = "enforce"; | 269 | postscreen_greet_action = "enforce"; |
270 | |||
271 | sender_bcc_maps = ''pgsql:${pkgs.writeText "sender_bcc_maps.cf" '' | ||
272 | hosts = postgresql:///email | ||
273 | dbname = email | ||
274 | query = SELECT value FROM sender_bcc_maps WHERE key = '%s' | ||
275 | ''}''; | ||
276 | recipient_bcc_maps = ''pgsql:${pkgs.writeText "recipient_bcc_maps.cf" '' | ||
277 | hosts = postgresql:///email | ||
278 | dbname = email | ||
279 | query = SELECT value FROM recipient_bcc_maps WHERE key = '%s' | ||
280 | ''}''; | ||
276 | }; | 281 | }; |
277 | masterConfig = { | 282 | settings.master = { |
278 | "465" = { | 283 | "465" = { |
279 | type = "inet"; | 284 | type = "inet"; |
280 | private = false; | 285 | private = false; |
@@ -342,7 +347,10 @@ in { | |||
342 | maxproc = 0; | 347 | maxproc = 0; |
343 | args = [ | 348 | args = [ |
344 | "-o" "header_checks=pcre:${pkgs.writeText "header_checks_submission" '' | 349 | "-o" "header_checks=pcre:${pkgs.writeText "header_checks_submission" '' |
350 | if /^Received: / | ||
351 | !/by surtr\.yggdrasil\.li/ STRIP | ||
345 | /^Received: from [^ ]+ \([^ ]+ [^ ]+\)\s+(.*)$/ REPLACE Received: $1 | 352 | /^Received: from [^ ]+ \([^ ]+ [^ ]+\)\s+(.*)$/ REPLACE Received: $1 |
353 | endif | ||
346 | ''}" | 354 | ''}" |
347 | ]; | 355 | ]; |
348 | }; | 356 | }; |
@@ -390,7 +398,7 @@ in { | |||
390 | enable = true; | 398 | enable = true; |
391 | user = "postfix"; group = "postfix"; | 399 | user = "postfix"; group = "postfix"; |
392 | socket = "local:/run/opendkim/opendkim.sock"; | 400 | socket = "local:/run/opendkim/opendkim.sock"; |
393 | domains = ''csl:${concatStringsSep "," (["surtr.yggdrasil.li"] ++ emailDomains)}''; | 401 | domains = ''csl:${concatStringsSep "," (["surtr.yggdrasil.li" "yggdrasil.li" "141.li" "kleen.li" "synapse.li" "praseodym.org"] ++ emailDomains)}''; |
394 | selector = "surtr"; | 402 | selector = "surtr"; |
395 | configFile = builtins.toFile "opendkim.conf" '' | 403 | configFile = builtins.toFile "opendkim.conf" '' |
396 | Syslog true | 404 | Syslog true |
@@ -494,7 +502,7 @@ in { | |||
494 | }; | 502 | }; |
495 | }; | 503 | }; |
496 | 504 | ||
497 | users.groups.${config.services.rspamd.group}.members = [ config.services.postfix.user "dovecot2" ]; | 505 | users.groups.${config.services.rspamd.group}.members = [ config.services.postfix.user config.services.dovecot2.user ]; |
498 | 506 | ||
499 | services.redis.servers.rspamd.enable = true; | 507 | services.redis.servers.rspamd.enable = true; |
500 | 508 | ||
@@ -504,22 +512,22 @@ in { | |||
504 | services.dovecot2 = { | 512 | services.dovecot2 = { |
505 | enable = true; | 513 | enable = true; |
506 | enablePAM = false; | 514 | enablePAM = false; |
507 | sslServerCert = "/run/credentials/dovecot2.service/surtr.yggdrasil.li.pem"; | 515 | sslServerCert = "/run/credentials/dovecot.service/surtr.yggdrasil.li.pem"; |
508 | sslServerKey = "/run/credentials/dovecot2.service/surtr.yggdrasil.li.key.pem"; | 516 | sslServerKey = "/run/credentials/dovecot.service/surtr.yggdrasil.li.key.pem"; |
509 | sslCACert = toString ./ca/ca.crt; | 517 | sslCACert = toString ./ca/ca.crt; |
510 | mailLocation = "maildir:/var/lib/mail/%u/maildir:UTF-8:INDEX=/var/lib/dovecot/indices/%u"; | 518 | mailLocation = "maildir:/var/lib/mail/%u/maildir:UTF-8:INDEX=/var/lib/dovecot/indices/%u"; |
511 | mailPlugins.globally.enable = [ "fts" "fts_xapian" ]; | 519 | mailPlugins.globally.enable = [ "fts" "fts_xapian" ]; |
512 | protocols = [ "lmtp" "sieve" ]; | 520 | protocols = [ "lmtp" "sieve" ]; |
513 | sieve = { | 521 | sieve = { |
514 | extensions = ["copy" "imapsieve" "variables" "imap4flags" "vacation"]; | 522 | extensions = ["copy" "imapsieve" "variables" "imap4flags" "vacation" "vacation-seconds" "vnd.dovecot.debug"]; |
515 | globalExtensions = ["copy" "imapsieve" "variables" "imap4flags" "vacation"]; | 523 | globalExtensions = ["copy" "imapsieve" "variables" "imap4flags" "vacation" "vacation-seconds" "vnd.dovecot.debug"]; |
516 | }; | 524 | }; |
517 | extraConfig = let | 525 | extraConfig = let |
518 | dovecotSqlConf = pkgs.writeText "dovecot-sql.conf" '' | 526 | dovecotSqlConf = pkgs.writeText "dovecot-sql.conf" '' |
519 | driver = pgsql | 527 | driver = pgsql |
520 | connect = dbname=email | 528 | connect = dbname=email |
521 | password_query = SELECT (CASE WHEN '%k' = 'valid' AND '%m' = 'EXTERNAL' THEN NULL ELSE "password" END) as password, (CASE WHEN '%k' = 'valid' AND '%m' = 'EXTERNAL' THEN true WHEN password IS NULL THEN true ELSE NULL END) as nopassword, "user", quota_rule, 'dovecot2' as uid, 'dovecot2' as gid FROM imap_user WHERE "user" = '%n' | 529 | password_query = SELECT (CASE WHEN '%k' = 'valid' AND '%m' = 'EXTERNAL' THEN NULL ELSE "password" END) as password, (CASE WHEN '%k' = 'valid' AND '%m' = 'EXTERNAL' THEN true WHEN password IS NULL THEN true ELSE NULL END) as nopassword, "user", quota_rule, '${config.services.dovecot2.user}' as uid, '${config.services.dovecot2.group}' as gid FROM imap_user WHERE "user" = '%n' |
522 | user_query = SELECT "user", quota_rule, 'dovecot2' as uid, 'dovecot2' as gid FROM imap_user WHERE "user" = '%n' | 530 | user_query = SELECT "user", quota_rule, '${config.services.dovecot2.user}' as uid, 'dovecot2' as gid FROM imap_user WHERE "user" = '%n' |
523 | iterate_query = SELECT "user" FROM imap_user | 531 | iterate_query = SELECT "user" FROM imap_user |
524 | ''; | 532 | ''; |
525 | in '' | 533 | in '' |
@@ -527,16 +535,16 @@ in { | |||
527 | 535 | ||
528 | mail_plugins = $mail_plugins quota | 536 | mail_plugins = $mail_plugins quota |
529 | 537 | ||
530 | first_valid_uid = ${toString config.users.users.dovecot2.uid} | 538 | first_valid_uid = ${toString config.users.users.${config.services.dovecot2.user}.uid} |
531 | last_valid_uid = ${toString config.users.users.dovecot2.uid} | 539 | last_valid_uid = ${toString config.users.users.${config.services.dovecot2.user}.uid} |
532 | first_valid_gid = ${toString config.users.groups.dovecot2.gid} | 540 | first_valid_gid = ${toString config.users.groups.${config.services.dovecot2.group}.gid} |
533 | last_valid_gid = ${toString config.users.groups.dovecot2.gid} | 541 | last_valid_gid = ${toString config.users.groups.${config.services.dovecot2.group}.gid} |
534 | 542 | ||
535 | ${concatMapStringsSep "\n\n" (domain: | 543 | ${concatMapStringsSep "\n\n" (domain: |
536 | concatMapStringsSep "\n" (subdomain: '' | 544 | concatMapStringsSep "\n" (subdomain: '' |
537 | local_name ${subdomain} { | 545 | local_name ${subdomain} { |
538 | ssl_cert = </run/credentials/dovecot2.service/${subdomain}.pem | 546 | ssl_cert = </run/credentials/dovecot.service/${subdomain}.pem |
539 | ssl_key = </run/credentials/dovecot2.service/${subdomain}.key.pem | 547 | ssl_key = </run/credentials/dovecot.service/${subdomain}.key.pem |
540 | } | 548 | } |
541 | '') ["imap.${domain}" domain] | 549 | '') ["imap.${domain}" domain] |
542 | ) emailDomains} | 550 | ) emailDomains} |
@@ -557,10 +565,10 @@ in { | |||
557 | auth_debug = yes | 565 | auth_debug = yes |
558 | 566 | ||
559 | service auth { | 567 | service auth { |
560 | user = dovecot2 | 568 | user = ${config.services.dovecot2.user} |
561 | } | 569 | } |
562 | service auth-worker { | 570 | service auth-worker { |
563 | user = dovecot2 | 571 | user = ${config.services.dovecot2.user} |
564 | } | 572 | } |
565 | 573 | ||
566 | userdb { | 574 | userdb { |
@@ -581,7 +589,7 @@ in { | |||
581 | args = ${pkgs.writeText "dovecot-sql.conf" '' | 589 | args = ${pkgs.writeText "dovecot-sql.conf" '' |
582 | driver = pgsql | 590 | driver = pgsql |
583 | connect = dbname=email | 591 | connect = dbname=email |
584 | user_query = SELECT DISTINCT ON (extension IS NULL, local IS NULL) "user", quota_rule, 'dovecot2' as uid, 'dovecot2' as gid FROM lmtp_mapping WHERE CASE WHEN extension IS NOT NULL AND local IS NOT NULL THEN ('%n' :: citext) = local || '+' || extension AND domain = ('%d' :: citext) WHEN local IS NOT NULL THEN (local = ('%n' :: citext) OR ('%n' :: citext) ILIKE local || '+%%') AND domain = ('%d' :: citext) WHEN extension IS NOT NULL THEN ('%n' :: citext) ILIKE '%%+' || extension AND domain = ('%d' :: citext) ELSE domain = ('%d' :: citext) END ORDER BY (extension IS NULL) ASC, (local IS NULL) ASC | 592 | user_query = SELECT DISTINCT ON (extension IS NULL, local IS NULL) "user", quota_rule, '${config.services.dovecot2.user}' as uid, '${config.services.dovecot2.group}' as gid FROM lmtp_mapping WHERE CASE WHEN extension IS NOT NULL AND local IS NOT NULL THEN ('%n' :: citext) = local || '+' || extension AND domain = ('%d' :: citext) WHEN local IS NOT NULL THEN (local = ('%n' :: citext) OR ('%n' :: citext) ILIKE local || '+%%') AND domain = ('%d' :: citext) WHEN extension IS NOT NULL THEN ('%n' :: citext) ILIKE '%%+' || extension AND domain = ('%d' :: citext) ELSE domain = ('%d' :: citext) END ORDER BY (extension IS NULL) ASC, (local IS NULL) ASC |
585 | ''} | 593 | ''} |
586 | 594 | ||
587 | skip = never | 595 | skip = never |
@@ -651,7 +659,7 @@ in { | |||
651 | quota_status_success = DUNNO | 659 | quota_status_success = DUNNO |
652 | quota_status_nouser = DUNNO | 660 | quota_status_nouser = DUNNO |
653 | quota_grace = 10%% | 661 | quota_grace = 10%% |
654 | quota_max_mail_size = ${config.services.postfix.config.message_size_limit} | 662 | quota_max_mail_size = ${toString config.services.postfix.settings.main.message_size_limit} |
655 | quota_vsizes = yes | 663 | quota_vsizes = yes |
656 | } | 664 | } |
657 | 665 | ||
@@ -704,8 +712,8 @@ in { | |||
704 | 712 | ||
705 | systemd.services.dovecot-fts-xapian-optimize = { | 713 | systemd.services.dovecot-fts-xapian-optimize = { |
706 | description = "Optimize dovecot indices for fts_xapian"; | 714 | description = "Optimize dovecot indices for fts_xapian"; |
707 | requisite = [ "dovecot2.service" ]; | 715 | requisite = [ "dovecot.service" ]; |
708 | after = [ "dovecot2.service" ]; | 716 | after = [ "dovecot.service" ]; |
709 | startAt = "*-*-* 22:00:00 Europe/Berlin"; | 717 | startAt = "*-*-* 22:00:00 Europe/Berlin"; |
710 | serviceConfig = { | 718 | serviceConfig = { |
711 | Type = "oneshot"; | 719 | Type = "oneshot"; |
@@ -770,28 +778,26 @@ in { | |||
770 | 778 | ||
771 | security.acme.rfc2136Domains = { | 779 | security.acme.rfc2136Domains = { |
772 | "surtr.yggdrasil.li" = { | 780 | "surtr.yggdrasil.li" = { |
773 | restartUnits = [ "postfix.service" "dovecot2.service" ]; | 781 | restartUnits = [ "postfix.service" "dovecot.service" ]; |
774 | }; | 782 | }; |
775 | } // listToAttrs (map (domain: nameValuePair "spm.${domain}" { restartUnits = ["nginx.service"]; }) spmDomains) | 783 | } // listToAttrs (map (domain: nameValuePair "spm.${domain}" { restartUnits = ["nginx.service"]; }) spmDomains) |
776 | // listToAttrs (concatMap (domain: [ | 784 | // listToAttrs (concatMap (domain: [ |
777 | (nameValuePair domain { restartUnits = ["postfix.service" "dovecot2.service"]; }) | 785 | (nameValuePair domain { restartUnits = ["postfix.service" "dovecot.service"]; }) |
778 | (nameValuePair "mailin.${domain}" { restartUnits = ["postfix.service"]; }) | 786 | (nameValuePair "mailin.${domain}" { restartUnits = ["postfix.service"]; }) |
779 | (nameValuePair "mailsub.${domain}" { restartUnits = ["postfix.service"]; }) | 787 | (nameValuePair "mailsub.${domain}" { restartUnits = ["postfix.service"]; }) |
780 | (nameValuePair "imap.${domain}" { restartUnits = ["dovecot2.service"]; }) | 788 | (nameValuePair "imap.${domain}" { restartUnits = ["dovecot.service"]; }) |
781 | (nameValuePair "mta-sts.${domain}" { restartUnits = ["nginx.service"]; }) | 789 | (nameValuePair "mta-sts.${domain}" { restartUnits = ["nginx.service"]; }) |
782 | ]) emailDomains); | 790 | ]) emailDomains); |
783 | 791 | ||
784 | systemd.services.postfix = { | 792 | systemd.services.postfix = { |
785 | serviceConfig.LoadCredential = [ | 793 | serviceConfig.LoadCredential = let |
786 | "surtr.yggdrasil.li.key.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/key.pem" | 794 | tlsCredential = domain: "${domain}.full.pem:${config.security.acme.certs.${domain}.directory}/full.pem"; |
787 | "surtr.yggdrasil.li.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/fullchain.pem" | 795 | in [ |
788 | ] ++ concatMap (domain: | 796 | (tlsCredential "surtr.yggdrasil.li") |
789 | map (subdomain: "${subdomain}.full.pem:${config.security.acme.certs.${subdomain}.directory}/full.pem") | 797 | ] ++ concatMap (domain: map tlsCredential [domain "mailin.${domain}" "mailsub.${domain}"]) emailDomains; |
790 | [domain "mailin.${domain}" "mailsub.${domain}"] | ||
791 | ) emailDomains; | ||
792 | }; | 798 | }; |
793 | 799 | ||
794 | systemd.services.dovecot2 = { | 800 | systemd.services.dovecot = { |
795 | preStart = '' | 801 | preStart = '' |
796 | for f in /etc/dovecot/sieve_flag.d/*.sieve /etc/dovecot/sieve_before.d/*.sieve; do | 802 | for f in /etc/dovecot/sieve_flag.d/*.sieve /etc/dovecot/sieve_before.d/*.sieve; do |
797 | ${getExe' pkgs.dovecot_pigeonhole "sievec"} $f | 803 | ${getExe' pkgs.dovecot_pigeonhole "sievec"} $f |
diff --git a/hosts/surtr/kimai.nix b/hosts/surtr/kimai.nix index a3712bb2..454b3d80 100644 --- a/hosts/surtr/kimai.nix +++ b/hosts/surtr/kimai.nix | |||
@@ -47,6 +47,8 @@ | |||
47 | client_max_body_size 0; | 47 | client_max_body_size 0; |
48 | proxy_request_buffering off; | 48 | proxy_request_buffering off; |
49 | proxy_buffering off; | 49 | proxy_buffering off; |
50 | |||
51 | proxy_read_timeout 300; | ||
50 | ''; | 52 | ''; |
51 | }; | 53 | }; |
52 | }; | 54 | }; |
diff --git a/hosts/surtr/postgresql/default.nix b/hosts/surtr/postgresql/default.nix index 0ae29058..3786ea7c 100644 --- a/hosts/surtr/postgresql/default.nix +++ b/hosts/surtr/postgresql/default.nix | |||
@@ -297,6 +297,47 @@ in { | |||
297 | 297 | ||
298 | COMMIT; | 298 | COMMIT; |
299 | 299 | ||
300 | BEGIN; | ||
301 | SELECT _v.register_patch('014-relay', ARRAY['000-base'], null); | ||
302 | |||
303 | CREATE TABLE relay_access ( | ||
304 | id uuid PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), | ||
305 | mailbox uuid REFERENCES mailbox(id), | ||
306 | domain citext NOT NULL CONSTRAINT domain_non_empty CHECK (domain <> ''') | ||
307 | ); | ||
308 | |||
309 | COMMIT; | ||
310 | |||
311 | BEGIN; | ||
312 | SELECT _v.register_patch('015-relay-unique', ARRAY['000-base', '014-relay'], null); | ||
313 | |||
314 | CREATE UNIQUE INDEX relay_unique ON relay_access (mailbox, domain); | ||
315 | |||
316 | COMMIT; | ||
317 | |||
318 | BEGIN; | ||
319 | SELECT _v.register_patch('015-sender_bcc', null, null); | ||
320 | |||
321 | CREATE TABLE sender_bcc_maps ( | ||
322 | id uuid PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), | ||
323 | key text NOT NULL CONSTRAINT key_not_empty CHECK (key <> '''), | ||
324 | value text NOT NULL CONSTRAINT value_not_empty CHECK (value <> '''), | ||
325 | CONSTRAINT key_unique UNIQUE (key) | ||
326 | ); | ||
327 | |||
328 | COMMIT; | ||
329 | |||
330 | BEGIN; | ||
331 | SELECT _v.register_patch('016-recipient_bcc', null, null); | ||
332 | |||
333 | CREATE TABLE recipient_bcc_maps ( | ||
334 | id uuid PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(), | ||
335 | key text NOT NULL CONSTRAINT key_not_empty CHECK (key <> '''), | ||
336 | value text NOT NULL CONSTRAINT value_not_empty CHECK (value <> '''), | ||
337 | CONSTRAINT recipient_bcc_maps_key_unique UNIQUE (key) | ||
338 | ); | ||
339 | |||
340 | COMMIT; | ||
300 | ''} | 341 | ''} |
301 | 342 | ||
302 | psql etebase postgres -eXf ${pkgs.writeText "etebase.sql" '' | 343 | psql etebase postgres -eXf ${pkgs.writeText "etebase.sql" '' |
diff --git a/hosts/surtr/tls/default.nix b/hosts/surtr/tls/default.nix index b1c05888..b25bd2ea 100644 --- a/hosts/surtr/tls/default.nix +++ b/hosts/surtr/tls/default.nix | |||
@@ -41,7 +41,7 @@ in { | |||
41 | 41 | ||
42 | acceptTerms = true; | 42 | acceptTerms = true; |
43 | # DNS challenge is slow | 43 | # DNS challenge is slow |
44 | preliminarySelfsigned = true; | 44 | # preliminarySelfsigned = true; |
45 | defaults = { | 45 | defaults = { |
46 | email = "phikeebaogobaegh@141.li"; | 46 | email = "phikeebaogobaegh@141.li"; |
47 | # We don't like NIST curves and Let's Encrypt doesn't support | 47 | # We don't like NIST curves and Let's Encrypt doesn't support |
diff --git a/hosts/vidhar/audiobookshelf/abs-podcast-autoplaylist-gkleen.toml b/hosts/vidhar/audiobookshelf/abs-podcast-autoplaylist-gkleen.toml index a5319e38..42920069 100644 --- a/hosts/vidhar/audiobookshelf/abs-podcast-autoplaylist-gkleen.toml +++ b/hosts/vidhar/audiobookshelf/abs-podcast-autoplaylist-gkleen.toml | |||
@@ -1,5 +1,5 @@ | |||
1 | { | 1 | { |
2 | "data": "ENC[AES256_GCM,data:60OmHwuLC7RJVNNn8lsCFjIFrtDlmmT3yAm3DYn/K2b8OJB/lzKBhMUCyPpoI2lfMm6y47/DMwXI3ExH3QwfgGRf4i/Tcv7p6FCkjFgDc0RhAM7cXNSnh1gKTff8QYtPoNIzmycFCThNr7iZsPsf2/1npVaVHTnt9nTc+cmDLc+lELlvjSE00JOXch/if7KPwFww9K83XlrFmoRvwybfXR0unJqxK2XLvj+dQuKD4Bhyb88iSgu4dX1yw2uBSZBD16S4Io0DaZ+as5Yw4Kon7WMj3Jd5kz8ZxK+0NCy1CVJHOfJIwgYl0SVPp4DpbAPtJO4R/ciXyDQ/XGpoLtHjxnKXaJlJoSiA7FhuSEk+jB/peLHrYV1obdIRE5Dstly01S5cydKlfQ+A0TSjxFSWBYMEiD89sD09Br3iSJX5FejOoS8d2IQJ5faVzgQl4T5aBKsxCNNwmYrEe8m9HN7o2eer8nTKMln5IxZi3ZWhnjgJfrJ4QTXFndxCb78jo8HroN3+7VhoM136UZkqH1OMrIgAH/XSlW08G8m9MRamKsAWklq9aVflcEsPWTHmYW7rjAapQYf+jyK6BbfHcYmyKM82TFZ5iNB60Pth6EJgb2V8PZiChGvDzQvFYYOO3p9a/J8bVqsnPZBXXYcIBt42ZuRPvyyUTfM+75V1eYE9ZGFML+QlofwNCAg+/Rnl+RRy4z+8xQxd8Dn06geDpHsr4yND72FRUTKLbjxF5xfbzBRcZEXjGkyFdEAF7rB78I8xIqii+n6Yt8uEURmd4geI9KWXRQnwofTz9pklaAnRbER8zy/BJIiIYy8zecUHJn9v/DPnsnksfL6RRmG4tHaRBDbpAag0kVkCrpO/flK6dZOl/wvoVVVqT2O69a9/RpHLSV2f//ZS6L9s6vaYe4pXL0M6QymgA22sNHaws6XggJlTxVOFGRejMGYrKqVWtC+2UNbnel+/J0N1qj4luWfQaf9+1j+fq7vyLSzXYFCiyOLAznpqOhzKu6VWy2IbR0UnCoL5ZbhIba9e2MXM7Czy9Yee4xc=,iv:M0GbtFFl1XUeq+y9H+MiD+9z/ASB9hsd06KhpPzSwEo=,tag:vTLIIf+CeZN6DU25CSP8tw==,type:str]", | 2 | "data": "ENC[AES256_GCM,data:7STcG1J3zLHzlHi2LZgSa+pmKlYU6X1eLvjXcx7gvCuHFkXwa/ldrHdzaBXAMrQ+C+DWM4+cyhdal3ypxXueBuBEvH3P7/KofPP2A519sdZo1vDkXCzYRD3Ow74M+hX5ej6hL1mv21HayrRMPnYfH8HUWk1kd/y69EjpjvDHyCpQuw1WG5M4FDUaTd4Vh51QRCSG/Is29dEkvQowhIvNqnAR4KW9PpfjlbUPHauZ6PQLnlJmI9QCcAGJ8hHtp5T+xctTym82GAlXugTJpHnkqcxnGteu9H7UuiDMQ3aKKGYzZCpWkNHrbD1IRhzPzSjVlN2nIX3Ydp8ENNf61EGOrp5hzmV0MhwRHKfz5rE1FRVuyHcwhwBdJzfhzrL9zXZYzn9Zuf9KWwsF+1+58i9u9hPym63r4c1+RbMjNKzHc1/yhhsRDCrTwvMd/Hc6KfUi3H1wW/r02Va2bOCkYrOkWIQpBdx4ThMgkTaHr94DBMqT8n3Fzhc7+uaUsl6I9gMwTn8QCV3g4U7Mp3+/gnQLOdsCTgKr69x1iPfp7jzzbC29MWhIk+2aig+iWRMVT0n4AWIxooc3cYnfOJNtCdJwKuPUl4xNlZ22NK3XQfxBURSw0pi5KyDO1wgTVRoRJMnXZyin3bZ10OU8QKBqLp22FXpG/+mHrm3Y6yLkqfIP5ry+b86Rb7nWJlxDTwTGSoGi8sJzwNb+H9ioG7LjaSmvr7V+2aSq0+72WopAkIFSBq/yIWX3J/rNZuia6jKMY/8bSLDJz3V/YuzeUJ5feUkOS4KW1J1UkaYd6XxZ9Y8szCS/B7Ocz0YiV8fHmOzZKRn8BTmmXUIoyxO07MmwQ1shYfiVCwXjdjq2f3/CZbXNVOPvhGBYOcutUztftu3H9DRDTKrVae1TnztCVSkBSk1o52uSj0r8t6f4l1r7UG1TviOnVLVh1/6iiJVQey0m8G6ugw22zxfhI0Uea/rB70i+2UuoxrmsOfg+TgnvKBuakEBifp4rx0S5wyz05RYXkBLJTIwi2fVGmulqjZuCQNQnI3cfPI+oGcykob9IQqdo/Dwd118hNPVAwdDHyaiGXGh8eu8N2OCLQxlGZDtkVUveaEasJaZ0WWWaK97FUeoNJfUnB7Y3lNjv5u2rzviZyk4=,iv:jT21FNnHod6btDlBa3UflK3au5VmcsABs5OTMXF6oFA=,tag:Oh8cOL+edT5Wp0I1L5+vwg==,type:str]", |
3 | "sops": { | 3 | "sops": { |
4 | "age": [ | 4 | "age": [ |
5 | { | 5 | { |
@@ -11,8 +11,8 @@ | |||
11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiRWFqSHNlY1IvMkkwaEto\ncHZHa2p1Y25SakFkS2JYMlRFcFhnZGY1dVRFCkxSWmxvcHZMampQKzdKRHI0ZVMx\nUTFtR0pHbzFaQ0xQUFA2ZERDSWpwS0UKLS0tIFBaSGczY3VWdy9TKzRDZWZ2SElY\nbVQ4dDNhQllmVmViWGs5c3V4TmNscjQKeugevQJFAN/8JrzeAm4hm2JsQGb26BCb\n3dKYnN1kJU7oVHr1aVfXwMpELNYt9poX6WTY2h9lsdHuRlqoFXAA5Q==\n-----END AGE ENCRYPTED FILE-----\n" | 11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiRWFqSHNlY1IvMkkwaEto\ncHZHa2p1Y25SakFkS2JYMlRFcFhnZGY1dVRFCkxSWmxvcHZMampQKzdKRHI0ZVMx\nUTFtR0pHbzFaQ0xQUFA2ZERDSWpwS0UKLS0tIFBaSGczY3VWdy9TKzRDZWZ2SElY\nbVQ4dDNhQllmVmViWGs5c3V4TmNscjQKeugevQJFAN/8JrzeAm4hm2JsQGb26BCb\n3dKYnN1kJU7oVHr1aVfXwMpELNYt9poX6WTY2h9lsdHuRlqoFXAA5Q==\n-----END AGE ENCRYPTED FILE-----\n" |
12 | } | 12 | } |
13 | ], | 13 | ], |
14 | "lastmodified": "2025-05-10T10:25:15Z", | 14 | "lastmodified": "2025-08-11T07:08:36Z", |
15 | "mac": "ENC[AES256_GCM,data:dhj7e+vF3uiR6I22PR5tdNdM8EyrWmGGTIqjj8H7IdNIsZBHzjeHlBDFOwN7z/JMO0BVwIi4DmhApg2BSPGsQZGDQZ28UTCC8TDtd1zmfGtSP8R8AFHADYdLK/desMtHg6BZTnLv5tpba34WWdflMNOQpwgWPZsIk/DkLaoXdvk=,iv:qkoAZngTz2sfWdxDs+h8Mb2IrkF8gqnQoR5iRoeKjbY=,tag:zXrkBJmPM4ItJxMnX8IDxQ==,type:str]", | 15 | "mac": "ENC[AES256_GCM,data:ZL/dOz+NC8sr8vPBsux+gFOWxUhQqMSmG1az7udhB0ckmOXtnrPBzMM1gs+5pwXLvfLux0m4xzT87+o87axIECnCq35FSuMjtEBK24OUJXsLG/q/tDv5dfRBy/976dM5W7YkBVX/uc03p8CLKf5w4XYNeRKnSwjLvWGd9runDOU=,iv:9ZIeJ5aDVVPHi3/oHqWkWtEfeivV/nFFyQ1lJWJwMu8=,tag:TfkHaopMa+Z0zk38A6/NTA==,type:str]", |
16 | "unencrypted_suffix": "_unencrypted", | 16 | "unencrypted_suffix": "_unencrypted", |
17 | "version": "3.10.2" | 17 | "version": "3.10.2" |
18 | } | 18 | } |
diff --git a/hosts/vidhar/default.nix b/hosts/vidhar/default.nix index 7da17e6f..547572c6 100644 --- a/hosts/vidhar/default.nix +++ b/hosts/vidhar/default.nix | |||
@@ -136,7 +136,7 @@ with lib; | |||
136 | wantedBy = ["basic.target"]; | 136 | wantedBy = ["basic.target"]; |
137 | serviceConfig = { | 137 | serviceConfig = { |
138 | ExecStart = pkgs.writeShellScript "limit-pstate-start" '' | 138 | ExecStart = pkgs.writeShellScript "limit-pstate-start" '' |
139 | echo 50 > /sys/devices/system/cpu/intel_pstate/max_perf_pct | 139 | echo 40 > /sys/devices/system/cpu/intel_pstate/max_perf_pct |
140 | ''; | 140 | ''; |
141 | RemainAfterExit = true; | 141 | RemainAfterExit = true; |
142 | ExecStop = pkgs.writeShellScript "limit-pstate-stop" '' | 142 | ExecStop = pkgs.writeShellScript "limit-pstate-stop" '' |
diff --git a/lib/pythonSet.nix b/lib/pythonSet.nix index 9dfb25ff..c69216cc 100644 --- a/lib/pythonSet.nix +++ b/lib/pythonSet.nix | |||
@@ -23,6 +23,20 @@ | |||
23 | (final.resolveBuildSystem { setuptools = []; }) | 23 | (final.resolveBuildSystem { setuptools = []; }) |
24 | ]; | 24 | ]; |
25 | }); | 25 | }); |
26 | halo = (prev.halo.override { | ||
27 | sourcePreference = "sdist"; | ||
28 | }).overrideAttrs (oldAttrs: { | ||
29 | nativeBuildInputs = (oldAttrs.nativeBuildInputs or []) ++ [ | ||
30 | (final.resolveBuildSystem { setuptools = []; }) | ||
31 | ]; | ||
32 | }); | ||
33 | unshare = (prev.unshare.override { | ||
34 | sourcePreference = "sdist"; | ||
35 | }).overrideAttrs (oldAttrs: { | ||
36 | nativeBuildInputs = (oldAttrs.nativeBuildInputs or []) ++ [ | ||
37 | (final.resolveBuildSystem { setuptools = []; }) | ||
38 | ]; | ||
39 | }); | ||
26 | }) | 40 | }) |
27 | ] | 41 | ] |
28 | ) | 42 | ) |
diff --git a/modules/abs-podcast-autoplaylist.nix b/modules/abs-podcast-autoplaylist.nix index 2532cfc3..f526a434 100644 --- a/modules/abs-podcast-autoplaylist.nix +++ b/modules/abs-podcast-autoplaylist.nix | |||
@@ -37,6 +37,7 @@ in { | |||
37 | PrivateDevices = true; | 37 | PrivateDevices = true; |
38 | Type = "oneshot"; | 38 | Type = "oneshot"; |
39 | ExecStart = "${lib.getExe pkgs.abs-podcast-autoplaylist} %I.toml"; | 39 | ExecStart = "${lib.getExe pkgs.abs-podcast-autoplaylist} %I.toml"; |
40 | TimeoutSec = "5min"; | ||
40 | }; | 41 | }; |
41 | }; | 42 | }; |
42 | } // lib.mapAttrs' (name: { configSecret, ... }: lib.nameValuePair "abs-podcast-autoplaylist@${utils.escapeSystemdPath name}" { | 43 | } // lib.mapAttrs' (name: { configSecret, ... }: lib.nameValuePair "abs-podcast-autoplaylist@${utils.escapeSystemdPath name}" { |
diff --git a/modules/borgcopy/.envrc b/modules/borgcopy/.envrc new file mode 100644 index 00000000..01e755c1 --- /dev/null +++ b/modules/borgcopy/.envrc | |||
@@ -0,0 +1,4 @@ | |||
1 | use flake | ||
2 | |||
3 | uv venv && uv sync | ||
4 | . .venv/bin/activate | ||
diff --git a/modules/borgcopy/.gitignore b/modules/borgcopy/.gitignore new file mode 100644 index 00000000..4ccfae70 --- /dev/null +++ b/modules/borgcopy/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | .venv | ||
2 | **/__pycache__ | ||
diff --git a/modules/borgcopy/default.nix b/modules/borgcopy/default.nix index 8e1afc27..af021777 100644 --- a/modules/borgcopy/default.nix +++ b/modules/borgcopy/default.nix | |||
@@ -1,25 +1,32 @@ | |||
1 | { config, pkgs, lib, utils, flakeInputs, ... }: | 1 | { config, pkgs, lib, utils, flake, flakeInputs, ... }: |
2 | 2 | ||
3 | with lib; | 3 | with lib; |
4 | 4 | ||
5 | let | 5 | let |
6 | copyBorg = | 6 | copyBorg = let |
7 | with pkgs.poetry2nix; | 7 | workspace = flakeInputs.uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; }; |
8 | mkPoetryApplication { | 8 | pythonSet = flake.lib.pythonSet { |
9 | projectDir = cleanPythonSources { src = ./.; }; | 9 | inherit pkgs; |
10 | python = pkgs.python312; | ||
11 | overlay = workspace.mkPyprojectOverlay { | ||
12 | sourcePreference = "wheel"; | ||
13 | }; | ||
14 | }; | ||
15 | virtualEnv = pythonSet.mkVirtualEnv "copy_borg" workspace.deps.default; | ||
16 | in virtualEnv.overrideAttrs (oldAttrs: { | ||
17 | meta = (oldAttrs.meta or {}) // { | ||
18 | mainProgram = "copy_borg"; | ||
19 | }; | ||
10 | 20 | ||
11 | overrides = overrides.withDefaults (self: super: { | 21 | nativeBuildInputs = (oldAttrs.nativeBuildInputs or []) ++ [ pkgs.makeWrapper ]; |
12 | pyprctl = super.pyprctl.overridePythonAttrs (oldAttrs: { | ||
13 | buildInputs = (oldAttrs.buildInputs or []) ++ [super.setuptools]; | ||
14 | }); | ||
15 | inherit (pkgs.python3Packages) python-unshare; | ||
16 | }); | ||
17 | 22 | ||
18 | postInstall = '' | 23 | postInstall = '' |
19 | wrapProgram $out/bin/copy_borg \ | 24 | ${oldAttrs.postInstall or ""} |
20 | --prefix PATH : ${makeBinPath (with pkgs; [util-linux borgbackup])}:${config.security.wrapperDir} | 25 | |
21 | ''; | 26 | wrapProgram $out/bin/copy_borg \ |
22 | }; | 27 | --prefix PATH : ${makeBinPath (with pkgs; [util-linux borgbackup])}:${config.security.wrapperDir} |
28 | ''; | ||
29 | }); | ||
23 | 30 | ||
24 | copyService = name: opts: nameValuePair "copy-borg@${utils.escapeSystemdPath name}" { | 31 | copyService = name: opts: nameValuePair "copy-borg@${utils.escapeSystemdPath name}" { |
25 | restartIfChanged = false; | 32 | restartIfChanged = false; |
diff --git a/modules/borgcopy/poetry.lock b/modules/borgcopy/poetry.lock deleted file mode 100644 index 759ecfe9..00000000 --- a/modules/borgcopy/poetry.lock +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | # This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. | ||
2 | |||
3 | [[package]] | ||
4 | name = "colorama" | ||
5 | version = "0.4.6" | ||
6 | description = "Cross-platform colored terminal text." | ||
7 | category = "main" | ||
8 | optional = false | ||
9 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" | ||
10 | files = [ | ||
11 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, | ||
12 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, | ||
13 | ] | ||
14 | |||
15 | [[package]] | ||
16 | name = "halo" | ||
17 | version = "0.0.31" | ||
18 | description = "Beautiful terminal spinners in Python" | ||
19 | category = "main" | ||
20 | optional = false | ||
21 | python-versions = ">=3.4" | ||
22 | files = [ | ||
23 | {file = "halo-0.0.31-py2-none-any.whl", hash = "sha256:5350488fb7d2aa7c31a1344120cee67a872901ce8858f60da7946cef96c208ab"}, | ||
24 | {file = "halo-0.0.31.tar.gz", hash = "sha256:7b67a3521ee91d53b7152d4ee3452811e1d2a6321975137762eb3d70063cc9d6"}, | ||
25 | ] | ||
26 | |||
27 | [package.dependencies] | ||
28 | colorama = ">=0.3.9" | ||
29 | log-symbols = ">=0.0.14" | ||
30 | six = ">=1.12.0" | ||
31 | spinners = ">=0.0.24" | ||
32 | termcolor = ">=1.1.0" | ||
33 | |||
34 | [package.extras] | ||
35 | ipython = ["IPython (==5.7.0)", "ipywidgets (==7.1.0)"] | ||
36 | |||
37 | [[package]] | ||
38 | name = "humanize" | ||
39 | version = "4.6.0" | ||
40 | description = "Python humanize utilities" | ||
41 | category = "main" | ||
42 | optional = false | ||
43 | python-versions = ">=3.7" | ||
44 | files = [ | ||
45 | {file = "humanize-4.6.0-py3-none-any.whl", hash = "sha256:401201aca462749773f02920139f302450cb548b70489b9b4b92be39fe3c3c50"}, | ||
46 | {file = "humanize-4.6.0.tar.gz", hash = "sha256:5f1f22bc65911eb1a6ffe7659bd6598e33dcfeeb904eb16ee1e705a09bf75916"}, | ||
47 | ] | ||
48 | |||
49 | [package.extras] | ||
50 | tests = ["freezegun", "pytest", "pytest-cov"] | ||
51 | |||
52 | [[package]] | ||
53 | name = "log-symbols" | ||
54 | version = "0.0.14" | ||
55 | description = "Colored symbols for various log levels for Python" | ||
56 | category = "main" | ||
57 | optional = false | ||
58 | python-versions = "*" | ||
59 | files = [ | ||
60 | {file = "log_symbols-0.0.14-py3-none-any.whl", hash = "sha256:4952106ff8b605ab7d5081dd2c7e6ca7374584eff7086f499c06edd1ce56dcca"}, | ||
61 | {file = "log_symbols-0.0.14.tar.gz", hash = "sha256:cf0bbc6fe1a8e53f0d174a716bc625c4f87043cc21eb55dd8a740cfe22680556"}, | ||
62 | ] | ||
63 | |||
64 | [package.dependencies] | ||
65 | colorama = ">=0.3.9" | ||
66 | |||
67 | [[package]] | ||
68 | name = "pyprctl" | ||
69 | version = "0.1.3" | ||
70 | description = "An interface to Linux's prctl() syscall written in pure Python using ctypes." | ||
71 | category = "main" | ||
72 | optional = false | ||
73 | python-versions = ">=3.6" | ||
74 | files = [ | ||
75 | {file = "pyprctl-0.1.3-py3-none-any.whl", hash = "sha256:6302e5114f078fb33e5799835d0a69e2fc180bb6b28ad073515fa40c5272f1dd"}, | ||
76 | {file = "pyprctl-0.1.3.tar.gz", hash = "sha256:1fb54d3ab030ec02e4afc38fb9662d6634c12834e91ae7959de56a9c09f69c26"}, | ||
77 | ] | ||
78 | |||
79 | [[package]] | ||
80 | name = "python-dateutil" | ||
81 | version = "2.8.2" | ||
82 | description = "Extensions to the standard Python datetime module" | ||
83 | category = "main" | ||
84 | optional = false | ||
85 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" | ||
86 | files = [ | ||
87 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, | ||
88 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, | ||
89 | ] | ||
90 | |||
91 | [package.dependencies] | ||
92 | six = ">=1.5" | ||
93 | |||
94 | [[package]] | ||
95 | name = "python-unshare" | ||
96 | version = "0.2" | ||
97 | description = "Python bindings for the Linux unshare() syscall" | ||
98 | category = "main" | ||
99 | optional = false | ||
100 | python-versions = "*" | ||
101 | files = [ | ||
102 | {file = "python-unshare-0.2.tar.gz", hash = "sha256:f79b7de441b6c27930b775085a6a4fd2f378b628737aaaebc2a6c519023fd47a"}, | ||
103 | ] | ||
104 | |||
105 | [[package]] | ||
106 | name = "six" | ||
107 | version = "1.16.0" | ||
108 | description = "Python 2 and 3 compatibility utilities" | ||
109 | category = "main" | ||
110 | optional = false | ||
111 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" | ||
112 | files = [ | ||
113 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, | ||
114 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, | ||
115 | ] | ||
116 | |||
117 | [[package]] | ||
118 | name = "spinners" | ||
119 | version = "0.0.24" | ||
120 | description = "Spinners for terminals" | ||
121 | category = "main" | ||
122 | optional = false | ||
123 | python-versions = "*" | ||
124 | files = [ | ||
125 | {file = "spinners-0.0.24-py3-none-any.whl", hash = "sha256:2fa30d0b72c9650ad12bbe031c9943b8d441e41b4f5602b0ec977a19f3290e98"}, | ||
126 | {file = "spinners-0.0.24.tar.gz", hash = "sha256:1eb6aeb4781d72ab42ed8a01dcf20f3002bf50740d7154d12fb8c9769bf9e27f"}, | ||
127 | ] | ||
128 | |||
129 | [[package]] | ||
130 | name = "termcolor" | ||
131 | version = "2.2.0" | ||
132 | description = "ANSI color formatting for output in terminal" | ||
133 | category = "main" | ||
134 | optional = false | ||
135 | python-versions = ">=3.7" | ||
136 | files = [ | ||
137 | {file = "termcolor-2.2.0-py3-none-any.whl", hash = "sha256:91ddd848e7251200eac969846cbae2dacd7d71c2871e92733289e7e3666f48e7"}, | ||
138 | {file = "termcolor-2.2.0.tar.gz", hash = "sha256:dfc8ac3f350788f23b2947b3e6cfa5a53b630b612e6cd8965a015a776020b99a"}, | ||
139 | ] | ||
140 | |||
141 | [package.extras] | ||
142 | tests = ["pytest", "pytest-cov"] | ||
143 | |||
144 | [[package]] | ||
145 | name = "tqdm" | ||
146 | version = "4.65.0" | ||
147 | description = "Fast, Extensible Progress Meter" | ||
148 | category = "main" | ||
149 | optional = false | ||
150 | python-versions = ">=3.7" | ||
151 | files = [ | ||
152 | {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, | ||
153 | {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, | ||
154 | ] | ||
155 | |||
156 | [package.dependencies] | ||
157 | colorama = {version = "*", markers = "platform_system == \"Windows\""} | ||
158 | |||
159 | [package.extras] | ||
160 | dev = ["py-make (>=0.1.0)", "twine", "wheel"] | ||
161 | notebook = ["ipywidgets (>=6)"] | ||
162 | slack = ["slack-sdk"] | ||
163 | telegram = ["requests"] | ||
164 | |||
165 | [[package]] | ||
166 | name = "xdg" | ||
167 | version = "6.0.0" | ||
168 | description = "Variables defined by the XDG Base Directory Specification" | ||
169 | category = "main" | ||
170 | optional = false | ||
171 | python-versions = ">=3.7,<4.0" | ||
172 | files = [ | ||
173 | {file = "xdg-6.0.0-py3-none-any.whl", hash = "sha256:df3510755b4395157fc04fc3b02467c777f3b3ca383257397f09ab0d4c16f936"}, | ||
174 | {file = "xdg-6.0.0.tar.gz", hash = "sha256:24278094f2d45e846d1eb28a2ebb92d7b67fc0cab5249ee3ce88c95f649a1c92"}, | ||
175 | ] | ||
176 | |||
177 | [metadata] | ||
178 | lock-version = "2.0" | ||
179 | python-versions = ">=3.10.0,<3.12" | ||
180 | content-hash = "3c6b538852447a8f3ae34e1be122716d47e669a2b44f7c5d3d850e5d877353c7" | ||
diff --git a/modules/borgcopy/pyproject.toml b/modules/borgcopy/pyproject.toml index f3401ed2..d76d73c6 100644 --- a/modules/borgcopy/pyproject.toml +++ b/modules/borgcopy/pyproject.toml | |||
@@ -1,22 +1,25 @@ | |||
1 | [tool.poetry] | 1 | [project] |
2 | name = "copy_borg" | 2 | name = "copy_borg" |
3 | version = "0.0.0" | 3 | version = "0.0.0" |
4 | authors = ["Gregor Kleen <gkleen@yggdrasil.li>"] | ||
5 | description = "" | 4 | description = "" |
5 | authors = [{ name = "Gregor Kleen", email = "gkleen@yggdrasil.li" }] | ||
6 | requires-python = "~=3.12" | ||
7 | dependencies = [ | ||
8 | "humanize>=4.6.0,<5", | ||
9 | "tqdm>=4.65.0,<5", | ||
10 | "python-dateutil>=2.8.2,<3", | ||
11 | "xdg>=6.0.0,<7", | ||
12 | "pyprctl>=0.1.3,<0.2", | ||
13 | "halo>=0.0.31,<0.0.32", | ||
14 | "unshare>=0.22", | ||
15 | ] | ||
6 | 16 | ||
7 | [tool.poetry.scripts] | 17 | [project.scripts] |
8 | copy_borg = "copy_borg.__main__:main" | 18 | copy_borg = "copy_borg.__main__:main" |
9 | 19 | ||
10 | [tool.poetry.dependencies] | ||
11 | python = ">=3.10.0,<3.12" | ||
12 | humanize = "^4.6.0" | ||
13 | tqdm = "^4.65.0" | ||
14 | python-dateutil = "^2.8.2" | ||
15 | xdg = "^6.0.0" | ||
16 | python-unshare = "^0.2" | ||
17 | pyprctl = "^0.1.3" | ||
18 | halo = "^0.0.31" | ||
19 | |||
20 | [build-system] | 20 | [build-system] |
21 | requires = ["poetry-core>=1.0.0"] | 21 | requires = ["hatchling"] |
22 | build-backend = "poetry.core.masonry.api" \ No newline at end of file | 22 | build-backend = "hatchling.build" |
23 | |||
24 | [tool.hatch.build.targets.wheel] | ||
25 | packages = ["copy_borg"] | ||
diff --git a/modules/borgcopy/uv.lock b/modules/borgcopy/uv.lock new file mode 100644 index 00000000..1a282598 --- /dev/null +++ b/modules/borgcopy/uv.lock | |||
@@ -0,0 +1,146 @@ | |||
1 | version = 1 | ||
2 | revision = 2 | ||
3 | requires-python = ">=3.12, <4" | ||
4 | |||
5 | [[package]] | ||
6 | name = "colorama" | ||
7 | version = "0.4.6" | ||
8 | source = { registry = "https://pypi.org/simple" } | ||
9 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } | ||
10 | wheels = [ | ||
11 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, | ||
12 | ] | ||
13 | |||
14 | [[package]] | ||
15 | name = "copy-borg" | ||
16 | version = "0.0.0" | ||
17 | source = { editable = "." } | ||
18 | dependencies = [ | ||
19 | { name = "halo" }, | ||
20 | { name = "humanize" }, | ||
21 | { name = "pyprctl" }, | ||
22 | { name = "python-dateutil" }, | ||
23 | { name = "tqdm" }, | ||
24 | { name = "unshare" }, | ||
25 | { name = "xdg" }, | ||
26 | ] | ||
27 | |||
28 | [package.metadata] | ||
29 | requires-dist = [ | ||
30 | { name = "halo", specifier = ">=0.0.31,<0.0.32" }, | ||
31 | { name = "humanize", specifier = ">=4.6.0,<5" }, | ||
32 | { name = "pyprctl", specifier = ">=0.1.3,<0.2" }, | ||
33 | { name = "python-dateutil", specifier = ">=2.8.2,<3" }, | ||
34 | { name = "tqdm", specifier = ">=4.65.0,<5" }, | ||
35 | { name = "unshare", specifier = ">=0.22" }, | ||
36 | { name = "xdg", specifier = ">=6.0.0,<7" }, | ||
37 | ] | ||
38 | |||
39 | [[package]] | ||
40 | name = "halo" | ||
41 | version = "0.0.31" | ||
42 | source = { registry = "https://pypi.org/simple" } | ||
43 | dependencies = [ | ||
44 | { name = "colorama" }, | ||
45 | { name = "log-symbols" }, | ||
46 | { name = "six" }, | ||
47 | { name = "spinners" }, | ||
48 | { name = "termcolor" }, | ||
49 | ] | ||
50 | sdist = { url = "https://files.pythonhosted.org/packages/ee/48/d53580d30b1fabf25d0d1fcc3f5b26d08d2ac75a1890ff6d262f9f027436/halo-0.0.31.tar.gz", hash = "sha256:7b67a3521ee91d53b7152d4ee3452811e1d2a6321975137762eb3d70063cc9d6", size = 11666, upload-time = "2020-11-10T02:36:48.335Z" } | ||
51 | |||
52 | [[package]] | ||
53 | name = "humanize" | ||
54 | version = "4.12.3" | ||
55 | source = { registry = "https://pypi.org/simple" } | ||
56 | sdist = { url = "https://files.pythonhosted.org/packages/22/d1/bbc4d251187a43f69844f7fd8941426549bbe4723e8ff0a7441796b0789f/humanize-4.12.3.tar.gz", hash = "sha256:8430be3a615106fdfceb0b2c1b41c4c98c6b0fc5cc59663a5539b111dd325fb0", size = 80514, upload-time = "2025-04-30T11:51:07.98Z" } | ||
57 | wheels = [ | ||
58 | { url = "https://files.pythonhosted.org/packages/a0/1e/62a2ec3104394a2975a2629eec89276ede9dbe717092f6966fcf963e1bf0/humanize-4.12.3-py3-none-any.whl", hash = "sha256:2cbf6370af06568fa6d2da77c86edb7886f3160ecd19ee1ffef07979efc597f6", size = 128487, upload-time = "2025-04-30T11:51:06.468Z" }, | ||
59 | ] | ||
60 | |||
61 | [[package]] | ||
62 | name = "log-symbols" | ||
63 | version = "0.0.14" | ||
64 | source = { registry = "https://pypi.org/simple" } | ||
65 | dependencies = [ | ||
66 | { name = "colorama" }, | ||
67 | ] | ||
68 | sdist = { url = "https://files.pythonhosted.org/packages/45/87/e86645d758a4401c8c81914b6a88470634d1785c9ad09823fa4a1bd89250/log_symbols-0.0.14.tar.gz", hash = "sha256:cf0bbc6fe1a8e53f0d174a716bc625c4f87043cc21eb55dd8a740cfe22680556", size = 3211, upload-time = "2019-08-08T06:32:22.538Z" } | ||
69 | wheels = [ | ||
70 | { url = "https://files.pythonhosted.org/packages/28/5d/d710c38be68b0fb54e645048fe359c3904cc3cb64b2de9d40e1712bf110c/log_symbols-0.0.14-py3-none-any.whl", hash = "sha256:4952106ff8b605ab7d5081dd2c7e6ca7374584eff7086f499c06edd1ce56dcca", size = 3081, upload-time = "2019-08-08T06:32:20.604Z" }, | ||
71 | ] | ||
72 | |||
73 | [[package]] | ||
74 | name = "pyprctl" | ||
75 | version = "0.1.3" | ||
76 | source = { registry = "https://pypi.org/simple" } | ||
77 | sdist = { url = "https://files.pythonhosted.org/packages/c9/16/6ed71ebcad76c1cd5f22185bcc6b31c0ee62fc5e693b626febea8fedeba3/pyprctl-0.1.3.tar.gz", hash = "sha256:1fb54d3ab030ec02e4afc38fb9662d6634c12834e91ae7959de56a9c09f69c26", size = 18739, upload-time = "2021-10-26T23:52:03.87Z" } | ||
78 | wheels = [ | ||
79 | { url = "https://files.pythonhosted.org/packages/bf/5e/62765de39bbce8111fb1f4453a4a804913bf49179fa265fb713ed66c9d15/pyprctl-0.1.3-py3-none-any.whl", hash = "sha256:6302e5114f078fb33e5799835d0a69e2fc180bb6b28ad073515fa40c5272f1dd", size = 20016, upload-time = "2021-10-26T23:52:02.986Z" }, | ||
80 | ] | ||
81 | |||
82 | [[package]] | ||
83 | name = "python-dateutil" | ||
84 | version = "2.9.0.post0" | ||
85 | source = { registry = "https://pypi.org/simple" } | ||
86 | dependencies = [ | ||
87 | { name = "six" }, | ||
88 | ] | ||
89 | sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } | ||
90 | wheels = [ | ||
91 | { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, | ||
92 | ] | ||
93 | |||
94 | [[package]] | ||
95 | name = "six" | ||
96 | version = "1.17.0" | ||
97 | source = { registry = "https://pypi.org/simple" } | ||
98 | sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } | ||
99 | wheels = [ | ||
100 | { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, | ||
101 | ] | ||
102 | |||
103 | [[package]] | ||
104 | name = "spinners" | ||
105 | version = "0.0.24" | ||
106 | source = { registry = "https://pypi.org/simple" } | ||
107 | sdist = { url = "https://files.pythonhosted.org/packages/d3/91/bb331f0a43e04d950a710f402a0986a54147a35818df0e1658551c8d12e1/spinners-0.0.24.tar.gz", hash = "sha256:1eb6aeb4781d72ab42ed8a01dcf20f3002bf50740d7154d12fb8c9769bf9e27f", size = 5308, upload-time = "2020-02-19T21:42:32.326Z" } | ||
108 | wheels = [ | ||
109 | { url = "https://files.pythonhosted.org/packages/9f/8e/3310207a68118000ca27ac878b8386123628b335ecb3d4bec4743357f0d1/spinners-0.0.24-py3-none-any.whl", hash = "sha256:2fa30d0b72c9650ad12bbe031c9943b8d441e41b4f5602b0ec977a19f3290e98", size = 5499, upload-time = "2020-02-19T21:42:30.876Z" }, | ||
110 | ] | ||
111 | |||
112 | [[package]] | ||
113 | name = "termcolor" | ||
114 | version = "3.1.0" | ||
115 | source = { registry = "https://pypi.org/simple" } | ||
116 | sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324, upload-time = "2025-04-30T11:37:53.791Z" } | ||
117 | wheels = [ | ||
118 | { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684, upload-time = "2025-04-30T11:37:52.382Z" }, | ||
119 | ] | ||
120 | |||
121 | [[package]] | ||
122 | name = "tqdm" | ||
123 | version = "4.67.1" | ||
124 | source = { registry = "https://pypi.org/simple" } | ||
125 | dependencies = [ | ||
126 | { name = "colorama", marker = "sys_platform == 'win32'" }, | ||
127 | ] | ||
128 | sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } | ||
129 | wheels = [ | ||
130 | { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, | ||
131 | ] | ||
132 | |||
133 | [[package]] | ||
134 | name = "unshare" | ||
135 | version = "0.22" | ||
136 | source = { registry = "https://pypi.org/simple" } | ||
137 | sdist = { url = "https://files.pythonhosted.org/packages/15/85/2ba218129c95b894efe87506489b525f859c40f6e21cb0521ff3cec754f4/unshare-0.22.tar.gz", hash = "sha256:d521d72cca6e876f22cbd5ff5eb51f1beef75e8f9c53b599b55fa05fba1dd3a6", size = 2041, upload-time = "2019-10-17T12:58:31.498Z" } | ||
138 | |||
139 | [[package]] | ||
140 | name = "xdg" | ||
141 | version = "6.0.0" | ||
142 | source = { registry = "https://pypi.org/simple" } | ||
143 | sdist = { url = "https://files.pythonhosted.org/packages/2a/b9/0e6e6f19fb75cf5e1758f4f33c1256738f718966700cffc0fde2f966218b/xdg-6.0.0.tar.gz", hash = "sha256:24278094f2d45e846d1eb28a2ebb92d7b67fc0cab5249ee3ce88c95f649a1c92", size = 3453, upload-time = "2023-02-27T19:27:44.309Z" } | ||
144 | wheels = [ | ||
145 | { url = "https://files.pythonhosted.org/packages/dd/54/3516c1cf349060fc3578686d271eba242f10ec00b4530c2985af9faac49b/xdg-6.0.0-py3-none-any.whl", hash = "sha256:df3510755b4395157fc04fc3b02467c777f3b3ca383257397f09ab0d4c16f936", size = 3855, upload-time = "2023-02-27T19:27:42.151Z" }, | ||
146 | ] | ||
diff --git a/modules/impermanence-timezone.nix b/modules/impermanence-timezone.nix new file mode 100644 index 00000000..a1edbfa5 --- /dev/null +++ b/modules/impermanence-timezone.nix | |||
@@ -0,0 +1,41 @@ | |||
1 | { config, lib, utils, pkgs, ... }: | ||
2 | |||
3 | { | ||
4 | options = { | ||
5 | environment.persistence = lib.mkOption { | ||
6 | type = lib.types.attrsOf (lib.types.submodule { | ||
7 | options = { | ||
8 | timezone = lib.mkEnableOption "storing system timezone"; | ||
9 | }; | ||
10 | }); | ||
11 | }; | ||
12 | }; | ||
13 | |||
14 | config = { | ||
15 | systemd = lib.mkMerge (lib.mapAttrsToList (name: cfg: lib.mkIf cfg.timezone { | ||
16 | services = { | ||
17 | "timezone@${utils.escapeSystemdPath name}" = { | ||
18 | wantedBy = [ "multi-user.target" ]; | ||
19 | serviceConfig = { | ||
20 | Type = "oneshot"; | ||
21 | RemainAfterExit = true; | ||
22 | ExecStart = "${pkgs.coreutils}/bin/cp -vP ${utils.escapeSystemdExecArg "${name}/etc/localtime"} /etc/localtime"; | ||
23 | ExecStop = "${pkgs.coreutils}/bin/cp -vP /etc/localtime ${utils.escapeSystemdExecArg "${name}/etc/localtime"}"; | ||
24 | }; | ||
25 | }; | ||
26 | "etc-localtime@${utils.escapeSystemdPath name}" = { | ||
27 | serviceConfig = { | ||
28 | Type = "oneshot"; | ||
29 | ExecStart = "${pkgs.coreutils}/bin/cp -vP /etc/localtime ${utils.escapeSystemdExecArg "${name}/etc/localtime"}"; | ||
30 | }; | ||
31 | }; | ||
32 | }; | ||
33 | paths."etc-localtime@${utils.escapeSystemdPath name}" = { | ||
34 | wantedBy = [ "timezone@${utils.escapeSystemdPath name}.service" ]; | ||
35 | after = [ "timezone@${utils.escapeSystemdPath name}.service" ]; | ||
36 | |||
37 | pathConfig.PathChanged = "/etc/localtime"; | ||
38 | }; | ||
39 | }) config.environment.persistence); | ||
40 | }; | ||
41 | } | ||
diff --git a/modules/impermanence.nix b/modules/impermanence.nix new file mode 100644 index 00000000..621576a3 --- /dev/null +++ b/modules/impermanence.nix | |||
@@ -0,0 +1,6 @@ | |||
1 | { flakeInputs, ... }: | ||
2 | { | ||
3 | imports = [ | ||
4 | flakeInputs.impermanence.nixosModules.impermanence | ||
5 | ]; | ||
6 | } | ||
diff --git a/modules/postsrsd.nix b/modules/postsrsd.nix index 205e669d..bc941e3e 100644 --- a/modules/postsrsd.nix +++ b/modules/postsrsd.nix | |||
@@ -101,6 +101,12 @@ in | |||
101 | type = lib.types.lines; | 101 | type = lib.types.lines; |
102 | default = ""; | 102 | default = ""; |
103 | }; | 103 | }; |
104 | |||
105 | configurePostfix = lib.mkOption { | ||
106 | type = lib.types.bool; | ||
107 | default = false; | ||
108 | description = "noop"; | ||
109 | }; | ||
104 | }; | 110 | }; |
105 | }; | 111 | }; |
106 | 112 | ||
diff --git a/modules/uucp.nix b/modules/uucp.nix deleted file mode 100644 index 10f7297b..00000000 --- a/modules/uucp.nix +++ /dev/null | |||
@@ -1,373 +0,0 @@ | |||
1 | { flake, config, lib, pkgs, ... }: | ||
2 | |||
3 | with lib; | ||
4 | |||
5 | let | ||
6 | portSpec = name: node: concatStringsSep "\n" (map (port: '' | ||
7 | port ${name}.${port} | ||
8 | type pipe | ||
9 | protocol ${node.protocols} | ||
10 | reliable true | ||
11 | command ${pkgs.openssh}/bin/ssh -x -o batchmode=yes ${name}.${port} | ||
12 | '') node.hostnames); | ||
13 | sysSpec = name: node: '' | ||
14 | system ${name} | ||
15 | time any | ||
16 | chat-seven-bit false | ||
17 | chat . "" | ||
18 | protocol ${node.protocols} | ||
19 | command-path ${concatStringsSep " " cfg.commandPath} | ||
20 | commands ${concatStringsSep " " node.commands} | ||
21 | ${concatStringsSep "\nalternate\n" (map (port: '' | ||
22 | port ${name}.${port} | ||
23 | '') node.hostnames)} | ||
24 | ''; | ||
25 | sshConfig = name: node: concatStringsSep "\n" (map (port: '' | ||
26 | Host ${name}.${port} | ||
27 | Hostname ${port} | ||
28 | IdentitiesOnly Yes | ||
29 | IdentityFile ${cfg.sshKeyDir}/${name} | ||
30 | '') node.hostnames); | ||
31 | sshKeyGen = name: node: '' | ||
32 | if [[ ! -e ${cfg.sshKeyDir}/${name} ]]; then | ||
33 | ${pkgs.openssh}/bin/ssh-keygen ${escapeShellArgs node.generateKey} -f ${cfg.sshKeyDir}/${name} | ||
34 | fi | ||
35 | ''; | ||
36 | restrictKey = key: '' | ||
37 | restrict,command="${chat}" ${key} | ||
38 | ''; | ||
39 | chat = pkgs.writeScript "chat" '' | ||
40 | #!${pkgs.stdenv.shell} | ||
41 | |||
42 | echo . | ||
43 | exec ${config.security.wrapperDir}/uucico | ||
44 | ''; | ||
45 | |||
46 | nodeCfg = { | ||
47 | options = { | ||
48 | commands = mkOption { | ||
49 | type = types.listOf types.str; | ||
50 | default = cfg.defaultCommands; | ||
51 | defaultText = literalExpression "config.services.uucp.defaultCommands"; | ||
52 | description = "Commands to allow for this remote"; | ||
53 | }; | ||
54 | |||
55 | protocols = mkOption { | ||
56 | type = types.separatedString ""; | ||
57 | default = cfg.defaultProtocols; | ||
58 | defaultText = literalExpression "config.services.uucp.defaultProtocols"; | ||
59 | description = "UUCP protocols to use for this remote"; | ||
60 | }; | ||
61 | |||
62 | publicKeys = mkOption { | ||
63 | type = types.listOf types.str; | ||
64 | default = []; | ||
65 | description = "SSH client public keys for this node"; | ||
66 | }; | ||
67 | |||
68 | generateKey = mkOption { | ||
69 | type = types.listOf types.str; | ||
70 | default = [ "-t" "ed25519" "-N" "" ]; | ||
71 | description = "Arguments to pass to `ssh-keygen` to generate a keypair for communication with this host"; | ||
72 | }; | ||
73 | |||
74 | hostnames = mkOption { | ||
75 | type = types.listOf types.str; | ||
76 | default = []; | ||
77 | description = "Hostnames to try in order when connecting"; | ||
78 | }; | ||
79 | }; | ||
80 | }; | ||
81 | |||
82 | cfg = config.services.uucp; | ||
83 | in { | ||
84 | options = { | ||
85 | services.uucp = { | ||
86 | enable = mkOption { | ||
87 | type = types.bool; | ||
88 | default = false; | ||
89 | description = '' | ||
90 | If enabled we set up an account accesible via uucp over ssh | ||
91 | ''; | ||
92 | }; | ||
93 | |||
94 | nodeName = mkOption { | ||
95 | type = types.str; | ||
96 | default = "nixos"; | ||
97 | description = "uucp node name"; | ||
98 | }; | ||
99 | |||
100 | sshUser = mkOption { | ||
101 | type = types.attrs; | ||
102 | default = {}; | ||
103 | description = "Overrides for the local uucp linux-user"; | ||
104 | }; | ||
105 | |||
106 | extraSSHConfig = mkOption { | ||
107 | type = types.str; | ||
108 | default = ""; | ||
109 | description = "Extra SSH config"; | ||
110 | }; | ||
111 | |||
112 | remoteNodes = mkOption { | ||
113 | type = types.attrsOf (types.submodule nodeCfg); | ||
114 | default = {}; | ||
115 | description = '' | ||
116 | Ports to set up | ||
117 | Names will probably need to be configured in sshConfig | ||
118 | ''; | ||
119 | }; | ||
120 | |||
121 | commandPath = mkOption { | ||
122 | type = types.listOf types.path; | ||
123 | default = [ "${pkgs.rmail}/bin" ]; | ||
124 | defaultText = literalExpression ''[ "''${pkgs.rmail}/bin" ]''; | ||
125 | description = '' | ||
126 | Command search path for all systems | ||
127 | ''; | ||
128 | }; | ||
129 | |||
130 | defaultCommands = mkOption { | ||
131 | type = types.listOf types.str; | ||
132 | default = ["rmail"]; | ||
133 | description = "Commands allowed for remotes without explicit override"; | ||
134 | }; | ||
135 | |||
136 | defaultProtocols = mkOption { | ||
137 | type = types.separatedString ""; | ||
138 | default = "te"; | ||
139 | description = "UUCP protocol to use within ssh unless overriden"; | ||
140 | }; | ||
141 | |||
142 | incomingProtocols = mkOption { | ||
143 | type = types.separatedString ""; | ||
144 | default = "te"; | ||
145 | description = "UUCP protocols to use when called"; | ||
146 | }; | ||
147 | |||
148 | homeDir = mkOption { | ||
149 | type = types.path; | ||
150 | default = "/var/uucp"; | ||
151 | description = "Home of the uucp user"; | ||
152 | }; | ||
153 | |||
154 | sshKeyDir = mkOption { | ||
155 | type = types.path; | ||
156 | default = "${cfg.homeDir}/.ssh/"; | ||
157 | defaultText = literalExpression ''''${config.services.uucp.homeDir}/.ssh/''; | ||
158 | description = "Directory to store ssh keypairs"; | ||
159 | }; | ||
160 | |||
161 | spoolDir = mkOption { | ||
162 | type = types.path; | ||
163 | default = "/var/spool/uucp"; | ||
164 | description = "Spool directory"; | ||
165 | }; | ||
166 | |||
167 | lockDir = mkOption { | ||
168 | type = types.path; | ||
169 | default = "/var/spool/uucp"; | ||
170 | description = "Lock directory"; | ||
171 | }; | ||
172 | |||
173 | pubDir = mkOption { | ||
174 | type = types.path; | ||
175 | default = "/var/spool/uucppublic"; | ||
176 | description = "Public directory"; | ||
177 | }; | ||
178 | |||
179 | logFile = mkOption { | ||
180 | type = types.path; | ||
181 | default = "/var/log/uucp"; | ||
182 | description = "Log file"; | ||
183 | }; | ||
184 | |||
185 | statFile = mkOption { | ||
186 | type = types.path; | ||
187 | default = "/var/log/uucp.stat"; | ||
188 | description = "Statistics file"; | ||
189 | }; | ||
190 | |||
191 | debugFile = mkOption { | ||
192 | type = types.path; | ||
193 | default = "/var/log/uucp.debug"; | ||
194 | description = "Debug file"; | ||
195 | }; | ||
196 | |||
197 | interval = mkOption { | ||
198 | type = types.nullOr types.str; | ||
199 | default = "1h"; | ||
200 | description = '' | ||
201 | Specification of when to run `uucico' in format used by systemd timers | ||
202 | The default is to do so every hour | ||
203 | ''; | ||
204 | }; | ||
205 | |||
206 | nmDispatch = mkOption { | ||
207 | type = types.bool; | ||
208 | default = config.networking.networkmanager.enable; | ||
209 | defaultText = literalExpression "config.networking.networkmanager.enable"; | ||
210 | description = '' | ||
211 | Install a network-manager dispatcher script to automatically | ||
212 | call all remotes when networking is available | ||
213 | ''; | ||
214 | }; | ||
215 | |||
216 | extraConfig = mkOption { | ||
217 | type = types.lines; | ||
218 | default = '' | ||
219 | run-uuxqt 1 | ||
220 | ''; | ||
221 | description = "Extra configuration to append verbatim to `/etc/uucp/config'"; | ||
222 | }; | ||
223 | |||
224 | extraSys = mkOption { | ||
225 | type = types.lines; | ||
226 | default = '' | ||
227 | protocol-parameter g packet-size 4096 | ||
228 | ''; | ||
229 | description = "Extra configuration to prepend verbatim to `/etc/uucp/sys`"; | ||
230 | }; | ||
231 | }; | ||
232 | }; | ||
233 | |||
234 | config = mkIf cfg.enable { | ||
235 | environment.etc."uucp/config" = { | ||
236 | text = '' | ||
237 | hostname ${cfg.nodeName} | ||
238 | |||
239 | spool ${cfg.spoolDir} | ||
240 | lockdir ${cfg.lockDir} | ||
241 | pubdir ${cfg.pubDir} | ||
242 | logfile ${cfg.logFile} | ||
243 | statfile ${cfg.statFile} | ||
244 | debugfile ${cfg.debugFile} | ||
245 | |||
246 | ${cfg.extraConfig} | ||
247 | ''; | ||
248 | }; | ||
249 | |||
250 | users.groups."uucp" = {}; | ||
251 | users.users."uucp" = { | ||
252 | name = "uucp"; | ||
253 | group = "uucp"; | ||
254 | isSystemUser = true; | ||
255 | isNormalUser = false; | ||
256 | createHome = true; | ||
257 | home = cfg.homeDir; | ||
258 | description = "User for uucp over ssh"; | ||
259 | useDefaultShell = true; | ||
260 | openssh.authorizedKeys.keys = map restrictKey (concatLists (mapAttrsToList (name: node: node.publicKeys) cfg.remoteNodes)); | ||
261 | } // cfg.sshUser; | ||
262 | |||
263 | system.activationScripts."uucp-sshconfig" = '' | ||
264 | mkdir -p ${config.users.users."uucp".home}/.ssh | ||
265 | chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.users.users."uucp".home}/.ssh | ||
266 | chmod 700 ${config.users.users."uucp".home}/.ssh | ||
267 | ln -fs ${builtins.toFile "ssh-config" '' | ||
268 | ${concatStringsSep "\n" (mapAttrsToList sshConfig cfg.remoteNodes)} | ||
269 | |||
270 | ${cfg.extraSSHConfig} | ||
271 | ''} ${config.users.users."uucp".home}/.ssh/config | ||
272 | |||
273 | mkdir -p ${cfg.sshKeyDir} | ||
274 | chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${cfg.sshKeyDir} | ||
275 | chmod 700 ${cfg.sshKeyDir} | ||
276 | |||
277 | ${concatStringsSep "\n" (mapAttrsToList sshKeyGen cfg.remoteNodes)} | ||
278 | ''; | ||
279 | |||
280 | system.activationScripts."uucp-logs" = '' | ||
281 | touch ${cfg.logFile} | ||
282 | chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${cfg.logFile} | ||
283 | chmod 644 ${cfg.logFile} | ||
284 | touch ${cfg.statFile} | ||
285 | chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${cfg.statFile} | ||
286 | chmod 644 ${cfg.statFile} | ||
287 | touch ${cfg.debugFile} | ||
288 | chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${cfg.debugFile} | ||
289 | chmod 644 ${cfg.debugFile} | ||
290 | ''; | ||
291 | |||
292 | environment.etc."uucp/port" = { | ||
293 | text = '' | ||
294 | port ssh | ||
295 | type stdin | ||
296 | protocol ${cfg.incomingProtocols} | ||
297 | '' + concatStringsSep "\n" (mapAttrsToList portSpec cfg.remoteNodes); | ||
298 | }; | ||
299 | environment.etc."uucp/sys" = { | ||
300 | text = cfg.extraSys + "\n" + concatStringsSep "\n" (mapAttrsToList sysSpec cfg.remoteNodes); | ||
301 | }; | ||
302 | |||
303 | security.wrappers = let | ||
304 | wrapper = p: { | ||
305 | name = p; | ||
306 | value = { | ||
307 | source = "${pkgs.uucp}/bin/${p}"; | ||
308 | owner = "root"; | ||
309 | group = "root"; | ||
310 | setuid = true; | ||
311 | setgid = false; | ||
312 | }; | ||
313 | }; | ||
314 | in listToAttrs (map wrapper ["uucico" "cu" "uucp" "uuname" "uustat" "uux" "uuxqt"]); | ||
315 | |||
316 | nixpkgs.overlays = [(self: super: { | ||
317 | rmail = super.writeShellScriptBin "rmail" '' | ||
318 | # Dummy UUCP rmail command for postfix/qmail systems | ||
319 | |||
320 | IFS=" " read junk from junk junk junk junk junk junk junk relay | ||
321 | |||
322 | case "$from" in | ||
323 | *[@!]*) ;; | ||
324 | *) from="$from@$relay";; | ||
325 | esac | ||
326 | |||
327 | exec ${config.security.wrapperDir}/sendmail -G -i -f "$from" -- "$@" | ||
328 | ''; | ||
329 | })]; | ||
330 | |||
331 | environment.systemPackages = with pkgs; [ | ||
332 | uucp | ||
333 | ]; | ||
334 | |||
335 | systemd.services."uucico@" = { | ||
336 | serviceConfig = { | ||
337 | User = "uucp"; | ||
338 | Type = "oneshot"; | ||
339 | ExecStart = "${config.security.wrapperDir}/uucico -D -S %i"; | ||
340 | }; | ||
341 | }; | ||
342 | |||
343 | systemd.timers."uucico@" = { | ||
344 | timerConfig.OnActiveSec = cfg.interval; | ||
345 | timerConfig.OnUnitActiveSec = cfg.interval; | ||
346 | }; | ||
347 | |||
348 | systemd.targets."multi-user" = { | ||
349 | wants = mapAttrsToList (name: node: "uucico@${name}.timer") cfg.remoteNodes; | ||
350 | }; | ||
351 | |||
352 | systemd.kill-user.enable = true; | ||
353 | systemd.targets."sleep" = { | ||
354 | after = [ "kill-user@uucp.service" ]; | ||
355 | wants = [ "kill-user@uucp.service" ]; | ||
356 | }; | ||
357 | |||
358 | networking.networkmanager.dispatcherScripts = optional cfg.nmDispatch { | ||
359 | type = "basic"; | ||
360 | source = pkgs.writeScript "callRemotes.sh" '' | ||
361 | #!${pkgs.stdenv.shell} | ||
362 | |||
363 | shopt -s extglob | ||
364 | |||
365 | case "''${2}" in | ||
366 | (?(vpn-)up) | ||
367 | ${concatStringsSep "\n " (mapAttrsToList (name: node: "${pkgs.systemd}/bin/systemctl start uucico@${name}.service") cfg.remoteNodes)} | ||
368 | ;; | ||
369 | esac | ||
370 | ''; | ||
371 | }; | ||
372 | }; | ||
373 | } | ||
diff --git a/overlays/etesync-dav.nix b/overlays/etesync-dav.nix index cec216e2..e0ced1e3 100644 --- a/overlays/etesync-dav.nix +++ b/overlays/etesync-dav.nix | |||
@@ -1,55 +1,58 @@ | |||
1 | { final, prev, ... }: { | 1 | { final, prev, ... }: { |
2 | etesync-dav = prev.python3Packages.buildPythonApplication rec { | 2 | etesync-dav = final.python3Packages.buildPythonApplication rec { |
3 | pname = "etesync-dav"; | 3 | pname = "etesync-dav"; |
4 | version = "0.33.4"; | 4 | version = "0.35.1"; |
5 | pyproject = true; | ||
5 | 6 | ||
6 | src = prev.fetchFromGitHub { | 7 | src = prev.fetchFromGitHub { |
7 | owner = "etesync"; | 8 | owner = "etesync"; |
8 | repo = "etesync-dav"; | 9 | repo = "etesync-dav"; |
9 | rev = "v${version}"; | 10 | tag = "v${version}"; |
10 | hash = "sha256-g+rK762tSWPDaBsaTwpTzfK/lqVs+Z/Qrpq2HCpipQE="; | 11 | hash = "sha256-y4BhU2kSn+RWqc5+pJQFhbwfat9cMWD0ED0EXJp25cY="; |
11 | }; | 12 | }; |
12 | 13 | ||
13 | dependencies = with prev.python3Packages; [ | 14 | build-system = with final.python3Packages; [ setuptools ]; |
15 | |||
16 | dependencies = with final.python3Packages; [ | ||
14 | appdirs | 17 | appdirs |
15 | etebase | 18 | etebase |
16 | etesync | 19 | etesync |
17 | flask | 20 | flask |
18 | flask-wtf | 21 | flask-wtf |
19 | msgpack | 22 | msgpack |
20 | setuptools | 23 | requests |
21 | (toPythonModule (buildPythonApplication rec { | 24 | requests.optional-dependencies.socks |
25 | (buildPythonApplication rec { | ||
22 | pname = "radicale"; | 26 | pname = "radicale"; |
23 | version = "3.2.3"; | 27 | version = "3.2.0"; |
24 | pyproject = true; | 28 | pyproject = true; |
25 | 29 | ||
26 | src = prev.fetchFromGitHub { | 30 | src = prev.fetchFromGitHub { |
27 | owner = "Kozea"; | 31 | owner = "Kozea"; |
28 | repo = "Radicale"; | 32 | repo = "Radicale"; |
29 | rev = "refs/tags/v${version}"; | 33 | rev = "refs/tags/v${version}"; |
30 | hash = "sha256-1IlnXVetQQuKBt6+QVKNeMM6qBQAiUhqc+4x3xOnSdE="; | 34 | hash = "sha256-RxC8VOfdTXJZiAroDHTKjJqGWu65Z5uyb4WK1LOqubQ="; |
31 | }; | 35 | }; |
32 | 36 | ||
37 | postPatch = '' | ||
38 | sed -i '/addopts/d' setup.cfg | ||
39 | ''; | ||
40 | |||
33 | build-system = [ | 41 | build-system = [ |
34 | setuptools | 42 | setuptools |
35 | ]; | 43 | ]; |
36 | 44 | ||
37 | dependencies = | 45 | dependencies = [ |
38 | [ | 46 | defusedxml |
39 | defusedxml | 47 | passlib |
40 | passlib | 48 | vobject |
41 | vobject | 49 | pika |
42 | pika | 50 | python-dateutil |
43 | python-dateutil | 51 | pytz # https://github.com/Kozea/Radicale/issues/816 |
44 | pytz # https://github.com/Kozea/Radicale/issues/816 | 52 | ] ++ passlib.optional-dependencies.bcrypt; |
45 | ] | ||
46 | ++ passlib.optional-dependencies.bcrypt; | ||
47 | 53 | ||
48 | doCheck = false; | 54 | doCheck = false; |
49 | })) | 55 | }) |
50 | requests | ||
51 | types-setuptools | ||
52 | requests.optional-dependencies.socks | ||
53 | ]; | 56 | ]; |
54 | 57 | ||
55 | doCheck = false; | 58 | doCheck = false; |
diff --git a/overlays/prometheus-lvm-exporter.nix b/overlays/prometheus-lvm-exporter.nix index 240f8d85..cae45003 100644 --- a/overlays/prometheus-lvm-exporter.nix +++ b/overlays/prometheus-lvm-exporter.nix | |||
@@ -3,7 +3,7 @@ | |||
3 | pname = "prometheus-lvm-exporter"; | 3 | pname = "prometheus-lvm-exporter"; |
4 | inherit (sources.prometheus-lvm-exporter) version src; | 4 | inherit (sources.prometheus-lvm-exporter) version src; |
5 | 5 | ||
6 | vendorHash = "sha256-z/fV0PzoWSDTJ44En19o7zJPPPox5ymFw7sw0Ab9t00="; | 6 | vendorHash = "sha256-QpJM11Rg+TUV0GWYlvIkwuQqiTsfSdQNtPpD6zT08ew="; |
7 | 7 | ||
8 | doCheck = false; | 8 | doCheck = false; |
9 | 9 | ||
diff --git a/overlays/spice-record.nix b/overlays/spice-record.nix index 06a114da..2d37079b 100644 --- a/overlays/spice-record.nix +++ b/overlays/spice-record.nix | |||
@@ -8,5 +8,7 @@ | |||
8 | wrapProgram $out/bin/spice-record \ | 8 | wrapProgram $out/bin/spice-record \ |
9 | --prefix PATH : ${prev.lib.makeBinPath (with prev; [ ffmpeg-full ])} | 9 | --prefix PATH : ${prev.lib.makeBinPath (with prev; [ ffmpeg-full ])} |
10 | ''; | 10 | ''; |
11 | pyproject = true; | ||
12 | build-system = [ prev.python3Packages.setuptools ]; | ||
11 | }; | 13 | }; |
12 | } | 14 | } |
diff --git a/overlays/swayosd/default.nix b/overlays/swayosd/default.nix index b4601a03..5e715dae 100644 --- a/overlays/swayosd/default.nix +++ b/overlays/swayosd/default.nix | |||
@@ -4,7 +4,7 @@ | |||
4 | cargoDeps = prev.rustPlatform.fetchCargoVendor { | 4 | cargoDeps = prev.rustPlatform.fetchCargoVendor { |
5 | inherit (oldAttrs) pname; | 5 | inherit (oldAttrs) pname; |
6 | inherit version src; | 6 | inherit version src; |
7 | hash = "sha256-yWybf4GKxHrk4WrW5SmjfPD0Gv79tpXOwNLlWeykYy0="; | 7 | hash = "sha256-J2sl6/4+bRWlkvaTJtFsMqvvOxYtWLRjJcYWcu0loRE="; |
8 | }; | 8 | }; |
9 | patches = (oldAttrs.patches or []) ++ [ | 9 | patches = (oldAttrs.patches or []) ++ [ |
10 | ./exponential.patch | 10 | ./exponential.patch |
diff --git a/overlays/uucp/default.nix b/overlays/uucp/default.nix deleted file mode 100644 index 4189dbcc..00000000 --- a/overlays/uucp/default.nix +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | { final, prev, ... }: { | ||
2 | uucp = prev.uucp.overrideAttrs (oldAttrs: { | ||
3 | configureFlags = (oldAttrs.configureFlags or []) ++ ["--with-newconfigdir=/etc/uucp"]; | ||
4 | patches = (oldAttrs.patches or []) ++ [ | ||
5 | ./mailprogram.patch | ||
6 | ]; | ||
7 | NIX_CFLAGS_COMPILE = "${oldAttrs.NIX_CFLAGS_COMPILE or ""} -Wno-error=incompatible-pointer-types"; | ||
8 | }); | ||
9 | } | ||
diff --git a/overlays/uucp/mailprogram.patch b/overlays/uucp/mailprogram.patch deleted file mode 100644 index 89ac8f31..00000000 --- a/overlays/uucp/mailprogram.patch +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | policy.h | 2 +- | ||
2 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
3 | |||
4 | diff --git a/policy.h b/policy.h | ||
5 | index 5afe34b..8e92c8b 100644 | ||
6 | --- a/policy.h | ||
7 | +++ b/policy.h | ||
8 | @@ -240,7 +240,7 @@ | ||
9 | the sendmail choice below. Otherwise, select one of the other | ||
10 | choices as appropriate. */ | ||
11 | #if 1 | ||
12 | -#define MAIL_PROGRAM "/usr/lib/sendmail -t" | ||
13 | +#define MAIL_PROGRAM "${config.security.wrapperDir}/sendmail -t" | ||
14 | /* #define MAIL_PROGRAM "/usr/sbin/sendmail -t" */ | ||
15 | #define MAIL_PROGRAM_TO_BODY 1 | ||
16 | #define MAIL_PROGRAM_SUBJECT_BODY 1 | ||
diff --git a/overlays/worktime/.envrc b/overlays/worktime/.envrc new file mode 100644 index 00000000..2c909235 --- /dev/null +++ b/overlays/worktime/.envrc | |||
@@ -0,0 +1,4 @@ | |||
1 | use flake | ||
2 | |||
3 | [[ -d ".venv" ]] || ( uv venv && uv sync ) | ||
4 | . .venv/bin/activate | ||
diff --git a/overlays/worktime/.gitignore b/overlays/worktime/.gitignore new file mode 100644 index 00000000..4ccfae70 --- /dev/null +++ b/overlays/worktime/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | .venv | ||
2 | **/__pycache__ | ||
diff --git a/overlays/worktime/default.nix b/overlays/worktime/default.nix index 1d8433af..579cf7ad 100644 --- a/overlays/worktime/default.nix +++ b/overlays/worktime/default.nix | |||
@@ -1,13 +1,19 @@ | |||
1 | { prev, ... }: | 1 | { prev, final, flake, flakeInputs, ... }: |
2 | 2 | ||
3 | with prev.poetry2nix; | 3 | let |
4 | 4 | workspace = flakeInputs.uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; }; | |
5 | { | 5 | pythonSet = flake.lib.pythonSet { |
6 | worktime = mkPoetryApplication { | 6 | pkgs = final; |
7 | python = prev.python312; | 7 | python = final.python312; |
8 | 8 | overlay = workspace.mkPyprojectOverlay { | |
9 | projectDir = cleanPythonSources { src = ./.; }; | 9 | sourcePreference = "wheel"; |
10 | 10 | }; | |
11 | meta.mainProgram = "worktime"; | ||
12 | }; | 11 | }; |
12 | virtualEnv = pythonSet.mkVirtualEnv "worktime" workspace.deps.default; | ||
13 | in { | ||
14 | worktime = virtualEnv.overrideAttrs (oldAttrs: { | ||
15 | meta = (oldAttrs.meta or {}) // { | ||
16 | mainProgram = "worktime"; | ||
17 | }; | ||
18 | }); | ||
13 | } | 19 | } |
diff --git a/overlays/worktime/poetry.lock b/overlays/worktime/poetry.lock deleted file mode 100644 index 7c1ca91d..00000000 --- a/overlays/worktime/poetry.lock +++ /dev/null | |||
@@ -1,284 +0,0 @@ | |||
1 | # This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. | ||
2 | |||
3 | [[package]] | ||
4 | name = "backoff" | ||
5 | version = "2.2.1" | ||
6 | description = "Function decoration for backoff and retry" | ||
7 | optional = false | ||
8 | python-versions = ">=3.7,<4.0" | ||
9 | groups = ["main"] | ||
10 | files = [ | ||
11 | {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, | ||
12 | {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, | ||
13 | ] | ||
14 | |||
15 | [[package]] | ||
16 | name = "certifi" | ||
17 | version = "2025.1.31" | ||
18 | description = "Python package for providing Mozilla's CA Bundle." | ||
19 | optional = false | ||
20 | python-versions = ">=3.6" | ||
21 | groups = ["main"] | ||
22 | files = [ | ||
23 | {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, | ||
24 | {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, | ||
25 | ] | ||
26 | |||
27 | [[package]] | ||
28 | name = "charset-normalizer" | ||
29 | version = "3.4.1" | ||
30 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." | ||
31 | optional = false | ||
32 | python-versions = ">=3.7" | ||
33 | groups = ["main"] | ||
34 | files = [ | ||
35 | {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, | ||
36 | {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, | ||
37 | {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, | ||
38 | {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, | ||
39 | {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, | ||
40 | {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, | ||
41 | {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, | ||
42 | {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, | ||
43 | {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, | ||
44 | {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, | ||
45 | {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, | ||
46 | {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, | ||
47 | {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, | ||
48 | {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, | ||
49 | {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, | ||
50 | {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, | ||
51 | {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, | ||
52 | {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, | ||
53 | {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, | ||
54 | {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, | ||
55 | {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, | ||
56 | {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, | ||
57 | {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, | ||
58 | {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, | ||
59 | {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, | ||
60 | {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, | ||
61 | {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, | ||
62 | {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, | ||
63 | {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, | ||
64 | {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, | ||
65 | {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, | ||
66 | {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, | ||
67 | {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, | ||
68 | {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, | ||
69 | {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, | ||
70 | {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, | ||
71 | {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, | ||
72 | {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, | ||
73 | {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, | ||
74 | {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, | ||
75 | {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, | ||
76 | {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, | ||
77 | {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, | ||
78 | {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, | ||
79 | {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, | ||
80 | {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, | ||
81 | {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, | ||
82 | {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, | ||
83 | {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, | ||
84 | {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, | ||
85 | {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, | ||
86 | {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, | ||
87 | {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, | ||
88 | {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, | ||
89 | {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, | ||
90 | {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, | ||
91 | {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, | ||
92 | {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, | ||
93 | {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, | ||
94 | {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, | ||
95 | {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, | ||
96 | {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, | ||
97 | {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, | ||
98 | {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, | ||
99 | {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, | ||
100 | {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, | ||
101 | {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, | ||
102 | {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, | ||
103 | {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, | ||
104 | {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, | ||
105 | {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, | ||
106 | {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, | ||
107 | {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, | ||
108 | {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, | ||
109 | {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, | ||
110 | {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, | ||
111 | {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, | ||
112 | {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, | ||
113 | {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, | ||
114 | {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, | ||
115 | {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, | ||
116 | {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, | ||
117 | {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, | ||
118 | {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, | ||
119 | {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, | ||
120 | {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, | ||
121 | {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, | ||
122 | {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, | ||
123 | {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, | ||
124 | {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, | ||
125 | {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, | ||
126 | {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, | ||
127 | ] | ||
128 | |||
129 | [[package]] | ||
130 | name = "idna" | ||
131 | version = "3.10" | ||
132 | description = "Internationalized Domain Names in Applications (IDNA)" | ||
133 | optional = false | ||
134 | python-versions = ">=3.6" | ||
135 | groups = ["main"] | ||
136 | files = [ | ||
137 | {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, | ||
138 | {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, | ||
139 | ] | ||
140 | |||
141 | [package.extras] | ||
142 | all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] | ||
143 | |||
144 | [[package]] | ||
145 | name = "jsonpickle" | ||
146 | version = "4.0.5" | ||
147 | description = "jsonpickle encodes/decodes any Python object to/from JSON" | ||
148 | optional = false | ||
149 | python-versions = ">=3.8" | ||
150 | groups = ["main"] | ||
151 | files = [ | ||
152 | {file = "jsonpickle-4.0.5-py3-none-any.whl", hash = "sha256:b4ac7d0a75ddcdfd93445737f1d36ff28768690d43e54bf5d0ddb1d915e580df"}, | ||
153 | {file = "jsonpickle-4.0.5.tar.gz", hash = "sha256:f299818b39367c361b3f26bdba827d4249ab5d383cd93144d0f94b5417aacb35"}, | ||
154 | ] | ||
155 | |||
156 | [package.extras] | ||
157 | cov = ["pytest-cov"] | ||
158 | dev = ["black", "pyupgrade"] | ||
159 | docs = ["furo", "rst.linker (>=1.9)", "sphinx (>=3.5)"] | ||
160 | packaging = ["build", "setuptools (>=61.2)", "setuptools-scm[toml] (>=6.0)", "twine"] | ||
161 | testing = ["PyYAML", "atheris (>=2.3.0,<2.4.0) ; python_version < \"3.12\"", "bson", "ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=6.0,!=8.1.*)", "pytest-benchmark", "pytest-benchmark[histogram]", "pytest-checkdocs (>=1.2.3)", "pytest-enabler (>=1.0.1)", "pytest-ruff (>=0.2.1)", "scikit-learn", "scipy (>=1.9.3) ; python_version > \"3.10\"", "scipy ; python_version <= \"3.10\"", "simplejson", "sqlalchemy", "ujson"] | ||
162 | |||
163 | [[package]] | ||
164 | name = "python-dateutil" | ||
165 | version = "2.9.0.post0" | ||
166 | description = "Extensions to the standard Python datetime module" | ||
167 | optional = false | ||
168 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" | ||
169 | groups = ["main"] | ||
170 | files = [ | ||
171 | {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, | ||
172 | {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, | ||
173 | ] | ||
174 | |||
175 | [package.dependencies] | ||
176 | six = ">=1.5" | ||
177 | |||
178 | [[package]] | ||
179 | name = "pyxdg" | ||
180 | version = "0.28" | ||
181 | description = "PyXDG contains implementations of freedesktop.org standards in python." | ||
182 | optional = false | ||
183 | python-versions = "*" | ||
184 | groups = ["main"] | ||
185 | files = [ | ||
186 | {file = "pyxdg-0.28-py2.py3-none-any.whl", hash = "sha256:bdaf595999a0178ecea4052b7f4195569c1ff4d344567bccdc12dfdf02d545ab"}, | ||
187 | {file = "pyxdg-0.28.tar.gz", hash = "sha256:3267bb3074e934df202af2ee0868575484108581e6f3cb006af1da35395e88b4"}, | ||
188 | ] | ||
189 | |||
190 | [[package]] | ||
191 | name = "requests" | ||
192 | version = "2.32.3" | ||
193 | description = "Python HTTP for Humans." | ||
194 | optional = false | ||
195 | python-versions = ">=3.8" | ||
196 | groups = ["main"] | ||
197 | files = [ | ||
198 | {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, | ||
199 | {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, | ||
200 | ] | ||
201 | |||
202 | [package.dependencies] | ||
203 | certifi = ">=2017.4.17" | ||
204 | charset-normalizer = ">=2,<4" | ||
205 | idna = ">=2.5,<4" | ||
206 | urllib3 = ">=1.21.1,<3" | ||
207 | |||
208 | [package.extras] | ||
209 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] | ||
210 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] | ||
211 | |||
212 | [[package]] | ||
213 | name = "six" | ||
214 | version = "1.17.0" | ||
215 | description = "Python 2 and 3 compatibility utilities" | ||
216 | optional = false | ||
217 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" | ||
218 | groups = ["main"] | ||
219 | files = [ | ||
220 | {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, | ||
221 | {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, | ||
222 | ] | ||
223 | |||
224 | [[package]] | ||
225 | name = "tabulate" | ||
226 | version = "0.9.0" | ||
227 | description = "Pretty-print tabular data" | ||
228 | optional = false | ||
229 | python-versions = ">=3.7" | ||
230 | groups = ["main"] | ||
231 | files = [ | ||
232 | {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, | ||
233 | {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, | ||
234 | ] | ||
235 | |||
236 | [package.extras] | ||
237 | widechars = ["wcwidth"] | ||
238 | |||
239 | [[package]] | ||
240 | name = "toml" | ||
241 | version = "0.10.2" | ||
242 | description = "Python Library for Tom's Obvious, Minimal Language" | ||
243 | optional = false | ||
244 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" | ||
245 | groups = ["main"] | ||
246 | files = [ | ||
247 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, | ||
248 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, | ||
249 | ] | ||
250 | |||
251 | [[package]] | ||
252 | name = "uritools" | ||
253 | version = "4.0.3" | ||
254 | description = "URI parsing, classification and composition" | ||
255 | optional = false | ||
256 | python-versions = ">=3.7" | ||
257 | groups = ["main"] | ||
258 | files = [ | ||
259 | {file = "uritools-4.0.3-py3-none-any.whl", hash = "sha256:bae297d090e69a0451130ffba6f2f1c9477244aa0a5543d66aed2d9f77d0dd9c"}, | ||
260 | {file = "uritools-4.0.3.tar.gz", hash = "sha256:ee06a182a9c849464ce9d5fa917539aacc8edd2a4924d1b7aabeeecabcae3bc2"}, | ||
261 | ] | ||
262 | |||
263 | [[package]] | ||
264 | name = "urllib3" | ||
265 | version = "2.3.0" | ||
266 | description = "HTTP library with thread-safe connection pooling, file post, and more." | ||
267 | optional = false | ||
268 | python-versions = ">=3.9" | ||
269 | groups = ["main"] | ||
270 | files = [ | ||
271 | {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, | ||
272 | {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, | ||
273 | ] | ||
274 | |||
275 | [package.extras] | ||
276 | brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] | ||
277 | h2 = ["h2 (>=4,<5)"] | ||
278 | socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] | ||
279 | zstd = ["zstandard (>=0.18.0)"] | ||
280 | |||
281 | [metadata] | ||
282 | lock-version = "2.1" | ||
283 | python-versions = "^3.12" | ||
284 | content-hash = "2b335da94bf3e2d2bee7d8ca6e84cdb56e97ac29d1224d8c8dca98d93bbdcea2" | ||
diff --git a/overlays/worktime/pyproject.toml b/overlays/worktime/pyproject.toml index de4b9fd4..42da51f5 100644 --- a/overlays/worktime/pyproject.toml +++ b/overlays/worktime/pyproject.toml | |||
@@ -1,23 +1,28 @@ | |||
1 | [tool.poetry] | 1 | [project] |
2 | name = "worktime" | 2 | name = "worktime" |
3 | version = "0.1.0" | 3 | version = "1.0.0" |
4 | description = "" | 4 | requires-python = "~=3.12" |
5 | authors = ["Gregor Kleen <gkleen@yggdrasil.li>"] | 5 | dependencies = [ |
6 | "pyxdg>=0.28,<0.29", | ||
7 | "python-dateutil>=2.9.0.post0,<3", | ||
8 | "uritools>=4.0.3,<5", | ||
9 | "requests>=2.32.3,<3", | ||
10 | "tabulate>=0.9.0,<0.10", | ||
11 | "toml>=0.10.2,<0.11", | ||
12 | "jsonpickle>=4.0.5,<5", | ||
13 | "frozendict>=2.4.6", | ||
14 | "atomicwriter>=0.2.5", | ||
15 | "desktop-notify>=1.3.3", | ||
16 | ] | ||
6 | 17 | ||
7 | [tool.poetry.dependencies] | 18 | [project.scripts] |
8 | python = "^3.12" | ||
9 | pyxdg = "^0.28" | ||
10 | python-dateutil = "^2.9.0.post0" | ||
11 | uritools = "^4.0.3" | ||
12 | requests = "^2.32.3" | ||
13 | tabulate = "^0.9.0" | ||
14 | backoff = "^2.2.1" | ||
15 | toml = "^0.10.2" | ||
16 | jsonpickle = "^4.0.5" | ||
17 | |||
18 | [tool.poetry.scripts] | ||
19 | worktime = "worktime.__main__:main" | 19 | worktime = "worktime.__main__:main" |
20 | worktime-ui = "worktime.__main__:ui" | ||
21 | worktime-stop = "worktime.__main__:stop" | ||
20 | 22 | ||
21 | [build-system] | 23 | [build-system] |
22 | requires = ["poetry-core"] | 24 | requires = ["hatchling"] |
23 | build-backend = "poetry.core.masonry.api" \ No newline at end of file | 25 | build-backend = "hatchling.build" |
26 | |||
27 | [dependency-groups] | ||
28 | dev = [] | ||
diff --git a/overlays/worktime/uv.lock b/overlays/worktime/uv.lock new file mode 100644 index 00000000..39de4ccf --- /dev/null +++ b/overlays/worktime/uv.lock | |||
@@ -0,0 +1,248 @@ | |||
1 | version = 1 | ||
2 | revision = 2 | ||
3 | requires-python = ">=3.12, <4" | ||
4 | |||
5 | [[package]] | ||
6 | name = "atomicwriter" | ||
7 | version = "0.2.5" | ||
8 | source = { registry = "https://pypi.org/simple" } | ||
9 | sdist = { url = "https://files.pythonhosted.org/packages/50/b4/dd04e186eb244d1ed84b1d0ebfba19ddc7f8886b98e345aaca4208b031d2/atomicwriter-0.2.5.tar.gz", hash = "sha256:5ced6afb0579377a13e191b17a16115e14c30ec00e6c38b60403f58235a867af", size = 64990, upload-time = "2025-05-24T20:35:42.538Z" } | ||
10 | wheels = [ | ||
11 | { url = "https://files.pythonhosted.org/packages/99/7c/672a0de09b0b355a2ffa521ef25cf106f1984823379dee37f7305fdc1774/atomicwriter-0.2.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c1fab874e62ebe96f1af0e965dc1e92c4c1ef2e2e9612a444371b8fc751ec43", size = 234141, upload-time = "2025-05-24T20:34:32.74Z" }, | ||
12 | { url = "https://files.pythonhosted.org/packages/b9/0c/e1c5bad033284c212c0a77121b48dd4147f80e9a7cd82a9d2ce0a2160901/atomicwriter-0.2.5-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:8dbb67cc730be7d6bdfd5e991271bc17052be8fb2e4fa27854b47d8a76d36349", size = 245788, upload-time = "2025-05-24T20:34:33.897Z" }, | ||
13 | { url = "https://files.pythonhosted.org/packages/f4/d3/7036e203cc5fc4c49bf916b4ba158e0d2779de127afad5963edd7e3b9400/atomicwriter-0.2.5-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:a4e7f81932839c738425dc96ad98e4a7511b740cd3d75f480bfabbcf8e6f7eae", size = 260428, upload-time = "2025-05-24T20:34:35.533Z" }, | ||
14 | { url = "https://files.pythonhosted.org/packages/e5/b9/9a4d235a8d67fb442302dc0f3ea2394b7bd994bfc99b1dc0f744c7852418/atomicwriter-0.2.5-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:de37a3a5d1b57b719cfb0b81a11cab2114acfdc2c36051bf0af72d05eb644411", size = 263648, upload-time = "2025-05-24T20:34:36.72Z" }, | ||
15 | { url = "https://files.pythonhosted.org/packages/71/7c/32d4ddad53375de42f3e972bb0633ec76f2c31772f2e508479d4788651d9/atomicwriter-0.2.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b925e55750092fd482565b6068b8c8366fd79de526681af9e58eb209f0deeca", size = 323775, upload-time = "2025-05-24T20:34:37.968Z" }, | ||
16 | { url = "https://files.pythonhosted.org/packages/06/fe/6a226368a3f7ea30001fbd165f6a97f28c8f1a884896357b3d694983f5d2/atomicwriter-0.2.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:538f78f25e01584535782397211c66b8b3c9de90c2d1fc01a668ddce73dd0cb2", size = 340819, upload-time = "2025-05-24T20:34:39.63Z" }, | ||
17 | { url = "https://files.pythonhosted.org/packages/92/95/b035b2296c483fde5392c629e0b6e3844eba6e54ea965c4b8827379b0893/atomicwriter-0.2.5-cp312-cp312-win_amd64.whl", hash = "sha256:1d2d49a1b94ea7b289be9f7134d756bfb0bbf53eb0e58411334ed1b9958abe5e", size = 152789, upload-time = "2025-05-24T20:34:40.905Z" }, | ||
18 | { url = "https://files.pythonhosted.org/packages/da/25/caa0959ae8ce24763e24e1f45be6cb897414545d224a155f929d496d6812/atomicwriter-0.2.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f5490fd5bec378509521f7c2a19a64031a0de07d368d76733c3f76a0b9f026b", size = 233830, upload-time = "2025-05-24T20:34:42.532Z" }, | ||
19 | { url = "https://files.pythonhosted.org/packages/d2/76/3c41bfd4fd74bc63bec29f05a806a767258eea7cf151496b4ab015cb5323/atomicwriter-0.2.5-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:a4dada83ff1255c7e640363cc2a4399ab9a822d4dbc9c18f55bbf0c8b12ce056", size = 245461, upload-time = "2025-05-24T20:34:44.454Z" }, | ||
20 | { url = "https://files.pythonhosted.org/packages/c3/1e/5512dbdfdc3f4ab12f5923c50ae4765cc2fc65a9f112bb9dccbcbe60b395/atomicwriter-0.2.5-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ef2cf15e67513f05ad37d4cec48e403982c6b3c07f491472effd76d2157de7e2", size = 259892, upload-time = "2025-05-24T20:34:45.688Z" }, | ||
21 | { url = "https://files.pythonhosted.org/packages/e5/1d/2382b6cacb119115828eb519697a555900bcfdb062efeb0f82603295402d/atomicwriter-0.2.5-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:73618f74c3c5f5401d3da0a3cd3043f23de5b6bb4a3d85bc580940a441355d25", size = 263125, upload-time = "2025-05-24T20:34:47.205Z" }, | ||
22 | { url = "https://files.pythonhosted.org/packages/07/d7/c4d68386161870db4a8d0452f0655a19902fa435b749c12e6ef800e89b19/atomicwriter-0.2.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbd5eda80710ddac7aefb421c79cef6b905852a827e764f0f12fcbaa88919f7a", size = 323503, upload-time = "2025-05-24T20:34:48.417Z" }, | ||
23 | { url = "https://files.pythonhosted.org/packages/b7/08/0fc03c0736ab8466e1b47a3ee17a528da18019cff93b7c4c2b33df82c19e/atomicwriter-0.2.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4776aaca40bc3040c3716c2adad74625c42285083ff31e8bf24a95315225c7b", size = 340156, upload-time = "2025-05-24T20:34:50.389Z" }, | ||
24 | { url = "https://files.pythonhosted.org/packages/fa/09/7ba888cf4d90bcabd9e82db3bdb9de50e4ef072e0ea0d375cd1931b79349/atomicwriter-0.2.5-cp313-cp313-win_amd64.whl", hash = "sha256:225ed1fbfa1996d9b0b2252f8a5d81263e51cbc797086d830f488c35b1d2ab42", size = 152274, upload-time = "2025-05-24T20:34:51.785Z" }, | ||
25 | { url = "https://files.pythonhosted.org/packages/2a/70/07d2ba2e0a126cfecfbfed46baf599c9e2155f4c8338fed4d3ae0041b133/atomicwriter-0.2.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:63b55982cfa47232f179689933bf003eefb2bd33464235883ed3ce7322cf38f3", size = 232879, upload-time = "2025-05-24T20:34:53.195Z" }, | ||
26 | { url = "https://files.pythonhosted.org/packages/f6/4d/397eb5435917135df93b339d849884bb1125896b1e15163c5244aa590336/atomicwriter-0.2.5-cp313-cp313t-macosx_11_0_x86_64.whl", hash = "sha256:e33f40b2a27f8831beeabb485923acb6dd067cc70bba1a63096749b3dc4747ff", size = 244386, upload-time = "2025-05-24T20:34:54.852Z" }, | ||
27 | { url = "https://files.pythonhosted.org/packages/8b/01/73f0b683fa55e61dd29d30e48e9a75ddb049e6dad0ac4ae1a29dbc05f21e/atomicwriter-0.2.5-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c646e115e88147d71f845a005fc53910f22c4dc65bd634768cb90b7f34259359", size = 258255, upload-time = "2025-05-24T20:34:56.046Z" }, | ||
28 | { url = "https://files.pythonhosted.org/packages/4b/19/692387c1fb1b8714a9b2fab99a58850fd4136bed988814c8ff74d0c8de02/atomicwriter-0.2.5-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:47f974e986ff6514351c3ea75041009a514be0c34c225c062b0ad8a28ec9c0a3", size = 261768, upload-time = "2025-05-24T20:34:57.795Z" }, | ||
29 | { url = "https://files.pythonhosted.org/packages/3e/f2/4d466f52ee635cc54011713272f302584c6d1ce612c331d9989fa6fa672f/atomicwriter-0.2.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e1db8b9004cd3f628166e83b25eb814b82345f9d6bc15e99b6d201c355455b45", size = 321975, upload-time = "2025-05-24T20:34:59.45Z" }, | ||
30 | { url = "https://files.pythonhosted.org/packages/84/ad/0189ad9783ca6609df47e06cc0cd22866a8073d46478f59c6ab3ec13e0fb/atomicwriter-0.2.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a7da4a114121ab865663578b801a0520b2b518d4591af0bd294f6aac0dad243b", size = 338946, upload-time = "2025-05-24T20:35:01.501Z" }, | ||
31 | { url = "https://files.pythonhosted.org/packages/94/79/2c4d8f75eeb09192cf572957f031271998f3c985fabd79d513fff66ac715/atomicwriter-0.2.5-cp313-cp313t-win_amd64.whl", hash = "sha256:7aab4b3956cc17219e7e4da76e8a1bceb3d3aeaf03234f89b90e234a2adcf27b", size = 151571, upload-time = "2025-05-24T20:35:02.747Z" }, | ||
32 | { url = "https://files.pythonhosted.org/packages/32/19/d6a686d189c3577e7f08b33df398b959c24bf74b3cec34359104db1a24ff/atomicwriter-0.2.5-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d0fccac2dfe5d884d97edbda28be9c16d55faee9bdf66f53a99384ac387cc43", size = 239320, upload-time = "2025-05-24T20:35:04.028Z" }, | ||
33 | { url = "https://files.pythonhosted.org/packages/8e/35/35571a4eed57816c3b5fdbefcb15f38563fbe4f3a4a7d1588c8ef899afaf/atomicwriter-0.2.5-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:6583c24333508839db2156d895cbbb5cd3ff20d4f9c698e341435e5b35990eaa", size = 250818, upload-time = "2025-05-24T20:35:05.21Z" }, | ||
34 | { url = "https://files.pythonhosted.org/packages/81/d9/145093630bc25f115a49d32d9ef66745f5cdef787492d77fd27e74d20389/atomicwriter-0.2.5-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:136a9902ae3f1c0cb262a07dd3ac85069d71f8b11347cd740030567e67d611aa", size = 265796, upload-time = "2025-05-24T20:35:06.388Z" }, | ||
35 | { url = "https://files.pythonhosted.org/packages/58/32/d1881adade2ebc70aa9dbb61cadabc2c00cfa99a7a5d6ba48f44e279056f/atomicwriter-0.2.5-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0b6830434b6a49c19473c3f3975dfa0a87dec95bee81297f7393e378f9a0b82f", size = 269378, upload-time = "2025-05-24T20:35:07.578Z" }, | ||
36 | { url = "https://files.pythonhosted.org/packages/93/f5/2661ea763784a4991c4c7be5c932a468937bd1d4618b833a63ec638a3b76/atomicwriter-0.2.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:53095a01891a2901aa04c10c8de52c0ba41e0d8a4a1893318cf34ccbdbde00b7", size = 328167, upload-time = "2025-05-24T20:35:08.764Z" }, | ||
37 | { url = "https://files.pythonhosted.org/packages/ec/bc/e3aa521671a589bee9662d3e2108e4835a5d80e6da76e4d05d98d1c78005/atomicwriter-0.2.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ecf4dc3983bb1f28b21cb09c2d96b6936d8864c559dcf151b57813cb1eae998b", size = 347153, upload-time = "2025-05-24T20:35:10.507Z" }, | ||
38 | { url = "https://files.pythonhosted.org/packages/59/b7/e190383e7240b1f247c6df9bc6667db8df10190cd0bb2dba8ea6bd704ea4/atomicwriter-0.2.5-cp39-abi3-win_amd64.whl", hash = "sha256:92cff264a20364301ab341b332fd0112866870b8cb35caf99a3f3fee0e6c19e8", size = 156374, upload-time = "2025-05-24T20:35:11.716Z" }, | ||
39 | ] | ||
40 | |||
41 | [[package]] | ||
42 | name = "certifi" | ||
43 | version = "2025.1.31" | ||
44 | source = { registry = "https://pypi.org/simple" } | ||
45 | sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload-time = "2025-01-31T02:16:47.166Z" } | ||
46 | wheels = [ | ||
47 | { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload-time = "2025-01-31T02:16:45.015Z" }, | ||
48 | ] | ||
49 | |||
50 | [[package]] | ||
51 | name = "charset-normalizer" | ||
52 | version = "3.4.1" | ||
53 | source = { registry = "https://pypi.org/simple" } | ||
54 | sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" } | ||
55 | wheels = [ | ||
56 | { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105, upload-time = "2024-12-24T18:10:38.83Z" }, | ||
57 | { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404, upload-time = "2024-12-24T18:10:44.272Z" }, | ||
58 | { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423, upload-time = "2024-12-24T18:10:45.492Z" }, | ||
59 | { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184, upload-time = "2024-12-24T18:10:47.898Z" }, | ||
60 | { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268, upload-time = "2024-12-24T18:10:50.589Z" }, | ||
61 | { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601, upload-time = "2024-12-24T18:10:52.541Z" }, | ||
62 | { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098, upload-time = "2024-12-24T18:10:53.789Z" }, | ||
63 | { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520, upload-time = "2024-12-24T18:10:55.048Z" }, | ||
64 | { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852, upload-time = "2024-12-24T18:10:57.647Z" }, | ||
65 | { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488, upload-time = "2024-12-24T18:10:59.43Z" }, | ||
66 | { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192, upload-time = "2024-12-24T18:11:00.676Z" }, | ||
67 | { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550, upload-time = "2024-12-24T18:11:01.952Z" }, | ||
68 | { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785, upload-time = "2024-12-24T18:11:03.142Z" }, | ||
69 | { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" }, | ||
70 | { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" }, | ||
71 | { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" }, | ||
72 | { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" }, | ||
73 | { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" }, | ||
74 | { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" }, | ||
75 | { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" }, | ||
76 | { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" }, | ||
77 | { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" }, | ||
78 | { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" }, | ||
79 | { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" }, | ||
80 | { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" }, | ||
81 | { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" }, | ||
82 | { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" }, | ||
83 | ] | ||
84 | |||
85 | [[package]] | ||
86 | name = "dbus-next" | ||
87 | version = "0.2.3" | ||
88 | source = { registry = "https://pypi.org/simple" } | ||
89 | sdist = { url = "https://files.pythonhosted.org/packages/ce/45/6a40fbe886d60a8c26f480e7d12535502b5ba123814b3b9a0b002ebca198/dbus_next-0.2.3.tar.gz", hash = "sha256:f4eae26909332ada528c0a3549dda8d4f088f9b365153952a408e28023a626a5", size = 71112, upload-time = "2021-07-25T22:11:28.398Z" } | ||
90 | wheels = [ | ||
91 | { url = "https://files.pythonhosted.org/packages/d2/fc/c0a3f4c4eaa5a22fbef91713474666e13d0ea2a69c84532579490a9f2cc8/dbus_next-0.2.3-py3-none-any.whl", hash = "sha256:58948f9aff9db08316734c0be2a120f6dc502124d9642f55e90ac82ffb16a18b", size = 57885, upload-time = "2021-07-25T22:11:25.466Z" }, | ||
92 | ] | ||
93 | |||
94 | [[package]] | ||
95 | name = "desktop-notify" | ||
96 | version = "1.3.3" | ||
97 | source = { registry = "https://pypi.org/simple" } | ||
98 | dependencies = [ | ||
99 | { name = "dbus-next" }, | ||
100 | ] | ||
101 | sdist = { url = "https://files.pythonhosted.org/packages/7a/d8/7ae5779257f5f1aa0a2d50c02d70b29522bd414692f3d3bd18ef119fe82d/desktop-notify-1.3.3.tar.gz", hash = "sha256:62934ad1f72f292f9a3af5ffe45af32814af18c396c00369385540c72bf08077", size = 7828, upload-time = "2021-01-03T16:46:36.483Z" } | ||
102 | wheels = [ | ||
103 | { url = "https://files.pythonhosted.org/packages/0a/cd/a7e3bd0262f3e8a9272fd24d0193e24dad7cb4e4edd27da48e74b5523e59/desktop_notify-1.3.3-py3-none-any.whl", hash = "sha256:8ad7ecc3a9a603dd5fa3cdc11cc6265cfbc7f6df9d8ed240f4663f43ef0de37a", size = 9937, upload-time = "2021-01-03T16:46:35.157Z" }, | ||
104 | ] | ||
105 | |||
106 | [[package]] | ||
107 | name = "frozendict" | ||
108 | version = "2.4.6" | ||
109 | source = { registry = "https://pypi.org/simple" } | ||
110 | sdist = { url = "https://files.pythonhosted.org/packages/bb/59/19eb300ba28e7547538bdf603f1c6c34793240a90e1a7b61b65d8517e35e/frozendict-2.4.6.tar.gz", hash = "sha256:df7cd16470fbd26fc4969a208efadc46319334eb97def1ddf48919b351192b8e", size = 316416, upload-time = "2024-10-13T12:15:32.449Z" } | ||
111 | wheels = [ | ||
112 | { url = "https://files.pythonhosted.org/packages/04/13/d9839089b900fa7b479cce495d62110cddc4bd5630a04d8469916c0e79c5/frozendict-2.4.6-py311-none-any.whl", hash = "sha256:d065db6a44db2e2375c23eac816f1a022feb2fa98cbb50df44a9e83700accbea", size = 16148, upload-time = "2024-10-13T12:15:26.839Z" }, | ||
113 | { url = "https://files.pythonhosted.org/packages/ba/d0/d482c39cee2ab2978a892558cf130681d4574ea208e162da8958b31e9250/frozendict-2.4.6-py312-none-any.whl", hash = "sha256:49344abe90fb75f0f9fdefe6d4ef6d4894e640fadab71f11009d52ad97f370b9", size = 16146, upload-time = "2024-10-13T12:15:28.16Z" }, | ||
114 | { url = "https://files.pythonhosted.org/packages/a5/8e/b6bf6a0de482d7d7d7a2aaac8fdc4a4d0bb24a809f5ddd422aa7060eb3d2/frozendict-2.4.6-py313-none-any.whl", hash = "sha256:7134a2bb95d4a16556bb5f2b9736dceb6ea848fa5b6f3f6c2d6dba93b44b4757", size = 16146, upload-time = "2024-10-13T12:15:29.495Z" }, | ||
115 | ] | ||
116 | |||
117 | [[package]] | ||
118 | name = "idna" | ||
119 | version = "3.10" | ||
120 | source = { registry = "https://pypi.org/simple" } | ||
121 | sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } | ||
122 | wheels = [ | ||
123 | { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, | ||
124 | ] | ||
125 | |||
126 | [[package]] | ||
127 | name = "jsonpickle" | ||
128 | version = "4.0.5" | ||
129 | source = { registry = "https://pypi.org/simple" } | ||
130 | sdist = { url = "https://files.pythonhosted.org/packages/d6/33/4bda317ab294722fcdfff8f63aab74af9fda3675a4652d984a101aa7587e/jsonpickle-4.0.5.tar.gz", hash = "sha256:f299818b39367c361b3f26bdba827d4249ab5d383cd93144d0f94b5417aacb35", size = 315661, upload-time = "2025-03-29T19:22:56.92Z" } | ||
131 | wheels = [ | ||
132 | { url = "https://files.pythonhosted.org/packages/dc/1b/0e79cf115e0f54f1e8f56effb6ffd2ef8f92e9c324d692ede660067f1bfe/jsonpickle-4.0.5-py3-none-any.whl", hash = "sha256:b4ac7d0a75ddcdfd93445737f1d36ff28768690d43e54bf5d0ddb1d915e580df", size = 46382, upload-time = "2025-03-29T19:22:54.252Z" }, | ||
133 | ] | ||
134 | |||
135 | [[package]] | ||
136 | name = "python-dateutil" | ||
137 | version = "2.9.0.post0" | ||
138 | source = { registry = "https://pypi.org/simple" } | ||
139 | dependencies = [ | ||
140 | { name = "six" }, | ||
141 | ] | ||
142 | sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } | ||
143 | wheels = [ | ||
144 | { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, | ||
145 | ] | ||
146 | |||
147 | [[package]] | ||
148 | name = "pyxdg" | ||
149 | version = "0.28" | ||
150 | source = { registry = "https://pypi.org/simple" } | ||
151 | sdist = { url = "https://files.pythonhosted.org/packages/b0/25/7998cd2dec731acbd438fbf91bc619603fc5188de0a9a17699a781840452/pyxdg-0.28.tar.gz", hash = "sha256:3267bb3074e934df202af2ee0868575484108581e6f3cb006af1da35395e88b4", size = 77776, upload-time = "2022-06-05T11:35:01Z" } | ||
152 | wheels = [ | ||
153 | { url = "https://files.pythonhosted.org/packages/e5/8d/cf41b66a8110670e3ad03dab9b759704eeed07fa96e90fdc0357b2ba70e2/pyxdg-0.28-py2.py3-none-any.whl", hash = "sha256:bdaf595999a0178ecea4052b7f4195569c1ff4d344567bccdc12dfdf02d545ab", size = 49520, upload-time = "2022-06-05T11:34:58.832Z" }, | ||
154 | ] | ||
155 | |||
156 | [[package]] | ||
157 | name = "requests" | ||
158 | version = "2.32.3" | ||
159 | source = { registry = "https://pypi.org/simple" } | ||
160 | dependencies = [ | ||
161 | { name = "certifi" }, | ||
162 | { name = "charset-normalizer" }, | ||
163 | { name = "idna" }, | ||
164 | { name = "urllib3" }, | ||
165 | ] | ||
166 | sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } | ||
167 | wheels = [ | ||
168 | { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, | ||
169 | ] | ||
170 | |||
171 | [[package]] | ||
172 | name = "six" | ||
173 | version = "1.17.0" | ||
174 | source = { registry = "https://pypi.org/simple" } | ||
175 | sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } | ||
176 | wheels = [ | ||
177 | { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, | ||
178 | ] | ||
179 | |||
180 | [[package]] | ||
181 | name = "tabulate" | ||
182 | version = "0.9.0" | ||
183 | source = { registry = "https://pypi.org/simple" } | ||
184 | sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090, upload-time = "2022-10-06T17:21:48.54Z" } | ||
185 | wheels = [ | ||
186 | { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, | ||
187 | ] | ||
188 | |||
189 | [[package]] | ||
190 | name = "toml" | ||
191 | version = "0.10.2" | ||
192 | source = { registry = "https://pypi.org/simple" } | ||
193 | sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } | ||
194 | wheels = [ | ||
195 | { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, | ||
196 | ] | ||
197 | |||
198 | [[package]] | ||
199 | name = "uritools" | ||
200 | version = "4.0.3" | ||
201 | source = { registry = "https://pypi.org/simple" } | ||
202 | sdist = { url = "https://files.pythonhosted.org/packages/d3/43/4182fb2a03145e6d38698e38b49114ce59bc8c79063452eb585a58f8ce78/uritools-4.0.3.tar.gz", hash = "sha256:ee06a182a9c849464ce9d5fa917539aacc8edd2a4924d1b7aabeeecabcae3bc2", size = 24184, upload-time = "2024-05-28T18:07:45.194Z" } | ||
203 | wheels = [ | ||
204 | { url = "https://files.pythonhosted.org/packages/e6/17/5a4510d9ca9cc8be217ce359eb54e693dca81cf4d442308b282d5131b17d/uritools-4.0.3-py3-none-any.whl", hash = "sha256:bae297d090e69a0451130ffba6f2f1c9477244aa0a5543d66aed2d9f77d0dd9c", size = 10304, upload-time = "2024-05-28T18:07:42.731Z" }, | ||
205 | ] | ||
206 | |||
207 | [[package]] | ||
208 | name = "urllib3" | ||
209 | version = "2.3.0" | ||
210 | source = { registry = "https://pypi.org/simple" } | ||
211 | sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268, upload-time = "2024-12-22T07:47:30.032Z" } | ||
212 | wheels = [ | ||
213 | { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369, upload-time = "2024-12-22T07:47:28.074Z" }, | ||
214 | ] | ||
215 | |||
216 | [[package]] | ||
217 | name = "worktime" | ||
218 | version = "1.0.0" | ||
219 | source = { editable = "." } | ||
220 | dependencies = [ | ||
221 | { name = "atomicwriter" }, | ||
222 | { name = "desktop-notify" }, | ||
223 | { name = "frozendict" }, | ||
224 | { name = "jsonpickle" }, | ||
225 | { name = "python-dateutil" }, | ||
226 | { name = "pyxdg" }, | ||
227 | { name = "requests" }, | ||
228 | { name = "tabulate" }, | ||
229 | { name = "toml" }, | ||
230 | { name = "uritools" }, | ||
231 | ] | ||
232 | |||
233 | [package.metadata] | ||
234 | requires-dist = [ | ||
235 | { name = "atomicwriter", specifier = ">=0.2.5" }, | ||
236 | { name = "desktop-notify", specifier = ">=1.3.3" }, | ||
237 | { name = "frozendict", specifier = ">=2.4.6" }, | ||
238 | { name = "jsonpickle", specifier = ">=4.0.5,<5" }, | ||
239 | { name = "python-dateutil", specifier = ">=2.9.0.post0,<3" }, | ||
240 | { name = "pyxdg", specifier = ">=0.28,<0.29" }, | ||
241 | { name = "requests", specifier = ">=2.32.3,<3" }, | ||
242 | { name = "tabulate", specifier = ">=0.9.0,<0.10" }, | ||
243 | { name = "toml", specifier = ">=0.10.2,<0.11" }, | ||
244 | { name = "uritools", specifier = ">=4.0.3,<5" }, | ||
245 | ] | ||
246 | |||
247 | [package.metadata.requires-dev] | ||
248 | dev = [] | ||
diff --git a/overlays/worktime/worktime/__main__.py b/overlays/worktime/worktime/__main__.py index 4eee5dc2..016690f0 100755 --- a/overlays/worktime/worktime/__main__.py +++ b/overlays/worktime/worktime/__main__.py | |||
@@ -1,10 +1,12 @@ | |||
1 | import requests | 1 | import requests |
2 | from requests.exceptions import HTTPError | 2 | from requests.exceptions import HTTPError |
3 | from requests.auth import HTTPBasicAuth | 3 | from requests.auth import HTTPBasicAuth |
4 | from requests.adapters import HTTPAdapter, Retry | ||
4 | from datetime import * | 5 | from datetime import * |
5 | from xdg import BaseDirectory | 6 | from xdg import BaseDirectory |
6 | import toml | 7 | import toml |
7 | from uritools import (uricompose) | 8 | from uritools import uricompose |
9 | from urllib.parse import urljoin | ||
8 | 10 | ||
9 | from inspect import signature | 11 | from inspect import signature |
10 | 12 | ||
@@ -27,77 +29,76 @@ from sys import stderr, stdout | |||
27 | 29 | ||
28 | from tabulate import tabulate | 30 | from tabulate import tabulate |
29 | 31 | ||
30 | from itertools import groupby, count | 32 | from itertools import groupby, count, islice |
31 | from functools import cache, partial | 33 | from functools import cache, partial |
32 | 34 | ||
33 | import backoff | ||
34 | |||
35 | from pathlib import Path | 35 | from pathlib import Path |
36 | 36 | ||
37 | from collections import defaultdict | 37 | from collections import defaultdict |
38 | from collections.abc import Iterable, Generator | ||
39 | from typing import Any | ||
38 | 40 | ||
39 | import jsonpickle | 41 | import jsonpickle |
40 | from hashlib import blake2s | 42 | from hashlib import blake2s |
41 | import json | 43 | import json |
42 | 44 | ||
43 | class TogglAPISection(Enum): | 45 | import asyncio |
44 | TOGGL = '/api/v9' | 46 | |
45 | REPORTS = '/reports/api/v2' | 47 | from frozendict import frozendict |
46 | 48 | from contextlib import closing | |
47 | class TogglAPIError(Exception): | 49 | import os |
48 | def __init__(self, response, *, http_error=None): | 50 | from time import clock_gettime_ns, CLOCK_MONOTONIC |
49 | self.http_error = http_error | 51 | from atomicwriter import AtomicWriter |
50 | self.response = response | 52 | import desktop_notify.aio as notify |
51 | 53 | ||
52 | def __str__(self): | 54 | class BearerAuth(requests.auth.AuthBase): |
53 | if not self.http_error is None: | 55 | def __init__(self, token): |
54 | return str(self.http_error) | 56 | self.token = token |
55 | else: | 57 | def __call__(self, r): |
56 | return self.response.text | 58 | r.headers["authorization"] = "Bearer " + self.token |
57 | 59 | return r | |
58 | class TogglAPI(object): | 60 | |
59 | def __init__(self, api_token, workspace_id, client_ids): | 61 | class KimaiSession(requests.Session): |
60 | self._api_token = api_token | 62 | def __init__(self, base_url: str, api_token: str): |
61 | self._workspace_id = workspace_id | 63 | super().__init__() |
62 | self._client_ids = set(map(int, client_ids.split(','))) if client_ids else None | 64 | self.base_url = base_url |
63 | 65 | self.auth = BearerAuth(api_token) | |
64 | def _make_url(self, api=TogglAPISection.TOGGL, section=['me', 'time_entries', 'current'], params={}): | 66 | retries = Retry(total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504]) |
65 | if api is TogglAPISection.REPORTS: | 67 | super().mount(base_url, HTTPAdapter(max_retries=retries)) |
66 | params.update({'user_agent': 'worktime', 'workspace_id': self._workspace_id}) | 68 | |
67 | 69 | def request(self, method, url, *args, **kwargs): | |
68 | api_path = api.value | 70 | joined_url = urljoin(self.base_url, url) |
69 | section_path = '/'.join(section) | 71 | return super().request(method, joined_url, *args, headers = {'Accept': 'application/json'} | (kwargs['headers'] if 'headers' in kwargs else {}), **{k: v for k, v in kwargs.items() if k not in ['headers']}) |
70 | uri = uricompose(scheme='https', host='api.track.toggl.com', path=f"{api_path}/{section_path}", query=params) | 72 | |
71 | 73 | class KimaiAPI(object): | |
72 | return uri | 74 | def __init__(self, base_url: str, api_token: str, clients: Iterable[str]): |
73 | 75 | self._session = KimaiSession(base_url, api_token) | |
74 | def _query(self, url, method): | 76 | self._kimai_clients = self._session.get('/api/customers').json() |
75 | response = self._raw_query(url, method) | 77 | self._client_ids = self.resolve_clients(clients) |
76 | response.raise_for_status() | 78 | kimai_user = self._session.get('/api/users/me').json() |
77 | return response | 79 | self._tz = gettz(kimai_user['timezone']) |
78 | 80 | ||
79 | @backoff.on_predicate( | 81 | def resolve_clients(self, clients: Iterable[str]) -> frozenset[int]: |
80 | backoff.expo, | 82 | return frozenset({ client['id'] for client in self._kimai_clients if client['name'] in clients }) |
81 | factor=0.1, max_value=2, | 83 | |
82 | predicate=lambda r: r.status_code == 429, | 84 | def render_datetime(self, datetime: datetime) -> str: |
83 | max_time=10, | 85 | return datetime.astimezone(self._tz).strftime('%Y-%m-%dT%H:%M:%S') |
84 | ) | 86 | |
85 | def _raw_query(self, url, method): | 87 | def get_timesheets(self, params: dict[str, Any] = {}) -> Generator[Any]: |
86 | headers = {'content-type': 'application/json', 'accept': 'application/json'} | 88 | for page in count(start=1): |
87 | response = None | 89 | resp = self._session.get('/api/timesheets', params=params | {'size': 100, 'page': page}) |
88 | 90 | if resp.status_code == 404: | |
89 | if method == 'GET': | 91 | break |
90 | response = requests.get(url, headers=headers, auth=HTTPBasicAuth(self._api_token, 'api_token')) | 92 | yield from resp.json() |
91 | elif method == 'POST': | ||
92 | response = requests.post(url, headers=headers, auth=HTTPBasicAuth(self._api_token, 'api_token')) | ||
93 | else: | ||
94 | raise ValueError(f"Undefined HTTP method “{method}”") | ||
95 | |||
96 | return response | ||
97 | 93 | ||
98 | def entry_durations(self, start_date, *, end_date, rounding=False, client_ids): | 94 | def entry_durations(self, start_date: datetime, *, end_date: datetime, clients: Iterable[str] | None = None) -> Generator[timedelta]: |
99 | if client_ids is not None and not client_ids: | 95 | client_ids = None |
96 | if clients is not None and not clients: | ||
100 | return | 97 | return |
98 | elif clients is None: | ||
99 | client_ids = self._client_ids | ||
100 | else: | ||
101 | client_ids = self.resolve_clients(clients) | ||
101 | 102 | ||
102 | cache_dir = Path(BaseDirectory.save_cache_path('worktime')) / 'entry_durations' | 103 | cache_dir = Path(BaseDirectory.save_cache_path('worktime')) / 'entry_durations' |
103 | step = timedelta(days = 120) | 104 | step = timedelta(days = 120) |
@@ -116,11 +117,8 @@ class TogglAPI(object): | |||
116 | cache_key = blake2s(jsonpickle.encode({ | 117 | cache_key = blake2s(jsonpickle.encode({ |
117 | 'start': req_start, | 118 | 'start': req_start, |
118 | 'end': req_end, | 119 | 'end': req_end, |
119 | 'rounding': rounding, | 120 | 'client_ids': client_ids, |
120 | 'clients': client_ids, | 121 | }).encode('utf-8'), key = self._session.auth.token.encode('utf-8')).hexdigest() |
121 | 'workspace': self._workspace_id, | ||
122 | 'workspace_clients': self._client_ids | ||
123 | }).encode('utf-8'), key = self._api_token.encode('utf-8')).hexdigest() | ||
124 | cache_path = cache_dir / cache_key[:2] / cache_key[2:4] / f'{cache_key[4:]}.json' | 122 | cache_path = cache_dir / cache_key[:2] / cache_key[2:4] / f'{cache_key[4:]}.json' |
125 | try: | 123 | try: |
126 | with cache_path.open('r', encoding='utf-8') as ch: | 124 | with cache_path.open('r', encoding='utf-8') as ch: |
@@ -130,85 +128,83 @@ class TogglAPI(object): | |||
130 | pass | 128 | pass |
131 | 129 | ||
132 | entries = list() | 130 | entries = list() |
133 | params = { 'since': (req_start - timedelta(days=1)).date().isoformat(), | 131 | params = { |
134 | 'until': (req_end + timedelta(days=1)).date().isoformat(), | 132 | 'begin': self.render_datetime(req_start), |
135 | 'rounding': 'yes' if rounding else 'no', | 133 | 'end': self.render_datetime(req_end), |
136 | 'billable': 'yes' | 134 | 'customers[]': list(client_ids), |
137 | } | 135 | 'billable': 1, |
138 | if client_ids is not None: | 136 | } |
139 | params |= { 'client_ids': ','.join(map(str, client_ids)) } | 137 | |
140 | for page in count(start = 1): | 138 | for entry in self.get_timesheets(params): |
141 | url = self._make_url(api = TogglAPISection.REPORTS, section = ['details'], params = params | { 'page': page }) | 139 | if entry['end'] is None: |
142 | r = self._query(url = url, method='GET') | 140 | continue |
143 | if not r or not r.json(): | ||
144 | raise TogglAPIError(r) | ||
145 | report = r.json() | ||
146 | for entry in report['data']: | ||
147 | start = isoparse(entry['start']) | ||
148 | end = isoparse(entry['end']) | ||
149 | |||
150 | if start > req_end or end < req_start: | ||
151 | continue | ||
152 | 141 | ||
153 | x = min(end, req_end) - max(start, req_start) | 142 | start = isoparse(entry['begin']) |
154 | if cache_key: | 143 | end = isoparse(entry['end']) |
155 | entries.append(x) | 144 | |
156 | yield x | 145 | if start > req_end or end < req_start: |
157 | if not report['data']: | 146 | continue |
158 | break | 147 | |
148 | x = min(end, req_end) - max(start, req_start) | ||
149 | if cache_key: | ||
150 | entries.append(x) | ||
151 | yield x | ||
159 | 152 | ||
160 | if cache_path: | 153 | if cache_path: |
161 | cache_path.parent.mkdir(parents=True, exist_ok=True) | 154 | cache_path.parent.mkdir(parents=True, exist_ok=True) |
162 | with cache_path.open('w', encoding='utf-8') as ch: | 155 | with cache_path.open('w', encoding='utf-8') as ch: |
163 | ch.write(jsonpickle.encode(entries)) | 156 | ch.write(jsonpickle.encode(entries)) |
164 | # res = timedelta(milliseconds=report['total_billable']) if report['total_billable'] else timedelta(milliseconds=0) | ||
165 | # return res | ||
166 | |||
167 | def get_billable_hours(self, start_date, end_date=datetime.now(timezone.utc), rounding=False): | ||
168 | billable_acc = timedelta(milliseconds = 0) | ||
169 | if 0 in self._client_ids: | ||
170 | url = self._make_url(api = TogglAPISection.TOGGL, section = ['workspaces', self._workspace_id, 'clients']) | ||
171 | r = self._query(url = url, method = 'GET') | ||
172 | if not r or not r.json(): | ||
173 | raise TogglAPIError(r) | ||
174 | |||
175 | billable_acc += sum(self.entry_durations(start_date, end_date=end_date, rounding=rounding, client_ids=None), start=timedelta(milliseconds=0)) - sum(self.entry_durations(start_date, end_date=end_date, rounding=rounding, client_ids=frozenset(map(lambda c: c['id'], r.json()))), start=timedelta(milliseconds=0)) | ||
176 | 157 | ||
177 | billable_acc += sum(self.entry_durations(start_date, end_date=end_date, rounding=rounding, client_ids=frozenset(*(self._client_ids - {0}))), start=timedelta(milliseconds=0)) | 158 | def get_billable_hours(self, start_date: datetime, end_date: datetime = datetime.now(timezone.utc)) -> timedelta: |
159 | return sum(self.entry_durations(start_date, end_date=end_date), start=timedelta(milliseconds=0)) | ||
178 | 160 | ||
179 | return billable_acc | 161 | def get_running_entry(self) -> Any | None: |
162 | kimai_entries = self._session.get('/api/timesheets/active').json() | ||
163 | if not kimai_entries: | ||
164 | return None | ||
165 | entry = kimai_entries[0] | ||
180 | 166 | ||
181 | def get_running_clock(self, now=datetime.now(timezone.utc)): | 167 | if entry['project']['customer']['id'] not in self._client_ids: |
182 | url = self._make_url(api = TogglAPISection.TOGGL, section = ['me', 'time_entries', 'current']) | 168 | return None |
183 | r = self._query(url = url, method='GET') | ||
184 | 169 | ||
185 | if not r or (not r.json() and r.json() is not None): | 170 | return entry |
186 | raise TogglAPIError(r) | ||
187 | 171 | ||
188 | if not r.json() or not r.json()['billable']: | 172 | def get_running_clock(self, now: datetime = datetime.now(timezone.utc)) -> timedelta | None: |
173 | entry = self.get_running_entry() | ||
174 | if not entry: | ||
189 | return None | 175 | return None |
176 | start = isoparse(entry['begin']) | ||
177 | return now - start if start <= now else None | ||
190 | 178 | ||
191 | if self._client_ids is not None: | 179 | def get_recent_entries(self) -> Generator[Any]: |
192 | if 'pid' in r.json() and r.json()['pid']: | 180 | step = timedelta(days = 7) |
193 | url = self._make_url(api = TogglAPISection.TOGGL, section = ['projects', str(r.json()['pid'])]) | 181 | now = datetime.now().astimezone(timezone.utc) |
194 | pr = self._query(url = url, method = 'GET') | 182 | ids = set() |
195 | if not pr or not pr.json(): | 183 | for req_end in (now - step * i for i in count()): |
196 | raise TogglAPIError(pr) | 184 | params = { |
185 | 'begin': self.render_datetime(req_end - step), | ||
186 | 'end': self.render_datetime(req_end), | ||
187 | 'full': 'true', | ||
188 | } | ||
189 | for entry in self.get_timesheets(params): | ||
190 | if entry['id'] in ids: | ||
191 | continue | ||
192 | ids.add(entry['id']) | ||
193 | yield entry | ||
197 | 194 | ||
198 | if not pr.json(): | 195 | def start_clock(self, project_id: int, activity_id: int, description: str | None = None, tags: Iterable[str] | None = None, billable: bool = True): |
199 | return None | 196 | self._session.post('/api/timesheets', json={ |
197 | 'begin': self.render_datetime(datetime.now()), | ||
198 | 'project': project_id, | ||
199 | 'activity': activity_id, | ||
200 | 'description': description if description else '', | ||
201 | 'tags': (','.join(tags)) if tags else '', | ||
202 | 'billable': billable, | ||
203 | }).raise_for_status() | ||
200 | 204 | ||
201 | if 'cid' in pr.json() and pr.json()['cid']: | 205 | def stop_clock(self, running_id: int): |
202 | if pr.json()['cid'] not in self._client_ids: | 206 | self._session.patch(f'/api/timesheets/{running_id}/stop').raise_for_status() |
203 | return None | ||
204 | elif 0 not in self._client_ids: | ||
205 | return None | ||
206 | elif 0 not in self._client_ids: | ||
207 | return None | ||
208 | 207 | ||
209 | start = isoparse(r.json()['start']) | ||
210 | |||
211 | return now - start if start <= now else None | ||
212 | 208 | ||
213 | class Worktime(object): | 209 | class Worktime(object): |
214 | time_worked = timedelta() | 210 | time_worked = timedelta() |
@@ -281,10 +277,10 @@ class Worktime(object): | |||
281 | 277 | ||
282 | config = Worktime.config() | 278 | config = Worktime.config() |
283 | config_dir = BaseDirectory.load_first_config('worktime') | 279 | config_dir = BaseDirectory.load_first_config('worktime') |
284 | api = TogglAPI( | 280 | api = KimaiAPI( |
285 | api_token=config.get("TOGGL", {}).get("ApiToken", None), | 281 | base_url=config.get("KIMAI", {}).get("BaseUrl", None), |
286 | workspace_id=config.get("TOGGL", {}).get("Workspace", None), | 282 | api_token=config.get("KIMAI", {}).get("ApiToken", None), |
287 | client_ids=config.get("TOGGL", {}).get("ClientIds", None) | 283 | clients=config.get("KIMAI", {}).get("Clients", None) |
288 | ) | 284 | ) |
289 | date_format = config.get("WORKTIME", {}).get("DateFormat", '%Y-%m-%d') | 285 | date_format = config.get("WORKTIME", {}).get("DateFormat", '%Y-%m-%d') |
290 | 286 | ||
@@ -379,10 +375,7 @@ class Worktime(object): | |||
379 | parse_datestr(stripped_line) | 375 | parse_datestr(stripped_line) |
380 | 376 | ||
381 | for day in [fromDay + timedelta(days = x) for x in range(0, (toDay - fromDay).days + 1)]: | 377 | for day in [fromDay + timedelta(days = x) for x in range(0, (toDay - fromDay).days + 1)]: |
382 | if self.end_date.date() < day or day < self.start_date.date(): | 378 | if self.would_be_workday(day) and self.start_date.date() <= day and day <= self.end_date.date(): |
383 | continue | ||
384 | |||
385 | if self.would_be_workday(day): | ||
386 | if excused_kind == 'leave': | 379 | if excused_kind == 'leave': |
387 | self.leave_days.add(day) | 380 | self.leave_days.add(day) |
388 | elif time is not None and time >= self.time_per_day(day): | 381 | elif time is not None and time >= self.time_per_day(day): |
@@ -397,9 +390,29 @@ class Worktime(object): | |||
397 | start_day = self.start_date.date() | 390 | start_day = self.start_date.date() |
398 | end_day = self.end_date.date() | 391 | end_day = self.end_date.date() |
399 | 392 | ||
393 | self.extra_days_to_work = dict() | ||
394 | |||
400 | try: | 395 | try: |
401 | with open(Path(config_dir) / "pull-forward", 'r') as excused: | 396 | with open(Path(config_dir) / "days-to-work", 'r') as extra_days_to_work_file: |
402 | for line in excused: | 397 | for line in extra_days_to_work_file: |
398 | stripped_line = line.strip() | ||
399 | if stripped_line: | ||
400 | splitLine = stripped_line.split(' ') | ||
401 | if len(splitLine) == 2: | ||
402 | [hours, datestr] = splitLine | ||
403 | day = datetime.strptime(datestr, date_format).replace(tzinfo=tzlocal()).date() | ||
404 | self.extra_days_to_work[day] = timedelta(hours = float(hours)) | ||
405 | else: | ||
406 | day = datetime.strptime(stripped_line, date_format).replace(tzinfo=tzlocal()).date() | ||
407 | self.extra_days_to_work[day] = self.time_per_day(day) | ||
408 | except IOError as e: | ||
409 | if e.errno != 2: | ||
410 | raise e | ||
411 | |||
412 | |||
413 | try: | ||
414 | with open(Path(config_dir) / "pull-forward", 'r') as pull_forward: | ||
415 | for line in pull_forward: | ||
403 | stripped_line = line.strip() | 416 | stripped_line = line.strip() |
404 | if stripped_line: | 417 | if stripped_line: |
405 | [hours, datestr] = stripped_line.split(' ') | 418 | [hours, datestr] = stripped_line.split(' ') |
@@ -420,15 +433,22 @@ class Worktime(object): | |||
420 | if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break | 433 | if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break |
421 | else: | 434 | else: |
422 | if d >= self.end_date.date(): | 435 | if d >= self.end_date.date(): |
423 | self.pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta())) | 436 | time_for_day = self.time_per_day(d) if d.isoweekday() in self.workdays else timedelta() |
437 | if d in self.extra_days_to_work: | ||
438 | time_for_day += self.extra_days_to_work[d] | ||
439 | self.pull_forward[d] = min(timedelta(hours = float(hours)), time_for_day) | ||
424 | except IOError as e: | 440 | except IOError as e: |
425 | if e.errno != 2: | 441 | if e.errno != 2: |
426 | raise e | 442 | raise e |
427 | 443 | ||
444 | if self.pull_forward: | ||
445 | for year in range(self.end_date.year + 1, max(self.pull_forward.keys()).year + 1): | ||
446 | holidays |= {k: v * timedelta(hours = hours_per_week(k)) / len(self.workdays) for k, v in Worktime.holidays(year).items()} | ||
447 | |||
428 | self.days_to_work = dict() | 448 | self.days_to_work = dict() |
429 | 449 | ||
430 | if self.pull_forward: | 450 | # if self.pull_forward: |
431 | end_day = max(end_day, max(list(self.pull_forward))) | 451 | # end_day = max(end_day, max(self.pull_forward.keys())) |
432 | 452 | ||
433 | for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: | 453 | for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: |
434 | if day.isoweekday() in self.workdays: | 454 | if day.isoweekday() in self.workdays: |
@@ -436,26 +456,6 @@ class Worktime(object): | |||
436 | if time_to_work > timedelta(): | 456 | if time_to_work > timedelta(): |
437 | self.days_to_work[day] = time_to_work | 457 | self.days_to_work[day] = time_to_work |
438 | 458 | ||
439 | self.extra_days_to_work = dict() | ||
440 | |||
441 | try: | ||
442 | with open(Path(config_dir) / "days-to-work", 'r') as extra_days_to_work_file: | ||
443 | for line in extra_days_to_work_file: | ||
444 | stripped_line = line.strip() | ||
445 | if stripped_line: | ||
446 | splitLine = stripped_line.split(' ') | ||
447 | if len(splitLine) == 2: | ||
448 | [hours, datestr] = splitLine | ||
449 | day = datetime.strptime(datestr, date_format).replace(tzinfo=tzlocal()).date() | ||
450 | self.extra_days_to_work[day] = timedelta(hours = float(hours)) | ||
451 | else: | ||
452 | day = datetime.strptime(stripped_line, date_format).replace(tzinfo=tzlocal()).date() | ||
453 | self.extra_days_to_work[day] = self.time_per_day(day) | ||
454 | except IOError as e: | ||
455 | if e.errno != 2: | ||
456 | raise e | ||
457 | |||
458 | |||
459 | self.now_is_workday = self.is_workday(self.now.date()) | 459 | self.now_is_workday = self.is_workday(self.now.date()) |
460 | 460 | ||
461 | self.time_worked = timedelta() | 461 | self.time_worked = timedelta() |
@@ -471,9 +471,9 @@ class Worktime(object): | |||
471 | 471 | ||
472 | self.time_to_work = sum([self.days_to_work[day] for day in self.days_to_work.keys() if day <= self.end_date.date()], timedelta()) | 472 | self.time_to_work = sum([self.days_to_work[day] for day in self.days_to_work.keys() if day <= self.end_date.date()], timedelta()) |
473 | for day in [d for d in list(self.pull_forward) if d > self.end_date.date()]: | 473 | for day in [d for d in list(self.pull_forward) if d > self.end_date.date()]: |
474 | days_forward = set([d for d in self.days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in self.pull_forward or d == self.end_date.date())]) | 474 | days_forward = set([d for d in [start_day + timedelta(days = x) for x in range(0, (day - start_day).days + 1)] if d >= self.end_date.date() and d < day and (d not in self.pull_forward or d == self.end_date.date())]) |
475 | extra_days_forward = set([d for d in self.extra_days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in self.pull_forward or d == self.end_date.date())]) | 475 | extra_days_forward = set([d for d in self.extra_days_to_work.keys() if d >= self.end_date.date() and d < day and (d not in self.pull_forward or d == self.end_date.date())]) |
476 | days_forward = days_forward.union(extra_days_forward) | 476 | days_forward |= extra_days_forward |
477 | 477 | ||
478 | extra_day_time_left = timedelta() | 478 | extra_day_time_left = timedelta() |
479 | for extra_day in extra_days_forward: | 479 | for extra_day in extra_days_forward: |
@@ -486,17 +486,30 @@ class Worktime(object): | |||
486 | day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) | 486 | day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) |
487 | self.extra_days_to_work[extra_day] += extra_day_time * (day_time / extra_day_time_left) | 487 | self.extra_days_to_work[extra_day] += extra_day_time * (day_time / extra_day_time_left) |
488 | 488 | ||
489 | hours_per_day_forward = time_forward / len(days_forward) if len(days_forward) > 0 else timedelta() | 489 | def days_count(days_forward): |
490 | r = 0 | ||
491 | for day in sorted(days_forward): | ||
492 | day_time = timedelta() | ||
493 | if day in self.extra_days_to_work: | ||
494 | day_time += self.extra_days_to_work | ||
495 | if day in holidays and not day in self.extra_days_to_work: | ||
496 | day_time -= holidays[day] | ||
497 | if day.isoweekday() in self.workdays: | ||
498 | day_time += timedelta(hours = hours_per_week(day)) / len(self.workdays) | ||
499 | r += max(timedelta(), day_time) / (timedelta(hours = hours_per_week(day)) / len(self.workdays)) | ||
500 | return r | ||
501 | |||
502 | hours_per_day_forward = time_forward / days_count(days_forward) if days_count(days_forward) > 0 else timedelta() | ||
490 | days_forward.discard(self.end_date.date()) | 503 | days_forward.discard(self.end_date.date()) |
491 | 504 | ||
492 | self.time_pulled_forward += time_forward - hours_per_day_forward * len(days_forward) | 505 | self.time_pulled_forward += time_forward - hours_per_day_forward * days_count(days_forward) |
493 | 506 | ||
494 | if self.end_date.date() in self.extra_days_to_work: | 507 | if self.end_date.date() in self.extra_days_to_work: |
495 | self.time_pulled_forward += self.extra_days_to_work[self.end_date.date()] | 508 | self.time_pulled_forward += self.extra_days_to_work[self.end_date.date()] |
496 | 509 | ||
497 | self.time_to_work += self.time_pulled_forward | 510 | # self.time_to_work += self.time_pulled_forward |
498 | 511 | ||
499 | self.time_worked += api.get_billable_hours(self.start_date, self.now, rounding = config.get("WORKTIME", {}).get("rounding", True)) | 512 | self.time_worked += api.get_billable_hours(self.start_date, self.now) |
500 | 513 | ||
501 | def format_days(worktime, days, date_format=None): | 514 | def format_days(worktime, days, date_format=None): |
502 | if not date_format: | 515 | if not date_format: |
@@ -573,7 +586,7 @@ def worktime(pull_forward_cutoff, waybar, **args): | |||
573 | pull_forward_sum = sum(worktime.pull_forward.values(), start=timedelta(milliseconds=0)) | 586 | pull_forward_sum = sum(worktime.pull_forward.values(), start=timedelta(milliseconds=0)) |
574 | if pull_forward_sum >= min(pull_forward_cutoff, timedelta(seconds = 1)): | 587 | if pull_forward_sum >= min(pull_forward_cutoff, timedelta(seconds = 1)): |
575 | worktime_no_pulled_forward = deepcopy(worktime) | 588 | worktime_no_pulled_forward = deepcopy(worktime) |
576 | worktime_no_pulled_forward.time_to_work -= worktime_no_pulled_forward.time_pulled_forward | 589 | # worktime_no_pulled_forward.time_to_work -= worktime_no_pulled_forward.time_pulled_forward |
577 | worktime_no_pulled_forward.time_pulled_forward = timedelta() | 590 | worktime_no_pulled_forward.time_pulled_forward = timedelta() |
578 | worktime_no_pulled_forward.pull_forward = dict() | 591 | worktime_no_pulled_forward.pull_forward = dict() |
579 | worktime.time_to_work += pull_forward_sum | 592 | worktime.time_to_work += pull_forward_sum |
@@ -611,7 +624,7 @@ def time_worked(now, waybar, **args): | |||
611 | out_text = None | 624 | out_text = None |
612 | out_class = "running" if now.running_entry else "stopped" | 625 | out_class = "running" if now.running_entry else "stopped" |
613 | tooltip = tooltip_timedelta(worked) | 626 | tooltip = tooltip_timedelta(worked) |
614 | target_time = max(then.time_per_day(then.now.date()), now.time_per_day(now.now.date())) if then.time_per_day(then.now.date()) and now.time_per_day(now.now.date()) else (then.time_per_day(then.now.date()) if then.time_per_day(then.now.date()) else now.time_per_day(now.now.date())); | 627 | target_time = max(then.time_per_day(then.now.date()), now.time_per_day(now.now.date())) if then.time_per_day(then.now.date()) and now.time_per_day(now.now.date()) else (then.time_per_day(then.now.date()) if then.time_per_day(then.now.date()) else now.time_per_day(now.now.date())) |
615 | difference = target_time - worked | 628 | difference = target_time - worked |
616 | difference_pull_forward = difference + now.time_pulled_forward | 629 | difference_pull_forward = difference + now.time_pulled_forward |
617 | if now.running_entry and difference_pull_forward < timedelta(seconds=0): | 630 | if now.running_entry and difference_pull_forward < timedelta(seconds=0): |
@@ -886,7 +899,7 @@ def main(): | |||
886 | 899 | ||
887 | config = Worktime.config() | 900 | config = Worktime.config() |
888 | 901 | ||
889 | parser = argparse.ArgumentParser(prog = "worktime", description = 'Track worktime using toggl API') | 902 | parser = argparse.ArgumentParser(prog = "worktime", description = 'Track worktime using Kimai API') |
890 | parser.add_argument('--time', dest = 'now', metavar = 'TIME', type = isotime, help = 'Time to calculate status for (default: current time)', default = datetime.now(tzlocal())) | 903 | parser.add_argument('--time', dest = 'now', metavar = 'TIME', type = isotime, help = 'Time to calculate status for (default: current time)', default = datetime.now(tzlocal())) |
891 | parser.add_argument('--start', dest = 'start_datetime', metavar = 'TIME', type = isotime, help = 'Time to calculate status from (default: None)', default = None) | 904 | parser.add_argument('--start', dest = 'start_datetime', metavar = 'TIME', type = isotime, help = 'Time to calculate status from (default: None)', default = None) |
892 | parser.add_argument('--no-running', dest = 'include_running', action = 'store_false') | 905 | parser.add_argument('--no-running', dest = 'include_running', action = 'store_false') |
@@ -923,5 +936,139 @@ def main(): | |||
923 | 936 | ||
924 | args.cmd(**vars(args)) | 937 | args.cmd(**vars(args)) |
925 | 938 | ||
939 | async def ui_update_options(api, cache_path): | ||
940 | options = set() | ||
941 | sort_order = dict() | ||
942 | entry_iter = enumerate(api.get_recent_entries()) | ||
943 | loop = asyncio.get_event_loop() | ||
944 | start = clock_gettime_ns(CLOCK_MONOTONIC) | ||
945 | while item := await loop.run_in_executor(None, next, entry_iter): | ||
946 | ix, entry = item | ||
947 | if len(options) >= 20 or ix >= 1000: | ||
948 | break | ||
949 | elif len(options) >= 3: | ||
950 | now = clock_gettime_ns(CLOCK_MONOTONIC) | ||
951 | if now - start >= 4000000000: | ||
952 | break | ||
953 | |||
954 | option = frozendict({ | ||
955 | 'tags': frozenset(entry['tags']), | ||
956 | 'activity': frozendict({'id': entry['activity']['id'], 'name': entry['activity']['name']}), | ||
957 | 'project': frozendict({'id': entry['project']['id'], 'customer': entry['project']['customer']['name'], 'name': entry['project']['name']}), | ||
958 | 'description': entry['description'] if entry['description'] else None, | ||
959 | 'billable': entry['billable'], | ||
960 | }) | ||
961 | sort_value = isoparse(entry['begin']) | ||
962 | if option in sort_order: | ||
963 | sort_value = max(sort_value, sort_order[option]) | ||
964 | sort_order[option] = sort_value | ||
965 | options.add(option) | ||
966 | |||
967 | options = list(sorted(options, key = lambda o: sort_order[o], reverse = True)) | ||
968 | |||
969 | with AtomicWriter(cache_path, overwrite=True) as ch: | ||
970 | ch.write_text(jsonpickle.encode(options)) | ||
971 | |||
972 | return options | ||
973 | |||
974 | def ui_render_option(option): | ||
975 | res = '' | ||
976 | if option['description']: | ||
977 | res += '„{}“, '.format(option['description']) | ||
978 | res += option['activity']['name'] + ', ' | ||
979 | res += option['project']['name'] | ||
980 | if option['project']['customer'] not in option['project']['name']: | ||
981 | res += ' ({})'.format(option['project']['customer']) | ||
982 | if option['tags']: | ||
983 | res += ', {}'.format(' '.join(map(lambda t: '#{}'.format(t), option['tags']))) | ||
984 | if not option['billable']: | ||
985 | res += ', not billable' | ||
986 | return res | ||
987 | |||
988 | async def ui_main(): | ||
989 | cache_path = Path(BaseDirectory.save_cache_path('worktime-ui')) / 'options.json' | ||
990 | options = None | ||
991 | try: | ||
992 | with cache_path.open('r', encoding='utf-8') as ch: | ||
993 | options = jsonpickle.decode(ch.read()) | ||
994 | except FileNotFoundError: | ||
995 | pass | ||
996 | |||
997 | config = Worktime.config() | ||
998 | api = KimaiAPI( | ||
999 | base_url=config.get("KIMAI", {}).get("BaseUrl", None), | ||
1000 | api_token=config.get("KIMAI", {}).get("ApiToken", None), | ||
1001 | clients=config.get("KIMAI", {}).get("Clients", None) | ||
1002 | ) | ||
1003 | running_entry = api.get_running_entry() | ||
1004 | |||
1005 | async with asyncio.TaskGroup() as tg: | ||
1006 | update_options = tg.create_task(ui_update_options(api, cache_path)) | ||
1007 | if not options: | ||
1008 | options = await update_options | ||
1009 | |||
1010 | read_fd, write_fd = os.pipe() | ||
1011 | w_pipe = open(write_fd, 'wb', 0) | ||
1012 | loop = asyncio.get_event_loop() | ||
1013 | w_transport, _ = await loop.connect_write_pipe( | ||
1014 | asyncio.Protocol, | ||
1015 | w_pipe, | ||
1016 | ) | ||
1017 | r_pipe = open(read_fd, 'rb', 0) | ||
1018 | |||
1019 | proc = await asyncio.create_subprocess_exec( | ||
1020 | "fuzzel", "--dmenu", "--index", "--width=60", | ||
1021 | stdout = asyncio.subprocess.PIPE, | ||
1022 | stdin = r_pipe, | ||
1023 | ) | ||
1024 | |||
1025 | with closing(w_transport) as t: | ||
1026 | if running_entry: | ||
1027 | t.write(b'Stop running timesheet\n') | ||
1028 | for option in options: | ||
1029 | t.write(ui_render_option(option).encode('utf-8') + b'\n') | ||
1030 | |||
1031 | stdout, _ = await proc.communicate() | ||
1032 | if proc.returncode != 0: | ||
1033 | return | ||
1034 | fuzzel_out = int(stdout.decode('utf-8')) | ||
1035 | if fuzzel_out < 0 or fuzzel_out >= len(options): | ||
1036 | return | ||
1037 | elif running_entry and fuzzel_out == 0: | ||
1038 | api.stop_clock(running_entry['id']) | ||
1039 | await notify.Server('worktime').Notify("Stopped running timesheet").set_timeout(65000).show() | ||
1040 | else: | ||
1041 | if running_entry: | ||
1042 | fuzzel_out -= 1 | ||
1043 | option = options[fuzzel_out] | ||
1044 | api.start_clock( | ||
1045 | project_id = option['project']['id'], | ||
1046 | activity_id = option['activity']['id'], | ||
1047 | description = option['description'], | ||
1048 | tags = option['tags'], | ||
1049 | billable = option['billable'], | ||
1050 | ) | ||
1051 | await notify.Server('worktime').Notify("Timesheet started…").set_timeout(65000).show() | ||
1052 | |||
1053 | |||
1054 | def ui(): | ||
1055 | asyncio.run(ui_main()) | ||
1056 | |||
1057 | async def stop_main(): | ||
1058 | config = Worktime.config() | ||
1059 | api = KimaiAPI( | ||
1060 | base_url=config.get("KIMAI", {}).get("BaseUrl", None), | ||
1061 | api_token=config.get("KIMAI", {}).get("ApiToken", None), | ||
1062 | clients=config.get("KIMAI", {}).get("Clients", None) | ||
1063 | ) | ||
1064 | if running_entry := api.get_running_entry(): | ||
1065 | api.stop_clock(running_entry['id']) | ||
1066 | await notify.Server('worktime').Notify("Stopped running timesheet").set_timeout(65000).show() | ||
1067 | else: | ||
1068 | await notify.Server('worktime').Notify("No timesheet currently running").set_timeout(65000).show() | ||
1069 | |||
1070 | def stop(): | ||
1071 | asyncio.run(stop_main()) | ||
1072 | |||
926 | if __name__ == "__main__": | 1073 | if __name__ == "__main__": |
927 | sys.exit(main()) | 1074 | sys.exit(main()) |
diff --git a/overlays/yt-dlp.nix b/overlays/yt-dlp.nix index 94ab1fdd..9a54a32b 100644 --- a/overlays/yt-dlp.nix +++ b/overlays/yt-dlp.nix | |||
@@ -1,5 +1,7 @@ | |||
1 | { prev, sources, ... }: { | 1 | { prev, sources, ... }: { |
2 | yt-dlp = prev.yt-dlp.overrideAttrs (oldAttrs: { | 2 | yt-dlp = prev.yt-dlp.overrideAttrs (oldAttrs: { |
3 | inherit (sources.yt-dlp) pname version src; | 3 | inherit (sources.yt-dlp) pname version src; |
4 | |||
5 | postPatch = ""; | ||
4 | }); | 6 | }); |
5 | } | 7 | } |
diff --git a/system-profiles/bcachefs.nix b/system-profiles/bcachefs.nix index f9f048b9..be12bf20 100644 --- a/system-profiles/bcachefs.nix +++ b/system-profiles/bcachefs.nix | |||
@@ -1,6 +1,16 @@ | |||
1 | { pkgs, ... } : { | 1 | { pkgs, lib, ... } : { |
2 | config = { | 2 | config = { |
3 | boot.supportedFilesystems.bcachefs = true; | 3 | boot.supportedFilesystems.bcachefs = true; |
4 | environment.systemPackages = with pkgs; [ bcachefs-tools ]; | 4 | environment.systemPackages = with pkgs; [ bcachefs-tools ]; |
5 | |||
6 | boot.kernelPatches = [ | ||
7 | { | ||
8 | name = "bcachefs-casefold-fix"; | ||
9 | patch = null; | ||
10 | structuredExtraConfig = with lib.kernel; { | ||
11 | UNICODE = lib.mkOverride 90 no; | ||
12 | }; | ||
13 | } | ||
14 | ]; | ||
5 | }; | 15 | }; |
6 | } | 16 | } |
diff --git a/system-profiles/core/default.nix b/system-profiles/core/default.nix index 229a007e..e5f9dc16 100644 --- a/system-profiles/core/default.nix +++ b/system-profiles/core/default.nix | |||
@@ -180,13 +180,7 @@ in { | |||
180 | }; | 180 | }; |
181 | environment.systemPackages = with pkgs; [ git-annex scutiger ]; | 181 | environment.systemPackages = with pkgs; [ git-annex scutiger ]; |
182 | } | 182 | } |
183 | ] ++ (optional (options ? system.switch.enableNg) { | 183 | ] ++ (optional (options ? system.rebuild.enableNg) { |
184 | system.switch = lib.mkDefault { | ||
185 | enable = false; | ||
186 | enableNg = true; | ||
187 | }; | ||
188 | }) | ||
189 | ++ (optional (options ? system.rebuild.enableNg) { | ||
190 | system.rebuild.enableNg = lib.mkDefault true; | 184 | system.rebuild.enableNg = lib.mkDefault true; |
191 | }) | 185 | }) |
192 | ++ (optional (options ? services.userborn) { | 186 | ++ (optional (options ? services.userborn) { |
diff --git a/system-profiles/initrd-all-crypto-modules.nix b/system-profiles/initrd-all-crypto-modules.nix index 45cd4b74..da6c781e 100644 --- a/system-profiles/initrd-all-crypto-modules.nix +++ b/system-profiles/initrd-all-crypto-modules.nix | |||
@@ -18,7 +18,7 @@ in { | |||
18 | { | 18 | { |
19 | name = "encrypted_key"; | 19 | name = "encrypted_key"; |
20 | patch = null; | 20 | patch = null; |
21 | extraStructuredConfig.ENCRYPTED_KEYS = lib.kernel.yes; | 21 | structuredExtraConfig.ENCRYPTED_KEYS = lib.kernel.yes; |
22 | } | 22 | } |
23 | ]; | 23 | ]; |
24 | } | 24 | } |
diff --git a/system-profiles/lanzaboote.nix b/system-profiles/lanzaboote.nix new file mode 100644 index 00000000..f1e179cf --- /dev/null +++ b/system-profiles/lanzaboote.nix | |||
@@ -0,0 +1,14 @@ | |||
1 | { flakeInputs, pkgs, ... }: | ||
2 | { | ||
3 | imports = [ | ||
4 | flakeInputs.lanzaboote.nixosModules.lanzaboote | ||
5 | ]; | ||
6 | |||
7 | config = { | ||
8 | environment.systemPackages = [ pkgs.sbctl ]; | ||
9 | boot.lanzaboote = { | ||
10 | enable = true; | ||
11 | pkiBundle = "/var/lib/sbctl"; | ||
12 | }; | ||
13 | }; | ||
14 | } | ||
diff --git a/system-profiles/nfsroot.nix b/system-profiles/nfsroot.nix index b0116d61..e3dc2d2e 100644 --- a/system-profiles/nfsroot.nix +++ b/system-profiles/nfsroot.nix | |||
@@ -1,4 +1,4 @@ | |||
1 | { config, options, pkgs, lib, flake, flakeInputs, ... }: | 1 | { config, options, pkgs, lib, flake, ... }: |
2 | 2 | ||
3 | with lib; | 3 | with lib; |
4 | 4 | ||
@@ -86,7 +86,7 @@ in { | |||
86 | mkdir -p /mnt-root/etc/ | 86 | mkdir -p /mnt-root/etc/ |
87 | cp /etc/resolv.conf /mnt-root/etc/resolv.conf | 87 | cp /etc/resolv.conf /mnt-root/etc/resolv.conf |
88 | ''; | 88 | ''; |
89 | networking.useDHCP = true; | 89 | networking.useDHCP = mkImageMediaOverride true; |
90 | networking.resolvconf.enable = false; | 90 | networking.resolvconf.enable = false; |
91 | networking.dhcpcd.persistent = true; | 91 | networking.dhcpcd.persistent = true; |
92 | 92 | ||
diff --git a/system-profiles/zfs.nix b/system-profiles/zfs.nix index a93dddd2..af9f1c17 100644 --- a/system-profiles/zfs.nix +++ b/system-profiles/zfs.nix | |||
@@ -1,4 +1,4 @@ | |||
1 | { pkgs, lib, ... } : { | 1 | { config, pkgs, lib, ... } : { |
2 | config = { | 2 | config = { |
3 | boot = { | 3 | boot = { |
4 | kernelPackages = pkgs.linuxPackages_6_12; | 4 | kernelPackages = pkgs.linuxPackages_6_12; |
diff --git a/user-profiles/tmux/default.nix b/user-profiles/tmux/default.nix index dc4e791f..7ea0c0d5 100644 --- a/user-profiles/tmux/default.nix +++ b/user-profiles/tmux/default.nix | |||
@@ -16,8 +16,8 @@ | |||
16 | 16 | ||
17 | installPhase = '' | 17 | installPhase = '' |
18 | substitute $src $out \ | 18 | substitute $src $out \ |
19 | --subst-var-by zsh ${config.programs.zsh.package} \ | 19 | --subst-var-by zsh ${lib.getExe config.programs.zsh.package} \ |
20 | --subst-var-by man ${config.programs.man.package} | 20 | --subst-var-by man ${lib.getExe config.programs.man.package} |
21 | ''; | 21 | ''; |
22 | }); | 22 | }); |
23 | }; | 23 | }; |
diff --git a/user-profiles/utils.nix b/user-profiles/utils.nix index da79e336..edf6da11 100644 --- a/user-profiles/utils.nix +++ b/user-profiles/utils.nix | |||
@@ -46,6 +46,8 @@ in { | |||
46 | lesspipe.enable = true; | 46 | lesspipe.enable = true; |
47 | 47 | ||
48 | man.enable = true; | 48 | man.enable = true; |
49 | |||
50 | vim.enable = true; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | home.sessionVariables = { | 53 | home.sessionVariables = { |
diff --git a/user-profiles/yt-dlp.nix b/user-profiles/yt-dlp.nix index ef0be87e..5c9858a6 100644 --- a/user-profiles/yt-dlp.nix +++ b/user-profiles/yt-dlp.nix | |||
@@ -13,11 +13,12 @@ | |||
13 | "best" | 13 | "best" |
14 | ]; | 14 | ]; |
15 | embed-subs = true; | 15 | embed-subs = true; |
16 | embed-thumbnail = true; | ||
17 | embed-metadata = true; | ||
16 | # write-subs = true; | 18 | # write-subs = true; |
17 | write-auto-subs = true; | 19 | write-auto-subs = true; |
18 | sub-langs = "en(-(gb|us|orig))?,de(-(de|orig))?,-live_chat,-rechat"; | 20 | sub-langs = "en(-(gb|us|orig))?,de(-(de|orig))?,-live_chat,-rechat"; |
19 | prefer-free-formats = true; | 21 | prefer-free-formats = true; |
20 | embed-metadata = true; | ||
21 | # downloader = "${pkgs.axel}/bin/axel"; | 22 | # downloader = "${pkgs.axel}/bin/axel"; |
22 | concurrent-fragments = 12; | 23 | concurrent-fragments = 12; |
23 | buffer-size = "16K"; | 24 | buffer-size = "16K"; |
@@ -29,6 +30,7 @@ | |||
29 | # ]; | 30 | # ]; |
30 | remux-video = "mp4>mkv"; | 31 | remux-video = "mp4>mkv"; |
31 | output = lib.mkDefault "\"%(modified_date>%Y%m%d,release_date>%Y%m%d,upload_date>%Y%m%d)s %(title)s [%(uploader)s %(webpage_url)s].%(ext)s\""; | 32 | output = lib.mkDefault "\"%(modified_date>%Y%m%d,release_date>%Y%m%d,upload_date>%Y%m%d)s %(title)s [%(uploader)s %(webpage_url)s].%(ext)s\""; |
33 | audio-multistreams = true; | ||
32 | }; | 34 | }; |
33 | }; | 35 | }; |
34 | }; | 36 | }; |