コード例 #1
0
ファイル: resource.py プロジェクト: dNG-git/pas_upnp
    def load_cds_id(_id, client_user_agent = None, cds = None, deleted = False):
        """
Load a UPnP resource by CDS ID.

:param _id: UPnP CDS ID
:param client_user_agent: Client user agent
:param cds: UPnP CDS
:param deleted: True to include deleted resources

:return: (object) Resource object; None on error
:since:  v0.2.00
        """

        _return = None

        if (_id == "0" and cds is not None):
            _return = NamedLoader.get_instance("dNG.data.upnp.resources.RootContainer")
            _return.init_cds_id(_id, client_user_agent, deleted)
        elif (_id is not None and "://" in _id):
            url_elements = urlsplit(_id)

            if (url_elements.scheme != ""):
                resource_class_name = "".join([ word.capitalize() for word in url_elements.scheme.split("-") ])
                resource = NamedLoader.get_instance("dNG.data.upnp.resources.{0}".format(resource_class_name), False)

                if (isinstance(resource, Resource) and resource.init_cds_id(_id, client_user_agent, deleted)): _return = resource
            #
        #

        return _return
コード例 #2
0
ファイル: control_point.py プロジェクト: dNG-git/pas_upnp
    def get_rootdevice(self, identifier):
        """
Returns a UPnP rootdevice for the given identifier.

:param identifier: Parsed UPnP identifier

:return: (object) UPnP rootdevice; None if not found
:since:  v0.2.00
        """

        _return = None

        with self.lock:
            if (identifier['class'] == "device" and identifier['usn'] in self.usns):
                if (identifier['uuid'] in self.managed_devices):
                    if (self.log_handler is not None): self.log_handler.debug("{0!r} got request to return the hosted device '{1}'", self, identifier['usn'], context = "pas_upnp")
                    _return = self.managed_devices[identifier['uuid']]
                    _return.set_configid(self.configid)
                else:
                    if (self.log_handler is not None): self.log_handler.debug("{0!r} got request to create an object for device '{1}'", self, identifier['usn'], context = "pas_upnp")

                    _return = (NamedLoader.get_instance("dNG.data.upnp.devices.{0}".format(identifier['type']), False) if (identifier['class'] == "device") else None)
                    if (_return is None): _return = Device()
                    if (_return.init_xml_desc(self.usns[identifier['usn']], self.get_desc_xml(identifier)) == False): _return = None
                #
            #
        #

        return _return
コード例 #3
0
ファイル: media_server.py プロジェクト: dNG-git/mp_core
    def init_device(self, control_point, udn = None, configid = None):
        """
Initialize a host device.

:return: (bool) Returns true if initialization was successful.
:since:  v0.2.00
        """

        AbstractDevice.init_device(self, control_point, udn, configid)

        self.device_model = "UPnP media server"
        self.device_model_desc = "Python based UPnP media server"
        self.device_model_url = "https://www.direct-netware.de/redirect?mp;core"
        self.device_model_version = "#echo(mpCoreVersion)#"
        self.manufacturer = "direct Netware Group"
        self.manufacturer_url = "http://www.direct-netware.de"

        #service = AvTransport()
        #if (service.init_host(self, configid = self.configid)): self.add_service(service)

        service = ConnectionManager()
        if (service.init_host(self, configid = self.configid)): self.add_service(service)

        service = ContentDirectory()
        if (service.init_host(self, configid = self.configid)): self.add_service(service)

        service = NamedLoader.get_instance("dNG.data.upnp.services.ScheduledRecording", False)
        if (service is not None and service.init_host(self, configid = self.configid)): self.add_service(service)

        service = XMSMediaReceiverRegistrar()
        if (service.init_host(self, configid = self.configid)): self.add_service(service)

        return True
