#!/bin/bash ### amaroKollection ### ### Dependencies: - Amarok ### - grep, sed, echo, sort, tail, rm, date, mktemp, cat, zip ### ### 2006-2007, Patrick Nagel (mail AT patrick-nagel DOT net) ### ### This program is free software; you can redistribute it and/or ### modify it under the terms of the GNU General Public License ### as published by the Free Software Foundation; either version 2 ### of the License, or (at your option) any later version. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ### ### The GNU General Public License (GPL) can be found here: ### http://www.gnu.org/licenses/gpl.html ### CUSTOMISATION (PLEASE CHANGE TO YOUR NEEDS) # Silent mode (no output except the actual data), useful when used in cron-jobs. SILENT=0 # Default directory for HTML index generation. Command line argument is stronger. DIRECTORY="." # Default index filename INDEXFILE="amaroKollection.html" # Filenames for the other HTML files ARTISTS_AND_THEIR_ALBUMS_FILE="amaroKollection_aa.html" GENRES_AND_THEIR_ARTISTS_FILE="amaroKollection_ga.html" # File for default CSS file (which will be generated) CSSFILE="amaroKollection.css" # Default filename for the ZIP archive. Command line argument is stronger. ZIPFILE="amaroKollection.zip" # Optional: Collection owner's name (displayed in HTML output if not set to DEFAULT) COLLECTIONOWNER="DEFAULT" # Optional: Collection owner's mail address (displayed in HTML output if not set to DEFAULT) COLLECTIONMAIL="DEFAULT" ### CUSTOMISATION END ### SCRIPT (CHANGE ONLY IF YOU KNOW WHAT YOU'RE DOING!) # Some variables and checks VERSION="0.43" RELEASE="2007-06-14" # Create tempdir securely TEMPDIR=$(mktemp -d ${TMPDIR:-/tmp}/amaroKollectionXXXXXX) || \ { echo "An error occurred while creating the temporary files directory. Exiting."; exit 1; } TEMP=${TEMPDIR}/amaroKollection.tmp TEMP2=${TEMPDIR}/amaroKollection-2.tmp TEMP3=${TEMPDIR}/amaroKollection-3.tmp TEMP4=${TEMPDIR}/amaroKollection-4.tmp TEMP5=${TEMPDIR}/amaroKollection-5.tmp TEMP6=${TEMPDIR}/amaroKollection-6.tmp # Check if Amarok is running and fill some more useful variables if so. dcop amarok >/dev/null || { echo "This script needs Amarok running in the same KDE session. Exiting."; exit -1; } COLLECTION_TRACKS=$(dcop amarok collection totalTracks) COLLECTION_ALBUMS=$(dcop amarok collection totalAlbums) COLLECTION_ARTISTS=$(dcop amarok collection totalArtists) COLLECTION_GENRES=$(dcop amarok collection totalGenres) COLLECTION_COMPILATIONS=$(dcop amarok collection totalCompilations) ## FUNCTIONS function exit_amaroKollection() { # Clean up rm -rf ${TEMPDIR} exit 0 } function append_to_html () { # This function is used for appending HTML code to the specified HTML file. # Here it's easily possible to do some transformations with sed. sed -e 's/\&/\&/g' >> ${HTMLFILE} } function fetch_artists_and_their_albums() { # Get artistID, albumID dcop amarok collection query "SELECT DISTINCT '', artist, '', '', album, '' FROM tags WHERE sampler=0 ORDER BY artist" | tr -d "\n" | sed -e 's/>\n ${TEMP2} # Get artistID, artistName, alphabetically dcop amarok collection query "SELECT DISTINCT '', id, '', '', name, '' FROM artist ORDER BY name" | tr -d "\n" | sed -e 's/>\n ${TEMP3} # Get albumID, albumName dcop amarok collection query "SELECT DISTINCT '', id, '', '', name, '' FROM album WHERE id IN ( SELECT DISTINCT tags.album FROM tags WHERE tags.sampler=0 ) ORDER BY name" | tr -d "\n" | sed -e 's/>\n ${TEMP4} # Make sorted artistID list from sorted artistName list grep "" ${TEMP3} | sed -e '/.*/d' -e 's///' -e 's/<\/artistID>//' > ${TEMP6} # Make sorted albums list from ${ARTIST_ID} function sorted_albums_list_from_artist_id() { # Get artistName from ${ARTIST_ID} grep -A 1 -x "${ARTIST_ID}" ${TEMP3} | sed -e '//d' -e '/^$/d' # Get albums from ${ARTIST_ID}, delete empty albums (no tag set) grep -A 1 -x "${ARTIST_ID}" ${TEMP2} | for i in $(sed -e '/.*/d' -e 's///' -e 's/<\/albumID>//'); do { grep -A 1 -x "$i" ${TEMP4} | sed -e '//d' -e '/^$/d'; }; done | sort return } # Put the sorted artist IDs one after another into the ARTIST_ID variable and call the function above, # which then will find out which artist's name has this ID and find the artist's albums. for i in $(cat ${TEMP6}); do ARTIST_ID=${i} sorted_albums_list_from_artist_id done > ${TEMP} ## We want only artists with albums, not artists of who we have tracks on samplers or whose albums have no name grep -B 1 "" ${TEMP} | sed -e '/--/d' > ${TEMP5} return } function fetch_genres_and_their_artists() { # Get genreID, artistID dcop amarok collection query "SELECT DISTINCT '', genre, '', '', artist, '' FROM tags ORDER BY genre" | tr -d "\n" | sed -e 's/>\n ${TEMP2} # Get genreID, genreName, alphabetically dcop amarok collection query "SELECT DISTINCT '', id, '', '', name, '' FROM genre ORDER BY name" | tr -d "\n" | sed -e 's/<\/genreName>/--<\/genreName>/' -e 's/>\n ${TEMP3} # Get artistID, artistName dcop amarok collection query "SELECT DISTINCT '', id, '', '', name, '' FROM artist ORDER BY name" | tr -d "\n" | sed -e 's/>\n ${TEMP4} # Make sorted genreID list from sorted genreName list grep "" ${TEMP3} | sed -e '/.*/d' -e 's///' -e 's/<\/genreID>//' > ${TEMP6} # Make sorted artists list from ${GENRE_ID} function sorted_artists_list_from_genre_id() { # Get genreName from ${GENRE_ID} grep -A 1 -x "${GENRE_ID}" ${TEMP3} | sed -e '//d' -e '/^$/d' # Get artists from ${GENRE_ID} grep -A 1 -x "${GENRE_ID}" ${TEMP2} | for i in $(sed -e '/.*/d' -e 's///' -e 's/<\/artistID>//'); do { grep -A 1 -x "$i" ${TEMP4} | sed -e '//d' -e '/^$/d'; }; done | sort return } # Put the sorted genre IDs one after another into the GENRE_ID variable and call the function above, # which then will find out which genre's name has this ID and find the genre's artists. for i in $(cat ${TEMP6}); do GENRE_ID=${i} sorted_artists_list_from_genre_id done > ${TEMP} cp ${TEMP} ${TEMP5} return } function css_generate() { echo -en 'body { color: #fff; background: #000000; margin-left: 15%; margin-right: 15%; } p { margin-top: 0px; margin-left: 3px; } h1 { letter-spacing: 4px; margin-bottom: 12px; color: #fff; background-color: #000; } h2 { margin-top: 40px; margin-bottom: 15px; color: #fff; background-color: #000; } ul { list-style-type: square; } li { margin-top: 5px; } a:link { font-weight: bold; text-decoration: none; color: #7777ff; background-color: #000; } a:visited { font-weight: bold; text-decoration: none; color: #7777ff; background-color: #000; } a:hover, a:active { text-decoration: underline; color: #9685BA; background-color: #000; } table { border-style: none; } tr { border-style: none; } td { border-style: none; } ' >${DIRECTORY}/${CSSFILE} return } function html_generate_header() { echo -en " Amarok collection

" | append_to_html # Insert COLLECTIONOWNER and COLLECTIONMAIL if [ ${COLLECTIONOWNER} != "DEFAULT" ] then if [ ${COLLECTIONMAIL} != "DEFAULT" ] then # Both set. echo -en "${COLLECTIONOWNER}'s " | append_to_html else # Only COLLECTIONOWNER set. echo -en "${COLLECTIONOWNER}'s " | append_to_html fi # Nothing set. fi echo -en 'Amarok collection

' | append_to_html css_generate return } function html_generate_footer() { echo -e '


Valid XHTML 1.0 Strict

' | append_to_html return } function html_export() { if (( ${SILENT} == 0 )) then echo -n "The information is being exported to HTML... please wait." fi # OUTPUTHTML will be considered by the print functions. OUTPUTHTML=1 # Abort if directory doesn't exist. [ -d ${DIRECTORY} ] || { echo -e "\nThe specified directory does not exist. Exiting."; exit 1; } HTMLFILE=${DIRECTORY}/${INDEXFILE} rm -f ${HTMLFILE} html_generate_header echo -e "

\n generated by amaroKollection ${VERSION} on $(date --iso-8601)\n

\n" | append_to_html print_collection_statistics echo -e "

Collection lists:

\n Artists and their albums

Genres and their artists

\n" | append_to_html HTMLFILE=${DIRECTORY}/${ARTISTS_AND_THEIR_ALBUMS_FILE} rm -f ${HTMLFILE} html_generate_header print_artists_and_their_albums html_generate_footer HTMLFILE=${DIRECTORY}/${GENRES_AND_THEIR_ARTISTS_FILE} rm -f ${HTMLFILE} html_generate_header print_genres_and_their_artists html_generate_footer OUTPUTHTML=0 HTMLFILE=${DIRECTORY}/${INDEXFILE} html_generate_footer if (( ${SILENT} == 0 )) then echo -e "\rHTML files have been generated. " fi return } function print_artists_and_their_albums() { fetch_artists_and_their_albums case "${OUTPUTHTML}" in ( 1 ) echo -en "

Artists and their albums:

\n\n" | append_to_html echo -en "
    \n" | append_to_html sed -i -e 's// <\/ul>\n <\/li>\n
  • /' -e 's/<\/artistName>/\n
      /' -e 's//
    • /' -e 's/<\/albumName>/<\/li>/' ${TEMP5} echo -en "
    \n
  • \n
\n\n" >> ${TEMP5} # doh... tail -n +3 ${TEMP5} | append_to_html ;; ( * ) echo "Artists and their albums:" echo sed -e 's///' -e 's/<\/artistName>//' -e 's// /' -e 's/<\/albumName>//' ${TEMP5} ;; esac return } function print_genres_and_their_artists() { fetch_genres_and_their_artists case "${OUTPUTHTML}" in ( 1 ) echo -en "

Genres and their artists:

\n\n" | append_to_html echo -en "
    \n" | append_to_html sed -i -e 's// <\/ul>\n <\/li>\n
  • /' -e 's/<\/genreName>/\n
      /' -e 's//
    • /' -e 's/<\/artistName>/<\/li>/' ${TEMP5} echo -en "
    \n
  • \n
\n\n" >> ${TEMP5} # doh... tail -n +3 ${TEMP5} | append_to_html ;; ( * ) echo "Genres and their artists:" echo sed -e 's///' -e 's/<\/genreName>//' -e 's// /' -e 's/<\/artistName>//' ${TEMP5} ;; esac return } function zip_htmls() { echo -n "Packing HTML files into ${DIRECTORY}/${ZIPFILE}..." zip ${DIRECTORY}/${ZIPFILE} ${DIRECTORY}/${INDEXFILE} ${DIRECTORY}/${CSSFILE} ${DIRECTORY}/${ARTISTS_AND_THEIR_ALBUMS_FILE} ${DIRECTORY}/${GENRES_AND_THEIR_ARTISTS_FILE} >/dev/null rm -f ${DIRECTORY}/${INDEXFILE} ${DIRECTORY}/${CSSFILE} ${DIRECTORY}/${ARTISTS_AND_THEIR_ALBUMS_FILE} ${DIRECTORY}/${GENRES_AND_THEIR_ARTISTS_FILE} >/dev/null echo -e "\rHTML files have been added to ${DIRECTORY}/${ZIPFILE}." return } function print_collection_statistics() { case "${OUTPUTHTML}" in ( 1 ) echo -en "

Collection statistics:

Track count ${COLLECTION_TRACKS}
Album count ${COLLECTION_ALBUMS}
Artist count ${COLLECTION_ARTISTS}
Genre count ${COLLECTION_GENRES}
Compilation count ${COLLECTION_COMPILATIONS}
" | append_to_html ;; ( * ) echo "Collection statistics:" echo echo "Track count: ${COLLECTION_TRACKS}" echo "Album count: ${COLLECTION_ALBUMS}" echo "Artist count: ${COLLECTION_ARTISTS}" echo "Genre count: ${COLLECTION_GENRES}" echo "Compilation count: ${COLLECTION_COMPILATIONS}" ;; esac return } function print_help() { echo "This bash script extracts information from Amarok's collection database." echo echo "Specify one of the following parameters:" echo echo " -h --help Display this message." echo " -s --statistics Display collection statistics." echo " -a --albums Display artists and their albums." echo " -g --genres Display genres and their artists." echo " -x --export [directory] Export all available information to HTML files;" echo " [directory] is the name of the target directory." echo " The directory must exist if specified." echo " -z --zipexp [directory] Same as -x but put the resulting HTML files into" echo " a ZIP archive in [directory]." echo " The directory must exist if specified." echo echo "Hint: The script has a configration section at the top, where you can" echo " adapt some variables to your needs." return } ## MAIN if (( ${SILENT} == 0 )) then echo echo "amaroKollection ${VERSION} (${RELEASE})" echo fi case "$1" in ("-h" | "--help") print_help ;; ("-s" | "--statistics") print_collection_statistics ;; ("-a" | "--albums") print_artists_and_their_albums ;; ("-g" | "--genres") print_genres_and_their_artists ;; ("-x" | "--export") if [ "$2" != "" ]; then DIRECTORY="$2"; fi html_export ;; ("-z" | "--zipexp") if [ "$2" != "" ]; then DIRECTORY="$2"; fi html_export zip_htmls ;; *) print_help ;; esac if (( ${SILENT} == 0 )) then echo fi exit_amaroKollection ### THE END