Exemplo n.º 1
0
    def init_metadata_xml_tree(self, device_identifier, url_base, xml_resource):
        """
Initialize the service metadata from a UPnP description.

:param device_identifier: Parsed UPnP device identifier
:param url_base: HTTP base URL
:param xml_resource: UPnP description XML parser instance

:return: (bool) True if parsed successfully
:since:  v0.2.00
        """

        _return = True

        if (xml_resource.count_node("upnp:service") > 0): xml_resource.set_cached_node("upnp:service")
        else: _return = False

        if (_return):
            value = xml_resource.get_node_value("upnp:service upnp:serviceType")
            re_result = (None if (value is None) else Service.RE_USN_URN.match(value))

            if (re_result is None or re_result.group(2) != "service"): _return = False
            else:
                self.name = "{0}:service:{1}".format(re_result.group(1), re_result.group(3))
                urn = "{0}:{1}".format(self.name, re_result.group(4))

                self._set_identifier({ "device": device_identifier['device'],
                                       "bootid": device_identifier['bootid'],
                                       "configid": device_identifier['configid'],
                                       "uuid": device_identifier['uuid'],
                                       "class": "service",
                                       "usn": "uuid:{0}::{1}".format(device_identifier['uuid'], value),
                                       "urn": urn,
                                       "domain": re_result.group(1),
                                       "type": re_result.group(3),
                                       "version": re_result.group(4)
                                     })
            #
        #

        if (_return):
            value = xml_resource.get_node_value("upnp:service upnp:serviceId")
            re_result = (None if (value is None) else Service.RE_SERVICE_ID_URN.match(value))

            if (re_result is None or re_result.group(2) != "serviceId"): _return = False
            else: self.service_id = { "urn": value[4:], "domain": re_result.group(1), "id": re_result.group(3) }
        #

        if (_return):
            self.url_scpd = Binary.str(urljoin(url_base, xml_resource.get_node_value("upnp:service upnp:SCPDURL")))
            self.url_control = Binary.str(urljoin(url_base, xml_resource.get_node_value("upnp:service upnp:controlURL")))

            value = xml_resource.get_node_value("upnp:service upnp:eventSubURL")
            self.url_event_control = (None if (value.strip == "") else Binary.str(urljoin(url_base, value)))
        #

        return _return
Exemplo n.º 2
0
    def get_upnp_value(variable, value):
        """
Returns a valid UPnP encoded value for the given variable definition and
value.

:param variable: Variable definition
:param value: Native python value

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

        native_type = Variable.get_native_type(variable)

        if (type(native_type) is tuple):
            value_normalized = (Binary.str(value) if (native_type[0] == str) else value)
            value_normalized_type = type(value_normalized)

            if (value_normalized_type != native_type[0]): raise ValueException("Given value mismatches defined format")
            elif (len(native_type) > 2):
                if (native_type[1] != "xmlns"): raise ValueException("Invalid native type definition")
                _return = value_normalized
            elif (len(native_type[1]) > 1):
                if (native_type[1] == "base64"): _return = Binary.str(b64encode(Binary.bytes(value) if (value == value_normalized) else value))
                elif (native_type[1] == "f14.4"): _return = "{0:14.4g}".format(value).strip()
                elif (native_type[1] == "date"): _return = strftime("%Y-%m-%d", localtime(value))
                elif (native_type[1] == "dateTime"): _return = strftime("%Y-%m-%dT%H:%M:%S", localtime(value))
                elif (native_type[1] == "dateTime.tz"): _return = strftime("%Y-%m-%dT%H:%M:%S%Z", localtime(value))
                elif (native_type[1] == "hex"): _return = Binary.str(hexlify(Binary.bytes(value) if (value == value_normalized) else value))
                elif (native_type[1] == "time"): _return = strftime("%H:%M:%S", localtime(value))
                elif (native_type[1] == "time.tz"): _return = strftime("%H:%M:%S%Z", localtime(value))
                elif (native_type[1] == "uri" and len(urlsplit(value).scheme.strip()) < 1): raise ValueException("Given value is not a valid URI")
                elif (native_type[1] == "uuid" and Variable.RE_UUID.match(value_normalized) is None): raise ValueException("Given value is not a valid UUID")
                else: _return = value_normalized
            else:
                pack("={0}".format(native_type[1]),
                                   (Binary.utf8_bytes(value)
                                    if (value_normalized_type == str and value == value_normalized) else
                                    value
                                   )
                                  )

                _return = "{0}".format(value_normalized)
            #
        else:
            if (native_type is str): value = Binary.str(value)
            if (type(value) is not native_type): raise ValueException("Given value mismatches defined format")

            if (native_type is bool): _return = "{0:b}".format(value)
            elif (native_type is int): _return = str(value)
            elif (native_type is float): _return = "{0:f}".format(value)
            else: _return = value
        #

        return _return
Exemplo n.º 3
0
    def get_url_base(self, _type, parameters):
        """
