Photo diary

DIY Photo Sharing

Article from Issue 155/2013
Author(s):

Instead of relying on a third-party service for instant photo sharing, you can build your own solution using existing software and a pinch of PHP and Python scripting.

Google+, Instagram, EyeEm  – services for instant photo sharing – are plentiful. However, the broad choice of photo sharing services doesn't mean you can't build your own photo-sharing solution. In fact, if you are not fond of the idea that third-party services harvest and datamine your accounts, as well as use your photos for their own purposes, then going the DIY route makes a lot of sense.

Privacy concerns, however, are just one reason for deploying a home-brewed solution. By building your own instant photo-sharing application, you can focus on the features that are important to you, leaving out all the unnecessary embellishments. Creating your own app is also an excellent opportunity to master some basic scripting skills and write code that you can later reuse in other projects.

Building your own instant photo-sharing system doesn't have to be as daunting as it may sound, provided you are interested in creating a utilitarian solution rather than an Instagram killer. In this article, I'll guide you through the process of building a no-frills instant photo-sharing system that uses existing software and requires only a minimum of scripting. Creating and setting up the entire solution shouldn't take more than a couple of hours, which makes it a perfect project for a rainy weekend.

Preparatory Work

Before you get down to the nitty-gritty, you have to do some preparatory work. Because the Photocrumbs app relies on existing software, you must install several key components on your Android device and a Linux server. On the Android device, you have to install two pieces of software: Scripting Layer for Android (SL4A) and Python for Android [1]. These two components add Python scripting capabilities to Android (Figure 1).

Figure 1: Photocrumbs' building blocks.

For the Linux server, you have to install the Apache HTTP server, PHP, and the ProFTPD FTP server. To do this on Debian-based Linux distributions, run

apt-get install apache2 php5 proftpd

as root. Next, grab Photocrumbs' source code from the project's GitHub repository [2]. If you have Git installed on your system, you can do that by cloning the repository with

git clone git@github.com:dmpop/photocrumbs.git

Open the photocrumbs.py Python script in a text editor and specify the correct server, username, and password values. Save the changes and move the script to the sl4a/scripts directory on your Android device. Then, move the entire photocrumbs directory to the root of your server and make the photocrumbs/photos directory writable with the chmod 774 -R photos command.

Next, you need to tweak the ProFTPD configuration. On the server, open the /etc/proftpd/proftpd.conf configuration file in a text editor, locate the DefaultRoot parameter, and modify it as follows:

DefaultRoot     /var/www/photocrumbs/photos

(Note that the exact path depends on the actual root directory of your server and the default directory for storing photos.) Then, restart the ProFTPD server by running the

/etc/init.d/proftpd restart

command as root. Changing the DefaultRoot parameter ensures that any FTP connection is automatically routed to the specified directory.

Finally, you have to make the server accessible from the Internet, so you can establish an FTP connection. To do this, you need to configure port forwarding on your router. Consult the documentation supplied with the router to find out the exact port forwarding procedure.

How Photocrumbs Works

The core of the Photocrumbs server application is a relatively simple PHP script (Listing 1), which pulls files with the .jpg file extension from a specified directory and displays them as a single-page stream. The script performs several other operations, too. It reads the values of the $title, $tagline, and $footer variables from the config.php file and inserts them into the page.

Listing 1

The index.php Script

01 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
02 <html>
03   <head>
04   <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
05   <link href="style.css" rel="stylesheet" type="text/css" media="all" />
06   <link href='http://fonts.googleapis.com/css?family=Asap:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
07   <link rel="shortcut icon" href="favicon.ico" />
08   <?php
09   include 'config.php';
10   echo "<title>$title</title>";
11   echo "</head>";
12   echo "<body>";
13   echo "<div id='content'><h1>$title</h1>";
14   echo "<div class='center'>$tagline</div>";
15   $f = $_GET['f'];
16   if (empty($f))
17     {
18     $dir=$basedir;
19     }
20   else
21     {
22     $dir=$basedir.$f."/";
23     }
24   $files = glob($dir.'*.jpg', GLOB_BRACE);
25   $fileCount = count(glob($dir.'*.jpg'));
26   for ($i=($fileCount-1); $i>=0; $i--)  {
27     $exif = exif_read_data($files[$i], 0, true);
28     $filepath = pathinfo($files[$i]);
29     echo "<h2>".$filepath['filename']."</h2>";
30     echo "<p>";
31     include $dir.$filepath['filename'].'.php';
32     echo "</p>";
33     echo '<a href="'.$files[$i].'"><img class="dropshadow" src="'.$files[$i].'" alt="" width="500px"></a>';
34     $Fnumber = explode("/", $exif['EXIF']['FNumber']);
35     $Fnumber = $Fnumber[0] / $Fnumber[1];
36     echo "<p class='box'>Aperture: f/".$Fnumber." Shutter speed: " .$exif['EXIF']['ExposureTime']. " ISO: ".$exif['EXIF']['ISOSpeedRatings']. " Date: ".$exif['EXIF']['DateTimeOriginal']."</p>";
37   }
38   echo "<div class='footer'>$footer</div>";
39   ?>
40   </div>
41   </body>
42 </html>

