home-manager/gui: Add Brainrot story mode screensaver
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 29m6s

This commit is contained in:
Jack O'Sullivan 2025-03-28 11:01:46 +00:00
parent 85a4b124e5
commit 854cc48479
2 changed files with 44 additions and 12 deletions

View File

@ -1,7 +1,7 @@
{ lib, pkgs', pkgs, config, ... }: { lib, pkgs', pkgs, config, ... }:
let let
inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault; inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault;
inherit (lib.my) mkBoolOpt'; inherit (lib.my) mkOpt' mkBoolOpt';
inherit (lib.my.c) pubDomain; inherit (lib.my.c) pubDomain;
cfg = config.my.gui; cfg = config.my.gui;
@ -25,26 +25,33 @@ let
hash = "sha256-723pRm4AsIjY/WFUyAHzTJp+JvH4Pn5hvzF9wHTnOPA="; hash = "sha256-723pRm4AsIjY/WFUyAHzTJp+JvH4Pn5hvzF9wHTnOPA=";
}; };
doomsaver = pkgs.runCommand "doomsaver" { genLipsum = pkgs.writeScript "lipsum" ''
inherit (pkgs) windowtolayer; #!${pkgs.python3.withPackages (ps: [ ps.python-lorem ])}/bin/python
import lorem
print(lorem.get_paragraph(count=5, sep='\n\n'))
'';
doomsaver' = brainrotTextCommand: pkgs.runCommand "doomsaver" {
inherit (pkgs) windowtolayer tmux terminaltexteffects;
chocoDoom = pkgs.chocolate-doom2xx; chocoDoom = pkgs.chocolate-doom2xx;
ffmpeg = pkgs.ffmpeg-full; ffmpeg = pkgs.ffmpeg-full;
python = pkgs.python3.withPackages (ps: [ ps.filelock ]); python = pkgs.python3.withPackages (ps: [ ps.filelock ]);
inherit doomWad; inherit doomWad;
enojy = ./enojy.jpg; enojy = ./enojy.jpg;
inherit subwaySurfers minecraftParkour; inherit brainrotTextCommand subwaySurfers minecraftParkour;
} '' } ''
mkdir -p "$out"/bin mkdir -p "$out"/bin
substituteAll ${./screensaver.py} "$out"/bin/doomsaver substituteAll ${./screensaver.py} "$out"/bin/doomsaver
chmod +x "$out"/bin/doomsaver chmod +x "$out"/bin/doomsaver
''; '';
doomsaver = doomsaver' cfg.screensaver.brainrotTextCommand;
in in
{ {
options.my.gui = { options.my.gui = with lib.types; {
enable = mkBoolOpt' true "Enable settings and packages meant for graphical systems"; enable = mkBoolOpt' true "Enable settings and packages meant for graphical systems";
manageGraphical = mkBoolOpt' false "Configure the graphical session"; manageGraphical = mkBoolOpt' false "Configure the graphical session";
standalone = mkBoolOpt' false "Enable settings for fully Nix managed systems"; standalone = mkBoolOpt' false "Enable settings for fully Nix managed systems";
screensaver.brainrotTextCommand = mkOpt' (either path str) genLipsum "Command to generate brainrot text.";
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [

View File

@ -73,7 +73,7 @@ class TTESaver(Screensaver):
def wait(self): def wait(self):
while self.running: while self.running:
effect_cmd = ['tte', random.choice(self.effects)] effect_cmd = ['@terminaltexteffects@/bin/tte', random.choice(self.effects)]
print(f"$ {self.cmd} | {' '.join(effect_cmd)}") print(f"$ {self.cmd} | {' '.join(effect_cmd)}")
content = subprocess.check_output(self.cmd, shell=True, env=self.env, stderr=subprocess.DEVNULL) content = subprocess.check_output(self.cmd, shell=True, env=self.env, stderr=subprocess.DEVNULL)
@ -87,17 +87,42 @@ class TTESaver(Screensaver):
self.proc.terminate() self.proc.terminate()
class FFmpegCACASaver(Screensaver): class FFmpegCACASaver(Screensaver):
@staticmethod
def command(video, size):
return ['@ffmpeg@/bin/ffmpeg', '-hide_banner', '-loglevel', 'error',
'-stream_loop', '-1', '-i', video,
'-pix_fmt', 'rgb24', '-window_size', f'{size}x{size}',
'-f', 'caca', '-']
def __init__(self, video, weight=2): def __init__(self, video, weight=2):
cols, lines = os.get_terminal_size() cols, lines = os.get_terminal_size()
# IDK if it's reasonable to do this as "1:1" # IDK if it's reasonable to do this as "1:1"
size = lines - 4 size = lines - 4
super().__init__( super().__init__(
['@ffmpeg@/bin/ffmpeg', '-hide_banner', '-loglevel', 'error', self.command(video, size),
'-stream_loop', '-1', '-i', video, env={'CACA_DRIVER': 'ncurses'},
'-pix_fmt', 'rgb24', '-window_size', f'{size}x{size}', weight=weight,
'-f', 'caca', '-'], )
def stop(self):
super().stop(kill=True)
class BrainrotStorySaver(Screensaver):
def __init__(self, video, text_command, weight=2):
cols, lines = os.get_terminal_size()
video_size = lines - 1
video_command = ' '.join(FFmpegCACASaver.command(video, video_size))
text_command = (
f'while true; do {text_command} | '
f'@terminaltexteffects@/bin/tte --wrap-text --canvas-width=80 --canvas-height={video_size//2} --anchor-canvas=c '
'print --final-gradient-stops=ffffff; clear; done' )
super().__init__(
['@tmux@/bin/tmux', 'new-session', '-s', f'screensaver-{os.urandom(4).hex()}', '-n', 'brainrot',
text_command, ';', 'split-window', '-hbl', str(lines), video_command],
# ['sh', '-c', text_command],
env={ env={
'CACA_DRIVER': 'ncurses', 'CACA_DRIVER': 'ncurses',
'SHELL': '/bin/sh',
}, },
weight=weight, weight=weight,
) )
@ -120,8 +145,8 @@ class MultiSaver:
TTESaver('ss -ntu'), TTESaver('ss -ntu'),
TTESaver('jp2a --width=100 @enojy@'), TTESaver('jp2a --width=100 @enojy@'),
FFmpegCACASaver('@subwaySurfers@'), BrainrotStorySaver('@subwaySurfers@', '@brainrotTextCommand@'),
FFmpegCACASaver('@minecraftParkour@'), BrainrotStorySaver('@minecraftParkour@', '@brainrotTextCommand@'),
] ]
state_filename = 'screensaver.json' state_filename = 'screensaver.json'