initial commit

This commit is contained in:
Danilo Reyes 2025-10-01 13:40:05 -06:00
commit d0fb48d1b0
165 changed files with 10586 additions and 0 deletions

View File

@ -0,0 +1,99 @@
name: Weekly NixOS Build & Cache
on:
schedule:
- cron: "30 09 * * 1,5"
workflow_dispatch: # Allow manual trigger
jobs:
build-and-cache:
runs-on: nixos
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git for automated commits
run: |
git config user.name "NixOS Builder Bot"
git config user.email "noreply@servidos.lat"
- name: Update flake inputs
run: |
nix flake update
- name: Check for changes
id: check_changes
run: |
if git diff --quiet flake.lock; then
echo "changes=false" >> $GITHUB_OUTPUT
echo "No changes in flake.lock"
else
echo "changes=true" >> $GITHUB_OUTPUT
echo "Changes detected in flake.lock"
fi
- name: Configure Attic cache
if: steps.check_changes.outputs.changes == 'true'
run: |
# Configure attic client to use your cache server
attic login servidos https://cache.servidos.lat ${{ secrets.ATTIC_TOKEN }}
- name: Build workstation configuration
if: steps.check_changes.outputs.changes == 'true'
run: |
echo "Building workstation configuration..."
nix build .#nixosConfigurations.workstation.config.system.build.toplevel --quiet
- name: Build server configuration
if: steps.check_changes.outputs.changes == 'true'
run: |
echo "Building server configuration..."
nix build .#nixosConfigurations.server.config.system.build.toplevel --quiet
- name: Build emacs-vm configuration
if: steps.check_changes.outputs.changes == 'true'
run: |
echo "Building emacs-vm configuration..."
nix build .#emacs-vm --quiet
- name: Push to cache
if: steps.check_changes.outputs.changes == 'true'
run: |
echo "Pushing builds to cache..."
# Push all built derivations to cache
if ls result* 1> /dev/null 2>&1; then
attic push servidos:nixos result*
fi
# Push the specific system derivations we just built
nix build .#nixosConfigurations.workstation.config.system.build.toplevel --print-out-paths | attic push servidos:nixos --stdin
nix build .#nixosConfigurations.server.config.system.build.toplevel --print-out-paths | attic push servidos:nixos --stdin
nix build .#emacs-vm --print-out-paths | attic push servidos:nixos --stdin
- name: Commit updated flake.lock
if: steps.check_changes.outputs.changes == 'true'
run: |
git add flake.lock
git commit -m "Weekly flake update: $(date -u '+%Y-%m-%d %H:%M UTC')"
git push origin main
- name: Create release tag
if: steps.check_changes.outputs.changes == 'true'
run: |
TAG_NAME="weekly-$(date -u '+%Y-%m-%d')"
git tag -a "$TAG_NAME" -m "Weekly build and cache update for $(date -u '+%Y-%m-%d')"
git push origin "$TAG_NAME"
- name: Summary
run: |
if [[ "${{ steps.check_changes.outputs.changes }}" == "true" ]]; then
echo "✅ Weekly build completed successfully!"
echo "- Updated flake.lock"
echo "- Built workstation and server configurations"
echo "- Pushed builds to Atticd cache"
echo "- Committed changes and created release tag"
else
echo " No updates needed - flake.lock is already up to date"
fi

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.direnv
config.el
*.qcow2
result

48
.sops.yaml Normal file
View File

@ -0,0 +1,48 @@
keys:
- &devkey age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
- &workstation age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
- &server age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
- &miniserver age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl
creation_rules:
- path_regex: secrets/secrets.yaml$
key_groups:
- age:
- *devkey
- *workstation
- *server
- *miniserver
- path_regex: secrets/keys.yaml$
key_groups:
- age:
- *devkey
- *workstation
- *server
- *miniserver
- path_regex: secrets/env.yaml$
key_groups:
- age:
- *devkey
- *workstation
- *server
- *miniserver
- path_regex: secrets/wireguard.yaml$
key_groups:
- age:
- *devkey
- *workstation
- *server
- *miniserver
- path_regex: secrets/homepage.yaml$
key_groups:
- age:
- *devkey
- *workstation
- *server
- *miniserver
- path_regex: secrets/certs.yaml$
key_groups:
- age:
- *devkey
- *workstation
- *server
- *miniserver

189
config/base.nix Normal file
View File

@ -0,0 +1,189 @@
{
lib,
pkgs,
inputs,
outputs,
config,
...
}:
{
imports = [
inputs.home-manager.nixosModules.home-manager
./jawz.nix
../modules/modules.nix
];
system.stateVersion = "23.05";
sops = {
defaultSopsFormat = "yaml";
defaultSopsFile = ../secrets/secrets.yaml;
age = {
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
keyFile = "/var/lib/sops-nix/key.txt";
generateKey = true;
};
};
home-manager = {
backupFileExtension = "hbckup";
useUserPackages = true;
useGlobalPkgs = true;
extraSpecialArgs = {
inherit inputs outputs;
};
users.jawz = import ./home-manager.nix;
};
time = {
inherit (config.my) timeZone;
hardwareClockInLocalTime = true;
};
i18n = {
defaultLocale = "en_CA.UTF-8";
extraLocaleSettings = {
LC_MONETARY = "es_MX.UTF-8";
};
};
console = {
font = "Lat2-Terminus16";
keyMap = "us";
};
security = {
polkit.enable = true;
sudo = {
enable = true;
wheelNeedsPassword = false;
};
pam.loginLimits = [
{
domain = "*";
type = "soft";
item = "nofile";
value = "8192";
}
];
};
users = {
mutableUsers = false;
groups = {
users.gid = 100;
piracy.gid = 985;
};
};
nixpkgs.config = {
allowUnfree = true;
permittedInsecurePackages = [
"aspnetcore-runtime-wrapped-6.0.36"
"aspnetcore-runtime-6.0.36"
"dotnet-runtime-6.0.36"
"dotnet-sdk-wrapped-6.0.428"
"dotnet-sdk-6.0.428"
];
};
nix = {
distributedBuilds = true;
optimise.automatic = true;
settings = {
use-xdg-base-directories = true;
auto-optimise-store = true;
trusted-users = [
"jawz"
"root"
"nixremote"
];
experimental-features = [
"nix-command"
"flakes"
"pipe-operators"
];
substituters = [
"${config.my.servers.atticd.url}/nixos"
"https://nix-gaming.cachix.org"
"https://nixpkgs-python.cachix.org"
"https://devenv.cachix.org"
"https://cuda-maintainers.cachix.org"
"https://ai.cachix.org"
"https://cache.lix.systems"
"https://cosmic.cachix.org"
];
trusted-public-keys = [
"nixos:kubuWhYCk9/aZp5GDJFAScYgigM66DszP8i1Pzbq0Fc="
"nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
"nixpkgs-python.cachix.org-1:hxjI7pFxTyuTHn2NkvWCrAUcNZLNS3ZAvfYNuYifcEU="
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
"cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E="
"ai.cachix.org-1:N9dzRK+alWwoKXQlnn0H6aUx0lU/mspIoz8hMvGvbbc="
"cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o="
"cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE="
];
};
};
documentation.enable = false;
environment = {
systemPackages = builtins.attrValues {
inherit (pkgs)
wget
sops
;
};
variables =
let
XDG_DATA_HOME = "\${HOME}/.local/share";
XDG_CONFIG_HOME = "\${HOME}/.config";
XDG_CACHE_HOME = "\${HOME}/.cache";
in
{
# PATH
inherit XDG_DATA_HOME XDG_CONFIG_HOME XDG_CACHE_HOME;
XDG_BIN_HOME = "\${HOME}/.local/bin";
XDG_STATE_HOME = "\${HOME}/.local/state";
# DEV PATH
PSQL_HISTORY = "${XDG_DATA_HOME}/psql_history";
REDISCLI_HISTFILE = "${XDG_DATA_HOME}/redis/rediscli_history";
WINEPREFIX = "${XDG_DATA_HOME}/wine";
# OPTIONS
ELECTRUMDIR = "${XDG_DATA_HOME}/electrum";
WGETRC = "${XDG_CONFIG_HOME}/wgetrc";
XCOMPOSECACHE = "${XDG_CACHE_HOME}/X11/xcompose";
"_JAVA_OPTIONS" = "-Djava.util.prefs.userRoot=${XDG_CONFIG_HOME}/java";
ORG_DEVICE = "workstation";
# WAYLAND
WLR_NO_HARDWARE_CURSORS = 1;
NIXOS_OZONE_WL = 1;
PATH = [ "\${HOME}/.local/bin" ];
NH_USE_DOAS = 1;
};
};
programs = {
nh = {
enable = true;
flake = "/home/jawz/Development/NixOS";
clean = {
enable = true;
extraArgs = "--keep-since 3d";
};
};
gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
};
services = {
udev.packages = [ pkgs.yubikey-personalization ];
smartd.enable = true;
fstrim.enable = true;
avahi = {
enable = true;
nssmdns4 = true;
};
openssh = {
enable = true;
openFirewall = true;
startWhenNeeded = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "prohibit-password";
KbdInteractiveAuthentication = false;
};
};
};
fonts.fontconfig.enable = true;
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
}

89
config/home-manager.nix Normal file
View File

@ -0,0 +1,89 @@
{
inputs,
config,
pkgs,
lib,
osConfig,
...
}:
let
inherit (pkgs) fd fzf;
inherit (inputs.jawz-scripts.packages.x86_64-linux) pokemon-colorscripts;
shellType = osConfig.my.shell.type;
commonInit = ''
${pokemon-colorscripts}/bin/pokemon-colorscripts -r --no-title
export command_timeout=60
'';
commonAliases = {
cp = "cp -i";
mv = "mv -i";
mkdir = "mkdir -p";
mkcd = "(){ mkdir -p \"$1\" && cd \"$1\" }";
copy = "xclip -selection clipboard";
cdp = "pwd | copy";
cfp = "(){ readlink -f \"$1\" | copy }";
".." = "cd ..";
"..." = "cd ../..";
".3" = "cd ../../..";
".4" = "cd ../../../..";
".5" = "cd ../../../../..";
c = "cat";
sc = "systemctl --user";
jc = "journalctl --user -xefu";
};
in
{
home.stateVersion = "23.05";
programs = {
direnv = {
enable = true;
enableBashIntegration = shellType == "bash";
enableZshIntegration = shellType == "zsh";
nix-direnv.enable = true;
};
git = {
enable = true;
userName = "Danilo Reyes";
userEmail = "CaptainJawZ@protonmail.com";
};
bash = lib.mkIf (shellType == "bash") {
enable = true;
historyFile = "\${XDG_STATE_HOME}/bash/history";
shellAliases = commonAliases;
enableVteIntegration = true;
initExtra = commonInit;
historyControl = [
"erasedups"
"ignorespace"
"ignoredups"
];
};
zsh = lib.mkIf (shellType == "zsh") {
enable = true;
dotDir = ".config/zsh";
shellAliases = commonAliases;
initContent = commonInit;
history = {
path = "\${XDG_STATE_HOME}/zsh/history";
expireDuplicatesFirst = true;
ignoreSpace = true;
ignoreAllDups = true;
};
};
};
xdg = {
enable = true;
userDirs = {
enable = true;
createDirectories = false;
desktop = "${config.home.homeDirectory}";
documents = "${config.home.homeDirectory}/Documents";
download = "${config.home.homeDirectory}/Downloads";
music = "${config.home.homeDirectory}/Music";
pictures = "${config.home.homeDirectory}/Pictures";
templates = "${config.xdg.dataHome}/Templates";
videos = "${config.home.homeDirectory}/Videos";
};
configFile.wgetrc.text = "hsts-file=\${XDG_CACHE_HOME}/wget-hsts";
};
}

180
config/jawz.nix Normal file
View File

@ -0,0 +1,180 @@
{ config, lib, ... }:
let
inherit (config.networking) hostName;
nixosHosts =
lib.attrNames config.my.ips
|> lib.filter (
name: !(lib.hasPrefix "wg-" name) && name != "vps" && name != "router" && name != hostName
);
nixosHostsMatch = lib.concatStringsSep " " nixosHosts;
in
{
sops.secrets = lib.mkIf config.my.secureHost (
let
baseDir = ".ssh/ed25519";
keyConfig = file: {
sopsFile = ../secrets/keys.yaml;
owner = config.users.users.jawz.name;
inherit (config.users.users.jawz) group;
path = "/home/jawz/${file}";
};
in
{
jawz-password.neededForUsers = true;
"private_keys/${hostName}" = keyConfig "${baseDir}_${hostName}";
"git_private_keys/${hostName}" = keyConfig "${baseDir}_git";
"syncthing_keys/${hostName}" = keyConfig ".config/syncthing/key.pem";
"syncthing_certs/${hostName}" = keyConfig ".config/syncthing/cert.pem";
"syncthing_password".sopsFile = ../secrets/keys.yaml;
}
);
home-manager.users.jawz = {
home.file.".librewolf/.stignore".source = ../dotfiles/stignore;
programs.ssh = lib.mkIf config.my.secureHost {
enable = true;
matchBlocks = {
vps = {
hostname = config.my.ips.vps;
user = "fedora";
port = 3456;
identityFile = config.sops.secrets."private_keys/${hostName}".path;
};
"${nixosHostsMatch}" = {
user = "jawz";
identityFile = config.sops.secrets."private_keys/${hostName}".path;
};
"${config.my.servers.gitea.host} github.com gitlab.com bitbucket.org".identityFile =
config.sops.secrets."git_private_keys/${hostName}".path;
};
};
};
services.syncthing = lib.mkIf config.my.secureHost {
enable = true;
user = "jawz";
group = "users";
overrideDevices = true;
overrideFolders = true;
openDefaultPorts = true;
key = config.sops.secrets."syncthing_keys/${hostName}".path;
cert = config.sops.secrets."syncthing_certs/${hostName}".path;
guiAddress = "${config.my.ips."${hostName}"}:8384";
settings = {
options = {
natEnabled = false;
relaysEnabled = false;
globalAnnounceEnabled = false;
};
gui = {
user = "jawz";
password = config.sops.secrets.syncthing_password.path;
};
devices = {
server.id = "BG6PF7S-KATABWO-7WAZFMX-6YO7IS3-WQTMR3M-VSOSV7V-HFFMNNH-BFX2EQ4";
miniserver.id = "HDYEGIR-GFU7ONK-MOOJUFH-N3L3XHX-SXWN3FI-O23K6LD-BJENQK5-VIPV2AT";
workstation.id = "4E4KJ6M-MSTNBVF-D7CNHDW-DUTB3VR-SXKZ4NH-ZKAOMF5-V24JECJ-4STSZAA";
galaxy.id = "UAZ5YDV-YUFBXOY-QMS6S6R-WPIIKZI-4OPPW5L-G4OVUPO-YW5KFYY-YASRAAV";
phone.id = "OSOX2VZ-AO2SA3C-BFB6NKF-K6CR6WX-64TDBKW-RRKEKJ4-FKZE5CV-J2RGJAJ";
wg-friend1 = {
id = "XBIYCD4-EFKS5SK-WFF73CU-P37GXVH-OMWEIA4-6KC5F3L-U5UQWSF-SYNNRQF";
addresses = [ "tcp://${config.my.ips.wg-friend1}:22000" ];
introducer = false;
autoAcceptFolders = false;
paused = false;
};
};
folders =
let
isMainHost = hostName == "workstation";
mkMobile =
path:
lib.mkIf isMainHost {
inherit path;
ignorePerms = false;
devices = [
"galaxy"
"phone"
];
};
in
{
cache = mkMobile "~/Downloads/cache/";
friends = mkMobile "~/Pictures/artist/friends/";
forme = mkMobile "~/Pictures/art for me/";
comfy = mkMobile "~/Development/AI/ComfyUI/output/";
gdl = {
path = "~/.config/jawz/";
ignorePerms = false;
devices = [
"server"
"miniserver"
"workstation"
];
};
librewolf = {
path = "~/.librewolf/";
ignorePerms = false;
copyOwnershipFromParent = true;
type = if isMainHost then "sendonly" else "receiveonly";
devices = [
"server"
"miniserver"
"workstation"
];
};
notes = {
path = "~/Documents/Notes";
ignorePerms = false;
devices = [
"galaxy"
"phone"
"server"
"miniserver"
"workstation"
];
};
friend_share = {
path = "~/Pictures/encrypted/friends";
ignorePerms = false;
type = "sendreceive";
devices = [
"server"
"workstation"
"wg-friend1"
];
};
};
};
};
users.users.jawz = {
uid = 1000;
linger = true;
isNormalUser = true;
hashedPasswordFile = lib.mkIf config.my.secureHost config.sops.secrets.jawz-password.path;
hashedPassword =
lib.mkIf (!config.my.secureHost)
"$6$s4kbia4u7xVwCmyo$LCN7.Ki2n3xQOqPKnTwa5idwOWYeMNTieQYbLkiiKcMFkFmK76BjtNofJk3U7yRmLGnW3oFT433.nTRq1aoN.1";
extraGroups = [
"wheel"
"networkmanager"
"scanner"
"lp"
"piracy"
"kavita"
"video"
"docker"
"libvirt"
"rslsync"
"plugdev"
"bluetooth"
];
openssh.authorizedKeys.keyFiles = [
../secrets/ssh/ed25519_deacero.pub
../secrets/ssh/ed25519_workstation.pub
../secrets/ssh/ed25519_server.pub
../secrets/ssh/ed25519_miniserver.pub
../secrets/ssh/ed25519_galaxy.pub
../secrets/ssh/ed25519_phone.pub
../secrets/ssh/ed25519_vps.pub
];
};
}

42
config/overlay.nix Normal file
View File

@ -0,0 +1,42 @@
{
mkpkgs,
inputs,
...
}:
let
pkgs = mkpkgs inputs.nixpkgs;
pkgsU = mkpkgs inputs.nixpkgs-unstable;
in
_final: prev: {
nautilus = prev.nautilus.overrideAttrs (old: {
buildInputs =
old.buildInputs
++ builtins.attrValues {
inherit (pkgs.gst_all_1)
gst-plugins-good
gst-plugins-bad
;
};
});
lutris = prev.lutris.override {
extraPkgs =
pkgs:
builtins.attrValues {
inherit (pkgs) pango winetricks;
}
++ (with pkgs; [
wine64Packages.stable
wineWowPackages.stable
]);
};
handbrake = prev.handbrake.override { useGtk = true; };
ripgrep = prev.ripgrep.override { withPCRE2 = true; };
discord = prev.discord.override {
withVencord = true;
withOpenASAR = true;
};
waybar = prev.waybar.overrideAttrs (old: {
mesonFlags = old.mesonFlags ++ [ "-Dexperimental=true" ];
});
inherit (pkgsU) symbola mealie flaresolver;
}

108
config/schemes.nix Normal file
View File

@ -0,0 +1,108 @@
{ pkgs, inputs }:
let
inherit (inputs) wallpapers;
mkScheme =
{
color ? null,
name ? null,
polarity,
image,
iconPackage ? pkgs.papirus-icon-theme.override { inherit color; },
base16Scheme ? if name != null then "${pkgs.base16-schemes}/share/themes/${name}.yaml" else null,
}:
{
inherit
color
name
polarity
image
iconPackage
base16Scheme
;
};
in
{
schemes = {
vulcano = mkScheme {
name = "mocha";
color = "brown";
polarity = "dark";
image = "${wallpapers}/la_fragua_de_vulcano.jpg";
};
who = mkScheme {
name = "catppuccin-frappe";
polarity = "dark";
image = "${wallpapers}/Nikolay_Kasatkin_Who.jpeg";
iconPackage = pkgs.catppuccin-papirus-folders.override {
flavor = "frappe";
accent = "peach";
};
};
space = mkScheme {
name = "solarflare";
color = "darkcyan";
polarity = "dark";
image = "${wallpapers}/space.jpg";
};
jesus = mkScheme {
color = "red";
name = "equilibrium-light";
polarity = "light";
image = "${wallpapers}/jesus.png";
};
ballerinas = mkScheme {
color = "brown";
name = "mocha";
polarity = "dark";
image = "${wallpapers}/Waay-Ballerinas.jpeg";
};
paul = mkScheme {
color = "green";
name = "valua";
polarity = "light";
image = "${wallpapers}/paul1.jpg";
base16Scheme = {
base00 = "#1a1f16"; # dark forest floor (was deep green-black)
base01 = "#23291a"; # bark shadow
base02 = "#3c422c"; # damp moss
base03 = "#50573c"; # lichen-streaked rock
base04 = "#767d5e"; # moss + sun mix
base05 = "#a9ae8a"; # dry fern or lichen dust
base06 = "#dfe1d2"; # pale sage
base07 = "#f5f7f0"; # slightly sunlit leaf white
base08 = "#4c7c4a"; # deep fern green
base09 = "#6b8f3c"; # olive bark
base0A = "#b5b938"; # lichen gold
base0B = "#7CC844"; # success green (kept from original)
base0C = "#4fbf87"; # turquoise vine
base0D = "#2aaf6f"; # jungle leaf
base0E = "#88a337"; # mossy lime
base0F = "#5c8b55"; # swamp olive
};
};
cheems = mkScheme {
color = "yellow";
name = "equilibrium-light";
polarity = "light";
image = "${wallpapers}/cheems.png";
base16Scheme = {
base00 = "#f5f0e9"; # very light cream
base01 = "#e8ddd4"; # light beige
base02 = "#d4c4b0"; # warm tan
base03 = "#b8a082"; # golden brown
base04 = "#9c7c5a"; # medium brown
base05 = "#7a5f3f"; # darker brown
base06 = "#5c4328"; # dark brown
base07 = "#3e2d1a"; # very dark brown
base08 = "#d2691e"; # golden orange
base09 = "#cd853f"; # peru
base0A = "#daa520"; # goldenrod
base0B = "#228b22"; # forest green
base0C = "#20b2aa"; # light sea green
base0D = "#4169e1"; # royal blue
base0E = "#8b008b"; # dark magenta
base0F = "#dc143c"; # crimson
};
};
};
}

52
config/stylix.nix Normal file
View File

@ -0,0 +1,52 @@
{
pkgs,
lib,
config,
inputs,
...
}:
let
schemesFile = import ./schemes.nix {
inherit pkgs inputs;
};
scheme = schemesFile.schemes.cheems;
cfg = config.my.stylix;
gnomeEnabled = config.services.xserver.desktopManager.gnome.enable;
in
{
options.my.stylix.enable = lib.mkEnableOption "system-wide theming with Stylix";
config = {
stylix = {
inherit (scheme) image polarity;
enable = true;
autoEnable = cfg.enable;
targets.qt.platform = lib.mkForce "qtct";
}
// lib.optionalAttrs (scheme ? base16Scheme) { inherit (scheme) base16Scheme; };
home-manager.users.jawz = {
gtk = lib.mkIf (!cfg.enable && gnomeEnabled) {
enable = true;
iconTheme = {
name = "Papirus-Light";
package = pkgs.papirus-icon-theme.override {
color = "yellow";
};
};
};
stylix = {
inherit (cfg) enable;
autoEnable = cfg.enable;
iconTheme = {
inherit (cfg) enable;
package = scheme.iconPackage;
light = "Papirus-Light";
dark = "Papirus-Dark";
};
targets.librewolf = {
firefoxGnomeTheme.enable = true;
profileNames = [ "jawz" ];
};
};
};
};
}

10
dotfiles/doom/bookmarks Normal file
View File

@ -0,0 +1,10 @@
;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8-emacs; mode: lisp-data -*-
;;; This format is meant to be slightly human-readable;
;;; nevertheless, you probably don't want to edit it.
;;; -*- End Of Bookmark File Format Version Stamp -*-
(("org-capture-last-stored"
(filename . "~/Documents/Notes/20240518175854-egypt.org")
(front-context-string)
(rear-context-string . "\n#+title: Egypt\n")
(position . 83))
)

1076
dotfiles/doom/config.org Executable file

File diff suppressed because it is too large Load Diff

21
dotfiles/doom/custom.el Normal file
View File

@ -0,0 +1,21 @@
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(flycheck-flake8-maximum-line-length 88)
'(safe-local-variable-values
'((org-hugo-auto-export-on-save . t)
(org-hugo-base-dir . /home/jawz/Development/Websites/portfolio/)
(git-commit-major-mode . git-commit-elisp-text-mode))))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(org-document-title ((t (:inherit outline-1 :height 2.0))))
'(org-level-1 ((t (:inherit outline-1 :height 1.4))))
'(org-level-2 ((t (:inherit outline-2 :height 1.3))))
'(org-level-3 ((t (:inherit outline-3 :height 1.2))))
'(org-level-4 ((t (:inherit outline-4 :height 1.1))))
'(org-level-5 ((t (:inherit outline-5 :height 1.0)))))

192
dotfiles/doom/init.el Executable file
View File

