aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dicoweb/INSTALL80
-rw-r--r--dicoweb/__init__.py0
-rw-r--r--dicoweb/dicoclient/__init__.py19
-rw-r--r--dicoweb/dicoclient/dicoclient.py392
-rw-r--r--dicoweb/dicoclient/dicoshell.py321
-rw-r--r--dicoweb/dicoclient/setup.py39
-rw-r--r--dicoweb/dicoweb.wsgi28
-rw-r--r--dicoweb/dummy_translations.py40
-rw-r--r--dicoweb/locale/.gitignore1
-rw-r--r--dicoweb/locale/pl/LC_MESSAGES/django.po160
-rw-r--r--dicoweb/locale/uk/LC_MESSAGES/django.po160
-rw-r--r--dicoweb/manage.py23
-rw-r--r--dicoweb/settings.py81
-rw-r--r--dicoweb/static/dicoweb.css126
-rw-r--r--dicoweb/static/dicoweb.js96
-rw-r--r--dicoweb/static/gnu-head-sm.jpgbin0 -> 5286 bytes
-rw-r--r--dicoweb/static/opensearch.xml7
-rw-r--r--dicoweb/templates/404.html5
-rw-r--r--dicoweb/templates/500.html5
-rw-r--r--dicoweb/templates/base.html41
-rw-r--r--dicoweb/templates/index.html121
-rw-r--r--dicoweb/templatetags/__init__.py0
-rw-r--r--dicoweb/templatetags/dictlookup.py27
-rw-r--r--dicoweb/templatetags/media.py29
-rw-r--r--dicoweb/urls.py26
-rw-r--r--dicoweb/views.py207
26 files changed, 2034 insertions, 0 deletions
diff --git a/dicoweb/INSTALL b/dicoweb/INSTALL
new file mode 100644
index 0000000..e213131
--- /dev/null
+++ b/dicoweb/INSTALL
@@ -0,0 +1,80 @@
+GNU Dico - Dicoweb INSTALL
+Copyright (C) 2008, 2009 Wojciech Polak
+
+* Dicoweb requirements
+======================
+
+- Django 1.0 -- a Python Web framework (http://www.djangoproject.com/)
+- Memcached -- a distributed memory object caching system
+ (http://www.danga.com/memcached/) alongside python-memcached module.
+- Wit -- a wiki translator distributed within GNU Dico.
+ (http://puszcza.gnu.org.ua/projects/wit/)
+
+* Installation instructions
+===========================
+
+Edit your local Dicoweb settings in the file 'dicoweb/settings.py'.
+
+
+** The development/test server
+------------------------------
+
+Change the current working directory into the `dicoweb' directory
+and run the command `python manage.py runserver'. You will see
+the following output:
+
+ Validating models...
+ 0 errors found.
+
+ Django version 1.0, using settings 'dicoweb.settings'
+ Development server is running at http://127.0.0.1:8000/
+ Quit the server with CONTROL-C.
+
+** Production server with mod_wsgi
+----------------------------------
+
+Apache configuration:
+
+ LoadModule wsgi_module modules/mod_wsgi.so
+ WSGIScriptAlias / /usr/local/django/dicoweb/dicoweb.wsgi
+ Alias /static "/usr/local/django/dicoweb/static"
+
+More detailed information is available at:
+http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
+
+** Production server with mod_python
+------------------------------------
+
+Apache configuration:
+
+ LoadModule python_module modules/mod_python.so
+ <Location "/">
+ SetHandler python-program
+ PythonHandler django.core.handlers.modpython
+ PythonPath "sys.path + ['/usr/local/django', '/usr/local/django/dicoweb']"
+ SetEnv DJANGO_SETTINGS_MODULE dicoweb.settings
+ PythonInterpreter dicoweb
+ PythonDebug Off
+ </Location>
+
+ <Location "/static">
+ SetHandler None
+ </Location>
+ <Location "/favicon.ico">
+ SetHandler None
+ </Location>
+
+ <Directory "/usr/local/django/dicoweb/">
+ AllowOverride All
+ Options None
+ Order allow,deny
+ Allow from all
+ </Directory>
+
+
+
+Local Variables:
+mode: outline
+paragraph-separate: "[ ]*$"
+version-control: never
+End:
diff --git a/dicoweb/__init__.py b/dicoweb/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dicoweb/__init__.py
diff --git a/dicoweb/dicoclient/__init__.py b/dicoweb/dicoclient/__init__.py
new file mode 100644
index 0000000..1091705
--- /dev/null
+++ b/dicoweb/dicoclient/__init__.py
@@ -0,0 +1,19 @@
+# This file is part of GNU Dico.
+# Copyright (C) 2008, 2009 Wojciech Polak
+#
+# GNU Dico is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Dico is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Dico. If not, see <http://www.gnu.org/licenses/>.
+
+__all__ = ["dicoclient"]
+
+from dicoclient import *
diff --git a/dicoweb/dicoclient/dicoclient.py b/dicoweb/dicoclient/dicoclient.py
new file mode 100644
index 0000000..75b5bd2
--- /dev/null
+++ b/dicoweb/dicoclient/dicoclient.py
@@ -0,0 +1,392 @@
+# This file is part of GNU Dico.
+# Copyright (C) 2008, 2009 Wojciech Polak
+#
+# GNU Dico is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Dico is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Dico. If not, see <http://www.gnu.org/licenses/>.
+
+import socket
+import select
+import re
+import base64
+import quopri
+
+__version__ = "1.0"
+
+class DicoClient:
+ """GNU Dico client module written in Python
+ (a part of GNU Dico software)"""
+
+ host = None;
+ levenshtein_distance = 0
+ mime = False
+
+ verbose = 0
+ timeout = 10
+ transcript = False
+ __connected = False
+
+ def __init__ (self, host = None):
+ if host != None:
+ self.host = host;
+
+ def __del__ (self):
+ if self.__connected:
+ self.socket.close ()
+
+ def open (self, host = None, port = 2628):
+ """Open the connection to the DICT server."""
+ if host != None:
+ self.host = host
+ if self.verbose:
+ self.__debug ("Connecting to %s:%d" % (self.host, port))
+ socket.setdefaulttimeout (int (self.timeout))
+ self.socket = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
+ self.socket.connect ((self.host, port))
+ self.__connected = True
+ self.fd = self.socket.makefile ();
+
+ self.server_banner = self.__read ()[0]
+ capas, msgid = re.search ('<(.*)> (<.*>)$',
+ self.server_banner).groups ()
+ self.server_capas = capas.split ('.')
+ self.server_msgid = msgid
+
+ self.__send_client ()
+ self.__read ()
+
+ def close (self):
+ """Close the connection."""
+ if self.__connected:
+ self.__send_quit ()
+ self.__read ()
+ self.socket.close ()
+ self.__connected = False
+
+ def option (self, name, *args):
+ """Send the OPTION command."""
+ if self.__connected:
+ self.__send ('OPTION %s%s' %
+ (name, reduce (lambda x, y: str (x) +' '+ str (y),
+ args, '')))
+ res = self.__read ()
+ code, msg = res[0].split (' ', 1)
+ if int (code) == 250:
+ if name.lower () == 'mime':
+ self.mime = True
+ return True
+ return False
+
+ def __get_mime (self, lines):
+ cnt = 0
+ mimeinfo = {}
+ firstline = lines[0].lower ()
+ if firstline.find ('content-type:') != -1 or \
+ firstline.find ('content-transfer-encoding:') != -1:
+ cnt += 1
+ for line in lines:
+ if line == '':
+ break
+ t = line.split (':', 1)
+ mimeinfo[t[0].lower ()] = t[1].strip ()
+ cnt += 1
+ for i in range (0, cnt):
+ lines.pop (0)
+ else:
+ lines.pop (0)
+ if 'content-transfer-encoding' in mimeinfo:
+ if mimeinfo['content-transfer-encoding'].lower () == 'base64':
+ buf = base64.decodestring ('\n'.join (lines))
+ lines[:] = (buf.split ('\r\n'))
+ if lines[-1] == '': del lines[-1]
+ del mimeinfo['content-transfer-encoding']
+ elif mimeinfo['content-transfer-encoding'].lower () == 'quoted-printable':
+ buf = quopri.decodestring ('\n'.join (lines))
+ lines[:] = buf.split ('\r\n')
+ if lines[-1] == '': del lines[-1]
+ del mimeinfo['content-transfer-encoding']
+ return mimeinfo
+
+ def __get_rs (self, line):
+ code, text = line.split (' ', 1)
+ code = int (code)
+ return code, text
+
+ def __read (self):
+ if not self.__connected:
+ raise DicoNotConnectedError ('Not connected')
+ buf = []
+ line = self.__readline ()
+ if len (line) == 0:
+ raise DicoNotConnectedError ('Not connected')
+ buf.append (line)
+ code, text = self.__get_rs (line)
+
+ if code >= 100 and code < 200:
+ if code == 150:
+ while True:
+ rs = self.__readline ()
+ code, text = self.__get_rs (rs)
+ if (code != 151):
+ buf.append (rs)
+ break
+ buf.append ([rs, self.__readblock ()])
+ else:
+ buf.append (self.__readblock ())
+ buf.append (self.__readline ())
+ return buf
+
+ def __readline (self):
+ line = self.fd.readline ().rstrip ()
+ if self.transcript:
+ self.__debug ("S:%s" % line)
+ return line
+
+ def __readblock (self):
+ buf = []
+ while True:
+ line = self.__readline ()
+ if line == '.':
+ break
+ buf.append (line)
+ return buf
+
+
+ def __send (self, command):
+ if not self.__connected:
+ raise DicoNotConnectedError ('Not connected')
+ self.socket.send (command.encode ('utf_8') + "\r\n")
+ if self.transcript:
+ self.__debug ("C:%s" % command)
+
+ def __send_client (self):
+ if self.verbose:
+ self.__debug ("Sending client information")
+ self.__send ('CLIENT "%s %s"' % ("GNU Dico (Python Edition)",
+ __version__))
+
+ def __send_quit (self):
+ if self.verbose:
+ self.__debug ("Quitting")
+ self.__send ('QUIT');
+
+ def __send_show (self, what, arg = None):
+ if arg != None:
+ self.__send ('SHOW %s "%s"' % (what, arg))
+ else:
+ self.__send ('SHOW %s' % what)
+ return self.__read ()
+
+ def __send_define (self, database, word):
+ if self.verbose:
+ self.__debug ('Sending query for word "%s" in database "%s"'
+ % (word, database))
+ self.__send ('DEFINE "%s" "%s"' % (database, word))
+ return self.__read ()
+
+ def __send_match (self, database, strategy, word):
+ if self.verbose:
+ self.__debug ('Sending query to match word "%s" in database "%s", using "%s"'
+ % (word, database, strategy))
+ self.__send ('MATCH "%s" "%s" "%s"' % (database, strategy, word))
+ return self.__read ()
+
+ def __send_xlev (self, distance):
+ self.__send ('XLEV %u' % distance)
+ return self.__read ()
+
+ def show_databases (self):
+ """List all accessible databases."""
+ if self.verbose:
+ self.__debug ("Getting list of databases")
+ res = self.__send_show ('DATABASES')
+ if (self.mime):
+ mimeinfo = self.__get_mime (res[1])
+ dbs_res = res[1:-1][0]
+ dbs = []
+ for d in dbs_res:
+ short_name, full_name = d.split (' ', 1)
+ dbs.append ([short_name, self.__unquote (full_name)])
+ dct = {
+ "count": len (dbs),
+ "databases": dbs
+ }
+ return dct
+
+ def show_strategies (self):
+ """List available matching strategies."""
+ if self.verbose:
+ self.__debug ("Getting list of strategies")
+ res = self.__send_show ('STRATEGIES')
+ if (self.mime):
+ mimeinfo = self.__get_mime (res[1])
+ sts_res = res[1:-1][0]
+ sts = []
+ for s in sts_res:
+ short_name, full_name = s.split (' ', 1)
+ sts.append ([short_name, self.__unquote (full_name)])
+ dct = {
+ "count": len (sts),
+ "strategies": sts
+ }
+ return dct
+
+ def show_info (self, database):
+ """Provide information about the database."""
+ res = self.__send_show ("INFO", database)
+ code, msg = res[0].split (' ', 1)
+ if int (code) < 500:
+ if (self.mime):
+ mimeinfo = self.__get_mime (res[1])
+ dsc = res[1]
+ return { "desc": '\n'.join (dsc) }
+ else:
+ return { "error": code, "msg": msg }
+
+ def show_lang_db (self):
+ """Show databases with their language preferences."""
+ res = self.__send_show ("LANG DB")
+ code, msg = res[0].split (' ', 1)
+ if int (code) < 500:
+ if (self.mime):
+ mimeinfo = self.__get_mime (res[1])
+ dsc = res[1]
+ lang_src = {}
+ lang_dst = {}
+ for i in dsc:
+ pair = i.split (' ', 1)[1]
+ src, dst = pair.split (':', 1)
+ for j in src:
+ lang_src[src.strip()] = True
+ for j in dst:
+ lang_dst[dst.strip()] = True
+ return { "desc": '\n'.join (dsc),
+ "lang_src": lang_src.keys (),
+ "lang_dst": lang_dst.keys () }
+ else:
+ return { "error": code, "msg": msg }
+
+ def show_lang_pref (self):
+ """Show server language preferences."""
+ res = self.__send_show ("LANG PREF")
+ code, msg = res[0].split (' ', 1)
+ if int (code) < 500:
+ return { "msg": msg }
+ else:
+ return { "error": code, "msg": msg }
+
+ def show_server (self):
+ """Provide site-specific information."""
+ res = self.__send_show ('SERVER')
+ code, msg = res[0].split (' ', 1)
+ if int (code) < 500:
+ dsc = res[1]
+ return { "desc": '\n'.join (dsc) }
+ else:
+ return { "error": code, "msg": msg }
+
+ def define (self, database, word):
+ """Look up word in database."""
+ database = database.replace ('"', "\\\"")
+ word = word.replace ('"', "\\\"")
+ res = self.__send_define (database, word)
+ code, msg = res[-1].split (' ', 1)
+ if int (code) < 500:
+ defs_res = res[1:-1]
+ defs = []
+ rx = re.compile ('^\d+ ("[^"]+"|\w+) ([a-zA-Z0-9_\-]+) ("[^"]+"|\w+)')
+ for i in defs_res:
+ term, db, db_fullname = rx.search (i[0]).groups ()
+ df = {"term": self.__unquote (term),
+ "db": db,
+ "db_fullname": self.__unquote (db_fullname)}
+ if (self.mime):
+ mimeinfo = self.__get_mime (i[1])
+ df.update (mimeinfo)
+ df['desc'] = '\n'.join (i[1])
+ defs.append (df)
+ dct = {
+ "count": len (defs),
+ "definitions": defs
+ }
+ return dct
+ else:
+ return { "error": code, "msg": msg }
+
+ def match (self, database, strategy, word):
+ """Match word in database using strategy."""
+ if not self.__connected:
+ raise DicoNotConnectedError ('Not connected')
+
+ if self.levenshtein_distance and 'xlev' in self.server_capas:
+ res = self.__send_xlev (self.levenshtein_distance)
+ code, msg = res[-1].split (' ', 1)
+ if int (code) != 250 and self.verbose:
+ self.__debug ("Server rejected XLEV command")
+ self.__debug ("Server reply: %s" % msg)
+
+ database = database.replace ('"', "\\\"")
+ strategy = strategy.replace ('"', "\\\"")
+ word = word.replace ('"', "\\\"")
+
+ res = self.__send_match (database, strategy, word)
+ code, msg = res[-1].split (' ', 1)
+ if int (code) < 500:
+ if (self.mime):
+ mimeinfo = self.__get_mime (res[1])
+ mts_refs = res[1:-1][0]
+ mts = {}
+ for i in mts_refs:
+ db, term = i.split (' ', 1)
+ if mts.has_key (db):
+ mts[db].append (self.__unquote (term))
+ else:
+ mts[db] = [self.__unquote (term)]
+ dct = {
+ "matches": mts
+ }
+ return dct
+ else:
+ return { "error": code, "msg": msg }
+
+ def xlev (self, distance):
+ """Set Levenshtein distance."""
+ self.levenshtein_distance = distance
+ res = self.__send_xlev (distance)
+ code, msg = res[0].split (' ', 1)
+ if int (code) == 250:
+ return True
+ return False
+
+ def __unquote (self, s):
+ s = s.replace ("\\\\'", "'")
+ if s[0] == '"' and s[-1] == '"':
+ s = s[1:-1]
+ try:
+ s = self.__decode (s)
+ except UnicodeEncodeError:
+ pass
+ return s
+
+ def __decode (self, encoded):
+ for octc in (c for c in re.findall (r'\\(\d{3})', encoded)):
+ encoded = encoded.replace (r'\%s' % octc, chr (int (octc, 8)))
+ return unicode (encoded, 'utf_8')
+
+ def __debug (self, msg):
+ print "dico: Debug: %s" % msg
+
+class DicoNotConnectedError (Exception):
+ def __init__ (self, value):
+ self.parameter = value
+ def __str__(self):
+ return repr (self.parameter)
diff --git a/dicoweb/dicoclient/dicoshell.py b/dicoweb/dicoclient/dicoshell.py
new file mode 100644
index 0000000..dfec3fc
--- /dev/null
+++ b/dicoweb/dicoclient/dicoshell.py
@@ -0,0 +1,321 @@
+# This file is part of GNU Dico.
+# Copyright (C) 2008, 2009 Wojciech Polak
+#
+# GNU Dico is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Dico is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Dico. If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import atexit
+import re
+import getopt
+import readline
+import curses.ascii
+import socket
+import dicoclient
+
+class Shell:
+ """Simple GNU Dico-Python Shell."""
+
+ prompt = 'dico> '
+ prefix = '.'
+
+ default_host = 'gnu.org.ua'
+ database = '!'
+ strategy = '.'
+ last_matches = []
+ last_databases = []
+ last_strategies = []
+ transcript = False
+
+ def __init__ (self, opts, args):
+ for o, a in opts:
+ if o in ('-h', '--host'):
+ self.default_host = a
+
+ self.dc = dicoclient.DicoClient (self.default_host)
+
+ def run (self):
+ histfile = os.path.expanduser ('~/.dico_history')
+ try:
+ readline.read_history_file (histfile)
+ except IOError:
+ pass
+ atexit.register (readline.write_history_file, histfile)
+
+ print "\nType ? for help summary\n"
+ while True:
+ try:
+ input = raw_input (self.prompt).strip ()
+ input = unicode (input, 'utf_8')
+ except (EOFError, KeyboardInterrupt):
+ print
+ sys.exit ()
+
+ try:
+ self.parse (input)
+ except socket.timeout:
+ self.__error ('socket timed out')
+ except dicoclient.DicoNotConnectedError:
+ try:
+ self.dc.open ()
+ dict = self.dc.show_databases ()
+ self.last_databases = dict['databases']
+ dict = self.dc.show_strategies ()
+ self.last_strategies = dict['strategies']
+ self.parse (input)
+ except socket.error, (errno, strerror):
+ self.__error (strerror)
+
+ def parse (self, input):
+ if len (input) < 1:
+ return
+ if input[0] == self.prefix:
+ self.parse_command (input[1:])
+ elif input == '?':
+ self.print_help ()
+ elif re.match (r'^[0-9]+$', input):
+ try:
+ match = self.last_matches[int (input)]
+ dict = self.dc.define (match[0], match[1])
+ if dict.has_key ('count'):
+ for d in dict['definitions']:
+ print "From %s, %s:" % (d['db'], d['db_fullname'].
+ encode ('utf_8'))
+ print d['desc']
+ elif dict.has_key ('error'):
+ print dict['msg']
+ except IndexError:
+ self.__error ('No previous match')
+ elif input[0] == '/':
+ if len (input) > 1:
+ dict = self.dc.match (self.database, self.strategy, input[1:])
+ if dict.has_key ('matches'):
+ self.last_matches = []
+ lmi = 0
+ for db in dict['matches']:
+ print "From %s, %s:" % (db, self.__lookup_db (db).
+ encode ('utf_8'))
+ for term in dict['matches'][db]:
+ print '%4d) "%s"' % (lmi, term.encode ('utf_8'))
+ self.last_matches.append ([db, term])
+ lmi = lmi + 1
+ elif dict.has_key ('error'):
+ print dict['msg']
+ else:
+ if len (self.last_matches) > 0:
+ m = {}
+ lmi = 0
+ for i, db in enumerate (self.last_matches):
+ if not db[0] in m: m[db[0]] = []
+ m[db[0]].append (self.last_matches[i][1])
+ for db in m:
+ print "From %s, %s:" % (db, self.__lookup_db (db))
+ for term in m[db]:
+ print '%4d) "%s"' % (lmi, term)
+ lmi = lmi + 1
+ else:
+ self.__error ('No previous match')
+ elif input[0] == '!':
+ if re.match (r'^![0-9]+$', input):
+ number = int (input[1:])
+ readline.insert_text (readline.get_history_item (number))
+ readline.redisplay ()
+ else:
+ dict = self.dc.define (self.database, input)
+ if dict.has_key ('count'):
+ for d in dict['definitions']:
+ print "From %s, %s:" % (d['db'], d['db_fullname'].
+ encode ('utf_8'))
+ print d['desc']
+ elif dict.has_key ('error'):
+ print dict['msg']
+
+ def parse_command (self, input):
+ input = input.split (' ', 1)
+ cmd = input[0]
+ args = None
+ if len (input) == 2:
+ args = input[1]
+
+ if cmd == 'open':
+ try:
+ if args != None:
+ args = args.split (' ', 1)
+ if len (args) == 2:
+ self.dc.open (args[0], int (args[1]))
+ else:
+ self.dc.open (args[0])
+ else:
+ self.dc.open ()
+ dict = self.dc.show_databases ()
+ self.last_databases = dict['databases']
+ dict = self.dc.show_strategies ()
+ self.last_strategies = dict['strategies']
+ except socket.error, (errno, strerror):
+ self.__error (strerror)
+ elif cmd == 'close':
+ self.dc.close ()
+ elif cmd == 'database':
+ if args != None:
+ self.database = args
+ else:
+ print self.database
+ elif cmd == 'strategy':
+ if args != None:
+ self.strategy = args
+ else:
+ print self.strategy
+ elif cmd == 'distance':
+ if args != None:
+ self.dc.levenshtein_distance = int (args)
+ else:
+ if self.dc.levenshtein_distance:
+ print "Configured Levenshtein distance: %u" \
+ % (self.dc.levenshtein_distance)
+ else:
+ print "No distance configured"
+ elif cmd == 'ls':
+ dict = self.dc.show_strategies ()
+ self.last_strategies = dict['strategies']
+ if len (self.last_strategies):
+ for i in self.last_strategies:
+ print '%s "%s"' % (i[0], i[1])
+ elif cmd == 'ld':
+ dict = self.dc.show_databases ()
+ self.last_databases = dict['databases']
+ if len (self.last_databases):
+ for i in self.last_databases:
+ print '%s "%s"' % (i[0], i[1])
+ elif cmd == 'mime':
+ print self.dc.option ('MIME')
+ elif cmd == 'server':
+ dict = self.dc.show_server ()
+ if dict.has_key ('desc'):
+ print dict['desc']
+ elif dict.has_key ('error'):
+ self.__error (dict['error'] + ' ' + dict['msg'])
+ elif cmd == 'info':
+ if args != None:
+ dict = self.dc.show_info (args)
+ if dict.has_key ('desc'):
+ print dict['desc']
+ elif dict.has_key ('error'):
+ self.__error (dict['error'] + ' ' + dict['msg'])
+ elif cmd == 'history':
+ hl = int (readline.get_current_history_length ())
+ for i in range (0, hl):
+ print "%4d) %s" % (i, readline.get_history_item (i))
+ elif cmd == 'help':
+ self.print_help ()
+ elif cmd == 'transcript':
+ if args != None:
+ if args == 'yes' or args == 'on' or args == 'true':
+ self.dc.transcript = True
+ elif args == 'no' or args == 'off' or args == 'false':
+ self.dc.transcript = False
+ else:
+ self.__error ('Expected boolean value')
+ else:
+ if self.dc.transcript:
+ print "transcript is on"
+ else:
+ print "transcript is off"
+ elif cmd == 'verbose':
+ if args != None:
+ self.dc.verbose = args
+ else:
+ print self.dc.verbose
+ elif cmd == 'prompt':
+ if args != None:
+ self.prompt = args
+ else:
+ self.__error ('not enough arguments')
+ elif cmd == 'prefix':
+ if args != None:
+ if len (args) == 1 and args != '#' and \
+ curses.ascii.ispunct (args):
+ self.prefix = args
+ else:
+ self.__error ('Expected a single punctuation character')
+ elif cmd == 'version':
+ self.print_version ()
+ elif cmd == 'warranty':
+ self.print_warranty ()
+ elif cmd == 'quit':
+ sys.exit ()
+
+ def __lookup_db (self, db):
+ for d in self.last_databases:
+ if d[0] == db:
+ return d[1]
+ return ""
+
+ def __error (self, msg):
+ print "dico: Error: %s" % msg
+
+ def print_version (self):
+ print "GNU Dico (Python Edition) " + dicoclient.__version__
+
+ def print_warranty (self):
+ self.print_version ()
+ print """Copyright (C) 2008, 2009 Wojciech Polak
+
+ GNU Dico is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Dico is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Dico. If not, see <http://www.gnu.org/licenses/>."""
+
+ def print_help (self):
+ print 'WORD Define WORD.'
+ print '/WORD Match WORD.'
+ print '/ Redisplay previous matches.'
+ print 'NUMBER Define NUMBERth match.'
+ print '!NUMBER Edit NUMBERth previous command.'
+ print
+ print self.prefix + 'open [HOST [PORT]] Connect to a DICT server.'
+ print self.prefix + 'close Close the connection.'
+ print self.prefix + 'database [NAME] Set or display current database name.'
+ print self.prefix + 'strategy [NAME] Set or display current strategy.'
+ print self.prefix + 'distance [NUM] Set or query Levenshtein distance (server-dependent).'
+ print self.prefix + 'ls List available matching strategies'
+ print self.prefix + 'ld List all accessible databases'
+ print self.prefix + 'info [DB] Display the information about the database.'
+ print self.prefix + 'prefix [CHAR] Set or display command prefix.'
+ print self.prefix + 'transcript [BOOL] Set or display session transcript mode.'
+ print self.prefix + 'verbose [NUMBER] Set or display verbosity level.'
+ print self.prefix + 'prompt STRING Change command line prompt.'
+ print self.prefix + 'history Display command history.'
+ print self.prefix + 'help Display this help text.'
+ print self.prefix + 'version Print program version.'
+ print self.prefix + 'warranty Print copyright statement.'
+ print self.prefix + 'quit Quit the shell.'
+
+if __name__ == '__main__':
+ try:
+ opts, args = getopt.getopt (sys.argv[1:], 'h:', ['host='])
+ except getopt.GetoptError:
+ print "\nusage: %s [-h, --host=hostname]" % (sys.argv[0])
+ sys.exit (0)
+
+ shell = Shell (opts, args)
+ shell.print_version ()
+ shell.run ()
diff --git a/dicoweb/dicoclient/setup.py b/dicoweb/dicoclient/setup.py
new file mode 100644
index 0000000..795b9ca
--- /dev/null
+++ b/dicoweb/dicoclient/setup.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+#
+# This file is part of GNU Dico.
+# Copyright (C) 2008, 2009 Wojciech Polak
+#
+# GNU Dico is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Dico is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You s