File Coverage

blib/lib/BusyBird/Filter/Twitter.pm
Criterion Covered Total %
statement 77 77 100.0
branch 23 24 95.8
condition 2 3 66.6
subroutine 17 17 100.0
pod 8 8 100.0
total 127 129 98.4


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