File Coverage

blib/lib/WWW/UsePerl/Journal/Thread.pm
Criterion Covered Total %
statement 81 81 100.0
branch 22 24 91.6
condition 9 12 75.0
subroutine 16 16 100.0
pod 4 4 100.0
total 132 137 96.3


line stmt bran cond sub pod time code
1             package WWW::UsePerl::Journal::Thread;
2              
3 6     6   307383 use strict;
  6         16  
  6         302  
4 6     6   36 use warnings;
  6         11  
  6         246  
5              
6 6     6   32 use vars qw($VERSION);
  6         13  
  6         449  
7             $VERSION = '0.14';
8              
9             #----------------------------------------------------------------------------
10              
11             =head1 NAME
12              
13             WWW::UsePerl::Journal::Thread - Handles the retrieval of UsePerl journal comment threads
14              
15             =head1 SYNOPSIS
16              
17             use WWW::UsePerl::Journal;
18             use WWW::UsePerl::Journal::Thread;
19              
20             my $journal = WWW::UsePerl::Journal->new('barbie');
21             my @entries = $journal->entryids();
22              
23             my $thread = WWW::UsePerl::Journal::Thread->new(
24             j => $journal,
25             thread => $entries[0]
26             );
27              
28             my @comments = $thread->commentids();
29             for my $id (@comments) {
30             printf "\n----\n%s [%d %s %d] %s",
31             $thread->comment($id)->subject(),
32             $thread->comment($id)->score(),
33             $thread->comment($id)->user(),
34             $thread->comment($id)->uid(),
35             $thread->comment($id)->date(),
36             $thread->comment($id)->content();
37             }
38              
39             my $threadid = $thread->thread();
40              
41             =head1 DESCRIPTION
42              
43             A collection of routines to handle the retrieval of threads from a
44             UsePerl (L) journal entry.
45              
46             Using WWW::UsePerl::Journal, journal entry ids can be obtain. Each entry id
47             can be used to obtain a comment thread. Each comment property is accessed
48             via a comment object from within the thread.
49              
50             Note that as on late 2010 use.perl was decommissioned. A read-only version of
51             the site now exists on the perl.org servers, and a full database backup is
52             also available if you wish to host your own use.perl archive.
53              
54             A future edition of this distribution will allow a DBI interface to a local
55             database to retrieve journal entries.
56              
57             =cut
58              
59             # -------------------------------------
60             # Library Modules
61              
62 6     6   8913 use HTTP::Request::Common;
  6         106262  
  6         542  
63 6     6   4041 use LWP::UserAgent;
  6         102409  
  6         184  
64 6     6   3605 use Time::Piece;
  6         36146  
  6         52  
65 6     6   3931 use WWW::UsePerl::Journal::Comment;
  6         22  
  6         75  
66              
67             # -------------------------------------
68             # Variables
69              
70 6     6   361 use constant USEPERL => 'http://use.perl.org/use.perl.org';
  6         14  
  6         7353  
