Example #1
0
 def _stopLoop(self):
     if self.loop is not None:
         try:
             self.loop.quit()
         except Exception as x:
             AVNLog.error("unable to stop dbus event loop %s" % str(x))
         self.loop = None
Example #2
0
 def writeFileFromInput(self, outname, rlen, overwrite=False, stream=None):
     if os.path.exists(outname) and not overwrite:
         raise Exception("file %s already exists" % outname)
     writename = outname + ".tmp"
     AVNLog.info("start upload of file %s", outname)
     fh = open(writename, "wb")
     if fh is None:
         raise Exception("unable to write to %s" % outname)
     if stream is None:
         stream = self.rfile
     bToRead = int(rlen)
     bufSize = 1000000
     try:
         while bToRead > 0:
             buf = stream.read(bufSize if bToRead >= bufSize else bToRead)
             if len(buf) == 0 or buf is None:
                 raise Exception("no more data received")
             bToRead -= len(buf)
             fh.write(buf)
         fh.close()
         if os.path.exists(outname):
             os.unlink(outname)
         os.rename(writename, outname)
     except:
         try:
             os.unlink(writename)
         except:
             pass
         raise
Example #3
0
 def do_POST(self):
     maxlen = 5000000
     (path, sep, query) = self.path.partition('?')
     if not path.startswith(self.server.navurl):
         self.send_error(404, "unsupported post url")
         return
     try:
         ctype, pdict = cgi.parse_header(
             self.headers.getheader('content-type'))
         if ctype == 'multipart/form-data':
             postvars = cgi.parse_multipart(self.rfile, pdict)
         elif ctype == 'application/x-www-form-urlencoded':
             length = int(self.headers.getheader('content-length'))
             if length > maxlen:
                 raise Exception("too much data" + unicode(length))
             postvars = cgi.parse_qs(self.rfile.read(length),
                                     keep_blank_values=1)
         elif ctype == 'application/json':
             length = int(self.headers.getheader('content-length'))
             if length > maxlen:
                 raise Exception("too much data" + unicode(length))
             postvars = {'_json': self.rfile.read(length)}
         else:
             postvars = {}
         requestParam = urlparse.parse_qs(query, True)
         requestParam.update(postvars)
         self.handleNavRequest(path, requestParam)
     except Exception as e:
         txt = traceback.format_exc()
         AVNLog.ld("unable to process request for ", path, query, txt)
         self.send_response(500, txt)
         self.end_headers()
         return
Example #4
0
    def handleNavRequest(self, path, requestParam):
        #check if we have something behind the navurl
        #treat this as a filename and set it ion the request parameter
        fname = path[(len(self.server.navurl) + 1):]
        if fname is not None and fname != "":
            fname = fname.split('?', 1)[0]
            if fname != "":
                if requestParam.get('filename') is None:
                    requestParam['filename'] = [fname.encode('utf-8')]
        requestType = requestParam.get('request')
        if requestType is None:
            requestType = 'gps'
        else:
            requestType = requestType[0]
        AVNLog.ld('navrequest', requestParam)
        try:
            rtj = None
            if requestType == 'gps' or requestType == 'self':
                rtj = self.handleGpsRequest(requestParam)
            elif requestType == 'nmeaStatus':
                rtj = self.handleNmeaStatus(requestParam)
            elif requestType == 'ais':
                rtj = self.handleAISRequest(requestParam)
            elif requestType == 'status':
                rtj = self.handleStatusRequest(requestParam)
            elif requestType == 'debuglevel' or requestType == 'loglevel':
                rtj = self.handleDebugLevelRequest(requestParam)
            elif requestType == 'listdir' or requestType == 'list':
                rtj = self.handleListDir(requestParam)
            elif requestType == 'download':
                #download requests are special
                # the dow not return json...
                self.handleDownloadRequest(requestParam)
                return
            elif requestType == 'upload':
                try:
                    rtj = self.handleUploadRequest(requestParam)
                except Exception as e:
                    AVNLog.error("upload error: %s", unicode(e))
                    rtj = json.dumps({'status': unicode(e)})
            elif requestType == 'delete':
                rtj = self.handleDeleteRequest(requestParam)

            elif requestType == 'capabilities':
                rtj = self.handleCapabilityRequest(requestParam)
            elif requestType == 'api':
                #new handling for dedicated requests for some handler
                type = self.getRequestParam(requestParam, 'type')
                rtj = self.handleSpecificRequest(requestParam, type)
            else:
                #legacy: have the api type as requestType
                rtj = self.handleSpecificRequest(requestParam, requestType)
            self.sendNavResponse(rtj, requestParam)
        except Exception as e:
            text = unicode(e)
            rtj = json.dumps(
                AVNUtil.getReturnData(error=text,
                                      stack=traceback.format_exc()))
            self.sendNavResponse(rtj, requestParam)
            return
