aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorChris Wells <chris@mathematicaster.org>2024-09-03 12:13:30 -0500
committerChris Wells <chris@mathematicaster.org>2024-09-03 12:13:30 -0500
commit849bdb056feb8e064396970f79c8962b20b0c07f (patch)
tree03c220b6f90ad1f68a45bb55cfba377c11260cf9 /modules
parentd7483ed8505710033384d7fabad34470818bc760 (diff)
downloadkobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.tar
kobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.tar.gz
kobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.tar.bz2
kobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.tar.lz
kobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.tar.xz
kobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.tar.zst
kobo-manager-849bdb056feb8e064396970f79c8962b20b0c07f.zip
Re-doing a bunch of this
Diffstat (limited to 'modules')
-rw-r--r--modules/firmware/default.nix27
-rw-r--r--modules/kfmon/default.nix59
-rw-r--r--modules/koreader/default.nix57
-rw-r--r--modules/lib/file-type.nix42
-rw-r--r--modules/lib/merge-files.nix10
-rw-r--r--modules/nickel/default.nix153
-rw-r--r--modules/plato/default.nix362
7 files changed, 710 insertions, 0 deletions
diff --git a/modules/firmware/default.nix b/modules/firmware/default.nix
new file mode 100644
index 0000000..609212a
--- /dev/null
+++ b/modules/firmware/default.nix
@@ -0,0 +1,27 @@
+{ config, pkgs, lib, ... }:
+with builtins // lib;
+let
+ cfg = config.firmware;
+in {
+ options.firmware = {
+ hardware = mkOption {
+ type = types.str;
+ };
+ date = mkOption {
+ type = types.str;
+ };
+ version = mkOption {
+ type = types.str;
+ };
+ hash = mkOption {
+ type = types.str;
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.kobo-firmware {
+ inherit (cfg) hardware date version hash;
+ };
+ };
+ };
+}
diff --git a/modules/kfmon/default.nix b/modules/kfmon/default.nix
new file mode 100644
index 0000000..8557a3e
--- /dev/null
+++ b/modules/kfmon/default.nix
@@ -0,0 +1,59 @@
+{ config, pkgs, lib, ... }:
+with builtins // lib;
+let
+ cfg = config.kfmon;
+ ini = pkgs.formats.ini {};
+in {
+ options.kfmon = {
+ enable = mkEnableOption "KFMon";
+
+ package = mkPackageOption pkgs "kfmon" {};
+
+ path = mkOption {
+ type = types.str;
+ readOnly = true;
+ internal = true;
+ default = ".adds/kfmon";
+ };
+
+ devicePath = mkOption {
+ type = types.str;
+ readOnly = true;
+ internal = true;
+ default = "/mnt/onboard/${cfg.path}";
+ };
+
+ file = mkOption {
+ default = {};
+ type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {}));
+ };
+
+ _allFiles = mkOption {
+ type = types.package;
+ internal = true;
+ readOnly = true;
+ default = (pkgs.callPackage ../lib/merge-files.nix {}) (attrValues file);
+ };
+
+ configs = mkOption {
+ type = types.attrsOf ini.type;
+ default = {};
+ description = ''
+ KFMon .ini config files. Do not touch this unless you know what you're doing!
+ '';
+ };
+ };
+
+ config = {
+ kfmon.file = mapAttrs' (n: v: {
+ name = "kfmon-config-${n}";
+ value = {
+ text = generators.toINI {} v;
+ target =
+ let
+ fixedN = if isSuffix ".ini" n then n else "${n}.ini";
+ in "config/${fixedN}";
+ };
+ });
+ };
+};
diff --git a/modules/koreader/default.nix b/modules/koreader/default.nix
new file mode 100644
index 0000000..db12219
--- /dev/null
+++ b/modules/koreader/default.nix
@@ -0,0 +1,57 @@
+{ config, pkgs, lib, ... }:
+with builtins // lib;
+let
+ cfg = config.koreader;
+in {
+ options.koreader = {
+ enable = mkEnableOption "KOReader";
+
+ package = mkPackageOption pkgs "kobo-koreader" {};
+
+ _allFiles = mkOption {
+ type = types.package;
+ readOnly = true;
+ internal = true;
+ default = (pkgs.callPackage ../lib/merge-files.nix {}) ([
+ cfg.package
+ ] ++ attrValues cfg.file);
+ };
+
+ path = mkOption {
+ type = types.str;
+ readOnly = true;
+ internal = true;
+ default = ".adds/koreader";
+ };
+
+ devicePath = mkOption {
+ type = types.str;
+ readOnly = true;
+ internal = true;
+ default = "/mnt/onboard/${cfg.path}";
+ };
+
+ file = mkOption {
+ default = {};
+ type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {}));
+ };
+
+ nickel = {
+ enable = mkEnableOption "Add NickelMenu entry" // { default = true; };
+ };
+ };
+
+ config = {
+ nickel.menu.item = mkIf (cfg.enable && cfg.nickel.enable) {
+ koreader = singleton {
+ location = "main";
+ label = "KOReader";
+ action = "cmd_spawn";
+ arg = [
+ "quiet"
+ "exec ${cfg.devicePath}/koreader.sh";
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix
new file mode 100644
index 0000000..c95c0d4
--- /dev/null
+++ b/modules/lib/file-type.nix
@@ -0,0 +1,42 @@
+{ writeTextFile, lib, ... }:
+{ name, config, ... }:
+with builtins // lib;
+let
+ sanitize = p:
+ let
+ safeChars = [ "+" "." "_" "?" "=" ] ++ lowerChars ++ upperChars ++ stringToCharacters "0123456789";
+ empties = l: genList (_: "") (length l);
+ unsafeInName = stringToCharacters (replaceStrings safeChars (empties safeChars) p;
+ in "kobo_" + replaceStrings unsafeInName (empties unsafeInName) p;
+in {
+ options = {
+ enable = mkEnableOption name // { default = true; };
+ name = mkOption {
+ type = types.str;
+ };
+ target = mkOption {
+ type = types.str;
+ default = name;
+ apply = x: if isPrefix "/" x then x else "/${x}";
+ };
+ executable = mkOption {
+ type = with types; nullOr bool;
+ default = null;
+ };
+ text = mkOption {
+ type = with types; nullOr lines;
+ default = null;
+ };
+ source = mkOption {
+ type = types.path;
+ };
+ };
+
+ config = {
+ source = mkIf (cfg.text != null) (mkDefault (writeTextFile {
+ inherit (config) text;
+ name = sanitieze name;
+ executable = config.executable == true;
+ }));
+ };
+}
diff --git a/modules/lib/merge-files.nix b/modules/lib/merge-files.nix
new file mode 100644
index 0000000..c024e0c
--- /dev/null
+++ b/modules/lib/merge-files.nix
@@ -0,0 +1,10 @@
+{ runCommandLocal, rsync, lib, ... }:
+files:
+let
+ cpFile = s: ''
+ ${lib.getExe rsync} -aL "${s.source}/" "$out${s.target}"
+ '';
+in runCommandLocal "merged-files" {} ''
+ mkdir $out
+ ${lib.concatMapStringsSep "\n" cpFile files}
+''
diff --git a/modules/nickel/default.nix b/modules/nickel/default.nix
new file mode 100644
index 0000000..c5736f0
--- /dev/null
+++ b/modules/nickel/default.nix
@@ -0,0 +1,153 @@
+{ config, pkgs, lib, options, ... }:
+with builtins // lib;
+let
+ cfg = config.nickel;
+ action = mkOption {
+ type = types.enum [
+ "cmd_spawn"
+ "cmd_output"
+ "dbg_syslog"
+ "dbg_error"
+ "dbg_msg"
+ "dbg_toast"
+ "kfmon"
+ "nickel_setting"
+ "nickel_extras"
+ "nickel_browser"
+ "nickel_misc"
+ "nickel_open"
+ "nickel_wifi"
+ "nickel_orientation"
+ "power"
+ "skip"
+ ];
+ };
+ location = mkOption {
+ type = types.enum [
+ "main"
+ "reader"
+ "browser"
+ "library"
+ "selection"
+ ];
+ };
+
+ createChainItem = { when, action, arg, ... }: concatStringsSep " : " ([ "chain_${when}" action ] ++ arg);
+ createMenuItem = { location, label, action, arg, chain, ... }: concatStringsSep "\n" (
+ singleton (
+ concatStringsSep " : " ([ "menu_item" location label action ] ++ arg)
+ ) ++ (map createChainItem chain)
+ );
+
+ createExperimental = k: v: "experimental : ${k} : ${v}";
+
+ createGenerator = { location, generator }: concatStringsSep " : " (
+ [ "generator" ] ++
+ (if isInt generator then [ "_test" (toString generator) ]
+ else splitString " " generator)
+ );
+
+in {
+ options.nickel = {
+ enable = mkEnableOption "nickelMenu";
+
+ package = mkPackageOption pkgs "nickel-menu" {};
+
+ _allFiles = mkOption {
+ type = types.package;
+ readOnly = true;
+ internal = true;
+ default = (pkgs.callPackage ../lib/merge-files.nix {}) (atrValues cfg.file);
+ };
+
+ path = mkOption {
+ type = types.str;
+ default = ".adds/nm";
+ readOnly = true;
+ internal = true;
+ # description = "Relative path to nickelMenu within src";
+ };
+
+ devicePath = mkOption {
+ type = types.str;
+ default = "/mnt/onboard/${cfg.path}";
+ readOnly = true;
+ internal = true;
+ };
+
+ file = mkOption {
+ default = {};
+ type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {});
+ };
+
+ menu = {
+ item = mkOption {
+ default = {};
+ description = "https://github.com/pgaskin/NickelMenu/blob/v0.5.4/res/doc";
+ type = with types; attrsOf (listOf (submodule {
+ options = {
+ inherit action location;
+ label = mkOption {
+ type = types.str;
+ };
+ arg = mkOption {
+ type = with types; nonEmptyListOf str;
+ };
+ chain = mkOption {
+ default = [];
+ type = with types; listOf (submodule {
+ options = {
+ when = mkOption {
+ type = types.enum [ "success" "failure" "always" ];
+ };
+ inherit action;
+ arg = mkOption {
+ type = with types; nonEmptyListOf str;
+ };
+ };
+ });
+ };
+ };
+ }));
+ };
+
+ experimental = mkOption {
+ default = {};
+ description = "https://github.com/pgaskin/NickelMenu/blob/v0.5.4/res/doc";
+ type = with types; attrsOf (attrsOf str);
+ };
+
+ generator = mkOption {
+ default = {};
+ description = "https://github.com/pgaskin/NickelMenu/blob/v0.5.4/res/doc";
+ type = with types; attrsOf (listOf (submodule {
+ options = {
+ inherit location;
+ generator = mkOption {
+ type = with types; either (enum [ "kfmon" "kfmon all" "kfmon gui" ]) (ints.between 0 10);
+ default = "kfmon";
+ };
+ };
+ }));
+ };
+ };
+ };
+
+ config = {
+ nickel = {
+ file = mkMerge [
+ (mapAttrs (_: v: {
+ text = concatMapStringsSep "\n" createGenerator v;
+ }) cfg.menu.generator)
+
+ (mapAttrs (_: v: {
+ text = concatStringsSep "\n" (mapAttrsToList createExperimental v);
+ }) cfg.menu.experimental)
+
+ (mapAttrs (_: v: {
+ text = concatMapStringsSep "\n" createMenuItem v;
+ }) cfg.menu.item)
+ ];
+ };
+ };
+}
diff --git a/modules/plato/default.nix b/modules/plato/default.nix
new file mode 100644
index 0000000..1886662
--- /dev/null
+++ b/modules/plato/default.nix
@@ -0,0 +1,362 @@
+{ config, pkgs, lib, options, ... }:
+with builtins // lib;
+let
+ cfg = config.plato;
+ toml = pkgs.formats.toml {};
+ # importOption = p: (import p { inherit pkgs lib; } cfg.path).option;
+in {
+ options.plato = {
+ enable = mkEnableOption "Plato";
+
+ package = mkPackageOption pkgs "plato" {};
+
+ path = mkOption {
+ type = types.str;
+ readOnly = true;
+ internal = true;
+ default = ".adds/plato";
+ };
+
+ devicePath = mkOption {
+ type = types.str;
+ readOnly = true;
+ internal = true;
+ default = "/mnt/onboard/${cfg.path}";
+ };
+
+ _allFiles = mkOption {
+ type = types.package;
+ readOnly = true;
+ internal = true;
+ default = (pkgs.callPackage ../lib/merge-files.nix {}) ([
+ cfg.package
+ ] ++ attrValues cfg.file);
+ };
+
+ file = mkOption {
+ default = {};
+ type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {}));
+ };
+
+ nickel = {
+ enable = mkEnableOption "Add NickelMenu option" // { default = true; };
+ };
+
+
+ settings = mkOption {
+ type = toml.type;
+ default = {};
+ description = ''
+ Contents of Settings.toml
+ '';
+ };
+
+ config = {
+ hyphenation = mkEnableOption "hyphenation" // { default = true; };
+ convertDictionaries = mkEnableOption "convert StartDict" // { default = true; };
+ setFramebufferDepth = mkEnableOption "set framebuffer's depth" // { default = true; };
+ extra = mkOption {
+ type = types.lines;
+ default = "";
+ };
+ };
+ # mkOption {
+ # type = types.lines;
+ # default = "";
+ # description = ''
+ # Contents of config.sh
+ # '';
+ # };
+
+ dictionaries = mkOption {
+ type = with types; listOf package;
+ default = [];
+ };
+
+ _dictionariesCombined = mkOption {
+ type = types.package;
+ readOnly = true;
+ internal = true;
+ default =
+ let
+ copyDicts = pkg: ''
+ find ${pkg}/share/dictd/ -type f -regex '.*\.\(dict\(\.dz\)?\|index\)' -exec cp -v {} $out/ \;
+ '';
+ in pkgs.runCommandLocal "plato-dictionaries" {} ''
+ mkdir $out
+ ${concatMapStringsSep "\n" copyDicts cfg.dictionaries}
+ '';
+ };
+
+ fonts = mkOption {
+ type = with types; listOf package;
+ default = [];
+ };
+
+ _fontsCombined = mkOption {
+ type = types.package;
+ readOnly = true;
+ internal = true;
+ default =
+ let
+ copyFonts = pkg: ''
+ find ${pkg}/share/fonts/truetype/ -type f -regex '.*\.\(ttf\|otf\)' -exec cp -v {} $out/ \;
+ '';
+ in pkgs.runCommandLocal {} ''
+ mkdir $out
+ ${concatMapStringsSep "\n" copyFonts cfg.fonts}
+ '';
+ };
+ };
+
+ config = mkMerge [
+ {
+ plato.file = {
+ "Settings.toml" = mkIf (cfg.settings != {}) {
+ source = toml.generate "Settings.toml" cfg.settings;
+ };
+
+ "config.sh" =
+ let
+ c = optional (!cfg.config.convertDictionaries) "unset PLATO_CONVERT_DICTIONARIES"
+ ++ optional (!cfg.config.setFramebufferDepth) "unset PLATO_SET_FRAMEBUFFER_DEPTH"
+ ++ optional (!cfg.config.hyphenation) "[ -d hyphenation-patters ] && rm -rf hyphenation-patterns"
+ ++ optional (cfg.config.extra != "") cfg.config.extra
+ ;
+ in mkIf (c != []) {
+ text = concatStringsSep "\n\n" c;
+ };
+
+ "_dictionaries" = {
+ target = "dictionaries";
+ source = cfg._dictionariesCombined;
+ };
+
+ "_fonts" = {
+ target = "fonts";
+ source = cfg._fontsCombined;
+ };
+ };
+
+ nickel.menu.item = mkIf (cfg.enable && cfg.nickel.enable) {
+ plato = singleton {
+ location = "main";
+ label = "Plato";
+ action = "cmd_spawn";
+ arg = [
+ "quiet"
+ "exec ${cfg.devicePath}/plato.sh"
+ ];
+ };
+ };
+ }
+ # (mkIf (cfg.enable && cfg.nickelEntry.enable {
+ # nickel.menu.item =
+ # })
+ ];
+}
+
+
+# imports = [
+# ./nickel.nix
+# ];
+
+# options.plato = {
+# enable = mkEnableOption "Plato";
+
+# path = mkOption {
+# type = types.str;
+# default = ".adds/plato";
+# description = "Relative path to Plato within src";
+# };
+
+# devPath = mkOption {
+# type = types.str;
+# default = "/mnt/onboard/${cfg.path}";
+# readOnly = true;
+# internal = true;
+# };
+
+# file = importOption ./lib/file.nix;
+# manifest = importOption ./lib/manifest.nix;
+
+# # file = mkOption {
+# # type = options.file.type;
+# # default = {};
+# # description = "Files relative to ${cfg.path}";
+# # };
+
+# # manifest = mkOption {
+# # type = options.manifest.type;
+# # default = {};
+# # description = "Manifest relative to ${cfg.path}";
+# # };
+
+# nickelEntry = mkEnableOption "Launch Plato directly from nickelMenu";
+
+# config = mkOption {
+# type = types.lines;
+# default = "";
+# description = "Plato config.sh";
+# };
+
+# hyphenation = mkEnableOption "hyphenation" // { default = true; };
+
+# convertDictionaries = mkEnableOption "convert StarDict" // { default = true; };
+
+# setFramebufferDepth = mkEnableOption "set framebuffer's depth" // { default = true; };
+
+# settings = mkOption {
+# type = toml.type;
+# default = {};
+# description = "Plato Settings.toml";
+# };
+
+# css = mkOption {
+# default = {};
+# type = with types; attrsOf lines;
+# description = ''
+# css style sheets.
+# Only use this for epub-user dictionary-user html-user
+# '';
+# };
+
+# scripts = mkOption {
+# default = {};
+# type = with types; attrsOf lines;
+# description = ''
+# Only use this for wifi-post-up wifi-post-down wifi-pre-up wifi-pre-down.
+# '';
+# # apply = mapAttrs (_: text: ''
+# # #!/bin/sh
+
+# # ${text}
+# # '')
+# };
+
+# dictionaries = mkOption {
+# type = with types; listOf package;
+# default = [];
+# };
+
+# allDictionaries = mkOption {
+# type = types.package;
+# readOnly = true;
+# internal = true;
+# default = pkgs.runCommand "PlatoDictionaries" {} (''
+# mkdir -p $out
+# '' + concatMapStringsSep "\n" (pkg: ''
+# find ${pkg}/share/dictd/ -type f -regex '.*\.\(dict\(\.dz\)?\|index\)' -exec cp -v {} $out/ \;
+# '') cfg.dictionaries
+# );
+
+# };
+
+# fonts = mkOption {
+# type = with types; listOf package;
+# default = [];
+# };
+
+# allFonts = mkOption {
+# type = types.package;
+# readOnly = true;
+# internal = true;
+# default = pkgs.runCommand "PlatoFonts" {} (''
+# mkdir -p $out
+# '' + concatMapStringsSep "\n" (pkg: ''
+# find ${pkg}/share/fonts/truetype/ -type f -regex '.*\.\(ttf\|otf\)' -exec cp -v {} $out/ \;
+# '') cfg.fonts
+# );
+
+# };
+# };
+
+# config = mkIf cfg.enable {
+# plato = {
+# config = concatStringsSep "\n\n" (
+# optional (!cfg.convertDictionaries) ''
+# unset PLATO_CONVERT_DICTIONARIES
+# ''
+# ++
+# optional (!cfg.setFramebufferDepth) ''
+# unset PLATO_SET_FRAMEBUFFER_DEPTH
+# ''
+# ++
+# optional (!cfg.hyphenation) ''
+# [ -d hyphenation-patterns ] && rm -rf hyphenation-patterns
+# ''
+# );
+# file = mkMerge [
+# (mkIf (cfg.settings != {}) {
+# "Settings.toml".source = toml.generate "Settings.toml" cfg.settings;
+# })
+
+# (mkIf (cfg.config != "") {
+# "config.sh".text = cfg.config;
+# })
+
+# (mapAttrs' (n: text:
+# let
+# n1 = if hasPrefix "css/" n then n else "css/${n}";
+# name = if hasSuffix ".css" n1 then n1 else "{n1}.css";
+# in {
+# inherit name;
+# value = { inherit text; };
+# }) cfg.css)
+
+# (mapAttrs' (n: t:
+# let
+# n1 = if hasPrefix "scripts/" n then n else "scripts/${n}";
+# name = if hasSuffix ".sh" n1 then n1 else "${n1}.sh";
+# text = if hasPrefix "#!/" t then t else "#!/bin/sh\n\n${t}";
+# in {
+# inherit name;
+# value = { inherit text; };
+# }) cfg.scripts)
+
+# {
+# dictionaries = {
+# # directory = true;
+# source = cfg.allDictionaries;
+# };
+# fonts = {
+# # directory = true;
+# source = cfg.allFonts;
+# };
+# }
+# ];
+
+# manifest = {
+# "config-sample.sh".mergeTool = _: _: "echo 'not copying config-sample.sh'";
+# "Settings-sample.toml".mergeTool = _: _: "echo 'not copying Settings-sample.toml'";
+# };
+# };
+
+# # file = mapAttrs' (n: v: {
+# # name = "plato-${n}";
+# # value = v // {
+# # target = "${cfg.path}/${v.target}";
+# # };
+# # }) cfg.file;
+
+# # manifest = mapAttrs' (n: v: {
+# # name = "plato-${n}";
+# # value = v // {
+# # targets = map (x: "${cfg.path}/${x}") v.targets;
+# # };
+# # }) cfg.manifest;
+
+# nickel.menu.item = mkIf cfg.nickelEntry {
+# plato = singleton {
+# location = "main";
+# label = "Plato";
+# action = "cmd_spawn";
+# arg = [
+# "quiet"
+# "exec ${cfg.devPath}/plato.sh"
+# ];
+# };
+# };
+
+# };
+# }