root/lang/perl/misc/WassrPod/wassrpod.pl @ 15513

Revision 15513, 3.7 kB (checked in by tokuhirom, 5 years ago)

use latest version of JSON.pm

Line 
1#!/usr/bin/env perl
2package WassrPod;
3use Moose;
4use HTTP::Engine;
5use HTTP::Headers;
6use LWP::UserAgent;
7use JSON 2.11;
8use DateTime;
9use XML::Simple;
10use Encode;
11
12our $VERSION = '0.0.1';
13
14use Data::Dumper;
15
16with 'MooseX::Getopt';
17
18has port =>
19    is      => 'ro',
20    isa     => 'Int',
21    default => 9277; # 9277 = wassr
22
23sub run {
24    my $self = shift;
25    my $engine = HTTP::Engine->new(
26        interface => {
27            module => 'ServerSimple',
28            args   => {
29                host => '127.0.0.1',
30                port => $self->port,
31            },
32            request_handler => sub { $self->handler(@_) },
33        },
34    );
35    $engine->run;
36}
37
38sub handler {
39    my($self, $c) = @_;
40    my $req = $c->req;
41
42    my $body = '';
43    if ($req->path eq 'http://twitter.com/statuses/friends_timeline.xml') {
44        $body = $self->friends_timeline($req);
45        $c->res->header('Content-Type' => 'application/xml');
46    } elsif ($req->path eq 'http://twitter.com/statuses/update.xml') {
47        $body = $self->update($req);
48        $c->res->header('Content-Type' => 'application/xml');
49    } elsif ($req->path =~ '^http://wassr.jp/.*$') {
50        my $ua = ua($req, 'wassr.jp');
51        my $res = $ua->get($req->path);
52        $c->res->header('Content-Type' => $res->header('Content-Type'));
53        $body = $res->content;
54    } else {
55        warn $req->path;
56    }
57    $c->res->body($body);
58};
59
60sub ua {
61    my $req = shift;
62    my $host = shift || 'api.wassr.jp';
63
64    my $headers = $req->headers->clone;
65    $headers->remove_header('host');
66    $headers->header( Host => $host );
67    $headers->remove_header('user-agent');
68    $headers->header( 'User-Agent' => sprintf('%s/%s', __PACKAGE__, $VERSION) );
69
70    my $ua = LWP::UserAgent->new(
71        default_headers => $headers,
72    );
73    $ua->default_headers($headers);
74    $ua;
75}
76
77sub friends_timeline {
78    my($self, $req) = @_;
79
80    my $ua = ua $req;
81
82    my $ret = $ua->get('http://api.wassr.jp/statuses/friends_timeline.json');
83    my $json = eval { decode_json($ret->content) };
84    return '<statuses></statuses>' if $@ || !ref($json);
85
86    my $data = {
87        statuses => {
88            status => [
89            ]
90        }
91    };
92
93    for my $status (@{ $json }) {
94        my $dt = DateTime->from_epoch( epoch => $status->{epoch} );
95        # $dt->set_time_zone( 'Asia/Tokyo' );
96        my $user = $status->{user_login_id};
97        my $tmp = {
98            created_at => $dt->strftime('%a %b %d %T %z %Y'),
99            id => $status->{rid},
100            text => $status->{text},
101            source => 'web',
102            truncated => 'false',
103            in_reply_to_status_id => undef,
104            in_reply_to_user_id => undef,
105            favorited => undef,
106
107            user => {
108                id => $user,
109                name => $user,
110                screen_name => $status->{user}->{screen_name},
111                location => undef,
112                description => undef,
113                profile_image_url => $status->{user}->{profile_image_url},
114                url => undef,
115                protected => ''.$status->{user}->{protected},
116                followers_count => 1,
117            },
118        };
119        push @{ $data->{statuses}->{status} }, $tmp;
120    }
121
122    my $xml = XMLout($data, NoAttr => 1, KeepRoot => 1, NumericEscape => 3 );
123    $xml =~ s/<statuses>/<statuses type="array">/;
124    $xml = qq{<?xml version="1.0" encoding="UTF-8"?>\n$xml};
125    $xml;
126}
127
128sub update {
129    my($self, $req) = @_;
130
131    my $status = $req->param('status');
132    my $source = "WassrPod(@{[ $req->param('source') ]})";
133
134    my $ua = ua $req;
135    my $ret = $ua->post('http://api.wassr.jp/statuses/update.json', {
136        status => $status,
137        source => $source,
138    });
139    $ret->content;
140}
141
142package main;
143WassrPod->new_with_options->run;
144
Note: See TracBrowser for help on using the browser.