Entry
Rudimentary dict (RFC 2229) client library
Jul 5th, 2000 10:03
Nathan Wallace, Hans Nowak, Snippet 377, Jim Meier
"""
Packages: networking.sockets;basic_datatypes.dictionaries
"""
"""
I needed to use some dict servers and wanted to do it in python.
"""
# -----> dictlib.py (cut here to end of message) <-----------
import socket
import types
import re
import string
class DictDefinition:
def __init__(self, dict, word):
self.dict = dict
self.word = word
self.defs = {}
def definitions(self):
return self.defs.values()
def adddef(self, dictid, definition):
self.defs[dictid] = definition
def dictids(self):
return self.defs.keys()
def dictnames(self):
return map(self.dict.dictname, self.defs.keys())
class Dict:
def __init__(self, server, port=2628):
self.server = server
self.port = port
self.open = 0
self.sock = None
self.file = None
self.databases = None
def _getdatabases(self):
self._connect()
self.databases = {}
self.sock.send("SHOW DB\n")
resp = self.file.readline()
n = string.atoi(string.split(resp)[1])
done = 0
while not done:
line = self.file.readline()
if line[0] == ".":
done =1
else:
id, name = self._quotesplit(line)
self.databases[id] = name
self.file.readline() # get the 250 ok
self._disconnect()
def dictids(self):
if not self.databases:
self._getdatabases()
return self.databases.keys()
def dictname(self, dictid):
if not self.databases:
self._getdatabased()
return self.databases[dictid]
def _connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect(self.server, self.port)
self.file = self.sock.makefile('rb')
welcome = self.file.readline()
def _disconnect(self):
self.sock.send("\nQUIT\n")
self.sock = None
self.file = None
def _quotesplit(self, s):
'''
like split, except everything between pairs of ->"<- counts as one part.
'''
parts = []
buf = ""
in_quotes = 0
for i in s:
if in_quotes:
if i =='"':
in_quotes = 0
parts.append(buf)
buf=""
else:
buf = buf + i
else:
if i == '"':
if buf !="":
parts.append(buf)
buf = ""
in_quotes = 1
elif i in string.whitespace and buf != "":
parts.append(buf)
buf = ""
else:
buf=buf+i
if buf != "":
parts.append(buf)
if parts[-1] == '\015':
del parts[-1]
print s
print parts
return parts
def _onedefine(self, word):
self.sock.send("DEFINE * %s\n"% word)
done = 0
res = DictDefinition(self, word)
while not done:
line = self.file.readline()
code = line[:3]
if code == "150":
n = string.atoi(string.split(line)[1])
elif code == "151":
parts = self._quotesplit(line)
word = parts[1]
dictid = parts[2]
dictname = parts[3]
done_def = 0
definition = ""
while not done_def:
line = self.file.readline()
if line[0] == ".":
done_def = 1
else:
definition = definition + line
res.adddef(dictid, definition)
elif code == "250": # ok
done =1
elif code == "552": # no match
done = 1
return res
def define(self, word_or_words):
if type(word_or_words) is types.StringType:
self._connect()
res = self._onedefine(word_or_words)
self._disconnect()
return res
elif type(word_or_words) is types.ListType:
self._connect()
res = []
for i in word_or_words:
res.append(self._onedefine(i))
self._disconnect()
return res
else:
raise TypeError("Need a string or list of strings.")