Beispiel #1
0
    def sendingString(self):
        if self.type is None:
            # invalid message
            return ''

        try:
            data = self.sendingDataString(self.data, self.type)
            datalen = len(data)

            if is_python3():
                name = self.name.encode('utf-8')
                data = data.encode('utf-8')
            else:
                name = str(self.name)

            header = struct.pack(self.packedHeaderDataFormat, self.magic,
                                 self.vers, self.size, self.sn, self.sec,
                                 self.usec, self.cmd, self.type, self.rows,
                                 self.cols, datalen, self.err, self.flags,
                                 name)
        except:
            import traceback
            log.log(2, "specmessage error: %s" % traceback.format_exc())

        return header + data
Beispiel #2
0
    def handle_read(self):
        try:
            received = self.recv(32768)

            self.received_strings.append(received)

            if is_python3():
                s = b''.join(self.received_strings)
                sbuffer = memoryview(s)
            else:
                s = ''.join(self.received_strings)
                sbuffer = buffer(s)

            consumedBytes = 0
            offset = 0
            received_messages = []

            while offset < len(sbuffer):

                if self.message is None:
                    try:
                        self.message = SpecMessage.message(
                            version=self.client_version,
                            order=self.client_order)
                    except:
                        import traceback
                        log.log(2, traceback.format_exc())

                consumedBytes = self.message.readFromStream(sbuffer[offset:])

                if consumedBytes == 0:
                    break

                offset += consumedBytes

                if self.message.isComplete():
                    # dispatch incoming message
                    if self.message.cmd == SpecMessage.HELLO:
                        self.client_order = self.message.packedHeaderDataFormat[
                            0]
                        self.client_version = self.message.vers
                        self.clientName = self.message.name
                        self.send_hello_reply(self.message.sn,
                                              str(self.server.name))
                    else:
                        received_messages.append(self.message)

                    self.message = None

            self.received_strings = [s[offset:]]

            for message in received_messages:
                if not self.dispatch_message(message):
                    self.send_error(
                        message.sn, '',
                        'unsupported command type : %d' % message.cmd)
        except:
            import traceback
            log.log(3, "SpecServer read error. %s" % traceback.format_exc())
            return
Beispiel #3
0
    def readFromStream(self, streamBuf):
        """Read buffer from stream and try to create a message from it

        Arguments:
        streamBuf - string buffer of the last bytes received from Spec

        Return value :
        the number of consumed bytes
        """
        consumedBytes = 0

        try:
            while self.bytesToRead > 0 and len(streamBuf[consumedBytes:]) >= self.bytesToRead:
                if self.readheader:
                    self.readheader = False
                    self.type, self.bytesToRead = self.readHeader(streamBuf[:self.headerLength])
                    consumedBytes = self.headerLength
                else:
                    rawdata = streamBuf[consumedBytes:consumedBytes+self.bytesToRead]
                    consumedBytes += self.bytesToRead
                    self.bytesToRead = 0
    
                    self.data = self.readData(rawdata, self.type)
    
        except BaseException as e:
            import traceback
            log.log(2, "error reading message from stream %s" % str(e))
            log.log(2,  traceback.format_exc())
  

        return consumedBytes
