1
0
mirror of https://github.com/kmein/niveum synced 2026-03-22 21:01:07 +01:00

88 Commits

Author SHA1 Message Date
704f745f5e try out whether new krops fixes the nixpkgs rebuilding issue 2022-02-16 09:11:10 +01:00
93dd8bd702 fix: less unstable, nixpkgs via krops git, NIX_PATH on makanek
systems wanted to build glibc all the time when updated
2022-02-15 22:16:50 +01:00
6e995764d4 chore: update horoscopy 2022-02-14 21:21:36 +01:00
87b9fc49ea feat(radio): opus streams 2022-02-14 08:14:15 +01:00
b4e42e6b22 feat: add horoscopy website 2022-02-14 08:02:08 +01:00
87f73a8fc1 fix(radio): clean up files after 1h 2022-02-10 19:28:34 +01:00
db8c06364f feat: wikipedia radio 2022-02-10 19:28:34 +01:00
24b7044a3f chore: update retiolum 2022-02-09 08:35:55 +01:00
908667267b feat: radio powered by liquidsoap 2022-02-08 00:47:10 +01:00
b3090737fd feat(grocy): disable 2022-02-07 12:59:34 +01:00
f195351474 feat(urlwatch): run later 2022-02-07 12:52:46 +01:00
1cce7dc8df feat: #hsmr moinbot 2022-02-07 11:44:29 +01:00
894cc6efef feat(polkit): dont need password for systemctl 2022-02-02 18:07:08 +01:00
f1ed00fe40 fix(traadfri): module scripts 2022-01-31 19:46:59 +01:00
7d1e1e712f feat(monitoring): simplify telegram alert message format 2022-01-31 09:33:24 +01:00
fd1c36874a feat(traadfri): no aliases but scripts 2022-01-31 09:33:04 +01:00
bc52a4a358 feat(traadfri): chain of lights 2022-01-30 22:47:54 +01:00
5aade69fbe fix(streams): remove defunct paradiso 2022-01-30 21:18:22 +01:00
0ead88d04a feat(git): bye hub 2022-01-30 20:58:37 +01:00
d21ff3e731 fix(ci): secrets for tuna 2022-01-28 14:25:32 +01:00
7a918319b7 fix(streams): di.fm 2022-01-28 12:54:12 +01:00
5524f3b92b feat: reactivate tuna 2022-01-28 12:54:12 +01:00
fe8af09148 feat(monitoring): improve messages 2022-01-28 09:04:40 +01:00
d9ca1e673d fix(flix): do not depend on wpa_supplicant 2022-01-27 18:27:34 +01:00
2efb8d7d8a feat(monitoring): streamline alerting 2022-01-27 17:47:33 +01:00
4e520a82aa Revert "feat(alertmanager): alert via irc"
This reverts commit 630d99e191.
2022-01-27 17:17:43 +01:00
62479936b1 feat(hu-berlin): split-tunnel via forti vpn 2022-01-27 16:54:22 +01:00
9419bb9bdd feat(i3): show which vpn is active 2022-01-27 16:45:51 +01:00
07b8813ae8 feat(prometheus): dont fail if no ssl 2022-01-27 15:49:36 +01:00
755105a428 feat(prometheus): monitor more URLs 2022-01-27 15:40:50 +01:00
ac75dcb826 feat(weechat): improve filter 2022-01-27 14:06:55 +01:00
76e22dba3c feat: bye bye russian keyboard 2022-01-26 20:54:05 +01:00
6b84a024a2 feat(i3): change rofi command 2022-01-26 20:54:05 +01:00
3f2fb3f5a3 feat(hu-berlin): prefer fortinet 2022-01-25 20:29:38 +01:00
40fa14d4a9 chore: update retiolum 2022-01-25 20:29:26 +01:00
272f2bdefe fix(restic): restart on failure 2022-01-24 09:17:04 +01:00
16b25d4890 feat(zaatar): mount restic disk via nixos 2022-01-23 16:46:32 +01:00
638751eb20 feat(rofi): theme 2022-01-23 16:40:54 +01:00
8b3a9be9fd feat(streams): add drachenhits 2022-01-23 16:40:47 +01:00
c3d94e5c49 fix(restic): remove tmp dir 2022-01-23 14:27:03 +01:00
13b8154a2b feat(weechat): smart filter, filter Mic92 gitlab 2022-01-23 14:27:03 +01:00
d17c3e942d feat: give rofi another chance 2022-01-23 14:27:03 +01:00
a8467cfb5a Revert "flake.lock: Update"
This reverts commit c417074b7d.

It wants to build `glibc` on all machines.
2022-01-23 08:56:48 +01:00
Kierán Meinhardt
4d9867a95d Merge pull request #2 from kmein/update_flake_lock_action
flake.lock: Update
2022-01-23 07:52:48 +01:00
github-actions[bot]
c417074b7d flake.lock: Update
Flake lock file changes:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/74f7e4319258e287b0f9cb95426c9853b282730b' (2021-11-28)
  → 'github:numtide/flake-utils/846b2ae0fc4cc943637d3d1def4454213e203cba' (2022-01-20)
• Updated input 'home-manager':
    'github:nix-community/home-manager/697cc8c68ed6a606296efbbe9614c32537078756' (2021-12-18)
  → 'github:nix-community/home-manager/28b9ae40c45c5e7711c353fee1b7af734e293979' (2022-01-20)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/5d3420c1285073d5061a5d88a533b347d1222750' (2022-01-10)
  → 'github:NixOS/nixpkgs/3d35529a48d3ad50ad959463755b0b7fe392cfa7' (2022-01-22)
• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/bd20b7f07fd337b2e85420edd642382a2cc0196d' (2022-01-11)
  → 'github:NixOS/nixpkgs/e5f7e0e5513455fa128d13d82095016b2dcffc55' (2022-01-22)
• Updated input 'retiolum':
    'github:krebs/retiolum/be4a56463af13a7dab5fd12378bef3b0ec8ae99b' (2022-01-18)
  → 'github:krebs/retiolum/e3818e1a3af803f43f42e96e5629fceaf9a18011' (2022-01-20)
• Updated input 'stockholm':
    'git+https://cgit.lassul.us/stockholm?ref=master&rev=f67bd5783d6ed2be836c7714ea38cbb3f7ac7257' (2022-01-09)
  → 'git+https://cgit.lassul.us/stockholm?ref=master&rev=a3e67719b9da74e208c4058c42c0bd555c56b049' (2022-01-18)
2022-01-23 07:49:25 +01:00
9ca72a841d fix(restic): run restic as restic 2022-01-22 09:18:59 +01:00
7ec0586cf1 feat(restic): depend on connection to retiolum 2022-01-22 09:18:38 +01:00
6d681e9f43 feat(restic): more sensible times 2022-01-21 19:14:45 +01:00
c9248ae9b9 fix(vim): fugitive command 2022-01-19 13:51:30 +01:00
215bae0b9f fix(ci): add restic password 2022-01-19 13:37:01 +01:00
6f2aab721d chore: revert flake update
it had to build too many things and broke while doing it
2022-01-19 12:36:39 +01:00
1434290100 feat(i3): bye bye astrology 2022-01-19 12:27:14 +01:00
abcbd4dff9 Merge remote-tracking branch 'origin/update_flake_lock_action' 2022-01-19 11:07:08 +01:00
5dbe6b61d1 feat(restic): add wrapper on zaatar 2022-01-19 10:58:44 +01:00
0dc1e167fd feat(restic): backup moodle-dl 2022-01-19 09:41:14 +01:00
6f06f0c9ef feat(restic): add mount script 2022-01-19 09:38:19 +01:00
59894e2734 feat(restic): backup redis 2022-01-19 08:32:44 +01:00
f3835ebd5e feat(restic): backup regular systems 2022-01-19 00:48:15 +01:00
20da594f97 feat(restic): backup git 2022-01-18 23:36:38 +01:00
30c2bfe598 feat(restic): run on makanek, prometheus 2022-01-18 23:28:53 +01:00
bdc5c147dd chore: update retiolum 2022-01-18 23:19:50 +01:00
59c420e8b0 feat(restic): add wrapper command 2022-01-18 22:38:28 +01:00
efb8dff677 feat(git): bye diff-so-fancy, hello delta 2022-01-18 21:52:46 +01:00
7518c0f893 feat(weechat): max nix prefix 2022-01-18 21:30:52 +01:00
1b7e0f903d feat: restic 2022-01-18 21:29:30 +01:00
github-actions[bot]
0a8ab261f2 flake.lock: Update
Flake lock file changes:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/5d3420c1285073d5061a5d88a533b347d1222750' (2022-01-10)
  → 'github:NixOS/nixpkgs/610d4ea2750e064bf34b33fa38cb671edd893d3d' (2022-01-18)
• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/bd20b7f07fd337b2e85420edd642382a2cc0196d' (2022-01-11)
  → 'github:NixOS/nixpkgs/222f62ed88f67a1c9a7854b7e95bd9a5fe67b7ca' (2022-01-18)
• Updated input 'retiolum':
    'github:krebs/retiolum/4fcbe17549fa742a32e05b5f2ca57a983ad500c1' (2022-01-11)
  → 'github:krebs/retiolum/b62eba68b0836a2ea0b786b3738b281f070a3e04' (2022-01-18)
• Updated input 'stockholm':
    'git+https://cgit.lassul.us/stockholm?ref=master&rev=f67bd5783d6ed2be836c7714ea38cbb3f7ac7257' (2022-01-09)
  → 'git+https://cgit.lassul.us/stockholm?ref=master&rev=8d67a33709db13fade3460cc01f385f5bcffd794' (2022-01-15)
2022-01-18 18:26:45 +00:00
9a2205121b feat(ci): add github action to update flake inputs 2022-01-18 19:19:17 +01:00
4316c604f6 feat(i3): bye bye vaccinations 2022-01-18 18:31:34 +01:00
2ce0a6415f feat(streams): renew c3 lounge 2022-01-18 12:28:40 +01:00
fbbc9767a3 feat(stardict): improve renderer 2022-01-18 12:18:31 +01:00
356269caf7 feat(zaatar): enable spotifyd 2022-01-17 21:03:38 +01:00
a001a98f7b feat(weechat): more libera 2022-01-17 10:10:16 +01:00
2624bf0a50 feat: timer script 2022-01-17 10:10:16 +01:00
5186b7ac28 feat: lojban software 2022-01-15 08:21:42 +01:00
5497739980 feat(stardict): lojban 2022-01-14 19:59:06 +01:00
5bbb01d275 feat(locale): use en_DK, which uses ISO date 2022-01-14 19:26:46 +01:00
83837932af feat(weechat): real name is first name 2022-01-14 19:26:46 +01:00
72c88d0f38 feat(stardict): replace lsj and sa, shorten oed 2022-01-14 19:26:46 +01:00
ed646335f1 feat: IBM 3270 colors 2022-01-14 19:17:01 +01:00
310e9d8b46 feat(stardict): case-insensitive 2022-01-14 09:11:20 +01:00
a7efa8a822 feat(watson): configure WATSON_DIR 2022-01-14 08:30:33 +01:00
f9ceed1352 feat(stardict): use built-in coloring 2022-01-13 20:01:50 +01:00
630d99e191 feat(alertmanager): alert via irc 2022-01-13 19:29:19 +01:00
f0e11f3147 feat(stardict): better rendering 2022-01-13 18:05:46 +01:00
c651413768 feat(stardict): more sanskrit 2022-01-13 17:43:47 +01:00
ac7ddcfd1a feat(krops): copy instead of fetching on target 2022-01-12 23:00:41 +01:00
03c944affd feat(unicodmenu): kaomoji first 2022-01-12 21:36:26 +01:00
57f440ced5 feat(unicodmenu): get from unicode website 2022-01-12 18:02:59 +01:00
46 changed files with 770 additions and 701 deletions

19
.github/workflows/flake.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Update flake.lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
jobs:
lockfile:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Nix
uses: cachix/install-nix-action@v16
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@v3

5
ci.nix
View File

@@ -31,11 +31,14 @@ let
"nextcloud-fysi/password" "nextcloud-fysi/password"
"nextcloud/password" "nextcloud/password"
"openweathermap.key" "openweathermap.key"
"restic/password"
"traadfri.key" "traadfri.key"
"wifi/Aether.psk" "wifi/Aether.psk"
"spotify/username"
"spotify/password"
]; ];
systemSecrets = let basic = [ "retiolum.ed25519" "retiolum.key" "syncthing/cert.pem" "syncthing/key.pem"]; in { systemSecrets = let basic = [ "retiolum.ed25519" "retiolum.key" "syncthing/cert.pem" "syncthing/key.pem"]; in {
zaatar = ensureFiles ([ "moodle.token" "telegram/moodle-dl.token" ] ++ basic); zaatar = ensureFiles ([ "moodle.token" "telegram/moodle-dl.token" "mpd-web.key" ] ++ basic);
kabsa = ensureFiles basic; kabsa = ensureFiles basic;
manakish = ensureFiles basic; manakish = ensureFiles basic;
makanek = ensureFiles ([ makanek = ensureFiles ([

44
configs/backup.nix Normal file
View File

@@ -0,0 +1,44 @@
{ pkgs, config, ... }:
let
inherit (import <niveum/lib>) restic;
in
{
services.restic.backups.niveum = {
initialize = true;
inherit (restic) repository;
timerConfig = { OnCalendar = "8:00"; RandomizedDelaySec = "1h"; };
passwordFile = toString <secrets/restic/password>;
extraBackupArgs = [
"--exclude=/home/kfm/projects/nixpkgs/.git"
"--exclude=node_modules"
];
paths = [
"/home/kfm/work"
"/home/kfm/projects"
"/home/kfm/cloud"
"/home/kfm/.gnupg"
"/home/kfm/.ssh"
];
};
systemd.services.restic-backups-niveum.serviceConfig = {
Restart = "on-failure";
RestartSec = "15s";
StartLimitIntervalSec = "1m"; # don't try more than 4 times
StartLimitBurst = 4;
};
environment.systemPackages = [
(pkgs.writers.writeDashBin "restic-niveum" ''
${pkgs.restic}/bin/restic -r ${restic.repository} -p ${<secrets/restic/password>} "$@"
'')
(pkgs.writers.writeDashBin "restic-mount" ''
mountdir=$(mktemp -d)
trap clean EXIT
clean() {
rm -r "$mountdir"
}
${pkgs.restic}/bin/restic -r ${restic.repository} -p ${<secrets/restic/password>} mount "$mountdir"
'')
];
}

View File

@@ -20,6 +20,7 @@ in {
config = { config = {
allowUnfree = true; allowUnfree = true;
packageOverrides = pkgs: { packageOverrides = pkgs: {
dmenu = pkgs.writers.writeDashBin "dmenu" ''exec ${pkgs.rofi}/bin/rofi -dmenu "$@"'';
gfs-fonts = pkgs.callPackage <niveum/packages/gfs-fonts.nix> {}; gfs-fonts = pkgs.callPackage <niveum/packages/gfs-fonts.nix> {};
tocharian-font = pkgs.callPackage <niveum/packages/tocharian-font.nix> {}; tocharian-font = pkgs.callPackage <niveum/packages/tocharian-font.nix> {};
iolanguage = pkgs.callPackage <niveum/packages/iolanguage.nix> { }; iolanguage = pkgs.callPackage <niveum/packages/iolanguage.nix> { };
@@ -136,7 +137,7 @@ in {
"${pkgs.youtube-dl}/bin/youtube-dl --add-metadata -xic"; # Download with audio "${pkgs.youtube-dl}/bin/youtube-dl --add-metadata -xic"; # Download with audio
}; };
} }
{ i18n.defaultLocale = "en_GB.UTF-8"; } { i18n.defaultLocale = "en_DK.UTF-8"; }
{ {
services.xserver = { services.xserver = {
enable = true; enable = true;
@@ -194,6 +195,7 @@ in {
}) localAddresses; }) localAddresses;
} }
./alacritty.nix ./alacritty.nix
./backup.nix
./bash.nix ./bash.nix
./beets.nix ./beets.nix
./bluetooth.nix ./bluetooth.nix
@@ -226,6 +228,7 @@ in {
./flameshot-once.nix ./flameshot-once.nix
./packages.nix ./packages.nix
./stardict.nix ./stardict.nix
./polkit.nix
./power-action.nix ./power-action.nix
./printing.nix ./printing.nix
./openweathermap.nix ./openweathermap.nix

View File

@@ -18,7 +18,6 @@ in {
"x-systemd.device-timeout=1" "x-systemd.device-timeout=1"
"x-systemd.idle-timeout=1min" "x-systemd.idle-timeout=1min"
"x-systemd.requires=tinc.retiolum.service" "x-systemd.requires=tinc.retiolum.service"
"x-systemd.requires=wpa_supplicant.service"
"user" "user"
"_netdev" "_netdev"
]; ];

View File

@@ -7,7 +7,6 @@ in
pkgs.mr pkgs.mr
pkgs.git pkgs.git
pkgs.gitAndTools.gitflow pkgs.gitAndTools.gitflow
pkgs.gitAndTools.hub
pkgs.gitAndTools.gh pkgs.gitAndTools.gh
pkgs.gitAndTools.git-extras pkgs.gitAndTools.git-extras
pkgs.gitAndTools.git-trim pkgs.gitAndTools.git-trim
@@ -23,37 +22,6 @@ in
}; };
home-manager.users.me = { home-manager.users.me = {
home.file.".mrconfig".text = let
prependPath = prefix:
lib.attrsets.mapAttrs'
(path: lib.attrsets.nameValuePair "${prefix}/${path}");
git = url: { checkout = "git clone ${url}"; };
github = owner: repo: git "git@github.com:${owner}/${repo}";
keybase = owner: repo: git "keybase://private/${owner}/${repo}";
in lib.generators.toINI { } ({
DEFAULT = { git_gc = ''git gc "$@"''; };
} // prependPath "projects" {
"menstruation.rs" = github "kmein" "menstruation.rs";
brockman = github "kmein" "brockman";
challenges = github "kmein" "challenges";
conlangs = github "kmein" "conlangs";
ledger = keybase "kmein" "ledger";
mahlzeit = github "kmein" "mahlzeit";
menstruation-telegram = github "kmein" "menstruation-telegram";
meteora = github "kmein" "meteora";
modernizr = github "kmein" "modernizr";
niveum = github "kmein" "niveum";
nixpkgs = github "NixOS" "nixpkgs";
poetry = github "kmein" "poetry";
quotes = github "kmein" "quotes";
sphinx = github "kmein" "sphinx";
stockholm = git "https://cgit.krebsco.de/stockholm";
telebots = github "kmein" "telebots";
traadfri = github "kmein" "traadfri";
wissen = github "kmein" "wissen";
zen = github "kmein" "zen";
});
programs.git = { programs.git = {
enable = true; enable = true;
package = pkgs.gitAndTools.gitFull; package = pkgs.gitAndTools.gitFull;
@@ -78,25 +46,13 @@ in
pull.ff = "only"; pull.ff = "only";
rebase.autoStash = true; rebase.autoStash = true;
merge.autoStash = true; merge.autoStash = true;
core.pager =
"${pkgs.gitAndTools.diff-so-fancy}/bin/diff-so-fancy | ${pkgs.less}/bin/less --tabs=4 -RFX"; # ref https://github.com/dandavison/delta
color = { core.pager = "${pkgs.delta}/bin/delta";
ui = true; interactive.diffFilter = "${pkgs.delta}/bin/delta --color-only";
diff = { delta.navigate = true;
meta = "11"; merge.conflictStyle = "diff3";
frag = "magenta bold"; diff.colorMoved = "default";
commit = "yellow bold";
old = "red bold";
new = "green bold";
whitespace = "red reverse";
};
diff-highlight = {
oldNormal = "red bold";
oldHighlight = "red bold 52";
newNormal = "green bold";
newHighlight = "green bold 22";
};
};
}; };
}; };
}; };

View File

@@ -14,7 +14,7 @@ let
"username=meinhaki" "username=meinhaki"
"password=${lib.strings.fileContents <secrets/mail/meinhaki>}" "password=${lib.strings.fileContents <secrets/mail/meinhaki>}"
"noauto" "noauto"
"x-systemd.requires=openvpn-hu-berlin.service" "x-systemd.requires=hu-vpn.service"
"x-systemd.automount" "x-systemd.automount"
"x-systemd.device-timeout=1" "x-systemd.device-timeout=1"
"x-systemd.idle-timeout=1min" "x-systemd.idle-timeout=1min"
@@ -67,7 +67,7 @@ in {
host = forti-ssl.vpn.hu-berlin.de host = forti-ssl.vpn.hu-berlin.de
port = 443 port = 443
trusted-cert = 42193a913d276d9eb86217612956e1e6464d6f07bed5393a4787c87adc4bd359 trusted-cert = 42193a913d276d9eb86217612956e1e6464d6f07bed5393a4787c87adc4bd359
username = ${eduroam.identity} username = ${eduroam.identity}@split_tunnel
password = ${eduroam.password} password = ${eduroam.password}
''} ''}
''; '';

View File

@@ -205,14 +205,12 @@ in {
"${modifier}+0" = "exec ${pkgs.scripts.menu-calc}/bin/="; "${modifier}+0" = "exec ${pkgs.scripts.menu-calc}/bin/=";
"${modifier}+Shift+w" = "exec ${pkgs.scripts.k-lock}/bin/k-lock"; "${modifier}+Shift+w" = "exec ${pkgs.scripts.k-lock}/bin/k-lock";
"${modifier}+a" = "${modifier}+d" = "exec ${pkgs.writers.writeDash "run" ''exec ${pkgs.rofi}/bin/rofi -modi run,window,ssh,filebrowser -show run''}";
"exec --no-startup-id ${pkgs.rofi}/bin/rofi -display-window -show window";
"${modifier}+d" = "exec --no-startup-id ${pkgs.dmenu}/bin/dmenu_run";
"${modifier}+Shift+d" = "exec ${ "${modifier}+Shift+d" = "exec ${
pkgs.writers.writeDash "notemenu" '' pkgs.writers.writeDash "notemenu" ''
set -efu set -efu
PATH=$PATH:${ PATH=$PATH:${
lib.makeBinPath [ pkgs.dmenu pkgs.findutils pkgs.coreutils ] lib.makeBinPath [ pkgs.rofi pkgs.findutils pkgs.coreutils ]
} }
cd ~/notes cd ~/notes
@@ -220,7 +218,7 @@ in {
echo diary/$(date -I).md echo diary/$(date -I).md
echo diary/$(date -I -d yesterday).md echo diary/$(date -I -d yesterday).md
find . -type f -printf "%T@ %p\n" | sort --reverse --numeric-sort | cut --delimiter=" " --fields=2 find . -type f -printf "%T@ %p\n" | sort --reverse --numeric-sort | cut --delimiter=" " --fields=2
} | dmenu -i) } | rofi -dmenu -i -p 'notes')
if test "$note_file" if test "$note_file"
then then
i3-sensible-terminal -e "$EDITOR" "$note_file" i3-sensible-terminal -e "$EDITOR" "$note_file"

