diff --git a/configuration.nix b/configuration.nix index 28e0e2f..427350e 100644 --- a/configuration.nix +++ b/configuration.nix @@ -49,6 +49,7 @@ ./system-modules/postgres.nix ./system-modules/nx2site/proxy.nix ./system-modules/nx2site/audiobookshelf.nix + ./system-modules/nx2site/copyparty.nix ./system-modules/nx2site/gitea.nix ./system-modules/nx2site/open-web-calendar.nix ./system-modules/nx2site/radicale.nix diff --git a/flake.nix b/flake.nix index 37f839b..e539f4d 100644 --- a/flake.nix +++ b/flake.nix @@ -2,28 +2,30 @@ description = "Multisystem NixOS Flake of Lennart J. Kurzweg"; inputs = { - nixpkgs = { url = "nixpkgs/nixos-25.05"; }; - nixpkgs-unstable = { url = "nixpkgs/nixos-unstable"; }; - nixpkgs-latest = { url = "github:nixos/nixpkgs?ref=master"; }; + nixpkgs = { url = "nixpkgs/nixos-25.05"; }; + nixpkgs-unstable = { url = "nixpkgs/nixos-unstable"; }; + nixpkgs-latest = { url = "github:nixos/nixpkgs?ref=master"; }; - home-manager = { url = "github:nix-community/home-manager/release-25.05"; inputs.nixpkgs.follows = "nixpkgs"; }; + home-manager = { url = "github:nix-community/home-manager/release-25.05"; inputs.nixpkgs.follows = "nixpkgs"; }; - nixos-wsl = { url = "github:nix-community/NixOS-WSL/main"; }; + nixos-wsl = { url = "github:nix-community/NixOS-WSL/main"; }; - sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - lanzaboote = { url = "github:nix-community/lanzaboote/v0.4.2"; }; + sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + lanzaboote = { url = "github:nix-community/lanzaboote/v0.4.2"; }; - hyprland = { url = "git+https://github.com/hyprwm/Hyprland?submodules=1"; }; - hyprland-plugins = { url = "github:hyprwm/hyprland-plugins"; inputs.hyprland.follows = "hyprland"; }; - hyprspace = { url = "github:KZDKM/Hyprspace"; inputs.hyprland.follows = "hyprland"; }; + hyprland = { url = "git+https://github.com/hyprwm/Hyprland?submodules=1"; }; + hyprland-plugins = { url = "github:hyprwm/hyprland-plugins"; inputs.hyprland.follows = "hyprland"; }; + hyprspace = { url = "github:KZDKM/Hyprspace"; inputs.hyprland.follows = "hyprland"; }; - yazi = { url = "github:sxyazi/yazi"; }; + yazi = { url = "github:sxyazi/yazi"; }; + copyparty = { url = "github:9001/copyparty"; }; }; outputs = { ... }@inputs: with inputs; let system = "x86_64-linux"; - config = { allowUnfreePredicate = pkg: builtins.elem (pkgs.lib.getName pkg) (import ./flake-modules/allowed.nix).unfree; }; + simple-pkgs = import nixpkgs { inherit system; }; + config = { allowUnfreePredicate = pkg: builtins.elem (simple-pkgs.lib.getName pkg) (import ./flake-modules/allowed.nix).unfree; }; hyper-base = rec { inherit system; @@ -34,31 +36,31 @@ pkgs-version = "25.05"; }; - pkgs = import nixpkgs { + my-pkgs = host: import nixpkgs { inherit system config; - overlays = [ - (final: prev: { - unstable = import nixpkgs-unstable { inherit system config; }; - latest = import nixpkgs-latest { inherit system config; }; - version = "25.05"; - }) - ]; + overlays = [(final: prev: { + unstable = import nixpkgs-unstable { inherit system config; }; + latest = import nixpkgs-latest { inherit system config; }; + version = "25.05"; + })] ++ (if host == "NxACE" then [ + copyparty.overlays.default + ] else []); }; nvidia-base = import ./flake-modules/nvidia.nix; secrets = import ./git-crypt/secrets.nix; - rice = import ./flake-modules/rice.nix pkgs; + rice = import ./flake-modules/rice.nix simple-pkgs; in { nixosConfigurations = let make-nixos-system = host: nvidia-settings: nixpkgs.lib.nixosSystem { - inherit pkgs; + pkgs = my-pkgs host; modules = [ ./configuration.nix ]; specialArgs = let hyper = hyper-base // { inherit host; nvidia = (nvidia-base // nvidia-settings); }; in { inherit inputs hyper rice secrets; }; }; make-nixos-wsl-system = host: nixpkgs.lib.nixosSystem { - inherit pkgs; + pkgs = my-pkgs host; modules = [ ./nixos-wsl.nix ]; specialArgs = let hyper = hyper-base // { inherit host; }; @@ -73,18 +75,18 @@ homeConfigurations = let make-home-configuration = host: user: nvidia-settings: home-manager.lib.homeManagerConfiguration { - inherit pkgs; + pkgs = my-pkgs host; modules = [ ./home.nix ]; extraSpecialArgs = let hyper = hyper-base // { inherit host; nvidia = nvidia-base // nvidia-settings; }; - in { inherit pkgs inputs hyper rice secrets; }; + in { inherit inputs hyper rice secrets; }; }; make-shell-configuration = host: user: home-manager.lib.homeManagerConfiguration { - inherit pkgs; + pkgs = my-pkgs host; modules = [ ./shell-only.nix ]; extraSpecialArgs = let hyper = hyper-base // { inherit host; }; - in { inherit pkgs inputs hyper rice secrets; }; + in { inherit inputs hyper rice secrets; }; }; in { "${hyper-base.user}@NxXPS" = make-home-configuration "NxXPS" hyper-base.user { enable = true; prime = true; }; diff --git a/git-crypt/secrets.nix b/git-crypt/secrets.nix index d5fa267..ef17bb3 100644 Binary files a/git-crypt/secrets.nix and b/git-crypt/secrets.nix differ diff --git a/home-modules/bar.nix b/home-modules/bar.nix new file mode 100644 index 0000000..06cd61e --- /dev/null +++ b/home-modules/bar.nix @@ -0,0 +1,9 @@ +{ ... }: { + imports = [ + # ./bar/submap-indicator.nix + ./bar/cclock.nix + ./bar/caldav-event.nix + # ./bar/waybar.nix + ./bar/hyprpanel.nix + ]; +} diff --git a/home-modules/bar/caldav-event.nix b/home-modules/bar/caldav-event.nix new file mode 100644 index 0000000..f8cefbc --- /dev/null +++ b/home-modules/bar/caldav-event.nix @@ -0,0 +1,126 @@ +{ pkgs, ... }@all: with all; { + sops.secrets = { + "nx2site/radicale/password" = { }; + }; + home.packages = [ + (pkgs.writers.writePython3Bin "caldav_event" { + libraries = with pkgs.python3Packages; [ caldav ics pytz ]; + flakeIgnore = [ "E302" "E305" "E501" "E261" ]; + } /* python */ '' +import os +import json +from caldav import DAVClient +from datetime import datetime, timezone +from ics import Calendar +from pytz import UTC + +def get_password(password_file): + with open(password_file, "r") as file: + return file.read().strip() + +def datetime_converter(obj): + if isinstance(obj, datetime): + return obj.isoformat() + return obj + +def datetime_parser(dct): + for key, value in dct.items(): + if isinstance(value, str): + try: + dct[key] = datetime.fromisoformat(value) + except ValueError: + pass + return dct + +def load_cache(cache_file): + if os.path.exists(cache_file): + with open(cache_file, "r") as file: + return json.load(file, object_hook=datetime_parser) + return None + +def save_cache(cache_file, data): + with open(cache_file, "w") as file: + json.dump(data, file, default=datetime_converter, indent=4) + + +def get_ongoing_or_next_event(url, username, password): + now = datetime.now(timezone.utc) + + try: + client = DAVClient(url, username=username, password=password) + principal = client.principal() + calendars = principal.calendars() + + next_event_dict = { + 'event_name': "fake", + 'event_begin': datetime(9000, 1, 1, tzinfo=UTC), # in the year 9000 + 'event_end': datetime(9000, 1, 1, 8, tzinfo=UTC), + } + + for calendar in calendars: + for event in calendar.search(start=now): + calendar_parsed = Calendar(event.data) + for ics_event in calendar_parsed.events: + event_dict = {} + event_dict['event_name'] = ics_event.name or "(No Title)" + event_dict['event_begin'] = ics_event.begin.astimezone(timezone.utc) + event_dict['event_end'] = ics_event.end.astimezone(timezone.utc) + + if event_dict['event_begin'] <= now and now <= event_dict['event_end']: + return event_dict + elif event_dict['event_begin'] >= now and next_event_dict['event_begin'] > event_dict['event_begin']: + next_event_dict = event_dict + return next_event_dict + + except Exception as e: + print(f"Error accessing {url}: {e}") + return None + +def is_expired(event_dict: dict): + now = datetime.now(timezone.utc).timestamp() + event_end = event_dict['event_end'].timestamp() + return not (now <= event_end) + +if __name__ == "__main__": + password_file = "${config.sops.secrets."nx2site/radicale/password".path}" # Path to password file + cache_file = "/tmp/caldav_event_cache.json" # Path to cache file + url = "https://dav.${hyper.domain}/" + username = "nx2" + password = get_password(password_file) + now = datetime.now(timezone.utc).timestamp() + + event_dict = load_cache(cache_file) + + if (event_dict is None) or (is_expired(event_dict)): + event_dict = get_ongoing_or_next_event(url, username, password) + save_cache(cache_file, event_dict) + + if event_dict is None: # none were found + print("* zen *") + exit(0) + + event_start = event_dict['event_begin'].timestamp() + event_end = event_dict['event_end'].timestamp() + + if event_start <= now <= event_end: # is currently ongoing + action_string = "ends" + t = event_end - now # time_remaining + else: # is in the future + action_string = "starts" + t = event_start - now # time_remaining + + hours, rem = divmod(int(t), 3600) + minutes, _ = divmod(rem, 60) + hour_string = f"{hours} hour{'s ' if hours != 1 else ' '}" if hours > 0 else "" + minu_string = f"{minutes} minute{'s ' if minutes != 1 else ' '}" if minutes > 0 else "" + if hour_string == "" and minu_string == "": + time_string = "now" + elif hour_string == "" or minu_string == "": + time_string = "in " + hour_string + minu_string + else: + time_string = "in " + hour_string + "and " + minu_string + + print(f"{event_dict['event_name']} {action_string} {time_string}") +'') + ]; +} diff --git a/home-modules/bar/cclock.nix b/home-modules/bar/cclock.nix new file mode 100644 index 0000000..ce2ab53 --- /dev/null +++ b/home-modules/bar/cclock.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: let + sep = " "; +in { + home.packages = [ + (pkgs.writeShellApplication { name = "cclock"; text = /* bash */ '' + ord=$(date +"%e" | awk '{printf("%d%s\n", $1, ($1==11||$1==12||$1==13)?"th":((($1%10)==1)?"st":((($1%10)==2)?"nd":((($1%10)==3)?"rd":"th"))))}') + if [ $# -eq 0 ]; then + echo "󰃮${sep}$(date +'%A the')" "$ord" "of" "$(date +'%B')" " ${sep}$(date +'%R')" + elif [ "$1" = "--no-icons" ]; then + echo "$(date +'%A the')" "$ord" "of" "$(date +'%B')" "$(date +'%R')" + fi + '';}) + ]; +} diff --git a/home-modules/bar/hyprpanel.nix b/home-modules/bar/hyprpanel.nix new file mode 100644 index 0000000..809af55 --- /dev/null +++ b/home-modules/bar/hyprpanel.nix @@ -0,0 +1,512 @@ +{ pkgs, ... }@all: with all; { + xdg.configFile = { + "hyprpanel/modules.scss".text = with rice.color; /* scss */ '' + @include styleModule('cmodule-cclock', ( + 'text-color': ${accent.base}, + /* 'icon-color': , */ + /* 'icon-background': , */ + /* 'label-background': #242438, */ + /* 'inner-spacing': 0.5em, */ + /* 'border-enabled': false, */ + /* 'border-color': #cba6f7, */ + /* 'icon-size': 1.2em */ + )); + @include styleModule('cmodule-caldav_event', ( + 'text-color': ${accent.base}, + )); + ''; + "hyprpanel/modules.json".text = builtins.toJSON { + "custom/cclock" = { + execute = "cclock"; + executeOnAction = ""; + label = "{}"; + interval = 60000; + hideOnEmpty = true; + actions.onLeftClick = "menu:calendar"; + }; + "custom/caldav_evnet" = { + execute = "caldav_event"; + executeOnAction = ""; + label = "{}"; + interval = 60000; + hideOnEmpty = true; + actions = {}; + }; + }; + }; + programs.hyprpanel = { + enable = true; + package = pkgs.unstable.hyprpanel; + settings = with rice.color; let + t = builtins.toString (builtins.ceil (rice.transparency * 100)); + in { + "bar.layouts" = { + "*" = { + "left" = [ + "volume" + # "microphone" + # "cpu" + # "cputemp" + # "ram" + "battery" + # "bluetooth" + "network" + "windowtitle" + ]; + "middle" = [ "workspaces" ]; + "right" = [ + "submap" + "custom/caldav_event" + "media" + "custom/cclock" + "notifications" + "systray" + ]; + }; + }; + + "bar.bluetooth.label" = true; + + "bar.customModules.submap.enabledIcon" = "[󰧹]"; + "bar.customModules.submap.showSubmapName" = false; + "bar.customModules.submap.label" = false; + "bar.customModules.submap.icon" = true; + "bar.customModules.submap.disabledIcon" = ""; + + "bar.workspaces.applicationIconEmptyWorkspace" = ""; + "bar.workspaces.applicationIconOncePerWorkspace" = false; + "bar.workspaces.numbered_active_indicator" = "underline"; + "bar.workspaces.scroll_speed" = 1; + "bar.workspaces.showAllActive" = false; + "bar.workspaces.showApplicationIcons" = true; + "bar.workspaces.show_icons" = false; + "bar.workspaces.show_numbered" = false; + "bar.workspaces.showWsIcons" = true; + "bar.workspaces.spacing" = 1; + "bar.workspaces.workspaceMask" = true; + "bar.workspaces.workspaces" = 5; + + "theme.bar.background" = background; + "theme.bar.border.color" = accent.base; + "theme.bar.border_radius" = "0.2em"; + + "theme.bar.buttons.background" = background; + "theme.bar.buttons.background_opacity" = 0; + "theme.bar.buttons.spacing" = "0em"; + "theme.bar.buttons.padding_x" = "0.5rem"; + + "theme.bar.buttons.battery.background" = background; + "theme.bar.buttons.battery.border" = accent.base; + "theme.bar.buttons.battery.icon_background" = background; + "theme.bar.buttons.battery.icon" = accent.base; + "theme.bar.buttons.battery.text" = accent.base; + + "theme.bar.buttons.bluetooth.background" = background; + "theme.bar.buttons.bluetooth.border" = accent.base; + "theme.bar.buttons.bluetooth.icon_background" = background; + "theme.bar.buttons.bluetooth.icon" = accent.base; + "theme.bar.buttons.bluetooth.text" = accent.base; + + "theme.bar.buttons.borderColor" = accent.base; + + "theme.bar.buttons.clock.background" = background; + "theme.bar.buttons.clock.border" = accent.base; + "theme.bar.buttons.clock.icon_background" = background; + "theme.bar.buttons.clock.icon" = accent.base; + "theme.bar.buttons.clock.text" = accent.base; + + "theme.bar.buttons.dashboard.background" = background; + "theme.bar.buttons.dashboard.border" = accent.base; + "theme.bar.buttons.dashboard.icon" = accent.base; + "theme.bar.buttons.icon_background" = background; + + "theme.bar.buttons.icon" = accent.base; + + "theme.bar.buttons.media.background" = background; + "theme.bar.buttons.media.border" = accent.base; + "theme.bar.buttons.media.icon_background" = background; + "theme.bar.buttons.media.icon" = accent.base; + "theme.bar.buttons.media.text" = accent.base; + + "theme.bar.buttons.modules.cava.background" = background; + "theme.bar.buttons.modules.cava.border" = accent.base; + "theme.bar.buttons.modules.cava.icon_background" = background; + "theme.bar.buttons.modules.cava.icon" = accent.base; + "theme.bar.buttons.modules.cava.text" = accent.base; + + "theme.bar.buttons.modules.cpu.background" = background; + "theme.bar.buttons.modules.cpu.border" = accent.base; + "theme.bar.buttons.modules.cpu.icon_background" = background; + "theme.bar.buttons.modules.cpu.icon" = accent.base; + "theme.bar.buttons.modules.cpu.text" = accent.base; + + "theme.bar.buttons.modules.cpuTemp.background" = background; + "theme.bar.buttons.modules.cpuTemp.border" = accent.base; + "theme.bar.buttons.modules.cpuTemp.icon_background" = background; + "theme.bar.buttons.modules.cpuTemp.icon" = accent.base; + "theme.bar.buttons.modules.cpuTemp.text" = accent.base; + + "theme.bar.buttons.modules.hypridle.background" = background; + "theme.bar.buttons.modules.hypridle.border" = accent.base; + "theme.bar.buttons.modules.hypridle.icon_background" = background; + "theme.bar.buttons.modules.hypridle.icon" = accent.base; + "theme.bar.buttons.modules.hypridle.text" = accent.base; + + "theme.bar.buttons.modules.hyprsunset.background" = background; + "theme.bar.buttons.modules.hyprsunset.border" = accent.base; + "theme.bar.buttons.modules.hyprsunset.icon_background" = background; + "theme.bar.buttons.modules.hyprsunset.icon" = accent.base; + "theme.bar.buttons.modules.hyprsunset.text" = accent.base; + + "theme.bar.buttons.modules.kbLayout.background" = background; + "theme.bar.buttons.modules.kbLayout.border" = accent.base; + "theme.bar.buttons.modules.kbLayout.icon_background" = background; + "theme.bar.buttons.modules.kbLayout.icon" = accent.base; + "theme.bar.buttons.modules.kbLayout.text" = accent.base; + + "theme.bar.buttons.modules.microphone.background" = background; + "theme.bar.buttons.modules.microphone.border" = accent.base; + "theme.bar.buttons.modules.microphone.icon_background" = background; + "theme.bar.buttons.modules.microphone.icon" = accent.base; + "theme.bar.buttons.modules.microphone.text" = accent.base; + + "theme.bar.buttons.modules.netstat.background" = background; + "theme.bar.buttons.modules.netstat.border" = accent.base; + "theme.bar.buttons.modules.netstat.icon_background" = background; + "theme.bar.buttons.modules.netstat.icon" = accent.base; + "theme.bar.buttons.modules.netstat.text" = accent.base; + + "theme.bar.buttons.modules.power.background" = background; + "theme.bar.buttons.modules.power.border" = accent.base; + "theme.bar.buttons.modules.power.icon_background" = background; + "theme.bar.buttons.modules.power.icon" = accent.base; + + "theme.bar.buttons.modules.ram.background" = background; + "theme.bar.buttons.modules.ram.border" = accent.base; + "theme.bar.buttons.modules.ram.icon_background" = background; + "theme.bar.buttons.modules.ram.icon" = accent.base; + "theme.bar.buttons.modules.ram.text" = accent.base; + + "theme.bar.buttons.modules.storage.background" = background; + "theme.bar.buttons.modules.storage.border" = accent.base; + "theme.bar.buttons.modules.storage.icon_background" = background; + "theme.bar.buttons.modules.storage.icon" = accent.base; + "theme.bar.buttons.modules.storage.text" = accent.base; + + "theme.bar.buttons.modules.submap.background" = background; + "theme.bar.buttons.modules.submap.border" = accent.base; + "theme.bar.buttons.modules.submap.icon_background" = background; + "theme.bar.buttons.modules.submap.icon" = accent.base; + "theme.bar.buttons.modules.submap.text" = special.base; + + "theme.bar.buttons.modules.updates.background" = background; + "theme.bar.buttons.modules.updates.border" = accent.base; + "theme.bar.buttons.modules.updates.icon_background" = background; + "theme.bar.buttons.modules.updates.icon" = accent.base; + "theme.bar.buttons.modules.updates.text" = accent.base; + + "theme.bar.buttons.modules.weather.background" = background; + "theme.bar.buttons.modules.weather.border" = accent.base; + "theme.bar.buttons.modules.weather.icon_background" = background; + "theme.bar.buttons.modules.weather.icon" = accent.base; + "theme.bar.buttons.modules.weather.text" = accent.base; + + "theme.bar.buttons.modules.worldclock.background" = background; + "theme.bar.buttons.modules.worldclock.border" = accent.base; + "theme.bar.buttons.modules.worldclock.icon_background" = background; + "theme.bar.buttons.modules.worldclock.icon" = accent.base; + "theme.bar.buttons.modules.worldclock.text" = accent.base; + "theme.bar.buttons.monochrome" = false; + + "theme.bar.buttons.network.background" = background; + "theme.bar.buttons.network.border" = accent.base; + "theme.bar.buttons.network.icon_background" = background; + "theme.bar.buttons.network.icon" = accent.base; + "theme.bar.buttons.network.text" = accent.base; + + "theme.bar.buttons.notifications.background" = background; + "theme.bar.buttons.notifications.border" = accent.base; + "theme.bar.buttons.notifications.icon_background" = background; + "theme.bar.buttons.notifications.icon" = accent.base; + "theme.bar.buttons.notifications.total" = accent.base; + + "theme.bar.buttons.opacity" = t; + + "theme.bar.buttons.separator.color" = accent.base; + + "theme.bar.buttons.style" = "default"; + + "theme.bar.buttons.systray.background" = background; + "theme.bar.buttons.systray.border" = accent.base; + "theme.bar.buttons.systray.customIcon" = accent.base; + + "theme.bar.buttons.text" = accent.base; + + "theme.bar.buttons.volume.background" = background; + "theme.bar.buttons.volume.border" = accent.base; + "theme.bar.buttons.volume.icon_background" = background; + "theme.bar.buttons.volume.icon" = accent.base; + "theme.bar.buttons.volume.text" = accent.base; + + "theme.bar.buttons.windowtitle.background" = background; + "theme.bar.buttons.windowtitle.border" = secondary.base; + "theme.bar.buttons.windowtitle.icon_background" = background; + "theme.bar.buttons.windowtitle.icon" = secondary.base; + "theme.bar.buttons.windowtitle.text" = secondary.base; + + "theme.bar.buttons.workspaces.active" = accent.bright; + "theme.bar.buttons.workspaces.available" = accent.base; + "theme.bar.buttons.workspaces.background" = background; + "theme.bar.buttons.workspaces.border" = accent.base; + "theme.bar.buttons.workspaces.hover" = foreground; + "theme.bar.buttons.workspaces.numbered_active_highlighted_text_color" = accent.base; + "theme.bar.buttons.workspaces.numbered_active_highlight_padding" = "0.2em"; + "theme.bar.buttons.workspaces.numbered_active_underline_color" = accent.bright; + "theme.bar.buttons.workspaces.numbered_inactive_padding" = "0.2em"; + "theme.bar.buttons.workspaces.occupied" = secondary.base; + "theme.bar.buttons.workspaces.pill.width" = "4em"; + "theme.bar.buttons.workspaces.smartHighlight" = true; + "theme.bar.buttons.y_margins" = "0em"; + + "theme.bar.location" = "bottom"; + + "theme.bar.menus.menu.battery.background.color" = background; + "theme.bar.menus.menu.battery.border.color" = accent.base; + "theme.bar.menus.menu.battery.card.color" = accent.dark; + "theme.bar.menus.menu.battery.icons.active" = accent.base; + "theme.bar.menus.menu.battery.icons.passive" = accent.base; + "theme.bar.menus.menu.battery.label.color" = accent.base; + "theme.bar.menus.menu.battery.listitems.active" = accent.base; + "theme.bar.menus.menu.battery.listitems.passive" = accent.base; + "theme.bar.menus.menu.battery.slider.background" = background; + "theme.bar.menus.menu.battery.slider.backgroundhover" = background; + "theme.bar.menus.menu.battery.slider.primary" = accent.base; + "theme.bar.menus.menu.battery.slider.puck" = accent.base; + "theme.bar.menus.menu.battery.text" = foreground; + + "theme.bar.menus.menu.bluetooth.background.color" = background; + "theme.bar.menus.menu.bluetooth.border.color" = accent.base; + "theme.bar.menus.menu.bluetooth.card.color" = accent.dark; + "theme.bar.menus.menu.bluetooth.iconbutton.active" = accent.base; + "theme.bar.menus.menu.bluetooth.iconbutton.passive" = accent.base; + "theme.bar.menus.menu.bluetooth.icons.active" = accent.base; + "theme.bar.menus.menu.bluetooth.icons.passive" = accent.base; + "theme.bar.menus.menu.bluetooth.label.color" = accent.base; + "theme.bar.menus.menu.bluetooth.listitems.active" = accent.base; + "theme.bar.menus.menu.bluetooth.listitems.passive" = accent.base; + "theme.bar.menus.menu.bluetooth.scroller.color" = accent.base; + "theme.bar.menus.menu.bluetooth.status" = accent.base; + "theme.bar.menus.menu.bluetooth.switch.disabled" = accent.base; + "theme.bar.menus.menu.bluetooth.switch_divider" = accent.base; + "theme.bar.menus.menu.bluetooth.switch.enabled" = accent.base; + "theme.bar.menus.menu.bluetooth.switch.puck" = accent.base; + "theme.bar.menus.menu.bluetooth.text" = foreground; + + "theme.bar.menus.menu.clock.background.color" = background; + "theme.bar.menus.menu.clock.border.color" = accent.base; + "theme.bar.menus.menu.clock.calendar.contextdays" = foreground; + "theme.bar.menus.menu.clock.calendar.currentday" = accent.base; + "theme.bar.menus.menu.clock.calendar.days" = accent.base; + "theme.bar.menus.menu.clock.calendar.paginator" = accent.base; + "theme.bar.menus.menu.clock.calendar.weekdays" = accent.base; + "theme.bar.menus.menu.clock.calendar.yearmonth" = accent.base; + "theme.bar.menus.menu.clock.card.color" = accent.dark; + "theme.bar.menus.menu.clock.text" = foreground; + "theme.bar.menus.menu.clock.time.time" = accent.base; + "theme.bar.menus.menu.clock.time.timeperiod" = accent.base; + "theme.bar.menus.menu.clock.weather.hourly.icon" = accent.base; + "theme.bar.menus.menu.clock.weather.hourly.temperature" = accent.base; + "theme.bar.menus.menu.clock.weather.hourly.time" = accent.base; + "theme.bar.menus.menu.clock.weather.icon" = accent.base; + "theme.bar.menus.menu.clock.weather.stats" = accent.base; + "theme.bar.menus.menu.clock.weather.status" = accent.base; + "theme.bar.menus.menu.clock.weather.temperature" = accent.base; + "theme.bar.menus.menu.clock.weather.thermometer.cold" = accent.base; + "theme.bar.menus.menu.clock.weather.thermometer.extremelycold" = accent.base; + "theme.bar.menus.menu.clock.weather.thermometer.extremelyhot" = accent.base; + "theme.bar.menus.menu.clock.weather.thermometer.hot" = accent.base; + "theme.bar.menus.menu.clock.weather.thermometer.moderate" = accent.base; + + "theme.bar.menus.menu.dashboard.background.color" = background; + "theme.bar.menus.menu.dashboard.border.color" = accent.base; + "theme.bar.menus.menu.dashboard.card.color" = accent.dark; + + "theme.bar.menus.menu.dashboard.controls.bluetooth.background" = background; + "theme.bar.menus.menu.dashboard.controls.bluetooth.text" = foreground; + "theme.bar.menus.menu.dashboard.controls.disabled" = accent.base; + "theme.bar.menus.menu.dashboard.controls.input.background" = background; + "theme.bar.menus.menu.dashboard.controls.input.text" = foreground; + "theme.bar.menus.menu.dashboard.controls.notifications.background" = background; + "theme.bar.menus.menu.dashboard.controls.notifications.text" = foreground; + "theme.bar.menus.menu.dashboard.controls.volume.background" = background; + "theme.bar.menus.menu.dashboard.controls.volume.text" = foreground; + "theme.bar.menus.menu.dashboard.controls.wifi.background" = background; + "theme.bar.menus.menu.dashboard.controls.wifi.text" = foreground; + + "theme.bar.menus.menu.dashboard.directories.left.bottom.color" = accent.base; + "theme.bar.menus.menu.dashboard.directories.left.middle.color" = accent.base; + "theme.bar.menus.menu.dashboard.directories.left.top.color" = accent.base; + "theme.bar.menus.menu.dashboard.directories.right.bottom.color" = accent.base; + "theme.bar.menus.menu.dashboard.directories.right.middle.color" = accent.base; + "theme.bar.menus.menu.dashboard.directories.right.top.color" = accent.base; + + "theme.bar.menus.menu.dashboard.monitors.bar_background" = background; + "theme.bar.menus.menu.dashboard.monitors.cpu.bar" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.cpu.icon" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.cpu.label" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.disk.bar" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.disk.icon" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.disk.label" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.gpu.bar" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.gpu.icon" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.gpu.label" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.ram.bar" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.ram.icon" = accent.base; + "theme.bar.menus.menu.dashboard.monitors.ram.label" = accent.base; + + "theme.bar.menus.menu.dashboard.powermenu.confirmation.background" = background; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.body" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.border" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.button_text" = foreground; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.card" = accent.dark; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.confirm" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.deny" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.confirmation.label" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.logout" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.restart" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.shutdown" = accent.base; + "theme.bar.menus.menu.dashboard.powermenu.sleep" = accent.base; + "theme.bar.menus.menu.dashboard.profile.name" = accent.base; + "theme.bar.menus.menu.dashboard.shortcuts.background" = background; + "theme.bar.menus.menu.dashboard.shortcuts.recording" = accent.base; + "theme.bar.menus.menu.dashboard.shortcuts.text" = foreground; + + "theme.bar.menus.menu.media.album" = accent.base; + "theme.bar.menus.menu.media.artist" = accent.base; + "theme.bar.menus.menu.media.background.color" = "#000000"; + "theme.bar.menus.menu.media.border.color" = accent.base; + "theme.bar.menus.menu.media.buttons.background" = background; + "theme.bar.menus.menu.media.buttons.enabled" = accent.base; + "theme.bar.menus.menu.media.buttons.inactive" = accent.base; + "theme.bar.menus.menu.media.buttons.text" = foreground; + "theme.bar.menus.menu.media.card.color" = accent.dark; + "theme.bar.menus.menu.media.card.tint" = accent.dark; + "theme.bar.menus.menu.media.slider.background" = accent.dark; + "theme.bar.menus.menu.media.slider.backgroundhover" = secondary.dark; + "theme.bar.menus.menu.media.slider.primary" = accent.base; + "theme.bar.menus.menu.media.slider.puck" = accent.bright; + "theme.bar.menus.menu.media.song" = accent.base; + "theme.bar.menus.menu.media.timestamp" = accent.base; + + "theme.bar.menus.menu.network.background.color" = background; + "theme.bar.menus.menu.network.border.color" = accent.base; + "theme.bar.menus.menu.network.card.color" = accent.dark; + "theme.bar.menus.menu.network.iconbuttons.active" = accent.base; + "theme.bar.menus.menu.network.iconbuttons.passive" = accent.base; + "theme.bar.menus.menu.network.icons.active" = accent.base; + "theme.bar.menus.menu.network.icons.passive" = accent.base; + "theme.bar.menus.menu.network.label.color" = accent.base; + "theme.bar.menus.menu.network.listitems.active" = accent.base; + "theme.bar.menus.menu.network.listitems.passive" = accent.base; + "theme.bar.menus.menu.network.scroller.color" = accent.base; + "theme.bar.menus.menu.network.status.color" = accent.base; + "theme.bar.menus.menu.network.switch.disabled" = accent.base; + "theme.bar.menus.menu.network.switch.enabled" = accent.base; + "theme.bar.menus.menu.network.switch.puck" = accent.base; + "theme.bar.menus.menu.network.text" = foreground; + + "theme.bar.menus.menu.notifications.background" = background; + "theme.bar.menus.menu.notifications.border" = accent.base; + "theme.bar.menus.menu.notifications.card" = accent.dark; + "theme.bar.menus.menu.notifications.clear" = accent.base; + "theme.bar.menus.menu.notifications.label" = accent.base; + "theme.bar.menus.menu.notifications.no_notifications_label" = accent.base; + "theme.bar.menus.menu.notifications.pager.background" = background; + "theme.bar.menus.menu.notifications.pager.button" = accent.dark; + "theme.bar.menus.menu.notifications.pager.label" = accent.base; + "theme.bar.menus.menu.notifications.scrollbar.color" = accent.base; + "theme.bar.menus.menu.notifications.switch.disabled" = accent.base; + "theme.bar.menus.menu.notifications.switch_divider" = accent.base; + "theme.bar.menus.menu.notifications.switch.enabled" = accent.base; + "theme.bar.menus.menu.notifications.switch.puck" = accent.base; + + + "theme.bar.menus.menu.power.background.color" = background; + "theme.bar.menus.menu.power.border.color" = accent.base; + + "theme.bar.menus.menu.power.buttons.logout.background" = background; + "theme.bar.menus.menu.power.buttons.logout.icon_background" = background; + "theme.bar.menus.menu.power.buttons.logout.icon" = accent.base; + "theme.bar.menus.menu.power.buttons.logout.text" = foreground; + + "theme.bar.menus.menu.power.buttons.restart.background" = background; + "theme.bar.menus.menu.power.buttons.restart.icon_background" = background; + "theme.bar.menus.menu.power.buttons.restart.icon" = accent.base; + "theme.bar.menus.menu.power.buttons.restart.text" = foreground; + + "theme.bar.menus.menu.power.buttons.shutdown.background" = background; + "theme.bar.menus.menu.power.buttons.shutdown.icon_background" = background; + "theme.bar.menus.menu.power.buttons.shutdown.icon" = accent.base; + "theme.bar.menus.menu.power.buttons.shutdown.text" = foreground; + + "theme.bar.menus.menu.power.buttons.sleep.background" = background; + "theme.bar.menus.menu.power.buttons.sleep.icon_background" = background; + "theme.bar.menus.menu.power.buttons.sleep.icon" = accent.base; + "theme.bar.menus.menu.power.buttons.sleep.text" = foreground; + + + "theme.bar.menus.menu.systray.dropdownmenu.background" = background; + "theme.bar.menus.menu.systray.dropdownmenu.divider" = accent.base; + "theme.bar.menus.menu.systray.dropdownmenu.text" = foreground; + + "theme.bar.menus.menu.volume.audio_slider.background" = background; + "theme.bar.menus.menu.volume.audio_slider.backgroundhover" = background; + "theme.bar.menus.menu.volume.audio_slider.primary" = accent.base; + "theme.bar.menus.menu.volume.audio_slider.puck" = accent.base; + "theme.bar.menus.menu.volume.background.color" = background; + "theme.bar.menus.menu.volume.border.color" = accent.base; + "theme.bar.menus.menu.volume.card.color" = accent.dark; + "theme.bar.menus.menu.volume.iconbutton.active" = accent.base; + "theme.bar.menus.menu.volume.iconbutton.passive" = accent.base; + "theme.bar.menus.menu.volume.input_slider.background" = background; + "theme.bar.menus.menu.volume.input_slider.backgroundhover" = background; + "theme.bar.menus.menu.volume.input_slider.primary" = accent.base; + "theme.bar.menus.menu.volume.input_slider.puck" = accent.base; + "theme.bar.menus.menu.volume.label.color" = accent.base; + "theme.bar.menus.menu.volume.listitems.active" = accent.base; + "theme.bar.menus.menu.volume.listitems.passive" = accent.base; + "theme.bar.menus.menu.volume.text" = foreground; + + "theme.bar.menus.monochrome" = false; + + "theme.bar.opacity" = t; + "theme.bar.outer_spacing" = "0em"; + "theme.bar.transparent" = false; + + "theme.font.name" = rice.font.code.name; + "theme.font.size" = "12px"; + + "theme.notification.actions.background" = background; + "theme.notification.actions.text" = foreground; + "theme.notification.background" = background; + "theme.notification.border" = accent.base; + "theme.notification.close_button.background" = accent.dark; + "theme.notification.close_button.label" = accent.base; + "theme.notification.label" = accent.base; + "theme.notification.labelicon" = accent.base; + "theme.notification.opacity" = 1.0; + "theme.notification.text" = foreground; + "theme.notification.time" = accent.base; + + "theme.osd.bar_color" = accent.base; + "theme.osd.bar_container" = accent.dark; + "theme.osd.bar_empty_color" = accent.dark; + "theme.osd.bar_overflow_color" = accent.base; + "theme.osd.border.color" = border; + "theme.osd.icon_container" = secondary.dark; + "theme.osd.icon" = secondary.bright; + "theme.osd.label" = accent.bright; + "theme.osd.opacity" = t; + }; + }; +} diff --git a/home-modules/bar/submap-indicator.nix b/home-modules/bar/submap-indicator.nix new file mode 100644 index 0000000..d79b2b3 --- /dev/null +++ b/home-modules/bar/submap-indicator.nix @@ -0,0 +1,37 @@ +{ pkgs, ... }: { + home.packages = [ + (pkgs.writeShellApplication { name = "submap_indicator"; text = /*bash*/ '' + print_help() { + echo "Usage: submap_indicator {set |unset}" + } + if [ $# -lt 1 ]; then + print_help; exit 1; + fi + case "$1" in + set) + # Check if there is a second argument for the 'set' operation + if [ $# -eq 2 ]; then + echo "$2" > /tmp/submap-indictor + pkill -RTMIN+8 waybar + pkill -RTMIN+8 hyprpanel + else + echo "Error: 'set' operation requires exactly one string argument." + print_help + exit 1 + fi + ;; + unset) + echo "" > /tmp/submap-indictor + pkill -RTMIN+8 waybar + pkill -RTMIN+8 hyprpanel + ;; + *) + echo "Error: Unknown command '$1'" + print_help + exit 1 + ;; + esac + exit 0 + '';}) + ]; +} diff --git a/home-modules/bar/waybar.nix b/home-modules/bar/waybar.nix new file mode 100644 index 0000000..52b91c9 --- /dev/null +++ b/home-modules/bar/waybar.nix @@ -0,0 +1,165 @@ +{ pkgs, ... }@all: with all; let + sep = " "; +in { + programs.waybar = { + enable = false; + package = pkgs.waybar; + settings = { + bar = { + # height = 20; + layer = "top"; + position = "bottom"; + margin-top = 0; + # margin-left = rice.gap-size; + # margin-bottom = rice.gap-size; + # margin-right = rice.gap-size; + margin-left = 0; + margin-bottom = 0; + margin-right = 0; + spacing = 10; + fixed-center = true; + modules-left = [ + # "cpu" + # "memory" + "wireplumber" + "backlight" + "battery" + "network" + "hyprland/window" + ]; + modules-center = [ + "hyprland/workspaces" + ]; + modules-right = [ + "custom/mode" + "custom/caldav_event" + "custom/cclock" + "tray" + ]; + "hyprland/workspaces" = { + on-click = "activate"; + format = "{name}"; + all-outputs = false; + active-only = false; + }; + "hyprland/window" = { + # format = "${sep}{}"; + format = "{}"; + separate-outputs = true; + }; + "custom/cclock" = { + exec = "cclock"; + restart-interval = 60; + }; + "custom/caldav_event" = { + format = "󰃰${sep}{}"; + exec = "caldav_event"; + restart-interval = 60; + max-width = 60; + }; + "custom/mode" = { + exec = "cat /tmp/submap-indictor"; + interval = "once"; + signal = 8; + }; + + cpu = { + interval = 1; + format = "󰍛${sep}{}%"; + max-length = 10; + }; + memory = { + interval = 5; + format = "${sep}{avail:.0f}G free"; + }; + battery = { + interval = 60; + tooltip = false; + format = "{icon}${sep}{capacity}%"; + states = { + warning = 15; + critical = 5; + }; + format-icons = [ " " " " " " " " " " ]; + format-charging = "{icon}${sep}+{capacity}%"; + format-plugged = "{icon}${sep}P{capacity}%"; + format-full = "{icon}${sep}F{capacity}%"; + }; + backlight = { + device = "eDP-1"; + format = "{icon}${sep}{percent}%"; + format-icons = [ "" "" "" "" "" "" "" "" "" ]; + }; + network = { + format-wifi = "${sep}{essid}"; + format-ethernet = "󰈀${sep}Wired"; + format-disconnected = "󰌙${sep}Disconnected"; + }; + wireplumber = { + format = "󰕾${sep}{volume}%"; + format-muted = "󰝟${sep}--%"; + }; + }; + }; + style = with rice.color; let f = rice.lib.hex-to-rgb-comma-string; in /* css */ '' + * { + font-family: ${rice.font.code.name}; + font-size: 1em; + min-height: 0px; + margin: 0px; + padding: 0px; + } + + window#waybar { + background: rgba(${f background},${builtins.toString rice.transparency}); + } + + #clock, + #custom-cclock, + #custom-mode, + #custom-caldav-event, + #battery, + #cpu, + #tray, + #disk, + #backlight, + #network, + #wireplumber, + #memory, + #window, + #workspaces { + padding: 0px 3px; + margin-top: 0.3em; + border-radius: ${builtins.toString rice.rounding}px; + color: rgb(${f accent.bright}); + } + + #workspaces button { + color: rgb(${f accent.base}); + padding-left: 15px; + padding-right: 15px; + border-radius: ${builtins.toString rice.rounding}px; + } + #workspaces button.active { color: rgb(${f background}); background-color: rgb(${f accent.base}); } + #workspaces button:hover { color: rgb(${f tertiary.bright}); } + #workspaces button.urgent { background-color: rgba(${f magenta.base},${builtins.toString rice.transparency}); } + + #window, #custom-caldav_event { + font-family: ${rice.font.base.name}, ${rice.font.code.name}; + color: rgb(${f tertiary.bright}); + } + + #wireplumber.muted { color: rgb(${f tertiary.bright}); } + #wireplumber { padding-left: 10px; } + + #battery.warning:not(.charging) { color: rgb(${f green.base});; } + #battery.charging { color: rgb(${f green.base}); } + #battery.critical { + background: rgb(${f negative.base}); + color: rgb(${f foreground}); + } + + #custom-mode { color: rgb(${f red.base}); } + ''; + }; +} diff --git a/home-modules/calendar-campuszeit-fix.nix b/home-modules/calendar-campuszeit-fix.nix index fd7cd55..cd9da30 100644 --- a/home-modules/calendar-campuszeit-fix.nix +++ b/home-modules/calendar-campuszeit-fix.nix @@ -20,22 +20,21 @@ def replace_campus_timezone(directory): with open(filepath, 'r', encoding='utf-8') as f: content = f.read() - if 'TZID:Europe/Berlin' in content or 'TZID="Europe/Berlin"' in content: - # Remove VTIMEZONE block for CampusNetZeit (optional depending on needs) - # Use a regex if multiple VTIMEZONE blocks may exist - start_idx = content.find('BEGIN:VTIMEZONE') - end_idx = content.find('END:VTIMEZONE', start_idx) - if start_idx != -1 and end_idx != -1: - content = content[:start_idx] + content[end_idx + len('END:VTIMEZONE\n'):] + start_idx = content.find('BEGIN:VTIMEZONE') + end_idx = content.find('END:VTIMEZONE', start_idx) + if start_idx != -1 and end_idx != -1: + content = content[:start_idx] + content[end_idx + len('END:VTIMEZONE\n'):] - # Replace all TZID references - content = content.replace('TZID:Europe/Berlin', 'TZID:Europe/Berlin') - content = content.replace('TZID="Europe/Berlin"', 'TZID="Europe/Berlin"') + # Replace all TZID references + content = content.replace('TZID:CampusNetZeit', 'TZID:Europe/Berlin') + content = content.replace('TZID=CampusNetZeit', 'TZID=Europe/Berlin') + content = content.replace('TZID:"CampusNetZeit"', 'TZID:"Europe/Berlin"') + content = content.replace('TZID="CampusNetZeit"', 'TZID="Europe/Berlin"') - with open(filepath, 'w', encoding='utf-8') as f: - f.write(content) + with open(filepath, 'w', encoding='utf-8') as f: + f.write(content) - print(f"Updated time zone in: {filename}") + print(f"Updated time zone in: {filename}") if __name__ == "__main__": if len(sys.argv) != 2: diff --git a/home-modules/chatterino.nix b/home-modules/chatterino.nix index ecdc68b..e0a8915 100644 --- a/home-modules/chatterino.nix +++ b/home-modules/chatterino.nix @@ -207,7 +207,7 @@ in { "external": { "streamlink": { "quality": "", - "options": "--config ${hyper.home}/.config/streamlink/config" + "options": "--config ${hyper.home}.config/streamlink/config" } } } @@ -329,10 +329,9 @@ in { ] } ''; - ".config/streamlink/config".text = '' - twitch-api-header=Authorization=OAuth='$(cat ${config.sops.secrets."streamlink/twitch-oauth".path})' + ".config/streamlink/config".text = /* ini */ '' + twitch-api-header=Authorization=OAuth ${secrets.streamlink.twitch-oauth} player=mpv - player-args='--no-terminal' twitch-low-latency default-stream=best ''; diff --git a/home-modules/gpg.nix b/home-modules/gpg.nix index 36aed64..a47f72d 100644 --- a/home-modules/gpg.nix +++ b/home-modules/gpg.nix @@ -19,48 +19,35 @@ enableFishIntegration = true; defaultCacheTtlSsh = min2sec 60; defaultCacheTtl = min2sec 30; - # pinentryPackage = pkgs.pinentry-curses; + pinentry = { + package = pkgs.pinentry; + program = "pinentry"; + }; + extraConfig = '' + allow-loopback-pinentry + ''; }; home.file.".gnupg/gpg.conf".text = '' - # Use AES256, 192, or 128 as cipher personal-cipher-preferences AES256 AES192 AES - # Use SHA512, 384, or 256 as digest personal-digest-preferences SHA512 SHA384 SHA256 - # Use ZLIB, BZIP2, ZIP, or no compression personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed - # Default preferences for new keys default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed - # SHA512 as digest to sign keys cert-digest-algo SHA512 - # SHA512 as digest for symmetric ops s2k-digest-algo SHA512 - # AES256 as cipher for symmetric ops s2k-cipher-algo AES256 - # UTF-8 support for compatibility charset utf-8 - # No comments in messages no-comments - # No version in output no-emit-version - # Disable banner no-greeting - # Long key id format keyid-format 0xlong - # Display UID validity list-options show-uid-validity verify-options show-uid-validity - # Display all keys and their fingerprints with-fingerprint - # Display key origins and updates - #with-key-origin - # Cross-certify subkeys are present and valid require-cross-certification - # Disable caching of passphrase for symmetrical ops no-symkey-cache - # Output ASCII instead of binary armor - # Enable smartcard - # use-agent + use-agent + pinentry-mode loopback ''; } diff --git a/home-modules/hyprland.nix b/home-modules/hyprland.nix index 90863d8..05bf154 100644 --- a/home-modules/hyprland.nix +++ b/home-modules/hyprland.nix @@ -217,7 +217,6 @@ in { "/usr/lib/polkit-kde-authentication-agent-1 " "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP" "syncthing -no-browser" - "mako" "fcitx5" # "ibus engine xkb:de::deu" "libinput-gestures" @@ -283,6 +282,11 @@ in { layerrule = [ "blur,waybar" + "blur,bar-0" # hyprpanel + "blur,bar-1" + "blur,bar-2" + "blur,bar-3" + "blur,bar-4" "dimaround,rofi" "blur,rofi" "xray,rofi" @@ -303,13 +307,13 @@ in { "SUPER SHIFT, F1, movetoworkspace, 100" # "SUPER, F2," # "SUPER, F3, toggleopaque" - "SUPER, F4, exec, rm /tmp/caldav_event_cache.json && notify-send 'Cleared Saved Event!' ''" - "SUPER, F5, exec, nx_gcal_event force-lookup" - "SUPER SHIFT, F5, exec, nx_gcal_event reauthenticate" + "SUPER, F4, exec, rm /tmp/caldav_event_cache.json && notify-send 'NxCaldavEvent' 'Cleared saved event cache!' ''" + # "SUPER, F5, exec, nx_gcal_event force-lookup" + # "SUPER SHIFT, F5, exec, nx_gcal_event reauthenticate" "SUPER, F6, exec, ${terminal-exec}'htop'" "SUPER, F7, exec, ${terminal-exec}'nmtui'" ''SUPER, F8, exec, find ~/Pictures/wallpapers/* -type f -not -path "~/Pictures/wallpapers/.git/*" | sort -R | head -n 1 | xargs -d '\n' swww img --transition-type wipe --transition-angle 60 --transition-step 120 --transition-fps 120 --transition-duration 2'' - "SUPER, F9, execr, waybar_mode set '󰸉 '" + "SUPER, F9, execr, submap_indicator set '󰸉 '" "SUPER, F9, submap, color" # "SUPER, F10, hyprload,update" "SUPER, F11, exec, waybar" @@ -355,7 +359,7 @@ in { "ALT, TAB, focuscurrentorlast" # "SUPER, TAB, exec, hyprswitch --daemon" "SUPER, Q, killactive" - "SUPER, W, exec, waybar_mode set '󰈹 '" + "SUPER, W, exec, submap_indicator set '󰈹 '" "SUPER, W, submap, browserSM " "SUPER, E, exec, element-desktop" "SUPER, R, exec, rofi -show drun" @@ -378,7 +382,7 @@ in { ########################################################################### ## ROW 3: - "SUPER, A, execr, waybar_mode set ' 󰹑 '" + "SUPER, A, execr, submap_indicator set ' 󰹑 '" "SUPER, A, submap, scrL" "SUPER, S, exec, spotify" "SUPER, D, exec, vesktop" @@ -397,7 +401,7 @@ in { ## ROW 4: # "SUPER, <, overview:toggle" - "SUPER, Y, execr, waybar_mode set '󰹑 '" + "SUPER, Y, execr, submap_indicator set '󰹑 '" "SUPER, Y, submap, scrR" "SUPER, X, exec, pkill wlogout || wlogout --protocol layer-shell -b 3" # "SUPER, C, exec, /home/nx2/scripts/quickconfig/quickconfig.sh " @@ -416,7 +420,7 @@ in { # bindr = SUPER, Ctrl, exec, # ?? # bindr = SUPERALT, Alt_L, exec, - "SUPER, Space, cyclenext" + # "SUPER, Space, cyclenext" "SUPER SHIFT, Space, swapnext" # "SUPER, , " # "SUPER, , " @@ -436,7 +440,7 @@ in { ########################################################################### ## MEGA KEYS: - ", Print, execr, waybar_mode set '󰄀 '" + ", Print, execr, submap_indicator set '󰄀 '" ", Print, submap, screenshot" # "SUPER, Next, resizeactive, 5% 5%" # binde @@ -520,18 +524,18 @@ in { # '8888Y' 'Y8888P' Y8888P' YP YP 88 YP YP '8888Y' extraConfig = let action_simple = { mods ? "", key, cmd }: '' - bind=${mods},${key},execr,waybar_mode unset + bind=${mods},${key},execr,submap_indicator unset bind=${mods},${key},${cmd} bind=${mods},${key},submap,reset ''; extra_workspace = { key, wsnumber }: '' - bind=,${key},execr,waybar_mode unset + bind=,${key},execr,submap_indicator unset bind=,${key},workspace,${wsnumber} bind=,${key},submap,reset - bind=SUPER,${key},execr,waybar_mode unset + bind=SUPER,${key},execr,submap_indicator unset bind=SUPER,${key},workspace,${wsnumber} bind=SUPER,${key},submap,reset - bind=SUPER SHIFT,${key},execr, waybar_mode unset + bind=SUPER SHIFT,${key},execr, submap_indicator unset bind=SUPER SHIFT,${key},movetoworkspace,${wsnumber} bind=SUPER SHIFT,${key},submap,reset ''; @@ -554,35 +558,35 @@ in { ${action_simple { key = "Y"; cmd = "exec,firefox https://youtube.com";}} ${action_simple { key = "P"; cmd = "exec,firefox https://pw.nx2.site";}} ${action_simple { key = "P"; cmd = "exec,firefox https://pw.nx2.site";}} - bind=,Z,exec,waybar_mode set ' ' + bind=,Z,exec,submap_indicator set ' ' bind=,Z,submap,tuda bind=,Z,submap,reset - bind=,Escape,exec,waybar_mode unset + bind=,Escape,exec,submap_indicator unset bind=,Escape,submap,reset submap = reset submap = scrL ${builtins.concatStringsSep "\n" (builtins.map (num: extra_workspace { key = builtins.toString num; wsnumber = "2" + builtins.toString num;}) [1 2 3 4 5 6 7 8 9 0])} - bind = , A, execr, waybar_mode unset + bind = , A, execr, submap_indicator unset bind = , A, submap, reset - bind = , Escape, execr, waybar_mode unset + bind = , Escape, execr, submap_indicator unset bind = , Escape, submap, reset submap = reset submap = scrR ${builtins.concatStringsSep "\n" (builtins.map (num: extra_workspace { key = builtins.toString num; wsnumber = "3" + builtins.toString num;}) [1 2 3 4 5 6 7 8 9 0])} - bind = , Y, execr, waybar_mode unset + bind = , Y, execr, submap_indicator unset bind = , Y, submap, reset - bind = , Escape, execr, waybar_mode unset + bind = , Escape, execr, submap_indicator unset bind = , Escape, submap, reset submap = reset submap = color - ${action_simple { key = "W"; cmd = ''exec,swww query | sed -n 1p | sed -E 's-.*image: (.*)-"\1"-g' | xargs change_colors_json img && notify-send 'change_colors_json img successfull' ''; }} - ${action_simple { key = "M"; cmd = ''exec,change_colors_json manual && notify-send 'change_colors_json manual successfull' ''; }} + ${action_simple { key = "W"; cmd = ''exec,swww query | sed -n 1p | sed -E 's-.*image: (.*)-"\1"-g' | xargs change_colors_json img && notify-send 'NxTheme' 'change_colors_json img successfull' ''; }} + ${action_simple { key = "M"; cmd = ''exec,change_colors_json manual && notify-send 'NxTheme' 'change_colors_json manual successfull' ''; }} ${action_simple { key = "D"; cmd = ''exec,firefox ${hyper.home}/.config/color-pallete.html''; }} - bind = , Escape, execr, waybar_mode unset + bind = , Escape, execr, submap_indicator unset bind = , Escape, submap, reset submap = reset @@ -590,7 +594,7 @@ in { ${action_simple { key = "T"; cmd = ''exec,firefox https://www.tucan.tu-darmstadt.de/''; }} ${action_simple { key = "M"; cmd = ''exec,firefox https://moodle.tu-darmstadt.de/''; }} ${action_simple { key = "I"; cmd = ''exec,firefox https://moodle.informatik.tu-darmstadt.de/''; }} - bind = , Escape, execr, waybar_mode unset + bind = , Escape, execr, submap_indicator unset bind = , Escape, submap, reset submap = reset @@ -598,7 +602,7 @@ in { ${action_simple { key = "W"; cmd = ''exec,hyprshot -m window''; }} ${action_simple { key = "M"; cmd = ''exec,hyprshot -m output''; }} ${action_simple { key = "R"; cmd = ''exec,hyprshot -m region''; }} - bind = , Escape, execr, waybar_mode unset + bind = , Escape, execr, submap_indicator unset bind = , Escape, submap, reset submap = reset diff --git a/home-modules/mako.nix b/home-modules/mako.nix index 8b6c35a..6ead07d 100644 --- a/home-modules/mako.nix +++ b/home-modules/mako.nix @@ -1,8 +1,8 @@ -{ pkgs, ... }@all: with all; +{ config, pkgs, ... }@all: with all; { home.packages = with pkgs; [ libnotify ]; services.mako = with rice; { - enable = true; + enable = if config.programs.hyprpanel.enable then false else true; settings = { default-timeout = 5000; # in ms background-color = color.background; diff --git a/home-modules/obs.nix b/home-modules/obs.nix index 5c5861a..e129c3f 100644 --- a/home-modules/obs.nix +++ b/home-modules/obs.nix @@ -1,5 +1,4 @@ { pkgs, ... }@all: with all; -lib.mkIf (hyper.host != "NxACE") { # home.packages = with pkgs; [ # obs-studio diff --git a/home-modules/pkgs-list/desktop.nix b/home-modules/pkgs-list/desktop.nix index fcb4830..d718c52 100644 --- a/home-modules/pkgs-list/desktop.nix +++ b/home-modules/pkgs-list/desktop.nix @@ -3,6 +3,7 @@ brightnessctl blueman fontpreview + gtk3 gsettings-desktop-schemas imv pavucontrol diff --git a/home-modules/rclone.nix b/home-modules/rclone.nix new file mode 100644 index 0000000..fee8dfc --- /dev/null +++ b/home-modules/rclone.nix @@ -0,0 +1,33 @@ +{ pkgs, ... }@all: with all; { + home.packages = with pkgs; [ rclone ]; + sops.secrets."nx2site/copyparty/user-password/${hyper.user}".path = "%r/secrets/copyparty/user-password/${hyper.user}"; + programs.rclone = { + enable = true; + package = pkgs.rclone; + remotes = { + "file.${hyper.domain}" = { + config = { + type = "webdav"; + vendor = "owncloud"; # copyparty + url = "https://file.${hyper.domain}/"; + user = hyper.user; + pacer_min_sleep = "0.01ms"; + }; + mounts = { + "" = { + enable = true; + mountPoint = "${hyper.home}/file.nx2.site/"; + options = { + vfs-cache-mode = "writes"; + dir-cache-time = "5s"; + }; + }; + }; + secrets = { + pass = "/run/user/1000/secrets/copyparty/user-password/${hyper.user}"; + }; + }; + }; + }; +} + diff --git a/home-modules/waybar.nix b/home-modules/waybar.nix deleted file mode 100644 index 8c014df..0000000 --- a/home-modules/waybar.nix +++ /dev/null @@ -1,379 +0,0 @@ -{ pkgs, hyper, ... }@all: with all; let - sep = " "; -in { - sops.secrets = { - "nx2site/radicale/password" = { }; - }; - home.packages = [ - (pkgs.writeShellApplication { name = "waybar_mode"; text = /*bash*/ '' - print_help() { - echo "Usage: waybar_mode {set |unset}" - } - if [ $# -lt 1 ]; then - print_help; exit 1; - fi - case "$1" in - set) - # Check if there is a second argument for the 'set' operation - if [ $# -eq 2 ]; then - echo "$2" > /tmp/waybar-mode - pkill -RTMIN+8 waybar - else - echo "Error: 'set' operation requires exactly one string argument." - print_help - exit 1 - fi - ;; - unset) - echo "" > /tmp/waybar-mode - pkill -RTMIN+8 waybar - ;; - *) - echo "Error: Unknown command '$1'" - print_help - exit 1 - ;; - esac - exit 0 - '';}) - (pkgs.writeShellApplication { name = "cclock"; text = /*bash*/ '' - ord=$(date +"%e" | awk '{printf("%d%s\n", $1, ($1==11||$1==12||$1==13)?"th":((($1%10)==1)?"st":((($1%10)==2)?"nd":((($1%10)==3)?"rd":"th"))))}') - if [ $# -eq 0 ]; then - echo "󰃮${sep}$(date +'%A the')" "$ord" "of" "$(date +'%B')" " ${sep}$(date +'%R')" - elif [ "$1" = "--no-icons" ]; then - echo "$(date +'%A the')" "$ord" "of" "$(date +'%B')" "$(date +'%R')" - fi - '';}) - (pkgs.writers.writePython3Bin "caldav_event" { - libraries = with pkgs.python3Packages; [ caldav ics pytz ]; - flakeIgnore = [ "E302" "E305" "E501" "E261" ]; - } /* python */ '' -import os -import json -from caldav import DAVClient -from datetime import datetime, timezone -from ics import Calendar -from pytz import UTC - -def get_password(password_file): - with open(password_file, "r") as file: - return file.read().strip() - -def datetime_converter(obj): - if isinstance(obj, datetime): - return obj.isoformat() - return obj - -def datetime_parser(dct): - for key, value in dct.items(): - if isinstance(value, str): - try: - dct[key] = datetime.fromisoformat(value) - except ValueError: - pass - return dct - -def load_cache(cache_file): - if os.path.exists(cache_file): - with open(cache_file, "r") as file: - return json.load(file, object_hook=datetime_parser) - return None - -def save_cache(cache_file, data): - with open(cache_file, "w") as file: - json.dump(data, file, default=datetime_converter, indent=4) - - -def get_ongoing_or_next_event(url, username, password): - now = datetime.now(timezone.utc) - - try: - client = DAVClient(url, username=username, password=password) - principal = client.principal() - calendars = principal.calendars() - - next_event_dict = { - 'event_name': "fake", - 'event_begin': datetime(9000, 1, 1, tzinfo=UTC), # in the year 9000 - 'event_end': datetime(9000, 1, 1, 8, tzinfo=UTC), - } - - for calendar in calendars: - for event in calendar.search(start=now): - calendar_parsed = Calendar(event.data) - for ics_event in calendar_parsed.events: - event_dict = {} - event_dict['event_name'] = ics_event.name or "(No Title)" - event_dict['event_begin'] = ics_event.begin.astimezone(timezone.utc) - event_dict['event_end'] = ics_event.end.astimezone(timezone.utc) - - if event_dict['event_begin'] <= now and now <= event_dict['event_end']: - return event_dict - elif event_dict['event_begin'] >= now and next_event_dict['event_begin'] > event_dict['event_begin']: - next_event_dict = event_dict - return next_event_dict - - except Exception as e: - print(f"Error accessing {url}: {e}") - return None - -def is_expired(event_dict: dict): - now = datetime.now(timezone.utc).timestamp() - event_start = event_dict['event_begin'].timestamp() - event_end = event_dict['event_end'].timestamp() - return not (event_start <= now <= event_end) - -if __name__ == "__main__": - password_file = "${config.sops.secrets."nx2site/radicale/password".path}" # Path to password file - cache_file = "/tmp/caldav_event_cache.json" # Path to cache file - url = "https://dav.${hyper.domain}/" - username = "nx2" - password = get_password(password_file) - now = datetime.now(timezone.utc).timestamp() - - event_dict = load_cache(cache_file) - - if (event_dict is None) or (is_expired(event_dict)): - event_dict = get_ongoing_or_next_event(url, username, password) - save_cache(cache_file, event_dict) - - if event_dict is None: # none were found - print("* zen *") - exit(0) - - event_start = event_dict['event_begin'].timestamp() - event_end = event_dict['event_end'].timestamp() - - if event_start <= now <= event_end: # is currently ongoing - action_string = "ends" - t = event_end - now # time_remaining - else: # is in the future - action_string = "starts" - t = event_start - now # time_remaining - - hours, rem = divmod(int(t), 3600) - minutes, _ = divmod(rem, 60) - hour_string = f"{hours} hour{'s ' if hours != 1 else ' '}" if hours > 0 else "" - minu_string = f"{minutes} minute{'s ' if minutes != 1 else ' '}" if minutes > 0 else "" - if hour_string == "" and minu_string == "": - time_string = "now" - elif hour_string == "" or minu_string == "": - time_string = "in " + hour_string + minu_string - else: - time_string = "in " + hour_string + "and " + minu_string - - print(f"{event_dict['event_name']} {action_string} {time_string}") -'') - ]; - - programs.waybar = { - enable = true; - package = pkgs.waybar; - settings = { - bar = { - # height = 20; - layer = "top"; - position = "bottom"; - margin-top = 0; - # margin-left = rice.gap-size; - # margin-bottom = rice.gap-size; - # margin-right = rice.gap-size; - margin-left = 0; - margin-bottom = 0; - margin-right = 0; - spacing = 10; - fixed-center = true; - modules-left = [ - # "cpu" - # "memory" - "wireplumber" - "backlight" - "battery" - "network" - "hyprland/window" - ]; - modules-center = [ - "hyprland/workspaces" - ]; - modules-right = [ - "custom/mode" - "custom/caldav_event" - "custom/cclock" - "tray" - ]; - "hyprland/workspaces" = { - on-click = "activate"; - format = "{name}"; - all-outputs = false; - active-only = false; - }; - "hyprland/window" = { - # format = "${sep}{}"; - format = "{}"; - separate-outputs = true; - }; - "custom/cclock" = { - exec = "cclock"; - restart-interval = 60; - }; - "custom/caldav_event" = { - format = "󰃰${sep}{}"; - exec = "caldav_event"; - restart-interval = 60; - max-width = 60; - }; - "custom/mode" = { - exec = "cat /tmp/waybar-mode"; - interval = "once"; - signal = 8; - }; - - cpu = { - interval = 1; - format = "󰍛${sep}{}%"; - max-length = 10; - }; - memory = { - interval = 5; - format = "${sep}{avail:.0f}G free"; - }; - battery = { - interval = 60; - tooltip = false; - format = "{icon}${sep}{capacity}%"; - states = { - warning = 15; - critical = 5; - }; - format-icons = [ - " " - " " - " " - " " - " " - ]; - format-charging = "{icon}${sep}+{capacity}%"; - format-plugged = "{icon}${sep}P{capacity}%"; - format-full = "{icon}${sep}F{capacity}%"; - }; - backlight = { - device = "eDP-1"; - format = "{icon}${sep}{percent}%"; - format-icons = [ - "" - "" - "" - "" - "" - "" - "" - "" - "" - ]; - }; - network = { - format-wifi = "${sep}{essid}"; - format-ethernet = "󰈀${sep}Wired"; - format-disconnected = "󰌙${sep}Disconnected"; - }; - wireplumber = { - format = "󰕾${sep}{volume}%"; - format-muted = "󰝟${sep}--%"; - }; - }; - }; - style = with rice.color; let f = rice.lib.hex-to-rgb-comma-string; in '' - * { - font-family: ${rice.font.code.name}; - font-size: 1em; - min-height: 0px; - margin: 0px; - padding: 0px; - } - - window#waybar { - background-color: rgba(${f background},${builtins.toString rice.transparency}); - transition-duration: 5s; - transition-property: background-color; - /* border: ${builtins.toString rice.border-width}px solid rgb(${f border}); */ - /* margin: ${builtins.toString rice.gap-size}px; */ - /* border-radius: ${builtins.toString rice.rounding}px; */ - } - - #clock, - #custom-cclock, - #custom-mode, - #custom-caldav-event, - #battery, - #cpu, - #tray, - #disk, - #backlight, - #network, - #wireplumber, - #memory, - #window, - #workspaces { - padding: 0px 3px; - margin-top: 0.3em; - border-radius: ${builtins.toString rice.rounding}px; - color: rgb(${f accent.bright}); - } - - #workspaces { - font-family: ${rice.font.code.name}; - } - - #workspaces button { - color: rgb(${f accent.base}); - padding-left: 15px; - padding-right: 15px; - border-radius: ${builtins.toString rice.rounding}px; - } - - #workspaces button.active { - color: rgb(${f background}); - background-color: rgb(${f accent.base}); - } - - #workspaces button:hover { - color: rgb(${f tertiary.bright}); - } - - #workspaces button.urgent { - background-color: rgba(${f magenta.base},${builtins.toString rice.transparency}); - } - - #custom-mode { - color: rgb(${f red.base}); - } - - #window, #custom-caldav_event { - font-family: ${rice.font.base.name}, ${rice.font.code.name}; - color: rgb(${f tertiary.bright}); - } - - #wireplumber.muted { - color: rgb(${f tertiary.bright}); - } - #wireplumber { - padding-left: 10px; - } - - #battery.warning:not(.charging) { - color: rgb(${f green.base});; - } - - #battery.charging { - color: rgb(${f green.base}); - } - - #battery.critical { - background: rgb(${f negative.base}); - color: rgb(${f foreground}); - } - ''; - - #battery.critical:not(.charging) { - }; -} diff --git a/home.nix b/home.nix index 724b593..cc672d4 100644 --- a/home.nix +++ b/home.nix @@ -1,6 +1,7 @@ { pkgs, ... }@all: with all; { imports = [ ./home-modules/auto-mount.nix + ./home-modules/bar.nix ./home-modules/bash.nix ./home-modules/bitwarden.nix ./home-modules/calendar.nix @@ -48,6 +49,7 @@ ./home-modules/programming/js.nix ./home-modules/programming/python.nix ./home-modules/qt.nix + ./home-modules/rclone.nix ./home-modules/rofi.nix ./home-modules/scanning.nix ./home-modules/sent.nix @@ -60,7 +62,6 @@ ./home-modules/virt-manager.nix ./home-modules/vscode.nix ./home-modules/wallpaper-to-colors.nix - ./home-modules/waybar.nix ./home-modules/wlogout.nix ./home-modules/xdg.nix ./home-modules/yazi.nix diff --git a/sops-secrets.yaml b/sops-secrets.yaml index ea7232d..da36693 100644 --- a/sops-secrets.yaml +++ b/sops-secrets.yaml @@ -37,6 +37,9 @@ nx2site: nextcloud: admin-pass: ENC[AES256_GCM,data:u6k70HwxBKAom8kvUihNjwbYsOikOt4sG1U=,iv:K0XPh1NfaGhFJ0ZVOWqnihZee6uuWxr0Vu8aR0ykr30=,tag:YyxgoVUxk4YxFnDmXkBXpw==,type:str] db-pass: ENC[AES256_GCM,data:HHY1XolLvLngYQHkfFEYTEmcIR7BSpwQ,iv:hFeuULgGVq+QxzIO0dcBaSlTFP1E7B6tv7BM0EUcTQA=,tag:ZsZyKMSeRLCEB3mZUiBa6w==,type:str] + copyparty: + user-password: + nx2: ENC[AES256_GCM,data:55yxXcN1eKvfpjWySw54r2dMlSg9,iv:w9rGUSUkumysj4ti6XqUm+sL0wwU6sgObfCefwfS5Mo=,tag:2TEDwHqU4RzOZ9+oiffGlg==,type:str] USERTrust: ECC: ENC[AES256_GCM,data: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,iv:GS5GMpbxeweqwjUvOzqg59xBOzNZqrL5t7RjsFjpucM=,tag:j0MaMw71fnRHxeydlqAaww==,type:str] RSA: ENC[AES256_GCM,data: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,iv:NJkjWL5kMHET68oR5Xp22kvkThXIp7WxRVajmTfsB5M=,tag:NSXeRItMKlOQYP4QtzMKIg==,type:str] @@ -86,8 +89,8 @@ sops: YkJWUEMySU50ZHVxUzVudjNnYURXak0KkMn/8sFrrviqb3s8DtS/BAbrdCwJ+jv/ A8rXQkKMjvTqG1f0fq5IlSmRAQy7XFBzkfbKdIUoefhey190WPEHaw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-06-16T08:57:57Z" - mac: ENC[AES256_GCM,data:Qwk39Cv+WhxnW8858qWtGPiCrYb4bje5nRGOkG4OrAC/dZ+wpbMd9DXF134PUM1NB/aI3ivnl4EeVAlcv/E32EjodZJOGkseKme5Hler69+nfL0DJT00XhBDR3aGVf3YMA5Po+XR9ikLKFF1wz4DhV4ylN6RxxMrpLJltba+0NI=,iv:QUulKPfnAujRUNWKBKUsIynOHsd4E09NO8TlaQwzFy0=,tag:N1LNlbvdjkXWarIAI9tkZg==,type:str] + lastmodified: "2025-08-06T22:09:56Z" + mac: ENC[AES256_GCM,data:s3lBIa/Y0fjtFFTDggC+Oxd9T5A1al9ULh4VM78vS+A6nmCZWdezLkY1CwXPrCcrwYQtnKrj5N4Y1jQQmEkF1UIcgkvH7ZQsT7MOJyvWhZUx2/wIg1DwcdlHYJAiwFkIkZ1fEvE4m/uDCWA8xO4qWU4NJaxPzTyapPKKF4VwkNs=,iv:tqDVOQlwS+CMzX8MxrBRPjBVj1Svx91eQx2xamAsSiE=,tag:VJf1at+026fQJ5ML2D/PEg==,type:str] pgp: - created_at: "2025-06-08T12:35:30Z" enc: |- diff --git a/system-modules/calendar/lr.nix b/system-modules/calendar/lr.nix index f81f5ab..1644817 100644 --- a/system-modules/calendar/lr.nix +++ b/system-modules/calendar/lr.nix @@ -23,7 +23,8 @@ from ics import Calendar import requests def filter_events(events): - return [event for event in events if ("LR" in event.name) or ("TBD" in event.name)] + return [event for event in events if ("LR" in event.name)] + # return [event for event in events if ("LR" in event.name) or ("TBD" in event.name)] def fetch_and_save_ical_events(ical_urls, save_path): """ diff --git a/system-modules/hardware-configuration.nix b/system-modules/hardware-configuration.nix index 57a9a4a..3772a32 100644 --- a/system-modules/hardware-configuration.nix +++ b/system-modules/hardware-configuration.nix @@ -49,4 +49,6 @@ libvdpau-va-gl intel-media-driver ] else []; + + services.upower.enable = true; } diff --git a/system-modules/health_reminder.nix b/system-modules/health_reminder.nix index 68772f4..a91228f 100644 --- a/system-modules/health_reminder.nix +++ b/system-modules/health_reminder.nix @@ -5,8 +5,8 @@ lib.mkIf (hyper.host != "NxACE") enable = true; wantedBy = [ "timers.target" ]; timerConfig = { - OnBootSec = "5m"; - OnUnitActiveSec = "5m"; + OnBootSec = "30m"; + OnUnitActiveSec = "10m"; Unit = "health_reminder.service"; }; }; @@ -34,11 +34,11 @@ lib.mkIf (hyper.host != "NxACE") return action actions = [ - Action(action="look away for %o Seconds!", likelihood=300, options=["10", "15"]), - Action(action="Posture Check!", likelihood=300), + Action(action="look away for %o Seconds!", likelihood=30, options=["10", "15"]), + Action(action="Posture Check!", likelihood=200), Action(action="Strech your upper body!", likelihood=20), Action(action="Strech your core!", likelihood=10), - Action(action="Strech your legs!", likelihood=10), + Action(action="Strech your legs!", likelihood=20), Action(action="Strech your arms/hands!", likelihood=10), Action(action="Make Tea!", likelihood=5), Action(action="说现在中文的时间!", likelihood=2), diff --git a/system-modules/nx2site/copyparty.nix b/system-modules/nx2site/copyparty.nix new file mode 100644 index 0000000..93d97ca --- /dev/null +++ b/system-modules/nx2site/copyparty.nix @@ -0,0 +1,44 @@ +{ config, pkgs, ... }@all: with all; { + imports = [ inputs.copyparty.nixosModules.default ]; + config = { + sops.secrets."nx2site/copyparty/user-password/${hyper.user}".owner = "copyparty"; + environment.systemPackages = with pkgs; [ copyparty ]; + services.copyparty = { + enable = true; + package = pkgs.copyparty; + openFilesLimit = 8192; + settings = { + i = [ "0.0.0.0" "unix:770:copyparty:/dev/shm/party.sock" ]; + p = [ 3210 3211 ]; + no-reload = true; + ignored-flag = false; + shr = "/shares"; + css-browser = "https://nx2.site/copyparty/extra-browser.css"; + theme = 6; + xff-hdr = "X-Forwarded-For"; # so that cpp knows the real client ip behind nginx. Must match with nginx config + rproxy = 1; + no-robots = true; + }; + accounts = { + "${hyper.user}" = { + passwordFile = config.sops.secrets."nx2site/copyparty/user-password/${hyper.user}".path; + }; + }; + volumes = { + "/" = { + path = "/srv/copyparty/root"; + access = { + "A" = "${hyper.user}"; + }; + flags = { + fk = 4; # url password length + scan = 60; # scan interval in seconds + e2d = true; # volflag "e2d" enables the uploads database + d2t = true; # "d2t" disables multimedia parsers (in case the uploads are malicious) + nohash = "\.iso$"; # skips hashing file contents if path matches *.iso + }; + }; + }; + }; + }; +} diff --git a/system-modules/nx2site/proxy.nix b/system-modules/nx2site/proxy.nix index 0b636b9..a8ab99a 100644 --- a/system-modules/nx2site/proxy.nix +++ b/system-modules/nx2site/proxy.nix @@ -19,7 +19,7 @@ }; }; users.users."nginx" = { - extraGroups = [ "nginx" "acme" ]; + extraGroups = [ "nginx" "acme" "copyparty" ]; useDefaultShell = false; linger = true; home = "/var/nginx/"; @@ -65,6 +65,14 @@ statusPage = false; streamConfig = ""; # udp config validateConfigFile = true; + upstreams = { + "partysock" = { + servers."unix:/dev/shm/party.sock".fail_timeout = "1s"; + extraConfig = /* nginx */ '' + keepalive 1; + ''; + }; + }; virtualHosts = let vh = { kTLS = true; @@ -186,10 +194,41 @@ # proxyWebsockets = true; # }; }; # }; + "file.${hyper.domain}" = { # copyparty + listen = dl; + forceSSL = true; + enableACME = true; + locations = { + "/" = { + proxyPass = "http://partysock"; + proxyWebsockets = true; + extraConfig = /* nginx */ '' + proxy_redirect off; + # disable buffering (next 4 lines) + # proxy_http_version 1.1; # this is set by nixos + client_max_body_size 0; + proxy_buffering off; + proxy_request_buffering off; + # improve download speed from 600 to 1500 MiB/s + proxy_buffers 32 8k; + proxy_buffer_size 16k; + proxy_busy_buffers_size 24k; + + proxy_set_header Connection "Keep-Alive"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # NOTE: with cloudflare you want this X-Forwarded-For instead: + #proxy_set_header X-Forwarded-For $http_cf_connecting_ip; + ''; + }; + }; + }; "~^(.*).${hyper.domain}$" = { listen = dl; root = "/var/nginx/webroot"; - locations = { "~.*" = { return = "301 https://${hyper.domain}/502.html"; }; }; + locations."~.*".return = "502"; }; }; };