Update of /cvsroot/tmda/tmda/bin
In directory sc8-pr-cvs1:/tmp/cvs-serv29611/bin

Modified Files:
        tmda-gui 
Log Message:
Added client functionnality to tmda-gui.

Expect the server part in a few days, it still needs a lot of cleaning and
tuning (BTW, anyone with a good name for the server ?).

I love suspense ;)




Index: tmda-gui
===================================================================
RCS file: /cvsroot/tmda/tmda/bin/tmda-gui,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- tmda-gui    5 Dec 2002 00:32:26 -0000       1.8
+++ tmda-gui    5 Dec 2002 23:37:56 -0000       1.9
@@ -28,14 +28,14 @@
 Where:
    <none>
    <none>
-       Gives a (yet) non functional Address generator interface.
+       Gives a functional (but yet to finish) Address generator interface.
 
    -p
    --pending
        Gives a functionnal (but yet to finish) Pending queue graphical
        interface.
 
-        Tricks:
+        Until I do the Help dialog, here are some tips:
         . you can resize the list columns width
         . you can resize the height of the list
         . double-click on a message and you'll see it's content
@@ -43,8 +43,24 @@
         . the list is refreshed every 5 mins by default but you can
           change it in Edit/Settings... (not memorized between runs yet)
 
+   -H hostname[:port]
+   --host hostname[:port]
+      Specify a hostname and a port to connect to.
+      This is mandatory if you don't have a local installation of TMDA.
+
+   -U username:password
+   -user username:password
+      Specify a username and a password to authenticate against on the
+      remote host.
+      See the NOTE below for security advisory.
+      This is mandatory if you don't have a local installation of TMDA.
+
 NOTE: This is early alpha software, so please try it, and send your
 comments to the [EMAIL PROTECTED] mailing list.
