Dropzone Scripting API


Overview

Dropzone can easily be extended using simple ruby scripts. Creating a Dropzone destination is as simple as writing your script, giving it a .dropzone extension, and then double clicking it to add the destination to Dropzones grid.

Dropzone uses destination scripts to implement all the built-in destinations that ship with the application, such as the Move Files, Share Text and FTP Upload destinations. These scripts are located inside the application bundle and can be viewed by right clicking on Dropzone in the Finder, clicking on 'Show Package Contents' and navigating to:
				Contents/Resources/Destination Scripts/
			
You should familiarize yourself with the layout of these scripts as user scripts follow the same format. User scripts are installed to:
				~/Library/Application Support/Dropzone/Destination Scripts
			
Inside the user scripts directory there are symbolic links to the lib and AppleScripts directories. When Dropzone runs for the first time it creates these links to point to the same folders inside the application bundle. This allows you to easily reference key libraries and tools such as CocoaDialog from within your script.

Built-in and user contributed scripts can be browsed at the github repositories.

Destination Meta Data

In order to describe your destination to Dropzone, you must provide destination meta data in the following format at the top of your script. You must provide all fields except for IconURL, KeyModifiers and OptionsNIB which are optional. You must also include the 'Dropzone Destination Info' comment at the top as in the below example.
				# Dropzone Destination Info
				# Name: Destination name (1) 
				# Description: A short description of what your destination does (2) 
				# Events: Indicates which events your script is able to handle, can be either dragged, clicked or both - see the Script Events section for more information
				# Handles: Indicates which dragging types your script is able to handle, can be either NSFilenamesPboardType, NSStringPboardType or both - see the Dragging Types section for more information (3)
				# KeyModifiers: Optional field that indicates which key modifiers your destination script supports. Can be either Control, Option, Command or Shift. 
				# Creator: Your name (4) 
				# URL: A link to your site (5) 
				# IconURL: A URL that is a path to a PNG image to be used for the destination. Dropzone automatically downloads this (6)
				# OptionsNIB: An optional panel that Dropzone loads into the configuration panel to get other information from the user such as an application, destination folder or login details (7)
			

When Dropzone loads your script, it will parse your meta data and show it in the configuration panel like in the above screenshot.

Script Events


Dropzone destination scripts must have either a dragged method, a clicked method, or both. The dragged method gets called when something is dragged onto your destination and the clicked method gets called when a user clicks on your destination in the grid. You can tell Dropzone which events your script supports by using the Events field in the meta data section of your script. Several examples of how to do this are given below:

Click only
				# Dropzone Destination Info
				# Name: Clickable Destination
				# Description: This destination will only respond to click events.
				# Events: Clicked
			
Drag only
				# Dropzone Destination Info
				# Name: Destination that only accepts drags
				# Description: This destination will only respond to drag events.
				# Handles: NSFilenamesPboardType
				# Events: Dragged
			
Click & Drag
				# Dropzone Destination Info
				# Name: Destination that accepts clicks and drags
				# Description: This destination responds to both clicks and drags.
				# Handles: NSFilenamesPboardType
				# Events: Clicked, Dragged
			

The Creator and URL fields have been left out of the above examples for the sake of brevity. Note that you only need to include the Handles field for destinations that support the drag event. If you specify that you support an event in your meta data, then your script must implement the corresponding method for that event i.e. if your script supports the dragged event, then you must implement the dragged method.

Dragging Types

If your destination supports the dragged event, then you must specify the types of content your destination can handle in the meta data as follows:
Handle files only
				# Handles: NSFilenamesPboardType
			
Handle strings of text only
				# Handles: NSStringPboardType
			
Handle both files and strings of text
				# Handles: NSFilenamesPboardType, NSStringPboardType
			
If you specify NSFilenamesPboardType then the user will only be allowed to drag files onto your destination. If you specify NSStringPboardType then the user will only be allowed to drag strings of text onto your destination.
If you specify both types, then either type may be dragged and your script will need to determine the type as follows:
			case ENV['DRAGGED_TYPE']
			  when 'NSFilenamesPboardType'
			    # Code to handle dragged files goes here
				# $items is an array of the dragged filenames
			  when 'NSStringPboardType'
			    # Code to handle dragged text goes here
				# $items[0] is the dragged string of text
			end
			
