File Coverage

blib/lib/BusyBird/Filter/Twitter.pm
Criterion Covered Total %
statement 74 74 100.0
branch 23 24 95.8
condition 2 3 66.6
subroutine 16 16 100.0
pod 8 8 100.0
total 123 125 98.4


line stmt bran cond sub pod time code
1             package BusyBird::Filter::Twitter;
2 1     1   29376 use strict;
  1         2  
  1         30  
3 1     1   4 use warnings;
  1         2  
  1         20  
4 1     1   422 use BusyBird::DateTime::Format;
  1         126808  
  1         38  
5 1     1   484 use BusyBird::Util qw(split_with_entities vivifiable_as);
  1         3  
  1         68  
6 1     1   342 use BusyBird::Filter qw(filter_map);
  1         2  
  1         50  
7 1     1   6 use Exporter qw(import);
  1         2  
  1         728  
8              
9             {
10             my @names = qw(all search_status status_id unescape);
11             our %EXPORT_TAGS = (
12             transform => [map { "trans_twitter_$_" } @names],
13             filter => [map { "filter_twitter_$_" } @names]
14             );
15             }
16             BusyBird::Util::export_ok_all_tags;
17              
18             my $DATETIME_FORMATTER = 'BusyBird::DateTime::Format';
19              
20              
21             my %_SEARCH_KEY_MAP = (
22             id => 'from_user_id',
23             id_str => 'from_user_id_str',
24             screen_name => 'from_user',
25             profile_image_url => 'profile_image_url',
26             );
27              
28             sub trans_twitter_search_status {
29 20     20 1 864 my ($status) = @_;
30 20 100       53 if(exists($status->{created_at})) {
31 4         20 $status->{created_at} = $DATETIME_FORMATTER->format_datetime(
32             $DATETIME_FORMATTER->parse_datetime($status->{created_at})
33             );
34             }
35 20 100       5006 return $status if defined $status->{user};
36 16         24 $status->{user} = {};
37 16         36 foreach my $new_id_key (keys %_SEARCH_KEY_MAP) {
38 64         57 my $orig_id_key = $_SEARCH_KEY_MAP{$new_id_key};
39 64 100       132 $status->{user}{$new_id_key} = delete $status->{$orig_id_key} if exists $status->{$orig_id_key};
40             }
41 16         45 return $status;
42             }
43              
44             my $FILTER_SEARCH = filter_map \&trans_twitter_search_status;
45              
46             sub filter_twitter_search_status {
47 1     1 1 3 return $FILTER_SEARCH;
48             }
49              
50             sub trans_twitter_status_id {
51 22     22 1 1440 my ($status, $api_url) = @_;
52 22 100       48 $api_url = "https://api.twitter.com/1.1/" if not defined $api_url;
53 22         85 $api_url =~ s|/+$||;
54 22         33 foreach my $key (qw(id id_str in_reply_to_status_id in_reply_to_status_id_str)) {
55 88 100       155 next if not defined $status->{$key};
56 30 100 66     82 if(vivifiable_as($status->{busybird}, "HASH")
57             && vivifiable_as($status->{busybird}{original}, "HASH")) {
58 27         53 $status->{busybird}{original}{$key} = $status->{$key};
59             }
60 30         89 $status->{$key} = "$api_url/statuses/show/" . $status->{$key} . ".json";
61             }
62 22         63 return $status;
63             }
64              
65             sub filter_twitter_status_id {
66 2     2 1 4 my ($api_url) = @_;
67 2     2   12 return filter_map sub { trans_twitter_status_id($_[0], $api_url) };
  2         7  
68             }
69              
70             sub trans_twitter_unescape {
71 29     29 1 4066 my ($status) = @_;
72 29 100       66 if(ref($status->{retweeted_status}) eq "HASH") {
73 3         9 trans_twitter_unescape($status->{retweeted_status});
74             }
75 29 100       53 if(!defined($status->{text})) {
76 19         75 return $status;
77             }
78 10         32 my $segments = split_with_entities($status->{text}, $status->{entities});
79 10         13 my $new_text = "";
80 10         13 my %new_entities = ();
81 10 100       51 if(ref($status->{entities}) eq 'HASH') {
82 6         7 %new_entities = map { $_ => [] } keys %{$status->{entities}};
  24         37  
  6         11  
83             }
84 10         15 foreach my $segment (@$segments) {
85 34         54 $segment->{text} =~ s/</
86 34         40 $segment->{text} =~ s/>/>/g;
87 34         32 $segment->{text} =~ s/"/"/g;
88 34         38 $segment->{text} =~ s/&/&/g;
89 34 100       65 if(ref($segment->{entity}) eq "HASH") {
90 14 50       28 if(vivifiable_as($segment->{entity}{indices}, "ARRAY")) {
91 14         19 $segment->{entity}{indices}[0] = length($new_text);
92 14         26 $segment->{entity}{indices}[1] = $segment->{entity}{indices}[0] + length($segment->{text});
93             }
94 14         14 push(@{$new_entities{$segment->{type}}}, $segment->{entity});
  14         21  
95             }
96 34         50 $new_text .= $segment->{text};
97             }
98 10         13 $status->{text} = $new_text;
99 10 100       20 if(defined($status->{entities})) {
100 6         7 $status->{entities} = \%new_entities;
101             }
102 10         69 return $status;
103             }
104              
105             my $FILTER_UNESCAPE = filter_map \&trans_twitter_unescape;
106              
107             sub filter_twitter_unescape {
108 4     4 1 10 return $FILTER_UNESCAPE;
109             }
110              
111             sub trans_twitter_all {
112 18     18 1 1635 my ($status, $api_url) = @_;
113 18         29 return trans_twitter_unescape(
114             trans_twitter_status_id(
115             trans_twitter_search_status($status),
116             $api_url
117             )
118             );
119             }
120              
121             sub filter_twitter_all {
122 3     3 1 2486 my ($api_url) = @_;
123 3     16   18 return filter_map sub { trans_twitter_all($_[0], $api_url) };
  16         35  
124             }
125              
126              
127             1;
128             __END__