root/plagger/trunk/lib/Plagger/Plugin/CustomFeed/iTunesRecentPlay.pm

Revision 97, 5.0 kB (checked in by miya, 3 years ago)

Add Filter::Amazon::WebService

  • Property svn:executable set to
Line 
1 package Plagger::Plugin::CustomFeed::iTunesRecentPlay;
2 use strict;
3 use warnings;
4 use base qw( Plagger::Plugin );
5 use File::Spec;
6 use Encode;
7 use DateTime::Format::W3CDTF;
8 use HTML::Entities;
9 use Plagger::UserAgent;
10
11 sub register {
12     my($self, $context) = @_;
13     $context->register_hook(
14         $self,
15         'subscription.load' => \&load,
16     );
17 }
18
19 sub load {
20     my($self, $context) = @_;
21
22     my $feed = Plagger::Feed->new;
23     $feed->aggregator(sub { $self->aggregate(@_) });
24     $context->subscription->add($feed);
25 }
26
27 sub aggregate {
28     my($self, $context, $args) = @_;
29
30     my $file = $self->conf->{library_path};
31     unless ($file) {
32         if ($^O eq 'MSWin32') {
33             require File::HomeDir::Windows;
34             my $mymusic = File::HomeDir::Windows->my_win32_folder('My Music');
35             $file = File::Spec->catfile($mymusic, 'iTunes', 'iTunes Music Library.xml');
36         } elsif ($^O eq 'darwin') {
37             $file = File::Spec->catfile($ENV{HOME}, 'Music', 'iTunes', 'iTunes Music Library.xml');
38         } else {
39             $context->log(error => "I can't guess library.xml path using your OS name $^O.");
40             return;
41         }
42     }
43
44     my $uri = URI->new($file);
45     if ($uri->scheme) {
46         $file = $self->cache->path_to('iTunes Music Library.xml');
47
48         my $ua = Plagger::UserAgent->new;
49         my $response = $ua->mirror($uri => $file);
50         if ($response->is_error) {
51             $context->log(error => "GET $uri failed: " . $response->status_line);
52             return;
53         }
54
55         $context->log(info => "Downloaded $uri to $file");
56     }
57
58     open my $fh, "<:encoding(utf-8)", $file
59         or return $context->log(error => "$file: $!");
60
61     my $feed = Plagger::Feed->new;
62     $feed->type('itunesrecentplay');
63     $feed->title("iTunes Recent Play");
64
65     my $data;
66     while (<$fh>) {
67         m!<key>Name</key><string>(.*?)</string>!
68             and $data->{track} = HTML::Entities::decode($1);
69         m!<key>Artist</key><string>(.*?)</string>!
70             and $data->{artist} = HTML::Entities::decode($1);
71         m!<key>Album</key><string>(.*?)</string>!
72             and $data->{album} = HTML::Entities::decode($1);
73         m!<key>Total Time</key><integer>(.*?)</integer>!
74             and $data->{duration} = HTML::Entities::decode($1);
75         m!<key>Play Date UTC</key><date>(.*?)</date>!
76             and $data->{date} = HTML::Entities::decode($1);
77         m!</dict>!
78             and do {
79                 if( $data->{date} and $data->{artist} ){
80                     my $dt = DateTime::Format::W3CDTF->parse_datetime($data->{date});
81                     unless ($dt) {
82                         $context->log( warn => "Can't parse $data->{date}");
83                         next;
84                     }
85                     if( !defined $self->conf->{duration} or $dt->epoch > time - $self->conf->{duration} * 60 ){
86                         my $entry = Plagger::Entry->new;
87                         $entry->date(Plagger::Date->from_epoch($dt->epoch));
88
89                         # author
90                         $entry->author($data->{artist});
91
92                         # title
93                         my $title = $self->conf->{title_format};
94                         $title = '%track - %artist' unless $title;
95                         $title =~ s/%artist/$data->{artist}/;
96                         $title =~ s/%album/$data->{album}/;
97                         $title =~ s/%track/$data->{track}/;
98                         $entry->title($title);
99
100                         # other attributes
101                         for my $key (keys %$data){
102                             $entry->meta->{$key} = $data->{$key};
103                         }
104
105                         # for Filter::AmazonWebService
106                         $entry->meta->{aws_mode} = 'music';
107
108                         $context->log( debug => $data->{artist} . ' ' . $data->{track});
109
110                         $feed->add_entry($entry);
111                     }
112                 }
113                 $data = {};
114             };
115     }
116
117     $context->update->add($feed);
118 }
119
120 1;
121 __END__
122
123 =head1 NAME
124
125 Plagger::Plugin::CustomFeed::iTunesRecentPlay - iTunes Recent Play custom feed
126
127 =head1 SYNOPSIS
128
129   # entries updated within 120 minutes
130   - module: CustomFeed::iTunesRecentPlay
131     config:
132       library_path: /path/to/iTunes Music Library.xml
133       duration: 120
134       title_format: %track - %artist
135
136 =head1 DESCRIPTION
137
138 This plugin fetches the data of musics you played with iTunes or iPod recently.
139
140 =head1 CONFIG
141
142 =over 4
143
144 =item library_path
145
146 A path name of iTunes Music Libary.xml.If you omit this parameter,
147 this plugin try to find it automatically.
148
149 =item duration
150
151 This plugin find a music played recently if last played time is within
152 this parameter.It's good to define this parameter same as execution
153 period of plagger with cron to reduce memory usage.
154
155 =item title_format
156
157 Set a title format of an entry.You can use %track, %artist and %album.
158
159 =back
160
161 =head1 AUTHOR
162
163 Gosuke Miyashita, E<lt>gosukenator@gmail.comE<gt>
164
165 Tatsuhiko Miyagawa
166
167 =head1 SEE ALSO
168
169 L<Plagger>
170
171 =cut
172
Note: See TracBrowser for help on using the browser.