views:

148

answers:

3

I didn't think this would be as tricky as it turned out to be, but here I am. I'm trying to write a Nautilus script in Python to upload one or more images to Imgur just by selecting and right clicking them. It works well enough with both single images and multiple images - as long as they don't contain any whitespace. In fact, you can upload a single image containing whitespace, just not multiple ones.

The problem is that NAUTILUS_SCRIPT_SELECTED_FILE_PATHS returns all the selected files and directories as a space separated string. So for example, it could look like this:

print os.environment['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS']
/home/nevon/Desktop/test image.png /home/nevon/Desktop/test.jpg

What I need is a way to -either in bash or Python- escape the spaces in the path - but not the spaces that delimit different items. Either that, or a way to put quotation marks around each item.

The ultimate solution would be if I could do that in bash and then send the items as separate arguments to my python script. Something like:

python uploader.py /home/nevon/Desktop/test\ image.png /home/nevon/Desktop/test.jpg

I've tried RTFM'ing, but there doesn't seem to be a lot of good solutions for this. At least not that I've found. Any ideas?

A: 

I think that $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS should be newline delimited, not space delimited. In that case, the following should work from bash:

echo -e $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS | xargs python uploader.py 
fmark
That's what I've read too, but here's the output I get from echo -e $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS > output/home/nevon/Desktop/test image.png /home/nevon/Desktop/test.gif
Tommy Brunn
Eh, I guess the comments don't allow for paragraphs. Anyway, despite what the docs say, it's a space delimited list. Your suggestion didn't work, sadly.
Tommy Brunn
I'm flagging this as correct. At first it didn't work, but now suddenly it does. I'm not sure what I did wrong the first time, but it works now. I did have to do: echo -e $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS | xargs --delimiter="\n" python uploader.pyBut now it works!
Tommy Brunn
you've got to admire the bravery of using an answer while having no idea how it works, kudos!
msw
A: 

I can't test this as I'm at a Windows machine, but have you tried using $NAUTILUS_SCRIPT_SELECTED_FILE_URIS instead? Then, in python you could get the paths with something like:

[f.strip() for f in os.environment['NAUTILUS_SCRIPT_SELECTED_FILE_URIS'].split('file://') if len(f) > 0]
fmark
A: 

Skipping one level of evaluation shows that the nautilus documentation is incomplete and that there is a better way much less subject to who-knows-how-many levels of interpretation. Nautilus passes selected files as script arguments:

$ cat ~/.gnome2/nautilus-scripts/arguments.sh
#!/bin/sh
rm -f /tmp/arguments.*
outf=/tmp/arguments.$$
echo "$0: $#" > $outf
while [ $# -gt 0 ] ; do
    echo "$1"
     if [ ! -r $1 ] ; then echo "cwd is not correct"; fi
    shift
done >> $outf
echo paths $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS >> $outf
for i in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ; do
    echo "+$i+"
done >> $outf

I sent the output to /tmp since I didn't want to hunt for the stdout. Given:

$ ls -1
a
b
c with space
d
e with space
g

Select all the files in the directory and Scripts->arguments.sh yields:

$ cat /tmp/arguments.20447 
/home/msw/.gnome2/nautilus-scripts/arguments.sh: 6
a
b
c with space
d
e with space
g
paths /home/msw/junk/a /home/msw/junk/b /home/msw/junk/c with space 
  /home/msw/junk/d /home/msw/junk/e with space 
  /home/msw/junk/g
+/home/msw/junk/a+
+/home/msw/junk/b+
+/home/msw/junk/c+
+with+
+space+
+/home/msw/junk/d+
+/home/msw/junk/e+
+with+
+space+
+/home/msw/junk/g+

Could I have quoted $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS to avoid this? Sure. I didn't to demonstrate that how many levels of interpolation with the variable is questionable, but argv stays unmolested.

Use argv (or sys.argv in Python) and save some headache. Also the documented semantics of the environment variables is weird.

msw