rip Reaktor

This commit is contained in:
lassulus 2021-09-14 19:10:16 +02:00
parent 04ba40838d
commit e7d5d99083
11 changed files with 46 additions and 373 deletions

View File

@ -10,7 +10,6 @@ in {
enable = true;
build.user = config.krebs.users.krebs;
build.host = config.krebs.hosts.test-all-krebs-modules;
Reaktor.test = {};
apt-cacher-ng.enable = true;
backup.enable = true;
bepasty.enable = true;

View File

@ -47,7 +47,7 @@ let
activate = "always";
command = {
filename =
"${pkgs.Reaktor.src}/reaktor/commands/tell-on_join";
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_join.sh>;
env = {
PATH = makeBinPath [
pkgs.coreutils # XXX env, touch
@ -95,10 +95,10 @@ let
}
hooks.sed
(generators.command_hook {
inherit (commands) hello random-emoji nixos-version;
inherit (commands) random-emoji nixos-version;
tell = {
filename =
"${pkgs.Reaktor.src}/reaktor/commands/tell-on_privmsg";
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_privmsg.sh>;
env = {
PATH = makeBinPath [
pkgs.coreutils # XXX date, env

View File

@ -183,7 +183,6 @@ in {
(sync-remote { name = "skytraq-datalogger"; url = "https://github.com/makefu/skytraq-datalogger"; })
(sync-remote { name = "realwallpaper"; url = "https://github.com/lassulus/realwallpaper"; })
(sync-remote { name = "painload"; url = "https://github.com/krebs/painload"; })
(sync-remote { name = "Reaktor"; url = "https://github.com/krebs/Reaktor"; })
(sync-remote { name = "nixos-wiki"; url = "https://github.com/Mic92/nixos-wiki.wiki.git"; })
];
}

View File

@ -1,155 +0,0 @@
{ config, lib, pkgs, ... }:
with import <stockholm/lib>;
let
cfg = config.krebs.Reaktor;
homedir = "/var/lib/Reaktor";
out = {
options.krebs.Reaktor = api;
config = mkIf (cfg != {}) imp;
};
api = mkOption {
default = {};
type = with types; attrsOf (submodule ({ options = {
nickname = mkOption {
default = config.krebs.build.host.name + "|r";
type = types.str;
description = ''
The nick name of the irc bot.
Defaults to {hostname}|r
'';
};
overrideConfig = mkOption {
default = null;
type = types.nullOr types.str;
description = ''
configuration to be used instead of default ones.
Reaktor default cfg can be retrieved via `reaktor get-config`
'';
};
plugins = mkOption {
default = [pkgs.ReaktorPlugins.nixos-version];
};
workdir = mkOption {
default = "/var/lib/Reaktor";
type = types.path;
description = ''
path to be used as workdir (home dir is still /var/lib/Reaktor)
'';
};
extraConfig = mkOption {
default = "";
type = types.str;
description = ''
configuration appended to the default or overridden configuration
'';
};
extraEnviron = mkOption {
default = {};
type = types.attrsOf types.str;
description = ''
Environment to be provided to the service, can be:
REAKTOR_HOST
REAKTOR_PORT
REAKTOR_STATEDIR
debug and nickname can be set separately via the Reaktor api
'';
};
channels = mkOption {
default = [ "#krebs" ];
type = types.listOf types.str;
description = ''
Channels the Reaktor should connect to at startup.
'';
};
debug = mkOption {
default = false;
description = ''
Reaktor debug output
'';
};
};}));
};
imp = {
# TODO get user per configured bot
# TODO get home from api
# for reaktor get-config
users.extraUsers = singleton rec {
name = "Reaktor";
uid = genid name;
description = "Reaktor user";
home = homedir;
createHome = true;
};
#users.extraGroups = singleton {
# name = "Reaktor";
# gid = config.ids.gids.Reaktor;
#};
systemd.services = mapAttrs' (name: botcfg:
let
ReaktorConfig = pkgs.writeText "config.py" ''
${if (isString botcfg.overrideConfig ) then ''
# Overriden Config
${botcfg.overrideConfig}
'' else ""}
## Extra Config
${concatStringsSep "\n" (map (plug: plug.config) botcfg.plugins)}
${botcfg.extraConfig}
'';
in nameValuePair "Reaktor-${name}" {
path = with pkgs; [
git # for nag
jq # for tell
python # for caps
utillinux # flock for tell
];
description = "Reaktor IRC Bot";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
GIT_SSL_CAINFO = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
PYTHONPATH = "${pkgs.Reaktor}/lib/python3.6/site-packages";
REAKTOR_NICKNAME = botcfg.nickname;
REAKTOR_DEBUG = (if botcfg.debug then "True" else "False");
REAKTOR_CHANNELS = lib.concatStringsSep "," botcfg.channels;
state_dir = botcfg.workdir;
} // botcfg.extraEnviron;
serviceConfig= {
ExecStartPre = pkgs.writeScript "Reaktor-init" ''
#! /bin/sh
${if (isString botcfg.overrideConfig) then
''cp ${ReaktorConfig} /tmp/reaktor-${name}-config.py''
else
''(${pkgs.Reaktor}/bin/reaktor get-config;cat "${ReaktorConfig}" ) > /tmp/reaktor-${name}-config.py''
}
mkdir -p ${botcfg.workdir}
'';
ExecStart = "${pkgs.Reaktor}/bin/reaktor run /tmp/reaktor-${name}-config.py";
PrivateTmp = "true";
User = "Reaktor";
Restart = "always";
RestartSec= "30" ;
};
}
) cfg;
};
in
out

View File

@ -43,7 +43,6 @@ let
./permown.nix
./per-user.nix
./power-action.nix
./Reaktor.nix
./reaktor2.nix
./realwallpaper.nix
./retiolum-bootstrap.nix

View File

@ -15,6 +15,4 @@ foldl' mergeAttrs {}
{
brockman = self.haskellPackages.brockman;
reaktor2 = self.haskellPackages.reaktor2;
ReaktorPlugins = self.callPackage ./simple/Reaktor/plugins.nix {};
}

View File

@ -1,24 +0,0 @@
{ lib, pkgs, python3Packages, fetchFromGitHub, ... }:
python3Packages.buildPythonPackage rec {
name = "Reaktor-${version}";
version = "0.7.1";
doCheck = false;
propagatedBuildInputs = with pkgs;[
python3Packages.docopt
python3Packages.requests
];
src = fetchFromGitHub {
owner = "krebs";
repo = "Reaktor";
rev = "v${version}";
sha256 = "0cv5a4x73ls6sk8qj2qi6gqn31rv8kvdg13dsf3jv92xdfx6brjn";
};
meta = {
homepage = http://krebsco.de/;
description = "An IRC bot based on asynchat";
license = lib.licenses.wtfpl;
};
}

View File

@ -1,182 +0,0 @@
{ stdenv, lib, pkgs, makeWrapper }:
rec {
# Begin API
buildBaseReaktorPlugin = { name
, config # python extra configuration for plugin
, phases ? []
, ... } @ attrs:
stdenv.mkDerivation (attrs // {
name = "Reaktor-plugin-" + name;
isReaktorPlugin = true;
});
buildSimpleReaktorPlugin = name: { script
, path ? []
, env ? {}
, append_rule ? false # append the rule instead of insert
, pattern ? ""
, ... } @ attrs:
let
path_env = { "PATH" = lib.makeSearchPath "bin" (path ++ [ pkgs.coreutils ]); };
src_dir = pkgs.substituteAll ( {
inherit name;
dir = "bin";
isExecutable = true;
src = script;
});
src_file = "${src_dir}/bin/${name}";
config = ''
public_commands.${if append_rule then "append(" else "insert(0," }{
'capname' : "${name}",
'pattern' : ${if pattern == "" then
''indirect_pattern.format("${name}")'' else
''"${pattern}"'' },
'argv' : ["${src_file}"],
'env' : ${builtins.toJSON (path_env // env)} })
'';
config_file = pkgs.writeText "plugin.py" config;
in buildBaseReaktorPlugin (attrs // rec {
inherit name config;
phases = [ "installPhase" ];
buildInputs = [ makeWrapper ];
installPhase = ''
mkdir -p $out/bin $out/etc/Reaktor
ln -s ${src_file} $out/bin
wrapProgram $out/bin/${name} \
--prefix PATH : ${path_env.PATH}
ln -s ${config_file} $out/etc/Reaktor/plugin.py
'';
});
# End API
# Begin Plugins
random-emoji = buildSimpleReaktorPlugin "emoji" {
path = with pkgs; [ gnused gnugrep xmlstarlet curl ];
script = ./scripts/random-emoji.sh;
};
sed-plugin = buildSimpleReaktorPlugin "sed-plugin" {
path = [ pkgs.gnused pkgs.python3 ];
# only support s///gi the plugin needs to see every msg
# TODO: this will eat up the last regex, fix Reaktor to support fallthru
append_rule = true;
pattern = "^(?P<args>.*)$$";
script = ./scripts/sed-plugin.py;
};
shack-correct = buildSimpleReaktorPlugin "shack-correct" {
path = [ pkgs.gnused ];
pattern = "^(?P<args>.*Shack.*)$$";
script = ./scripts/shack-correct.sh;
};
nixos-version = buildSimpleReaktorPlugin "nixos-version" {
script = pkgs.writeDash "nixos-version" ''
. /etc/os-release
echo "$PRETTY_NAME"
'';
};
stockholm-issue = buildSimpleReaktorPlugin "stockholm-issue" {
script = ./scripts/random-issue.sh;
path = with pkgs; [ git gnused haskellPackages.lentil ];
env = { "origin" = "http://cgit.gum/stockholm"; };
};
titlebot =
let
pypkgs = pkgs.python3Packages;
titlebot_cmds = pypkgs.buildPythonPackage {
name = "titlebot_cmds";
propagatedBuildInputs = with pypkgs; [ setuptools ];
src = pkgs.fetchurl {
url = "https://github.com/makefu/reaktor-titlebot/archive/2.1.0.tar.gz";
sha256 = "0wvf09wmk8b52f9j65qrw81nwrhs9pfhijwrlkzp5l7l2q8cjkp6";
};
};
in buildBaseReaktorPlugin rec {
name = "titlebot";
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out
ln -s ${titlebot_cmds}/* $out
'';
config = ''
def titlebot_cmd(cmd):
from os import environ
return { 'capname': None,
'env': { 'TITLEDB':
environ['state_dir']+'/suggestions.json' },
'pattern': '^\\.' + cmd + '\\s*(?:\\s+(?P<args>.*))?$$',
'argv': [ '${titlebot_cmds}/bin/' + cmd ] }
for i in ['up','help','list','top','new']:
public_commands.insert(0,titlebot_cmd(i))
commands.insert(0,titlebot_cmd('clear'))
'';
};
url-title = (buildSimpleReaktorPlugin "url-title" {
pattern = "^.*(?P<args>http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+).*$$";
path = with pkgs; [ curl perl ];
script = pkgs.writePython3 "url-title" { deps = with pkgs.python3Packages; [ beautifulsoup4 lxml ]; } ''
import cgi
import sys
import urllib.request
from bs4 import BeautifulSoup
try:
req = urllib.request.Request(sys.argv[1])
req.add_header('user-agent', 'Reaktor-url-title')
resp = urllib.request.urlopen(req)
if resp.headers['content-type'].find('text/html') >= 0:
soup = BeautifulSoup(resp.read(16000), "lxml")
title = soup.find('title').string
if len(title.split('\n')) > 5:
title = '\n'.join(title.split('\n')[:5])
print(title[:450])
else:
cd_header = resp.headers['content-disposition']
print(cgi.parse_header(cd_header)[1]['filename'])
except: # noqa: E722
pass
'';
});
task = name: let
rcFile = builtins.toFile "taskrc" ''
confirmation=no
'';
in {
add = buildSimpleReaktorPlugin "${name}-task-add" {
pattern = "^${name}-add: (?P<args>.*)$$";
script = pkgs.writeDash "${name}-add" ''
TASKDATA=$HOME/${name} ${pkgs.taskwarrior}/bin/task rc:${rcFile} add "$*"
'';
};
list = buildSimpleReaktorPlugin "task-list" {
pattern = "^${name}-list";
script = pkgs.writeDash "task-list" ''
TASKDATA=$HOME/${name} ${pkgs.taskwarrior}/bin/task rc:${rcFile} export | ${pkgs.jq}/bin/jq -r '.[] | select(.id != 0) | "\(.id) \(.description)"'
'';
};
delete = buildSimpleReaktorPlugin "task-delete" {
pattern = "^${name}-delete: (?P<args>.*)$$";
script = pkgs.writeDash "task-delete" ''
TASKDATA=$HOME/${name} ${pkgs.taskwarrior}/bin/task rc:${rcFile} delete "$*"
'';
};
done = buildSimpleReaktorPlugin "task-done" {
pattern = "^${name}-done: (?P<args>.*)$$";
script = pkgs.writeDash "task-done" ''
TASKDATA=$HOME/${name} ${pkgs.taskwarrior}/bin/task rc:${rcFile} done "$*"
'';
};
};
}

View File

@ -0,0 +1,25 @@
#! /bin/sh
set -euf
# require flock from util-linux (pkgs.utillinux)
if test "${FLOCK-}" != "$state_file"; then
exec env FLOCK="$state_file" flock "$state_file" "$0" "$@"
fi
# TODO tell now, if already joined
jq -r <"$state_file" \
--arg to "$_from" \
--arg msgtarget "$_msgtarget" \
'
select(.to == $to and .msgtarget == $msgtarget) |
"\(.to): \(.text) \u00032-- \(.from)\u00032 \(.date)"
'
jq -c <"$state_file" >"$state_file.tmp" \
--arg to "$_from" \
--arg msgtarget "$_msgtarget" \
'
select((.to == $to and .msgtarget == $msgtarget) | not)
'
mv "$state_file.tmp" "$state_file"

View File

@ -0,0 +1,18 @@
#! /bin/sh
set -euf
# require flock from util-linux
if test "${FLOCK-}" != "$state_file"; then
exec env FLOCK="$state_file" flock "$state_file" "$0" "$@"
fi
# TODO tell now, if already joined
jq -cn \
--arg from "$_from" \
--arg to "${1%% *}" \
--arg text "${1#* }" \
--arg msgtarget "$_msgtarget" \
'{ $from, $to, $text, $msgtarget, date: (now | todate) }' \
>> "$state_file"
echo 'Consider it noted.' # that's what lambdabot says...

View File

@ -14,10 +14,6 @@ rec {
commands = {
hello = {
filename = "${pkgs.Reaktor.src}/reaktor/commands/hello";
};
random-emoji = {
filename = <stockholm/krebs/5pkgs/simple/Reaktor/scripts/random-emoji.sh>;
env = {