mirror of
https://github.com/nix-community/home-manager
synced 2024-12-26 03:39:47 +01:00
256 lines
8 KiB
Nix
256 lines
8 KiB
Nix
|
{ 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;
|
||
|
})
|
||
|
]);
|
||
|
}
|