- Timestamp:
- Sep 20, 2011, 11:15:31 PM (13 years ago)
- Branches:
- master, release-1.10, release-1.9
- Children:
- 3d10ed3
- Parents:
- 24bd860
- git-author:
- Edward Z. Yang <ezyang@mit.edu> (06/19/11 22:39:49)
- git-committer:
- Edward Z. Yang <ezyang@mit.edu> (09/20/11 23:15:31)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
perl/modules/Facebook/lib/BarnOwl/Module/Facebook/Handle.pm
r24bd860 r63afb72 17 17 use Data::Dumper; 18 18 use JSON; 19 use Date::Parse; 20 use POSIX; 19 21 20 22 use Scalar::Util qw(weaken); … … 24 26 25 27 our $app_id = 235537266461636; # for application 'barnowl' 28 29 # Unfortunately, Facebook does not offer a comment stream, in the same 30 # way we can get a post stream using the news feed. This makes it a bit 31 # difficult to de-duplicate comments we have already seen. We use a 32 # simple heuristic to fix this: we check if the comment's time is dated 33 # from before our last update, and don't re-post if it's dated before. 34 # Be somewhat forgiving, since it's better to duplicate a post than to 35 # drop one. Furthermore, we must use Facebook's idea of time, since the 36 # server BarnOwl is running on may be desynchronized. So we need to 37 # utilize Facebook's idea of time, not ours. We do this by looking at 38 # all of the timestamps we see while processing an update, and take the 39 # latest one and increment it by one second. 40 # 41 # What properties do we get with this setup? 42 # 43 # - We get comment updates only for the latest N posts on a news feed. 44 # Any later ones, you have to use Facebook's usual mechanisms (e.g. 45 # email notifications). 46 # 47 # - Processing a poll is relatively expensive, since we have to 48 # iterate over N new posts. It might be worthwhile polling for new 49 # comments less frequently than polling for new posts. 26 50 27 51 sub fail { … … 39 63 'cfg' => $cfg, 40 64 'facebook' => undef, 41 'last_poll' => time - 60 * 60 * 24, 42 'last_message_poll' => time, 65 66 # Initialized with our 'time', but will be synced to Facebook 67 # soon enough. 68 'last_poll' => time - 60 * 60 * 24 * 2, 43 69 'timer' => undef, 44 'message_timer' => undef, 70 71 # Message polling not implemented yet 72 #'last_message_poll' => time, 73 #'message_timer' => undef, 74 45 75 # yeah yeah, inelegant, I know. You can try using 46 76 # $fb->authorize, but at time of writing (1.0300) they didn't support … … 49 79 # minified to fit in most terminal windows. 50 80 'login_url' => 'http://goo.gl/yA42G', 81 51 82 'logged_in' => 0 52 83 }; … … 110 141 #BarnOwl::message("Polling Facebook..."); 111 142 112 # blah blah blah 143 # XXX Oh no! This blocks the user interface. Not good. 144 # Ideally, we should have some worker thread for polling facebook. 145 # But BarnOwl is probably not thread-safe >_< 113 146 114 147 my $updates = eval { … … 116 149 ->query 117 150 ->from("my_news") 118 # ->include_metadata() 119 # ->select_fields( ??? ) 120 ->where_since( "@" . $self->{last_poll} ) 151 # Not using this, because we want to pick up comment 152 # updates. We need to manually de-dup, though. 153 # ->where_since( "@" . $self->{last_poll} ) 154 ->limit_results( 200 ) 121 155 ->request() 122 156 ->as_hashref() 123 157 }; 124 125 $self->{last_poll} = time;126 158 $self->die_on_error($@); 127 159 128 160 #warn Dumper($updates); 129 161 162 my $new_last_poll = $self->{last_poll}; 130 163 for my $post ( reverse @{$updates->{data}} ) { 131 # no app invites, thanks! (XXX make configurable)164 # No app invites, thanks! (XXX make configurable) 132 165 if ($post->{type} eq 'link' && $post->{application}) { 133 166 next; 134 167 } 135 # XXX need to somehow access Facebook's user hiding mechanism... 136 # indexing is fragile 137 my $msg = BarnOwl::Message->new( 138 type => 'Facebook', 139 sender => $post->{from}{name}, 140 sender_id => $post->{from}{id}, 141 name => $post->{to}{data}[0]{name} || $post->{from}{name}, 142 name_id => $post->{to}{data}[0]{id} || $post->{from}{id}, 143 direction => 'in', 144 body => $self->format_body($post), 145 postid => $post->{id}, 146 zsig => $post->{actions}[0]{link}, 147 ); 148 BarnOwl::queue_message($msg); 149 } 168 169 # XXX Need to somehow access Facebook's user hiding 170 # mechanism 171 172 # There can be multiple recipients! Strange! Pick the first one. 173 my $name = $post->{to}{data}[0]{name} || $post->{from}{name}; 174 my $name_id = $post->{to}{data}[0]{id} || $post->{from}{id}; 175 176 # Only handle post if it's new 177 my $created_time = str2time($post->{created_time}); 178 if ($created_time >= $self->{last_poll}) { 179 # XXX indexing is fragile 180 my $msg = BarnOwl::Message->new( 181 type => 'Facebook', 182 sender => $post->{from}{name}, 183 sender_id => $post->{from}{id}, 184 name => $name, 185 name_id => $name_id, 186 direction => 'in', 187 body => $self->format_body($post), 188 postid => $post->{id}, 189 time => asctime(localtime $created_time), 190 # XXX The intent is to get the 'Comment' link, which also 191 # serves as a canonical link to the post. The {name} 192 # field should equal 'Comment'. 193 zsig => $post->{actions}[0]{link}, 194 ); 195 BarnOwl::queue_message($msg); 196 } 197 198 # This will have funky interleaving of times (they'll all be 199 # sorted linearly), but since we don't expect too many updates between 200 # polls this is pretty acceptable. 201 my $updated_time = str2time($post->{updated_time}); 202 if ($updated_time >= $self->{last_poll} && defined $post->{comments}{data}) { 203 for my $comment ( @{$post->{comments}{data}} ) { 204 my $comment_time = str2time($comment->{created_time}); 205 if ($comment_time < $self->{last_poll}) { 206 next; 207 } 208 my $msg = BarnOwl::Message->new( 209 type => 'Facebook', 210 sender => $comment->{from}{name}, 211 sender_id => $comment->{from}{id}, 212 name => $name, 213 name_id => $name_id, 214 direction => 'in', 215 body => $comment->{message}, 216 postid => $post->{id}, 217 time => asctime(localtime $comment_time), 218 ); 219 BarnOwl::queue_message($msg); 220 } 221 } 222 if ($updated_time + 1 > $new_last_poll) { 223 $new_last_poll = $updated_time + 1; 224 } 225 } 226 227 $self->{last_poll} = $new_last_poll; 150 228 } 151 229
Note: See TracChangeset
for help on using the changeset viewer.