Beispiel #1
0
    def restart(self, httpRequest=None):
        headers = None
        if self.authenticationKey is not None:
            headers = {"Cookie": "token=" + self.authenticationKey}

        if httpRequest is not None:
            context = httpRequest.context
        else:
            context = KContext()
            context.originDevId = self.id
            context.originDevType = self.type
            context.originContainerId = self.id
            context.originGroup = self.groupName

        context.targetDevType = "container"

        for devId in self.clients:
            item = self.clients[devId]
            if item["type"] == "container":
                ret, retType, retData = sendHTTPRequest(urljoin(
                    item["url"], "container/" + str(devId) + "/restart"),
                                                        "GET",
                                                        headers=headers)

        return super().restart(httpRequest)
Beispiel #2
0
    def shutdown(self, httpRequest):

        self.logger.info("Shutdown detected.")
        headers = None
        if self.authenticationKey is not None:
            headers = {"Cookie": "token=" + self.authenticationKey}

        context = httpRequest.context
        context.targetDevType = "container"

        for devId in self.clients:
            item = self.clients[devId]
            if item["type"] == "container":
                self.logger.debug("Shutting down device: " + str(devId))
                ret, retType, retData = sendHTTPRequest(urljoin(
                    item["url"], "container/" + str(devId) + "/stop"),
                                                        "GET",
                                                        headers=headers,
                                                        context=context)

        return self.stop(httpRequest)
Beispiel #3
0
    def upgradeAll(self, httpRequest=None):
        headers = None
        if self.authenticationKey is not None:
            headers = {"Cookie": "token=" + self.authenticationKey}

        if httpRequest is not None:
            context = httpRequest.context
        else:
            context = KContext()
            context.originDevId = self.id
            context.originDevType = self.type
            context.originContainerId = self.id
            context.originGroup = self.groupName

        context.isInput = True

        finalRet = True

        for devId in self.clients:
            item = self.clients[devId]
            if "upgrade" in item["accepts"]:
                context.targetDevId = devId
                context.targetDevType = self.clients[devId]["type"]

                ret, retType, retData = sendHTTPRequest(urljoin(
                    item["url"], "device/" + str(devId) + "/upgrade"),
                                                        "GET",
                                                        headers=headers,
                                                        context=context)
                if not ret:
                    self.logger.error("Upgrade failed for device " +
                                      str(devId))
                    finalRet = False

        if not self.upgrade(httpRequest):
            finalRet = False

        return finalRet
Beispiel #4
0
    def status(self, httpRequest):
        headers = None
        if self.authenticationKey is not None:
            headers = {"Cookie": "token=" + self.authenticationKey}

        stat = self._getStatus()

        context = httpRequest.context
        context.targetDevType = "container"

        # Real-time
        for devId in self.clients:
            item = self.clients[devId]
            if item["url"] not in stat and item["type"] == "container":
                context.targetDevType = item["type"]
                ret, retType, retData = sendHTTPRequest(urljoin(
                    item["url"], "container/" + str(devId) + "/status"),
                                                        "GET",
                                                        headers=headers,
                                                        context=context)
                if ret:
                    stat[item["url"]] = retData[item["url"]]

        return httpRequest.sendJSON(stat)
Beispiel #5
0
    def _processRequest(self, httpRequest):

        headers = None
        if self.authenticationKey is not None:
            headers = {"Cookie": "token=" + self.authenticationKey}

        if httpRequest.isAuthRequest:
            return super()._processRequest(httpRequest)

        if httpRequest.isFileRequest:
            return self._processFileRequest(httpRequest)

        if not httpRequest.authenticated:
            return httpRequest.sendRedirect("/admin/login.html")

        if httpRequest.isDeviceRequest \
                and httpRequest.item in self.clients \
                and self.my_url != self.clients[httpRequest.item]["url"]:

            # Forward request to client
            reqUrl = urljoin(self.clients[httpRequest.item]["url"],
                             httpRequest.path)

            if reqUrl not in self.streams:
                self.streams[reqUrl] = {"contentType": None, "clients": []}

            if reqUrl in self.streams \
                    and len(self.streams[reqUrl]["clients"]) > 0:

                # We're just pass thru here so resend exactly what we get
                sclient = TCPStreamingClient(httpRequest.socket,
                                             includeHeader=True,
                                             includeBoundary=True,
                                             includeImageHeader=True)

                sclient.start()
                self.streams[reqUrl]["clients"].append(sclient)

                return True

            if httpRequest.isJSON:
                ret, retType, retData = sendHTTPRequest(
                    urljoin(self.clients[httpRequest.item]["url"],
                            httpRequest.path),
                    type=httpRequest.command,
                    jsonData=httpRequest.JSONData,
                    headers=headers,
                    context=httpRequest.context)

            else:
                ret, retType, retData = sendHTTPRequest(
                    urljoin(self.clients[httpRequest.item]["url"],
                            httpRequest.path),
                    type=httpRequest.command,
                    headers=headers,
                    context=httpRequest.context)

            if retType == "application/json":
                return httpRequest.sendJSON(contentBody=retData,
                                            contentType="application/json")

            elif retType.startswith("multipart/x-mixed-replace"):

                if self.streams[reqUrl]["contentType"] is None:
                    self.streams[reqUrl]["contentType"] = retType

                cType, cParam = parse_header(
                    retData.headers.get("content-type"))
                boundary = cParam["boundary"]
                boundary = ("\n--" + boundary).encode()
                endHeaders = "\n\n".encode()
                sock = httpRequest.socket

                # Relaying messages that already have this info
                sclient = TCPStreamingClient(sock,
                                             includeHeader=True,
                                             includeBoundary=True,
                                             includeImageHeader=True)

                sclient.start()

                self.streams[reqUrl]["clients"].append(sclient)

                part = None
                try:
                    for data in retData.iter_content(chunk_size=64):
                        if len(self.streams[reqUrl]["clients"]) == 0:
                            break

                        p = data.find(boundary)
                        if p > 0:

                            part += data[:p]

                            iEnd = part.find(endHeaders)
                            if iEnd >= 0:
                                # Parse Headers:
                                #
                                # hdrs = part[len(boundary):iEnd].decode().strip().split("\n")
                                # for item in hdrs:
                                #     if item.lower().startswith("x-timestamp: "):
                                #         timeStamp = item[12:]
                                #         import datetime
                                #         print(datetime.datetime.fromtimestamp(float(timeStamp.strip())).strftime('%Y-%m-%d %H:%M:%S.%f'))
                                #         break

                                part = part[iEnd + len(endHeaders):]

                            for c in self.streams[reqUrl]["clients"]:
                                if c.connected:

                                    # Prevent overloading stream to
                                    # keep output current
                                    if c.streamQueue.empty():
                                        c.bufferStreamData(part)
                                    else:
                                        # Dropping frame
                                        pass
                                else:
                                    c.logger.debug(
                                        "Streaming client disconnected.")
                                    self.streams[reqUrl]["clients"].remove(c)

                            part = data[p:]

                        else:
                            if part is None:
                                part = data
                            else:
                                part += data

                except Exception:
                    return True

            return httpRequest.sendHTTP(contentBody=retData,
                                        contentType=retType)

        # Default
        return super()._processRequest(httpRequest)
Beispiel #6
0
    def say(self, text, context=None):

        headers = None
        if self.authenticationKey is not None:
            headers = {"Cookie": "token=" + self.authenticationKey}

        targetDevId = None
        targetDevType = None
        targetContainerId = None
        targetGroup = None

        if context is not None:
            targetDevId = context.targetDevId
            targetDevType = context.targetDevType
            targetContainerId = context.targetContainerId
            targetGroup = context.targetGroup

        bFound = False
        speakerId = None

        # Check levels
        # * Device (if specified)
        # * Container (if specified) + Type (if specified)
        # * Group (if specified) + Type (if specified)
        # * Anywhere

        # Check if we are targeting a specific speaker
        if targetDevId is not None and targetDevId in self.clients:
            if targetDevType is None or targetDevType == self.clients[
                    targetDevId]["type"]:
                if "speak" in self.clients[targetDevId]["accepts"]:
                    speakerId = targetDevId

                    if targetGroup is not None:
                        groupName = targetGroup
                    elif "groupName" in self.clients[speakerId]:
                        groupName = self.clients[speakerId]["groupName"]
                    else:
                        None

                    bFound = True

        # Check if we are targeting a specific container
        if not bFound and targetContainerId is not None:
            for devId in self.clients:
                item = self.clients[devId]
                if targetDevType is None or targetDevType == item["type"]:
                    if (targetContainerId == item["containerId"]
                        ) and "speak" in item["accepts"]:
                        speakerId = devId
                        groupName = item[
                            "groupName"] if "groupName" in item else None
                        bFound = True

        # Check if we are targeting a group
        if not bFound and targetGroup is not None:
            for devId in self.clients:
                item = self.clients[devId]
                if targetDevType is None or targetDevType == item["type"]:
                    if (targetGroup == item["groupName"]
                        ) and "speak" in item["accepts"]:
                        speakerId = devId
                        groupName = item[
                            "groupName"] if "groupName" in item else None
                        bFound = True

        # Fall back: Check for a speaker even if it isn't at the origin device, container, or in the group
        if not bFound:
            for devId in self.clients:
                item = self.clients[devId]
                if "speak" in self.clients[devId]["accepts"]:
                    speakerId = devId
                    groupName = self.clients[devId][
                        "groupName"] if "groupName" in self.clients[
                            devId] else None
                    bFound = True

        if not bFound:
            return False

        for devId in self.clients:
            item = self.clients[devId]
            if "audioOutStart" in self.clients[devId]["accepts"] and (
                    groupName is None
                    or groupName == self.clients[devId]["groupName"]):
                sendHTTPRequest(urljoin(
                    item["url"], "device/" + str(devId) + "/audioOutStart"),
                                "GET",
                                headers=headers)[0]

        ret = sendHTTPRequest(urljoin(self.clients[speakerId]["url"],
                                      "device/" + str(speakerId) + "/speak"),
                              "POST",
                              jsonData={"text": text},
                              headers=headers)[0]

        for devId in self.clients:
            item = self.clients[devId]
            if "audioOutEnd" in self.clients[devId]["accepts"] and (
                    groupName is None
                    or groupName == self.clients[devId]["groupName"]):
                sendHTTPRequest(urljoin(
                    item["url"], "device/" + str(devId) + "/audioOutEnd"),
                                "GET",
                                headers=headers)[0]

        return ret