<%once> $::callback = 'http://hackathon.cavalletto.org/'; $::client_id = 'XYXZ2PQ2MCZSEKVBXTIJMWAT04H3BS1KD0MG5EZXCWWEX45D'; $::secret = '************************************************'; $::googlemaps_key = 'ABQIAAAA2pyCudwQAcTbZLxShRorbBQ9yyPHBptkhx-L7IpYPKc7yRKXYBSEXH4lhBj9IA2WQXgMbk1tq_6tgg'; $::heatmaps_key = '7524764b-bde2-44bb-9d06-6bfa91ef2efd'; #################################################################### use Carp qw( carp confess ); use Data::Dumper; sub data_dumper { Data::Dumper->new( \@_ )->Indent(1)->Terse(1)->Dump() } sub debug_message { join( ' ', map { ( ! ref $_ and length $_ ) ? $_ : Data::Dumper->new( [ $_ ] )->Indent(1)->Terse(1)->Dump() } @_ ); } sub log_msg { my $msg = debug_message( @_ ); $msg .= "\n" unless ( substr( $msg, -1, 1 ) eq "\n" ); warn( $msg ) } #################################################################### sub commify { my $text = reverse $_[0]; $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; return scalar reverse $text; } #################################################################### use URI; sub url { my ( $path, @args ) = @_; my $url = URI->new( $path ); $url->query_form( @args ); "$url" } #################################################################### use LWP::UserAgent; $::user_agent = LWP::UserAgent->new(); $::user_agent->agent( "Traffic Finder +http://hackathon.cavalletto.org/" ); sub http_get { my $request_url = url( @_ ); # log_msg( 'Sending HTTP Get:', $request_url ); my $request = HTTP::Request->new( GET => $request_url ); my $response = $::user_agent->request($request); unless ( $response->is_success ) { log_msg("Error from", $request_url, ':', $response ); } my $data = $response->content; } #################################################################### use JSON::XS; sub decode_json_from_http_get { my ( $target_url, %params ) = @_; my $data = eval { my $json = http_get( $target_url, %params ); my $data = decode_json( $json ); # log_msg( 'Retrieved JSON', $data ); return $data; }; if ( $@ ) { log_msg( 'Failed', $@ ); } $data; } #################################################################### sub call_foursquare_method { my ( $method, @params ) = @_; my $json = decode_json_from_http_get( 'https://api.foursquare.com/v2/' . $method, @params ); } <%args> $startover => undef $resetform => undef $authtoken => undef $gentoken => undef $code => undef $region => undef $findrecent => undef $category => undef $listcats => undef <%perl> my @debug_footer; my @choose_region_venues; my @display_categories; my @matching_venues; my $have_display; if ( defined $gentoken ) { my $auth_req_url = url( 'https://foursquare.com/oauth2/authenticate', 'client_id' => $::client_id, 'response_type' => 'code', 'redirect_uri' => url ( $::callback, region => $region, category => $category, ), ); $m->redirect( $auth_req_url ); } if ( $code ) { my $auth_token_url = url( 'https://foursquare.com/oauth2/access_token', 'client_id' => $::client_id, 'client_secret' => $::secret, 'grant_type' => 'authorization_code', 'redirect_uri' => $::callback, 'code' => $code, ); # log_msg( "Auth URL:", $auth_token_url ); my $json = decode_json_from_http_get( $auth_token_url ); # log_msg( "Auth JSON:", $json ); $authtoken = $json->{access_token}; $m->redirect( url ( '/', authtoken => $authtoken, region => $region, category => $category, ) ); } if ( $startover ) { $m->redirect( url ( '/', ) ); } if ( $resetform ) { $m->redirect( url ( '/', authtoken => $authtoken, ) ); } if ( $authtoken and ! $region and ! $category and ! $listcats ) { $findrecent ++; } if ( defined $findrecent ) { my $json = call_foursquare_method( 'users/self/checkins', 'oauth_token' => $authtoken ); push @debug_footer, 'Recent:', $json; foreach my $location ( @{ $json->{response}{checkins}{items} } ) { push @choose_region_venues, $location->{venue}; } $have_display ++; } if ( $authtoken and $region and ! $category ) { $listcats ++; } if ( defined $listcats ) { my $json = call_foursquare_method( 'venues/categories', 'client_id' => $::client_id, 'client_secret' => $::secret ); push @debug_footer, 'Categories:', $json; my $pushcats; $pushcats = sub { my ( $target, $level ) = @_; my @categories = @$target; foreach my $category ( @categories ) { push @display_categories, [ $level, $category->{id}, $category->{name}, $category->{icon} ]; if ( $category->{categories} ) { $pushcats->( $category->{categories}, $level + 1 ); } } }; $pushcats->( $json->{response}{categories} ); $have_display ++; } my ( $ll ) = split( ' ', $region, 2 ); my ( $cat_id, $cat_label ) = split( ' ', $category, 2 ); if ( $region and $category and ! $have_display ) { my $json = call_foursquare_method( 'venues/search', 'll' => $ll, 'query' => $cat_label, $authtoken ? ( 'oauth_token' => $authtoken ) : ( 'client_id' => $::client_id, 'client_secret' => $::secret, ) ); push @debug_footer, 'Venues:', $json; my @venues = map { @{ $_->{items} } } @{ $json->{response}{groups} }; push @matching_venues, @venues; $have_display ++; } TrafficFinder -- A Quick FourSquare Hack
<%perl> if ( $region ) { <%perl> } <%perl> if ( $authtoken ) { <%perl> }

