1
0
mirror of https://github.com/kmein/niveum synced 2026-03-20 12:01:06 +01:00

1 Commits

Author SHA1 Message Date
06c1be9e09 wip: flakes 2021-12-29 17:41:53 +01:00
117 changed files with 2113 additions and 2071 deletions

View File

@@ -1 +0,0 @@
ssh mud@hotdog.r -t "MUD_NICKNAME=$LOGNAME mud"

View File

@@ -1,49 +0,0 @@
import ephem
from datetime import datetime, date, timedelta
now = datetime.now()
limit = now + timedelta(days=365)
def events_until(limit):
initial_date = ephem.Date(datetime.now())
events = {}
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_full_moon(now)
events[now] = "🌕"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_new_moon(now)
events[now] = "🌑"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_vernal_equinox(now)
events[now] = "spring equinox"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_autumnal_equinox(now)
events[now] = "fall equinox"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_winter_solstice(now)
events[now] = "winter solstice"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_summer_solstice(now)
events[now] = "summer solstice"
return events
events = events_until(limit)
for date, event in sorted(events.items(), key=lambda x: x[0]):
if ephem.localtime(date) < limit:
print(ephem.localtime(date), event)

View File

@@ -1,19 +0,0 @@
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

View File

@@ -1,14 +0,0 @@
name: CI
on:
push:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
system: [makanek,manakish,kabsa,zaatar]
steps:
- uses: actions/checkout@v2
- uses: cachix/install-nix-action@v16
- run: nix run .#build-${{matrix.system}}

9
.gitmodules vendored Normal file
View File

@@ -0,0 +1,9 @@
[submodule "submodules/menstruation-telegram"]
path = submodules/menstruation-telegram
url = https://github.com/kmein/menstruation-telegram
[submodule "submodules/menstruation-backend"]
path = submodules/menstruation-backend
url = https://github.com/kmein/menstruation.rs
[submodule "submodules/nur-packages"]
path = submodules/nur-packages
url = git@github.com:kmein/nur-packages.git

View File

@@ -0,0 +1,11 @@
{
"url": "https://github.com/nix-community/home-manager.git",
"rev": "697cc8c68ed6a606296efbbe9614c32537078756",
"date": "2021-12-19T00:59:29+01:00",
"path": "/nix/store/fb46bv10azrag2jjlzhil6j11f4x8glw-home-manager",
"sha256": "1c8gxm86zshr2zj9dvr02qs7y3m46gqavr6wyv01r09jfd99dxz9",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

11
.versions/krops.json Normal file
View File

@@ -0,0 +1,11 @@
{
"url": "https://cgit.krebsco.de/krops",
"rev": "cccebf3ff7a53336b3f106cb96dddd5892d427ed",
"date": "2021-03-23T22:47:37+01:00",
"path": "/nix/store/mz13xxnil35lwsf90hwnrm2agir7hb51-krops",
"sha256": "07mg3iaqjf1w49vmwfchi7b1w55bh7rvsbgicp2m47gnj9alwdb6",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

View File

@@ -0,0 +1,11 @@
{
"url": "https://cgit.krebsco.de/nix-writers",
"rev": "c528cf970e292790b414b4c1c8c8e9d7e73b2a71",
"date": "2019-04-02T20:05:33+02:00",
"path": "/nix/store/wm5zhsha1a2iy0d582nlfi7604ayd1vz-nix-writers",
"sha256": "0xdivaca1hgbxs79jw9sv4gk4f81vy8kcyaff56hh2dgq2awyvw4",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

View File

@@ -0,0 +1,11 @@
{
"url": "https://github.com/mozilla/nixpkgs-mozilla",
"rev": "7c1e8b1dd6ed0043fb4ee0b12b815256b0b9de6f",
"date": "2021-12-07T09:28:33-05:00",
"path": "/nix/store/pqwcw589i2y2w2116wn3ifl834adjsa0-nixpkgs-mozilla",
"sha256": "1a71nfw7d36vplf89fp65vgj3s66np1dc0hqnqgj5gbdnpm1bihl",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

View File

@@ -0,0 +1,11 @@
{
"url": "https://github.com/NixOS/nixpkgs.git",
"rev": "f01adc7b35a8f80e82f3466e6d873b8b9c8f1b28",
"date": "2021-12-22T23:05:28+01:00",
"path": "/nix/store/zhfrvg77dzpc3hq02v9zv20dfgqwpzk6-nixpkgs",
"sha256": "17iyf2iiizi7c1wr71day3wvgalbkkm2zgc9lpy7y42rl4frq9sf",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

11
.versions/nixpkgs.json Normal file
View File

@@ -0,0 +1,11 @@
{
"url": "https://github.com/NixOS/nixpkgs.git",
"rev": "9ab7d12287ced0e1b4c03b61c781901f178d9d77",
"date": "2021-12-21T10:09:48+01:00",
"path": "/nix/store/minmlh0avkwvvc3p7flhpbglp13kr585-nixpkgs",
"sha256": "0bbd2pgcyavqn5wgq0xp8p67lha0kv9iqnh49i9w5fb5g29q7i30",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

11
.versions/retiolum.json Normal file
View File

@@ -0,0 +1,11 @@
{
"url": "https://github.com/krebs/retiolum",
"rev": "b72b0a987767b587c79cba8499b5114d69fceeef",
"date": "2021-12-28T19:46:45+00:00",
"path": "/nix/store/kyaqwf89v6id9mda92x4b0hf778j987x-retiolum",
"sha256": "19hjzzlfk1m9ign33w4ppqgmg23v7c6k8l0fm7f33spq8982w7rb",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

11
.versions/stockholm.json Normal file
View File

@@ -0,0 +1,11 @@
{
"url": "https://cgit.lassul.us/stockholm",
"rev": "576c05cf3a0ceddefa29c2d0073108177c3cfa52",
"date": "2021-12-22T13:59:46+01:00",
"path": "/nix/store/yx1j5pardgd9114f0cf3c4xjfq6r4yfv-stockholm",
"sha256": "18napi4k8i2iizrismlp9ha3ga6c3n2dvrhijy59kl1jxqrsaq9l",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
}

67
ci.nix
View File

@@ -1,67 +0,0 @@
{ inputs, system, name }:
let
inherit (inputs) nixpkgs;
pkgs = nixpkgs.legacyPackages.${system};
ensureFiles = paths: pkgs.runCommand "directory" {} ''
set -efu
mkdir $out
cd $out
${nixpkgs.lib.concatMapStringsSep "\n" (path: ''
mkdir -p "$(dirname ${nixpkgs.lib.escapeShellArg path})"
echo foo > ${nixpkgs.lib.escapeShellArg path}
'') paths}
'';
nixPath = nixpkgs.lib.concatStringsSep ":" ([
"niveum=${toString ./.}"
"nixos-config=${toString ./.}/systems/${name}/configuration.nix"
"system-secrets=${systemSecrets}"
"secrets=${sharedSecrets}"
] ++ nixpkgs.lib.mapAttrsToList (name: value: "${name}=${value}") inputs);
# cd ~/.password-store/shared && find * -type f | sed 's/.gpg$//'
sharedSecrets = ensureFiles [
"di.fm/key"
"eduroam/identity"
"eduroam/password"
"mail/cock"
"mail/fastmail"
"mail/gmail/amroplay"
"mail/gmail/kieran.meinhardt"
"mail/meinhaki"
"mail/posteo"
"nextcloud-fysi/password"
"nextcloud/password"
"openweathermap.key"
"restic/password"
"traadfri.key"
"wifi/Aether.psk"
"spotify/username"
"spotify/password"
];
systemSecrets = let basic = [ "retiolum.ed25519" "retiolum.key" "syncthing/cert.pem" "syncthing/key.pem"]; in {
zaatar = ensureFiles ([ "moodle.token" "telegram/moodle-dl.token" "mpd-web.key" ] ++ basic);
kabsa = ensureFiles basic;
manakish = ensureFiles basic;
makanek = ensureFiles ([
"irc/retiolum"
"irc/hackint"
"irc/libera"
"irc/oftc"
"matrix/nibbana"
"maxmind/license.key"
"moodle-dl/faye.token"
"nextcloud/admin"
"nextcloud/database"
"telegram/nachtischsatan.token"
"telegram/reverse.token"
"telegram/odyssey.token"
"telegram/betacode.token"
"telegram/moodle-dl.token"
"telegram/proverb.token"
"telegram/menstruation.token"
"telegram/cool_village.token"
"telegram/kmein.token"
"telegram/prometheus.token"
"weechat/relay"
] ++ basic);
}.${name};
in toString (pkgs.writers.writeDash "build" "NIX_PATH=${nixPath} nix-build '<nixpkgs/nixos>' -A system --dry-run")

View File

@@ -1,44 +0,0 @@
{ 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"
'')
];
}

57
configs/bvg.nix Normal file
View File

@@ -0,0 +1,57 @@
{ pkgs, lib, ... }:
let
inherit (import <niveum/lib>) serveHtml;
stations = [
900068204 # A/M
900068302 # KAS
900068203 # B-P
];
fahrplan = pkgs.writeText "fahrplan.html" ''
<!DOCTYPE html>
<title>Fahrplan</title>
<link
rel="icon"
type="image/x-icon"
href="https://mobil.bvg.de/Fahrinfo/img/ua_xhtml/logo.gif"
/>
<style>
body {
margin: 0;
--bvg-yellow: #f0d722;
}
#fahrplan {
display: flex;
height: 100vh;
width: 100%;
flex-direction: row;
}
#fahrplan iframe {
flex-grow: 1;
border: none;
}
#fahrplan iframe + iframe {
border-left: 2px solid var(--bvg-yellow);
}
</style>
<body>
<div id="fahrplan">
${lib.concatMapStrings (station: ''
<iframe scrolling="no" src="https://mobil.bvg.de/Fahrinfo/bin/stboard.bin/dox?ld=0.1&input=${toString station}&boardType=depRT&start=yes"></iframe>
'') stations}
</div>
</body>
'';
in
{
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
services.nginx.virtualHosts."bvg.kmein.r" = {
locations."/".extraConfig = serveHtml fahrplan pkgs;
};
}

View File

@@ -10,7 +10,7 @@
]; ];
}; };
environment.systemPackages = [ pkgs.brave ]; environment.systemPackages = [ pkgs.chromium pkgs.brave ];
environment.variables.BROWSER = "brave"; environment.variables.BROWSER = "brave";
} }

View File

@@ -1,12 +1,4 @@
{ config, lib, pkgs, ... }: { { config, lib, pkgs, ... }: {
imports = [
<niveum/modules/dropbox.nix>
];
niveum = {
dropbox.enable = false;
};
system.activationScripts.home-symlinks = '' system.activationScripts.home-symlinks = ''
ln -sfn ${config.users.users.me.home}/cloud/syncthing/common/mahlzeit ${config.users.users.me.home}/mahlzeit ln -sfn ${config.users.users.me.home}/cloud/syncthing/common/mahlzeit ${config.users.users.me.home}/mahlzeit
ln -sfn ${config.users.users.me.home}/cloud/Seafile/Wiki ${config.users.users.me.home}/notes ln -sfn ${config.users.users.me.home}/cloud/Seafile/Wiki ${config.users.users.me.home}/notes
@@ -14,10 +6,7 @@
''; '';
home-manager.users.me = { home-manager.users.me = {
services.nextcloud-client = { services.nextcloud-client.enable = true;
enable = true;
startInBackground = true;
};
}; };
environment.systemPackages = [ environment.systemPackages = [

View File

@@ -1,18 +1,16 @@
{ pkgs, lib, config, options, ... }: { inputs, pkgs, lib, config, options, ... }:
let let
inherit (lib.strings) makeBinPath; inherit (lib.strings) makeBinPath;
inherit (import <niveum/lib>) localAddresses kieran; inherit (import <niveum/lib>) localAddresses kieran;
in { in {
imports = [ imports = [
<home-manager/nixos> ../modules/system-dependent.nix
<niveum/modules/system-dependent.nix>
{ {
boot.supportedFilesystems = [ "ntfs" ]; boot.supportedFilesystems = [ "ntfs" ];
} }
{ {
nix.nixPath = [ nix.nixPath = [
"/var/src" "/var/src"
"nixpkgs-overlays=${toString ../overlays}"
]; ];
} }
{ {
@@ -20,16 +18,14 @@ 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> {};
iolanguage = pkgs.callPackage <niveum/packages/iolanguage.nix> { }; iolanguage = pkgs.callPackage <niveum/packages/iolanguage.nix> { };
ix = pkgs.callPackage <niveum/packages/ix.nix> { }; ix = pkgs.callPackage <niveum/packages/ix.nix> { };
}; };
}; };
overlays = [ overlays = [
(self: super: { (self: super: {
scripts = import <niveum/packages/scripts> { pkgs = super; lib = super.lib; }; scripts = import <niveum/packages/scripts> { pkgs = super; inherit lib; };
}) })
]; ];
}; };
@@ -137,7 +133,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_DK.UTF-8"; } { i18n.defaultLocale = "en_GB.UTF-8"; }
{ {
services.xserver = { services.xserver = {
enable = true; enable = true;
@@ -195,23 +191,23 @@ in {
}) localAddresses; }) localAddresses;
} }
./alacritty.nix ./alacritty.nix
./backup.nix
./bash.nix ./bash.nix
./beets.nix ./beets.nix
./bluetooth.nix ./bluetooth.nix
./ccc.nix ./ccc.nix
# ./kleiter.nix
./khal.nix ./khal.nix
./chromium.nix ./chromium.nix
./cloud.nix ./cloud.nix
./copyq.nix ./copyq.nix
./compton.nix ./compton.nix
./direnv.nix ./direnv.nix
./distrobump.nix
./docker.nix ./docker.nix
./dunst.nix ./dunst.nix
./flix.nix ./flix.nix
./fonts.nix ./fonts.nix
./fzf.nix ./fzf.nix
./gaslight.nix
./git.nix ./git.nix
./hledger.nix ./hledger.nix
./htop.nix ./htop.nix
@@ -221,13 +217,13 @@ in {
./lb.nix ./lb.nix
./mpv.nix ./mpv.nix
./mime.nix ./mime.nix
./nano.nix
./neovim.nix ./neovim.nix
./neomutt.nix ./neomutt.nix
./nix.nix ./nix.nix
./newsboat.nix ./newsboat.nix
./flameshot-once.nix ./flameshot-once.nix
./packages.nix ./packages
./stardict.nix
./power-action.nix ./power-action.nix
./printing.nix ./printing.nix
./openweathermap.nix ./openweathermap.nix
@@ -243,8 +239,10 @@ in {
./sxiv.nix ./sxiv.nix
./theming.nix ./theming.nix
./tmux.nix ./tmux.nix
# ./tor.nix
./traadfri.nix ./traadfri.nix
./unclutter.nix ./unclutter.nix
./version.nix
./vscode.nix ./vscode.nix
./watson.nix ./watson.nix
./zsh.nix ./zsh.nix

View File

@@ -1,10 +0,0 @@
{ lib, config, pkgs, ... }: {
imports = [
(import <stockholm/makefu/3modules/bump-distrowatch.nix> {
inherit lib config;
pkgs = pkgs // { writeDash = pkgs.writers.writeDash; };
})
];
makefu.distrobump.enable = false;
}

View File

@@ -1,42 +1,24 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let let
inherit (import <niveum/lib>) defaultApplications; inherit (import <niveum/lib>) defaultApplications;
flameshot-once = flameshot-once = pkgs.callPackage <stockholm/krebs/5pkgs/simple/flameshot-once> {};
pkgs.callPackage <stockholm/krebs/5pkgs/simple/flameshot-once> {};
in { in {
nixpkgs.overlays = [
(self: super: {
write =
super.callPackage <stockholm/krebs/5pkgs/simple/xwaitforwindow.nix> { };
})
];
environment.systemPackages = [ environment.systemPackages = [
(flameshot-once.override { (flameshot-once.override {
config = { config.imgur = {
imgur = { enable = true;
enable = true; createUrl = "http://p.r/image";
createUrl = "http://p.r/image"; deleteUrl = "http://p.r/image/delete/%1";
deleteUrl = "http://p.r/image/delete/%1"; xdg-open.browser = (defaultApplications pkgs).browser;
xdg-open.browser = (defaultApplications pkgs).browser;
};
timeout = 1000;
drawColor = "#ff0000";
drawThickness = 2;
showDesktopNotification = true;
buttons = [
"ARROW"
"BLUR"
"CIRCLE"
"CIRCLECOUNT"
"COPY"
"DRAWER"
"EXIT"
"IMAGEUPLOADER"
"MARKER"
"MOVESELECTION"
"PENCIL"
"RECTANGLE"
"SAVE"
"SELECTION"
"SELECTIONINDICATOR"
"TEXT"
"UNDO"
];
}; };
config.timeout = 1000;
}) })
]; ];
} }

View File

@@ -18,6 +18,7 @@ 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

@@ -30,7 +30,6 @@
jetbrains-mono jetbrains-mono
twemoji-color-font twemoji-color-font
joypixels joypixels
tocharian-font
]; ];
fontconfig.defaultFonts = { fontconfig.defaultFonts = {
monospace = [ "JetBrains Mono" "JoyPixels" ]; monospace = [ "JetBrains Mono" "JoyPixels" ];

View File

@@ -7,6 +7,7 @@ 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
@@ -22,6 +23,37 @@ 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;
@@ -46,13 +78,25 @@ in
pull.ff = "only"; pull.ff = "only";
rebase.autoStash = true; rebase.autoStash = true;
merge.autoStash = true; merge.autoStash = true;
core.pager =
# ref https://github.com/dandavison/delta "${pkgs.gitAndTools.diff-so-fancy}/bin/diff-so-fancy | ${pkgs.less}/bin/less --tabs=4 -RFX";
core.pager = "${pkgs.delta}/bin/delta"; color = {
interactive.diffFilter = "${pkgs.delta}/bin/delta --color-only"; ui = true;
delta.navigate = true; diff = {
merge.conflictStyle = "diff3"; meta = "11";
diff.colorMoved = "default"; frag = "magenta bold";
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";
};
};
}; };
}; };
}; };