@ -0,0 +1,192 @@
;;; init.el -*- lexical-binding: t; -*-
;; This file controls what Doom modules are enabled and what order they load
;; in. Remember to run 'doom sync' after modifying it!
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;; documentation. There you'll find a link to Doom's Module Index where all
;; of our modules are listed, including what flags they support.
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;; 'C-c c k' for non-vim users) to view its documentation. This works on
;; flags as well (those symbols that start with a plus).
;;
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;; directory (for easy access to its source code).
(doom! :input
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
;;chinese
;;japanese
;;layout ; auie,ctsrnm is the superior home row
:completion
;; company ; the ultimate code completion backend
(corfu +orderless) ; complete with cap(f), cape and a flying feather!
;;helm ; the *other* search engine for love and life
;;ido ; the other *other* search engine...
;;(ivy +fuzzy +childframe +icons) ; a search engine for love and life
vertico ; the search engine of the future
:ui
deft ; notational velocity for Emacs
doom ; what makes DOOM look the way it does
doom-dashboard ; a nifty splash screen for Emacs
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
;;(emoji +unicode +github) ; 🙂
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;indent-guides ; highlighted indent columns
;;(ligatures +extra +iosevka) ; ligatures and symbols to make your code pretty again
;;minimap ; show a map of the code on the side
modeline ; snazzy, Atom-inspired modeline, plus API
;;nav-flash ; blink cursor line after big motions
;;neotree ; a project drawer, like NERDTree for vim
ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows
;;tabs ; a tab bar for Emacs
(treemacs +lsp) ; a project drawer, like neotree but cooler
;;unicode ; extended unicode support for various languages
(vc-gutter +pretty) ; vcs diff in the fringe
vi-tilde-fringe ; fringe tildes to mark beyond EOB
;;window-select ; visually switch windows
workspaces ; tab emulation, persistence & separate workspaces
;;zen ; distraction-free coding or writing
:editor
(evil +everywhere); come to the dark side, we have cookies
file-templates ; auto-snippets for empty files
fold ; (nigh) universal code folding
(format +onsave) ; automated prettiness
;;god ; run Emacs commands without modifier keys
;;lispy ; vim for lisp, for people who don't like vim
;;multiple-cursors ; editing in many places at once
;;objed ; text object editing for the innocent
;;parinfer ; turn lisp into python, sort of
rotate-text ; cycle region at point between text candidates
snippets ; my elves. They type so I don't have to
;;word-wrap ; soft wrapping with language-aware indent
:emacs
dired ; making dired pretty [functional]
electric ; smarter, keyword-based electric-indent
eww ; the internet is gross
ibuffer ; interactive buffer management
(undo +tree) ; persistent, smarter undo for your inevitable mistakes
vc ; version-control and Emacs, sitting in a tree
:term
;;eshell ; the elisp shell that works everywhere
;;shell ; simple shell REPL for Emacs
;;term ; basic terminal emulator for Emacs
vterm ; the best terminal emulation in Emacs
:checkers
syntax ; tasing you for every semicolon you forget
(spell +flyspell +hunspell) ; tasing you for misspelling mispelling
grammar ; tasing grammar mistake every you make
:tools
;;ansible
;;biblio ; Writes a PhD for you (citation needed)
;;collab ; buffers with friends
;;debugger ; FIXME stepping through code, to help you add bugs
direnv
(docker +lsp)
editorconfig ; let someone else argue about tabs vs spaces
;;ein ; tame Jupyter notebooks with emacs
(eval +overlay) ; run code, run (also, repls)
(lookup +dictionary + offline) ; navigate your code and its documentation
(lsp +peek) ; M-x vscode
magit ; a git porcelain for Emacs
;;make ; run make tasks from Emacs
;;pass ; password manager for nerds
;;pdf ; pdf enhancements
;;prodigy ; FIXME managing external services & code builders
;;terraform ; infrastructure as code
tmux ; an API for interacting with tmux
;; tree-sitter ; syntax and parsing, sitting in a tree...
upload ; map local to remote projects via ssh/ftp
:os
;;(:if (featurep :system 'macos) macos) ; improve compatibility with macOS tty ; improve the terminal Emacs experience
:lang
;;agda ; types of types of types of types...
;;beancount ; mind the GAAP
(cc +lsp) ; C > C++ == 1
;;clojure ; java with a lisp
;;common-lisp ; if you've seen one lisp, you've seen them all
;;coq ; proofs-as-programs
;;crystal ; ruby at the speed of c
;; (csharp +lsp) ; unity, .NET, and mono shenanigans
;;data ; config/data formats
;;(dart +flutter) ; paint ui and not much else
;;dhall
;;elixir ; erlang done right
;;elm ; care for a cup of TEA?
emacs-lisp ; drown in parentheses
;;erlang ; an elegant language for a more civilized age
;;ess ; emacs speaks statistics
;;factor
;;faust ; dsp, but you get to keep your soul
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
;;fsharp ; ML stands for Microsoft's Language
;;fstar ; (dependent) types and (monadic) effects and Z3
(gdscript +lsp) ; the language you waited for
;;(go +lsp) ; the hipster dialect
;;(graphql +lsp) ; Give queries a REST
(haskell +lspr) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python
;;idris ; a language you can depend on
(json +lsp) ; At least it ain't XML
;;(java +lsp) ; the poster child for carpal tunnel syndrome
(javascript +lsp) ; all(hope(abandon(ye(who(enter(here))))))
(julia +lsp) ; a better, faster MATLAB
;;kotlin ; a better, slicker Java(Script)
;;latex ; writing papers in Emacs has never been so fun
;;lean ; for folks with too much to prove
;;ledger ; be audit you can be
;;lua ; one-based indices? one-based indices
;;markdown ; writing docs for people to ignore
;;nim ; python + lisp at the speed of c
(nix +lsp) ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel
(org +hugo +pretty +roam2) ; organize your plain life in plain text
;;(php +lsp) ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
;; graphviz ; diagrams for confusing yourself even more
;;purescript ; javascript, but functional
(python +pyright +lsp) ; beautiful is better than ugly
;;qt ; the 'cutest' gui framework ever
;;racket ; a DSL for DSLs
;;raku ; the artist formerly known as perl6
;;rest ; Emacs as a REST client
;;rst ; ReST in peace
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
;;scala ; java, but good
;;(scheme +guile) ; a fully conniving family of lisps
(sh +lsp) ; she sells {ba,z,fi}sh shells on the C xor
;;sml
;;solidity ; do you need a blockchain? No.
;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance.
;;web ; the tubes
(yaml +lsp) ; JSON, but readable
;;zig ; C, but simpler
:email
;;(mu4e +org +gmail)
;;notmuch
;;(wanderlust +gmail)
:app
calendar
;;emms
everywhere ; *leave* Emacs!? You must be joking
;;irc ; how neckbeards socialize
;;(rss +org) ; emacs as an RSS reader
:config
literate
(default +bindings +smartparens))

96
dotfiles/doom/packages.el Executable file
View File

@ -0,0 +1,96 @@
;; -*- no-byte-compile: t; -*-
;;; $DOOMDIR/packages.el
;; To install a package with Doom you must declare them here and run 'doom sync'
;; on the command line, then restart Emacs for the changes to take effect -- or
;; use 'M-x doom/reload'.
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
;(package! some-package)
;; To install a package directly from a remote git repo, you must specify a
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
;; https://github.com/raxod502/straight.el#the-recipe-format
;(package! another-package
; :recipe (:host github :repo "username/repo"))
;; If the package you are trying to install does not contain a PACKAGENAME.el
;; file, or is located in a subdirectory of the repo, you'll need to specify
;; `:files' in the `:recipe':
;(package! this-package
; :recipe (:host github :repo "username/repo"
; :files ("some-file.el" "src/lisp/*.el")))
;; If you'd like to disable a package included with Doom, you can do so here
;; with the `:disable' property:
;(package! builtin-package :disable t)
;; You can override the recipe of a built in package without having to specify
;; all the properties for `:recipe'. These will inherit the rest of its recipe
;; from Doom or MELPA/ELPA/Emacsmirror:
;(package! builtin-package :recipe (:nonrecursive t))
;(package! builtin-package-2 :recipe (:repo "myfork/package"))
;; Specify a `:branch' to install a package from a particular branch or tag.
;; This is required for some packages whose default branch isn't 'master' (which
;; our package manager can't deal with; see raxod502/straight.el#279)
;(package! builtin-package :recipe (:branch "develop"))
;; Use `:pin' to specify a particular commit to install.
;(package! builtin-package :pin "1a2b3c4d5e")
;; Doom's packages are pinned to a specific commit and updated from release to
;; release. The `unpin!' macro allows you to unpin single packages...
;(unpin! pinned-package)
;; ...or multiple packages
;(unpin! pinned-package another-pinned-package)
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
;(unpin! t)
;; (package! nixos-options) ;; enable when migrating to nixos
;; (package! quick-preview) ;; preview files with sushi
;; (package! codeium :recipe (:host github :repo "Exafunction/codeium.el"))
(package! config-general-mode)
(package! dired-open)
(package! dired-subtree)
;; (package! doom-modeline-now-playing)
(package! ini-mode)
(package! insert-esv) ;; bible passages
(package! olivetti) ;; writing mode centering text, looks like word
(package! org-alert)
(package! org-auto-tangle)
(package! org-roam-ui)
(package! org-transclusion)
(package! peep-dired) ;; kind of cool but never could make it work
(package! php-cs-fixer)
(package! systemd)
;; (package! 2048-game)
;; (package! academic-phrases)
;; (package! caddyfile-mode)
;; (package! clippy)
;; (package! crontab-mode) ;; crontab colors
;; (package! evil-tutor) ;; vim tutorial
;; (package! ewal) ;; theme colors based on pywal
;; (package! ewal-doom-themes)
;; (package! ewal-evil-cursors)
;; (package! fish-completion) ;; what does it do???????????????????????????
;; (package! flycheck-aspell)
;; (package! ivy-posframe)
;; (package! mw-thesaurus)
;; (package! org-appear) ;; couldn't get it to work
;; (package! org-recur) ;; works but I want to keep org vanilla
;; (package! ox-chameleon
;; :recipe (:host github :repo "tecosaur/ox-chameleon"))
;; (package! renpy)
;; (package! resize-window)
;; (package! tldr)
;; (package! typit) ;; type speed test
;; (package! vimgolf) ;; vim puzzles
;; (package! wc-mode) ;; displays character count of buffer
(package! expand-region)
(package! gptel :recipe (:nonrecursive t))

View File

@ -0,0 +1 @@
%?

View File

@ -0,0 +1,21 @@
%?
* Sources
1.
* Belligerents
1.
* Casualties and losses
* Location
* Causes
* Events
* Major Contention Events
* Outcome
* Important Notes

View File

@ -0,0 +1,13 @@
%?
- Influenced by
- Influenced
- Related tools
* Hello World
* Tips
* Resources
- Documentation
- YouTube channels

203
dotfiles/gallery-dl.nix Normal file
View File

@ -0,0 +1,203 @@
{
extractor = {
skip = "abort:5";
cookies = [
"firefox"
"/home/jawz/.librewolf/jawz"
"gnomekeyring"
];
retries = 10;
sleep-request = 0;
directlink = {
filename = "{filename}.{extension}";
directory = [ ];
};
twitter = {
skip = "abort:1";
retweets = false;
videos = "ytdl";
logout = true;
include = [ "media" ];
directory = [ "{user[name]}" ];
};
pinterest.directory = [
"{board[owner][username]}"
"{board[name]}"
];
instagram = {
browser = "firefox:linux";
user-agent = "Mozilla/5.0 (X11; Linux x86_64; rv:138.0) Gecko/20100101 Firefox/138.0";
sleep = "66-123";
sleep-request = "66-123";
parent-directory = true;
directory = [ "{username}" ];
previews = true;
highlights = {
reverse = true;
directory = [ "{username}" ];
};
stories = {
reverse = true;
directory = [ "{username}" ];
};
tagged.directory = [
"{username}"
"tagged"
"{tagged_username}"
];
};
furaffinity = {
directory = [
"{user}"
"{subcategory}"
];
include = [
"scraps"
"gallery"
];
};
patreon = {
filename = "{filename}.{num}.{extension}";
browser = "firefox";
directory = [
"(Patreon) {creator[vanity]}"
"({date:%Y%m%d}) {title} ({id})"
];
};
blogger = {
filename = "{filename} - {num}.{extension}";
directory = [
"{blog[name]}"
"{post[author]}"
"{post[title]} - [{post[id]}]"
];
};
artstation = {
external = true;
directory = [ "{userinfo[username]}" ];
};
gfycat.format = "webm";
reddit = {
parent-directory = true;
directory = [ "{author}" ];
};
redgifs = {
reverse = true;
directory = [ "{userName}" ];
};
imgur.mp4 = true;
fanbox = {
embeds = true;
directory = [
"{category}"
"{creatorId}"
];
};
readcomiconline = {
chapter-reverse = true;
quality = "hq";
captcha = "wait";
postprocessors = [ "cbz" ];
directory = [
"comics"
"{comic}"
"{comic} #{issue}"
];
};
kissmanga = {
chapter-reverse = true;
captcha = "wait";
postprocessors = [ "cbz" ];
directory = [
"manga"
"{subcategory}"
"{manga}"
"{manga} Ch.{chapter}{chapter_minor}"
];
};
mangahere = {
chapter-reverse = true;
postprocessors = [ "cbz" ];
directory = [
"manga"
"{subcategory}"
"{manga}"
"{manga} Ch.{chapter}{chapter_minor}"
];
};
mangadex = {
chapter-reverse = true;
chapter-filter = "lang == 'en'";
postprocessors = [ "cbz" ];
directory = [
"manga"
"manga"
"{manga}"
"{manga} Ch.{chapter}{chapter_minor}"
];
};
manganelo = {
chapter-reverse = true;
chapter-filter = "lang == 'en'";
postprocessors = [ "cbz" ];
directory = [
"manga"
"{subcategory}"
"{manga}"
"{manga} Ch.{chapter}{chapter_minor}"
];
};
mangareader = {
chapter-reverse = true;
postprocessors = [ "cbz" ];
directory = [
"manga"
"{subcategory}"
"{manga}"
"{manga} Ch.{chapter}{chapter_minor}"
];
};
mangapanda = {
chapter-reverse = true;
postprocessors = [ "cbz" ];
directory = [
"manga"
"{subcategory}"
"{manga}"
"{manga} Ch.{chapter}{chapter_minor}"
];
};
webtoons = {
chapter-reverse = true;
postprocessors = [ "cbz" ];
directory = [
"webtoons"
"{comic}"
"{comic} #{episode}"
];
};
};
output.mode = "auto";
downloader = {
part = true;
part-directory = "/home/jawz/.cache/gallery-dl";
ytdl = {
logging = true;
format = "bestvideo+bestaudio/best";
module = "yt_dlp";
forward-cookies = true;
};
http = {
rate = null;
retries = 5;
timeout = 10.0;
verify = true;
};
};
postprocessor.cbz = {
name = "zip";
compression = "store";
mode = "safe";
extension = "cbz";
};
}

7
dotfiles/npmrc Normal file
View File

@ -0,0 +1,7 @@
user=0
unsafe-perm=true
prefix=${XDG_DATA_HOME}/npm
cache=${XDG_CACHE_HOME}/npm
tmp=${XDG_RUNTIME_DIR}/npm
init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js
store-dir=${XDG_DATA_HOME}/pnpm-store

17
dotfiles/pythonrc Normal file
View File

@ -0,0 +1,17 @@
import os
import atexit
import readline
history = os.path.join(os.environ['XDG_CACHE_HOME'], 'python_history')
try:
readline.read_history_file(history)
except OSError:
pass
def write_history():
try:
readline.write_history_file(history)
except OSError:
pass
atexit.register(write_history)

7
dotfiles/stignore Normal file
View File

@ -0,0 +1,7 @@
(?d)jawz/chrome/userChrome.css
(?d)jawz/chrome/userContent.css
(?d)jawz/lock
(?d)jawz/user.js
(?d)native-messaging-hosts/org.gnome.browser_connector.json
(?d)native-messaging-hosts/org.gnome.chrome_gnome_shell.json
(?d)profiles.ini

222
dotfiles/unpackerr.conf Normal file
View File

@ -0,0 +1,222 @@
## Unpackerr Example Configuration File ##
## The following values are application defaults. ##
## Environment Variables may override all values. ##
####################################################
# [true/false] Turn on debug messages in the output. Do not wrap this in quotes.
# Recommend trying this so you know what it looks like. I personally leave it on.
debug = false
# Disable writing messages to stdout. This silences the app. You should set a log
# file below if you set this to true. Recommended when starting with systemctl.
quiet = false
# Setting activity to true will silence all app queue log lines with only zeros.
# Set this to true when you want less log spam.
activity = false
# The application queue data is logged on an interval. Adjust that interval with this setting.
# Default is a minute. 2m, 5m, 10m, 30m, 1h are also perfectly acceptable.
log_queues = "1m"
# Write messages to a log file. This is the same data that is normally output to stdout.
# This setting is great for Docker users that want to export their logs to a file.
# The alternative is to use syslog to log the output of the application to a file.
# Default is no log file; this is unset. log_files=0 turns off auto-rotation.
# Default files is 10 and size(mb) is 10 Megabytes; both doubled if debug is true.
#log_file = '/downloads/unpackerr.log'
log_files = 10
log_file_mb = 10
# How often to poll sonarr and radarr.
# Recommend 1m-5m. Uses Go Duration.
interval = "5m"
# How long an item must be queued (download complete) before extraction will start.
# One minute is the historic default and works well. Set higher if your downloads
# take longer to finalize (or transfer locally). Uses Go Duration.
start_delay = "1m"
# How long to wait before removing the history for a failed extraction.
# Once the history is deleted the item will be recognized as new and
# extraction will start again. Uses Go Duration.
retry_delay = "5m"
# How many files may be extracted in parallel. 1 works fine.
# Do not wrap the number in quotes. Raise this only if you have fast disks and CPU.
parallel = 1
# Use these configurations to control the file modes used for newly extracted
# files and folders. Recommend 0644/0755 or 0666/0777.
file_mode = "0664"
dir_mode = "0775"
[webserver]
## The web server currently only supports metrics; set this to true if you wish to use it.
metrics = false
## This may be set to a port or an ip:port to bind a specific IP. 0.0.0.0 binds ALL IPs.
listen_addr = "0.0.0.0:5656"
## Recommend setting a log file for HTTP requests. Otherwise, they go with other logs.
log_file = ""
## This app automatically rotates logs. Set these to the size and number to keep.
log_files = 10
log_file_mb = 10
## Set both of these to valid file paths to enable HTTPS/TLS.
ssl_cert_file = ""
ssl_key_file = ""
## Base URL from which to serve content.
urlbase = "/"
## Upstreams should be set to the IP or CIDR of your trusted upstream proxy.
## Setting this correctly allows X-Forwarded-For to be used in logs.
## In the future it may control auth proxy trust. Must be a list of strings.
upstreams = [ ] # example: upstreams = [ "127.0.0.1/32", "10.1.2.0/24" ]
##-Notes-#######-READ THIS!!!-##################################################
## The following sections can be repeated if you have more than one Sonarr, ##
## Radarr or Lidarr, Readarr, Folder, Webhook, or Command Hook. ##
## You MUST uncomment the [[header]] and api_key at a minimum for Starr apps. ##
## ALL LINES BEGINNING WITH A HASH # ARE IGNORED ##
## REMOVE THE HASH # FROM CONFIG LINES YOU WANT TO CHANGE ##
################################################################################
[[sonarr]]
url = "http://localhost:8989"
api_key = "52869fe7bec4482dafb21c4053fe71e4"
## File system path where downloaded Sonarr items are located.
paths = ['/srv/pool/multimedia/downloads/torrent']
## Default protocols is torrent. Alternative: "torrent,usenet"
protocols = "torrent"
## How long to wait for a reply from the backend.
timeout = "10s"
## How long to wait after import before deleting the extracted items.
delete_delay = "5m"
## If you use this app with NZB you may wish to delete archives after extraction.
## General recommendation is: do not enable this for torrent use.
## Setting this to true deletes the entire original download folder after import.
# delete_orig = false
## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish.
# syncthing = false
[[radarr]]
url = "http://127.0.0.1:7878"
api_key = "a987ac45ca2c47bc88e762031ea33296"
## File system path where downloaded Radarr items are located.
paths = ['/srv/pool/multimedia/downloads/torrent']
## Default protocols is torrents. Alternative: "torrent,usenet"
protocols = "torrent"
## How long to wait for a reply from the backend.
timeout = "10s"
## How long to wait after import before deleting the extracted items.
delete_delay = "5m"
## If you use this app with NZB you may wish to delete archives after extraction.
## General recommendation is: do not enable this for torrent use.
## Setting this to true deletes the entire original download folder after import.
# delete_orig = false
## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish.
# syncthing = false
#[[lidarr]]
# url = "http://127.0.0.1:8686"
# api_key = "0123456789abcdef0123456789abcdef"
## File system path where downloaded Lidarr items are located.
# paths = ['/downloads']
## Default protocols is torrent. Alternative: "torrent,usenet"
# protocols = "torrent"
## How long to wait for a reply from the backend.
# timeout = "10s"
## How long to wait after import before deleting the extracted items.
# delete_delay = "5m"
## If you use this app with NZB you may wish to delete archives after extraction.
## General recommendation is: do not enable this for torrent use.
## Setting this to true deletes the entire original download folder after import.
# delete_orig = false
## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish.
# syncthing = false
#[[readarr]]
# url = "http://127.0.0.1:8787"
# api_key = "0123456789abcdef0123456789abc"
## File system path where downloaded Readarr items are located.
# paths = ['/downloads']
## Default protocols is torrent. Alternative: "torrent,usenet"
# protocols = "torrent"
## How long to wait for a reply from the backend.
# timeout = "10s"
## How long to wait after import before deleting the extracted items.
# delete_delay = "5m"
## If you use this app with NZB you may wish to delete archives after extraction.
## General recommendation is: do not enable this for torrent use.
## Setting this to true deletes the entire original download folder after import.
# delete_orig = false
## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish.
# syncthing = false
##################################################################################
### ### STOP HERE ### STOP HERE ### STOP HERE ### STOP HERE #### STOP HERE ### #
### Only using Starr apps? The things above. The below configs are OPTIONAL. ### #
##################################################################################
##-Folders-#######################################################################
## This application can also watch folders for things to extract. If you copy a ##
## subfolder into a watched folder (defined below) any extractable items in the ##
## folder will be decompressed. This has nothing to do with Starr applications. ##
##################################################################################
#[[folder]]
# path = '/some/folder/to/watch'
## Path to extract files to. The default (leaving this blank) is the same as `path` (above).
# extract_path = ""
## Delete extracted or original files this long after extraction.
## The default is 0. Set to 0 to disable all deletes. Uncomment it to enable deletes. Uses Go Duration.
# delete_after = "10m"
## Delete extracted files after successful extraction? true/false, no quotes. Honors delete_after.
# delete_files = false
## Delete original items after successful extraction? true/false, no quotes. Honors delete_after.
# delete_original = false
## Disable extraction log (unpackerred.txt) file creation? true/false, no quotes.
# disable_log = false
## Move extracted files into original folder? If false, files go into an _unpackerred folder.
# move_back = false
## Set this to true if you want this app to extract ISO files with .iso extension.
# extract_isos = false
################
### Webhooks ###
################
# Sends a webhook when an extraction queues, starts, finishes, and/or is deleted.
# Created to integrate with notifiarr.com.
# Also works natively with Discord.com, Telegram.org, and Slack.com webhooks.
# Can possibly be used with other services by providing a custom template_path.
###### Don't forget to uncomment [[webhook]] and url at a minimum !!!!
#[[webhook]]
# url = "https://notifiarr.com/api/v1/notification/unpackerr/api_key_from_notifiarr_com"
# name = "" # Set this to hide the URL in logs.
# silent = false # do not log success (less log spam)
# events = [0] # list of event ids to include, 0 == all.
## Advanced Optional Webhook Configuration
# nickname = "" # Used in Discord and Slack templates as bot name, in Telegram as chat_id.
# channel = "" # Also passed into templates. Used in Slack templates for destination channel.
# exclude = [] # list of apps to exclude, ie. ["radarr", "lidarr"]
# template_path = "" # Override internal webhook template for discord.com or other hooks.
# template = "" # Override automatic template detection. Values: notifiarr, discord, telegram, gotify, pushover, slack
# ignore_ssl = false # Set this to true to ignore the SSL certificate on the server.
# timeout = "10s" # You can adjust how long to wait for a server response.
# content_type = "application/json" # If your custom template uses another MIME type, set this.
#####################
### Command Hooks ###
#####################
# Executes a script or command when an extraction queues, starts, finishes, and/or is deleted.
# All data is passed in as environment variables. Try /usr/bin/env to see what variables are available.
###### Don't forget to uncomment [[cmdhook]] and url at a minimum !!!!
#[[cmdhook]]
# command = '/my/cool/app' # Path to command or script.
# shell = false # Runs the command inside /bin/sh ('nix) or cmd.exe (Windows).
# name = "" # Provide an optional name for logging.
# silent = false # Hides command output from logs.
# events = [0] # list of event ids to include, 0 == all.
## Optional Command Hook Configuration
# exclude = [] # list of apps to exclude, ie. ["radarr", "lidarr"]
# timeout = "10s" # You can adjust how long to wait for a server response.

21
environments/cinnamon.nix Normal file
View File

@ -0,0 +1,21 @@
{ pkgs, ... }:
{
services = {
libinput.enable = true;
xserver = {
enable = true;
displayManager.lightdm.enable = true;
desktopManager.cinnamon.enable = true;
};
};
qt = {
enable = true;
style = "adwaita";
};
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
adw-gtk3 # theme legacy applications
papirus-icon-theme # icon theme
;
};
}

45
environments/gnome.nix Normal file
View File

@ -0,0 +1,45 @@
{
pkgs,
lib,
...
}:
{
services = {
gvfs.enable = true;
libinput.enable = true;
xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager = {
gnome.enable = true;
xterm.enable = lib.mkForce false;
};
};
};
environment.gnome.excludePackages = builtins.attrValues {
inherit (pkgs)
baobab
cheese
epiphany
gnome-characters
gnome-connections
gnome-font-viewer
gnome-photos
# gnome-text-editor
gnome-tour
yelp
gnome-music
totem
;
};
qt.enable = true;
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs.gnomeExtensions)
tactile # window manager
freon # hardware temperature monitor
gamemode-shell-extension # I guess I'm a gamer now?
burn-my-windows # special effects for when closing windows
pano # clipboard manager
;
};
}

109
environments/hyprland.nix Normal file
View File

@ -0,0 +1,109 @@
{
pkgs,
...
}:
let
startupScript = pkgs.pkgs.writeShellScriptBin "start" ''
${pkgs.waybar}/bin/waybar &
${pkgs.swww}/bin/swww init &
sleep 1
'';
in
{
programs.hyprland.enable = true;
services.greetd = {
enable = true;
settings.default_session = {
command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd Hyprland";
user = "greeter";
};
};
xdg.portal = {
enable = true;
extraPortals = [
pkgs.xdg-desktop-portal-hyprland
# pkgs.xdg-desktop-portal-gtk
];
};
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
# Wayland utilities
wl-clipboard
wf-recorder
grim
slurp
wofi # Application launcher
mako # Notification daemon
libnotify # dependency of mako
swaylock-effects # Screen locker
# nautilus # File manager
;
};
home-manager.users.jawz = {
programs.kitty.enable = true;
wayland.windowManager.hyprland = {
enable = true;
settings = {
"$mainMod" = "SUPER";
exec-once = "${startupScript}/bin/start";
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 2;
layout = "dwindle";
};
dwindle = {
pseudotile = true;
preserve_split = true;
force_split = 2;
};
bind = [
"$mainMod, return, exec, kitty"
"$mainMod, Q, killactive,"
"$mainMod SHIFT, F, togglefloating,"
"$mainMod, F, fullscreen,"
"$mainMod, T, pin,"
"$mainMod, G, togglegroup,"
"$mainMod, bracketleft, changegroupactive, b"
"$mainMod, bracketright, changegroupactive, f"
"$mainMod, S, exec, wofi --show drun icons"
"$mainMod, P, pin, active"
",XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%+"
",XF86AudioLowerVolume, exec, wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%-"
"$mainMod, left, movefocus, l"
"$mainMod, right, movefocus, r"
"$mainMod, up, movefocus, u"
"$mainMod, down, movefocus, d"
"$mainMod, h, movefocus, l"
"$mainMod, l, movefocus, r"
"$mainMod, k, movefocus, u"
"$mainMod, j, movefocus, d"
"$mainMod SHIFT, h, movewindow, l"
"$mainMod SHIFT, l, movewindow, r"
"$mainMod SHIFT, k, movewindow, u"
"$mainMod SHIFT, j, movewindow, d"
];
binde = [
"$mainMod SHIFT, h, moveactive, -20 0"
"$mainMod SHIFT, l, moveactive, 20 0"
"$mainMod SHIFT, k, moveactive, 0 -20"
"$mainMod SHIFT, j, moveactive, 0 20"
"$mainMod CTRL, l, resizeactive, 30 0"
"$mainMod CTRL, h, resizeactive, -30 0"
"$mainMod CTRL, k, resizeactive, 0 -10"
"$mainMod CTRL, j, resizeactive, 0 10"
];
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
];
};
};
};
}

1259
flake.lock generated Normal file

File diff suppressed because it is too large Load Diff

130
flake.nix Normal file
View File

@ -0,0 +1,130 @@
{
description = "JawZ NixOS flake setup";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.05";
nixpkgs-small.url = "github:nixos/nixpkgs?ref=nixos-25.05-small";
nixpkgs-unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable";
ucodenix.url = "github:e-tho/ucodenix";
doom-emacs = {
url = "github:marienz/nix-doom-emacs-unstraightened";
inputs.nixpkgs.follows = "";
};
jawz-scripts = {
url = "git+https://git.servidos.lat/jawz/scripts.git";
inputs.nixpkgs.follows = "nixpkgs";
};
wallpapers = {
url = "git+https://git.servidos.lat/jawz/wallpapers.git";
flake = false;
};
fonts = {
url = "git+https://git.servidos.lat/jawz/fonts.git";
flake = false;
};
nur = {
url = "github:nix-community/nur";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-gaming = {
url = "github:fufexan/nix-gaming";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprland = {
url = "github:hyprwm/Hyprland";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager?ref=release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
stylix = {
url = "github:danth/stylix/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nixtendo-switch = {
url = "github:nyawox/nixtendo-switch";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ self, jawz-scripts, ... }@inputs:
let
inherit (self) outputs;
system = "x86_64-linux";
mkpkgs =
repo:
import repo {
inherit system;
config.allowUnfree = true;
};
langList = builtins.filter (name: name != "emacs") (
builtins.map (file: builtins.replaceStrings [ ".nix" ] [ "" ] (baseNameOf file)) (
builtins.attrNames (builtins.readDir ./modules/dev)
)
);
commonModules = name: [
{
nixpkgs.overlays = [
(import ./config/overlay.nix { inherit mkpkgs inputs; })
inputs.doom-emacs.overlays.default
];
}
{
nix.registry = {
jawz.flake = self;
unstable.flake = inputs.nixpkgs-unstable;
};
}
./hosts/${name}/configuration.nix
inputs.nur.modules.nixos.default
inputs.sops-nix.nixosModules.sops
inputs.stylix.nixosModules.stylix
inputs.nixtendo-switch.nixosModules.nixtendo-switch
];
createConfig =
name: local-nixpkgs:
let
lib = local-nixpkgs.lib // inputs.home-manager.lib;
in
lib.nixosSystem {
inherit system;
specialArgs = {
inherit inputs outputs;
};
modules = commonModules name;
};
in
{
nixosConfigurations = {
workstation = createConfig "workstation" inputs.nixpkgs;
miniserver = createConfig "miniserver" inputs.nixpkgs-small;
server = createConfig "server" inputs.nixpkgs-small;
galaxy = createConfig "galaxy" inputs.nixpkgs-small;
emacs = createConfig "emacs" inputs.nixpkgs;
};
packages.${system} = (jawz-scripts.packages.${system} or { }) // {
emacs-vm = inputs.nixos-generators.nixosGenerate {
inherit system;
specialArgs = {
inherit inputs outputs;
};
modules = commonModules "emacs";
format = "vm";
};
};
devShells.${system} = builtins.listToAttrs (
map (name: {
inherit name;
value = self.nixosConfigurations.emacs.config.devShells.${name};
}) langList
);
};
}

View File

@ -0,0 +1,49 @@
{
lib,
...
}:
{
imports = [
../../config/base.nix
../../config/stylix.nix
../../environments/hyprland.nix
];
virtualisation.vmVariant.virtualisation = {
memorySize = 4096;
cores = 4;
graphics = true;
resolution = {
x = 1920;
y = 1080;
};
};
my = {
secureHost = false;
stylix.enable = true;
emacs.enable = true;
apps.fonts.enable = true;
shell.tools.enable = true;
services.network.enable = true;
dev = {
nix.enable = true;
python.enable = true;
sh.enable = true;
rust.enable = true;
ruby.enable = true;
javascript.enable = true;
go.enable = true;
haskell.enable = true;
cc.enable = true;
julia.enable = true;
zig.enable = true;
docker.enable = true;
};
interfaces = lib.mkMerge [
{
emacs = "eth0";
}
];
};
networking.hostName = "emacs";
environment.systemPackages = [ ];
}

View File

@ -0,0 +1,7 @@
{ ... }:
{
imports = [
../../config/base.nix
../../config/stylix.nix
];
}

View File

@ -0,0 +1,52 @@
{ config, ... }:
{
imports = [
./hardware-configuration.nix
../../config/base.nix
../../config/stylix.nix
];
my = import ./toggles.nix // {
nix.cores = 3;
nix.maxJobs = 8;
users.nixremote.enable = true;
users.nixremote.authorizedKeys = [
../../secrets/ssh/ed25519_nixworkstation.pub
../../secrets/ssh/ed25519_nixserver.pub
];
};
nix.buildMachines =
let
buildMachine = hostName: maxJobs: speedFactor: {
inherit hostName maxJobs speedFactor;
system = "x86_64-linux";
sshUser = "nixremote";
supportedFeatures = config.my.nix.features;
};
in
[
(buildMachine "workstation" 8 40)
(buildMachine "server" 6 17)
];
networking = {
hostName = "miniserver";
firewall = {
allowedTCPPorts = [ 2049 ];
allowedUDPPorts = [ 2049 ];
};
};
nixpkgs.config.permittedInsecurePackages = [ "openssl-1.1.1w" ];
services = {
btrfs.autoScrub = {
enable = true;
fileSystems = [ "/" ];
};
minidlna = {
enable = false;
openFirewall = true;
settings = {
inotify = "yes";
media_dir = [ "/srv/pool/" ];
};
};
};
}

View File

@ -0,0 +1,139 @@
{
lib,
modulesPath,
pkgs,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
hardware = {
cpu.intel.updateMicrocode = lib.mkDefault true;
graphics = {
enable = true;
enable32Bit = true;
extraPackages = [ pkgs.vpl-gpu-rt ];
};
};
boot = {
kernelModules = [ "kvm-intel" ];
kernel.sysctl."vm.swappiness" = 80;
loader = {
efi = {
canTouchEfiVariables = true;
efiSysMountPoint = "/boot/efi";
};
grub = {
enable = true;
device = "nodev";
efiSupport = true;
enableCryptodisk = true;
};
};
extraModulePackages = [ ];
initrd = {
secrets."/keyfile" = /etc/keyfile;
luks.devices.nvme = {
device = "/dev/disk/by-uuid/30fd7d86-9bed-42a6-8a4e-a2ddb0031233";
keyFile = "keyfile";
preLVM = true;
};
availableKernelModules = [
"xhci_pci"
"ahci"
"usbhid"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
"sdhci_pci"
];
kernelModules = [ "kvm-intel" ];
};
};
fileSystems =
let
nfsMount = server: nfsDisk: {
device = "${server}:/${nfsDisk}";
fsType = "nfs";
options = [
"x-systemd.automount"
"noauto"
"x-systemd.idle-timeout=600"
];
};
in
{
"/" = {
device = "/dev/mapper/nvme";
fsType = "btrfs";
options = [
"subvol=nix"
"ssd"
"compress=zstd:3"
"x-systemd.device-timeout=0"
"space_cache=v2"
"commit=120"
"datacow"
"noatime"
];
};
"/home" = {
device = "/dev/mapper/nvme";
fsType = "btrfs";
options = [
"subvol=home"
"ssd"
"compress=zstd:3"
"x-systemd.device-timeout=0"
"space_cache=v2"
"commit=120"
"datacow"
];
};
"/boot" = {
device = "/dev/disk/by-uuid/bf0aeb95-94cc-4377-b6e4-1dbb4958b334";
fsType = "ext4";
};
"/boot/efi" = {
device = "/dev/disk/by-uuid/0C7B-4D4C";
fsType = "vfat";
};
"/var/lib/nextcloud/data" = {
device = "/srv/pool/nextcloud";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
"/export/pool" = {
device = "/srv/pool";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
"/export/jawz" = {
device = "/home/jawz";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
"/srv/server/pool" = nfsMount "server" "pool" // { };
"/srv/server/jawz" = nfsMount "server" "jawz" // { };
};
services.nfs.server = {
enable = true;
exports = ''
/export workstation(rw,fsid=0,no_subtree_check)
/export/jawz workstation(rw,nohide,insecure,no_subtree_check)
/export/pool workstation(rw,nohide,insecure,no_subtree_check)
'';
};
swapDevices = [
{
device = "/dev/nvme0n1p3";
randomEncryption = {
enable = true;
cipher = "aes-xts-plain64";
keySize = 512;
sectorSize = 4096;
};
}
];
}

View File

@ -0,0 +1,50 @@
let
mkEnabled = name: {
inherit name;
value.enable = true;
};
mkEnabledWithProxy = name: {
inherit name;
value = {
enable = true;
enableProxy = true;
};
};
enableList = func: list: list |> map func |> builtins.listToAttrs;
in
{
emacs.enable = true;
enableProxy = true;
websites.portfolio.enableProxy = true;
apps = enableList mkEnabled [
"dictionaries"
];
services = enableList mkEnabled [
"network"
];
shell = enableList mkEnabled [
"tools"
"multimedia"
];
dev = enableList mkEnabled [
"nix"
"python"
"sh"
];
units = enableList mkEnabled [
"download"
"stream-dl"
];
scripts = enableList mkEnabled [
"split-dir"
"pika-list"
"update-dns"
];
servers =
enableList mkEnabled [
"qbittorrent"
]
// enableList mkEnabledWithProxy [
"audiobookshelf"
];
}

View File

@ -0,0 +1,74 @@
{
pkgs,
config,
lib,
...
}:
{
imports = [
./hardware-configuration.nix
../../config/base.nix
../../config/stylix.nix
];
my = import ./toggles.nix { inherit config; } // {
nix.cores = 6;
users.nixremote.enable = true;
users.nixremote.authorizedKeys = [
../../secrets/ssh/ed25519_nixworkstation.pub
../../secrets/ssh/ed25519_nixminiserver.pub
];
network.firewall.enabledServicePorts = true;
network.firewall.additionalPorts = [
2049 # idk
8384 # syncthing gui
22000 # syncthing relay
3452 # sonarqube
8448 # synapse ssl
];
};
nix.buildMachines = [
{
hostName = "workstation";
system = "x86_64-linux";
sshUser = "nixremote";
maxJobs = 8;
speedFactor = 2;
supportedFeatures = config.my.nix.features;
}
];
sops.secrets."vps/home/private" = lib.mkIf config.my.secureHost {
sopsFile = ../../secrets/wireguard.yaml;
};
networking = {
hostName = "server";
firewall = {
allowedUDPPorts = config.networking.firewall.allowedTCPPorts;
interfaces.wg0.allowedTCPPorts = [ 8081 ];
};
wireguard.interfaces.wg0 = lib.mkIf config.my.secureHost {
ips = [ "${config.my.ips.wg-server}/32" ];
privateKeyFile = config.sops.secrets."vps/home/private".path;
peers = [
{
publicKey = "dFbiSekBwnZomarcS31o5+w6imHjMPNCipkfc2fZ3GY=";
endpoint = "${config.my.ips.vps}:51820";
allowedIPs = [
"${config.my.ips.wg-vps}/32"
"${config.my.ips.wg-friends}/24" # all friends
];
persistentKeepalive = 25;
}
];
};
};
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs) podman-compose attic-client;
};
services.btrfs.autoScrub = {
enable = true;
fileSystems = [
"/"
"/srv/pool"
];
};
}

View File

@ -0,0 +1,187 @@
{ lib, modulesPath, ... }:
let
getUUID = uuid: "/dev/disk/by-uuid/${uuid}";
in
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
hardware.cpu.intel.updateMicrocode = lib.mkDefault true;
security.pam.loginLimits = [
{
domain = "*";
type = "hard";
item = "nofile";
value = "131072";
}
{
domain = "*";
type = "soft";
item = "nofile";
value = "131072";
}
{
domain = "*";
type = "hard";
item = "nproc";
value = "8192";
}
{
domain = "*";
type = "soft";
item = "nproc";
value = "8192";
}
];
boot = {
loader = {
efi = {
canTouchEfiVariables = true;
efiSysMountPoint = "/boot/efi";
};
grub = {
enable = true;
device = "nodev";
efiSupport = true;
enableCryptodisk = true;
};
};
initrd = {
secrets."/keyfile" = /etc/keyfile;
luks.devices =
let
decryptLuks = uuid: {
device = getUUID uuid;
keyFile = "/keyfile";
preLVM = true;
};
in
{
nvme = decryptLuks "af72f45c-cf7c-4e7d-8eab-2a95ab754921";
disk1 = decryptLuks "a9b0f346-7e38-40a6-baf6-3ad80cafc842";
disk2 = decryptLuks "0ed12b83-4c56-4ba8-b4ea-75a9e927d771";
disk3 = decryptLuks "8cd728f6-0d5b-4cea-8f7d-01aad11192c1";
disk4 = decryptLuks "7fcac808-491f-4846-a4a9-a34cc77cb43d";
disk5 = decryptLuks "1d05cf50-0f5f-427a-b41f-fab0d11e85e9";
};
};
kernelModules = [ "kvm-intel" ];
kernel.sysctl = {
"vm.swappiness" = 80;
"vm.max_map_count" = 524288;
"fs.file-max" = 131072;
};
extraModulePackages = [ ];
initrd = {
availableKernelModules = [
"xhci_pci"
"ahci"
"usbhid"
"nvme"
"usb_storage"
"sd_mod"
];
kernelModules = [ ];
};
};
fileSystems = {
"/" = {
device = "/dev/mapper/nvme";
fsType = "btrfs";
options = [
"subvol=nix"
"ssd"
"compress=zstd:3"
"x-systemd.device-timeout=0"
"space_cache=v2"
"commit=120"
"datacow"
"noatime"
];
};
"/home" = {
device = "/dev/mapper/nvme";
fsType = "btrfs";
options = [
"subvol=home"
"ssd"
"compress=zstd:3"
"x-systemd.device-timeout=0"
"space_cache=v2"
"commit=120"
"datacow"
];
};
"/boot" = {
device = "/dev/disk/by-uuid/c574cb53-dc40-46db-beff-0fe8a4787156";
fsType = "ext4";
options = [ "nofail" ];
};
"/boot/efi" = {
device = "/dev/disk/by-uuid/CBE7-5DEB";
fsType = "vfat";
};
"/srv/pool" = {
device = "/dev/disk/by-uuid/1e7cf787-e34d-4e3e-ac3c-0c07309dbd34";
fsType = "btrfs";
options = [
"subvol=@data"
"compress=zstd:3"
"space_cache=v2"
"commit=120"
"datacow"
];
depends = [ "/boot/efi" ];
};
"/var/lib/nextcloud/data" = {
device = "/srv/pool/nextcloud";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
"/srv/jellyfin/media" = {
device = "/srv/pool/multimedia/media";
options = [
"bind"
"ro"
];
depends = [ "/srv/pool" ];
};
"/export/pool" = {
device = "/srv/pool";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
"/export/jawz" = {
device = "/home/jawz";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
"/export/backups" = {
device = "/srv/backups";
options = [ "bind" ];
depends = [ "/srv/pool" ];
};
};
services.nfs.server = {
enable = true;
exports = ''
/export workstation(rw,fsid=0,no_subtree_check)
miniserver(rw,fsid=0,no_subtree_check)
/export/jawz workstation(rw,nohide,insecure,no_subtree_check)
miniserver(rw,nohide,insecure,no_subtree_check)
/export/pool workstation(rw,nohide,insecure,no_subtree_check)
miniserver(rw,nohide,insecure,no_subtree_check)
/export/backups workstation(rw,nohide,insecure,no_subtree_check)
miniserver(rw,nohide,insecure,no_subtree_check)
'';
};
swapDevices = [
{
device = "/dev/disk/by-partuuid/cb0ad486-ebf8-4bfc-ad7c-96bdc68576ca";
randomEncryption = {
enable = true;
cipher = "aes-xts-plain64";
keySize = 512;
sectorSize = 4096;
};
}
];
}

92
hosts/server/toggles.nix Normal file
View File

@ -0,0 +1,92 @@
{ config }:
let
mkEnabled = name: {
inherit name;
value.enable = true;
};
mkEnabledIp = name: {
inherit name;
value = {
enable = true;
ip = config.my.ips.wg-server;
};
};
enableList = func: list: list |> map func |> builtins.listToAttrs;
in
{
mainServer = "server";
emacs.enable = true;
stylix.enable = true;
enableProxy = true;
enableContainers = true;
apps.dictionaries.enable = true;
shell = enableList mkEnabled [
"tools"
"multimedia"
];
services = enableList mkEnabled [
"network"
"nvidia"
];
dev = enableList mkEnabled [
"nix"
"python"
"sh"
];
units = enableList mkEnabled [
"downloadManga"
"download"
"stream-dl"
];
scripts = enableList mkEnabled [
"run"
"download"
"split-dir"
"ffmpreg"
"ffmpeg4discord"
"manage-library"
"library-report"
"stream-dl"
"pika-list"
"find-dup-episodes"
"tuh-activity-logger"
];
servers = {
nextcloud = {
enable = true;
enableCron = true;
enableProxy = true;
};
}
// enableList mkEnabled [
"qbittorrent"
"sabnzbd"
"unpackerr"
"postgres"
"paperless"
"bazarr"
"collabora"
"homepage"
"kavita"
"lidarr"
"maloja"
"microbin"
"multi-scrobbler"
"plex"
"prowlarr"
"radarr"
"ryot"
"sonarr"
"synapse"
"jellyfin"
"gitea"
"mealie"
"metube"
"atticd"
]
// enableList mkEnabledIp [
"audiobookshelf"
"vaultwarden"
"readeck"
];
}

View File

@ -0,0 +1,173 @@
{
lib,
pkgs,
config,
...
}:
let
shellType = config.my.shell.type;
krita-thumbnailer = pkgs.writeTextFile {
name = "krita-thumbnailer";
destination = "/share/thumbnailers/kra.thumbnailer";
text = ''
[Thumbnailer Entry]
Exec=sh -c "${pkgs.unzip}/bin/unzip -p %i preview.png > %o"
MimeType=application/x-krita;
'';
};
in
{
imports = [
./hardware-configuration.nix
../../config/base.nix
../../config/stylix.nix
];
my = import ./toggles.nix // {
nix.cores = 8;
nix.maxJobs = 8;
users.nixremote.enable = true;
users.nixremote.authorizedKeys = [
../../secrets/ssh/ed25519_nixserver.pub
../../secrets/ssh/ed25519_nixminiserver.pub
];
};
home-manager.users.jawz = {
programs = {
vscode = {
enable = true;
package = pkgs.vscode;
};
ghostty = {
enable = true;
package = pkgs.ghostty;
enableBashIntegration = shellType == "bash";
enableZshIntegration = shellType == "zsh";
installBatSyntax = true;
installVimSyntax = true;
};
};
};
specialisation = {
gnome.configuration = {
imports = [ ../../environments/gnome.nix ];
services.flatpak.enable = true;
};
hyprland.configuration = {
imports = [ ../../environments/hyprland.nix ];
services.flatpak.enable = true;
};
};
networking = {
hostName = "workstation";
firewall =
let
kdeconnectPortRange = {
from = 1714;
to = 1764;
};
ns-usbloaderPort = 6674;
syncthingPort = 8384;
openPorts = [
ns-usbloaderPort
syncthingPort
];
openPortRanges = [ kdeconnectPortRange ];
in
{
allowedTCPPorts = openPorts;
allowedUDPPorts = openPorts;
allowedTCPPortRanges = openPortRanges;
allowedUDPPortRanges = openPortRanges;
};
};
users.users.jawz.packages = [
(pkgs.google-cloud-sdk.withExtraComponents [
pkgs.google-cloud-sdk.components.gke-gcloud-auth-plugin
])
]
++ builtins.attrValues {
inherit (pkgs)
distrobox # install packages from other os
gocryptfs # encrypted filesystem! shhh!!!
vcsi # video thumbnails for torrents, can I replace it with ^?
keypunch # practice typing
google-cloud-sdk-gce
;
};
environment = {
pathsToLink = [ "share/thumbnailers" ];
systemPackages = builtins.attrValues {
# thumbnail for heif files & videos
inherit krita-thumbnailer;
inherit (pkgs)
libheif
ffmpegthumbnailer
bign-handheld-thumbnailer
gnome-epub-thumbnailer
podman-compose
code-cursor
scrcpy
;
inherit (pkgs.libheif) out;
};
etc."wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = ''
bluez_monitor.properties = {
["bluez5.enable-sbc-xq"] = true,
["bluez5.enable-msbc"] = true,
["bluez5.enable-hw-volume"] = true,
["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
}
'';
};
programs = {
kdeconnect = {
enable = true;
package = pkgs.gnomeExtensions.gsconnect;
};
obs-studio = {
enable = true;
enableVirtualCamera = true;
plugins = builtins.attrValues {
inherit (pkgs.obs-studio-plugins)
droidcam-obs
obs-vkcapture
obs-vaapi
obs-tuna
input-overlay
;
};
};
};
security.pki.certificateFiles = [
../../secrets/ssh/iqQCY4iAWO-ca.pem
../../secrets/ssh/root-private-ca.pem
];
services = {
flatpak.enable = lib.mkDefault false;
open-webui.enable = true;
scx = {
enable = true;
scheduler = "scx_lavd";
};
btrfs.autoScrub = {
enable = true;
fileSystems = [ "/" ];
};
protonmail-bridge = {
enable = true;
path = [ pkgs.gnome-keyring ];
};
ollama = {
enable = true;
acceleration = "cuda";
models = "/srv/ai/ollama";
};
sunshine = {
enable = true;
autoStart = true;
capSysAdmin = true;
openFirewall = true;
};
tailscale.enable = true;
};
}

View File

@ -0,0 +1,144 @@
{
modulesPath,
config,
pkgs,
inputs,
lib,
...
}:
let
getMapper = mapper: "/dev/mapper/${mapper}";
getUUID = uuid: "/dev/disk/by-uuid/${uuid}";
in
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
inputs.ucodenix.nixosModules.default
];
services = {
udev.extraRules = lib.mkIf config.my.apps.gaming.enable ''
SUBSYSTEM=="usb", ATTRS{idVendor}=="0cf3", ATTRS{idProduct}=="3005", TAG+="uaccess"
'';
ucodenix = {
enable = true;
cpuModelId = "00A50F00";
};
};
hardware.bluetooth = {
enable = true;
settings.General = {
Enable = "Source,Sink,Media,Socket";
Experimental = true;
};
};
boot = {
plymouth.enable = true;
consoleLogLevel = 0;
loader.timeout = 5;
kernelParams = [
"splash"
"boot.shell_on_fail"
"loglevel=3"
"rd.systemd.show_status=false"
"rd.udev.log_level=3"
"udev.log_priority=3"
"preempt=full"
"microcode.amd_sha_check=off"
];
kernelPackages = pkgs.linuxPackages;
kernel.sysctl = {
"vm.swappiness" = 80;
"net.ipv4.tcp_mtu_probing" = 1;
"kernel.sched_cfsbandwidth_slice_us" = lib.mkDefault 3000;
"net.ipv4.tcp_fin_timeout" = lib.mkDefault 5;
"vm.max_map_count" = lib.mkDefault 2147483642;
};
loader = {
efi = {
canTouchEfiVariables = true;
efiSysMountPoint = "/boot/efi";
};
grub = {
enable = true;
device = "nodev";
efiSupport = true;
useOSProber = true;
enableCryptodisk = true;
};
};
initrd = {
verbose = false;
secrets."/keyfile" = /etc/keyfile;
availableKernelModules = [
"xhci_pci"
"ahci"
"usbhid"
"nvme"
"usb_storage"
"sd_mod"
];
luks.devices.nvme = {
device = getUUID "e9618e85-a631-4374-b2a4-22c376d6e41b";
keyFile = "/keyfile";
preLVM = true;
};
};
};
fileSystems =
let
nfsMount = server: nfsDisk: {
device = "${server}:/${nfsDisk}";
fsType = "nfs";
options = [
"x-systemd.automount"
"noauto"
"x-systemd.idle-timeout=600"
];
};
btrfsMount = device: subvol: extraOpts: {
inherit device;
fsType = "btrfs";
options = extraOpts ++ [
"subvol=${subvol}"
"ssd"
"compress=lzo"
"x-systemd.device-timeout=0"
"space_cache=v2"
"commit=120"
"datacow"
];
};
trashOptions = [
"x-gvfs-trash"
"x-gvfs-show"
];
in
{
"/" = btrfsMount (getMapper "nvme") "nixos" [ "noatime" ];
"/home" = btrfsMount (getMapper "nvme") "home" [ ];
"/srv/games" = btrfsMount (getMapper "nvme") "games" trashOptions;
"/srv/ai" = btrfsMount (getUUID "ca1671e1-e201-4960-ad30-593393f970fb") "ai" trashOptions;
"/srv/pool" = nfsMount "server" "pool";
"/srv/server_home" = nfsMount "server" "jawz";
"/srv/backups" = nfsMount "server" "backups";
"/boot" = {
device = getUUID "ac6d349a-96b9-499e-9009-229efd7743a5";
fsType = "ext4";
};
"/boot/efi" = {
device = getUUID "B05D-B5FB";
fsType = "vfat";
};
};
swapDevices = [
{
device = "/dev/disk/by-partuuid/c1bd22d7-e62c-440a-88d1-6464be1aa1b0";
randomEncryption = {
enable = true;
cipher = "aes-xts-plain64";
keySize = 512;
sectorSize = 4096;
};
}
];
}

View File

@ -0,0 +1,51 @@
let
mkEnabled = name: {
inherit name;
value.enable = true;
};
enableList = func: list: list |> map func |> builtins.listToAttrs;
in
{
stylix.enable = true;
emacs.enable = true;
enableContainers = true;
servers.drpp.enable = true;
apps = enableList mkEnabled [
"art"
"piano"
"dictionaries"
"fonts"
"gaming"
"switch"
"internet"
"multimedia"
"office"
"misc"
];
dev = enableList mkEnabled [
"nix"
"python"
"gameDev"
"sh"
];
shell = enableList mkEnabled [
"exercism"
"multimedia"
"tools"
];
services = enableList mkEnabled [
"network"
"nvidia"
"printing"
"sound"
];
scripts = enableList mkEnabled [
"tasks"
"run"
"split-dir"
"download"
"ffmpreg"
"ffmpeg4discord"
"update-org-agenda-cache"
];
}

44
modules/apps/art.nix Normal file
View File

@ -0,0 +1,44 @@
{
config,
lib,
pkgs,
...
}:
let
# Patch to libpng so that big brushes can be loaded
patched-krita = pkgs.replaceDependency {
drv = pkgs.krita;
oldDependency = pkgs.libpng;
newDependency = pkgs.libpng.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [ ../../patches/libpng.patch ];
});
};
attrValuesIf = cond: attrs: if cond then builtins.attrValues attrs else [ ];
artPackages = attrValuesIf config.my.apps.art.enable {
inherit patched-krita; # art to your heart desire!
inherit (pkgs)
eyedropper # color picker
emulsion-palette # self explanatory
gimp # the coolest bestest art program to never exist
mypaint # not the best art program
mypaint-brushes # but it's got some
mypaint-brushes1 # nice damn brushes
blender # cgi animation and sculpting
drawpile # arty party with friends!!
pureref # create inspiration/reference boards
;
};
gameDevPackages = attrValuesIf config.my.dev.gameDev.enable {
inherit (pkgs)
godot_4 # game development
gdtoolkit_4 # gdscript language server
;
};
in
{
options.my = {
apps.art.enable = lib.mkEnableOption "digital art and creative applications";
dev.gameDev.enable = lib.mkEnableOption "game development tools and engines";
};
config.users.users.jawz.packages = artPackages ++ gameDevPackages;
}

View File

@ -0,0 +1,21 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.apps.dictionaries.enable = lib.mkEnableOption "dictionaries and language tools";
config = lib.mkIf config.my.apps.dictionaries.enable {
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
hunspell
;
inherit (pkgs.hunspellDicts)
it_IT
es_MX
en_CA-large
;
};
};
}

44
modules/apps/fonts.nix Normal file
View File

@ -0,0 +1,44 @@
{
config,
lib,
pkgs,
inputs,
...
}:
let
customFonts = pkgs.stdenvNoCC.mkDerivation {
name = "custom-fonts";
src = inputs.fonts;
installPhase = ''
mkdir -p $out/share/fonts
find $src -type f \( \
-name "*.ttf" -o \
-name "*.otf" -o \
-name "*.woff" -o \
-name "*.woff2" \
\) -exec cp {} $out/share/fonts/ \;
'';
};
in
{
options.my.apps.fonts.enable = lib.mkEnableOption "additional fonts and typography";
config = lib.mkIf config.my.apps.fonts.enable {
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "corefonts" ];
fonts.packages = builtins.attrValues {
inherit customFonts;
inherit (pkgs)
symbola
comic-neue
cascadia-code
corefonts
;
inherit (pkgs.nerd-fonts)
caskaydia-cove
open-dyslexic
comic-shanns-mono
iosevka
agave
;
};
};
}

60
modules/apps/gaming.nix Normal file
View File

@ -0,0 +1,60 @@
{
inputs,
config,
lib,
pkgs,
...
}:
{
imports = [ inputs.nix-gaming.nixosModules.platformOptimizations ];
options.my.apps = {
gaming.enable = lib.mkEnableOption "gaming applications and emulators";
switch.enable = lib.mkEnableOption "Nintendo Switch homebrew tools";
};
config = lib.mkIf config.my.apps.gaming.enable {
# sops.secrets.switch-presence = lib.mkIf config.my.apps.gaming.switch.enable {
# sopsFile = ../../secrets/env.yaml;
# format = "dotenv";
# owner = config.users.users.jawz.name;
# inherit (config.users.users.jawz) group;
# };
programs = {
gamemode.enable = true;
steam = {
enable = true;
gamescopeSession.enable = true;
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
platformOptimizations.enable = true;
};
};
services = lib.mkIf config.my.apps.switch.enable {
switch-boot.enable = true;
# switch-presence = {
# enable = true;
# environmentFile = config.sops.secrets.switch-presence.path;
# };
};
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
shipwright # zelda OoT port
mangohud # fps & stats overlay
lutris # games launcher & emulator hub
cartridges # games launcher
gamemode # optimizes linux to have better gaming performance
heroic # install epic games
protonup-qt # update proton-ge
ns-usbloader # load games into my switch
# emulators
rpcs3 # ps3
pcsx2 # ps2
cemu # wii u
dolphin-emu # wii
snes9x-gtk # snes
ryubing # switch
azahar # 3Ds
prismlauncher # minecraft launcher with jdk overlays
;
};
};
}

56
modules/apps/internet.nix Normal file
View File

@ -0,0 +1,56 @@
{
config,
lib,
pkgs,
...
}:
let
krisp-patcher =
pkgs.writers.writePython3Bin "krisp-patcher"
{
libraries = builtins.attrValues {
inherit (pkgs.python3Packages)
capstone
pyelftools
;
};
flakeIgnore = [
"E501" # line too long (82 > 79 characters)
"F403" # 'from module import *' used; unable to detect undefined names
"F405" # name may be undefined, or defined from star imports: module
];
}
(
builtins.readFile (
pkgs.fetchurl {
url = "https://pastebin.com/raw/8tQDsMVd";
sha256 = "sha256-IdXv0MfRG1/1pAAwHLS2+1NESFEz2uXrbSdvU9OvdJ8=";
}
)
);
in
{
options.my.apps.internet.enable = lib.mkEnableOption "internet browsers and communication apps";
config = lib.mkIf config.my.apps.internet.enable {
home-manager.users.jawz.programs.librewolf = import ./librewolf.nix;
programs.geary.enable = true;
users.users.jawz.packages = builtins.attrValues {
# inherit (inputs.zen-browser.packages.x86_64-linux) twilight;
inherit krisp-patcher;
inherit (pkgs)
# thunderbird # email client
warp # transfer files with based ppl
brave # crypto-browser that at least somewhat integrates with gtk
nextcloud-client # self-hosted google-drive alternative
fragments # beautiful torrent client
tor-browser-bundle-bin # dark web, so dark!
telegram-desktop # furry chat
nicotine-plus # remember Ares?
discord # :3
vdhcoapp # video download helper assistant
nextcloud-talk-desktop # nextcloud talk client
fractal # matrix client
;
};
};
}

View File

@ -0,0 +1,79 @@
{
enable = true;
languagePacks = [
"en-CA"
"es-MX"
"it"
];
policies.DisabledFirefoxAccounts = false;
profiles.jawz = {
id = 0;
name = "jawz";
path = "jawz";
settings = {
# Enable custom userChrome.css (for GNOME theme)
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
# Enables Firefox GNOME Theme SVG icons
"svg.context-properties.content.enabled" = true;
# GNOME theme refinements
"gnomeTheme.hideSingleTab" = true;
"gnomeTheme.bookmarksToolbarUnderTabs" = true;
"gnomeTheme.allTabsButtonOnOverflow" = true;
# Normal UI density
"browser.uidensity" = 0;
"browser.toolbars.bookmarks.visibility" = "never";
"general.autoScroll" = true;
# Tabs
"browser.sessionstore.resume_from_crash" = true;
"browser.sessionstore.max_tabs_undo" = 50;
"browser.startup.page" = 3;
# DRM
"media.eme.enabled" = true;
# Prevents private windows from using dark theme
"browser.theme.dark-private-windows" = false;
# Enables rounded corners on the main window
"widget.gtk.rounded-bottom-corners.enabled" = true;
# General privacy & fingerprinting
"privacy.sanitize.sanitizeOnShutdown" = false;
"privacy.clearOnShutdown_v2.browsingHistoryAndDownloads" = false;
"privacy.resistFingerprinting" = false; # You explicitly disabled this
"privacy.fingerprintingProtection" = true;
"privacy.query_stripping.enabled" = true;
"privacy.query_stripping.enabled.pbmode" = true;
"privacy.trackingprotection.enabled" = true;
"privacy.trackingprotection.socialtracking.enabled" = true;
"privacy.trackingprotection.emailtracking.enabled" = true;
"privacy.bounceTrackingProtection.mode" = 1;
"privacy.clearSiteData.cookiesAndStorage" = false;
"privacy.clearSiteData.historyFormDataAndDownloads" = true;
# Do Not Track
"privacy.donottrackheader.enabled" = true;
# GPC (Global Privacy Control)
"privacy.globalprivacycontrol.was_ever_enabled" = true;
# DNS-over-HTTPS (LibreDNS with adblock)
"network.trr.mode" = 2;
"network.trr.uri" = "https://doh.libredns.gr/noads";
# Prevent predictive browsing
"network.prefetch-next" = false;
"network.predictor.enabled" = false;
"network.http.speculative-parallel-limit" = 0;
# Referrer sanitization
"network.http.referer.disallowCrossSiteRelaxingDefault.top_navigation" = true;
# Partitioning and isolation
"network.cookie.cookieBehavior.optInPartitioning" = true;
# HTTPS-only
"dom.security.https_only_mode_ever_enabled" = true;
# Disable captive portal checks
"network.captive-portal-service.enabled" = false;
"network.connectivity-service.enabled" = false;
# Permissions tightening
"permissions.delegation.enabled" = false;
# Disable safe browsing remote lookups (relies on Google)
"browser.safebrowsing.downloads.remote.enabled" = false;
"browser.safebrowsing.downloads.remote.block_potentially_unwanted" = false;
"browser.safebrowsing.downloads.remote.block_uncommon" = false;
# Enable anti-cookie tracking + purge trackers
"privacy.annotate_channels.strict_list.enabled" = true;
};
};
}

20
modules/apps/misc.nix Normal file
View File

@ -0,0 +1,20 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.apps.misc.enable = lib.mkEnableOption "miscellaneous desktop applications";
config = lib.mkIf config.my.apps.misc.enable {
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
collector # stores things and throws them anywhere
blanket # background noise
metadata-cleaner # remove any metadata and geolocation from files
pika-backup # backups
gnome-obfuscate # censor private information
;
};
};
}

View File

@ -0,0 +1,25 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.apps.multimedia.enable = lib.mkEnableOption "multimedia applications and media players";
config = lib.mkIf config.my.apps.multimedia.enable {
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
recordbox # libadwaita music player
pitivi # video editor
celluloid # video player
curtail # image compressor
easyeffects # equalizer
handbrake # video converter, may be unnecessary
identity # compare images or videos
mousai # poor man shazam
shortwave # listen to world radio
tagger # tag music files
;
};
};
}

18
modules/apps/music.nix Normal file
View File

@ -0,0 +1,18 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.apps.piano.enable = lib.mkEnableOption "piano learning and music theory apps";
config = lib.mkIf config.my.apps.piano.enable {
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
neothesia
linthesia
timidity
;
};
};
}

22
modules/apps/office.nix Normal file
View File

@ -0,0 +1,22 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.apps.office.enable = lib.mkEnableOption "office applications and productivity tools";
config = lib.mkIf config.my.apps.office.enable {
environment.variables.CALIBRE_USE_SYSTEM_THEME = "1";
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs)
jre17_minimal # for libreoffice extensions
libreoffice # office, but based & european
calibre # ugly af eBook library manager
newsflash # feed reader, syncs with nextcloud
furtherance # I packaged this one tehee track time utility
# planify # let's pretend I will organize my tasks
;
};
};
}

36
modules/dev/cc.nix Normal file
View File

@ -0,0 +1,36 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs)
clang # C/C++ compiler frontend (part of LLVM)
clang-tools # Extra LLVM tools (e.g. clang-tidy, clang-apply-replacements)
gcc # GNU Compiler Collection (C, C++, etc.)
gdb # GNU Debugger
valgrind # Memory leak detector and performance profiler
;
};
in
{
options = {
my.dev.cc.enable = lib.mkEnableOption "Install C/C++ tooling globally";
devShells.cc = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "cc-dev-shell";
shellHook = ''
echo "🔧 C/C++ dev environment"
'';
};
description = "C/C++ development shell";
};
};
config = lib.mkIf config.my.dev.cc.enable {
users.users.jawz = { inherit packages; };
};
}

38
modules/dev/docker.nix Normal file
View File

@ -0,0 +1,38 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs) dockfmt; # Format Dockerfiles
inherit (pkgs.nodePackages)
dockerfile-language-server-nodejs # LSP for Dockerfiles
;
};
in
{
options = {
my.dev.docker.enable = lib.mkEnableOption "Install Docker tooling globally";
devShells.docker = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "docker-dev-shell";
shellHook = ''
echo "🐳 Docker dev environment"
'';
};
description = "Docker and Dockerfile tooling shell";
};
};
config = lib.mkMerge [
(lib.mkIf config.my.dev.docker.enable {
users.users.jawz = { inherit packages; };
})
{
environment.variables.DOCKER_CONFIG = "\${XDG_CONFIG_HOME}/docker";
}
];
}

73
modules/dev/emacs.nix Normal file
View File

@ -0,0 +1,73 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.emacs.enable = lib.mkEnableOption "Doom Emacs configuration";
config = lib.mkIf config.my.emacs.enable {
home-manager.users.jawz = {
xdg.dataFile = {
"doom/templates/events.org".source = ../../dotfiles/doom/templates/events.org;
"doom/templates/default.org".source = ../../dotfiles/doom/templates/default.org;
"doom/templates/programming.org".source = ../../dotfiles/doom/templates/programming.org;
};
services.lorri.enable = true;
programs.${config.my.shell.type}.shellAliases = {
edit = "emacsclient -t";
e = "edit";
};
};
users.users.jawz.packages = builtins.attrValues {
inherit (pkgs.xorg) xwininfo;
inherit (pkgs)
#emacs everywhere
xdotool
xclip
wl-clipboard-rs
fd # modern find, faster searches
fzf # fuzzy finder! super cool and useful
ripgrep # modern grep
tree-sitter # code parsing based on symbols and shit, I do not get it
graphviz # graphs
tetex # export pdf
languagetool # proofreader for English
# lsps
yaml-language-server
markdownlint-cli
;
inherit (pkgs.nodePackages)
vscode-json-languageserver
prettier # multi-language linter
;
};
services.emacs = {
enable = true;
defaultEditor = true;
package = pkgs.emacsWithDoom {
doomDir = ../../dotfiles/doom;
doomLocalDir = "/home/jawz/.local/share/nix-doom";
tangleArgs = "--all config.org";
extraPackages =
epkgs:
let
inherit (config.home-manager.users.jawz.programs.emacs)
extraPackages
extraConfig
;
extra = extraPackages epkgs;
themes = lib.optional config.my.stylix.enable [
(epkgs.trivialBuild {
pname = "stylix-theme";
src = pkgs.writeText "stylix-theme.el" extraConfig;
version = "0.1.0";
packageRequires = extra;
})
];
in
extra ++ themes;
};
};
};
}

44
modules/dev/go.nix Normal file
View File

@ -0,0 +1,44 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs)
go # Go compiler and core toolchain
gocode-gomod # Code completion for Go (modern fork of gocode)
gotools # Contains godoc, gorename, goimports, etc.
gore # Go REPL
gotests # Generate Go tests from function signatures
gomodifytags # Struct tag manipulation
golangci-lint # Linter aggregation
;
};
GOPATH = "\${XDG_DATA_HOME}/go";
in
{
options = {
my.dev.go.enable = lib.mkEnableOption "Install Go tooling globally";
devShells.go = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages GOPATH;
name = "go-dev-shell";
shellHook = ''
echo "🐹 Go dev environment"
'';
};
description = "Go development shell with Emacs tooling, REPL, formatter, and linter";
};
};
config = lib.mkMerge [
{
environment.variables = { inherit GOPATH; };
}
(lib.mkIf config.my.dev.go.enable {
users.users.jawz = { inherit packages; };
})
];
}

46
modules/dev/haskell.nix Normal file
View File

@ -0,0 +1,46 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs)
haskell-language-server # LSP server for Haskell
cabal-install # Standard Haskell build tool
hlint # Linter for Haskell source code
;
inherit (pkgs.haskellPackages)
hoogle # Haskell API search engine
;
};
in
{
options = {
my.dev.haskell.enable = lib.mkEnableOption "Install Haskell tooling globally";
devShells.haskell = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "haskell-dev-shell";
shellHook = ''
echo "λ Haskell dev environment"
'';
};
description = "Haskell development shell";
};
};
config = lib.mkMerge [
(lib.mkIf config.my.dev.haskell.enable {
users.users.jawz = { inherit packages; };
})
{
environment.variables = {
CABAL_DIR = "\${XDG_CACHE_HOME}/cabal";
STACK_ROOT = "\${XDG_DATA_HOME}/stack";
GHCUP_USE_XDG_DIRS = "true";
};
}
];
}

View File

@ -0,0 +1,50 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs) nodejs; # Node.js runtime
inherit (pkgs.nodePackages) pnpm; # Fast package manager alternative to npm
};
in
{
options = {
my.dev.javascript.enable = lib.mkEnableOption "Install JavaScript tooling globally";
devShells.javascript = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "javascript-dev-shell";
shellHook = ''
echo "📦 JavaScript dev environment"
'';
};
description = "JavaScript/Node development shell with npm/pnpm support";
};
};
config = lib.mkMerge [
(lib.mkIf config.my.dev.javascript.enable {
users.users.jawz = { inherit packages; };
})
{
home-manager.users.jawz.xdg.configFile = {
"npm/npmrc".source = ../../dotfiles/npmrc;
"configstore/update-notifier-npm-check.json".text = builtins.toJSON {
optOut = false;
lastUpdateCheck = 1646662583446;
};
};
environment.variables = {
NPM_CONFIG_USERCONFIG = "\${XDG_CONFIG_HOME}/npm/npmrc";
PNPM_HOME = "\${XDG_DATA_HOME}/pnpm";
PATH = [
"\${XDG_DATA_HOME}/npm/bin"
"\${XDG_DATA_HOME}/pnpm"
];
};
}
];
}

30
modules/dev/julia.nix Normal file
View File

@ -0,0 +1,30 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs) julia; # High-performance dynamic language for technical computing
};
in
{
options = {
my.dev.julia.enable = lib.mkEnableOption "Install Julia globally";
devShells.julia = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "julia-dev-shell";
shellHook = ''
echo "🔬 Julia dev environment"
'';
};
description = "Julia development shell";
};
};
config = lib.mkIf config.my.dev.julia.enable {
users.users.jawz = { inherit packages; };
};
}

43
modules/dev/nix.nix Normal file
View File

@ -0,0 +1,43 @@
{
config,
lib,
pkgs,
...
}:
let
shellType = config.my.shell.type;
packages = builtins.attrValues {
inherit (pkgs)
nixfmt-rfc-style # formatting
cachix # binary cache management
nixd # language server for Nix
statix # linter for Nix expressions
;
};
in
{
options = {
my.dev.nix.enable = lib.mkEnableOption "Install Nix tooling globally";
devShells.nix = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "nix-dev-shell";
shellHook = ''
echo " Nix dev environment"
'';
};
description = "Nix/NixOS development shell with formatter, linter, LSP, and Cachix";
};
};
config = lib.mkIf config.my.dev.nix.enable {
users.users.jawz = { inherit packages; };
home-manager.users.jawz.programs.${shellType}.shellAliases = {
nixformat = ''
nix run unstable#deadnix -- -e && \
nix run unstable#nixfmt-tree && \
nix run unstable#statix fix
'';
};
};
}

56
modules/dev/python.nix Normal file
View File

@ -0,0 +1,56 @@
{
config,
lib,
pkgs,
...
}:
let
python = pkgs.python3.withPackages (
ps:
builtins.attrValues {
inherit (ps)
black # Python code formatter
editorconfig # follow rules of contributin
flake8 # wraper for pyflakes, pycodestyle and mccabe
isort # sort Python imports
pyflakes # checks source code for errors
pylint # bug and style checker for python
pytest # tests
speedtest-cli # check internet speed from the comand line
;
}
);
packages = builtins.attrValues {
inherit python;
inherit (pkgs)
pipenv # python development workflow for humans
pyright # LSP
;
};
in
{
options = {
my.dev.python.enable = lib.mkEnableOption "Install Python tools globally";
devShells.python = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "python-dev-shell";
shellHook = ''
echo "🐍 Python dev environment"
which python
'';
description = "Python development shell";
};
};
};
config = lib.mkMerge [
(lib.mkIf config.my.dev.python.enable {
users.users.jawz = { inherit packages; };
})
{
home-manager.users.jawz.xdg.configFile."python/pythonrc".source = ../../dotfiles/pythonrc;
environment.variables.PYTHONSTARTUP = "\${XDG_CONFIG_HOME}/python/pythonrc";
}
];
}

40
modules/dev/ruby.nix Normal file
View File

@ -0,0 +1,40 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs) ruby; # Ruby interpreter
inherit (pkgs.rubyPackages) solargraph; # LSP for Ruby
};
in
{
options = {
my.dev.ruby.enable = lib.mkEnableOption "Install Ruby tooling globally";
devShells.ruby = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "ruby-dev-shell";
shellHook = ''
echo "💎 Ruby dev environment"
'';
};
description = "Ruby development shell with interpreter and Solargraph LSP";
};
};
config = lib.mkMerge [
(lib.mkIf config.my.dev.ruby.enable {
users.users.jawz = { inherit packages; };
})
{
environment.variables = {
GEM_HOME = "\${XDG_DATA_HOME}/ruby/gems";
GEM_PATH = "\${XDG_DATA_HOME}/ruby/gems";
GEM_SPEC_CACHE = "\${XDG_DATA_HOME}/ruby/specs";
};
}
];
}

41
modules/dev/rust.nix Normal file
View File

@ -0,0 +1,41 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs)
rustc # Rust compiler
cargo # Rust package manager
rust-analyzer # Language server for Rust
clippy # Linter for Rust
rustfmt # Formatter for Rust code
;
};
in
{
options = {
my.dev.rust.enable = lib.mkEnableOption "Install Rust tooling globally";
devShells.rust = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "rust-dev-shell";
shellHook = ''
echo "🦀 Rust dev environment"
'';
};
description = "Rust development shell with cargo and rust-analyzer";
};
};
config = lib.mkMerge [
(lib.mkIf config.my.dev.rust.enable {
users.users.jawz = { inherit packages; };
})
{
environment.variables.CARGO_HOME = "\${XDG_DATA_HOME}/cargo";
}
];
}

36
modules/dev/sh.nix Normal file
View File

@ -0,0 +1,36 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs)
bashdb # Debugger and completion support
shellcheck # Shell script linter
shfmt # Shell parser and formatter
;
# LSP for Bash and sh
inherit (pkgs.nodePackages) bash-language-server;
};
in
{
options = {
my.dev.sh.enable = lib.mkEnableOption "Install shell scripting tools globally";
devShells.sh = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "sh-dev-shell";
shellHook = ''
echo "💻 Shell scripting dev environment"
'';
};
description = "Shell scripting dev shell";
};
};
config = lib.mkIf config.my.dev.sh.enable {
users.users.jawz = { inherit packages; };
};
}

33
modules/dev/zig.nix Normal file
View File

@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
...
}:
let
packages = builtins.attrValues {
inherit (pkgs)
zig # Zig compiler and stdlib
zls # Language server for Zig
;
};
in
{
options = {
my.dev.zig.enable = lib.mkEnableOption "Install Zig tooling globally";
devShells.zig = lib.mkOption {
type = lib.types.package;
default = pkgs.mkShell {
inherit packages;
name = "zig-dev-shell";
shellHook = ''
echo "🦎 Zig dev environment"
'';
};
description = "Zig development shell with compiler and LSP";
};
};
config = lib.mkIf config.my.dev.zig.enable {
users.users.jawz = { inherit packages; };
};
}

View File

@ -0,0 +1,80 @@
{
config,
lib,
pkgs,
...
}:
{
options.my.scripts = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
enable = lib.mkEnableOption "Whether to enable this script";
install = lib.mkEnableOption "Whether to install the script package";
service = lib.mkEnableOption "Whether to enable the script service";
name = lib.mkOption {
type = lib.types.str;
description = "Name of the script.";
};
timer = lib.mkOption {
type = lib.types.str;
default = "*:0";
description = "Systemd timer schedule.";
};
description = lib.mkOption {
type = lib.types.str;
description = "Description of the service.";
};
package = lib.mkOption {
type = lib.types.package;
description = "Package containing the executable script.";
};
};
}
);
default = { };
description = "Configuration for multiple scripts.";
};
config = lib.mkIf (lib.any (s: s.enable) (lib.attrValues config.my.scripts)) {
users.users.jawz.packages =
config.my.scripts
|> lib.mapAttrsToList (_name: script: lib.optional (script.enable && script.install) script.package)
|> lib.flatten;
systemd.user.services =
config.my.scripts
|> lib.mapAttrs' (
_name: script:
lib.nameValuePair "${script.name}" (
lib.mkIf (script.enable && script.service) {
restartIfChanged = true;
inherit (script) description;
wantedBy = [ "default.target" ];
path = [
pkgs.nix
script.package
];
serviceConfig = {
Restart = "on-failure";
RestartSec = 30;
ExecStart = "${script.package}/bin/${script.name}";
};
}
)
);
systemd.user.timers =
config.my.scripts
|> lib.mapAttrs' (
_name: script:
lib.nameValuePair "${script.name}" (
lib.mkIf (script.enable && script.service) {
enable = true;
inherit (script) description;
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = script.timer;
};
}
)
);
};
}

View File

@ -0,0 +1,110 @@
{ lib, config, ... }:
let
mkOptions = name: subdomain: port: {
enable = lib.mkEnableOption "this server service";
enableCron = lib.mkEnableOption "enable cronjob";
enableProxy = lib.mkEnableOption "enable reverse proxy";
port = lib.mkOption {
type = lib.types.int;
default = port;
};
name = lib.mkOption {
type = lib.types.str;
default = name;
};
domain = lib.mkOption {
type = lib.types.str;
default = config.my.domain;
};
host = lib.mkOption {
type = lib.types.str;
default = "${subdomain}.${config.my.servers.${name}.domain}";
};
hostName = lib.mkOption {
type = lib.types.str;
default = config.networking.hostName;
};
url = lib.mkOption {
type = lib.types.str;
default = "https://${config.my.servers.${name}.host}";
};
ip = lib.mkOption {
type = lib.types.str;
default =
if config.my.servers."${name}".isLocal then
config.my.localhost
else
config.my.ips."${config.my.servers.${name}.hostName}";
};
local = lib.mkOption {
type = lib.types.str;
default = "http://${config.my.servers.${name}.ip}:${toString port}";
};
isLocal = lib.mkOption {
type = lib.types.bool;
default = "${config.my.servers.${name}.hostName}" == config.my.mainServer;
};
enableSocket = lib.mkOption {
type = lib.types.bool;
default = false;
};
certPath = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
};
};
proxy = locations: {
inherit locations;
forceSSL = true;
enableACME = true;
http2 = true;
};
proxyReverse =
cfg:
proxy {
"/" = {
proxyPass = "http://${cfg.ip}:${toString cfg.port}/";
proxyWebsockets = cfg.enableSocket;
};
};
proxyReverseFix =
cfg:
let
useLocalhost = cfg.hostName == config.networking.hostName;
localHeaders = ''
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
'';
in
proxyReverse cfg
// {
extraConfig = ''
${if useLocalhost then localHeaders else ""}
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_redirect off;
proxy_http_version 1.1;
'';
};
proxyReversePrivate =
cfg:
proxyReverse cfg
// {
extraConfig = ''
ssl_verify_client on;
ssl_client_certificate ${cfg.certPath};
error_page 403 /403.html;
'';
};
in
{
inherit
mkOptions
proxy
proxyReverse
proxyReverseFix
proxyReversePrivate
;
}

196
modules/modules.nix Normal file
View File

@ -0,0 +1,196 @@
{ lib, config, ... }:
let
filterNames = file: file != "librewolf.nix";
autoImport =
dir:
builtins.readDir ./${dir}
|> builtins.attrNames
|> builtins.filter (file: builtins.match ".*\\.nix" file != null && filterNames file)
|> map (file: ./${dir}/${file});
in
{
imports =
autoImport "apps"
++ autoImport "dev"
++ autoImport "scripts"
++ autoImport "servers"
++ autoImport "services"
++ autoImport "shell"
++ autoImport "network"
++ [
./nix/build.nix
./users/nixremote.nix
];
options.my = {
localhost = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "The localhost address.";
};
localhost6 = lib.mkOption {
type = lib.types.str;
default = "::1";
description = "The localhost ipv6 address.";
};
secureHost = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether this is a secure host that should use SOPS,";
};
domain = lib.mkOption {
type = lib.types.str;
default = "servidos.lat";
description = "The domain name.";
};
ips = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = {
router = "192.168.100.1";
server = "192.168.100.15";
miniserver = "192.168.1.100";
workstation = "192.168.100.18";
vps = "51.222.141.104";
wg-vps = "10.77.0.1";
wg-server = "10.77.0.2";
wg-friend1 = "10.8.0.2";
wg-friends = "10.8.0.0";
};
description = "Set of IP's for all my computers.";
};
interfaces = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = {
server = "enp0s31f6";
miniserver = "enp2s0";
workstation = "enp5s0";
};
description = "Set of network interface names for all my computers.";
};
mainServer = lib.mkOption {
type = lib.types.str;
default = "miniserver";
description = "The hostname of the main server.";
};
postgresSocket = lib.mkOption {
type = lib.types.str;
default = "/run/postgresql";
description = "The PostgreSQL socket path.";
};
containerSocket = lib.mkOption {
type = lib.types.str;
default = "/var/run/docker.sock";
description = "The docker/podman socket path.";
};
containerData = lib.mkOption {
type = lib.types.str;
default = "/var/lib/docker-configs";
description = "The docker/podman socket path.";
};
smtpemail = lib.mkOption {
type = lib.types.str;
default = "stunner6399@gmail.com";
description = "localhost smtp email";
};
email = lib.mkOption {
type = lib.types.str;
default = "CaptainJawZ@protonmail.com";
description = "localhost smtp email";
};
timeZone = lib.mkOption {
type = lib.types.str;
default = "America/Mexico_City";
description = "Timezone";
};
enableContainers = lib.mkEnableOption "container services (Docker/Podman)";
enableProxy = lib.mkEnableOption "nginx reverse proxy for services";
};
config = {
assertions = [
{
assertion = config.my.servers.nextcloud.enable -> config.my.servers.postgres.enable;
message = "Nextcloud requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.vaultwarden.enable -> config.my.servers.postgres.enable;
message = "Vaultwarden requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.firefly-iii.enable -> config.my.servers.postgres.enable;
message = "Firefly III requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.mealie.enable -> config.my.servers.postgres.enable;
message = "Mealie requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.shiori.enable -> config.my.servers.postgres.enable;
message = "Shiori requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.ryot.enable -> config.my.servers.postgres.enable;
message = "Ryot requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.synapse.enable -> config.my.servers.postgres.enable;
message = "Matrix Synapse requires PostgreSQL to be enabled";
}
{
assertion = config.my.servers.gitea.enable -> config.my.servers.postgres.enable;
message = "Gitea requires PostgreSQL to be enabled";
}
{
assertion =
config.my.enableProxy
-> (builtins.any (s: s.enableProxy or false) (builtins.attrValues config.my.servers));
message = "enableProxy is true but no services have enableProxy enabled";
}
{
assertion =
config.my.enableContainers
|| !(builtins.any (opt: opt) [
config.my.servers.ryot.enable
config.my.servers.lidarr.enable
config.my.servers.prowlarr.enable
config.my.servers.maloja.enable
config.my.servers.multi-scrobbler.enable
config.my.servers.flame.enable
config.my.servers.flameSecret.enable
config.my.servers.metube.enable
config.my.servers.go-vod.enable
config.my.servers.tranga.enable
config.my.servers.drpp.enable
config.my.servers.plex-discord-bot.enable
]);
message = "Container services are enabled but enableContainers is false";
}
];
virtualisation = {
containers.enable = true;
oci-containers.backend = "podman";
podman = lib.mkIf config.my.enableContainers {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
defaultNetwork.settings.dns_enabled = true;
autoPrune = {
enable = true;
flags = [ "--all" ];
dates = "weekly";
};
};
};
security.acme = lib.mkIf config.services.nginx.enable {
acceptTerms = true;
defaults.email = config.my.email;
};
services.nginx = {
enable = config.my.enableProxy;
clientMaxBodySize = "4096m";
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
};
};
}

View File

@ -0,0 +1,55 @@
{ lib, config, ... }:
let
nativeServicesWithOpenFirewall = [
"adguardhome"
"plex"
"nix-serve"
"radarr"
"sonarr"
"jellyfin"
"prowlarr"
"bazarr"
"ombi"
"flaresolverr"
];
servicesConfig = lib.listToAttrs (
map (serviceName: {
name = serviceName;
value.openFirewall = config.my.servers.${serviceName}.enable or false;
}) nativeServicesWithOpenFirewall
);
in
{
options.my.network.firewall = {
enabledServicePorts = lib.mkEnableOption "auto-open ports for enabled services";
staticPorts = lib.mkOption {
type = lib.types.listOf lib.types.int;
default = [ ];
description = "Static ports to always open";
};
additionalPorts = lib.mkOption {
type = lib.types.listOf lib.types.int;
default = [ ];
description = "Additional ports to open (like syncthing, gitea, etc.)";
};
};
config = lib.mkIf config.my.network.firewall.enabledServicePorts {
services = servicesConfig;
networking.firewall.allowedTCPPorts =
config.my.network.firewall.staticPorts
++ config.my.network.firewall.additionalPorts
++ (
config.my.servers
|> lib.filterAttrs (
name: srv:
(srv.enable or false) && (srv ? port) && !(builtins.elem name nativeServicesWithOpenFirewall)
)
|> lib.attrValues
|> map (srv: srv.port)
)
++ (lib.optionals config.services.nginx.enable [
config.services.nginx.defaultHTTPListenPort
config.services.nginx.defaultSSLListenPort
]);
};
}

60
modules/network/nginx.nix Normal file
View File

@ -0,0 +1,60 @@
{ lib, config, ... }:
let
setup = import ../factories/mkserver.nix { inherit lib config; };
proxyReverseServices = [
"firefox-syncserver"
"readeck"
"microbin"
"ryot"
"bazarr"
"shiori"
"metube"
"maloja"
"vaultwarden"
"mealie"
"kavita"
"multi-scrobbler"
"nix-serve"
"flame"
"flameSecret"
];
proxyReverseFixServices = [
"audiobookshelf"
"lidarr"
"gitea"
"prowlarr"
"ombi"
"radarr"
"sonarr"
"atticd"
];
proxyReversePrivateServices = [
"homepage"
];
mkServiceConfig =
type: services: lib.listToAttrs (map (name: lib.nameValuePair name { inherit type; }) services);
standardProxyServices =
(mkServiceConfig "proxyReverse" proxyReverseServices)
// (mkServiceConfig "proxyReverseFix" proxyReverseFixServices)
// (mkServiceConfig "proxyReversePrivate" proxyReversePrivateServices);
generateProxyConfig =
serviceName: serviceConfig:
let
cfg = config.my.servers.${serviceName};
proxyFunc =
if serviceConfig.type == "proxyReverse" then
setup.proxyReverse
else if serviceConfig.type == "proxyReverseFix" then
setup.proxyReverseFix
else if serviceConfig.type == "proxyReversePrivate" then
setup.proxyReversePrivate
else
throw "Unknown proxy type: ${serviceConfig.type}";
in
lib.nameValuePair cfg.host (lib.mkIf cfg.enableProxy (proxyFunc cfg));
in
{
config = lib.mkIf config.my.enableProxy {
services.nginx.virtualHosts = lib.mapAttrs' generateProxyConfig standardProxyServices;
};
}

47
modules/nix/build.nix Normal file
View File

@ -0,0 +1,47 @@
{ lib, config, ... }:
{
options.my.nix = {
features = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
"gccarch-znver3"
"gccarch-skylake"
"gccarch-alderlake"
];
description = "List of supported nix build features for this system";
};
buildMachines = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
default = [ ];
description = "List of remote build machines configuration";
};
cores = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = "Number of cores to use for builds (null = auto-detect)";
};
maxJobs = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = "Maximum number of parallel jobs (null = auto-detect)";
};
};
config = {
nix.settings = lib.mkMerge [
{
system-features = config.my.nix.features;
}
(lib.mkIf (config.my.nix.cores != null) {
inherit (config.my.nix) cores;
})
(lib.mkIf (config.my.nix.maxJobs != null) {
max-jobs = config.my.nix.maxJobs;
})
];
nix.buildMachines = lib.mkIf (config.my.nix.buildMachines != [ ]) config.my.nix.buildMachines;
};
}

View File

@ -0,0 +1,32 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.my.servers.gitea;
in
{
config = lib.mkIf (cfg.enable && config.my.secureHost) {
services.gitea-actions-runner.instances.nixos = {
inherit (cfg) url enable;
name = "${config.networking.hostName}-nixos";
tokenFile = config.sops.secrets.gitea.path;
labels = [
"nixos:host"
];
hostPackages = builtins.attrValues {
inherit (pkgs)
bash
coreutils
gitMinimal
nix
attic-client
nodejs # Required for GitHub Actions
openssh # Required for SSH git operations
;
};
};
};
}

View File

@ -0,0 +1,59 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.my.servers.gitea;
in
{
config = lib.mkIf (cfg.enable && config.my.secureHost) {
services.gitea-actions-runner.instances.ryujinx = {
inherit (cfg) url enable;
name = "${config.networking.hostName}-ryujinx";
tokenFile = config.sops.secrets.gitea.path;
labels = [
"ubuntu-latest:host"
"ubuntu-20.04:host"
];
hostPackages =
let
python3 = pkgs.python3.withPackages (
ps:
builtins.attrValues {
inherit (ps)
pyyaml
lxml
;
}
);
in
builtins.attrValues {
inherit python3;
inherit (pkgs.xorg) libX11;
inherit (pkgs)
bash
coreutils
curl
gawk
gitMinimal
gnused
nodejs
wget
gnutar
gzip
dotnet-sdk_8
openal
vulkan-loader
libGL
gtk3
llvm_15
rcodesign
gh
p7zip
;
};
};
};
}

View File

@ -0,0 +1,121 @@
{
inputs,
pkgs,
lib,
config,
...
}:
{
imports = [ ../factories/mkscript.nix ];
options.my.units = {
download.enable = lib.mkEnableOption "media download automation scripts";
downloadManga.enable = lib.mkEnableOption "manga download automation";
};
config =
let
inherit (inputs.jawz-scripts.packages.x86_64-linux) download;
in
{
home-manager.users.jawz.programs.${config.my.shell.type} = {
shellAliases = {
dl = "${download}/bin/download -u jawz -i";
comic = ''dl "$(cat "$LC" | fzf --multi --exact -i)"'';
gallery = ''dl "$(cat "$LW" | fzf --multi --exact -i)"'';
};
}
// (
if config.my.shell.type == "bash" then
{
initExtra = ''
list_root=$XDG_CONFIG_HOME/jawz/lists/jawz
export LW=$list_root/watch.txt
export LI=$list_root/instant.txt
export LC=$list_root/comic.txt
'';
}
else
{
initContent = ''
list_root=$XDG_CONFIG_HOME/jawz/lists/jawz
export LW=$list_root/watch.txt
export LI=$list_root/instant.txt
export LC=$list_root/comic.txt
'';
}
);
systemd.user = {
services =
let
mkDownloadService = desc: execStartCmd: {
restartIfChanged = true;
description = "Downloads ${desc}";
wantedBy = [ "default.target" ];
path = [
pkgs.bash
];
serviceConfig = {
TimeoutStartSec = 2000;
TimeoutStopSec = 2000;
Restart = "on-failure";
RestartSec = 30;
ExecStart = "${download}/bin/download ${execStartCmd}";
};
};
in
{
tuhmayto = lib.mkIf config.my.units.download.enable (
mkDownloadService "tuhmayto stuff" ''
-u jawz -i https://x.com/tuhmayto/media \
https://www.furaffinity.net/user/tuhmayto/ \
https://bsky.app/profile/tumayto.bsky.social''
);
"download@" = lib.mkIf (config.my.units.download.enable || config.my.units.downloadManga.enable) (
mkDownloadService "post from multiple sources" "%I"
);
"instagram@" = lib.mkIf config.my.units.download.enable (
mkDownloadService "post types from instagram" "instagram -u jawz -t %I"
);
};
timers =
let
downloadTimer = time: delay: {
enable = true;
description = "Downloads post types from different sites";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = time;
RandomizedDelaySec = delay;
Persistent = true;
};
};
in
{
# "instagram@stories" = lib.mkIf config.my.units.download.enable (
# downloadTimer "*-*-* 12:34:00" 120 // { }
# );
"download@main" = lib.mkIf config.my.units.download.enable (
downloadTimer "*-*-* 06,18:02:00" 30 // { }
);
"download@push" = lib.mkIf config.my.units.download.enable (downloadTimer "*:0/5" 30 // { });
"download@manga" = lib.mkIf config.my.units.downloadManga.enable (
downloadTimer "*-*-* 03:08:00" 30 // { }
);
tuhmayto = lib.mkIf config.my.units.download.enable {
enable = true;
description = "Downloads tuhmayto stuff";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*:0/10";
};
};
};
};
my.scripts.download = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "download";
package = download;
};
};
}

View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.ffmpeg4discord = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "ffmpeg4discord";
package = inputs.jawz-scripts.packages.x86_64-linux.ffmpeg4discord;
};
}

View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.ffmpreg = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "ffmpreg";
package = inputs.jawz-scripts.packages.x86_64-linux.ffmpreg;
};
}

View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.find-dup-episodes = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "find-dup-episodes";
package = inputs.jawz-scripts.packages.x86_64-linux.find-dup-episodes;
};
}

View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.library-report = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "library-report";
package = inputs.jawz-scripts.packages.x86_64-linux.library-report;
};
}

View File

@ -0,0 +1,13 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.manage-library = {
enable = lib.mkDefault false;
install = true;
service = true;
name = "manage-library";
timer = "00:30";
description = "scans the library directory and sorts files";
package = inputs.jawz-scripts.packages.x86_64-linux.manage-library;
};
}

View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.pika-list = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "pika-list";
package = inputs.jawz-scripts.packages.x86_64-linux.pika-list;
};
}

11
modules/scripts/run.nix Normal file
View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.run = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "run";
package = inputs.jawz-scripts.packages.x86_64-linux.run;
};
}

View File

@ -0,0 +1,11 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.split-dir = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "split-dir";
package = inputs.jawz-scripts.packages.x86_64-linux.split-dir;
};
}

View File

@ -0,0 +1,60 @@
{
inputs,
pkgs,
lib,
config,
...
}:
{
imports = [ ../factories/mkscript.nix ];
options.my.units.stream-dl.enable = lib.mkEnableOption "streaming media download service";
config =
let
inherit (inputs.jawz-scripts.packages.x86_64-linux) stream-dl;
in
{
systemd.user = lib.mkIf config.my.units.stream-dl.enable {
services."stream@" = {
description = "monitors a stream channel for online streams.";
restartIfChanged = true;
wantedBy = [ "default.target" ];
path = [
pkgs.nix
stream-dl
];
serviceConfig = {
Restart = "on-failure";
RestartSec = 30;
ExecStart = "${stream-dl}/bin/stream-dl %I";
};
};
timers =
let
streamTimer = {
enable = true;
description = "monitors a stream channel for online streams.";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "5min";
OnUnitActiveSec = "65min";
RandomizedDelaySec = 30;
};
};
in
{
"stream@johnneal911" = streamTimer // { };
"stream@uk2011boy" = streamTimer // { };
"stream@tommy9x6" = streamTimer // { };
"stream@brocollirob" = streamTimer // { };
"stream@tomayto\\x20picarto" = streamTimer // { };
};
};
my.scripts.stream-dl = {
enable = lib.mkDefault false;
install = true;
service = false;
name = "stream-dl";
package = stream-dl;
};
};
}

13
modules/scripts/tasks.nix Normal file
View File

@ -0,0 +1,13 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.tasks = {
enable = lib.mkDefault false;
install = true;
service = true;
name = "tasks";
timer = "*:0/10";
description = "Runs a bunch of organizing tasks on selected directories";
package = inputs.jawz-scripts.packages.x86_64-linux.tasks;
};
}

View File

@ -0,0 +1,13 @@
{ inputs, lib, ... }:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.tuh-activity-logger = {
enable = lib.mkDefault false;
install = true;
service = true;
name = "tuh-activity-logger";
timer = "0/4:00";
description = "Logs the online activity on a website";
package = inputs.jawz-scripts.packages.x86_64-linux.tuh-activity-logger;
};
}

View File

@ -0,0 +1,51 @@
{
inputs,
config,
pkgs,
lib,
...
}:
{
imports = [ ../factories/mkscript.nix ];
config = lib.mkIf config.my.secureHost {
sops.secrets = {
cloudflare-api.sopsFile = ../../secrets/env.yaml;
dns = {
sopsFile = ../../secrets/env.yaml;
owner = config.users.users.jawz.name;
inherit (config.users.users.jawz) group;
};
};
services.cloudflare-dyndns = {
# inherit (config.my.scripts.update-dns) enable;
enable = false;
ipv4 = true;
ipv6 = false;
proxied = false;
domains = [
config.my.domain
];
apiTokenFile = config.sops.secrets.cloudflare-api.path;
};
my.scripts.update-dns = {
enable = lib.mkDefault false;
install = true;
service = true;
name = "update-dns";
timer = "*:0/30";
description = "Updates the IP of all my domains";
package =
let
inherit (inputs.jawz-scripts.packages.x86_64-linux) update-dns;
in
pkgs.writeScriptBin "update-dns" ''
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p bash curl
set -a
source ${config.sops.secrets.dns.path}
set -a
${update-dns}/bin/update-dns
'';
};
};
}

View File

@ -0,0 +1,22 @@
{
config,
lib,
pkgs,
...
}:
{
imports = [ ../factories/mkscript.nix ];
config.my.scripts.update-org-agenda-cache = {
enable = lib.mkDefault false;
install = config.my.emacs.enable;
service = config.my.emacs.enable;
name = "update-org-agenda-cache";
timer = "*:0/30";
description = "runs a function which builds a cache file.";
package = pkgs.writeScriptBin "update-org-agenda-cache" ''
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p bash
${config.services.emacs.package}/bin/emacsclient --eval '(my/update-org-agenda-cache)'
'';
};
}

View File

@ -0,0 +1,13 @@
{ lib, config, ... }:
let
cfg = config.my.servers.adguardhome;
in
{
options.my.servers.adguardhome.enable = lib.mkEnableOption "AdGuard Home DNS ad blocker";
config = lib.mkIf (cfg.enable && config.my.secureHost) {
services.adguardhome = {
inherit (cfg) enable;
mutableSettings = true;
};
};
}

View File

@ -0,0 +1,33 @@
{ lib, config, ... }:
let
cfg = config.my.servers.atticd;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers.atticd = setup.mkOptions "atticd" "cache" 2343;
config = lib.mkIf (cfg.enable && config.my.secureHost) {
sops.secrets."private_cache_keys/atticd".sopsFile = ../../secrets/keys.yaml;
services.atticd = {
inherit (cfg) enable;
environmentFile = config.sops.secrets."private_cache_keys/atticd".path;
settings = {
listen = "[::]:${toString cfg.port}";
jwt = { };
chunking = {
nar-size-threshold = 64 * 1024; # 64 KiB
min-size = 16 * 1024; # 16 KiB
avg-size = 64 * 1024; # 64 KiB
max-size = 256 * 1024; # 256 KiB
};
compression = {
type = "zstd";
level = 8;
};
garbage-collection = {
interval = "7 days";
default-retention-period = "7 days";
};
};
};
};
}

View File

@ -0,0 +1,16 @@
{ lib, config, ... }:
let
cfg = config.my.servers.audiobookshelf;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers.audiobookshelf = setup.mkOptions "audiobookshelf" "audiobooks" 5687;
config = lib.mkIf (cfg.enable && config.my.secureHost) {
my.servers.audiobookshelf.enableSocket = true;
services.audiobookshelf = {
inherit (cfg) enable port;
host = cfg.ip;
group = "piracy";
};
};
}

View File

@ -0,0 +1,12 @@
{ lib, config, ... }:
let
cfg = config.my.servers.bazarr;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers.bazarr = setup.mkOptions "bazarr" "subs" config.services.bazarr.listenPort;
config.services.bazarr = lib.mkIf cfg.enable {
inherit (cfg) enable;
group = "piracy";
};
}

19
modules/servers/drpp.nix Normal file
View File

@ -0,0 +1,19 @@
{ lib, config, ... }:
let
cfg = config.my.servers.drpp;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers.drpp = setup.mkOptions "drpp" "drpp" 0;
config.virtualisation.oci-containers.containers.drpp = lib.mkIf cfg.enable {
image = "ghcr.io/phin05/discord-rich-presence-plex:latest";
environment = {
DRPP_UID = toString config.users.users.jawz.uid;
DRPP_GID = toString config.users.groups.users.gid;
};
volumes = [
"${config.my.containerData}/drpp:/app/data"
"/run/user/${toString config.users.users.jawz.uid}:/run/app"
];
};
}

View File

@ -0,0 +1,25 @@
{ lib, config, ... }:
let
cfg = config.my.servers.firefly-iii;
in
{
options.my.servers.firefly-iii = {
enable = lib.mkEnableOption "Firefly III personal finance manager";
enableProxy = lib.mkEnableOption "enableProxy";
};
config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) {
sops.secrets.firefly-iii-keyfile = {
owner = config.users.users.firefly-iii.name;
inherit (config.users.users.firefly-iii) group;
};
services.firefly-iii = {
inherit (cfg) enable;
enableNginx = cfg.enableProxy;
settings = {
APP_KEY_FILE = config.sops.secrets.firefly-iii-keyfile.path;
DB_HOST = config.my.postgresSocket;
DB_CONNECTION = "pgsql";
};
};
};
}

View File

@ -0,0 +1,23 @@
{ lib, config, ... }:
let
cfg = config.my.servers.firefox-syncserver;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers.firefox-syncserver = setup.mkOptions "firefox-syncserver" "sync" 4233;
config = lib.mkIf (cfg.enable && config.my.secureHost) {
# sops.secrets.firefox-syncserver.sopsFile = ../../secrets/env.yaml;
services.firefox-syncserver = {
inherit (cfg) enable;
# secrets = config.sops.secrets.firefox-syncserver;
settings.port = cfg.port;
singleNode = {
enable = true;
enableTLS = true;
enableNginx = true;
hostname = config.networking.hostName;
# url = cfg.host;
};
};
};
}

47
modules/servers/flame.nix Normal file
View File

@ -0,0 +1,47 @@
{ lib, config, ... }:
let
cfg = config.my.servers.flame;
cfgS = config.my.servers.flameSecret;
enable = (cfg.enable || cfgS.enable) && config.my.secureHost;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers = {
flame = setup.mkOptions "flame" "start" 5005;
flameSecret = setup.mkOptions "flameSecret" "qampqwn4wprhqny8h8zj" 5007;
};
config = lib.mkIf enable {
sops.secrets = {
flame.sopsFile = ../../secrets/env.yaml;
};
virtualisation.oci-containers.containers = lib.mkIf enable {
flame = lib.mkIf cfg.enable {
autoStart = true;
image = "pawelmalak/flame";
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
volumes = [
"${config.my.containerData}/flame:/app/data"
"${config.my.containerSocket}:${config.my.containerSocket}"
];
environmentFiles = [ config.sops.secrets.flame.path ];
environment = {
TZ = config.my.timeZone;
PUID = toString config.users.users.jawz.uid;
PGID = toString config.users.groups.users.gid;
};
};
flame-nsfw = lib.mkIf cfgS.enable {
autoStart = true;
image = "pawelmalak/flame";
ports = [ "${toString cfgS.port}:${toString cfg.port}" ];
volumes = [ "${config.my.containerData}/flame-nsfw:/app/data" ];
environmentFiles = [ config.sops.secrets.flame.path ];
environment = {
TZ = config.my.timeZone;
PUID = toString config.users.users.jawz.uid;
PGID = toString config.users.groups.users.gid;
};
};
};
};
}

42
modules/servers/gitea.nix Normal file
View File

@ -0,0 +1,42 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.my.servers.gitea;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
imports = [
../nix/gitea-actions-runners/ryujinx.nix
../nix/gitea-actions-runners/nixos.nix
];
options.my.servers.gitea = setup.mkOptions "gitea" "git" 9083;
config = lib.mkIf (cfg.enable && config.my.secureHost) {
sops.secrets.gitea.sopsFile = ../../secrets/env.yaml;
services.gitea = {
inherit (cfg) enable;
settings = {
session.COOKIE_SECURE = true;
server = {
DOMAIN = cfg.host;
ROOT_URL = cfg.url;
HTTP_PORT = cfg.port;
};
mailer = {
ENABLED = true;
PROTOCOL = "sendmail";
FROM = config.my.smtpemail;
SENDMAIL_PATH = "${pkgs.msmtp}/bin/msmtp";
};
};
database = {
socket = config.my.postgresSocket;
type = "postgres";
createDatabase = false;
};
};
};
}

View File

@ -0,0 +1,35 @@
{ lib, config, ... }:
let
cfg = config.my.servers.homepage;
setup = import ../factories/mkserver.nix { inherit lib config; };
in
{
options.my.servers.homepage = setup.mkOptions "homepage" "home" 8082;
config = lib.mkIf config.my.secureHost {
sops.secrets = lib.mkIf cfg.enable {
homepage.sopsFile = ../../secrets/homepage.yaml;
"private-ca/pem" = {
sopsFile = ../../secrets/certs.yaml;
owner = "nginx";
group = "nginx";
};
};
my.servers.homepage.certPath = config.sops.secrets."private-ca/pem".path;
services.homepage-dashboard = lib.mkIf cfg.enable {
inherit (cfg) enable;
listenPort = cfg.port;
environmentFile = config.sops.secrets.homepage.path;
settings = {
providers.openweathermap = "{{HOMEPAGE_VAR_OPENWEATHERMAP_API_KEY}}";
layout = import ./homepage/layout.nix;
};
widgets = import ./homepage/widgets.nix;
services = import ./homepage/services.nix { inherit lib config; };
bookmarks =
builtins.readDir ./homepage/bookmarks
|> builtins.attrNames
|> builtins.filter (file: builtins.match ".*\\.nix" file != null)
|> map (file: import ./homepage/bookmarks/${file});
};
};
}

View File

@ -0,0 +1,49 @@
{
"art" = [
{
deviantart = [
{
abbr = "DA";
href = "https://deviantart.com/";
description = "";
}
];
}
{
furaffinity = [
{
abbr = "FA";
href = "https://furaffinity.net/";
description = "";
}
];
}
{
patreon = [
{
abbr = "PT";
href = "https://patreon.com/";
description = "";
}
];
}
{
pillowfort = [
{
abbr = "MJ";
href = "https://www.midjourney.com";
description = "";
}
];
}
{
tumblr = [
{
abbr = "TB";
href = "https://tumblr.com/";
description = "";
}
];
}
];
}

View File

@ -0,0 +1,49 @@
{
"development" = [
{
chatgpt = [
{
abbr = "CGPT";
href = "https://chatgpt.com/";
description = "";
}
];
}
{
protonmail = [
{
abbr = "PM";
href = "https://account.proton.me/mail";
description = "";
}
];
}
{
github = [
{
abbr = "GH";
href = "https://github.com/";
description = "";
}
];
}
{
gitlab = [
{
abbr = "GL";
href = "https://gitlab.com/";
description = "";
}
];
}
{
exercism = [
{
abbr = "EX";
href = "https://exercism.org/";
description = "";
}
];
}
];
}

View File

@ -0,0 +1,49 @@
{
"entertainment" = [
{
epicgames = [
{
abbr = "EG";
href = "https://store.epicgames.com/";
description = "";
}
];
}
{
deezer = [
{
abbr = "DZ";
href = "https://deezer.com/us/";
description = "";
}
];
}
{
readcomiconline = [
{
abbr = "RCO";
href = "https://readcomiconline.li/";
description = "";
}
];
}
{
primevideo = [
{
abbr = "PV";
href = "https://primevideo.com/";
description = "";
}
];
}
{
youtube = [
{
abbr = "YT";
href = "https://youtube.com/";
description = "";
}
];
}
];
}

View File

@ -0,0 +1,67 @@
{
"secret art" = [
{
"{{HOMEPAGE_VAR_NAME_1}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_1}}";
href = "{{HOMEPAGE_VAR_URL_1}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_2}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_2}}";
href = "{{HOMEPAGE_VAR_URL_2}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_3}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_3}}";
href = "{{HOMEPAGE_VAR_URL_3}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_4}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_4}}";
href = "{{HOMEPAGE_VAR_URL_4}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_5}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_5}}";
href = "{{HOMEPAGE_VAR_URL_5}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_6}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_6}}";
href = "{{HOMEPAGE_VAR_URL_6}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_7}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_7}}";
href = "{{HOMEPAGE_VAR_URL_7}}";
description = "";
}
];
}
];
}

View File

@ -0,0 +1,67 @@
{
"secret media" = [
{
"{{HOMEPAGE_VAR_NAME_8}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_8}}";
href = "{{HOMEPAGE_VAR_URL_8}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_9}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_9}}";
href = "{{HOMEPAGE_VAR_URL_9}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_10}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_10}}";
href = "{{HOMEPAGE_VAR_URL_10}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_11}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_11}}";
href = "{{HOMEPAGE_VAR_URL_11}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_12}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_12}}";
href = "{{HOMEPAGE_VAR_URL_12}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_13}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_13}}";
href = "{{HOMEPAGE_VAR_URL_13}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_14}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_14}}";
href = "{{HOMEPAGE_VAR_URL_14}}";
description = "";
}
];
}
];
}

View File

@ -0,0 +1,67 @@
{
"secret social" = [
{
"{{HOMEPAGE_VAR_NAME_15}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_15}}";
href = "{{HOMEPAGE_VAR_URL_15}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_16}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_16}}";
href = "{{HOMEPAGE_VAR_URL_16}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_17}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_17}}";
href = "{{HOMEPAGE_VAR_URL_17}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_18}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_18}}";
href = "{{HOMEPAGE_VAR_URL_18}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_19}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_19}}";
href = "{{HOMEPAGE_VAR_URL_19}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_20}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_20}}";
href = "{{HOMEPAGE_VAR_URL_20}}";
description = "";
}
];
}
{
"{{HOMEPAGE_VAR_NAME_21}}" = [
{
abbr = "{{HOMEPAGE_VAR_ABBR_21}}";
href = "{{HOMEPAGE_VAR_URL_21}}";
description = "";
}
];
}
];
}

View File

@ -0,0 +1,58 @@
{
"server bookmarks" = [
{
readeck = [
{
abbr = "RD";
href = "https://laters.servidos.lat/";
description = "";
}
];
}
{
maloja = [
{
abbr = "ML";
href = "https://maloja.servidos.lat/";
description = "";
}
];
}
{
microbin = [
{
abbr = "CP";
href = "https://copy.servidos.lat/";
description = "";
}
];
}
{
multi-scrobbler = [
{
abbr = "MS";
href = "https://scrobble.servidos.lat/";
description = "";
}
];
}
{
ryot = [
{
abbr = "RT";
href = "https://tracker.servidos.lat/";
description = "";
}
];
}
{
vaultwarden = [
{
abbr = "VW";
href = "https://vault.servidos.lat";
description = "";
}
];
}
];
}

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