def __init__(self): """ Constructor __init__(Client) :since: v1.0.0 """ self._log_handler = NamedLoader.get_singleton("dNG.data.logging.LogHandler", False) """ The LogHandler is called whenever debug messages should be logged or errors happened. """ self._message = None """ e-mail message instance """ self.timeout = 0 """ Request timeout value """ Settings.read_file("{0}/settings/pas_email.json".format(Settings.get("path_data")), True) Settings.read_file("{0}/settings/pas_smtp_client.json".format(Settings.get("path_data")), True) self.timeout = int(Settings.get("pas_smtp_client_timeout", 30))
def _configure(self): """ Configures the server :since: v1.0.0 """ listener_host = Settings.get("pas_http_twisted_server_host", self.socket_hostname) self.port = int(Settings.get("pas_http_twisted_server_port", 8080)) self.reactor = reactor self.reactor.addSystemEventTrigger('before', 'shutdown', self.stop) server_description = "tcp:{0:d}".format(self.port) if (listener_host == ""): self.host = Settings.get("pas_http_server_preferred_hostname", self.socket_hostname) else: self.host = listener_host server_description += ":interface={0}".format(self.host) # self.thread_pool = ThreadPool() self.thread_pool.start() if (self._log_handler is not None): self._log_handler.info("pas.http.core Twisted server starts at '{0}:{1:d}'", listener_host, self.port, context = "pas_http_core") server = serverFromString(self.reactor, server_description) server.listen(Site(WSGIResource(reactor, self.thread_pool, HttpWsgi1Request))) """ Configure common paths and settings """ AbstractServer._configure(self)
def __init__(self): """ Constructor __init__(GstVideo) :since: v0.2.00 """ AbstractVideo.__init__(self) Gstreamer.__init__(self) self.playback_control_timeout = 5 """ Playback control command timeout. """ self.thumbnail_position_percentage = 0.05 """ Position in percent where to generate a thumbnail from. """ playback_control_timeout = float(Settings.get("pas_gapi_gstreamer_playback_control_timeout", 0)) if (playback_control_timeout > 0): self.playback_control_timeout = playback_control_timeout self.supported_features['thumbnail'] = True thumbnail_position_percentage = Settings.get("pas_gapi_gstreamer_thumbnail_position_percentage", 0) if (thumbnail_position_percentage > 0 and thumbnail_position_percentage <= 100 ): self.thumbnail_position_percentage = (thumbnail_position_percentage / 100)
def send(self): """ Sends a message. :since: v1.0.0 """ if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}.send()- (#echo(__LINE__)#)", self, context = "pas_email") if (self.message is None): raise IOException("No message defined to be send") if (not self.message.is_recipient_set): raise ValueException("No recipients defined for e-mail") if (not self.message.is_subject_set): raise IOException("No subject defined for e-mail") bcc_list = self.message.bcc cc_list = self.message.cc to_list = self.message.to rcpt_list = to_list if (len(bcc_list) > 0): rcpt_list = Client._filter_unique_list(rcpt_list, bcc_list) if (len(cc_list) > 0): rcpt_list = Client._filter_unique_list(rcpt_list, cc_list) is_auth_possible = False smtp_user = None smtp_password = None if (Settings.is_defined("pas_smtp_client_user") and Settings.is_defined("pas_smtp_client_password")): is_auth_possible = True smtp_user = Settings.get("pas_smtp_client_user") smtp_password = Settings.get("pas_smtp_client_password") # smtp_connection = None try: smtp_connection = (self._get_lmtp_connection() if (Settings.is_defined("pas_smtp_client_lmtp_host") or Settings.is_defined("pas_smtp_client_lmtp_path_name") ) else self._get_smtp_connection() ) if (is_auth_possible): smtp_connection.login(smtp_user, smtp_password) if (not self.message.is_sender_set): self.message.sender = (Settings.get("pas_email_sender_public") if (Settings.is_defined("pas_email_sender_public")) else Settings.get("pas_email_address_public") ) # sender = self.message.sender smtp_connection.sendmail(sender, rcpt_list, self.message.as_string()) self.message = None finally: try: if (smtp_connection is not None): smtp_connection.quit() except SMTPServerDisconnected: pass
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
def _init_theme_renderer(self): """ Set up theme framework if renderer has not already been initialized. :since: v1.0.0 """ if (self._theme_renderer is None): if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._init_theme_renderer()- (#echo(__LINE__)#)", self, context = "pas_http_core") Settings.read_file("{0}/settings/pas_http_theme.json".format(Settings.get("path_data"))) if (self._theme is None): theme = AbstractHttpRequest.get_instance().get_parameter("theme") if (theme is not None): self._theme = theme # theme = (Hook.call("dNG.pas.http.Theme.checkCandidates", theme = self._theme) if (Settings.get("pas_http_theme_plugins_supported", True)) else None ) if (theme is not None): theme = re.sub("\\W", "", theme) self._theme_renderer = NamedLoader.get_instance("dNG.data.xhtml.theme.Renderer") self._theme_renderer.theme = (self._theme if (theme is None) else theme) self._theme_active = self._theme_renderer.theme Settings.set("x_pas_http_theme", self.theme) self.theme_active_base_path = path.join(Settings.get("path_data"), "assets", "themes", self.theme_active ) self._theme_renderer.log_handler = self._log_handler self._theme_renderer.theme = self.theme_active self._theme_renderer.theme_subtype = self.theme_subtype if (self._description is not None): self._theme_renderer.description = self._description if (self._canonical_url is not None): self._theme_renderer.canonical_url = self.canonical_url for css_file in self.css_files_cache: self.add_css_file(css_file) self.css_files_cache = [ ] for js_file in self.js_files_cache: self.add_js_file(js_file) self.js_files_cache = [ ] for theme_css_file in self.theme_css_files_cache: self.add_theme_css_file(theme_css_file) self.theme_css_files_cache = [ ] for webc_file in self.webc_files_cache: self.add_webc_file(webc_file) self.webc_files_cache = [ ]
def __init__(self): """ Constructor __init__(Module) :since: v0.2.00 """ AbstractHttpController.__init__(self) Settings.read_file("{0}/settings/pas_tasks.json".format(Settings.get("path_data"))) Settings.read_file("{0}/settings/pas_http_tasks.json".format(Settings.get("path_data")))
def _on_run(self, args): """ Callback for execution. :param args: Parsed command line arguments :since: v0.2.00 """ # pylint: disable=attribute-defined-outside-init Settings.read_file("{0}/settings/pas_global.json".format(Settings.get("path_data"))) Settings.read_file("{0}/settings/pas_core.json".format(Settings.get("path_data")), True) Settings.read_file("{0}/settings/pas_tasks_daemon.json".format(Settings.get("path_data")), True) if (args.additional_settings is not None): Settings.read_file(args.additional_settings, True) if (not Settings.is_defined("pas_tasks_daemon_listener_address")): raise IOException("No listener address defined for the TasksDaemon") if (args.reload_plugins): client = BusClient("pas_tasks_daemon") client.request("dNG.pas.Plugins.reload") elif (args.stop): client = BusClient("pas_tasks_daemon") pid = client.request("dNG.pas.Status.getOSPid") client.request("dNG.pas.Status.stop") self._wait_for_os_pid(pid) else: self.cache_instance = NamedLoader.get_singleton("dNG.data.cache.Content", False) if (self.cache_instance is not None): Settings.set_cache_instance(self.cache_instance) self.log_handler = NamedLoader.get_singleton("dNG.data.logging.LogHandler", False) if (self.log_handler is not None): Hook.set_log_handler(self.log_handler) NamedLoader.set_log_handler(self.log_handler) # Hook.load("tasks") Hook.register("dNG.pas.Status.getOSPid", self.get_os_pid) Hook.register("dNG.pas.Status.getTimeStarted", self.get_time_started) Hook.register("dNG.pas.Status.getUptime", self.get_uptime) Hook.register("dNG.pas.Status.stop", self.stop) self.server = BusServer("pas_tasks_daemon") self._set_time_started(time()) if (self.log_handler is not None): self.log_handler.info("TasksDaemon starts listening", context = "pas_tasks") Hook.call("dNG.pas.Status.onStartup") Hook.call("dNG.pas.tasks.Daemon.onStartup") self.set_mainloop(self.server.run)
def _on_run(self, args): """ Callback for execution. :param args: Parsed command line arguments :since: v0.2.00 """ Settings.read_file("{0}/settings/pas_global.json".format(Settings.get("path_data"))) Settings.read_file("{0}/settings/pas_core.json".format(Settings.get("path_data")), True) Settings.read_file("{0}/settings/pas_http.json".format(Settings.get("path_data")), True) if (args.additional_settings is not None): Settings.read_file(args.additional_settings, True) if (args.reload_plugins): client = BusClient("pas_http_bus") client.request("dNG.pas.Plugins.reload") elif (args.stop): client = BusClient("pas_http_bus") pid = client.request("dNG.pas.Status.getOSPid") client.request("dNG.pas.Status.stop") self._wait_for_os_pid(pid) else: self.log_handler = NamedLoader.get_singleton("dNG.data.logging.LogHandler", False) if (self.log_handler is not None): Hook.set_log_handler(self.log_handler) NamedLoader.set_log_handler(self.log_handler) # self.cache_instance = NamedLoader.get_singleton("dNG.data.cache.Content", False) if (self.cache_instance is not None): Settings.set_cache_instance(self.cache_instance) Hook.load("http") Hook.register("dNG.pas.Status.getOSPid", self.get_os_pid) Hook.register("dNG.pas.Status.getTimeStarted", self.get_time_started) Hook.register("dNG.pas.Status.getUptime", self.get_uptime) Hook.register("dNG.pas.Status.stop", self.stop) self._set_time_started(time()) http_server = _HttpServer.get_instance() self.server = BusServer("pas_http_bus") if (http_server is not None): Hook.register("dNG.pas.Status.onStartup", http_server.start) Hook.register("dNG.pas.Status.onShutdown", http_server.stop) if (self.log_handler is not None): self.log_handler.info("pas.http starts listening", context = "pas_http_site") Hook.call("dNG.pas.Status.onStartup") self.set_mainloop(self.server.run)
def _get_implementation_class_name(): """ Returns the media implementation class name based on the configuration set. :return: (str) Media implementation class name :since: v0.2.00 """ Settings.read_file("{0}/settings/pas_media.json".format(Settings.get("path_data"))) _return = Settings.get("pas_media_video_implementation", "") if (_return == ""): LogLine.warning("Media video implementation class is not configured") return _return
def __init__(self, _type, control_point = None): """ Constructor __init__(ControlPointEvent) :param _type: Event to be delivered :param control_point: Control point scheduling delivery :since: v0.2.00 """ AbstractEvent.__init__(self, _type) self.announcement_divider = None """ Divider for the announcements interval to set how many announcements will be within the interval """ self.announcement_interval = None """ Announcement interval """ self.configid = None """ UPnP configId value (configid.upnp.org) """ self.location = None """ UPnP HTTP location URL """ self.search_target = None """ M-SEARCH ST value """ self.target_host = None """ M-SEARCH response target host """ self.target_port = None """ M-SEARCH response target port """ self.usn = None """ UPnP USN """ Settings.read_file("{0}/settings/pas_upnp.json".format(Settings.get("path_data"))) self.announcement_divider = int(Settings.get("pas_upnp_announcement_divider", 3)) self.announcement_interval = int(Settings.get("pas_upnp_announcement_interval", 3600)) self.control_point = control_point
def get_view(self): """ Action for "view" :since: v1.0.0 """ cid = InputFilter.filter_file_path(self.request.get_parameter("cid", "")) source_iline = InputFilter.filter_control_chars(self.request.get_parameter("source", "")).strip() L10n.init("pas_http_core_contentfile") Settings.read_file("{0}/settings/pas_http_contentfiles.json".format(Settings.get("path_data"))) contentfiles = Settings.get("pas_http_contentfiles_list", { }) if (type(contentfiles) is not dict): raise TranslatableError("pas_http_core_contentfile_cid_invalid", 404) if (source_iline != ""): if (self.response.is_supported("html_css_files")): self.response.add_theme_css_file("mini_default_sprite.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 ) # if (cid not in contentfiles or "title" not in contentfiles[cid] or "filepath" not in contentfiles[cid] ): raise TranslatableError("pas_http_core_contentfile_cid_invalid", 404) file_content = FileContent.read(contentfiles[cid]['filepath']) if (file_content is None): raise TranslatableError("pas_http_core_contentfile_cid_invalid", 404) if (path.splitext(contentfiles[cid]['filepath'])[1].lower() == ".ftg"): file_content = FormTags.render(file_content) content = { "title": contentfiles[cid]['title'], "content": file_content } self.response.init() self.response.page_title = contentfiles[cid]['title'] self.response.add_oset_content("core.simple_content", content)
def is_preferred_defined(context = None): """ Returns true if a defined preferred URL exists for the given context. :param context: Context for the preferred link :return: (bool) True if defined :since: v0.2.00 """ url = None if (context is not None): url = Settings.get("pas_http_site_preferred_url_base_{0}".format(re.sub("\\W+", "_", context))) if (url is None): url = Settings.get("pas_http_site_preferred_url_base") return (url is not None)
def __init__(self, db_instance = None): """ Constructor __init__(Uuids) :since: v0.2.00 """ Abstract.__init__(self) if (db_instance is None): db_instance = _DbUuids() Instance.__init__(self, db_instance) self.session_time = int(Settings.get("pas_session_uuids_session_time", 900)) """ Max age of the session """ self.uuid = db_instance.uuid """ Database uuID used for reloading """ self.validity = None """ Validity of the session """ if (self.local.db_instance.data is not None and self.local.db_instance.data != ""): self.cache = JsonResource().json_to_data(self.local.db_instance.data) if (self.local.db_instance.session_timeout is None): self.local.db_instance.session_timeout = int(time() + self.session_time)
def _get_default_list_condition_definition(): """ Returns the default condition definition used for listings. :return: (object) ConditionDefinition instance :since: v0.2.00 """ _return = ConditionDefinition() archive_timeout = int(Settings.get("pas_tasks_database_tasks_archive_timeout", 28)) * 86400 completed_condition_definition = ConditionDefinition(ConditionDefinition.AND) timestamp = int(time()) timestamp_archive = timestamp - archive_timeout completed_condition_definition.add_exact_match_condition("status", DatabaseTask.STATUS_COMPLETED) completed_condition_definition.add_greater_than_match_condition("time_scheduled", 0) completed_condition_definition.add_less_than_match_condition("time_scheduled", timestamp_archive) _return.add_sub_condition(completed_condition_definition) _return.add_exact_no_match_condition("status", DatabaseTask.STATUS_COMPLETED) _return.add_exact_match_condition("timeout", 0) _return.add_greater_than_match_condition("timeout", timestamp) return _return
def _is_file_access_allowed(self, file_path_name): """ Checks if the file access is allowed for streaming. :param file_path_name: Path to the requested file :return: (bool) True if allowed :since: v0.2.00 """ _return = False if Settings.is_defined("pas_streamer_file_basedir_list"): basedir_list = Settings.get("pas_streamer_file_basedir_list") if type(basedir_list) is list: file_absolute_path_name = path.abspath(file_path_name) for basedir in basedir_list: if file_absolute_path_name.startswith(basedir): _return = True break # # if (not _return) and self.log_handler is not None: self.log_handler.warning( "streamer.File denied access to {0}", file_path_name, context="pas_streamer" ) # else: _return = True return _return
def schedule(self, wait_timeout = 0): """ Activates all relevant multicast listeners based on the IP address given. :param wait_timeout: Time to wait before delivery :since: v0.2.00 """ # pylint: disable=star-args if (self.type == ControlPointEvent.TYPE_DEVICE_ALIVE): event = ControlPointEvent(ControlPointEvent.TYPE_DEVICE_SHUTDOWN, control_point = self.control_point) if (self.configid is not None): event.set_configid(self.configid) event.set_usn(self.usn) event.deliver() elif (self.type == ControlPointEvent.TYPE_DEVICE_UPDATE and (not Settings.get("pas_upnp_ssdp_update_disabled", False)) ): event = ControlPointEvent(ControlPointEvent.TYPE_DEVICE_SHUTDOWN, control_point = self.control_point) if (self.configid is not None): event.set_configid(self.configid) event.set_usn(self.usn) event.set_location(self.location) event.schedule() self.type = ControlPointEvent.TYPE_DEVICE_ALIVE if (wait_timeout < 0.3): wait_timeout = 0.3 # AbstractEvent.schedule(self, wait_timeout)
def _enter_context(self): """ Enters the connection context. :since: v1.0.0 """ if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._enter_context()- (#echo(__LINE__)#)", self, context = "pas_database") self._ensure_thread_local() if (self.local.context_depth < 1): if (Connection.is_serialized()): Connection._serialized_lock.acquire() if (self._log_handler is not None and Settings.get("pas_database_threaded_debug", False) ): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._enter_context()- reporting: Connection acquired for thread ID {1:d}", self, current_thread().ident, context = "pas_database") # try: self._ensure_thread_local_session() self.local.context_depth += 1 except Exception: if (self.local.context_depth < 1 and Connection.is_serialized() ): Connection._serialized_lock.release() raise
def _handle_host_definition_headers(self, headers, default_host_definition_headers): """ Handles headers containing the server host name and port. :param headers: Headers to search :param default_host_definition_headers: Default list of HOST header names :since: v1.0.0 """ host_definition_headers = Settings.get("pas_http_server_host_definition_headers", default_host_definition_headers ) for host_definition_header in host_definition_headers: if (host_definition_header in headers): host_definition_header = host_definition_header.upper() host_parts = headers[host_definition_header].rsplit(":", 2) if (len(host_parts) < 2 or host_parts[1][-1:] == "]"): self._server_host = headers[host_definition_header] else: self._server_host = host_parts[0] if (self.server_port is None): self._server_port = int(host_parts[1]) # del(headers[host_definition_header]) break
def _get_blake2_password(self, variant, password, username = None): """ Returns the BLAKE2 generated password hash. :param password: User profile password :param username: User name used while generating BLAKE2 hash :return: (str) Hash on success; None if not supported :since: v0.2.00 """ blake2 = None blake2_person = None blake2_salt = None salt = Settings.get("pas_user_profile_password_salt") if (salt is None): raise ValueException("User profile password salt is not defined") if (variant == PasswordGeneratorsMixin.PASSWORD_TYPE_BLAKE2B): blake2 = blake2b blake2_salt = Binary.bytes(salt[:blake2b.SALT_SIZE]) blake2_person = Binary.utf8_bytes(username[:blake2b.PERSON_SIZE]) # if (variant == PasswordGeneratorsMixin.PASSWORD_TYPE_BLAKE2S): blake2 = blake2s blake2_salt = Binary.bytes(salt[:blake2s.SALT_SIZE]) blake2_person = Binary.utf8_bytes(username[:blake2s.PERSON_SIZE]) # if (blake2 is None): raise ValueException("BLAKE2 variant given is invalid") return blake2(Binary.utf8_bytes(password), salt = blake2_salt, person = blake2_person).hexdigest()
def _parse_gst_caps_codec(self, caps, codec): """ Parses the GStreamer caps codec for a matching mimetype identifier. :param caps: GStreamer caps dict :param codec: GStreamer codec name :return: (str) GStreamer codec / Mimetype identifier :since: v0.2.00 """ _return = codec if (type(caps) is dict and type(codec) is str): gst_mimetypes = Settings.get("pas_gapi_gstreamer_mimetypes", { }) if (codec in gst_mimetypes): if (type(gst_mimetypes[codec]) is str): _return = gst_mimetypes[codec] else: codec = self._parse_gst_caps_dependencies(caps, gst_mimetypes[codec]) if (codec is not None): _return = codec # # # return _return
def get_user_agent_identifiers(user_agent): """ Returns a UPnP client based on the given HTTP or SSDP user agent value. :param user_agent: HTTP or SSDP user agent value :return: (object) UPnP client; None on error :since: v0.2.00 """ _return = "" if (not Settings.is_defined("pas_upnp_client_replacement_list")): Settings.read_file("{0}/settings/pas_upnp.json".format(Settings.get("path_data"))) replacement_list = Settings.get("pas_upnp_client_replacement_list", None) if (type(replacement_list) is dict): replacement_list_keys = sorted(replacement_list.keys(), reverse = True) for upnp_value in replacement_list_keys: user_agent = user_agent.replace(upnp_value, replacement_list[upnp_value]) # for re_result in re.finditer("([\\d\\w\\.]+/([0-9\\.]+(\\W|$))+)", user_agent): if (_return != ""): _return += "_" _return += re.sub("\\W+", "_", re_result.group(1)).strip("_") # if (_return == ""): _return = re.sub("\\W+", "_", user_agent).lower() else: _return = _return.lower() return _return
def _exit_context(self, exc_type, exc_value, traceback): """ Exits the connection context. :since: v1.0.0 """ if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._exit_context()- (#echo(__LINE__)#)", self, context = "pas_database") self.local.context_depth -= 1 try: if (self.local.context_depth < 1): if (self.local.transactions > 0 and self._log_handler is not None): self._log_handler.warning("{0!r} has active transactions ({1:d}) while exiting the connection context", self, self.local.transactions, context = "pas_database") # if (self.local.sa_session is not None): if (exc_type is None and exc_value is None and self.local.sa_session.is_active): self.local.sa_session.commit() else: self.local.sa_session.rollback() # self.local.transactions = 0 if (self._log_handler is not None and Settings.get("pas_database_threaded_debug", False) ): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._exit_context()- reporting: Cleared session instances for thread ID {1:d}", self, current_thread().ident, context = "pas_database") # # finally: if (Connection.is_serialized() and self.local.context_depth < 1 ): Connection._serialized_lock.release()
def __init__(self): """ Constructor __init__(Multipart) :since: v1.0.0 """ Data.__init__(self) self.parts = None """ Parts found in the "multipart/form_data" submission. """ self.pending_buffer = None """ Currently receiving buffer. """ self.pending_buffer_header_size_max = int(Settings.get("pas_http_site_request_body_multipart_pending_buffer_header_size_max", 65536)) """ Maximum size in bytes for a part header """ self.pending_mime_parts = [ ] """ MIME parts currently opened. """ self.pending_received_data = None """ Data received but not yet completely parsed. """ self.supported_features['body_parser'] = True
def _run_hook(self, **kwargs): """ Hook execution :return: (mixed) Task result :since: v0.2.00 """ condition_definition = self._get_condition_definition() _return = MpEntry.get_entries_count_with_condition(condition_definition) limit = Settings.get("pas_database_delete_iterator_limit", 50) entry_iterator_count = ceil(_return / limit) LogLine.info("{0!r} removes {1:d} matches", self, _return, context = "mp_server") for _ in range(0, entry_iterator_count): with TransactionContext(): entries = MpEntry.load_entries_list_with_condition(condition_definition, limit = limit) for entry in entries: parent_entry = entry.load_parent() if (isinstance(parent_entry, MpEntry)): parent_entry.remove_content(entry) entry.delete() # # # return _return
def _get_lmtp_connection(self): """ Returns an established LMTP connection. :return: (object) LMTP connection :since: v1.0.0 """ smtp_options = { } if (Settings.is_defined("pas_smtp_client_sender_hostname")): smtp_options['local_hostname'] = Settings.get("pas_smtp_client_sender_hostname") _return = (LMTP(Settings.get("pas_smtp_client_lmtp_host"), int(Settings.get("pas_smtp_client_lmtp_port", 24))) if (Settings.is_defined("pas_smtp_client_lmtp_host")) else LMTP(Settings.get("pas_smtp_client_lmtp_path_name")) ) return _return
def is_valid(self): """ Returns true if the defined session is valid. :return: (bool) True if session is valid :since: v1.0.0 """ _return = False passcode = self.session.get("uuids.passcode") if (not self.session.is_persistent): _return = True elif (passcode is not None): cookie_passcode = None request = NamedLoader.get_singleton("dNG.controller.AbstractHttpRequest", False) response = AbstractHttpResponse.get_instance() if (request is not None): uuids_cookie = request.get_cookie("uuids") if (uuids_cookie is not None): cookie_data = uuids_cookie.split(":", 1) if (cookie_data[0] == self.session.uuid): cookie_passcode = cookie_data[1] # # passcode_prev = self.session.get("uuids.passcode_prev") passcode_timeout = self.session.get("uuids.passcode_timeout", 0) if (passcode_timeout + Settings.get("pas_session_uuids_passcode_grace_period", 15) > time()): passcode_prev_timeout = self.session.get("uuids.passcode_prev_timeout") if (cookie_passcode == Tmd5.hash(passcode)): _return = True elif (passcode_prev_timeout is not None and (passcode_prev_timeout + Settings.get("pas_session_uuids_passcode_grace_period", 15) > time() or (passcode_prev is not None and cookie_passcode == Tmd5.hash(passcode_prev)) ) ): _return = True # if (not _return and isinstance(response, AbstractHttpResponse)): response.set_cookie("uuids", "", 0) # return _return
def _apply_form(self, form, document = None): """ Applies document form fields to given form instance. :param form: Form instance :param document: Document to get default data values from :since: v0.2.00 """ document_data = ({ "title": None, "tag": None, "content": None, "description": None } if (document is None) else document.get_data_attributes("title", "tag", "content", "description") ) field = TextField("ctitle") field.set_title(L10n.get("pas_http_contentor_document_title")) field.set_value(document_data['title']) field.set_required() field.set_size(TextField.SIZE_LARGE) field.set_limits(int(Settings.get("pas_http_contentor_document_title_min", 3))) form.add(field) field = TextField("ctag") field.set_title(L10n.get("pas_http_contentor_document_tag")) field.set_value(document_data['tag']) field.set_size(TextField.SIZE_SMALL) field.set_limits(_max = 255) field.set_validators([ self._check_tag_unique ]) form.add(field) field = FormTagsTextareaField("cdescription") field.set_title(L10n.get("pas_http_contentor_document_description")) field.set_value(document_data['description']) field.set_size(FormTagsTextareaField.SIZE_SMALL) field.set_limits(_max = 255) form.add(field) field = FormTagsTextareaField("ccontent") field.set_title(L10n.get("pas_http_contentor_document_content")) field.set_value(document_data['content']) field.set_required() field.set_size(FormTagsTextareaField.SIZE_LARGE) field.set_limits(int(Settings.get("pas_http_contentor_document_content_min", 6))) form.add(field)
def default_theme(self): """ Returns the default theme name. :return: (str) Theme name :since: v1.0.0 """ return Settings.get("pas_http_site_theme_default", "simple")
def __init__(self, username): """ Constructor __init__(UpdateSecID) :param username: Username to unlock :since: v0.2.00 """ AbstractTask.__init__(self) self.username = username """ Username to send the e-mail to """ Settings.read_file("{0}/settings/pas_http.json".format(Settings.get("path_data"))) Settings.read_file("{0}/settings/pas_user_profile.json".format(Settings.get("path_data")))
def _ensure_administrative_user_account(): """ Checks if at least one active administrative user profile exists. Creates one if this is not the case. :since: v0.2.00 """ cli = InteractiveCli.get_instance() cli.output_info("Validating administrative account ...") user_profile_class = NamedLoader.get_class("dNG.data.user.Profile") if (next(user_profile_class.load_list(limit = 1, _type = "ad"), None) is not None): cli.output_info("Administrative account is available") else: cli.output_info("No valid administrative account found") Settings.read_file("{0}/settings/pas_user_profile.json".format(Settings.get("path_data"))) password = "".join(choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for _ in range(20)) password_encrypted = Tmd5.password_hash(password, Settings.get("pas_user_profile_password_salt"), "root") cli.output("") cli.output("A new default account will be generated.") cli.output("") cli.output("---------------------------------") cli.output("User name: root") cli.output(" e-mail: [email protected]") cli.output(" Password: {0}", password) cli.output("---------------------------------") cli.output("") cli.output("Please change this account as soon as possible.") cli.output("") user_profile = user_profile_class() user_profile.set_data_attributes(type = user_profile_class.get_type_int("ad"), name = "root", password = password_encrypted, locked = False, email = "*****@*****.**" ) user_profile.save()
def _generate_secid_value(): """ Generates a list of "Security ID string elements" usually joined and saved in a hashed form in a database. :return: (generator) Security ID string element generator :since: v0.2.00 """ elements = int(Settings.get("pas_user_profile_secid_elements", 10)) for _ in range(0, elements): yield "{0}{1:0>3d}".format(chr(randrange(65, 71)), randrange(1, 1000))
def _get_tmd5_password(self, password, username = None): """ Returns the triple MD5 generated password hash. :param password: User profile password :param username: User name used while generating the triple MD5 hash :return: (str) Hash on success; None if not supported :since: v0.2.00 """ salt = Settings.get("pas_user_profile_password_salt") if (salt is None): raise ValueException("User profile password salt is not defined") return Tmd5.password_hash(password, salt, username)
def __init__(self, db_instance=None): """ Constructor __init__(Profile) :since: v0.2.00 """ if (db_instance is None): db_instance = _DbUserProfile() AbstractProfile.__init__(self) Instance.__init__(self, db_instance) LockableMixin.__init__(self) PasswordGeneratorsMixin.__init__(self) self.db_id = (None if (db_instance is None) else self.get_id()) """ Database ID used for reloading """ Settings.read_file("{0}/settings/pas_user_profile.json".format( Settings.get("path_data"))) self.supported_features['password_missed'] = True