Returns the base URL for the given type and parameters.

:param _type: Link type (see constants)
:param parameters: Link parameters

:return: (str) Base URL
:since:  v0.2.00
        """

        _return = ""

        if (_type & Link.TYPE_PREDEFINED_URL == Link.TYPE_PREDEFINED_URL):
            if ("__link__" not in parameters): raise ValueException("Required parameter not defined for the predefined URL")
            _return = parameters['__link__']
        elif (self.path is not None):
            if (_type & Link.TYPE_RELATIVE_URL != Link.TYPE_RELATIVE_URL):
                if (self.scheme is None): raise ValueException("Can't construct an absolute URL without an URI scheme")
                _return = "{0}://".format(Binary.str(self.scheme))

                if (self.host is None): raise ValueException("Can't construct an absolute URL without a host")
                _return += Binary.str(self.host)

                if (self.port is not None):
                    port = Link.filter_well_known_port(self.scheme, self.port)
                    if (port > 0): _return += ":{0:d}".format(port)
                #
            #

            path = ("/" if (self.path is None) else Binary.str(self.path))
            _return += ("/" if (path == "") else path)
        else:
            request = AbstractHttpRequest.get_instance()
            if (request is None): raise ValueException("Can't construct an URL from a request instance if it is not provided")

            if (_type & Link.TYPE_ABSOLUTE_URL == Link.TYPE_ABSOLUTE_URL):
                scheme = request.get_server_scheme()

                _return = "{0}://".format(Binary.str(scheme))

                host = request.get_server_host()
                if (host is not None): _return += Binary.str(host)

                port = Link.filter_well_known_port(scheme, request.get_server_port())
                if (port > 0): _return += ":{0:d}".format(port)

                if (_type & Link.TYPE_BASE_PATH == Link.TYPE_BASE_PATH
                    or _type & Link.TYPE_VIRTUAL_PATH == Link.TYPE_VIRTUAL_PATH
                   ): _return += self._get_url_path(request, False)
                else: _return += self._get_url_path(request)
            else: _return = self._get_url_path(request)
        #

        return _return
Exemplo n.º 4
0
    def request(self, _hook, **kwargs):
        """
Requests the IPC aware application to call the given hook.

:param _hook: Hook
:param args: Parameters

:return: (mixed) Result data; None on error
:since:  v0.3.00
        """

        _hook = Binary.str(_hook)

        if (self.log_handler is not None): self.log_handler.debug("#echo(__FILEPATH__)# -{0!r}.request({1})- (#echo(__LINE__)#)", self, _hook, context = "pas_bus")
        _return = None

        if (not self.connected): raise IOException("Connection already closed")

        request_message = self._get_message_call_template()
        if (_hook == "dNG.pas.Status.stop"): request_message.set_flags(Message.FLAG_NO_REPLY_EXPECTED)

        request_message_body = { "method": _hook }
        if (len(kwargs) > 0): request_message_body['params'] = TypeObject("a{sv}", kwargs)

        request_message.set_body(request_message_body)

        if (not self._write_message(request_message)): raise IOException("Failed to transmit request")

        if (_hook == "dNG.pas.Status.stop"): self.connected = False
        else:
            response_message = self._get_response_message()

            if (((not response_message.is_error()) and (not response_message.is_method_reply()))
                or response_message.get_reply_serial() != 1
                or response_message.get_serial() != 2
               ): raise IOException("IPC response received is invalid")

            if (response_message.is_error()):
                response_body = response_message.get_body()

                raise IOException(Binary.str(response_body)
                                  if (type(response_body) == Binary.BYTES_TYPE) else
                                  response_message.get_error_name()
                                 )
            else: _return = response_message.get_body()
        #

        return _return
Exemplo n.º 5
0
    def parse(self):
        """
Parses the content of the request body.

:since: v1.0.0
        """

        byte_buffer = self.get_buffer()

        field_arrays = { }

        parsed_fields = ([ ]
                         if (byte_buffer is None or byte_buffer.size < 1) else
                         parse_qsl(Binary.str(byte_buffer.read()), True, True)
                        )

        for parsed_field in parsed_fields:
            re_result = Urlencoded.RE_ARRAY.match(parsed_field[0])

            if (re_result is None): self.parsed_data[parsed_field[0]] = parsed_field[1]
            elif (re_result.group(1) in field_arrays): field_arrays[re_result.group(1)].append({ "key": re_result.group(2), "value": parsed_field[1] })
            else: field_arrays[re_result.group(1)] = [ { "key": re_result.group(2), "value": parsed_field[1] } ]
        #

        for field in field_arrays:
            element_position = 0
            if (field in self.parsed_data): field_arrays[field].insert(0, self.parsed_data[field])
            self.parsed_data[field] = { }

            for element in field_arrays[field]:
                if (len(element['key']) > 0): self.parsed_data[field][element['key']] = element['value']
                else:
                    self.parsed_data[field][element_position] = element['value']
                    element_position += 1
Exemplo n.º 6
0
    def read(self, n = 0):
        """