When files are dragged onto your destination, an array of dragged filenames is stored in the $items global variable for your script to access. If your destination supports the NSStringPboardType then the dropped text is contained in the first element of this array i.e. $items[0].

Providing Status Updates

Your script can optionally provide status updates to to tell Dropzone what it is doing as it executes so that the floating status window can be updated. To do this you need to send output to Dropzone, and you must do this by calling methods on the $dz global which is an instance of the Dropzone class. This is setup for you when Dropzone calls your script. The methods for providing status updates from your script are outlined below:

determinate(value)

Value may be either true or false. Determinate mode (true) indicates that you will be providing progress information to Dropzone from your script as a percent and indeterminate mode (false) means that no progress information will be provided.

You can switch between determinate and indeterminate modes as your script executes. For example, you might choose to resize some images and then upload them to a server - you may not be able to provide progress information as the images are resized, but you can provide progress information while uploading them to a server. Therefore you would tell Dropzone to use indeterminate mode initially and then switch to determinate mode once you begin uploading. You should use determinate mode and provide progress information wherever possible.

Examples
				$dz.determinate(false)
			
				$dz.determinate(true)
			

begin(message)

Tells Dropzone to display the floating status window if it isn't already showing and sets the label above the progress bar to the specified message.

You can call this method multiple times as your script executes to update the displayed text.

Examples
				$dz.begin("Uploading files...")
			

percent(value)

Value is an integer value between 0 and 100. Dropzone updates the status window progress bar to reflect this value.

You only need to call this method when in determinate mode.

Examples
				$dz.percent(50)
			

finish(message)

Sets the message that will be shown in large text before the status window is hidden.

This method only sets the message, it will not be displayed and the window hidden until you call $dz.url. You should only call this method once.

Examples
				$dz.finish("Task Complete")
			

url(url)

Sets a URL to be placed on the pasteboard. This is useful for writing scripts that result in content being made available at a URL so a user can quickly paste the URL into other applications.

If you do not wish to specify a URL, you must still call this method with false as the argument. This method also causes the message that was passed to the finish method to be displayed and then the status window will be faded out after a short delay. You should only call this method once and it should be the last thing your script does before it terminates.

Examples
The following would result in the URL http://aptonic.com being placed on the pasteboard.
				$dz.url("http://aptonic.com")
			
You can use the following if you do not wish to provide a URL:
				$dz.url(false)
			

text(text)

You can use this in place of $dz.url. It behaves exactly the same except that it does not attempt to encode the argument as a URL so you can place raw strings of text on the pasteboard.
Examples
The following would result in the raw string 'This is a test string that will not be URL encoded' being placed on the pasteboard.
				$dz.text("This is a test string that will not be URL encoded")
			

Example Script

An example that demonstrates how to combine the meta data, status updates and dragged/clicked methods into a working destination script is given below:
				#!/usr/bin/ruby

				# Dropzone Destination Info
				# Name: Test Destination
				# Description: Provides the ability to do some cool thing.
				# Handles: NSFilenamesPboardType
				# Events: Clicked, Dragged
				# Creator: Aptonic Software
				# URL: http://aptonic.com
				# IconURL: http://aptonic.com/destinations/icons/test.png

				def dragged
				  $dz.determinate(true)
				  file_path = $items[0]
				  $dz.begin("Doing something with #{file_path}...")

				  $dz.percent(20)
				  sleep(1)
				  $dz.percent(50)
				  sleep(1)
				  $dz.percent(100)
				  sleep(1)

				  $dz.finish("Finished Task")
				  $dz.url(false)
				end

				def clicked
				  $dz.finish("You clicked me!")
				  $dz.url(false)
				end
			
To use the above script, create a new file named 'Test Destination.dropzone' with the above code and then double click it to add the destination to Dropzone. Once added to your grid, try dragging a file or folder onto the destination and Dropzone will execute the scripts dragged method. Also, try opening the grid and clicking on the destination, this will cause the scripts clicked method to be executed.

When you install a destination script by double clicking on it, Dropzone copies it to the ~/Library/Application Support/Dropzone/Destination Scripts/ directory. This is where the Dropzone user scripts and libraries live.