+
+Please note that the options will be visible by any other local user on
+your machine with the 'ps' command, so don't use the -U option if you don't
+want to expose your password.
 """
 
 import getopt
@@ -59,11 +75,149 @@
                            'site-packages', 'TMDA', 'pythonlib')
     sys.path.insert(0, sitedir)
 
-from TMDA import Version
+## Lib access functions
+def lib_getAddress(tag, option=None, address=None):
+    try:
+        tagged_address = Address.Factory(tag = tag).create(address, option).address
+    except ValueError, msg:
+        return ''
+
+    return tagged_address
+
+def lib_checkAddress(address, sender_address=None):
+    #FIXME: Add localtime support
+    localtime = None
+    status = []
+    try:
+        addr = Address.Factory(address)
+        addr.verify(sender_address)
+        status.append("STATUS: VALID")
+        try:
+            status.append("EXPIRES: %s" % addr.timestamp(1, localtime))
+        except AttributeError:
+            pass
+    except Address.AddressError, msg:
+        status.append("STATUS: " + str(msg))
+
+    return '\n'.join(status)
+
+def lib_processMessage(msgid, command, **args):
+    msg = Pending.Message(msgid)
+    try:
+        try:
+            data = getattr(msg, command)(args)
+        except TypeError:
+            # if command takes no argument
+            data = getattr(msg, command)()
+        if type(data) == str:
+            return data
+        else:
+            return '\n'.join(data)
+    except AttributeError:
+        return None
+
+def lib_processPending(command, **args):
+    Q = Pending.Queue(descending=1).initQueue()
+    if command == 'list':
+        return Q.listPendingIds()
+    return None
+
+## Net access functions
+import socket
+sock = None
+sin = None
+sout = None
+
+def connectToServer(host, auth):
+    global sock, sin, sout
+    if sock:
+        print "Already connected"
+        return 0
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    sock.connect(host)
+    sin = sock.makefile('r', 0)
+    sout = sock.makefile('w', 0)
+    # eat up greetings from manager
+    while sin.readline() and sin.read(1) != '+':
+        pass
+    sout.write('auth %s %s\n' % auth)
+    if sin.read(1) != '+':
+        return 0
+    return 1
+
+def net_command(command):
+    data = []
+    sout.write(str(command)+'\n')
+    cc = sin.read(1)
+    while cc == ' ':
+        data.append(sin.readline()[:-1])
+        cc = sin.read(1)
+    if cc == '-':
+        msg = sin.readline()[:-1]
+        ## FIXME: think about error recovery (check the '+')
+        raise ProtoError, msg
+    return data
+
+def net_getAddress(tag, option=None, address=None):
+    tagged_address = '\n'.join(net_command('address %s %s' % (tag, option)))
+    return tagged_address
+
+def net_checkAddress(address, sender_address=None):
+    status = '\n'.join(net_command('checkaddress %s %s' % (address, sender_address)))
+    print status
+    return status
+
+def net_processMessage(msgid, command, **args):
+    try:
+        data = net_command('message %s %s' % (command, msgid))
+        return '\n'.join(data)
+    except ProtoError, msg:
+        print "%s: %s" % (ProtoError, msg)
+        
+    return ''
+
+ProtoError = "Protocole Error"
+
+def net_processPending(command, **args):
+    if command == 'list':
+        try:
+            data = net_command('pending only')
+            return data
+        except ProtoError, msg:
+            print "%s: %s" % (ProtoError, msg)
+
+    return []
+
+# Let's check if we're running locally or through the network
+
+try:
+    from TMDA import Version
+    from TMDA import Address
+    from TMDA import Pending
+
+    using_network = 0
+    getAddress = lib_getAddress
+    checkAddress = lib_checkAddress
+    processMessage = lib_processMessage
+    processPending = lib_processPending
+
+
+# No TMDA library around, we're not on the server
+except ImportError:
+    using_network = 1
+    # Hack to have the --version flag
+    class VersionObject:
+        ALL = 'unknown'
+        TMDA = 'unknown'
+    Version = VersionObject()
+
+
+
 
 try:
     from Tkinter import *
 except ImportError:
+    ## FIXME: what to do if we don't have TMDA ?
     from TMDA.Util import wraptext
     no_tk = 'It appears your Python is not configured with Tkinter ' + \
             'support. Visit http://python.org/topics/tkinter/trouble.html ' + \
@@ -81,11 +235,58 @@
         print msg
     sys.exit(code)
 
-# getopt crud goes here
-
-# end getopt crud
+try:
+    opts, args = getopt.getopt(sys.argv[1:],
+                               'H:U:pVh',
+                                        ['host=',
+                                         'user=',
+                                         'pending',
+                                         'version',
+                                         'help'])
+except getopt.error, msg:
+    usage(1, msg)
+
+pending_first = 0
+host = None
+port = 8765
+for opt, arg in opts:
+    if opt in ('-h', '--help'):
+        usage(0)
+    if opt == '-V':
+        print Version.ALL
+        sys.exit()
+    if opt == '--version':
+        print Version.TMDA
+        sys.exit()
+    if opt in ('-p', '--pending'):
+        pending_first = 1
+    elif opt in ('-H', '--host'):
+        using_network=1
+        try:
+            (host, port) = arg.split(':', 1)
+        except ValueError:
+            (host, port) = (arg, 8765)
+    elif opt in ('-U', '--user'):
+        try:
+            (user, passwd) = arg.split(':', 1)
+        except ValueError:
+            print "Error: missing the password"
+            sys.exit()
+
+if using_network:
+    if not host:
+        print "Error: no TMDA library available and no host to connect to."
+        sys.exit()
+    if not user or not passwd:
+        print "Error: please provide a user:password pair to connect to remote host."
+        sys.exit()
+
+    # map the accessors to the net_* functions
+    getAddress = net_getAddress
+    checkAddress = net_checkAddress
+    processMessage = net_processMessage
+    processPending = net_processPending
 
-from TMDA import Pending
 
 
 class HSplitterFrame(Frame):
@@ -213,7 +414,7 @@
 
     def WhitelistSelectedMessage(self):
         try:
-            Pending.Message(self.msgs[int(self.curselection()[0])]).whitelist()
+            processMessage(self.msgs[int(self.curselection()[0])], 
+command='whitelist')
         except IndexError:
             return 0
         self.Refresh()
@@ -221,7 +422,7 @@
 
     def BlacklistSelectedMessage(self):
         try:
-            Pending.Message(self.msgs[int(self.curselection()[0])]).blacklist()
+            processMessage(self.msgs[int(self.curselection()[0])], 
+command='blacklist')
         except IndexError:
             return 0
         self.Refresh()
@@ -229,7 +430,7 @@
 
     def ReleaseSelectedMessage(self):
         try:
-            Pending.Message(self.msgs[int(self.curselection()[0])]).release()
+            processMessage(self.msgs[int(self.curselection()[0])], command='release')
         except IndexError:
             return 0
         self.Refresh()
@@ -237,7 +438,7 @@
 
     def DeleteSelectedMessage(self):
         try:
-            Pending.Message(self.msgs[int(self.curselection()[0])]).delete()
+            processMessage(self.msgs[int(self.curselection()[0])], command='delete')
             print "Deleted"
         except IndexError:
             print "No such message"
@@ -253,8 +454,8 @@
         
     def GetSelectedMsgContent(self):
         try:
-            return Pending.Message(self.msgs[int(self.curselection()
-                                                 [0])]).show().split('\n\n', 1)
+            return processMessage(self.msgs[int(self.curselection()[0])],
+                                  command='show').split('\n\n', 1)
         except IndexError:
             return ('', '')
         
@@ -262,10 +463,11 @@
         for col in self._cols:
             col.delete(0, END)
         self.msgs = []
-        Q = Pending.Queue(descending=1).initQueue()
-        for item in Q.listPendingIds():
+        lst = processPending('list')
+        lst.reverse()
+        for item in lst:
             self.msgs.append(item)
-            msg = Pending.Message(item).terse(date=1)
+            msg = processMessage(item, command='terse', date=1).split('\n')
             i = 0
             for col in self._cols:
                 col.insert(END, msg[i])
@@ -493,40 +695,6 @@
         self.master.after(1000, self.poll)
 
 
-try:
-    from TMDA import Address
-
-    def getAddress(tag, option=None, address=None):
-        try:
-            tagged_address = Address.Factory(tag = tag).create(address, 
option).address
-        except ValueError, msg:
-            usage(msg)
-            sys.exit(0)
-
-        return tagged_address
-
-    def checkAddress(address, sender_address=None):
-        #FIXME: Add localtime support
-        localtime = None
-        status = []
-        try:
-            addr = Address.Factory(address)
-            addr.verify(sender_address)
-            status.append("STATUS: VALID")
-            try:
-                status.append("EXPIRES: %s" % addr.timestamp(1, localtime))
-            except AttributeError:
-                pass
-        except Address.AddressError, msg:
-            status.append("STATUS: " + str(msg))
-
-        return '\n'.join(status)
-
-except ImportError:
-    print "Missing TMDA library, and no client mode yet"
-    raise
-
-
 class AddressGUI(Frame):
     def __init__(self, master=None, **args):
         R = 0
@@ -569,8 +737,7 @@
 
         f = Frame(f)
         f.grid(row=0, column=1)
-        self.m_du = Button(f, text=self.units[self.uidx][0], relief=RAISED)
-        self.m_du.bind('<Button-1>', self.LClick)
+        self.m_du = Button(f, text=self.units[self.uidx][0], relief=RAISED, 
+command=self.LClick)
         self.m_du.bind('<Button-3>', self.RClick)
         self.m_du.pack(fill=BOTH, expand=1)
 
@@ -597,11 +764,11 @@
         
         self.Calc()
 
-    def RClick(self, ev):
+    def RClick(self, ev=None):
         self.uidx = (len(self.units) + self.uidx - 1) % len(self.units)
         self.m_du.configure(text=self.units[self.uidx][0])
 
-    def LClick(self, ev):
+    def LClick(self, ev=None):
         self.uidx = (len(self.units) + self.uidx + 1) % len(self.units)
         self.m_du.configure(text=self.units[self.uidx][0])
 
@@ -644,7 +811,11 @@
 
 def main():
     root = Tk()
-    if len(sys.argv) > 1 and sys.argv[1] == '-p':
+    if using_network:
+        r = connectToServer(host=(host, port), auth=(user, passwd))
+        if not r:
+            raise
+    if pending_first:
         PendingGUI(root).pack(fill=BOTH, expand=YES)
     else:
         AddressGUI(root).pack(fill=BOTH, expand=YES)

_______________________________________
tmda-cvs mailing list
http://tmda.net/lists/listinfo/tmda-cvs

Reply via email to