Beispiel #4
0
 def dispatch_message(self, message):
     try:
         if message.cmd == SpecMessage.CHAN_READ:
             # temporary code (workaround for a Spec client bug)
             self.get_and_reply(reply_id=message.sn, channame=message.name)
         elif message.cmd == SpecMessage.CHAN_SEND:
             self.set_and_reply(reply_id=message.sn,
                                channame=message.name,
                                value=message.data)
         elif message.cmd in (SpecMessage.CMD_WITH_RETURN,
                              SpecMessage.FUNC_WITH_RETURN):
             self.run_and_reply(reply_id=message.sn, cmd=message.data)
         elif message.cmd == SpecMessage.FUNC_WITH_RETURN:
             self.run_and_reply(reply_id=message.sn, cmd=message.data)
         elif message.cmd == SpecMessage.CMD:
             # in this case we allow for multiple commands separated by colon
             cmdstr = message.data
             cmds = cmdstr.split(";")
             for cmd in cmds:
                 self.run_and_reply(reply_id=message.sn, cmd=cmd)
         elif message.cmd == SpecMessage.REGISTER:
             if message.name == 'update':
                 log.log(3, "update channel registered !")
                 self.updateRegistered = True
         else:
             return False
         return True
     except:
         import traceback
         log.log(2, traceback.format_exc())
         return False
    def put(self, event):
        """Put an event into the queue."""
        receiversList = event.receivers

        EventQueue.queue.mutex.acquire()

        try:
            showstatus()
            was_empty = not EventQueue.queue._qsize()

            for r in receiversList:
                if not was_empty:
                    if r.dispatchMode == UPDATEVALUE:
                        for i in range(len(EventQueue.queue.queue)):
                            _r, args = EventQueue.queue.queue[i]
                            if r == _r:
                                del EventQueue.queue.queue[i]
                                break

                EventQueue.queue._put((r, event.args))
        except:
            import traceback
            log.log(DEBUG,
                    "could not add event to queue %s" % traceback.format_exc())
        finally:
            EventQueue.queue.mutex.release()
Beispiel #6
0
    def _update(self):

        asyncore.loop(timeout=1, count=1)

        if time.time() - self.last_log_print > self.log_period:
            log.log(4, "command server is running")
            self.last_log_print = time.time()
Beispiel #7
0
def rawtodictonary(rawstring):
    """Transform a list as coming from a SPEC associative array
    to a dictonary - 2dim arrays are transformed top dict with dict
    entries. In SPEC the key contains \x1c"""
    if is_python3():
        rawstring = bytes(rawstring).decode('utf-8')  # from memoryview
        #raw = bytes(rawstring).decode('utf-8').split(NULL)[:-2]
    #else:
    raw = rawstring.split(NULL)[:-2]

    log.log(2, "converting to dict raw data %s" % raw)

    data = {}
    for i in range(0,len(raw) - 1,2):
        key,val = raw[i], raw[i+1]
        keyel = key.split("\x1c")
        if len(keyel) == 1:
            if key in data:
              data[key][None] = val
            else:
              data[key]=val
        else:
            #if keyel[0] in data and type(data[keyel[0]])!=types.DictType:
            if keyel[0] in data and not isinstance(data[keyel[0]], dict):
              data[keyel[0]]={ None: data[keyel[0]] }

            try:
                data[keyel[0]][keyel[1]] = val
            except TypeError:
                data[keyel[0]] = {keyel[1] : val}
            except KeyError:
                data[keyel[0]] = {keyel[1] : val}
    return data
Beispiel #8
0
 def handle_close(self):
     self.close()
     try:
         self.server.clients.remove(self)
     except:
         log.log(
             2, "removing client from spec server. but it is gone already")
         pass
def emit(sender, signal, arguments=()):
    try:
        ev = Event(sender, signal, arguments)
        eventsToDispatch.put(ev)
    except:
        log.log(DEBUG, "failed adding event")
        import traceback
        log.log(DEBUG, traceback.format_exc())
Beispiel #10
0
    def set_update_time(self, update_time):
        self.update_time = update_time is None and \
                              self.default_update_time or update_time
        self.update_time /= 1000.0 # in seconds

        # minimum 10 milliseconds update cycle time
        if self.update_time < 0.01:
            log.log(2, "update time of %s secs too short. using 0.01")
            self.update_time = 0.01
 def specConnected(self):
     """Emit the 'connected' signal when the remote Spec version is connected."""
     old_state = self.state
     self.state = CONNECTED
     if old_state != CONNECTED:
         log.log(
             1, 'Connected to %s:%s' %
             (self.host, (self.scanport and self.scanname) or self.port))
         SpecEventsDispatcher.emit(self, 'connected', ())