Example #5
0
 def timeChanged(self):
     AVNLog.info("%s: time changed, re-register", self.getName())
     try:
         self._deregisterAll()
     except:
         pass
     self.stateSequence += 1
Example #6
0
 def log_message(self, format, *args):
     if self.id is None:
         self.id = AVNLog.getThreadId()
         if self.id is None:
             self.id = "?"
         threading.current_thread().setName("[%s]HTTPHandler" % (self.id))
     AVNLog.debug(format, *args)
Example #7
0
 def _newService(self, interface, protocol, name, stype, domain, flags):
     AVNLog.info("detected new service %s.%s at %i.%i", stype, name,
                 interface, protocol)
     try:
         self.foundServices.add(
             FoundService(stype, name, interface, protocol))
     except Exception as e:
         AVNLog.error("unable to add service: %s", e)
Example #8
0
def registerHandler(handler):
    """add a handler class"""
    if not issubclass(handler, worker.AVNWorker):
        raise TypeError("handler is not of type AVNWorker")
    name = handler.getConfigName()
    if handlerList.get(name) is not None:
        return
    logger.info("register handler %s", name)
    handlerList[name] = handler
Example #9
0
 def __init__(self, request, client_address, server):
     #allow write buffering
     #see https://lautaportti.wordpress.com/2011/04/01/basehttprequesthandler-wastes-tcp-packets/
     self.wbufsize = -1
     self.id = None
     self.getRequestParam = AVNUtil.getHttpRequestParam
     AVNLog.ld("receiver thread started", client_address)
     SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(
         self, request, client_address, server)
Example #10
0
 def setInfo(self,name,info,status,childId=None,canDelete=False,timeout=None):
   existing=self.status.get(name)
   if existing:
     if existing.update(status,info,timeout=timeout):
       AVNLog.info("%s",str(existing))
       return True
   else:
     ns=WorkerStatus(name,status,info,childId=childId,canDelete=canDelete,timeout=timeout)
     self.status[name]=ns
     AVNLog.info("%s",str(ns))
Example #11
0
 def _runInternal(self):
   self.usedResources=[]
   AVNLog.info("run started")
   try:
     self.run()
     self.setInfo('main','handler stopped',WorkerStatus.INACTIVE)
   except Exception as e:
     self.setInfo('main','handler stopped with %s'%str(e),WorkerStatus.ERROR)
     AVNLog.error("handler run stopped with exception %s",traceback.format_exc())
   self.usedResources=[]
   self.currentThread=None
Example #12
0
 def getThreadPrefix(self):
     '''
 nicely compute the name prefix for a thread
 if we have the default name (just from the config name) - avoid to have this twice
 @return:
 '''
     n = self.getName()
     if "AVN%s" % n == self.getConfigName():
         return "[ %s]-%s" % (AVNLog.getThreadId(), n)
     else:
         return "[ %s]-%s-%s" % (AVNLog.getThreadId(), self.getConfigName(),
                                 n)