コード例 #4
0
ファイル: database_task.py プロジェクト: dNG-git/pas_tasks
    def _get_hook(self):
        """
Returns the task hook to be called.

:return: (mixed) Task hook either as str or an instance of "AbstractHook"
:since:  v0.2.00
        """

        _return = (NamedLoader.get_instance("dNG.tasks.DatabaseLrtHook", hook = self.hook, **self.params)
                   if (self.params.get("_lrt_hook", False)) else
                   self.hook
                  )

        return _return
コード例 #5
0
    def _load_instance_json_data(data, url = None):
        """
Load metadata into the correct instance.

:param data: Raw metadata dict

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

        # pylint: disable=protected-access

        _return = None

        if (("_meta_url" in data or url is not None) and "_py_class" in data):
            _return = NamedLoader.get_instance(data['_py_class'], False, url = (data['_meta_url'] if (url is None) else url))
            if (not _return._load_json_data(data)): _return = None
        #

        return _return
コード例 #6
0
    def run(self):
        """
Task execution

:since: v0.2.00
        """

        if (self.__class__.EMAIL_RENDERER is None): raise ValueException("Defined e-mail renderer is invalid")

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        user_profile = user_profile_class.load_username(self.username)

        user_profile_data = user_profile.get_data_attributes("name", "lang", "email")

        email = self.get_email_recipient()
        if (email is None): email = user_profile_data['email']

        L10n.init("core", user_profile_data['lang'])
        L10n.init("pas_core", user_profile_data['lang'])
        L10n.init("pas_http_user", user_profile_data['lang'])

        l10n = L10n.get_instance(user_profile_data['lang'])

        email_renderer = NamedLoader.get_instance(self.__class__.EMAIL_RENDERER, l10n = l10n)
        content = email_renderer.render(user_profile_data, self.vid, self.vid_timeout_days)

        subject = self.get_email_subject(l10n)
        if (subject is None): subject = l10n.get("pas_http_user_title_verification")

        part = Part(Part.TYPE_MESSAGE_BODY, "text/plain", content)

        message = Message()
        message.add_body(part)
        message.set_subject(subject)
        message.set_to(Message.format_address(user_profile_data['name'], email))

        smtp_client = SmtpClient()
        smtp_client.set_message(message)
        smtp_client.send()
コード例 #7
0
ファイル: mp_entry.py プロジェクト: dNG-git/mp_core
    def load_encapsulating_entry(_id, client_user_agent = None, cds = None, deleted = False):
        """
Loads a matching MpEntry for the given MpEntry instance based ID or VFS URL.

:param _id: MpEntry instance based ID or VFS URL
:param client_user_agent: Client user agent
:param cds: UPnP CDS
:param deleted: True to include deleted resources

:return: (object) Resource object; None on error
:since:  v0.2.00
        """

        if (_id is None): raise TypeException("MpEntry ID or VFS URL given is invalid")
        _return = None

        if ("://" in _id
            and (_id.startswith("mp-entry:") or _id.startswith("mp-entry-"))
           ): _return = MpEntry.load_cds_id(_id, client_user_agent, cds, deleted)
        else:
            vfs_object = Implementation.load_vfs_url(_id, True)

            if (vfs_object.is_directory()): entry_class_name = "dNG.data.upnp.resources.MpEntry"
            else:
                mimetype = vfs_object.get_mimetype()
                mimetype_definition = MimeType.get_instance().get(mimetype = mimetype)

                mimeclass = (mimetype.split("/", 1)[0] if (mimetype_definition is None) else mimetype_definition['class'])
                camel_case_mimeclass = "".join([ word.capitalize() for word in re.split("\\W", mimeclass) ])

                entry_class_name = "dNG.data.upnp.resources.MpEntry{0}".format(camel_case_mimeclass)
                if (not NamedLoader.is_defined(entry_class_name)): entry_class_name = "dNG.data.upnp.resources.MpEntry"
            #

            _return = NamedLoader.get_instance(entry_class_name, False)
            if (_return is not None and (not _return.init_cds_id(_id, client_user_agent, deleted))): _return = None
        #

        return _return
コード例 #8
0
    def run(self):
        """
