Difference between revisions of "Tutorial: Simple Drobox-Based Server for iPad/iPhone"

From dftwiki3
Jump to: navigation, search
(Step 2: Control the Script with launchd)
 
(27 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
----
 
----
 
<br />
 
<br />
 +
{| width="100%"
 +
| style="width: 60%;" |
 
__TOC__
 
__TOC__
 +
| style="width: 40%;" |
 +
[[image:dropboxLogo.png|200px]]
 +
|}
 +
 
<br />
 
<br />
 
<bluebox>
 
<bluebox>
 
The purpose of this tutorial is to setup a simple server to process photographs taken on a mobile device.  Two devices must be linked by a shared Dropbox folder: a Mac running iOS and working as the server, and a mobile device on which the Dropbox app is installed.  Whenever a new photo is deposited in the shared Dropbox folder on the mobile device, the image is replicated in the Mac's local Dropbox folder, and an iOS launchd process is automatically called to process the image and generate some new version of it.  The resulting new version is automatically replicated in the Dropbox folder on the mobile device.  Et voilà! <br />This type of setup can easily be modified to work in cases where programming in php/javascript is not possible or easy.  The advantage of the method presented here is that the launchd script is run with the same privileges as the user, and has access to the the whole set of executable and file systems available to the logged in user.
 
The purpose of this tutorial is to setup a simple server to process photographs taken on a mobile device.  Two devices must be linked by a shared Dropbox folder: a Mac running iOS and working as the server, and a mobile device on which the Dropbox app is installed.  Whenever a new photo is deposited in the shared Dropbox folder on the mobile device, the image is replicated in the Mac's local Dropbox folder, and an iOS launchd process is automatically called to process the image and generate some new version of it.  The resulting new version is automatically replicated in the Dropbox folder on the mobile device.  Et voilà! <br />This type of setup can easily be modified to work in cases where programming in php/javascript is not possible or easy.  The advantage of the method presented here is that the launchd script is run with the same privileges as the user, and has access to the the whole set of executable and file systems available to the logged in user.
 +
''Caveat'': Your iOS device '''must be connected''' to the Internet (wifi) in order for it to communicate with the OSX server.
 
</bluebox>
 
</bluebox>
 +
<br />
 
<br />
 
<br />
 
=Overview=
 
=Overview=
 
<br />
 
<br />
 +
<center><videoflash>xy56BJTccVw</videoflash></center>
 +
<br />
 +
<br />
 +
<br />
 +
 
<center>[[Image:SimpleServerDropboxiPad.png|600px]]</center>
 
<center>[[Image:SimpleServerDropboxiPad.png|600px]]</center>
 
<br />
 
<br />
Line 18: Line 31:
  
 
<br />
 
<br />
 +
 
=Step 1: Create a Bash Script to Process the Image=
 
=Step 1: Create a Bash Script to Process the Image=
 
<br />
 
<br />
 
This step should be performed on your Mac/OSX machine.
 
This step should be performed on your Mac/OSX machine.
  
The first step is create a regular bash script that checks for the presence of a file in a given Dropbox folder, say '''inputDir''', and if found, creates a monochrome version that is stored in a different Dropbox folder, say '''outputDir'''.  The original file is removed from '''inputDir''' to prevent an endless processing of the file.
+
The first step is create a regular bash script that checks for the presence of a file in a given Dropbox folder, say '''inputDir''', and if it finds one, creates a monochrome version that is stored in a different Dropbox folder, say '''outputDir'''.  The original file is removed from '''inputDir''' to prevent an endless processing of the file.
 +
 
 +
We use [http://www.imagemagick.org/ ImageMagick]'s '''convert''' utility to perform the black-and-white transformation.  Make sure ImageMagick is installed on your system (or use another application that will perform a similar operation).
 +
<br />
 
==Source Code==
 
==Source Code==
 
<br />
 
<br />
 
Here's a the script, below:
 
Here's a the script, below:
 
<br />
 
<br />
<source lang="bash" highlight="9-11">
+
<source lang="bash" highlight="9-10,19">
 
#! /bin/bash
 
#! /bin/bash
 
# makeMonochrome.sh
 
# makeMonochrome.sh
Line 38: Line 55:
 
inputDir=/whereEverYourDropboxFolderIsLocated/Dropbox/inputDir
 
inputDir=/whereEverYourDropboxFolderIsLocated/Dropbox/inputDir
 
outputDir=/whereEverYourDropboxFolderIsLocated/Dropbox/outputDir
 
outputDir=/whereEverYourDropboxFolderIsLocated/Dropbox/outputDir
log=/WhereEverYouWantToSaveTheLog/log.txt
 
  
 +
# if this script is already currently running then exit.  Only one script should be active at a time.
 +
if ! mkdir /tmp/makeMonochrome.lock  2>/dev/null; then
 +
    exit 1
 +
fi
  
# if there's a file in the inputDir folder, process it, then remove it
+
# set log to /dev/null if you do not want to record debugging information, or
if ls ${inputDir}/*  &> /dev/null; then
+
# once your script has been fully debugged
 +
log=/WhereEverYouWantToSaveTheLog/log.txt
 +
date > $log
  
    date > $log
+
# while there's a file in the inputDir folder, process it, then remove it
 +
while ls ${inputDir}/*  &> /dev/null; then
  
 
     file=`ls -1 ${inputDir}/* | head -1`
 
     file=`ls -1 ${inputDir}/* | head -1`
 
     basename=${file##*/}
 
     basename=${file##*/}
 
     newFile=${outputDir}/BW_${basename}
 
     newFile=${outputDir}/BW_${basename}
    echo "file    = $file" >> $log
 
    echo "newFile = $newFile" >> $log
 
 
     echo "convert $file -monochrome $newFile" >> $log
 
     echo "convert $file -monochrome $newFile" >> $log
  
 
     # transform to black and white
 
     # transform to black and white
     convert $file -monochrome $newFile
+
     convert "$file" -monochrome "$newFile"
  
 
     # remove the file from the inputDir
 
     # remove the file from the inputDir
     rm $file
+
     rm "$file"
 +
fi
 +
 
 +
#--- record end of operations ---
 +
echo "makeMonochrome.sh done!" >> $log
 +
date >> $log
  
    echo "makeMonochrome.sh done!" >> $log
+
#--- remove lock so that the script can run as a singleton again---
    date >> $log
+
rmdir /tmp/makeMonochrome.lock
  
fi
 
 
</source>
 
</source>
 
<br />
 
<br />
Line 77: Line 102:
 
<br />
 
<br />
 
<br />
 
<br />
 +
 
=Step 2: Control the Script with '''launchd'''=
 
=Step 2: Control the Script with '''launchd'''=
 
<br />
 
<br />
Line 87: Line 113:
 
Run this command and copy the list of paths generated:
 
Run this command and copy the list of paths generated:
 
   
 
   
  echo $PATH
+
  <u>echo $PATH</u>
 +
/opt/local/bin:/opt/local/sbin: . . .  /sw/bin:/sw/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
 
   
 
   
Save the resulting string in a safe place.
+
Save the resulting long string (do not use the one above, it is incomplete and won't work for you) in a safe place.
 
<br />
 
<br />
 
Create a new file, called '''makeMonochrome.plist''' with the code shown below:
 
Create a new file, called '''makeMonochrome.plist''' with the code shown below:
 
<br />
 
<br />
<source lang="xml">
+
<br />
 +
<br />
 +
<source lang="xml" highlight="9,16,20,22,27">
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
Line 127: Line 156:
 
</source>
 
</source>
 
<br />
 
<br />
 +
Make sure you edit the file above with information relevant to your directory system, and paste your environment path in the '''PATH''' key string (last highlighted line above).
 +
<br />
 +
==Activate the Launchd Script==
 +
<br />
 +
Activation is very simple at this point.  Assuming that you are in terminal and in the same directory where '''makeMonochrome.plist''' is located, simply type:
 +
 +
launchctl load  makeMonochrome.plist
 +
 +
If you get no output after you press ENTER, then everything worked fine!
 +
 +
If, however, you get some error message of some sort, for example:
 +
 +
''launchctl: no plist was returned for: makeMonochrome.plist''
 +
''launchctl: no plist was returned for: makeMonochrome.plist ''
 +
''nothing found to load''
 +
 +
then check the syntax of your plist file with this command:
 +
 +
plutil -lint makeMonochrome.plist
 +
 +
This should point to a possible syntax error in your file.
 +
<br />
 +
 +
=Testing=
 +
<br />
 +
Simply copy an image file in the '''inputDir''' folder of your '''Dropbox''' and see it quickly disappear once a black and white version of it will have been created in the '''outputDir''' folder of '''Dropbox'''.  Verify that the black-and-white file is indeed there.
 +
 +
That's it!
 +
 +
You can now use your iPad and load images in the '''inputDir''' folder of your '''Dropbox''' app and get their black and white version available a few seconds later in the '''outputDir''' folder.
 
<br />
 
<br />
 +
=Miscellaneous Comments=
 
<br />
 
<br />
 +
This setup is attractive in situations where files captured or generated on a mobile device must be processed by applications that run only on OSX devices, or require significant processing time that a multicore computer can help with.  Below are some possible applications for which this setup can prove useful. 
 +
 +
Remember, though, that this setup uses the ''privacy''  of one user's shared Dropbox folders on separate devices, that the the OSX machine must be ON, and that the user must be logged in to this machine while using the mobile device.  The security of this setup is linked to the security provided by Dropbox, and the security of the OSX machine.
 
<br />
 
<br />
 +
==Possible applications==
 
<br />
 
<br />
 +
* Processing of images using '''ImageMagick's convert''' utility.  See [http://www.imagemagick.org/Usage/ this URL] or [http://www.imagemagick.org/Usage/annotating/ this one] for examples of image processing with '''convert'''.  Modifications include:
 +
** adding borders to images
 +
** creating masks over images
 +
** annotating images
 +
** labeling images
 +
** adding watermarks
 +
** changing the colors
 +
** merging the image with a background image
 +
* Taking the image dropped in the input folder and storing it in various repositories:
 +
** in Amazon's S3 storage
 +
** in a MySQL database
 +
** automatically posted on a Web page
 +
** sent via email
 +
* Placing images taken by the mobile device into the Dropbox folder for remote processing of its metadata, including its geolocation, and overlaying a thumbnail map on top of the image.
 +
* Getting the OSX server to execute the contents of the file dropped in the DropBox folder.  This could be dangerous, so make sure you know what you are doing if doing this.  But one could imagine making the server execute a bash file, or take a picture with its connected Webcam, or [https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/say.1.html "say"] something.
 
<br />
 
<br />
 
<br />
 
<br />
Line 145: Line 224:
 
<br />
 
<br />
 
<br />
 
<br />
[[Category:Tutorials]]
+
[[Category:Tutorials]][[Category:Dropbox]]

Latest revision as of 14:56, 23 May 2014

--D. Thiebaut (talk) 12:12, 20 May 2014 (EDT)



DropboxLogo.png


The purpose of this tutorial is to setup a simple server to process photographs taken on a mobile device. Two devices must be linked by a shared Dropbox folder: a Mac running iOS and working as the server, and a mobile device on which the Dropbox app is installed. Whenever a new photo is deposited in the shared Dropbox folder on the mobile device, the image is replicated in the Mac's local Dropbox folder, and an iOS launchd process is automatically called to process the image and generate some new version of it. The resulting new version is automatically replicated in the Dropbox folder on the mobile device. Et voilà!
This type of setup can easily be modified to work in cases where programming in php/javascript is not possible or easy. The advantage of the method presented here is that the launchd script is run with the same privileges as the user, and has access to the the whole set of executable and file systems available to the logged in user. Caveat: Your iOS device must be connected to the Internet (wifi) in order for it to communicate with the OSX server.



Overview





SimpleServerDropboxiPad.png


This is the scenario we want to implement

  1. we put a picture in a a Dropbox folder on our mobile device. Here we assume that the mobile device is an iPad but the idea would work on any mobile device where a Dropbox app is running.
  2. Dropbox automatically syncs the picture onto a Dropbox folder on an OSX computer. We assume that the same user is logged in the two devices, the iPad and the OSX computer, so that the two Dropbox folders are automatically synchronized.
  3. Once the file appears in the OSX computer, a launchd script discovers it and processes it in some way. For this tutorial we will simply generate a black and white version of it. This new image is automatically synchronized and replicated in the iPad's Dropbox folder.


Step 1: Create a Bash Script to Process the Image


This step should be performed on your Mac/OSX machine.

The first step is create a regular bash script that checks for the presence of a file in a given Dropbox folder, say inputDir, and if it finds one, creates a monochrome version that is stored in a different Dropbox folder, say outputDir. The original file is removed from inputDir to prevent an endless processing of the file.

We use ImageMagick's convert utility to perform the black-and-white transformation. Make sure ImageMagick is installed on your system (or use another application that will perform a similar operation).

Source Code


Here's a the script, below:

#! /bin/bash
# makeMonochrome.sh
# D. Thiebaut
# checks the Dropbox folder's iPad directory inputDir
# for an image file. When found, transforms it to 
# black and white and saves the resulting version in 
# outputDir

inputDir=/whereEverYourDropboxFolderIsLocated/Dropbox/inputDir
outputDir=/whereEverYourDropboxFolderIsLocated/Dropbox/outputDir

# if this script is already currently running then exit.  Only one script should be active at a time.
if ! mkdir /tmp/makeMonochrome.lock  2>/dev/null; then
    exit 1
fi

# set log to /dev/null if you do not want to record debugging information, or
# once your script has been fully debugged
log=/WhereEverYouWantToSaveTheLog/log.txt
date > $log

# while there's a file in the inputDir folder, process it, then remove it
while ls ${inputDir}/*  &> /dev/null; then

    file=`ls -1 ${inputDir}/* | head -1`
    basename=${file##*/}
    newFile=${outputDir}/BW_${basename}
    echo "convert $file -monochrome $newFile" >> $log

    # transform to black and white
    convert "$file" -monochrome "$newFile"

    # remove the file from the inputDir
    rm "$file"
fi

#--- record end of operations ---
echo "makeMonochrome.sh done!" >> $log
date >> $log

#--- remove lock so that the script can run as a singleton again---
rmdir /tmp/makeMonochrome.lock


The script is self explanatory. Make sure to replace the paths of inputDir, outputDir and log with valid paths on your system.

Testing


Make the script executable:

chmod +x makeMonochrome.sh

Then put a jpg or png file in the inputDir folder. Run the makeMonochrome.sh script from the command line. Verify that the result is a new file prefixed with BW_ in the outputDir folder of Dropbox.

Step 2: Control the Script with launchd


Mac OS/X supports a feature-rich system for launching scripts when various conditions occur. It is called launchd. A good tutorial on this system can be found here.
To create a launchd script requires very meticulous setup, and careful attention to details. The setup must be stored in a plist file in the user's ~/Library/LaunchAgents directory on the OS/X machine. We'll call this file makeMonochrome.plist.
One of the recurring problems with launchd scripts is that these scripts are run by the OS with the user's privileges, but without logging into the system, or using the user's environment. As a result, a script that runs perfectly fine from the command line may not run correctly as a launchd script because the launchd script gets a different default path. So we have to assign to the launchd script the user's default path.
Run this command and copy the list of paths generated:

echo $PATH
/opt/local/bin:/opt/local/sbin: . . .  /sw/bin:/sw/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Save the resulting long string (do not use the one above, it is incomplete and won't work for you) in a safe place.
Create a new file, called makeMonochrome.plist with the code shown below:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
 	 <string>make.Monochrome</string>

        <key>Program</key>
         <string>/whatEverDirectoryYouScriptSitsIn/makeMonochrome.sh</string>

        <key>KeepAlive</key>
         <false/>

        <key>WatchPaths</key>
         <array>
           <string>/WhateverDirectionYourDropboxFolderSitsIn/Dropbox/inputDir</string>
         </array>

        <key>StandardOutPath</key>
         <string>/UseTheSamePathSpecifiedInMakeMonochrome.sh/log.txt</string>
        <key>StandardErrorPath</key>
         <string>/UseTheSamePathSpecifiedInMakeMonochrome.sh/log.txt</string>

        <key>EnvironmentVariables</key>
         <dict>
           <key>PATH</key>
            <string>pasteHereTheLongPathStringGeneratedInTheStepAbove</string>
         </dict>

</dict>
</plist>


Make sure you edit the file above with information relevant to your directory system, and paste your environment path in the PATH key string (last highlighted line above).

Activate the Launchd Script


Activation is very simple at this point. Assuming that you are in terminal and in the same directory where makeMonochrome.plist is located, simply type:

launchctl load  makeMonochrome.plist

If you get no output after you press ENTER, then everything worked fine!

If, however, you get some error message of some sort, for example:

launchctl: no plist was returned for: makeMonochrome.plist
launchctl: no plist was returned for: makeMonochrome.plist 
nothing found to load

then check the syntax of your plist file with this command:

plutil -lint makeMonochrome.plist

This should point to a possible syntax error in your file.

Testing


Simply copy an image file in the inputDir folder of your Dropbox and see it quickly disappear once a black and white version of it will have been created in the outputDir folder of Dropbox. Verify that the black-and-white file is indeed there.

That's it!

You can now use your iPad and load images in the inputDir folder of your Dropbox app and get their black and white version available a few seconds later in the outputDir folder.

Miscellaneous Comments


This setup is attractive in situations where files captured or generated on a mobile device must be processed by applications that run only on OSX devices, or require significant processing time that a multicore computer can help with. Below are some possible applications for which this setup can prove useful.

Remember, though, that this setup uses the privacy of one user's shared Dropbox folders on separate devices, that the the OSX machine must be ON, and that the user must be logged in to this machine while using the mobile device. The security of this setup is linked to the security provided by Dropbox, and the security of the OSX machine.

Possible applications


  • Processing of images using ImageMagick's convert utility. See this URL or this one for examples of image processing with convert. Modifications include:
    • adding borders to images
    • creating masks over images
    • annotating images
    • labeling images
    • adding watermarks
    • changing the colors
    • merging the image with a background image
  • Taking the image dropped in the input folder and storing it in various repositories:
    • in Amazon's S3 storage
    • in a MySQL database
    • automatically posted on a Web page
    • sent via email
  • Placing images taken by the mobile device into the Dropbox folder for remote processing of its metadata, including its geolocation, and overlaying a thumbnail map on top of the image.
  • Getting the OSX server to execute the contents of the file dropped in the DropBox folder. This could be dangerous, so make sure you know what you are doing if doing this. But one could imagine making the server execute a bash file, or take a picture with its connected Webcam, or "say" something.