Example #13
0
    def handleDownloadRequest(self, requestParam):
        type = self.getRequestParam(requestParam, "type")
        try:
            handler = self.server.getRequestHandler('download', type)
            if handler is not None:
                AVNLog.debug("found handler %s to handle download %s" %
                             (handler.getConfigName(), type))
                dl = handler.handleApiRequest('download',
                                              type,
                                              requestParam,
                                              handler=self)
                if dl is None:
                    raise Exception("unable to download %s", type)
                if dl.get('mimetype') is None:
                    raise Exception("no mimetype")
                if dl.get('size') is None:
                    raise Exception("no size")
                if dl.get("stream") is None:
                    raise Exception("missing stream")
                self.send_response(200)
                fname = self.getRequestParam(requestParam, "filename")
                if fname is not None and fname != "" and self.getRequestParam(
                        requestParam, 'noattach') is None:
                    self.send_header("Content-Disposition", "attachment")
                self.send_header("Content-type", dl['mimetype'])
                self.send_header("Content-Length", dl['size'])
                self.send_header("Last-Modified", self.date_time_string())
                self.end_headers()
                try:
                    self.writeStream(dl['size'], dl['stream'])
                except:
                    try:
                        dl['stream'].close()
                    except:
                        pass
                return

        except Exception as e:
            if self.getRequestParam(requestParam, 'noattach') is None:
                #send some empty data
                data = StringIO.StringIO("error: %s" % e.message)
                data.seek(0)
                self.send_response(200)
                self.send_header("Content-type", "application/octet-stream")
                try:
                    self.copyfile(data, self.wfile)
                finally:
                    data.close()
            else:
                self.send_error(404, traceback.format_exc(1))
            return
        self.send_error(404, "invalid download request %s" % type)
Example #14
0
 def handleDebugLevelRequest(self, requestParam):
     rt = {'status': 'ERROR', 'info': 'missing parameter'}
     level = self.getRequestParam(requestParam, 'level')
     if not level is None:
         crt = AVNLog.changeLogLevel(level)
         if crt:
             rt['status'] = 'OK'
             rt['info'] = 'set loglevel to ' + str(level)
         else:
             rt['info'] = "invalid level " + str(level)
     filter = self.getRequestParam(requestParam, 'filter')
     AVNLog.setFilter(filter)
     return json.dumps(rt)
Example #15
0
 def startStopAlarm(self, start, name=ALARMS.waypoint):
     alert = self.findHandlerByName("AVNAlarmHandler")
     if alert is None:
         return
     if start:
         if self.activatedAlarms.get(name) is None:
             AVNLog.info("starting alarm %s", name)
         self.activatedAlarms[name] = True
         alert.startAlarm(name)
     else:
         if self.activatedAlarms.get(name) is not None:
             AVNLog.info("stopping alarm %s", name)
             del self.activatedAlarms[name]
         alert.stopAlarm(name)
Example #16
0
 def sendNavResponse(self, rtj, requestParam):
     if not rtj is None:
         self.send_response(200)
         if not requestParam.get('callback') is None:
             rtj = "%s(%s);" % (requestParam.get('callback'), rtj)
             self.send_header("Content-type", "text/javascript")
         else:
             self.send_header("Content-type", "application/json")
         self.send_header("Content-Length", str(len(rtj)))
         self.send_header("Last-Modified", self.date_time_string())
         self.end_headers()
         self.wfile.write(rtj)
         AVNLog.ld("nav response", rtj)
     else:
         raise Exception("empty response")
Example #17
0
 def getTileData(self, tile, source):
     if not self.isOpen:
         raise Exception("not open")
     request = QueueEntry(tile)
     self.cond.acquire()
     try:
         self.requestQueue.append(request)
         self.cond.notify_all()
     except:
         pass
     self.cond.release()
     AVNLog.debug("waiting for tile")
     data = request.waitAndGet()
     AVNLog.debug("tile received")
     return data
Example #18
0
 def _deregister(self, description: ServiceDescription) -> object:
     if description.group is None:
         description.reset()
         return
     try:
         AVNLog.info("deregister")
         description.reset()
         description.group.Reset()
         description.group.Free()
         description.group = None
         self.deleteInfo(description.getKey())
     except Exception as e:
         AVNLog.error("unable to deregister: %s", str(e))
         self.setInfo(description.getKey(),
                      "error in deregister %s" % str(e), WorkerStatus.ERROR)
