wcc_client.py :  » GUI » PmwContribD » PmwContribD-r2_0_2 » SampleApps » WhackyChat » Client » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » PmwContribD 
PmwContribD » PmwContribD r2_0_2 » SampleApps » WhackyChat » Client » wcc_client.py
#!/usr/bin/env python
#
# $Id: wcc_client.py,v 1.3 2001/11/03 11:05:22 doughellmann Exp $
#
# Copyright 2001 Doug Hellmann.
#
#
#                         All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of Doug
# Hellmann not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
# NO EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

"""GUI Client to talk to a WackyChat server.

"""

__rcs_info__ = {
    #
    #  Creation Information
    #
    'module_name'  : '$RCSfile: wcc_client.py,v $',
    'rcs_id'       : '$Id: wcc_client.py,v 1.3 2001/11/03 11:05:22 doughellmann Exp $',
    'creator'      : 'Doug Hellmann <doug@hellfly.net>',
    'project'      : 'PmwContribD',
    'created'      : 'Sun, 27-May-2001 11:42:08 EDT',

    #
    #  Current Information
    #
    'author'       : '$Author: doughellmann $',
    'version'      : '$Revision: 1.3 $',
    'date'         : '$Date: 2001/11/03 11:05:22 $',
}

#
# Import system modules
#
import string
import socket
import sys
import os
import Pmw
from Tkinter import *


#
# Import Local modules
#
import GuiAppD
from MCScrolledListBox import MCScrolledListBox
import Table

import wcc_dialog
from wcc_options import hermesrc
import wcc_protocol
from wcc_status import WackyStatusInfo

import cvsversion

#
# Module
#

class ChangePasswordDialog(Pmw.Dialog):
    OK = 'OK'
    CANCEL = 'Cancel'
    def __init__(self, parent=None, **kw):
        optiondefs = (
            ('currentpassword', '', None),
            ('setpassword', None, Pmw.INITOPT),
            ('buttons', (self.OK, self.CANCEL), self._buttons),
            ('defaultbutton', 0, self._defaultButton),
            ('command', self.commandCB, Pmw.INITOPT),
            )
        self.defineoptions(kw, optiondefs)
        Pmw.Dialog.__init__(self, parent)
        #
        # Create an entry field for the old password
        #
        self.old_password = StringVar(self.interior())
        self.old_password.set('')
        old = self.createcomponent(
            'old',
            (), None,
            Pmw.EntryField,
            (self.interior(),),
            labelpos='w',
            label_text='Current Password:',
            entry_textvariable=self.old_password,
            entry_show='*',
            )
        old.pack(side=TOP)
        self.new_password = StringVar(self.interior())
        new = self.createcomponent(
            'new',
            (), None,
            Pmw.EntryField,
            (self.interior(),),
            labelpos='w',
            label_text='New Password',
            entry_textvariable=self.new_password,
            entry_show='*',
            )
        new.pack(side=TOP)
        Pmw.alignlabels( (new, old) )
        self.initialiseoptions(self.__class__)
        return

    def activate(self):
        self.old_password.set('')
        self.new_password.set('')
        self.component('old_entry').focus_set()
        return Pmw.Dialog.activate(self)
        
    def errorMessage(self, message):
        dlg = Pmw.MessageDialog(self.interior(),
                                title='Invalid Password',
                                message_text=message,
                                iconpos='w',
                                icon_bitmap='error',
                                defaultbutton=0)
        dlg.activate()
        return
    
    def commandCB(self, button):
        if button == self.CANCEL:
            self.deactivate()
            return
        elif button == self.OK:
            #
            # Test old password
            #
            old_val = string.strip(self.old_password.get())
            if not old_val:
                # They did not enter a password at all
                self.errorMessage('You must enter a value for the current password.')
                return
            elif old_val != self['currentpassword']:
                # They did not get the current value right!
                self.errorMessage('Incorrect value for the current password.')
                return
            else:
                # See about changing the password
                new_val = string.strip(self.new_password.get())
                if not new_val:
                    self.errorMessage('No value specified for new password.')
                    return
                elif ((string.find(new_val, ' ') >= 0)
                      or
                      (string.find(new_val, '\t') >= 0)):
                    # No whitespace allowed
                    self.errorMessage(
                        'Whitespace characters are not allowed in passwords.')
                    return
                else:
                    # Seems ok, set the new value
                    setpassword = self['setpassword']
                    if setpassword:
                        setpassword(new_val)
        self.deactivate()
        return
    