Beispiel #12
0
 def spec_disconnected(self):
     """Emit the 'disconnected' signal when the remote Spec version is disconnected."""
     # SpecEventsDispatcher.dispatch()
     old_state = self.state
     self.state = DISCONNECTED
     if old_state == CONNECTED:
         log.log(
             1, 'disconnected from %s:%s' %
             (self.host, self.specname or self.port))
         SpecEventsDispatcher.emit(self, 'disconnected', ())
Beispiel #13
0
    def update(self, data, error, error_code):
        """Emit the 'replyFromSpec' signal."""

        self.data = data
        self.error = error
        self.error_code = error_code

        self.pending = False
        log.log(2, "emitting replyArrived")
        SpecEventsDispatcher.emit(self, 'replyArrived', (self, ))
Beispiel #14
0
    def run(self):

        if self.is_running():
            return

        # start a thread for automatic update
        self.updater = spec_updater.spec_updater(method=spec_updater.THREAD,
                                                 update_func=self._update)

        log.log(2, "starting spec server with name: %s" % self.name)
        self.updater.start()
Beispiel #15
0
    def set_name(self, name):

        if self.name is not None and name != self.name:
            new_name = True
        else:
            new_name = False

        if not self.allow_name_change and new_name:
            if self.name is not None and name != self.name:
                return

        if name is None:
            log.log(2, "cannot start SpecServer without a name.")
            return

        self.name = name

        if new_name:
            log.log(2, "server name has been changed.")
            return

        # start only once and when a name is provided
        # a name change does not change the port

        if isinstance(self.name, str):
            # choose a port number from PORT range
            host = ""
            for p in range(MIN_PORT, MAX_PORT):
                self.server_address = (host, p)

                try:
                    self.bind(self.server_address)
                    self.bind_ok = True
                    break
                except:
                    # already used. continue
                    continue
            else:
                log.log(2, "ALL server addresses are taken. Cannot start")
        else:
            # it is a port number. use that one
            self.server_address = (self.host, self.name)
            try:
                self.bind(self.server_address)
                self.bind_ok = True
            except:
                log.log(
                    2, "Cannot start server on port %s. Already used?" %
                    self.name)

        if self.bind_ok:
            log.log(2,
                    "spec server listening on %s" % str(self.server_address))
            self.listen(5)
Beispiel #16
0
    def set_and_reply(self, reply_id, channame, value):

        try:
            ret = self.server.set_value(channame, value)
        except Exception:
            import traceback
            log.log(2, traceback.format_exc())

        if ret is None:
            self.send_error(reply_id, '', 'cannot set channel ' + channame)
        else:
            self.send_reply(reply_id, '', ret)
Beispiel #17
0
    def _update(self, timeout=0.01):
        try:
            self.check_connection()
            if asyncore.socket_map:
                asyncore.loop(timeout=0.01, count=1)

            if self.thread_update:
                self.update_events()

        except Exception as e:
            import traceback
            log.log(2, traceback.format_exc())
    def __init__(self, sender, signal, arguments):
        self.receivers = []
        senderId = id(sender)
        signal = str(signal)
        self.args = arguments

        log.log(
            DEBUG, " creating event for signal %s - senderId is %s" %
            (signal, senderId))

        try:
            self.receivers = connections[senderId][signal]
        except:
            pass