Reads data using the given body reader and parse the JSON response. Chunked
transfer-encoded data is handled automatically.

:param n: Bytes to read

:return: (bytes) Data received
:since:  v1.0.0
        """

        # pylint: disable=access-member-before-definition, attribute-defined-outside-init, not-callable, used-before-assignment

        if (n > 0): raise OperationNotSupportedException()

        if (self.json_resource is None):
            json_data = self.body_reader()
            self.body_reader = None

            self.json_resource = JsonResource()
            self.json_resource.parse(Binary.str(json_data))
            if (self.json_resource.data is None): raise ValueException("Data received is not a valid JSON encoded response")

            _return = Binary.bytes(json_data)
        else: _return = Binary.bytes("")

        return _return
Exemplo n.º 7
0
    def theme(self, theme):
        """
Sets the theme to use.

:param theme: Output theme

:since: v1.0.0
        """

        theme = Binary.str(theme)

        """
Set theme or reset to None to use the default one configured
        """

        if (theme is None): self._theme = None
        else:
            theme_path = InputFilter.filter_file_path(theme).replace(".", path.sep)
            file_path_name = path.join(self.path, theme_path, "site.tsc")

            if (os.access(file_path_name, os.R_OK)): self._theme = theme
            else: self._theme = None
        #

        """
Read corresponding theme configuration
        """

        if (self._theme is None): file_path_name = path.join(self.path, self.theme.replace(".", path.sep), "site.tsc")

        file_path_name = file_path_name[:-3] + "json"
        Settings.read_file(file_path_name)
    def __init__(self, url, gst_stream_metadata):
        """
Constructor __init__(GstAudioStreamMetadata)

:since: v0.2.00
        """

        # pylint: disable=star-args

        mimetype_definition = MimeType.get_instance().get(mimetype = gst_stream_metadata['codec'])
        if (mimetype_definition is None): mimetype_definition = { "type": gst_stream_metadata['codec'], "class": gst_stream_metadata['codec'].split("/", 1)[0] }
        if (mimetype_definition['class'] != "audio"): LogLine.debug("Metadata '{0}' do not correspond to audio".format(mimetype_definition['type']), context = "pas_media")

        kwargs = { }

        kwargs['codec'] = gst_stream_metadata['codec']
        if (gst_stream_metadata['bitrate'] > 0): kwargs['bitrate'] = gst_stream_metadata['bitrate']
        if (gst_stream_metadata['bits_per_sample'] > 0): kwargs['bps'] = gst_stream_metadata['bits_per_sample']
        if (gst_stream_metadata['channels'] > 0): kwargs['channels'] = gst_stream_metadata['channels']

        if ("profile" in gst_stream_metadata):
        #
            profile = Binary.str(gst_stream_metadata['profile']).lower()
            if ("level" in gst_stream_metadata): profile += "-{0}".format(gst_stream_metadata['level'].lower())
            kwargs['codec_profile'] = profile
        #
        elif ("format" in gst_stream_metadata): kwargs['codec_profile'] = gst_stream_metadata['format'].lower()

        if ("language-code" in gst_stream_metadata['tags']): kwargs['lang'] = GstMetadataMixin._parse_tag(gst_stream_metadata['tags']['language-code'])
        kwargs['mimeclass'] = mimetype_definition['class']
        kwargs['mimetype'] = mimetype_definition['type']
        if (gst_stream_metadata['sample_rate'] > 0): kwargs['sample_rate'] = gst_stream_metadata['sample_rate']

        AudioStreamMetadata.__init__(self, url, **kwargs)
Exemplo n.º 9
0
    def _handle_mime_part_headers(self, mime_part_id, data):
        """
Handles MIME part header.

:param mime_part_id: MIME part ID
:param data: Data read from input

:since: v1.0.0
        """

        mime_headers = Header.get_headers(Binary.str(data))

        if (mime_part_id not in self.parts):
            part_position = len(self.parts)
            self.parts[mime_part_id] = { "headers": mime_headers, "position": part_position }
        elif ("list" in self.parts[mime_part_id]): self.parts[mime_part_id]['list'].append({ "headers": mime_headers })
        else:
            single_mime_part = { "headers": self.parts[mime_part_id]['headers'] }
            if ("data" in self.parts[mime_part_id]): single_mime_part['data'] = self.parts[mime_part_id]['data']

            self.parts[mime_part_id] = { "position": self.parts[mime_part_id]['position'],
                                         "list": [ single_mime_part,
                                                   { "headers": mime_headers }
                                                 ]
                                       }
Exemplo n.º 10
0
    def _add_metadata_to_didl_xml_node(self, xml_resource, xml_node_path, parent_id = None):
        """
