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
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
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
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
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
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()
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
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()
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)
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
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)