File Coverage

blib/lib/Yahoo/Music/Ratings.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Yahoo::Music::Ratings;
2              
3 1     1   748812 use LWP::UserAgent;
  1         154217  
  1         30  
4 1     1   636 use XML::Simple;
  0            
  0            
5             use strict;
6             use warnings;
7              
8             our $VERSION = '2.00';
9              
10              
11             # Preloaded methods go here.
12              
13             sub new {
14             my $class = shift;
15             my $this = bless {}, $class;
16            
17             # Set sessions options
18             $this->{options} = shift;
19            
20             print '-' x 80,
21             "\nYahoo::Music::Ratings Progress Output Enabled\n",
22             '-' x 80,
23             "\n" if $this->{options}->{progress};
24            
25             return $this;
26             }
27              
28             sub findMemberId {
29             my $this = shift;
30            
31             unless ( $this->{memberid} ){
32             my $ua = LWP::UserAgent->new;
33             $ua->timeout(10);
34             $ua->env_proxy;
35            
36             $ua->max_redirect(0);
37            
38             my $url = 'http://music.yahoo.com/launchcast/membersearch.asp?memberName='.$this->{options}->{memberName};
39             print "Fetching web page\n" if $this->{options}->{progress};
40             my $response = $ua->get( $url );
41            
42             if ($response->is_success) {
43             #print $response->status_line;
44             $this->{errorMessage} = "\nLooks like either Yahoo is down, the membername provided is down or they've changed their site which means this module no longer works. Sorry :(";
45             print "$this->{errorMessage}\n" if $this->{options}->{progress};
46             return( 0 );
47             }
48             else {
49             ($this->{memberid}) = $response->header('Location') =~ m/station\.asp\?u=(\d+)/g;
50             print "Found $this->{options}->{memberName}'s memberId: $this->{memberid}\n" if $this->{options}->{progress};
51             return( $this->{memberid} );
52             }
53             }
54             }
55              
56             # Backward Compatibility with version 1.00
57             sub getRatings {
58             my $this = shift;
59             return $this->getSongs();
60             }
61              
62             # Display a list of Song Rankings
63             sub getSongs {
64             my $this = shift;
65            
66             # Check if we have a member id, if not, return 0
67             return 0 unless $this->_checkIfMemberId() ;
68            
69             # Reset the data hash as to not colide with old data
70             undef($this->{data});
71            
72             print "Loading Ratings Pages\n" if $this->{options}->{progress};
73             if ( $this->_parseRatings( 0, 1 ) ){
74             for(my $i=1; $i < $this->{totalPages}; $i++){
75             $this->_parseRatings( $i, 1 );
76             }
77            
78             return( $this->{data} );
79             }
80             else {
81             return( 0 );
82             }
83            
84             }
85              
86             # Display a list of Album Rankings
87             sub getAlbums {
88             my $this = shift;
89            
90             # Check if we have a member id, if not, return 0
91             return 0 unless $this->_checkIfMemberId() ;
92            
93             # Reset the data hash as to not colide with old data
94             undef($this->{data});
95            
96             print "Loading Ratings Pages\n" if $this->{options}->{progress};
97             if ( $this->_parseRatings( 0, 2 ) ){
98             for(my $i=1; $i < $this->{totalPages}; $i++){
99             $this->_parseRatings( $i, 2 );
100             }
101            
102             return( $this->{data} );
103             }
104             else {
105             return( 0 );
106             }
107            
108             }
109              
110             # Display a list of Artist Rankings
111             sub getArtists {
112             my $this = shift;
113            
114             # Check if we have a member id, if not, return 0
115             return 0 unless $this->_checkIfMemberId() ;
116            
117             # Reset the data hash as to not colide with old data
118             undef($this->{data});
119            
120             print "Loading Ratings Pages\n" if $this->{options}->{progress};
121             if ( $this->_parseRatings( 0, 3 ) ){
122             for(my $i=1; $i < $this->{totalPages}; $i++){
123             $this->_parseRatings( $i, 3 );
124             }
125            
126             return( $this->{data} );
127             }
128             else {
129             return( 0 );
130             }
131            
132             }
133              
134             # Display a list of Song Rankings
135             sub getGenres {
136             my $this = shift;
137            
138             # Check if we have a member id, if not, return 0
139             return 0 unless $this->_checkIfMemberId() ;
140            
141             $this->{errorMessage} = "Genre Listing Is not Yet Enabled. This is partly becuase Yahoo has yet to provide much of usfulness.";
142             print "$this->{errorMessage}\n" if $this->{options}->{progress};
143            
144             return( 0 );
145            
146             }
147              
148             # Internal Function to check if we have a member ID yet.
149             sub _checkIfMemberId {
150             my $this = shift;
151            
152             # check to see if we have a memberId for this user,
153             # if not fetch one
154             unless ( $this->{memberid} ){
155             unless ( $this->findMemberId() ){
156             # if we were unable to fetch a memberId then return negativly
157             # User should check $foo->error_message() for errors
158             return( 0 );
159             }
160             }
161             }
162              
163             # Parse Yahoo XML feed
164             # Arguments:
165             # int, pageNumber
166             # int, search type - 1 = song
167             # 2 = album
168             # 3 = artist
169             # 4 = genre
170             sub _parseRatings {
171             my $this = shift;
172             my $page = shift;
173             my $type = shift;
174            
175             my $xs = new XML::Simple();
176             my $ua = LWP::UserAgent->new;
177             $ua->timeout(10);
178             $ua->env_proxy;
179            
180             my $url = 'http://yme.us.music.yahoo.com/profile/rating_xml.asp?type='. $type .'&uid='. $this->{memberid} .'&p='. $page .'&g=undefined>=1';
181             print "Fetching web page " if $this->{options}->{progress};
182            
183             my $response = $ua->get( $url );
184            
185             if ($response->is_success) {
186             my $ref = $xs->XMLin( $response->content );
187              
188             # Search for type 1, songs
189             if ($type == 1){
190             $this->{totalPages} = $ref->{SONG_RATINGS}->{SONG_RATING_LIST}->{POSITION}->{PAGES}->{TOTAL};
191             $this->{currentPage} = $ref->{SONG_RATINGS}->{SONG_RATING_LIST}->{POSITION}->{PAGES}->{CURRENT};
192             print "$this->{currentPage} of $this->{totalPages}\n" if $this->{options}->{progress};
193            
194             foreach my $elem (@{$ref->{SONG_RATINGS}->{SONG_RATING_LIST}->{LIST}->{LIST_ROW}}) {
195             # {
196             # 'VIEWER_RATING' => {
197             # 'VALUE' => '-1'
198             # },
199             # 'SONG' => {
200             # 'ID' => '319952',
201             # 'ALBUM' => {
202             # 'ID' => '115213',
203             # 'NAME' => 'The Slim Shady LP (Edited)'
204             # },
205             # 'NAME' => 'My Name Is',
206             # 'HAS_SAMPLE' => {},
207             # 'ARTIST' => {
208             # 'ID' => '289114',
209             # 'NAME' => 'Eminem'
210             # },
211             # 'HAS_TETHDOWNLOAD' => {},
212             # 'HAS_ODSTREAM' => {},
213             # 'HAS_PERMDOWNLOAD' => {}
214             # },
215             # 'USER_RATING' => {
216             # 'VALUE' => '100'
217             # }
218             # },
219            
220             push(@{$this->{data}}, [
221             $elem->{SONG}->{ARTIST}->{NAME},
222             $elem->{SONG}->{NAME},
223             $elem->{SONG}->{ALBUM}->{NAME},
224             $elem->{USER_RATING}->{VALUE},
225             ]);
226             }
227            
228             return( 1 );
229             }
230             # Search for type 2, albums
231             elsif ( $type == 2 ){
232             $this->{totalPages} = $ref->{ALBUM_RATINGS}->{ALBUM_RATING_LIST}->{POSITION}->{PAGES}->{TOTAL};
233             $this->{currentPage} = $ref->{ALBUM_RATINGS}->{ALBUM_RATING_LIST}->{POSITION}->{PAGES}->{CURRENT};
234             print "$this->{currentPage} of $this->{totalPages}\n" if $this->{options}->{progress};
235            
236             foreach my $elem (@{$ref->{ALBUM_RATINGS}->{ALBUM_RATING_LIST}->{LIST}->{LIST_ROW}}) {
237             #{
238             # 'ALBUM' => {
239             # 'ID' => '48792',
240             # 'NAME' => 'New Adventures In Hi-Fi',
241             # 'ARTIST' => {
242             # 'ID' => '261307',
243             # 'NAME' => 'R.E.M.'
244             # }
245             # },
246             # 'VIEWER_RATING' => {
247             # 'VALUE' => '-1'
248             # },
249             # 'USER_RATING' => {
250             # 'VALUE' => '90'
251             # }
252             #},
253            
254             push(@{$this->{data}}, [
255             $elem->{ALBUM}->{ARTIST}->{NAME},
256             $elem->{ALBUM}->{NAME},
257             $elem->{USER_RATING}->{VALUE},
258             ]);
259             }
260            
261             return( 1 );
262             }
263             # Search for type 3, artist
264             elsif ( $type == 3 ){
265             $this->{totalPages} = $ref->{ARTIST_RATINGS}->{ARTIST_RATING_LIST}->{POSITION}->{PAGES}->{TOTAL};
266             $this->{currentPage} = $ref->{ARTIST_RATINGS}->{ARTIST_RATING_LIST}->{POSITION}->{PAGES}->{CURRENT};
267             print "$this->{currentPage} of $this->{totalPages}\n" if $this->{options}->{progress};
268            
269             foreach my $elem (@{$ref->{ARTIST_RATINGS}->{ARTIST_RATING_LIST}->{LIST}->{LIST_ROW}}) {
270             #{
271             # 'VIEWER_RATING' => {
272             # 'VALUE' => '-1'
273             # },
274             # 'ARTIST' => {
275             # 'ID' => '314672',
276             # 'NAME' => 'Bill Engvall'
277             # },
278             # 'USER_RATING' => {
279             # 'VALUE' => '60'
280             # }
281             #},
282            
283             push(@{$this->{data}}, [
284             $elem->{ARTIST}->{NAME},
285             $elem->{USER_RATING}->{VALUE},
286             ]);
287             }
288            
289             return( 1 );
290             }
291             # Search for type 4, genre
292             elsif ( $type == 4 ){
293             return( 0 );
294             }
295             }
296             else {
297             $this->{errorMessage} = "\nLooks like either Yahoo is down or they've changed their site which means this module no longer works. Sorry :(";
298             print "$this->{errorMessage}\n" if $this->{options}->{progress};
299             return( 0 );
300             }
301             }
302              
303             sub tab_output {
304             my $this = shift;
305            
306             my @tabbed;
307            
308             foreach my $row (sort {uc($a->[0]) cmp uc($b->[0])} @{$this->{data}}){
309             push(@tabbed, join("\t", @{$row} ) );
310             }
311            
312             my $tabbed = join("\n", @tabbed);
313             undef(@tabbed);
314             return( $tabbed );
315             }
316              
317             sub error_message {
318             my $this = shift;
319             return( $this->{errorMessage} );
320             }
321              
322              
323             1;
324             __END__