Uses the given XML resource to add the DIDL metadata of this UPnP resource.

:param xml_resource: XML resource
:param xml_base_path: UPnP resource XML base path (e.g. "DIDL-Lite
       item")

:since: v0.2.00
        """

        if (self.get_type() & AbstractResource.TYPE_CDS_RESOURCE == AbstractResource.TYPE_CDS_RESOURCE):
            attributes = { }
            didl_fields = self.get_didl_fields()
            res_protocol = self.get_didl_res_protocol()
            size = self.get_size()

            if (res_protocol is not None): attributes['protocolInfo'] = res_protocol
            if (size is not None): attributes['size'] = size

            didl_fields_filtered = (len(didl_fields) > 0)

            metadata = self.get_metadata()

            for key in metadata:
                if ((not didl_fields_filtered) or "res@{0}".format(key) in didl_fields): attributes[key] = metadata[key]
            #

            url = Binary.str(self.get_content(0))
            value = (url if (type(url) is str) else "")

            xml_resource.add_node(xml_node_path, value, attributes)
Exemplo n.º 11
0
    def _get_hook_proxy_params(self, hook, timeout = None, kwargs = None):
        """
Returns serializable parameters for the persistent proxy.

:param hook: Task hook to be called
:param timeout: Timeout in seconds; None to use global task timeout
:param kwargs: Keyword arguments

:return: (dict)
:since:  v0.2.00
        """

        _return = { }

        if (isinstance(hook, PersistentLrtHook)):
            _return['hook'] = hook.get_hook()

            _return['kwargs'] = ({ } if (kwargs is None) else kwargs)
            _return['kwargs'].update(hook.get_params())
            _return['kwargs']['_lrt_hook'] = True
        else:
            hook = Binary.str(hook)
            if (type(hook) is not str): raise TypeException("Hook given is invalid")

            _return['hook'] = hook
            if (kwargs is not None): _return['kwargs'] = kwargs
        #

        if (timeout is not None): _return['timeout'] = timeout

        return _return
Exemplo n.º 12
0
    def prepare_socket(listener_type, *listener_data):
        """
Prepare socket returns a bound socket for the given listener data.

:param listener_type: Listener type
:param listener_data: Listener data

:since: v0.2.00
        """

        _return = None

        if (listener_type == socket.AF_INET or listener_type == socket.AF_INET6):
            listener_data = ( Binary.str(listener_data[0]), listener_data[1] )

            _return = socket.socket(listener_type, socket.SOCK_STREAM)
            _return.setblocking(0)
            if (hasattr(socket, "SO_REUSEADDR")): _return.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            _return.bind(listener_data)
        elif (listener_type == socket.AF_UNIX):
            unixsocket_path_name = path.normpath(Binary.str(listener_data[0]))
            if (os.access(unixsocket_path_name, os.F_OK)): os.unlink(unixsocket_path_name)

            _return = socket.socket(listener_type, socket.SOCK_STREAM)
            if (hasattr(socket, "SO_REUSEADDR")): _return.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            _return.bind(unixsocket_path_name)

            socket_chmod = 0
            socket_chmod_value = int(Settings.get("pas_global_server_chmod_unix_sockets", "600"), 8)

            if ((1000 & socket_chmod_value) == 1000): socket_chmod |= stat.S_ISVTX
            if ((2000 & socket_chmod_value) == 2000): socket_chmod |= stat.S_ISGID
            if ((4000 & socket_chmod_value) == 4000): socket_chmod |= stat.S_ISUID
            if ((0o100 & socket_chmod_value) == 0o100): socket_chmod |= stat.S_IXUSR
            if ((0o200 & socket_chmod_value) == 0o200): socket_chmod |= stat.S_IWUSR
            if ((0o400 & socket_chmod_value) == 0o400): socket_chmod |= stat.S_IRUSR
            if ((0o010 & socket_chmod_value) == 0o010): socket_chmod |= stat.S_IXGRP
            if ((0o020 & socket_chmod_value) == 0o020): socket_chmod |= stat.S_IWGRP
            if ((0o040 & socket_chmod_value) == 0o040): socket_chmod |= stat.S_IRGRP
            if ((0o001 & socket_chmod_value) == 0o001): socket_chmod |= stat.S_IXOTH
            if ((0o002 & socket_chmod_value) == 0o002): socket_chmod |= stat.S_IWOTH
            if ((0o004 & socket_chmod_value) == 0o004): socket_chmod |= stat.S_IROTH

            os.chmod(unixsocket_path_name, socket_chmod)
        #

        return _return
Exemplo n.º 13
0
    def request_soap_action(self, action, arguments):
        """
Request the given SOAP action with the given arguments from a remote UPnP
device.

:param action: SOAP action
:param arguments: SOAP action arguments

:return: (dict) SOAP action response
:since:  v0.2.00
        """

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

        _return = None

        urn = "urn:{0}".format(self.get_urn())

        xml_resource = self._init_xml_resource()
        xml_resource.register_ns("s", "http://schemas.xmlsoap.org/soap/envelope/")
        xml_resource.register_ns("u", urn)
        xml_resource.set_parse_only(False)

        xml_resource.add_node("s:Envelope", attributes = { "xmlns:s": "http://schemas.xmlsoap.org/soap/envelope/", "encodingStyle": "http://schemas.xmlsoap.org/soap/encoding/" })
        xml_resource.add_node("s:Envelope s:Body")

        xml_base_path = "s:Envelope s:Body u:{0}".format(action)

        xml_resource.add_node(xml_base_path, attributes = { "xmlns:u": urn })
        xml_resource.set_cached_node("s:Envelope s:Body")

        for argument in arguments: xml_resource.add_node("{0} {1}".format(xml_base_path, argument['name']), argument['value'])

        http_client = HttpClient(self.url_control, event_handler = self.log_handler)
        http_client.set_header("Content-Type", "text/xml; charset=UTF-8")
        http_client.set_header("SoapAction", "\"{0}#{1}\"".format(urn, action))
        http_client.set_header("User-Agent", Service.get_pas_upnp_http_client_identifier_string())

        post_data = "<?xml version='1.0' encoding='UTF-8' ?>{0}".format(xml_resource.export_cache(True))
        http_response = http_client.request_post(post_data)
        xml_response_variables = None

        if (http_response.is_readable()):
            xml_resource.parse(Binary.str(http_response.read()))
            xml_response_variables = xml_resource.get_node("{0}Response".format(xml_base_path))
        elif (self.log_handler is not None): self.log_handler.error(http_response.get_error_message(), context = "pas_upnp")

        if (xml_response_variables is not None):
            _return = { }

            for key in xml_response_variables:
                _return[key] = xml_response_variables[key]['value']
            #
        #

        return _return
Exemplo n.º 14
0
    def theme_subtype(self, subtype):
        """
Sets the theme subtype to use.

:param subtype: Output theme subtype

:since: v1.0.0
        """

        self._theme_subtype = Binary.str(subtype)
Exemplo n.º 15
0
	def execute_new(self, is_save_mode = False):
	#
		"""
Action for "new"

:since: v0.1.00
		"""

		form_id = InputFilter.filter_control_chars(self.request.get_dsd("oform_id", "")).strip()
		form_field_id = InputFilter.filter_control_chars(self.request.get_dsd("oform_field_id", "")).strip()

		L10n.init("pas_http_core_form")

		form = FormProcessor(form_id)
		form.set_form_render_id(Binary.str(hexlify(urandom(16))))

		if (is_save_mode): form.set_input_available()

		self._apply_new_form(form)

		if (is_save_mode and form.check()):
		#
			entry_data = self._save_new_form(form)

			form_store = form.get_form_store()
			form_store_dict = form_store.get_value_dict()
			form_store_field_id = "form_api_dynamic_{0}".format(form_field_id)

			entry_list = form_store_dict.get(form_store_field_id, [ ])
			entry_list.append(entry_data)

			form_store_dict[form_store_field_id] = entry_list
			form_store.set_value_dict(form_store_dict)

			self._set_destroy_dom_result()
		#
		else:
		#
			content = { "title": self._get_form_action_new_title(),
			            "on_closed_query": Link().build_url(Link.TYPE_QUERY_STRING, { "__request__": True, "a": "get" })
			          }

			content['form'] = { "object": form,
			                    "url_parameters": { "__request__": True,
			                                        "a": "new-save"
			                                      },
			                    "button_title": "core_continue"
			                  }

			method = (self._set_replace_dom_oset_result
			          if (is_save_mode) else
			          self._set_append_overlay_dom_oset_result
			         )

			method("dynamic_form.overlay", content)
Exemplo n.º 16
0
    def get_user_agent_settings(user_agent):
        """
Returns the user agent specific client settings dictionary.

:param user_agent: User agent

:return: (dict) User agent specific client settings; None on error
:since:  v0.2.00
        """

        _return = { }

        settings = None
        user_agent = Binary.str(user_agent)

        if (type(user_agent) is str):
            settings = Hook.call("dNG.pas.upnp.Client.getUserAgentSettings", user_agent = user_agent)

            if (not isinstance(settings, dict)):
                identifier = ClientSettings.get_user_agent_identifiers(user_agent)
                settings_file_name = "{0}.json".format(identifier)

                settings = JsonFileContent.read(path.join(Settings.get("path_data"),
                                                          "upnp",
                                                          "user_agents",
                                                          settings_file_name
                                                         )
                                               )

                if (settings is None):
                    log_line = "pas.upnp.ClientSettings reporting: No client settings found for user agent '{0}' with identifier '{1}'"

                    if (Settings.get("pas_upnp_log_missing_user_agent", False)): LogLine.warning(log_line, user_agent, identifier, context = "pas_upnp")
                    else: LogLine.debug(log_line, user_agent, identifier, context = "pas_upnp")
                #
            #
        #

        if (settings is not None):
            if ("client_file" in settings):
                base_settings = JsonFileContent.read(path.join(Settings.get("path_data"),
                                                               "upnp",
                                                               "user_agents",
                                                               InputFilter.filter_file_path(settings['client_file'])
                                                              )
                                                    )

                if (type(base_settings) is dict): _return.update(base_settings)
                del(settings['client_file'])
            #

            _return.update(settings)
        #

        return _return
Exemplo n.º 17
0
    def _unescape_path(url_elements_path):
        """
Unescapes the path.

:param url_elements_path: Escaped path from an URL

:return: (str) Unescaped path
:since:  v0.2.00
        """

        return path.normpath(unquote(Binary.str(url_elements_path)))
Exemplo n.º 18
0
    def _get_url_path(self, request = None, include_script_name = True):
        """
Returns the base URL path for the given URL or the current handled one.

:return: (str) Base URL path
:since:  v0.2.00
        """

        if (self.path is None):
            if (request is None): request = AbstractHttpRequest.get_instance()
            if (request is None): raise ValueException("Can't construct an URL from a request instance if it is not provided")

            script_name = request.get_script_name()

            if ((not include_script_name) or script_name == ""): path = "/"
            else:
                script_name = Binary.str(script_name)
                path = (script_name if (script_name[:1] == "/") else "/{0}".format(script_name))
            #
        else: path = Binary.str(self.path)

        return ("/" if (path == "") else path)
Exemplo n.º 19
0
	def execute(self):
	#
		"""
Executes the processor.

:since: v0.1.00
		"""

		if (self.form is None or (not self.validate_settings(self.settings))): raise ValueException("Processor is not configured")

		lang = (self.settings['email_lang']
		        if ("email_lang" in self.settings) else
		        L10n.get_instance().get_lang()
		       )

		sender = (InputFilter.filter_control_chars(self.form.get_input(self.settings['email_sender_field_name']))
		          if ("email_sender_field_name" in self.settings) else
		          None
		         )

		subject = (InputFilter.filter_control_chars(self.form.get_input(self.settings['email_subject_field_name']))
		           if ("email_subject_field_name" in self.settings) else
		           self.settings['email_subject_title']
		          )

		if (subject is None or len(subject.strip()) < 1): raise ValueException("Given e-mail subject is invalid")

		content_list = [ ]
		titles = self.settings.get("form_field_titles", { })

		for field_name in self.settings['email_content_field_names']:
		#
			value = InputFilter.filter_control_chars(self.form.get_input(field_name))

			content_list.append("{0}:\n{1}".format((titles[field_name] if (field_name in titles) else field_name),
			                                       value
			                                      )
			                   )
		#

		content = "\n\n".join(content_list)

		DatabaseTasks.get_instance().add("dNG.pas.http.Form.sendEMail.{0}".format(Binary.str(hexlify(urandom(16)))),
		                                 "dNG.pas.http.Form.sendEMail",
		                                 1,
		                                 lang = lang,
		                                 sender = sender,
		                                 subject = subject,
		                                 content = content
		                                )
Exemplo n.º 20
0
    def load_json(json):
        """
Load metadata previously exported with the "get_json()" method.

:param json: JSON encoded metadata

:return: (object) Metadata object; None if metadata is incompatible
:since:  v0.2.00
        """

        json = Binary.str(json)
        data = (JsonResource().json_to_data(json) if (type(json) is str) else None)

        if (data is None): raise ValueException("Failed to decode JSON metadata")
        return (AbstractMetadata._load_instance_json_data(data) if (data.get("_meta_version") == AbstractMetadata.JSON_VERSION) else None)
Exemplo n.º 21
0
    def unregister_timeout(self, tid):
        """
Removes the given TID from the storage.

:param tid: Task ID

:return: (bool) True on success
:since:  v0.2.00
        """

        tid = Binary.str(tid)
        _return = self._delete(tid)

        if (_return and self.log_handler is not None): self.log_handler.debug("{0!r} removed TID '{1}'", self, tid, context = "pas_tasks")
        return _return
Exemplo n.º 22
0
    def set_sort_criteria(self, sort_criteria):
        """
Sets the UPnP sort criteria.

:param sort_criteria: UPnP sort criteria

:since: v0.2.00
        """

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

        if (type(sort_criteria) is list): self.sort_criteria = sort_criteria
        else:
            sort_criteria = Binary.str(sort_criteria)
            self.sort_criteria = (sort_criteria.split(",") if (type(sort_criteria) is str and len(sort_criteria) > 0) else [ ])
Exemplo n.º 23
0
    def get_identifier(usn, bootid = None, configid = None):
        """
Parses the given UPnP USN string.

:param usn: UPnP USN
:param bootid: UPnP bootId (bootid.upnp.org) if any
:param configid: UPnP configId (configid.upnp.org) if any

:return: (dict) Parsed UPnP identifier; None on error
:since:  v0.2.00
        """

        usn = Binary.str(usn)

        if (type(usn) == str):
            usn_data = usn.split("::", 1)
            device_id = usn_data[0].lower().replace("-", "")
        else: device_id = ""

        if (device_id.startswith("uuid:")):
            device_id = device_id[5:]

            _return = { "device": device_id,
                        "bootid": None,
                        "configid": None,
                        "uuid": usn_data[0][5:],
                        "class": "unknown",
                        "usn": usn
                      }

            if (bootid is not None and configid is not None):
                _return['bootid'] = bootid
                _return['configid'] = configid
            #

            re_result = (IdentifierMixin.RE_USN_URN.match(usn_data[1]) if (len(usn_data) > 1) else None)

            if (re_result is not None):
                _return['urn'] = usn_data[1][4:]

                _return['domain'] = re_result.group(1)
                _return['class'] = re_result.group(2)
                _return['type'] = re_result.group(3)
                _return['version'] = re_result.group(4)
            elif (usn[-17:].lower() == "::upnp:rootdevice"): _return['class'] = "rootdevice"
        else: _return = None

        return _return
Exemplo n.º 24
0
    def unset_permission(self, name):
        """
Unsets the permission with the specified name.

:since: v0.2.00
        """

        name = Binary.str(name)
        if (self.log_handler is not None): self.log_handler.debug("#echo(__FILEPATH__)# -{0!r}.set_permission({1})- (#echo(__LINE__)#)", self, name, context = "pas_database")

        self._ensure_thread_local_permission_cache()

        with self:
            if (self.local.permission_cache is not None
                and name in self.local.permission_cache
               ):
                self.remove_permission(Permission(self.local.permission_cache[name]['db_instance']))
                del(self.local.permission_cache[name])
Exemplo n.º 25
0
    def init_scpd(self):
        """
Initialize actions from the SCPD URL.

:return: (bool) True if parsed successfully
:since:  v0.2.00
        """

        _return = False

        http_client = HttpClient(self.url_scpd, event_handler = self.log_handler)
        http_client.set_header("User-Agent", Service.get_pas_upnp_http_client_identifier_string())
        http_response = http_client.request_get()

        if (http_response.is_readable()): _return = self.init_xml_scpd(Binary.str(http_response.read()))
        elif (self.log_handler is not None): self.log_handler.error(http_response.get_error_message(), context = "pas_upnp")

        return _return
Exemplo n.º 26
0
    def unmarshal(data):
        """
Unmarshals a D-Bus message and returns a Message instance.

:param data: Wire-formatted data

:return: (object) Message instance
:since:  v0.2.00
        """

        # pylint: disable=protected-access

        data = Binary.bytes(data)
        data_size = len(data)
        if (data_size < 16): raise IOException("D-Bus message is invalid")

        header = [ Message.unmarshal_data("y", data[:1]) ]
        is_le = (Binary.str(header[0]) == "l")
        header += Message.unmarshal_data("yyyuu", data[:12], is_le, 1)

        header_size = 12
        body_size = header[4]

        header_size += Message.get_marshaled_data_size("a(yv)", data, is_le, 12)
        if (header_size > data_size): raise IOException("D-Bus message is invalid (calculated header size < size)")

        header_fields = Message.unmarshal_data("a(yv)", data[:header_size], is_le, 12)

        if (header_size + body_size > data_size): raise IOException("D-Bus message truncated")
        elif (header_size + body_size < data_size): raise IOException("D-Bus message is invalid (calculated message size < size)")

        _return = Message(header[1])
        _return.set_flags(unpack(("<" if (is_le) else ">") + "B", header[2])[0])
        _return.set_serial(header[5])

        for header_field in header_fields: _return._set_header_field(header_field[0], header_field[1])

        if (body_size > 0):
            body_signature = _return.get_body_signature()
            if (body_signature is None): raise IOException("D-Bus message contains a body without a signature header")
            _return.set_body(Message.unmarshal_data(body_signature, data, is_le, header_size))
        #

        return _return
Exemplo n.º 27
0
    def add(self, tid, hook, timeout = None, **kwargs):
        """
Add a new task with the given TID to the storage for later activation.

:param tid: Task ID
:param hook: Task hook to be called
:param timeout: Timeout in seconds; None to use global task timeout

:since: v0.2.00
        """

        tid = Binary.str(tid)
        if (timeout is None): timeout = self.task_timeout

        if (self.log_handler is not None): self.log_handler.debug("{0!r} added TID '{1}' with target {2!r} and timeout '{3}'", self, tid, hook, timeout, context = "pas_tasks")

        params = kwargs
        params['_tid'] = tid
        self._insert({ "hook": hook, "params": params, "tid": tid }, timeout)
Exemplo n.º 28
0
    def call(_hook, **kwargs):
        """
Call all functions registered for the hook with the specified parameters.

:param _hook: Hook-ID

:return: (mixed) Hook results; None if not defined
:since:  v0.2.00
        """

        # pylint: disable=broad-except

        _hook = Binary.str(_hook)

        if (Hook._log_handler is not None): Hook._log_handler.debug("#echo(__FILEPATH__)# -Hook.call({0})- (#echo(__LINE__)#)", _hook, context = "pas_plugins")
        _return = None

        hook_registry = Hook.get_instance()
        params = kwargs

        if (_hook in hook_registry and (not Hook._instance_freed)):
            if ("hook" not in params): params['hook'] = _hook
            hooks = (hook_registry[_hook].copy() if (hasattr(hook_registry[_hook], "copy")) else copy(hook_registry[_hook]))

            for _callback in hooks:
                callback = (_callback()
                            if (isinstance(_callback, WeakrefMethod) or type(_callback) is ref) else
                            _callback
                           )

                if (callback is None): Hook.unregister(_hook, _callback)
                else:
                    try: _return = callback(params, last_return = _return)
                    except Exception as handled_exception:
                        if (Hook._log_handler is not None): Hook._log_handler.error(handled_exception, context = "pas_plugins")
                        _return = handled_exception
                    #
                #
            #
        #

        return _return
Exemplo n.º 29
0
    def _apply_sql_file(file_path_name):
        """
Applies the given SQL file.

:param file_path_name: Database specific SQL file

:since: v1.0.0
        """

        file_content = None
        file_object = File()

        if (file_object.open(file_path_name, True, "r")):
            file_content = Binary.str(file_object.read())
            file_object.close()
        #

        if (file_content is None): raise IOException("Schema file given is invalid")

        file_content = file_content.replace("__db_prefix__", _DbAbstract.get_table_prefix())
        file_content = Schema.RE_SQL_COMMENT_LINE.sub("", file_content)

        current_sql_command = ""
        sql_commands = file_content.split(";")

        for sql_command in sql_commands:
            re_result = Schema.RE_ESCAPED.search(sql_command)

            if (re_result is not None
                and (len(re_result.group(1)) % 2) == 1
               ): current_sql_command += sql_command
            else:
                current_sql_command = (sql_command
                                       if (current_sql_command == "") else
                                       current_sql_command + sql_command
                                      )

                current_sql_command = current_sql_command.strip()

                if (current_sql_command != ""):
                    Schema._apply_sql_command(current_sql_command)
                    current_sql_command = ""
Exemplo n.º 30
0
    def unregister(hook, callback):
        """
Unregister a python function from the hook.

:param hook: Hook-ID
:param callback: Python function to be unregistered

:since: v0.2.00
        """

        hook = Binary.str(hook)

        if (Hook._log_handler is not None): Hook._log_handler.debug("#echo(__FILEPATH__)# -Hook.unregister({0}, {1!r})- (#echo(__LINE__)#)", hook, callback, context = "pas_plugins")

        hook_registry = Hook.get_instance()

        if (hook in hook_registry and callback in hook_registry[hook]):
            with Hook._instance_lock:
                # Thread safety
                if (hook in hook_registry and callback in hook_registry[hook]): hook_registry[hook].remove(callback)
Exemplo n.º 31
0
    def set_permission(self, name, permitted = True):
        """
Sets the permission with the specified name.

:since: v0.2.00
        """

        name = Binary.str(name)
        if (self.log_handler is not None): self.log_handler.debug("#echo(__FILEPATH__)# -{0!r}.set_permission({1})- (#echo(__LINE__)#)", self, name, context = "pas_database")

        self._ensure_thread_local_permission_cache()

        with self:
            if (self.local.permission_cache is None): self._init_permission_cache()

            if (name not in self.local.permission_cache):
                permission = Permission()
                permission.set_data_attributes(name = name, permitted = permitted)

                self.add_permission(permission)
                self.local.permission_cache[name] = { "permitted": permitted, "db_instance": permission }