Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass path names to Python script by "dropping" files/folders over script icon

Tags:

python

macos

I am working in Mac OS X and have been writing simple file/folder copy scripts in Python. Is there a way to drag and drop a folder on top of a Python script icon and pass the file or folder's path as an argument in the script?

Currently, I have an AppleScript droplet (which supports drag and drop) that passes the paths of dropped folders and files to Python. However, I would like to have just one Python script instead of an AppleScript and a Python script.

Any help would be greatly appreciated.

like image 563
John1538 Avatar asked Nov 18 '11 16:11

John1538


2 Answers

Just use the "Build Applet" utility:

/Developer/Applications/Utilities/MacPython\ 2.5/Build\ Applet.app

and the dropped file paths will be available thru sys.argv.

Note that you may have to use Python2.5 (or a patched version) -- See this note: https://bitbucket.org/ronaldoussoren/py2app/issue/16/argv-emulation-code-needs-rewrite

Quick example -- edit this file and put it on your desktop:

#!/usr/bin/python2.5
import sys
print sys.argv

Control-click on it, and select open with "Build Applet (2.5.4)"

App icon will appear on desktop.

Open Console Utility & clear display.

Drop some files onto App icon -- you'll see the print in the console window.

like image 166
Steven D. Majewski Avatar answered Oct 09 '22 15:10

Steven D. Majewski


What you might really like is Mac OS Services. They are Automator workflows which can nicely integrate into the operating system in a context-specifc manner: e.g. you can make your script appear in Finder's context menu when you select a folder.

You can make a service from python script in following way:

  1. Open Automator.app and create a new Service;
  2. On top of workflow block you select what kind of input your application expects (folders is your choice if I understand correctly);
  3. Drag "Run Shell Script" block from left pane into workflow;
  4. Now you can either use default bash shell (/bin/bash) to call your script:

    /full/path/to/your/python /full/path/to/your/script.py $@
    

  5. Or use /usr/bin/python (default python) and paste your code directly into text block;

  6. Don't forget to set Pass input: as arguments in top right corner of the block.

It's a little bit tricky to debug such workflows (as you won't see stdout & stderr). Possible workaround for debugging is to setup custom excepthook and output all exceptions into some plain text file:

import sys, traceback

def excepthook(type, exc, tb):
    with open("error.log", "a") as f:
        traceback.print_exc(file=f)

sys.excepthook = excepthook
like image 27
Denys Shabalin Avatar answered Oct 09 '22 14:10

Denys Shabalin