File Coverage

blib/lib/App/LastStats.pm
Criterion Covered Total %
statement 24 24 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 32 32 100.0


line stmt bran cond sub pod time code
1 2     2   440851 use Feature::Compat::Class;
  2         1174  
  2         12  
2              
3             package App::LastStats; # For MetaCPAN
4              
5             class App::LastStats {
6              
7 2     2   450 use strict;
  2         4  
  2         82  
8 2     2   16 use warnings;
  2         7  
  2         93  
9 2     2   10 use feature 'say';
  2         6  
  2         175  
10              
11 2     2   15 no if $^V >= v5.38, warnings => 'experimental::class';
  2         4  
  2         195  
12              
13 2     2   1384 use Net::LastFM;
  2         1548658  
  2         123  
14 2     2   1790 use Getopt::Long;
  2         33067  
  2         11  
15 2     2   2105 use JSON;
  2         12016  
  2         17  
16              
17             our $VERSION = '0.1.0';
18              
19             field $username :param = 'davorg';
20             field $period :param = '7day';
21             field $format :param = 'text';
22             field $count :param = 10;
23             field $api_key :param = $ENV{LASTFM_API_KEY};
24             field $api_secret :param = $ENV{LASTFM_API_SECRET};
25             field $lastfm = Net::LastFM->new(
26             api_key => $api_key,
27             api_secret => $api_secret,
28             );
29             field $method = 'user.getTopArtists';
30             field $data;
31             field @artists;
32              
33             field $renderer = {
34             text => \&render_text,
35             html => \&render_html,
36             json => \&render_json,
37             };
38              
39             method run {
40             $self->validate;
41             $self->laststats;
42             $self->render;
43             }
44              
45             method validate {
46             $period = lc $period;
47             $format = lc $format;
48              
49             my @valid_periods = qw(overall 7day 1month 3month 6month 12month);
50             unless (grep { $_ eq $period } @valid_periods) {
51             die "Invalid period: $period\n",
52             'Valid periods are: ', join(', ', @valid_periods), "\n";
53             }
54              
55             unless (exists $renderer->{$format}) {
56             die "Invalid format: $format\n",
57             'Valid formats are: ', join(', ', keys %$renderer), "\n";
58             }
59             }
60              
61             method render_text {
62             say "* $_->{name} ($_->{playcount})" for @artists;
63             }
64              
65             method render_json {
66             my $pos = 1;
67              
68             my @data = map { {
69             position => $pos++,
70             name => $_->{name},
71             count => $_->{playcount},
72             url => $_->{url}
73             } } @artists;
74             say JSON->new->canonical(1)->pretty(1)->encode(\@data);
75             }
76              
77             method render_html {
78             my $html = "<ol>\n";
79             $html .= qq[ <li><a href="$_->{url}">$_->{name}</a> ($_->{playcount})</li>\n] for @artists;
80             $html .= "</ol>";
81             say $html;
82             }
83              
84             method render {
85             my $method = $renderer->{$format};
86             $self->$method;
87             }
88              
89             method laststats {
90             my $page = 1;
91              
92             while (@artists < $count) {
93              
94             $data = $lastfm->request_signed(
95             method => $method,
96             user => $username,
97             period => $period,
98             limit => $count,
99             page => $page++,
100             );
101              
102             last unless @{$data->{topartists}{artist}};
103              
104             push @artists, @{$data->{topartists}{artist}};
105             }
106              
107             $#artists = $count - 1 if @artists > $count;
108             }
109             }
110              
111             1;
112              
113             __END__
114              
115             =head1 NAME
116              
117             App::LastStats - A module to fetch and display Last.fm statistics
118              
119             =head1 SYNOPSIS
120              
121             use App::LastStats;
122              
123             my $stats = App::LastStats->new(
124             username => 'davorg',
125             period => '7day',
126             format => 'text',
127             count => 10,
128             api_key => 'your_api_key',
129             api_secret => 'your_api_secret',
130             );
131              
132             $stats->run;
133              
134             =head1 DESCRIPTION
135              
136             App::LastStats is a module that fetches and displays Last.fm statistics for a given user. It allows you to specify the time period, format, and number of artists to display.
137              
138             =head1 METHODS
139              
140             =head2 run
141              
142             Fetches and displays the Last.fm statistics based on the provided options.
143              
144             =head2 validate
145              
146             Validates the provided options.
147              
148             =head2 render_text
149              
150             Renders the statistics in plain text format.
151              
152             =head2 render_json
153              
154             Renders the statistics in JSON format.
155              
156             =head2 render_html
157              
158             Renders the statistics in HTML format.
159              
160             =head2 render
161              
162             Renders the statistics using the specified format.
163              
164             =head2 laststats
165              
166             Fetches the Last.fm statistics for the specified user and time period.
167              
168             =head1 API
169              
170             You will need an API key and secret in order to use this program. You can
171             get these from L<https://www.last.fm/api/account/create>.
172              
173             The API key and secret can be passed as arguments to the constructor (as
174             in the sample code above). Alternatively, they can be read from
175             environment variables called C<LASTFM_API_KEY> and C<LASTFM_API_SECRET>.
176              
177             =head1 AUTHOR
178              
179             Dave Cross <dave@perlhacks.com>
180              
181             =head1 LICENSE
182              
183             This library is free software; you can redistribute it and/or modify it
184             under the same terms as Perl itself.
185              
186             =cut