def feedsealevel_api1(self, inst, secret, timestamp, value, station, **data): inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None: sta = self._db["stations"].find_one({ "inst": inst["name"], "name": station }) if sta is not None: data["timestamp"] = int(timestamp) data["value"] = value data["station"] = station data["inst"] = inst["name"] # update = { # "inst": inst["name"], # "station": station, # "timestamp": int(timestamp), # } if "evid" in data: data["_id"] = "{evid}_{station}_{timestamp!s}" \ .format_map(data) self._db["simsealeveldata"].save(data) else: data["_id"] = "{inst}_{station}_{timestamp!s}" \ .format_map(data) self._db["sealeveldata"].save(data) return jssuccess() return jsfail(errors=["There is no stations named %s." % station]) return jsdeny()
def feedstation(self, apiver, inst, secret, station): if apiver == "1": inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None and inst.get("feedstations", False): station = json.loads(station) if station is not None and "name" in station: station["inst"] = inst["name"] station["lastmetadataupdate"] = int(time.time()) res = self._db["stations"].update( { "inst": inst["name"], "name": station["name"] }, {"$set": station}) if not res["updatedExisting"]: self._db["stations"].insert(station) station = self._db["stations"].find_one({ "inst": inst["name"], "name": station["name"] }) return jssuccess(station=station) return jsfail(errors=["The station needs a name."]) return jsdeny() return jsfail(errors=["API version not supported."])
def displaymapmsg(self, apiver, msgid): user = self.getUser() if user is not None: if apiver == "1": self._db["messages_received"].update( { "Message-ID": msgid, "MapDisplayTime": None, "ReceiverID": user["_id"] }, {"$set": { "MapDisplayTime": datetime.datetime.utcnow() }}) msg = self._db["messages_received"].find_one({ "Message-ID": msgid, "ReceiverID": user["_id"] }) if msg is None: mdtime = None else: mdtime = msg["MapDisplayTime"] \ .strftime("%b %d, %Y %I:%M:%S %p") return jssuccess(mapdisplaytime=mdtime) return jsfail(errors=["API version not supported."]) return jsdeny()
def register(self, inst, secret, workerid, name, priority, providedsims): inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None: find = self._db["workers"].find_one({"workerid": workerid}) if find is None: worker = { "workerid": workerid, "inst": inst["name"], "name": name, "priority": int(priority), "providedsimtypes": [s.strip() for s in providedsims.split(",")], "state": "offline", "lastcontact": time.time(), "task": None, "progress": None, } self._db["workers"].insert(worker) return jssuccess() return jsfail() return jsdeny()
def intmsg(self, apiver, to, subject, text, evid=None, parentid=None, groupID=None, msgnr=None): user = self.getUser() if user is not None and user["permissions"].get("intmsg", False): if apiver == "1": dbmsg = { "Type": "INTERNAL", "SenderID": user["_id"], "CreatedTime": datetime.datetime.utcnow(), "EventID": evid, "ParentId": parentid, "Message-ID": make_msgid(), } if msgnr is not None: dbmsg["NextMsgNr"] = int(msgnr) dbmsg["Text"] = text dbmsg["Subject"] = subject errors = [] success = False send_to = to.replace(",", " ").replace(";", " ").split() for sto in send_to: ruser = self._db["users"].find_one({"username": sto}) if ruser is None: errors.append((sto, "Unknown User %s" % sto)) else: success = True rmsg = copy.deepcopy(dbmsg) rmsg["ReceiverID"] = ruser["_id"] rmsg["ReadTime"] = None rmsg["MapDisplayTime"] = None self._db["messages_received"].insert(rmsg) msgevt2 = { "id": rmsg["Message-ID"], "user": rmsg["ReceiverID"], "timestamp": dbmsg["CreatedTime"], "event": "msg_recv", } self._db["events"].insert(msgevt2) dbmsg["To"] = send_to dbmsg["errors"] = errors self._db["messages_sent"].insert(dbmsg) msgevt = { "id": dbmsg["Message-ID"], "user": dbmsg["SenderID"], "timestamp": dbmsg["CreatedTime"], "event": "msg_sent", } self._db["events"].insert(msgevt) if success: return jssuccess(errors=errors) return jsfail(errors=errors) return jsfail(errors=["API version not supported."]) return jsdeny()
def getenv(self, workerid): worker = self._db["workers"].find_one({"workerid": workerid}) if worker is not None: env = list(self._db["envfiles"].find()) for item in env: item.pop("_id") return jssuccess(env=env) return jsdeny()
def gettask(self, workerid, taskid): worker = self._db["workers"].find_one({"workerid": workerid}) if worker is not None: task = self._db["tasks"].find_one({"taskid": taskid}) if task is not None: return jssuccess(task=task) return jsfail() return jsdeny()
def ftp(self, apiver, fname, text, evid=None, parentid=None, groupID=None, msgnr=None): user = self.getUser() if user is not None and user["permissions"].get("ftp", False) and \ fname is not None and fname != "": if apiver == "1": dbmsg = { "Type": "FTP", "SenderID": user["_id"], "CreatedTime": datetime.datetime.utcnow(), "EventID": evid, "ParentId": parentid, "Message-ID": make_msgid(), } if msgnr is not None: dbmsg["NextMsgNr"] = int(msgnr) host = user["properties"].get("FtpHost", "") port = user["properties"].get("FtpPort", 21) path = user["properties"].get("FtpPath", "") + "/" + fname username = user["properties"].get("FtpUser", "anonymous") password = user["properties"].get("FtpPassword", "anonymous") dbmsg["To"] = ["%s@%s:%d%s" % (username, host, port, path)] dbmsg["Text"] = text error = None try: ftp = ftplib.FTP() ftp.connect(host, port) ftp.login(username, password) ftp.set_pasv(True) path = os.path.normpath(path) ftp.cwd(os.path.dirname(path)) ftp.storbinary("STOR %s" % os.path.basename(path), io.BytesIO(bytes(text, "utf-8"))) ftp.quit() except ftplib.all_errors as err: error = str(err) dbmsg["errors"] = error self._db["messages_sent"].insert(dbmsg) msgevt = { "id": dbmsg["Message-ID"], "user": dbmsg["SenderID"], "timestamp": dbmsg["CreatedTime"], "event": "msg_sent", } self._db["events"].insert(msgevt) if error is None: return jssuccess() return jsfail(errors=[error]) return jsfail(errors=["API version not supported."]) return jsdeny()
def feedhazardevent(self, apiver, inst, secret, event): if apiver == "1": inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None: return self.feed_hazard_event(jsonlib.loads(event)) return jsdeny() return jsfail(errors=["API version not supported."])
def setstate(self, workerid, state, progress=None, task=None): worker = self._db["workers"].find_one({"workerid": workerid}) if worker is not None: self._db["workers"].update({"workerid": workerid}, { "$set": { "state": state, "progress": progress, "task": task, "lastcontact": time.time() } }) return jssuccess() return jsdeny()
def feed(self, cls="auto", **data): if ("inst" in data and "secret" in data and self._db["institutions"].find_one({ "name": data["inst"], "secret": data["secret"] }) is not None): if cls == "auto": cls = self.guessclass(data) if cls is None: return jsfail(errors=["Auto recognizing data failed."]) if cls == "station": return self.feedstation(**data) if cls == "sealeveldata": return self.feedsealevel(**data) return jsfail(errors=["Unknown class %s." % cls]) return jsdeny()
def instsms(self, apiver, inst, secret, username, to, text): if apiver == "1": inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None and inst.get("instsms", False): to = to.replace(",", ";").split(";") user = self._db["users"].find_one({"username": username}) twisid = user["properties"].get("TwilioSID", "") twitoken = user["properties"].get("TwilioToken", "") twifrom = user["properties"].get("TwilioFrom", "") success, errors = sendtwilliosms(twisid, twitoken, twifrom, to, text) if success != []: return jssuccess(sentsmsids=success, errors=errors) return jsfail(errors=errors) return jsdeny() return jsfail(errors=["API version not supported."])
def scanenv(self, username=None, password=None): if username is None and password is None: user = self.getUser() else: user = self._db["users"].find_one({"username": username}) if user is not None: if "pwsalt" in user and "pwhash" in user: if not checkpassword(password, user["pwsalt"], user["pwhash"]): user = None if user is not None and user["permissions"].get("admin", False): self._db["envfiles"].remove() for file in recursivelistdir(config["simenv"]["envdir"]): elm = { "fname": os.path.relpath(file, config["simenv"]["envdir"]), "hash": hashfile(file), "size": os.stat(file).st_size, } elm["name"] = os.path.basename(elm["fname"]) elm["kind"] = os.path.dirname(elm["fname"]) self._db["envfiles"].insert(elm) return jssuccess(files=list(self._db["envfiles"].find())) return jsdeny()
def instmail(self, apiver, inst, secret, fromaddr, toaddr, subject, text, cc=""): if apiver == "1": inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None and inst.get("instmail", False): toaddr = toaddr.replace(",", " ").replace(";", " ").split() cc = cc.replace(",", " ").replace(";", " ").split() success, errors = sendmail(fromaddr, toaddr, subject, text, cc) if success: return jssuccess(errors=errors) return jsfail(errors=errors) return jsdeny() return jsfail(errors=["API version not supported."])
def feedsealevel_api2(self, inst, secret, json=None, xml=None, text=None, **data): inst = self._db["institutions"].find_one({ "name": inst, "secret": secret }) if inst is not None: if json is not None: return self.feedsealevel_api2_json(inst, json, **data) if xml is not None: return self.feedsealevel_api2_xml(inst, xml, **data) if text is not None: return self.feedsealevel_api2_text(inst, text, **data) return jsfail(errors=[ "One of the following Parameters is mandatory: " + "json, xml, text" ]) return jsdeny()
def sms(self, apiver, to, text, evid=None, parentid=None, groupID=None): user = self.getUser() if user is not None and user["permissions"].get("sms", False): if apiver == "1": dbmsg = { "Type": "SMS", "SenderID": user["_id"], "CreatedTime": datetime.datetime.utcnow(), "EventID": evid, "ParentId": parentid, "Message-ID": make_msgid(), } to = to.replace(",", ";").split(";") dbmsg["To"] = to dbmsg["Text"] = text twisid = user["properties"].get("TwilioSID", "") twitoken = user["properties"].get("TwilioToken", "") twifrom = user["properties"].get("TwilioFrom", "") success, errors = sendtwilliosms(twisid, twitoken, twifrom, to, text) dbmsg["sentsmsids"] = success dbmsg["errors"] = errors self._db["messages_sent"].insert(dbmsg) msgevt = { "id": dbmsg["Message-ID"], "user": dbmsg["SenderID"], "timestamp": dbmsg["CreatedTime"], "event": "msg_sent", } self._db["events"].insert(msgevt) if success != []: return jssuccess(sentsmsids=success, errors=errors) return jsfail(errors=errors) return jsfail(errors=["API version not supported."]) return jsdeny()
def fax(self, apiver, to, text, evid=None, parentid=None, groupID=None, msgnr=None): user = self.getUser() if user is not None and user["permissions"].get("fax", False): if apiver == "1": dbmsg = { "Type": "FAX", "SenderID": user["_id"], "CreatedTime": datetime.datetime.utcnow(), "EventID": evid, "ParentId": parentid, "Message-ID": make_msgid(), } if msgnr is not None: dbmsg["NextMsgNr"] = int(msgnr) to = to.replace(",", ";").split(";") dbmsg["To"] = to dbmsg["Text"] = text errors = [] success = [] for fnr in to: payload = {} payload["Username"] = user["properties"] \ .get("InterfaxUsername", "") payload["Password"] = user["properties"] \ .get("InterfaxPassword", "") payload["FileType"] = "HTML" payload["FaxNumber"] = fnr payload["Data"] = '<html><body><pre style="' + \ 'font-family: monospace; white-space: pre-wrap; ' + \ 'word-wrap: break-word;">' + text + \ '</pre></body></html>' req = requests.post( "https://ws.interfax.net/dfs.asmx/SendCharFax", data=payload) elm = ElementTree.fromstring(req.text) if int(elm.text) >= 0: success.append((fnr, elm.text)) else: errors.append((fnr, elm.text)) dbmsg["errors"] = errors dbmsg["sentfaxids"] = success self._db["messages_sent"].insert(dbmsg) msgevt = { "id": dbmsg["Message-ID"], "user": dbmsg["SenderID"], "timestamp": dbmsg["CreatedTime"], "event": "msg_sent", } self._db["events"].insert(msgevt) if success != []: return jssuccess(sentfaxids=success, errors=errors) return jsfail(errors=errors) return jsfail(errors=["API version not supported."]) return jsdeny()
def mail(self, apiver, to, subject, text, cc="", evid=None, parentid=None, groupID=None, msgnr=None): user = self.getUser() if user is not None and user["permissions"].get("mail", False): if apiver == "1": dbmsg = { "Type": "MAIL", "SenderID": user["_id"], "CreatedTime": datetime.datetime.utcnow(), "EventID": evid, "ParentId": parentid, } if msgnr is not None: dbmsg["NextMsgNr"] = int(msgnr) send_from = user["username"] send_to = to.replace(",", " ").replace(";", " ").split() send_cc = cc.replace(",", " ").replace(";", " ").split() send_subject = str(subject) send_text = str(text) send_date = formatdate() send_msgid = make_msgid() dbmsg["From"] = send_from if send_to != []: dbmsg["To"] = send_to if send_cc != []: dbmsg["Cc"] = send_cc dbmsg["Subject"] = send_subject dbmsg["Date"] = send_date dbmsg["Message-ID"] = send_msgid dbmsg["Text"] = send_text success, errors = sendmail(send_from, send_to, send_subject, send_text, send_cc, send_date, send_msgid) if errors != [] and success is not None: errtext = "There were errors while sending your Message.\n" for err in errors: errtext += "\n%s:\t%d: %s" % \ (err[0], err[1][0], err[1][1]) sendmail(user["username"], user["username"], "Error in mailing system", errtext) dbmsg["errors"] = errors self._db["messages_sent"].insert(dbmsg) msgevt = { "id": dbmsg["Message-ID"], "user": dbmsg["SenderID"], "timestamp": dbmsg["CreatedTime"], "event": "msg_sent", } self._db["events"].insert(msgevt) if success: return jssuccess(errors=errors) return jsfail(errors=errors) return jsfail(errors=["API version not supported."]) return jsdeny()
def waitforwork(self, workerid): worker = self._db["workers"].find_one({"workerid": workerid}) if worker is None: return jsdeny() self._db["workers"].update({"workerid": workerid}, {"$set": { "lastcontact": time.time() }}) def handler(self, workerid): count = 0 while count < 60: self._db["workers"].update( {"lastcontact": { "$lt": time.time() - 60 }}, {"$set": { "state": "offline" }}) task = self._db["tasks"].find_and_modify( {"state": "queued"}, update={"$set": { "state": "pending" }}, sort=[("created", 1)], new=True) if task is not None: if set(task.keys()).issuperset( set(["taskid", "simtype", "created", "state"])): print("queued task %s" % task["taskid"]) worker = self._db["workers"].find_and_modify( { "state": "idle", "providedsimtypes": { "$all": [task["simtype"]] } }, update={ "$set": { "state": "chosen", "task": task["taskid"] } }, sort=[("priority", 1)]) if worker is None: self._db["tasks"].update( {"_id": task["_id"]}, {"$set": { "state": "queued" }}) else: print("queued for worker %s" % worker["workerid"]) else: self._db["tasks"].update( {"_id": task["_id"]}, {"$set": { "state": "missing_parameter" }}) worker = self._db["workers"].find_one({"workerid": workerid}) if worker is not None and worker["task"] is not None: yield bytes( json.dumps({"taskid": worker["task"]}, cls=JSONEncoder), "utf-8") return if worker is not None and worker["state"] == "offline": return yield "\n" time.sleep(1) count += 1 return handler(self, workerid)