Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / operating-systems / Linux

Programmatically Upload Pictures to Picasa

4.83/5 (4 votes)
11 Nov 2011CDDL9 min read 21.8K   389  
Quick and efficient way to upload an entire folder to Picasa / Google+

Introduction

With the new social networking Google+ people need to upload pictures to it.
There are tools that transfer pictures from Facebook albums to Google, but this is not convenient because the information on pictures are lost (Facebook crops exif data and resizes pictures with a really low resolution while Google supports pictures up to 2048px on longest side). So re-uploading all your pictures again should be preferred.

Google+ offers a user friendly way to do this through a nice web interface but this may be time consuming because the images are sent to the server and then resized by Google. As you can imagine, transferring huge images and resizing them on server consumes a lot of bandwidth.

Fortunately, there are two great open source tools that, with some scripting, can automate the whole process for you.
ImageMagick and GoogleCL are everything we need.
Moreover the script will, optionally, put a watermark on all the uploaded pictures (don't worry, your original pictures will be left untouched on your disk).

Background

The script is not meant to be the "best way" to upload files on Google+ but a fairly complete guide to most of bash commands and features. This is the reason why if you look at the script code, you'll find that I used different approaches in different parts of the script to achieve the same functionality.

Using the Code

First of all, we should prepare the environment and install the tools (if not already installed in your system).
In a terminal window, we have to:

sudo apt-get install imagemagick
sudo apt-get install googlecl 

When both packages are installed, we need to allow GoogleCL to access our Picasa/Google+ account:

google picasa list-albums 

The program will ask for the Picasa/Google account and will give a link to click:

Please specify user: yourpicasaaccount@email.com
Please log in and/or grant access via your browser at
https://www.google.com/accounts/OAuthAuthorizeToken?
    oauth_token=lotsofnumbersandletters&hd=default
then hit enter. 

Once authorized on the web return in the terminal and hit enter.
You will see all albums you already uploaded, if any.

Download the .sh script attached to the article into the ~/bin folder and give it executable permissions with:

sudo chmod a+x ~/bin/UploadToPicasa.sh
Warning: The script uses the ~/Pictures/Watermarked folder (hardcoded in the script) to store the files before uploading them (and leaves there the files that it didn't upload for an error or because you told the script to not upload them).
If your system has localized folder names, you really should modify the script to match "Pictures" with the one you have in your system (for example, in my italian ubuntu 11.10 that folder is named "Immagini").
If, at the end of the article, you think you are able to apply some of the concepts explained here you could try to modify the script by extracting the localized Pictures folder from ~/.config/user-dirs.dirs (if it does exist) with sed:
sed -n 's/\(XDG_PICTURES_DIR[:blank:]*=[:blank:]*"\)\(.*\)"/\2/p' 
~/.config/user-dirs.dirs
Don't worry, it's really simple.
You could also try to find a different regular expression that does the same.

GREAT! We are ready to go.

Launch the script with:

UploadToPicasa.sh 

It will guide you through the whole process.
Let's analyze how the script actually works...

First of all, the script needs to know where are the pictures to upload. By default, it uses the current folder. You can change it or accept it. If you type a wrong path it will be asked again.

Then it asks about watermarking. You can select the position or "none" if you don't want to watermark the pictures. If you choose to apply a watermark, the script asks for the watermark file. If you don't have any, you can build a simple text-only one (before running the script) with a command like this:

convert -size 600x150 xc:grey30 -font /usr/share/fonts/truetype/ubuntu-font-family/
Ubuntu-BI.ttf -pointsize 40 -gravity center -draw "fill grey70  text 0,0  
'Photo by Lino Barreca'" stamp_fgnd.png
convert -size 600x150 xc:black -font /usr/share/fonts/truetype/ubuntu-font-family/
Ubuntu-BI.ttf -pointsize 40 -gravity center -draw "fill white  text  1,1  
'Photo by Lino Barreca' text  0,0  'Photo by Lino Barreca' fill black  text -1,-1 
'Photo by Lino Barreca'" +matte stamp_mask.png
composite -compose CopyOpacity  stamp_mask.png  stamp_fgnd.png  stamp.png

The last question is about online album name.
By default, the script uses the folder name so if you have
~/Pictures/Family/Christmas 2011
The name proposed will be "Christmas 2011".
If you leave the album name blank the processed pictures will not be uploaded but left on disk.

Now the script has all required information. You can sit and wait. :)

If you choose to upload the pictures, they will be removed as soon as the upload completes. If you didn't choose to upload them, you will find the photos into the required folder I was referring into my "warning" above.

Points of Interest

Let's analyze, line by line, all the bash features that the script uses...

First line of the script is a comment (all lines starting with # are treated as comments). Comments can also be used at the line ends or inside a command.

Line 3 contains:

  • Variable declaration (DestFolder)
  • Environment variable expansion ($HOME that contains the user home folder, typically /home/username). The $ sign is very important in bash and has lots of uses.
  • String declaration with variable concatenation.

In line 4, you will see:

  • Conditional evaluation instruction if
  • NOT operator ! reverses the result of the comparison.
  • Square brackets [ and ] are used for evaluation. Double brackets [[ and ]] (not shown here) are the extended test evaluation operators. No filename expansion or word splitting takes place between [[ and ]].
  • File/folder test operator -d. It returns true if the argument is a directory.
  • Command continuation special character ; allows to specify more than one command on a single line. if syntax in bash requires the then keyword to be put on another line.

Line 5:

  • Command to create a folder mkdir.
  • Useful parameter -p. Tells mkdir to create the whole folder tree and not only the last folder. Without -p the mkdir will fail if "Pictures" doesn't exist.

Line 6:

  • Else-If shortcut elif. Allows you to check another condition if the above if condition evaluates to FALSE.
  • Subshell with backtick: the commands inside ` and ` are executed and the results are evaluated.
  • Folder contents listing command ls. One of the most used commands in unix. It lists everything matching the specification given.
  • Useful parameter -A. It is used to tell ls to ignore . and .. folders. The logic behind here is: tell me what files are inside the folders and store the results in a temporary variable (to be evaluated with the if).
  • Checks for variable definition/contents. if [ somevariable ] evaluates to true if somevariable is defined and contains a value.

Line 7:

  • Command echo to print things to user it accepts strings in double quotes, in single quotes and without quotes (behaviour changes accordingly).
  • Parameter -e tells echo to escape characters. It is used to put a new line inside the message instead of using two echo commands (each echo, by default puts a new-line at the end)

Line 8: terminate script with a return value. An exit code of 0 usually means success, anything different means error.

Line 9: if condition termination: fi.

Line 11: another variable assignment, using the PWD internal variable (it contains the actual working directory). You could also use ~+ it is the same and contains the same value.

Line 12:

  • while loop. The while executes everything inside the do done block while the condition evaluates to TRUE.
  • null command : it is a built-in nop command, evaluates to true giving us an infinite loop.
  • do keyword, normally must be put on a new line but used with ; can be put on the same line (as explained above)

Line 13:

  • read user input from stdin.
  • -e is used to read a line (until enter is pressed)
  • -i is used to put something as the default input (in this case the actual value of SourceFolder)
  • -p used to print something (the question)
  • variable to store read value into (SourceFolder specified at the end of the line)

Line 14 contains the break statement used to exit the infinite loop and already explained commands/keywords.

Line 18:

  • select command (used here to ask the user to make a choiche). this command is usually needed when you want to create a "menu" of possible operations. Choosen option is stored in position.
  • subshell with $ (another use of the $ sign). The concept here is similar to the backticks already explained: execute the command inside parentesis and store the result in a variable.
  • composite command of the imagemagick package. it returns a list \n separated of possible parameters to use. The list is stored in a temporary array variable by $ and used by select to build a menĂ¹.

Line 21: the break here is used because the select command loops infinitely.

Line 24: String comparison with the != operator (same as C)

Line 33: String extraction (from SourceFolder variable) with bash pattern matching. It is a bit long to explain how this actually works (and it's not a "beginner level") but you can find it yourself here and here.

Line 36: -n option is another way to check if the variable contains a value (same as line 6 last point)

Line 38:

  • grep command is another common unix command. It is used to find things. -q parameter is what we are searching for.
  • subshell for the command list-albums of the googlecl package.
  • Here string (redirection) <<< keyword is an advanced bash feature called Here String. Info here. It could be thought as a way to put the contents of the variable into a command.

Line 49 saves the contents of the internal field separator variable IFS. This is used to determine word boundaries when looking at arrays.

Line 50 replaces the IFS. We need to change this because the SourceFolder could contain spaces in the path or the files contained could have spaces inside their name.
We need to interpret a path like '/home/user/Pictures/my christmas 2011/Picture 1.JPG' like a SINGLE entry. Without replacing the IFS variable that would be recognized as '/home/user/Pictures/my', 'christmas', '2011/Picture', '1.JPG'

Line 53 contains a for each loop. It takes a variable after the in keyword. Each element contained in the variable is assigned to the each variable and this is used inside the do done block.

Line 55 contains the let command. It is used to do aritmetic operations and supports C syntax.

Line 68 contains a pipe |. Piping is a common task in unix system it is used to pass the output of the command preceding the pipe to the input of the command after the pipe. It is useful to concatenate operations without using temporary files as input/output.

Line 75 contains:

  • the rm command, used to delete a file from disk.
  • the && operator. It is used to AND things.
    Used with conditions it evaluates to true if all are true.
    Used with commands (like this one), it allow the user to say "if the first command succeeds THEN execute the second command". If the first fails, the second will be skipped (leaving the not-uploaded file on disk)

History

The first version will also be the last one as it is intended to be a sample on how to use the tools. Take it as a base and modify it as you want (and based on your needs).

If you have any questions/hints or you need help on customizing the script, leave a comment. I'll be glad to help you (when I have some free time).

...and don't forget to rate it, thanks :)

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)