Beispiel #19
0
    def __init__(self,
                 host=None,
                 name=None,
                 allow_name_change=True,
                 handler=SpecHandler):

        asyncore.dispatcher.__init__(self)

        self.handler_class = handler
        self.updater = None
        self.last_print = time.time()

        if host is None:
            self.host = "localhost"
        else:
            self.host = host  # only needed to select a particular ip in the computer

        #
        self.last_log_print = time.time()
        self.log_period = 10

        self.name = None
        self.allow_name_change = allow_name_change

        self.clients = []

        self.commands = {
            "?": [
                self.get_help,
            ],
            "command_list": [
                self.get_command_list,
            ],
            "channel_list": [
                self.get_channel_list,
            ],
        }

        self.channels = {}

        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()

        if name is not None:
            self.set_name(name)
        else:
            # delay socket creation
            log.log(
                2, "SpecServer created without a name. set a name to start it")
Beispiel #20
0
    def handle_write(self):
        #
        # send all the messages from the queue
        #
        while len(self.sendq) > 0:
            self.outputStrings.append(self.sendq.pop().sendingString())

        try:
            outputBuffer = b''.join(self.outputStrings)

            sent = self.send(outputBuffer)
            self.outputStrings = [outputBuffer[sent:]]
        except:
            import traceback
            log.log(3, "error writing message: %s", traceback.format_exc())
def _cleanupConnections(senderId, signal):
    """Delete any empty signals for sender. Delete sender if empty."""

    receivers = connections[senderId][signal]

    log.log(DEBUG, "   number of receivers is %d" % len(receivers))

    if len(receivers) == 0:
        # no more receivers
        log.log(DEBUG, "   - deleting connection for %s" % senderId)
        signals = connections[senderId]
        del signals[signal]

        if len(signals) == 0:
            # no more signals
            _removeSender(senderId)
Beispiel #22
0
    def executeCommand(self, command):
        if self._conn.server_version < 3:
            conn_cmd = 'send_msg_cmd_with_return'
        else:
            if isinstance(command,str):
                conn_cmd = self._conn.send_msg_cmd_with_return
            else:
                conn_cmd = self._conn.send_msg_func_with_return

        reply_id = conn_cmd(command)

        if self.synchronous:
            log.log(2, "synchronous command waiting for reply")
            self.wait()
            return self.retvalue
        else:
            return reply_id
    def handle_write(self):
        """Handle 'write' events on socket

        Send all the messages from the queue.
        """
        log.log(DEBUG, "writing to socket")
        while len(self.sendq) > 0:
            self.outputStrings.append(self.sendq.pop().sendingString())

        if is_python3():
            outputBuffer = b''.join(self.outputStrings)
        else:
            outputBuffer = ''.join(self.outputStrings)

        log.log(DEBUG, "SpecConnection - writing data out")
        sent = self.send(outputBuffer)

        self.outputStrings = [outputBuffer[sent:]]
def connect(sender, signal, slot, dispatchMode=UPDATEVALUE):
    if sender is None or signal is None:
        return

    if not callable(slot):
        return

    senderId = id(sender)
    signal = str(signal)
    signals = {}

    log.log(
        DEBUG, "connecting (%s) %s to %s - %s" %
        (str(sender), senderId, signal, signals))

    if senderId in connections:
        signals = connections[senderId]
    else:
        connections[senderId] = signals

    def remove(object, senderId=senderId):
        _removeSender(senderId)

    try:
        weakSender = weakref.ref(sender, remove)
        senders[senderId] = weakSender
    except:
        pass

    receivers = []

    if signal in signals:
        receivers = signals[signal]
    else:
        signals[signal] = receivers

    weakReceiver = callableObjectRef(slot)

    for r in receivers:
        if r.weakReceiver == weakReceiver:
            r.dispatchMode = dispatchMode
            return

    receivers.append(Receiver(weakReceiver, dispatchMode))
Beispiel #25
0
    def replyArrived(self, reply):
        log.log(2, "reply arrived for command")
        self.reply_pending = False
        self.retvalue = reply.get_data()

        if reply.error:
            if callable(self.__error_callback):
                try:
                    self.__error_callback(reply.error)
                except:
                    log.exception("Error while calling error callback (command=%s,spec version=%s)", self.command, self.specapp)
                self.__error_callback = None
        else:
            if callable(self.__callback):
                try:
                    self.__callback(reply.data)
                except:
                    log.exception("Error while calling reply callback (command=%s,spec version=%s)", self.command, self.specapp)
                self.__callback = None
