Esempio n. 1
0
    def get_native(native_type, value):
        """
Returns the native value for the given variable definition and UPnP encoded
value.

:param native_type: Native type definition
:param value: Native python value

:return: (str) UPnP encoded value
:since:  v0.2.00
        """

        if (type(native_type) is tuple):
            if (native_type[1] == "xmlns"): _return = value
            elif (native_type[1] == "base64"): _return = Binary.raw_str(b64decode(Binary.utf8_bytes(value)))
            elif (native_type[1] == "date"): _return = RfcBasics.get_iso8601_timestamp(value, has_time = False)
            elif (native_type[1] == "dateTime"): _return = RfcBasics.get_iso8601_timestamp(value, has_timezone = False)
            elif (native_type[1] == "dateTime.tz"): _return = RfcBasics.get_iso8601_timestamp(value)
            elif (native_type[1] == "hex"): _return = Binary.raw_str(unhexlify(Binary.utf8_bytes(value)))
            elif (native_type[1] == "time"): _return = RfcBasics.get_iso8601_timestamp(value, False, has_timezone = False)
            elif (native_type[1] == "time.tz"): _return = RfcBasics.get_iso8601_timestamp(value, False)
            elif (native_type[1] == "uri" and re.match("^\\w+\\:\\w", value) is None): raise ValueException("Given value mismatches defined format for URIs")
            elif (native_type[1] == "uuid" and (not value.startswith("uuid:"))): raise ValueException("Given value mismatches defined format for UUIDs")
            elif (native_type[0] is not str): _return = native_type[0](value)
        elif (native_type is not str): _return = native_type(value)
        else: _return = value

        return _return
Esempio n. 2
0
    def _read_upnp_descs(self):
        """
Parse unread UPnP descriptions.

:since: v0.2.00
        """

        # pylint: disable=broad-except

        if (self.log_handler is not None): self.log_handler.debug("#echo(__FILEPATH__)# -{0!r}._read_upnp_descs()- (#echo(__LINE__)#)", self, context = "pas_upnp")

        upnp_desc_unread = self.upnp_desc_unread.copy()

        for url in upnp_desc_unread:
            try:
                if (self.log_handler is not None): self.log_handler.debug("{0!r} reads UPnP device description from '{1}'", self, url, context = "pas_upnp")

                usns = upnp_desc_unread[url]

                http_client = HttpClient(url, event_handler = self.log_handler)
                http_client.set_header("Accept-Language", self.http_language)
                http_client.set_header("User-Agent", ControlPoint.get_pas_upnp_http_client_identifier_string())
                http_client.set_ipv6_link_local_interface(Settings.get("pas_global_ipv6_link_local_interface"))

                http_response = http_client.request_get()

                if (http_response.is_readable()):
                    with self.lock:
                        if (url in self.upnp_desc): self.upnp_desc[url]['xml_data'] = Binary.raw_str(http_response.read())
                        else: self.upnp_desc[url] = { "xml_data": Binary.raw_str(http_response.read()), "usns": [ ] }

                        if (url in self.upnp_desc_unread): del(self.upnp_desc_unread[url])

                        for usn in usns:
                            if (usn in self.usns and usn not in self.upnp_desc[url]['usns']):
                                self.upnp_desc[url]['usns'].append(usn)

                                Hook.call("dNG.pas.upnp.ControlPoint.onUsnAdded", identifier = self.usns[usn])
                                if (self.usns[usn]['class'] == "device"): Hook.call("dNG.pas.upnp.ControlPoint.onDeviceAdded", identifier = self.usns[usn])
                            #
                        #
                    #
                else:
                    if (self.log_handler is not None): self.log_handler.error(http_response.get_error_message(), context = "pas_upnp")

                    with self.lock:
                        if (url in self.upnp_desc_unread): del(self.upnp_desc_unread[url])
                    #

                    self._delete_usns(usns)
                #
            except Exception as handled_exception:
                if (self.log_handler is not None): self.log_handler.error(handled_exception, context = "pas_upnp")

                with self.lock:
                    if (url in self.upnp_desc_unread): del(self.upnp_desc_unread[url])
                #
            #
        #

        with self.lock:
            if (len(self.upnp_desc_unread) > 0): self._add_task(0, "read_upnp_descs")