View File

@@ -2,8 +2,8 @@
let commaSep = builtins.concatStringsSep ","; let commaSep = builtins.concatStringsSep ",";
in { in {
services.xserver = { services.xserver = {
layout = commaSep [ "de" "gr" "ru" ]; layout = commaSep [ "de" "gr" ];
xkbVariant = commaSep [ "T3" "polytonic" "phonetic" ]; xkbVariant = commaSep [ "T3" "polytonic" ];
xkbOptions = xkbOptions =
commaSep [ "compose:caps" "terminate:ctrl_alt_bksp" "grp:ctrls_toggle" ]; commaSep [ "compose:caps" "terminate:ctrl_alt_bksp" "grp:ctrls_toggle" ];
libinput.enable = true; libinput.enable = true;

View File

@@ -1,6 +1,5 @@
{ pkgs, lib, ... }: let { pkgs, lib, ... }: let
swallow = command: "${pkgs.scripts.swallow}/bin/swallow ${command}"; swallow = command: "${pkgs.scripts.swallow}/bin/swallow ${command}";
nixpkgs-unstable = import <nixpkgs-unstable> { config.allowUnfree = true; };
in { in {
environment.shellAliases.smpv = swallow "mpv"; environment.shellAliases.smpv = swallow "mpv";
@@ -22,7 +21,7 @@ in {
"Alt+j" = "add video-pan-y -0.05"; "Alt+j" = "add video-pan-y -0.05";
}; };
scripts = [ scripts = [
nixpkgs-unstable.mpvScripts.youtube-quality pkgs.mpvScripts.youtube-quality
]; ];
}; };
}; };

View File

@@ -118,6 +118,7 @@ in {
inkscape inkscape
astrolog astrolog
anki # flashcards anki # flashcards
jbofihe # lojbanic software
nixpkgs-unstable.zoom-us # video conferencing nixpkgs-unstable.zoom-us # video conferencing
pdfgrep # search in pdf pdfgrep # search in pdf
pdftk # pdf toolkit pdftk # pdf toolkit
@@ -165,17 +166,16 @@ in {
scripts.vg scripts.vg
scripts.fkill scripts.fkill
scripts.wttr scripts.wttr
scripts.sanskrit-dictionary
scripts.unicodmenu scripts.unicodmenu
scripts.horoscope scripts.horoscope
scripts.closest scripts.closest
scripts.trans scripts.trans
scripts.liddel-scott-jones
scripts.mpv-radio scripts.mpv-radio
# kmein.slide # kmein.slide
scripts.tolino-screensaver scripts.tolino-screensaver
scripts.rfc scripts.rfc
scripts.tag scripts.tag
scripts.timer
python3Packages.eyeD3 python3Packages.eyeD3
scripts.menu-calc scripts.menu-calc
nix-prefetch-git nix-prefetch-git
@@ -197,7 +197,7 @@ in {
(pkgs.writers.writeDashBin "ncmpcpp-zaatar" ''MPD_HOST=${(import <niveum/lib/local-network.nix>).zaatar} exec ${pkgs.ncmpcpp}/bin/ncmpcpp "$@"'') (pkgs.writers.writeDashBin "ncmpcpp-zaatar" ''MPD_HOST=${(import <niveum/lib/local-network.nix>).zaatar} exec ${pkgs.ncmpcpp}/bin/ncmpcpp "$@"'')
(pkgs.writers.writeDashBin "mpc-zaatar" ''MPD_HOST=${(import <niveum/lib/local-network.nix>).zaatar} exec ${pkgs.mpc_cli}/bin/mpc "$@"'') (pkgs.writers.writeDashBin "mpc-zaatar" ''MPD_HOST=${(import <niveum/lib/local-network.nix>).zaatar} exec ${pkgs.mpc_cli}/bin/mpc "$@"'')
nixpkgs-unstable.spotify spotify
ncspot ncspot
playerctl playerctl

13
configs/polkit.nix Normal file
View File

@@ -0,0 +1,13 @@
{ config, ... }:
let
user = config.users.users.me.name;
in
{
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.user == "${user}" && action.id == "org.freedesktop.systemd1.manage-units") {
return polkit.Result.YES;
}
});
'';
}

View File

@@ -1,9 +1,10 @@
{ config, ... }: { config, pkgs, ... }:
let let
inherit (import <niveum/lib>) colours; inherit (import <niveum/lib>) colours;
in{ in{
home-manager.users.me.programs.rofi = { home-manager.users.me.programs.rofi = {
enable = true; enable = true;
font = "Monospace 10"; font = "Monospace 10";
theme = "${pkgs.rofi}/share/rofi/themes/Arc-Dark.rasi";
}; };
} }

View File

@@ -1,6 +1,24 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
dictionaries = { dictionaries = {
lojban = {
jbo-deu = pkgs.fetchzip {
url = "https://guskant.github.io/lojbo/stardict/jbo-deu-20160110.tar.gz";
sha256 = "18ia15wyvd8ksi7yxn939qmvpdlrip8mvfywafv7vjj685rdhk80";
};
rafsi-jbo = pkgs.fetchzip {
url = "https://guskant.github.io/lojbo/stardict/rafsi-jbo-20160110.tar.gz";
sha256 = "00fkw964b48liz1jayfjb5jnpwihghkq4i28y8i11yqb56w6bn3c";
};
jbo-eng = pkgs.fetchzip {
url = "https://guskant.github.io/lojbo/stardict/jbo-eng-20160110.tar.gz";
sha256 = "15l65yshqdp0a7fr4a7ffwx3m2v6ymchxgra9zmk5bsgcxsb4r8m";
};
jbo-jbo = pkgs.fetchzip {
url = "https://guskant.github.io/lojbo/stardict/jbo-jbo-20160110.tar.gz";
sha256 = "1psfyrjrq84prr2s4jcm31ijykm7clyqygmbacr09n570xfwqcfw";
};
};
classics = { classics = {
Pape = pkgs.fetchzip { Pape = pkgs.fetchzip {
url = "http://tovotu.de/data/stardict/pape_gr-de.zip"; url = "http://tovotu.de/data/stardict/pape_gr-de.zip";
@@ -45,88 +63,91 @@ let
url = "http://tovotu.de/data/stardict/etymonline.zip"; url = "http://tovotu.de/data/stardict/etymonline.zip";
sha256 = "1bjja3n3layfd08xa1r0a6375dxh5zi6hlv7chkhgnx800cx7hxn"; sha256 = "1bjja3n3layfd08xa1r0a6375dxh5zi6hlv7chkhgnx800cx7hxn";
}; };
Roget = builtins.fetchTarball { Roget = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Roget_s_II_The_New_Thesaurus_3th_Ed-2.4.2.tar.bz2"; url = "http://download.huzheng.org/bigdict/stardict-Roget_s_II_The_New_Thesaurus_3th_Ed-2.4.2.tar.bz2";
sha256 = "1szyny9497bpyyccf9l5kr3bnw0wvl4cnsd0n1zscxpyzlsrqqbz"; sha256 = "1szyny9497bpyyccf9l5kr3bnw0wvl4cnsd0n1zscxpyzlsrqqbz";
}; };
JargonFile = builtins.fetchTarball { JargonFile = pkgs.fetchzip {
url = "http://download.huzheng.org/dict.org/stardict-dictd-jargon-2.4.2.tar.bz2"; url = "http://download.huzheng.org/dict.org/stardict-dictd-jargon-2.4.2.tar.bz2";
sha256 = "096phar9qpmm0fnaqv5nz8x9lpxwnfj78g4vjfcfyd7kqp7iqla4"; sha256 = "096phar9qpmm0fnaqv5nz8x9lpxwnfj78g4vjfcfyd7kqp7iqla4";
}; };
Oxford-Collocations = builtins.fetchTarball { Oxford-Collocations = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Oxford_Collocations_Dictionary_2nd_Ed-2.4.2.tar.bz2"; url = "http://download.huzheng.org/bigdict/stardict-Oxford_Collocations_Dictionary_2nd_Ed-2.4.2.tar.bz2";
sha256 = "1zkfs0zxkcn21z2lhcabrs77v4ma9hpv7qm119hpyi1d8ajcw07q"; sha256 = "1zkfs0zxkcn21z2lhcabrs77v4ma9hpv7qm119hpyi1d8ajcw07q";
}; };
Langenscheidt-Deu-En = builtins.fetchTarball { Langenscheidt-Deu-En = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Handw_rterbuch_Deutsch_Englisc-2.4.2.tar.bz2"; url = "http://download.huzheng.org/babylon/german/stardict-Handw_rterbuch_Deutsch_Englisc-2.4.2.tar.bz2";
sha256 = "12q9i5azq7ylyrpb6jqbaf1rxalc3kzcwjvbinvb0yabdxb80y30"; sha256 = "12q9i5azq7ylyrpb6jqbaf1rxalc3kzcwjvbinvb0yabdxb80y30";
}; };
Langenscheidt-En-Deu = builtins.fetchTarball { Langenscheidt-En-Deu = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Handw_rterbuch_Englisch_Deutsc-2.4.2.tar.bz2"; url = "http://download.huzheng.org/babylon/german/stardict-Handw_rterbuch_Englisch_Deutsc-2.4.2.tar.bz2";
sha256 = "087b05h155j5ldshfgx91pz81h6ijq2zaqjirg7ma8ig3l96zb59"; sha256 = "087b05h155j5ldshfgx91pz81h6ijq2zaqjirg7ma8ig3l96zb59";
}; };
Duden_Das_Fremdworterbuch = builtins.fetchTarball { Duden_Das_Fremdworterbuch = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_Das_Fremdworterbuch-2.4.2.tar.bz2"; url = "http://download.huzheng.org/babylon/german/stardict-Duden_Das_Fremdworterbuch-2.4.2.tar.bz2";
sha256 = "1zrcay54ccl031s6dvjwsah5slhanmjab87d81rxlcy8fx0xd8wq"; sha256 = "1zrcay54ccl031s6dvjwsah5slhanmjab87d81rxlcy8fx0xd8wq";
}; };
Duden_De_De = builtins.fetchTarball { Duden_De_De = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_De_De-2.4.2.tar.bz2"; url = "http://download.huzheng.org/babylon/german/stardict-Duden_De_De-2.4.2.tar.bz2";
sha256 = "1fhay04w5aaj83axfmla2ql34nb60gb05dgv0k94ig7p8x4yxxlf"; sha256 = "1fhay04w5aaj83axfmla2ql34nb60gb05dgv0k94ig7p8x4yxxlf";
}; };
ConciseOED = builtins.fetchTarball { ConciseOED = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Concise_Oxford_English_Dictionary-2.4.2.tar.bz2"; url = "http://download.huzheng.org/bigdict/stardict-Concise_Oxford_English_Dictionary-2.4.2.tar.bz2";
sha256 = "19kpcxbhqzpmhi94mp48nalgmsh6s7rsx1gb4kwkhirp2pbjcyl7"; sha256 = "19kpcxbhqzpmhi94mp48nalgmsh6s7rsx1gb4kwkhirp2pbjcyl7";
}; };
# Duden_Rechtschreibung = builtins.fetchTarball { Duden_Synonym = pkgs.fetchzip {
# url = "http://download.huzheng.org/babylon/german/stardict-Duden_Rechtschreibung-2.4.2.tar.bz2";
# sha256 = "0xiprb45s88w62rn8rlbjrsagbiliay9hszsiy20glwabf6zsfji";
# };
Duden_Synonym = builtins.fetchTarball {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_Synonym-2.4.2.tar.bz2"; url = "http://download.huzheng.org/babylon/german/stardict-Duden_Synonym-2.4.2.tar.bz2";
sha256 = "0cx086zvb86bmz7i8vnsch4cj4fb0cp165g4hig4982zakj6f2jd"; sha256 = "0cx086zvb86bmz7i8vnsch4cj4fb0cp165g4hig4982zakj6f2jd";
}; };
# Duden = builtins.fetchTarball {
# url = "http://download.huzheng.org/de/stardict-duden-2.4.2.tar.bz2";
# sha256 = "049i4ynfqqxykv1nlkyks94mvn14s22qdax5gg7hx1ks5y4xw64j";
# };
# FreeOnlineDictionaryOfComputing = builtins.fetchTarball {
# url = "http://download.huzheng.org/dict.org/stardict-dictd_www.dict.org_foldoc-2.4.2.tar.bz2";
# sha256 = "1lw2i8dzxpx929cpgvv0x366dnh4drr10wzqmrhcd0kvwglqawgm";
# };
}; };
sanskrit = { sanskrit = let repo = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f"; in {
BoehtlingkRoth = pkgs.fetchzip { BoehtlingkRoth = pkgs.fetchzip {
url = "https://c.krebsco.de/Bohtlingk-and-Roth-Grosses-Petersburger-Worterbuch.zip"; url = "${repo}/sa-head/german-entries/tars/Bohtlingk-and-Roth-Grosses-Petersburger-Worterbuch__2021-10-05_14-23-18Z__19MB.tar.gz";
sha256 = "13414a8rgd7hd5ffar6nl68nk3ys60wjkgb7m11hp0ahaasmf6ly"; sha256 = "13414a8rgd7hd5ffar6nl68nk3ys60wjkgb7m11hp0ahaasmf6ly";
stripRoot = false; stripRoot = false;
}; };
BoehtlingkRothKurz = pkgs.fetchzip {
url = "${repo}/sa-head/german-entries/tars/Bohtlingk-Sanskrit-Worterbuch-in-kurzerer-Fassung__2021-10-05_14-23-18Z__10MB.tar.gz";
sha256 = "15yx31yrk40k9nn6kaysp4pprzj8dpd13dj3wafklc3izm8lr2wq";
stripRoot = false;
};
MonierWilliams = pkgs.fetchzip { MonierWilliams = pkgs.fetchzip {
url = "https://c.krebsco.de/mw-cologne.zip"; url = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f/sa-head/en-entries/tars/mw-cologne__2021-10-06_00-16-23Z__16MB.tar.gz";
sha256 = "0p99ybxwxmmd94hf035hvm2hhnfy84av7qq79xf28bh2rbx6s9ng"; sha256 = "0p99ybxwxmmd94hf035hvm2hhnfy84av7qq79xf28bh2rbx6s9ng";
stripRoot = false; stripRoot = false;
}; };
MonierWilliamsEnglish = pkgs.fetchzip { MonierWilliamsEnglish = pkgs.fetchzip {
url = "https://c.krebsco.de/mw-english-sanskrit.zip"; url = "${repo}/en-head/tars/mw-english-sanskrit__2021-10-05_14-23-18Z__3MB.tar.gz";
sha256 = "09a61hhii4b1m2fkrlh4rm2xnlgwrllh84iypbc6wyj00w9jkl3x"; sha256 = "09a61hhii4b1m2fkrlh4rm2xnlgwrllh84iypbc6wyj00w9jkl3x";
stripRoot = false; stripRoot = false;
}; };
Borooah = pkgs.fetchzip {
url = "${repo}/en-head/tars/borooah__2021-10-05_14-23-18Z__2MB.tar.gz";
sha256 = "0qmmfbynqgv125v48383i51ky9yi69zibhh7vwk95gyar2yrprn2";
stripRoot = false;
};
ApteEnglish = pkgs.fetchzip {
url = "${repo}/en-head/tars/apte-english-sanskrit-cologne__2021-10-06_00-12-51Z__1MB.tar.gz";
sha256 = "064ysm24ydc534ca689y5i2flnra8jkmh8zn0gsb6n8hdsb0d1lq";
stripRoot = false;
};
}; };
oed = { oed = {
OED1 = builtins.fetchTarball { OED1 = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Oxford_English_Dictionary_2nd_Ed._P1-2.4.2.tar.bz2"; url = "http://download.huzheng.org/bigdict/stardict-Oxford_English_Dictionary_2nd_Ed._P1-2.4.2.tar.bz2";
sha256 = "0i5vv1rv44yfwyf9bfbdrb9brzhhpvz2jnh39fv8hh107nkv2vcf"; sha256 = "0i5vv1rv44yfwyf9bfbdrb9brzhhpvz2jnh39fv8hh107nkv2vcf";
}; };
OED2 = builtins.fetchTarball { OED2 = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Oxford_English_Dictionary_2nd_Ed._P2-2.4.2.tar.bz2"; url = "http://download.huzheng.org/bigdict/stardict-Oxford_English_Dictionary_2nd_Ed._P2-2.4.2.tar.bz2";
sha256 = "1pk234pbq4pk55d8sjk0pp9j5sajm82f8804kf2xm2x5p387q1rg"; sha256 = "1pk234pbq4pk55d8sjk0pp9j5sajm82f8804kf2xm2x5p387q1rg";
}; };
}; };
russian = { russian = {
LingvoGermanRussian = builtins.fetchTarball { LingvoGermanRussian = pkgs.fetchzip {
url = "http://download.huzheng.org/lingvo/stardict-GR-LingvoUniversal-2.4.2.tar.bz2"; url = "http://download.huzheng.org/lingvo/stardict-GR-LingvoUniversal-2.4.2.tar.bz2";
sha256 = "0p353gs2z4vj70hqsdhffjaaw3a4zlmcs46flipmf35lm5wmaj0g"; sha256 = "0p353gs2z4vj70hqsdhffjaaw3a4zlmcs46flipmf35lm5wmaj0g";
}; };
LingvoRussianGerman = builtins.fetchTarball { LingvoRussianGerman = pkgs.fetchzip {
url = "http://download.huzheng.org/lingvo/stardict-RG-LingvoUniversal-2.4.2.tar.bz2"; url = "http://download.huzheng.org/lingvo/stardict-RG-LingvoUniversal-2.4.2.tar.bz2";
sha256 = "03f9wdmkgpjifpms7dyh10ma29wf3ka1j3zlp1av0cybhdldk2a8"; sha256 = "03f9wdmkgpjifpms7dyh10ma29wf3ka1j3zlp1av0cybhdldk2a8";
}; };
@@ -138,16 +159,16 @@ let
makeStardict = name: dicts: pkgs.writers.writeDashBin name '' makeStardict = name: dicts: pkgs.writers.writeDashBin name ''
set -efu set -efu
export SDCV_PAGER=${toString sdcvPager} export SDCV_PAGER=${toString sdcvPager}
exec ${pkgs.sdcv}/bin/sdcv --only-data-dir --data-dir ${makeStardictDataDir dicts} "$@" exec ${pkgs.sdcv}/bin/sdcv --color --only-data-dir --data-dir ${makeStardictDataDir dicts} "$@"
''; '';
sdcvPager = pkgs.writeDash "sdcvPager" '' sdcvPager = pkgs.writeDash "sdcvPager" ''
export PATH=${lib.makeBinPath [pkgs.gnused pkgs.ncurses pkgs.less]} export PATH=${lib.makeBinPath [pkgs.gnused pkgs.ncurses pkgs.less]}
sed " sed "
s!<sup>1</sup>!¹!g s!<sup>1</sup>!¹!gI
s!<sup>2</sup>!²!g s!<sup>2</sup>!²!gI
s!<sup>3</sup>!³!g s!<sup>3</sup>!³!gI
s!<sup>4</sup>!!g s!<sup>4</sup>!!gI
s! style=\"color: #...\"!!g; s! style=\"color: #...\"!!g;
s!<span class=\"zenoTXSpaced\">\([^<>]*\)</span>!\1!g; s!<span class=\"zenoTXSpaced\">\([^<>]*\)</span>!\1!g;
s!</\?dictionary[^>]*>!!g; s!</\?dictionary[^>]*>!!g;
@@ -170,6 +191,8 @@ let
s!</\?pron[^>]*>!!g s!</\?pron[^>]*>!!g
s!</\?gen[^>]*>!!g s!</\?gen[^>]*>!!g
s!</\?tns[^>]*>!!g s!</\?tns[^>]*>!!g
s!</\?per[^>]*>!!g
s!</\?blockquote[^>]*>!!g
s!</\?etym[^>]*>!!g s!</\?etym[^>]*>!!g
s!<foreign[^>]*>!$(tput sitm)!g s!<foreign[^>]*>!$(tput sitm)!g
s!</foreign[^>]*>!$(tput sgr0)!g s!</foreign[^>]*>!$(tput sgr0)!g
@@ -179,6 +202,7 @@ let
s!</\?p>!!g s!</\?p>!!g
s!<input[^>]*>!!g s!<input[^>]*>!!g
s!</\?orth[^>]*>!!g s!</\?orth[^>]*>!!g
s!</\?number[^>]*>!!g
s!</\?forename[^>]*>!!g s!</\?forename[^>]*>!!g
s!</\?persName[^>]*>!!g s!</\?persName[^>]*>!!g
s!</\?surname[^>]*>!!g s!</\?surname[^>]*>!!g
@@ -187,20 +211,23 @@ let
s!</\?cit[^>]*>!!g s!</\?cit[^>]*>!!g
s!</\?pos[^>]*>!!g s!</\?pos[^>]*>!!g
s!</\?usg[^>]*>!!g s!</\?usg[^>]*>!!g
s!</\?span>!!g s!</\?ul>!!g
s!<li>!\n!g
s!</li>!!g
s!<bibl[^>]*>!$(tput setaf 245)!g s!<bibl[^>]*>!$(tput setaf 245)!g
s!</bibl[^>]*>!$(tput sgr0)!g s!</bibl[^>]*>!$(tput sgr0)!g
s/<dt>/$(tput bold)/g; s/<dt>/$(tput bold)/g;
s:</dt>:$(tput sgr0):g; s:</dt>:$(tput sgr0):g;
s/<dd>/\n/g; s/<dd>/\n/g;
s:</dd>::g; s:</dd>::g;
s/<[bB]>/$(tput bold)/g; s:<script>.*</script>::g;
s:</[bB]>:$(tput sgr0):g; s/<b>/$(tput bold)/gI;
s:<[bB][rR]\s*/\?>:\n:g; s:</b>:$(tput sgr0):gI;
s:<[iI]>:$(tput sitm):g; s:<br\s*/\?>:\n:gI;
s:</[iI]>:$(tput sgr0):g; s:<i>:$(tput sitm):gI;
s:<[uU]>:$(tput smul):g; s:</i>:$(tput sgr0):gI;
s:</[uU]>:$(tput sgr0):g; s:<u>:$(tput smul):gI;
s:</u>:$(tput sgr0):gI;
s:<FONT face=[^>]*>::g; s:<FONT face=[^>]*>::g;
s:</FONT>::g; s:</FONT>::g;
s!<head>\([^<>]*\)</head>!$(tput bold)\1$(tput sgr0)!g; s!<head>\([^<>]*\)</head>!$(tput bold)\1$(tput sgr0)!g;
@@ -222,13 +249,12 @@ let
s:<IMG src=\"223E9A06.bmp\"[^>]*>:ː:g; s:<IMG src=\"223E9A06.bmp\"[^>]*>:ː:g;
s:<IMG src=\"502F5DDA.bmp\"[^>]*>::g; s:<IMG src=\"502F5DDA.bmp\"[^>]*>::g;
s:<IMG src=\"8DAD7054.bmp\"[^>]*>:n̩:g s:<IMG src=\"8DAD7054.bmp\"[^>]*>:n̩:g
s!</\?TABLE>!!g s!</\?TABLE>!!gI
s!</\?TR[^>]*>!!g s!</\?TR[^>]*>!!gI
s!</\?TD>!!g s!</\?TD>!!gI
s!</\?FONT[^>]*>!!g s!</\?FONT[^>]*>!!gI
s!</\?A[^>]*>!!g s!</\?A[^>]*>!!gI
s!<SPAN class=\"bsptext\">\([^<>]*\)</SPAN>!$(tput setaf 245)\1$(tput sgr0)!g s!<SPAN class=\"bsptext\">\([^<>]*\)</SPAN>!$(tput setaf 245)\1$(tput sgr0)!g
s!</\?SPAN[^>]*>!!g
s! +! !g; s! +! !g;
s!<div part=\"[^\"]*\">!\n\n&!g s!<div part=\"[^\"]*\">!\n\n&!g
s!<sense n=\"\([^\"]*\)\"!\n$(tput setaf 5)\1.$(tput sgr0) &!g; s!<sense n=\"\([^\"]*\)\"!\n$(tput setaf 5)\1.$(tput sgr0) &!g;
@@ -236,19 +262,14 @@ let
s!</\?div[^>]*>!!g s!</\?div[^>]*>!!g
s!<span lang=\"gr\">!!g # unbalanced in Frisk s!<span lang=\"gr\">!!g # unbalanced in Frisk
s!^\s*[0-9])!$(tput setaf 5)&$(tput sgr0)!g s!^\s*[0-9])!$(tput setaf 5)&$(tput sgr0)!g
s#^\(-->.*\)\$#$(tput bold)\1$(tput sgr0)# s!</\?span[^>]*>!!gI
s!</\?p[^>]*>!!gI
" | less -FR " | less -FR
''; '';
in in
{ {
# https://github.com/latin-dict/Georges1910/releases/download/v1.0/Georges1910-stardict.zip
# https://github.com/nikita-moor/latin-dictionary/releases/download/2020-02-14/LiddellScott1940-stardict.zip
# http://download.huzheng.org/bigdict/stardict-Cambridge_Dictionary_of_American_Idioms-2.4.2.tar.bz2
# http://download.huzheng.org/bigdict/stardict-Concise_Oxford_Thesaurus_2nd_Ed-2.4.2.tar.bz2
# http://download.huzheng.org/bigdict/stardict-Urban_Dictionary_P1-2.4.2.tar.bz2
# http://download.huzheng.org/bigdict/stardict-Urban_Dictionary_P2-2.4.2.tar.bz2
environment.etc.stardict.source = toString (makeStardictDataDir ({ environment.etc.stardict.source = toString (makeStardictDataDir ({
Crum = builtins.fetchTarball { Crum = pkgs.fetchzip {
url = "http://download.huzheng.org/misc/stardict-Coptic-English_all_dialects-2.4.2.tar.bz2"; url = "http://download.huzheng.org/misc/stardict-Coptic-English_all_dialects-2.4.2.tar.bz2";
sha256 = "1fi281mb9yzv40wjsdapi8fzpa7x2yscz582lv2qnss9g8zzzzr9"; sha256 = "1fi281mb9yzv40wjsdapi8fzpa7x2yscz582lv2qnss9g8zzzzr9";
}; };
@@ -264,10 +285,73 @@ in
environment.systemPackages = [ environment.systemPackages = [
pkgs.goldendict pkgs.goldendict
(makeStardict "sd-classics" dictionaries.classics) (makeStardict "lsj" dictionaries.classics)
(makeStardict "sd-sanskrit" dictionaries.sanskrit) (makeStardict "sa" dictionaries.sanskrit)
(makeStardict "sd-oed" dictionaries.oed) (makeStardict "oed" dictionaries.oed)
(makeStardict "sd-russian" dictionaries.russian) (makeStardict "sd-russian" dictionaries.russian)
(makeStardict "sd" dictionaries.englishGerman) (makeStardict "sd" dictionaries.englishGerman)
(makeStardict "jbo" dictionaries.lojban)
]; ];
} }
/*
https://github.com/latin-dict/Georges1910/releases/download/v1.0/Georges1910-stardict.zip
https://github.com/nikita-moor/latin-dictionary/releases/download/2020-02-14/LiddellScott1940-stardict.zip
http://download.huzheng.org/bigdict/stardict-Cambridge_Dictionary_of_American_Idioms-2.4.2.tar.bz2
http://download.huzheng.org/bigdict/stardict-Concise_Oxford_Thesaurus_2nd_Ed-2.4.2.tar.bz2
http://download.huzheng.org/bigdict/stardict-Urban_Dictionary_P1-2.4.2.tar.bz2
http://download.huzheng.org/bigdict/stardict-Urban_Dictionary_P2-2.4.2.tar.bz2
Duden_Rechtschreibung = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_Rechtschreibung-2.4.2.tar.bz2";
sha256 = "0xiprb45s88w62rn8rlbjrsagbiliay9hszsiy20glwabf6zsfji";
};
Duden = pkgs.fetchzip {
url = "http://download.huzheng.org/de/stardict-duden-2.4.2.tar.bz2";
sha256 = "049i4ynfqqxykv1nlkyks94mvn14s22qdax5gg7hx1ks5y4xw64j";
};
FreeOnlineDictionaryOfComputing = pkgs.fetchzip {
url = "http://download.huzheng.org/dict.org/stardict-dictd_www.dict.org_foldoc-2.4.2.tar.bz2";
sha256 = "1lw2i8dzxpx929cpgvv0x366dnh4drr10wzqmrhcd0kvwglqawgm";
};
Cappeller = pkgs.fetchzip {
url = "${repo}/sa-head/german-entries/tars/capeller-sanskrit-german__2021-10-05_14-23-18Z__1MB.tar.gz";
sha256 = "0jwrj2aih2lrcjg0lqm8jrvq9vsas9s8j4c9ggbg2n0jyz03kci3";
stripRoot = false;
};
Yates = pkgs.fetchzip {
url = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f/sa-head/en-entries/tars/yates__2021-10-05_14-23-18Z__2MB.tar.gz";
sha256 = "1k7gbalysf48pwa06zfykrqhdk466g35xy64b30k4z8bybgdn8z2";
stripRoot = false;
};
Wilson = pkgs.fetchzip {
url = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f/sa-head/en-entries/tars/wilson__2021-10-05_14-23-18Z__3MB.tar.gz";
sha256 = "0r5z1xif56zlw9r2jp3fvwmcjv4f2fhd9r17j30nah9awx2m1isg";
stripRoot = false;
};
SpokenSanskrit = pkgs.fetchzip {
url = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f/sa-head/en-entries/tars/spokensanskrit__2019-01-12_05-13-52Z__12MB.tar.gz";
sha256 = "0x8j657mawvdcyd1knzvf33yp15z77d661n3h6g9hcj7wn9s5xyk";
stripRoot = false;
};
Grassmann = pkgs.fetchzip {
url = "${repo}/sa-head/german-entries/tars/grassman-sanskrit-german__2021-10-05_14-23-18Z__2MB.tar.gz";
sha256 = "0jalsykaxkl6wzrky72lz8g3jdz26lmjpyibbfaf7a5vvnr55k02";
stripRoot = false;
};
Benfey = pkgs.fetchzip {
url = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f/sa-head/en-entries/tars/benfey__2021-10-05_14-23-18Z__2MB.tar.gz";
sha256 = "0lj3hgphqgnihn482g9kgjwbvdrcd38vc29v1fi36srn08qdhvcb";
stripRoot = false;
};
ApteSa = pkgs.fetchzip {
url = "${repo}/sa-head/en-entries/tars/apte-sa__2021-12-18_13-20-56Z__6MB.tar.gz";
sha256 = "0cq1dd02d1pvmjnibbs2cscifjnk2z0nqccf5yzzilxkzsrarh32";
stripRoot = false;
};
MacDonell = pkgs.fetchzip {
url = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f/sa-head/en-entries/tars/macdonell__2021-10-05_14-23-18Z__2MB.tar.gz";
sha256 = "1yzmj0393mxvjv4n2lnvd2c722v2bmxxiyq7pscdwni3bxip3h8s";
stripRoot = false;
};
*/

View File

@@ -29,7 +29,7 @@ in
bedroom = 131082; bedroom = 131082;
living-room = living-room-id; living-room = living-room-id;
bedside = 131087; bedside = 131087;
chain = 131089;
}; };
bulbs.kette = 65570;
}; };
} }

