blib/lib/WWW/UsePerl/Journal/Comment.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 74 | 81 | 91.3 |
branch | 22 | 30 | 73.3 |
condition | n/a | ||
subroutine | 14 | 15 | 93.3 |
pod | 2 | 2 | 100.0 |
total | 112 | 128 | 87.5 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package WWW::UsePerl::Journal::Comment; | ||||||
2 | |||||||
3 | 6 | 6 | 45438 | use strict; | |||
6 | 14 | ||||||
6 | 244 | ||||||
4 | 6 | 6 | 35 | use warnings; | |||
6 | 12 | ||||||
6 | 226 | ||||||
5 | |||||||
6 | 6 | 6 | 111 | use vars qw($VERSION $AUTOLOAD); | |||
6 | 21 | ||||||
6 | 593 | ||||||
7 | $VERSION = '0.14'; | ||||||
8 | |||||||
9 | #---------------------------------------------------------------------------- | ||||||
10 | |||||||
11 | =head1 NAME | ||||||
12 | |||||||
13 | WWW::UsePerl::Journal::Comment - Handles the retrieval of UsePerl journal entry comments. | ||||||
14 | |||||||
15 | =head1 SYNOPSIS | ||||||
16 | |||||||
17 | my $comment = WWW::UsePerl::Journal::Comment->new( | ||||||
18 | # required | ||||||
19 | j => $journal, | ||||||
20 | cid => $commentid, | ||||||
21 | eid => $entryid, | ||||||
22 | extract => $extract | ||||||
23 | ); | ||||||
24 | |||||||
25 | $comment->subject(); | ||||||
26 | |||||||
27 | # called from WWW::UsePerl::Journal::Thread object | ||||||
28 | $thread->comment( $cid )->content(); | ||||||
29 | |||||||
30 | =head1 DESCRIPTION | ||||||
31 | |||||||
32 | A collection of routines to handle the retrieval of comments from a | ||||||
33 | UsePerl (L |
||||||
34 | |||||||
35 | =cut | ||||||
36 | |||||||
37 | # ------------------------------------- | ||||||
38 | # Library Modules | ||||||
39 | |||||||
40 | 6 | 6 | 35 | use base qw(Class::Accessor::Fast); | |||
6 | 29 | ||||||
6 | 6203 | ||||||
41 | |||||||
42 | 6 | 6 | 29686 | use HTTP::Request::Common; | |||
6 | 144721 | ||||||
6 | 617 | ||||||
43 | 6 | 6 | 3926 | use LWP::UserAgent; | |||
6 | 105805 | ||||||
6 | 175 | ||||||
44 | 6 | 6 | 2779 | use Time::Piece; | |||
6 | 33409 | ||||||
6 | 51 | ||||||
45 | 6 | 6 | 32854 | use WWW::UsePerl::Journal; | |||
6 | 261475 | ||||||
6 | 2349 | ||||||
46 | |||||||
47 | # ------------------------------------- | ||||||
48 | # Constants & Variables | ||||||
49 | |||||||
50 | 6 | 6 | 84 | use constant USEPERL => 'http://use.perl.org/use.perl.org'; | |||
6 | 15 | ||||||
6 | 854 | ||||||
51 | 6 | 6 | 39 | use overload q{""} => sub { $_[0]->stringify() }; | |||
6 | 2 | 13 | |||||
6 | 75 | ||||||
2 | 10446 | ||||||
52 | |||||||
53 | my %months = ( | ||||||
54 | 'January' => 1, | ||||||
55 | 'February' => 2, | ||||||
56 | 'March' => 3, | ||||||
57 | 'April' => 4, | ||||||
58 | 'May' => 5, | ||||||
59 | 'June' => 6, | ||||||
60 | 'July' => 7, | ||||||
61 | 'August' => 8, | ||||||
62 | 'September' => 9, | ||||||
63 | 'October' => 10, | ||||||
64 | 'November' => 11, | ||||||
65 | 'December' => 12, | ||||||
66 | ); | ||||||
67 | |||||||
68 | # ------------------------------------- | ||||||
69 | # Public Interface | ||||||
70 | |||||||
71 | =head1 PUBLIC INTERFACE | ||||||
72 | |||||||
73 | =head2 The Constructor | ||||||
74 | |||||||
75 | =over 4 | ||||||
76 | |||||||
77 | =item new | ||||||
78 | |||||||
79 | Each comment is retrieved as an object. Note that the parent object | ||||||
80 | (from WWW::UsePerl::Journal), thread id and comment id are mandatory | ||||||
81 | requirements to create the object. | ||||||
82 | |||||||
83 | =back | ||||||
84 | |||||||
85 | =cut | ||||||
86 | |||||||
87 | sub new { | ||||||
88 | 10 | 10 | 1 | 5701 | my ($class,%opts) = @_; | ||
89 | |||||||
90 | 10 | 26 | for(qw/j eid cid extract/) { | ||||
91 | 37 | 100 | 110 | return unless(exists $opts{$_}); | |||
92 | } | ||||||
93 | |||||||
94 | 9 | 100 | 66 | die "No parent object" | |||
95 | unless $opts{j}->isa('WWW::UsePerl::Journal'); | ||||||
96 | |||||||
97 | 8 | 17 | my %atts = map {$_ => $opts{$_}} qw(j eid cid extract); | ||||
32 | 98 | ||||||
98 | 8 | 38 | my $self = bless \%atts, $class; | ||||
99 | |||||||
100 | 8 | 29 | $self->_get_content(); | ||||
101 | |||||||
102 | 8 | 61 | return $self; | ||||
103 | } | ||||||
104 | |||||||
105 | #---------------------------------------------------------------------------- | ||||||
106 | # Accessors | ||||||
107 | |||||||
108 | =head2 The Accessors | ||||||
109 | |||||||
110 | The following accessor methods are available: | ||||||
111 | |||||||
112 | id | ||||||
113 | date | ||||||
114 | subject | ||||||
115 | user | ||||||
116 | uid | ||||||
117 | score | ||||||
118 | content | ||||||
119 | |||||||
120 | All functions can be called to return the current value of the associated | ||||||
121 | object variable. | ||||||
122 | |||||||
123 | =cut | ||||||
124 | |||||||
125 | __PACKAGE__->mk_accessors($_) for qw(cid date subject user uid score content); | ||||||
126 | |||||||
127 | =head2 Methods | ||||||
128 | |||||||
129 | =over 4 | ||||||
130 | |||||||
131 | =item stringify - For String Context | ||||||
132 | |||||||
133 | When an object is called directly, stringification occurs. Safer to | ||||||
134 | use -E |
||||||
135 | |||||||
136 | =back | ||||||
137 | |||||||
138 | =cut | ||||||
139 | |||||||
140 | sub stringify { | ||||||
141 | 2 | 2 | 1 | 5 | my $self = shift; | ||
142 | 2 | 8 | return $self->content(); | ||||
143 | } | ||||||
144 | |||||||
145 | # ------------------------------------- | ||||||
146 | # The Private Subs | ||||||
147 | |||||||
148 | # name: _get_content | ||||||
149 | # args: self .... object itself | ||||||
150 | # retv: content text | ||||||
151 | # desc: Retrieves the content and additional information for a given | ||||||
152 | # comment. Splits the fields into object variables and returns | ||||||
153 | # the content text | ||||||
154 | |||||||
155 | sub _get_content { | ||||||
156 | 8 | 8 | 15 | my $self = shift; | |||
157 | |||||||
158 | 8 | 124 | my $content = $self->{extract}; | ||||
159 | |||||||
160 | 8 | 100 | 29 | if($self->{j}->debug) { | |||
161 | 3 | 36 | $self->{j}->log('mess' => "\n#_get_content: content=[$content]\n"); | ||||
162 | } | ||||||
163 | |||||||
164 | 8 | 100 | 104 | return $self->{j}->error("Error getting entry") unless $content; | |||
165 | |||||||
166 | # remember there are different presentations for dates!!!! | ||||||
167 | |||||||
168 | 7 | 11 | my ($string,$format); | ||||
169 | 7 | 123 | $content =~ s/\n//g; | ||||
170 | 7 | 163 | my @fields = ( $content =~ m! | ||||
171 | |
||||||
172 | .*? ]+>([^<]+) # subject |
||||||
173 | .*? | ||||||
174 | .*? Score:(\d+).*? # score | ||||||
175 | .*? \s*(\w+) # username | ||||||
176 | .*? \((\d+)\) # userid | ||||||
177 | (?:\s+ | ||||||
178 | .*? on\s+(\d+\.\d+.\d+\s\d+:\d+) # date/time - "2003.05.20 17:31" or "Friday August 08 2003, @01:51PM" | ||||||
179 | .*? )? | ||||||
180 | .*? (.*?) # text |
||||||
181 | !mixs ); | ||||||
182 | |||||||
183 | 7 | 55 | ($self->{pid}) = $content =~ m/id="commtree_(\d+)"/; | ||||
184 | |||||||
185 | 7 | 100 | 28 | if($self->{j}->debug) { | |||
186 | 3 | 100 | 26 | $self->{j}->log('mess' => "\n#_get_content: fields=[".(join("][",map {$_||''} @fields))."]\n"); | |||
21 | 77 | ||||||
187 | } | ||||||
188 | |||||||
189 | 7 | 100 | 71 | return unless(@fields); | |||
190 | |||||||
191 | 6 | 100 | 18 | if($fields[5]) { | |||
192 | 2 | 17 | my ($year, $month, $day, $hr, $mi) = $fields[5] =~ m! (\d+)\.(\d+)\.(\d+) .*? (\d+):(\d+) !smx; | ||||
193 | 2 | 50 | 7 | unless($day) { | |||
194 | 0 | 0 | my $amp; | ||||
195 | 0 | 0 | ($month, $day, $year, $hr, $mi, $amp) = $fields[5] =~ m! \w+\s+ (\w+) \s+(\d+)\s*(\d*), \s+ @(\d+):(\d+)([AP]M) !smx; | ||||
196 | 0 | 0 | $month = $months{$month}; | ||||
197 | 0 | 0 | 0 | $year = (localtime)[5] unless($year); # current year formatting drops the year. | |||
198 | 0 | 0 | 0 | $hr += 12 if ($amp eq 'PM'); | |||
199 | 0 | 0 | 0 | $hr = 0 if $hr == 24; | |||
200 | } | ||||||
201 | |||||||
202 | 2 | 100 | 9 | if($self->{j}->debug) { | |||
203 | 1 | 13 | $self->{j}->log('mess' => "\n#_get_content: date=[$year $month $day ${hr}:$mi]\n"); | ||||
204 | } | ||||||
205 | |||||||
206 | # sometimes Time::Piece can't parse the date :( | ||||||
207 | 2 | 17 | eval { | ||||
208 | 2 | 37 | $self->{date} = Time::Piece->strptime( | ||||
209 | "$month $day $year ${hr}:$mi", | ||||||
210 | '%m %d %Y %H:%M' | ||||||
211 | ); | ||||||
212 | }; | ||||||
213 | |||||||
214 | 2 | 100 | 95 | if($self->{j}->debug) { | |||
215 | 1 | 105 | $self->{j}->log('mess' => "\n#_get_content: date=[".$self->{date}."]\n"); | ||||
216 | } | ||||||
217 | } | ||||||
218 | |||||||
219 | 6 | 117 | $self->{subject} = $fields[1]; | ||||
220 | 6 | 17 | $self->{score} = $fields[2]; | ||||
221 | 6 | 19 | $self->{user} = $fields[3]; | ||||
222 | 6 | 14 | $self->{uid} = $fields[4]; | ||||
223 | 6 | 10 | $self->{content} = $fields[6]; | ||||
224 | |||||||
225 | 6 | 50 | 14 | return unless($self->{content}); # What no content! | |||
226 | |||||||
227 | 6 | 707 | $self->{content} =~ s!(\s+<(?:p|br /)>)*$!!gi; # remove trailing whitespace formatting | ||||
228 | 6 | 81 | $self->{content} =~ s!\s+(<(p|br /)>)!$1!gi; # remove whitespace before whitespace formatting | ||||
229 | 6 | 44 | $self->{content} =~ s!(<(p|br /)>){2,}! !gi; # remove repeated whitespace formatting |
||||
230 | |||||||
231 | 6 | 19 | return; | ||||
232 | } | ||||||
233 | |||||||
234 | 0 | 0 | sub DESTROY {} | ||||
235 | |||||||
236 | 1; | ||||||
237 | |||||||
238 | __END__ |