The exif_read_data() routine reads EXIF data from each photo (aperture, shutter speed, ISO, and date); other statements take care of parsing the obtained values and displaying them on the page. By default, the script pulls photos from a directory specified in the config.php file. However, it can also display photos from a specific subfolder inside the default directory by reading the $f variable from the entered URL.

Another key part of the Photocrumbs system is the photocrumbs.py Python script on the Android device. The basic version of the script (Listing 2) performs three operations: It captures a photo, prompts the user to enter a short note, and then uploads both parts to the server via FTP. The script also saves the captured photo and the accompanying note in the photocrumbs directory on the Android device (if the directory doesn't exist, the script creates it).

Listing 2

Photocrumbs.py Python Script

01 import android, time, os, ftplib
02 server = '127.0.0.1'
03 username = 'username'
04 password = 'password'
05 droid = android.Android()
06 if not os.path.exists('/sdcard/photocrumbs/'):
07        os.makedirs('/sdcard/photocrumbs/')
08 timestamp = time.strftime('%Y%m%d-%H%M%S', time.localtime())
09 droid.cameraInteractiveCapturePicture('/sdcard/photocrumbs/' + timestamp + '.jpg')
10 notetext = droid.dialogGetInput('Note', 'Add a note to the photocrumb:').result
11 note = timestamp + '.php'
12 file = open('/sdcard/photocrumbs/' + note, 'a')
13 file.write('%s\n' % (notetext))
14 file.close()
15 droid.dialogCreateSpinnerProgress('Uploading to FTP...')
16 droid.dialogShow()
17 conn = ftplib.FTP(server, username, password)
18 file = open ('/sdcard/photocrumbs/' + timestamp + '.jpg', 'rb')
19 conn.storbinary('STOR ' + timestamp + '.jpg', file)
20 file.close()
21 file = open ('/sdcard/photocrumbs/' + note, 'rb')
22 conn.storbinary('STOR ' + note, file)
23 file.close()
24 conn.quit()
25 droid.notify('Photocrumbs', 'Upload completed.')
26 droid.dialogDismiss()

Using and Tweaking Photocrumbs

Thanks to its simple design, Photocrumbs is very simple to use. All you have to do is run the photocrumbs.py script on your Android device, snap a photo, enter a note, and upload both to the server. To launch a script on Android, you need to open the SL4A app first and select the item you want from the list of available scripts. Although that additional step is not particularly complicated, it can quickly become a nuisance.

Fortunately, the SL4A app lets you add a homescreen widget for launching the script with a single tap (Figure 2). To add the widget, long-click on the SL4A Scripts item in the Widgets section (how you access it depends on your specific Android device) and drag the item onto the homescreen. Then, select the photocrumbs.py script, and you are done.

Figure 2: To speed up access to the script, you can create a homescreen widget for it.

By default, the PHP script running on the server obtains the path to the directory containing photos from the config.php file. However, you can point the script to a specific subfolder inside the default directory using the $f variable in the URL. For example, if you want to view photos stored in the photos/tokyo subdirectory, the URL should be as follows (replace <127.0.0.1> with the actual IP address or domain name of your server):

http://<127.0.0.1>/photocrumbs./index.php?f=tokyo

This simple feature can be useful for keeping your photocrumbs neatly organized into folders (Figure 3).

Figure 3: Photocrumbs in all its bare-bones beauty.

The Python script in Listing 2 pushes snapshots and notes to the FTP server without a prompt. This setup can be problematic when either the Android device doesn't have a fast and reliable connection or data transfer is too expensive (or when you prefer to edit photos before uploading them). To fix this, you might want to tweak the script to ask whether or not it should upload the captured snap and the accompanying note. This change can be made using a couple of Android-specific Python routines and the if...else condition. Look at the photocrumbs.py script in the Photocrumbs repository to see how this functionality has been implemented. Alternatively, you can create two versions of the script in Listing 2: one with FTP upload and the other without. This way, you can run the appropriate script depending on the situation.

In the original version of photocrumbs.py, the FTP connection variables are hard-wired into the script. However, you can also store the connection info in a separate configuration file and point the script to it. To do so, create a config.ini file, which should look something like this,

[ftp]
server = 127.0.0.1
username = foo
password = pass

then add the following code to the photocrumbs.py script

from ConfigParser import SafeConfigParser
parser = SafeConfigParser()
parser.read('config.ini')

and modify the FTP connection variables as follows:

server = parser.get('ftp', 'server')
username = parser.get('ftp', 'username')
password = parser.get('ftp', 'password')

Because Photocrumbs' PHP script can display photos stored in a subdirectory by reading the $f variable in the URL, you can also add the subdir =subdirname/ configuration option (note the trailing slash) to the config.ini file and modify the conn.storbinary statement in the photocrumbs.py script as follows:

conn.storbinary('STOR ' + subdir + timestamp + '.jpg', file)
conn.storbinary('STOR ' + subdir + note, file)

In this way, you can point the script to a specific directory on the fly. Make sure, though, that the specified subdirectory exists on the server. Also, make sure the config.ini file is saved in the sl4a directory and not in sl4a/scripts. If you choose not to upload snaps and notes using the script, then you will need to do that later. Plenty of third-party apps can be used for that purpose, including the excellent FolderSync [3].

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

comments powered by Disqus

Direct Download

Read full article as PDF:

Price $2.95

News