Tuesday, March 25, 2008

Amarok embedded album art : EmbedCover script

The latest version of Amarok (1.4.8) suffers from a side effect of a feature called "Dynamic Collection" (http://bugs.kde.org/show_bug.cgi?id=159663). This results in a initial dot "." to every file in the collection.

EmbedCover script for Amarok works great for embedding album arts directly in the mp3 file. But it will report "Song is not in your collection" if the file paths are incorrect in the database due to that bug.

I've provided a temporary fix in the script for that problem till the bug in Amarok gets fixed. The patched EmbedCover.rb is here:

  • file to patch: $HOME/.kde/share/apps/amarok/scripts/embedcover/


#!/usr/bin/env ruby
#
# amaroK Script for embedding album cover images in MP3 files.
#
# (c) 2005 Mark Kretschmann <markey@web.de>
# License: GNU General Public License V2

################################
# This is my patched version   #
# Perfectly working my ubuntu. #
# So, Good luck !!             #
################################


require 'md5'
require "uri"

MenuItemName = "EmbedCover Embed!"

def cleanup()
    `dcop amarok script removeCustomMenuItem #{MenuItemName}`
end


trap( "SIGTERM" ) { cleanup() }

`dcop amarok script addCustomMenuItem #{MenuItemName}`


loop do
    message = gets().chomp()
    command = /[A-Za-z]*/.match( message ).to_s()

    case command
        when "configure"
            msg  = '"EmbedCover does not have configuration options. Simply select a track in the '
            msg += 'playlist, then start EmbedCover from the context-menu (right mouse click)."'

            `dcop amarok playlist popupMessage "#{msg}"`

        when "customMenuClicked"
            if message.include?( MenuItemName )
                args = message.split()
                # Remove the command args
                3.times() { args.delete_at( 0 ) }

                # Iterate over all selected files
                args.each() do |arg|
                    uri = URI.parse( arg )
                    file = URI.unescape( uri.path() )

   dcopfile = file
   hds = `dcop amarok collection query "SELECT DISTINCT lastmountpoint FROM devices"`.split()

   for n in hds
    unless n == "/"
    g = /(^#{n})/.match(dcopfile)
     if n = g
     dcopfile = dcopfile.sub(/(^#{n})\//, './')
     break
     else
     end
    else
    end
   end

      dcopfile = dcopfile.sub(/^\//, './')
      file = dcopfile
      
      #`dcop amarok playlist popupMessage "#{file}"`

                    file.gsub!( /[']/, '\\\\\'' )  # Escape for SQL

                    puts( "Path: #{file}" )

                    backend = File.dirname( File.expand_path( __FILE__ ) ) + "/addimage2mp3.rb"

                    # Query is two parts, first ID, then name
                    artist_id = `dcop amarok collection query "SELECT DISTINCT artist FROM tags WHERE url = '#{file}'"`.chomp()
                    artist    = `dcop amarok collection query "SELECT DISTINCT artist.name FROM artist WHERE id = '#{artist_id}'"`.chomp()

                    album_id  = `dcop amarok collection query "SELECT DISTINCT album FROM tags WHERE url = '#{file}'"`.chomp()
                    album     = `dcop amarok collection query "SELECT DISTINCT album.name FROM album WHERE id = '#{album_id}'"`.chomp()

                    puts( "ArtistId : #{artist_id}" )
                    puts( "Artist   : #{artist}" )
                    puts( "AlbumId  : #{album_id}" )
                    puts( "Album    : #{album}" )

                    if artist_id.empty?() and album_id.empty?()
                        `dcop amarok playlist popupMessage "EmbedCover Error: This track is not in your Collection."`
                        next
                    end

                    md5sum = MD5.hexdigest( "#{artist.downcase()}#{album.downcase()}" )
                    imagefolder = "#{ENV['HOME']}/.kde/share/apps/amarok/albumcovers/large/"
                    image = "#{imagefolder}#{md5sum}"

                    puts( "Imagepath: #{image}" )

                    unless FileTest.exist?( image )
                        `dcop amarok playlist popupMessage "EmbedCover: No image found for this track."`
                        next
                    end

                    
      file = file.sub(/^\.\//, '/')
      #`dcop amarok playlist popupMessage "#{file}"`
      
      output = `ruby #{backend} "#{image}" "#{file}"`

                    if $?.success?()
                        `dcop amarok playlist popupMessage "image embedded SUCCESSFULLY !!!."`
                    else
                        reg = Regexp.new( "Error:.*", Regexp::MULTILINE )
                        errormsg = reg.match( output )

                        `dcop amarok playlist popupMessage "EmbedCover #{errormsg}"`
                    end
                end
            end
    end
end