class Hermes(GuiAppD.GuiAppD):

    #
    # About box information
    #
    appversion=cvsversion.cvs_product_version()
    appname='Hermes'
    copyright = '\nClient program:\nCopyright Doug Hellmann\n' +\
                '<doug@hellfly.net> 1999\n' + \
                'All rights reserved.\n\n' + \
                'Webguys Instant Message (WIM)\nServer protocol:\n' + \
                '(AKA Wacky-Chat)\n' + \
                'Copyright 1998 Kevin Birch <kbirch@pobox.com>'

    usebuttonbox = 1

    #
    # Broadcast dialog title
    #
    BROADCAST_DIALOG_TITLE = 'Broadcast Messages'

    #
    # How frequently to poll?
    #
    polling_frequency = 100

    user_preferences = hermesrc()

    ONLINE        = 'Online'
    AWAY          = 'Away'
    NA            = 'Not Available'
    OCCUPIED      = 'Occupied'
    DND           = 'Do not disturb'
    PRIVACY       = 'Privacy'
    AUTO_RESPONSE = 'Auto-response'

    dispositions = (ONLINE,
                    AWAY,
                    NA,
                    OCCUPIED,
                    DND,
                    PRIVACY,
                    )
    
    disposition_message = {
        ONLINE     : None,
        AWAY       : 'araway',
        NA         : 'arna',
        OCCUPIED   : 'aroccupied',
        DND        : 'ardnd',
        PRIVACY    : 'arprivacy',
        }

    disposition_protocol_param = {
        ONLINE     : 'ONLINE',
        AWAY       : 'AWAY',
        NA         : 'NA',
        OCCUPIED   : 'OCCUPIED',
        DND        : 'DND',
        PRIVACY    : 'PRIVACY',
        }

    disposition_display_value = {
        'ONLINE'   : ONLINE,
        'AWAY'     : AWAY,
        'NA'       : NA,
        'OCCUPIED' : OCCUPIED,
        'DND'      : DND,
        'PRIVACY'  : PRIVACY,
        }

    shown_initial_motd = 0
    
    ##
    ## GUIAPP STUFF
    ##
    
    def appInit(self):
        #
        # Interface not created yet
        #
        self._interface_created = 0
        #
        # User preferences
        #
        self.user_preferences.store() # only really useful the first time
        #
        # My current online status
        #
        self.disposition = self.disposition_protocol_param[self.ONLINE]
        #
        # Find the MOTD that we know already
        #
        self._motdRead()
        #
        # Storage for Messages of the day
        #
        self._motd = []
        #
        # Storage for message dialogs, so we can
        # reuse them
        #
        self._message_dialogs = {}
        return

    def main(self):
        if self._wimd:
            GuiAppD.GuiAppD.main(self)
        return
    
    ##
    ## MAKE THE INTERFACE
    ##
    
    def createMenuBar(self):
        #
        # File menu
        #
        self.addMenuItem('File', 'command', 'Connect to the server',
                         label='Connect',
                         command=self.connect
                         )
        self.addHelpItem('Interface:Menu:File:Connect',
                         """
                         Connect to the WIMD server.
                         """
                         )
        self.addMenuItem('File', 'command', 'Disconnect from the server',
                         label='Disconnect',
                         command=self.disconnect
                         )
        self.addHelpItem('Interface:Menu:File:Disconnect',
                         """
                         Disconnect from the WIMD server.
                         """
                         )
        self.menuBar.addmenuitem('File', 'separator')
        self.addMenuItem('File', 'command', 'Send a broadcast message',
                         label='Broadcast...',
                         command=self.broadcastMessage
                         )
        self.addHelpItem('Interface:Menu:File:Broadcast...',
                         """
                         Send a broadcast message to all current
                         users.
                         """)
        self.menuBar.addmenuitem('File', 'separator')
        #
        # Options
        #
        self.addMenuItem('Options', 'command', 'Change password',
                         label='Password...',
                         command=self.showChangePasswordCB,
                         )
        self.addHelpItem('Interface:Menu:Options:Password...',
                         """
                         Change the users password on the server.
                         """
                         )
        #
        # Info menu
        #
        try:
            self.menuBar.addmenu('Info', 'Server and user information')
        except ValueError:
            pass
        self.addMenuItem('Info', 'command', 'Server daily messages',
                         label='MOTD...',
                         command=self.showMOTD
                         )
        self.addHelpItem('Interface:Menu:Info:MOTD...',
                         """
                         The MOTD menu item displays a dialog containing
                         all of the message of the day information from the
                         last time a connection to the server was initiated.
                         """)
        self.addMenuItem('Info', 'command', 'Update user status list',
                         label='Update users',
                         command=self.statusUpdateCB,
                         )
        self.addHelpItem('Interface:Menu:Info:Update users',
                         """
                         Poll the server to get the status of all
                         current users.  This happens periodically,
                         but it can be useful to scan manually.
                         """)
        self.addMenuItem('Info', 'command',
                         'Show all information about the selected user',
                         label='Show user info...',
                         command=self.showUserInfoCB,
                         acceleratorKey='i')
        self.addHelpItem('Interface:Menu:Info:Show user info...',
                         """
                         Display all of the information about
                         the selected user.
                         """)
        GuiAppD.GuiAppD.createMenuBar(self)
        return

    def createInterface(self):
        #
        # Double check that we know enough to
        # sign them on.  This cannot be done
        # in appInit() because we do not have
        # all of the required GUI pieces initialized
        # yet.
        #
        self.connect()
        if self._wimd:
            self.configureWimd()
            self.createChatInterface()
        return

    def createChatInterface(self):
        #
        # Create the actual interface
        #
        self.component('progressmeter').pack_forget()
        self.addHelpItem('Interface:Main Window',
                         """
                         The main window displays the list of users
                         who are currently available for chats, and
                         provides menu options and controls for configuring
                         the behavior of the application.
                         """)
        #
        # Create a table to hold the user information
        # for all the users on the system
        #
        user_list = self.createcomponent(
            'usertable',
            (), None,
            MCScrolledListBox,
            (self.interior(),),
            dblclickcommand=self.newChatWithSelected,
            clipper_width=285,
            clipper_height=200,
            )
        for cl, ex, w in ( ('User',    YES, 20),
                           ('Status',  NO,  10),
                           ('M',       NO,   5),
                           ):
            user_list.addColumn(label=cl, expand=ex, width=w)
        self.bind(user_list, 'Double click on a user to send them a message')
        self.addHelpItem('Interface:Main Window:User List',
                         """
                         The user list displays a list of the users
                         currently connected to the wimd server.  The
                         list is automatically updated every time
                         a user logs on or off from the server.

                         Double click on a user name to open a
                         chat window with that user.
                         """)
        self._interface_created = 1
        self.wStatusUpdate()
        user_list.pack(
            side=TOP,
            fill=BOTH,
            expand=YES,
            )
        disposition = self.createcomponent(
            'DispositionMenu',
            (), None,
            Pmw.OptionMenu,
            (self.interior(),),
            items=self.dispositions,
            initialitem=0,
            labelpos='w',
            label_text='Status:',
            command=self.changeDispositionCB,
            )
        self.bind(disposition, 'Set your online status')
        disposition.pack(
            side=TOP,
            fill=X,
            expand=NO,
            )
        #
        # Create buttons
        #
        self.addHelpItem('Interface:Main Window:Action Buttons',
                         """
                         The action buttons along the bottom of the
                         main window provide quick access to commonly
                         executed chat commands.
                         """)
        self.buttonAdd('Chat',
                       helpMessage='Chat with selected users',
                       statusMessage='Chat with selected users',
                       command=self.newChatWithSelected,
                       )
        self.addHelpItem('Interface:Main Window:Action Buttons:Chat',
                         """
                         Use this button to create a chat window to talk
                         to the user(s) selected in the User List.
                         """)
        self.buttonAdd('Broadcast',
                       helpMessage='Send a broadcast message to all users',
                       statusMessage='Send a broadcast message to all users',
                       command=self.broadcastMessage,
                       )
        self.addHelpItem(
            'Interface:Main Window:Action Buttons:Broadcast',
            """
            Use this button to send a message to all users who
            are currently logged in to the server.
            """)
        self.buttonAdd('Stored',
                       helpMessage='Retrieve stored messages',
                       statusMessage='Retrieve stored messages',
                       state='disabled',
                       )
        self.addHelpItem(
            'Interface:Main Window:Action Buttons:Stored',
            """
            Use this button to display messages which have
            been received and stored by the client because the
            status was set to 'Do not disturb'.
            """
            )
        #
        # Register the polling function
        #
        self.after(self.polling_frequency, self.poll)
        return

    ##
    ## CALLBACKS
    ##

    def changePasswordCB(self, new_value):
        print 'changing password: %s' % new_value
        try:
            self._wimd.passwd(new_value)
        except wcc_protocol.WackyProtocolError, msg:
            self.showError(str(msg))
            return
        except IOError:
            pass
        self.user_preferences['password'] = new_value
        return
    
    def showChangePasswordCB(self, *args):
        try:
            dlg = self._change_password_dialog
        except AttributeError:
            dlg = ChangePasswordDialog(self.interior(),
                                       setpassword=self.changePasswordCB)
            self._change_password_dialog = dlg
        dlg.configure(currentpassword=self.user_preferences['password'])
        dlg.activate()
        return
    
    def statusUpdateCB(self, *args):
        self.busyStart()
        if self._connected:
            self._status_info.update()
        self.wStatusUpdate()
        self.busyEnd()
        return
    
    def showUserInfoCB(self, event=None):
        selidxs = self.component('usertable').curselection()
        if not selidxs:
            return
        selected_list = []
        for idx in selidxs:
            idx = int(idx)
            selected_list.append(self._display_user_info[idx])
        selected_list.sort()
        info = []
        for sel in selected_list:
            info.append('User:\t%s\nUID:\t%s\nStatus:\t%s\nEmail:\t%s' % sel)
        info = string.join(info, '\n\n')
        btn = self.showMessageDialog(info, justify='left',
                                     buttons=('Chat', 'OK'),
                                     title='User Information')
        if btn == 'Chat':
            self.newChatWithSelected()
        return

    def broadcastMessage(self):
        dlg = self.getDialog( self.BROADCAST_DIALOG_TITLE, (), () )
        dlg.deiconify()
        dlg.show()
        return
    
    def savePrefsCB(self, prefs):
        """
        We need to update the preferences for dialogs
        that can be changed at runtime.
        """
        #print 'Saved preferences: ', prefs
        new_dialog_settings = {
            'ringbell':prefs['ringbell'],
            'dateface':prefs['dateface'],
            'fromface':prefs['fromface'],
            'messageface':prefs['messageface'],
            'urlface':prefs['urlface'],
            'clearonclose':prefs['clearwindow'],
            'webbrowser':prefs['webbrowser'],
            }
        apply(wcc_dialog.updateDialogSettings, (), new_dialog_settings)
        GuiAppD.GuiAppD.savePrefsCB(self, prefs)
        try:
            self._wimd.nick(prefs['nickname'])
            if prefs['email']:
                self._wimd.mail(prefs['email'])
        except AttributeError:
            # no connection yet
            pass
        return

    def changeDispositionCB(self, *args):
        self.disposition = self.disposition_protocol_param[args[0]]
        self._wimd.disp(self.disposition)
        self._status_info.setUserStatus(str(self.user_preferences['uid']),
                                        self.disposition)
        self.wStatusUpdate()
        return
    
    ##
    ## WIMD MESSAGE HANDLERS
    ##

    def poll(self):
        """
        Poll the wimd connection.
        """
        if self._connected:
            messages = self._wimd.poll()
            #if messages:
            #    print 'Got messages: ', messages
            self.after(self.polling_frequency, self.poll)
        return

    def _wimdmhMESG(self, fromType, fromName, fromID, message):
        self.busyStart()
        #
        # Determine how the message was addressed
        #
        if message[:3] == 'To:':
            eofln = string.index(message, '\r')
            addressee = message[3:eofln]
            message = message[eofln+2:]
        else:
            addressee = None
        #
        # Determine if we have a message window from this
        # user already
        #
        if addressee:
            # Use the addressee list to find the window
            addressee_list = string.split(addressee, ',')
            addressee_list = map(string.strip, addressee_list)
            addressee_list.sort()
            dlg_id = self.getDialogId(addressee_list + [fromName])
            addressee_id_list = map(self._status_info.uidFromName,
                                    addressee_list)
            pass
        else:
            # Use the from id to find the window
            dlg_id = self.getDialogId( (fromName,) )
            addressee_list = (fromName,)
            addressee_id_list = (fromID,)
            pass
        #
        # Get the dialog, add the message, make the dialog
        # visible.
        #
        dlg = self.getDialog( dlg_id, addressee_list, addressee_id_list )
        dlg.addMessage(fromName, message)
        disp_key = self.disposition_display_value[self.disposition]
        if ((disp_key != 'ONLINE')
            and self.user_preferences['senddisposition']):
            try:
                pref_name = self.disposition_message[disp_key]
                if pref_name:
                    auto_response = '%s\n\n%s' \
                                    % (self.user_preferences['arprefix'],
                                       self.user_preferences[pref_name])
                else:
                    auto_response = None
            except KeyError:
                auto_response = None
            if auto_response:
                dlg.sendMessage(auto_response)
        self.busyEnd()
        return

    def _wimdmhCAST(self, fromType, fromName, fromID, message):
        if fromID != str(self.user_preferences['uid']):
            dlg = self.getDialog( self.BROADCAST_DIALOG_TITLE, (), () )
            dlg.addMessage(fromName, message)
        return
    
    def _wimdmhMOTD(self, message):
        #print 'MOTD:', message
        self._motd.append(message)
        return
    
    def _wimdmhUPDT(self, *args):
        #print '_wimdmhUPDT', args
        if args[0] in ( 'USER', 'DISP' ):
            # User signed on or off
            if args[2] == str(self.user_preferences['uid']):
                # this is us, and we know our state
                return
        elif args[0] == 'NICK':
            pass
        elif args[0] == 'SERV':
            # Server status message
            if args[1] == 'KICK':
                msg = 'You have been kicked off of the server.'
            elif args[1] == 'DOWN':
                msg = 'The server is going down.'
            elif args[1] == 'DISCONNECT':
                msg = 'You have been disconnected from the server.'
            else:
                msg = 'Unknown server message: %s' % str(args)
            self.showMessageDialog(msg)
            self.disconnect(1)
        #
        # Retrieve status info and redisplay
        #
        self.after_idle(self.statusUpdateCB)
        return

    def configureWimd(self):
        #
        # Set up the various "callbacks" for messages coming
        # in over the wimd connection
        #
        for msg_type in (
            'MOTD',
            'MESG',
            'UPDT',
            'CAST',
            ):
            self._wimd.registerMessageHandler(
                msg_type, getattr(self, '_wimdmh%s' % msg_type))
        return

    ##
    ## SUPPORT ROUTINES
    ##

    def _motdRead(self):
        """
        Read from the motd file that we stored last time.
        """
        try:
            motdFile = open(os.path.join(os.environ['HOME'], '.hermes.motd'),
                            'rt')
        except KeyError:
            # No home directory set
            self.previous_motd = ''
        except IOError:
            # No file written yet
            self.previous_motd = ''
        else:
            self.previous_motd = motdFile.read()
            motdFile.close()
        return

    def _motdWrite(self, new_motd_str):
        print '_motdWrite'
        try:
            motdFileName = os.path.join(os.environ['HOME'], '.hermes.motd',)
            motdFile = open(motdFileName, 'wt')
        except KeyError:
            # No home directory set
            return
        except IOError:
            # cannot write to file
            return
        else:
            print '\twriting to %s' % motdFileName
            motdFile.write(new_motd_str)
            motdFile.close()
        return
    

    def showNewMotd(self):
        if self.shown_initial_motd:
            return
        new_motd_str = string.join(self._motd, '\n')
        if not new_motd_str:
            return
        self.shown_initial_motd = 1
        if new_motd_str == self.previous_motd:
            return
        self.after_idle(self.showMOTD)
        self._motdWrite(new_motd_str)
        return
    
    def showMOTD(self):
        """
        Show a dialog with the message of the day.
        """
        motd = '%s\n\nContact Doug Hellmann <doug@hellfly.net>\nfor problems with Hermes.' \
               % string.join(self._motd, '\n')
        self.showMessageDialog(motd, title='Server Message of the Day')
        return
        
    def getDialogId(self, users):
        whoami = self._status_info.nameFromUid(self.user_preferences['uid'])
        users = filter(lambda x, ignore=whoami: x != ignore, users)
        if not users:
            users = [ whoami ]
        return wcc_dialog.getMessageDialogIDFromUsers(users)

    def wStatusUpdate(self):
        """
        Update the user information presented in the interface.
        """
        if not self._interface_created: return
        #print 'status info: ', self._status_info
        #
        # Reduce to only online users:
        #
        #online_users = filter( lambda x: x[2] == 'ONLINE',
        #                       self._status_info)
        if self._connected:
            if self.user_preferences['ignoreself']:
                display_info = filter(
                    lambda x,
                    ignore_id=str(self.user_preferences['uid']):
                    x[1] != ignore_id,
                    self._status_info)
            else:
                display_info = self._status_info
            #print 'display_info : ', display_info
            self._display_user_info = display_info
            usernames = map( lambda x: str(x[0]), display_info)
            #user_status = map( lambda x: str(x[2]), display_info)
            user_status = map(lambda x, m=self.disposition_display_value: \
                              str(m[x[2]]),
                              display_info)
        else:
            usernames = []
            user_status = []
        self.component('usertable').setlists( (usernames, user_status) )
        return

    def newChatWithSelected(self, event=None):
        """
        Create a new chat session (window) with the
        currently selected names from the usertable.
        """
        selidxs = self.component('usertable').curselection()
        if not selidxs:
            return
        selected_list = []
        for idx in selidxs:
            idx = int(idx)
            selected_list.append(self._display_user_info[idx])
        selected_list.sort()
        addressee_list = map(lambda x: x[0], selected_list)
        addressee_id_list = map(lambda x: x[1], selected_list)
        #print 'address message to ', addressee_list
        self.sendMessage(addressee_list, addressee_id_list)
        return

    def getDialog(self, dlg_id, addressee_list, addressee_id_list):
        dlg = wcc_dialog.getMessageDialog(
            parent=self.interior(),
            uid=self.user_preferences['uid'],
            uname=self._status_info.nameFromUid(self.user_preferences['uid']),
            dialogID=dlg_id,
            addressees=addressee_list,
            addressee_ids=addressee_id_list,
            app=self,
            webbrowser=self.user_preferences['webbrowser'],
            ringbell=self.user_preferences['ringbell'],
            dateface=self.user_preferences['dateface'],
            fromface=self.user_preferences['fromface'],
            messageface=self.user_preferences['messageface'],
            urlface=self.user_preferences['urlface'],
            clearonclose=self.user_preferences['clearwindow'],
            )
        return dlg
    
    def sendMessage(self, addressee_list=(), addressee_id_list=()):
        """
        Send a message to a list of users.
        """
        dlg_id = self.getDialogId(addressee_list)
        dlg = self.getDialog(dlg_id, addressee_list, addressee_id_list)
        dlg.show()
        return
        
    ##
    ## Connection stuff
    ##
    
    def disconnect(self, forced=0):
        #if not forced:
        self._wimd.quit()
        del self._wimd
        self._wimd = None
        self._connected = None
        self.wStatusUpdate()
        self.showMessage('busy', 'Disconnected')
        return
    
    def connect(self):
        self._motd = []
        num_tries = 2
        self._connected = 0
        while num_tries > 0:
            try:
                self.login()
            except wcc_protocol.WackyProtocolError, msg:
                self._wimd = None
                self.showError('Login error:\n\n%s\n\nNot connected.' % msg[0])
                self.showPrefsDialog()
                num_tries = num_tries - 1
            else:
                num_tries = 0
                try:
                    self._status_info = WackyStatusInfo(self._wimd)
                except IOError:
                    # broken pipe, probably bad login
                    self.showError(
                        'Problem connecting to server.\nProbably a bad password?')
                    self.showChangePasswordCB()
                    self.quit()
                else:
                    self._connected = 1
                self.showMessage('busy', None)
        self.wStatusUpdate()
        #
        # At this point, we will have received
        # other messages besides the unknown number of MOTD
        # messages.  That means we can display the new
        # MOTD, if it is different from the previous one.
        #
        self.showNewMotd()
        #
        # Register the polling function
        #
        self.after(self.polling_frequency, self.poll)
        return
    
    def login(self, first_time=1):
        if ((self.user_preferences['password'] == '')
            or
            (self.user_preferences['uid']) == 0):
            #
            # Need to prompt them for their password
            #
            self.getLoginInfo()
        #
        # Make the connection
        #
        try:
            self._wimd = wcc_protocol.WackyConnection(
                hostname=self.user_preferences['hostname'],
                port=self.user_preferences['port'],
                userid=str(self.user_preferences['uid']),
                password=self.user_preferences['password'],
                )
        except socket.error, errMsg:
            #
            # Socket connection problem.
            #
            msg = 'An error occured connecting to the server\n' + \
                  ('on port %d of %s as the user %s.\n' \
                   % (self.user_preferences['port'],
                      self.user_preferences['hostname'],
                      self.user_preferences['uid'])
                   ) + \
                   'Verify the settings in your preferences file' + \
                   '(~/.hermesrc).'
            if errMsg[0] == 111:
                msg = msg + \
                      '\n\nCheck to make sure that the server is running.'
            else:
                msg = msg + '\n\nThe message was:\n%s' % str(errMsg)
            self.showError(msg)
            self._connected = 0
            self._wimd = None
        else:
            self._connected = 1
            self.configureWimd()
        return

    def getLoginInfo(self):
        self.showMessageDialog(
            'No connection information has been specified.\n'
            'Set the user id, password, server, and port preferences\n'
            'to continue.'
            )
        self.showPrefsDialog()
        return

    ##
    ## Service methods
    ##
    
    def pick_user(self):
        """
        pick_user(parent, wimd)

        Given a parent widget and a connection to a wimd server, present a
        dialog to get the user to pick multiple users.
        """
        status = self._status_info
        dialog = Pmw.SelectionDialog( parent=self.interior() )
        dialog.component('buttonbox').setdefault(0)
        addable_users = map(lambda x: x[0], status)
        dialog.component('scrolledlist').setlist(addable_users)
        result = dialog.activate()
        if result == 'OK':
            # get selection
            moniker = dialog.getcurselection()[0]
            uid = status.uidFromName(moniker)
        else:
            moniker = None
            uid = None
        return moniker, uid

    def connection(self):
        """
        Get a reference to the wimd connection for
        this application.
        """
        return self._wimd

    def statusInfo(self):
        """
        Get a reference to the wimd status manager
        for this application.
        """
        return self._status_info
    
if __name__ == '__main__':
    Hermes().run()
    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.