Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- # Get the latest N tweets, using well-tried technologies, as are Perl and
- # James Clark's "expat" XML parser, back from the golden 90es
- # No CGI modules needed, hand-written output with "print"
- # Except CGI::Carp for exception handling
- # Idea:
- # Use a hash to keep track of which elements are currently open
- # Collect the text content of open elements
- # Output as HTML fragment: unordered list
- # Buffer on client and server with max-age 300 sec. = 5 min.
- use strict;
- use warnings;
- use CGI::Carp qw(fatalsToBrowser);
- use Encode;
- use LWP::Simple;
- use XML::Parser;
- use File::stat;
- my $MAX_AGE_IN_SECS = 300;
- my $NUMBER_OF_TWEETS = 7;
- # --- Get data from Twitter, buffer it on server file
- my $xml;
- get_tweets_cached(
- \$xml,
- $MAX_AGE_IN_SECS,
- "tweets_cache.xml",
- { count => $NUMBER_OF_TWEETS,
- screen_name => "rplantiko" }
- );
- # --- Output result
- print "Content-Type: text/html; charset=utf-8\n";
- print "Cache-Control: max-age=$MAX_AGE_IN_SECS\n";
- print "\n";
- print "<ul>\n";
- if ($xml =~ /<text>/) { # If we have a chance
- my $parser = new XML::Parser(Handlers => { Init => \&handle_init,
- Start => \&handle_start,
- End => \&handle_end,
- Char => \&handle_text } );
- $parser->parse($xml);
- }
- print "</ul>\n";
- { # <<<--- Begin of XML Parser Block
- my (%watched, $current);
- sub handle_init {
- %watched = (
- retweeted_status => { active => 0, content => "" },
- id => { active => 0, content => "" },
- text => { active => 0, content => "" },
- created_at => { active => 0, content => "" },
- );
- $current = "";
- }
- sub handle_start {
- my ($p, $el, %atts) = @_;
- my $status;
- if ($status = $watched{$el}) {
- $status->{active} = 1;
- $status->{content} = "";
- }
- $current = $el;
- }
- sub handle_end {
- my ($p, $el) = @_;
- my $status;
- if ($status = $watched{$el} and $status->{active}) {
- $status->{active} = 0;
- if ($el eq "text" and not $watched{retweeted_status}->{active}) {
- my $text = $status->{content};
- $text =~ s/(http:\/\/\S+)/<a href="$1">$1<\/a>/g;
- $text =~ s/@(\w+)/<a href="http:\/\/twitter.com\/#!\/$1">\@$1<\/a>/g;
- $text =~ s/#(\w+)/<a href="http:\/\/twitter.com\/#!\/search?q=%23$1">\#$1<\/a>/g;
- my $created_at = $watched{created_at}->{content};
- $created_at =~ s/\s*\+\d{4}.*//;
- my $id = $watched{id}->{content};
- my $item =
- qq(<li><a href="http://twitter.com/#!/rplantiko/status/$id">$created_at</a> $text</li>\n);
- # explicit encode is necessary here, since the text content comes from twitter in Latin-1:
- print encode( 'utf-8', $item );
- }
- }
- }
- sub handle_text {
- my ($p, $s) = @_;
- my $status;
- if ($status = $watched{$current} and $status->{active}) {
- $status->{content} .= $s;
- }
- }
- } # --->>> End of XML Parser Block
- # Use buffer file if still valid
- sub get_tweets_cached {
- my ($xmlref,$max_age,$filename,$params) = @_;
- local $/=undef;
- open my $file, "<$filename"; # for stats
- if (not eof $file and (time()-stat($file)->[9] < $max_age)) {
- $$xmlref = <$file>;
- }
- else {
- open $file, ">$filename";
- $$xmlref = get twitter_api_url( $params );
- print $file $$xmlref;
- }
- close $file;
- }
- # Build Twitter API URL
- sub twitter_api_url {
- my %param = (
- %{$_[0]},
- # add some more obscure parameters
- include_entities => "false",
- contributor_details => "false",
- include_rts => "true" );
- my $url = "http://api.twitter.com/1/statuses/user_timeline.xml";
- my $query = "";
- while (my ($key,$value) = each %param ) {
- $query .= "&" if $query;
- $query .= "$key=$value";
- }
- return "$url?$query";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement