Esempio n. 1
0
def _decode(rawstr):
    """Convert a raw string to a Message.
    """
    # Check for the magick word.
    try:
        rawstr = rawstr.decode('utf-8')
    except (AttributeError, UnicodeEncodeError):
        pass
    except (UnicodeDecodeError):
        try:
            rawstr = rawstr.decode('iso-8859-1')
        except (UnicodeDecodeError):
            rawstr = rawstr.decode('utf-8', 'ignore')
    if not rawstr.startswith(_MAGICK):
        raise MessageError("This is not a '%s' message (wrong magick word)"
                           % _MAGICK)
    rawstr = rawstr[len(_MAGICK):]

    # Check for element count and version
    raw = re.split(r"\s+", rawstr, maxsplit=6)
    if len(raw) < 5:
        raise MessageError("Could node decode raw string: '%s ...'"
                           % str(rawstr[:36]))
    version = raw[4][:len(_VERSION)]
    if not _is_valid_version(version):
        raise MessageError("Invalid Message version: '%s'" % str(version))

    # Start to build message
    msg = dict((('subject', raw[0].strip()),
                ('type', raw[1].strip()),
                ('sender', raw[2].strip()),
                ('time', strp_isoformat(raw[3].strip())),
                ('version', version)))

    # Data part
    try:
        mimetype = raw[5].lower()
        data = raw[6]
    except IndexError:
        mimetype = None

    if mimetype is None:
        msg['data'] = ''
        msg['binary'] = False
    elif mimetype == 'application/json':
        try:
            msg['data'] = json.loads(raw[6], object_hook=datetime_decoder)
            msg['binary'] = False
        except ValueError:
            raise MessageError("JSON decode failed on '%s ...'" % raw[6][:36])
    elif mimetype == 'text/ascii':
        msg['data'] = str(data)
        msg['binary'] = False
    elif mimetype == 'binary/octet-stream':
        msg['data'] = data
        msg['binary'] = True
    else:
        raise MessageError("Unknown mime-type '%s'" % mimetype)

    return msg
Esempio n. 2
0
 def run(self):
     last_hb = datetime.now()
     minutes = 2
     while self._loop:
         if datetime.now() - last_hb > timedelta(minutes=minutes):
             logger.error("No heartbeat from " + str(self._pubaddress))
             last_hb = datetime.now()
             minutes = 1440
         socks = dict(self._poller.poll(2000))
         if (socks and self._subsocket in socks
                 and socks[self._subsocket] == POLLIN):
             message = Message.decode(self._subsocket.recv())
         else:
             continue
         if message.type == "have":
             sat = message.data["satellite"]
             key = strp_isoformat(message.data["timecode"])
             elevation = message.data["elevation"]
             quality = message.data.get("quality", 100)
             data = _MirrorGetter(self._req, sat, key)
             self._holder.add(sat, key, elevation, quality, data)
         if message.type == "heartbeat":
             logger.debug("Got heartbeat from " + str(self._pubaddress) +
                          ": " + str(message))
             self._sched.mirror_next_pass = message.data["next_pass"]
             last_hb = datetime.now()
             minutes = 2
Esempio n. 3
0
 def run(self):
     last_hb = datetime.now()
     minutes = 2
     while self._loop:
         if datetime.now() - last_hb > timedelta(minutes=minutes):
             logger.error("No heartbeat from " + str(self._pubaddress))
             last_hb = datetime.now()
             minutes = 1440
         socks = dict(self._poller.poll(2000))
         if (socks and
                 self._subsocket in socks and
                 socks[self._subsocket] == POLLIN):
             message = Message.decode(self._subsocket.recv())
         else:
             continue
         if message.type == "have":
             sat = message.data["satellite"]
             key = strp_isoformat(message.data["timecode"])
             elevation = message.data["elevation"]
             quality = message.data.get("quality", 100)
             data = _MirrorGetter(self._req, sat, key)
             self._holder.add(sat, key, elevation, quality, data)
         if message.type == "heartbeat":
             logger.debug("Got heartbeat from " + str(self._pubaddress)
                          + ": " + str(message))
             self._sched.mirror_next_pass = message.data["next_pass"]
             last_hb = datetime.now()
             minutes = 2
Esempio n. 4
0
    def run(self):

        for message in self._sub.recv(1):
            if message is None:
                continue
            if (message.type == "have"):
                logger.debug("Relaying " + str(message.data["timecode"]))
                self.scanlines.add_scanline(
                    message.data["satellite"],
                    strp_isoformat(message.data["timecode"]),
                    message.data["elevation"], None, self._reqaddr)
Esempio n. 5
0
 def scanline(self, message):
     """Reply to scanline request
     """
     sat = message.data["satellite"]
     key = strp_isoformat(message.data["utctime"])
     try:
         data = self._holder.get_data(sat, key)
     except KeyError:
         resp = Message(subject, "missing")
     else:
         resp = Message(subject, "scanline", data, binary=True)
     return resp
Esempio n. 6
0
    def run(self):

        for message in self._sub.recv(1):
            if message is None:
                continue
            if(message.type == "have"):
                logger.debug("Relaying " + str(message.data["timecode"]))
                self.scanlines.add_scanline(message.data["satellite"],
                                            strp_isoformat(message.data["timecode"]),
                                            message.data["elevation"],
                                            None,
                                            self._reqaddr)
Esempio n. 7
0
 def scanline(self, message):
     """Reply to scanline request
     """
     sat = message.data["satellite"]
     key = strp_isoformat(message.data["utctime"])
     try:
         data = self._holder.get_data(sat, key)
     except KeyError:
         resp = Message(subject, "missing")
     else:
         resp = Message(subject, "scanline", data, binary=True)
     return resp
Esempio n. 8
0
def datetime_decoder(dct):
    """Decode datetimes to python objects.
    """
    if isinstance(dct, list):
        pairs = enumerate(dct)
    elif isinstance(dct, dict):
        pairs = dct.items()
    result = []
    for key, val in pairs:
        if isinstance(val, six.string_types):
            try:
                val = strp_isoformat(val)
            except ValueError:
                pass
        elif isinstance(val, (dict, list)):
            val = datetime_decoder(val)
        result.append((key, val))
    if isinstance(dct, list):
        return [x[1] for x in result]
    elif isinstance(dct, dict):
        return dict(result)
Esempio n. 9
0
    def run(self):
        poller = Poller()
        poller.register(self._socket, POLLIN)

        while self._loop:
            socks = dict(poller.poll(timeout=2000))
            if self._socket in socks and socks[self._socket] == POLLIN:
                message = Message(rawstr=self._socket.recv(NOBLOCK))
                logger.debug("Request: " + str(message))
                # send list of scanlines
                if (message.type == "request"
                        and message.data["type"] == "scanlines"):
                    sat = message.data["satellite"]
                    epoch = "1950-01-01T00:00:00"
                    start_time = strp_isoformat(
                        message.data.get("start_time", epoch))
                    end_time = strp_isoformat(
                        message.data.get("end_time", epoch))

                    resp = Message(
                        '/oper/polar/direct_readout/' + self._station,
                        "scanlines",
                        [(utctime.isoformat(), self._holder[sat][utctime][2])
                         for utctime in self._holder.get(sat, [])
                         if utctime >= start_time and utctime <= end_time])
                    self._socket.send(str(resp))

                # send one scanline
                elif (message.type == "request"
                      and message.data["type"] == "scanline"):
                    sat = message.data["satellite"]
                    utctime = strp_isoformat(message.data["utctime"])
                    try:
                        url = urlparse(self._holder[sat][utctime][1])
                    except KeyError:
                        resp = Message(
                            '/oper/polar/direct_readout/' + self._station,
                            "missing")
                    else:
                        if url.scheme in ["",
                                          "file"]:  # data is locally stored.
                            resp = Message(
                                '/oper/polar/direct_readout/' + self._station,
                                "scanline",
                                self._holder.get_scanline(sat, utctime),
                                binary=True)
                        else:  # it's the address of a remote server.
                            resp = self.forward_request(
                                urlunparse(url), message)
                    self._socket.send(str(resp))

                # take in a new scanline
                elif (message.type == "notice"
                      and message.data["type"] == "scanline"):
                    sat = message.data["satellite"]
                    utctime = message.data["utctime"]
                    elevation = message.data["elevation"]
                    filename = message.data["filename"]
                    line_start = message.data["file_position"]
                    utctime = strp_isoformat(utctime)
                    self._holder.add_scanline(sat, utctime, elevation,
                                              line_start, filename)
                    resp = Message(
                        '/oper/polar/direct_readout/' + self._station,
                        "notice", "ack")
                    self._socket.send(str(resp))
                elif (message.type == "ping"):
                    resp = Message(
                        '/oper/polar/direct_readout/' + self._station, "pong",
                        {"station": self._station})
                    self._socket.send(str(resp))

                if resp.binary:
                    logger.debug("Response: " +
                                 " ".join(str(resp).split()[:6]))
                else:
                    logger.debug("Response: " + str(resp))
