aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/default.nix7
-rw-r--r--config/nickel.nix21
-rw-r--r--config/plato.nix44
-rw-r--r--config/screensaver.nix11
-rw-r--r--config/screensaver.pngbin2718976 -> 0 bytes
-rw-r--r--flake.nix12
-rw-r--r--kobo/clara/default.nix1
-rw-r--r--modules/build.nix174
-rw-r--r--modules/build/default.nix2
-rw-r--r--modules/build/firmware.nix70
-rw-r--r--modules/build/info.nix55
-rw-r--r--modules/build/koboroot.nix31
-rw-r--r--modules/builder.nix11
-rw-r--r--modules/default.nix9
-rw-r--r--modules/device/default.nix9
-rw-r--r--modules/file.nix7
-rw-r--r--modules/firmware/default.nix8
-rw-r--r--modules/installScript.nix75
-rw-r--r--modules/installer.nix26
-rw-r--r--modules/kfmon.nix46
-rw-r--r--modules/kfmon/default.nix53
-rw-r--r--modules/kobo.nix73
-rw-r--r--modules/kobo/default.nix52
-rw-r--r--modules/koboroot/default.nix20
-rw-r--r--modules/koreader.nix55
-rw-r--r--modules/koreader/default.nix72
-rw-r--r--modules/manifest.nix38
-rw-r--r--modules/nickel.nix148
-rw-r--r--modules/nickel/default.nix34
-rw-r--r--modules/plato.nix210
-rw-r--r--modules/plato/default.nix39
-rw-r--r--modules/root.nix21
-rw-r--r--overlays/default.nix2
-rw-r--r--pkgs/firmware/default.nix8
-rw-r--r--pkgs/install.nix110
-rw-r--r--pkgs/misc/create-koboroot.nix5
-rw-r--r--pkgs/misc/deploy.nix65
-rw-r--r--pkgs/misc/merge.nix10
-rw-r--r--pkgs/plato.nix46
-rw-r--r--pkgs/source.nix21
40 files changed, 412 insertions, 1289 deletions
diff --git a/config/default.nix b/config/default.nix
deleted file mode 100644
index 6da8197..0000000
--- a/config/default.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- imports = [
- ./nickel.nix
- ./plato.nix
- ./screensaver.nix
- ];
-}
diff --git a/config/nickel.nix b/config/nickel.nix
deleted file mode 100644
index 5e62fc6..0000000
--- a/config/nickel.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-{
- nickel = {
- enable = true;
-
- menu.item = {
- settings = [
- {
- location = "main";
- label = "IP Address";
- action = "cmd_output";
- arg = [
- "500"
- "/sbin/ifconfg | /usr/bin/awk '/inet addr/{print substr($2,6)}'"
- ];
- }
- ];
- };
- };
-}
diff --git a/config/plato.nix b/config/plato.nix
deleted file mode 100644
index 16531b3..0000000
--- a/config/plato.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-{
- # kfmon.enable = true;
- # koreader.enable = true;
-
- plato = {
- enable = true;
-
- fonts.packages = [
- # pkgs.atkinson-hyperlegible
- pkgs.fira-math
- ];
-
- dictionaries.packages = with pkgs.dictdDBs; [
- wordnet
- wiktionary
- ];
-
- settings = {
- keyboard-layout = "English";
- frontlight = true;
- wifi = false;
- sleep-cover = true;
- auto-share = true;
- auto-suspend = 15.0;
- auto-power-off = 4.0;
- time-format = "%I:%M%P";
- # intermissions = {
- # suspend = "cover:";
- # power-off = "cover:";
- # share = "logo:";
- # };
- reader = {
- font-size = 10.0;
- font-family = "Fira Math";
- # font-family = "Atkinson Hyperlegible";
- };
- dictionary = {
- font-size = 10.0;
- };
- };
- };
-}
diff --git a/config/screensaver.nix b/config/screensaver.nix
deleted file mode 100644
index 2706202..0000000
--- a/config/screensaver.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-{
- file.".kobo/screensaver/main.png".source = ./screensaver.png;
-
- plato.settings.intermissions = rec {
- suspend = "cover:";
- power-off = "/mnt/onboard/.kobo/screensaver/main.png";
- share = power-off;
- };
-}
diff --git a/config/screensaver.png b/config/screensaver.png
deleted file mode 100644
index c26ab78..0000000
--- a/config/screensaver.png
+++ /dev/null
Binary files differ
diff --git a/flake.nix b/flake.nix
index 2b0e39b..73e7ce3 100644
--- a/flake.nix
+++ b/flake.nix
@@ -41,12 +41,12 @@
nickel-menu
plato
;
- firmware-test = pkgs.kobo-firmware {
- hardware = "kobo7";
- date = "Jun2024";
- version = "4.38.23038";
- hash = "sha256-ma9Hf0Hc4hDqf1KQwM6TdX3lZo9HPWMrQqU45eFBScs=";
- };
+ # firmware-test = pkgs.kobo-firmware {
+ # hardware = "kobo7";
+ # date = "Jun2024";
+ # version = "4.38.23038";
+ # hash = "sha256-ma9Hf0Hc4hDqf1KQwM6TdX3lZo9HPWMrQqU45eFBScs=";
+ # };
# installer = myKobo.config.installer.package;
};
diff --git a/kobo/clara/default.nix b/kobo/clara/default.nix
index f2d026b..b061c7f 100644
--- a/kobo/clara/default.nix
+++ b/kobo/clara/default.nix
@@ -8,6 +8,7 @@ with builtins // lib;
firmware = {
version = "4.38.23038";
date = "Jun2024";
+ hash = "sha256-ma9Hf0Hc4hDqf1KQwM6TdX3lZo9HPWMrQqU45eFBScs=";
};
kobo = {
diff --git a/modules/build.nix b/modules/build.nix
deleted file mode 100644
index dfff338..0000000
--- a/modules/build.nix
+++ /dev/null
@@ -1,174 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-let
- cfg = config.build;
-
- copyFileFunc = ''
- function copyFile() {
- local SOURCE="$1"
- local RELTARGET="$2"
- local EXECUTABLE="3"
-
- local TARGET
- TARGET="$(realpath -m "$REALOUT/$RELTARGET")"
- if [[ ! $TARGET == $REALOUT* ]]; then
- echo "Error installing file $RELTARGET outside of kobo src" >&2
- exit 1
- fi
-
- mkdir -pv "$(dirname "$TARGET")"
- if [[ -d "$SOURCE" ]]; then
- if [[ -d "$TARGET" ]]; then
- cp -rfv "$SOURCE/." "$TARGET/"
- else
- cp -rfv "$SOURCE" "$TARGET"
- fi
- else
- cp -fv "$SOURCE" "$TARGET"
- fi
-
- if [[ "$EXECUTABLE" == "inherit" ]]; then
- :
- elif [[ "$EXECUTABLE" ]]; then
- chmod +x "$TARGET"
- else
- chmod -x "$TARGET"
- fi
- }
- '';
-
- copyFile = { source, executable, target, ... }: ''
- copyFile ${escapeShellArgs [
- source
- (if executable == null then "inherit" else toString executable)
- ]}
- '';
-
- installFile = writeShellApplication {
- name = "kobo-install-file";
- runtimeInputs = [ pkgs.coreutils ];
- text = ''
- DRY_RUN_ARG="''${1-}"
- LOCAL_DIR="''${2-}"
- KOBO_DIR="''${3-}"
- LOCAL_FILE="''${4-}"
-
- FILENAME="''${LOCAL_FILE/#$LOCAL_DIR}"
- KOBO_FILE="$KOBO_DIR/$FILENAME"
-
- ${toShellVar "MANIFEST" (cfg.manifestLookupFor "$LOCAL_FILE" "$KOBO_FILE")}
-
- ACTION="''${MANIFEST["$FILENAME"]}"
-
- if [[ -n "$ACTION" ]]; then
- $DRY_RUN_ARG eval "$ACTION"
- elif [[ -d "$LOCAL_FILE" ]]; then
- $DRY_RUN_ARG mkdir -p "$KOBO_FILE"
- else
- $DRY_RUN_ARG mkdir -p "$(dirname "$KOBO_FILE")"
- $DRY_RUN_ARG cp -f "$LOCAL_FILE" "$KOBO_FILE"
- fi
- '';
- };
-in {
- options.build = {
- allFiles = mkOption {
- readOnly = true;
- internal = true;
- default = with config; concatMap (_: attrValues) [
- file
- kfmon.file
- kobo.file
- koreader.file
- nickel.file
- plato.file
- ];
- apply = filter (v: v.enable);
- };
-
- allManifests = mkOption {
- readOnly = true;
- internal = true;
- default = with config; concatMap (_: attrValues) [
- manifest
- kfmon.manifest
- kobo.manifest
- koreader.manifest
- nickel.manifest
- plato.manifest
- ];
- apply = filter (v: v.enable);
- };
-
- manifestLookup = mkOption {
- readOnly = true;
- internal = true;
- type = with types; attrsOf (functionTo (functionTo str));
- default =
- let
- split = concatMap ({ targets, mergeTool, ... }: map (name: { inherit name; value = mergeTool; }) targets);
- in listToAttrs split;
- };
-
- manifestLookupFor = mkOption {
- readOnly = true;
- internal = true;
- type = with types; functionTo (functionTo (attrsOf str));
- default = x: y: mapAttrs (_: f: f x y) cfg.manifestLookup;
- };
-
- src = mkOption {
- type = types.package;
- readOnly = true;
- internal = true;
- default = pkgs.stdenv.mkDerivation {
- inherit (config) src;
- name = "kobo_src";
- phases = [ "installPhase" ];
- installPhase = ''
- mkdir -pv $out
- cp -rv $src/. $out/
- chmod -R +w $out
-
- REALOUT="$(realpath -m "$out")"
-
- ${copyFileFunc}
-
- ${concatStringsSep "\n" (
- mapAttrsToList (_: copyFile) cfg.allFiles
- )}
- '';
- };
- };
-
- installer = mkOption {
- type = types.package;
- readOnly = true;
- internal = true;
- default = pkgs.writeShellApplication {
- name = "kobo-installer";
- runtimeInputs = [
- pkgs.coreutils
- pkgs.util-linux
- ];
- text = '' #TODO DRY_RUN_ARG
- KOBO_LABEL="''${1:-KOBOeReader}"
-
- KOBO_MOUNTPOINT="$(findmnt -nlo TARGET LABEL="$KOBO_LABEL")"
- if [[ -z "$KOBO_MOUNTPOINT" ]]; then
- echo "Couldn't find a Kobo eReader volume with label $KOBO_LABEL. Are you sure one is actually mounted?"
- exit 255
- fi
-
- KOBO_DIR="$KOBO_MOUNTPOINT/.kobo"
- if [[ ! -d "$KOBO_DIR" ]]; then
- echo "It doesn't seem like $KOBO_MOUNTPOINT actually points to a Kobo eReader since it doesn't contain a .kobo directory . . . "
- exit 255
- fi
-
- find "${cfg.src}/" -not -path "${cfg.src}/" -exec ${installFile}/bin/kobo-install-file "" "${cfg.src}" "$KOBO_DIR" {} \;
- '';
- };
- };
- };
-}
diff --git a/modules/build/default.nix b/modules/build/default.nix
index be3f3b0..3c0948e 100644
--- a/modules/build/default.nix
+++ b/modules/build/default.nix
@@ -1,5 +1,7 @@
{
imports = [
./firmware.nix
+ ./info.nix
+ ./koboroot.nix
];
}
diff --git a/modules/build/firmware.nix b/modules/build/firmware.nix
index 673c379..3a1039b 100644
--- a/modules/build/firmware.nix
+++ b/modules/build/firmware.nix
@@ -1,60 +1,54 @@
{ config, pkgs, lib, ... }:
with builtins // lib;
let
- cfg = config.build;
+ cfg = config.build.firmware;
in {
options.build = {
firmware = {
- checkDevice = mkOption {
+ updateCheck = mkOption {
internal = true;
readOnly = true;
type = types.package;
default = pkgs.writeShellApplication {
- name = "check-firmware";
+ name = "update-check";
runtimeInputs = with pkgs; [
- kobo-utils
+ curl
+ jq
];
- text = ''
- echo "hi"
+ text = with config.device; ''
+ curl --silent "https://api.kobobooks.com/1.0/UpgradeCheck/Device/${deviceID}/${affiliate}/${config.firmware.version}/${serialNumber}" | jq .
'';
};
};
-
- bundle =
- let
- b = pkgs.runCommandLocal "package-firmware" {} ''
- cp -r "${config.firmware.package.out}" $out
- tar czvf $out/KoboRoot.tgz --directory="${config.firmware.package.KoboRoot}"
- '';
- in pkgs.runCommandLocal "bundle-firmware" {} ''
- tar czvf $out --directory "${b}"
- '';
-
-
- deploy = pkgs.writeShellApplication {
- name = "deploy-firmware";
- runtimeInputs = with pkgs; [
- gnutar
- kobo-utils
- ];
- text = ''
- echo "Looking for kobo"
- KOBOPATH="$(kobo-find -f -w)"
-
- if [ -z "$KOBOPATH" ]; then
- >&2 echo "Cannot locate kobo device"
+ payload = mkOption {
+ internal = true;
+ readOnly = true;
+ type = types.path;
+ default = pkgs.runCommandLocal "firmware-payload" {
+ nativeBuildInputs = with pkgs; [
+ kobo-utils
+ gawk
+ rsync
+ ];
+ } ''
+ mkdir $out
+ tar czvf $out/KoboRoot.tgz --directory="${config.firmware.package.KoboRoot}" . --mode=u+w
+ rsync -rv --links --executability --chmod=u+w "${config.firmware.package.out}/" $out
+
+ # Check that we haven't fucked up!
+ KOBOVERSION="$(kobo-versionextract "$out/KoboRoot.tgz" | awk '{if ($1 == "Version:") print $2}')"
+ if [[ ! "$KOBOVERSION" == "${config.firmware.version}" ]]; then
+ >&2 echo "Expected version ${config.firmware.version}, but actual firmware is version $KOBOVERSION"
exit 1
fi
-
- echo "Found kobo device at $KOBOPATH"
-
- echo "Placing firmware on device"
-
- tar xzvf "${cfg.fimware.bundle}" --directory="$KOBOPATH/.kobo/"
-
- echo "Successfully installed kobo firmware. Please eject your device so it can install."
'';
};
+ deploy = mkOption {
+ internal = true;
+ readOnly = true;
+ type = types.package;
+ default = pkgs.kobo-deploy cfg.payload;
+ };
};
};
}
diff --git a/modules/build/info.nix b/modules/build/info.nix
new file mode 100644
index 0000000..95ef664
--- /dev/null
+++ b/modules/build/info.nix
@@ -0,0 +1,55 @@
+{ config, pkgs, lib, ... }:
+with builtins // lib;
+let
+ json = pkgs.formats.json {};
+ cfg = config.build.info;
+in {
+ options = {
+ info = mkOption {
+ internal = true;
+ type = json.type;
+ default = {};
+ };
+ build = {
+ info = mkOption {
+ internal = true;
+ readOnly = true;
+ type = types.package;
+ default = pkgs.writeShellApplication {
+ name = "kobo-info";
+ runtimeInputs = with pkgs; [
+ jq
+ kobo-utils
+ ];
+ text = ''
+ echo "Local information:"
+ echo '${toJSON config.info}' | jq .
+
+
+ echo "Remote information:"
+
+ KOBOPATH="$(kobo-find -f || echo "")"
+
+ if [[ -z "$KOBOPATH" ]]; then
+ echo "No remote found"
+ exit 0
+ fi
+
+ kobo-info --json "$KOBOPATH" | jq .
+ '';
+ };
+ };
+ };
+ };
+
+ config = {
+ info = {
+ device = {
+ inherit (config.device) name affiliate hardware deviceID serialNumber;
+ };
+ firmware = {
+ inherit (config.firmware) version date;
+ };
+ };
+ };
+}
diff --git a/modules/build/koboroot.nix b/modules/build/koboroot.nix
new file mode 100644
index 0000000..9bea19d
--- /dev/null
+++ b/modules/build/koboroot.nix
@@ -0,0 +1,31 @@
+{ config, pkgs, lib, ... }:
+with builtins // lib;
+let
+ cfg = config.build.koboroot;
+in {
+ options.build = {
+ koboroot = {
+ unpacked-payload = mkOption {
+ type = types.path;
+ internal = true;
+ readOnly = true;
+ default = config.koboroot.finalPackage;
+ };
+ payload = mkOption {
+ type = types.path;
+ internal = true;
+ readOnly = true;
+ default = pkgs.runCommandLocal "koboroot-payload" {} ''
+ mkdir $out
+ tar czvf $out/KoboRoot.tgz --directory="${cfg.unpacked-payload}" . --mode=u+w
+ '';
+ };
+ deploy = mkOption {
+ internal = true;
+ readOnly = true;
+ type = types.package;
+ default = pkgs.kobo-deploy cfg.payload;
+ };
+ };
+ };
+}
diff --git a/modules/builder.nix b/modules/builder.nix
deleted file mode 100644
index 5f74a1e..0000000
--- a/modules/builder.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{ pkgs, lib, ... }:
-with builtins // lib;
-{
- copyFile = { source, directory, executable, target, ... }: ''
- cp -${if directory then "r" else ""}v "${source}" "${target}"
-
- ${optionalString (isBool executable) ''
- chmod ${if executable then "+" else "-"}x "${target}"
- ''}
- '';
-}
diff --git a/modules/default.nix b/modules/default.nix
index a5c0395..1c9fee4 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -6,15 +6,8 @@
./kfmon
./kobo
./koboroot
+ ./koreader
./nickel
./plato
- # ./installer.nix
- # ./build.nix
- # ./file.nix
- # ./manifest.nix
- # ./kfmon.nix
- # ./kobo.nix
- # ./koreader.nix
- # ./plato.nix
];
}
diff --git a/modules/device/default.nix b/modules/device/default.nix
index a1f80ef..23be585 100644
--- a/modules/device/default.nix
+++ b/modules/device/default.nix
@@ -4,10 +4,10 @@ let
devices = import ../../data/devices.nix;
hardware = mkOption {
- type = types.strMatching ''^kobo\d+$'';
+ type = types.strMatching ''^kobo[0-9]+$'';
};
deviceID = mkOption {
- type = types.strMatching ''00000000-0000-0000-0000-000000000\d\d\d'';
+ type = types.strMatching ''^00000000-0000-0000-0000-000000000[0-9][0-9][0-9]$'';
};
deviceInfo = types.submodule {
@@ -41,6 +41,11 @@ in {
deviceID = deviceID // {
default = config._allDevices.${config.device.name}.deviceID;
};
+
+ serialNumber = mkOption {
+ type = types.str;
+ default = "N0";
+ };
};
};
}
diff --git a/modules/file.nix b/modules/file.nix
deleted file mode 100644
index 7bd2549..0000000
--- a/modules/file.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-let
- cfg = config.file;
-in {
- options.file = (import ./lib/file.nix { inherit pkgs lib; } "").option;
-}
diff --git a/modules/firmware/default.nix b/modules/firmware/default.nix
index 30a0779..c13d399 100644
--- a/modules/firmware/default.nix
+++ b/modules/firmware/default.nix
@@ -10,15 +10,15 @@ in {
version = mkOption {
type = types.str;
};
- # hash = mkOption {
- # type = types.str;
- # };
+ hash = mkOption {
+ type = types.str;
+ };
package = mkOption {
type = types.package;
default = pkgs.kobo-firmware {
inherit (config.device) hardware;
- inherit (cfg) date version;
+ inherit (cfg) date version hash;
};
};
};
diff --git a/modules/installScript.nix b/modules/installScript.nix
deleted file mode 100644
index 1e5e355..0000000
--- a/modules/installScript.nix
+++ /dev/null
@@ -1,75 +0,0 @@
-{ writeShellApplication
-, coreutils
-, util-linux
-, lib
-
-, koboInput
-, koboLabel ? "KOBOeReader"
-, koboManifest ? {}
-, ... }:
-with builtins // lib;
-let
- manValues = attrValues koboManifest;
- createMergeTool = local: remote: name: mergeTool: {
- inherit name;
- value = mergeTool "${local}/${name}" "${remote}/${name}";
- };
- collectMergeTools = local: remote: xs: listToAttrs (concatMap (v: map (name: createMergeTool local remote name v.mergeTool) v.targets) xs);
- onDevManifest = local: remote: collectMergeTools local remote (filter (v: v.remoteOnly) manValues;
- manifest = local: remote: collectMergeTools local remote (filter (v: ! v.remoteOnly) manValues);
-
- execApp = writeShellApplication {
- name = "kobo-exec";
- runtimeInputs = [
- coreutils
- ];
- text = ''
- REMOTE_OR_LOCAL="''${1-}"
- KOBO_DIR="''${2-}"
- FILE="''${3-}"
-
- if [[ "$REMOTE_OR_LOCAL" == "REMOTE" ]]; then
- ${toShellVar "MANIFEST" (onDevManifest ${koboInput} "$KOBO_DIR")}
- FILEBASE="''${FILE/#$KOBO_DIR}"
- else
- ${toShellVar "MANIFEST" (manifest ${koboInput} "$KOBO_DIR")}
- FILEBASE="''${FILE/#${koboInput}}"
- fi
-
- ACTION="''${MANIFEST["$FILEBASE"]}"
-
- if [[ -n "$ACTION" ]]; then
- eval "$ACTION"
- elif [[ "$REMOTE_OR_LOCAL" == "LOCAL" ]]; then
- if [[ -d "$FILE" ]]; then
- mkdir -p "$KOBO_DIR/$FILEBASE"
- else
- cp -v "$FILE" "$KOBO_DIR/$FILEBASE"
- fi
- fi
- '';
- };
-in writeShellApplication {
- name = "KoboInstaller";
- runtimeInputs = [
- coreutils
- util-linux
- ];
- text = ''
- KOBO_MOUNTPOINT="$(findmnt -nlo TARGET LABEL="${koboLabel}")"
- if [[ -z "$KOBO_MOUNTPOINT" ]]; then
- echo "Couldn't find a Kobo eReader volume with label ${koboLabel}. Are you sure one is actually mounted?"
- exit 255
- fi
-
- KOBO_DIR="$KOBO_MOUNTPOINT/.kobo"
- if [[ ! -d "$KOBO_DIR" ]]; then
- echo "It doesn't seem like $KOBO_MOUNTPOINT actually points to a Kobo eReader since it doesn't contain a .kobo directory . . . "
- exit 255
- fi
-
- find "$KOBO_DIR/" -not -path "$KOBO_DIR/" -exec ${execApp}/bin/kobo-exec "REMOTE" "$KOBO_DIR" {} \;
-
- find "${koboInput}/" -not -path "${koboInput}/" -exec ${execApp}/bin/kobo-exec "LOCAL" "$KOBO_DIR" {} \;
- '';
-}
diff --git a/modules/installer.nix b/modules/installer.nix
deleted file mode 100644
index 2fcc546..0000000
--- a/modules/installer.nix
+++ /dev/null
@@ -1,26 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-let
- cfg = config.installer;
-in {
- imports = [
- ./kobo.nix
- ];
-
- options.installer = {
- package = mkOption {
- type = types.package;
- default = pkgs.callpackage ./installScript.nix {
- koboInput = null;
- koboLabel = cfg.koboLabel;
- koboManifest = config.manifest;
- };
- };
-
- koboLabel = mkOption {
- type = types.str;
- default = "KOBOeReader";
- description = "The label of the Kobo eReader mount target";
- };
- };
-}
diff --git a/modules/kfmon.nix b/modules/kfmon.nix
deleted file mode 100644
index adb53bd..0000000
--- a/modules/kfmon.nix
+++ /dev/null
@@ -1,46 +0,0 @@
-{ config, pkgs, lib, options, ... }:
-with builtins // lib;
-let
- cfg = config.kfmon;
- ini = pkgs.formats.ini {};
- importOption = p: (import p { inherit pkgs lib; } cfg.path).option;
-
- addSuffix = s: p: if hasSuffix s p then p else p + s;
-in {
- options.kfmon = {
- enable = mkEnableOption "KFMon";
-
- path = mkOption {
- type = types.str;
- default = ".adds/kfmon";
- description = "Relative path to kfmon 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;
-
- 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 = addSuffix ".ini" n;
- value = {
- target = "config/${addSuffix ".ini" n}";
- text = generators.toINI {} v;
- };
- }) cfg.configs;
-
-}
diff --git a/modules/kfmon/default.nix b/modules/kfmon/default.nix
index ac20b86..a2fcbb9 100644
--- a/modules/kfmon/default.nix
+++ b/modules/kfmon/default.nix
@@ -29,16 +29,44 @@ in {
apply = filterAttrs (_: v: v.enable);
};
- _allFiles = mkOption {
+ _createdFiles = mkOption {
type = types.package;
internal = true;
readOnly = true;
- default = pkgs.symlinkJoin {
- name = "kfmon-files";
- paths = mapAttrsToList (v: v._package) cfg.file;
+ default = pkgs.buildEnv {
+ name = "kfmon-files-created";
+ paths = mapAttrsToList (_: v: v._package) cfg.file;
+ extraPrefix = cfg.devicePath;
};
};
+ finalPackage = mkOption {
+ type = types.package;
+ internal = true;
+ readOnly = true;
+ default = pkgs.mergePaths {
+ name = "kfmon-package";
+ paths = [
+ (pkgs.linkFarm "kfmon" [{
+ name = removePrefix "/" cfg.devicePath;
+ path = cfg.package.out;
+ }])
+ cfg._createdFiles
+ cfg.package.KoboRoot
+ ];
+ };
+ };
+
+ # _allFiles = mkOption {
+ # type = types.package;
+ # internal = true;
+ # readOnly = true;
+ # default = pkgs.symlinkJoin {
+ # name = "kfmon-files";
+ # paths = mapAttrsToList (v: v._package) cfg.file;
+ # };
+ # };
+
configs = mkOption {
type = types.attrsOf ini.type;
default = {};
@@ -50,6 +78,8 @@ in {
config = mkMerge [
{
+ info.kfmon = cfg.enable;
+
kfmon.file = mapAttrs' (n: v: {
name = "kfmon-config-${n}";
value = {
@@ -62,13 +92,14 @@ in {
});
}
(mkIf cfg.enable {
- koboroot.include = [
- (pkgs.linkFarm [{
- name = cfg.devicePath;
- path = cfg._allFiles;
- }])
- cfg.package.KoboRoot
- ];
+ koboroot.include = singleton cfg.finalPackage;
+ # koboroot.include = [
+ # (pkgs.linkFarm [{
+ # name = cfg.devicePath;
+ # path = cfg._allFiles;
+ # }])
+ # cfg.package.KoboRoot
+ # ];
})
];
}
diff --git a/modules/kobo.nix b/modules/kobo.nix
deleted file mode 100644
index 1b59a21..0000000
--- a/modules/kobo.nix
+++ /dev/null
@@ -1,73 +0,0 @@
-{ config, pkgs, lib, options, ... }:
-with builtins // lib;
-let
- cfg = config.kobo;
- ini = pkgs.formats.ini {};
- importOption = p: (import p { inherit pkgs lib; } cfg.path).option;
-in {
- options.kobo = {
- enable = mkEnableOption "main configurations";
-
- path = mkOption {
- type = types.str;
- default = ".kobo/Kobo";
- description = "Relative path to main Kobo config";
- };
-
- devPath = mkOption {
- type = types.str;
- default = "/mnt/onboard/${cfg.path}"
- readOnly = true;
- internal = true;
- };
-
- file = importOption ./lib/file.nix;
- manifest = importOption ./lib/manifest.nix;
-
- config = mkOption {
- type = ini.type;
- default = {};
- description = "https://wiki.mobileread.com/wiki/Kobo_Configuration_Options";
- };
- };
-
- config = {
- # file = mapAttrs' (n: v: {
- # name = "kobo-${n}";
- # value = v // {
- # target = "${cfg.path}/${v.target}";
- # };
- # }) cfg.file;
-
- # manifest = mapAttrs' (n: v: {
- # name = "kobo-${n}";
- # value = v // {
- # targets = map (x: "${cfg.path}/${x}") v.targets;
- # };
- # }) cfg.manifest;
-
- kobo = {
- config = {
- FeatureSettings = {
- ExcludeSyncFolders = ''(\.(?!kobo|adobe).+|([^.][^/]*/)+\..+)'';
- };
- ApplicationPreferences = {
- QuickTourShown = true;
- };
- };
- file = mkMerge [
- (mkIf (cfg.config != {}) {
- "Kobo eReader.conf".text = generators.toINI {} cfg.config;
- })
- ];
-
- manifest = {
- "Kobo eReader.conf".mergeTool = local: remote: ''
- ${getBin pkgs.crudini}/bin/crudini --merge "${remote}" < "${local}"
- '';
- };
- };
-
-
- };
-}
diff --git a/modules/kobo/default.nix b/modules/kobo/default.nix
index cdf9728..48bca11 100644
--- a/modules/kobo/default.nix
+++ b/modules/kobo/default.nix
@@ -21,22 +21,45 @@ in {
default = "/mnt/onboard/${cfg.path}";
};
- file = mkOption {
- default = {};
- type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {}));
- apply = filterAttrs (_: v: v.enable);
+ _createdFiles = mkOption {
+ type = types.package;
+ internal = true;
+ readOnly = true;
+ default = pkgs.buildEnv {
+ name = "kobo-files-created";
+ paths = mapAttrsToList (_: v: v._package) cfg.file;
+ extraPrefix = cfg.devicePath;
+ };
};
- _allFiles = mkOption {
+ finalPackage = mkOption {
type = types.package;
- readOnly = true;
internal = true;
- default = pkgs.symlinkJoin {
- name = "kobo-files";
- paths = mapAttrsToList (v: v._package) cfg.file;
+ readOnly = true;
+ default = pkgs.mergePaths {
+ name = "kobo-package";
+ paths = [
+ cfg._createdFiles
+ ];
};
};
+ file = mkOption {
+ default = {};
+ type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {}));
+ apply = filterAttrs (_: v: v.enable);
+ };
+
+ # _allFiles = mkOption {
+ # type = types.package;
+ # readOnly = true;
+ # internal = true;
+ # default = pkgs.symlinkJoin {
+ # name = "kobo-files";
+ # paths = mapAttrsToList (v: v._package) cfg.file;
+ # };
+ # };
+
conf = mkOption {
type = ini.type;
default = {};
@@ -55,16 +78,15 @@ in {
};
};
- file = mkIf (cfg.conf != {}) {
- "Kobo eReader.conf".text = generators.toINI {} cfg.conf;
+ file = {
+ "Kobo eReader.conf" = mkIf (cfg.conf != {}) {
+ text = generators.toINI {} cfg.conf;
+ };
};
};
}
(mkIf cfg.enable {
- koboroot.include = singleton (pkgs.linkFarm [{
- name = cfg.devicePath;
- path = cfg._allFiles;
- }]);
+ koboroot.include = singleton cfg.finalPackage;
})
];
}
diff --git a/modules/koboroot/default.nix b/modules/koboroot/default.nix
index 308ac6b..b0daf82 100644
--- a/modules/koboroot/default.nix
+++ b/modules/koboroot/default.nix
@@ -12,23 +12,33 @@ in {
include = mkOption {
default = [];
- type = with types; listOf path;
+ type = with types; listOf (either path package);
};
- _allFiles = mkOption {
+ finalPackage = mkOption {
type = types.package;
readOnly = true;
internal = true;
- default = pkgs.buildEnv {
- name = "koboroot-files";
+ default = pkgs.mergePaths {
+ name = "koboroot-package";
paths = cfg.include;
};
};
+
+ # _allFiles = mkOption {
+ # type = types.package;
+ # readOnly = true;
+ # internal = true;
+ # default = pkgs.buildEnv {
+ # name = "koboroot-files";
+ # paths = cfg.include;
+ # };
+ # };
};
config = {
koboroot = {
- include = mkBefore (mapAttrsToList (_: v: v._package));
+ include = mkBefore (mapAttrsToList (_: v: v._package) cfg.file);
};
};
}
diff --git a/modules/koreader.nix b/modules/koreader.nix
deleted file mode 100644
index 5bcca42..0000000
--- a/modules/koreader.nix
+++ /dev/null
@@ -1,55 +0,0 @@
-{ config, pkgs, lib, options, ... }:
-with builtins // lib;
-let
- cfg = config.koreader;
- importOption = p: (import p { inherit pkgs lib; } cfg.path).option;
-in {
- options.koreader = {
- enable = mkEnableOption "KOReader";
-
- path = mkOption {
- type = types.str;
- default = ".adds/koreader";
- description = "Relative path to KOReader within src";
- };
-
- devPath = mkOption {
- type = types.str;
- default = "/mnt/onboard/${cfg.path}";
- readOnly = true;
- internal = true;
- };
-
- nickelEntry = mkEnableOption "Launch KOReader directly via nickelMenu";
-
- file = importOption ./lib/file.nix;
- manifest = importOption ./lib/manifest.nix;
-
- # file = mkOption {
- # type = options.file.type;
- # default = {};
- # description = "Files relative to ${cfg.path}";
- # };
- };
-
- config = mkIf cfg.enable {
- # file = mapAttrs' (n: v: {
- # name = "koreader-${n}";
- # value = v // {
- # target = "${cfg.path}/${v.target}";
- # };
- # }) cfg.file;
-
- nickel.menu.item = mkIf cfg.nickelEntry {
- koreader = singleton {
- location = "main";
- label = "KOReader";
- action = "cmd_spawn";
- arg = [
- "quiet"
- "exec ${cfg.devPath}/koreader.sh"
- ];
- };
- };
- };
-}
diff --git a/modules/koreader/default.nix b/modules/koreader/default.nix
index 3cc5281..ab1be83 100644
--- a/modules/koreader/default.nix
+++ b/modules/koreader/default.nix
@@ -8,15 +8,42 @@ in {
package = mkPackageOption pkgs "kobo-koreader" {};
- _allFiles = mkOption {
+ _createdFiles = mkOption {
type = types.package;
+ internal = true;
readOnly = true;
+ default = pkgs.buildEnv {
+ name = "koreader-files-created";
+ paths = mapAttrsToList (_: v: v._package) cfg.file;
+ extraPrefix = cfg.devicePath;
+ };
+ };
+
+ finalPackage = mkOption {
+ type = types.package;
internal = true;
- default = pkgs.symlinkJoin {
- name = "koreader-files";
- paths = mapAttrsToList (_: v: v._package) cfg.file ++ [ cfg.package ];
+ readOnly = true;
+ default = pkgs.mergePaths {
+ name = "koreader-package";
+ paths = [
+ (pkgs.linkFarm "koreader" [{
+ name = removePrefix "/" cfg.devicePath;
+ path = cfg.package.out;
+ }])
+ cfg._createdFiles
+ cfg.package.KoboRoot
+ ];
};
};
+ # _allFiles = mkOption {
+ # type = types.package;
+ # readOnly = true;
+ # internal = true;
+ # default = pkgs.symlinkJoin {
+ # name = "koreader-files";
+ # paths = mapAttrsToList (_: v: v._package) cfg.file ++ [ cfg.package ];
+ # };
+ # };
path = mkOption {
type = types.str;
@@ -43,25 +70,24 @@ in {
};
};
- config = mkIf cfg.enable {
- koboroot.include = [
- (pkgs.linkFarm [{
- name = cfg.devicePath;
- path = cfg._allFiles;
- })
- cfg.package.KoboRoot
- ];
+ config = mkMerge [
+ {
+ info.koreader = cfg.enable;
+ }
+ (mkIf cfg.enable {
+ koboroot.include = singleton cfg.finalPackage;
- nickel.menu.item = mkIf cfg.nickel.enable {
- koreader = singleton {
- location = "main";
- label = "KOReader";
- action = "cmd_spawn";
- arg = [
- "quiet"
- "exec ${cfg.devicePath}/koreader.sh";
- ];
+ nickel.menu.item = mkIf cfg.nickel.enable {
+ koreader = singleton {
+ location = "main";
+ label = "KOReader";
+ action = "cmd_spawn";
+ arg = [
+ "quiet"
+ "exec ${cfg.devicePath}/koreader.sh"
+ ];
+ };
};
- };
- };
+ })
+ ];
}
diff --git a/modules/manifest.nix b/modules/manifest.nix
deleted file mode 100644
index 30a2060..0000000
--- a/modules/manifest.nix
+++ /dev/null
@@ -1,38 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-let
- cfg = config.manifest;
-in {
- options.manifest = mkOption {
- default = {};
- type = with types; attrsOf (submodule ({ name, config, ... }: {
- options = {
- enable = mkEnableOption name // { default = true; };
- targets = mkOption {
- type = with types; listOf str;
- default = [ name ];
- };
- mergeTool = mkOption {
- type = with types; functionTo (functionTo str);
- description = ''
- Sometimes we don't just want to overwrite the existing kobo file; instead we need to merge them.
- This is the executable which does this.
- The first argument is the local file and the second is the kobo file.
- Note that the local file path and the kobo file path only disagree in their top-level directory and otherwise are the same path.
- '';
- example = ''
- localFile: koboFile: "cp ''${localFile} ''${koboFile}"
- '';
- };
- remoteOnly = mkOption {
- type = types.bool;
- default = false;
- description = ''
- In general, the manifest only considers local files that match the target/pattern.
- Setting this to true means that the kobo files will be scanned and the provided mergeTool will be run with the first argument set to null.
- '';
- };
- };
- }));
- };
-}
diff --git a/modules/nickel.nix b/modules/nickel.nix
deleted file mode 100644
index cfba224..0000000
--- a/modules/nickel.nix
+++ /dev/null
@@ -1,148 +0,0 @@
-{ config, pkgs, lib, options, ... }:
-with builtins // lib;
-let
- cfg = config.nickel;
- importOption = p: (import p { inherit pkgs lib; } cfg.path).option;
- 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";
-
- path = mkOption {
- type = types.str;
- default = ".adds/nm";
- description = "Relative path to nickelMenu 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;
-
- 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 = mkIf cfg.enable {
- 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)
- ];
- };
-
- # file = mapAttrs' (n: v: {
- # name = "nm-${n}";
- # value = v // {
- # target = "${cfg.path}/${v.target}";
- # };
- # }) cfg.file;
- };
-}
diff --git a/modules/nickel/default.nix b/modules/nickel/default.nix
index 30b40d4..7663e93 100644
--- a/modules/nickel/default.nix
+++ b/modules/nickel/default.nix
@@ -53,13 +53,31 @@ in {
package = mkPackageOption pkgs "nickel-menu" {};
- _allFiles = mkOption {
+ _createdFiles = mkOption {
type = types.package;
readOnly = true;
internal = true;
- default = symlinkJoin {
- name = "nickel-files";
- paths = mapAttrsToList (v: v._package) cfg.file;
+ default = pkgs.buildEnv {
+ name = "nickel-files-created";
+ paths = mapAttrsToList (_: v: v._package) cfg.file;
+ extraPrefix = cfg.devicePath;
+ };
+ };
+
+ finalPackage = mkOption {
+ type = types.package;
+ readOnly = true;
+ internal = true;
+ default = pkgs.mergePaths {
+ name = "nickel-menu-package";
+ paths = [
+ (pkgs.linkFarm "nickel-menu" [{
+ name = removePrefix "/" cfg.devicePath;
+ path = cfg.package.out;
+ }])
+ cfg._createdFiles
+ cfg.package.KoboRoot
+ ];
};
};
@@ -68,7 +86,6 @@ in {
default = ".adds/nm";
readOnly = true;
internal = true;
- # description = "Relative path to nickelMenu within src";
};
devicePath = mkOption {
@@ -139,6 +156,8 @@ in {
config = mkMerge [
{
+ info.nickel = cfg.enable;
+
nickel = {
file = mkMerge [
(mapAttrs (_: v: {
@@ -156,10 +175,7 @@ in {
};
}
(mkIf cfg.enable {
- koboroot.include = singleton (pkgs.linkFarm [{
- name = cfg.devicePath;
- path = cfg._allFiles;
- }]);
+ koboroot.include = singleton cfg.finalPackage;
})
];
}
diff --git a/modules/plato.nix b/modules/plato.nix
deleted file mode 100644
index 0d0d05d..0000000
--- a/modules/plato.nix
+++ /dev/null
@@ -1,210 +0,0 @@
-{ 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 {
- 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"
- ];
- };
- };
-
- };
-}
diff --git a/modules/plato/default.nix b/modules/plato/default.nix
index ac0c5d7..74fe8c1 100644
--- a/modules/plato/default.nix
+++ b/modules/plato/default.nix
@@ -55,25 +55,36 @@ in {
};
};
- _finalPackage = mkOption {
+ finalPackage = mkOption {
type = types.package;
internal = true;
readOnly = true;
- default = pkgs.symlinkJoin {
+ default = pkgs.mergePaths {
name = "plato-package";
paths = [
+ (pkgs.linkFarm "plato" [{
+ name = removePrefix "/" cfg.devicePath;
+ path = cfg.package.out;
+ }])
cfg._createdFiles
- # (pkgs.linkFarm "plato-files" [{
- # name = removePrefix "/" cfg.devicePath;
- # path = cfg.package.out;
- # }])
- (pkgs.runCommandLocal "plato-files" {} ''
- mkdir -p "$(dirname "$out${cfg.devicePath}")"
- cp -r "${cfg.package.out}" "$out${cfg.devicePath}"
- '')
cfg.package.KoboRoot
];
};
+ # pkgs.symlinkJoin {
+ # name = "plato-package";
+ # paths = [
+ # cfg._createdFiles
+ # # (pkgs.linkFarm "plato-files" [{
+ # # name = removePrefix "/" cfg.devicePath;
+ # # path = cfg.package.out;
+ # # }])
+ # (pkgs.runCommandLocal "plato-files" {} ''
+ # mkdir -p "$(dirname "$out${cfg.devicePath}")"
+ # cp -r "${cfg.package.out}" "$out${cfg.devicePath}"
+ # '')
+ # cfg.package.KoboRoot
+ # ];
+ # };
};
_allFiles = mkOption {
@@ -173,6 +184,7 @@ in {
config = mkMerge [
{
+ info.plato = cfg.enable;
plato.file = {
"Settings.toml" = mkIf (cfg.settings != {}) {
source = toml.generate "Settings.toml" cfg.settings;
@@ -205,11 +217,8 @@ in {
};
}
(mkIf cfg.enable {
- koboroot.include = singleton cfg._finalPackage;
- # singleton (pkgs.linkFarm [{
- # name = cfg.devicePath;
- # path = cfg._allFiles;
- # }]);
+ koboroot.include = singleton cfg.finalPackage;
+
nickel.menu.item = mkIf cfg.nickel.enable {
plato = singleton {
diff --git a/modules/root.nix b/modules/root.nix
deleted file mode 100644
index d74fe66..0000000
--- a/modules/root.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-{ config, pkgs, lib, ... }:
-with builtins // lib;
-let
- importOption = p: (import p { inherit pkgs lib; } "").option;
-in {
- options = {
- file = importOption ./lib/file.nix;
- manifest = importOption ./lib/manifest.nix;
-
- src = mkOption {
- type = types.package;
- description = "The base source files to use";
- default = with pkgs.kobo.src;
- if config.plato.enable && config.koreader.enable then KOReader-Plato
- else if config.plato.enable then Plato
- else if config.koreader.enable then KOReader
- else if config.kfmon.enable then KFMon
- else pkgs.runCommandLocal "empty-kobo" {} "mkdir -p $out";
- };
- };
-}
diff --git a/overlays/default.nix b/overlays/default.nix
index 1dc4349..f38a538 100644
--- a/overlays/default.nix
+++ b/overlays/default.nix
@@ -6,6 +6,8 @@ final: prev: {
kobo-check-firmware = prev.callPackage ../pkgs/misc/firmware-check.nix {};
+ kobo-deploy = prev.callPackage ../pkgs/misc/deploy.nix {};
+
kobo-firmware = prev.callPackage ../pkgs/firmware {};
kobo-koreader = prev.callPackage ../pkgs/koreader {};
diff --git a/pkgs/firmware/default.nix b/pkgs/firmware/default.nix
index 8403abb..e33cf4a 100644
--- a/pkgs/firmware/default.nix
+++ b/pkgs/firmware/default.nix
@@ -1,4 +1,4 @@
-{ stdenvNoCC, fetchzip, lib, kobo-utils, gawk, ... }:
+{ stdenvNoCC, fetchzip, lib, rsync, kobo-utils, gawk, ... }:
{ hardware, date, version, hash ? "", ... }:
stdenvNoCC.mkDerivation (finalAttrs: {
pname = "kobo-firmware";
@@ -13,6 +13,7 @@ stdenvNoCC.mkDerivation (finalAttrs: {
nativeBuildInputs = [
kobo-utils
gawk
+ rsync
];
outputs = [
@@ -39,10 +40,9 @@ stdenvNoCC.mkDerivation (finalAttrs: {
installPhase = ''
runHook preInstall
- cp -r $src $out
- rm $out/KoboRoot.tgz
+ rsync -av --links --exclude="KoboRoot.tgz" $src/ $out
- mkdir $KoboROot
+ mkdir $KoboRoot
tar xvzf $src/KoboRoot.tgz --directory=$KoboRoot
runHook postInstall
diff --git a/pkgs/install.nix b/pkgs/install.nix
deleted file mode 100644
index e25108d..0000000
--- a/pkgs/install.nix
+++ /dev/null
@@ -1,110 +0,0 @@
-{ writeShellApplication
-, coreutils
-, gnugrep
-, rsync
-, util-linux
-, koboLabel ? "KOBOeReader"
-, ... }: writeShellApplication {
- name = "KoboInstaller";
- runtimeInputs = [
- coreutils
- gnugrep
- rsync
- util-linux
- ];
- text = ''
- INPUT=${1-}
-
- if [[ -z "$INPUT" ]]; then
- echo "Must provide an input directory"
- exit 255
- fi
-
- if [[ ! -d "$INPUT/.kobo" ]] || [[ ! -d "$INPUT/.adds" ]]; then
- echo "Missing one of $INPUT/.kobo or $INPUT/.adds. Are you sure your input directory is correct?"
- exit 255
- fi
-
- KOBO_MOUNTPOINT="$(findmnt -nlo TARGET LABEL="${koboLabel}")"
- if [[ -z "$KOBO_MOUNTPOINT" ]]; then
- echo "Couldn't find a Kobo eReader volume! Is one actually mounted?"
- exit 255
- fi
-
- KOBO_DIR="$KOBO_MOUNTPOINT/.kobo"
- if [[ ! -d "$KOBO_DIR" ]]; then
- echo "It doesn't seem like $KOBO_MOUNTPOINT actually points to a Kobo eReader since it doesn't contain a .kobo directory..."
- exit 255
- fi
-
- # Tiny DRY helper for the failure message...
- recap_failure() {
- echo "* As a result, the device may have been left in an inconsistent state!"
- echo "* Please note that NO automatic cleanup will be done!"
- echo "* As such, before unplugging your device, consider removing:"
- echo "* The following folders:"
- for kfm_folder in .adds/kfmon .adds/koreader .adds/plato ; do
- local current_folder="$KOBO_MOUNTPOINT/$kfm_folder"
- if [[ -d "$current_folder" ]] ; then
- printf "\t%s\n" "$current_folder"
- else
- printf "\t%-96s%32s\n" "$current_folder" "[OK: Already gone]"
- fi
- done
- echo "* As well as the following files:"
- for kfm_file in .kobo/KoboRoot.tgz kfmon.png koreader.png icons/plato.png ; do
- local current_file="$KOBO_MOUNTPOINT/$kfm_file"
- if [[ -f "$current_file" ]] ; then
- printf "\t%s\n" "$current_file"
- else
- printf "\t%-96s%32s\n" "$current_file" "[OK: Already gone]"
- fi
- done
- }
-
- KOBO_CONFIG="$KOBO_DIR/Kobo/Kobo eReader.conf"
- echo "* Preventing Nickel from scanning hidden directories . . ."
- cat >> "${KOBO_CONFIG}" <<-\EoM
-
- [FeatureSettings]
- ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+)
- EoM
-
- # Check for a cat failure, as unlikely as it might be (permissions?)...
- ret=$?
- if [[ $ret -ne 0 ]] ; then
- echo "* Installation FAILED: Failed to update Nickel config!"
- echo "* No permanent changes have been made."
- exit $ret
- fi
-
- # Double-check that it was updated, in case of gremlins attack...
- if ! grep -Fq 'ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+)' "${KOBO_CONFIG}" ; then
- echo "* Installation FAILED: Nickel config update was ineffective o_O !"
- echo "* No permanent changes have been made."
- exit 255
- fi
-
- echo "* Installing Kobo package"
- rsync -vr "$INPUT/" "$KOBO_MOUNTPOINT"
-
- ret=$?
- if [[ $ret -ne 0 ]]; then
- echo "* Installation FAILED: Failed to copy archive!"
- recap_failure
- exit $ret
- fi
-
- echo "* Sanity check . . ."
- if [[ ! "$KOBO_DIR/KoboRoot.tgz" ]]; then
- echo "* Installation FAILED: Copying was ineffective (no KoboRoot tarball) o_O !"
- recap_failure
- exit 255
- fi
-
- echo "* Installation successful!"
- echo "* Please make sure to eject & unplug your device safely!"
-
- exit 0
- '';
-}
diff --git a/pkgs/misc/create-koboroot.nix b/pkgs/misc/create-koboroot.nix
new file mode 100644
index 0000000..7cf1bff
--- /dev/null
+++ b/pkgs/misc/create-koboroot.nix
@@ -0,0 +1,5 @@
+{ runCommandLocal, ... }: p:
+runCommand "mk-koboroot" {} ''
+ mkdir -p $out
+ tar czvf --mode=u+w $out/KoboRoot.tgz "${p}"
+''
diff --git a/pkgs/misc/deploy.nix b/pkgs/misc/deploy.nix
new file mode 100644
index 0000000..23973e9
--- /dev/null
+++ b/pkgs/misc/deploy.nix
@@ -0,0 +1,65 @@
+{ stdenvNoCC, writeShellApplication, makeWrapper, rsync, kobo-utils, lib, ... }:
+src:
+let
+ deployScript = writeShellApplication {
+ name = "deploy";
+ runtimeInputs = [
+ rsync
+ kobo-utils
+ ];
+ text = ''
+ PAYLOAD="./payload"
+
+ if [[ ! -d "$PAYLOAD" ]]; then
+ >&2 echo "./payload is not a directory I can copy..."
+ exit 1
+ fi
+
+ KOBOMNT="$(kobo-find -f -w)"
+ KOBODIR="$KOBOMNT/.kobo"
+
+ if [[ -z "$KOBOMNT" ]]; then
+ >&2 echo "Cannot find mounted kobo"
+ exit 1
+ elif [[ ! -d "$KOBODIR" ]]; then
+ >&2 echo "$KOBODIR does not appear to exist. Is this really a kobo?"
+ exit 1
+ fi
+
+ echo "Deploying payload"
+
+ rsync -rv --executability --chmod=u+w "$PAYLOAD/" "$KOBODIR"
+ '';
+ };
+in stdenvNoCC.mkDerivation (finalAttrs: {
+ name = "deploy-kobo";
+
+ inherit src;
+
+ nativeBuildInputs = [
+ makeWrapper
+ ];
+
+ buildInputs = [
+ kobo-utils
+ rsync
+ ];
+
+ phases = "installPhase";
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p $out
+ cp -r $src $out/payload
+
+ mkdir -p $out/bin
+ makeWrapper "${lib.getExe deployScript}" $out/bin/deploy --chdir "$out"
+
+ runHook postInstall
+ '';
+
+ meta = {
+ mainProgram = "deploy";
+ };
+})
diff --git a/pkgs/misc/merge.nix b/pkgs/misc/merge.nix
index 9d6eabb..b4b4892 100644
--- a/pkgs/misc/merge.nix
+++ b/pkgs/misc/merge.nix
@@ -1,7 +1,7 @@
{ runCommand, writeShellApplication, rsync, lib, ... }:
args@{ name, paths, preferLocalBuild ? true, allowSubstitutes ? false, postBuild ? "" }:
let
- env = builtins.removeAttrs args [ "name" "postBuild" ]] // {
+ env = builtins.removeAttrs args [ "name" "postBuild" ] // {
inherit preferLocalBuild allowSubstitutes;
nativeBuildInputs = (args.nativeBuildInputs or []) ++ [
rsync
@@ -28,8 +28,7 @@ let
case "$REALPATH" in
"/nix/store/"* )
- echo "Replacing $FILE by $REALPATH"
- cp -v --remove-destination "$REALPATH" "$FILE"
+ cp -vf --remove-destination "$REALPATH" "$FILE"
;;
esac
'';
@@ -39,10 +38,11 @@ in runCommand name env ''
mkdir -p $out
for i in $(cat $pathsPath); do
- rsync -rv --copy-dirlinks --links --executability "$i/" "$out"
+ rsync -rv --copy-dirlinks --links --executability --chmod=u+w "$i/" "$out"
done
- find $out -type l -exec "replaceBadSymlink {}" \;
+ find $out/ -type l -exec replaceBadSymlink {} \;
+
${postBuild}
''
diff --git a/pkgs/plato.nix b/pkgs/plato.nix
deleted file mode 100644
index 815ac76..0000000
--- a/pkgs/plato.nix
+++ /dev/null
@@ -1,46 +0,0 @@
-{ stdenvNoCC
-, formats
-, runCommand
-, writeScript
-, lib
-
-, platoSrc
-, platoSettings ? {}
-, platoCfg ? ""
-, dictionaries ? []
-, fonts ? []
-, ... }:
-with builtins // lib;
-stdenvNoCC.mkDerivation (finalAttrs: {
- name = "plato";
-
- src = platoSrc;
-
- dontFix = true;
- dontPatch = true;
- dontConfigure = true;
- dontBuild = true;
-
- installPhase = ''
- mkdir -p $out
- cp -rv . $out
-
- # mkdir -p $out/.adds/plato/dictionaries
- for d in ${concatMapStringsSep " " toString dictionaries}; do
- find $d/share/dictd/ -type f -regex '.*\.\(dict\(\.dz\)?\|index\)' -exec cp -v {} $out/.adds/plato/dictionaries/ \;
- done
-
- for d in ${concatMapStringsSep " " toString fonts}; do
- find $d/share/fonts/truetype/ -type f -regex '.*\.\(ttf\|otf\)' -exec cp -v {} $out/.adds/plato/fonts/ \;
- done
-
- ${optionalString (platoSettings != {}) ''
- cp -v ${(formats.toml {}).generate "Settings.toml" platoSettings} $out/.adds/plato/Settings.toml
- ''}
- ${optionalString (platoCfg != "") ''
- cp -v ${writeScript "config.sh" platoCfg} $out/.adds/plato/config.sh
- ''}
- ''
- ;
-
-})
diff --git a/pkgs/source.nix b/pkgs/source.nix
deleted file mode 100644
index dcf40fe..0000000
--- a/pkgs/source.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-{ fetchzip, ... }:
-{
- KOReader = fetchzip {
- stripRoot = false;
- url = "https://storage.gra.cloud.ovh.net/v1/AUTH_2ac4bfee353948ec8ea7fd1710574097/kfmon-pub/OCP-KOReader-v2024.01.zip";
- };
- Plato = fetchzip {
- stripRoot = false;
- url = "https://storage.gra.cloud.ovh.net/v1/AUTH_2ac4bfee353948ec8ea7fd1710574097/kfmon-pub/OCP-Plato-0.9.40.zip";
- sha256 = "sha256-jOCC3p9Q/DNtSADgMgmCwPvoZ4XA4ka1zH7dfg8r/kg=";
- };
- KOReader-Plato = fetchzip {
- stripRoot = false;
- url = "https://storage.gra.cloud.ovh.net/v1/AUTH_2ac4bfee353948ec8ea7fd1710574097/kfmon-pub/OCP-Plato-0.9.40_KOReader-v2024.01.zip";
- sha256 = "sha256-A0ImPLQ+5/MLg5Iw3U3WnoKc2Cd/g6lSiSzAiBnrfZM=";
- };
- KFMon = fetchzip {
- stripRoot = false;
- url = "https://storage.gra.cloud.ovh.net/v1/AUTH_2ac4bfee353948ec8ea7fd1710574097/kfmon-pub/OCP-KFMon-1.4.6-43-g2c54087.zip";
- };
-}