diff options
| author | Chris Wells <chris@mathematicaster.org> | 2024-09-10 14:51:28 -0500 |
|---|---|---|
| committer | Chris Wells <chris@mathematicaster.org> | 2024-09-10 14:51:28 -0500 |
| commit | 4f471484b3a1e16230979a8406503a220b9101f4 (patch) | |
| tree | dc3f5256f275f34d3bcc9573462ed34c7fd97f77 | |
| parent | 5cb16c34a8c5b803ec723934c1dc828c0e8e3bad (diff) | |
| download | kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.tar kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.tar.gz kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.tar.bz2 kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.tar.lz kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.tar.xz kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.tar.zst kobo-manager-4f471484b3a1e16230979a8406503a220b9101f4.zip | |
I think this is almost working!
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 Binary files differdeleted file mode 100644 index c26ab78..0000000 --- a/config/screensaver.png +++ /dev/null @@ -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"; - }; -} |
