root/xchestival/irssi_speak.pl

Revision 1064, 14.8 kB (checked in by alpt, 3 years ago)

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl
2 #
3 # Un interfaccia a festival per Irssi, ottimizzata per l'italiano.
4 #
5 # Questo codice deriva da xchat_speak.pl:
6 # http://www.nogas.org/xchat_speak/
7 #
8 # Il nuovo codice e' stato scritto da AlpT (@freaknet.org)
9 #
10 # http://www.freaknet.org/alpt/src/xchestival/
11
12 ########### CONFIGURE THIS BIT!
13 # Adjust this so it reflects the location of your festival executable
14 $festival='/usr/bin/festival --pipe';
15
16 $home=`echo ~`;   # la tua home
17 $home =~ s/\n//;  # toglia la newline finale
18 # Il file usato da xchestival per le sostituzioni
19 $xchestival_sub = "$home/.irssi/xchestival.sub";
20 $xchestival_sub_default="/usr/share/xchestival/xchestival.sub";
21
22 $lang="it"#"en" if english
23
24 # Adjust this to your preferred Voice
25 $VOICE = "voice_lp_mbrola";     # Voce della femmina italiana
26
27 #$VOICE = "voice_pc_mbrola";    # voce del maschio italiano
28 #$VOICE = "voice_lp_diphone";   # voce del robot femmina italiano
29 #$VOICE = "voice_pc_diphone";   # voce del robot maschio italiano
30 #$VOICE = "voice_rab_diphone"; # A muted British-esque voice
31 #$VOICE = "voice_kal_diphone"; # An American male voice
32 #$VOICE = "voice_ked_diphone"; # A less mechanical American male voice
33
34 # Smaller numbers = faster speech
35 $SPEED = ".99";
36
37 ########## YOU CAN STOP CONFIGURING!
38
39 %IRSSI = (
40     name        => 'speak',
41     authors     => 'AlpT',
42     contact     => 'alpt (@freaknet org)',
43     description => 'Irrsi parla',
44     license     => 'GPL',
45     url         => 'http://www.freaknet.org/alpt/src/xchestival/',
46 ); 
47
48 use Irssi;
49 use Irssi::Irc;
50 #use Irssi::UI;
51
52 sub evento {
53   my ($server, $data) = @_;
54   if($data !~ /PRIVMSG/ &&  $data !~ /TOPIC/ && $data !~ /JOIN/  &&
55           $data !~ /NICK/ && $data !~ /INVITE/ && $data !~ /PART/ &&
56           $data !~ /QUIT/ ) {
57           return;
58   }
59   &speak($data);
60 }
61
62 $already_loaded=0;
63 $spaccaballe=1;
64 $do_queue_mutex=0;
65 $pidof_festival="";
66 $lastchan="";
67 $lastquery="";
68 $buf_lines = "10"# Quante linee svuota ogni volta dal buffer del canale.
69 $says="dice";
70 $query_says="ti dice";
71 $line_highlight="";
72 $MY_NAME = "irssi_speak.pl";
73 $VERSION = "0.3.6";
74
75 %chan_queue = ();
76 %channels = ();
77 $lastthingsaid = "";
78 %lastwho = ();
79 %smilesub = ();
80 %wordsub = ();
81
82
83
84 Irssi::command_bind("muto", \&cmd_speechoff);
85 Irssi::command_bind("voce", \&cmd_speechvoice);
86 Irssi::command_bind("velocita",\&cmd_speechspeed);
87 Irssi::command_bind("censure", \&cmd_censure);
88 Irssi::command_bind("parla", \&cmd_speechon);
89 Irssi::command_bind("associazioni", \&load_sub);
90 Irssi::command_bind("associa", \&write_sub);
91 Irssi::command_bind("seleziona", \&cmd_highlight);
92 Irssi::command_bind("solotesto", cmd_solotesto);
93 Irssi::command_bind("parlatutto", cmd_parlatutto);
94 Irssi::command_bind("parlasoloin", cmq_parlasoloin);
95 Irssi::signal_add("server incoming", "evento");
96
97 sub cmd_parlatutto {
98         $spaccaballe=1;
99         Irssi::print("   Comunico anche: topic, join, cambio nick, invite, part e quit\n");
100 }
101 sub cmd_solotesto {
102         $spaccaballe=0;
103         Irssi::print("   Non dico: topic, join, cambio nick, invite, part e quit\n");
104 }
105
106 sub update_chan_list {
107         my $linein=$_[0], $c, $status;
108
109         if(!$linein) {
110                 $status="on";
111         } else {
112                 $status=$linein;
113         }
114        
115         @chan_list=Irssi::channels();
116         foreach my $ch (@chan_list) {
117                 $c = $ch->{name};
118                 if($c =~ /^[#+]/) {
119                         $channels{$c}=$status;
120 #                       Irssi::print("$c == $channels{$c}");
121                 }
122                
123         }
124 }
125
126 sub cmq_parlasoloin {
127         my $linein=$_[0];
128         if(!$linein) { return 0; }
129         &cmd_speechoff();
130         &cmd_speechon($linein);
131 }
132
133 sub cmd_highlight {
134         my $linein=$_[0];
135        
136         if(!$linein) {
137                 Irssi::print("La selezione delle frasi e' disabilitata");
138                 undef $line_highlight;
139                 return;
140         }
141
142         $line_highlight=$linein;
143         Irssi::print("Ora leggero' solo le frasi che contengono: $line_highlight");
144 }
145
146 sub load_sub {
147         my $linein=$_[0], $smi, $line;
148         if(!$linein) { $linein = $xchestival_sub; }
149
150         open(SUBFD, "< $linein")
151         || do {
152                         Irssi::print("*E* Error opening $linein : $!");
153                         Irssi::print("*E* trying with $xchestival_sub_default");
154                 $linein = $xchestival_sub_default;
155                 open(SUBFD, "< $linein")
156                         || do {
157                      Irssi::print("*E* Error opening $xchestival_sub_default : $!");
158                          return;
159                                   };
160               };
161
162         Irssi::print("Il file delle sostituzioni ora e': $linein");
163         %smilesub = ();
164         %wordsub = ();
165
166         while(<SUBFD>) {
167                 s/[\r\n]//g;
168                 warning("whitespace follows the \\ at the end-of-line.\nIf you
169                         meant to have a line continuation, remove the trailing
170                         whitespace.")
171                 if /\\\s+$/;
172                 $line = "$_\n" unless /^#/;
173                 s/#.*//;                # remove comments
174                 s/^\s+//;               # remove leading white space
175                 s/\s+$//;               # remove trailing white space
176                 s/\s+/ /g;              # canonify
177                 next if /^$/;
178
179                 $line =~ s/[\r\n]//g;
180                 $smi=0;
181                 if($line =~ /^SMILE:/) { $line =~ s/SMILE://; $smi=1; }
182                 $line =~ s/^\s+//;
183                
184                 ($a, $b) = split(/\s*==\s*/, "$line", 2);
185
186                 if($smi) {
187                         $smilesub{$a} = $b;     
188                 } else {
189                         $wordsub{$a} = $b;
190                 }
191         }
192         close SUBFD;
193 }
194
195 sub write_sub {
196         my $sub=$_[0] ,$linein, $line;
197        
198         if(!$sub) { return; }
199         $linein = $xchestival_sub;
200
201         open(SUBFD, ">>$linein") || do { Irssi::print("*E* Error opening $linein : $!"); return; };
202        
203         print SUBFD "$sub\n";
204
205         $line = $sub;
206         if($line =~ /^SMILE:/) { $line =~ s/SMILE://; $smi=1; }
207         $line =~ s/^\s+//;
208         ($a, $b) = split(/\s*==\s*/, "$line", 2);
209         if($smi) {
210                 $smilesub{$a} = $b;
211                 Irssi::print("smile $a == $b");
212         } else {
213                 $wordsub{$a} = $b;
214                 Irssi::print("$a == $b");
215         }
216         close SUBFD;
217 }
218
219 sub smile_sub {
220         my $linein=$_[0];
221         my $sub;
222
223         foreach my $word (split(' ',$linein)) {
224                 $sub=$smilesub{$word} unless $sub;
225                 if ($sub) {
226                         return $sub;
227                 }
228                 undef($sub);
229         }
230         return $sub;
231 }
232
233 sub spch_substitute {
234         my $linein=$_[0];
235         my ($sub,$lineout);
236         foreach my $word (split(' ',$linein)) {
237                 #       $sub=$wordsub{$word};
238                 $sub=$wordsub{$word} unless $sub;
239                 if ($sub) {
240                         $lineout.=" $sub ";
241                 } else {
242                         $lineout.=" $word ";
243                 }
244                 undef($sub);
245         }
246         return($lineout);
247 }
248
249 sub cmd_censure {
250         if(!$already_loaded) { return 0; }
251         Irssi::print("Questa e' la lista dei canali dove NON posso parlare:");
252         @key=keys(%channels);
253         foreach my $ch (@key) {
254                 $channels{$ch} eq "off" && Irssi::print("   $ch\n");
255         }
256 }
257
258 sub cmd_speechvoice {
259         if(!$_[0]) { return 0; }
260         $says="dice";
261         $query_says="ti dice";
262         $lang="it";
263         if ( $_[0] eq "donna" )
264         {
265                 $VOICE = "voice_lp_mbrola";
266                 $ghgh="Voce settata a femmina italiana.";
267         }
268         if( $_[0] eq "uomo" )
269         {       
270                 $VOICE = "voice_pc_mbrola";
271                 $ghgh="Voce settata a masculo italiano.";
272         }
273         if( $_[0] eq "uomo_robot" )
274         {               
275                 $VOICE = "voice_pc_diphone";
276                 $ghgh="Voce settata a robot maschio italiano";
277         }
278         if ( $_[0] eq "donna_robot" )
279         {       $VOICE = "voice_lp_diphone";
280                 $ghgh="Voce settata a robot femmina italiana";
281         }
282
283         if ( $_[0] eq "inglese" )
284         {               $VOICE = "voice_ked_diphone";
285                 $ghgh="Voice setted to brute yankee";
286                 $says="says";
287                 $query_says="says";
288                 $lang="en";
289         }
290
291         Irssi::print("*** Voice $VOICE");
292         print SPEECH "($VOICE)\n";
293         &speak("$ghgh");
294 }
295
296 sub cmd_speechspeed {
297         if(!$_[0]) { return 0; }
298         $SPEED=$_[0];
299         if($SPEED > 3) {
300                 &parla("Non posso settare quella velocita', sarei troppo lenta!", "1");
301                 Irssi::print("Non posso settare quella velocita', sarei troppo lenta!", "1");
302                 return 0;
303         }
304         if($SPEED < 0.40) {
305                 &parla("Non posso settare quella velocita', sarei troppo veloce!", "1");
306                 Irssi::print("Non posso settare quella velocita', sarei troppo veloce!");
307                 return 0;
308         }
309         Irssi::print("*** Speed $SPEED");
310         print SPEECH "(Parameter.set 'Duration_Stretch $SPEED)\n";
311         &parla("Velocita' settata a: $SPEED", "1");
312         %lastwho = ();
313 }               
314
315 sub cmd_speechon {
316         my $linein=$_[0];
317
318
319         if (!defined($speech_pipe)) {
320                 open(SPEECH,"|$festival 2>&1 >/dev/null") || do { &print("*E* Error opening pipe to $festival"); return; };
321                 $pidof_festival=`pidof -s festival`;
322                 $pidof_festival =~ s/\n//;
323                 $fhcp=select(SPEECH);
324                 $|=1;
325                 select($fhcp);
326                 $speech_pipe=1;
327                 Irssi::print("*** Speech activated!");
328                 if(!$already_loaded) {
329                         $already_loaded=1;
330                 }
331                 print SPEECH "($VOICE)\n";
332                 print SPEECH "(Parameter.set 'Duration_Stretch $SPEED)\n";
333                
334                 if(!$linein) {
335                         $channels{"1"}="on";
336                         &update_chan_list("on");
337                         @key=keys(%channels);
338                         foreach my $ch (@key) { $channels{$ch}="on"; }
339
340                         %lastwho = ();
341                         print SPEECH "(SayText \"Ora  comincio a parlare\")\n";
342                         &load_sub($xchestival_sub);
343                         return(1);
344                 }
345         }
346
347         if($linein) {
348                 $linein =~ s/ //g;
349                 $channels{$linein} = "on";
350                 Irssi::print("Ora parlero' nel canale $linein");
351                 $linein =~ s/#//;
352                 print SPEECH "(SayText \"Ora parlero' nel canale $linein\")\n";
353                 $lastwho{$linein} = "";
354                 return 0;
355         } else {
356                 @key=keys(%channels);
357                 foreach my $ch (@key) { $channels{$ch}="on";    }
358                 Irssi::print("Ora parlero' in tutti i canali");
359                 print SPEECH "(SayText \"Ora parlero' in tutti i canali\")\n";
360                 %lastwho = ();
361         }
362 }
363
364 sub cmd_speechoff {
365         my $linein=$_[0];
366
367         if(defined($speech_pipe)) {
368                 if($linein) {
369                         $linein =~ s/ //g;
370                         $channels{$linein} = "off";
371                         @{ $chan_queue{$linein} } = undef;
372                         Irssi::print("Ora staro' muta nel canale $linein");
373                         $linein =~ s/#//;
374                         &parla("Ora staro' muta nel canale $linein", "1");
375                         $lastwho{$linein} = "";
376                         return 0;
377                 } else {
378                         &update_chan_list("off");
379                         @key=keys(%channels);
380                         foreach my $ch (@key) {
381                                 $channels{$ch}="off";
382                                 @{ $chan_queue{$ch} } = undef;
383                         }
384                         Irssi::print("*** Ora mi disattivo");
385                         print SPEECH "(SayText \"Ora mi disattivo\")\n";
386                         %lastwho = ();
387                         undef($speech_pipe);
388                         if($pidof_festival) {
389                                 kill 15, $pidof_festival;
390                                 $pidof_festival="";
391                         }
392                         close(SPEECH);
393                 }
394
395         }
396
397         return(1);
398 }
399
400 sub do_chan_queue {
401         if($do_queue_mutex) { return 0; }
402         $do_queue_mutex=1;
403        
404         @key=keys(%chan_queue);
405         foreach my $ch (@key) {
406                 my $sayit="cacca", $i=0, $chh="";
407                 while($sayit && $i < $buf_lines) {
408                         $sayit=shift @{ $chan_queue{$ch} };
409                         if($channels{$ch} eq "off" || !$sayit) { last; }
410                         if($sayit && (($channels{$ch} eq "on") || $ch eq "1")) {
411                                 if(!$i && ($lastchan ne $ch) && ($ch ne "1") &&
412                                 ($ch =~ /^[#+]/)) {
413                                         ($chh = $ch) =~ s/[^a-zA-Z]//g;
414                                         print SPEECH "(SayText \"Nel canale $chh, \")\n";
415                                 }
416                                 #               Irssi::print( "ch: $ch, last: $lastchan, $sayit");
417
418                                 print SPEECH "(SayText \"$sayit\")\n";
419                                 $lastchan=$ch;
420                                 $i++;
421                         }
422                 }
423         }
424         $do_queue_mutex=0;
425 }
426
427 sub parla {
428         my $linein=$_[0];
429         my $can=$_[1];
430
431         if(!$can) { $can="1"; }
432         push @{ $chan_queue{$can} }, $linein;
433
434         &do_chan_queue();
435 }
436
437 sub togli_merda {
438         my $linein=$_[0];
439
440         # Togliamo tutta la MMERDA dalla stringa,
441         # Questa REGEX DELLA MORTE MALE e' stata scritta da quel pazzo di sand,
442         # lode a lui o/
443 #       $linein =~ s/(?:\s|\A)\S*?[^a-z\s]+\S*?(?<![\.,:;'`])(?:\s|\Z)/ /gi;
444 #       $linein =~ s/(?:\s|\A)\S*?[^a-z\s]+\S*?(?<![\.,:;'`?!])(?:\s|\Z)/ /gi;
445 #       $linein =~ s/(?:\s|\A)\S*?[^a-z\s']+\S*?(?<![\.,:;'`?!])(?:\s|\Z)/ /gi;
446         $linein =~ s/(?:\s|\A)\S*?[^a-z0-9\s')("]+\S*?(?<![\.,:;'`?!])(?:\s|\Z)/ /gi;
447         return $linein;
448 }
449
450 sub speak {
451         defined($speech_pipe) || return;
452         my $speakline;
453         my $smile, $chan="1", $query=0, $qualcosa=0;
454         $speakline=$_[0];
455         $speakline = lc($speakline);
456         
457
458         if("$lastthingsaid" eq "$speakline") {  return 0; }
459         $lastthingsaid = $speakline;
460
461
462         #### Escludi i canali e le query azzittite #####
463         if ($speakline=~/^:(.*)!.*privmsg[^:]*[#+]([a-z0-9_A-Z]*)/) {
464                 $chan = "#"."$2";
465                 if($channels{$chan} eq "off") { return 0; }
466         } else {
467                 if ($speakline=~/^:(.*)!.*privmsg[^:]*[a-z0-9_A-Z]*/) {
468                         $chan=$1;
469                         $query=1;
470                         if($channels{$chan} eq "off") { return 0; }
471                 }
472         }
473         if ($speakline=~/^:(.*)!.*part[^:]*[#+]([a-z0-9_A-Z]*)/) {
474                 $chan = "#"."$2";
475                 if($channels{$chan} eq "off") { return 0; }
476         }
477         if ($speakline=~/^:(.*)!.*topic[^:]*[#+]([a-z0-9_A-Z]*)/) {
478                 $chan = "#"."$2";
479                 if($channels{$chan} eq "off") { return 0; }
480         }
481         if ($speakline=~/^:(.*)!.*join[^:]*:(.*)/) {
482                 $chan = "#"."$2";
483                 if($channels{$chan} eq "off") { return 0; }
484         }
485
486         $channels{$chan}="on";
487
488         if(!$query) { $lastquery=""; }
489
490         if ($speakline=~/^:(.*)!.*privmsg[^:]*:(.*)/) {
491                 $uno=$1;
492                 $smile=&smile_sub($2);
493                 $due = &togli_merda($2);
494
495                 if($speakline =~ /:.action /) {
496                         $speakline =~ s/.action//;
497                         if($speakline =~/^:(.*)!.*privmsg[^:]*:(.*)/) {
498                                 $uno=$1; $due = $2;
499                                 $uno =~ s/[^a-z]//g;
500                                 $speakline ="$uno $due";
501                                 $lastwho{$chan} = "";
502                                 if($query) { $lastquery=""; }
503                         }
504                 } else {
505                         $uno =~ s/[^a-z]//g;
506                         if($query) { $speakline="$uno $query_says, $due";
507                         } else {$speakline="$uno $says, $due"; }
508                         if(!$query && $lastwho{$chan} eq "$uno") { $speakline="$due"; }
509                         if($query && $lastquery eq "$chan") { $speakline="$due"; }
510                         if($query) { $lastquery=$chan; }
511                         $lastwho{$chan} = $uno;
512                 }
513                 ($t=$due)=~ s/ //g;
514                 if(!$due || !$t) { if($smile) { &parla("$uno $smile", "$chan"); } return 0; }
515                 $qualcosa=1;
516         }
517
518         if ($spaccaballe) {
519         if ($speakline=~/^:(.*)!.*topic[^:]*:(.*)/) {
520                 $uno=$1;
521                 $smile=&smile_sub($2);
522                 $due = &togli_merda($2);
523                 $speakline="il nuovo topicc e': $due";
524                 $uno =~ s/[^a-z]//g;
525                 ($t=$due)=~ s/ //g;
526                 if(!$due || !$t) { if($smile) { &parla("$uno $smile","$chan"); } return 0; }
527                 $lastwho{$chan} = "";
528         }
529         if ($speakline=~/^:(.*)!.*join[^:]*:(.*)/) {
530                 $uno=$1; $due=$2;
531                 $uno =~ s/[^a-z]//g;
532                 $speakline="$uno ha gioinato";
533                 $lastwho{$chan} = "";
534         }
535         if ($speakline=~/^:(.*)!.*nick[^:]*:(.*)/) {
536                 $uno=$1; $due = $2;
537                 $uno =~ s/[^a-z]//g;
538                 $due =~ s/[^a-z]//g;
539                 $speakline="$uno ha cambiato il nick in  $due";
540                 $lastwho{$chan} = "";
541         }
542         if ($speakline=~/^:(.*)!.*invite[^:]*:(.*)/) {
543                 $uno=$1;
544                 $uno =~ s/[^a-z]//g;
545                 $due = &togli_merda($2);
546                 $chan = "1";
547                 $speakline="$uno ti ha invitato in  $due";
548                 $lastwho{$chan} = "";
549         }
550         if ($speakline=~/^:(.*)!.*part[^:]*:(.*)/) {
551                 $uno=$1;
552                 $due = &togli_merda($2);
553                 $uno =~ s/[^a-z]//g;
554                 $speakline="$uno e' uscito e dice: $due";
555                 $lastwho{$chan} = "";
556         }
557         if ($speakline=~/^:(.*)!.*quit[^:]*:(.*)/) {
558                 $uno=$1;
559                 $due = &togli_merda($2);
560                 $uno =~ s/[^a-z]//g;
561                 $speakline="$uno e' uscito e dice: $due";
562                 $lastwho{$chan} = "";
563         }
564                 $qualcosa=1;
565         }
566         if(!$qualcosa) { return; }
567
568         $speakline=&spch_substitute($speakline);
569
570         $speakline =~ tr/a-z0-9,.<>?'@+=&%$£!\/: ]//cd;
571         $speakline =~ s/\?+/\?/g; # Collapse '?'
572         $speakline =~ s/\!+/\!/g; # Collapse '!'
573         $speakline =~ s/ +/ /g; # Collapse spaces
574         $speakline =~ s/\.{2,}/ /g; # Collapse multiple dots
575         $speakline =~ s/\s*\?\s*$/\?/; # "phrase    ?" = "phrase?"
576         $speakline =~ s/\s*\!\s*$/\!/; # "phrase    !" = "frase!"
577         $speakline =~ s/\s*\?/\?/; # "phrase    ?" = "phrase?"
578         $speakline =~ s/\s*\!/\!/; # "phrase    !" = "frase!"
579
580         # " frase " = ,frase,;   ( frase  ) = ,frase,;
581         $speakline =~ s/([a-zA-Z])\s*\)|\(\s*([a-zA-Z])/\1, \2/g;
582         $speakline =~ s/\s*"\s*/, /g;
583         $speakline =~ s/\s*,\s*,\s*/, /g;
584         $speakline =~ s/^,\s*//g;
585         $speakline =~ s/\s*,\s*$//g;
586
587         #collapse long repetition
588         foreach my $i (split(//, $speakline)) {
589                 if($i) { $speakline=~ s/[$i]{8,}/$i$i$i$i$i$i$i/g; }
590         }
591         
592         
593         if($lang eq "it") { $speakline =~ s/y/i/g; } # 'y' = 'i'
594
595 #       Irssi::print("$speakline");
596         
597         if($line_highlight && $speakline !~ /$line_highlight/) { return 0; }
598         
599         &parla("$speakline", "$chan");
600         if($smile) { &parla("$uno $smile", "$chan"); }
601
602         return 0;
603 }
604
605 Irssi::command("/parla");
606
Note: See TracBrowser for help on using the browser.