def gotEntryCallback(self, result, name): entryPath, filename, methodName = result filepath = os.path.join(entryPath, filename) self.debug('Got the UI for %s and it lives in %s' % (name, filepath)) self.uidir = os.path.split(filepath)[0] #handle = open(filepath, "r") #data = handle.read() #handle.close() # try loading the class moduleName = common.pathToModuleName(filename) statement = 'import %s' % moduleName self.debug('running %s' % statement) try: exec(statement) except SyntaxError, e: # the syntax error can happen in the entry file, or any import where = getattr(e, 'filename', "<entry file>") lineno = getattr(e, 'lineno', 0) msg = "Syntax Error at %s:%d while executing %s" % (where, lineno, filename) self.warning(msg) raise errors.EntrySyntaxError(msg)
def bundleErrback(self, failure, fileName='<unknown>'): """ Handle all coding mistakes that could be triggered by loading bundles. This is a convenience method to help in properly reporting problems. The EntrySyntaxError should be caught and wrapped in a UI message, with the message generated here as debug information. @param failure: the failure to be handled @type failure: L{twisted.python.failure.Failure} @param filename: name of the file being loaded @type filename: str @raises: L{errors.EntrySyntaxError} """ try: raise failure.value except SyntaxError, e: # the syntax error can happen in the entry file, or any import where = getattr(e, 'filename', "<entry file>") lineno = getattr(e, 'lineno', 0) msg = "Syntax Error at %s:%d while executing %s" % (where, lineno, fileName) self.warning(msg) raise errors.EntrySyntaxError(msg)
class AdminTextView(log.Loggable, gobject.GObject, misc_curses.CursesStdIO): implements(flavors.IStateListener) logCategory = 'admintextview' global_commands = ['startall', 'stopall', 'clearall', 'quit'] LINES_BEFORE_COMPONENTS = 5 LINES_AFTER_COMPONENTS = 6 def __init__(self, model, stdscr): self.initialised = False self.stdscr = stdscr self.inputText = '' self.command_result = "" self.lastcommands = [] self.nextcommands = [] self.rows, self.cols = self.stdscr.getmaxyx() self.max_components_per_page = self.rows - \ self.LINES_BEFORE_COMPONENTS - \ self.LINES_AFTER_COMPONENTS self._first_onscreen_component = 0 self._components = {} self._comptextui = {} self._setAdminModel(model) # get initial info we need self.setPlanetState(self.admin.planet) def _setAdminModel(self, model): self.admin = model self.admin.connect('connected', self.admin_connected_cb) self.admin.connect('disconnected', self.admin_disconnected_cb) self.admin.connect('connection-refused', self.admin_connection_refused_cb) self.admin.connect('connection-failed', self.admin_connection_failed_cb) #self.admin.connect('component-property-changed', # self.property_changed_cb) self.admin.connect('update', self.admin_update_cb) # show the whole text admin screen def show(self): self.initialised = True self.stdscr.addstr(0, 0, "Main Menu") self.show_components() self.display_status() self.stdscr.move(self.lasty, 0) self.stdscr.clrtoeol() self.stdscr.move(self.lasty + 1, 0) self.stdscr.clrtoeol() self.stdscr.addstr(self.lasty + 1, 0, "Prompt: %s" % self.inputText) self.stdscr.refresh() #gobject.io_add_watch(0, gobject.IO_IN, self.keyboard_input_cb) # show the view of components and their mood # called from show def show_components(self): if self.initialised: self.stdscr.addstr(2, 0, "Components:") # get a dictionary of components names = self._components.keys() names.sort() cury = 4 # if number of components is less than the space add # "press page up for previous components" and # "press page down for next components" lines if len(names) > self.max_components_per_page: if self._first_onscreen_component > 0: self.stdscr.move(cury, 0) self.stdscr.clrtoeol() self.stdscr.addstr( cury, 0, "Press page up to scroll up components list") cury = cury + 1 cur_component = self._first_onscreen_component for name in names[self._first_onscreen_component:len(names)]: # check if too many components for screen height if cury - self.LINES_BEFORE_COMPONENTS >= \ self.max_components_per_page: self.stdscr.move(cury, 0) self.stdscr.clrtoeol() self.stdscr.addstr( cury, 0, "Press page down to scroll down components list") cury = cury + 1 break component = self._components[name] mood = component.get('mood') # clear current component line self.stdscr.move(cury, 0) self.stdscr.clrtoeol() # output component name and mood self.stdscr.addstr(cury, 0, "%s: %s" % (name, moods[mood].name)) cury = cury + 1 cur_component = cur_component + 1 self.lasty = cury #self.stdscr.refresh() def gotEntryCallback(self, result, name): entryPath, filename, methodName = result filepath = os.path.join(entryPath, filename) self.debug('Got the UI for %s and it lives in %s' % (name, filepath)) self.uidir = os.path.split(filepath)[0] #handle = open(filepath, "r") #data = handle.read() #handle.close() # try loading the class moduleName = common.pathToModuleName(filename) statement = 'import %s' % moduleName self.debug('running %s' % statement) try: exec(statement) except SyntaxError, e: # the syntax error can happen in the entry file, or any import where = getattr(e, 'filename', "<entry file>") lineno = getattr(e, 'lineno', 0) msg = "Syntax Error at %s:%d while executing %s" % (where, lineno, filename) self.warning(msg) raise errors.EntrySyntaxError(msg) except NameError, e: # the syntax error can happen in the entry file, or any import msg = "NameError while executing %s: %s" % (filename, " ".join( e.args)) self.warning(msg) raise errors.EntrySyntaxError(msg)
lineno = getattr(e, 'lineno', 0) msg = "Syntax Error at %s:%d while executing %s" % (where, lineno, filename) self.warning(msg) raise errors.EntrySyntaxError(msg) except NameError, e: # the syntax error can happen in the entry file, or any import msg = "NameError while executing %s: %s" % (filename, " ".join( e.args)) self.warning(msg) raise errors.EntrySyntaxError(msg) except ImportError, e: msg = "ImportError while executing %s: %s" % (filename, " ".join( e.args)) self.warning(msg) raise errors.EntrySyntaxError(msg) # make sure we're running the latest version module = reflect.namedAny(moduleName) rebuild.rebuild(module) # check if we have the method if not hasattr(module, methodName): self.warning('method %s not found in file %s' % (methodName, filename)) raise #FIXME: something appropriate klass = getattr(module, methodName) # instantiate the GUIClass, giving ourself as the first argument # FIXME: we cheat by giving the view as second for now, # but let's decide for either view or model
class AdminModel(medium.PingingMedium, signals.SignalMixin): """ I live in the admin client. I am a data model for any admin view implementing a UI to communicate with one manager. I send signals when things happen. Manager calls on us through L{flumotion.manager.admin.AdminAvatar} """ __signals__ = ('connected', 'disconnected', 'connection-refused', 'connection-failed', 'connection-error', 'reloading', 'message', 'update') logCategory = 'adminmodel' implements(interfaces.IAdminMedium) # Public instance variables (read-only) planet = None def __init__(self): # All of these instance variables are private. Cuidado cabrones! self.connectionInfo = None self.keepTrying = None self._writeConnection = True self.managerId = '<uninitialized>' self.connected = False self.clientFactory = None self._deferredConnect = None self._components = {} # dict of components self.planet = None self._workerHeavenState = None def disconnectFromManager(self): """ Disconnects from the actual manager and frees the connection. """ if self.clientFactory: # We are disconnecting, so we don't want to be # notified by the model about it. if self.remote: self.remote.dontNotifyOnDisconnect(self._remoteDisconnected) self.clientFactory.stopTrying() self.clientFactory.disconnect() self.clientFactory = None def connectToManager(self, connectionInfo, keepTrying=False, writeConnection=True): """ Connects to the specified manager. @param connectionInfo: data for establishing the connection @type connectionInfo: a L{PBConnectionInfo} @param keepTrying: when this is L{True} the Factory will try to reconnect when it loses the connection @type keepTrying: bool @param writeConnection: when this is L{True} the connection is saved for future uses on cache @type writeConnection: bool @rtype: L{twisted.internet.defer.Deferred} """ assert self.clientFactory is None self.connectionInfo = connectionInfo self._writeConnection = writeConnection # give the admin an id unique to the manager -- if a program is # adminning multiple managers, this id should tell them apart # (and identify duplicates) self.managerId = str(connectionInfo) self.logName = self.managerId self.info('Connecting to manager %s with %s', self.managerId, connectionInfo.use_ssl and 'SSL' or 'TCP') self.clientFactory = AdminClientFactory(self, extraTenacious=keepTrying, maxDelay=20) self.clientFactory.startLogin(connectionInfo.authenticator) if connectionInfo.use_ssl: common.assertSSLAvailable() from twisted.internet import ssl reactor.connectSSL(connectionInfo.host, connectionInfo.port, self.clientFactory, ssl.ClientContextFactory()) else: reactor.connectTCP(connectionInfo.host, connectionInfo.port, self.clientFactory) def connected(model, d): # model is really "self". yay gobject? d.callback(model) def disconnected(model, d): # can happen after setRemoteReference but before # getPlanetState or getWorkerHeavenState returns if not keepTrying: d.errback(errors.ConnectionFailedError('Lost connection')) def connection_refused(model, d): if not keepTrying: d.errback(errors.ConnectionRefusedError()) def connection_failed(model, reason, d): if not keepTrying: d.errback(errors.ConnectionFailedError(reason)) def connection_error(model, failure, d): if not keepTrying: d.errback(failure) d = defer.Deferred() ids = [] ids.append(self.connect('connected', connected, d)) ids.append(self.connect('disconnected', disconnected, d)) ids.append(self.connect('connection-refused', connection_refused, d)) ids.append(self.connect('connection-failed', connection_failed, d)) ids.append(self.connect('connection-error', connection_error, d)) def success(model): map(self.disconnect, ids) self._deferredConnect = None return model def failure(f): map(self.disconnect, ids) self._deferredConnect = None return f d.addCallbacks(success, failure) self._deferredConnect = d return d def bundleErrback(self, failure, fileName='<unknown>'): """ Handle all coding mistakes that could be triggered by loading bundles. This is a convenience method to help in properly reporting problems. The EntrySyntaxError should be caught and wrapped in a UI message, with the message generated here as debug information. @param failure: the failure to be handled @type failure: L{twisted.python.failure.Failure} @param filename: name of the file being loaded @type filename: str @raises: L{errors.EntrySyntaxError} """ try: raise failure.value except SyntaxError, e: # the syntax error can happen in the entry file, or any import where = getattr(e, 'filename', "<entry file>") lineno = getattr(e, 'lineno', 0) msg = "Syntax Error at %s:%d while executing %s" % (where, lineno, fileName) self.warning(msg) raise errors.EntrySyntaxError(msg) except NameError, e: msg = "NameError while executing %s: %s" % (fileName, " ".join( e.args)) self.warning(msg) raise errors.EntrySyntaxError(msg)