mirror of git://git.psyced.org/git/pypsyc
451 lines
15 KiB
Python
451 lines
15 KiB
Python
# -*- coding: latin-1 -*-
|
||
from wxPython.wx import *
|
||
|
||
# XXX Please feel free to modify and vershclimmbesser this piece of code
|
||
# especially the bits marked with XXX
|
||
##from pypsyc.objects.PSYCObject import
|
||
from pypsyc.objects.PSYCObject import ClientUser, ClientPlace, PSYCClient, PSYCObject
|
||
from pypsyc.center import ClientCenter
|
||
|
||
from pypsyc import netLocation, parsetext
|
||
|
||
import asyncore, sys, os
|
||
|
||
# ich glaub ich weiss jetzt wofuer die hier toll sind
|
||
# !!!
|
||
# this list isn't up-to-date anymore, stolen from the old gui code
|
||
# !!!
|
||
ID_ABOUT = 1002
|
||
ID_CONNECT = 1001
|
||
ID_DISCONNECT = 10011
|
||
ID_SAY = 3300
|
||
ID_NOTEBOOK = 3301
|
||
ID_STATUS = 9901
|
||
ID_MENU = 9902
|
||
ID_BUDDY_LIST = 9903
|
||
ID_BUDDY_LIST_DK = 990301
|
||
ID_EXIT = 1099
|
||
ID_CLOSECHATNOTEBOOK = 2099
|
||
ID_CLOSECHATNOTE = 2098
|
||
|
||
def opj(path):
|
||
"""Convert paths to the platform-specific separator"""
|
||
return apply(os.path.join, tuple(path.split('/')))
|
||
|
||
def print_psyc(vars, mc, data, caller = ''):
|
||
print '------ ' + str(caller)
|
||
print '-- mc:'
|
||
print mc
|
||
print '-- vars:'
|
||
print str(vars.items())
|
||
print '-- data:'
|
||
print str([data])
|
||
print '------'
|
||
|
||
|
||
class DevNull:
|
||
def write(self, text):
|
||
return
|
||
|
||
class wxCenter(wxApp, ClientCenter):
|
||
def __init__(self): #vllt noch cmd line args uebergeben or so
|
||
wxApp.__init__(self, 0)
|
||
self.run()
|
||
|
||
def OnInit(self):
|
||
ClientCenter.__init__(self)
|
||
self.config = {} # = { 'uin' : 'psyc://blah/~user', 'foo': 'bar'}
|
||
self.config[u'uni'] = u'psyc://ve.symlynx.com/~betatim3'
|
||
self.config[u'password'] = u'tim'
|
||
self.config[u'action'] = u'brabbel'
|
||
self.config[u'bgcolour'] = (255, 236, 191)
|
||
self.config[u'fontcolour'] = (34, 63, 92)
|
||
self.config[u'fontsize'] = 8
|
||
self.config[u'prompt'] = u'* '
|
||
print sys.getdefaultencoding()
|
||
print os.name
|
||
|
||
#print self.config
|
||
self.frame = wxPFrame(logic_parent=self) # nen frame um die tabs aufzuheben
|
||
self.client = PClient(self.config['uni'], self)
|
||
self.create_server_place(netLocation(self.config['uni'])) # eignetlich is es kein place aber naja
|
||
|
||
self.default_connection = netLocation(self.config['uni'])
|
||
self.client.online()
|
||
self.client.create_display(self)
|
||
self.SetTopWindow(self.client.display)
|
||
self.client.display.Show()
|
||
|
||
self.timer = wxPyTimer(self.socket_check)
|
||
self.timer.Start(100) # alle 100 ms
|
||
return True
|
||
|
||
def input(self, event):
|
||
print event.GetString()
|
||
event.Skip()
|
||
|
||
def socket_check(self):
|
||
asyncore.poll(timeout=0.0) # das sollte vllt klappen
|
||
|
||
def run(self):
|
||
self.MainLoop()
|
||
|
||
def sendmsg(self, vars, mc, data, caller = None):
|
||
print_psyc(vars, mc, data, 'center sending')
|
||
ClientCenter.sendmsg(self, vars, mc, data, caller)
|
||
|
||
def set_default_connection(self, uni):
|
||
#netLocation(self.uni)
|
||
print 'set_default_connect: ' + netLocation(uni)
|
||
self.default_connection = netLocation(uni)
|
||
|
||
def create_user(self, netname):
|
||
#print "this should create a user"
|
||
t = PUser(netname, self)
|
||
# nicht tab.display damit wir netname haben ,]]
|
||
# auch wenn es extrem strange ist wir uebergeben
|
||
self.frame.addTab(t)
|
||
return t
|
||
|
||
def create_place(self, netname):
|
||
#print "this should create a room"
|
||
t = PPlace(netname, self)
|
||
self.frame.addTab(t) # same here
|
||
return t
|
||
|
||
def create_server_place(self, netname):
|
||
t = PServer(netname, self)
|
||
self.frame.addTab(t, extra_display='server') # same here
|
||
sys.stdout = t
|
||
return t
|
||
|
||
|
||
class wxPTab(wxPanel):
|
||
def __init__(self, parent, logic_parent = None):
|
||
""" all das ausehen usw """
|
||
wxPanel.__init__(self, parent, -1, style=0)
|
||
# we use logic_parent to call the functions pypsyc provides
|
||
# gui stuff in the wxBlah objects, psyc stuff in the PBlah objects
|
||
if not logic_parent: print 'WARNING: no logic_parent set, this could be a problem'
|
||
self.logic_parent = logic_parent
|
||
config = self.logic_parent.center.config
|
||
self.prompt = config['prompt']
|
||
self.lock = 0
|
||
self.counter = 0
|
||
self.buffer = ''
|
||
self.text_box = wxTextCtrl(self, -1, style=wxTE_MULTILINE|wxTE_RICH2|wxTE_READONLY, size=wxDefaultSize)
|
||
self.entry_box = wxTextCtrl(self, ID_SAY, style=wxTE_PROCESS_ENTER|wxTE_RICH2|wxTE_PROCESS_TAB, size=wxDefaultSize)
|
||
|
||
fontcolour = wxColour(config['fontcolour'][0], config['fontcolour'][1], config['fontcolour'][2])
|
||
bgcolour = wxColour(config['bgcolour'][0], config['bgcolour'][1], config['bgcolour'][2])
|
||
self.entry_box.SetBackgroundColour(bgcolour)
|
||
self.text_box.SetBackgroundColour(bgcolour)
|
||
points = self.text_box.GetFont().GetPointSize() # get the current size
|
||
f = wxFont(points, wxMODERN, wxNORMAL, wxBOLD, False)
|
||
self.text_box.SetDefaultStyle(wxTextAttr(fontcolour, bgcolour, f))
|
||
self.entry_box.SetDefaultStyle(wxTextAttr(fontcolour, bgcolour, f))
|
||
self.SetBackgroundColour(bgcolour)
|
||
|
||
sizer = wxBoxSizer(wxVERTICAL)
|
||
sizer.Add(self.text_box, 1, wxEXPAND)
|
||
sizer.Add(self.entry_box, 0, wxEXPAND)
|
||
self.SetSizer(sizer)
|
||
|
||
#print 'wxPTab: ' + str(dir(self))
|
||
EVT_TEXT_ENTER(self, ID_SAY, self.input)
|
||
|
||
def input(self, event):
|
||
text = event.GetString()
|
||
text = text.lstrip() # only strip whites from the beginning
|
||
mc = ''
|
||
vars = {}
|
||
data = ''
|
||
vars['_target'] = self.logic_parent.netname # eigentlich is target immer netname
|
||
if text != '' and text[0] == '/':
|
||
# houston we have a command
|
||
if text.startswith("/join"): # and text.__len__() > 16:
|
||
mc = '_request_enter'
|
||
vars['_target'] = text[6:]
|
||
elif text.startswith("/part"):
|
||
mc = '_request_leave'
|
||
vars['_target'] = text[6:]
|
||
elif text.startswith('/password'):
|
||
mc = '_set_password'
|
||
t = text.split('/password')
|
||
if t[1] != '' and t[1] != ' ':
|
||
vars['_password'] = t[1]
|
||
vars['_target'] = self.logic_parent.center.config['uni']
|
||
else:
|
||
self.append1('Usage: /password <secret>')
|
||
return
|
||
elif text.startswith('/retrieve'):
|
||
mc = '_request_retrieve'
|
||
vars['_target'] = self.logic_parent.center.config['uni']
|
||
else:
|
||
mc = '_request_execute'
|
||
data = text
|
||
|
||
elif text != '' and text[0] == '#':
|
||
self.append1(text)
|
||
self.entry_box.SetValue('')
|
||
return
|
||
|
||
else:
|
||
mc = '_message_public'
|
||
try:
|
||
text2 = text.decode('iso-8859-15')
|
||
except:
|
||
text2 = text
|
||
print 'unicode'
|
||
data1 = text2.encode('iso-8859-1')
|
||
data = data1
|
||
# am ende einfach wegschicken das fertige paket
|
||
self.entry_box.SetValue('')
|
||
#print_psyc(mmp, psyc, mc, data, 'place sending')
|
||
self.logic_parent.sendmsg(vars, mc, data)
|
||
|
||
def append1(self, line):
|
||
""" use this to append multi/single line text"""
|
||
if type(line) == type(u'<EFBFBD><EFBFBD><EFBFBD>'):
|
||
line = line.encode('iso-8859-15')
|
||
if os.name == 'posix':
|
||
if self.lock == 0:
|
||
self.lock = 1
|
||
if self.buffer != '':
|
||
self.text_box.AppendText('buffered: ' + self.buffer)
|
||
self.buffer = ''
|
||
for linex in line.split('\n'):
|
||
self.text_box.AppendText(self.prompt.encode('iso-8859-15') + linex)
|
||
self.text_box.AppendText('\n')
|
||
self.logic_parent.center.Yield()
|
||
self.lock = 0
|
||
else:
|
||
self.buffer += line + '\n'
|
||
elif os.name == 'nt':
|
||
# AppendText() doesn't seem to do the right thing in windows
|
||
for linex in line.split('\n'):
|
||
self.text_box.WriteText(self.prompt.encode('iso-8859-15') + linex)
|
||
self.text_box.WriteText('\n')
|
||
# we should find out how many 'lines' we write and scroll the right
|
||
# amount instead of scrolling 10000 at once XXX
|
||
self.text_box.ScrollLines(10000)
|
||
self.logic_parent.center.Yield()
|
||
|
||
def append(self, text):
|
||
""" use this for more then one line USE append1() this is obsolete!! """
|
||
# is this broken? do we have to do the same as in append1()?
|
||
lines = text.split('\n')
|
||
for line in lines:
|
||
self.text_box.AppendText(self.prompt + line + '\n')
|
||
#print self.netname + ': ' + str(text)
|
||
|
||
|
||
class wxPFrame(wxFrame):
|
||
def __init__(self, parent = None, logic_parent = None, title = 'pypsyc-frame', pos = wxDefaultPosition, size = wxSize(920, 570), style = wxDEFAULT_FRAME_STYLE):
|
||
wxFrame.__init__(self, None, -1, title, size=size)
|
||
# do we need it here? wxFrame is only supposed to be a container
|
||
# and shouldn't do that much -> only here to be flexible
|
||
# we use logic_parent to call the functions pypsyc provides
|
||
# gui stuff in the wxBlah objects, psyc stuff in the PBlah objects
|
||
if not logic_parent: print 'WARNING: no logic_parent set, this could be a problem'
|
||
self.logic_parent = logic_parent
|
||
self.notebook = wxNotebook(self, -1, style=0)
|
||
self.CreateStatusBar()
|
||
self.SetStatusText("welcome to pypsyc")
|
||
self.Show()
|
||
|
||
def addTab(self, tab,extra_display = None):
|
||
tab.create_display(self.notebook)
|
||
if extra_display:
|
||
self.logic_parent.client.set_display(extra_display, tab.display)
|
||
self.notebook.AddPage(tab.display, str(tab.netname), 1)
|
||
|
||
|
||
class wxPPlace(wxPTab):
|
||
def __init__(self, parent, logic_parent = None):
|
||
wxPTab.__init__(self, parent=parent, logic_parent=logic_parent)
|
||
self.netname = self.logic_parent.netname
|
||
|
||
|
||
class wxPUser(wxPTab):
|
||
def __init__(self, parent, logic_parent = None):
|
||
wxPTab.__init__(self, parent=parent, logic_parent=logic_parent)
|
||
self.netname = self.logic_parent.netname
|
||
|
||
|
||
class wxPClient(wxFrame):
|
||
def __init__(self, parent = None, title = 'pypsyc', logic_parent = None, pos = wxDefaultPosition, size = wxSize(100, 400), style = wxDEFAULT_FRAME_STYLE):
|
||
wxFrame.__init__(self, None, -1, title, size=size)
|
||
# we use logic_parent to call the functions pypsyc provides
|
||
# gui stuff in the wxBlah objects, psyc stuff in the PBlah objects
|
||
if not logic_parent: print 'WARNING: no logic_parent set, this could be a problem'
|
||
self.logic_parent = logic_parent
|
||
|
||
self.CreateStatusBar()
|
||
self.SetStatusText("welcome to pypsyc")
|
||
self.BuddyList = wxListCtrl(self, 2222, style=wxLC_REPORT|wxLC_SINGLE_SEL|wxSUNKEN_BORDER)
|
||
self.BuddyList.InsertColumn(0, "ST")
|
||
self.BuddyList.InsertColumn(1, "Nick")# , wxLIST_FORMAT_RIGHT)
|
||
self.BuddyList.SetColumnWidth(0, 20)
|
||
|
||
self.status = wxComboBox(self, ID_STATUS, "", choices=["Offline", "Online", "Away"], size=(150,-1), style=wxCB_DROPDOWN)
|
||
self.menu_button = wxButton( self, ID_MENU, 'pypsyc')
|
||
self.exit_button = wxButton( self, ID_EXIT, 'exit')
|
||
self.con_menu = wxBoxSizer(wxHORIZONTAL)
|
||
self.con_menu.Add(self.menu_button, 1, wxALIGN_BOTTOM)
|
||
self.con_menu.Add(self.exit_button, 1, wxALIGN_BOTTOM)
|
||
|
||
sizer = wxFlexGridSizer(3, 0 , 0,0)
|
||
sizer.Add(self.BuddyList, 1, wxGROW)
|
||
sizer.Add(self.con_menu, 1,wxGROW)
|
||
sizer.Add(self.status, 1,wxGROW)
|
||
sizer.AddGrowableRow(0)
|
||
sizer.AddGrowableCol(0)
|
||
# do something so that the buttons don't vanish in a too small window
|
||
# this is h4x0r-style but does the job at the moment
|
||
sizer.SetItemMinSize(self.BuddyList, 30, 10)
|
||
sizer.SetMinSize(wxSize(200,280))
|
||
self.SetSizer(sizer)
|
||
self.SetAutoLayout(true)
|
||
self.Show()
|
||
|
||
|
||
class PPlace(ClientPlace):
|
||
def __init__(self, netname, center):
|
||
ClientPlace.__init__(self, netname, center)
|
||
self.display = None
|
||
|
||
def create_display(self, parent):
|
||
self.display = wxPPlace(parent=parent, logic_parent=self)
|
||
|
||
def msg(self, vars, mc, data, caller = None):
|
||
print_psyc(vars, mc, data, 'place')
|
||
#print 'ddd' + str(type(data))
|
||
parsedtext = parsetext(vars, mc, data)
|
||
#print dir(parsedtext) , type(parsedtext)
|
||
#parsedtext = parsedtext.encode('iso-8859-15')
|
||
#print type(parsedtext)
|
||
if mc == '_message_public':
|
||
line = u''
|
||
line += vars['_nick']
|
||
if vars['_action']: line += ' ' + vars['_action'] + '>'
|
||
else: line += '>'
|
||
try:
|
||
line += ' ' + parsedtext.decode('iso-8859-15')
|
||
except:
|
||
line += ' ' + parsedtext
|
||
self.display.append1(line)
|
||
elif mc.startswith('_status_place_topic'):
|
||
self.display.append1('TOPIC: ' + parsedtext)
|
||
else:
|
||
self.display.append1(parsedtext)
|
||
|
||
|
||
class PUser(ClientUser):
|
||
def __init__(self, netname, center):
|
||
ClientUser.__init__(self, netname, center)
|
||
self.display = None
|
||
|
||
def create_display(self, parent):
|
||
self.display = wxPUser(parent=parent, logic_parent=self)
|
||
|
||
def msg(self, vars, mc, data, caller = None):
|
||
print_psyc(vars, mc, data, caller)
|
||
parsedtext = parsetext(vars, mc,data)
|
||
#parsedtext = parsedtext.encode('iso-8859-15')
|
||
if mc == '_message_public':
|
||
self.display.append1(parsedtext)
|
||
else:
|
||
self.display.append1(parsedtext)
|
||
|
||
|
||
class PServer(PSYCObject):
|
||
def __init__(self, netname, center):
|
||
PSYCObject.__init__(self, netname, center)
|
||
print 'registered server'
|
||
#print 'PServer: ' + str(dir(self))
|
||
self.display = None
|
||
|
||
def create_display(self, parent):
|
||
self.display = wxPPlace(parent=parent, logic_parent=self)
|
||
|
||
def msg(self, vars, mc, data, caller = None):
|
||
print_psyc(vars, mc, data, 'server')
|
||
parsedtext = parsetext(vars, mc,data)
|
||
#parsedtext = parsedtext.encode('iso-8859-15')
|
||
#self.center.Yield()
|
||
if mc == '_notice_circuit_established':
|
||
mc = '_request_link'
|
||
vars = {}
|
||
data =''
|
||
vars['_target'] = self.center.config['uni']
|
||
self.sendmsg(vars, mc, data)
|
||
self.display.append1(parsedtext)
|
||
else:
|
||
self.display.append1(parsedtext)
|
||
|
||
def write(self, text):
|
||
""" redirected stdout """
|
||
# we have problems if text contains \n and with print adding an extra \n
|
||
lines = text.split('\n')
|
||
for line in lines:
|
||
if line == '':
|
||
return
|
||
else:
|
||
self.display.append1('printed: ' + line)
|
||
|
||
def sendmsg(self, vars, mc, data, caller = None):
|
||
print_psyc(vars, mc, data, 'server sending...')
|
||
PSYCObject.sendmsg(self, vars, mc, data, caller)
|
||
|
||
|
||
class PClient(PSYCClient):
|
||
def __init__(self, netname, center):
|
||
PSYCClient.__init__(self, netname, center)
|
||
self.display = None
|
||
self.extra_display = {} # XXX
|
||
#self.create_display(parent=None)
|
||
print 'default_conmnect is --> ' + self.center.default_connection
|
||
|
||
def create_display(self, parent):
|
||
self.display = wxPClient(parent=parent)
|
||
def set_display(self, which, display):
|
||
self.extra_display[which] = display
|
||
|
||
|
||
def msg(self, vars, mc, data, caller = None):
|
||
print_psyc(vars, mc, data, 'client')
|
||
parsedtext = parsetext(vars, mc,data)
|
||
#parsedtext = parsedtext.encode('iso-8859-15')
|
||
if mc == '_query_password':
|
||
if self.center.config['password'] != '':
|
||
mc = '_set_password'
|
||
vars = {'_password' : self.center.config['password']}
|
||
vars['_target'] = self.netname
|
||
data =''
|
||
self.sendmsg(vars, mc, data)
|
||
else:
|
||
self.extra_display['server'].append1("Please enter your password or choose a different nick if you don't know the password")
|
||
self.extra_display['server'].entry_box.SetValue('/password ')
|
||
elif mc == '_status_friends':
|
||
self.extra_display['server'].append1(parsedtext)
|
||
|
||
elif mc == '_error_invalid_password':
|
||
self.extra_display['server'].append1(parsedtext)
|
||
self.extra_display['server'].append1("Please enter your password or choose a different nick if you don't know the password")
|
||
self.extra_display['server'].entry_box.SetValue('/password ')
|
||
else:
|
||
self.extra_display['server'].append1(parsedtext)
|
||
|
||
def online(self):
|
||
self.center.connect(self.center.default_connection)
|
||
#mc = '_request_link'
|
||
#mmp = {}
|
||
#psyc = {}
|
||
#data =''
|
||
#mmp['_target'] = self.netname
|
||
|
||
#self.sendmsg(mmp, psyc, mc, data)
|
||
|
||
|