Ejemplo n.º 1
0
class Bot(gobject.GObject):
	""""""

	# custom properties
	__gproperties__ = {
		'apiAccessible' : (gobject.TYPE_BOOLEAN, 'api accessible', 'is api accessible', False, gobject.PARAM_READWRITE),
		'isRunning' : (gobject.TYPE_BOOLEAN, 'is running', 'is running', False, gobject.PARAM_READWRITE)
	}

	CHANNEL_TELL = 0
	CHANNEL_ORG = 1
	CHANNEL_PRIVATE = 2
 
	def __init__(self, name, settingModel):
		"""Constructor method."""
		self.__gobject_init__()
		self.name = name
		self.settingModel = settingModel
		self.api = budapi.Budapi()
		self.process = Process()
		self.consoleModel = gtk.TextBuffer()
		self.configFile = None
		self.noRestart = False
		self.set_property('apiAccessible', False)
		self.process.connect('stdout_received', self.onBotStdoutReceived)
		self.process.connect('stderr_received', self.onBotStderrReceived)
		self.process.connect('stopped', self.onBotDied)

		tagTable = self.consoleModel.get_tag_table()

		def addTag(buffer, name, foreground, weight = None):
			"""Adds a text tag to buffer with given name and styles."""
			tag = gtk.TextTag(name)
			tag.set_property('foreground', foreground)
			if weight != None:
				tag.set_property('weight', weight)
			buffer.get_tag_table().add(tag)

		addTag(self.consoleModel, 'error', foreground = 'red', weight = pango.WEIGHT_BOLD)
		addTag(self.consoleModel, 'response', foreground = 'lightblue')


	def do_get_property(self, property):
		"""Returns value of given property.
		This is required to make GTK's properties to work.
		See: http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm#d0e127
		"""
		if property.name == 'apiAccessible':
			return self.apiAccessible
		elif property.name == 'isRunning':
			return self.process.isRunning()
		else:
			raise AttributeError, 'unknown property %s' % property.name

	def do_set_property(self, property, value):
		"""Sets value of given property.
		This is required to make GTK's properties to work.
		See: http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm#d0e127
		"""
		if property.name == 'apiAccessible':
			self.apiAccessible = value
		else:
			raise AttributeError, 'unknown property %s' % property.name

	def getName(self):
		"""Returns name of the bot."""
		return self.name

	def getConsoleModel(self):
		"""Returns console model"""
		return self.consoleModel

	def start(self):
		"""Starts the bot."""
		# do nothing if bot process is still running.
		if self.process.isRunning():
			return

		configPath = self.settingModel.getValue(self.name, 'configfile')
		self.configFile = BotPhpConfigFile(configPath)
		self.configFile.load()
		port = self.configFile.getVar('API Port')

		# make sure that port is within defined range
		lowPort  = self.settingModel.getApiPortRangeLow()
		highPort = self.settingModel.getApiPortRangeHigh()
		if port < lowPort or port > highPort:
			port = lowPort
			self.configFile.setVar('API Port', port)
			self.configFile.save()

		# find a free port if currently set port is not free
		if self.isPortFree(port) == False:
			for port in range(lowPort, highPort + 1):
				if self.isPortFree(port):
					self.configFile.setVar('API Port', port)
					self.configFile.save()
					break

		self.noRestart = False
		self.process.setConfigFilePath(configPath)
		self.process.setWorkingDirectoryPath(self.settingModel.getValue(self.name, 'installdir'))
		self.process.start()
		self.notify('isRunning')
		self.pollApi()

	def isPortFree(self, port):
		"""Returns True if given TCP/IP port is free."""
		s = None
		try:
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			s.bind(('0.0.0.0', port))
			return True
		except socket.error, e:
			try:
				s.close()
			except:
				pass
		return False