61
configs/hass/default.nix Normal file
View File

@@ -0,0 +1,61 @@
{ config, pkgs, lib, ... }:
let
inherit (import ./lib.nix) triggers;
inherit (import <niveum/lib>) localAddresses;
in
{
imports = [
./zigbee.nix
./frontend.nix
];
services.home-assistant = {
enable = true;
configWritable = true;
lovelaceConfigWritable = true;
openFirewall = true;
config = {
homeassistant = {
name = "Toum";
latitude = config.location.latitude;
longitude = config.location.longitude;
elevation = 90; # TODO find out how high I live
unit_system = "metric";
time_zone = config.time.timeZone;
};
config = {};
discovery = {};
system_health = {};
history = {};
# tradfri.host = localAddresses.tradfri; # dont use until python3Packages.pytradfri is packaged
sun = {};
mobile_app = {};
shopping_list = {};
sensor = [
{
platform = "dwd_weather_warnings";
region_name = "Berlin";
}
];
mqtt = {
broker = "localhost";
port = 1883;
client_id = "home-assistant";
username = "albrecht";
password = lib.strings.fileContents <system-secrets/mosquitto>;
keepalive = 60;
protocol = "3.1";
discovery = true;
birth_message = {
topic = "/hass/status";
payload = "online";
};
will_message = {
topic = "/hass/status";
payload = "offline";
};
};
};
};
}

37
configs/hass/frontend.nix Normal file
View File

@@ -0,0 +1,37 @@
let
inherit (import ./lib.nix) triggers;
in
{
services.home-assistant.config = {
frontend = {
themes = {
day_theme = import ./themes/clear.nix;
night_theme = import ./themes/clear-dark.nix;
};
};
automation = [
{
alias = "Night Theme";
hide_entity = true;
trigger = triggers.night;
action = [
{
service = "frontend.set_theme";
data.name = "night_theme";
}
];
}
{
alias = "Day Theme";
hide_entity = true;
trigger = triggers.day;
action = [
{
service = "frontend.set_theme";
data.name = "day_theme";
}
];
}
];
};
}

16
configs/hass/lib.nix Normal file
View File

@@ -0,0 +1,16 @@
{
triggers = {
night = {
platform = "numeric_state";
entity_id = "sun.sun";
value_template = "{{ state.attributes.elevation }}";
below = -4.0;
};
day = {
platform = "numeric_state";
entity_id = "sun.sun";
value_template = "{{ state.attributes.elevation }}";
above = 0;
};
};
}

View File

@@ -0,0 +1,72 @@
rec {
# Colors
text-color = "#DADADB"; # Grey text
text-medium-light-color = "#A0A2A8"; # Medium-light grey text
text-medium-color = "#80828A"; # Medium grey text
text-dark-color = "#6A6B74"; # Dark grey text
accent-color = "#008bef"; # Blue
accent-medium-color = "#2484C9"; # Decent blue
background-color = "#3b4049"; # Dark grey background
background-color-2 = "#484E59"; # Light grey background
background-card-color = "#434952"; # Grey background
border-color = "#383C46"; # Grey border
# Header
app-header-background-color = "#363941"; # Background color
# Text
primary-color = text-color;
text-primary-color = text-color;
# Left Menu
paper-listbox-background-color = background-color; # Background
sidebar-icon-color = text-medium-color; # icons
sidebar-selected-icon-color = text-medium-light-color; # Selected row icon and background (15%)
sidebar-selected-text-color = text-color; # Selected row label
# UI
paper-card-header-color = text-color; # Title in settings
primary-background-color = background-color; # Background (also title background in left menu)
mdc-theme-primary = accent-medium-color; # Action Buttons (save, restart etc.)
card-background-color = background-card-color; # Entity Registry Background
# Card
paper-card-background-color = background-card-color; # Background
dark-primary-color = text-color;
primary-text-color = text-color;
paper-listbox-color = text-color;
light-primary-color = text-dark-color;
secondary-text-color = text-medium-color;
disabled-text-color = text-dark-color;
paper-dialog-button-color = text-color;
secondary-background-color = background-color-2; # Background more info title
# Icons
paper-item-icon-color = text-dark-color; # Off
paper-item-icon-active-color = accent-color; # On
# Switches
switch-checked-button-color = text-medium-light-color; # Knob On
switch-unchecked-button-color = text-medium-light-color; # Knob Off
switch-checked-track-color = "#009FFF"; # Background On
switch-unchecked-track-color = "#767682"; # Background Off
# Slider
paper-slider-active-color = accent-color; # Line On
paper-slider-knob-color = text-medium-light-color; # Knob On
paper-slider-container-color = text-dark-color; # Line Off
paper-slider-knob-start-color = text-medium-light-color; # Knob Off
# Badges
label-badge-text-color = text-color;
label-badge-background-color = "rgba(54, 57, 65, 0.6)";
# Shadows
ha-card-box-shadow = "inset 0px 0px 0px 1px var(--border-color)";
# HACS
hacs-badge-color = accent-color; # New Badge
hacs-status-installed = text-color; # Installed Icon
hacs-status-pending-restart = text-dark-color; # Restart Icon
hacs-status-pending-update = accent-color;
}

View File

@@ -0,0 +1,52 @@
rec {
text-color = "#636B75"; # Grey text
text-medium-color = "#8c96a5"; # Medium grey text
text-light-color = "#BAC0C6"; # Light grey text
accent-color = "#00a1ff"; # Blue
background-color = "#F7F8F9"; # Light grey background
background-color-2 = "#F4F5F6"; # Light grey background
background-card-color = "rgba(255,255,255,1.0)"; # White background
border-color = "#E8E8E8"; # Light grey border
# Header
primary-color = text-color; # Background
text-primary-color = "#FFF"; # Text
# Left Menu
paper-listbox-background-color = background-color; # Background
# TODO = Text and Icons
# UI
paper-card-header-color = text-color; # Title in settings
primary-background-color = background-color; # Background color (also title background in left menu)
# Card
paper-card-background-color = background-card-color; # Background
dark-primary-color = text-color;
primary-text-color = text-color;
paper-listbox-color = text-color;
light-primary-color = text-light-color;
secondary-text-color = text-medium-color;
disabled-text-color = text-light-color;
paper-dialog-button-color = text-color;
secondary-background-color = background-color-2; # Background more info title
# Icons
paper-item-icon-color = text-light-color; # Off
paper-item-icon-active-color = accent-color; # On
# Switches
switch-checked-button-color = "#FFF"; # Knob On
switch-unchecked-button-color = "#FFF"; # Knob Off
switch-checked-track-color = "#0077FF"; # Background On
switch-unchecked-track-color = disabled-text-color; # Background Off
# Slider
paper-slider-active-color = accent-color; # Line On
paper-slider-container-color = "#e5e7ea"; # Line Off
paper-slider-knob-color = text-light-color; # Knob On
paper-slider-knob-start-color = text-light-color; # Knob Off
# Shadows
ha-card-box-shadow = "inset 0px 0px 0px 1px var(--border-color)";
}

102
configs/hass/zigbee.nix Normal file
View File

@@ -0,0 +1,102 @@
{ config, pkgs, lib, ... }:
let
inherit (import <niveum/lib>) localAddresses;
in
{
services.zigbee2mqtt = {
enable = true;
config = {
permit_join = false;
homeassistant = true;
serial = {
port = "/dev/ttyACM0";
disable_led = true;
};
mqtt = {
discovery = true;
base_topic = "zigbee";
server = "mqtt://${localAddresses.toum}";
user = "albrecht";
password = lib.strings.fileContents <system-secrets/mosquitto>;
};
};
};
services.mosquitto = {
enable = true;
host = "0.0.0.0";
allowAnonymous = false;
checkPasswords = true;
users."albrecht" = {
password = lib.strings.fileContents <system-secrets/mosquitto>;
acl = [ "topic readwrite #" ];
};
};
networking.firewall.allowedTCPPorts = [ 1883 ];
environment.systemPackages = [ pkgs.mosquitto ];
services.home-assistant = {
config = {
switch = [
{
platform = "mqtt";
name = "zigbee2mqtt_join";
state_topic = "/zigbee2mqtt/bridge/config/permit_join";
command_topic = "/zigbee2mqtt/bridge/config/permit_join";
payload_on = "true";
payload_off = "false";
}
];
timer.zigbee_permit_join = {
name = "Zigbee Time remaining";
duration = 120;
};
automation = [
# Automation to start timer when enable join is turned on
{
id = "zigbee_join_enabled";
alias = "";
hide_entity = "true";
trigger = {
platform = "state";
entity_id = "switch.zigbee2mqtt_join";
to = "on";
};
action = {
service = "timer.start";
entity_id = "timer.zigbee_permit_join";
};
}
# Automation to stop timer when switch turned off and turn off switch when timer finished
{
id = "zigbee_join_disabled";
hide_entity = "true";
trigger = [
{
platform = "event";
event_type = "timer.finished";
event_data.entity_id = "timer.zigbee_permit_join";
}
{
platform = "state";
entity_id = "switch.zigbee2mqtt_join";
to = "off";
}
];
action = [
{
service = "timer.cancel";
data.entity_id = "timer.zigbee_permit_join";
}
{
service = "switch.turn_off";
entity_id = "switch.zigbee2mqtt_join";
}
];
}
];
};
};
}

View File

@@ -1,5 +1,5 @@
{ config, pkgs, ... }: { { config, pkgs, ... }: {
imports = [ <niveum/modules/hledger.nix> ]; imports = [ ../modules/hledger.nix ];
niveum.hledger = { niveum.hledger = {
enable = true; enable = true;

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=hu-vpn.service" "x-systemd.requires=openvpn-hu-berlin.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}@split_tunnel username = ${eduroam.identity}
password = ${eduroam.password} password = ${eduroam.password}
''} ''}
''; '';

View File

@@ -33,9 +33,6 @@ let
"curl" = pkgs.writers.writeDash "curl" '' "curl" = pkgs.writers.writeDash "curl" ''
${pkgs.curl}/bin/curl -fSs "$(${pkgs.coreutils}/bin/cat)" ${pkgs.curl}/bin/curl -fSs "$(${pkgs.coreutils}/bin/cat)"
''; '';
ocr = pkgs.writers.writeDash "ocr" ''
${pkgs.tesseract4}/bin/tesseract -l eng+deu - stdout
'';
}; };
}; };
@@ -205,12 +202,14 @@ 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}+d" = "exec ${pkgs.writers.writeDash "run" ''exec ${pkgs.rofi}/bin/rofi -modi run,window,ssh,filebrowser -show run''}"; "${modifier}+a" =
"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.rofi pkgs.findutils pkgs.coreutils ] lib.makeBinPath [ pkgs.dmenu pkgs.findutils pkgs.coreutils ]
} }
cd ~/notes cd ~/notes
@@ -218,7 +217,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
} | rofi -dmenu -i -p 'notes') } | dmenu -i)
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" ]; layout = commaSep [ "de" "gr" "ru" ];
xkbVariant = commaSep [ "T3" "polytonic" ]; xkbVariant = commaSep [ "T3" "polytonic" "phonetic" ];
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,4 +1,7 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let
nixpkgs-unstable = import <nixpkgs-unstable> {};
in
{ {
systemd.services.lb-subscription = { systemd.services.lb-subscription = {
enable = true; enable = true;
@@ -12,10 +15,10 @@
first_year=2019 first_year=2019
for year in $(${pkgs.coreutils}/bin/seq "$first_year" "$(date +%Y)"); do for year in $(${pkgs.coreutils}/bin/seq "$first_year" "$(date +%Y)"); do
${pkgs.curl}/bin/curl -sSL "https://www.literarische-blaetter.de/jahrgang-$year/" \ ${pkgs.curl}/bin/curl -sSL "https://www.literarische-blaetter.de/jahrgang-$year/" \
| ${pkgs.htmlq}/bin/htmlq --attribute href 'ul.slides a' \ | ${nixpkgs-unstable.htmlq}/bin/htmlq --attribute href 'ul.slides a' \
| while read -r month; do | while read -r month; do
${pkgs.curl}/bin/curl -sSL "$month" \ ${pkgs.curl}/bin/curl -sSL "$month" \
| ${pkgs.htmlq}/bin/htmlq --attribute src iframe \ | ${nixpkgs-unstable.htmlq}/bin/htmlq --attribute src iframe \
| ${pkgs.gnused}/bin/sed 's/.*?pdf=//;s/?wp-hosted.*//' | ${pkgs.gnused}/bin/sed 's/.*?pdf=//;s/?wp-hosted.*//'
done done
done | ${pkgs.findutils}/bin/xargs ${pkgs.wget}/bin/wget --no-clobber done | ${pkgs.findutils}/bin/xargs ${pkgs.wget}/bin/wget --no-clobber

41
configs/menstruation.nix Normal file
View File

@@ -0,0 +1,41 @@
{ pkgs, lib, ... }:
let
backend = pkgs.callPackage <niveum/submodules/menstruation-backend> {};
telegram = pkgs.callPackage <niveum/submodules/menstruation-telegram> {};
backendPort = 8000;
in
{
containers.menstruation.autoStart = true;
containers.menstruation.config = { config, pkgs, ... }: {
services.redis.enable = true;
systemd.services.menstruation-telegram = {
wants = [
"network-online.target"
"menstruation-backend.service"
"redis.service"
];
wantedBy = [ "multi-user.target" ];
environment = {
MENSTRUATION_TOKEN = lib.strings.fileContents <system-secrets/telegram/menstruation.token>;
MENSTRUATION_ENDPOINT = "http://localhost:${toString backendPort}";
MENSTRUATION_MODERATORS = "18980945";
};
serviceConfig = {
Restart = "always";
DynamicUser = true;
ExecStart = "${telegram}/bin/menstruation-telegram";
};
};
systemd.services.menstruation-backend = {
wants = [ "network-online.target" ];
environment.ROCKET_PORT = toString backendPort;
serviceConfig = {
Restart = "always";
DynamicUser = true;
ExecStart = "${backend}/bin/menstruation_server";
};
};
};
}

View File

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

View File

@@ -2,7 +2,6 @@
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 = {
@@ -27,7 +26,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.name}} failed on {{$labels.job}}"; summary = "{{$labels.job}}: Service {{$labels.name}} failed to start.";
}; };
} }
{ {
@@ -35,7 +34,8 @@ 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 }} running out of space: {{ $value | printf "%.2f" }}% < ${toString diskFreeThreshold}%''; summary = "{{ $labels.job }}: Filesystem is running out of space soon.";
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}} running out of space in 7 days"; summary = "{{$labels.job}}: Filesystem is running out of space in 7 days.";
}; };
} }
{ {
@@ -52,85 +52,106 @@ 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 = "uptime monster {{$labels.job}} up for more than 30 days"; annotations.summary = "{{$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 = "{{ $labels.job }} seeming down since 5 minutes"; summary = "Host {{ $labels.job }} down for 5 minutes.";
}; };
} }
{ {
alert = "Reboot"; alert = "Reboot";
expr = "time() - node_boot_time_seconds < 300"; expr = "time() - node_boot_time_seconds < 300";
annotations.summary = "{{$labels.job}} rebooted"; annotations.summary = "{{$labels.job}}: Reboot";
} }
{ {
alert = "ProbeFailed"; alert = "ProbeFailed";
expr = "probe_success == 0"; expr = "probe_success == 0";
for = "5m"; for = "5m";
annotations.summary = "HTTP probe failed for {{$labels.instance}}"; annotations.summary = "{{$labels.instance}}: probe failed";
} }
{ {
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 = "HTTP probe slow for {{$labels.instance}}"; annotations.summary = "{{$labels.instance}}: HTTP probe slow";
} }
{ {
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 = "status code {{$value}} for {{$labels.instance}}"; annotations.summary = "{{$labels.instance}}: status code {{$value}}";
} }
{ {
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 = "SSL certificate for {{$labels.instance}} expires in 30 days"; annotations.summary = "{{$labels.instance}}: SSL certificate 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 = "SSL certificate for {{$labels.instance}} has expired"; annotations.summary = "{{$labels.instance}}: SSL certificate 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 = ''${pkgs.alertmanager-bot-telegram}/bin/alertmanager-bot \ ExecStart = ''${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 -}}
{{.Status}}: {{ index .Annotations "summary"}} {{ if eq .Status "firing" }}
<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}}
''}''; ''}'';
@@ -182,24 +203,12 @@ 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 = [ static_configs = [ { targets = [ "zaatar.r:${toString config.services.prometheus.exporters.node.port}" ]; } ];
"zaatar.r:${toString config.services.prometheus.exporters.node.port}"
"zaatar.r:${toString restic.port}"
]; } ];
} }
]; ];

View File

