Thursday, September 2, 2010
  • Index
  •  » Code Exchange
  •  » Coverlover - A PDF wallpaper showing random iTunes cover art

#1 2008-07-08 04:09:28 am

Martin Michel
Administrator
From: Berlin, Germany
Registered: 2008-03-03
Posts: 655
Website

Coverlover - A PDF wallpaper showing random iTunes cover art

Initially I developed this script for a Majorcan disco owner who wanted to show cover art with a video projector, but after finishing Lacurne I slightly modified it to create and set a customizable PDF wallpaper on your desktop that shows random iTunes cover art.

Once again, the raw image and PDF processing is done with Python and its Quartz 2D bindings while the GUI, Finder interaction and preferences management is handled by AppleScript. Together this makes for a very efficient and convenient Mac automation solution.

The script allows to adjust the maximum cover width and height, let's you set a foreground color and a color tint and can reduce the file size of the created PDF wallpaper by applying a Quartz filter.

Of course I invite you to download and inspect this free little AppleScript, but please don't expect a polished application this time wink It's still beta software (nevertheless it works just fine on all my private and company Macs):

http://files.macscripter.net/joy/images/coverart.jpg




Coverlover requires Mac OS X 10.5 Leopard and iTunes 7. It was successfully tested on Intel and PowerPC based Macs, but runs significantly faster on Intel Macs.

To create and set a PDF wallpaper just open the script with a double click. If you want to open the configuration menu, then just drag and drop a Finder item onto the script's icon:

http://files.macscripter.net/joy/images/coverlover.jpg


Please note, that you won't instantly see the changes made in the configuration menu. The new settings will only show up after you run Coverlover once again, as it will then create and set a new PDF document according to the chosen options.

Coverlover currently assumes that your iTunes folder containing ITC cover art files is located here:

~/Music/iTunes/Album Artwork/

The preferences are currently saved inside Coverlover's script bundle.

If you are interested in the Python code that generates the PDF wallpaper, you can study it right here.

Important: Opening and saving the below script code in Script Editor won't result in a usable AppleScript! That is because Coverlover internally relies on several scripts, which are located inside its Script bundle. Therefor please download the complete script here.

Applescript:


-- created: 07.06.2008
-- version: 0.1
-- requires:
-- • Mac OS X 10.5 Leopard & iTunes 7
-- tested on:
-- • Intel & PowerPC based Macs
-- notes:
-- • runs a lot faster on an Intel based Mac
-- • dual monitor setups are currently not supported

-- This AppleScript creates and sets a PDF wallpaper made of random iTunes cover art according to the chosen options.
-- To enter the configuration menu, just drop Finder items onto the script's icon.

property mytitle : "Coverlover"

-- I am called when the user drops Finder items onto the script's icon.
-- I am displaying the configuration menu and managing the preferences.
on open finderitems
   repeat
       set chosenmenuitem to my dspmainmenu()
       if chosenmenuitem begins with "Set cover width" then
           set coverwidth to my askforcoversize("width")
           if coverwidth is not missing value then
               my savepref("coverwidth", coverwidth)
           end if
       else if chosenmenuitem begins with "Set cover height" then
           set coverheight to my askforcoversize("height")
           if coverheight is not missing value then
               my savepref("coverheight", coverheight)
           end if
       else if chosenmenuitem is "Set foreground color" then
           set fgcolor to my askforfgcolor()
           if fgcolor is not missing value then
               my savepref("fgcolor", fgcolor)
           end if
       else if chosenmenuitem is "Deactivate foreground color" then
           my savepref("fgcolor", missing value)
       else if chosenmenuitem begins with "Set foreground color tint" then
           set colortint to my askforcolortint()
           if colortint is not missing value then
               my savepref("colortint", colortint)
           end if
       else if chosenmenuitem is "Enable file size reduction" then
           my savepref("quartzfilter", true)
       else if chosenmenuitem is "Disable file size reduction" then
           my savepref("quartzfilter", false)
       else if chosenmenuitem is missing value then
           exit repeat
       end if
   end repeat
end open