71              
72             my %months = (
73             'January' => 1,
74             'February' => 2,
75             'March' => 3,
76             'April' => 4,
77             'May' => 5,
78             'June' => 6,
79             'July' => 7,
80             'August' => 8,
81             'September' => 9,
82             'October' => 10,
83             'November' => 11,
84             'December' => 12,
85             );
86              
87             # -------------------------------------
88             # Public Interface
89              
90             =head1 PUBLIC INTERFACE
91              
92             =head2 The Constructor
93              
94             =over 4
95              
96             =item new
97              
98             use WWW::UsePerl::Journal;
99             my $journal = WWW::UsePerl::Journal->new('barbie');
100              
101             use WWW::UsePerl::Journal::Thread;
102             my $j = WWW::UsePerl::Journal::Thread->new(
103             j => $journal,
104             eid => $entryid,
105             );
106              
107             Creates an thread instance for the specified journal entry. An entry ID
108             returned from $journal->entryids() must use the entry => $entryid form to
109             obtain the correct thread.
110              
111             =back
112              
113             =cut
114              
115             sub new {
116 4     4 1 153841 my ($class,%opts) = @_;
117              
118 4         267 for(qw/j eid/) {
119 7 100       41 return unless(exists $opts{$_});
120             }
121              
122 3 100       54 die "No parent object"
123             unless $opts{j}->isa('WWW::UsePerl::Journal');
124              
125 2         7 my %atts = map {$_ => $opts{$_}} qw(j eid);
  4         22  
126 2         9 my $self = bless \%atts, $class;
127              
128 2         9 return $self;
129             }
130              
131             =head2 Methods
132              
133             =over 4
134              
135             =item thread()
136              
137             Returns the current thread id.
138              
139             =cut
140              
141             sub thread {
142 2     2 1 1570 my $self = shift;
143 2 100       14 $self->_commenthash unless($self->{thread});
144 2         16 return $self->{thread};
145             }
146              
147             =item comment($commentid)
148              
149             Returns a comment object of the given comment ID
150              
151             =cut
152              
153             sub comment {
154 2     2 1 1934 my $self = shift;
155 2         5 my $cid = shift;
156 2         7 my %entries = $self->_commenthash;
157 2         10 return $entries{$cid};
158             }
159              
160             =item commentids()
161              
162             Returns an ascending array of the comment IDs.
163              
164             Can take an optional hash containing; {descending=>1} to return a descending
165             list of comment IDs, {ascending=>1} to return an ascending list or
166             {threaded=>1} to return a thread ordered list. 'ascending' being the default.
167              
168             =back
169              
170             =cut
171              
172             sub commentids {
173 5     5 1 2451 my ($self,%hash) = @_;
174              
175 5         14 my ($key,$sorter) = ('_commentids_asc',\&_ascender);
176 5 100 100     42 ($key,$sorter) = ('_commentids_dsc',\&_descender) if(%hash && $hash{descending});
177 5 100 100 3   28 ($key,$sorter) = ('_commentids_thd',sub{-1}) if(%hash && $hash{threaded});
  3         7  
178              
179 5   66     42 $self->{$key} ||= do {
180 4         20 my %entries = $self->_commenthash;
181 4         29 my @ids = sort $sorter keys %entries;
182 4         22 \@ids;
183             };
184              
185 5         9 return @{$self->{$key}};
  5         32  
186             }
187              
188             # -------------------------------------
189             # The Private Methods
190              
191             # name: commenthash
192             # desc: Returns a hash of WWW::UsePerl::Journal::Comment objects
193              
194             sub _commenthash {
195 7     7   14 my $self = shift;
196              
197 7 100       33 return %{ $self->{_commenthash} } if($self->{_commenthash});
  5         28  
198              
199             # URL depends upon which id we've been given, as thread and entry
200             # are different, but both can still return the thread list, just in
201             # different formats
202              
203 2         18 my $user = $self->{j}->user;
204 2         30 my $url = USEPERL . "/_$user/journal/$self->{eid}.html";
205              
206 2         8 my $content;
207 2         4 eval { $content = $self->{j}->{ua}->request(GET $url)->content; };
  2         24  
208 2 50 33     810865 return $self->{j}->error("could not create comment list") if($@ || !$content);
209              
210 2 100       20 if($self->{j}->debug) {
211 1         15 $self->{j}->log('mess' => "#_commenthash: url=[$url]\n");
212 1         24 $self->{j}->log('mess' => "#_commenthash: content=[$content]\n");
213             }
214              
215             # main comment thread
216 2         72 my %comments;
217 2         358 my @cids = $content =~ m!
218 2 100       9 if($self->{j}->debug) {
219 1         14 $self->{j}->log('mess' => "#cids: @cids\n");
220             }
221              
222 2         63 ($self->{thread}) = $content =~ m!sid=(\d+)!;
223              
224 2         10 for my $cid (@cids) {
225              
226 6 100       22 if($self->{j}->debug) {
227 3         32 $self->{j}->log('mess' => "\n#_commenthash: cid=[$cid]\n");
228             }
229              
230 6 50       60 next if($comments{$cid});
231              
232 6         9124 my ($extract) = $content =~ m! (]*>\s*.*?) !six;
233 6 100       37 if($self->{j}->debug) {
234 3         83 $self->{j}->log('mess' => "\n#extract: [$extract]\n");
235             }
236              
237 6         116 $comments{$cid} = WWW::UsePerl::Journal::Comment->new(
238             j => $self->{j},
239             cid => $cid,
240             eid => $self->{eid},
241             extract => $extract
242             );
243             }
244              
245 2         8 %{ $self->{_commenthash} } = %comments;
  2         11  
246 2         5 return %{ $self->{_commenthash} };
  2         16  
247             }
248              
249             # sort methods
250              
251 5     5   20 sub _ascender { $a <=> $b }
252 2     2   9 sub _descender { $b <=> $a }
253              
254             1;
255              
256             __END__