@@ -0,0 +1,31 @@
{ config, pkgs, lib, ... }:
let
moodle-dl-package = pkgs.moodle-dl.overrideAttrs (old: old // {
patches = [ <niveum/packages/moodle-dl/telegram-format.patch> ];
});
in
{
containers.moodle-dl-borsfaye = {
autoStart = true;
config = { lib, pkgs, ...}: {
imports = [ <niveum/modules/moodle-dl.nix> ];
services.moodle-dl = {
enable = true;
startAt = "hourly";
package = moodle-dl-package;
notifyOnly = true;
settings = {
telegram = {
token = lib.strings.fileContents <system-secrets/telegram/moodle-dl.token>;
chat_id = "311425510";
send_error_msg = false;
};
token = lib.strings.fileContents <system-secrets/moodle-dl/faye.token>;
moodle_domain = "moodle.hu-berlin.de";
moodle_path = "/";
};
};
};
};
}

View File

@@ -82,8 +82,6 @@ in
networking.firewall.allowedTCPPorts = [ 2049 ]; networking.firewall.allowedTCPPorts = [ 2049 ];
services.nginx.enable = true;
services.nginx.virtualHosts."moodle.kmein.r" = services.nginx.virtualHosts."moodle.kmein.r" =
let let
identity = lib.strings.fileContents <secrets/eduroam/identity>; identity = lib.strings.fileContents <secrets/eduroam/identity>;

View File

@@ -1,8 +1,13 @@
{ pkgs, lib, ... }: { pkgs, lib, ... }:
let let
port = 5703; port = 5703;
geogen-src = "${<scripts>}/onomastics"; geogen = (pkgs.fetchFromGitHub {
geogen = pkgs.callPackage geogen-src {}; owner = "kmein";
repo = "scripts";
rev = "8945430f27a8c6fd632dd35382cb094abe3543ff";
sha256 = "1djyxkynypxsrmdf6idgjszqpcgqyq607rrsvl58p2bpymmwibzb";
}) + "/onomastics";
inherit (pkgs.callPackage geogen {}) dependencyEnv;
in in
{ {
systemd.services.names = { systemd.services.names = {
@@ -14,8 +19,8 @@ in
}; };
script = '' script = ''
cd $(mktemp -d) cd $(mktemp -d)
ln -s "${geogen-src}/wsgi.py" wsgi.py ln -s "${geogen}/wsgi.py" wsgi.py
${geogen.dependencyEnv}/bin/gunicorn wsgi:app -b :${toString port} ${dependencyEnv}/bin/gunicorn wsgi:app -b :${toString port}
''; '';
}; };

10
configs/nano.nix Normal file
View File

@@ -0,0 +1,10 @@
{
programs.nano.nanorc = ''
set autoindent
set boldtext
set morespace
set smarthome
set tabsize 4
set tabstospaces
'';
}

View File

@@ -31,7 +31,7 @@
supertab supertab
undotree undotree
tabular tabular
# vimwiki vimwiki
vim-colors-paramount vim-colors-paramount
vim-commentary vim-commentary
vim-css-color vim-css-color
@@ -45,19 +45,26 @@
]; ];
opt = [ opt = [
csv csv
dhall-vim
elm-vim elm-vim
emmet-vim emmet-vim
haskell-vim haskell-vim
icalendar-vim icalendar-vim
idris-vim
nim-vim
jq-vim jq-vim
purescript-vim
rust-vim rust-vim
typescript-vim typescript-vim
vim-fsharp
vim-javascript vim-javascript
vim-ledger vim-ledger
vim-nix vim-nix
vim-reason-plus
vim-toml
vimtex vimtex
vim-pandoc vim-pandoc
vim-pandoc-syntax vim-pandoc-syntax # vim-pandoc-after
vim-256noir vim-256noir
]; ];
}; };

View File

@@ -1,5 +1,6 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let let
autowifi = pkgs.writers.writePython3Bin "autowifi" { flakeIgnore = [ "E501" ]; } <stockholm/lass/5pkgs/autowifi/autowifi.py>;
profile = name: custom: lib.recursiveUpdate { profile = name: custom: lib.recursiveUpdate {
connection.id = name; connection.id = name;
connection.type = "wifi"; connection.type = "wifi";
@@ -38,7 +39,7 @@ let
}; };
in in
{ {
imports = [ <niveum/modules/networkmanager-declarative.nix> ]; imports = [ ../modules/networkmanager-declarative.nix ];
networking.networkmanager = { networking.networkmanager = {
enable = true; enable = true;
@@ -82,5 +83,18 @@ in
users.users.me.extraGroups = [ "networkmanager" ]; users.users.me.extraGroups = [ "networkmanager" ];
systemd.services.autowifi = {
enable = false;
description = "Automatic wifi connector";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.networkmanager ];
serviceConfig = {
Type = "simple";
Restart = "always";
RestartSec = "10s";
ExecStart = "${autowifi}/bin/autowifi";
};
};
environment.systemPackages = [ pkgs.speedtest-cli ]; environment.systemPackages = [ pkgs.speedtest-cli ];
} }

View File

@@ -1,14 +1,8 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
nixpkgs = { # enable `nix flake`
config.allowUnfree = true;
overlays = [
(import <nix-writers/pkgs>)
(import <stockholm/krebs/5pkgs>)
];
};
nix = { nix = {
package = pkgs.nixUnstable; package = pkgs.nixFlakes;
extraOptions = "experimental-features = nix-command flakes"; extraOptions = "experimental-features = nix-command flakes";
}; };
} }

View File

