Drag and drop from iTunes to AppleScript Studio

I have an ASS application with an image view as a drop zone. I would like to be able to drag and drop files from the Finder, music from iTunes and photos from iPhoto. Finder and iPhoto both work when I set the image view to register the drag type “file names”, but iTunes does not. I also tried to register all the drag types that are listed here (“color”, “file”, “file names”, “font”, “html”, “image”, “pdf”, “pict image”, “postscript”, “rich text”, “rich text data”, “ruler”, “string”, “tabular text”, “url”, and “vcard”), but it still does not respond to a drag and drop from iTunes.

Is there some other drag type that I need to register, or how could I get it to work? Thanks for any help.

Hi Sälli,

I think you need to register for NSFilesPromisePboardType - in Applescript it’s called “Apple files promise pasteboard type”.

I hope this helps - unfortunately I have no idea how to process data of this pastboard type in AppleScript. :frowning:

D.

In searching the web I found this page, which describes a method of handling iTunes drags. I modified it a bit to do it all in just the applescript file.

--> Key elements of this code derived from example at...
--> http://themorgue.org/2006/09/05/drag-and-drop-tracks-from-itunes-in-applescript/

property iTunesPasteboard : "CorePasteboardFlavorType 0x6974756E"

on awake from nib theObject
	if name of theObject is "Image" then
		tell theObject to register drag types {"file names", iTunesPasteboard}
	end if
end awake from nib

on drop theObject drag info dragInfo
	if name of theObject is "Image" then
		set dragTypes to types of pasteboard of dragInfo
		
		if iTunesPasteboard is in dragTypes then
			(* Use 'call method' to access obj-c methods that evaluate the iTunes pasteboard *)
			set iTunesPBContents to call method "propertyListForType:" of (pasteboard of dragInfo) with parameter iTunesPasteboard
			set iTunesTracks to call method "objectForKey:" of iTunesPBContents with parameter "Tracks"
			set iTunesTracks to call method "allValues" of iTunesTracks
			
			(* Go through each track dropped and get it's name and url *)
			repeat with theTrack in iTunesTracks
				set trackName to |Name| of theTrack
				set trackPath to |Location| of theTrack
				log ((trackName & " (" & trackPath & ")") as string)
			end repeat
		end if
	end if
end drop

Ah great, Jobu - I had seen the data in CorePasteboardFlavorType 0x6974756E on the pasteboard, but I wasn’t sure if this type is consistent from one iTunes release to the next …

If you want to use ist, there is no call method necessary at all:

on drop theObject drag info dragInfo
	set dataTypes to types of pasteboard of dragInfo
	if "CorePasteboardFlavorType 0x6974756E" is in dataTypes then
		
		set preferred type of pasteboard of dragInfo to "CorePasteboardFlavorType 0x6974756E"
		
		set droppedTunesDict to (contents of pasteboard of dragInfo) as record
		try
			set droppedTracksDict to |Tracks| of droppedTunesDict
			set droppedTrackDict to (item 1 of (droppedTracksDict as list)) as record -- or loop like in Jobu's example ...
			
			set trackName to |Name| of droppedTrackDict
			log trackName
			set artistName to |Artist| of droppedTrackDict
			log artistName
			set albumName to |Album| of droppedTrackDict
			log albumName
			set fileLocation to |Location| of droppedTrackDict
			log fileLocation
			-- etc.
			
			return true
		end try
	end if
end drop

Thanks, Dominik. Believe it or not, it’s become easier for me to write stuff like this in obj-c than in AS. :stuck_out_tongue: Your code is much more appropriate in this context.

As far as the pasteboard type goes, I certainly can’t personally guarantee that it’s going to be consistent in the long-term. The page I referenced in my post was posted nearly a year ago, during which time there have been many updates to iTunes. I would guess that this is fairly reliable pasteboard type to use for now, but as with any scripting of other people’s software that you do, you should be willing and capable of updating your software if its developer decides to make changes.

j

Thanks a lot guys!

The script will return the file’s location as a URL (e.g. “file://localhost/Users/username/Music/iTunes/iTunes%20Music/Artist/Album/Song%20Name.m4a”). What I needed was a POSIX path, so I used the following function I found in this thread:

on urlToPOSIXPath(theURL)
   return do shell script "python -c \"import urllib, urlparse, sys; print urllib.unquote(urlparse.urlparse(sys.argv[1])[2])\" " & quoted form of theURL
end urlToPOSIXPath

or you can use:

on urlToPOSIXPath(theURL)
	return (call method "path" of (call method "URLWithString:" of class "NSURL" with parameter theURL))
end urlToPOSIXPath

might be a little bit faster :wink:

Thought I’d resurrect this thread for a question I have. I’m trying to make an applescript app that needs to get the references to iTunes tracks when they are dragged and dropped from iTunes onto a “drop zone” in my app. I’m new to applescript and am wondering if there is a way to do this in Applescript/AS and the on drop theObject drag info dragInfo event handler, without having to work with Objective-C? I appreciate any help.

Dominiks example should work fine for you

Open this Scriplet in your Editor:
on drop theObject drag info dragInfo
   set dataTypes to types of pasteboard of dragInfo
   if "CorePasteboardFlavorType 0x6974756E" is in dataTypes then
       
       set preferred type of pasteboard of dragInfo to "CorePasteboardFlavorType 0x6974756E"
       
       set droppedTunesDict to (contents of pasteboard of dragInfo) as record
       try
           set droppedTracksDict to |Tracks| of droppedTunesDict
           set droppedTrackDict to (item 1 of (droppedTracksDict as list)) as record -- or loop like in Jobu's example ...
           
           set trackName to |Name| of droppedTrackDict
           log trackName
           set artistName to |Artist| of droppedTrackDict
           log artistName
           set albumName to |Album| of droppedTrackDict
           log albumName
           set fileLocation to |Location| of droppedTrackDict
           log fileLocation
           -- etc.
           
           return true
       end try
   end if
end drop

Thanks, the example does work, but I’ve run into another problem. The script stores the dragged contents (i.e. Tracks) from iTunes and store them as a record. All I need is a reference to the dragged contents however. Normally I can get this easily with a simple:

tell application "iTunes"
if selection is not {} then --selection must not be empty in iTunes
set selectedTracks to a reference to selection --get the references to the selected tracks
end if
end tell

Unfortunately I can’t do this since adding a tell application command in a drop event causes a delay discussed in: http://macscripter.net/viewtopic.php?id=20189 Is there a way to modify the script so I can just get the references to the dragged tracks from iTunes without having to go through records first? If not, is there a way to get the references to the dragged tracks from the records?

I appreciate any help.

I’m still stumped by this, can anyone lend a hand to a AppleScript newbie?

Anyone?