View File

@@ -2,17 +2,5 @@
{ {
environment.systemPackages = [ pkgs.watson ]; environment.systemPackages = [ pkgs.watson ];
home-manager.users.me.xdg.configFile."watson/config".text = '' environment.variables.WATSON_DIR = "${config.users.users.me.home}/cloud/Seafile/Documents/watson";
[options]
confirm_new_project = true
confirm_new_tag = true
date_format = %Y-%m-%d
log_current = true
report_current = true
'';
system.activationScripts.watson-home = ''
ln -sfn ${config.users.users.me.home}/cloud/Seafile/Documents/watson/frames ${config.users.users.me.home}/.config/watson/frames
ln -sfn ${config.users.users.me.home}/cloud/Seafile/Documents/watson/state ${config.users.users.me.home}/.config/watson/state
'';
} }

46
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": { "nodes": {
"flake-utils": { "flake-utils": {
"locked": { "locked": {
"lastModified": 1638122382, "lastModified": 1644229661,
"narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=", "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "74f7e4319258e287b0f9cb95426c9853b282730b", "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -22,11 +22,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1639871969, "lastModified": 1643933536,
"narHash": "sha256-6feWUnMygRzA9tzkrfAzpA5/NBYg75bkFxnqb1DtD7E=", "narHash": "sha256-yRmsWAG4DnLxLIUtlaZsl0kH7rN5xSoyNRlf0YZrcH4=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "697cc8c68ed6a606296efbbe9614c32537078756", "rev": "2860d7e3bb350f18f7477858f3513f9798896831",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -46,11 +46,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1632420452, "lastModified": 1644957911,
"narHash": "sha256-ncK6vABW/Ku9XI0kqj1otarUfblryoQzSaOCnaZ0oSs=", "narHash": "sha256-ggie/j7pdBqzDs4W7OiPmhqH9IGbXAbJxGqBdVxA8jA=",
"owner": "Mic92", "owner": "Mic92",
"repo": "krops", "repo": "krops",
"rev": "0388970c568905fedcbf429e5745aacd4f7a6633", "rev": "86fb3d2ee94fd8306231853b323ed8804edf26ec",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -109,27 +109,27 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1641829252, "lastModified": 1644837400,
"narHash": "sha256-CI0qi7k1Y4nFna+kdQtVCbN4ZEVwZcD/oIGgfTcUNrA=", "narHash": "sha256-treFS89w/xKzeTjJSJdYp/Ceddv6oqq7bL9mZMQDPi0=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5d3420c1285073d5061a5d88a533b347d1222750", "rev": "a03ae0e6d078cfdbb8404c3bff3622bd4e2f1c57",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "release-21.11", "ref": "nixos-21.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1641935776, "lastModified": 1644951967,
"narHash": "sha256-8q/V9EgzyW0KvGnBjbTfQ19qoTCFqsEd1mF9DheCukw=", "narHash": "sha256-j+l8bt++dsYTJSGABuqeBEom5aNpD4n0BsOTdewFYuU=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "bd20b7f07fd337b2e85420edd642382a2cc0196d", "rev": "05e1f8a2c7797b0d9f9e07ab2aaeccecdcf9b7da",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -158,11 +158,11 @@
"retiolum": { "retiolum": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1641939337, "lastModified": 1644849126,
"narHash": "sha256-VDVe1VtHM/BdndP2Ta5jRyQaBpdu+Dh250jRS4rfb9A=", "narHash": "sha256-iaRNvfQrUD+ZownDWWNdDwhVPgSsU5ojvVdswVq1IpY=",
"owner": "krebs", "owner": "krebs",
"repo": "retiolum", "repo": "retiolum",
"rev": "4fcbe17549fa742a32e05b5f2ca57a983ad500c1", "rev": "6de359ef848dc1f38fb76731c35e712ee885fd88",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -210,11 +210,11 @@
"stockholm": { "stockholm": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1641747862, "lastModified": 1644865613,
"narHash": "sha256-gAGM3sxCP//k83CUow3ZpeHQCeuW62YJ6kWvWd8D1vk=", "narHash": "sha256-z7hPtMYxoQuWyLujUs5vbdZOGbjFosh+/IX3GpCDlkc=",
"ref": "master", "ref": "master",
"rev": "f67bd5783d6ed2be836c7714ea38cbb3f7ac7257", "rev": "e3785b22b2c6cb173a58fd066c4eda80a67fb872",
"revCount": 10285, "revCount": 10404,
"type": "git", "type": "git",
"url": "https://cgit.lassul.us/stockholm" "url": "https://cgit.lassul.us/stockholm"
}, },

View File

@@ -2,7 +2,7 @@
description = "niveum: packages, modules, systems"; description = "niveum: packages, modules, systems";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/release-21.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/master"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/master";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
home-manager = { home-manager = {
@@ -64,27 +64,7 @@
}; };
} // nixpkgs.lib.mapAttrs' (name: value: { } // nixpkgs.lib.mapAttrs' (name: value: {
inherit name; inherit name;
value.git = { value.file = toString value;
url = {
# having to declare the git upstream urls here is suboptimal, but the inputs don't remember where they're from
home-manager = "https://github.com/nix-community/home-manager";
menstruation-backend = "https://github.com/kmein/menstruation.rs";
menstruation-telegram = "https://github.com/kmein/menstruation-telegram";
nix-writers = "https://cgit.krebsco.de/nix-writers";
nixpkgs = "https://github.com/NixOS/nixpkgs";
nixpkgs-unstable = "https://github.com/NixOS/nixpkgs";
recht = "https://github.com/kmein/recht";
retiolum = "https://github.com/krebs/retiolum";
scripts = "https://github.com/kmein/scripts";
stockholm = "https://cgit.lassul.us/stockholm";
telebots = "https://github.com/kmein/telebots";
tinc-graph = "https://github.com/kmein/tinc-graph";
traadfri = "https://github.com/kmein/traadfri";
tuna = "https://github.com/kmein/tuna";
}.${name};
ref = value.rev;
shallow = true;
};
}) (nixpkgs.lib.filterAttrs (name: _: !builtins.elem name [ "flake-utils" "krops" "self" ]) inputs); }) (nixpkgs.lib.filterAttrs (name: _: !builtins.elem name [ "flake-utils" "krops" "self" ]) inputs);
deployScriptFor = {name, host}: let inherit (import ./lib/default.nix) sshPort; in toString (krops.packages.${system}.writeDeploy "deploy-${name}" { deployScriptFor = {name, host}: let inherit (import ./lib/default.nix) sshPort; in toString (krops.packages.${system}.writeDeploy "deploy-${name}" {
source = krops.lib.evalSource [ (source name) ]; source = krops.lib.evalSource [ (source name) ];

37
lib/colours/ibm-3270.nix Normal file
View File

@@ -0,0 +1,37 @@
rec {
black = {
bright = "#888888";
dark = "#222222";
};
red = {
bright = "#ef8383";
dark = "#f01818";
};
yellow = {
bright = "#efe28b";
dark = "#f8d824";
};
green = {
bright = "#23d830";
dark = "#7ed684";
};
blue = {
bright = "#b3bfef";
dark = "#7890f0";
};
magenta = {
bright = "#efb3e3";
dark = "#f078d8";
};
cyan = {
bright = "#9ce2e2";
dark = "#54e4e4";
};
white = {
bright = "#ffffff";
dark = "#a5a5a5";
};
background = "#000000";
foreground = "#bbbbbb";
cursor = green.bright;
}

View File

@@ -1,6 +1,12 @@
rec { rec {
tmpfilesConfig = {type, path, mode ? "-", user ? "-", group ? "-", age ? "-", argument ? "-"}: "${type} '${path}' ${mode} ${user} ${group} ${age} ${argument}"; tmpfilesConfig = {type, path, mode ? "-", user ? "-", group ? "-", age ? "-", argument ? "-"}: "${type} '${path}' ${mode} ${user} ${group} ${age} ${argument}";
restic = rec {
port = 3571;
host = "zaatar.r";
repository = "rest:http://${host}:${toString port}/";
};
firewall = lib: { firewall = lib: {
accept = { source, protocol, dport }: "nixos-fw -s ${lib.escapeShellArg source} -p ${lib.escapeShellArg protocol} --dport ${lib.escapeShellArg (toString dport)} -j nixos-fw-accept"; accept = { source, protocol, dport }: "nixos-fw -s ${lib.escapeShellArg source} -p ${lib.escapeShellArg protocol} --dport ${lib.escapeShellArg (toString dport)} -j nixos-fw-accept";
addRules = lib.concatMapStringsSep "\n" (rule: "iptables -A ${rule}"); addRules = lib.concatMapStringsSep "\n" (rule: "iptables -A ${rule}");
@@ -15,7 +21,7 @@ rec {
sshPort = 22022; sshPort = 22022;
colours = import ./colours/mac-os.nix; colours = import ./colours/ibm-3270.nix;
theme = pkgs: { theme = pkgs: {
gtk = { gtk = {

View File

@@ -92,12 +92,6 @@ in {
units = "metric"; units = "metric";
}; };
} }
{
block = "custom";
interval = 60 * 5;
command = let inherit (import <niveum/configs/spacetime.nix>) location; in "${pkgs.scripts.horoscope}/bin/horoscope --latitude=${toString location.latitude} --longitude=${toString location.longitude}";
# astrolog -zN Berlin -n -k | tail -n +4 | head -n 7 | sed 's/://g;s/\s\+/ /g;s/ R/R/;s/\[\s*/[/g;s/Sun/☉/;s/Moon/☽/;s/Merc/☿/;s/Venu/♀/;s/Mars/♂/;s/Jupi/♃/;s/Satu/♄/' | cut -f1-2 -d' ' | paste -sd' ' -
}
{ {
block = "custom"; block = "custom";
interval = 60 * 5; interval = 60 * 5;
@@ -129,28 +123,14 @@ in {
} }
{ {
block = "custom"; block = "custom";
interval = 60 * 60; interval = 5;
command = pkgs.writers.writeDash "vax" '' command = pkgs.writers.writeDash "hu-berlin-vpn" ''
${pkgs.curl}/bin/curl -sSL https://api.corona-zahlen.org/vaccinations \ PATH=${lib.makeBinPath [ pkgs.systemd ]}
| ${pkgs.jq}/bin/jq -r '"💉 \(.data.quote * 1000 | floor | . / 10)% \(.data.secondVaccination.quote * 1000 | floor | . / 10)%"' (systemctl is-active --quiet openvpn-hu-berlin.service && echo "🎓👍 (OpenVPN)") \
|| (systemctl is-active --quiet hu-vpn.service && echo "🎓👍 (PPP+SSL)") \
|| echo "🎓👎"
''; '';
} }
(let service = "openvpn-hu-berlin"; in {
block = "custom";
interval = 5;
command = pkgs.writers.writeDash "net-device" ''
PATH=${lib.makeBinPath [ pkgs.systemd ]}
systemctl is-active --quiet ${service}.service && echo "🎓👍" || echo "🎓👎"
'';
on_click = pkgs.writers.writeDash "toggle" ''
PATH=${lib.makeBinPath [ pkgs.systemd pkgs.libnotify ]}
systemctl is-active --quiet ${service}.service && {
systemctl stop ${service}.service && notify-send -a "${service}" stopped
} || {
systemctl start ${service}.service && notify-send -a "${service}" started
}
'';
})
{ {
block = "net"; block = "net";
device = wirelessInterface; device = wirelessInterface;

View File

@@ -6,7 +6,7 @@ let
importJSON = path: builtins.fromJSON (builtins.readFile path); importJSON = path: builtins.fromJSON (builtins.readFile path);
di-fm-name = name: "${name} | DI.FM"; di-fm-name = name: "${name} | DI.FM";
di-fm = name: "http://prem2.di.fm/${name}_hi?${di-fm-key}"; di-fm = name: "http://prem3.di.fm/${name}_hi?${di-fm-key}";
soma-fm-name = name: "${name} | soma.fm"; soma-fm-name = name: "${name} | soma.fm";
soma-fm = name: "http://ice1.somafm.com/${name}-128-aac"; soma-fm = name: "http://ice1.somafm.com/${name}-128-aac";
@@ -50,24 +50,26 @@ in [
desc = "Diminutive from lassus (weary, faint, tired). A programming human. Doing superior professional art."; desc = "Diminutive from lassus (weary, faint, tired). A programming human. Doing superior professional art.";
} }
{ {
stream = "https://cdn.c3voc.de/hls/abchillgleis/segment_Native.m3u8"; station = "C3 Lounge";
station = "RC3 Abchillgleis"; stream = "https://c3lounge.de/radio/8000/radio.mp3";
} }
{ {
stream = "https://cdn.c3voc.de/hls/c3lounge/segment_Native.m3u8"; stream = "https://radio.kmein.de/lyrik.ogg";
station = "RC3 Lounge";
}
{
stream = "https://radio.kmein.de/lyrik/listen.ogg";
station = "Lyrik"; station = "Lyrik";
desc = "Lyrik-Lesung rund um die Uhr."; desc = "Lyrik-Lesung rund um die Uhr.";
} }
{ {
stream = "https://radio.kmein.de/lyrikline/listen.ogg"; stream = "https://radio.kmein.de/lyrikline.ogg";
station = "Lyrikline"; station = "Lyrikline";
logo = "https://www.lyrikline.org/themes/lyrik/svg/Logo_lyrikline_pure.svg"; logo = "https://www.lyrikline.org/themes/lyrik/svg/Logo_lyrikline_pure.svg";
desc = "24/7 zufällige Wiedergaben von lyrikline.org."; desc = "24/7 zufällige Wiedergaben von lyrikline.org.";
} }
{
stream = "https://radio.kmein.de/wikipedia.ogg";
station = "Wikipedia";
desc = "Zufällige Wikipedia-Artikel";
logo = "https://de.wikipedia.org/wiki/Wikipedia:Enzyklop%C3%A4die/Logo_von_Wikipedia#/media/Datei:Wikipedia-logo-v2.svg";
}
{ {
stream = "http://162.244.80.20:6948"; stream = "http://162.244.80.20:6948";
station = "Cool Jazz Florida"; station = "Cool Jazz Florida";
@@ -100,583 +102,491 @@ in [
logo = "http://radio-rb.de/img/site/logo.png"; logo = "http://radio-rb.de/img/site/logo.png";
desc = "Голос нашего города ..."; desc = "Голос нашего города ...";
} }
{
stream = "https://drachenhits.stream.laut.fm/drachenhits";
station = "Drachenhits";
}
] ++ ] ++
# generated via: curl https://radiorecord.ru/api/stations | jq '.result.stations | sort_by(.sort) | map({station:.title,desc:.tooltip,logo:.icon_fill_colored,stream:.stream_320})' > radiorecord.json # generated via: curl https://radiorecord.ru/api/stations | jq '.result.stations | sort_by(.sort) | map({station:.title,desc:.tooltip,logo:.icon_fill_colored,stream:.stream_320})' > radiorecord.json
importJSON ./radiorecord.json importJSON ./radiorecord.json
++ [ ++ [
{ {
desc = "Your favorite dance tunes from the start of the decade. Familiar hits and overlooked classics in abundance."; desc = "Your favorite dance tunes from the start of the decade. Familiar hits and overlooked classics in abundance.";
logo = "http://cdn-images.audioaddict.com/1/4/0/3/5/b/14035b0944a3c2e77852b6d0944f381e.jpg?size=180x180";
station = di-fm-name "00s Club Hits"; station = di-fm-name "00s Club Hits";
stream = di-fm "00sclubhits"; stream = di-fm "00sclubhits";
} }
{ {
desc = "Electronic sounds and atmospheric textures create a genre to enhance your state of mind and take you deeper."; desc = "Electronic sounds and atmospheric textures create a genre to enhance your state of mind and take you deeper.";
logo = "http://cdn-images.audioaddict.com/a/9/4/6/2/f/a9462ff46233f40fe0aa306379ae7cd8.jpg?size=180x180";
station = di-fm-name "Ambient"; station = di-fm-name "Ambient";
stream = di-fm "ambient"; stream = di-fm "ambient";
} }
{ {
desc = "Spaced out, melodic and full of warmth these broken beat dance tunes will keep you dazed and amused."; desc = "Spaced out, melodic and full of warmth these broken beat dance tunes will keep you dazed and amused.";
logo = "http://cdn-images.audioaddict.com/3/9/7/3/4/3/397343ffcf5543b60bba72f393e1c3c0.jpg?size=180x180";
station = di-fm-name "Atmospheric Breaks"; station = di-fm-name "Atmospheric Breaks";
stream = di-fm "atmosphericbreaks"; stream = di-fm "atmosphericbreaks";
} }
{ {
desc = "From the funkiest grooves to the dirtiest beats. Hard-hitting, high energy 4/4 club cuts to move the masses."; desc = "From the funkiest grooves to the dirtiest beats. Hard-hitting, high energy 4/4 club cuts to move the masses.";
logo = "http://cdn-images.audioaddict.com/4/f/e/d/8/9/4fed8974f4cfbbd0712baa8ae2cc2ed2.jpg?size=180x180";
station = di-fm-name "Bass & Jackin' House"; station = di-fm-name "Bass & Jackin' House";
stream = di-fm "bassnjackinhouse"; stream = di-fm "bassnjackinhouse";
} }
{ {
desc = "Blending together elements of house music, speed garage, and techno it's all about the low end frequencies."; desc = "Blending together elements of house music, speed garage, and techno it's all about the low end frequencies.";
logo = "http://cdn-images.audioaddict.com/9/1/9/9/6/d/91996d1fed5b9607c625069bcb8d3b52.jpg?size=180x180";
station = di-fm-name "Bassline"; station = di-fm-name "Bassline";
stream = di-fm "bassline"; stream = di-fm "bassline";
} }
{ {
desc = "Heavily focused on breakbeats and dusty samples. A defining 90s musical movement still going strong today."; desc = "Heavily focused on breakbeats and dusty samples. A defining 90s musical movement still going strong today.";
logo = "http://cdn-images.audioaddict.com/6/f/4/3/2/4/6f4324c4a776101fd91008d739ac3020.jpg?size=180x180";
station = di-fm-name "Big Beat"; station = di-fm-name "Big Beat";
stream = di-fm "bigbeat"; stream = di-fm "bigbeat";
} }
{ {
desc = "Fusing together house elements from the past and the present prime time music full of uplifting high energy."; desc = "Fusing together house elements from the past and the present prime time music full of uplifting high energy.";
logo = "http://cdn-images.audioaddict.com/0/4/1/2/5/7/0412578b5e31cf1b68f23c3cb5377139.jpg?size=180x180";
station = di-fm-name "Big Room House"; station = di-fm-name "Big Room House";
stream = di-fm "bigroomhouse"; stream = di-fm "bigroomhouse";
} }
{ {
desc = "Inspired by hip hop and UK rave music, breaks features broken up drum loops and creative samples, synths and fx."; desc = "Inspired by hip hop and UK rave music, breaks features broken up drum loops and creative samples, synths and fx.";
logo = "http://cdn-images.audioaddict.com/2/1/b/1/2/9/21b12909a0618017285f62a5af4b2ce5.jpg?size=180x180";
station = di-fm-name "Breaks"; station = di-fm-name "Breaks";
stream = di-fm "breaks"; stream = di-fm "breaks";
} }
{ {
desc = "The sounds of Chill & Tropical House are expertly made for lounging and dancing alike with its deeper house vibes."; desc = "The sounds of Chill & Tropical House are expertly made for lounging and dancing alike with its deeper house vibes.";
logo = "http://cdn-images.audioaddict.com/2/9/0/1/e/f/2901ef5c923bb0f9ff856ac4007975f0.jpg?size=180x180";
station = di-fm-name "Chill & Tropical House"; station = di-fm-name "Chill & Tropical House";
stream = di-fm "chillntropicalhouse"; stream = di-fm "chillntropicalhouse";
} }
{ {
desc = "Good EDM doesn't have to blow out your speakers and our curated selection of Chill EDM is a testament to the strength of mellow, chilled out electronic music."; desc = "Good EDM doesn't have to blow out your speakers and our curated selection of Chill EDM is a testament to the strength of mellow, chilled out electronic music.";
logo = "http://cdn-images.audioaddict.com/f/0/7/5/2/e/f0752e6df86dc7a0f3ffd7a63497df4e.jpg?size=180x180";
station = di-fm-name "Chill EDM"; station = di-fm-name "Chill EDM";
stream = di-fm "chilledm"; stream = di-fm "chilledm";
} }
{ {
desc = "Mellow chill beats, lofi hip-hop, trip hop, downtempo beats and jazz, blended together in a laid back style for perfect listening."; desc = "Mellow chill beats, lofi hip-hop, trip hop, downtempo beats and jazz, blended together in a laid back style for perfect listening.";
logo = "http://cdn-images.audioaddict.com/f/2/3/8/8/b/f2388be364717a3aa33f62411d9e3585.jpg?size=180x180";
station = di-fm-name "ChillHop"; station = di-fm-name "ChillHop";
stream = di-fm "chillhop"; stream = di-fm "chillhop";
} }
{ {
desc = "Electronic sounds, mellow mid-tempo rhythms, and a groove meant to calm the senses and ease the mind."; desc = "Electronic sounds, mellow mid-tempo rhythms, and a groove meant to calm the senses and ease the mind.";
logo = "http://cdn-images.audioaddict.com/f/d/9/6/c/a/fd96ca5c52508a2755a266ebf506f162.jpg?size=180x180";
station = di-fm-name "Chillout"; station = di-fm-name "Chillout";
stream = di-fm "chillout"; stream = di-fm "chillout";
} }
{ {
desc = "The perfect musical soundtrack for when you want to close your eyes, get truly comfortable, and drift away."; desc = "The perfect musical soundtrack for when you want to close your eyes, get truly comfortable, and drift away.";
logo = "http://cdn-images.audioaddict.com/1/d/4/f/3/3/1d4f3310f94769b4e2f55ee0887eead3.jpg?size=180x180";
station = di-fm-name "Chillout Dreams"; station = di-fm-name "Chillout Dreams";
stream = di-fm "chilloutdreams"; stream = di-fm "chilloutdreams";
} }
{ {
desc = "The brilliant combination of dubstep rhythms with the mellow grooves of chillout. A unique sound all its own."; desc = "The brilliant combination of dubstep rhythms with the mellow grooves of chillout. A unique sound all its own.";
logo = "http://cdn-images.audioaddict.com/c/e/9/b/d/1/ce9bd1666b49921b440ec796653b24f0.jpg?size=180x180";
station = di-fm-name "Chillstep"; station = di-fm-name "Chillstep";
stream = di-fm "chillstep"; stream = di-fm "chillstep";
} }
{ {
desc = "European pop music born in the 90s full of high energy sounds and big hooks now heard in gyms and malls worldwide."; desc = "European pop music born in the 90s full of high energy sounds and big hooks now heard in gyms and malls worldwide.";
logo = "http://cdn-images.audioaddict.com/a/9/8/1/5/3/a98153e6c9fcee321fd6dff0c8a6d0ba.jpg?size=180x180";
station = di-fm-name "Classic EuroDance"; station = di-fm-name "Classic EuroDance";
stream = di-fm "classiceurodance"; stream = di-fm "classiceurodance";
} }
{ {
desc = "Conceived in the European discos in the 70s, evolving through the decades into modern electronic masterpieces."; desc = "Conceived in the European discos in the 70s, evolving through the decades into modern electronic masterpieces.";
logo = "http://cdn-images.audioaddict.com/0/1/0/a/6/6/010a6648f8afc52654b07c07c68e9cad.jpg?size=180x180";
station = di-fm-name "Classic EuroDisco"; station = di-fm-name "Classic EuroDisco";
stream = di-fm "classiceurodisco"; stream = di-fm "classiceurodisco";
} }
{ {
desc = "The classic melodies, the epic breakdowns and gigantic builds. Re-experience Trance music in her prime."; desc = "The classic melodies, the epic breakdowns and gigantic builds. Re-experience Trance music in her prime.";
logo = "http://cdn-images.audioaddict.com/4/6/8/0/a/3/4680a3fd0e35f0b2f9bf60c9889d4343.jpg?size=180x180";
station = di-fm-name "Classic Trance"; station = di-fm-name "Classic Trance";
stream = di-fm "classictrance"; stream = di-fm "classictrance";
} }
{ {
desc = "Classic sounds of Vocal Trance"; desc = "Classic sounds of Vocal Trance";
logo = "http://cdn-images.audioaddict.com/1/e/1/8/1/a/1e181a502369be86e3f2e696723c26fe.jpg?size=180x180";
station = di-fm-name "Classic Vocal Trance"; station = di-fm-name "Classic Vocal Trance";
stream = di-fm "classicvocaltrance"; stream = di-fm "classicvocaltrance";
} }
{ {
desc = "The bassbin rattling, speaker-freaking hits of Dubstep all tried, tested and approved to work in the clubs."; desc = "The bassbin rattling, speaker-freaking hits of Dubstep all tried, tested and approved to work in the clubs.";
logo = "http://cdn-images.audioaddict.com/3/6/b/5/e/7/36b5e73f328251b20120a6bc5365777f.jpg?size=180x180";
station = di-fm-name "Club Dubstep"; station = di-fm-name "Club Dubstep";
stream = di-fm "clubdubstep"; stream = di-fm "clubdubstep";
} }
{ {
desc = "The music heard in the biggest venues worldwide. From prime time pushers to deeper house shakers the sounds of now."; desc = "The music heard in the biggest venues worldwide. From prime time pushers to deeper house shakers the sounds of now.";
logo = "http://cdn-images.audioaddict.com/2/e/e/f/9/8/2eef98b26e5490acc78ff6ab22e04827.jpg?size=180x180";
station = di-fm-name "Club Sounds"; station = di-fm-name "Club Sounds";
stream = di-fm "club"; stream = di-fm "club";
} }
{ {
desc = "From techno, deep house, progressive and trance check out the sounds of the DJ deep in the mix."; desc = "From techno, deep house, progressive and trance check out the sounds of the DJ deep in the mix.";
logo = "http://cdn-images.audioaddict.com/1/3/a/a/0/8/13aa08b5dce2525029c6ddfb8e286dc2.jpg?size=180x180";
station = di-fm-name "DJ Mixes"; station = di-fm-name "DJ Mixes";
stream = di-fm "djmixes"; stream = di-fm "djmixes";
} }
{ {
desc = "Evil, gritty and twisted DnB / Drum & Bass. at 160+ BPM, hear the darkest basslines and the hardest hitting percussion."; desc = "Evil, gritty and twisted DnB / Drum & Bass. at 160+ BPM, hear the darkest basslines and the hardest hitting percussion.";
logo = "http://cdn-images.audioaddict.com/6/e/4/7/c/1/6e47c1d85f09957d568c9535dda75e58.jpg?size=180x180";
station = di-fm-name "Dark DnB"; station = di-fm-name "Dark DnB";
stream = di-fm "darkdnb"; stream = di-fm "darkdnb";
} }
{ {
desc = "The darker form of PsyTrance, which is a sound all its own direct from Goa to your headphones."; desc = "The darker form of PsyTrance, which is a sound all its own direct from Goa to your headphones.";
logo = "http://cdn-images.audioaddict.com/0/e/1/0/b/9/0e10b950ca2f3e828becbe3dd3c2d0b3.jpg?size=180x180";
station = di-fm-name "Dark PsyTrance"; station = di-fm-name "Dark PsyTrance";
stream = di-fm "darkpsytrance"; stream = di-fm "darkpsytrance";
} }
{ {
desc = "House music crafted for the smaller and mid-sized rooms deeper tracks full of silky, smooth grooves."; desc = "House music crafted for the smaller and mid-sized rooms deeper tracks full of silky, smooth grooves.";
logo = "http://cdn-images.audioaddict.com/9/a/1/b/4/6/9a1b469ae251c084465096038312d506.jpg?size=180x180";
station = di-fm-name "Deep House"; station = di-fm-name "Deep House";
stream = di-fm "deephouse"; stream = di-fm "deephouse";
} }
{ {
desc = "Elements of house, funk, and disco. Mid-tempo beats, soulful grooves and head nodding selections."; desc = "Elements of house, funk, and disco. Mid-tempo beats, soulful grooves and head nodding selections.";
logo = "http://cdn-images.audioaddict.com/b/2/a/7/1/5/b2a715bb711ab06822bcaf07fde74d51.jpg?size=180x180";
station = di-fm-name "Deep Nu-Disco"; station = di-fm-name "Deep Nu-Disco";
stream = di-fm "deepnudisco"; stream = di-fm "deepnudisco";
} }
{ {
desc = "This smooth, groove-heavy selection of deep progressive house tracks is the perfect soundtrack for smaller and mid-sized rooms."; desc = "This smooth, groove-heavy selection of deep progressive house tracks is the perfect soundtrack for smaller and mid-sized rooms.";
logo = "http://cdn-images.audioaddict.com/b/0/e/1/9/0/b0e19018c34150a07d76224e5fcdbeda.jpg?size=180x180";
station = di-fm-name "Deep Progressive House"; station = di-fm-name "Deep Progressive House";
stream = di-fm "deepprogressivehouse"; stream = di-fm "deepprogressivehouse";
} }
{ {
desc = "A fusion of deep house & techno. Punchy grooves, spaced out sounds and forward thinking productions."; desc = "A fusion of deep house & techno. Punchy grooves, spaced out sounds and forward thinking productions.";
logo = "http://cdn-images.audioaddict.com/d/3/2/1/7/5/d32175a432f823ce84261c01d4b53f57.jpg?size=180x180";
station = di-fm-name "Deep Tech"; station = di-fm-name "Deep Tech";
stream = di-fm "deeptech"; stream = di-fm "deeptech";
} }
{ {
desc = "Where would dance music be without Detroit? The city that started it all continues to inspire and educate."; desc = "Where would dance music be without Detroit? The city that started it all continues to inspire and educate.";
logo = "http://cdn-images.audioaddict.com/d/7/b/3/1/d/d7b31d5973593af0043fed3f180df702.jpg?size=180x180";
station = di-fm-name "Detroit House & Techno"; station = di-fm-name "Detroit House & Techno";
stream = di-fm "detroithousentechno"; stream = di-fm "detroithousentechno";
} }
{ {
desc = "The feel good sound inspired from 70s disco combined with the warm kick drum of modern house music."; desc = "The feel good sound inspired from 70s disco combined with the warm kick drum of modern house music.";
logo = "http://cdn-images.audioaddict.com/2/7/9/7/0/5/279705ae85a4e0f529f6f7fbaa47a646.jpg?size=180x180";
station = di-fm-name "Disco House"; station = di-fm-name "Disco House";
stream = di-fm "discohouse"; stream = di-fm "discohouse";
} }
{ {
desc = "Head nodding beats, chilled vocals, and lush soundscapes to bring down the sun and start the night."; desc = "Head nodding beats, chilled vocals, and lush soundscapes to bring down the sun and start the night.";
logo = "http://cdn-images.audioaddict.com/f/8/3/3/6/f/f8336fff9bcb4b01a36f2684ecd150c6.jpg?size=180x180";
station = di-fm-name "Downtempo Lounge"; station = di-fm-name "Downtempo Lounge";
stream = di-fm "downtempolounge"; stream = di-fm "downtempolounge";
} }
{ {
desc = "Born in the mid 90s, Drum and Bass / DnB is all about fast breakbeats, urban vibes, and rib rattling basslines."; desc = "Born in the mid 90s, Drum and Bass / DnB is all about fast breakbeats, urban vibes, and rib rattling basslines.";
logo = "http://cdn-images.audioaddict.com/1/9/8/1/3/f/19813f3ba29ad66caa06bbee4aba558a.jpg?size=180x180";
station = di-fm-name "Drum and Bass"; station = di-fm-name "Drum and Bass";
stream = di-fm "drumandbass"; stream = di-fm "drumandbass";
} }
{ {
desc = "A hybrid of half-time Dubstep and intense Drum and Bass / DnB."; desc = "A hybrid of half-time Dubstep and intense Drum and Bass / DnB.";
logo = "http://cdn-images.audioaddict.com/1/c/6/0/b/9/1c60b9976b4d861ddc90d668f749fe6f.jpg?size=180x180";
station = di-fm-name "Drumstep"; station = di-fm-name "Drumstep";
stream = di-fm "drumstep"; stream = di-fm "drumstep";
} }
{ {
desc = "An emphasis on the bass and drums / DnB, delayed effects, sampled vocals and smokey Reggae inspired vibes."; desc = "An emphasis on the bass and drums / DnB, delayed effects, sampled vocals and smokey Reggae inspired vibes.";
logo = "http://cdn-images.audioaddict.com/e/2/c/8/6/5/e2c865e92c65cfb91ad0e2d3933234e0.jpg?size=180x180";
station = di-fm-name "Dub"; station = di-fm-name "Dub";
stream = di-fm "dub"; stream = di-fm "dub";
} }
{ {
desc = "The beloved sounds of deep techno saturated with tape delays, heavy reverb and ice cold atmospherics."; desc = "The beloved sounds of deep techno saturated with tape delays, heavy reverb and ice cold atmospherics.";
logo = "http://cdn-images.audioaddict.com/1/9/d/6/1/0/19d61084830ef94886b32d847fc5d29e.jpg?size=180x180";
station = di-fm-name "Dub Techno"; station = di-fm-name "Dub Techno";
stream = di-fm "dubtechno"; stream = di-fm "dubtechno";
} }
{ {
desc = "The wobbles of the bass, the party rocking beats, and the biggest crowd destroying drops."; desc = "The wobbles of the bass, the party rocking beats, and the biggest crowd destroying drops.";
logo = "http://cdn-images.audioaddict.com/7/7/c/1/a/e/77c1aec493eeb9e2a5d22951447fbd48.jpg?size=180x180";
station = di-fm-name "Dubstep"; station = di-fm-name "Dubstep";
stream = di-fm "dubstep"; stream = di-fm "dubstep";
} }
{ {
desc = "The sound of the largest events. From the gargantuan festivals, the huge main rooms and the biggest DJs."; desc = "The sound of the largest events. From the gargantuan festivals, the huge main rooms and the biggest DJs.";
logo = "http://cdn-images.audioaddict.com/d/d/1/1/8/f/dd118f5fe9befc191907a32d0877a13d.jpg?size=180x180";
station = di-fm-name "EDM Festival"; station = di-fm-name "EDM Festival";
stream = di-fm "edmfestival"; stream = di-fm "edmfestival";
} }
{ {
desc = "Where dance meets pop. Crossover favorites, stadium-sized anthems and the biggest electronic tunes in existence."; desc = "Where dance meets pop. Crossover favorites, stadium-sized anthems and the biggest electronic tunes in existence.";
logo = "http://cdn-images.audioaddict.com/6/9/b/2/c/c/69b2cc01d4cbcb5a813ee6428bc4e455.jpg?size=180x180";
station = di-fm-name "EDM Hits"; station = di-fm-name "EDM Hits";
stream = di-fm "edm"; stream = di-fm "edm";
} }
{ {
desc = "Buzzing basslines, huge kicks, party rocking drops. House music packed full of gigantic bass and massive synths."; desc = "Buzzing basslines, huge kicks, party rocking drops. House music packed full of gigantic bass and massive synths.";
logo = "http://cdn-images.audioaddict.com/7/4/2/3/8/0/742380673147770eef642532828dbc6c.jpg?size=180x180";
station = di-fm-name "Electro House"; station = di-fm-name "Electro House";
stream = di-fm "electrohouse"; stream = di-fm "electrohouse";
} }
{ {
desc = "The combination of 1920s-1940s jazz and swing music, big band horns and modern day electro house."; desc = "The combination of 1920s-1940s jazz and swing music, big band horns and modern day electro house.";
logo = "http://cdn-images.audioaddict.com/3/3/e/6/0/9/33e609d64ca20b0719d28d2193eece31.jpg?size=180x180";
station = di-fm-name "Electro Swing"; station = di-fm-name "Electro Swing";
stream = di-fm "electroswing"; stream = di-fm "electroswing";
} }
{ {
desc = "The trailblazers, the renegades and the experimental musicians who gave early inspiration with electronic instruments."; desc = "The trailblazers, the renegades and the experimental musicians who gave early inspiration with electronic instruments.";
logo = "http://cdn-images.audioaddict.com/5/7/4/a/3/3/574a3373b242bed1018c5c99e5021c3f.jpg?size=180x180";
station = di-fm-name "Electronic Pioneers"; station = di-fm-name "Electronic Pioneers";
stream = di-fm "electronicpioneers"; stream = di-fm "electronicpioneers";
} }
{ {
desc = "Catchy pop music blended together with vintage synthesizers and electronic instrumentation."; desc = "Catchy pop music blended together with vintage synthesizers and electronic instrumentation.";
logo = "http://cdn-images.audioaddict.com/2/8/c/1/e/8/28c1e8587ae6e0b2589b4d66ccd99324.jpg?size=180x180";
station = di-fm-name "Electropop"; station = di-fm-name "Electropop";
stream = di-fm "electropop"; stream = di-fm "electropop";
} }
{ {
desc = "Trance in its most boisterous form. Uplifting melodies on top of high energy beats create these euphoric anthems."; desc = "Trance in its most boisterous form. Uplifting melodies on top of high energy beats create these euphoric anthems.";
logo = "http://cdn-images.audioaddict.com/f/1/f/d/f/e/f1fdfea9ba9622ecdee020cc53126e60.jpg?size=180x180";
station = di-fm-name "Epic Trance"; station = di-fm-name "Epic Trance";
stream = di-fm "epictrance"; stream = di-fm "epictrance";
} }
{ {
desc = "Pop music infused with a high energy 4/4 pulse. Heavy on the synthesizers, the melodies and the vocals."; desc = "Pop music infused with a high energy 4/4 pulse. Heavy on the synthesizers, the melodies and the vocals.";
logo = "http://cdn-images.audioaddict.com/4/b/b/2/7/5/4bb2756bcacce0a2bf44ebaaf743f2ab.jpg?size=180x180";
station = di-fm-name "EuroDance"; station = di-fm-name "EuroDance";
stream = di-fm "eurodance"; stream = di-fm "eurodance";
} }
{ {
desc = "Focused on the funkiest grooves, with plenty of the guitar licks and clever samples placed around a 4/4 swing."; desc = "Focused on the funkiest grooves, with plenty of the guitar licks and clever samples placed around a 4/4 swing.";
logo = "http://cdn-images.audioaddict.com/3/3/7/0/b/a/3370baa3700e4578558dff57c6443a0f.jpg?size=180x180";
station = di-fm-name "Funky House"; station = di-fm-name "Funky House";
stream = di-fm "funkyhouse"; stream = di-fm "funkyhouse";
} }
{ {
desc = "Hard basslines, booming beats and insatiable grooves. Inspired by Trap, Juke and Garage molded together into a unique booming style."; desc = "Hard basslines, booming beats and insatiable grooves. Inspired by Trap, Juke and Garage molded together into a unique booming style.";
logo = "http://cdn-images.audioaddict.com/3/9/e/5/8/b/39e58b7b675d6ec353582cd5e9f38dbe.jpg?size=180x180";
station = di-fm-name "Future Bass"; station = di-fm-name "Future Bass";
stream = di-fm "futurebass"; stream = di-fm "futurebass";
} }
{ {
desc = "2step Garage rhythms, chunky bass line driven grooves and plenty of forward thinking innovation."; desc = "2step Garage rhythms, chunky bass line driven grooves and plenty of forward thinking innovation.";
logo = "http://cdn-images.audioaddict.com/0/e/9/0/4/2/0e904268ec98b8c0521c30da4ac321bb.jpg?size=180x180";
station = di-fm-name "Future Garage"; station = di-fm-name "Future Garage";
stream = di-fm "futuregarage"; stream = di-fm "futuregarage";
} }
{ {
desc = "Finest selection of futurepop and synthpop."; desc = "Finest selection of futurepop and synthpop.";
logo = "http://cdn-images.audioaddict.com/e/e/8/5/2/3/ee8523a0d6165465961cb2d0445c4f27.jpg?size=180x180";
station = di-fm-name "Future Synthpop"; station = di-fm-name "Future Synthpop";
stream = di-fm "futuresynthpop"; stream = di-fm "futuresynthpop";
} }
{ {
desc = "The hardest form of techno with punishing tracks designed to drive the crowds into a sweaty frenzy."; desc = "The hardest form of techno with punishing tracks designed to drive the crowds into a sweaty frenzy.";
logo = "http://cdn-images.audioaddict.com/d/a/f/c/e/d/dafced37829e69724be99dc375bc5713.jpg?size=180x180";
station = di-fm-name "Gabber"; station = di-fm-name "Gabber";
stream = di-fm "gabber"; stream = di-fm "gabber";
} }
{ {
desc = "The sound of digital malfunctions, electric hum and bit rate distortions perfectly placed alongside laid-back hip hop beats."; desc = "The sound of digital malfunctions, electric hum and bit rate distortions perfectly placed alongside laid-back hip hop beats.";
logo = "http://cdn-images.audioaddict.com/7/3/5/a/b/b/735abb160f950c98e2bd7caf6843e255.jpg?size=180x180";
station = di-fm-name "Glitch Hop"; station = di-fm-name "Glitch Hop";
stream = di-fm "glitchhop"; stream = di-fm "glitchhop";
} }
{ {
desc = "A very psychedelic form of trance, Goa-Psy Trance is a sound full of arpeggiated synths and trippy effects."; desc = "A very psychedelic form of trance, Goa-Psy Trance is a sound full of arpeggiated synths and trippy effects.";
logo = "http://cdn-images.audioaddict.com/4/e/e/e/4/4/4eee448424df2768055ee7503f0251e9.jpg?size=180x180";
station = di-fm-name "Goa-Psy Trance"; station = di-fm-name "Goa-Psy Trance";
stream = di-fm "goapsy"; stream = di-fm "goapsy";
} }
{ {
desc = "A channel showcasing everything from hard dance, trance and happy hardcore to lift the spirits (and the arms)."; desc = "A channel showcasing everything from hard dance, trance and happy hardcore to lift the spirits (and the arms).";
logo = "http://cdn-images.audioaddict.com/d/f/7/7/8/e/df778eed294536f4e858093124aa2be5.jpg?size=180x180";
station = di-fm-name "Hands Up"; station = di-fm-name "Hands Up";
stream = di-fm "handsup"; stream = di-fm "handsup";
} }
{ {
desc = "Concrete kicks and punching rhythms, hard dance is a tougher side of music with sharp edges and aggressive power."; desc = "Concrete kicks and punching rhythms, hard dance is a tougher side of music with sharp edges and aggressive power.";
logo = "http://cdn-images.audioaddict.com/5/9/d/a/e/5/59dae529a51feb3f90b542f3d33808ec.jpg?size=180x180";
station = di-fm-name "Hard Dance"; station = di-fm-name "Hard Dance";
stream = di-fm "harddance"; stream = di-fm "harddance";
} }
{ {
desc = "Tough as nails warehouse jams full of cold aggression, sinister structures and pounding rhythms that hit hard."; desc = "Tough as nails warehouse jams full of cold aggression, sinister structures and pounding rhythms that hit hard.";
logo = "http://cdn-images.audioaddict.com/5/e/5/1/1/d/5e511d67198b404149e7eaed9858e5d4.jpg?size=180x180";
station = di-fm-name "Hard Techno"; station = di-fm-name "Hard Techno";
stream = di-fm "hardtechno"; stream = di-fm "hardtechno";
} }
{ {
desc = "Strictly for the hardcore. These are the biggest and boldest bangers, and the hardest hitting tracks."; desc = "Strictly for the hardcore. These are the biggest and boldest bangers, and the hardest hitting tracks.";
logo = "http://cdn-images.audioaddict.com/e/0/5/3/8/5/e05385cf844ef4884a26c19ed254efbf.jpg?size=180x180";
station = di-fm-name "Hardcore"; station = di-fm-name "Hardcore";
stream = di-fm "hardcore"; stream = di-fm "hardcore";
} }
{ {
desc = "Hard techno & hardcore. A global phenomenon with powerful kicks, distorted effects and infectious melodies."; desc = "Hard techno & hardcore. A global phenomenon with powerful kicks, distorted effects and infectious melodies.";
logo = "http://cdn-images.audioaddict.com/8/b/1/0/3/c/8b103c03fbf78becf042085552e9ef41.jpg?size=180x180";
station = di-fm-name "Hardstyle"; station = di-fm-name "Hardstyle";
stream = di-fm "hardstyle"; stream = di-fm "hardstyle";
} }
{ {
desc = "Born in Chicago and now global, house music is always evolving but remains true to its pure 4/4 structure."; desc = "Born in Chicago and now global, house music is always evolving but remains true to its pure 4/4 structure.";
logo = "http://cdn-images.audioaddict.com/5/3/0/b/6/9/530b699645ddff8d66a2333ae09bb06a.jpg?size=180x180";
station = di-fm-name "House"; station = di-fm-name "House";
stream = di-fm "house"; stream = di-fm "house";
} }
{ {
desc = "Smooth, groovy and full of cutting-edge, fresh ideas beats to kick back and enjoy far from the club setting."; desc = "Smooth, groovy and full of cutting-edge, fresh ideas beats to kick back and enjoy far from the club setting.";
logo = "http://cdn-images.audioaddict.com/9/1/8/4/2/b/91842b0ec15b8b69e50315dbd3afe03e.jpg?size=180x180";
station = di-fm-name "Indie Beats"; station = di-fm-name "Indie Beats";
stream = di-fm "indiebeats"; stream = di-fm "indiebeats";
} }
{ {
desc = "The spirit of Rock & Roll with an electronic soul. Club culture and live music combined."; desc = "The spirit of Rock & Roll with an electronic soul. Club culture and live music combined.";
logo = "http://cdn-images.audioaddict.com/9/f/7/0/a/d/9f70ad76ec13a6123405c6d7a03325f3.jpg?size=180x180";
station = di-fm-name "Indie Dance"; station = di-fm-name "Indie Dance";
stream = di-fm "indiedance"; stream = di-fm "indiedance";
} }
{ {
desc = "One of the biggest cultural soundtracks with the infectious thump of house music. Expect sultry saxophones, trumpets, and finger snapping grooves."; desc = "One of the biggest cultural soundtracks with the infectious thump of house music. Expect sultry saxophones, trumpets, and finger snapping grooves.";
logo = "http://cdn-images.audioaddict.com/f/4/b/3/3/e/f4b33e8cbd9f0b1776e64f17b9c35abd.jpg?size=180x180";
station = di-fm-name "Jazz House"; station = di-fm-name "Jazz House";
stream = di-fm "jazzhouse"; stream = di-fm "jazzhouse";
} }
{ {
desc = "Jungle keeps the breakbeat tempos high and celebrates the diverse ideas found within urban and rave music."; desc = "Jungle keeps the breakbeat tempos high and celebrates the diverse ideas found within urban and rave music.";
logo = "http://cdn-images.audioaddict.com/4/1/e/d/e/7/41ede7b8b43cffcc42876e6e319b7ef3.jpg?size=180x180";
station = di-fm-name "Jungle"; station = di-fm-name "Jungle";
stream = di-fm "jungle"; stream = di-fm "jungle";
} }
{ {
desc = "The sounds of Salsa, Brazilian beats and Latin Jazz with the steady grooves of modern East Coast dance music."; desc = "The sounds of Salsa, Brazilian beats and Latin Jazz with the steady grooves of modern East Coast dance music.";
logo = "http://cdn-images.audioaddict.com/6/0/1/7/6/e/60176ec05138ad9b621cb92de7f0c8c8.jpg?size=180x180";
station = di-fm-name "Latin House"; station = di-fm-name "Latin House";
stream = di-fm "latinhouse"; stream = di-fm "latinhouse";
} }
{ {
desc = "Smooth as water, with the fast paced rhythms, Liquid DNB / Drum and Bass flows with rolling ease without losing momentum."; desc = "Smooth as water, with the fast paced rhythms, Liquid DNB / Drum and Bass flows with rolling ease without losing momentum.";
logo = "http://cdn-images.audioaddict.com/6/7/5/9/9/a/67599a0b4f3575ea5f6a74fe633899d7.jpg?size=180x180";
station = di-fm-name "Liquid DnB"; station = di-fm-name "Liquid DnB";
stream = di-fm "liquiddnb"; stream = di-fm "liquiddnb";
} }
{ {
desc = "Smooth, rolling and steady this fresh formation of Dubstep keeps the sounds you love with a flowing Drum and Bass groove."; desc = "Smooth, rolling and steady this fresh formation of Dubstep keeps the sounds you love with a flowing Drum and Bass groove.";
logo = "http://cdn-images.audioaddict.com/6/e/f/6/c/e/6ef6ced4249faec61c8fbc58b10b6343.jpg?size=180x180";
station = di-fm-name "Liquid Dubstep"; station = di-fm-name "Liquid Dubstep";
stream = di-fm "liquiddubstep"; stream = di-fm "liquiddubstep";
} }
{ {
desc = "The smoother side of Trap but still packed with mechanical grooves and hip hop moods."; desc = "The smoother side of Trap but still packed with mechanical grooves and hip hop moods.";
logo = "http://cdn-images.audioaddict.com/6/b/5/b/d/6/6b5bd66a99e46fa1258cb565d988ea7c.jpg?size=180x180";
station = di-fm-name "Liquid Trap"; station = di-fm-name "Liquid Trap";
stream = di-fm "liquidtrap"; stream = di-fm "liquidtrap";
} }
{ {
desc = "Tastefully selected LoFi Hip-Hop tunes with textured atmospheres & laid back beats with a dash of chillhop and perfectly designed to chill your ears."; desc = "Tastefully selected LoFi Hip-Hop tunes with textured atmospheres & laid back beats with a dash of chillhop and perfectly designed to chill your ears.";
logo = "http://cdn-images.audioaddict.com/c/f/7/0/d/a/cf70daf883c01687f321d72376227493.jpg?size=180x180";
station = di-fm-name "LoFi Hip-Hop"; station = di-fm-name "LoFi Hip-Hop";
stream = di-fm "lofihiphop"; stream = di-fm "lofihiphop";
} }
{ {
desc = "Punch your one-way ticket to peace of mind and mental clarity with this curated selection of LoFi Lounge & Chill tracks today."; desc = "Punch your one-way ticket to peace of mind and mental clarity with this curated selection of LoFi Lounge & Chill tracks today.";
logo = "http://cdn-images.audioaddict.com/0/2/7/2/1/f/02721f4098dbeae07a8956d832f59cd8.jpg?size=180x180";
station = di-fm-name "LoFi Lounge & Chill"; station = di-fm-name "LoFi Lounge & Chill";
stream = di-fm "lofiloungenchill"; stream = di-fm "lofiloungenchill";
} }
{ {
desc = "Music to chill to. Music made for when it's all about kicking off your shoes, laying back, and totally relaxing."; desc = "Music to chill to. Music made for when it's all about kicking off your shoes, laying back, and totally relaxing.";
logo = "http://cdn-images.audioaddict.com/f/7/a/5/f/b/f7a5fbb67a1a0f0992f131506917c2e6.jpg?size=180x180";
station = di-fm-name "Lounge"; station = di-fm-name "Lounge";
stream = di-fm "lounge"; stream = di-fm "lounge";
} }
{ {
desc = "The melodic side of progressive house, packed with driving rhythms and forward thinking sounds."; desc = "The melodic side of progressive house, packed with driving rhythms and forward thinking sounds.";
logo = "http://cdn-images.audioaddict.com/4/4/8/c/f/6/448cf62c2d3c68ede713008015da9bfc.jpg?size=180x180";
station = di-fm-name "Melodic Progressive"; station = di-fm-name "Melodic Progressive";
stream = di-fm "melodicprogressive"; stream = di-fm "melodicprogressive";
} }
{ {
desc = "Minimal fuses elements of house, techno and electronica and strips it back to focus on the spaces between the sound."; desc = "Minimal fuses elements of house, techno and electronica and strips it back to focus on the spaces between the sound.";
logo = "http://cdn-images.audioaddict.com/a/9/1/b/1/4/a91b1414a8712794672e3ea1324ffe92.jpg?size=180x180";
station = di-fm-name "Minimal"; station = di-fm-name "Minimal";
stream = di-fm "minimal"; stream = di-fm "minimal";
} }
{ {
desc = "Pitched up vocals, happy hardcore beats, and high energy music non-stop."; desc = "Pitched up vocals, happy hardcore beats, and high energy music non-stop.";
logo = "http://cdn-images.audioaddict.com/e/f/8/f/b/e/ef8fbe63f86e496f0ce514ee2e85c30a.jpg?size=180x180";
station = di-fm-name "Nightcore"; station = di-fm-name "Nightcore";
stream = di-fm "nightcore"; stream = di-fm "nightcore";
} }
{ {
desc = "Modern disco music blending the familiar funk of the 70s and 80s with futuristic beats and up to date grooves."; desc = "Modern disco music blending the familiar funk of the 70s and 80s with futuristic beats and up to date grooves.";
logo = "http://cdn-images.audioaddict.com/f/2/3/7/8/a/f2378a19d61a3063a2a6271a29fb1595.jpg?size=180x180";
station = di-fm-name "Nu Disco"; station = di-fm-name "Nu Disco";
stream = di-fm "nudisco"; stream = di-fm "nudisco";
} }
{ {
desc = "Acid, one of the characteristics of the TB-303, is celebrated here with the best tracks from house, techno and trance."; desc = "Acid, one of the characteristics of the TB-303, is celebrated here with the best tracks from house, techno and trance.";
logo = "http://cdn-images.audioaddict.com/7/0/a/7/8/3/70a7830bce8d22eb1a7c868773f443e8.jpg?size=180x180";
station = di-fm-name "Oldschool Acid"; station = di-fm-name "Oldschool Acid";
stream = di-fm "oldschoolacid"; stream = di-fm "oldschoolacid";
} }
{ {
desc = "The biggest classics and secret weapons this is a true treasure chest of house tracks from back in the day."; desc = "The biggest classics and secret weapons this is a true treasure chest of house tracks from back in the day.";
logo = "http://cdn-images.audioaddict.com/7/d/0/c/e/f/7d0cefbcb479ce257b24471f3d600eba.jpg?size=180x180";
station = di-fm-name "Oldschool House"; station = di-fm-name "Oldschool House";
stream = di-fm "oldschoolhouse"; stream = di-fm "oldschoolhouse";
} }
{ {
desc = "Grab your whistles, white gloves and reach for the laser beams. This is the sound of raving when raving was new."; desc = "Grab your whistles, white gloves and reach for the laser beams. This is the sound of raving when raving was new.";
logo = "http://cdn-images.audioaddict.com/b/1/0/c/2/6/b10c2672a6a54a8ae5356f3ddb49b4c1.jpg?size=180x180";
station = di-fm-name "Oldschool Rave"; station = di-fm-name "Oldschool Rave";
stream = di-fm "oldschoolrave"; stream = di-fm "oldschoolrave";
} }
{ {
desc = "Go back in time and hear the biggest and best tracks within techno and trance that defined a decade of dance culture."; desc = "Go back in time and hear the biggest and best tracks within techno and trance that defined a decade of dance culture.";
logo = "http://cdn-images.audioaddict.com/2/4/9/d/1/8/249d182058ac9e5631557eb309efe80f.jpg?size=180x180";
station = di-fm-name "Oldschool Techno & Trance"; station = di-fm-name "Oldschool Techno & Trance";
stream = di-fm "oldschool"; stream = di-fm "oldschool";
} }
{ {
desc = "Always moving forward, progressive continues to reinvent itself into new sounds and styles made for the floor."; desc = "Always moving forward, progressive continues to reinvent itself into new sounds and styles made for the floor.";
logo = "http://cdn-images.audioaddict.com/3/3/5/5/3/1/3355314492d633a5330c659cfe98fc1b.jpg?size=180x180";
station = di-fm-name "Progressive"; station = di-fm-name "Progressive";
stream = di-fm "progressive"; stream = di-fm "progressive";
} }
{ {
desc = "Progress your mind to undiscovered psychedelic dimensions."; desc = "Progress your mind to undiscovered psychedelic dimensions.";
logo = "http://cdn-images.audioaddict.com/5/f/a/5/6/5/5fa5659badbaf1a4ff817323ee5e998a.jpg?size=180x180";
station = di-fm-name "Progressive Psy"; station = di-fm-name "Progressive Psy";
stream = di-fm "progressivepsy"; stream = di-fm "progressivepsy";
} }
{ {
desc = "Downtempo psychedelic dub grooves, goa ambient, and world beats."; desc = "Downtempo psychedelic dub grooves, goa ambient, and world beats.";
logo = "http://cdn-images.audioaddict.com/4/5/2/d/1/4/452d14ab72381941b1bd5f94af15678b.jpg?size=180x180";
station = di-fm-name "PsyChill"; station = di-fm-name "PsyChill";
stream = di-fm "psychill"; stream = di-fm "psychill";
} }
{ {
desc = "Dub, ambient, and psychedelic trance, fused together in atmospheric harmony."; desc = "Dub, ambient, and psychedelic trance, fused together in atmospheric harmony.";
logo = "http://cdn-images.audioaddict.com/4/0/0/d/5/3/400d53d541322f0883a807c9b79d5540.jpg?size=180x180";
station = di-fm-name "PsyDub"; station = di-fm-name "PsyDub";
stream = di-fm "psydub"; stream = di-fm "psydub";
} }
{ {
desc = "The psychedelic side of ambient."; desc = "The psychedelic side of ambient.";
logo = "http://cdn-images.audioaddict.com/a/7/b/0/d/c/a7b0dcee2110e6d01fec96758a639ea3.jpg?size=180x180";
station = di-fm-name "Psybient"; station = di-fm-name "Psybient";
stream = di-fm "psybient"; stream = di-fm "psybient";
} }
{ {
desc = "Russia's hottest club hits."; desc = "Russia's hottest club hits.";
logo = "http://cdn-images.audioaddict.com/5/8/2/6/2/e/58262e338e405ab82ab92aa55f719f86.jpg?size=180x180";
station = di-fm-name "Russian Club Hits"; station = di-fm-name "Russian Club Hits";
stream = di-fm "russianclubhits"; stream = di-fm "russianclubhits";
} }
{ {
desc = "House music saturated with feeling full of melodies, vocals and true soul. Steady warm 4/4 vibes."; desc = "House music saturated with feeling full of melodies, vocals and true soul. Steady warm 4/4 vibes.";
logo = "http://cdn-images.audioaddict.com/e/6/5/5/c/d/e655cd614bd4a1c981273a555081c309.jpg?size=180x180";
station = di-fm-name "Soulful House"; station = di-fm-name "Soulful House";
stream = di-fm "soulfulhouse"; stream = di-fm "soulfulhouse";
} }
{ {
desc = "Ambient space music for expanding minds."; desc = "Ambient space music for expanding minds.";
logo = "http://cdn-images.audioaddict.com/b/e/c/b/e/0/becbe0cb9c3002fc21f97f9e65cf9da1.jpg?size=180x180";
station = di-fm-name "Space Dreams"; station = di-fm-name "Space Dreams";
stream = di-fm "spacemusic"; stream = di-fm "spacemusic";
} }
{ {
desc = "This selection of summer chill house classics has been handpicked to elicit that special summer feeling year-round."; desc = "This selection of summer chill house classics has been handpicked to elicit that special summer feeling year-round.";
logo = "http://cdn-images.audioaddict.com/3/d/8/b/6/1/3d8b619652faa1969274e0d51c8bd59d.jpg?size=180x180";
station = di-fm-name "Summer Chill House"; station = di-fm-name "Summer Chill House";
stream = di-fm "summerchillhouse"; stream = di-fm "summerchillhouse";
} }
{ {
desc = "Influenced by video games and movie soundtracks of the 80s, Synthwave's mission continues today with great new music keeping things future retro."; desc = "Influenced by video games and movie soundtracks of the 80s, Synthwave's mission continues today with great new music keeping things future retro.";
logo = "http://cdn-images.audioaddict.com/d/8/e/a/6/4/d8ea647113c8cdec87b4751f20b3360b.jpg?size=180x180";
station = di-fm-name "Synthwave"; station = di-fm-name "Synthwave";
stream = di-fm "synthwave"; stream = di-fm "synthwave";
} }
{ {
desc = "Blending the warmth of house music with the cold structural precision of techno, tech house bridges the divide."; desc = "Blending the warmth of house music with the cold structural precision of techno, tech house bridges the divide.";
logo = "http://cdn-images.audioaddict.com/2/7/b/a/7/0/27ba70234566a810d9dd33745195f088.jpg?size=180x180";
station = di-fm-name "Tech House"; station = di-fm-name "Tech House";
stream = di-fm "techhouse"; stream = di-fm "techhouse";
} }
{ {
desc = "Techno is a true musical force full of structure and style. Robotic, mechanical and full of soul, always facing the future."; desc = "Techno is a true musical force full of structure and style. Robotic, mechanical and full of soul, always facing the future.";
logo = "http://cdn-images.audioaddict.com/7/a/3/1/4/a/7a314a3ff87e31013172e9099d9aa843.jpg?size=180x180";
station = di-fm-name "Techno"; station = di-fm-name "Techno";
stream = di-fm "techno"; stream = di-fm "techno";
} }
{ {
desc = "Emotive dance music which embraces incredible melodies, future-facing production and energetic anthems heard worldwide."; desc = "Emotive dance music which embraces incredible melodies, future-facing production and energetic anthems heard worldwide.";
logo = "http://cdn-images.audioaddict.com/b/1/0/5/6/7/b10567777ad265dcc63816fa32396654.jpg?size=180x180";
station = di-fm-name "Trance"; station = di-fm-name "Trance";
stream = di-fm "trance"; stream = di-fm "trance";
} }
{ {
desc = "Born out of Southern Hip-Hop and influenced by techno, trap is analog drum machines / DnB & with hip-hop aesthetics."; desc = "Born out of Southern Hip-Hop and influenced by techno, trap is analog drum machines / DnB & with hip-hop aesthetics.";
logo = "http://cdn-images.audioaddict.com/8/8/6/e/b/2/886eb22e09893237ff5a851991543e4b.jpg?size=180x180";
station = di-fm-name "Trap"; station = di-fm-name "Trap";
stream = di-fm "trap"; stream = di-fm "trap";
} }
{ {
desc = "The percussive side of the house and tech house scene, tribal house takes drums and puts them in the forefront."; desc = "The percussive side of the house and tech house scene, tribal house takes drums and puts them in the forefront.";
logo = "http://cdn-images.audioaddict.com/5/9/d/5/b/0/59d5b064c1bc9e165850a8d9371d32a5.jpg?size=180x180";
station = di-fm-name "Tribal House"; station = di-fm-name "Tribal House";
stream = di-fm "tribalhouse"; stream = di-fm "tribalhouse";
} }
{ {
desc = "UMF Radio 24/7"; desc = "UMF Radio 24/7";
logo = "http://cdn-images.audioaddict.com/b/4/5/7/b/9/b457b9fe45596e28a7c4b7b004c82ce4.jpg?size=180x180";
station = di-fm-name "UMF Radio"; station = di-fm-name "UMF Radio";
stream = di-fm "umfradio"; stream = di-fm "umfradio";
} }
{ {
desc = "From gritty Berlin streets to dark corners of Brooklyn, this is techno made by artists pushing the genre further."; desc = "From gritty Berlin streets to dark corners of Brooklyn, this is techno made by artists pushing the genre further.";
logo = "http://cdn-images.audioaddict.com/9/f/7/1/0/f/9f710f7f4c2a663bab3ff5551f8669eb.jpg?size=180x180";
station = di-fm-name "Underground Techno"; station = di-fm-name "Underground Techno";
stream = di-fm "undergroundtechno"; stream = di-fm "undergroundtechno";
} }
{ {
desc = "Relaxing vibes and a collection of vocal songs providing the laid back soundtrack to your day."; desc = "Relaxing vibes and a collection of vocal songs providing the laid back soundtrack to your day.";
logo = "http://cdn-images.audioaddict.com/5/7/4/8/8/c/57488ced7c732709c72764636b0065dc.jpg?size=180x180";
station = di-fm-name "Vocal Chillout"; station = di-fm-name "Vocal Chillout";
stream = di-fm "vocalchillout"; stream = di-fm "vocalchillout";
} }
{ {
desc = "The glorious 4/4 thump of House music paired perfectly with the human voice. Sultry, soulful, sexy sounds."; desc = "The glorious 4/4 thump of House music paired perfectly with the human voice. Sultry, soulful, sexy sounds.";
logo = "http://cdn-images.audioaddict.com/8/5/a/1/3/b/85a13bb220281bf22bf04d4f1f778b59.jpg?size=180x180";
station = di-fm-name "Vocal House"; station = di-fm-name "Vocal House";
stream = di-fm "vocalhouse"; stream = di-fm "vocalhouse";
} }
{ {
desc = "Laid back grooves and a collection of smooth vocals soothe the ears and relax the mind."; desc = "Laid back grooves and a collection of smooth vocals soothe the ears and relax the mind.";
logo = "http://cdn-images.audioaddict.com/8/4/3/6/f/9/8436f9d3338ba7c8de0e88dbe45ea4d5.jpg?size=180x180";
station = di-fm-name "Vocal Lounge"; station = di-fm-name "Vocal Lounge";
stream = di-fm "vocallounge"; stream = di-fm "vocallounge";
} }
{ {
desc = "Lush vocals paired together with emotive dance music. Beautiful melodies and endless energy."; desc = "Lush vocals paired together with emotive dance music. Beautiful melodies and endless energy.";
logo = "http://cdn-images.audioaddict.com/3/0/9/f/2/4/309f243a8a181ad83e8c5e15cd4b24c3.jpg?size=180x180";
station = di-fm-name "Vocal Trance"; station = di-fm-name "Vocal Trance";
stream = di-fm "vocaltrance"; stream = di-fm "vocaltrance";
} }
@@ -1263,15 +1173,15 @@ importJSON ./radiorecord.json
station = "Dhol Radio"; station = "Dhol Radio";
desc = " "; desc = " ";
} }
{ logo = bhaktiworld-logo; stream = bhaktiworld "2bhanuman"; station = bhaktiworld-name "Hanuman"; } { stream = bhaktiworld "2bhanuman"; station = bhaktiworld-name "Hanuman"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "djbeat"; station = bhaktiworld-name "Mantra Shakti"; } { stream = bhaktiworld "djbeat"; station = bhaktiworld-name "Mantra Shakti"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "gurbani"; station = bhaktiworld-name "Sangam"; } { stream = bhaktiworld "gurbani"; station = bhaktiworld-name "Sangam"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "hot"; station = bhaktiworld-name "Shiv"; } { stream = bhaktiworld "hot"; station = bhaktiworld-name "Shiv"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "ibadat"; station = bhaktiworld-name "Devi Maa"; } { stream = bhaktiworld "ibadat"; station = bhaktiworld-name "Devi Maa"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "iskon2b"; station = bhaktiworld-name "Om Sai"; } { stream = bhaktiworld "iskon2b"; station = bhaktiworld-name "Om Sai"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "millenniumhits"; station = bhaktiworld-name "Krishna"; } { stream = bhaktiworld "millenniumhits"; station = bhaktiworld-name "Krishna"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "dard"; station = bhaktiworld-name "Shri Ram"; } { stream = bhaktiworld "dard"; station = bhaktiworld-name "Shri Ram"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "bhaktiworldindia"; station = bhaktiworld-name "Ganesh"; } { stream = bhaktiworld "bhaktiworldindia"; station = bhaktiworld-name "Ganesh"; }
{ {
station = "Rockabilly Radio"; station = "Rockabilly Radio";
stream = "http://lin3.ash.fast-serv.com:6026/stream_96"; stream = "http://lin3.ash.fast-serv.com:6026/stream_96";
@@ -1427,16 +1337,6 @@ importJSON ./radiorecord.json
station = "The UK 1950s Radio Station"; station = "The UK 1950s Radio Station";
logo = "http://www.1950sukradio.co.uk/images/page_componants/1950s_Station_Logo.png"; logo = "http://www.1950sukradio.co.uk/images/page_componants/1950s_Station_Logo.png";
} }
{
stream = "https://rhb-de-hz-fal-stream02-cluster01.radiohost.de/paradiso-jazz_mp3-128";
station = "Paradiso Jazz";
logo = "https://www.paradiso.de/wp-content/uploads/2019/11/191111_Paradiso-Jazz.jpg";
}
{
stream = "https://rhb-stream20.radiohost.de/paradiso-nashville_mp3-128";
station = "Paradiso Nashville";
logo = "https://www.paradiso.de/wp-content/uploads/2019/11/191111_Paradiso-Nashville.jpg";
}
{ {
stream = stereoscenic "mod-h"; stream = stereoscenic "mod-h";
station = stereoscenic-name "Ambient Modern"; station = stereoscenic-name "Ambient Modern";

View File

@@ -17,7 +17,7 @@ let maplocalleader="\\"
" noremap <Leader>h :<C-u>split<CR> " noremap <Leader>h :<C-u>split<CR>
" noremap <Leader>v :<C-u>vsplit<CR> " noremap <Leader>v :<C-u>vsplit<CR>
noremap <Leader>gs :Git status<CR> noremap <Leader>gs :Git<CR>
noremap <Leader>gc :Git commit<CR> noremap <Leader>gc :Git commit<CR>
noremap <leader>n :bn<CR> noremap <leader>n :bn<CR>
noremap <leader>p :bp<CR> noremap <leader>p :bp<CR>

View File

@@ -22,12 +22,6 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.shellAliases = lib.attrsets.mapAttrs' (name: value:
lib.nameValuePair "traadfri-${name}" "traadfri --target Bulb ${toString value}")
cfg.bulbs // lib.attrsets.mapAttrs' (name: value:
lib.nameValuePair "traadfri-${name}" "traadfri --target Room ${toString value}")
cfg.rooms;
environment.systemPackages = [ environment.systemPackages = [
(pkgs.writers.writeDashBin "traadfri" '' (pkgs.writers.writeDashBin "traadfri" ''
TRAADFRI_USER="${cfg.user}" \ TRAADFRI_USER="${cfg.user}" \
@@ -35,6 +29,11 @@ in {
TRAADFRI_HUB="${cfg.host}" \ TRAADFRI_HUB="${cfg.host}" \
${traadfri}/bin/traadfri $@ ${traadfri}/bin/traadfri $@
'') '')
]; ] ++ lib.mapAttrsToList (name: value: pkgs.writers.writeDashBin "traadfri-${name}" ''
exec traadfri --target Room ${toString value} "$@"
'') cfg.rooms
++ lib.mapAttrsToList (name: value: pkgs.writers.writeDashBin "traadfri-${name}" ''
exec traadfri --target Bulb ${toString value} "$@"
'') cfg.bulbs;
}; };
} }

View File

@@ -0,0 +1,28 @@
regex: https://www.radioeins.de/musik/cd_der_woche/
selectors:
httpsettings:
cookie: {}
header: {}
useragent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/90.0.4430.72 Safari/537.36
insecure: false
feed:
title: .boxhead h2
description: .manualteaserShortText
authorname: ""
authoremail: ""
item:
container: .doctyperezension
title: h2 a.rezension
link: a.rezension
linkattr: href
created: .manualteaserDateTime
createdformat: 02.01.2006
description: .manualteaserShortText
content: ""
image: picture > img
imageattr: src
nextpage: ""
nextpageattr: href
nextpagecount: 0
sort: ""

View File

@@ -322,6 +322,18 @@ in rec {
devanagari = pkgs.callPackage ../devanagari {}; devanagari = pkgs.callPackage ../devanagari {};
timer = pkgs.writers.writeDashBin "timer" ''
[ $# -eq 2 ] || {
echo "Usage: $0 TIME MESSAGE" 1>&2
exit 1
}
time=$(echo "$1" | ${pkgs.bc}/bin/bc)
echo "sleeping $time seconds, then saying: $2"
${pkgs.coreutils}/bin/sleep "$time" && {
echo "$2" | ${pkgs.espeak}/bin/espeak -v german-mbrola-6
}
'';
manual-sort = pkgs.writers.writeHaskellBin "manual-sort" {} '' manual-sort = pkgs.writers.writeHaskellBin "manual-sort" {} ''
{-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-}
import Data.Char (toLower) import Data.Char (toLower)

View File

@@ -15,7 +15,7 @@ twoscreen() { # If multi-monitor is selected and there are two screens.
# Mirror displays using native resolution of external display and a scaled # Mirror displays using native resolution of external display and a scaled
# version for the internal display # version for the internal display
if [ "$mirror" = "yes" ]; then if [ "$mirror" = "yes" ]; then
external=$(echo "$screens" | dmenu -i -p "Optimize resolution for:") external=$(echo "$screens" | dmenu -i -p "Optimize resolution for")
internal=$(echo "$screens" | grep -v "$external") internal=$(echo "$screens" | grep -v "$external")
res_external=$(xrandr --query | sed -n "/^$external/,/\+/p" | \ res_external=$(xrandr --query | sed -n "/^$external/,/\+/p" | \
@@ -38,7 +38,7 @@ twoscreen() { # If multi-monitor is selected and there are two screens.
else else
primary=$(echo "$screens" | dmenu -i -p "Select primary display:") primary=$(echo "$screens" | dmenu -i -p "Select primary display")
secondary=$(echo "$screens" | grep -v "$primary") secondary=$(echo "$screens" | grep -v "$primary")
direction=$(query_direction | dmenu -i -p "What side of $primary should $secondary be on?") direction=$(query_direction | dmenu -i -p "What side of $primary should $secondary be on?")
xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction" "$primary" --auto --scale 1.0x1.0 xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction" "$primary" --auto --scale 1.0x1.0

View File

@@ -1,47 +1,65 @@
{ lib, fetchurl, writeText, writers, coreutils, dmenu, gnused, libnotify, xclip, xdotool }: { lib, runCommand, fetchurl, writeText, writers, coreutils, dmenu, gnused, libnotify, xclip, xdotool, gawk }:
let let
emoji-file = fetchurl { unicode-file = runCommand "unicode.txt" {} ''
url = "https://raw.githubusercontent.com/kmein/unipicker/master/symbols"; ${writers.writePython3 "generate.py" { flakeIgnore = [ "E501" "E722" ]; } ''
sha256 = "1q6ampv4fhdvd0riz4ihx43gkbyvdab4c38q96ybn0ka9d30vi3g"; import csv
};
with open("${fetchurl {
url = "https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt";
sha256 = "sha256-NgGOaGV/3LNIX2NmMP/oyFMuAcl3cD0oA/W4nWxf6vs=";
}}", "r") as unicode_data:
reader = csv.reader(unicode_data, delimiter=";")
next(reader) # skip first row containing \0
for row in reader:
codepoint = row[0]
name = row[1]
alternate_name = row[10]
try:
print(chr(int(codepoint, 16)), codepoint, name, alternate_name, sep=" ")
except:
continue
''} > $out
'';
kaomoji-file = writeText "kaomoji.txt" '' kaomoji-file = writeText "kaomoji.txt" ''
¯\(°_o)/¯ dunno lol shrug dlol ¯\(°_o)/¯ dunno lol shrug dlol
¯\_()_/¯ dunno lol shrug dlol ¯\_()_/¯ dunno lol shrug dlol
( ͡° ͜ʖ ͡°) lenny ( ͡° ͜ʖ ͡°) lenny
¯\_( ͡° ͜ʖ ͡°)_/¯ lenny shrug dlol ¯\_( ͡° ͜ʖ ͡°)_/¯ lenny shrug dlol
( д) aaah sad noo ( д) aaah sad noo
(^o^)丿 hi yay hello (^o^)丿 hi yay hello
(^o^: ups hehe (^o^: ups hehe
(^^) yay (^^) yay
(´) angry argh (´) angry argh
(^_^) byebye!! bye (^_^) byebye!! bye
<(^.^<) <(^.^)> (>^.^)> (7^.^)7 (>^.^<) dance <(^.^<) <(^.^)> (>^.^)> (7^.^)7 (>^.^<) dance
(-.-)Zzz... sleep (-.-)Zzz... sleep
() oh noes woot () oh noes woot
(°°  table flip (°° table flip
() why woot () why woot
(___) gloom I see you (___) gloom I see you
    sad sad
(\/) (°,,,,°) (\/) krebs (\/) (°,,,,°) (\/) krebs
 (ل͜) putting table back (ل͜) putting table back
 \(°°)/   flip all dem tablez \(°°)/ flip all dem tablez
(`ω´) bear look (`ω´) bear look
(ل͜) strong flex muscle bicep (ل͜) strong flex muscle bicep
(ò_óˇ) strong flex muscle bicep (ò_óˇ) strong flex muscle bicep
(><) excite (><) excite
( ` -´).* wizard spell magic ( ` -´).* wizard spell magic
   puss in boots big eye puss in boots big eye
̯̫̯̫(ˆ̮ ̮ˆ) nyan cat ̯̫̯̫(ˆ̮ ̮ˆ) nyan cat
ʕʔ bear ʕʔ bear
(ԾɷԾ) adventure time (ԾɷԾ) adventure time
() happy yay () happy yay
() happy yay () happy yay
(º  º )/ panic (º º )/ panic
𓂺 penis
𓂸 penis
''; '';
in # ref https://github.com/LukeSmithxyz/voidrice/blob/9fe6802122f6e0392c7fe20eefd30437771d7f8e/.local/bin/dmenuunicode in # ref https://github.com/LukeSmithxyz/voidrice/blob/9fe6802122f6e0392c7fe20eefd30437771d7f8e/.local/bin/dmenuunicode
writers.writeDashBin "unicodmenu" '' writers.writeDashBin "unicodmenu" ''
PATH=${lib.makeBinPath [ coreutils dmenu gnused libnotify xclip xdotool ]} PATH=${lib.makeBinPath [ coreutils dmenu gnused libnotify xclip xdotool ]}
chosen=$(cat ${emoji-file} ${kaomoji-file} | dmenu -i -l 10 | sed "s/ .*//") chosen=$(cat ${kaomoji-file} ${unicode-file} | dmenu -p unicode -i -l 10 | sed "s/ .*//")
[ "$chosen" != "" ] || exit [ "$chosen" != "" ] || exit

View File

@@ -1,6 +1,5 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
nixpkgs-unstable = import <nixpkgs-unstable> { config.allowUnfree = true; };
inherit (import <niveum/lib>) retiolumAddresses; inherit (import <niveum/lib>) retiolumAddresses;
in in
{ {
@@ -22,7 +21,7 @@ in
maxJobs = 2; maxJobs = 2;
}; };
environment.systemPackages = [ nixpkgs-unstable.minecraft ]; environment.systemPackages = [ pkgs.minecraft ];
networking = { networking = {
hostName = "kabsa"; hostName = "kabsa";

View File

@@ -1,6 +1,6 @@
{ lib, config, pkgs, ... }: { lib, config, pkgs, ... }:
let let
inherit (import <niveum/lib>) kieran retiolumAddresses; inherit (import <niveum/lib>) kieran retiolumAddresses restic;
in in
{ {
imports = [ imports = [
@@ -9,11 +9,13 @@ in
./hedgedoc.nix ./hedgedoc.nix
./matterbridge.nix ./matterbridge.nix
./menstruation.nix ./menstruation.nix
./moinbot.nix
./horoscopy.nix
./monitoring ./monitoring
./moodle-dl-borsfaye.nix ./moodle-dl-borsfaye.nix
./names.nix ./names.nix
./nextcloud.nix ./nextcloud.nix
./radio ./radio.nix
./retiolum-map.nix ./retiolum-map.nix
./tarot.nix ./tarot.nix
./urlwatch.nix ./urlwatch.nix
@@ -27,6 +29,24 @@ in
<niveum/modules/retiolum.nix> <niveum/modules/retiolum.nix>
]; ];
services.restic.backups.niveum = {
initialize = true;
inherit (restic) repository;
timerConfig = { OnCalendar = "daily"; RandomizedDelaySec = "1h"; };
passwordFile = toString <secrets/restic/password>;
paths = [
"/var/lib/codimd"
"/var/lib/postgresql"
"/var/lib/weechat"
"/var/lib/nextcloud"
"/var/lib/grafana"
"/var/lib/gitea"
"/var/lib/redis"
];
};
nix.nixPath = [ "/var/src" ];
networking = { networking = {
firewall.allowedTCPPorts = [ 80 443 ]; firewall.allowedTCPPorts = [ 80 443 ];
hostName = "makanek"; hostName = "makanek";

View File

@@ -0,0 +1,45 @@
{ pkgs, lib, ... }:
let
port = 5040;
punkt = pkgs.fetchzip {
url = "https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt.zip";
sha256 = "113cv87dj5ml7g8pjm7psk4q1hrf0zqpmc945lmpdz91vp2wn1nc";
};
horoscopy-src = pkgs.fetchzip {
url = "http://c.krebsco.de/horoscopy.tar.gz";
stripRoot = false;
hash = "sha256-KBAbCvayTEr4+cOHnMXHCBA+8RWDMiQF65xzP4fOdaE=";
};
horoscopy = import horoscopy-src;
in
{
systemd.services.horoscopy = {
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
description = "AI astrologer";
serviceConfig = {
DynamicUser = true;
};
environment.NLTK_DATA = pkgs.linkFarm "punkt-tokenizers" [
{ name = "tokenizers/punkt"; path = punkt; }
];
script = ''
cd ${horoscopy-src}
${horoscopy.dependencyEnv}/bin/gunicorn wsgi:app -b :${toString port}
'';
};
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
services.nginx.virtualHosts."horoscopy.kmein.de" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${toString port}";
};
}

View File

@@ -0,0 +1,17 @@
{ pkgs, ... }:
{
systemd.services.moinbot = {
startAt = "7:00";
script = ''
echo moin | ${pkgs.ircaids}/bin/ircsink \
--nick moinbot \
--server irc.hackint.org \
--port 6697 \
--secure \
--target '#hsmr' >/dev/null 2>&1
'';
serviceConfig.DynamicUser = true;
};
systemd.timers.moinbot.timerConfig.RandomizedDelaySec = "14h";
}

View File

@@ -3,7 +3,7 @@
{ {
modules.http_2xx = { modules.http_2xx = {
http = { http = {
fail_if_not_ssl = true; fail_if_not_ssl = false;
ip_protocol_fallback = false; ip_protocol_fallback = false;
method = "GET"; method = "GET";
no_follow_redirects = false; no_follow_redirects = false;

View File

@@ -2,6 +2,7 @@
let let
lokiConfig = import ./loki.nix; lokiConfig = import ./loki.nix;
blackboxConfig = import ./blackbox.nix; blackboxConfig = import ./blackbox.nix;
inherit (import <niveum/lib>) restic;
in in
{ {
services.grafana = { services.grafana = {
@@ -26,7 +27,7 @@ in
alert = "ServiceDown"; alert = "ServiceDown";
expr = ''node_systemd_unit_state{state="failed"} == 1''; expr = ''node_systemd_unit_state{state="failed"} == 1'';
annotations = { annotations = {
summary = "{{$labels.job}}: Service {{$labels.name}} failed to start."; summary = "{{$labels.name}} failed on {{$labels.job}}";
}; };
} }
{ {
@@ -34,8 +35,7 @@ in
for = "10m"; for = "10m";
expr = ''(node_filesystem_free_bytes{mountpoint="/"} * 100) / node_filesystem_size_bytes{mountpoint="/"} < ${toString diskFreeThreshold}''; expr = ''(node_filesystem_free_bytes{mountpoint="/"} * 100) / node_filesystem_size_bytes{mountpoint="/"} < ${toString diskFreeThreshold}'';
annotations = { annotations = {
summary = "{{ $labels.job }}: Filesystem is running out of space soon."; summary = ''{{ $labels.job }} running out of space: {{ $value | printf "%.2f" }}% < ${toString diskFreeThreshold}%'';
description = ''The root disk of {{ $labels.job }} has {{ $value | printf "%.2f" }}% free disk space (threshold at ${toString diskFreeThreshold}%).'';
}; };
} }
{ {
@@ -44,7 +44,7 @@ in
expr = ''node_filesystem_free_bytes{mountpoint="/"} '' expr = ''node_filesystem_free_bytes{mountpoint="/"} ''
+ ''and predict_linear(node_filesystem_free_bytes{mountpoint="/"}[2d], 7*24*3600) <= 0''; + ''and predict_linear(node_filesystem_free_bytes{mountpoint="/"}[2d], 7*24*3600) <= 0'';
annotations = { annotations = {
summary = "{{$labels.job}}: Filesystem is running out of space in 7 days."; summary = "{{$labels.job}} running out of space in 7 days";
}; };
} }
{ {
@@ -52,106 +52,85 @@ in
expr = ''node_load15 / on(job) count(node_cpu_seconds_total{mode="system"}) by (job) >= 1.0''; expr = ''node_load15 / on(job) count(node_cpu_seconds_total{mode="system"}) by (job) >= 1.0'';
for = "10m"; for = "10m";
annotations = { annotations = {
summary = "{{$labels.job}}: Running on high load: {{$value}}"; summary = "{{$labels.job}} running on high load: {{$value}}";
}; };
} }
{ {
alert = "HighRAM"; alert = "HighRAM";
expr = "node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes < node_memory_MemTotal_bytes * 0.1"; expr = "node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes < node_memory_MemTotal_bytes * 0.1";
for = "1h"; for = "1h";
annotations.summary = "{{$labels.job}}: Using lots of RAM."; annotations.summary = "{{$labels.job}} using lots of RAM";
} }
{ {
alert = "UptimeMonster"; alert = "UptimeMonster";
expr = "time() - node_boot_time_seconds > 2592000"; expr = "time() - node_boot_time_seconds > 2592000";
annotations.summary = "{{$labels.job}}: up for more than 30 days."; annotations.summary = "uptime monster {{$labels.job}} up for more than 30 days";
} }
{ {
alert = "HostDown"; alert = "HostDown";
expr = ''up == 0''; expr = ''up == 0'';
for = "5m"; for = "5m";
annotations = { annotations = {
summary = "Host {{ $labels.job }} down for 5 minutes."; summary = "{{ $labels.job }} seeming down since 5 minutes";
}; };
} }
{ {
alert = "Reboot"; alert = "Reboot";
expr = "time() - node_boot_time_seconds < 300"; expr = "time() - node_boot_time_seconds < 300";
annotations.summary = "{{$labels.job}}: Reboot"; annotations.summary = "{{$labels.job}} rebooted";
} }
{ {
alert = "ProbeFailed"; alert = "ProbeFailed";
expr = "probe_success == 0"; expr = "probe_success == 0";
for = "5m"; for = "5m";
annotations.summary = "{{$labels.instance}}: probe failed"; annotations.summary = "HTTP probe failed for {{$labels.instance}}";
} }
{ {
alert = "SlowProbe"; alert = "SlowProbe";
expr = "avg_over_time(probe_http_duration_seconds[1m]) > 1"; expr = "avg_over_time(probe_http_duration_seconds[1m]) > 1";
for = "5m"; for = "5m";
annotations.summary = "{{$labels.instance}}: HTTP probe slow"; annotations.summary = "HTTP probe slow for {{$labels.instance}}";
} }
{ {
alert = "HttpStatusCode"; alert = "HttpStatusCode";
expr = "probe_http_status_code != 0 AND (probe_http_status_code <= 199 OR probe_http_status_code >= 400)"; expr = "probe_http_status_code != 0 AND (probe_http_status_code <= 199 OR probe_http_status_code >= 400)";
for = "5m"; for = "5m";
annotations.summary = "{{$labels.instance}}: status code {{$value}}"; annotations.summary = "status code {{$value}} for {{$labels.instance}}";
} }
{ {
alert = "SslExpirySoon"; alert = "SslExpirySoon";
expr = "probe_ssl_earliest_cert_expiry - time() < 86400 * 30"; expr = "probe_ssl_earliest_cert_expiry - time() < 86400 * 30";
for = "5m"; for = "5m";
annotations.summary = "{{$labels.instance}}: SSL certificate expires in 30 days"; annotations.summary = "SSL certificate for {{$labels.instance}} expires in 30 days";
} }
{ {
alert = "SslExpiry"; alert = "SslExpiry";
expr = "probe_ssl_earliest_cert_expiry - time() <= 0"; expr = "probe_ssl_earliest_cert_expiry - time() <= 0";
for = "5m"; for = "5m";
annotations.summary = "{{$labels.instance}}: SSL certificate has expired"; annotations.summary = "SSL certificate for {{$labels.instance}} has expired";
} }
]; ];
}]; }];
})]; })];
systemd.services.alertmanager-bot-telegram = systemd.services.alertmanager-bot-telegram = {
let
alertmanager-bot-telegram = pkgs.buildGoModule rec {
pname = "alertmanager-bot";
version = "2020-07-13";
src = pkgs.fetchFromGitHub {
owner = "metalmatze";
repo = "alertmanager-bot";
rev = "5efc0bbbf8023d4324e9da98562f064a714a7206";
sha256 = "09cciml1j8x76jpm2v5v6h2q6j1fkhsz1kswslmx8wl4wk40xgp4";
};
vendorSha256 = "1v0fgin8dn81b559zz4lqmrl7hikr46g4gb18sci4riql5qs1isj";
postInstall = ''
install -D ./default.tmpl $out/templates/default.tmpl
'';
};
in {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "ip-up.target" ]; after = [ "ip-up.target" ];
environment.TELEGRAM_ADMIN = "18980945"; environment.TELEGRAM_ADMIN = "18980945";
environment.TELEGRAM_TOKEN = lib.strings.fileContents <system-secrets/telegram/prometheus.token>; environment.TELEGRAM_TOKEN = lib.strings.fileContents <system-secrets/telegram/prometheus.token>;
serviceConfig = { serviceConfig = {
Restart = "on-failure";
RestartSec = "15s";
DynamicUser = true; DynamicUser = true;
StateDirectory = "alertbot"; StateDirectory = "alertbot";
ExecStart = ''${alertmanager-bot-telegram}/bin/alertmanager-bot \ ExecStart = ''${pkgs.alertmanager-bot-telegram}/bin/alertmanager-bot \
--alertmanager.url=http://localhost:9093 --log.level=info \ --alertmanager.url=http://localhost:9093 --log.level=info \
--store=bolt --bolt.path=/var/lib/alertbot/bot.db \ --store=bolt --bolt.path=/var/lib/alertbot/bot.db \
--listen.addr="0.0.0.0:16320" \ --listen.addr="0.0.0.0:16320" \
--template.paths=${pkgs.writeText "template.tmpl" '' --template.paths=${pkgs.writeText "template.tmpl" ''
{{ define "telegram.default" }} {{ define "telegram.default" }}
{{range .Alerts -}} {{range .Alerts -}}
{{ if eq .Status "firing" }} {{.Status}}: {{ index .Annotations "summary"}}
<b>{{ index .Annotations "summary"}}</b>
{{ index .Annotations "description" }}
See on Grafana: http://${config.services.grafana.domain}/d/alpUteInz/niveum
{{ else -}}
RESOLVED 😌 <del>{{ index .Annotations "summary"}}</del>
{{- end }}
{{end -}} {{end -}}
{{end}} {{end}}
''}''; ''}'';
@@ -203,12 +182,24 @@ in
static_configs = [{ static_configs = [{
targets = [ targets = [
"alew.hu-berlin.de" "alew.hu-berlin.de"
"pad.kmein.de"
"code.kmein.de"
"radio.kmein.de"
"tarot.kmein.de"
"cloud.xn--kiern-0qa.de"
"grafana.kmein.r"
"names.kmein.r"
"rrm.r"
"graph.r"
]; ];
}]; }];
} }
{ {
job_name = "zaatar"; job_name = "zaatar";
static_configs = [ { targets = [ "zaatar.r:${toString config.services.prometheus.exporters.node.port}" ]; } ]; static_configs = [ { targets = [
"zaatar.r:${toString config.services.prometheus.exporters.node.port}"
"zaatar.r:${toString restic.port}"
]; } ];
} }
]; ];

127
systems/makanek/radio.nix Normal file
View File

@@ -0,0 +1,127 @@
{ lib, pkgs, config, ... }:
let
inherit (import <niveum/lib>) tmpfilesConfig;
liquidsoapDirectory = "/var/cache/liquidsoap";
icecastPassword = "hackme";
lyrikline-poem = pkgs.writers.writeDash "lyrikline.sh" ''
set -efu
html=$(mktemp)
trap clean EXIT
clean() {
rm "$html"
}
lyrikline=https://www.lyrikline.org
random_route="$(${pkgs.curl}/bin/curl -sSL "$lyrikline/index.php/tools/getrandompoem" --data-raw 'lang=de' --compressed | ${pkgs.jq}/bin/jq -r .link)"
poem_url="$lyrikline$random_route"
${pkgs.curl}/bin/curl -sSL "$poem_url" > "$html"
poem_file="$(${pkgs.gnugrep}/bin/grep -o 'https://.*\.mp3' "$html" | head -n1)"
author="$(${pkgs.htmlq}/bin/htmlq -f "$html" --text '#gedicht-autor')"
title="$(${pkgs.htmlq}/bin/htmlq -f "$html" --text .gedicht-originaltitel)"
echo "annotate:title=\"$title | $poem_url\",artist=\"$author\":$poem_file"
'';
stavenhagen-poem = pkgs.writers.writeDash "stavenhagen.sh" ''
base=https://www.deutschelyrik.de
author=$(${pkgs.curl}/bin/curl -sSL "$base" | ${pkgs.htmlq}/bin/htmlq option --attribute value | shuf -n1)
poem=$(${pkgs.curl}/bin/curl -sSL "$base/$author" | ${pkgs.htmlq}/bin/htmlq '#mnav2 li > a' --attribute href | shuf -n1)
html=$(mktemp)
trap clean EXIT
clean() {
rm "$html"
}
${pkgs.curl}/bin/curl -sSL "$base/$poem" > "$html"
printf "annotate:title=\"%s | %s\",artist=\"%s\":$base/%s\n" \
"$(${pkgs.htmlq}/bin/htmlq --text '.ce_text h1' -f "$html")" \
"$base/$poem" \
"$(${pkgs.htmlq}/bin/htmlq --text 'h1 + p em' -f "$html")" \
"$(${pkgs.htmlq}/bin/htmlq 'audio source' --attribute src -f "$html")"
'';
wikipedia-article = pkgs.writers.writeDash "wikipedia.sh" ''
set -efu
opus=$(mktemp ${liquidsoapDirectory}/wikipedia.XXX.opus)
html=$(mktemp)
trap clean EXIT
clean() {
rm "$html"
}
${pkgs.curl}/bin/curl -sSL https://de.wikipedia.org/wiki/Spezial:Zuf%C3%A4llige_Seite > "$html"
${pkgs.htmlq}/bin/htmlq '.mw-parser-output p' --text -f "$html" \
| ${pkgs.gnused}/bin/sed 's/\[[0-9]\+]//g' \
| ${pkgs.espeak}/bin/espeak -v german-mbrola-6 -w /dev/stdout \
| ${pkgs.opusTools}/bin/opusenc --quiet - "$opus"
printf "annotate:title=\"%s\":%s" \
"$(${pkgs.htmlq}/bin/htmlq -f "$html" --text h1)" \
"$opus"
'';
in {
# https://github.com/savonet/liquidsoap/issues/1043#issuecomment-593354427
services.liquidsoap.streams.radio = pkgs.writeText "lyrikline.liq" ''
set("protocol.external.curl","${pkgs.curl}/bin/curl")
def random_url(script) =
mksafe(audio_to_stereo(request.dynamic.list(
fun () -> list.map(request.create, get_process_lines(script))
)))
end
def make_streams(name, audio, ~description, ~genre) =
output.icecast(%vorbis, audio, mount = name ^ ".ogg", genre = genre, description = description,
port = ${toString config.services.icecast.listen.port},
password = "${icecastPassword}",
)
output.icecast(%opus, audio, mount = name ^ ".opus", genre = genre, description = description,
port = ${toString config.services.icecast.listen.port},
password = "${icecastPassword}",
)
end
make_streams("lyrikline", random_url("${lyrikline-poem}"), description="lyrikline. listen to the poet (unofficial)", genre="poetry")
make_streams("lyrik", random_url("${stavenhagen-poem}"), description="Fritz Stavenhagen Lyrik für alle | www.deutschelyrik.de", genre="poetry")
make_streams("wikipedia", random_url("${wikipedia-article}"), description="Zufällige Artikel von Wikipedia", genre="useless knowledge")
'';
systemd.services.radio.environment.TMPDIR = liquidsoapDirectory;
systemd.tmpfiles.rules = [
(tmpfilesConfig {
type = "d";
path = liquidsoapDirectory;
mode = "0750";
user = "liquidsoap";
group = "liquidsoap";
age = "1h";
})
];
services.icecast = {
enable = true;
hostname = "radio.kmein.de";
admin.password = "hackme";
listen.port = 6457;
extraConf = ''
<authentication>
<source-password>${icecastPassword}</source-password>
</authentication>
'';
};
services.nginx.virtualHosts."radio.kmein.de" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${toString config.services.icecast.listen.port}";
};
}

View File

@@ -1,212 +0,0 @@
{ lib, pkgs, config, ... }:
let
inherit (import <niveum/lib>) tmpfilesConfig serveHtml;
radioStore = "/var/lib/radio";
htgenPort = 8080;
stations = {
lyrikline = {
streamPort = 8001;
mpdPort = 6601;
description = ''
Weltklang. Welt als ewiges Gedicht, das seine Schallspuren durch Raum und Zeit jagt. Endlose Zufallswiedergabe von <a href="//lyrikline.org">lyrikline</a>. Listen to the sound of voices and poems permeating linguistic and geographic barriers, 24 hours per day.
'';
};
lyrik = {
streamPort = 8002;
mpdPort = 6602;
description = ''
Deutsche Lyrik, die du noch nicht gut genug kennst. Tritt in einen Fluss aus Reim und Maß; keine zwei Mal ist er derselbe.
'';
};
};
mpd-add-with-tags = pkgs.writers.writeHaskell "mpd-add-with-tags" {
libraries = with pkgs.haskellPackages; [ optparse-generic libmpd ];
} ''
{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}
import Control.Monad (void)
import Data.String
import Network.MPD
import Options.Generic
data Options = Options { url :: String, artist :: Maybe String, title :: Maybe String }
deriving (Generic)
instance ParseRecord Options
main :: IO ()
main = do
options <- getRecord "Add to MPD with tags"
void $ withMPD $ do
songId <- addId (fromString $ url options) Nothing
maybe (pure ()) (addTagId songId Artist . fromString) $ artist options
maybe (pure ()) (addTagId songId Title . fromString) $ title options
'';
mpcs = lib.mapAttrs (name: station: pkgs.writers.writeDashBin "mpc-${name}" ''
MPD_PORT=${toString station.mpdPort} ${pkgs.mpc_cli}/bin/mpc "$@"
'') stations;
in
{
imports = [ <stockholm/krebs/3modules/htgen.nix> ];
nixpkgs.overlays = [
(self: super: { htgen = super.callPackage <stockholm/krebs/5pkgs/simple/htgen> {}; })
];
systemd.tmpfiles.rules = [
(tmpfilesConfig {
type = "d";
path = radioStore;
mode = "0755";
user = config.users.extraUsers.radio.name;
age = "1d";
})
];
users.extraUsers.radio = {
isSystemUser = true;
group = "radio";
};
users.groups.radio = {};
krebs.htgen.radio = {
port = htgenPort;
user.name = "radio";
script = ''. ${pkgs.writers.writeDash "meinskript" ''
send200() {
printf 'HTTP/1.1 200 OK\r\n'
printf 'Content-Type: text/html; charset=UTF-8\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
}
case "$Method $Request_URI" in
"GET /lyrik/status")
send200
video_id="$(
${mpcs.lyrik}/bin/mpc-lyrik status -f %file% \
| head -n1 \
| grep -o 'id=[^&]*' \
| sed 's/^id=//g'
)"
${pkgs.youtube-dl}/bin/youtube-dl -j "https://www.youtube.com/watch?v=$video_id" \
| ${pkgs.jq}/bin/jq -r '"% [\(.title)](\(.webpage_url))\n\n\(.description)"' \
| sed 's/$/ /g' \
| ${pkgs.pandoc}/bin/pandoc -s
exit
;;
"GET /lyrikline/status")
send200
hash="$(
${mpcs.lyrikline}/bin/mpc-lyrikline status -f '%file%' \
| head -n 1 \
| md5sum \
| cut -d' ' -f 1
)"
url="$(cat ${radioStore}/$hash)"
echo "<html><body style='margin:0'><iframe style='width:100%;height:100%;border:0' src="$url"></iframe></body></html>"
exit
;;
esac
''}'';
};
containers = lib.mapAttrs (name: station: {
autoStart = true;
config = {config, pkgs, ...}: {
services.mpd = {
enable = true;
network.port = station.mpdPort;
extraConfig = ''
log_level "default"
audio_output {
name "${name}"
type "httpd"
encoder "vorbis"
port "${toString station.streamPort}"
bitrate "128"
format "44100:16:2"
always_on "yes"
tags "yes"
}
'';
};
};
}) stations;
environment.systemPackages = lib.attrValues mpcs;
systemd.services.lyrikline = {
after = [ "container@lyrikline.service" ];
wantedBy = [ "container@lyrikline.service" ];
startAt = "*:00/5";
serviceConfig.User = config.users.extraUsers.radio.name;
preStart = "${mpcs.lyrikline}/bin/mpc-lyrikline crop || :";
script = ''
set -efu
lyrikline=https://www.lyrikline.org
for _ in $(seq 1 10); do
random_route="$(${pkgs.curl}/bin/curl -sSL "$lyrikline/index.php/tools/getrandompoem" --data-raw 'lang=de' --compressed | ${pkgs.jq}/bin/jq -r .link)"
poem_url="$lyrikline$random_route"
poem_file="$(
${pkgs.curl}/bin/curl -sSL "$poem_url" \
| grep -o 'https://.*\.mp3' \
| head -n1
)"
hash="$(echo "$poem_file" | md5sum | cut -d' ' -f 1)"
echo "$poem_file ($hash) -> $poem_url"
echo "$poem_url" > "${radioStore}/$hash"
${mpcs.lyrikline}/bin/mpc-lyrikline add "$poem_file"
done
${mpcs.lyrikline}/bin/mpc-lyrikline play
'';
};
systemd.services.lyrik = {
after = [ "container@lyrik.service" ];
wantedBy = [ "container@lyrik.service" ];
preStart = "${mpcs.lyrik}/bin/mpc-lyrik crop || :";
restartIfChanged = true;
serviceConfig.User = config.users.extraUsers.radio.name;
script =
let
invidious = "https://invidious.silkky.cloud";
videoIds = import <niveum/lib/hot-rotation/lyrik.nix>;
streams = lib.concatMapStringsSep "\n" (id: "${invidious}/latest_version?id=${id}&itag=251") videoIds;
streamsFile = pkgs.writeText "hotrot" streams;
in ''
set -efu
${mpcs.lyrik}/bin/mpc-lyrik add < ${toString streamsFile}
${mpcs.lyrik}/bin/mpc-lyrik crossfade 5
${mpcs.lyrik}/bin/mpc-lyrik random on
${mpcs.lyrik}/bin/mpc-lyrik repeat on
${mpcs.lyrik}/bin/mpc-lyrik play
'';
};
services.nginx.virtualHosts."radio.kmein.de" = {
enableACME = true;
forceSSL = true;
locations = lib.mkMerge (
[
{ "/".extraConfig = serveHtml (import ./station-list.nix { inherit pkgs lib stations; }) pkgs; }
] ++ (lib.mapAttrsToList (name: station: {
"= /${name}/status".proxyPass = "http://127.0.0.1:${toString htgenPort}";
"= /${name}/listen.ogg".proxyPass = "http://127.0.0.1:${toString station.streamPort}";
"= /${name}.ogg".return = "301 http://radio.xn--kiern-0qa.de/${name}/listen.ogg"; # legacy
}) stations)
);
};
}

View File

@@ -1,43 +0,0 @@
{ pkgs, lib, stations }:
let
theStations = lib.mapAttrsToList (name: value: value // {name = name;}) stations;
in
pkgs.writeText "index.html" ''
<!doctype html>
<html>
<head>
<title>radio.kierán</title>
<link
rel="stylesheet"
href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.2/css/bulma.min.css"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf-8" />
</head>
<body>
<main class="section">
<div class="subtitle is-3">Welcome to</div>
<h1 class="title is-1">radio.kierán</h1>
<div class="columns is-multiline">
${lib.concatMapStringsSep "\n" (station: ''
<div class="column">
<div class="box">
<strong class="is-uppercase">${station.name}</strong>
(<a href="/${station.name}/status">status</a>, <a href="/${station.name}/listen.ogg">link</a>)
<p class="has-text-grey">${station.description}</p>
<hr/>
<audio style="width:100%" controls src="/${station.name}/listen.ogg"/>
</div>
</div>'') theStations
}
</div>
</main>
</body>
</html>
''

View File

@@ -12,6 +12,8 @@ let
}; };
in in
{ {
imports = [ <stockholm/krebs/3modules/htgen.nix> ];
krebs.htgen.tarot = { krebs.htgen.tarot = {
port = tarotPort; port = tarotPort;
user.name = "radio"; user.name = "radio";

View File

@@ -140,7 +140,7 @@ in
systemd.services.urlwatch = { systemd.services.urlwatch = {
enable = true; enable = true;
startAt = "*-*-* 05:00:00"; startAt = "12:00";
script = '' script = ''
${urlwatch}/bin/urlwatch \ ${urlwatch}/bin/urlwatch \
--config=${lib.escapeShellArg configFile} \ --config=${lib.escapeShellArg configFile} \

View File

@@ -31,6 +31,7 @@ in {
settings = let nick = "kmein"; in { settings = let nick = "kmein"; in {
weechat = { weechat = {
look.mouse = true; look.mouse = true;
look.prefix_align_max = 15;
color.chat_nick_colors = lib.lists.subtractLists (lib.range 52 69 ++ lib.range 231 248) (lib.range 31 254); color.chat_nick_colors = lib.lists.subtractLists (lib.range 52 69 ++ lib.range 231 248) (lib.range 31 254);
}; };
irc = { irc = {
@@ -43,7 +44,7 @@ in {
msg_part = "tschö mit ö"; msg_part = "tschö mit ö";
msg_quit = "ciao kakao"; msg_quit = "ciao kakao";
msg_kick = "warum machst du diese?"; msg_kick = "warum machst du diese?";
realname = kieran.name; realname = lib.head (lib.strings.split " " kieran.name);
}; };
server = { server = {
hackint = { hackint = {
@@ -60,7 +61,7 @@ in {
autoconnect = true; autoconnect = true;
address = "irc.libera.chat/6697"; address = "irc.libera.chat/6697";
ssl = true; ssl = true;
autojoin = [ "#flipdot" "#haskell" "#nixos" "#fysi" "#binaergewitter" ]; autojoin = [ "#flipdot" "#haskell" "#nixos" "#fysi" "#binaergewitter" "#neovim" "#lojban" "#vim" ];
sasl_mechanism = "plain"; sasl_mechanism = "plain";
sasl_username = nick; sasl_username = nick;
sasl_password = lib.strings.fileContents <system-secrets/irc/libera>; sasl_password = lib.strings.fileContents <system-secrets/irc/libera>;
@@ -114,11 +115,11 @@ in {
zerocovid = { zerocovid = {
buffer = "*"; buffer = "*";
tags = "*"; tags = "*";
regex = "[kc]orona|💉|🤒|😷|[kc]ovid|virus|lockdown|va[kc][sc]in|mutante|mutation|impf|pandemi|κορ[ωο]ν[αο]ϊό|корона|expert|infe[ck]t|infizi|in[cz]iden[cz]|sars-cov|drosten|virolog|lauterbach|delta|omi[ck]ron|epidemi|booster|r-wert"; regex = "[kc]orona|💉|🤒|😷|[kc]ovid|virus|lockdown|va[kc][sc]in|vaxx|mutante|mutation|impf|pandemi|κορ[ωο]ν[αο]ϊό|корона|expert|infe[ck]t|infizi|in[cz]iden[cz]|sars-cov|drosten|virolog|lauterbach|delta|omi[ck]ron|epidemi|booster|r-wert";
}; };
joinquit = { smart = {
buffer = "*"; buffer = "*";
tags = [ "irc_join" "irc_part" "irc_quit" "irc_nick" ]; tags = "irc_smart_filter";
regex = "*"; regex = "*";
}; };
playlist_topic = { playlist_topic = {
@@ -131,6 +132,11 @@ in {
tags = "irc_notice"; tags = "irc_notice";
regex = "*"; regex = "*";
}; };
bots = {
buffer = "irc.retiolum.*";
tags = [ "nick_gitlab" ];
regex = "*";
};
}; };
}; };
extraCommands = ''/matrix connect nibbana''; extraCommands = ''/matrix connect nibbana'';

42
systems/zaatar/backup.nix Normal file
View File

@@ -0,0 +1,42 @@
{ pkgs, lib, ... }:
let
niveumLib = import <niveum/lib>;
inherit (niveumLib) retiolumAddresses restic;
firewall = niveumLib.firewall lib;
dataDir = "/backup/restic";
in
{
services.restic.server = {
enable = true;
appendOnly = true;
inherit dataDir;
prometheus = true;
extraFlags = [ "--no-auth" ]; # auth is done via firewall
listenAddress = ":${toString restic.port}";
};
environment.systemPackages = [
(pkgs.writers.writeDashBin "restic-niveum" ''
exec ${pkgs.util-linux}/bin/runuser -u restic -g restic ${pkgs.restic}/bin/restic -r ${toString dataDir} -p ${<secrets/restic/password>} "$@"
'')
];
fileSystems."/backup" = {
device = "/dev/disk/by-id/ata-ST500LM021-1KJ152_W626LS9M";
fsType = "ext4";
};
networking.firewall =
let
dport = restic.port;
protocol = "tcp";
rules = [
(firewall.accept { inherit dport protocol; source = retiolumAddresses.kabsa.ipv4; })
(firewall.accept { inherit dport protocol; source = retiolumAddresses.manakish.ipv4; })
(firewall.accept { inherit dport protocol; source = retiolumAddresses.makanek.ipv4; })
];
in {
extraCommands = firewall.addRules rules;
extraStopCommands = firewall.removeRules rules;
};
}

View File

@@ -1,9 +1,10 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
inherit (import <niveum/lib>) retiolumAddresses; inherit (import <niveum/lib>) retiolumAddresses restic;
in in
{ {
imports = [ imports = [
./backup.nix
./gaslight.nix ./gaslight.nix
./hardware-configuration.nix ./hardware-configuration.nix
./kiosk.nix ./kiosk.nix
@@ -11,6 +12,7 @@ in
./pulseaudio.nix ./pulseaudio.nix
./tuna.nix ./tuna.nix
./grocy.nix ./grocy.nix
./spotifyd.nix
<home-manager/nixos> <home-manager/nixos>
<niveum/configs/keyboard.nix> <niveum/configs/keyboard.nix>
<niveum/configs/monitoring.nix> <niveum/configs/monitoring.nix>
@@ -24,6 +26,16 @@ in
<niveum/modules/retiolum.nix> <niveum/modules/retiolum.nix>
]; ];
services.restic.backups.moodle-dl = {
initialize = true;
inherit (restic) repository;
timerConfig = { OnCalendar = "daily"; RandomizedDelaySec = "1h"; };
passwordFile = toString <secrets/restic/password>;
paths = [
"/var/lib/moodle-dl"
];
};
nix.nixPath = [ "/var/src" ]; nix.nixPath = [ "/var/src" ];
services.logind = { services.logind = {

View File

@@ -1,6 +1,6 @@
{ {
services.grocy = { services.grocy = {
enable = true; enable = false;
hostName = "grocy.kmein.r"; hostName = "grocy.kmein.r";
nginx.enableSSL = false; nginx.enableSSL = false;
settings.calendar.firstDayOfWeek = 1; settings.calendar.firstDayOfWeek = 1;

View File

@@ -10,7 +10,7 @@
user = config.users.extraUsers.kiosk.name; user = config.users.extraUsers.kiosk.name;
extraArguments = [ "-s" ]; # allow vt switching extraArguments = [ "-s" ]; # allow vt switching
program = program =
let startUrls = [ "https://open.spotify.com" "https://youtube.com" "http://bvg.kmein.r" ]; let startUrls = [ "https://youtube.com" "http://radio.kmein.r" ];
in pkgs.writers.writeDash "kiosk-browser" '' in pkgs.writers.writeDash "kiosk-browser" ''
while true; do while true; do
${pkgs.brave}/bin/brave \ ${pkgs.brave}/bin/brave \

View File

@@ -1,8 +1,5 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
{ {
imports = [ <niveum/modules/spotifyd.nix> ];
disabledModules = [ "services/audio/spotifyd.nix" ];
services.spotifyd = { services.spotifyd = {
enable = true; enable = true;
settings = { settings = {

View File

@@ -81,6 +81,7 @@ in
stations = lib.lists.imap0 (id: {desc ? "", logo ? "https://picsum.photos/seed/${builtins.hashString "md5" stream}/300", stream, station}: { inherit id desc logo stream station; }) streams; stations = lib.lists.imap0 (id: {desc ? "", logo ? "https://picsum.photos/seed/${builtins.hashString "md5" stream}/300", stream, station}: { inherit id desc logo stream station; }) streams;
stationsJson = (pkgs.formats.json {}).generate "stations.json" stations; stationsJson = (pkgs.formats.json {}).generate "stations.json" stations;
in { in {
enable = false;
wantedBy = [ "tuna.service" ]; wantedBy = [ "tuna.service" ];
startAt = "hourly"; startAt = "hourly";
script = '' script = ''
@@ -95,7 +96,6 @@ in
}; };
/*
services.nginx = { services.nginx = {
enable = true; enable = true;
recommendedGzipSettings = true; recommendedGzipSettings = true;
@@ -110,5 +110,4 @@ in
}; };
}; };
}; };
*/
} }