<%perl> my $msg = 'Welcome to Traffic Finder.'; if ( ! $have_display ) { $msg .= ' This site will show the FourSquare venues with the most checkins in a given category and location. Generate an auth token to let us find your recent locations, or choose one of the examples below.' } <% $msg %>

<%perl> if ( scalar @choose_region_venues ) { foreach my $location ( @choose_region_venues ) {
  • {location}{lat},$location->{location}{lng} $location->{location}{address}, $location->{location}{city}, $location->{location}{state}", category => $category ) %>"><% $location->{name} %>, <% $location->{location}{address} %>, <% $location->{location}{city} %>, <% $location->{location}{state} %> (<% $location->{location}{lat} %>, <% $location->{location}{lng} %>) <%perl> } }

<%perl> if ( scalar @display_categories ) { foreach my $category ( @display_categories ) {
<% '  ' x ( $category->[0] * 2 + 1 ) |n %>• [1] $category->[2]" ) %>"><% $category->[2] %> (<% $category->[1] %>) <%perl> } }

<%perl> if ( @matching_venues ) { my %counter; @matching_venues = reverse sort { $a->{stats}{checkinsCount} <=> $b->{stats}{checkinsCount} } grep { ! $counter{ $_->{id} || $_->{name} } ++ } @matching_venues; my $max_size = $matching_venues[0]->{stats}{checkinsCount}; my @markers; my $counter = 'A'; foreach my $venue ( grep $_, @matching_venues ) { last if $counter > 'P'; my $size_ratio = $venue->{stats}{checkinsCount} / $max_size; my $size_param = ( $size_ratio < .2 ) ? 'size:tiny|' : ( $size_ratio < .4 ) ? 'size:small|' : ( $size_ratio < .6 ) ? 'size:mid|' : ''; push @markers, $size_param . 'label:' . ($counter ++) . '|' . $venue->{location}{lat} . ',' . $venue->{location}{lng}; } my $map_url = url( 'http://maps.google.com/maps/api/staticmap', 'center'=>$ll, 'sensor'=>'false', # 'zoom'=>'13', 'size'=>'640x480', 'maptype'=>'roadmap', map { ( 'markers' => $_ ) } @markers );

<%perl> $counter = '1'; foreach my $venue ( @matching_venues ) { my $size_ratio = $venue->{stats}{checkinsCount} / $max_size; my $color_image = ( $size_ratio < .2 ) ? 'green' : ( $size_ratio < .4 ) ? 'blue' : ( $size_ratio < .6 ) ? 'red' : 'red'; <%perl> }
Venue Unique
Users
Checkins
Ever
Return
Rate
There
Now
<% commify( $counter ++ ) %> <% $venue->{name} %> (<% $venue->{location}{address} ? "$venue->{location}{address}, " : '' %><% commify( int( $venue->{location}{distance} * 0.0621371192 ) / 100 ) %> miles) <% commify( $venue->{stats}{usersCount} ) %> <% commify( $venue->{stats}{checkinsCount} ) %> <% map { s{(..)$}{\.$1}; $_ } int( $venue->{stats}{checkinsCount} / ( $venue->{stats}{usersCount} || 1 ) * 100 ) %> <% commify( $venue->{hereNow}{count} ) %>
<%perl> } if ( ! $have_display ) {
<%perl> my @examples = ( [ 'Cupcakes near Times Square', 'region=40.756847459589%2C-73.9870834350586+W+42nd+St%2C+NYC&category=4bf58dd8d48988d1bc941735+Cupcakes' ], [ 'Tacos near Chelsea', 'region=40.7391974377614%2C-73.9897602796555+Chelsea+NYC&category=4bf58dd8d48988d151941735+Tacos' ], [ 'Theaters near the Theater District', 'region=40.756847459589%2C-73.9870834350586+W+42nd+St%2C+NYC&category=4bf58dd8d48988d137941735+Theater' ], [ 'Bookstores in Upper Manhattan', 'region=40.8011389%2C-73.9689004+Upper%20West%20Side%2C+NYC&category=4bf58dd8d48988d1b1941735+Bookstore' ], [ 'Coworking Spaces near Union Square', 'region=40.7371%2C-73.9924+Union+Square%2C+NYC&category=4bf58dd8d48988d174941735+Coworking+Space' ], [ 'Coworking Spaces in Brooklyn', 'region=40.68%2C-73.95+241+Brooklyn&category=4bf58dd8d48988d174941735+Coworking+Space' ], ); foreach ( @examples ) { <%perl> }
Examples
<% $_->[1] |n %>"><% $_->[0] %>
<%perl> }