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 string
s 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 :)