1 |
dpavlin |
1 |
#!/usr/bin/perl |
2 |
|
|
# Copyright David Leadbeater 2007 <http://dgl.cx>. |
3 |
|
|
# Licensed under the same terms as Perl itself. |
4 |
|
|
|
5 |
|
|
# A simple example of using WWW::Facebook::API within a facebook canvas. |
6 |
|
|
# You will need to change the api_key, secret and app_path below to match your |
7 |
|
|
# account. To get an api_key and secret, go to |
8 |
|
|
# http://www.facebook.com/developers/editapp.php?new, choose "Use FBML" and |
9 |
|
|
# enter a unique name for the canvas which you should put into app_path. |
10 |
|
|
|
11 |
|
|
use strict; |
12 |
|
|
use CGI; |
13 |
|
|
use WWW::Facebook::API; |
14 |
|
|
use Data::Dump qw/dump/; |
15 |
|
|
use XML::FeedPP; |
16 |
dpavlin |
2 |
use Time::HiRes qw/time/; |
17 |
dpavlin |
1 |
|
18 |
dpavlin |
2 |
our ($api_key,$secret,$rss_url,$app_path); # XXX configure this in config.pl |
19 |
dpavlin |
1 |
require 'config.pl'; |
20 |
|
|
|
21 |
dpavlin |
2 |
# UI elements |
22 |
|
|
|
23 |
dpavlin |
3 |
my $facebook = WWW::Facebook::API->new( |
24 |
|
|
api_key => $api_key, |
25 |
|
|
secret => $secret, |
26 |
|
|
app_path => $app_path, |
27 |
|
|
parse => 1, |
28 |
|
|
); |
29 |
|
|
|
30 |
|
|
warn dump($facebook); |
31 |
|
|
|
32 |
dpavlin |
2 |
sub dashboard { |
33 |
|
|
print qq| |
34 |
|
|
<fb:dashboard> |
35 |
|
|
<fb:action href=/$app_path/>Search</fb:action> |
36 |
|
|
</fb:dashboard> |
37 |
|
|
|; |
38 |
|
|
''; |
39 |
|
|
} |
40 |
|
|
|
41 |
|
|
sub form { |
42 |
|
|
my $q = shift; |
43 |
|
|
my $v = $q->param('search'); |
44 |
|
|
$v = qq| value="$v"| if defined $v; |
45 |
|
|
|
46 |
|
|
print qq| |
47 |
|
|
<form method="post" action="search"> |
48 |
|
|
<input name="search" $v> |
49 |
|
|
<input type="submit"> |
50 |
|
|
</form> |
51 |
|
|
|; |
52 |
|
|
''; |
53 |
|
|
} |
54 |
|
|
|
55 |
dpavlin |
3 |
# dispatcher |
56 |
dpavlin |
2 |
|
57 |
dpavlin |
1 |
our %action_map = ( |
58 |
|
|
'' => \&index_page, |
59 |
|
|
info => \&info_page, |
60 |
|
|
search => \&search_page, |
61 |
dpavlin |
2 |
debug => \&debug_page, |
62 |
dpavlin |
1 |
); |
63 |
|
|
|
64 |
|
|
sub main { |
65 |
|
|
|
66 |
|
|
# Should also work with FastCGI (via CGI::Fast). |
67 |
|
|
my $q = new CGI; |
68 |
|
|
print "Content-type: text/html; encoding=utf-8\r\n\r\n"; |
69 |
|
|
|
70 |
|
|
# redirect("Must be called in facebook canvas") |
71 |
|
|
# unless $facebook->canvas->in_fb_canvas($q); |
72 |
|
|
|
73 |
|
|
my $params = $facebook->canvas->validate_sig($q); |
74 |
|
|
if ( $params->{user} ) { |
75 |
|
|
|
76 |
|
|
# Canvas takes care of setting up a session for us, no need to call the |
77 |
|
|
# auth methods. |
78 |
|
|
$facebook->session_key( $params->{session_key} ); |
79 |
|
|
} |
80 |
|
|
else { |
81 |
|
|
|
82 |
|
|
# User hasn't added app (could reject/display info/whatever) |
83 |
|
|
# (Or handle later when a user is needed). |
84 |
|
|
} |
85 |
|
|
|
86 |
|
|
my ( $action, $param ) = ( $q->path_info =~ m!^/(\w+)/?(.*)! ); |
87 |
dpavlin |
2 |
|
88 |
dpavlin |
3 |
print dashboard; |
89 |
|
|
|
90 |
dpavlin |
1 |
if ( my $s = $action_map{$action} ) { |
91 |
dpavlin |
2 |
print qq|<div style='padding-left: 2em'>|; |
92 |
dpavlin |
1 |
$s->( $q, $params ); |
93 |
dpavlin |
2 |
print qq|</div>|; |
94 |
dpavlin |
1 |
} |
95 |
|
|
else { |
96 |
dpavlin |
3 |
print "Action <tt>$action</tt> unknown"; |
97 |
|
|
warn "unknown action $action"; |
98 |
dpavlin |
1 |
} |
99 |
|
|
|
100 |
|
|
# Clear session_key (for if running under FastCGI). |
101 |
|
|
$facebook->session_key(undef); |
102 |
|
|
} |
103 |
|
|
|
104 |
|
|
sub index_page { |
105 |
dpavlin |
2 |
my ( $q, $params ) = @_; |
106 |
dpavlin |
1 |
|
107 |
dpavlin |
3 |
warn dump($params); |
108 |
|
|
|
109 |
dpavlin |
2 |
form($q); |
110 |
dpavlin |
1 |
|
111 |
dpavlin |
2 |
=for later |
112 |
|
|
|
113 |
dpavlin |
1 |
# You could do this easier by using <fb:name>, just showing some API stuff here. |
114 |
|
|
my $name = "You"; |
115 |
|
|
if ($params) { |
116 |
|
|
my $res = |
117 |
|
|
$facebook->fql->query( query => |
118 |
|
|
"SELECT first_name FROM user WHERE uid=$params->{canvas_user}" ); |
119 |
|
|
$name = "Hi $res->[0]->{first_name}, you"; |
120 |
|
|
} |
121 |
|
|
print "$name ", ( $params ? "have" : "have't" ), |
122 |
|
|
" added this application. Some <a href='info'>info</a>."; |
123 |
dpavlin |
3 |
=cut |
124 |
|
|
|
125 |
dpavlin |
1 |
if ( !$params ) { |
126 |
|
|
print "<a href='", $facebook->get_add_url, |
127 |
|
|
"'>Add this application</a>."; |
128 |
|
|
} |
129 |
|
|
|
130 |
|
|
|
131 |
|
|
|
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
sub info_page { |
135 |
dpavlin |
2 |
open( my $fh, '<', 'info.html' ); |
136 |
|
|
print <$fh>; |
137 |
|
|
close($fh); |
138 |
|
|
} |
139 |
dpavlin |
1 |
|
140 |
dpavlin |
2 |
sub debug_page { |
141 |
|
|
my ( $q, $params ) = @_; |
142 |
|
|
print "<pre>"; |
143 |
dpavlin |
1 |
print dump($params); |
144 |
dpavlin |
2 |
print "</pre>"; |
145 |
dpavlin |
1 |
} |
146 |
|
|
|
147 |
|
|
sub search_page { |
148 |
|
|
my ( $q, $params ) = @_; |
149 |
|
|
|
150 |
|
|
my $search = $q->param('search'); |
151 |
dpavlin |
2 |
|
152 |
|
|
my $t = time(); |
153 |
|
|
|
154 |
|
|
my $feed = XML::FeedPP->new( $rss_url . $search ); |
155 |
|
|
|
156 |
|
|
my $t = time() - $t; |
157 |
dpavlin |
1 |
|
158 |
dpavlin |
2 |
print form($q), qq| |
159 |
dpavlin |
1 |
<ol> |
160 |
|
|
|; |
161 |
|
|
|
162 |
|
|
foreach my $item ( $feed->get_item ) { |
163 |
|
|
print qq|<li><a href="|, $item->link, qq|">|, $item->title, qq|</a><br>|, $item->description; |
164 |
|
|
} |
165 |
|
|
|
166 |
|
|
print qq| |
167 |
|
|
</ol> |
168 |
dpavlin |
2 |
|
169 |
|
|
<div style="color: #ccc;">search took $t sec</div> |
170 |
dpavlin |
1 |
|; |
171 |
|
|
|
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
sub redirect { |
175 |
dpavlin |
2 |
print("Please go <a href='" |
176 |
dpavlin |
1 |
. $facebook->get_app_url |
177 |
|
|
. "'>to facebook</a>" ); |
178 |
|
|
exit; |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
main(); |