Skip to content

Instantly share code, notes, and snippets.

@ciis0
Last active February 1, 2021 14:07
Show Gist options
  • Save ciis0/e51c4da4c92940a119202104772feb57 to your computer and use it in GitHub Desktop.
Save ciis0/e51c4da4c92940a119202104772feb57 to your computer and use it in GitHub Desktop.
Shuffle XSPF file by album using xsltproc for e.g. Clementine
#!/bin/bash
cd $(dirname $0)
playlist=shuffled.xspf
cat >$playlist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
EOF
albums=$(xsltproc.exe tracks2albums.xsl Alle\ Titel.xspf)
xsltproc <(cat <<EOF
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xspf="http://xspf.org/ns/0/">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="albums">
$(for index in $(echo "$albums" | shuf -i 1-$(xmllint --xpath "string((//album)[last()]/@index)" -)); do echo '<xsl:apply-templates select="//album[@index = '$index']" />'; done)
</xsl:template>
<xsl:template match="album">
<xsl:for-each select="xspf:track">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
EOF
) <(echo "$albums") >>$playlist
cat >>$playlist <<EOF
</trackList>
</playlist>
EOF
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xspf="http://xspf.org/ns/0/">
<xsl:output method="xml" indent="yes" />
<xsl:key name="album" match="xspf:track" use="xspf:album" />
<xsl:template match="xspf:trackList">
<xsl:element name="albums">
<xsl:apply-templates select="xspf:track[generate-id(.)=generate-id(key('album',xspf:album)[1])]" />
</xsl:element>
</xsl:template>
<xsl:template match="xspf:track">
<xsl:element name="album">
<xsl:if test="xspf:album != '' and xspf:album != 'No Album'">
<xsl:variable name="i" select="position()" />
<xsl:attribute name="index">
<xsl:value-of select="$i" />
</xsl:attribute>
<xsl:for-each select="key('album', xspf:album)">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:if>
</xsl:element>
</xsl:template>
<!-- <xsl:template match="xspf:track">
<xsl:if test="xspf:album != ''">
<album><xsl:value-of select="xspf:album" /></album>
</xsl:if>
</xsl:template>
-->
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment