File: //usr/share/doc/jabberpy-0.5/examples/pygtkjab.py
#!/usr/bin/env python
#
# TODO:
# -- fix mass transport subscribe crash ??
# -- implement group chat
# -- catch errors better with dialog to show em.
#
import sys,string,os,re,time
import gtk, _gtk, GDK
# Change path so we find jabber libs strait from tarball
sys.path.insert(1, os.path.join(sys.path[0], '..'))
sys.path.insert(1, os.path.join(sys.path[0], '../util'))
import jabber
import sleepy
TRUE = 1
FALSE = 0
OK = 1
CANCEL = 2
## add a server name entry to the below ##
Known = {
'yahoo':
{ 'xpm' : 'an xpm path' },
'msn':
{ 'xpm' : 'info....'},
'icq':
{ 'xpm' : 'info....'},
}
def makeKnownNice(jid):
for known in Known.keys():
if re.match("^"+known+".*", jid.getDomain()):
if jid.getNode():
return jid.getNode()
else:
return known + " transport"
return str(jid)
def sort_jids(a,b):
if string.lower(str(a)) < string.lower(str(b)): return -1
if string.lower(str(a)) > string.lower(str(b)): return 1
return 0
class Tab:
def __init__(self, gui, title):
self._type = type
self._notebook = gui.notebook
self._title = title
self._id = None
self._box = gtk.GtkVBox()
self._main_callback = None
self._cb = None
self.cmap = gui.get_colormap()
self.cols={}
self.cols['blue'] = self.cmap.alloc('blue')
self.cols['red'] = self.cmap.alloc('red')
self.cols['black'] = self.cmap.alloc('black')
self.cols['green'] = self.cmap.alloc('green')
self.gui = gui
def getID(self): return self._id;
def setID(self,val): self._id = val;
def recieve(self,obj): pass
def setCallBack(self,cb): self._cb = cb
def getCallBack(self): return self._cb
def getData(self): pass
def setData(self,val): pass
def _addToNoteBook(self):
self._tab_label = gtk.GtkLabel(self._title)
self._tab_label.show()
self._notebook.append_page(self._box,self._tab_label)
def tabClicked(self, *args):
return gtk.FALSE
def highlight(self):
#style = _gtk.gtk_rc_get_style() # self._tab_label)
style = self._tab_label.get_style()
new_style = style.copy()
new_style.fg[0] = self.cols['blue']
self._tab_label.set_style(new_style)
def lowlight(self):
style = self._tab_label.get_style()
new_style = style.copy()
new_style.fg[0] = self.cols['black']
self._tab_label.set_style(new_style)
def getJID(self):
return None
def destroy(self,*args):
i = 0
for tab in self.gui._tabs:
if tab == self:
self._notebook.remove_page(i)
del(self.gui._tabs[i])
## self.__destroy__ ?
i=i+1
class Chat_Tab(Tab): ### Make bigger and Better !!!
def __init__(self, gui, jid, title='a tab'):
Tab.__init__(self, gui, title)
self._id = str(jid.getStripped())
self._scroll = gtk.GtkScrolledWindow()
self._txt = gtk.GtkText()
self._txt.set_word_wrap( gtk.TRUE )
self._scroll.add(self._txt)
self._scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self._box.pack_start(self._scroll, fill=gtk.TRUE, expand=gtk.TRUE)
self._hbox = gtk.GtkHBox()
self._entry = gtk.GtkEntry()
self._hbox.pack_start(self._entry, fill=gtk.TRUE, expand=gtk.TRUE)
self._send_button = gtk.GtkButton('send')
#self._send_button.connect('clicked', self._cb, self)
#self._entry.connect('activate', self._cb, self )
self._hbox.pack_end(self._send_button, fill=gtk.FALSE, expand=gtk.FALSE)
self._box.pack_end(self._hbox, fill=gtk.TRUE, expand=gtk.FALSE)
self._box.show_all()
self._addToNoteBook()
self._entry.grab_focus()
## this_tab.event_connected = 0 ??
def getJID(self):
return self._id
def recieve(self,obj):
if obj.getFrom().getStripped() == self._id:
if str(obj.__class__) == 'jabber.Message':
if obj.getError():
err_code = ''
if obj.getErrorCode(): err_code = obj.getErrorCode()
self._txt.insert(None,self.cols['red'], None,
"%s ( %s )" % (obj.getError(),
err_code) )
else:
self._txt.insert(None,self.cols['red'], None,
"<%s> " % obj.getFrom().getStripped())
self._txt.insert(None,None, None, "%s\n" % obj.getBody())
return TRUE
if str(obj.__class__) == 'jabber.Presence':
if obj.getType() != 'unavailable':
self._txt.insert(None,self.cols['green'], None,
"<%s> ( %s / %s )\n" %
( obj.getFrom().getStripped(),
obj.getStatus(), obj.getShow() ) )
else:
self._txt.insert(None,self.cols['green'], None,
"<%s> went offline\n" %
obj.getFrom().getStripped() )
return TRUE
return FALSE
def getData(self):
txt = self._entry.get_text()
self._entry.set_text('')
self._txt.insert(None,None,None, "<%s> %s\n" %
( self.gui.jabberObj.loggedin_jid.getStripped(), txt)
)
return txt
class Debug_Tab(Tab): ### Make bigger and Better !!!
def __init__(self, gui, title='DEBUG'):
Tab.__init__(self, gui, title)
self._id = "DEBUG"
self._scroll = gtk.GtkScrolledWindow()
self._txt = gtk.GtkText()
self._txt.set_word_wrap( gtk.TRUE )
self._scroll.add(self._txt)
self._scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self._box.pack_start(self._scroll, fill=gtk.TRUE, expand=gtk.TRUE)
self._hbox = gtk.GtkHBox()
self._box.show_all()
self._addToNoteBook()
## this_tab.event_connected = 0 ??
def getJID(self):
return self._id
def recieve(self,obj):
return TRUE
class Url_Tab(Tab): ### Make bigger and Better !!!
def __init__(self, gui):
Tab.__init__(self, gui, 'URLs')
self._id = 'URLs'
self._regexp = re.compile('(http://[^\s]+)', re.IGNORECASE)
self._scrolled_win = gtk.GtkScrolledWindow()
self._scrolled_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self._box.pack_start(self._scrolled_win)
self._list = gtk.GtkList()
self._list.set_selection_mode(gtk.SELECTION_BROWSE)
self._scrolled_win.add_with_viewport(self._list)
self._list.connect("select-child" , self.selectCB)
self._hbox = gtk.GtkHBox()
self._open_button = gtk.GtkButton('open')
self._hbox.pack_end(self._open_button, fill=gtk.FALSE,
expand=gtk.FALSE)
self._box.pack_end(self._hbox, fill=gtk.TRUE, expand=gtk.FALSE)
self._box.show_all()
self._addToNoteBook()
## this_tab.event_connected = 0 ??
def getJID(self):
return self._id
def recieve(self,obj):
if str(obj.__class__) == 'jabber.Message':
m = self._regexp.match(obj.getBody())
if m:
list_item = gtk.GtkListItem(m.group())
self._list.add(list_item)
list_item.show()
return TRUE
return FALSE
def selectCB(self, *args): pass
class Roster_Tab(Tab): ### Make bigger and Better !!!
def __init__(self, gui, title):
Tab.__init__(self, gui, title)
self._roster_selected = None
self._online_icon, self._online_mask = \
gtk.create_pixmap_from_xpm( gui.get_window(), None,"online.xpm" );
self._offline_icon, self._offline_mask = \
gtk.create_pixmap_from_xpm( gui.get_window(), None,"offline.xpm" );
self._pending_icon, self._pending_mask = \
gtk.create_pixmap_from_xpm( gui.get_window(), None,"pending.xpm" );
self._rows = []
self._scroll = gtk.GtkScrolledWindow()
self._ctree = gtk.GtkCTree(1,0)
self._ctree.set_column_width(0,200);
self._ctree.set_line_style(gtk.CTREE_LINES_NONE)
self._ctree.set_expander_style(gtk.CTREE_EXPANDER_CIRCULAR)
self._ctree.connect("select_row" , self.rosterSelectCB)
self.paint_tree()
self._scroll.add(self._ctree)
self._scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.FALSE)
self._box.pack_start(self._scroll, fill=gtk.TRUE, expand=gtk.TRUE)
self._hbox = gtk.GtkHBox()
self._box.pack_end(self._hbox, fill=gtk.TRUE, expand=gtk.FALSE)
self._box.show_all()
self._addToNoteBook()
def rosterSelectCB(self, *args):
self._roster_selected = self._ctree.get_row_data(int(args[1]))
if args[3].type == GDK._2BUTTON_PRESS:
self._cb()
def get_roster_selection(self):
return self._roster_selected
def recieve(self,obj):
if str(obj.__class__) != 'jabber.Message':
if str(obj.__class__) == 'jabber.Iq':
if obj.getQuery() == jabber.NS_ROSTER:
self.paint_tree() ## only paint if roster iq
else:
self.paint_tree() ## a presence
def paint_tree(self):
self._ctree.freeze()
self._ctree.clear()
self._online_node = self._ctree.insert_node(
None, None, ( 'online', ), 2,
None, None, None, None, gtk.FALSE,
gtk.TRUE )
self._offline_node = self._ctree.insert_node(
None, None, ( 'offline', ), 2,
None, None, None, None, gtk.FALSE,
gtk.TRUE )
self._pending_node = self._ctree.insert_node(
None, None, ( 'pending', ), 2,
None, None, None, None, gtk.FALSE,
gtk.TRUE )
_roster = self.gui.jabberObj.getRoster()
self._nodes = []
jids = _roster.getJIDs()
jids.sort(sort_jids)
for jid in jids:
attach_node = None
nice_name = makeKnownNice(jid)
show = ''
if _roster.getShow(jid): show = _roster.getShow(jid)
if _roster.getStatus(jid):
if show:
show = " ( %s / %s )" % ( show, _roster.getStatus(jid) )
else:
show = " ( %s )" % _roster.getStatus(jid)
nice_name = str("%s %s" % ( nice_name, show ))
if _roster.getOnline(jid) == 'online':
node =self._ctree.insert_node(
self._online_node, None, ( nice_name, )
, 2,
pixmap_closed = self._online_icon,
mask_closed = self._online_mask,
is_leaf=gtk.TRUE,
expanded=gtk.TRUE )
elif _roster.getOnline(jid) == 'offline':
node =self._ctree.insert_node(
self._offline_node, None, ( nice_name, )
, 2,
pixmap_closed = self._offline_icon,
mask_closed = self._offline_mask,
is_leaf=gtk.TRUE,
expanded=gtk.TRUE )
elif _roster.getOnline(jid) == 'pending':
node =self._ctree.insert_node(
self._pending_node, None, ( nice_name, )
, 2,
pixmap_closed = self._pending_icon,
mask_closed = self._pending_mask,
is_leaf=gtk.TRUE,
expanded=gtk.TRUE )
else:
pass
self._nodes.append(node)
self._ctree.node_set_row_data(node, str(jid))
self._ctree.thaw()
if self.gui._tabs and self != self.gui.getSelectedTab():
self.highlight()
class Logon_dialog(gtk.GtkWindow):
def __init__(self, master):
gtk.GtkWindow.__init__(self)
self.password = ''
self.username = ''
self.server = 'jabber.org'
self.done = None
self.connect("delete_event", self.delete_event)
self.master = master
self.vbox = gtk.GtkVBox(gtk.FALSE,5)
self.add(self.vbox)
self.frame_s = gtk.GtkFrame("Server to use")
self.table_s = gtk.GtkTable(1,6,gtk.FALSE)
self.server_lbl = gtk.GtkLabel('Server')
self.server_lbl.set_alignment(1,0.5)
self.server_entry = gtk.GtkEntry()
self.table_s.attach( self.server_lbl,
0,2,0,1,xpadding=3,ypadding=2)
self.table_s.attach( self.server_entry,
2,6,0,1,xpadding=3,ypadding=2)
self.frame_s.add(self.table_s)
self.vbox.pack_start(self.frame_s)
self.frame = gtk.GtkFrame("Have Account?")
self.table = gtk.GtkTable(6,6,gtk.FALSE)
self.username_lbl = gtk.GtkLabel('Username')
self.username_lbl.set_alignment(1,0.5)
self.password_lbl = gtk.GtkLabel('Password')
self.password_lbl.set_alignment(1,0.5)
self.username_entry = gtk.GtkEntry()
self.password_entry = gtk.GtkEntry()
self.password_entry.set_visibility(gtk.FALSE)
self.table.attach( self.username_lbl, 0,2,1,2,xpadding=3,ypadding=2)
self.table.attach( self.password_lbl, 0,2,2,3,xpadding=3,ypadding=2)
self.table.attach( self.username_entry, 2,6,1,2,xpadding=3,ypadding=2)
self.table.attach( self.password_entry, 2,6,2,3,xpadding=3,ypadding=2)
self.save_check = gtk.GtkCheckButton('Save Details')
self.table.attach( self.save_check, 3,6,4,5,xpadding=3,ypadding=2)
self.login_button = gtk.GtkButton('Login')
self.login_button.connect('clicked', self.login)
self.table.attach( self.login_button, 3,6,5,6,xpadding=5)
self.frame.add(self.table)
self.vbox.pack_start(self.frame)
self.frame_acc = gtk.GtkFrame("New User?")
self.table_acc = gtk.GtkTable(1,1,gtk.FALSE)
self.button_acc = gtk.GtkButton("Get an Account")
self.button_acc.connect('clicked', self.new_account)
self.table_acc.attach( self.button_acc, 0,1,0,1,xpadding=5,ypadding=5)
self.frame_acc.add(self.table_acc)
self.vbox.pack_end(self.frame_acc)
self.readRC()
self.username_entry.set_text(self.username)
self.password_entry.set_text(self.password)
self.server_entry.set_text(self.server)
self.vbox.show_all()
self.show()
self.set_modal(gtk.TRUE)
def login(self,*args):
self.password = self.password_entry.get_text()
self.username = self.username_entry.get_text()
self.server = self.server_entry.get_text()
self.done = gtk.TRUE
if self.save_check.get_active():
try:
rcfile = open(os.environ['HOME'] + "/.pyjab",'w')
except:
return
rcfile.write("%s\0%s\0%s\n" % (self.server, self.username, self.password))
rcfile.close()
else:
try: os.remove(os.environ['HOME'] + "/.pyjab")
except: pass # file dont exist, or I cant delete
def readRC(self):
try:
rcfile = open(os.environ['HOME'] + "/.pyjab",'r')
except:
return
self.save_check.set_active(gtk.TRUE)
data = (rcfile.readline().splitlines())[0]
self.server, self.username, self.password = data.split("\0")
rcfile.close()
return
def new_account(self,*args):
self.done = 2
def delete_event(self, *args):
gtk.mainquit()
sys.exit(0)
def close(self,*args):
self.hide()
del self
class New_ac_dialog(gtk.GtkWindow):
def __init__(self, master, jabber, agent=None):
gtk.GtkWindow.__init__(self)
self.connect("delete_event", self.delete_event)
self.master = master
self.jabber = jabber
self.done = None
self.agent = agent
self.vbox = gtk.GtkVBox(gtk.FALSE,5)
self.add(self.vbox)
self.frame = gtk.GtkFrame("New Account")
self.jabber.requestRegInfo(self.agent)
req = self.jabber.getRegInfo()
self.table = gtk.GtkTable(6,6,gtk.FALSE)
self.instr_lbl = gtk.GtkLabel(req[u'instructions'])
self.entrys = {}
i = 0
for info in req.keys():
if info != u'instructions' and \
info != u'key':
self.entrys[info] = {}
self.entrys[info]['lbl'] = gtk.GtkLabel(info)
self.entrys[info]['lbl'].set_alignment(1,0.5)
self.entrys[info]['entry'] = gtk.GtkEntry()
self.table.attach(
self.entrys[info]['lbl'], 0,2,1+i,2+i,
xpadding=3,ypadding=2)
self.table.attach(
self.entrys[info]['entry'], 2,6,1+i,2+i,
xpadding=3,ypadding=2)
i=i+1
self.reg_button = gtk.GtkButton('Register')
self.table.attach( self.reg_button, 2,6,0,1,xpadding=3,ypadding=2)
self.reg_button.connect('clicked', self.register)
self.frame.add(self.table)
self.vbox.pack_start(self.frame)
self.vbox.show_all()
self.show()
self.set_modal(gtk.TRUE)
def register(self,*args):
for info in self.entrys.keys():
self.jabber.setRegInfo( info,
self.entrys[info]['entry'].get_text() )
self.username = self.entrys['username']['entry'].get_text()
self.password = self.entrys['password']['entry'].get_text()
self.jabber.sendRegInfo(self.agent)
self.done = OK
def delete_event(win, event=None):
self.hide()
return gtk.TRUE
def close(self,*args):
self.hide()
del self
class Add_dialog(gtk.GtkDialog):
def __init__(self, master, jabberObj):
gtk.GtkDialog.__init__(self)
self.jid_str = None
self.done = None
self.connect("delete_event", self.delete_event)
self.master = master
self.jabber = jabberObj
if self.master:
self.set_transient_for(self.master)
self.set_usize(200,150)
self.table = gtk.GtkTable(5,2,gtk.FALSE)
self.jid_lbl = gtk.GtkLabel('JID')
self.jid_entry = gtk.GtkEntry()
self.table.attach( self.jid_lbl, 0,1,0,1)
self.table.attach( self.jid_entry, 1,2,0,1)
self.add_button = gtk.GtkButton('Add')
self.add_button.connect('clicked', self.add)
self.action_area.pack_start(self.add_button,expand=gtk.FALSE)
self.vbox.pack_start(self.table)
self.vbox.show_all()
self.action_area.show_all()
self.show()
self.set_modal(gtk.TRUE)
def add(self,*args):
self.done = self.jid_entry.get_text()
def delete_event(win, event=None):
self.hide()
self.done = 1
return gtk.FALSE
def close(self,*args):
self.hide()
del self
class Status_dialog(gtk.GtkDialog):
def __init__(self):
gtk.GtkDialog.__init__(self)
self.jid_str = None
self.done = None
self.type = 'available'
self.connect("delete_event", self.delete_event)
#self.master = master
#self.jabber = jabberObj
self.set_usize(200,150)
self.table = gtk.GtkTable(5,2,gtk.FALSE)
self.jid_lbl = gtk.GtkLabel('Status')
self.jid_entry = gtk.GtkEntry()
self.table.attach( self.jid_lbl, 0,1,0,1)
self.table.attach( self.jid_entry, 1,2,0,1)
self.add_button = gtk.GtkButton('Set')
self.add_button.connect('clicked', self.set)
self.action_area.pack_start(self.add_button,expand=gtk.FALSE)
self.avail_radio = gtk.GtkRadioButton(None, 'available')
self.unavail_radio = gtk.GtkRadioButton(self.avail_radio, 'unavailable')
self.avail_radio.connect('clicked', self.avail)
self.unavail_radio.connect('clicked', self.unavail)
self.avail_radio.set_active(gtk.TRUE)
self.table.attach( self.avail_radio, 0,2,1,2)
self.table.attach( self.unavail_radio, 0,2,2,3)
self.vbox.pack_start(self.table)
self.vbox.show_all()
self.action_area.show_all()
self.show()
self.set_modal(gtk.TRUE)
def avail(self, *args): self.type = None
def unavail(self, *args): self.type = 'unavailable'
def set(self,*args):
self.done = ( self.type , self.jid_entry.get_text() )
def delete_event(win, event=None):
self.hide()
self.done = 1
return gtk.FALSE
def close(self,*args):
self.hide()
del self
MSG_DIA_TYPE_OK = 0
MSG_DIA_TYPE_YESNO = 1
MSG_DIA_RET_OK = 1
MSG_DIA_RET_CANCEL = 2
class Msg_dialog(gtk.GtkDialog):
def __init__(self, master, msg, type = MSG_DIA_TYPE_OK ):
gtk.GtkDialog.__init__(self)
self.done = None
self.connect("delete_event", self.delete_event)
self.master = master
self.set_usize(200,150)
if self.master:
self.set_transient_for(self.master)
self.msg_lbl = gtk.GtkLabel(msg)
self.ok_button = gtk.GtkButton('Ok')
self.ok_button.connect('clicked', self.okay)
self.action_area.pack_start(self.ok_button,expand=gtk.FALSE)
if type == MSG_DIA_TYPE_YESNO:
self.cancel_button = gtk.GtkButton('Cancel')
self.cancel_button.connect('clicked', self.cancel)
self.action_area.pack_start(self.cancel_button,expand=gtk.FALSE)
self.vbox.pack_start(self.msg_lbl)
self.vbox.show_all()
self.action_area.show_all()
self.show()
self.set_modal(gtk.TRUE)
def okay(self,*args):
self.done = MSG_DIA_RET_OK
def cancel(self,*args):
self.done = MSG_DIA_RET_CANCEL
def delete_event(win, event=None):
self.hide()
self.done = MSG_DIA_RET_CANCEL
def close(self,*args):
self.hide()
del self
class Trans_dialog(gtk.GtkDialog):
def __init__(self, master, jabberObj ):
gtk.GtkDialog.__init__(self)
self.agents = jabberObj.requestAgents()
self.done = None
self.connect("delete_event", self.delete_event)
self.master = master
self.set_usize(200,150)
if self.master:
self.set_transient_for(self.master)
self.ok_button = gtk.GtkButton('Ok')
self.ok_button.connect('clicked', self.okay)
self.action_area.pack_start(self.ok_button,expand=gtk.FALSE)
self.cancel_button = gtk.GtkButton('Cancel')
self.cancel_button.connect('clicked', self.cancel)
self.action_area.pack_start(self.cancel_button,expand=gtk.FALSE)
self.scrolled_win = gtk.GtkScrolledWindow()
self.scrolled_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.vbox.pack_start(self.scrolled_win)
self.list = gtk.GtkList()
self.list.set_selection_mode(gtk.SELECTION_BROWSE)
self.scrolled_win.add_with_viewport(self.list)
for i in self.agents.keys():
if self.agents[i].has_key('transport'):
list_item = gtk.GtkListItem(self.agents[i]['name'])
list_item.set_data('jid', i)
self.list.add(list_item)
list_item.show()
self.list.connect("select-child" , self.selectCB)
self.vbox.pack_start(self.scrolled_win)
self.vbox.show_all()
self.action_area.show_all()
self.show()
self.selected = None
self.set_modal(gtk.TRUE)
def selectCB(self, *args):
self.selected = args[1].get_data('jid')
def okay(self,*args):
self.done = OK
def cancel(self,*args):
self.done = CANCEL
def delete_event(win, event=None):
self.hide()
self.done = MSG_DIA_RET_CANCEL
def close(self,*args):
self.hide()
del self
class mainWindow(gtk.GtkWindow): # Usual Base
def __init__(self, title='pygtk app', jabberObj=None,
width=None, height=None):
gtk.GtkWindow.__init__(self)
self.set_title(title)
if width is None:
if gtk.screen_width() > 300: ## Fit the display
width = 320
height = 200
else:
width = 240
height = 300
self._tabs = []
self.cols = {};
self.jabberObj = jabberObj
self.roster_selected = None
self.set_usize(width,height)
self.connect("delete_event", self.quit)
self.box = gtk.GtkVBox()
self.add(self.box)
self.box.show()
self.tbox = gtk.GtkHBox()
self.checkItemCalled = 0
self.init_menu()
self.init_status_select()
self.close_but = gtk.GtkButton('X')
self.close_but.connect("clicked", self.closeTabCB);
self.close_but.show()
self.tbox.pack_end(self.close_but, fill=gtk.FALSE, expand=gtk.FALSE)
self.tbox.show()
self.box.pack_start(self.tbox, fill=gtk.FALSE, expand=gtk.FALSE)
self.notebook = gtk.GtkNotebook()
self.notebook.set_tab_pos (gtk.POS_BOTTOM);
self.notebook.set_scrollable( gtk.TRUE )
self.notebook.connect('switch_page', self.notebook_switched)
self.box.pack_end(self.notebook, fill=gtk.TRUE, expand=gtk.TRUE)
self._tabs.append( Roster_Tab(self, 'roster') )
self.notebook.show()
self.show()
def init_status_select(self):
ag = gtk.GtkAccelGroup()
self.itemsel = gtk.GtkItemFactory(gtk.GtkOptionMenu, "<select>", ag)
self.add_accel_group(ag)
self.itemsel.create_items([
('/Available', None, self.statusCB, 1, ''),
('/Unavailable', None, self.statusCB, 0, ''),
('/Custom', None, self.custstatusCB, 0, ''),
])
self.status_select = self.itemsel.get_widget('<select>')
self.tbox.pack_start(self.status_select,
fill=gtk.TRUE, expand=gtk.TRUE)
self.status_select.show()
def init_menu(self):
ag = gtk.GtkAccelGroup()
self.itemf = gtk.GtkItemFactory(gtk.GtkMenuBar, "<main>", ag)
self.add_accel_group(ag)
self.itemf.create_items([
('/File', None, None, 0, '<Branch>'),
('/File/Exit', None, self.quit, 0, ''),
('/Tools', None, None, 0, '<Branch>'),
('/Tools/Chat', None, self.jabberObj.addChatTabViaRoster,
1, ''),
('/Tools/sep1', None, None, 0, '<Separator>'),
('/Tools/Add', None, self.addCB, 1, ''),
('/Tools/Remove', None, self.removeCB, 0, ''),
('/Tools/Status/Available', None, self.statusCB, 1, '<CheckItem>'),
('/Tools/Status/Unavailable', None, self.statusCB, 0, '<CheckItem>'),
('/Tools/Status/Custom', None, self.custstatusCB, 0, ''),
('/Tools/sep2', None, None, 0, '<Separator>'),
('/Tools/Transports', None, self.transCB, 0, ''),
('/Tools/Tabs/Rotate', None, self.rotateTabCB, 0, ''),
('/Tools/Tabs/Url Grabber', None, self.urlTabCB, 0, ''),
('/Tools/Tabs/Debug', None, self.debugTabCB, 0, ''),
('/Help', None, None, 0, '<Branch>') ,
('/Help/About', None, self.infoCB, 0, '')
])
self.menubar = self.itemf.get_widget('<main>')
self.itemf.get_widget( '/Tools/Status/Available' ).set_active(gtk.TRUE)
self.tbox.pack_start(self.menubar, fill=gtk.TRUE, expand=gtk.TRUE)
self.menubar.show()
def statusCB(self,action,widget):
if self.checkItemCalled == 1: ## Make sure set_active does not
return ## recall the callback
self.checkItemCalled = 1;
## More nasty workarounds for ItemFactory Radiobutton problems
for path in [ '/Tools/Status/Available', '/Tools/Status/Unavailable' ]:
if widget != self.itemf.get_widget( path ):
self.itemf.get_widget( path ).set_active(gtk.FALSE)
self.checkItemCalled = 0;
if action == 1:
# available
self.jabberObj.presence_details = [ 'available', None ]
pres = jabber.Presence()
else:
self.jabberObj.presence_details = [ 'unavailable', None ]
pres = jabber.Presence(type='unavailable')
self.jabberObj.send(pres)
def custstatusCB(self, *args):
dia = Status_dialog()
while dia.done is None:
self.jabberObj.process()
type, show = dia.done
pres = jabber.Presence(type=type)
pres.setShow(show)
self.jabberObj.presence_details = [ type, show ]
self.jabberObj.send(pres)
dia.close()
def urlTabCB(self, *args):
url_tab = self.findTab( 'URLs' )
if url_tab:
url_tab.destroy()
else:
self._tabs.append( Url_Tab(self) )
def debugTabCB(self, *args):
dbg_tab = self.findTab( 'DEBUG' )
if dbg_tab:
dbg_tab.destroy()
else:
self._tabs.append( Debug_Tab(self) )
def rotateTabCB(self, *args):
if self.notebook.get_tab_pos() == gtk.POS_BOTTOM:
self.notebook.set_tab_pos( gtk.POS_LEFT )
else:
self.notebook.set_tab_pos( gtk.POS_BOTTOM )
def transCB(self, *args):
trans_dia = Trans_dialog(None, self.jabberObj)
while (trans_dia.done is None):
self.jabberObj.process()
if trans_dia.done == OK and trans_dia.selected:
names = string.split(trans_dia.selected, '.')
agent = names[0]
trans_dia.close()
new_acc_dia = New_ac_dialog(None, self.jabberObj, agent=agent)
while (new_acc_dia.done is None):
self.jabberObj.process()
new_acc_dia.close()
return
trans_dia.close()
def addCB(self, *args):
add_dia = Add_dialog(self, self.jabberObj )
while (add_dia.done is None):
self.jabberObj.process()
self.jabberObj.send(jabber.Presence(add_dia.done, 'subscribe'))
add_dia.close()
def removeCB(self,*args):
who = self.getTab(0).get_roster_selection()
if not who: return
msg_dia = Msg_dialog(None,
"unsubscribe %s ?" % (who),
MSG_DIA_TYPE_YESNO
)
while (msg_dia.done is None): self.jabberObj.process()
if (msg_dia.done == MSG_DIA_RET_OK):
self.jabberObj.send(jabber.Presence(to=who, type='unsubscribe'))
msg_dia.close()
def closeTabCB(self, *args):
if self.notebook.get_current_page():
self.getSelectedTab().destroy()
def findCB(self, *args): pass
def infoCB(self, *args): pass
def handle_switch(self,*args):
tab_no = self.notebook.get_current_page()
self.getTab(tab_no).lowlight()
def notebook_switched(self, *args):
gtk.idle_add(self.handle_switch)
def findTab(self,id):
for tab in self._tabs:
if tab._id == id: return tab
return None
def getTabs(self):
return self._tabs
def getTab(self,val):
return self._tabs[val]
def getSelectedTab(self):
return self._tabs[self.notebook.get_current_page()]
def addTab(self,tab_obj):
self._tabs.append( tab_obj )
return tab_obj
def removeTab(self,tab):
if type(tab) == type(1):
self.notebook.remove_tab(tab)
del self._tabs[tab]
else:
print "not yet implemented"
def quit(self, *args):
#gtk.mainquit()
sys.exit(0)
class jabberClient(jabber.Client):
def __init__(self):
self.sleeper = None
self.sleeper_state = None
self.gui = None
not_connected = 1
while not_connected:
login_dia = Logon_dialog(None)
while (login_dia.done is None):
while gtk.events_pending(): gtk.mainiteration()
login_dia.close()
server = login_dia.server
jabber.Client.__init__(self,host=server,debug=0)
try:
self.connect()
except:
msg_dia = Msg_dialog(None, "Couldnt connect to "+server)
while (msg_dia.done is None):
while gtk.events_pending(): gtk.mainiteration()
msg_dia.close()
sys.exit(0)
else:
print "connected!"
if (login_dia.done == 2):
new_acc_dia = New_ac_dialog(None, self)
while (new_acc_dia.done is None):
self.process()
new_acc_dia.close()
username = new_acc_dia.username
password = new_acc_dia.password
else:
username = login_dia.username
password = login_dia.password
resource = 'pygtkjab'
print "logging in"
if self.auth(username,password,resource):
not_connected = 0
else:
msg_dia = Msg_dialog(None, self.lastErr)
while (msg_dia.done is None):
while gtk.events_pending(): gtk.mainiteration()
msg_dia.close()
#print "eek -> ", self.lastErr, self.lastErrCode
sys.exit(1)
self.loggedin_jid = jabber.JID( node = username, domain = server,
resource = resource );
self.presence_details = [ 'available', None ]
Known[server] = { 'xpm':'something' }
## Build the roster Tab ##
self.roster = []
r = self.requestRoster()
self.gui = mainWindow("jabber app",jabberObj=self)
self.gui.getTab(0)._cb = self.addChatTabViaRoster;
self.sendInitPresence()
self._unsub_lock = 0 ## hack to fix unsubscribe wierdo bug
self._pres_queue = []
self.sleeper = sleepy.Sleepy()
def addToRoster(self, *args): pass
def dispatch_to_gui(self,obj):
recieved = None
for t in self.gui.getTabs():
if t.recieve(obj): recieved = t
return recieved
def addChatTabViaRoster(self, *args):
jid_raw = self.gui.getTab(0).get_roster_selection()
if jid_raw:
jid = jabber.JID(jid_raw)
i = 0
for t in self.gui.getTabs():
if t.getJID() == jid.getStripped():
self.gui.notebook.set_page(i)
return
i=i+1
self.gui.addTab( Chat_Tab(self.gui, jid, makeKnownNice(jid) ) )
self.gui.getTab(-1)._send_button.connect('clicked',
self.messageSend,
self.gui.getTab(-1) )
self.gui.getTab(-1)._entry.connect('activate',
self.messageSend,
self.gui.getTab(-1) )
self.gui.notebook.set_page(i)
def messageSend(self, *args):
tab = args[-1]
msg = tab.getData()
msg_obj = jabber.Message(tab._id, msg)
msg_obj.setType('chat')
self.send(msg_obj)
def messageHandler(self, msg_obj):
tab = self.dispatch_to_gui(msg_obj)
if tab is None:
self.gui.addTab(
Chat_Tab(self.gui, msg_obj.getFrom(),
makeKnownNice(msg_obj.getFrom()) )
).recieve(msg_obj)
self.gui._tabs[-1]._send_button.connect('clicked',
self.messageSend,
self.gui._tabs[-1] )
self.gui.getTab(-1)._entry.connect('activate',
self.messageSend,
self.gui.getTab(-1) )
self.gui._tabs[-1].highlight()
else:
if tab != self.gui.getSelectedTab():
tab.highlight()
def presenceHandler(self, prs_obj):
type = prs_obj.getType()
who = prs_obj.getFrom().getStripped()
if type == 'subscribe':
msg_dia = Msg_dialog(None,
"subscribe request from %s" % (who),
MSG_DIA_TYPE_YESNO
)
while (msg_dia.done is None): self.process()
if (msg_dia.done == MSG_DIA_RET_OK):
self.send(jabber.Presence(to=who, type='subscribed'))
if who not in self.getRoster().getJIDs() or \
self.getRoster().getSub(who) != 'both':
self.send(jabber.Presence(to=who, type='subscribe'))
msg_dia.close()
elif type == 'unsubscribe' and not self._unsub_lock:
self._unsub_lock = 1 ## HACK !
msg_dia = Msg_dialog(None,
"unsubscribe request from %s" % (who),
MSG_DIA_TYPE_YESNO
)
while (msg_dia.done is None): self.process()
if (msg_dia.done == MSG_DIA_RET_OK):
self.send(jabber.Presence(to=who, type='unsubscribed'))
msg_dia.close()
else: pass
self.dispatch_to_gui(prs_obj)
self._unsub_lock = 0
def iqHandler(self, iq_obj):
self.dispatch_to_gui(iq_obj)
def process(self,time=0.1):
while gtk.events_pending(): gtk.mainiteration()
jabber.Client.process(self,time)
if self.sleeper:
state_pres = None
self.sleeper.poll()
state = self.sleeper.getState()
if state != self.sleeper_state:
if state == sleepy.STATE_WOKEN:
state_pres = jabber.Presence(type='available')
state_pres.setStatus('online')
state_pres.setShow('')
if state == sleepy.STATE_SLEEPING:
state_pres = jabber.Presence(type='available')
state_pres.setStatus('away')
state_pres.setShow('Away from computer')
if state_pres: self.send(state_pres)
self.sleeper_state = state
def log(self, data, inout=''):
## we overide xmlstreams log method with our own
if self.gui:
dbg_tab = self.gui.findTab( 'DEBUG' )
if dbg_tab:
dbg_tab._txt.insert(None, None, None, "%s - %s - %s\n" % \
(time.asctime(time.localtime(time.time())), inout, data ) )
def main():
# pass args to jabberClient object
# if -f exists mkfifo named with f param, open for writing ( r+ )
# launcher will open this for reading after forking the app
# app will then pipe messages to it
s = jabberClient()
while(1): s.process()
if __name__ == "__main__":
main()