File Coverage

blib/lib/WWW/VieDeMerde.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package WWW::VieDeMerde;
2              
3 6     6   188778 use warnings;
  6         16  
  6         239  
4 6     6   36 use strict;
  6         15  
  6         208  
5              
6 6     6   33 use Carp;
  6         16  
  6         525  
7 6     6   7245 use LWP::UserAgent;
  6         462379  
  6         232  
8 6     6   17612 use XML::Twig;
  0            
  0            
9              
10             use WWW::VieDeMerde::Message;
11             use WWW::VieDeMerde::Comment;
12              
13             =encoding utf8
14              
15             =head1 NAME
16              
17             WWW::VieDeMerde - A perl module to use the viedemerde.fr API
18              
19             =head1 VERSION
20              
21             Version 0.21
22              
23             =cut
24              
25             our $VERSION = '0.21';
26              
27             =head1 SYNOPSIS
28              
29             use WWW::VieDeMerde;
30            
31             my $toto = WWW::VieDeMerde->new();
32             my $tata = $toto->last();
33             my $tata = $toto->page(17);
34             my $tata = $toto->random();
35             my $tata = $toto->get(1234);
36            
37             print $tata->text, $tata->author;
38              
39             =head1 DESCRIPTION
40              
41             viedemerde.fr and fmylife.com are microblogs where people post short
42             messages in order to show how their life is crappy. It offers a simple
43             but efficient http-based API.
44              
45             This module aims to implement a full interface for the version 2.0 of
46             the API. The full documentation is here:
47             L.
48              
49             =head1 METHODS
50              
51             =head2 new
52              
53             Creates a new WWW::VieDeMerde object.
54              
55             Parameters are:
56              
57             =over 4
58              
59             =item * key
60              
61             Your developper key. The defaults value ("readonly") is sufficient for
62             readonly functions. You can ask for a key here:
63             L or L.
64              
65             =item * token
66              
67             The authentification to use an user account. See the API doc.
68              
69             Not sure it will works.
70              
71             =item * url
72              
73             The URL of the API server. Do not change it, the defaults value ("api.betacie.com") is good enough.
74              
75             =back
76              
77             =cut
78              
79             sub new {
80             my $class = shift;
81             my %params = @_;
82              
83             my %defaults = (
84             key => 'readonly',
85             token => undef,
86             url => 'http://api.betacie.com',
87             autoerrors => 0,
88             lang => 'fr',
89             );
90              
91             my $self = {};
92             bless($self, $class);
93              
94             for (keys %defaults) {
95             if (exists $params{$_}) {
96             $self->{$_} = $params{$_};
97             }
98             else {
99             $self->{$_} = $defaults{$_};
100             }
101             }
102              
103             $self->{ua} = LWP::UserAgent->new();
104             $self->{twig} = XML::Twig->new();
105              
106             return $self;
107             }
108              
109             =head2 page
110              
111             C<< $vdm->page() >> returns the last 15 entries.
112              
113             C<< $vdm->page($n) >> the $n page (0 is the last one).
114              
115             If the page you ask is empty, returns an empty list.
116              
117             =cut
118              
119             sub page {
120             my $self = shift;
121             my $page = shift;
122              
123             my $t = $self->{twig};
124              
125             my $xml = $self->_run('view', 'last', $page);
126              
127             if (defined($xml)) {
128             my @result = WWW::VieDeMerde::Message->parse($t);
129             return @result;
130             }
131             return undef;
132             }
133              
134             =head2 last
135              
136             C<< $vdm->last >> alias for C<< $vdm->page >>.
137              
138             =cut
139              
140             sub last {
141             my $self = shift;
142              
143             return $self->page();
144             }
145              
146             =head2 random
147              
148             C<< $vdm->random() >> returns a random entry.
149              
150             =cut
151              
152             sub random {
153             my $self = shift;
154              
155             my $t = $self->{twig};
156              
157             my $xml = $self->_run('view', 'random');
158             if (defined($xml)) {
159             my @l = WWW::VieDeMerde::Message->parse($t);
160             return $l[0];
161             }
162             return undef;
163             }
164              
165             =head2 get
166              
167             C<< $vdm->get($id) >> returns the item number $id.
168              
169             =cut
170              
171             sub get {
172             my $self = shift;
173             my $id = shift;
174             my $t = $self->{twig};
175              
176             my $xml = $self->_run('view', $id, 'nocomment');
177             if (defined($xml)) {
178             my @l = WWW::VieDeMerde::Message->parse($t);
179             return $l[0];
180             }
181             return undef;
182             }
183              
184             =head2 comments
185              
186             C<< $vdm->comments($id) >> returns the comments of the item $id.
187              
188             =cut
189              
190             sub comments {
191             my $self = shift;
192             my $id = shift;
193             my $t = $self->{twig};
194              
195             my $xml = $self->_run('view', $id);
196             if (defined($xml)) {
197             my @l = WWW::VieDeMerde::Comment->parse($t);
198             return @l;
199             }
200             return undef;
201             }
202              
203              
204             =head2 top
205              
206             C<< $vdm->top() >> returns the 15 better ranked entries.
207              
208             This function and all the top_* and flop_* functions accept a page
209             number as argument.
210              
211             =cut
212              
213             sub top {
214             my $self = shift;
215             my $page = shift;
216              
217             my $t = $self->{twig};
218              
219             my $xml = $self->_run('view', 'top', $page);
220             if (defined($xml)) {
221             my @result = WWW::VieDeMerde::Message->parse($t);
222             return @result;
223             }
224             return undef;
225             }
226              
227             =head2 top_day
228              
229             C<< $vdm->top_day() >> returns the top of the day.
230              
231             =cut
232              
233             sub top_day {
234             my $self = shift;
235             my $page = shift;
236              
237             my $t = $self->{twig};
238              
239             my $xml = $self->_run('view', 'top_day', $page);
240             if (defined($xml)) {
241             my @result = WWW::VieDeMerde::Message->parse($t);
242             return @result;
243             }
244             return undef;
245             }
246              
247             =head2 top_jour
248              
249             C<< $vdm->top_jour >> is an alias for C<< $vdm->top_day >>.
250              
251             =cut
252              
253             sub top_jour {
254             my $self = shift;
255             my $page = shift;
256              
257             return $self->top_day($page);
258             }
259              
260              
261             =head2 top_week
262              
263             C<< $vdm->top_week() >> return the week top.
264              
265             =cut
266              
267             sub top_week {
268             my $self = shift;
269             my $page = shift;
270              
271             my $t = $self->{twig};
272              
273             my $xml = $self->_run('view', 'top_week', $page);
274             if (defined($xml)) {
275             my @result = WWW::VieDeMerde::Message->parse($t);
276             return @result;
277             }
278             return undef;
279             }
280              
281             =head2 top_semaine
282              
283             C<< $vdm->top_semaine >> is an alias for C<< $vdm->top_week >>.
284              
285             =cut
286              
287             sub top_semaine {
288             my $self = shift;
289             my $page = shift;
290              
291             return $self->top_week($page);
292             }
293              
294              
295             =head2 top_month
296              
297             C<< $vdm->top_month() >> returns the month top.
298              
299             =cut
300              
301             sub top_mois {
302             my $self = shift;
303             my $page = shift;
304              
305             my $t = $self->{twig};
306              
307             my $xml = $self->_run('view', 'top_mois', $page);
308             if (defined($xml)) {
309             my @result = WWW::VieDeMerde::Message->parse($t);
310             return @result;
311             }
312             return undef;
313             }
314              
315             =head2 top_mois
316              
317             C<< $vdm->top_mois >> is an alias for C<< $vdm->top_month >>.
318              
319             =cut
320              
321             sub top_month {
322             my $self = shift;
323             my $page = shift;
324              
325             return $self->top_month($page);
326             }
327              
328             =head2 flop
329              
330             C<< $vdm->flop() >> returns the global top.
331              
332             =cut
333              
334             sub flop {
335             my $self = shift;
336             my $page = shift;
337              
338             my $t = $self->{twig};
339              
340             my $xml = $self->_run('view', 'flop', $page);
341             if (defined($xml)) {
342             my @result = WWW::VieDeMerde::Message->parse($t);
343             return @result;
344             }
345             return undef;
346             }
347              
348             =head2 flop_day
349              
350             C<< $vdm->flop_day() >> returns day flop.
351              
352             =cut
353              
354             sub flop_day {
355             my $self = shift;
356             my $page = shift;
357              
358             my $t = $self->{twig};
359              
360             my $xml = $self->_run('view', 'flop_day', $page);
361             if (defined($xml)) {
362             my @result = WWW::VieDeMerde::Message->parse($t);
363             return @result;
364             }
365             return undef;
366             }
367              
368             =head2 flop_jour
369              
370             C<< $vdm->flop_jour >> is an alias for C<< $vdm->top_day >>.
371              
372             =cut
373              
374             sub flop_jour {
375             my $self = shift;
376             my $page = shift;
377              
378             return $self->flop_day($page);
379             }
380              
381             =head2 flop_week
382              
383             C<< $vdm->flop_week() >> returns week flop.
384              
385             =cut
386              
387             sub flop_week {
388             my $self = shift;
389             my $page = shift;
390              
391             my $t = $self->{twig};
392              
393             my $xml = $self->_run('view', 'flop_week', $page);
394             if (defined($xml)) {
395             my @result = WWW::VieDeMerde::Message->parse($t);
396             return @result;
397             }
398             return undef;
399             }
400              
401             =head2 flop_semaine
402              
403             C<< $vdm->flop_semaine >> is an alias for C<< $vdm->flop_semain >>.
404              
405             =cut
406              
407             sub flop_semaine {
408             my $self = shift;
409             my $page = shift;
410              
411             return $self->flop_week($page);
412             }
413              
414             =head2 flop_month
415              
416             C<< $vdm->flop_month() >> returns month flop.
417              
418             =cut
419              
420             sub flop_month {
421             my $self = shift;
422             my $page = shift;
423              
424             my $t = $self->{twig};
425              
426             my $xml = $self->_run('view', 'flop_month', $page);
427             if (defined($xml)) {
428             my @result = WWW::VieDeMerde::Message->parse($t);
429             return @result;
430             }
431             return undef;
432             }
433              
434             =head2 flop_mois
435              
436             C<< $vdm->flop_mois >> is an alias for C<< $vdm->flop_month >>.
437              
438             =cut
439              
440             sub flop_mois {
441             my $self = shift;
442             my $page = shift;
443              
444             return $self->flop_month($page);
445             }
446              
447             =head2 categories
448              
449             C<< $vdm->categories($cat) >> returns a list for all categories.
450              
451             =cut
452              
453             sub categories {
454             my $self = shift;
455              
456             my $t = $self->{twig};
457              
458             my $xml = $self->_run('view', 'categories');
459             warn 'WWW::VieDeMerde->categories gives raw xml';
460             return $xml;
461             # if (defined($xml)) {
462             # my @result = WWW::VieDeMerde::Message->parse($t);
463             # return @result;
464             # }
465             # return undef;
466             }
467              
468             =head2 from_cat
469              
470             C<< $vdm->from_cat($cat) >> returns entries of the category $cat.
471              
472             =cut
473              
474             sub from_cat {
475             my $self = shift;
476             my $cat = shift;
477             my $page = shift;
478              
479             my $t = $self->{twig};
480              
481             my $xml = $self->_run('view', $cat, $page);
482             if (defined($xml)) {
483             my @result = WWW::VieDeMerde::Message->parse($t);
484             return @result;
485             }
486             return undef;
487             }
488              
489             =head2 errors
490              
491             Read/write accessor for errors.
492              
493             =cut
494              
495             sub errors {
496             my $self = shift;
497             my $e = shift;
498             if (defined $e) {
499             $self->{errors} = $e;
500             return;
501             }
502             else {
503             return $self->{errors}
504             }
505             }
506              
507             =head1 INTERNAL METHODS AND FUNCTIONS
508              
509              
510             =head2 _run
511              
512             Build the request by joining arguments with slashes.
513              
514             =cut
515              
516             sub _run {
517             my $self = shift;
518             my @commands = grep {defined $_} @_;
519              
520             my $token = $self->{token};
521             my $key = $self->{key};
522             my $url = $self->{url};
523             my $lang = $self->{lang};
524              
525             my $ua = $self->{ua};
526             my $t = $self->{twig};
527              
528             my $cmd = $url . '/' . join('/', @commands);
529             my $args = '';
530             if (defined $key) {
531             $args .= '?key=' . $key;
532             }
533             if (defined $token) {
534             $args .= '&token=' . $token;
535             }
536             if (defined $lang) {
537             $args .= '&language=' . $lang;
538             }
539              
540             my $response = $ua->get($cmd . $args);
541              
542             if ($response->is_success) {
543             my $xml = $response->content;
544             return undef if $self->_errors($xml) == 1;
545             return $xml;
546             }
547             else {
548             carp $response->status_line;
549             $self->errors([$response->status_line]);
550             return undef;
551             }
552             }
553              
554             =head2 _errors
555              
556             Detect errors in an xml fragment returned by _run.
557              
558             =cut
559              
560             sub _errors {
561             my $self = shift;
562             my $xml = shift;
563              
564             my $t = $self->{twig};
565              
566             if (defined($xml) and $t->safe_parse($xml)) {
567             my $root = $t->root;
568              
569             my $errors = $root->first_child('errors');
570             my @errors = map {$_->text} $errors->children('error');
571             if (@errors) {
572             map {carp($_)} @errors;
573             $self->errors(\@errors);
574             return 1;
575             }
576            
577             my $items = $root->first_child('items');
578             my @items = $items->children('item');
579             if (! @items) {
580             my $error = 'No item found';
581             carp $error;
582             $self->errors([$error]);
583             return 2;
584             }
585             return 0;
586             }
587             }
588              
589             =head2 raw_xml
590              
591             Outputs raw xml for the given commands.
592              
593             =cut
594              
595             sub raw_xml {
596             my $self = shift;
597             return $self->_run(@_);
598             }
599              
600             =head1 AUTHOR
601              
602             Olivier Schwander, C<< >>
603              
604             =head1 BUGS
605              
606             Please report any bugs or feature requests to C
607             rt.cpan.org>, or through the web interface at
608             L. I will
609             be notified, and then you'll automatically be notified of progress on
610             your bug as I make changes.
611              
612             =head1 SUPPORT
613              
614             A darcs repository is available here :
615              
616             L
617              
618             You can find documentation for this module with the perldoc command.
619              
620             perldoc WWW::VieDeMerde
621              
622              
623             You can also look for information at:
624              
625             =over 4
626              
627             =item * RT: CPAN's request tracker
628              
629             L
630              
631             =item * AnnoCPAN: Annotated CPAN documentation
632              
633             L
634              
635             =item * CPAN Ratings
636              
637             L
638              
639             =item * Search CPAN
640              
641             L
642              
643             =back
644              
645             =head1 SEE ALSO
646              
647             L
648              
649             In early development, it seems to intend to support votes and comments
650             which is not my priority right now. Supports both French and English
651             version, despite the name.
652              
653             =head1 COPYRIGHT & LICENSE
654              
655             Copyright 2008 Olivier Schwander, all rights reserved.
656              
657             This program is free software; you can redistribute it and/or modify it
658             under the same terms as Perl itself.
659              
660              
661             =cut
662              
663             1; # End of WWW::VieDeMerde