Ah, Flickr. Absolutely the best place on Earth for pictures of cute puppies, slightly out-of-focus sunsets, and wedding cakes. It's hardly famous as a business hub, but this article shows some ways to use Flickr through Perl that are more business oriented.
A common business use for Flickr has been to show a product. This works well enough for companies with a physical product to sell, especially one that benefits from visual exposure. There isn't much need to dig into that here—dozens of available tools will handle uploading a product portfolio to Flickr just fine.
Instead, I show you how to build a custom chart using the CPAN Chart module (originally by Dave Bonner, now maintained by the Chart group) for business use. We'll look at the performance of stock gains over a year (using fake data), and then we'll post the chart in a Flickr album that shows past performance charts as well. We'll use only the Flickr features that make sense for this application, so this won't be a tour of the whole Flickr API. For that, you should go to the API site and read through the documentation. It's easy to read and very thorough; using it from Perl is simple.
You could use the Google API for charts, but at the time of this writing,
the Chart module can do more from Perl than the
Google Charts API from Javascript. This may change, however, so you should
definitely keep an eye on Google's tools.
First, let's generate the data for the chart randomly and place it directly in a list. Normally, the data would come from a file or a database, but we'll skip that step because it's not terribly interesting.
I'll use the list to create a chart as an image. The chart can then be uploaded to Flickr, tagged correctly, and described appropriately. Simple, right?
When you install the Chart module, remember that you can't just install "Chart," you need to install "Chart::Lines," for example.
It's not hard to generate random data, so let's just start with the number 100 and make every successive data point a random offset from the previous one, for 200 data points, with a random gain or loss of at most 0.5. There's only so far we need to go in a fictitious example, but using composite charts to mark the top and bottom of the curves, calculating MACD, etc., would be a fun project. If you feel adventurous, go for it.
Listing 1. chart_uploadr.pl: Generating random data
my $max = 200; # the maximum data points
# generate random data and labels for it
my @data = ([100], [100]);
my @labels = (0);
foreach (1..$max)
{
# I know there are 20 options for skipping ticks, but this works better for me
push @labels, every(25) ? $_ : undef ;
# the delta is from [ -.5 up to .5 )
foreach my $array (@data)
{
push @$array, $array->[-1];
$array->[-1] += (0.5 - rand 1);
}
}
|
Here's the approach: start with @data
containing two arrays of one element each. This is the starting value for
the two data sets. The labels also have just the starting zero. Now, do
this 200 times: add a label equal to the current loop iteration to the
@labels list (every 25th time, you add
200/25 = 8 labels total); then copy the last value for each data set into
the same data set and apply a random up or down adjustment to the new last
value. No need for temporary variables.
I should mention that this uses the CPAN Every
module to insert either nothing (an undef
value) or the current loop iteration in the
@labels list. I know there are many
Chart options for skipping labels, but this was
a simpler solution. I also wanted to show the
every() function, which, given a number, will
return true just once when it's called that many times (so
every(2) will return true on the second,
fourth, sixth, etc. time it's called). I wrote the
Every module, and I find it very handy for this
kind of use and for debugging.
The adjustment is between -0.5 and 0.5 (up to but not including 0.5 exactly). With a starting value of 100, this seemed reasonable.
The CPAN Chart modules are nice and make life
easy. They use the GD library.
Use the installation instructions and search the Web if you have trouble.
The Chart modules come with a Documentation.pdf
file that has all the documentation for all the modules with examples of
each chart type.
Once everything is set up, generating a PNG chart is easy:
Listing 2. Creating the chart
my $save_name = "performance.png"; # file name to use
my $title = "Performance of MoneyCo funds over 200 days";
my $desc = "Total value at EOD starting " .
strftime("%Y-%m-%d", localtime);
my $chart = Chart::Lines->new(800,600);
$chart->set(title => $title,
sub_title => $desc,
x_label => "days",
y_label => "millions USD",
legend => "bottom",
legend_labels => [ "Aggressive Fund", "Passive Fund" ],
y_grid_lines => "true",
);
$chart->png($save_name, [ \@labels, @data ]);
die "Couldn't create $save_name: $!" unless -f $save_name && -r $save_name;
|
We've set up the chart with a title, a descriptive subtitle, X and Y labels, placed the chart legend at the bottom, and labeled the two data sets. Finally, we asked for Y grid lines (they go from left to right). This way, the value of the funds can be easily seen.
The title should include the current date so it will make sense when
multiples are uploaded in the Flickr photostream. Whatever your desired
date format is, make sure you use the strftime
function from the POSIX module to generate it. Without a doubt, the most
annoying messes of Perl code I've had to untangle over the last 15 years
have come from the author's ignorance of the
POSIX::strftime() function.
With the png() method call, the chart is saved
as a PNG file to the $save_name variable.
Flickr authentication and authorization
The application must be run with two parameters and takes an optional third parameter:
Listing 3. Command-line parameters
my $api_key = shift @ARGV; my $secret = shift @ARGV; my $auth_token = shift @ARGV; die "Syntax: $0 API_KEY SECRET [AUTH_TOKEN]" unless defined $secret; |
This is a really simple way to do command-line options. You may want to
use Getopt::Long instead. It requires two
parameters and dies with a usage summary if they are not given.
The API key and secret can be retrieved from Flickr. Ask for a non-commercial key unless you know you need a commercial one, and you'll get it immediately. Those two parameters will authenticate your application (chart_uploadr.pl).
Now, if you have not provided the $auth_token
(the third command-line parameter), the script will get it with your help
(I copied this approach from the flickr_upload script that comes with
Flickr::Upload, FIXMEs and all).
You can't do an upload without the token. The token authorizes the authenticated application to upload to Flickr. So, the user that runs the application will see a URL they have to visit in order to allow the application to upload. The user could be the same one that requested the API key, but doesn't have to be.
We create a $ua variable (an object of type
LWP::UserAgent) to interact with the Flickr
servers. You should look at the LWP::UserAgent
documentation; that module
is essential for any Web client written in Perl. Many other incredible
modules, such as WWW::Mechanize, depend on
LWP::UserAgent.
Listing 4. Authentication and authorization
my $ua = Flickr::Upload->new({
'key' => $api_key,
'secret' => $secret,
});
# from the flickr_upload script that comes with Flickr::Upload
unless (defined $auth_token)
{
# 1. get a frob
my $frob = getFrob( $ua );
# 2. get a url for the frob
my $url = $ua->request_auth_url('write', $frob);
# 3. tell the user what to do with it
print "1. Enter the following URL into your browser\n\n",
"$url\n\n",
"2. Follow the instructions on the web page\n",
"3. Hit <Enter> when finished or Control-C to exit.\n\n";
# 4. wait for enter.
<STDIN>;
# 5. Get the token from the frob
my $auth_token = getToken( $ua, $frob );
die "Failed to get authentication token!" unless defined $auth_token;
# 6. Tell the user what they won.
print "Your authentication token for this application is\n\t\t",
$auth_token, "\n";
exit 0;
}
# from the flickr_upload script that comes with Flickr::Upload
sub getFrob
{
my $ua = shift;
my $res = $ua->execute_method("flickr.auth.getFrob");
return undef unless defined $res and $res->{success};
# FIXME: error checking, please. At least look for the node named 'frob'.
return $res->{tree}->{children}->[1]->{children}->[0]->{content};
}
sub getToken
{
my $ua = shift;
my $frob = shift;
my $res = $ua->execute_method("flickr.auth.getToken",
{ 'frob' => $frob } );
return undef unless defined $res and $res->{success};
# FIXME: error checking, please.
return $res->{tree}->{children}->[1]->{children}->[1]->{children}->[0]->{content};
}
|
It would be nice if Flickr gave you a way to get the authorization token without this URL visit, but that's not available currently, so you must cope. It's a one-time thing; once you have the authorization token, you can use it until the human race is extinct, the Flickr servers are turned off, or you don't need uploads anymore—whichever comes first.
As an aside, I wish Flickr would distinguish between authentication and authorization in their API documentation. They are very different things, and confusing them leads to confused users. (This has been a message from the Word Police. Thank you.)
To run the application once you have the token, you just enter:
./chart_uploadr.pl key secret token
and if all goes well, it will exit quietly.
At last, we can actually upload the image.
Listing 5. Uploading
$ua->upload(
photo => $save_name,
title => $title,
description => $desc,
auth_token => $auth_token,
tags => 'MoneyCo fund performance',
is_public => 1,
is_friend => 1,
is_family => 1
) or die "Failed to upload $save_name: $!";
|
This part is pretty simple. There are many parameters you can use, all
documented in the Flickr Upload API (see
Resources). The photo
parameter points to the actual file. The title
and description are the same as the ones we
used for title and subtitle when generating the chart. The tags are static
at this point but could be appropriate for whatever chart is being
generated. Finally, all the is_whatever
parameters make the image really, truly, absolutely public.
An example upload is at http://www.flickr.com/photos/58365921@N00/3497574717/.
Now, when the user who authorized chart_uploadr.pl sees this image uploaded in their photostream, so will the whole world.
You've created randomized data representing fund performance, created a simple stock chart in a PNG file from that data, and uploaded the PNG file to Flickr. The whole process is fully automated.
In real life, of course, the data will not be random. You will have to write the code that gets the data out of a file or a database. Plotting the data will then produce consistent results every time.
Word to the wise: you can make the chart much better. Look at any financial chart for inspiration; common improvements are better labels, pointing out the maximum and minimum, and so on. This is a worthwhile project because better-looking charts will always translate into impressed customers, whereas improving the upload process by using a better Getopt module will not impress them. In other words, if you must produce a visual product, make sure it looks professional.
Good luck with your uploads!
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample script | chart_uploadr.zip | 2KB | HTTP |
Information about download methods
Learn
- To prove Flickr's business worth, Chris
Brogan redefines it from a photo-sharing tool to a platform in this list
of
Flickr business hacks.
- Scott Lake also points out
one very valuable business reason for Flickr.
- The Small Business Search Marketing site
shows you how to
market on Flickr.
- You might want to compare/contrast the
Flickr API with the
Google Chart API.
-
In the
developerWorks Linux zone,
find more resources for Linux developers, and scan our
most popular articles and
tutorials.
-
See all
Linux tips and
Linux tutorials on developerWorks.
-
Stay current with
developerWorks technical events and Webcasts.
Get products and technologies
- You need Flickr's
tools for this article to make sense, including the
upload API and parameters
and the
authentication API.
- At the
CPAN (Comprehensive Perl Archive Network)
site you can find modules—scads and scads of modules—and
module documentation. Here are the current
Chartmodules andFlickr::Uploadmodule. -
With
IBM trial software,
available for download directly from developerWorks, build your next development
project on Linux.
Discuss
-
Get involved in the
My developerWorks community; with your personal profile and custom home page, you
can tailor developerWorks to your interests and interact with other developerWorks users.





