diff options
| -rw-r--r-- | flake.nix | 7 | ||||
| -rw-r--r-- | modules/firmware/default.nix | 27 | ||||
| -rw-r--r-- | modules/kfmon/default.nix | 59 | ||||
| -rw-r--r-- | modules/koreader/default.nix | 57 | ||||
| -rw-r--r-- | modules/lib/file-type.nix | 42 | ||||
| -rw-r--r-- | modules/lib/merge-files.nix | 10 | ||||
| -rw-r--r-- | modules/nickel/default.nix | 153 | ||||
| -rw-r--r-- | modules/plato/default.nix | 362 | ||||
| -rw-r--r-- | overlays/default.nix | 16 | ||||
| -rw-r--r-- | pkgs/firmware/default.nix | 33 | ||||
| -rw-r--r-- | pkgs/kfmon/default.nix | 29 | ||||
| -rw-r--r-- | pkgs/kobo-patch/default.nix | 29 | ||||
| -rw-r--r-- | pkgs/kobo-utils/default.nix | 23 | ||||
| -rw-r--r-- | pkgs/koreader/default.nix | 27 | ||||
| -rw-r--r-- | pkgs/nickel-menu/default.nix | 26 | ||||
| -rw-r--r-- | pkgs/plato/default.nix | 27 |
16 files changed, 927 insertions, 0 deletions
@@ -24,6 +24,13 @@ in { packages = { + inherit (pkgs) + kfmon + kobo-koreader + kobo-utils + nickel-menu + plato + ; default = myKobo.config.build.src; # installer = myKobo.config.installer.package; }; diff --git a/modules/firmware/default.nix b/modules/firmware/default.nix new file mode 100644 index 0000000..609212a --- /dev/null +++ b/modules/firmware/default.nix @@ -0,0 +1,27 @@ +{ config, pkgs, lib, ... }: +with builtins // lib; +let + cfg = config.firmware; +in { + options.firmware = { + hardware = mkOption { + type = types.str; + }; + date = mkOption { + type = types.str; + }; + version = mkOption { + type = types.str; + }; + hash = mkOption { + type = types.str; + }; + + package = mkOption { + type = types.package; + default = pkgs.kobo-firmware { + inherit (cfg) hardware date version hash; + }; + }; + }; +} diff --git a/modules/kfmon/default.nix b/modules/kfmon/default.nix new file mode 100644 index 0000000..8557a3e --- /dev/null +++ b/modules/kfmon/default.nix @@ -0,0 +1,59 @@ +{ config, pkgs, lib, ... }: +with builtins // lib; +let + cfg = config.kfmon; + ini = pkgs.formats.ini {}; +in { + options.kfmon = { + enable = mkEnableOption "KFMon"; + + package = mkPackageOption pkgs "kfmon" {}; + + path = mkOption { + type = types.str; + readOnly = true; + internal = true; + default = ".adds/kfmon"; + }; + + devicePath = mkOption { + type = types.str; + readOnly = true; + internal = true; + default = "/mnt/onboard/${cfg.path}"; + }; + + file = mkOption { + default = {}; + type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {})); + }; + + _allFiles = mkOption { + type = types.package; + internal = true; + readOnly = true; + default = (pkgs.callPackage ../lib/merge-files.nix {}) (attrValues file); + }; + + configs = mkOption { + type = types.attrsOf ini.type; + default = {}; + description = '' + KFMon .ini config files. Do not touch this unless you know what you're doing! + ''; + }; + }; + + config = { + kfmon.file = mapAttrs' (n: v: { + name = "kfmon-config-${n}"; + value = { + text = generators.toINI {} v; + target = + let + fixedN = if isSuffix ".ini" n then n else "${n}.ini"; + in "config/${fixedN}"; + }; + }); + }; +}; diff --git a/modules/koreader/default.nix b/modules/koreader/default.nix new file mode 100644 index 0000000..db12219 --- /dev/null +++ b/modules/koreader/default.nix @@ -0,0 +1,57 @@ +{ config, pkgs, lib, ... }: +with builtins // lib; +let + cfg = config.koreader; +in { + options.koreader = { + enable = mkEnableOption "KOReader"; + + package = mkPackageOption pkgs "kobo-koreader" {}; + + _allFiles = mkOption { + type = types.package; + readOnly = true; + internal = true; + default = (pkgs.callPackage ../lib/merge-files.nix {}) ([ + cfg.package + ] ++ attrValues cfg.file); + }; + + path = mkOption { + type = types.str; + readOnly = true; + internal = true; + default = ".adds/koreader"; + }; + + devicePath = mkOption { + type = types.str; + readOnly = true; + internal = true; + default = "/mnt/onboard/${cfg.path}"; + }; + + file = mkOption { + default = {}; + type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {})); + }; + + nickel = { + enable = mkEnableOption "Add NickelMenu entry" // { default = true; }; + }; + }; + + config = { + nickel.menu.item = mkIf (cfg.enable && cfg.nickel.enable) { + koreader = singleton { + location = "main"; + label = "KOReader"; + action = "cmd_spawn"; + arg = [ + "quiet" + "exec ${cfg.devicePath}/koreader.sh"; + ]; + }; + }; + }; +} diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix new file mode 100644 index 0000000..c95c0d4 --- /dev/null +++ b/modules/lib/file-type.nix @@ -0,0 +1,42 @@ +{ writeTextFile, lib, ... }: +{ name, config, ... }: +with builtins // lib; +let + sanitize = p: + let + safeChars = [ "+" "." "_" "?" "=" ] ++ lowerChars ++ upperChars ++ stringToCharacters "0123456789"; + empties = l: genList (_: "") (length l); + unsafeInName = stringToCharacters (replaceStrings safeChars (empties safeChars) p; + in "kobo_" + replaceStrings unsafeInName (empties unsafeInName) p; +in { + options = { + enable = mkEnableOption name // { default = true; }; + name = mkOption { + type = types.str; + }; + target = mkOption { + type = types.str; + default = name; + apply = x: if isPrefix "/" x then x else "/${x}"; + }; + executable = mkOption { + type = with types; nullOr bool; + default = null; + }; + text = mkOption { + type = with types; nullOr lines; + default = null; + }; + source = mkOption { + type = types.path; + }; + }; + + config = { + source = mkIf (cfg.text != null) (mkDefault (writeTextFile { + inherit (config) text; + name = sanitieze name; + executable = config.executable == true; + })); + }; +} diff --git a/modules/lib/merge-files.nix b/modules/lib/merge-files.nix new file mode 100644 index 0000000..c024e0c --- /dev/null +++ b/modules/lib/merge-files.nix @@ -0,0 +1,10 @@ +{ runCommandLocal, rsync, lib, ... }: +files: +let + cpFile = s: '' + ${lib.getExe rsync} -aL "${s.source}/" "$out${s.target}" + ''; +in runCommandLocal "merged-files" {} '' + mkdir $out + ${lib.concatMapStringsSep "\n" cpFile files} +'' diff --git a/modules/nickel/default.nix b/modules/nickel/default.nix new file mode 100644 index 0000000..c5736f0 --- /dev/null +++ b/modules/nickel/default.nix @@ -0,0 +1,153 @@ +{ config, pkgs, lib, options, ... }: +with builtins // lib; +let + cfg = config.nickel; + action = mkOption { + type = types.enum [ + "cmd_spawn" + "cmd_output" + "dbg_syslog" + "dbg_error" + "dbg_msg" + "dbg_toast" + "kfmon" + "nickel_setting" + "nickel_extras" + "nickel_browser" + "nickel_misc" + "nickel_open" + "nickel_wifi" + "nickel_orientation" + "power" + "skip" + ]; + }; + location = mkOption { + type = types.enum [ + "main" + "reader" + "browser" + "library" + "selection" + ]; + }; + + createChainItem = { when, action, arg, ... }: concatStringsSep " : " ([ "chain_${when}" action ] ++ arg); + createMenuItem = { location, label, action, arg, chain, ... }: concatStringsSep "\n" ( + singleton ( + concatStringsSep " : " ([ "menu_item" location label action ] ++ arg) + ) ++ (map createChainItem chain) + ); + + createExperimental = k: v: "experimental : ${k} : ${v}"; + + createGenerator = { location, generator }: concatStringsSep " : " ( + [ "generator" ] ++ + (if isInt generator then [ "_test" (toString generator) ] + else splitString " " generator) + ); + +in { + options.nickel = { + enable = mkEnableOption "nickelMenu"; + + package = mkPackageOption pkgs "nickel-menu" {}; + + _allFiles = mkOption { + type = types.package; + readOnly = true; + internal = true; + default = (pkgs.callPackage ../lib/merge-files.nix {}) (atrValues cfg.file); + }; + + path = mkOption { + type = types.str; + default = ".adds/nm"; + readOnly = true; + internal = true; + # description = "Relative path to nickelMenu within src"; + }; + + devicePath = mkOption { + type = types.str; + default = "/mnt/onboard/${cfg.path}"; + readOnly = true; + internal = true; + }; + + file = mkOption { + default = {}; + type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {}); + }; + + menu = { + item = mkOption { + default = {}; + description = "https://github.com/pgaskin/NickelMenu/blob/v0.5.4/res/doc"; + type = with types; attrsOf (listOf (submodule { + options = { + inherit action location; + label = mkOption { + type = types.str; + }; + arg = mkOption { + type = with types; nonEmptyListOf str; + }; + chain = mkOption { + default = []; + type = with types; listOf (submodule { + options = { + when = mkOption { + type = types.enum [ "success" "failure" "always" ]; + }; + inherit action; + arg = mkOption { + type = with types; nonEmptyListOf str; + }; + }; + }); + }; + }; + })); + }; + + experimental = mkOption { + default = {}; + description = "https://github.com/pgaskin/NickelMenu/blob/v0.5.4/res/doc"; + type = with types; attrsOf (attrsOf str); + }; + + generator = mkOption { + default = {}; + description = "https://github.com/pgaskin/NickelMenu/blob/v0.5.4/res/doc"; + type = with types; attrsOf (listOf (submodule { + options = { + inherit location; + generator = mkOption { + type = with types; either (enum [ "kfmon" "kfmon all" "kfmon gui" ]) (ints.between 0 10); + default = "kfmon"; + }; + }; + })); + }; + }; + }; + + config = { + nickel = { + file = mkMerge [ + (mapAttrs (_: v: { + text = concatMapStringsSep "\n" createGenerator v; + }) cfg.menu.generator) + + (mapAttrs (_: v: { + text = concatStringsSep "\n" (mapAttrsToList createExperimental v); + }) cfg.menu.experimental) + + (mapAttrs (_: v: { + text = concatMapStringsSep "\n" createMenuItem v; + }) cfg.menu.item) + ]; + }; + }; +} diff --git a/modules/plato/default.nix b/modules/plato/default.nix new file mode 100644 index 0000000..1886662 --- /dev/null +++ b/modules/plato/default.nix @@ -0,0 +1,362 @@ +{ config, pkgs, lib, options, ... }: +with builtins // lib; +let + cfg = config.plato; + toml = pkgs.formats.toml {}; + # importOption = p: (import p { inherit pkgs lib; } cfg.path).option; +in { + options.plato = { + enable = mkEnableOption "Plato"; + + package = mkPackageOption pkgs "plato" {}; + + path = mkOption { + type = types.str; + readOnly = true; + internal = true; + default = ".adds/plato"; + }; + + devicePath = mkOption { + type = types.str; + readOnly = true; + internal = true; + default = "/mnt/onboard/${cfg.path}"; + }; + + _allFiles = mkOption { + type = types.package; + readOnly = true; + internal = true; + default = (pkgs.callPackage ../lib/merge-files.nix {}) ([ + cfg.package + ] ++ attrValues cfg.file); + }; + + file = mkOption { + default = {}; + type = types.attrsOf (types.submodule (pkgs.callPackage ../lib/file-type.nix {})); + }; + + nickel = { + enable = mkEnableOption "Add NickelMenu option" // { default = true; }; + }; + + + settings = mkOption { + type = toml.type; + default = {}; + description = '' + Contents of Settings.toml + ''; + }; + + config = { + hyphenation = mkEnableOption "hyphenation" // { default = true; }; + convertDictionaries = mkEnableOption "convert StartDict" // { default = true; }; + setFramebufferDepth = mkEnableOption "set framebuffer's depth" // { default = true; }; + extra = mkOption { + type = types.lines; + default = ""; + }; + }; + # mkOption { + # type = types.lines; + # default = ""; + # description = '' + # Contents of config.sh + # ''; + # }; + + dictionaries = mkOption { + type = with types; listOf package; + default = []; + }; + + _dictionariesCombined = mkOption { + type = types.package; + readOnly = true; + internal = true; + default = + let + copyDicts = pkg: '' + find ${pkg}/share/dictd/ -type f -regex '.*\.\(dict\(\.dz\)?\|index\)' -exec cp -v {} $out/ \; + ''; + in pkgs.runCommandLocal "plato-dictionaries" {} '' + mkdir $out + ${concatMapStringsSep "\n" copyDicts cfg.dictionaries} + ''; + }; + + fonts = mkOption { + type = with types; listOf package; + default = []; + }; + + _fontsCombined = mkOption { + type = types.package; + readOnly = true; + internal = true; + default = + let + copyFonts = pkg: '' + find ${pkg}/share/fonts/truetype/ -type f -regex '.*\.\(ttf\|otf\)' -exec cp -v {} $out/ \; + ''; + in pkgs.runCommandLocal {} '' + mkdir $out + ${concatMapStringsSep "\n" copyFonts cfg.fonts} + ''; + }; + }; + + config = mkMerge [ + { + plato.file = { + "Settings.toml" = mkIf (cfg.settings != {}) { + source = toml.generate "Settings.toml" cfg.settings; + }; + + "config.sh" = + let + c = optional (!cfg.config.convertDictionaries) "unset PLATO_CONVERT_DICTIONARIES" + ++ optional (!cfg.config.setFramebufferDepth) "unset PLATO_SET_FRAMEBUFFER_DEPTH" + ++ optional (!cfg.config.hyphenation) "[ -d hyphenation-patters ] && rm -rf hyphenation-patterns" + ++ optional (cfg.config.extra != "") cfg.config.extra + ; + in mkIf (c != []) { + text = concatStringsSep "\n\n" c; + }; + + "_dictionaries" = { + target = "dictionaries"; + source = cfg._dictionariesCombined; + }; + + "_fonts" = { + target = "fonts"; + source = cfg._fontsCombined; + }; + }; + + nickel.menu.item = mkIf (cfg.enable && cfg.nickel.enable) { + plato = singleton { + location = "main"; + label = "Plato"; + action = "cmd_spawn"; + arg = [ + "quiet" + "exec ${cfg.devicePath}/plato.sh" + ]; + }; + }; + } + # (mkIf (cfg.enable && cfg.nickelEntry.enable { + # nickel.menu.item = + # }) + ]; +} + + +# imports = [ +# ./nickel.nix +# ]; + +# options.plato = { +# enable = mkEnableOption "Plato"; + +# path = mkOption { +# type = types.str; +# default = ".adds/plato"; +# description = "Relative path to Plato within src"; +# }; + +# devPath = mkOption { +# type = types.str; +# default = "/mnt/onboard/${cfg.path}"; +# readOnly = true; +# internal = true; +# }; + +# file = importOption ./lib/file.nix; +# manifest = importOption ./lib/manifest.nix; + +# # file = mkOption { +# # type = options.file.type; +# # default = {}; +# # description = "Files relative to ${cfg.path}"; +# # }; + +# # manifest = mkOption { +# # type = options.manifest.type; +# # default = {}; +# # description = "Manifest relative to ${cfg.path}"; +# # }; + +# nickelEntry = mkEnableOption "Launch Plato directly from nickelMenu"; + +# config = mkOption { +# type = types.lines; +# default = ""; +# description = "Plato config.sh"; +# }; + +# hyphenation = mkEnableOption "hyphenation" // { default = true; }; + +# convertDictionaries = mkEnableOption "convert StarDict" // { default = true; }; + +# setFramebufferDepth = mkEnableOption "set framebuffer's depth" // { default = true; }; + +# settings = mkOption { +# type = toml.type; +# default = {}; +# description = "Plato Settings.toml"; +# }; + +# css = mkOption { +# default = {}; +# type = with types; attrsOf lines; +# description = '' +# css style sheets. +# Only use this for epub-user dictionary-user html-user +# ''; +# }; + +# scripts = mkOption { +# default = {}; +# type = with types; attrsOf lines; +# description = '' +# Only use this for wifi-post-up wifi-post-down wifi-pre-up wifi-pre-down. +# ''; +# # apply = mapAttrs (_: text: '' +# # #!/bin/sh + +# # ${text} +# # '') +# }; + +# dictionaries = mkOption { +# type = with types; listOf package; +# default = []; +# }; + +# allDictionaries = mkOption { +# type = types.package; +# readOnly = true; +# internal = true; +# default = pkgs.runCommand "PlatoDictionaries" {} ('' +# mkdir -p $out +# '' + concatMapStringsSep "\n" (pkg: '' +# find ${pkg}/share/dictd/ -type f -regex '.*\.\(dict\(\.dz\)?\|index\)' -exec cp -v {} $out/ \; +# '') cfg.dictionaries +# ); + +# }; + +# fonts = mkOption { +# type = with types; listOf package; +# default = []; +# }; + +# allFonts = mkOption { +# type = types.package; +# readOnly = true; +# internal = true; +# default = pkgs.runCommand "PlatoFonts" {} ('' +# mkdir -p $out +# '' + concatMapStringsSep "\n" (pkg: '' +# find ${pkg}/share/fonts/truetype/ -type f -regex '.*\.\(ttf\|otf\)' -exec cp -v {} $out/ \; +# '') cfg.fonts +# ); + +# }; +# }; + +# config = mkIf cfg.enable { +# plato = { +# config = concatStringsSep "\n\n" ( +# optional (!cfg.convertDictionaries) '' +# unset PLATO_CONVERT_DICTIONARIES +# '' +# ++ +# optional (!cfg.setFramebufferDepth) '' +# unset PLATO_SET_FRAMEBUFFER_DEPTH +# '' +# ++ +# optional (!cfg.hyphenation) '' +# [ -d hyphenation-patterns ] && rm -rf hyphenation-patterns +# '' +# ); +# file = mkMerge [ +# (mkIf (cfg.settings != {}) { +# "Settings.toml".source = toml.generate "Settings.toml" cfg.settings; +# }) + +# (mkIf (cfg.config != "") { +# "config.sh".text = cfg.config; +# }) + +# (mapAttrs' (n: text: +# let +# n1 = if hasPrefix "css/" n then n else "css/${n}"; +# name = if hasSuffix ".css" n1 then n1 else "{n1}.css"; +# in { +# inherit name; +# value = { inherit text; }; +# }) cfg.css) + +# (mapAttrs' (n: t: +# let +# n1 = if hasPrefix "scripts/" n then n else "scripts/${n}"; +# name = if hasSuffix ".sh" n1 then n1 else "${n1}.sh"; +# text = if hasPrefix "#!/" t then t else "#!/bin/sh\n\n${t}"; +# in { +# inherit name; +# value = { inherit text; }; +# }) cfg.scripts) + +# { +# dictionaries = { +# # directory = true; +# source = cfg.allDictionaries; +# }; +# fonts = { +# # directory = true; +# source = cfg.allFonts; +# }; +# } +# ]; + +# manifest = { +# "config-sample.sh".mergeTool = _: _: "echo 'not copying config-sample.sh'"; +# "Settings-sample.toml".mergeTool = _: _: "echo 'not copying Settings-sample.toml'"; +# }; +# }; + +# # file = mapAttrs' (n: v: { +# # name = "plato-${n}"; +# # value = v // { +# # target = "${cfg.path}/${v.target}"; +# # }; +# # }) cfg.file; + +# # manifest = mapAttrs' (n: v: { +# # name = "plato-${n}"; +# # value = v // { +# # targets = map (x: "${cfg.path}/${x}") v.targets; +# # }; +# # }) cfg.manifest; + +# nickel.menu.item = mkIf cfg.nickelEntry { +# plato = singleton { +# location = "main"; +# label = "Plato"; +# action = "cmd_spawn"; +# arg = [ +# "quiet" +# "exec ${cfg.devPath}/plato.sh" +# ]; +# }; +# }; + +# }; +# } diff --git a/overlays/default.nix b/overlays/default.nix index 561e8c2..8f47998 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,4 +1,20 @@ final: prev: { + + kfmon = prev.callPackage ../pkgs/kfmon {}; + + kobo-firmware = prev.callPackage ../pkgs/firmware {}; + + kobo-koreader = prev.callPackage ../pkgs/koreader {}; + + kobo-patch = prev.callPackage ../pkgs/kobo-patch {}; + + kobo-utils = prev.callPackage ../pkgs/kobo-utils {}; + + + nickel-menu = prev.callPackage ../pkgs/nickel-menu {}; + + plato = prev.callPackage ../pkgs/plato {}; + kobo = { src = prev.callPackage ../pkgs/source.nix {}; diff --git a/pkgs/firmware/default.nix b/pkgs/firmware/default.nix new file mode 100644 index 0000000..813746a --- /dev/null +++ b/pkgs/firmware/default.nix @@ -0,0 +1,33 @@ +{ stdenvNoCC, fetchzip, lib, ... }: +{ hardware, date, version, hash ? "", sha256 ? "", ... }: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "kobo-firmware"; + inherit version hardware date; + + src = fetchzip { + url = "https://ereaderfiles.kobo.com/firmwares/${finalAttrs.hardware}/${finalAttrs.date}/kobo-update-${finalAttrs.version}.zip"; + inherit hash sha256; + }; + + phases = "installPhase"; + + installPhase = '' + runHook preInstall + + cp -r $src $out + + runHook postInstall + ''; + + passthru = { + inherit hardware date; + }; + + meta = with lib; { + homepage = "https://pgaskin.net/KoboStuff/kobofirmware.html"; + description = '' + Kobo firmware files. + ''; + platform = platforms.all; + }; +}) diff --git a/pkgs/kfmon/default.nix b/pkgs/kfmon/default.nix new file mode 100644 index 0000000..6cb9c23 --- /dev/null +++ b/pkgs/kfmon/default.nix @@ -0,0 +1,29 @@ +{ stdenvNoCC, fetchzip, lib, ... }: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "kfmon"; + version = "1.4.6-89-g8daae26"; + + src = fetchzip { + url = "https://storage.gra.cloud.ovh.net/v1/AUTH_2ac4bfee353948ec8ea7fd1710574097/kfmon-pub/OCP-KFMon-${finalAttrs.version}.zip"; + stripRoot = false; + hash = "sha256-yaFRNdnlzelLsdGdmBjeH1hx8anYFx6zpcaRpRzqDlY="; + }; + + phases = "installPhase"; + + installPhase = '' + runHook preInstall + + cp -ra $src $out + + chmod +x $out/.adds/kfmon/bin/* + + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://github.com/NiLuJe/kfmon"; + platform = platforms.all; + license = licenses.gpl3Plus; + }; +}) diff --git a/pkgs/kobo-patch/default.nix b/pkgs/kobo-patch/default.nix new file mode 100644 index 0000000..dc80f00 --- /dev/null +++ b/pkgs/kobo-patch/default.nix @@ -0,0 +1,29 @@ +{ stdenvNoCC, fetchzip, lib, ... }: +{ version, hash ? "", sha256 ? "", ... }: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "kobo-patch"; + inherit version; + + kobopatchVersion = "84"; + + src = fetchzip { + url = "https://github.com/pgaskin/kobopatch-patches/releases/download/v${finalAttrs.kobopatchVersion}/kobopatch_${finalAttrs.version}.zip"; + inherit hash sha256; + }; + + phases = "installPhase"; + + installPhase = '' + runHook preInstall + + cp -r $src $out + + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://github.com/pgaskin/kobopatch-patches"; + platform = platforms.all; + }; + +}) diff --git a/pkgs/kobo-utils/default.nix b/pkgs/kobo-utils/default.nix new file mode 100644 index 0000000..9e00064 --- /dev/null +++ b/pkgs/kobo-utils/default.nix @@ -0,0 +1,23 @@ +{ buildGoModule, fetchFromGitHub, lib, util-linux, ... }: +buildGoModule rec { + pname = "kobo-utils"; + version = "2.2.0"; + + src = fetchFromGitHub { + owner = "pgaskin"; + repo = "koboutils"; + rev = "v${version}"; + sha256 = "sha256-8w3kHj4wB2tEoZMRT5yE5sbXgnCr6dMhFN7BrJ48ouw="; + }; + + vendorHash = "sha256-0ju5ovqUXaCjv0tLSa+hDJPtaf0fdUQd5O0U5XN9AX8="; + + buildInputs = [ + util-linux + ]; + + meta = with lib; { + homepage = "https://github.com/pgaskin/koboutils"; + license = licenses.mit; + }; +} diff --git a/pkgs/koreader/default.nix b/pkgs/koreader/default.nix new file mode 100644 index 0000000..fb81d71 --- /dev/null +++ b/pkgs/koreader/default.nix @@ -0,0 +1,27 @@ +{ stdenvNoCC, fetchzip, lib, ... }: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "koreader"; + version = "2024.07"; + + src = fetchzip { + url = "https://github.com/koreader/koreader/releases/download/v${finalAttrs.version}/koreader-kobo-v${finalAttrs.version}.zip"; + stripRoot = false; + hash = "sha256-9Ga42XSCC5FUQmlAygPhhXlFs0TIdxAf3/sWBmZ5URU="; + }; + + phases = "installPhase"; + + installPhase = '' + runHook preInstall + + cp -ra $src/koreader $out + + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://github.com/koreader/koreader"; + platform = platforms.all; + license = licenses.agpl3Plus; + }; +}) diff --git a/pkgs/nickel-menu/default.nix b/pkgs/nickel-menu/default.nix new file mode 100644 index 0000000..c151aaf --- /dev/null +++ b/pkgs/nickel-menu/default.nix @@ -0,0 +1,26 @@ +{ stdenvNoCC, fetchzip, lib, ... }: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "NickelMenu"; + version = "0.5.4"; + + src = fetchzip { + url = "https://github.com/pgaskin/NickelMenu/releases/download/v${finalAttrs.version}/KoboRoot.tgz"; + stripRoot = false; + hash = "sha256-BJC7zuvEHzI9zP9GR0K6psxumXcz5cDYhyCPxCsr8J0="; + }; + + phases = "installPhase"; + + installPhase = '' + runHook preInstall + + cp -ra $src $out + + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://github.com/pgaskin/NickelMenu"; + platform = platforms.all; + }; +}) diff --git a/pkgs/plato/default.nix b/pkgs/plato/default.nix new file mode 100644 index 0000000..797044c --- /dev/null +++ b/pkgs/plato/default.nix @@ -0,0 +1,27 @@ +{ stdenvNoCC, fetchzip, lib, ... }: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "plato"; + version = "0.9.43"; + + src = fetchzip { + url = "https://github.com/baskerville/plato/releases/download/${finalAttrs.version}/plato-${finalAttrs.version}.zip"; + stripRoot = false; + hash = "sha256-1E9trfAF3w0+ix8JVDJwYjWQ/dfsLjLPmkCLJAYXkZU="; + }; + + phases = "installPhase"; + + installPhase = '' + runHook preInstall + + cp -r $src $out + + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://github.com/baskerville/plato"; + platform = platforms.all; + license = licenses.agpl3Plus; + }; +}) |
