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
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
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)
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
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)
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)
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))
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))