Example #19
0
 def handleDeleteRequest(self, requestParam):
     type = self.getRequestParam(requestParam, "type")
     if type is None:
         raise Exception("no type for delete")
     handler = self.server.getRequestHandler('delete', type)
     rt = {'status': 'OK'}
     if handler is not None:
         AVNLog.debug("found handler for delete request %s:%s" %
                      (type, handler.getConfigName()))
         handler.handleApiRequest('delete',
                                  type,
                                  requestParam,
                                  handler=self)
         return json.dumps(rt)
     raise Exception("invalid type %s" % type)
Example #20
0
 def handleGemfRequest(self, path, query):
     try:
         path = path.replace("/gemf/", "", 1)
         parr = path.split("/")
         gemfname = parr[0] + ".gemf"
         for g in self.server.gemflist.values():
             if g['name'] == gemfname:
                 AVNLog.debug("gemf file %s, request %s, lend=%d", gemfname,
                              path, len(parr))
                 #found file
                 #basically we can today handle 2 types of requests:
                 #get the overview /gemf/<name>/avnav.xml
                 #get a tile /gemf/<name>/<srcname>/z/x/y.png
                 if parr[1] == self.server.navxml:
                     AVNLog.debug("avnav request for GEMF %s", gemfname)
                     data = g['avnav']
                     self.send_response(200)
                     self.send_header("Content-type", "text/xml")
                     self.send_header("Content-Length", len(data))
                     self.send_header("Last-Modified",
                                      self.date_time_string())
                     self.end_headers()
                     self.wfile.write(data)
                     return None
                 if len(parr) != 5:
                     raise Exception("invalid request to GEMF file %s: %s" %
                                     (gemfname, path))
                 data = g['gemf'].getTileData((int(parr[2]), int(
                     parr[3]), int(parr[4].replace(".png", ""))), parr[1])
                 if data is None:
                     empty = self.server.emptytile
                     if empty is not None:
                         data = empty
                 if data is None:
                     self.send_error(404, "File %s not found" % (path))
                     return None
                 self.send_response(200)
                 self.send_header("Content-type", "image/png")
                 self.send_header("Content-Length", len(data))
                 self.send_header("Last-Modified", self.date_time_string())
                 self.end_headers()
                 self.wfile.write(data)
                 return None
         raise Exception("gemf file %s not found" % (gemfname))
     except:
         self.send_error(500, "Error: %s" % (traceback.format_exc()))
         return
Example #21
0
 def handleCurrentLevelRequest(self, requestParam):
     (level, filter) = AVNLog.getCurrentLevelAndFilter()
     return json.dumps({
         'status': 'OK',
         'level': level,
         'filter': filter
     },
                       cls=Encoder)
Example #22
0
  def startInstance(self,navdata):
    """

    @type navdata: AVNStore
    """
    self.navdata=navdata
    self.feeder = self.findFeeder(self.getStringParam('feederName'))
    try:
      self.checkConfig(self.param)
    except Exception as e:
      self.setInfo('main','%s'%str(e),WorkerStatus.ERROR)
      raise
    if not self.isDisabled():
      self.startThread()
    else:
      self.setInfo('main','disabled',WorkerStatus.INACTIVE)
      AVNLog.info("not starting %s (disabled) with config %s", self.getName(), self.getConfigString())
Example #23
0
 def fillInfo(self, baseDir):
     routeFile = os.path.join(baseDir, self.name)
     try:
         if os.path.isfile(routeFile):
             content = ""
             with open(routeFile, "r", encoding='utf-8') as f:
                 content = f.read()
             parser = gpxparser.GPXParser(content)
             gpx = parser.parse()
             if gpx.routes is None or len(gpx.routes) == 0:
                 AVNLog.error("no routes in %s", routeFile)
             else:
                 route = gpx.routes[0]
                 self.numpoints = len(route.points)
                 self.length = route.length() / AVNUtil.NM
     except Exception as e:
         AVNLog.error("error when parsing route %s: %s", routeFile, str(e))