@@ -2,34 +2,10 @@
let let
hc = pkgs.callPackage <stockholm/tv/5pkgs/simple/hc.nix> {}; hc = pkgs.callPackage <stockholm/tv/5pkgs/simple/hc.nix> {};
worldradio = pkgs.callPackage <niveum/packages/worldradio.nix> {}; worldradio = pkgs.callPackage <niveum/packages/worldradio.nix> {};
menstruation = pkgs.callPackage <menstruation-backend> {}; menstruation = pkgs.callPackage <niveum/submodules/menstruation-backend> {};
pandoc-doc = pkgs.callPackage <niveum/packages/man/pandoc.nix> {};
nixpkgs-unstable = import <nixpkgs-unstable> { config.allowUnfree = true; }; nixpkgs-unstable = import <nixpkgs-unstable> { config.allowUnfree = true; };
zoteroStyle = { name, sha256 }: {
name = "${name}.csl";
path = pkgs.fetchurl {
url = "https://www.zotero.org/styles/${name}";
inherit sha256;
};
};
cslDirectory = pkgs.linkFarm "citation-styles" [
(zoteroStyle {
name = "chicago-author-date-de";
sha256 = "0fz0xn46rkciblr34a7x2v60j0lbq9l3fmzi43iphph27m0czn6s";
})
(zoteroStyle {
name = "din-1505-2";
sha256 = "1pvy1b7qm13mnph7z365rrz1j082bl2y8ih73rhzd0zd6dz1jyjq";
})
(zoteroStyle {
name = "apa";
sha256 = "1878vxp0y0h05yzaghnd51n981623mxskw3lsdyzmffqhihvv111";
})
];
astrolog = nixpkgs-unstable.astrolog.overrideAttrs (old: old // { astrolog = nixpkgs-unstable.astrolog.overrideAttrs (old: old // {
installPhase = '' installPhase = ''
${old.installPhase} ${old.installPhase}
@@ -49,13 +25,42 @@ let
''; '';
}); });
recht = pkgs.callPackage <recht> {}; recht = pkgs.callPackage (pkgs.fetchFromGitHub {
owner = "kmein";
repo = "recht";
rev = "0.6.2";
sha256 = "08gnrnz3lwh8h6fyga56yfy9qryzm89xbshm7wpxfyxf2pmp1qfx";
}) {};
in { in {
home-manager.users.me.home.file = { imports = [
".csl".source = cslDirectory; ./writing.nix
".local/share/pandoc/csl".source = cslDirectory; # as of pandoc 2.11, it includes citeproc ./python.nix
}; ./haskell
{
environment.systemPackages = let
# nightly = pkgs.rustChannelOf {
# date = "2019-12-27";
# channel = "nightly";
# };
in with pkgs; [
htmlTidy
nodePackages.csslint
nodePackages.jsonlint
nodePackages.prettier
nodePackages.typescript
nodePackages.yarn
nodejs
nodePackages.javascript-typescript-langserver
tokei # count lines of code
gnumake
binutils # for strip, ld, ...
# nightly.rust
shellcheck
];
}
];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
# INTERNET # INTERNET
@@ -65,7 +70,9 @@ in {
w3m w3m
wget wget
whois whois
ix
dnsutils dnsutils
# mtr # my traceroute
# FILE MANAGERS # FILE MANAGERS
ranger ranger
pcmanfm pcmanfm
@@ -73,6 +80,7 @@ in {
ffmpeg ffmpeg
imagemagick imagemagick
exiftool exiftool
scrot
# ARCHIVE TOOLS # ARCHIVE TOOLS
unzip unzip
unrar unrar
@@ -93,17 +101,19 @@ in {
python3Packages.jsonschema # json validation python3Packages.jsonschema # json validation
jq # json toolkit jq # json toolkit
pup # html toolkit pup # html toolkit
htmlq nixpkgs-unstable.htmlq
xsv # csv toolkit xsv # csv toolkit
xmlstarlet # xml toolkit xmlstarlet # xml toolkit
manpages manpages
posix_man_pages posix_man_pages
# moreutils # for parallel, sponge, combine
tree tree
fuse_exfat # to mount windows drives fuse_exfat # to mount windows drives
parallel # for parallel, since moreutils shadows task spooler parallel # for parallel, since moreutils shadows task spooler
ripgrep # better grep ripgrep # better grep
rlwrap rlwrap
progress # display progress bars for pipes progress # display progress bars for pipes
up # universal plumber (piping tool)
# HARDWARE TOOLS # HARDWARE TOOLS
usbutils # for lsusb usbutils # for lsusb
pciutils # for lspci pciutils # for lspci
@@ -116,26 +126,22 @@ in {
audacity audacity
calibre calibre
inkscape inkscape
astrolog 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
mupdf
poppler_utils # pdf toolkit poppler_utils # pdf toolkit
foxitreader # for viewing pdf annotations foxitreader # for viewing pdf annotations
xournalpp # for annotating pdfs xournalpp # for annotating pdfs
pdfpc # presenter console for pdf slides pdfpc # presenter console for pdf slides
hc # print files as qr codes hc # print files as qr codes
youtubeDL youtubeDL
espeak
bc # calculator bc # calculator
pari # gp -- better calculator pari # gp -- better calculator
scripts.auc scripts.auc
scripts.infschmv scripts.infschmv
scripts.qrpaste scripts.qrpaste
scripts.ttspaste
scripts.new-mac # get a new mac address scripts.new-mac # get a new mac address
scripts.scanned scripts.scanned
scripts.default-gateway scripts.default-gateway
@@ -152,8 +158,11 @@ in {
recht recht
scripts.vimv scripts.vimv
scripts.swallow # window swallowing scripts.swallow # window swallowing
scripts.genius
scripts.instaget
scripts.literature-quote scripts.literature-quote
scripts.nav # json navigation scripts.nav # json navigation
scripts.n
scripts.notetags scripts.notetags
scripts.booksplit scripts.booksplit
scripts.dmenurandr scripts.dmenurandr
@@ -166,23 +175,24 @@ 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
scripts.menu-calc scripts.menu-calc
nix-prefetch-git nix-prefetch-git
scripts.nix-git scripts.nix-git
nixfmt nixfmt
par par
qrencode qrencode
wtf
menstruation menstruation
@@ -212,53 +222,6 @@ in {
irc-announce irc-announce
git-preview git-preview
ircaids ircaids
(python3.withPackages (py: [
py.black
# py.python-language-server
# py.pyls-mypy
# py.pyls-black
# py.pyls-isort
py.flake8
py.pygments
py.schema
]))
python3Packages.poetry
htmlTidy
nodePackages.csslint
nodePackages.jsonlint
nodePackages.prettier
nodePackages.typescript
nodePackages.yarn
nodejs
nodePackages.javascript-typescript-langserver
texlive.combined.scheme-full
latexrun
(aspellWithDicts (dict: [ dict.de dict.en dict.en-computers ]))
# haskellPackages.pandoc-citeproc
scripts.text2pdf
lowdown
glow # markdown to term
libreoffice
# gnumeric
dia
pandoc
pandoc-doc
# proselint
asciidoctor
wordnet
tokei # count lines of code
gnumake
binutils # for strip, ld, ...
# nightly.rust
shellcheck
]; ];
home-manager.users.me.xdg.configFile."pycodestyle".text = ''
[pycodestyle]
max-line-length = 110
'';
} }

View File

@@ -0,0 +1,46 @@
{ config, pkgs, ... }: {
home-manager.users.me.home.file = {
".ghc/ghci.conf".text = ''
:set editor vim
:def hoogle \s -> return $ ":!${pkgs.haskellPackages.hoogle}/bin/hoogle search --color -l --count=15 \"" ++ s ++ "\""
:def doc \s -> return $ ":!${pkgs.haskellPackages.hoogle}/bin/hoogle search --color -l --info \"" ++ s ++ "\""
:set prompt "\o033[1m%s\o033[1;34m λ\o033[0m "
:set -Wall
:set -XOverloadedStrings
'';
# :def unpl \x -> return $ ":!${pkgs.haskellPackages.pointful}/bin/pointful \"" ++ x ++ "\""
# :def pl \x -> return $ ":!${pkgs.haskellPackages.pointfree}/bin/pointfree -v \"" ++ x ++ "\""
".stack/config.yaml".source =
let inherit (import <niveum/lib>) kieran;
in (pkgs.formats.yaml {}).generate "config.yaml" {
templates.params = {
author-name = kieran.name;
author-email = kieran.email;
copyright = "Copyright: (c) 2020 ${kieran.name}";
github-username = kieran.github;
};
};
};
services.hoogle = {
enable = false;
packages = import ./packages.nix;
port = 8091;
};
environment.systemPackages = with pkgs;
[
cabal2nix
cabal-install
hlint
haskellPackages.ormolu
(haskellPackages.ghcWithHoogle (import ./packages.nix))
] ++ map haskell.lib.justStaticExecutables [
haskellPackages.ghcid
haskellPackages.hasktags
# haskellPackages.hindent
# haskellPackages.pointfree
# haskellPackages.pointful
haskellPackages.hpack
];
}

View File

@@ -0,0 +1,100 @@
haskellPackages:
with haskellPackages; [
HTTP
HUnit
MissingH
QuickCheck
ad
adjunctions
aeson
# algebra
ansi-terminal
async
attoparsec
base-orphans
bifunctors
binary
blaze-html
blaze-markup
brick
bytes
bytestring
case-insensitive
cassava
cereal
clock
comonad
comonad-transformers
conduit
conduit-extra
constraints
containers
contravariant
criterion
data-default
diagrams
directory
dlist
either
edit-distance
exceptions
extra
filepath
foundation
free
haskeline
hedgehog
hourglass
hspec
http-client
http-conduit
kan-extensions
lens
linear
lucid
megaparsec
microlens
monad-logger
monad-memo
mono-traversable
mtl
network
parallel
parsec
persistent
pipes
pointed
pretty
pretty-show
prettyprinter
primitive
process
profunctors
regex-tdfa
safe
scalpel
semigroupoids
semigroups
servant
servant-blaze
servant-client
servant-docs
servant-server
servant-swagger
split
stm
tagsoup
tasty
text
time
transformers
turtle
unix-time
unordered-containers
vector
void
vty
warp
wreq
yaml
]

View File

@@ -0,0 +1,20 @@
{ pkgs, ... }: {
environment.systemPackages = [
(pkgs.python3.withPackages (py: [
py.black
# py.python-language-server
# py.pyls-mypy
# py.pyls-black
# py.pyls-isort
py.flake8
py.pygments
py.schema
]))
pkgs.python3Packages.poetry
];
home-manager.users.me.xdg.configFile."pycodestyle".text = ''
[pycodestyle]
max-line-length = 110
'';
}

View File

@@ -0,0 +1,81 @@
{ pkgs, lib, config, ... }:
let
pandoc-doc = pkgs.callPackage <niveum/packages/man/pandoc.nix> {};
zoteroStyle = { name, sha256 }: {
name = "${name}.csl";
path = pkgs.fetchurl {
url = "https://www.zotero.org/styles/${name}";
inherit sha256;
};
};
cslDirectory = pkgs.linkFarm "citation-styles" [
(zoteroStyle {
name = "chicago-author-date-de";
sha256 = "0fz0xn46rkciblr34a7x2v60j0lbq9l3fmzi43iphph27m0czn6s";
})
(zoteroStyle {
name = "din-1505-2";
sha256 = "1pvy1b7qm13mnph7z365rrz1j082bl2y8ih73rhzd0zd6dz1jyjq";
})
(zoteroStyle {
name = "apa";
sha256 = "1878vxp0y0h05yzaghnd51n981623mxskw3lsdyzmffqhihvv111";
})
];
makeStardictDataDir = dicts:
pkgs.linkFarm "dictionaries" (map ({ name, path }: {
name = "dic/${name}";
inherit path;
}) dicts);
in {
environment.variables.STARDICT_DATA_DIR = toString (makeStardictDataDir [
{
name = "gr-de";
path = pkgs.fetchurl {
url = "http://tovotu.de/data/stardict/pape_gr-de.zip";
sha256 = "1d705y47b40vp0mg79vbwasw4y0i8fmnlwvf4x4ri0dkfqng9sky";
};
}
{
name = "la-de";
path = pkgs.fetchurl {
url = "http://tovotu.de/data/stardict/georges_lat-de.zip";
sha256 = "12n26nzwg28wn4zwv45mv0wkgy1jh1d8p0k6haamz9601cqq7hkj";
};
}
{
name = "de-la";
path = pkgs.fetchurl {
url = "http://tovotu.de/data/stardict/georges_de-lat.zip";
sha256 = "0inm6xn1lcnb851cj329n0v2vbfc1z1bxwhgsd8fnm0zxy3f3ifq";
};
}
]);
home-manager.users.me.home.file = {
".csl".source = cslDirectory;
".local/share/pandoc/csl".source = cslDirectory; # as of pandoc 2.11, it includes citeproc
};
environment.systemPackages = with pkgs; [
texlive.combined.scheme-full
latexrun
(aspellWithDicts (dict: [ dict.de dict.en dict.en-computers ]))
# haskellPackages.pandoc-citeproc
scripts.text2pdf
lowdown
glow # markdown to term
libreoffice
# gnumeric
dia
pandoc
pandoc-doc
# proselint
asciidoctor
wordnet
# sdcv # stardict cli
];
}

View File

@@ -3,8 +3,6 @@ let
suspend = pkgs.writers.writeDash "suspend" "${pkgs.systemd}/bin/systemctl suspend"; suspend = pkgs.writers.writeDash "suspend" "${pkgs.systemd}/bin/systemctl suspend";
in in
{ {
imports = [ <stockholm/krebs/3modules/power-action.nix> ];
krebs.power-action = { krebs.power-action = {
enable = true; enable = true;
plans.suspend = { plans.suspend = {

View File

@@ -7,7 +7,13 @@ let
geo-ip-database = "${lib.head config.services.geoipupdate.settings.EditionIDs}.mmdb"; geo-ip-database = "${lib.head config.services.geoipupdate.settings.EditionIDs}.mmdb";
geo-ip-database-path = "${config.services.geoipupdate.settings.DatabaseDirectory}/${geo-ip-database}"; geo-ip-database-path = "${config.services.geoipupdate.settings.DatabaseDirectory}/${geo-ip-database}";
tinc-graph = pkgs.callPackage <tinc-graph> {}; tinc-graph-source = pkgs.fetchFromGitHub {
owner = "kmein";
repo = "tinc-graph";
rev = "1b9c69ffdbdab82d30a23e44f739feea63d94163";
sha256 = "0bk4x9l399f80lmz4asx7s5fcsgrfdb6xyymbq884621x4z3d2vp";
};
tinc-graph = pkgs.callPackage tinc-graph-source {};
in in
{ {
systemd.services.retiolum-index = { systemd.services.retiolum-index = {
@@ -48,8 +54,6 @@ in
recommendedProxySettings = true; recommendedProxySettings = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
virtualHosts."graph.r".locations."/".root = "/var/lib/${stateDirectory}"; virtualHosts."graph.r".locations."/".root = "/var/lib/${stateDirectory}";
# RRM @ https://github.com/krebs/cholerab/blob/master/thesauron.adoc
virtualHosts."rrm.r".locations."/".root = "/var/lib/${stateDirectory}";
}; };
systemd.services.geoip-share = { systemd.services.geoip-share = {

View File

@@ -1,6 +1,6 @@
{ config, pkgs, ... }: { { config, pkgs, ... }: {
imports = [ imports = [
<niveum/modules/retiolum.nix> ../modules/retiolum.nix
]; ];
networking.hosts = { "42:0:ca48:f98f:63d7:31ce:922b:245d" = [ "go" ]; }; networking.hosts = { "42:0:ca48:f98f:63d7:31ce:922b:245d" = [ "go" ]; };

View File

@@ -1,10 +1,9 @@
{ config, pkgs, ... }: { config, ... }:
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,5 +1,8 @@
{ 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

@@ -1,357 +0,0 @@
{ config, pkgs, lib, ... }:
let
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 = {
Pape = pkgs.fetchzip {
url = "http://tovotu.de/data/stardict/pape_gr-de.zip";
sha256 = "1kmbdjqinrcxkc6jdyyrq5rl2wzhnrychyynnh91yhrjwjxlh44k";
};
Woodhouse = pkgs.fetchzip {
url = "https://c.krebsco.de/Woodhouse.zip";
sha256 = "1dvnc2679yb048q2f3hr2h34acvhan0n3iir6h9ajlrdzz48mlkq";
stripRoot = false;
};
LSJ = pkgs.fetchzip {
url = "https://github.com/nikita-moor/latin-dictionary/releases/download/2020-02-14/LiddellScott1940-stardict.zip";
sha256 = "13rprgd9jvnhxk9735c91xr6ywr0j5jiwkjnpm3qpvy93isyjbys";
};
GreekMorphology = pkgs.fetchzip {
url = "https://github.com/latin-dict/Morphologia-Graeca/releases/download/v0.5/morphology-mobile-goldendict.oxia.zip";
sha256 = "0m75cppjjjmvv18cs7yh9f4p7ckqzxfznnndgkiw3yrfd50k8p96";
};
Frisk = pkgs.fetchzip {
url = "https://github.com/latin-dict/Frisk1960/releases/download/v1.1/Frisk1960-stardict.zip";
sha256 = "1rk5a3n3fpfdcmg4bc5945m88s6ldxql8cjn4jqs33rgklh7n046";
};
Georges-De-Lat = pkgs.fetchzip {
url = "http://tovotu.de/data/stardict/georges_de-lat.zip";
sha256 = "1gx4vv64bi9lxw2zgd861j469jvw4f2hhfwy1gglb12id8r7rdrl";
};
Georges-Lat-De = pkgs.fetchzip {
url = "http://tovotu.de/data/stardict/georges_lat-de.zip";
sha256 = "0cc5xipn60anxvq8z2mw53d4gi1k92wbrj9m4ws3g9rh87fmkvgz";
};
LewisShort = pkgs.fetchzip {
url = "https://github.com/latin-dict/LewisShort1879/releases/download/v1.3/LewisShort1879-stardict.zip";
sha256 = "1y3ans47iv8bzzb1paimdqvcid8ms04ikjbqy3iw077i2js3qbjk";
};
DoederleinSynonymes = pkgs.fetchzip {
url = "https://github.com/latin-dict/Doederlein1874/releases/download/v1.1/Doederlein1875-stardict.zip";
sha256 = "0mhik7gjxl8ncr9g5z2l4pfk60k1c5n0gc1w0cnp2x1v6lqvb57h";
};
};
englishGerman = {
Etymonline = pkgs.fetchzip {
url = "http://tovotu.de/data/stardict/etymonline.zip";
sha256 = "1bjja3n3layfd08xa1r0a6375dxh5zi6hlv7chkhgnx800cx7hxn";
};
Roget = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Roget_s_II_The_New_Thesaurus_3th_Ed-2.4.2.tar.bz2";
sha256 = "1szyny9497bpyyccf9l5kr3bnw0wvl4cnsd0n1zscxpyzlsrqqbz";
};
JargonFile = pkgs.fetchzip {
url = "http://download.huzheng.org/dict.org/stardict-dictd-jargon-2.4.2.tar.bz2";
sha256 = "096phar9qpmm0fnaqv5nz8x9lpxwnfj78g4vjfcfyd7kqp7iqla4";
};
Oxford-Collocations = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Oxford_Collocations_Dictionary_2nd_Ed-2.4.2.tar.bz2";
sha256 = "1zkfs0zxkcn21z2lhcabrs77v4ma9hpv7qm119hpyi1d8ajcw07q";
};
Langenscheidt-Deu-En = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Handw_rterbuch_Deutsch_Englisc-2.4.2.tar.bz2";
sha256 = "12q9i5azq7ylyrpb6jqbaf1rxalc3kzcwjvbinvb0yabdxb80y30";
};
Langenscheidt-En-Deu = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Handw_rterbuch_Englisch_Deutsc-2.4.2.tar.bz2";
sha256 = "087b05h155j5ldshfgx91pz81h6ijq2zaqjirg7ma8ig3l96zb59";
};
Duden_Das_Fremdworterbuch = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_Das_Fremdworterbuch-2.4.2.tar.bz2";
sha256 = "1zrcay54ccl031s6dvjwsah5slhanmjab87d81rxlcy8fx0xd8wq";
};
Duden_De_De = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_De_De-2.4.2.tar.bz2";
sha256 = "1fhay04w5aaj83axfmla2ql34nb60gb05dgv0k94ig7p8x4yxxlf";
};
ConciseOED = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Concise_Oxford_English_Dictionary-2.4.2.tar.bz2";
sha256 = "19kpcxbhqzpmhi94mp48nalgmsh6s7rsx1gb4kwkhirp2pbjcyl7";
};
Duden_Synonym = pkgs.fetchzip {
url = "http://download.huzheng.org/babylon/german/stardict-Duden_Synonym-2.4.2.tar.bz2";
sha256 = "0cx086zvb86bmz7i8vnsch4cj4fb0cp165g4hig4982zakj6f2jd";
};
};
sanskrit = let repo = "https://github.com/indic-dict/stardict-sanskrit/raw/4ebd2d3db5820f7cbe3a649c3d5aa8f83d19b29f"; in {
BoehtlingkRoth = pkgs.fetchzip {
url = "${repo}/sa-head/german-entries/tars/Bohtlingk-and-Roth-Grosses-Petersburger-Worterbuch__2021-10-05_14-23-18Z__19MB.tar.gz";
sha256 = "13414a8rgd7hd5ffar6nl68nk3ys60wjkgb7m11hp0ahaasmf6ly";
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 {
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";
stripRoot = false;
};
MonierWilliamsEnglish = pkgs.fetchzip {
url = "${repo}/en-head/tars/mw-english-sanskrit__2021-10-05_14-23-18Z__3MB.tar.gz";
sha256 = "09a61hhii4b1m2fkrlh4rm2xnlgwrllh84iypbc6wyj00w9jkl3x";
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 = {
OED1 = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Oxford_English_Dictionary_2nd_Ed._P1-2.4.2.tar.bz2";
sha256 = "0i5vv1rv44yfwyf9bfbdrb9brzhhpvz2jnh39fv8hh107nkv2vcf";
};
OED2 = pkgs.fetchzip {
url = "http://download.huzheng.org/bigdict/stardict-Oxford_English_Dictionary_2nd_Ed._P2-2.4.2.tar.bz2";
sha256 = "1pk234pbq4pk55d8sjk0pp9j5sajm82f8804kf2xm2x5p387q1rg";
};
};
russian = {
LingvoGermanRussian = pkgs.fetchzip {
url = "http://download.huzheng.org/lingvo/stardict-GR-LingvoUniversal-2.4.2.tar.bz2";
sha256 = "0p353gs2z4vj70hqsdhffjaaw3a4zlmcs46flipmf35lm5wmaj0g";
};
LingvoRussianGerman = pkgs.fetchzip {
url = "http://download.huzheng.org/lingvo/stardict-RG-LingvoUniversal-2.4.2.tar.bz2";
sha256 = "03f9wdmkgpjifpms7dyh10ma29wf3ka1j3zlp1av0cybhdldk2a8";
};
};
};
makeStardictDataDir = dicts: pkgs.linkFarm "dictionaries" (lib.mapAttrsToList (name: path: { inherit name path; }) dicts);
makeStardict = name: dicts: pkgs.writers.writeDashBin name ''
set -efu
export SDCV_PAGER=${toString sdcvPager}
exec ${pkgs.sdcv}/bin/sdcv --color --only-data-dir --data-dir ${makeStardictDataDir dicts} "$@"
'';
sdcvPager = pkgs.writeDash "sdcvPager" ''
export PATH=${lib.makeBinPath [pkgs.gnused pkgs.ncurses pkgs.less]}
sed "
s!<sup>1</sup>!¹!gI
s!<sup>2</sup>!²!gI
s!<sup>3</sup>!³!gI
s!<sup>4</sup>!!gI
s! style=\"color: #...\"!!g;
s!<span class=\"zenoTXSpaced\">\([^<>]*\)</span>!\1!g;
s!</\?dictionary[^>]*>!!g;
s!<style.*</style>!!g;
s!<author>\([^<>]*\)</author>!\1 !g;
s!<quote lang=\"\(greek\|la\)\">\([^<>]*\)</quote>!$(tput sitm)\2$(tput sgr0)!g;
s!<biblScope>\([^<>]*\)</biblScope>!\1!g;
s!<mood>\([^<>]*\)</mood>!$(tput sitm)\1$(tput sgr0)!g;
s!<adv>\([^<>]*\)</adv>!$(tput sitm)\1$(tput sgr0)!g;
s!<gram[^>]*>\([^<>]*\)</gram>!$(tput sitm)\1$(tput sgr0)!g;
s!<bibl_title>\([^<>]*\)</bibl_title>!$(tput sitm)\1$(tput sgr0) !g;
s!<hi rend=\"ital\">\([^<>]*\)</hi>!$(tput sitm)\1$(tput sgr0) !g;
s!<dict_tr>\([^<>]*\)</dict_tr>!$(tput setaf 3)\1$(tput sgr0)!g;
s!<headword>\([^<>]*\)</headword>!$(tput bold)\1$(tput sgr0)\t!g;
s!</\?a[^>]*>!!g
s!</\?[cp]b[^>]*>!!g
s!</\?gramGrp[^>]*>!!g
s!</\?lbl[^>]*>!!g
s!</\?xr[^>]*>!!g
s!</\?pron[^>]*>!!g
s!</\?gen[^>]*>!!g
s!</\?tns[^>]*>!!g
s!</\?per[^>]*>!!g
s!</\?blockquote[^>]*>!!g
s!</\?etym[^>]*>!!g
s!<foreign[^>]*>!$(tput sitm)!g
s!</foreign[^>]*>!$(tput sgr0)!g
s!</\?date[^>]*>!!g
s!</\?placeName[^>]*>!!g
s!</\?itype[^>]*>!!g
s!</\?p>!!g
s!<input[^>]*>!!g
s!</\?orth[^>]*>!!g
s!</\?number[^>]*>!!g
s!</\?forename[^>]*>!!g
s!</\?persName[^>]*>!!g
s!</\?surname[^>]*>!!g
s!</\?entryFree[^>]*>!!g
s!</\?def[^>]*>!!g
s!</\?cit[^>]*>!!g
s!</\?pos[^>]*>!!g
s!</\?usg[^>]*>!!g
s!</\?ul>!!g
s!<li>!\n!g
s!</li>!!g
s!<bibl[^>]*>!$(tput setaf 245)!g
s!</bibl[^>]*>!$(tput sgr0)!g
s/<dt>/$(tput bold)/g;
s:</dt>:$(tput sgr0):g;
s/<dd>/\n/g;
s:</dd>::g;
s:<script>.*</script>::g;
s/<b>/$(tput bold)/gI;
s:</b>:$(tput sgr0):gI;
s:<br\s*/\?>:\n:gI;
s:<i>:$(tput sitm):gI;
s:</i>:$(tput sgr0):gI;
s:<u>:$(tput smul):gI;
s:</u>:$(tput sgr0):gI;
s:<FONT face=[^>]*>::g;
s:</FONT>::g;
s!<head>\([^<>]*\)</head>!$(tput bold)\1$(tput sgr0)!g;
s!<span lang=\"\(gr\|la\)\">\([^<>]*\)</span>!\2!g
s#<div style=\"margin-left:1em\">\(.*\)</div>#\\1#g;
s:<font color=\"brown\">\([^<>]*\)</font>:$(tput setaf 3)\\1$(tput sgr0):g;
s:<font color=\"blue\">\([^<>]*\)</font>:$(tput setaf 4)\\1$(tput sgr0):g;
s:<font color=\"red\">\([^<>]*\)</font>:$(tput setaf 1)\\1$(tput sgr0):g;
s:<font color=\"darkviolet\">\([^<>]*\)</font>:$(tput setaf 5)\\1$(tput sgr0):g;
s:<font color=\"#a0a\">\([^<>]*\)</font>:$(tput bold)\1$(tput sgr0):g
s:<font color=\"#838\">\([^<>]*\)</font>:$(tput setaf 3)\1$(tput sgr0):g
s:&#x27;:':g
s:&lt;:<:g
s:&gt;:>:g
s:<font color=\"#007000\">\([^<>]*\)</font>:$(tput setaf 2)\\1$(tput sgr0):g;
s:<font color=\"#007000\">\([^<>]*\)</font>:$(tput setaf 2)\\1$(tput sgr0):g;
s:<font color=#000099>\([^<>]*\)</font>:$(tput setaf 4)\\1$(tput sgr0):g;
s:<font color=0000FF>\([^<>]*\)</font>:$(tput bold)\\1$(tput sgr0):g;
s:<IMG src=\"223E9A06.bmp\"[^>]*>:ː:g;
s:<IMG src=\"502F5DDA.bmp\"[^>]*>::g;
s:<IMG src=\"8DAD7054.bmp\"[^>]*>:n̩:g
s!</\?TABLE>!!gI
s!</\?TR[^>]*>!!gI
s!</\?TD>!!gI
s!</\?FONT[^>]*>!!gI
s!</\?A[^>]*>!!gI
s!<SPAN class=\"bsptext\">\([^<>]*\)</SPAN>!$(tput setaf 245)\1$(tput sgr0)!g
s! +! !g;
s!<div part=\"[^\"]*\">!\n\n&!g
s!<sense n=\"\([^\"]*\)\"!\n$(tput setaf 5)\1.$(tput sgr0) &!g;
s!</\?sense[^>]*>!!g
s!</\?div[^>]*>!!g
s!<span lang=\"gr\">!!g # unbalanced in Frisk
s!^\s*[0-9])!$(tput setaf 5)&$(tput sgr0)!g
s!</\?span[^>]*>!!gI
s!</\?p[^>]*>!!gI
" | less -FR
'';
in
{
environment.etc.stardict.source = toString (makeStardictDataDir ({
Crum = pkgs.fetchzip {
url = "http://download.huzheng.org/misc/stardict-Coptic-English_all_dialects-2.4.2.tar.bz2";
sha256 = "1fi281mb9yzv40wjsdapi8fzpa7x2yscz582lv2qnss9g8zzzzr9";
};
SmithBiographyMythology = pkgs.fetchzip {
url = "https://github.com/latin-dict/Smith1873/releases/download/v1.0/Smith1873-stardict.zip";
sha256 = "01h5fxacp2m60xir8kzslkfy772vs3vmz07zhdwfhcwdaxif2af2";
};
SmithAntiquities = pkgs.fetchzip {
url = "https://github.com/latin-dict/Smith1890/releases/download/v1.0/Smith1890-stardict.zip";
sha256 = "0vpsv62p2lrzmgys4d1swpnc6lqhdi7rxwkj2ngy3lz5dk3fysyb";
};
} // dictionaries.classics // dictionaries.sanskrit // dictionaries.oed // dictionaries.russian // dictionaries.englishGerman));
environment.systemPackages = [
pkgs.goldendict
(makeStardict "lsj" dictionaries.classics)
(makeStardict "sa" dictionaries.sanskrit)
(makeStardict "oed" dictionaries.oed)
(makeStardict "sd-russian" dictionaries.russian)
(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

@@ -40,16 +40,14 @@ let
in { in {
niveum.telegramBots.transits = { niveum.telegramBots.transits = {
enable = true; enable = true;
time = "*:0/1"; time = "4:00";
token = lib.strings.fileContents <system-secrets/telegram/kmein.token>; token = lib.strings.fileContents <system-secrets/telegram/kmein.token>;
chatIds = [ "-1001796440545" ]; chatIds = [ "18980945" ];
command = toString (pkgs.writers.writeDash "common-transits" '' command = toString (pkgs.writers.writeDash "common-transits" ''
now=$(${pkgs.coreutils}/bin/date +%_H:%M | ${pkgs.gnused}/bin/sed 's/^\s*//')
date=$(${pkgs.coreutils}/bin/date +'%m %d %Y')
{ {
${nixpkgs-unstable.astrolog}/bin/astrolog -qd $date -zN Berlin -Yt -Yd -d -R Uranus Neptune Pluto "North Node" ${nixpkgs-unstable.astrolog}/bin/astrolog -n -zN Berlin -Yt -Yd -d -R Uranus Neptune Pluto
${nixpkgs-unstable.astrolog}/bin/astrolog -Yt -Yd -q 10 22 1999 6:32 -zN Kassel -td $date -R Uranus Neptune Pluto "North Node" ${nixpkgs-unstable.astrolog}/bin/astrolog -Yt -Yd -q 10 22 1999 6:32 -zN Kassel -td $(${pkgs.coreutils}/bin/date +'%m %d %Y') -R Uranus Neptune Pluto
} | ${toSymbols} | ${pkgs.coreutils}/bin/sort -n | ${pkgs.gnugrep}/bin/grep "^$now" || : } | ${toSymbols} | ${pkgs.coreutils}/bin/sort -n
''); '');
}; };
} }

View File

@@ -1,6 +1,13 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
telebots = pkgs.callPackage <telebots> {}; telebots = let
telebots-package = pkgs.fetchFromGitHub {
owner = "kmein";
repo = "telebots";
rev = "22931c9457e092c4e413555dbe61819d77844246";
sha256 = "0byp3w6li3fin7ry0ki4rmgkaajdil424y5pc1j7ci9mpws0s5ik";
};
in pkgs.callPackage telebots-package {};
reverseDirectory = "/run/telegram-reverse"; reverseDirectory = "/run/telegram-reverse";
proverbDirectory = "/run/telegram-proverb"; proverbDirectory = "/run/telegram-proverb";
inherit (import <niveum/lib>) tmpfilesConfig; inherit (import <niveum/lib>) tmpfilesConfig;

View File

@@ -4,7 +4,7 @@ let
living-room-id = 131090; living-room-id = 131090;
in in
{ {
imports = [ <niveum/modules/traadfri.nix> ]; imports = [ ../modules/traadfri.nix ];
environment.systemPackages = [ environment.systemPackages = [
(pkgs.writers.writeDashBin "traadfri-party" '' (pkgs.writers.writeDashBin "traadfri-party" ''
@@ -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; desk = 131089;
}; };
}; };
} }

View File

@@ -81,7 +81,6 @@ 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 = ''
@@ -96,6 +95,7 @@ in
}; };
/*
services.nginx = { services.nginx = {
enable = true; enable = true;
recommendedGzipSettings = true; recommendedGzipSettings = true;
@@ -110,4 +110,5 @@ in
}; };
}; };
}; };
*/
} }

View File

@@ -107,7 +107,7 @@ let
to = kieran.email; to = kieran.email;
}; };
telegram = { telegram = {
enabled = false; enabled = true;
bot_token = lib.strings.fileContents <system-secrets/telegram/kmein.token>; bot_token = lib.strings.fileContents <system-secrets/telegram/kmein.token>;
chat_id = "-1001504043752"; chat_id = "-1001504043752";
}; };

4
configs/version.nix Normal file
View File

@@ -0,0 +1,4 @@
{ lib, config, ... }:
{
environment.etc."niveum/version".text = lib.sources.commitIdFromGitRepo <niveum/.git>;
}

View File

@@ -1,7 +1,5 @@
{ pkgs, lib, ... }: { pkgs, lib, ... }:
{ {
imports = [ <stockholm/krebs/3modules/fetchWallpaper.nix> ];
krebs.fetchWallpaper = { krebs.fetchWallpaper = {
enable = true; enable = true;
url = "http://prism.r/realwallpaper-krebs-stars-berlin.png"; url = "http://prism.r/realwallpaper-krebs-stars-berlin.png";

View File

@@ -1,6 +1,4 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
environment.systemPackages = [ pkgs.watson ]; environment.systemPackages = [ pkgs.watson ];
environment.variables.WATSON_DIR = "${config.users.users.me.home}/cloud/Seafile/Documents/watson";
} }

119
configs/weechat.nix Normal file
View File

@@ -0,0 +1,119 @@
{ lib, pkgs, ... }:
let
inherit (import <niveum/lib>) kieran;
relayPassword = lib.fileContents <system-secrets/weechat/relay>;
in {
systemd.services.weechat =
let
tmux = pkgs.writers.writeDash "tmux" ''
exec ${pkgs.tmux}/bin/tmux -f ${pkgs.writeText "tmux.conf" ''
set-option -g prefix `
unbind-key C-b
bind ` send-prefix
set-option -g status off
set-option -g default-terminal screen-256color
#use session instead of windows
bind-key c new-session
bind-key p switch-client -p
bind-key n switch-client -n
bind-key C-s switch-client -l
''} "$@"
'';
weechat = pkgs.weechat.override {
configure = { ... }: {
scripts = [ pkgs.weechatScripts.weechat-autosort pkgs.weechatScripts.colorize_nicks pkgs.weechatScripts.weechat-matrix ];
init = let
coolColors = lib.lists.subtractLists (lib.range 52 69 ++ lib.range 231 248) (lib.range 31 254);
nick = "kmein";
in ''
/mouse enable
/set irc.server_default.nicks "${nick}"
/set irc.server_default.msg_part "tschö mit ö"
/set irc.server_default.msg_quit "ciao kakao"
/set irc.server_default.msg_kick "warum machst du diese?"
/set irc.server_default.realname "${kieran.name}"
/set irc.look.color_nicks_in_nicklist "on"
/set weechat.color.chat_nick_colors "${lib.concatMapStringsSep "," toString coolColors}"
/server add hackint irc.hackint.org/6697 -ipv6 -ssl
/server add libera irc.libera.chat/6697 -ssl
/server add oftc irc.oftc.net/6697 -ssl -ipv6
/server add retiolum irc.r
/server add news news.r
/matrix server add nibbana nibbana.jp
/alias add mod /quote omode $channel +o $nick
/relay add weechat 9000
/set relay.network.password ${relayPassword}
/set matrix.server.nibbana.username ${nick}
/set matrix.server.nibbana.password "${lib.strings.fileContents <system-secrets/matrix/nibbana>}"
/set irc.server.oftc.command /msg nickserv IDENTIFY ${lib.strings.fileContents <system-secrets/irc/oftc>};/msg nickserv SET CLOAK ON
/set irc.server.oftc.autojoin "#osm,#osm-de,#home-manager"
/set irc.server.hackint.autojoin "#krebs,#nixos,#the_playlist"
/set irc.server.hackint.sasl_mechanism plain
/set irc.server.hackint.sasl_username ${nick}
/set irc.server.hackint.sasl_password ${lib.strings.fileContents <system-secrets/irc/hackint>}
/set irc.server.libera.autojoin "#flipdot,#haskell,#nixos,#fysi,#binaergewitter"
/set irc.server.libera.sasl_mechanism plain
/set irc.server.libera.sasl_username ${nick}
/set irc.server.libera.sasl_password ${lib.strings.fileContents <system-secrets/irc/libera>}
/set irc.server.retiolum.autojoin "#xxx,#brockman,#flix,#autowifi"
/set irc.server.retiolum.command "/oper aids balls"
/set irc.server.news.autojoin "#cook,#drachengame,#oepnv,#kmeinung,#memes"
/set irc.server.news.command "/oper aids balls"
/set logger.level.irc.news 0
/filter addreplace zerocovid * * [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
/filter addreplace joinquit * irc_join,irc_part,irc_quit,irc_nick *
/filter addreplace playlist_topic irc.*.#the_playlist irc_topic *
/filter addreplace brockman_notice irc.news.* irc_notice *
/set irc.look.server_buffer independent
/connect libera
/connect oftc
/connect hackint
/connect retiolum
/connect news
/matrix connect nibbana
'';
};
};
in {
description = "Weechat bouncer";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
restartIfChanged = true;
path = [ pkgs.alacritty.terminfo ];
environment.WEECHAT_HOME = "/var/lib/weechat";
script = "${tmux} -2 new-session -d -s IM ${weechat}/bin/weechat";
preStop = "${tmux} kill-session -t IM";
serviceConfig = {
User = "weechat";
RemainAfterExit = true;
Type = "oneshot";
};
};
users.groups.weechat = {};
users.extraUsers.weechat = {
useDefaultShell = true;
openssh.authorizedKeys.keys = kieran.sshKeys pkgs ++ [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC+KVDmYYH7mA8v81e9O3swXm3ZVYY9t4HP65ud61uXy weechat_android@heym"
];
createHome = true;
group = "weechat";
home = "/var/lib/weechat";
isSystemUser = true;
packages = [ pkgs.tmux ];
};
}

38
deploy.nix Normal file
View File

@@ -0,0 +1,38 @@
let
inherit (import ./lib/default.nix) sshPort;
krops = builtins.fetchGit { url = "https://cgit.krebsco.de/krops/"; };
lib = import "${krops}/lib";
pkgs = import "${krops}/pkgs" { };
source = name: lib.evalSource [{
niveum.file = toString ./.;
system-secrets.pass = {
dir = toString ~/.password-store;
name = "systems/${name}";
};
secrets.pass = {
dir = toString ~/.password-store;
name = "shared";
};
}];
command = targetPath: ''
nix-shell -p git --run '
nixos-rebuild switch -v --show-trace --flake ${targetPath}/niveum || \
nixos-rebuild switch -v --flake ${targetPath}/niveum
'
'';
createHost = name: target: pkgs.krops.writeCommand "deploy-${name}" {
source = source name;
inherit command target;
};
in rec {
zaatar = createHost "zaatar" "root@zaatar.r:${toString sshPort}";
kabsa = createHost "kabsa" "root@kabsa.r:${toString sshPort}";
makanek = createHost "kabsa" "root@makanek.r:${toString sshPort}";
manakish = createHost "kabsa" "root@manakish.r:${toString sshPort}";
all = pkgs.writeScript "deploy-all"
(lib.concatStringsSep "\n" [ zaatar kabsa makanek manakish ]);
}

223
flake.lock generated
View File

@@ -1,20 +1,5 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"locked": {
"lastModified": 1638122382,
"narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "74f7e4319258e287b0f9cb95426c9853b282730b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -37,58 +22,19 @@
} }
}, },
"krops": { "krops": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1632420452,
"narHash": "sha256-ncK6vABW/Ku9XI0kqj1otarUfblryoQzSaOCnaZ0oSs=",
"owner": "Mic92",
"repo": "krops",
"rev": "0388970c568905fedcbf429e5745aacd4f7a6633",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "krops",
"type": "github"
}
},
"menstruation-backend": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1634573652, "lastModified": 1637419569,
"narHash": "sha256-FIj8oCOJO+Wqxr2o5MMqIShvzMJud4iUq3o8y4NIRvw=", "narHash": "sha256-0hxKZQIoByRDoPsfQq5qzFJioyWRX/fbpvMO2EYQ9lc=",
"owner": "kmein", "ref": "master",
"repo": "menstruation.rs", "rev": "13ae434b140035e7e2664bd5a8ef4c475413b2e0",
"rev": "dd405fe2acf32441e8ac56e488e689bb1c4bea82", "revCount": 115,
"type": "github" "type": "git",
"url": "https://cgit.krebsco.de/krops"
}, },
"original": { "original": {
"owner": "kmein", "type": "git",
"repo": "menstruation.rs", "url": "https://cgit.krebsco.de/krops"
"type": "github"
}
},
"menstruation-telegram": {
"flake": false,
"locked": {
"lastModified": 1634815642,
"narHash": "sha256-q1OTMx5ayNu9ppHJBDUie/ow+BcA5DXnHEm11EY+C4E=",
"owner": "kmein",
"repo": "menstruation-telegram",
"rev": "a34555cf46f02157718b0565b5456348fff54181",
"type": "github"
},
"original": {
"owner": "kmein",
"repo": "menstruation-telegram",
"type": "github"
} }
}, },
"nix-writers": { "nix-writers": {
@@ -109,60 +55,59 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1641829252, "lastModified": 1640759603,
"narHash": "sha256-CI0qi7k1Y4nFna+kdQtVCbN4ZEVwZcD/oIGgfTcUNrA=", "narHash": "sha256-k4d7oC6GvDV1OKxG325JUDpKtZcDUPEiddnJMOQQ/x8=",
"owner": "NixOS", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5d3420c1285073d5061a5d88a533b347d1222750", "rev": "e101dc111ac1e5a21efca7822417acc1cb92013a",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "nixos",
"ref": "release-21.11", "ref": "release-21.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-mozilla": {
"flake": false,
"locked": { "locked": {
"lastModified": 1641935776, "lastModified": 1638887313,
"narHash": "sha256-8q/V9EgzyW0KvGnBjbTfQ19qoTCFqsEd1mF9DheCukw=", "narHash": "sha256-FMYV6rVtvSIfthgC1sK1xugh3y7muoQcvduMdriz4ag=",
"owner": "NixOS", "owner": "mozilla",
"repo": "nixpkgs", "repo": "nixpkgs-mozilla",
"rev": "bd20b7f07fd337b2e85420edd642382a2cc0196d", "rev": "7c1e8b1dd6ed0043fb4ee0b12b815256b0b9de6f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "mozilla",
"ref": "master", "repo": "nixpkgs-mozilla",
"repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"recht": { "nixpkgs-unstable": {
"flake": false,
"locked": { "locked": {
"lastModified": 1619583518, "lastModified": 1640725200,
"narHash": "sha256-3eFw6xWue9cvPxXq1ROq32ecvPOmqOedgQhyOr7N9iE=", "narHash": "sha256-yR8clhRTt1OBFojyBaNnNgD+om51nhuJ1OLqWqdY2Ow=",
"owner": "kmein", "owner": "nixos",
"repo": "recht", "repo": "nixpkgs",
"rev": "d551afed23122bb3106e59eb2274394ec5555048", "rev": "eaeea6e9337b93d2acb7c2aa27e3f4617408375a",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "kmein", "owner": "nixos",
"repo": "recht", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"retiolum": { "retiolum": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1643369411, "lastModified": 1640724425,
"narHash": "sha256-FRfEQdRJxVF6w41jgjQXDtK5YxIjDh5S4acA0FbwPyE=", "narHash": "sha256-eGzvF96ZnrKqvQ7wnpa9OYsfBxUMV0Jdh3QGdZhbSek=",
"owner": "krebs", "owner": "krebs",
"repo": "retiolum", "repo": "retiolum",
"rev": "23e04565a0360d31605a6c6cdc1becb5b9f76f32", "rev": "5a32ea07d6ca5668ea06f14dffe94fb46d42c674",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -173,48 +118,24 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"home-manager": "home-manager", "home-manager": "home-manager",
"krops": "krops", "krops": "krops",
"menstruation-backend": "menstruation-backend",
"menstruation-telegram": "menstruation-telegram",
"nix-writers": "nix-writers", "nix-writers": "nix-writers",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-mozilla": "nixpkgs-mozilla",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"recht": "recht",
"retiolum": "retiolum", "retiolum": "retiolum",
"scripts": "scripts", "stockholm": "stockholm"
"stockholm": "stockholm",
"telebots": "telebots",
"tinc-graph": "tinc-graph",
"traadfri": "traadfri",
"tuna": "tuna"
}
},
"scripts": {
"flake": false,
"locked": {
"lastModified": 1639436812,
"narHash": "sha256-6CajvfDo7t4ANgjc7DxqH7lI3WRE4MK8q3mBKAjk80k=",
"owner": "kmein",
"repo": "scripts",
"rev": "d34a8161ba11135a45d3141dc9af482db945d63c",
"type": "github"
},
"original": {
"owner": "kmein",
"repo": "scripts",
"type": "github"
} }
}, },
"stockholm": { "stockholm": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1641747862, "lastModified": 1640726454,
"narHash": "sha256-gAGM3sxCP//k83CUow3ZpeHQCeuW62YJ6kWvWd8D1vk=", "narHash": "sha256-twePnoB0NRhSM4zJOrUI/Zxzwx/u52ey6zA4YYGEvOc=",
"ref": "master", "ref": "master",
"rev": "f67bd5783d6ed2be836c7714ea38cbb3f7ac7257", "rev": "2a47990f16935d909930c9dd1ed6f8f2982df638",
"revCount": 10285, "revCount": 10218,
"type": "git", "type": "git",
"url": "https://cgit.lassul.us/stockholm" "url": "https://cgit.lassul.us/stockholm"
}, },
@@ -222,70 +143,6 @@
"type": "git", "type": "git",
"url": "https://cgit.lassul.us/stockholm" "url": "https://cgit.lassul.us/stockholm"
} }
},
"telebots": {
"flake": false,
"locked": {
"lastModified": 1623510321,
"narHash": "sha256-MxYNNL81RXZkYLd4IgiNTSo1X80kTuDzsdGNSA0f1y8=",
"owner": "kmein",
"repo": "telebots",
"rev": "22931c9457e092c4e413555dbe61819d77844246",
"type": "github"
},
"original": {
"owner": "kmein",
"repo": "telebots",
"type": "github"
}
},
"tinc-graph": {
"flake": false,
"locked": {
"lastModified": 1639820904,
"narHash": "sha256-d4s2PulBGIIQXtX7blZz+Wnmij5dK/IrBcilNGjqZC4=",
"owner": "kmein",
"repo": "tinc-graph",
"rev": "1b9c69ffdbdab82d30a23e44f739feea63d94163",
"type": "github"
},
"original": {
"owner": "kmein",
"repo": "tinc-graph",
"type": "github"
}
},
"traadfri": {
"flake": false,
"locked": {
"lastModified": 1640451803,
"narHash": "sha256-zS/b93uFpPM9basNP7ngmm+YjYV0IUQAmNghetHA6Ss=",
"owner": "kmein",
"repo": "traadfri",
"rev": "cf46bd09cd3263b90a09b0ca979aa705a4c3671c",
"type": "github"
},
"original": {
"owner": "kmein",
"repo": "traadfri",
"type": "github"
}
},
"tuna": {
"flake": false,
"locked": {
"lastModified": 1627117248,
"narHash": "sha256-OfqbWLblJY4BJlrCpn8EkHoP3baNJSDTbw45SPaX+0Q=",
"owner": "kmein",
"repo": "tuna",
"rev": "1cbed44069a3009738afdafecefe0a05316039a6",
"type": "github"
},
"original": {
"owner": "kmein",
"repo": "tuna",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

143
flake.nix
View File

@@ -1,92 +1,79 @@
# imported from https://github.com/pinpox/nixos/blob/bdc0d47111d57cd19512c83538a01f9f9a3fc847/flake.nix
# ref https://www.youtube.com/watch?v=mJbQ--iBc1U
{ {
description = "niveum: packages, modules, systems"; description = "niveum systems";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/release-21.11"; nixpkgs.url = "github:nixos/nixpkgs/release-21.11";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/master"; nixpkgs-unstable.url = "github:nixos/nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-21.11"; url = "github:nix-community/home-manager/release-21.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
krops = { # flake-utils.url = "github:numtide/flake-utils";
url = "github:Mic92/krops"; # flake-compat = {
inputs.nixpkgs.follows = "nixpkgs"; # url = "github:edolstra/flake-compat";
inputs.flake-utils.follows = "flake-utils"; # flake = false;
# };
stockholm = {
url = "git+https://cgit.lassul.us/stockholm";
flake = false;
};
nix-writers = {
url = "git+https://cgit.krebsco.de/nix-writers";
flake = false;
};
krops = {
url = "git+https://cgit.krebsco.de/krops";
flake = false;
};
retiolum = {
url = "github:krebs/retiolum";
flake = false;
};
nixpkgs-mozilla = {
url = "github:mozilla/nixpkgs-mozilla";
flake = false;
}; };
# legacy
menstruation-backend = { url = "github:kmein/menstruation.rs"; flake = false; };
menstruation-telegram = { url = "github:kmein/menstruation-telegram"; flake = false; };
nix-writers = { url = "git+https://cgit.krebsco.de/nix-writers"; flake = false; };
recht = { url = "github:kmein/recht"; flake = false; };
retiolum = { url = "github:krebs/retiolum"; flake = false; };
scripts = { url = "github:kmein/scripts"; flake = false; };
stockholm = { url = "git+https://cgit.lassul.us/stockholm"; flake = false; };
telebots = { url = "github:kmein/telebots"; flake = false; };
tinc-graph = { url = "github:kmein/tinc-graph"; flake = false; };
traadfri = { url = "github:kmein/traadfri"; flake = false; };
tuna = { url = "github:kmein/tuna"; flake = false; };
}; };
outputs = outputs = { self, nixpkgs, nix-writers, home-manager, stockholm, ... }@inputs:
{ self
, flake-utils
, home-manager
, krops
, menstruation-backend
, menstruation-telegram
, nix-writers
, nixpkgs
, nixpkgs-unstable
, recht
, retiolum
, scripts
, stockholm
, telebots
, tinc-graph
, traadfri
, tuna
}@inputs:
let let
system = "x86_64-linux"; nixosSystem = nixpkgs.lib.makeOverridable nixpkgs.lib.nixosSystem;
pkgs = nixpkgs.legacyPackages.${system};
source = name: { defaultModules = [
niveum.file = toString ./.; { _module.args.inputs = inputs; }
nixos-config.symlink = "niveum/systems/${name}/configuration.nix"; {
system-secrets.pass = { imports = [
dir = toString ~/.password-store; home-manager.nixosModules.home-manager
name = "systems/${name}"; "${stockholm}/krebs/3modules/power-action.nix"
}; "${stockholm}/krebs/3modules/fetchWallpaper.nix"
secrets.pass = { ({ pkgs, ... }: {
dir = toString ~/.password-store; nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
name = "shared"; nixpkgs.overlays = [
}; (import "${nix-writers}/pkgs")
} // nixpkgs.lib.mapAttrs' (name: value: { (import "${stockholm}/krebs/5pkgs")
inherit name; ];
value.file = toString value; })
}) (nixpkgs.lib.filterAttrs (name: _: !builtins.elem name [ "flake-utils" "krops" "self" ]) inputs); ({ pkgs, ... }: { # https://github.com/Mic92/dotfiles/blob/50826e8f247909557975f4f193ecbb4162b07310/nixos/modules/upgrade-diff.nix
deployScriptFor = {name, host}: let inherit (import ./lib/default.nix) sshPort; in toString (krops.packages.${system}.writeDeploy "deploy-${name}" { system.activationScripts.diff = ''
source = krops.lib.evalSource [ (source name) ]; ${pkgs.nix}/bin/nix store diff-closures /run/current-system "$systemConfig"
target = "root@${host}:${toString sshPort}"; '';
}); })
];
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
}
];
in { in {
apps.${system} = let nixosConfigurations = {
forSystems = f: builtins.listToAttrs (map f (builtins.attrNames (builtins.readDir ./systems))); kabsa = nixosSystem {
deployScripts = forSystems (name: { system = "x86_64-linux";
name = "deploy-${name}"; modules = defaultModules ++ [
value = { systems/kabsa/configuration.nix
type = "app"; ];
program = deployScriptFor { inherit name; host = "${name}.r"; }; };
}; };
});
ciScripts = forSystems (name: {
name = "build-${name}";
value = {
type = "app";
program = import ./ci.nix { inherit name system inputs; };
};
});
in deployScripts // ciScripts;
}; };
} }

View File

@@ -1,37 +0,0 @@
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,12 +1,6 @@
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}");
@@ -21,7 +15,7 @@ rec {
sshPort = 22022; sshPort = 22022;
colours = import ./colours/ibm-3270.nix; colours = import ./colours/mac-os.nix;
theme = pkgs: { theme = pkgs: {
gtk = { gtk = {

View File

@@ -1,179 +0,0 @@
{pkgs, path}: ''
<config>
<paths>
<path recursive="1">${path}</path>
</paths>
<sounddirs/>
<dictionaryOrder name="" id="0">
<mutedDictionaries/>
</dictionaryOrder>
<inactiveDictionaries name="" id="0">
<mutedDictionaries/>
</inactiveDictionaries>
<groups nextId="1"/>
<hunspell dictionariesPath=""/>
<transliteration>
<enableRussianTransliteration>0</enableRussianTransliteration>
<enableGermanTransliteration>0</enableGermanTransliteration>
<enableGreekTransliteration>0</enableGreekTransliteration>
<enableBelarusianTransliteration>0</enableBelarusianTransliteration>
<chinese>
<enable>0</enable>
<enableSCToTWConversion>1</enableSCToTWConversion>
<enableSCToHKConversion>1</enableSCToHKConversion>
<enableTCToSCConversion>1</enableTCToSCConversion>
</chinese>
<romaji>
<enable>0</enable>
<enableHepburn>1</enableHepburn>
<enableNihonShiki>0</enableNihonShiki>
<enableKunreiShiki>0</enableKunreiShiki>
<enableHiragana>1</enableHiragana>
<enableKatakana>1</enableKatakana>
</romaji>
</transliteration>
<forvo>
<enable>0</enable>
<apiKey></apiKey>
<languageCodes></languageCodes>
</forvo>
<mediawikis>
<mediawiki enabled="0" name="English Wikipedia" icon="" id="ae6f89aac7151829681b85f035d54e48" url="https://en.wikipedia.org/w"/>
<mediawiki enabled="0" name="English Wiktionary" icon="" id="affcf9678e7bfe701c9b071f97eccba3" url="https://en.wiktionary.org/w"/>
<mediawiki enabled="0" name="German Wikipedia" icon="" id="a8a66331a1242ca2aeb0b4aed361c41d" url="https://de.wikipedia.org/w"/>
<mediawiki enabled="0" name="German Wiktionary" icon="" id="21c64bca5ec10ba17ff19f3066bc962a" url="https://de.wiktionary.org/w"/>
</mediawikis>
<websites>
<website enabled="0" name="Google En-En (Oxford)" icon="" id="b88cb2898e634c6638df618528284c2d" url="https://www.google.com/search?q=define:%GDWORD%&amp;hl=en" inside_iframe="1"/>
<website enabled="0" name="Urban Dictionary" icon="" id="f376365a0de651fd7505e7e5e683aa45" url="https://www.urbandictionary.com/define.php?term=%GDWORD%" inside_iframe="1"/>
<website enabled="0" name="Multitran (En)" icon="" id="324ca0306187df7511b26d3847f4b07c" url="https://multitran.ru/c/m.exe?CL=1&amp;l1=1&amp;s=%GD1251%" inside_iframe="1"/>
<website enabled="0" name="Lingvo (En-Ru)" icon="" id="924db471b105299c82892067c0f10787" url="http://lingvopro.abbyyonline.com/en/Search/en-ru/%GDWORD%" inside_iframe="1"/>
<website enabled="0" name="Michaelis (Pt-En)" icon="" id="087a6d65615fb047f4c80eef0a9465db" url="http://michaelis.uol.com.br/moderno/ingles/index.php?lingua=portugues-ingles&amp;palavra=%GDISO1%" inside_iframe="1"/>
</websites>
<dictservers/>
<programs>
<program enabled="0" name="Espeak" icon="" id="2cf8b3a60f27e1ac812de0b57c148340" commandLine="${pkgs.espeak}/bin/espeak %GDWORD%" type="0"/>
<program enabled="0" name="Manpages" icon="" id="4f898f7582596cea518c6b0bfdceb8b3" commandLine="${pkgs.man_db}/bin/man -a --html=/bin/cat %GDWORD%" type="2"/>
</programs>
<voiceEngines/>
<mutedDictionaries/>
<popupMutedDictionaries>
<mutedDictionary>ae6f89aac7151829681b85f035d54e48</mutedDictionary>
</popupMutedDictionaries>
<preferences>
<interfaceLanguage></interfaceLanguage>
<helpLanguage></helpLanguage>
<displayStyle>modern</displayStyle>
<newTabsOpenAfterCurrentOne>0</newTabsOpenAfterCurrentOne>
<newTabsOpenInBackground>1</newTabsOpenInBackground>
<hideSingleTab>0</hideSingleTab>
<mruTabOrder>0</mruTabOrder>
<hideMenubar>0</hideMenubar>
<enableTrayIcon>1</enableTrayIcon>
<startToTray>1</startToTray>
<closeToTray>1</closeToTray>
<autoStart>0</autoStart>
<doubleClickTranslates>1</doubleClickTranslates>
<selectWordBySingleClick>0</selectWordBySingleClick>
<escKeyHidesMainWindow>0</escKeyHidesMainWindow>
<zoomFactor>1</zoomFactor>
<helpZoomFactor>1</helpZoomFactor>
<wordsZoomLevel>0</wordsZoomLevel>
<enableMainWindowHotkey>1</enableMainWindowHotkey>
<mainWindowHotkey>Ctrl+F11, Ctrl+F11</mainWindowHotkey>
<enableClipboardHotkey>1</enableClipboardHotkey>
<clipboardHotkey>Ctrl+C, Ctrl+C</clipboardHotkey>
<enableScanPopup>1</enableScanPopup>
<startWithScanPopupOn>0</startWithScanPopupOn>
<enableScanPopupModifiers>0</enableScanPopupModifiers>
<scanPopupModifiers>0</scanPopupModifiers>
<scanPopupAltMode>0</scanPopupAltMode>
<scanPopupAltModeSecs>3</scanPopupAltModeSecs>
<ignoreOwnClipboardChanges>0</ignoreOwnClipboardChanges>
<scanToMainWindow>0</scanToMainWindow>
<ignoreDiacritics>0</ignoreDiacritics>
<showScanFlag>0</showScanFlag>
<scanPopupUseUIAutomation>1</scanPopupUseUIAutomation>
<scanPopupUseIAccessibleEx>1</scanPopupUseIAccessibleEx>
<scanPopupUseGDMessage>1</scanPopupUseGDMessage>
<scanPopupUnpinnedWindowFlags>0</scanPopupUnpinnedWindowFlags>
<scanPopupUnpinnedBypassWMHint>0</scanPopupUnpinnedBypassWMHint>
<pronounceOnLoadMain>0</pronounceOnLoadMain>
<pronounceOnLoadPopup>0</pronounceOnLoadPopup>
<useInternalPlayer>1</useInternalPlayer>
<internalPlayerBackend>FFmpeg+libao</internalPlayerBackend>
<audioPlaybackProgram>mplayer</audioPlaybackProgram>
<alwaysOnTop>1</alwaysOnTop>
<searchInDock>1</searchInDock>
<historyStoreInterval>0</historyStoreInterval>
<favoritesStoreInterval>0</favoritesStoreInterval>
<confirmFavoritesDeletion>1</confirmFavoritesDeletion>
<proxyserver enabled="0" useSystemProxy="0">
<type>0</type>
<host></host>
<port>3128</port>
<user></user>
<password></password>
<systemProxyUser></systemProxyUser>
<systemProxyPassword></systemProxyPassword>
</proxyserver>
<disallowContentFromOtherSites>0</disallowContentFromOtherSites>
<enableWebPlugins>0</enableWebPlugins>
<hideGoldenDictHeader>0</hideGoldenDictHeader>
<maxNetworkCacheSize>50</maxNetworkCacheSize>
<clearNetworkCacheOnExit>1</clearNetworkCacheOnExit>
<maxStringsInHistory>500</maxStringsInHistory>
<storeHistory>1</storeHistory>
<alwaysExpandOptionalParts>0</alwaysExpandOptionalParts>
<addonStyle></addonStyle>
<collapseBigArticles>0</collapseBigArticles>
<articleSizeLimit>2000</articleSizeLimit>
<limitInputPhraseLength>0</limitInputPhraseLength>
<inputPhraseLengthLimit>1000</inputPhraseLengthLimit>
<maxDictionaryRefsInContextMenu>20</maxDictionaryRefsInContextMenu>
<trackClipboardChanges>0</trackClipboardChanges>
<synonymSearchEnabled>1</synonymSearchEnabled>
<fullTextSearch>
<searchMode>0</searchMode>
<matchCase>0</matchCase>
<maxArticlesPerDictionary>100</maxArticlesPerDictionary>
<maxDistanceBetweenWords>2</maxDistanceBetweenWords>
<useMaxArticlesPerDictionary>0</useMaxArticlesPerDictionary>
<useMaxDistanceBetweenWords>1</useMaxDistanceBetweenWords>
<dialogGeometry></dialogGeometry>
<disabledTypes></disabledTypes>
<enabled>1</enabled>
<ignoreWordsOrder>0</ignoreWordsOrder>
<ignoreDiacritics>0</ignoreDiacritics>
<maxDictionarySize>0</maxDictionarySize>
</fullTextSearch>
</preferences>
<lastMainGroupId>0</lastMainGroupId>
<lastPopupGroupId>0</lastPopupGroupId>
<popupWindowState>AAAA/wAAAAH9AAAAAAAAAg0AAAGTAAAABAAAAAQAAAAIAAAACPwAAAABAAAAAQAAAAEAAAAaAGQAaQBjAHQAaQBvAG4AYQByAHkAQgBhAHIDAAAAAP////8AAAAAAAAAAA==</popupWindowState>
<popupWindowGeometry>AdnQywADAAAAAAC6AAABEgAAAuYAAAKkAAAAugAAARIAAALmAAACpAAAAAAAAAAABVYAAAC6AAABEgAAAuYAAAKk</popupWindowGeometry>
<pinPopupWindow>0</pinPopupWindow>
<popupWindowAlwaysOnTop>0</popupWindowAlwaysOnTop>
<mainWindowState>AAAA/wAAAAH9AAAAAgAAAAAAAADMAAAC0PwCAAAAAfsAAAAUAHMAZQBhAHIAYwBoAFAAYQBuAGUBAAAAFAAAAtAAAAB9AP///wAAAAEAAADMAAAC0PwCAAAAA/sAAAASAGQAaQBjAHQAcwBQAGEAbgBlAQAAABQAAAFvAAAAYQD////7AAAAGgBmAGEAdgBvAHIAaQB0AGUAcwBQAGEAbgBlAAAAABQAAALQAAAAYQD////7AAAAFgBoAGkAcwB0AG8AcgB5AFAAYQBuAGUBAAABhAAAAWAAAABhAP///wAAA7QAAALQAAAABAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAIAAAAUAG4AYQB2AFQAbwBvAGwAYgBhAHIAAAAAAP////8AAAAAAAAAAAAAABoAZABpAGMAdABpAG8AbgBhAHIAeQBCAGEAcgAAAAAA/////wAAAAAAAAAA</mainWindowState>
<mainWindowGeometry>AdnQywADAAAAAAAEAAAAGAAABVEAAAL7AAAABAAAABgAAAVRAAAC+wAAAAAAAAAABVYAAAAEAAAAGAAABVEAAAL7</mainWindowGeometry>
<helpWindowGeometry>AdnQywADAAAAAAF3AAAAgwAAA9AAAAJGAAABeAAAAIQAAAPPAAACRQAAAAAAAAAABVYAAAF4AAAAhAAAA88AAAJF</helpWindowGeometry>
<helpSplitterState>AAAA/wAAAAEAAAACAAABBAAABAAB/////wEAAAABAA==</helpSplitterState>
<dictInfoGeometry>AdnQywADAAAAAAF1AAAAmgAAA84AAAIrAAABdgAAAJsAAAPNAAACKgAAAAAAAAAABVYAAAF2AAAAmwAAA80AAAIq</dictInfoGeometry>
<inspectorGeometry></inspectorGeometry>
<timeForNewReleaseCheck></timeForNewReleaseCheck>
<skippedRelease></skippedRelease>
<showingDictBarNames>1</showingDictBarNames>
<usingSmallIconsInToolbars>1</usingSmallIconsInToolbars>
<editDictionaryCommandLine></editDictionaryCommandLine>
<maxPictureWidth>0</maxPictureWidth>
<maxHeadwordSize>256</maxHeadwordSize>
<maxHeadwordsToExpand>0</maxHeadwordsToExpand>
<headwordsDialog>
<searchMode>0</searchMode>
<matchCase>0</matchCase>
<autoApply>0</autoApply>
<headwordsExportPath></headwordsExportPath>
<headwordsDialogGeometry></headwordsDialogGeometry>
</headwordsDialog>
</config>
''

View File

@@ -92,6 +92,11 @@ 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}";
}
{ {
block = "custom"; block = "custom";
interval = 60 * 5; interval = 60 * 5;
@@ -100,6 +105,7 @@ in {
import astral import astral
import astral.moon import astral.moon
import astral.sun import astral.sun
import math
moon_phases = { moon_phases = {
0: "🌑", 0: "🌑",
@@ -115,22 +121,38 @@ in {
current_phase = astral.moon.phase() current_phase = astral.moon.phase()
closest_phase = min(moon_phases.keys(), key=lambda x: abs(current_phase - x)) closest_phase = min(moon_phases.keys(), key=lambda x: abs(current_phase - x))
moon_percentage = round(100 * math.sin(current_phase / 28 * math.pi), 1)
city = astral.LocationInfo("Berlin", "Germany", "${spacetime.time.timeZone}", ${toString spacetime.location.latitude}, ${toString spacetime.location.longitude}) city = astral.LocationInfo("Berlin", "Germany", "${spacetime.time.timeZone}", ${toString spacetime.location.latitude}, ${toString spacetime.location.longitude})
sun = astral.sun.sun(city.observer, date=astral.today(), tzinfo=city.timezone) sun = astral.sun.sun(city.observer, date=astral.today(), tzinfo=city.timezone)
print("🌅 {} 🌇 {} {} {}".format(sun["sunrise"].strftime("%R"), sun["sunset"].strftime("%R"), moon_phases[closest_phase], round(current_phase, 1))) print("🌅 {} 🌇 {} {} {}%".format(sun["sunrise"].strftime("%R"), sun["sunset"].strftime("%R"), moon_phases[closest_phase], moon_percentage))
''; '';
} }
{ {
block = "custom"; block = "custom";
interval = 5; interval = 60 * 60;
command = pkgs.writers.writeDash "hu-berlin-vpn" '' command = pkgs.writers.writeDash "vax" ''
PATH=${lib.makeBinPath [ pkgs.systemd ]} ${pkgs.curl}/bin/curl -sSL https://api.corona-zahlen.org/vaccinations \
(systemctl is-active --quiet openvpn-hu-berlin.service && echo "🎓👍 (OpenVPN)") \ | ${pkgs.jq}/bin/jq -r '"💉 \(.data.quote * 1000 | floor | . / 10)% \(.data.secondVaccination.quote * 1000 | floor | . / 10)%"'
|| (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://prem3.di.fm/${name}_hi?${di-fm-key}"; di-fm = name: "http://prem2.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";
@@ -49,10 +49,6 @@ in [
logo = "http://lassul.us/art/portraits/selbstportrait.jpg"; logo = "http://lassul.us/art/portraits/selbstportrait.jpg";
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.";
} }
{
station = "C3 Lounge";
stream = "https://c3lounge.de/radio/8000/radio.mp3";
}
{ {
stream = "https://radio.kmein.de/lyrik/listen.ogg"; stream = "https://radio.kmein.de/lyrik/listen.ogg";
station = "Lyrik"; station = "Lyrik";
@@ -96,491 +92,583 @@ 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";
} }
@@ -1331,6 +1419,16 @@ 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,14 +17,16 @@ 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<CR> noremap <Leader>gs :Gstatus<CR>
noremap <Leader>gc :Git commit<CR> noremap <Leader>gc :Gcommit<CR>
noremap <leader>n :bn<CR> noremap <leader>n :bn<CR>
noremap <leader>p :bp<CR> noremap <leader>p :bp<CR>
noremap <leader>c :bd<CR> noremap <leader>c :bd<CR>
noremap <leader>b :Buffers<CR> noremap <leader>b :Buffers<CR>
noremap <leader>t :Tags<CR> noremap <leader>t :Tags<CR>
noremap <leader>f :Goyo<CR>
" reindent whole file " reindent whole file
noremap <leader>i mzgg=G`z noremap <leader>i mzgg=G`z
@@ -60,17 +62,18 @@ set list listchars=tab:⇥\ ,extends:,precedes:,nbsp:␣,trail:· showbrea
set foldlevelstart=30 set foldlevelstart=30
iabbrev ddate <C-R>=strftime("%F")<CR> iabbrev ddate <C-R>=strftime("%F")<CR>
iabbrev dtime <C-R>=strftime("%F %T")<CR>
" if exists("g:loaded_netrwPlugin")
let g:netrw_banner=0 let g:netrw_banner=0
let g:netrw_browse_split=4 let g:netrw_browse_split=4
let g:netrw_altv=1 " open splits to the right let g:netrw_altv=1 " open splits to the right
let g:netrw_liststyle=3 " tree view let g:netrw_liststyle=3 " tree view
let g:netrw_list_hide=netrw_gitignore#Hide() let g:netrw_list_hide=netrw_gitignore#Hide()
let g:netrw_list_hide.=',\(^\|\s\s\)\zs\.\S\+' let g:netrw_list_hide.=',\(^\|\s\s\)\zs\.\S\+'
" endif
call matchadd('colorcolumn', '\%101v', 100) " call matchadd('colorcolumn', '\%101v', 100)
highlight colorcolumn ctermbg=red " highlight colorcolumn ctermbg=red
" undofile - This allows you to use undos after exiting and restarting " undofile - This allows you to use undos after exiting and restarting
" This, like swap and backups, uses .vim-undo first, then ~/.vim/undo " This, like swap and backups, uses .vim-undo first, then ~/.vim/undo
@@ -79,7 +82,8 @@ if exists("+undofile")
if isdirectory($HOME . '/.vim/undo') == 0 if isdirectory($HOME . '/.vim/undo') == 0
:silent !mkdir -p ~/.vim/undo > /dev/null 2>&1 :silent !mkdir -p ~/.vim/undo > /dev/null 2>&1
endif endif
set undodir=~/.vim/undo/ set undodir=./.vim-undo//
set undodir+=~/.vim/undo//
set undofile set undofile
endif endif
@@ -109,37 +113,61 @@ command! ToggleBackground call s:toggle_background()
inoremap <F12> <C-O>:ToggleBackground<CR> inoremap <F12> <C-O>:ToggleBackground<CR>
nnoremap <F12> :ToggleBackground<CR> nnoremap <F12> :ToggleBackground<CR>
autocmd bufnewfile,bufread *.4th set filetype=forth if has("autocmd")
autocmd bufnewfile,bufread *.asm set filetype=nasm autocmd bufnewfile,bufread *.4th set filetype=forth
autocmd bufnewfile,bufread *.c set keywordprg=man\ 3 autocmd bufnewfile,bufread *.asm set filetype=nasm
autocmd bufnewfile,bufread *.h set keywordprg=man\ 3 autocmd bufnewfile,bufread *.c set keywordprg=man\ 3
autocmd bufnewfile,bufread *.conf set filetype=conf autocmd bufnewfile,bufread *.conf set filetype=conf
autocmd bufnewfile,bufread *.nix packadd vim-nix | set filetype=nix | set path+=/var/src autocmd bufnewfile,bufread *.fs packadd vim-fsharp | set filetype=fsharp
autocmd bufnewfile,bufread *.rust packadd rust-vim autocmd bufnewfile,bufread *.h set keywordprg=man\ 3
autocmd bufnewfile,bufread *.csv packadd csv.vim | set filetype=csv autocmd bufnewfile,bufread *.nix packadd vim-nix | set filetype=nix | set path+=/var/src
autocmd bufnewfile,bufread *.tex packadd vimtex | set filetype=tex autocmd bufnewfile,bufread *.rust packadd rust-vim " | packadd deoplete-rust
autocmd bufnewfile,bufread *.ics packadd icalendar.vim | set filetype=icalendar autocmd bufnewfile,bufread *.csv packadd csv-vim | set filetype=csv
autocmd bufnewfile,bufread *.ts packadd typescript-vim | set filetype=typescript autocmd bufnewfile,bufread *.toml packadd vim-toml | set filetype=toml
autocmd bufnewfile,bufread *.jq packadd jq.vim autocmd bufnewfile,bufread *.nim packadd nim-vim | set filetype=nim
autocmd bufnewfile,bufread *.journal packadd vim-ledger | set filetype=ledger shiftwidth=4 autocmd bufnewfile,bufread *.tex packadd vimtex | set filetype=tex
autocmd bufnewfile,bufread urls,config set filetype=conf autocmd bufnewfile,bufread *.ics packadd icalendar.vim | set filetype=icalendar
autocmd bufnewfile,bufread *.elm packadd elm-vim | set filetype=elm shiftwidth=4 autocmd bufnewfile,bufread *.ts packadd typescript-vim | set filetype=typescript
autocmd bufnewfile,bufread *.md packadd vim-pandoc | packadd vim-pandoc-syntax | set filetype=pandoc autocmd bufnewfile,bufread *.purs packadd purescript-vim | set filetype=purescript
autocmd filetype haskell packadd haskell-vim | set keywordprg=hoogle\ -i autocmd bufnewfile,bufread *.jq packadd jq.vim
autocmd filetype javascript packadd vim-javascript autocmd bufnewfile,bufread *.re packadd vim-reason-plus | set filetype=reason
autocmd filetype make setlocal noexpandtab autocmd bufnewfile,bufread *.journal packadd vim-ledger | set filetype=ledger shiftwidth=4
autocmd bufnewfile,bufread *.md packadd vim-pandoc | packadd vim-pandoc-syntax
autocmd bufnewfile,bufread urls,config set filetype=conf
autocmd bufnewfile,bufread *.elm packadd elm-vim | set filetype=elm shiftwidth=4
autocmd bufnewfile,bufread *.dhall packadd dhall-vim | set filetype=dhall
autocmd filetype haskell packadd haskell-vim | set keywordprg=hoogle\ -i
autocmd filetype javascript packadd vim-javascript
autocmd filetype make setlocal noexpandtab
autocmd filetype html packadd emmet-vim
autocmd filetype gitcommit setlocal spell spelllang=en
autocmd filetype mail setlocal spell spelllang=de textwidth=0 | command Send %! mail-send
autocmd bufreadpost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
autocmd bufreadpre * setlocal foldmethod=indent
" autocmd bufwritepre * :call <SID>StripTrailingWhitespaces()
" autocmd bufwinenter * if &fdm == 'indent' | setlocal foldmethod=manual | endif
autocmd filetype html packadd emmet-vim autocmd VimEnter * UpdateRemotePlugins
autocmd filetype gitcommit setlocal spell spelllang=en endif
autocmd filetype mail setlocal spell spelllang=de textwidth=0
autocmd bufreadpost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
autocmd bufreadpre * setlocal foldmethod=indent
let g:startify_custom_header = ''
" let g:deoplete#enable_at_startup = 1
set completeopt=noinsert,menuone,noselect set completeopt=noinsert,menuone,noselect
set complete+=kspell set complete+=kspell
" let g:deoplete#sources = {}
" let g:deoplete#sources._ = ['ale', 'file', 'omni', 'buffer']
"
" let g:deoplete#sources#rust#racer_binary = $HOME . '/.cargo/bin/racer'
" let g:deoplete#sources#rust#rust_source_path = substitute(system('rustc --print sysroot'), '\n$', '', '') . '/lib/rustlib/src/rust/src'
inoremap ^] ^X^]
inoremap ^F ^X^F
inoremap ^D ^X^D
inoremap ^L ^X^L
let g:SuperTabDefaultCompletionType = 'context' let g:SuperTabDefaultCompletionType = 'context'
@@ -169,6 +197,7 @@ let g:ale_fixers = {
\ 'typescript': ['prettier'], \ 'typescript': ['prettier'],
\ 'css': ['prettier'], \ 'css': ['prettier'],
\ 'html': ['prettier'], \ 'html': ['prettier'],
\ 'markdown': ['prettier'],
\ 'json': ['jq'], \ 'json': ['jq'],
\ 'python': ['black'], \ 'python': ['black'],
\ 'rust': ['rustfmt'] \ 'rust': ['rustfmt']
@@ -180,5 +209,29 @@ autocmd bufnewfile,bufread elm.json let g:ale_fix_on_save = 0
let g:ale_completion_enabled = 1 let g:ale_completion_enabled = 1
"if exists("g:loaded_airline")
" set noshowmode laststatus=0 noruler
let g:airline#extensions#tabline#close_symbol = 'X'
let g:airline#extensions#tabline#enabled = 0
"let g:airline#extensions#tabline#left_alt_sep = ''
"let g:airline#extensions#tabline#left_sep = ''
"let g:airline#extensions#tabline#right_alt_sep = ''
"let g:airline#extensions#tabline#right_sep = ''
let g:airline#extensions#tabline#show_close_button = 1
let g:airline#extensions#tabline#show_tab_type = 0
let g:airline#extensions#tabline#tab_min_count = 2
let g:airline#extensions#tabline#tab_nr_type = 0
let g:airline#extensions#tmuxline#enabled = 0
"let g:airline#extensions#wordcount#enabled = 1
"let g:airline_left_alt_sep = ''
"let g:airline_left_sep = ''
"let g:airline_right_alt_sep = ''
"let g:airline_right_sep = ''
let g:airline_section_z = '%{line(".")}/%{line("$")} %{col(".")}'
"endif
"if exists("g:loaded_airline_themes")
let g:airline_theme='base16'
"endif
let g:vimwiki_list = [{'path': '~/notes/', let g:vimwiki_list = [{'path': '~/notes/',
\ 'syntax': 'markdown', 'ext': '.md'}] \ 'syntax': 'markdown', 'ext': '.md'}]

View File

@@ -1,29 +0,0 @@
{ pkgs, lib, config, ... }:
with lib;
let cfg = config.niveum.dropbox;
in {
options.niveum.dropbox = { enable = mkEnableOption "Dropbox"; };
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.dropbox-cli ];
networking.firewall = {
allowedTCPPorts = [ 17500 ];
allowedUDPPorts = [ 17500 ];
};
systemd.user.services.dropbox = {
description = "Dropbox synchronisation service";
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.dropbox.out}/bin/dropbox";
ExecReload = "${pkgs.coreutils.out}/bin/kill -HUP $MAINPID";
KillMode = "control-group"; # upstream recommends process
Restart = "on-failure";
PrivateTmp = true;
ProtectSystem = "full";
Nice = 10;
};
};
};
}

View File

@@ -9,7 +9,7 @@ let
startAt = bot.time; startAt = bot.time;
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
script = strings.concatStringsSep "\n" ([ "QUOTE=$(${bot.command})" "if [ -n \"$QUOTE\" ]; then" ] script = strings.concatStringsSep "\n" ([ "QUOTE=$(${bot.command})" ]
++ map (chatId: '' ++ map (chatId: ''
${pkgs.curl}/bin/curl -s -X POST "https://api.telegram.org/bot${bot.token}/sendMessage" \ ${pkgs.curl}/bin/curl -s -X POST "https://api.telegram.org/bot${bot.token}/sendMessage" \
-d chat_id="${chatId}" \ -d chat_id="${chatId}" \
@@ -17,8 +17,7 @@ let
lib.strings.optionalString (bot.parseMode != null) lib.strings.optionalString (bot.parseMode != null)
"-d parse_mode=${bot.parseMode}" "-d parse_mode=${bot.parseMode}"
} }
'') bot.chatIds '') bot.chatIds);
++ [ "fi" ]);
}; };
in { in {
options.niveum.telegramBots = mkOption { options.niveum.telegramBots = mkOption {
@@ -28,7 +27,7 @@ in {
time = mkOption { type = types.str; }; time = mkOption { type = types.str; };
token = mkOption { type = types.strMatching "[0-9A-Za-z:-]+"; }; token = mkOption { type = types.strMatching "[0-9A-Za-z:-]+"; };
chatIds = mkOption { chatIds = mkOption {
type = types.listOf (types.strMatching "-?[0-9]+|@[A-Za-z0-9]+"); type = types.listOf (types.strMatching "[0-9]+|@[A-Za-z0-9]+");
}; };
command = mkOption { type = types.str; }; command = mkOption { type = types.str; };
parseMode = mkOption { parseMode = mkOption {

View File

@@ -2,7 +2,14 @@
with lib; with lib;
let let
cfg = config.niveum.traadfri; cfg = config.niveum.traadfri;
traadfri = pkgs.callPackage <traadfri> { traadfri = let
traadfri-package = pkgs.fetchFromGitHub {
owner = "kmein";
repo = "traadfri";
rev = "cf46bd09cd3263b90a09b0ca979aa705a4c3671c";
sha256 = "0az9q38pl8fqk00488blhn6rhvwsw2wky3dbdlyz7945ggvxnbyd";
};
in pkgs.callPackage traadfri-package {
libcoap = pkgs.callPackage <niveum/packages/libcoap.nix> { tls = true; }; libcoap = pkgs.callPackage <niveum/packages/libcoap.nix> { tls = true; };
}; };
in { in {
@@ -22,6 +29,12 @@ 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}" \
@@ -29,11 +42,6 @@ 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

@@ -1,7 +1,13 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
tuna = pkgs.callPackage <tuna> {}; tuna-src = pkgs.fetchFromGitHub {
owner = "kmein";
repo = "tuna";
rev = "1cbed44069a3009738afdafecefe0a05316039a6";
sha256 = "0i7vjzv4hf8fdz9j09cdnvfhyylh0izsdhjs4q0qw9g5nrc9pyir";
};
tuna = pkgs.callPackage tuna-src {};
cfg = config.services.tuna; cfg = config.services.tuna;
in { in {
imports = []; imports = [];

View File

@@ -1,6 +0,0 @@
self: super:
with super.lib;
let
eval = import <nixpkgs/nixos/lib/eval-config.nix>;
paths = (eval {modules = [(import <nixos-config>)];}).config.nixpkgs.overlays;
in foldl' (flip extends) (_: super) paths self

1
overlays/rust.nix Normal file
View File

@@ -0,0 +1 @@
import <nixpkgs-mozilla>

View File

@@ -81,17 +81,9 @@ in rec {
''; '';
qrpaste = pkgs.writers.writeDashBin "qrpaste" '' qrpaste = pkgs.writers.writeDashBin "qrpaste" ''
file="$(${pkgs.mktemp}/bin/mktemp --tmpdir)" file="$(${pkgs.mktemp}/bin/mktemp qrpasteXXX.png --tmpdir)"
trap clean EXIT
clean() {
rm "$file"
}
${pkgs.qrencode}/bin/qrencode "$(${pkgs.xclip}/bin/xclip -selection clipboard -out)" -o "$file" ${pkgs.qrencode}/bin/qrencode "$(${pkgs.xclip}/bin/xclip -selection clipboard -out)" -o "$file"
${pkgs.sxiv}/bin/sxiv "$file" ${pkgs.sxiv}/bin/sxiv "$file" ; rm "$file"
'';
ttspaste = pkgs.writers.writeDashBin "ttspaste" ''
${pkgs.xclip}/bin/xclip -selection clipboard -out | ${pkgs.curl}/bin/curl -G http://tts.r/api/tts --data-urlencode 'text@-' | ${pkgs.mpv}/bin/mpv -
''; '';
interdimensional-cable = interdimensional-cable =
@@ -176,7 +168,7 @@ in rec {
| ${pkgs.man}/bin/man --local-file --pager="${pkgs.bat}/bin/bat -p" - | ${pkgs.man}/bin/man --local-file --pager="${pkgs.bat}/bin/bat -p" -
''; '';
playlist = import ./pls.nix { inherit pkgs; }; playlist = import ./pls.nix { inherit pkgs lib; };
mpv-tv = import ./mpv-tv.nix { inherit pkgs lib; }; mpv-tv = import ./mpv-tv.nix { inherit pkgs lib; };
@@ -294,46 +286,27 @@ in rec {
packages = [ pkgs.xdo ]; packages = [ pkgs.xdo ];
}; };
ipa = pkgs.writers.writeHaskellBin "ipa" { ipa = wrapScript {
libraries = with pkgs; [ haskellPackages.text haskellPackages.ipa ]; script = ./ipa.py;
} '' name = "ipa";
import Data.Maybe (fromJust) packages = [ pkgs.python3 ];
import Language.IPA };
import qualified Data.Text as T
import qualified Data.Text.IO as T
main = T.interact (T.unwords . map (unIPA . fromJust . (xSampaToIpa =<<) . mkXSampa) . T.words)
'';
default-gateway = pkgs.writers.writeDashBin "default-gateway" '' default-gateway = pkgs.writers.writeDashBin "default-gateway" ''
${pkgs.iproute}/bin/ip -json route | ${pkgs.jq}/bin/jq --raw-output '.[0].gateway' ${pkgs.iproute}/bin/ip -json route | ${pkgs.jq}/bin/jq --raw-output '.[0].gateway'
''; '';
betacode = pkgs.writers.writeHaskellBin "betacode" { betacode = pkgs.writers.writePython3Bin "betacode" {
libraries = with pkgs; [ libraries = [ betacode ];
(haskell.lib.unmarkBroken (haskell.lib.doJailbreak haskellPackages.betacode))
haskellPackages.text
];
} '' } ''
import qualified Data.Text.IO as T import betacode.conv
import qualified Data.Text as T import sys
import Text.BetaCode
main = T.interact (either (error . T.unpack) id . fromBeta) sys.stdout.write(betacode.conv.beta_to_uni(sys.stdin.read()))
''; '';
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)
@@ -421,12 +394,17 @@ in rec {
''; '';
nix-index-update = pkgs.writers.writeDashBin "nix-index-update" '' nix-index-update = pkgs.writers.writeDashBin "nix-index-update" ''
filename="index-x86_64-$(uname | tr A-Z a-z)" mkdir -p $HOME/.cache/nix-index
mkdir -p ~/.cache/nix-index tag=$(git -c 'versionsort.suffix=-' \
cd ~/.cache/nix-index ls-remote \
# -N will only download a new version if there is an update. --exit-code \
${pkgs.wget}/bin/wget -q -N https://github.com/Mic92/nix-index-database/releases/latest/download/$filename --refs \
ln -f $filename files --tags \
--sort='v:refname' \
https://github.com/Mic92/nix-index-database \
| awk 'END {match($2, /([^/]+)$/, m); print m[0]}')
curl -L "https://github.com/Mic92/nix-index-database/releases/download/$tag/files" -o $XDG_RUNTIME_DIR/files-$tag
mv $XDG_RUNTIME_DIR/files-$tag $HOME/.cache/nix-index/files
''; '';
} // { } // {
devour = pkgs.callPackage <niveum/packages/devour.nix> { }; devour = pkgs.callPackage <niveum/packages/devour.nix> { };

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,7 +1,5 @@
{ pkgs }: { lib, pkgs }:
let let
inherit (pkgs) lib;
playlistAPI = "https://radio.lassul.us"; playlistAPI = "https://radio.lassul.us";
sendIRC = pkgs.writers.writeDash "send-irc" '' sendIRC = pkgs.writers.writeDash "send-irc" ''
@@ -51,10 +49,6 @@ pkgs.writers.writeDashBin "pls" ''
${pkgs.curl}/bin/curl -sS -XPOST "${playlistAPI}/skip" ${pkgs.curl}/bin/curl -sS -XPOST "${playlistAPI}/skip"
echo ${lib.escapeShellArg (lib.concatStringsSep "\n" messages.bad)} | shuf -n1 | ${sendIRC} echo ${lib.escapeShellArg (lib.concatStringsSep "\n" messages.bad)} | shuf -n1 | ${sendIRC}
;; ;;
say|msg)
shift
echo "$@" | ${sendIRC}
;;
recent) recent)
${pkgs.curl}/bin/curl -sS -XGET "${playlistAPI}/recent" | tac | head ${pkgs.curl}/bin/curl -sS -XGET "${playlistAPI}/recent" | tac | head
;; ;;

View File

@@ -1,65 +1,47 @@
{ lib, runCommand, fetchurl, writeText, writers, coreutils, dmenu, gnused, libnotify, xclip, xdotool, gawk }: { lib, fetchurl, writeText, writers, coreutils, dmenu, gnused, libnotify, xclip, xdotool }:
let let
unicode-file = runCommand "unicode.txt" {} '' emoji-file = fetchurl {
${writers.writePython3 "generate.py" { flakeIgnore = [ "E501" "E722" ]; } '' url = "https://raw.githubusercontent.com/kmein/unipicker/master/symbols";
import csv sha256 = "1q6ampv4fhdvd0riz4ihx43gkbyvdab4c38q96ybn0ka9d30vi3g";
};
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 ${kaomoji-file} ${unicode-file} | dmenu -p unicode -i -l 10 | sed "s/ .*//") chosen=$(cat ${emoji-file} ${kaomoji-file} | dmenu -i -l 10 | sed "s/ .*//")
[ "$chosen" != "" ] || exit [ "$chosen" != "" ] || exit

View File

@@ -1,24 +0,0 @@
{ stdenv, lib, fetchurl, mupdf }:
stdenv.mkDerivation {
pname = "tocharian-font";
version = "unstable-2022-01-11";
src = fetchurl {
url = "https://unicode.org/L2/L2015/15236-tocharian.pdf";
sha256 = "08bzkva9a6b2cfl38p9m22b1cf6yv27xsw6nrvq5ly5nffjm32hv";
};
dontUnpack = true;
buildInputs = [ mupdf ];
buildPhase = ''
mutool extract $src
'';
installPhase = ''
mkdir -p $out/share/fonts/truetype
install font-0021.ttf $out/share/fonts/truetype/Tocharian.ttf
'';
meta = with lib; {
description = "Tocharian font by Lee Wilson";
license = licenses.unfree;
platforms = platforms.all;
maintainers = with maintainers; [ kmein ];
};
}

121
shell.nix Normal file
View File

@@ -0,0 +1,121 @@
{ pkgs ? import <nixpkgs> { }
, release ? "21.11"
}:
let
inherit (pkgs) lib;
dependencies = {
nixpkgs = {
ref = "refs/heads/nixos-${release}";
url = "https://github.com/NixOS/nixpkgs.git";
path = toString .versions/nixpkgs.json;
};
nixpkgs-unstable = {
ref = "refs/heads/master";
url = "https://github.com/NixOS/nixpkgs.git";
path = toString .versions/nixpkgs-unstable.json;
};
nix-writers = {
ref = "refs/heads/master";
url = "https://cgit.krebsco.de/nix-writers";
path = toString .versions/nix-writers.json;
};
home-manager = {
ref = "refs/heads/release-${release}";
url = "https://github.com/nix-community/home-manager.git";
path = toString .versions/home-manager.json;
};
krops = {
ref = "refs/tags/v1.25.0";
url = "https://cgit.krebsco.de/krops";
path = toString .versions/krops.json;
};
stockholm = {
ref = "refs/heads/master";
url = "https://cgit.lassul.us/stockholm";
path = toString .versions/stockholm.json;
};
retiolum = {
ref = "refs/heads/master";
url = "https://github.com/krebs/retiolum";
path = toString .versions/retiolum.json;
};
nixpkgs-mozilla = {
ref = "refs/heads/master";
url = "https://github.com/mozilla/nixpkgs-mozilla";
path = toString .versions/nixpkgs-mozilla.json;
};
};
in pkgs.mkShell {
buildInputs = [
(let
updateCommand = pkgs.writers.writeDash "niveum-update-one" ''
[ $# -eq 1 ] || {
echo "Please provide a dependency to update." >&2
exit 1
}
case "$1" in
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: dependency: ''
${name})
${pkgs.nix-prefetch-git}/bin/nix-prefetch-git --url "${dependency.url}" --rev "${dependency.ref}" > "${dependency.path}";;
'') dependencies)}
esac
'';
in pkgs.writers.writeDashBin "niveum-update" ''
if [ $# -gt 0 ]; then
dependencies="$@"
else
dependencies="${lib.concatStringsSep " " (lib.attrNames dependencies)}"
fi
${pkgs.parallel}/bin/parallel --line-buffer --tagstring '{}' -q ${updateCommand} '{1}' ::: $dependencies
'')
(let
deployCommand = pkgs.writers.writeDash "niveum-deploy-one" ''
${pkgs.git}/bin/git diff $(${pkgs.openssh}/bin/ssh "$1" cat /etc/niveum/version)
eval "$(${pkgs.nix}/bin/nix-build --no-out-link "${toString ./.}/deploy.nix" -A "$1")"
'';
in pkgs.writers.writeDashBin "niveum-deploy" ''
deploy() {
${pkgs.parallel}/bin/parallel --line-buffer --tagstring '{}' -q ${deployCommand} '{1}' ::: "$@"
}
if [ -z "$(${pkgs.git}/bin/git status --porcelain)" ]; then
deploy "$@"
else
if [ "$1" = --force ]; then
shift
deploy "$@"
else
echo Working directory is dirty. Not deploying.
exit 1
fi
fi
'')
(let
statusCommand = pkgs.writers.writeDash "niveum-status-one" ''
[ $# -eq 1 ] || {
echo "Please provide a niveum system hostname." >&2
exit 1
}
hostname="$1"
version_file=/etc/niveum/version
if commit_id="$(${pkgs.coreutils}/bin/timeout 2s ${pkgs.openssh}/bin/ssh "$hostname" cat $version_file 2>/dev/null)"; then
${pkgs.git}/bin/git log -1 --oneline "$commit_id"
else
echo offline
fi
'';
in pkgs.writers.writeDashBin "niveum-status" ''
if [ $# -gt 0 ]; then
systems="$@"
else
systems="$(ls ${toString ./.}/systems)"
fi
${pkgs.parallel}/bin/parallel --line-buffer --tagstring '{}' -q ${statusCommand} '{1}' ::: $systems
'')
];
}

View File

@@ -5,10 +5,11 @@ let
in in
{ {
imports = [ imports = [
../../configs/default.nix
../../configs/battery.nix
../../configs/networkmanager.nix
./hardware-configuration.nix ./hardware-configuration.nix
<niveum/configs/battery.nix> # <stockholm/krebs/2configs/hw/x220.nix>
<niveum/configs/default.nix>
<niveum/configs/networkmanager.nix>
]; ];
niveum = { niveum = {
@@ -17,18 +18,29 @@ in
promptColours.success = "cyan"; promptColours.success = "cyan";
}; };
nix = { nix.buildCores = 1;
buildCores = 1; nix.maxJobs = 2;
maxJobs = 2;
};
environment.systemPackages = [ nixpkgs-unstable.minecraft ]; environment.systemPackages = [ nixpkgs-unstable.minecraft ];
networking = { boot.loader.systemd-boot = {
hostName = "kabsa"; enable = true;
wireless.interfaces = [ "wlp3s0" ]; configurationLimit = 5;
retiolum = retiolumAddresses.kabsa; consoleMode = "max";
}; };
fileSystems."/mnt/sd-card" = {
device = "/dev/disk/by-id/mmc-SD32G_0xda0aa352-part1";
fsType = "vfat";
};
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "kabsa";
networking.wireless.interfaces = [ "wlp3s0" ];
networking.retiolum = retiolumAddresses.kabsa;
system.stateVersion = "19.03"; system.stateVersion = "19.03";
} }

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