Annotation of foursquare/foursquare.pl, revision 1.1

1.1     ! nick        1: #!/usr/bin/perl -wT
        !             2: 
        !             3: =begin comment info
        !             4: +------------------------------------------------------------------------------
        !             5: |
        !             6: | See end of script for comments and 'pod2man foursquare.pl | nroff -man' to
        !             7: | view man page or pod2text foursquare.pl for plain text.
        !             8: |
        !             9: | The core submit to FourScore and some concepts such as randomzing some 
        !            10: | items to avoid looking automated were taken from Mayank Lahiri's code 
        !            11: | found on his web site here:
        !            12: |      http://compbio.cs.uic.edu/~mayank/4sq.html
        !            13: |
        !            14: |   Nicholas DeClario <nick@demandred.dyndns.org>
        !            15: |   August 2010
        !            16: |      $Id$
        !            17: |
        !            18: +------------------------------------------------------------------------------
        !            19: =end comment
        !            20: =cut
        !            21: BEGIN {
        !            22:         delete @ENV{ qw(IFS CDPATH ENV BASH_ENV PATH) };
        !            23:         $ENV{'PATH'} = "/bin:/usr/bin";
        !            24:        $|++;
        !            25:       }
        !            26: 
        !            27: use strict;
        !            28: use Getopt::Long;
        !            29: use Pod::Usage;
        !            30: use Data::Dumper;
        !            31: use IO::Socket;
        !            32: use MIME::Base64;
        !            33: 
        !            34: my %opts  = &fetchOptions( );
        !            35: my $vb    = $opts{'verbose'} || 0;
        !            36: my $dbf   = $opts{'db'} || &findDBLocation( ) || exit;
        !            37: my $locs  = &readLocations( $dbf ) || exit;
        !            38: my $email = "nick\@declario.com";
        !            39: my $up    = "bmlja0BkZWNsYXJpby5jb206MzIxd2FmZmxlMQ==";
        !            40: 
        !            41: srand;
        !            42: 
        !            43: ##
        !            44: ## Generate a new username/email and password
        !            45: ## in base64 encoding and exit.
        !            46: ##
        !            47: if ( $opts{'genup'} )
        !            48: {
        !            49:        print "Base64 encoded username/pass: " . &genup( ) . "\n";
        !            50:        exit( 0 );
        !            51: }
        !            52: 
        !            53: ##
        !            54: ## Confirm we were handed a valid location
        !            55: ##
        !            56: if ( ! defined $locs->{$opts{'location'}} ) 
        !            57: {
        !            58:        print STDERR "ERROR: Invalid Location: " . $opts{'location'} . "\n";
        !            59:        exit( 1 );
        !            60: }
        !            61: 
        !            62: &displayStatus( $vb );
        !            63: 
        !            64: my $results = &postToFourSquare( );
        !            65: print "Result: $results\n" if ( $opts{'verbose'} );
        !            66: 
        !            67: exit( 0 );
        !            68: 
        !            69: ###############################################################################
        !            70: ##
        !            71: ##  &postToFourSquare( );
        !            72: ##
        !            73: ###############################################################################
        !            74: sub postToFourSquare
        !            75: {
        !            76:        my $result = 0;
        !            77: 
        !            78:        ##
        !            79:        ## Put a delay of up to 10 minutes so we don't look like
        !            80:        ## like an automated bot.
        !            81:        ##
        !            82:        print STDOUT "Sleeping...\n" if (   $opts{'verbose'} &&
        !            83:                                        ! $opts{'nosleep'} );
        !            84:        sleep( rand( ) * 400 ) if ( ! $opts{'nosleep'} );
        !            85:        
        !            86:        ##
        !            87:        ## Set up our post to the FourSquare server
        !            88:        ##
        !            89:        my $sock = IO::Socket::INET->new( PeerAddr => 'api.foursquare.com', 
        !            90:                                          PeerPort => 80, 
        !            91:                                          Proto    => 'tcp', 
        !            92:                                          Type     => SOCK_STREAM
        !            93:                                        ) or die;
        !            94: 
        !            95:        my $str = "vid=" . $locs->{$opts{'location'}}{'vid'} . 
        !            96:                  "&private=0&geolat=" . $locs->{$opts{'location'}}{'lat'} .
        !            97:                  "&geolong=" . $locs->{$opts{'location'}}{'long'};
        !            98: 
        !            99:        print $sock "POST /v1/checkin HTTP/1.1\r\n"
        !           100:             . "Host: api.foursquare.com\r\nUser-Agent: "
        !           101:             . "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid Build/FRG01B) "
        !           102:            . "AppleWebKit/533.1 (KHTML, like Gecko)"
        !           103:             . "Version/4.0 Mobile Safari/533.1\r\nContent-Type: "
        !           104:             . "application/x-www-form-urlencoded\r\nAuthorization: Basic "
        !           105:             . "$up\r\nContent-length: ", length( $str ) + 2, "\r\n\r\n$str\r\n";
        !           106: 
        !           107:        $result = <$sock>;
        !           108:        
        !           109:        chomp $result;
        !           110: 
        !           111:        return $result;
        !           112: }
        !           113: 
        !           114: ###############################################################################
        !           115: ## 
        !           116: ## &readLOcations( $file );
        !           117: ##
        !           118: ##   Read in the locations database.  The format of the database is as 
        !           119: ##  as follows: 
        !           120: ##
        !           121: ##     id, venue id, description, longitutde, latitude
        !           122: ##
        !           123: ##  The venue ID is required and found vie FourSquares website.  
        !           124: ##
        !           125: ##  Everything will be pushed in to an hash with 'id' as the key.
        !           126: ##
        !           127: ###############################################################################
        !           128: sub readLocations 
        !           129: {
        !           130:        my $file    = shift || 0;
        !           131:        my %loc     = ( );
        !           132:        my @deletes = ( );
        !           133: 
        !           134:        if ( ! $file ) 
        !           135:        {
        !           136:                print STDERR "ERROR: Filename of location database missing!\n";
        !           137:                return 0;
        !           138:        }       
        !           139: 
        !           140:        open( DB, "<$file" ) or die( "ERROR: Failed to open $file: $!\n" );
        !           141:                while( <DB> ) 
        !           142:                {
        !           143:                        chomp;
        !           144: 
        !           145:                        ##
        !           146:                        ## Ignore Comments and invalid fields
        !           147:                        ##
        !           148:                        next if ( m/^#/ );      
        !           149:                        next if ( ! m/(?:.*,){4}/ );
        !           150: 
        !           151:                        ##
        !           152:                        ## Read in fields
        !           153:                        ##
        !           154:                        my ( $key, @fields ) = split( /,/, $_ );
        !           155:                        $loc{$key}{'vid'}  = $fields[0] || 0;
        !           156:                        $loc{$key}{'desc'} = $fields[1] || "N/A";
        !           157:                        $loc{$key}{'long'} = $fields[2] || 0;
        !           158:                        $loc{$key}{'lat'}  = $fields[3] || 0;
        !           159: 
        !           160:                        ##
        !           161:                        ## We don't want to look like a bot, so we'll
        !           162:                        ## fudge our long and lat a tick
        !           163:                        ##
        !           164:                        $loc{$key}{'lat'}  += rand() * 0.0001 - 0.00005;
        !           165:                        $loc{$key}{'long'} += rand() * 0.0001 - 0.00005;
        !           166:        
        !           167:                        ##
        !           168:                        ##  Search for missing fields
        !           169:                        ##
        !           170:                        foreach my $k ( keys %{ $loc{ $key } } )
        !           171:                        {
        !           172:                                if ( ! $loc{$key}{$k} )
        !           173:                                {       
        !           174:                                        print STDERR "WARNING: " . $key .
        !           175:                                             " has an invalid field: $k\n" .
        !           176:                                             "This location will be removed.\n";
        !           177:                                        push @deletes, $key;
        !           178:                                }
        !           179:                        }
        !           180:                }
        !           181:        close( DB );
        !           182: 
        !           183:        map { delete $loc{$_}; } @deletes;
        !           184: 
        !           185:        print STDERR "ERROR: No valid locatons found in DB!\n"
        !           186:                if ( ! %loc );
        !           187: 
        !           188:        return \%loc;
        !           189: }
        !           190: 
        !           191: ###############################################################################
        !           192: ##
        !           193: ## my $database_file_path = &findDBLocation( );
        !           194: ##
        !           195: ##  If no file path for the GPS locations is given, try and figure out 
        !           196: ##  where it could be.  
        !           197: ##
        !           198: ###############################################################################
        !           199: sub findDBLocation 
        !           200: {
        !           201:        my @locations = qw| /etc /etc/foursquare /opt/foursquare . ~ |;
        !           202:        my @filenames = qw| fs_locations fs_locations.txt fs_locations.db |;
        !           203: 
        !           204:        foreach my $loc ( @locations ) 
        !           205:        {
        !           206:                map { return $loc . "/" . $_ if ( -f $loc . "/" . $_ ) } 
        !           207:                        @filenames;
        !           208:        }
        !           209: 
        !           210:        print STDERR "ERROR: Failed to locate foursquare locations database.\n";
        !           211: 
        !           212:        return 0;
        !           213: }
        !           214: 
        !           215: ###############################################################################
        !           216: #
        !           217: # &displayStatus( $verbose )
        !           218: #
        !           219: ###############################################################################
        !           220: sub displayStatus
        !           221: {
        !           222:        my $verbose = shift || 0;
        !           223: 
        !           224:        print "Using database: $dbf\n";
        !           225:                     
        !           226:        map 
        !           227:        { 
        !           228:                print sprintf( "%-10s: %s\n", $_, 
        !           229:                                $locs->{$opts{'location'}}{$_} );
        !           230:        } keys %{ $locs->{$opts{'location'}} };
        !           231: }
        !           232: 
        !           233: ###############################################################################
        !           234: ##
        !           235: ## &sendmail( %mail );
        !           236: ##
        !           237: ###############################################################################
        !           238: sub sendmail
        !           239: {
        !           240:        my $mail = shift || return 0;
        !           241: 
        !           242: }
        !           243: 
        !           244: ###############################################################################
        !           245: ###############################################################################
        !           246: sub genup
        !           247: {
        !           248:        ##
        !           249:        ## Prompt user for email/username and password
        !           250:        ##
        !           251:        print "Enter e-mail or username: ";
        !           252:        my $u = <STDIN>;
        !           253:        chomp $u;
        !           254:        
        !           255:        print "Enter password: ";
        !           256:        ## 
        !           257:        ## Turn echo off
        !           258:        ##
        !           259:        my $p = <STDIN>;
        !           260:        chomp $p;
        !           261:        
        !           262:        ##
        !           263:        ## Display the results
        !           264:        ##
        !           265:        return ${\encode_base64($u . ":" . $p)};
        !           266: }
        !           267: 
        !           268: ###############################################################################
        !           269: ##
        !           270: ## &fetchOptions( );
        !           271: ##
        !           272: ##      Grab our command line arguments and toss them in to a hash
        !           273: ##
        !           274: ###############################################################################
        !           275: sub fetchOptions {
        !           276:         my %opts;
        !           277: 
        !           278:         &GetOptions(
        !           279:                        "database=s"    => \$opts{'db'},
        !           280:                        "email"         => \$opts{'email'},
        !           281:                        "genup"         => \$opts{'genup'},
        !           282:                         "help|?"        => \$opts{'help'},
        !           283:                        "location=s"    => \$opts{'location'},
        !           284:                         "man"           => \$opts{'man'},
        !           285:                        "sleep"         => \$opts{'nosleep'},
        !           286:                        "verbose"       => \$opts{'verbose'},
        !           287:                    ) || &pod2usage( );
        !           288:        &pod2usage( ) if ( ! defined $opts{'location'} &&
        !           289:                            ! defined $opts{'genup'} );
        !           290:         &pod2usage( ) if defined $opts{'help'};
        !           291:         &pod2usage( { -verbose => 2, -input => \*DATA } ) if defined $opts{'man'};
        !           292: 
        !           293:         return %opts;
        !           294: }
        !           295: 
        !           296: __END__
        !           297: 
        !           298: =head1 NAME
        !           299: 
        !           300: masterbuild.pl - blurb
        !           301: 
        !           302: =head1 SYNOPSIS
        !           303: 
        !           304: masterbuild.pl [options]
        !           305: 
        !           306:  Options:
        !           307:         --help,?        Display the basic help menu
        !           308:        --email,e       Enable sending results via e-mail
        !           309:        --genup         Generate base64 encoded username password
        !           310:        --location,l    Path to foursquare locations database
        !           311:         --man,m         Display the detailed man page
        !           312:        --sleep,s       Disable sleep delay
        !           313:        --verbose,v     Increase verbosity
        !           314: 
        !           315: =head1 DESCRIPTION
        !           316: 
        !           317: =head1 HISTORY
        !           318: 
        !           319: =head1 AUTHOR
        !           320: 
        !           321: Nicholas DeClario <nick@declario.com>
        !           322: 
        !           323: =head1 BUGS
        !           324: 
        !           325: This is a work in progress.  Please report all bugs to the author.
        !           326: 
        !           327: =head1 SEE ALSO
        !           328: 
        !           329: =head1 COPYRIGHT
        !           330: 
        !           331: =cut

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>