···11+{ config, pkgs, ... }:
22+let
33+ dunstConfig = pkgs.writeText "dunst-config" ''
44+ [global]
55+ font = Iosevka Term 11
66+77+ # Allow a small subset of html markup:
88+ # <b>bold</b>
99+ # <i>italic</i>
1010+ # <s>strikethrough</s>
1111+ # <u>underline</u>
1212+ #
1313+ # For a complete reference see
1414+ # <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
1515+ # If markup is not allowed, those tags will be stripped out of the
1616+ # message.
1717+ markup = yes
1818+ plain_text = no
1919+2020+ # The format of the message. Possible variables are:
2121+ # %a appname
2222+ # %s summary
2323+ # %b body
2424+ # %i iconname (including its path)
2525+ # %I iconname (without its path)
2626+ # %p progress value if set ([ 0%] to [100%]) or nothing
2727+ # Markup is allowed
2828+ format = "%a\n<b>%s</b>\n%b"
2929+3030+ # Sort messages by urgency.
3131+ sort = yes
3232+3333+ # Show how many messages are currently hidden (because of geometry).
3434+ indicate_hidden = yes
3535+3636+ # Alignment of message text.
3737+ # Possible values are "left", "center" and "right".
3838+ alignment = center
3939+4040+ # The frequency with wich text that is longer than the notification
4141+ # window allows bounces back and forth.
4242+ # This option conflicts with "word_wrap".
4343+ # Set to 0 to disable.
4444+ bounce_freq = 0
4545+4646+ # Show age of message if message is older than show_age_threshold
4747+ # seconds.
4848+ # Set to -1 to disable.
4949+ show_age_threshold = 1
5050+5151+ # Split notifications into multiple lines if they don't fit into
5252+ # geometry.
5353+ word_wrap = yes
5454+5555+ # Ignore newlines '\n' in notifications.
5656+ ignore_newline = no
5757+5858+ # Hide duplicate's count and stack them
5959+ stack_duplicates = yes
6060+ hide_duplicates_count = no
6161+6262+6363+ # The geometry of the window:
6464+ # [{width}]x{height}[+/-{x}+/-{y}]
6565+ # The geometry of the message window.
6666+ # The height is measured in number of notifications everything else
6767+ # in pixels. If the width is omitted but the height is given
6868+ # ("-geometry x2"), the message window expands over the whole screen
6969+ # (dmenu-like). If width is 0, the window expands to the longest
7070+ # message displayed. A positive x is measured from the left, a
7171+ # negative from the right side of the screen. Y is measured from
7272+ # the top and down respectevly.
7373+ # The width can be negative. In this case the actual width is the
7474+ # screen width minus the width defined in within the geometry option.
7575+ geometry = "500x10-0+0"
7676+7777+ # Shrink window if it's smaller than the width. Will be ignored if
7878+ # width is 0.
7979+ shrink = no
8080+8181+ # The transparency of the window. Range: [0; 100].
8282+ # This option will only work if a compositing windowmanager is
8383+ # present (e.g. xcompmgr, compiz, etc.).
8484+ # transparency = 5
8585+8686+ # Don't remove messages, if the user is idle (no mouse or keyboard input)
8787+ # for longer than idle_threshold seconds.
8888+ # Set to 0 to disable.
8989+ idle_threshold = 0
9090+9191+ # Which monitor should the notifications be displayed on.
9292+ monitor = keyboard
9393+9494+ # Display notification on focused monitor. Possible modes are:
9595+ # mouse: follow mouse pointer
9696+ # keyboard: follow window with keyboard focus
9797+ # none: don't follow anything
9898+ #
9999+ # "keyboard" needs a windowmanager that exports the
100100+ # _NET_ACTIVE_WINDOW property.
101101+ # This should be the case for almost all modern windowmanagers.
102102+ #
103103+ # If this option is set to mouse or keyboard, the monitor option
104104+ # will be ignored.
105105+ follow = none
106106+107107+ # Should a notification popped up from history be sticky or timeout
108108+ # as if it would normally do.
109109+ sticky_history = yes
110110+111111+ # Maximum amount of notifications kept in history
112112+ history_length = 15
113113+114114+ # Display indicators for URLs (U) and actions (A).
115115+ show_indicators = no
116116+117117+ # The height of a single line. If the height is smaller than the
118118+ # font height, it will get raised to the font height.
119119+ # This adds empty space above and under the text.
120120+ line_height = 3
121121+122122+ # Draw a line of "separatpr_height" pixel height between two
123123+ # notifications.
124124+ # Set to 0 to disable.
125125+ separator_height = 1
126126+127127+ # Padding between text and separator.
128128+ padding = 1
129129+130130+ # Horizontal padding.
131131+ horizontal_padding = 1
132132+133133+ # Define a color for the separator.
134134+ # possible values are:
135135+ # * auto: dunst tries to find a color fitting to the background;
136136+ # * foreground: use the same color as the foreground;
137137+ # * frame: use the same color as the frame;
138138+ # * anything else will be interpreted as a X color.
139139+ separator_color = frame
140140+141141+ # Print a notification on startup.
142142+ # This is mainly for error detection, since dbus (re-)starts dunst
143143+ # automatically after a crash.
144144+ startup_notification = true
145145+146146+ # dmenu path.
147147+ dmenu = ${pkgs.dmenu}/bin/dmenu -p dunst:
148148+149149+ # Browser for opening urls in context menu.
150150+ browser = /usr/bin/firefox -new-tab
151151+152152+ # Align icons left/right/off
153153+ icon_position = off
154154+ max_icon_size = 80
155155+156156+ # Paths to default icons.
157157+ icon_folders = /usr/share/icons/Paper/16x16/mimetypes/:/usr/share/icons/Paper/48x48/status/:/usr/share/icons/Paper/16x16/devices/:/usr/share/icons/Paper/48x48/notifications/:/usr/share/icons/Paper/48x48/emblems/
158158+159159+ frame_width = 2
160160+ frame_color = "#8EC07C"
161161+162162+ [shortcuts]
163163+164164+ # Shortcuts are specified as [modifier+][modifier+]...key
165165+ # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
166166+ # "mod3" and "mod4" (windows-key).
167167+ # Xev might be helpful to find names for keys.
168168+169169+ # Close notification.
170170+ close = ctrl+space
171171+172172+ # Close all notifications.
173173+ close_all = ctrl+shift+space
174174+175175+ # Redisplay last message(s).
176176+ # On the US keyboard layout "grave" is normally above TAB and left
177177+ # of "1".
178178+ history = ctrl+grave
179179+180180+ # Context menu.
181181+ context = mod4+u
182182+183183+ [urgency_low]
184184+ # IMPORTANT: colors have to be defined in quotation marks.
185185+ # Otherwise the "#" and following would be interpreted as a comment.
186186+ frame_color = "#3B7C87"
187187+ foreground = "#3B7C87"
188188+ background = "#191311"
189189+ #background = "#2B313C"
190190+ timeout = 1
191191+192192+ [urgency_normal]
193193+ frame_color = "#5B8234"
194194+ foreground = "#5B8234"
195195+ background = "#191311"
196196+ #background = "#2B313C"
197197+ timeout = 1
198198+199199+ [urgency_critical]
200200+ frame_color = "#B7472A"
201201+ foreground = "#B7472A"
202202+ background = "#191311"
203203+ #background = "#2B313C"
204204+ timeout = 1
205205+206206+207207+ # Every section that isn't one of the above is interpreted as a rules to
208208+ # override settings for certain messages.
209209+ # Messages can be matched by "appname", "summary", "body", "icon", "category",
210210+ # "msg_urgency" and you can override the "timeout", "urgency", "foreground",
211211+ # "background", "new_icon" and "format".
212212+ # Shell-like globbing will get expanded.
213213+ #
214214+ # SCRIPTING
215215+ # You can specify a script that gets run when the rule matches by
216216+ # setting the "script" option.
217217+ # The script will be called as follows:
218218+ # script appname summary body icon urgency
219219+ # where urgency can be "LOW", "NORMAL" or "CRITICAL".
220220+ #
221221+ # NOTE: if you don't want a notification to be displayed, set the format
222222+ # to "".
223223+ # NOTE: It might be helpful to run dunst -print in a terminal in order
224224+ # to find fitting options for rules.
225225+226226+ #[espeak]
227227+ # summary = "*"
228228+ # script = dunst_espeak.sh
229229+230230+ #[script-test]
231231+ # summary = "*script*"
232232+ # script = dunst_test.sh
233233+234234+ #[ignore]
235235+ # # This notification will not be displayed
236236+ # summary = "foobar"
237237+ # format = ""
238238+239239+ #[signed_on]
240240+ # appname = Pidgin
241241+ # summary = "*signed on*"
242242+ # urgency = low
243243+ #
244244+ #[signed_off]
245245+ # appname = Pidgin
246246+ # summary = *signed off*
247247+ # urgency = low
248248+ #
249249+ #[says]
250250+ # appname = Pidgin
251251+ # summary = *says*
252252+ # urgency = critical
253253+ #
254254+ #[twitter]
255255+ # appname = Pidgin
256256+ # summary = *twitter.com*
257257+ # urgency = normal
258258+ #
259259+ # vim: ft=cfg
260260+ '';
261261+in {
262262+ systemd.user.services.dunst = {
263263+ wantedBy = [ "graphical-session.target" ];
264264+ requires = [ "xmonad.service" ];
265265+ environment = {
266266+ DISPLAY = ":${toString config.services.xserver.display}";
267267+ };
268268+ serviceConfig = {
269269+ SyslogIdentifier = "dunst";
270270+ ExecStart = "${pkgs.dunst}/bin/dunst -conf ${dunstConfig}";
271271+ Restart = "always";
272272+ RestartSec = "15s";
273273+ StartLimitBurst = 0;
274274+ };
275275+ };
276276+}
···11+{ pkgs, lib, ... }:
22+33+let
44+ dl_subs = pkgs.writers.writeDashBin "dl_subs" ''
55+ filename=$1
66+ ${pkgs.subdl}/bin/subdl --output='/tmp/{m}.{M}.sub' "$filename" 1>&2
77+ echo "/tmp/$(basename "$filename").sub"
88+ '';
99+1010+ autosub = pkgs.writeText "autosub.lua" ''
1111+ -- Requires Subliminal version 1.0 or newer
1212+ -- Make sure to specify your system's Subliminal location below:
1313+ local utils = require 'mp.utils'
1414+1515+ -- Log function: log to both terminal and mpv OSD (On-Screen Display)
1616+ function log(string, secs)
1717+ secs = secs or 2 -- secs defaults to 2 when the secs parameter is absent
1818+ mp.msg.warn(string) -- This logs to the terminal
1919+ mp.osd_message(string, secs) -- This logs to mpv screen
2020+ end
2121+2222+ function download()
2323+ log('Searching subtitles ...', 10)
2424+ path = mp.get_property('path')
2525+ result = utils.subprocess({ args = {"${dl_subs}/bin/dl_subs", path} })
2626+ if result.error == nil then
2727+ filename = string.gsub(result.stdout, "\n", "")
2828+ log(filename)
2929+ mp.commandv('sub_add', filename)
3030+ log('Subtitles ready!')
3131+ else
3232+ log('Subtitles failed downloading')
3333+ end
3434+ end
3535+3636+ -- Control function: only download if necessary
3737+ function control_download()
3838+ duration = tonumber(mp.get_property('duration'))
3939+ if duration < 900 then
4040+ mp.msg.warn('Video is less than 15 minutes\n', '=> NOT downloading any subtitles')
4141+ return
4242+ end
4343+ -- There does not seem to be any documentation for the 'sub' property,
4444+ -- but it works on both internally encoded as well as external subtitle files!
4545+ -- -> sub = '1' when subtitles are present
4646+ -- -> sub = 'no' when subtitles are not present
4747+ -- -> sub = 'auto' when called before the 'file-loaded' event is triggered
4848+ sub = mp.get_property('sub')
4949+ if sub == '1' then
5050+ mp.msg.warn('Sub track is already present\n', '=> NOT downloading other subtitles')
5151+ return
5252+ end
5353+ mp.msg.warn('No sub track was detected\n', '=> Proceeding to download subtitles:')
5454+ download()
5555+ end
5656+5757+ mp.add_key_binding('S', "download_subs", download)
5858+ '';
5959+6060+ mpvInput = pkgs.writeText "mpv.input" ''
6161+ : script-binding console/enable
6262+ x add audio-delay -0.050
6363+ X add audio-delay 0.050
6464+ '';
6565+6666+ mpvConfig = pkgs.writeText "mpv.conf" ''
6767+ osd-font-size=20
6868+ '';
6969+7070+ mpv = pkgs.symlinkJoin {
7171+ name = "mpv";
7272+ paths = [
7373+ (pkgs.writeDashBin "mpv" ''
7474+ set -efu
7575+ Y_RES=1081
7676+ # we need to disable sponsorblock local database because of
7777+ # https://github.com/po5/mpv_sponsorblock/issues/31
7878+ exec ${pkgs.mpv.override {
7979+ scripts = with pkgs.mpvScripts; [
8080+ sponsorblock
8181+ quality-menu
8282+ ];
8383+ }}/bin/mpv \
8484+ --no-config \
8585+ --input-conf=${mpvInput} \
8686+ --include=${mpvConfig} \
8787+ --script=${autosub} \
8888+ --ytdl-format="best[height<$Y_RES]" \
8989+ --script-opts=ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp \
9090+ --script-opts-append=sponsorblock-local_database=no \
9191+ --audio-channels=2 \
9292+ "$@"
9393+ '')
9494+ pkgs.mpv
9595+ ];
9696+ };
9797+9898+in {
9999+ environment.systemPackages = [
100100+ mpv
101101+ dl_subs
102102+ ];
103103+}
···11+{ pkgs, ... }:
22+# Enables second factor for ssh password login
33+44+## Usage:
55+# gen-oath-safe <username> totp
66+## scan the qrcode with google authenticator (or FreeOTP)
77+## copy last line into secrets/<host>/users.oath (chmod 700)
88+{
99+ security.pam.oath = {
1010+ # enabling it will make it a requisite of `all` services
1111+ # enable = true;
1212+ digits = 6;
1313+ # TODO assert existing
1414+ usersFile = "${config.krebs.secret.directory}/users.oath";
1515+ };
1616+ # I want TFA only active for sshd with password-auth
1717+ security.pam.services.sshd.oathAuth = true;
1818+}
···11+Very WIP
22+Automatically connect to WIFIs.
33+passwords can be stored in an easy db format
44+55+Requirements:
66+- NetworkManager
77+- python3
88+99+example wifi db:
1010+```
1111+myssid/mywifipassword
1212+myssid2/mywifipassword2
1313+```
1414+1515+will fallback to open wifis if no known wifi is found.
1616+will try to ping the gateway on the wifi after connecting.
1717+1818+Available options:
1919+(all directory options take multiple directories)
2020+* `--scan-hooks, -s` - directories with hooks which are run after the scanning phase
2121+* `--connection-hooks, -c` - directories with hooks which are run after connecting to a wifi
2222+* `--wifi_dirs, -w` - directories with wifi dbs
2323+* `--loglevel, -l` - loglevel to log to STDOUT, takes INFO and DEBUG as arguments
2424+* `--pidfile, -p` - file to write the PID to
2525+* `--no-open` - don't connect to open wifis in the end
2626+2727+2828+## FLOW
2929+3030+
···11+{ pkgs }:
22+pkgs.writers.writeDashBin "nix-index-update" ''
33+ set -efux
44+ filename="index-$(uname -m)-$(uname | tr A-Z a-z)"
55+ mkdir -p ~/.cache/nix-index && cd ~/.cache/nix-index
66+ # -N will only download a new version if there is an update.
77+ ${pkgs.wget}/bin/wget -q -N https://github.com/Mic92/nix-index-database/releases/latest/download/$filename
88+ ln -f $filename files
99+''
···11+{ nsxiv, writers }:
22+33+writers.writeDashBin "sxiv" ''
44+ set -efu
55+ tmpfile="''${TMPDIR:-/tmp}/nsxiv_pipe_$$"
66+ trap 'rm -f -- $tmpfile' EXIT
77+88+ if [ "$#" -eq 0 ]; then
99+ if [ -t 0 ]; then
1010+ echo "sxiv: No arguments provided" >&2; exit 1
1111+ else
1212+ # Consume stdin and put it in the temporal file
1313+ cat > "$tmpfile"
1414+ fi
1515+ fi
1616+1717+ for arg in "$@"; do
1818+ # if it's a pipe then drain it to $tmpfile
1919+ [ -p "$arg" ] && cat "$arg" > "$tmpfile"
2020+ done
2121+2222+ if [ -s "$tmpfile" ]; then
2323+ ${nsxiv}/bin/nsxiv -q "$@" "$tmpfile" # -q to silence warnings
2424+ else
2525+ ${nsxiv}/bin/nsxiv "$@" # fallback
2626+ fi
2727+''
···11+import geoip2.database
22+import fileinput
33+import json
44+import requests
55+import os
66+import random
77+88+99+geoip = geoip2.database.Reader(os.environ['MAXMIND_GEOIP_DB'])
1010+seen = {}
1111+output = []
1212+for ip in fileinput.input():
1313+ if "80.147.140.51" in ip:
1414+ output.append(
1515+ 'Weather report for c-base, space. '
1616+ 'It is empty space outside '
1717+ 'with a temperature of -270 degrees, '
1818+ 'a lightspeed of 299792 kilometers per second '
1919+ 'and a humidity of Not a Number percent. '
2020+ f'The probability of reincarnation is {random.randrange(0, 100)} percent. '
2121+ )
2222+ else:
2323+ try:
2424+ location = geoip.city(ip.strip())
2525+ if location.city.geoname_id not in seen:
2626+ seen[location.city.geoname_id] = True
2727+ weather_api_key = os.environ['OPENWEATHER_API_KEY']
2828+ url = (
2929+ f'https://api.openweathermap.org/data/2.5/onecall'
3030+ f'?lat={location.location.latitude}'
3131+ f'&lon={location.location.longitude}'
3232+ f'&appid={weather_api_key}'
3333+ f'&units=metric'
3434+ )
3535+ resp = requests.get(url)
3636+ weather = json.loads(resp.text)
3737+ output.append(
3838+ f'Weather report for {location.city.name}, {location.country.name}. '
3939+ f'It is {weather["current"]["weather"][0]["description"]} outside '
4040+ f'with a temperature of {weather["current"]["temp"]:.1f} degrees, '
4141+ f'a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second '
4242+ f'and a humidity of {weather["current"]["humidity"]} percent. '
4343+ f'The probability of precipitation is {weather["hourly"][0]["pop"] * 100:.0f} percent. '
4444+ )
4545+ except: # noqa E722
4646+ pass
4747+4848+print('\n'.join(output))
···11+7NIGHTS_4AB/7nights4you
22+HUB/IFeelGood
33+continuousdelivery/Pr0ud70f81l3arly
44+cccac/23cccac42
55+devolo-guest-30d32d5ab677/QNWTHNJYAYUUQEPG
66+vodafoneACF3E4/puriri01
77+Rotorua Int Motor Inn/apple123
88+Fitzroy Beach Motel/Summ3r*S@nds
99+Hawera Central Motor Lodge/53princes