pubsubclient: d41e36268cb237a816b2c5532e33bb594e510413

     1: import time
     2: import pubsubclient
     3: from pubsubclient import Node, Server, JID
     4: import pygtk
     5: import gtk
     6: import gobject
     7: from kiwi.ui.objectlist import Column, ObjectTree, ObjectList
     8: 
     9: class Window(object):
    10: 	"""This is the browser application."""
    11: 
    12: 	def __init__(self):
    13: 		## FIXME: The GUI should appear straight away, connecting should
    14: 		## happen after!
    15: 		# Set up the main window
    16: 		self.window = gtk.Window()
    17: 		self.window.set_title("PubSub Browser")
    18: 		self.window.set_default_size(400, 400)
    19: 		self.window.connect("destroy", self.quit)
    20: 
    21: 		# Divide it vertically
    22: 		self.vbox = gtk.VBox()
    23: 		self.window.add(self.vbox)
    24: 
    25: 		# This holds the location entry and the Get button
    26: 		self.top_box = gtk.HBox()
    27: 		self.vbox.pack_start(self.top_box, expand=False)
    28: 
    29: 		self.location_label = gtk.Label("Server:")
    30: 		self.top_box.pack_start(self.location_label, expand=False)
    31: 
    32: 		# This is where the server location is given
    33: 		self.location_entry = gtk.Entry()
    34: 		self.top_box.pack_start(self.location_entry)
    35: 
    36: 		# This button run get_button_released to fetch the server's nodes
    37: 		self.get_button = gtk.Button(label="Get")
    38: 		self.get_button.connect("released", self.get_button_released)
    39: 		self.top_box.pack_end(self.get_button, expand=False)
    40: 
    41: 		# Draw the tree using Kiwi, since plain GTK is a pain :P
    42: 
    43: 		# The attribute is the data, ie. a Column looking for attribute
    44: 		# "foo", when appended by an object bar, will show bar.foo
    45: 
    46: 		# We can put multiple things into a column (eg. an icon and a
    47: 		# label) by making 2 columns and passing the first to the second
    48: 		self.tree_columns = [\
    49: 			Column(attribute='icon', title='Nodes', use_stock=True, \
    50: 			justify=gtk.JUSTIFY_LEFT, icon_size=gtk.ICON_SIZE_MENU), \
    51: 			Column(attribute='name', justify=gtk.JUSTIFY_LEFT, column='icon')]
    52: 		self.tree_columns[0].expand = False
    53: 		self.tree_columns[1].expand = False
    54: 		self.tree_view = ObjectTree(self.tree_columns)
    55: 		self.tree_view.connect("selection-changed", self.selection_changed)
    56: 		self.vbox.pack_start(self.tree_view)
    57: 
    58: 		# This holds the Add button and the Delete button
    59: 		self.bottom_box = gtk.HBox()
    60: 		self.vbox.pack_end(self.bottom_box, expand=False)
    61: 
    62: 		# Make the Delete button, which runs the delete_button_released method
    63: 		self.delete_button = gtk.Button(stock=gtk.STOCK_REMOVE)
    64: 		try:
    65: 			# Attempt to change the label of the stock button
    66: 			delete_label = self.delete_button.get_children()[0]
    67: 			delete_label = delete_label.get_children()[0].get_children()[1]
    68: 			delete_label = delete_label.set_label("Delete Selection")
    69: 		except:
    70: 			# If it fails then just go back to the default
    71: 			self.delete_button = gtk.Button(stock=gtk.STOCK_REMOVE)
    72: 		self.delete_button.connect("released", self.delete_button_released)
    73: 		self.delete_button.set_sensitive(False)
    74: 		self.bottom_box.pack_start(self.delete_button, expand=True)
    75: 
    76: 		# Make the Properties button, which runs the properties_button_released method
    77: 		self.properties_button = gtk.Button(stock=gtk.STOCK_PROPERTIES)
    78: 		try:
    79: 			# Attempt to change the label of the stock button
    80: 			properties_label = self.properties_button.get_children()[0]
    81: 			properties_label = properties_label.get_children()[0].get_children()[1]
    82: 			properties_label = properties_label.set_label("Node Properties...")
    83: 		except:
    84: 			# If it fails then just go back to the default
    85: 			self.properties_button = gtk.Button(stock=gtk.STOCK_PROPERTIES)
    86: 		self.properties_button.connect("released", self.properties_button_released)
    87: 		self.properties_button.set_sensitive(False)
    88: 		self.bottom_box.pack_start(self.properties_button, expand=True)
    89: 
    90: 		# Make the Add button, which runs the add_button_released method
    91: 		self.add_button = gtk.Button(stock=gtk.STOCK_ADD)
    92: 		try:
    93: 			# Attempt to change the label of the stock button
    94: 			add_label = self.add_button.get_children()[0]
    95: 			add_label = add_label.get_children()[0].get_children()[1]
    96: 			add_label = add_label.set_label("Add Child...")
    97: 		except:
    98: 			# If it fails then just go back to the default
    99: 			self.add_button = gtk.Button(stock=gtk.STOCK_ADD)
   100: 		self.add_button.connect("released", self.add_button_released)
   101: 		self.add_button.set_sensitive(False)
   102: 		self.bottom_box.pack_end(self.add_button, expand=True)
   103: 
   104: 		# This handles our XMPP connection. Feel free to change the JID
   105: 		# and password
   106: 		self.client = pubsubclient.PubSubClient("test1@localhost", "test")
   107: 
   108: 		# Using the tree to store everything seems to have a few
   109: 		# glitches, so we use a regular list as our definitive memory
   110: 		self.known = []
   111: 
   112: 	def selection_changed(self, list, object):
   113: 		self.add_button.set_sensitive(True)
   114: 		if type(object) == type(Node()):
   115: 			self.delete_button.set_sensitive(True)
   116: 			self.properties_button.set_sensitive(True)
   117: 		elif type(object) == type(Server()):
   118: 			self.delete_button.set_sensitive(False)
   119: 			self.properties_button.set_sensitive(False)
   120: 
   121: 	def get_button_released(self, arg):
   122: 		"""This is run when the Get button is pressed. It adds the given
   123: 		server to the tree and runs get_nodes with that server."""
   124: 		listed_server = False		# Assume this server is not listed
   125: 		# Check every row of the tree to see if it matches given server
   126: 		for known_server in self.tree_view:
   127: 			if type(known_server) == type(Server()) and \
   128: 				self.location_entry.get_text() == str(known_server):
   129: 				listed_server = True		# True if server is listed
   130: 		# If we didn't find the server in the tree then add it
   131: 		if not listed_server:
   132: 			server = Server(name=self.location_entry.get_text())
   133: 			server.icon = gtk.STOCK_NETWORK
   134: 			self.tree_view.append(None, server)
   135: 			self.known.append(server)
   136: 		# Get the PubSub nodes on this server
   137: 		self.client.get_nodes(self.location_entry.get_text(), None, return_function=self.handle_incoming)
   138: 
   139: 	def handle_incoming(self, nodes):
   140: 		# Go through each new node
   141: 		for node in nodes:
   142: 			# Assume we do not already know about this node
   143: 			node_is_known = False
   144: 			# Go through each node that we know about
   145: 			for known_entry in self.known:
   146: 				# See if this node is the same as the known node being checked
   147: 				if known_entry.name == node.name:	## FIXME: Needs to check server
   148: 					node_is_known = True
   149: 			if not node_is_known:
   150: 				parent = None
   151: 				for known_entry in self.known:
   152: 					if known_entry.name == node.parent.name:		## FIXME: Needs to check server
   153: 						parent = known_entry
   154: 
   155: 				self.known.append(node)
   156: 				self.tree_view.append(parent, node)
   157: 
   158: 				node.get_information(self.client, self.handle_information)
   159: 
   160: 			node.get_sub_nodes(self.client, self.handle_incoming)
   161: 
   162: 	def handle_information(self, node):
   163: 		known = False
   164: 		if node.type == 'leaf':
   165: 			if node.name is not None and node.server is not None:
   166: 				for known_entry in self.known:
   167: 					if known_entry.name == node.name:
   168: 						known_entry.set_type('leaf')
   169: 						known_entry.icon = gtk.STOCK_FILE
   170: 		elif node.type == 'collection':
   171: 			if node.name is not None and node.server is not None:
   172: 				for known_entry in self.known:
   173: 					if known_entry.name == node.name and known_entry.server == node.server:
   174: 						known_entry.set_type('collection')
   175: 						known_entry.icon = gtk.STOCK_DIRECTORY
   176: 			node.get_sub_nodes(self.client, self.handle_incoming)
   177: 
   178: 	def handle_node_creation(self, return_value):
   179: 		if return_value == 0:
   180: 			self.tree_view.get_selected().get_sub_nodes(self.client, self.handle_incoming)
   181: 		else:
   182: 			print return_value
   183: 
   184: 	def delete_button_released(self, args):
   185: 		to_delete = self.tree_view.get_selected()
   186: 		if type(to_delete) == type(Node()):
   187: 			self.client.delete_a_node(to_delete.server, str(to_delete), return_function=self.handle_deleted)
   188: 
   189: 	def handle_deleted(self, return_value):
   190: 		if return_value == 0:
   191: 			deleted = self.tree_view.get_selected()
   192: 			self.tree_view.remove(deleted)
   193: 			self.known.remove(deleted)
   194: 		else:
   195: 			print return_value
   196: 
   197: 	def add_button_released(self, args):
   198: 		self.add_window = {}
   199: 		self.add_window["parent"] = self.tree_view.get_selected()
   200: 		self.add_window["window"] = gtk.Window()
   201: 		self.add_window["window"].set_title("Add new node to " + self.add_window["parent"].name)
   202: 		self.add_window["vbox"] = gtk.VBox()
   203: 		self.add_window["window"].add(self.add_window["vbox"])
   204: 
   205: 		self.add_window["top_box"] = gtk.HBox()
   206: 		self.add_window["vbox"].pack_start(self.add_window["top_box"], expand=False)
   207: 		self.add_window["name_label"] = gtk.Label("Name:")
   208: 		self.add_window["name_entry"] = gtk.Entry()
   209: 		self.add_window["top_box"].pack_start(self.add_window["name_label"], expand=False)
   210: 		self.add_window["top_box"].pack_end(self.add_window["name_entry"], expand=True)
   211: 
   212: 		self.add_window["bottom_box"] = gtk.HBox()
   213: 		self.add_window["vbox"].pack_end(self.add_window["bottom_box"], expand=False)
   214: 		self.add_window["add_button"] = gtk.Button(stock=gtk.STOCK_ADD)
   215: 		self.add_window["add_button"].connect("released", self.add_add_released)
   216: 		self.add_window["bottom_box"].pack_end(self.add_window["add_button"], expand=False)
   217: 
   218: 		self.add_window["middle_box"] = gtk.HBox()
   219: 		self.add_window["vbox"].pack_end(self.add_window["middle_box"], expand=False)
   220: 		self.add_window["type_label"] = gtk.Label("Type:")
   221: 		self.add_window["type_select"] = gtk.combo_box_new_text()
   222: 		self.add_window["type_select"].append_text("Leaf")
   223: 		self.add_window["type_select"].append_text("Collection")
   224: 		self.add_window["middle_box"].pack_start(self.add_window["type_label"], expand=False)
   225: 		self.add_window["middle_box"].pack_end(self.add_window["type_select"], expand=True)
   226: 
   227: 		self.add_window["window"].show_all()
   228: 
   229: 	def add_add_released(self, args):
   230: 		name = self.add_window["name_entry"].get_text()
   231: 		node_type = self.add_window["type_select"].get_active_text()
   232: 		parent = self.add_window["parent"]
   233: 		self.add_node(name, node_type, parent)
   234: 		self.add_window["window"].destroy()
   235: 		del(self.add_window)
   236: 
   237: 	def add_node(self, name, node_type, parent):
   238: 		"""Request a new child node of parent. For top-level a node
   239: 		parent should be a Server. node_type is either "leaf" or
   240: 		"collection"."""
   241: 		# This half runs if the parent is a Server
   242: 		if type(parent) == type(pubsubclient.Server()):
   243: 			# Request a top-level leaf node
   244: 			if node_type == 'Leaf':
   245: 				self.client.get_new_leaf_node(parent, \
   246: 					self.add_window["name_entry"].get_text(), None, None, return_function=self.handle_node_creation)
   247: 			# Request a top-level collection node
   248: 			elif node_type == 'Collection':
   249: 				self.client.get_new_collection_node(parent, \
   250: 					self.add_window["name_entry"].get_text(), None, None, return_function=self.handle_node_creation)
   251: 
   252: 		# This half runs if the parent is a Node
   253: 		elif type(parent) == type(pubsubclient.Node()):
   254: 			# Request a child leaf node
   255: 			if node_type == 'Leaf':
   256: 				self.client.get_new_leaf_node(parent.server, \
   257: 					self.add_window["name_entry"].get_text(), parent, None, return_function=self.handle_node_creation)
   258: 			# Request a child collection node
   259: 			elif node_type == 'Collection':
   260: 				self.client.get_new_collection_node(parent.server, \
   261: 					self.add_window["name_entry"].get_text(), parent, None, return_function=self.handle_node_creation)
   262: 
   263: 	def properties_button_released(self, args):
   264: 		## FIXME: This should allow multiple properties windows to be open at once
   265: 		# Setup a window containing a notebook
   266: 		self.properties_window = {}
   267: 		self.properties_window["node"] = self.tree_view.get_selected()
   268: 		self.properties_window["window"] = gtk.Window()
   269: 		self.properties_window["window"].set_title("Properties of " + str(self.properties_window["node"]))
   270: 		self.properties_window["window"].set_default_size(350, 450)
   271: 		self.properties_window["notebook"] = gtk.Notebook()
   272: 		self.properties_window["window"].add(self.properties_window["notebook"])
   273: 
   274: 		# Add the Metadata page
   275: 		self.properties_window["metadata_page"] = gtk.VBox()
   276: 		self.properties_window["metadata_label"] = gtk.Label("Metadata")
   277: 		self.properties_window["notebook"].append_page(self.properties_window["metadata_page"], tab_label=self.properties_window["metadata_label"])
   278: 
   279: 		# Add the Affiliations page
   280: 		self.properties_window["affiliations_page"] = gtk.VBox()
   281: 		self.properties_window["affiliations_label"] = gtk.Label("Affiliations")
   282: 		self.properties_window["notebook"].append_page(self.properties_window["affiliations_page"], tab_label=self.properties_window["affiliations_label"])
   283: 
   284: 		node = self.tree_view.get_selected()
   285: 		node.get_information(self.client, self.information_received)
   286: 		node.request_all_affiliated_entities(self.client, return_function=self.properties_received)
   287: 
   288: 	def information_received(self, info_dict):
   289: 		# Generate the contents of the Metadata page
   290: 		## FIXME: It would be awesome if this were generated automatically from what is found :)
   291: 		# The Name entry
   292: 		self.properties_window["name_box"] = gtk.HBox()
   293: 		self.properties_window["metadata_page"].pack_start(self.properties_window["name_box"], expand=False)
   294: 		self.properties_window["name_label"] = gtk.Label("Name:")
   295: 		self.properties_window["name_box"].pack_start(self.properties_window["name_label"], expand=False)
   296: 		self.properties_window["name_entry"] = gtk.Entry()
   297: 		self.properties_window["name_entry"].set_text(str(self.properties_window["node"]))		# Default to Node's name
   298: 		self.properties_window["name_box"].pack_start(self.properties_window["name_entry"], expand=True)
   299: 		self.properties_window["name_set"] = gtk.Button(label="Set")
   300: 		self.properties_window["name_set"].connect("released", self.set_name)
   301: 		self.properties_window["name_box"].pack_end(self.properties_window["name_set"], expand=False)
   302: 
   303: 		# The Title entry
   304: 		## FIXME: This should default to the node's title
   305: 		self.properties_window["title_box"] = gtk.HBox()
   306: 		self.properties_window["metadata_page"].pack_start(self.properties_window["title_box"], expand=False)
   307: 		self.properties_window["title_label"] = gtk.Label("Title:")
   308: 		self.properties_window["title_box"].pack_start(self.properties_window["title_label"], expand=False)
   309: 		self.properties_window["title_entry"] = gtk.Entry()
   310: 		self.properties_window["title_box"].pack_start(self.properties_window["title_entry"], expand=True)
   311: 		self.properties_window["title_set"] = gtk.Button(label="Set")
   312: 		self.properties_window["title_set"].connect("released", self.set_title)
   313: 		self.properties_window["title_box"].pack_end(self.properties_window["title_set"], expand=False)
   314: 
   315: 	def properties_received(self, affiliation_dictionary):
   316: 		# Add a warning about affiliation status
   317: 		self.properties_window["warning_label"] = gtk.Label("Note that a Jabber ID can only be in one state at a time. Adding a Jabber ID to a category will remove it from the others. There must always be at least one owner.")
   318: 		self.properties_window["warning_label"].set_line_wrap(True)
   319: 		self.properties_window["affiliations_page"].pack_start(self.properties_window["warning_label"], expand=False)
   320: 
   321: 		# Owners frame
   322: 		self.properties_window["owners_frame"] = gtk.Frame("Owners")
   323: 		self.properties_window["affiliations_page"].pack_start(self.properties_window["owners_frame"], expand=True)
   324: 		self.properties_window["owners_box"] = gtk.HBox()
   325: 		self.properties_window["owners_frame"].add(self.properties_window["owners_box"])
   326: 
   327: 		# Owners list
   328: 		self.properties_window["owners_column"] = Column(attribute="name", title="Jabber ID")
   329: 		self.properties_window["owners"] = ObjectList([self.properties_window["owners_column"]])
   330: 		self.properties_window["owners_box"].pack_start(self.properties_window["owners"], expand=True)
   331: 
   332: 		# Add Owner button
   333: 		self.properties_window["owners_buttons"] = gtk.VBox()
   334: 		self.properties_window["owners_box"].pack_end(self.properties_window["owners_buttons"], expand=False)
   335: 		self.properties_window["add_owner"] = gtk.Button(stock=gtk.STOCK_ADD)
   336: 		try:
   337: 			# Attempt to change the label of the stock button
   338: 			label = self.properties_window["add_owner"].get_children()[0]
   339: 			label = label.get_children()[0].get_children()[1]
   340: 			label = label.set_label("Add...")
   341: 		except:
   342: 			# If it fails then just go back to the default
   343: 			self.properties_window["add_owner"] = gtk.Button(stock=gtk.STOCK_ADD)
   344: 		self.properties_window["add_owner"].connect("released", self.add_owner)
   345: 		self.properties_window["owners_buttons"].pack_start(self.properties_window["add_owner"], expand=False)
   346: 
   347: 		# Remove Owner button
   348: 		self.properties_window["remove_owner"] = gtk.Button(stock=gtk.STOCK_REMOVE)
   349: 		self.properties_window["remove_owner"].connect("released", self.remove_owner)
   350: 		self.properties_window["owners_buttons"].pack_end(self.properties_window["remove_owner"], expand=False)
   351: 
   352: 		# Publishers frame
   353: 		self.properties_window["publishers_frame"] = gtk.Frame("Publishers")
   354: 		self.properties_window["affiliations_page"].pack_start(self.properties_window["publishers_frame"], expand=True)
   355: 		self.properties_window["publishers_box"] = gtk.HBox()
   356: 		self.properties_window["publishers_frame"].add(self.properties_window["publishers_box"])
   357: 
   358: 		# Add Publisher button
   359: 		self.properties_window["publishers_buttons"] = gtk.VBox()
   360: 		self.properties_window["publishers_box"].pack_end(self.properties_window["publishers_buttons"], expand=False)
   361: 		self.properties_window["add_publisher"] = gtk.Button(stock=gtk.STOCK_ADD)
   362: 		try:
   363: 			# Attempt to change the label of the stock button
   364: 			label = self.properties_window["add_publisher"].get_children()[0]
   365: 			label = label.get_children()[0].get_children()[1]
   366: 			label = label.set_label("Add...")
   367: 		except:
   368: 			# If it fails then just go back to the default
   369: 			self.properties_window["add_publisher"] = gtk.Button(stock=gtk.STOCK_ADD)
   370: 		self.properties_window["add_publisher"].connect("released", self.add_publisher)
   371: 		self.properties_window["publishers_buttons"].pack_start(self.properties_window["add_publisher"], expand=False)
   372: 
   373: 		# Remove Publisher button
   374: 		self.properties_window["remove_publisher"] = gtk.Button(stock=gtk.STOCK_REMOVE)
   375: 		self.properties_window["remove_publisher"].connect("released", self.remove_publisher)
   376: 		self.properties_window["publishers_buttons"].pack_end(self.properties_window["remove_publisher"], expand=False)
   377: 
   378: 		# Publishers list
   379: 		self.properties_window["publishers_column"] = Column(attribute="name", title="Jabber ID")
   380: 		self.properties_window["publishers"] = ObjectList([self.properties_window["publishers_column"]])
   381: 		self.properties_window["publishers_box"].pack_start(self.properties_window["publishers"], expand=True)
   382: 
   383: 		# Outcasts frame
   384: 		self.properties_window["outcasts_frame"] = gtk.Frame("Outcasts")
   385: 		self.properties_window["affiliations_page"].pack_start(self.properties_window["outcasts_frame"], expand=True)
   386: 		self.properties_window["outcasts_box"] = gtk.HBox()
   387: 		self.properties_window["outcasts_frame"].add(self.properties_window["outcasts_box"])
   388: 
   389: 		# Add Outcast button
   390: 		self.properties_window["outcasts_buttons"] = gtk.VBox()
   391: 		self.properties_window["outcasts_box"].pack_end(self.properties_window["outcasts_buttons"], expand=False)
   392: 		self.properties_window["add_outcast"] = gtk.Button(stock=gtk.STOCK_ADD)
   393: 		try:
   394: 			# Attempt to change the label of the stock button
   395: 			label = self.properties_window["add_outcast"].get_children()[0]
   396: 			label = label.get_children()[0].get_children()[1]
   397: 			label = label.set_label("Add...")
   398: 		except:
   399: 			# If it fails then just go back to the default
   400: 			self.properties_window["add_outcast"] = gtk.Button(stock=gtk.STOCK_ADD)
   401: 		self.properties_window["add_outcast"].connect("released", self.add_outcast)
   402: 		self.properties_window["outcasts_buttons"].pack_start(self.properties_window["add_outcast"], expand=False)
   403: 
   404: 		# Remove Outcast button
   405: 		self.properties_window["remove_outcast"] = gtk.Button(stock=gtk.STOCK_REMOVE)
   406: 		self.properties_window["remove_outcast"].connect("released", self.remove_outcast)
   407: 		self.properties_window["outcasts_buttons"].pack_end(self.properties_window["remove_outcast"], expand=False)
   408: 
   409: 		# Outcasts list
   410: 		self.properties_window["outcasts_column"] = Column(attribute="name", title="Jabber ID")
   411: 		self.properties_window["outcasts"] = ObjectList([self.properties_window["outcasts_column"]])
   412: 		self.properties_window["outcasts_box"].pack_start(self.properties_window["outcasts"], expand=True)
   413: 
   414: 		self.properties_window["window"].show_all()
   415: 
   416: 		if "owner" in affiliation_dictionary.keys():
   417: 			for jid in affiliation_dictionary["owner"]:
   418: 				self.properties_window["owners"].append(jid)
   419: 		if "publisher" in affiliation_dictionary.keys():
   420: 			for jid in affiliation_dictionary["publisher"]:
   421: 				self.properties_window["publishers"].append(jid)
   422: 		if "outcast" in affiliation_dictionary.keys():
   423: 			for jid in affiliation_dictionary["outcast"]:
   424: 				self.properties_window["outcasts"].append(jid)
   425: 
   426: 	def set_name(self, args):
   427: 		pass
   428: 
   429: 	def set_title(self, args):
   430: 		pass
   431: 
   432: 	def add_owner(self, args):
   433: 		self.add_owner_window = {}
   434: 		self.add_owner_window["window"] = gtk.Window()
   435: 		self.add_owner_window["window"].set_title("Add owner to " + str(self.tree_view.get_selected()))
   436: 		self.add_owner_window["box"] = gtk.HBox()
   437: 		self.add_owner_window["window"].add(self.add_owner_window["box"])
   438: 		self.add_owner_window["jid_label"] = gtk.Label("Jabber ID:")
   439: 		self.add_owner_window["box"].pack_start(self.add_owner_window["jid_label"], expand=False)
   440: 		self.add_owner_window["jid_entry"] = gtk.Entry()
   441: 		self.add_owner_window["box"].pack_start(self.add_owner_window["jid_entry"], expand=False)
   442: 		self.add_owner_window["add_button"] = gtk.Button(stock=gtk.STOCK_ADD)
   443: 		self.add_owner_window["add_button"].connect("released", self.add_owner_send)
   444: 		self.add_owner_window["box"].pack_end(self.add_owner_window["add_button"], expand=False)
   445: 		self.add_owner_window["window"].show_all()
   446: 
   447: 	def add_owner_send(self, args):
   448: 		self.add_owner_window["jid"] = JID(self.add_owner_window["jid_entry"].get_text())
   449: 		self.tree_view.get_selected().modify_affiliations(self.client, {self.add_owner_window["jid"]:"owner"}, self.owner_added)
   450: 
   451: 	def owner_added(self, reply):
   452: 		if reply == 0:
   453: 			self.properties_window["owners"].append(self.add_owner_window["jid"])
   454: 			for jid in self.properties_window["publishers"]:
   455: 				if str(jid) == str(self.add_owner_window["jid"]):
   456: 					self.properties_window["publishers"].remove(jid)
   457: 			for jid in self.properties_window["outcasts"]:
   458: 				if str(jid) == str(self.add_owner_window["jid"]):
   459: 					self.properties_window["outcasts"].remove(jid)
   460: 		else:
   461: 			print "Error"
   462: 		self.add_owner_window["window"].destroy()
   463: 		del self.add_owner_window
   464: 
   465: 	def remove_owner(self, args):
   466: 		self.tree_view.get_selected().modify_affiliations(self.client, {self.properties_window["owners"].get_selected():"none"}, self.owner_removed)
   467: 
   468: 	def owner_removed(self, reply):
   469: 		if reply == 0:
   470: 			self.properties_window["owners"].remove(self.properties_window["owners"].get_selected())
   471: 		else:
   472: 			print "Error"
   473: 
   474: 	def add_publisher(self, args):
   475: 		self.add_publisher_window = {}
   476: 		self.add_publisher_window["window"] = gtk.Window()
   477: 		self.add_publisher_window["window"].set_title("Add publisher to " + str(self.tree_view.get_selected()))
   478: 		self.add_publisher_window["hbox"] = gtk.HBox()
   479: 		self.add_publisher_window["window"].add(self.add_publisher_window["hbox"])
   480: 		self.add_publisher_window["jid_label"] = gtk.Label("Jabber ID:")
   481: 		self.add_publisher_window["hbox"].pack_start(self.add_publisher_window["jid_label"], expand=False)
   482: 		self.add_publisher_window["jid_entry"] = gtk.Entry()
   483: 		self.add_publisher_window["hbox"].pack_start(self.add_publisher_window["jid_entry"], expand=False)
   484: 		self.add_publisher_window["add_button"] = gtk.Button(stock=gtk.STOCK_ADD)
   485: 		self.add_publisher_window["add_button"].connect("released", self.add_publisher_send)
   486: 		self.add_publisher_window["hbox"].pack_end(self.add_publisher_window["add_button"], expand=False)
   487: 		self.add_publisher_window["window"].show_all()
   488: 
   489: 	def add_publisher_send(self, args):
   490: 		self.add_publisher_window["jid"] = JID(self.add_publisher_window["jid_entry"].get_text())
   491: 		self.tree_view.get_selected().modify_affiliations(self.client, {self.add_publisher_window["jid"]:"publisher"}, self.publisher_added)
   492: 
   493: 	def publisher_added(self, reply):
   494: 		if reply == 0:
   495: 			self.properties_window["publishers"].append(self.add_publisher_window["jid"])
   496: 			for jid in self.properties_window["owners"]:
   497: 				if str(jid) == str(self.add_publisher_window["jid"]):
   498: 					self.properties_window["owners"].remove(jid)
   499: 			for jid in self.properties_window["outcasts"]:
   500: 				if str(jid) == str(self.add_publisher_window["jid"]):
   501: 					self.properties_window["outcasts"].remove(jid)
   502: 		else:
   503: 			print "Error"
   504: 		self.add_publisher_window["window"].destroy()
   505: 		del self.add_publisher_window
   506: 
   507: 	def remove_publisher(self, args):
   508: 		self.tree_view.get_selected().modify_affiliations(self.client, {self.properties_window["publishers"].get_selected():"none"}, self.publisher_removed)
   509: 
   510: 	def publisher_removed(self, reply):
   511: 		if reply == 0:
   512: 			self.properties_window["publishers"].remove(self.properties_window["publishers"].get_selected())
   513: 		else:
   514: 			print "Error"
   515: 
   516: 	def add_outcast(self, args):
   517: 		self.add_outcast_window = {}
   518: 		self.add_outcast_window["window"] = gtk.Window()
   519: 		self.add_outcast_window["window"].set_title("Add outcast to " + str(self.tree_view.get_selected()))
   520: 		self.add_outcast_window["hbox"] = gtk.HBox()
   521: 		self.add_outcast_window["window"].add(self.add_outcast_window["hbox"])
   522: 		self.add_outcast_window["jid_label"] = gtk.Label("Jabber ID:")
   523: 		self.add_outcast_window["hbox"].pack_start(self.add_outcast_window["jid_label"], expand=False)
   524: 		self.add_outcast_window["jid_entry"] = gtk.Entry()
   525: 		self.add_outcast_window["hbox"].pack_start(self.add_outcast_window["jid_entry"], expand=False)
   526: 		self.add_outcast_window["add_button"] = gtk.Button(stock=gtk.STOCK_ADD)
   527: 		self.add_outcast_window["add_button"].connect("released", self.add_outcast_send)
   528: 		self.add_outcast_window["hbox"].pack_end(self.add_outcast_window["add_button"], expand=False)
   529: 		self.add_outcast_window["window"].show_all()
   530: 
   531: 	def add_outcast_send(self, args):
   532: 		self.add_outcast_window["jid"] = JID(self.add_outcast_window["jid_entry"].get_text())
   533: 		self.tree_view.get_selected().modify_affiliations(self.client, {self.add_outcast_window["jid"]:"outcast"}, self.outcast_added)
   534: 
   535: 	def outcast_added(self, reply):
   536: 		if reply == 0:
   537: 			self.properties_window["outcasts"].append(self.add_outcast_window["jid"])
   538: 			for jid in self.properties_window["publishers"]:
   539: 				if str(jid) == str(self.add_outcast_window["jid"]):
   540: 					self.properties_window["publishers"].remove(jid)
   541: 			for jid in self.properties_window["owners"]:
   542: 				if str(jid) == str(self.add_outcast_window["jid"]):
   543: 					self.properties_window["owners"].remove(jid)
   544: 		else:
   545: 			print "Error"
   546: 		self.add_outcast_window["window"].destroy()
   547: 		del self.add_outcast_window
   548: 
   549: 	def remove_outcast(self, args):
   550: 		self.tree_view.get_selected().modify_affiliations(self.client, {self.properties_window["outcasts"].get_selected():"none"}, self.outcast_removed)
   551: 
   552: 	def outcast_removed(self, reply):
   553: 		if reply == 0:
   554: 			self.properties_window["outcasts"].remove(self.properties_window["outcasts"].get_selected())
   555: 		else:
   556: 			print "Error"
   557: 
   558: 	def main(self):
   559: 		self.window.show_all()
   560: 		self.client.connect()
   561: 		#gobject.idle_add(self.idle_process, priority=gobject.PRIORITY_LOW)
   562: 		gobject.timeout_add(250, self.idle_process)
   563: 		gtk.main()
   564: 
   565: 	def idle_process(self):
   566: 		"""A PubSubClient needs its process method run regularly. This
   567: 		method can be used to do that in gobject.timeout or idle_add."""
   568: 		self.client.process()
   569: 		return True
   570: 
   571: 	def quit(self, arg):
   572: 		"""Exits the application. Runs when a signal to quit is received."""
   573: 		gtk.main_quit()
   574: 
   575: if __name__ == "__main__":
   576: 	main_window = Window()		# Make a browser application
   577: 
   578: 	# This sets a default server, so testing the same server again and
   579: 	# again only requires pressing the "Get" button
   580: 	main_window.location_entry.set_text("pubsub.localhost")
   581: 
   582: 	main_window.main()		# Run the browser

Generated by git2html.