Task execution

:since: v0.2.00
        """

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        user_profile = user_profile_class.load_username(self.username)

        secid = user_profile_class.generate_secid()
        secid_hashed = Tmd5.password_hash(re.sub("\\W+", "", secid), Settings.get("pas_user_profile_password_salt"), self.username)

        user_profile.set_data_attributes(secid = secid_hashed)
        user_profile.save()

        user_profile_data = user_profile.get_data_attributes("name", "lang", "email")

        L10n.init("core", user_profile_data['lang'])
        L10n.init("pas_core", user_profile_data['lang'])
        L10n.init("pas_http_user", user_profile_data['lang'])

        l10n = L10n.get_instance(user_profile_data['lang'])

        email_renderer = NamedLoader.get_instance("dNG.data.text.user.SecIDUpdatedEMailRenderer", l10n = l10n)
        content = email_renderer.render(user_profile_data, secid)
        subject = l10n.get("pas_http_user_title_sec_id_updated")

        part = Part(Part.TYPE_MESSAGE_BODY, "text/plain", content)

        message = Message()
        message.add_body(part)
        message.set_subject(subject)
        message.set_to(Message.format_address(user_profile_data['name'], user_profile_data['email']))

        smtp_client = SmtpClient()
        smtp_client.set_message(message)
        smtp_client.send()
コード例 #9
0
	def execute_form(self, is_save_mode = False):
	#
		"""
Action for "form"

:since: v0.1.00
		"""

		form_id = InputFilter.filter_file_path(self.request.get_dsd("fid", ""))

		source_iline = InputFilter.filter_control_chars(self.request.get_dsd("source", "")).strip()
		target_iline = InputFilter.filter_control_chars(self.request.get_dsd("target", "")).strip()

		source = source_iline

		target = target_iline

		if (target_iline == ""):
		#
			target_iline = (source_iline
			                if (source_iline != "") else
			                "s=file_form;dsd=fid+{0}".format(Link.encode_query_value(form_id))
			               )
		#

		Hook.call("dNG.pas.http.l10n.services.FileForm.init", form_id = form_id)
		L10n.init("pas_http_file_form")

		if (self.response.is_supported("html_css_files")): self.response.add_theme_css_file("mini_default_sprite.min.css")

		Link.set_store("servicemenu",
		               Link.TYPE_RELATIVE_URL,
		               L10n.get("core_back"),
		               { "__query__": re.sub("\\_\\_\\w+\\_\\_", "", source_iline) },
		               icon = "mini-default-back",
		               priority = 7
		              )

		file_path_name = path.abspath("{0}/forms/{1}.json".format(Settings.get("path_data"), form_id))

		if ((not path.exists(file_path_name))
		    or (not os.access(file_path_name, os.R_OK))
		   ): raise TranslatableError("pas_http_file_form_not_found", 404)

		file_data = JsonFileContent.read(file_path_name)
		lang = self.request.get_lang()

		if (file_data is None
		    or (("form_{0}".format(lang) not in file_data) and ("form" not in file_data))
		    or "execution" not in file_data
		    or (not isinstance(file_data['execution'], dict))
		    or "processor" not in file_data['execution']
		    or (("title_{0}".format(lang) not in file_data) and ("title" not in file_data))
		   ): raise TranslatableException("pas_http_file_form_not_supported")

		if (source_iline == ""
		    and (("html_back_url_{0}".format(lang) not in file_data) and ("html_back_url" not in file_data))
		   ):
		#
			Link.set_store("servicemenu",
			               Link.TYPE_RELATIVE_URL,
			               L10n.get("core_back"),
			               { "__query__": (file_data["html_back_url_{0}".format(lang)]
			                               if ("html_back_url_{0}".format(lang) in file_data) else
			                               file_data['html_back_url']
			                              )
			               },
			               icon = "mini-default-back",
			               priority = 7
			              )
		#

		form_id = InputFilter.filter_control_chars(self.request.get_parameter("form_id"))

		form = FormProcessor(form_id)
		if (is_save_mode): form.set_input_available()

		processor = NamedLoader.get_instance(file_data['execution']['processor'])

		if ((not isinstance(processor, AbstractFileFormProcessor))
		    or (not processor.validate_settings(file_data['execution']))
		   ): raise TranslatableException("pas_http_file_form_not_supported")

		form.load_definition(file_data["form_{0}".format(lang)] if ("form_{0}".format(lang) in file_data) else file_data['form'])

		if (is_save_mode and form.check()):
		#
			processor.set_form(form)
			processor.set_settings(file_data['execution'])

			processor.execute()

			target_iline = re.sub("\\_\\_\\w+\\_\\_", "", target_iline)

			title = (file_data["title_{0}".format(lang)] if ("title_{0}".format(lang) in file_data) else file_data['title'])

			if ("html_done_message_{0}".format(lang) in file_data): html_info = file_data["html_done_message_{0}".format(lang)]
			elif ("html_done_message" in file_data): html_info = file_data['html_done_message']
			else: html_info = L10n.get("pas_http_core_form_done_message")

			NotificationStore.get_instance().add_completed_info(html_info)

			Link.clear_store("servicemenu")

			redirect_request = PredefinedHttpRequest()
			redirect_request.set_iline(target_iline)
			self.request.redirect(redirect_request)
		#
		else:
		#
			title = (file_data["title_{0}".format(lang)] if ("title_{0}".format(lang) in file_data) else file_data['title'])

			if ("html_title_{0}".format(lang) in file_data): html_title = file_data["html_title_{0}".format(lang)]
			elif ("html_title" in file_data): html_title = file_data['html_title']
			else: html_title = XHtmlFormatting.escape(title)

			content = { "title": html_title }

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

			self.response.init()
			self.response.set_title(title)
			self.response.add_oset_content("core.form", content)
コード例 #10
0
ファイル: mp_core.py プロジェクト: dNG-git/mp_core
def on_control_point_startup(params, last_return = None):
    """
