comparison etc/dict.lua @ 0:4b915342e2a8

LuaSocket 2.0.2 + CMake build description.
author Eric Wing <ewing . public |-at-| gmail . com>
date Tue, 26 Aug 2008 18:40:01 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4b915342e2a8
1 -----------------------------------------------------------------------------
2 -- Little program to download DICT word definitions
3 -- LuaSocket sample files
4 -- Author: Diego Nehab
5 -- RCS ID: $Id: dict.lua,v 1.22 2005/11/22 08:33:29 diego Exp $
6 -----------------------------------------------------------------------------
7
8 -----------------------------------------------------------------------------
9 -- Load required modules
10 -----------------------------------------------------------------------------
11 local base = _G
12 local string = require("string")
13 local table = require("table")
14 local socket = require("socket")
15 local url = require("socket.url")
16 local tp = require("socket.tp")
17 module("socket.dict")
18
19 -----------------------------------------------------------------------------
20 -- Globals
21 -----------------------------------------------------------------------------
22 HOST = "dict.org"
23 PORT = 2628
24 TIMEOUT = 10
25
26 -----------------------------------------------------------------------------
27 -- Low-level dict API
28 -----------------------------------------------------------------------------
29 local metat = { __index = {} }
30
31 function open(host, port)
32 local tp = socket.try(tp.connect(host or HOST, port or PORT, TIMEOUT))
33 return base.setmetatable({tp = tp}, metat)
34 end
35
36 function metat.__index:greet()
37 return socket.try(self.tp:check(220))
38 end
39
40 function metat.__index:check(ok)
41 local code, status = socket.try(self.tp:check(ok))
42 return code,
43 base.tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)")))
44 end
45
46 function metat.__index:getdef()
47 local line = socket.try(self.tp:receive())
48 local def = {}
49 while line ~= "." do
50 table.insert(def, line)
51 line = socket.try(self.tp:receive())
52 end
53 return table.concat(def, "\n")
54 end
55
56 function metat.__index:define(database, word)
57 database = database or "!"
58 socket.try(self.tp:command("DEFINE", database .. " " .. word))
59 local code, count = self:check(150)
60 local defs = {}
61 for i = 1, count do
62 self:check(151)
63 table.insert(defs, self:getdef())
64 end
65 self:check(250)
66 return defs
67 end
68
69 function metat.__index:match(database, strat, word)
70 database = database or "!"
71 strat = strat or "."
72 socket.try(self.tp:command("MATCH", database .." ".. strat .." ".. word))
73 self:check(152)
74 local mat = {}
75 local line = socket.try(self.tp:receive())
76 while line ~= '.' do
77 database, word = socket.skip(2, string.find(line, "(%S+) (.*)"))
78 if not mat[database] then mat[database] = {} end
79 table.insert(mat[database], word)
80 line = socket.try(self.tp:receive())
81 end
82 self:check(250)
83 return mat
84 end
85
86 function metat.__index:quit()
87 self.tp:command("QUIT")
88 return self:check(221)
89 end
90
91 function metat.__index:close()
92 return self.tp:close()
93 end
94
95 -----------------------------------------------------------------------------
96 -- High-level dict API
97 -----------------------------------------------------------------------------
98 local default = {
99 scheme = "dict",
100 host = "dict.org"
101 }
102
103 local function there(f)
104 if f == "" then return nil
105 else return f end
106 end
107
108 local function parse(u)
109 local t = socket.try(url.parse(u, default))
110 socket.try(t.scheme == "dict", "invalid scheme '" .. t.scheme .. "'")
111 socket.try(t.path, "invalid path in url")
112 local cmd, arg = socket.skip(2, string.find(t.path, "^/(.)(.*)$"))
113 socket.try(cmd == "d" or cmd == "m", "<command> should be 'm' or 'd'")
114 socket.try(arg and arg ~= "", "need at least <word> in URL")
115 t.command, t.argument = cmd, arg
116 arg = string.gsub(arg, "^:([^:]+)", function(f) t.word = f end)
117 socket.try(t.word, "need at least <word> in URL")
118 arg = string.gsub(arg, "^:([^:]*)", function(f) t.database = there(f) end)
119 if cmd == "m" then
120 arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end)
121 end
122 string.gsub(arg, ":([^:]*)$", function(f) t.n = base.tonumber(f) end)
123 return t
124 end
125
126 local function tget(gett)
127 local con = open(gett.host, gett.port)
128 con:greet()
129 if gett.command == "d" then
130 local def = con:define(gett.database, gett.word)
131 con:quit()
132 con:close()
133 if gett.n then return def[gett.n]
134 else return def end
135 elseif gett.command == "m" then
136 local mat = con:match(gett.database, gett.strat, gett.word)
137 con:quit()
138 con:close()
139 return mat
140 else return nil, "invalid command" end
141 end
142
143 local function sget(u)
144 local gett = parse(u)
145 return tget(gett)
146 end
147
148 get = socket.protect(function(gett)
149 if base.type(gett) == "string" then return sget(gett)
150 else return tget(gett) end
151 end)
152