Esempio n. 3
0
    def _handle_data(self, data):
        """
Handles data received.

:param data: Data read from input

:since: v1.0.0
        """

        data = self._decompress(data)

        if (data is not None):
            buffered_data = self.pending_buffer + data
            buffered_data_size = len(buffered_data)
            data_size = len(data)
            last_boundary_end_position = 0

            if (self.pending_received_data is None):
                re_result = Multipart.RE_MIME_BOUNDARY.search(buffered_data)

                if (re_result is not None):
                    mime_part_id = Binary.str(re_result.group(2))
                    mime_part_trailing_data = Binary.str(re_result.group(3))

                    if (mime_part_trailing_data == "--"
                        or (len(self.pending_mime_parts) > 0
                            and mime_part_id not in self.pending_mime_parts
                           )
                       ): raise IOException("Invalid MIME part received")

                    if (len(self.pending_mime_parts) < 1): self.pending_mime_parts.append(mime_part_id)

                    self._handle_mime_part_headers(mime_part_id, mime_part_trailing_data.strip())

                    last_boundary_end_position = re_result.end()
                    last_boundary_end_position += 2 # Ignore CR LF of look-ahead match end

                    self.pending_received_data = ByteBuffer()
                elif (buffered_data_size >= self.pending_buffer_header_size_max): raise IOException("MIME part buffer exceeded")
            #

            self.received_data_size += data_size
            if (self.received_size_max > 0 and self.received_data_size > self.received_size_max): raise ValueException("Input size exceeds allowed limit")

            if (Multipart.BINARY_BOUNDARY_PREFIX not in buffered_data):
                self.pending_buffer = Binary.BYTES_TYPE()
                self.pending_received_data.write(buffered_data)
            else:
                for re_result in Multipart.RE_MIME_BOUNDARY.finditer(buffered_data, last_boundary_end_position):
                    current_boundary_start_position = re_result.start()
                    current_boundary_end_position = re_result.end()

                    mime_part_id = Binary.raw_str(re_result.group(2))

                    if (last_boundary_end_position != current_boundary_start_position):
                        self.pending_received_data.write(buffered_data[last_boundary_end_position:current_boundary_start_position])
                    #

                    if (self._check_mime_part_id(mime_part_id)):
                        mime_part_trailing_data = Binary.str(re_result.group(3))

                        if (self.pending_received_data is not None):
                            self._handle_mime_part_received(mime_part_id)
                            self.pending_received_data = ByteBuffer()
                        #

                        if (mime_part_trailing_data == "--"): self.pending_mime_parts.remove(mime_part_id)
                        else:
                            self._handle_mime_part_headers(mime_part_id, mime_part_trailing_data.strip())
                            current_boundary_end_position += 2 # Ignore CR LF of look-ahead match end
                        #
                    else: self.pending_received_data.write(buffered_data[current_boundary_start_position:current_boundary_end_position])

                    last_boundary_end_position = current_boundary_end_position
                #

                pending_buffer_start_position = (buffered_data_size - last_boundary_end_position)

                if (pending_buffer_start_position > self.pending_buffer_header_size_max):
                    self.pending_buffer = buffered_data[-1 * self.pending_buffer_header_size_max:]
                    self.pending_received_data.write(buffered_data[:-1 * self.pending_buffer_header_size_max])
                else:
                    self.pending_buffer = (Binary.BYTES_TYPE()
                                           if (pending_buffer_start_position < 1) else
                                           buffered_data[-1 * pending_buffer_start_position:]
                                          )