Called for "dNG.pas.upnp.ControlPoint.onStartup"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:since: v0.2.00
    """

    # global: _instances, _lock

    with _lock:
        if (len(_instances) < 1):
            upnp_control_point = ControlPoint.get_instance()

            device = NamedLoader.get_instance("dNG.data.upnp.devices.mp.ApiEndpointDevice")
            udn = Settings.get("mp_core_api_endpoint_server_udn")
            if (udn is None): udn = str(uuid_of_namespace(NAMESPACE_URL, "upnp://{0}/mp/ApiEndpoint".format(getfqdn())))

            if (device.init_device(upnp_control_point, udn)):
                device_name = Settings.get("mp_core_api_endpoint_server_name")
                if (device_name is not None): device.set_name(device_name)

                _instances.append(device)
                upnp_control_point.add_device(device)
            #

            device = NamedLoader.get_instance("dNG.data.upnp.devices.MediaServer")
            udn = Settings.get("mp_core_media_server_udn")
            if (udn is None): udn = str(uuid_of_namespace(NAMESPACE_URL, "upnp://{0}/mp/MediaServer".format(getfqdn())))

            if (device.init_device(upnp_control_point, udn)):
                device_name = Settings.get("mp_core_media_server_name")
                if (device_name is not None): device.set_name(device_name)

                _instances.append(device)
                upnp_control_point.add_device(device)
            #

            device = NamedLoader.get_instance("dNG.data.upnp.devices.RemoteUiServerDevice")
            udn = Settings.get("mp_core_remote_ui_server_udn")
            if (udn is None): udn = str(uuid_of_namespace(NAMESPACE_URL, "upnp://{0}/mp/RemoteUIServer".format(getfqdn())))

            if (device.init_device(upnp_control_point, udn)):
                device_name = Settings.get("mp_core_remote_ui_server_name")
                if (device_name is not None): device.set_name(device_name)

                _instances.append(device)
                upnp_control_point.add_device(device)
            #

            with Connection.get_instance():
                for entry in MpEntry.load_root_containers():
                    entry_id = entry.get_resource_id()

                    if (not entry.is_supported("auto_maintenance")):
                        MemoryTasks.get_instance().add("mp.tasks.ResourceScanner.{0}".format(entry_id),
                                                       ResourceScanner(entry_id),
                                                       0
                                                      )
                    #
                #
            #
        #
    #

    return last_return
コード例 #11
0
ファイル: stream.py プロジェクト: dNG-git/pas_upnp
    def execute_resource(self):
        """