Esempio n. 10
0
    def run(self):
        poller = Poller()
        poller.register(self._socket, POLLIN)
        
        while self._loop:
            socks = dict(poller.poll(timeout=2000))
            if self._socket in socks and socks[self._socket] == POLLIN:
                message = Message(rawstr=self._socket.recv(NOBLOCK))
                logger.debug("Request: " + str(message))
                # send list of scanlines
                if(message.type == "request" and
                   message.data["type"] == "scanlines"):
                    sat = message.data["satellite"]
                    epoch = "1950-01-01T00:00:00"
                    start_time = strp_isoformat(message.data.get("start_time",
                                                                 epoch))
                    end_time = strp_isoformat(message.data.get("end_time",
                                                               epoch))

                    resp = Message('/oper/polar/direct_readout/' + self._station,
                                   "scanlines",
                                   [(utctime.isoformat(),
                                     self._holder[sat][utctime][2])
                                    for utctime in self._holder.get(sat, [])
                                    if utctime >= start_time
                                    and utctime <= end_time])
                    self._socket.send(str(resp))

                # send one scanline
                elif(message.type == "request" and
                     message.data["type"] == "scanline"):
                    sat = message.data["satellite"]
                    utctime = strp_isoformat(message.data["utctime"])
                    try:
                        url = urlparse(self._holder[sat][utctime][1])
                    except KeyError:
                        resp = Message('/oper/polar/direct_readout/'
                                       + self._station,
                                       "missing")
                    else:
                        if url.scheme in ["", "file"]: # data is locally stored.
                            resp = Message('/oper/polar/direct_readout/'
                                           + self._station,
                                           "scanline",
                                           self._holder.get_scanline(sat, utctime),
                                           binary=True)
                        else: # it's the address of a remote server.
                            resp = self.forward_request(urlunparse(url),
                                                        message)
                    self._socket.send(str(resp))

                # take in a new scanline
                elif(message.type == "notice" and
                     message.data["type"] == "scanline"):
                    sat = message.data["satellite"]
                    utctime = message.data["utctime"]
                    elevation = message.data["elevation"]
                    filename = message.data["filename"]
                    line_start = message.data["file_position"]
                    utctime = strp_isoformat(utctime)
                    self._holder.add_scanline(sat, utctime, elevation,
                                              line_start, filename)
                    resp = Message('/oper/polar/direct_readout/'
                                       + self._station,
                                       "notice",
                                       "ack")
                    self._socket.send(str(resp))
                elif(message.type == "ping"):
                    resp = Message('/oper/polar/direct_readout/'
                                   + self._station,
                                   "pong",
                                   {"station": self._station})
                    self._socket.send(str(resp))

                if resp.binary:
                    logger.debug("Response: " + " ".join(str(resp).split()[:6]))
                else:
                    logger.debug("Response: " + str(resp))