When testing your scripts, you can either create them somewhere else and then double click them so they get copied to the correct path or directly create them yourself in the ~/Library/Application Support/Dropzone/Destination Scripts/ directory.

Debugging Scripts

Before you try using your destination script by running it with Dropzone, you should first try running it yourself from the command line to check its output is correct.

Dropzone scripts are not run directly but are called by another script (runner.rb in the lib directory) that loads your script and then calls either the dragged or clicked method. You can simulate this and test your script as if Dropzone were running it using the following steps:

Open Terminal and cd to the lib directory:
				cd ~/"Library/Application Support/Dropzone/Destination Scripts/lib/"
			
Then you can use the Dropzone runner to load and execute your script. The below example assumes you have installed the example script in the section above.

Important: You must be in the lib directory and your script must be in ~/Library/Application Support/Dropzone/Destination Scripts/ before you try and debug it.

The below line simulates a user dragging test_file onto your destination:
				./runner.rb "Test Destination.dropzone" dragged test_file
			
You can either reference the destination script directly by name as in the above example, or by using a relative path as follows:
				./runner.rb ../"Test Destination.dropzone" dragged test_file
			
You will need to replace test_file with a real file path when debugging actual destinations.

When you run the above, it should output 'Determinate: 1' and then wait. When Dropzone calls a script, it sends a newline character to acknowledge that it has received and processed each incoming line of status output. You can simulate this by pressing return each time your script gives output. The full output you should receive from the example script is given below, this is the raw output that the Dropzone library generated. When debugging your own scripts you should make sure that your script is not producing any extra output (such as warnings or errors) and that the output closely resembles the example output below:
				Determinate: 1

				Begin_Message: Doing something with test_file...

				Progress: 20

				Progress: 50

				Progress: 100

				Finish_Message: Finished Task

				URL: 0
			
You can also simulate a user clicking on a grid destination with the following line:
				./runner.rb "Test Destination.dropzone" clicked
			
This will produce the below output:
				Finish_Message: You clicked me!

				URL: 0
			

Dropzone also provides a debugging console so that you can view the output it is receiving from your script. You can show this console by clicking 'Debugging console' in the main application menu. It can also be activated with the keyboard shortcut Command+Shift+D

The debugging console is pictured above, bolded text is information added by Dropzone and the non-bolded text is output from your script.

Managing Scripts

When you double click on a Dropzone destination script in the Finder, it is simply copied to ~/Library/Application Support/Dropzone/Destination Scripts and the below dialog is shown.

If there is already a destination script with the same filename in this folder, it is replaced. Copying scripts manually into this folder or creating them in a text editor has the same effect as installing by double clicking them. When you go to add a destination in the preferences, Dropzone looks to see which user scripts are in this folder, and parses the meta data as required.

You can edit scripts that are in your user scripts directory and the changes you make will take effect immediately - i.e. there is no need to double click your script or restart Dropzone.

You can also manage your destination scripts in the settings pane of the Dropzone preferences (pictured above). Clicking the 'Remove' button deletes the currently highlighted destination script from your user scripts directory and clicking 'Edit' opens the currently highlighted script in your default text editor.

OptionsNIBs

Some destination scripts will require additional information from the user, such as login details, API keys and folder paths in order to function correctly. Dropzone provides a way to collect this information by loading an additional interface into the 'Add Destination' panel of Dropzone. An example of this is pictured in the Destination Meta Data section, in that instance the OptionsNIB is a simple interface for selecting an application. When Dropzone executes your script, shell environment variables are set with the information collected in the OptionsNIB.

The currently available OptionsNIBs and the names of the environment variables set by them are outlined below:

Login


Field

Environment Variable

Username

ENV['USERNAME']

Password

ENV['PASSWORD']

The Login OptionsNIB also allows you to provide a title for the label that will be displayed above the view in your destination meta data. An example that shows how to do this is provided below:
				# LoginTitle: Twitter Login Details
			
If you do not specify a LoginTitle then the label title will default to 'Login Details'

ExtendedLogin


Field

Environment Variable

Server

ENV['SERVER']

Port

ENV['PORT']

Username

ENV['USERNAME']

Password

ENV['PASSWORD']

Remote Path

ENV['REMOTE_PATH']

Root URL

ENV['ROOT_URL']

