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
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")
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:] )