Example #24
0
 def computeAnchor(self):
     curGps = self.navdata.getDataByPrefix(AVNStore.BASE_KEY_GPS, 1)
     lat = curGps.get('lat')
     lon = curGps.get('lon')
     if lat is None or lon is None:
         self.startStopAlarm(False, self.ALARMS.anchor)
         if self.activatedAlarms.get(self.ALARMS.gps) is None:
             self.startStopAlarm(True, self.ALARMS.gps)
         return
     self.startStopAlarm(False, self.ALARMS.gps)
     anchorDistance = AVNUtil.distanceM(
         (lat, lon), self.wpToLatLon(self.currentLeg.getFrom()))
     AVNLog.debug("Anchor distance %d, allowed %d", anchorDistance,
                  self.currentLeg.getAnchorDistance())
     if anchorDistance > self.currentLeg.getAnchorDistance():
         self.startStopAlarm(True, self.ALARMS.anchor)
     return
Example #25
0
    def handleListDir(self, requestParam):
        type = self.getRequestParam(requestParam, "type")
        if type is None:
            raise Exception("no type for listdir")
        handler = self.server.getRequestHandler('list', type)
        if handler is not None:
            AVNLog.debug("found handler for list request %s:%s" %
                         (type, handler.getConfigName()))
            rt = handler.handleApiRequest('list',
                                          type,
                                          requestParam,
                                          handler=self)
            if rt is None:
                raise Exception("invalid list response")
            return json.dumps(rt)

        raise Exception("invalid type %s" % type)
Example #26
0
 def resolveService(self, type, name):
     '''
 resove a service (IPv4)
 @param type: the service type
 @param name: the service name
 @return: a tuple (hostname,ip,port) if found or None otherwise
 '''
     if self.server is None:
         return None
     try:
         res = self.server.ResolveService(self.IF_UNSPEC, self.PROTO_INET,
                                          name, type, "local",
                                          self.PROTO_INET, 0)
         return (str(res[5]), str(res[7]), int(res[8]))
     except Exception as e:
         AVNLog.error("unable to resolve service %s.%s: %s", type, name,
                      str(e))
         return None
Example #27
0
 def periodicRun(self):
     hasLeg = False
     hasRMB = False
     if self.currentLeg and self.currentLeg.isActive():
         hasLeg = True
         if self.currentLeg.getAnchorDistance() is not None:
             routerInfo = "Anchor watch, from %s, (anchor radius %sm)" % (
                 str(self.currentLeg.getFrom()),
                 str(self.currentLeg.getAnchorDistance()))
         else:
             routerInfo = "from %s, to %s, route=%s, activeWp=%s, approach=%s (approach radius %sm)" % (
                 str(self.currentLeg.getFrom()), str(
                     self.currentLeg.getTo()),
                 self.currentLeg.getRouteName(),
                 self.currentLeg.getCurrentTarget(),
                 self.currentLeg.isApproach(),
                 self.currentLeg.getApproachDistance())
         AVNLog.debug(routerInfo)
         self.setInfo("leg", routerInfo, WorkerStatus.RUNNING)
     try:
         if self.currentLeg is not None and self.currentLeg.getAnchorDistance(
         ) is not None:
             self.computeAnchor()
         else:
             self.startStopAlarm(False, self.ALARMS.anchor)
             self.startStopAlarm(False, self.ALARMS.gps)
             computeRMB = self.getBoolParam("computeRMB")
             computeAPB = self.getBoolParam("computeAPB")
             if computeRMB or computeAPB:
                 hasRMB = self.computeRMB(computeRMB, computeAPB)
     except Exception as e:
         AVNLog.warn("exception in computeRMB %s, retrying",
                     traceback.format_exc())
     try:
         self.computeApproach()
     except:
         AVNLog.warn("exception in computeApproach %s, retrying",
                     traceback.format_exc())
     if (not hasLeg):
         self.setInfo("leg", "no leg", WorkerStatus.INACTIVE)
     if (not hasRMB):
         self.setInfo("autopilot", "no autopilot data",
                      WorkerStatus.INACTIVE)
     try:
         lat = self.navdata.getSingleValue(AVNStore.BASE_KEY_GPS + ".lat")
         lon = self.navdata.getSingleValue(AVNStore.BASE_KEY_GPS + ".lon")
         if lat is not None and lon is not None:
             self.startStopAlarm(False, self.ALARMS.gps)
     except:
         pass
     AVNLog.debug("router main loop")