Action for "resource"

:since: v0.2.00
        """

        rid = InputFilter.filter_control_chars(self.request.get_dsd("urid", ""))

        client_settings = self.get_client_settings()

        self.response.init(True, compress = client_settings.get("upnp_http_compression_supported", True))

        self._ensure_access_granted()

        if (client_settings.get("upnp_stream_filter_resource_id_hook_call", False)):
            rid_filtered = Hook.call("dNG.pas.upnp.Stream.filterResourceID",
                                     rid = rid,
                                     request = self.request,
                                     response = self.response,
                                     client_settings = client_settings
                                    )

            if (rid_filtered is not None): rid = rid_filtered
        #

        resource = Resource.load_cds_id(rid, client_settings)

        if (resource is None): raise TranslatableError("pas_http_core_404", 404)

        if ((not resource.is_supported("stream_vfs_url"))
            and (not resource.is_supported("vfs_url"))
           ): raise TranslatableError("pas_http_core_400", 400)

        if (self.response.is_supported("headers")):
            Stream._add_dlna_headers(self.request, self.response, resource)

            self.response.set_header("Content-Type", resource.get_mimetype())
        #

        vfs_url = (resource.get_stream_vfs_url()
                   if (resource.is_supported("stream_vfs_url"))
                   else resource.get_vfs_url()
                  )

        if (client_settings.get("upnp_stream_filter_url_hook_call", False)):
            vfs_url_filtered = Hook.call("dNG.pas.upnp.Stream.filterUrl",
                                         resource = resource,
                                         vfs_url = vfs_url,
                                         request = self.request,
                                         response = self.response,
                                         client_settings = client_settings
                                        )

            if (vfs_url_filtered is not None): vfs_url = vfs_url_filtered
        #

        vfs_url_elements = urlsplit(vfs_url)

        streamer_class = (""
                          if (vfs_url_elements.scheme == "") else
                          "".join([ word.capitalize() for word in vfs_url_elements.scheme.split("-") ])
                         )

        streamer = None

        if (streamer_class == "" or (not NamedLoader.is_defined("dNG.data.streamer.{0}".format(streamer_class)))):
            vfs_object = Implementation.load_vfs_url(vfs_url, True)
            if (not vfs_object.is_valid()): raise TranslatableError("pas_http_core_400", 400)

            streamer = FileLike()
            streamer.set_file(vfs_object)
            streamer.set_size(resource.get_size())
        else:
            streamer = NamedLoader.get_instance("dNG.data.streamer.{0}".format(streamer_class))
            if (not streamer.open_url(vfs_url)): raise TranslatableError("pas_http_core_400", 400)
        #

        if (client_settings.get("upnp_stream_handle_event_hook_call", False)):
            Hook.call("dNG.pas.upnp.Stream.onHandle",
                      resource = resource,
                      streamer = streamer,
                      request = self.request,
                      response = self.response,
                      client_settings = client_settings
                     )
        #

        Streaming.handle(self.request, streamer, self.response)