{ config, lib, pkgs, fetchurl, ... }: with lib; let cfg = config.services.news2kindle; portString = toString cfg.smtp.port; convertScript = pkgs.writeText "convertScript.sh" ''#!/bin/bash NAME=$1 RECIPEPATH=$2 MOBIPATH=$3 FROMADDR=$4 TOADDR=$5 if [ ! -f mobi/$NAME.mobi ]; then ebook-convert $RECIPEPATH/$NAME.recipe $MOBIPATH/$NAME.mobi --output-profile kindle -v fi mailsend -smtp ${cfg.smtp.address} -port ${portString} -from $FROMADDR -to $TOADDR -sub "New news from $NAME" -attach $MOBIPATH/$NAME.mobi sleep 60 ''; reps = mapAttrsToList (name: value: let mailAddress = if value.mailAddress != null then value.mailAddress else name; cronJobs = mapAttrsToList ( jobExpr: jobValue: let cronExpression = if jobValue.cronExpression != "0 5 * * *" then jobValue.cronExpression else jobExpr; in jobValue // {cronExpression = cronExpression;}) value.cronJobs; in value // { mailAddress = name; cronJobs = cronJobs; } ) cfg.recipients; jobs = concatMap(recipient: concatMap(cronjob: let scriptName = builtins.replaceStrings ["*"] ["star"] (builtins.replaceStrings [" "] ["_"] (builtins.replaceStrings ["@"] [""] "${recipient.mailAddress}-${cronjob.cronExpression}.sh")); scriptlines = concatMapStrings(recipe: if isNull recipe.content then "bash ${convertScript} ${recipe.name} ${calibreWithRecipes}/var/news2kindle/recipes ${cfg.mobiPath} ${recipient.fromMail} ${recipient.mailAddress}\n" else '' mkdir -p /tmp/news2kindle/recipes echo "${recipe.content}" > /tmp/news2kindle/recipes/${recipe.name}.recipe bash ${convertScript} ${recipe.name} /tmp/news2kindle/recipes/ ${cfg.mobiPath} ${recipient.fromMail} ${recipient.mailAddress} '' ) cronjob.recipes; script = pkgs.writeText "${scriptName}" ''#!/bin/bash rm -f ${cfg.mobiPath}/*.mobi mkdir -p ${cfg.mobiPath} ${scriptlines} ''; in ["${cronjob.cronExpression} root bash ${script}"]) recipient.cronJobs) reps; odfpyNoTest = pkgs.python38Packages.odfpy.overrideAttrs (oldAttrs: rec { doInstallCheck = false; }); apswNoTest = pkgs.python38Packages.apsw.overrideAttrs (oldAttrs: rec { doInstallCheck = false; }); calibreWithRecipes = pkgs.calibre.overrideAttrs (oldAttrs: rec { installPhase = '' mkdir -p $out/var/news2kindle/recipes cp -ravf recipes $out/var/news2kindle ''+ oldAttrs.installPhase ; buildInputs = (remove pkgs.python38Packages.apsw (remove pkgs.python38Packages.odfpy oldAttrs.buildInputs)) ++ [odfpyNoTest apswNoTest pkgs.python38Packages.feedparser pkgs.python38Packages.pyqt5]; # patches = oldAttrs.patches ++ [./calibre-disable_plugins.patch]; # patches = [./calibre-disable_plugins.patch]; }); in { ###### interface options = { services.news2kindle = { enable = mkOption { type = types.bool; default = false; description = '' Whether to enable news2kindle service. ''; }; recipePath = mkOption { example = "/var/news2kindle/recipes"; default = "/var/news2kindle/recipes"; type = types.str; description = '' Path where the recipes should be saved ''; }; mobiPath = mkOption { example = "/tmp/news2kindle/mobi"; default = "/tmp/news2kindle/mobi"; type = types.str; description = '' Path where the mobi files should be saved ''; }; fromMail = mkOption { example = "news@stubbe.rocks"; default = "news@stubbe.rocks"; type = types.str; description = '' Adrees of the sender, please allow this mail in your kindle doc service ''; }; recipients = mkOption { type = types.attrsOf (types.submodule (import ./recipient-options.nix { inherit config lib; })); }; smtp = { address = mkOption { type = types.str; default = "localhost"; description = "Address of the SMTP server for news2kindle."; }; port = mkOption { type = types.int; default = 25; description = "Port of the SMTP server for news2kindle."; }; username = mkOption { type = types.nullOr types.str; default = null; description = "Username of the SMTP server for news2kindle."; }; password = mkOption { type = types.nullOr types.str; default = null; description = "Password of the SMTP server for news2kindle."; }; }; }; }; ###### implementation config = mkIf cfg.enable{ environment.systemPackages = [ # pkgs.python27Packages.pyqt5 # pkgs.python36Packages.pyqt5 pkgs.mailsend calibreWithRecipes ]; services.cron.enable = true; services.cron.systemCronJobs = jobs; }; }