faqts : Computers : Programming : Languages : Python : Snippets

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

2 of 4 people (50%) answered Yes
Recently 1 of 3 people (33%) answered Yes

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.")