The 'Test Connection' button is only shown if you have specified in your destination meta data that your script responds to the TestConnection event.

ChooseApplication


Environment Variable

Description

ENV['EXTRA_PATH']

Full path to the selected application

ChooseFolder


Environment Variable

Description

ENV['EXTRA_PATH']

Full path to the selected folder

This is an area of Dropzone that is under active development - a system whereby you can design and package your own OptionNIBs along with your destination for Dropzone to load is planned.

Key Modifiers



If the user holds down a modifier key while dragging items onto your destination and you have specified in your scripts meta data that the modifier key is supported then the symbol for the held modifier is overlaid on your destination as shown above and the ENV["KEY_MODIFIERS"] environment variable is set with the currently held modifier for your script to access. You can specify that your script supports multiple key modifiers by specifying each supported modifier delimited by a comma, however, only one key modifier may be used at a time.

A working example that displays the currently held modifier when an item is dragged onto it is given below:
				#!/usr/bin/ruby

				# Dropzone Destination Info
				# Name: Key Modifier Test
				# Description: Displays the currently held key modifier.
				# Handles: NSFilenamesPboardType
				# Events: Dragged
				# KeyModifiers: Command, Option, Control, Shift
				# Creator: Aptonic Software
				# URL: http://aptonic.com
				# IconURL: http://aptonic.com/destinations/icons/test.png

				def dragged
				  $dz.finish((ENV["KEY_MODIFIERS"] == "" ? "None" : ENV["KEY_MODIFIERS"]))
				  $dz.url(false)
				end
			

Errors & Alerts

You can instruct Dropzone to display an alert or error dialog from your script as shown below:

Display Alert
				$dz.alert("Alert Title", "Some informative text...")
			
Display Error
				$dz.error("Error Title", "An error occurred...")
			

$dz.error results in your script terminating immediately while $dz.alert allows you to display a message and then continue execution of your script.

Copying Files

As copying files is a common thing to need to do in a Dropzone destination script - e.g. to resize some images and then copy them to a folder, a ruby library is provided by Dropzone that handles this for you. An advantage of using the Rsync library to copy files is that it also prompts the user to cancel or replace if a file they are copying already exists at the destination. This library is automatically loaded for you by the runner script.

You can call it as follows:
				Rsync.do_copy(files, destination, remove_sent)
			
Files is an array of file and/or folder paths to copy, destination is the path to the destination folder and remove_sent is a boolean value that indicates whether files and directories at the source should be deleted after copying. A working destination script that shows how to make use of this is given below:
				#!/usr/bin/ruby

				# Dropzone Destination Info
				# Name: Copy Files
				# Description: Allows you to copy dropped files to a specified folder.
				# Handles: NSFilenamesPboardType
				# Creator: Aptonic Software
				# URL: http://aptonic.com
				# OptionsNIB: ChooseFolder

				def dragged
				  $dz.determinate(true)
				  $dz.begin("Copying files...")

				  Rsync.do_copy($items, ENV['EXTRA_PATH'], false)

				  $dz.finish("Copy Complete")
				  $dz.url(false)
				end
			
The Dropzone Rsync library makes calls to $dz.percent for you so progress information is output to Dropzone during the copy. Therefore, you should always call $dz.determinate(true) as demonstrated above before you call the Rsync.do_copy method.

Using CocoaDialog

CocoaDialog is an OS X application that allows the use of common GUI controls such as file selectors, text input, progress bars, yes/no confirmations and more with a command-line application. You can learn more about how to use CocoaDialog here. CocoaDialog has many possible applications in a Dropzone destination script, for example, the 'Create new file with text' destination that ships with Dropzone uses CocoaDialog to popup a dialog box to get the desired filename.

CocoaDialog is bundled with Dropzone and can be run from your destination script as follows:
				output = `./CocoaDialog standard-inputbox --title "New Text File" --e --informative-text "Enter name for new text file (minus extension):"`
				filename = output.split("\n")[1]
			
The above example would produce the following dialog and store the result in filename.

Contributing

Dropzone destination scripts are managed via the github repositories.
If you wish to contribute a user destination script you should fork the dropzone-user-scripts repository, add your script and then send a pull request. The same applies to the Dropzone bundled scripts.

If you have any feedback regarding the API, you can email us at contact@aptonic.com