Example #28
0
 def createOverview(self):
     zoomlevels = []
     zoomLevelBoundings = {}
     connection = sqlite3.connect(self.filename)
     if connection is None:
         raise Exception("unable to open mbtiles file %s" % (self.filename))
     AVNLog.info("opening mbtiles file %s", self.filename)
     cu = None
     hasAvnavScheme = False
     try:
         cu = connection.cursor()
         for sr in cu.execute("select value from metadata where name=?",
                              ["avnav_scheme"]):
             v = sr[0]
             if v is not None:
                 v = v.lower()
                 if v in ['tms', 'xyz']:
                     AVNLog.info("setting scheme for %s to %s",
                                 self.filename, v)
                     self.schemeTMS = False if v == "xyz" else True
                     self.schemeInconsistent = False
                     hasAvnavScheme = True
         #check if there is a schema entry
         for sr in cu.execute("select value from metadata where name=?",
                              ["scheme"]):
             v = sr[0]
             if v is not None:
                 v = v.lower()
                 self.originalScheme = v
                 if not hasAvnavScheme:
                     self.schemeInconsistent = True
         for zl in cu.execute("select distinct zoom_level from tiles;"):
             zoomlevels.append(zl[0])
         for zl in zoomlevels:
             el = {}
             for rowmima in cu.execute(
                     "select min(tile_row),max(tile_row) from tiles where zoom_level=?",
                 [zl]):
                 # names must match getGemfInfo in create_overview
                 if self.schemeTMS:
                     el['ymin'] = self.rowToY(zl, rowmima[1])
                     el['ymax'] = self.rowToY(zl, rowmima[0])
                 else:
                     el['ymin'] = self.rowToY(zl, rowmima[0])
                     el['ymax'] = self.rowToY(zl, rowmima[1])
             for colmima in cu.execute(
                     "select min(tile_column),max(tile_column) from tiles where zoom_level=?",
                 [zl]):
                 el['xmin'] = self.colToX(zl, colmima[0])
                 el['xmax'] = self.colToX(zl, colmima[1])
             zoomLevelBoundings[zl] = el
     except Exception as e:
         AVNLog.error("error reading base info from %s:%s", self.filename,
                      str(e))
     self.zoomlevels = zoomlevels
     self.zoomLevelBoundings = zoomLevelBoundings
     if cu is not None:
         cu.close()
     connection.close()
     self.changeCount = AVNUtil.utcnow()
Example #29
0
 def setCurrentLeg(self, leg):
     # type: (AVNRoutingLeg) -> object
     changed = self.currentLeg == None or not self.currentLeg.equal(leg)
     if changed:
         self.navdata.updateChangeCounter(self.LEG_CHANGE_KEY)
     self.currentLeg = leg
     if leg is None:
         if os.path.exists(self.currentLegFileName):
             os.unlink(self.currentLegFileName)
             AVNLog.info("current leg removed")
         return
     AVNLog.info("new leg %s", str(leg))
     f = open(self.currentLegFileName, "w", encoding='utf-8')
     try:
         f.write(json.dumps(leg.getJson()))
     except:
         f.close()
         raise
     f.close()
     if not leg.isActive():
         self.computeApproach(
         )  #ensure that we immediately switch off alarms
Example #30
0
 def handleUploadRequest(self, requestParam):
     rlen = None
     try:
         rlen = self.headers.get("Content-Length")
         if rlen is None:
             raise Exception("Content-Length not set in upload request")
         self.connection.settimeout(30)
         type = self.getRequestParam(requestParam, "type")
         handler = self.server.getRequestHandler("upload", type)
         if handler is not None:
             AVNLog.debug("found handler for upload request %s:%s" %
                          (type, handler.getConfigName()))
             rt = handler.handleApiRequest("upload",
                                           type,
                                           requestParam,
                                           rfile=self.rfile,
                                           flen=rlen,
                                           handler=self)
             return json.dumps(rt)
         else:
             raise Exception("invalid request %s", type)
     except Exception as e:
         return json.dumps({'status': unicode(e)})