kodi: add module
Kodi is a media center software.
This commit is contained in:
parent
93b52ce0bd
commit
cbc176010b
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
@ -114,6 +114,9 @@
|
|||
|
||||
/modules/programs/keychain.nix @marsam
|
||||
|
||||
/modules/programs/kodi.nix @dwagenk
|
||||
/tests/modules/programs/kodi @dwagenk
|
||||
|
||||
/modules/programs/lazygit.nix @kalhauge
|
||||
|
||||
/modules/programs/less.nix @pamplemousse
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
github = "CarlosLoboxyz";
|
||||
githubId = 86011416;
|
||||
};
|
||||
dwagenk = {
|
||||
email = "dwagenk@mailbox.org";
|
||||
github = "dwagenk";
|
||||
githubId = 32838899;
|
||||
name = "Daniel Wagenknecht";
|
||||
};
|
||||
justinlovinger = {
|
||||
name = "Justin Lovinger";
|
||||
email = "git@justinlovinger.com";
|
||||
|
|
|
@ -2387,6 +2387,14 @@ in
|
|||
A new module is available: 'programs.pandoc'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2022-01-26T22:08:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'programs.kodi'.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ let
|
|||
./programs/kakoune.nix
|
||||
./programs/keychain.nix
|
||||
./programs/kitty.nix
|
||||
./programs/kodi.nix
|
||||
./programs/lazygit.nix
|
||||
./programs/less.nix
|
||||
./programs/lesspipe.nix
|
||||
|
|
255
modules/programs/kodi.nix
Normal file
255
modules/programs/kodi.nix
Normal file
|
@ -0,0 +1,255 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.kodi;
|
||||
|
||||
stylesheetCommonHeader = ''
|
||||
<?xml version="1.0"?>
|
||||
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
||||
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
|
||||
<xsl:strip-space elements="*"/>
|
||||
'';
|
||||
|
||||
stylesheetCommonFooter = "</xsl:stylesheet>";
|
||||
|
||||
stylesheetNestedTags = ''
|
||||
<xsl:template match="attr[attrs]">
|
||||
<xsl:variable name="elementName" select="@name"/>
|
||||
<xsl:element name="{$elementName}">
|
||||
<xsl:apply-templates select="attrs" />
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
<xsl:template match="attr[list[attrs]]">
|
||||
<xsl:variable name="elementName" select="@name"/>
|
||||
<xsl:for-each select="list/attrs">
|
||||
<xsl:element name="{$elementName}">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:element>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
<xsl:template match="attr[not(attrs|list)]">
|
||||
<xsl:variable name="elementName" select="@name"/>
|
||||
<xsl:element name="{$elementName}">
|
||||
<xsl:if test="$elementName='path'">
|
||||
<!-- needed in sources.xml but will be used for all "path" tags -->
|
||||
<xsl:attribute name="pathversion">1</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="*/@value" />
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
'';
|
||||
|
||||
stylesheetTagsAsSettingWithId = ''
|
||||
<xsl:template match='attr'>
|
||||
<setting>
|
||||
<xsl:attribute name="id">
|
||||
<xsl:value-of select="@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="*/@value" />
|
||||
</setting>
|
||||
</xsl:template>
|
||||
'';
|
||||
|
||||
stylesheetAdvancedSettingsRootTag = ''
|
||||
<xsl:template match='/'>
|
||||
<xsl:comment> Generated by Home Manager. </xsl:comment>
|
||||
<advancedsettings version="1.0">
|
||||
<xsl:apply-templates/>
|
||||
</advancedsettings>
|
||||
</xsl:template>
|
||||
'';
|
||||
|
||||
stylesheetSourcesRootTag = ''
|
||||
<xsl:template match='/'>
|
||||
<xsl:comment> Generated by Home Manager. </xsl:comment>
|
||||
<sources>
|
||||
<xsl:apply-templates/>
|
||||
</sources>
|
||||
</xsl:template>
|
||||
'';
|
||||
|
||||
stylesheetAddonSettingsRootTag = ''
|
||||
<xsl:template match='/'>
|
||||
<xsl:comment> Generated by Home Manager. </xsl:comment>
|
||||
<settings version="2">
|
||||
<xsl:apply-templates/>
|
||||
</settings>
|
||||
</xsl:template>
|
||||
'';
|
||||
|
||||
attrsetToXml = attrs: name: stylesheet:
|
||||
pkgs.runCommand name {
|
||||
# Package splicing for libxslt does not work correctly leading to errors
|
||||
# when cross-compiling. Use the version from buildPackages explicitely to
|
||||
# fix this.
|
||||
nativeBuildInputs = [ pkgs.buildPackages.libxslt.bin ];
|
||||
xml = builtins.toXML attrs;
|
||||
passAsFile = [ "xml" ];
|
||||
} ''
|
||||
xsltproc ${stylesheet} - < "$xmlPath" > "$out"
|
||||
'';
|
||||
|
||||
attrsetToAdvancedSettingsXml = attrs: name:
|
||||
let
|
||||
stylesheet = builtins.toFile "stylesheet.xsl" ''
|
||||
${stylesheetCommonHeader}
|
||||
${stylesheetAdvancedSettingsRootTag}
|
||||
${stylesheetNestedTags}
|
||||
${stylesheetCommonFooter}
|
||||
'';
|
||||
in attrsetToXml attrs name stylesheet;
|
||||
|
||||
attrsetToSourcesXml = attrs: name:
|
||||
let
|
||||
stylesheet = builtins.toFile "stylesheet.xsl" ''
|
||||
${stylesheetCommonHeader}
|
||||
${stylesheetSourcesRootTag}
|
||||
${stylesheetNestedTags}
|
||||
${stylesheetCommonFooter}
|
||||
'';
|
||||
in attrsetToXml attrs name stylesheet;
|
||||
|
||||
attrsetToAddonSettingsXml = attrs: name:
|
||||
let
|
||||
stylesheet = builtins.toFile "stylesheet.xsl" ''
|
||||
${stylesheetCommonHeader}
|
||||
${stylesheetAddonSettingsRootTag}
|
||||
${stylesheetTagsAsSettingWithId}
|
||||
${stylesheetCommonFooter}
|
||||
'';
|
||||
in attrsetToXml attrs name stylesheet;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ hm.maintainers.dwagenk ];
|
||||
|
||||
options.programs.kodi = {
|
||||
enable = mkEnableOption "Kodi";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.kodi;
|
||||
defaultText = literalExpression "pkgs.kodi";
|
||||
example = literalExpression ''
|
||||
{ pkgs.kodi.withPackages (exts: [ exts.pvr-iptvsimple ]) }
|
||||
'';
|
||||
description = ''
|
||||
The <literal>kodi</literal> package to use.
|
||||
Can be used to specify extensions.
|
||||
'';
|
||||
};
|
||||
|
||||
datadir = mkOption {
|
||||
type = types.path;
|
||||
default = "${config.home.homeDirectory}/.kodi";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/.kodi"'';
|
||||
example = literalExpression ''"''${config.xdg.dataHome}/kodi"'';
|
||||
description = "Directory to store configuration and metadata.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types;
|
||||
let
|
||||
valueType = either str (attrsOf valueType) // {
|
||||
description = "attribute sets of strings";
|
||||
};
|
||||
in nullOr valueType;
|
||||
default = null;
|
||||
example = literalExpression ''
|
||||
{ videolibrary.showemptytvshows = "true"; }
|
||||
'';
|
||||
description = ''
|
||||
Configuration to write to the <literal>advancedsettings.xml</literal>
|
||||
file in kodis userdata directory. Settings specified here will be
|
||||
immutable from inside kodi and be hidden from the GUI settings dialog.
|
||||
</para><para>
|
||||
See <link xlink:href="https://kodi.wiki/view/Advancedsettings.xml"/> as
|
||||
reference for how settings need to be specified.
|
||||
</para><para>
|
||||
The innermost attributes must be of type str.
|
||||
'';
|
||||
};
|
||||
|
||||
sources = mkOption {
|
||||
type = with types;
|
||||
let
|
||||
valueType = oneOf [ str (attrsOf valueType) (listOf valueType) ] // {
|
||||
description = "attribute sets or lists of strings";
|
||||
};
|
||||
in nullOr valueType;
|
||||
default = null;
|
||||
example = literalExpression ''
|
||||
{
|
||||
video = {
|
||||
default = "movies";
|
||||
source = [
|
||||
{ name = "videos"; path = "/path/to/videos"; allowsharing = "true"; }
|
||||
{ name = "movies"; path = "/path/to/movies"; allowsharing = "true"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Contents to populate the file <literal>sources.xml</literal> in kodis
|
||||
userdata directory.
|
||||
</para><para>
|
||||
See <link xlink:href="https://kodi.wiki/view/Sources.xml"/> as
|
||||
reference for how sources need to be specified.
|
||||
</para><para>
|
||||
Kodi will still show the dialogs to modify sources in the GUI and they
|
||||
appear to be mutable. This however is not the case and the sources will
|
||||
stay as specified via Home Manager.
|
||||
</para><para>
|
||||
The innermost attributes must be of type str.
|
||||
'';
|
||||
};
|
||||
|
||||
addonSettings = mkOption {
|
||||
type = with types; nullOr (attrsOf (attrsOf str));
|
||||
default = null;
|
||||
example = literalExpression ''
|
||||
{ "service.xbmc.versioncheck".versioncheck_enable = "false"; }
|
||||
'';
|
||||
description = ''
|
||||
Attribute set with the plugin namespace as toplevel key and the plugins
|
||||
settings as lower level key/value pairs.
|
||||
</para><para>
|
||||
Kodi will still show the settings of plugins configured via this
|
||||
mechanism in the GUI and they appear to be mutable. This however is
|
||||
not the case and the settings will stay as specified via Home Manager.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.kodi" pkgs
|
||||
lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
home.sessionVariables = { KODI_DATA = cfg.datadir; };
|
||||
}
|
||||
|
||||
(mkIf (cfg.settings != null) {
|
||||
home.file."${cfg.datadir}/userdata/advancedsettings.xml".source =
|
||||
attrsetToAdvancedSettingsXml cfg.settings "kodi-advancedsettings.xml";
|
||||
})
|
||||
|
||||
(mkIf (cfg.sources != null) {
|
||||
home.file."${cfg.datadir}/userdata/sources.xml".source =
|
||||
attrsetToSourcesXml cfg.sources "kodi-sources.xml";
|
||||
})
|
||||
|
||||
(mkIf (cfg.addonSettings != null) {
|
||||
home.file = mapAttrs' (k: v:
|
||||
attrsets.nameValuePair
|
||||
("${cfg.datadir}/userdata/addon_data/${k}/settings.xml") {
|
||||
source = attrsetToAddonSettingsXml v "kodi-addon-${k}-settings.xml";
|
||||
}) cfg.addonSettings;
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -123,6 +123,7 @@ import nmt {
|
|||
./modules/programs/gnome-terminal
|
||||
./modules/programs/hexchat
|
||||
./modules/programs/i3status-rust
|
||||
./modules/programs/kodi
|
||||
./modules/programs/mangohud
|
||||
./modules/programs/ncmpcpp-linux
|
||||
./modules/programs/neovim # Broken package dependency on Darwin.
|
||||
|
|
5
tests/modules/programs/kodi/default.nix
Normal file
5
tests/modules/programs/kodi/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
kodi-example-addon-settings = ./example-addon-settings.nix;
|
||||
kodi-example-settings = ./example-settings.nix;
|
||||
kodi-example-sources = ./example-sources.nix;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<!-- Generated by Home Manager. -->
|
||||
<settings version="2">
|
||||
<setting id="versioncheck_enable">false</setting>
|
||||
</settings>
|
18
tests/modules/programs/kodi/example-addon-settings.nix
Normal file
18
tests/modules/programs/kodi/example-addon-settings.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
programs.kodi = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
|
||||
addonSettings = {
|
||||
"service.xbmc.versioncheck".versioncheck_enable = "false";
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.kodi/userdata/addon_data/service.xbmc.versioncheck/settings.xml \
|
||||
${./example-addon-settings-expected.xml}
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<!-- Generated by Home Manager. -->
|
||||
<advancedsettings version="1.0">
|
||||
<videolibrary>
|
||||
<showemptytvshows>true</showemptytvshows>
|
||||
</videolibrary>
|
||||
</advancedsettings>
|
16
tests/modules/programs/kodi/example-settings.nix
Normal file
16
tests/modules/programs/kodi/example-settings.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
programs.kodi = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
|
||||
settings = { videolibrary.showemptytvshows = "true"; };
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.kodi/userdata/advancedsettings.xml \
|
||||
${./example-settings-expected.xml}
|
||||
'';
|
||||
}
|
16
tests/modules/programs/kodi/example-sources-expected.xml
Normal file
16
tests/modules/programs/kodi/example-sources-expected.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!-- Generated by Home Manager. -->
|
||||
<sources>
|
||||
<video>
|
||||
<default>movies</default>
|
||||
<source>
|
||||
<allowsharing>true</allowsharing>
|
||||
<name>videos</name>
|
||||
<path pathversion="1">/path/to/videos</path>
|
||||
</source>
|
||||
<source>
|
||||
<allowsharing>true</allowsharing>
|
||||
<name>movies</name>
|
||||
<path pathversion="1">/path/to/movies</path>
|
||||
</source>
|
||||
</video>
|
||||
</sources>
|
33
tests/modules/programs/kodi/example-sources.nix
Normal file
33
tests/modules/programs/kodi/example-sources.nix
Normal file
|
@ -0,0 +1,33 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
programs.kodi = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
|
||||
sources = {
|
||||
video = {
|
||||
default = "movies";
|
||||
source = [
|
||||
{
|
||||
name = "videos";
|
||||
path = "/path/to/videos";
|
||||
allowsharing = "true";
|
||||
}
|
||||
{
|
||||
name = "movies";
|
||||
path = "/path/to/movies";
|
||||
allowsharing = "true";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.kodi/userdata/sources.xml \
|
||||
${./example-sources-expected.xml}
|
||||
'';
|
||||
}
|
Loading…
Reference in a new issue