root/trunk/plagger/lib/Plagger/Plugin/Notify/MSAgent.pm

Revision 216 (checked in by miyagawa, 15 years ago)

rename some of Publish modules to Notify, to be clear

Line 
1 package Plagger::Plugin::Notify::MSAgent;
2 use base qw( Plagger::Plugin );
3
4 use strict;
5 use Win32::OLE;
6 use Win32::MSAgent 0.07;
7 use Encode;
8 use Locale::Country;
9 use Locale::Language;
10 use Time::HiRes 'sleep';
11
12 sub register {
13     my($self, $context) = @_;
14     $context->register_hook(
15         $self,
16         'publish.feed' => \&feed,
17     );
18 }
19
20 sub feed {
21     my($self, $context, $args) = @_;
22
23     my $character = $self->conf->{character} || 'Merlin';
24     my $agent = Win32::MSAgent->new($character);
25
26     my $char = $agent->Characters($character);
27     $char->SoundEffectsOn(1);
28     $char->Show();
29
30     my @pos = split /,\s*/, ($self->conf->{position} || "300,300");
31     $char->MoveTo(@pos);
32     sleep(5);
33
34     if (my $animation = $self->conf->{animation}) {
35         $char->Play($animation);
36     }
37
38     my($lang, $encoding) = $self->detect_locale( ($args->{feed}->entries)[0] );
39
40     my($t1, $t2) = split /-/, $lang;
41     my $key = code2language($t1);
42        $key.= " (".code2country($t2).")" if code2country($t2);
43
44     # xxx hack to load VoiceText
45     $agent->Language2LanguageID("English (United States)");
46     my $voice = $agent->{_vt};
47
48     my $code = $voice->Language2LanguageID($key);
49     my $gender = $self->conf->{voice} || 'male';
50     my @try_gender  = $gender =~ /^male$/i ? (1, 2) : (2, 1);
51
52  TRY: for my $gender (@try_gender) {
53         for my $i (1 .. $voice->CountEngines) {
54             if ( $voice->LanguageID($i) == $code && $voice->Gender($i) == $gender ) {
55                 Plagger->context->log(debug => "Found voice $i for Lang $lang and Gender $gender");
56                 $voice->Select($i);
57                 last TRY;
58             }
59         }
60     }
61
62     $self->speak( $char, encode($encoding, $args->{feed}->title_text) );
63
64     for my $entry ($args->{feed}->entries) {
65         $self->speak( $char, encode($encoding, $entry->title_text) );
66         my $text = $entry->body_text;
67         while ($text =~ s/^(.{64})//) {
68             $self->speak( $char, encode($encoding, $1) );
69         }
70         $self->speak( $char, encode($encoding, $text) ) if $text;
71     }
72 }
73
74 sub detect_locale {
75     my($self, $entry) = @_;
76
77     my $stuff = $entry->title_text . $entry->body_text;
78
79     # HACK this should be handled in $entry->locale
80     my $lang     = $stuff =~ /\p{Hiragana}|\p{Katakana}|\p{Han}/ ? 'ja' : 'en-us';
81     my $encoding = $lang eq 'ja' ? 'cp932' : 'latin-1';
82
83     return ($lang, $encoding);
84 }
85
86 sub speak {
87     my($self, $character, $message) = @_;
88     my $request = $character->Speak($message);
89
90     my $i = 0;
91     while (($request->Status == 2) || ($request->Status == 4)) {
92         $character->Stop($request) if $i >10; sleep(1);  $i++;
93     }
94 }
95
96 1;
97
98 __END__
99
100 =head1 NAME
101
102 Plagger::Plugin::Notify::MSAgent - Let your Agent speak feed updates
103
104 =head1 SYNOPSIS
105
106   - module: Notify::MSAgent
107     config:
108       character: Merlin
109       voice: male
110       position: 300,300
111       animation: Announce
112
113 =head1 DESCRIPTION
114
115 This plugin uses Microsoft Agent API to let your agent speack feed updates.
116
117 =head1 AUTHOR
118
119 Tatsuhiko Miyagawa
120
121 =head1 SEE ALSO
122
123 L<Plagger>, L<Win32::MSAgent>
124
125 =cut
Note: See TracBrowser for help on using the browser.