-- I am called when the user opens the script with a double click on its icon.
-- I am trying to create the wallpaper made of iTunes cover art.
on run
   try
       -- loading the preferences script object
       set prefs to my loadprefs()
       if prefs is missing value then
           set errmsg to "Could not load the preferences script located inside my script bundle."
           my dsperrmsg(errmsg, "--")
           return
       end if
       -- preparing the preferences, so that they can be passed as
       -- string arguments to the Python script
       set coverwidth to (prefs's coverwidth) as Unicode text
       set coverheight to (prefs's coverheight) as Unicode text
       set fgcolor to prefs's fgcolor
       if fgcolor is missing value then
           set fgcolor to quoted form of "missing value"
       else
           set {redval, greenval, blueval} to prefs's fgcolor
           -- replacing commas with points in float values, as
           -- Python only accepts a point as decimal separator
           set redval to my searchnreplace(",", ".", redval as Unicode text)
           set greenval to my searchnreplace(",", ".", greenval as Unicode text)
           set blueval to my searchnreplace(",", ".", blueval as Unicode text)
           set fgcolor to redval & space & greenval & space & blueval
       end if
       set colortint to my searchnreplace(",", ".", (prefs's colortint as Unicode text))
       set quartzfilter to (prefs's quartzfilter) as Unicode text
       -- creating the shell command calling the Python script with the
       -- corresponding arguments
       set pyscriptpath to (((path to me) as Unicode text) & "Contents:Resources:Scripts:coverlover.py")
       set command to "/usr/bin/python " & quoted form of POSIX path of pyscriptpath & " " & coverwidth & " " & coverheight & " " & fgcolor & " " & colortint & " " & quartzfilter
       set shellresult to paragraphs of (do shell script command)
       -- maybe there was an error...
       if item 1 of shellresult begins with "Error:" then
           set errmsg to ((characters 8 through -1 of (item 1 of shellresult)) as Unicode text)
           my dsperrmsg(errmsg, "--")
           return
       end if
       -- PDF wallpaper successfully created?
       set pdffilepath to (((path to application support folder from user domain) as Unicode text) & "Coverlover:coverlover.pdf")
       if not itempathexists(pdffilepath) then
           set errmsg to "The PDF wallpaper could not be created."
           my dsperrmsg(errmsg, "--")
           return
       end if
       -- file path to the PNG image used as an update helper: if you try to update the desktop picture and
       -- the file path of your new image is the same as the current one, you won't see
       -- the new image. therefor we first «switch» to the small PNG image before updating
       -- the wallpaper.
       set switchfilepath to (((path to me) as Unicode text) & "Contents:Resources:switch.png")
       tell application "Finder"
           set desktop picture to (switchfilepath as alias)
       end tell
       delay 0.25
       tell application "Finder"
           set desktop picture to (pdffilepath as alias)
       end tell
       -- catching unexpected errors
   on error errmsg number errnum
       my dsperrmsg(errmsg, errnum)
   end try
end run

-- I am displaying the configuration menu and return the chosen menu item.
-- In case the user cancels I return «missing value».
on dspmainmenu()
   -- loading the preferences script object
   set prefs to my loadprefs()
   if prefs is missing value then
       set errmsg to "Could not load the preferences script located inside my script bundle."
       my dsperrmsg(errmsg, "--")
       return missing value
   end if
   set micoverwidth to "Set cover width (" & prefs's coverwidth & "px)"
   set micoverheight to "Set cover height (" & prefs's coverheight & "px)"
   set micolortint to "Set foreground color tint (" & prefs's colortint & ")"
   set menuitems to {micoverwidth, micoverheight, "Set foreground color", "Deactivate foreground color", micolortint, "Enable file size reduction", "Disable file size reduction"}
   choose from list menuitems with title mytitle OK button name "Select" cancel button name "Quit" with prompt "Please choose an option" without multiple selections allowed and empty selection allowed
   set usrchoice to result
   if usrchoice is not false then
       return item 1 of (usrchoice as list)
   else
       return missing value
   end if
end dspmainmenu

-- I am loading the preferences script object and return it.
-- In case of an error I return «missing value».
on loadprefs()
   set prefsfilepath to (((path to me) as Unicode text) & "Contents:Resources:Scripts:prefs.scpt")
   try
       set prefs to load script (prefsfilepath as alias)
       return prefs
   on error
       return missing value
   end try
end loadprefs

-- I am saving the chosen preferences to a script file
on savepref(prefkey, prefvalue)
   set prefsfilepath to (((path to me) as Unicode text) & "Contents:Resources:Scripts:prefs.scpt")
   set prefs to load script (prefsfilepath as alias)
   if prefkey is "coverwidth" then
       set prefs's coverwidth to prefvalue
   else if prefkey is "coverheight" then
       set prefs's coverheight to prefvalue
   else if prefkey is "fgcolor" then
       set prefs's fgcolor to prefvalue
   else if prefkey is "colortint" then
       set prefs's colortint to prefvalue
   else if prefkey is "quartzfilter" then
       set prefs's quartzfilter to prefvalue
   end if
   store script prefs in (prefsfilepath as alias) replacing yes
end savepref

-- I am asking the user to provide the maximum cover width/height and return the integer value.
-- In case the user cancels I return «missing value».
on askforcoversize(mode)
   set dlgmsg to "Please enter the maximum cover " & mode & " as an integer:"
   try
       display dialog dlgmsg default answer "" buttons {"Cancel", "Enter"} default button 2 with title mytitle
   on error
       -- User canceled
       return missing value
   end try
   set dlgresult to result
   set usrinput to text returned of dlgresult
   -- the user did not enter anything...
   if usrinput is "" then
       my askforcoversize(mode)
   else
       -- let's check if the user entered numbers only
       set nums to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
       set invalidchars to ""
       repeat with char in usrinput
           if char is not in nums then
               set invalidchars to invalidchars & char & space
           end if
       end repeat
       -- we found invalid characters
       if invalidchars is not "" then
           set errmsg to "We found the following characters in the given input. Please enter numbers only." & return & return & invalidchars & return
           my dsperrmsg(errmsg, "--")
           my askforcoversize(mode)
       else
           -- let's try to transform the user input into an integer
           try
               set intvalue to usrinput as integer
               return intvalue
           on error
               set errmsg to "We could not coerce the given input into an integer:" & return & return & usrinput & return
               my dsperrmsg(errmsg, "--")
               my askforcoversize(mode)
           end try
       end if
   end if
end askforcoversize

-- I am asking the user to choose a color.
-- In case the user cancels I return «missing value».
on askforfgcolor()
   try
       set chosencolor to choose color
   on error
       return missing value
   end try
   set {redval, greenval, blueval} to chosencolor
   set redval to redval / 65535
   set greenval to greenval / 65535
   set blueval to blueval / 65535
   return {redval, greenval, blueval}
end askforfgcolor

-- I am asking the user to choose a tint value to highlight the last and next month
on askforcolortint()
   set decseparator to my getdecseparator()
   set dlgmsg to "Please choose a tint value used for the foreground color:" & return & "(value must be between 0 and 1," & return & "decimal separator: «" & decseparator & "»)"
   try
       tell me
           activate
           display dialog dlgmsg default answer "" buttons {"Cancel", "Enter"} default button 2 with title mytitle
       end tell
       set dlgresult to result
   on error
       return missing value
   end try
   set usrinput to text returned of dlgresult
   if usrinput is "" then
       my askforcolortint()
   else
       set usrinputisnum to true
       try
           set usrinput to usrinput as number
       on error
           set usrinputisnum to false
       end try
       if usrinputisnum is false then
           set errmsg to "The entered value could not be coerced into a number."
           my dsperrmsg(errmsg, "--")
           my askforcolortint()
       else
           if usrinput < 0 or usrinput > 1 then
               set errmsg to "The entered value is less than 0 or greater than 1."
               my dsperrmsg(errmsg, "--")
               my askforcolortint()
           else
               return usrinput
           end if
       end if
   end if
end askforcolortint

-- I am returning the currently used decimal separator
on getdecseparator()
   set strnum to 0.1 as Unicode text
   set decseparator to character 2 of strnum
   return decseparator
end getdecseparator

-- I am a very old search & replace function...
on searchnreplace(searchstr, replacestr, txt)
   considering case, diacriticals and punctuation
       if txt contains searchstr then
           set olddelims to AppleScript's text item delimiters
           set AppleScript's text item delimiters to {searchstr}
           set txtitems to text items of txt
           set AppleScript's text item delimiters to {replacestr}
           set txt to txtitems as Unicode text
           set AppleScript's text item delimiters to olddelims
       end if
   end considering
   return txt
end searchnreplace

-- I am indicating if a given item path exists or not
on itempathexists(itempath)
   try
       set itemalias to itempath as alias
       return true
   on error
       return false
   end try
end itempathexists

-- I am displaying error messages to the user
on dsperrmsg(errmsg, errnum)
   
   tell me
       activate
       display dialog "Sorry, an error occured:" & return & return & errmsg & return & "(" & errnum & ")" buttons {"OK"} default button 1 with icon stop giving up after 20 with title mytitle
   end tell
end dsperrmsg


Sal Soghoian is my role model.

Offline

 
  • Index
  •  » Code Exchange
  •  » Coverlover - A PDF wallpaper showing random iTunes cover art

Board footer

Powered by FluxBB

[ Generated in 0.542 seconds, 10 queries executed ]

RSS (new topics) RSS (active topics)