def emit(sender, signal, arguments=()):
    try:
        ev = Event(sender, signal, arguments)
        log.log(
            DEBUG, "adding event with signal \"%s\" to the queue %s (%s)" %
            (signal, ev, id(eventsToDispatch)))
        eventsToDispatch.put(ev)
        log.log(DEBUG, "is queue empty0 %s" % eventsToDispatch.empty())
    except:
        log.log(DEBUG, "failed adding event")
        import traceback
        log.log(DEBUG, traceback.format_exc())
def _removeReceiver(weakReceiver):
    """Remove receiver from connections"""
    #log.log(DEBUG, "cleaning up connections, because receiver is removed %s" % str(weakReceiver))
    return
    for senderId in list(connections.keys()):
        for signal in list(connections[senderId].keys()):
            receivers = connections[senderId][signal]

            for r in receivers:
                log.log(
                    DEBUG,
                    "cleaning up connections, because receiver is removed %s" %
                    str(r))
                receivers.remove(r)
                break

            log.log(
                DEBUG,
                "cleaning up connections, because receiver is removed for signal %s"
                % str(signal))
            _cleanupConnections(senderId, signal)
def dispatch(max_time_in_s=1):
    t0 = time.time()
    while True:
        try:
            if eventsToDispatch.empty():
                break
            log.log(DEBUG, "is queueue empty %s" % eventsToDispatch.empty())
            receiver, args = eventsToDispatch.get()
        except queue.Empty:
            log.log(2, "uhmmm")
            break
        except:
            log.log(1, "other exception while dispatching events")
            import traceback
            log.log(1, traceback.format_exc())
        else:
            log.log(DEBUG,
                    "got a new event to dispatch with args %s" % str(args))
            receiver(args)
            if max_time_in_s < 0:
                continue
            elif (time.time() - t0) >= max_time_in_s:
                break
Beispiel #29
0
    def send_msg_cmd_with_return(self, cmd, caller=None):
        """Send a command message to the remote Spec server, and return the reply id.

        Arguments:
        cmd -- command string, i.e. '1+1'
        """
        if not self.is_connected():
            raise SpecClientNotConnectedError

        if not caller:
            try:
                caller = sys._getframe(1).f_locals['self']
            except KeyError:
                log.log(2, "caller not identified")
                caller = None
        log.log(2,
                "executing command. reply to be informed to %s" % str(caller))

        reply, msg = SpecMessage.msg_cmd_with_return(
            cmd, version=self.server_version)
        reply_id = self.__send_msg_with_reply(reply, msg, receiver_obj=caller)

        return reply_id
Beispiel #30
0
    def check_connection(self):
        """Establish a connection to Spec

        If the connection is already established, do nothing.
        Otherwise, create a socket object and try to connect.
        If we are in port scanning mode, try to connect using
        a port defined in the range from MIN_PORT to MAX_PORT
        """
        if not self.socket_connected:
            if self.scanports:
                if self.port is None or self.port > MAX_PORT:
                    self.port = MIN_PORT
                else:
                    self.port += 1

            while not self.scanports or self.port < MAX_PORT:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.settimeout(0.2)
                try:
                    if s.connect_ex((self.host, self.port)) == 0:
                        self.set_socket(s)
                        self.handle_connect()
                        break
                except socket.error:
                    pass  # exception could be 'host not found' for example, we ignore it

                if self.scanports:
                    self.port += 1
                else:
                    break
        elif self.state == WAITINGFORHELLO:
            if (time.time() - self.waiting_hello_started) > WAIT_HELLO_TIMEOUT:
                log.log(
                    2,
                    "socket connected but no response to hello message.forget this socket"
                )
                self.handle_close()