#!/usr/bin/perl
# flickr city
# v0.1
# chris heathcote, worst programmer in the world 2005, http://anti-mega.com
# probably GPL, or something
# variables - change these before use
$cityname = 'gothamcity'; # this will be displayed on the page, and is the tag used to search
$photosperpage = 50; # number of entries per page
$maplat = 0; # initial map centre latitude
$maplon = 0; # initial map centre longitude
$mapzoom = 3; # initial google maps zoom level (1 is maximum zoom)
$pimphtml = ''; # this html is added between paragraph marks in the sidebar
# you need both a google maps api key and a flickr api key to run this
$flickrkey = 'flickrkeyhere';
$gmapskey = 'googlemapskeyhere';
# specify where the cache directory is - this is a complete absolute computer pathname, and this directory must be writable to by this script
$cachedirectory = '/www/example.com/admin/flickrcity';
# change this if the css file is in a different place
$cssfile = '/flickrcity/flickrcity.css';
######
# do not edit under here. contains demons and wilderbeest.
# setup application
use LWP::UserAgent;
use CGI qw(:cgi);
$| = 1;
my $query = new CGI;
my $markerhtml, $htmloutput, $cachedoutput;
my $absolute_url = url(-absolute=>1);
# hack to get round Google Maps key problem
my $path = path_info();
if ($path) {
# get parameters from URL - tags, user, pageno
# (works for urls apart from /tags/user/pageno/ )
my $tags, $user, $usernsid, $pageno;
if ($path =~ m|/(.*)|) { ($tags) = $path =~ m|/(.*)|; }
if ($path =~ m|/(.*)/(.*)|) { ($tags, $user) = $path =~ m|/(.*)/(.*)|; }
if ($path =~ m|/(.*)/(.*)/(.*)|) { ($tags, $user, $pageno) = $path =~ m|/(.*)/(.*)/(.*)|; }
if ($user !~ m|\D|) {
$pageno = $user;
$user = '';
}
} else {
$tags = param('tags');
$user = param('user');
$pageno = param('pageno');
}
if (!$pageno) { $pageno = 1; }
# DEBUG print "
$path
$tags
$user
$pageno
";
# check for cached file
my $cachefilename = $cityname . '_' . $tags . '_' . $user. '_' . $pageno;
$cachefilename =~ s/\W//g;
$cachefilename = lc($cachefilename);
my $completecache = $cachedirectory . '/' . $cachefilename;
if (-e "$completecache") {
# output cache
print "Content-Type: text/html\n\n";
open (CACHE,"$completecache") or die "$! $completecache $cachedirectory $cachefilename";
while () { print "$_\n"; }
close CACHE;
$cachedoutput = 1;
# file exists, output and quit
if (-M "$completecache" < 0.02083) {
# file is less than half an hour old
exit;
}
}
# open (DEBUG, ">>/www/anti-mega.com/admin/flickrcity/DEBUG")or die "$! DEBUG $completecache $cachedirectory $cachefilename";
# set up the HTTP connection
my $ua = LWP::UserAgent->new;
$ua->agent("FlickrCityLWP_0.1");
# get user ID from username
if ($user) {
my $flickrapiurl3 = 'http://www.flickr.com/services/rest/?method=flickr.people.findByUsername&'
. "api_key=$flickrkey&"
. "username=$user";
print DEBUG $flickrapiurl3;
my $req3 = HTTP::Request->new(GET => $flickrapiurl3);
# Pass request to the user agent and get a response back
my $res3 = $ua->request($req3);
# Check the outcome of the response
if ($res3->is_success) {
# print DEBUG $res->content, "\n";
}
else {
# error handling
# print DEBUG $res3->status_line, "\n";
}
# check request was good
if ($res3 !~ m|rsp stat="ok"|) {
# error condition
}
($usernsid) = $res3->content =~ m|nsid="(.*?)"|;
}
# search Flickr for photos
if ($tags) {
$tags = ',' . $tags;
}
my $flickrapiurl = 'http://www.flickr.com/services/rest/?method=flickr.photos.search&'
. "api_key=$flickrkey&"
. "tags=$cityname,geotagged$tags&"
. 'tag_mode=all&'
. "user_id=$usernsid&"
. 'extras=owner_name&'
. "perpage=$photosperpage&"
. "page=$pageno";
# print DEBUG $flickrapiurl, "\n";
my $req = HTTP::Request->new(GET => $flickrapiurl);
# Pass request to the user agent and get a response back
my $res = $ua->request($req);
# Check the outcome of the response
if ($res->is_success) {
# print DEBUG $res->content, "\n";
}
else {
# error handling
# print DEBUG $res->status_line, "\n";
}
# check request was good
if ($res !~ m|rsp stat="ok"|) {
# error condition
}
# for each photo, get geotags
my @photolist = split />/, $res->content;
my $markerscript, $i;
foreach $photoxml (@photolist) {
$i++;
# process each photo
if ($photoxml =~ m|new(GET => $flickrapiurl2);
# Pass request to the user agent and get a response back
my $res2 = $ua->request($req2);
# print DEBUG $res2->content, "\n";
my @infolist = split />/, $res2->content;
foreach $infoxml (@infolist) {
# process each tag
if ($infoxml =~ m|$phototitle
";
$markerscript .= " var point$i = new GPoint($taggeolong,$taggeolat);
var marker$i = new GMarker(point$i);
var html$i = \"
$phototitle
$photoownername
\";
GEvent.addListener(marker$i, \"click\", function() {
marker$i.openInfoWindowHtml(html$i);
});
map.addOverlay(marker$i);
";
}
# print DEBUG "photo $taggeolat, $taggeolong, http://www.flickr.com/photos/$photoowner/$photoid/ , $photosrc \n";
$taggeolat = '';
$taggeolong = '';
}
}
# create html
if ($user) { $userhtml = "by $user"; }
my $tagsurl = "$cityname $tags";
$tagsurl =~ s|\W|\%2C|g;
$htmloutput = <
flickrcity $cityname $tags $user
photos:
$markerhtml
Built using the Flickr and Google Maps APIs. All copyrights belong to the relevent parties.
Photos may take up to half an hour to appear after geotagging.
$pimphtml
Linkage and glue by Chris Heathcote.
flickrcity home
v0.1
ENDHTML
# write cache
open (CACHE,">$completecache") or die $!;
print CACHE $htmloutput;
close CACHE;
# output html if cache not sent
if (!$cachedoutput) {
print "Content-Type: text/html\n\n";
print $htmloutput;
}
# close DEBUG;
1;