]> git.donarmstrong.com Git - infobot.git/blob - src/Modules/Dict.pl
- Remaining files that were changed due to removal of $noreply or
[infobot.git] / src / Modules / Dict.pl
1 #
2 #  Dict.pl: Frontend to dict.org.
3 #   Author: dms
4 #  Version: v0.6c (20000924).
5 #  Created: 19990914.
6 #
7
8 package Dict;
9
10 use IO::Socket;
11 use strict;
12
13 my $server      = "dict.org";   # need a specific host||ip.
14 my $port        = 2628;
15 my $proto       = getprotobyname('tcp');
16
17 ###local $SIG{ALRM} = sub { die "alarm\n" };
18
19 sub Dict {
20     my ($query) = @_;
21 ###    return unless &::loadPerlModule("IO::Socket");
22     my $socket = new IO::Socket;
23     my @results;
24
25     for ($query) {
26         s/^[\s\t]+//;
27         s/[\s\t]+$//;
28         s/[\s\t]+/ /;
29     }
30
31     # connect.
32     socket($socket, PF_INET, SOCK_STREAM, $proto) or return "error: socket: $!";
33     eval {
34         alarm 15;
35         connect($socket, sockaddr_in($port, inet_aton($server))) or return "error: connect: $!";
36         alarm 0;
37     };
38
39     my $retval;
40     if ($@ && $@ ne "alarm\n") {        # failure.
41         $retval = "i could not get info from dict.org";
42     } else {                            # success.
43         $socket->autoflush(1);  # required.
44
45         my $num;
46         if ($query =~ /^(\d+)\s+/) {
47             $num = $1;
48         }
49
50         # body.
51         push(@results, &Dict_Wordnet($socket,$query));
52         push(@results, &Dict_Foldoc($socket,$query));
53         # end.
54
55         print $socket "QUIT\n";
56         close $socket;
57
58         my $total = scalar @results;
59
60         if (defined $num and ($num > $total or $num < 0)) {
61             &msg($::who, "error: choice in definition is out of range.");
62             return;
63         }
64
65         # parse the results.
66         if ($total > 1) {
67             if (defined $num) {
68                 $retval = sprintf("[%d/%d] %s", $num, $total, $results[$num]);
69             } else {
70                 # suggested by larne and others.
71                 my $prefix = "Dictionary '$query' ";
72                 $retval = &::formListReply(1, $prefix, @results);
73             }
74         } elsif ($total == 1) {
75             $retval = "Dictionary '$query' ".$results[0];
76         } else {
77             $retval = "could not find definition for \002$query\002";
78         }
79     }
80
81     &::performStrictReply($retval);
82 }
83
84 sub Dict_Wordnet {
85     my ($socket, $query) = @_;
86     my @results;
87
88     &::status("Dict: asking Wordnet.");
89     print $socket "DEFINE wn \"$query\"\n";
90
91     my $def             = "";
92     my $wordtype        = "";
93
94     while (<$socket>) {
95         chop;   # remove \n
96         chop;   # remove \r
97
98         if ($_ eq ".") {                                # end of def.
99             push(@results, $def);
100         } elsif (/^250 /) {                             # stats.
101             last;
102         } elsif (/^552 no match/) {                     # no match.
103             return;
104         } elsif (/^\s+(\S+ )?(\d+)?: (.*)/) {   # start of sub def.
105             my $text = $3;
106             $def =~ s/\s+$//;
107 ###         &::DEBUG("def => '$def'.");
108             push(@results, $def)                if ($def ne "");
109             $def = $text;
110
111             if (0) {    # old non-fLR format.
112                 $def = "$query $wordtype: $text" if (defined $text);
113                 $wordtype = substr($1,0,-1)     if (defined $1);
114 ###             &::DEBUG("_ => '$_'.") if (!defined $text);
115             }
116
117         } elsif (/^\s+(.*)/) {
118             s/^\s{2,}/ /;
119             $def        .= $_;
120             $def =~ s/\[.*?\]$//g;
121         }
122     }
123
124     &::status("Dict: wordnet: found ". scalar(@results) ." defs.");
125
126     return if (!scalar @results);
127
128     return @results;
129 }
130
131 sub Dict_Foldoc {
132     my ($socket,$query) = @_;
133     my @results;
134
135     &::status("Dict: asking Foldoc.");
136     print $socket "DEFINE foldoc \"$query\"\n";
137
138     my $firsttime = 1;
139     my $string;
140     while (<$socket>) {
141         chop;   # remove \n
142         chop;   # remove \r
143
144         return if /^552 /;              # no match.
145
146         if ($firsttime) {
147             $firsttime-- if ($_ eq "");
148             next;
149         }
150
151         last if (/^250/ or /^\.$/);     # stats; end of def.
152
153         s/^\s+|\s+$//g;                 # each line.
154
155         if ($_ eq "") {                 # sub def separator.
156             $string =~ s/^\s+|\s+$//g;  # sub def.
157             $string =~ s/[{}]//g;
158
159             next if ($string eq "");
160
161             push(@results, $string);
162             $string = "";
163         }
164
165         $string .= $_." ";
166     }
167
168     &::status("Dict: foldoc: found ". scalar(@results) ." defs.");
169
170     return if (!scalar @results);
171     pop @results;       # last def is date of entry.
172
173     return @results;
174 }
175
176 1;