def get_registered_log_names(
            self,
            mod_identifier: Union[str, CommonModIdentity] = None) -> List[str]:
        """get_registered_log_names()

        Retrieve the names of all registered logs.

        :param mod_identifier: The name or identifier of the mod the log is registered for. Default is None.
        :type mod_identifier: Union[str, CommonModIdentity], optional
        :return: A collection of registered logs.
        :rtype: List[str]
        """
        if self._registered_logs is None:
            return list()
        mod_name = CommonModIdentity._get_mod_name(mod_identifier)
        if mod_name is None:
            log_names = []
            for log_mod_name in self._registered_logs:
                for log_name in self._registered_logs[log_mod_name]:
                    log_names.append(log_name)
            return log_names
        else:
            mod_name = mod_name.lower()
            if mod_name not in self._registered_logs:
                return list()
            return list(self._registered_logs[mod_name].keys())
    def catch_exceptions(mod_identifier: Union[str, CommonModIdentity], fallback_return: Any=None) -> Callable[..., Any]:
        """catch_exceptions(mod_identifier, fallback_return=None)

        Automatically catch exceptions thrown by the decorated function, log them to a file, and notify the player about the exception.

        .. note:: Decorate functions with this decorator to catch and log exceptions

        :param mod_identifier: The name or identity of the mod catching exceptions.
        :type mod_identifier: Union[str, CommonModIdentity]
        :param fallback_return: A value to return upon an exception being caught. Default is None.
        :type fallback_return: Any, optional
        :return: A function wrapped to catch and log exceptions.
        :rtype: Callable[..., Any]
        """
        mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)

        def _catch_exception(exception_function: Callable[..., Any]):
            @wraps(exception_function)
            def _wrapper(*args, **kwargs) -> Any:
                try:
                    return exception_function(*args, **kwargs)
                except Exception as ex:
                    CommonExceptionHandler.log_exception(mod_identifier, 'Exception caught while invoking: {}'.format(exception_function.__name__), exception=ex)
                return fallback_return
            return _wrapper
        return _catch_exception
Ejemplo n.º 3
0
    def register_log(self, mod_identifier: Union[str, CommonModIdentity], log_name: str) -> CommonLog:
        """register_log(mod_identifier, log_name)

        Create and register a log with the specified name.

        .. note:: If `log_name` matches the name of a Log already registered, that log will be returned rather than creating a new Log.

        :param mod_identifier: The name or identifier of the mod the log is registered for.
        :type mod_identifier: Union[str, CommonModIdentity]
        :param log_name: The name of the log.
        :type log_name: str
        :return: An object of type CommonLog
        :rtype: CommonLog
        """
        if self._registered_logs is None:
            self._registered_logs = dict()
        mod_name = CommonModIdentity._get_mod_name(mod_identifier)
        if mod_name is None:
            mod_name = 'Unknown_Mod_Name'
        mod_name = mod_name.lower()
        # Dict[str, Dict[str, CommonLog]]
        if mod_name not in self._registered_logs:
            self._registered_logs[mod_name] = dict()
            self._delete_old_log_files(mod_name)
        # Dict[str, CommonLog]
        if log_name in self._registered_logs[mod_name]:
            return self._registered_logs[mod_name][log_name]
        log = CommonLog(mod_identifier, log_name)
        self._registered_logs[mod_name][log_name] = log
        return log
Ejemplo n.º 4
0
    def disable_logs(self, log_name: str, mod_identifier: Union[str, CommonModIdentity]=None) -> bool:
        """disable_logs(log_name, mod_identifier=None)

        Disable all logs with the specified name.

        :param log_name: The name of the logs to disable.
        :type log_name: str
        :param mod_identifier: The name or identity of the mod to disable logs for. Default is None.
        :type mod_identifier: Union[str, CommonModIdentity], optional
        :return: True, if successful. False, if not.
        :rtype: bool
        """
        if self._registered_logs is None:
            self._registered_logs = dict()
        mod_name = CommonModIdentity._get_mod_name(mod_identifier)
        if mod_name is None:
            for log_mod_name in self._registered_logs:
                if log_name not in self._registered_logs[log_mod_name]:
                    continue
                log = self._registered_logs[log_mod_name][log_name]
                log.disable()
        else:
            mod_name = mod_name.lower()
            if log_name not in self._registered_logs[mod_name]:
                return False
            self._registered_logs[mod_name][log_name].disable()
        return True
    def log_exists(
            self,
            log_name: str,
            mod_identifier: Union[str, CommonModIdentity] = None) -> bool:
        """log_exists(log_name, mod_identifier=None)

        Determine if logs exist with the specified name.

        :param log_name: The name of the log to locate.
        :type log_name: str
        :param mod_identifier: The name or identity of the mod the log belongs to. Default is None.
        :type mod_identifier: Union[str, CommonModIdentity], optional
        :return: True, if a handler exists with the specified name.
        :rtype: bool
        """
        mod_name = CommonModIdentity._get_mod_name(mod_identifier)
        if mod_name is None:
            for log_mod_name in self._registered_logs:
                if log_name not in self._registered_logs[log_mod_name]:
                    continue
                return True
        else:
            mod_name = mod_name.lower()
            return mod_name in self._registered_logs and log_name in self._registered_logs[
                mod_name]
    def log_exception(mod_identifier: Union[str, CommonModIdentity], exception_message: str, exception: Exception=None, custom_file_path: str=None) -> bool:
        """log_exception(mod_identifier, exception_message, exception=None, custom_file_path=None)

        Manually log an exception with a custom message.

        :param mod_identifier: The name or identity of the mod logging the exception.
        :type mod_identifier: Union[str, CommonModIdentity]
        :param exception_message: A message to provide more information about the exception.
        :type exception_message: str
        :param exception: The exception being logged. Default is None.
        :type exception: Exception, optional
        :param custom_file_path: A custom file path relative to The Sims 4 folder. Example: Value is 'fake_path/to/directory', the final path would be 'The Sims 4/fake_path/to_directory'. Default is None.
        :type custom_file_path: str, optional
        :return: True, if the message was successfully logged. False, if the message was not successfully logged.
        :rtype: bool
        """
        mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
        exceptions = CommonStacktraceUtil.get_full_stack_trace()
        stack_trace = '{}{} -> {}: {}\n'.format(''.join(exceptions), exception_message, type(exception).__name__, exception)
        from sims4communitylib.utils.common_log_registry import CommonLogUtils
        file_path = CommonLogUtils.get_exceptions_file_path(mod_identifier, custom_file_path=custom_file_path)
        result = CommonExceptionHandler._log_stacktrace(mod_identifier, stack_trace, file_path)
        if result:
            CommonExceptionHandler._notify_exception_occurred(file_path, mod_identifier=mod_identifier)
        return result
Ejemplo n.º 7
0
 def _get_old_file_path_name(mod_identifier: Union[str, CommonModIdentity], file_name: str, custom_file_path: str=None) -> str:
     mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
     root_path = CommonLogUtils.get_sims_documents_location_path()
     old_file_name = 'Old_{}_{}.txt'.format(mod_identifier, file_name)
     file_path = root_path
     if custom_file_path is not None:
         file_path = os.path.join(file_path, custom_file_path)
     return os.path.join(file_path, old_file_name)
Ejemplo n.º 8
0
 def _log_stacktrace(mod_identifier: Union[str, CommonModIdentity],
                     _traceback: str, file_path: str) -> bool:
     mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
     exception_traceback_text = '[{}] {} {}\n'.format(
         mod_identifier, CommonRealDateUtils.get_current_date_string(),
         _traceback)
     return CommonIOUtils.write_to_file(file_path,
                                        exception_traceback_text,
                                        ignore_errors=True)
Ejemplo n.º 9
0
 def _get_file_path(mod_identifier: Union[str, CommonModIdentity], file_name: str) -> str:
     mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
     root_path = CommonLogUtils.get_sims_documents_location_path()
     file_path = os.path.join(root_path, '{}_{}.txt'.format(mod_identifier, file_name))
     if os.path.exists(file_path) and CommonLogUtils._file_is_too_big(file_path):
         old_file_name = 'Old_{}_{}.txt'.format(mod_identifier, file_name)
         old_file_path = os.path.join(root_path, old_file_name)
         if os.path.exists(old_file_path):
             os.remove(old_file_path)
         os.rename(file_path, old_file_path)
     return file_path
 def get_identity(cls) -> CommonModIdentity:
     """ Retrieve an identity for this mod. """
     identity_property_name = '_MOD_IDENTITY'
     if getattr(cls, identity_property_name, None) is None:
         mod_info: CommonModInfo = cls.get()
         setattr(
             cls, identity_property_name,
             CommonModIdentity(mod_info._name, mod_info._author,
                               mod_info._base_namespace,
                               mod_info._file_path))
     return getattr(cls, identity_property_name)
Ejemplo n.º 11
0
    def log(self) -> CommonLog:
        """The log for instances of the class.

        .. note:: It uses the `mod_identity` and `log_identifier` when logging.

        :return: An instance of CommonLog
        :rtype: CommonLog
        """
        if self._log is None:
            mod_name = CommonModIdentity._get_mod_name(self.mod_identity)
            self._log = CommonLogRegistry.get().register_log(
                mod_name, self.log_identifier)
        return self._log
Ejemplo n.º 12
0
 def _delete_old_log_files(self, mod_identifier: Union[str, CommonModIdentity]):
     from sims4communitylib.utils.common_io_utils import CommonIOUtils
     mod_name = CommonModIdentity._get_mod_name(mod_identifier)
     files_to_delete = (
         CommonLogUtils.get_message_file_path(mod_name),
         CommonLogUtils.get_exceptions_file_path(mod_name),
         CommonLogUtils.get_old_message_file_path(mod_name),
         CommonLogUtils.get_old_exceptions_file_path(mod_name)
     )
     for file_to_delete in files_to_delete:
         # noinspection PyBroadException
         try:
             CommonIOUtils.delete_file(file_to_delete, ignore_errors=True)
         except:
             continue
 def _notify_exception_occurred(file_path: str, mod_identifier: Union[str, CommonModIdentity]=None):
     from ui.ui_dialog_notification import UiDialogNotification
     from sims4communitylib.notifications.common_basic_notification import CommonBasicNotification
     from sims4communitylib.enums.strings_enum import CommonStringId
     from sims4communitylib.events.zone_spin.common_zone_spin_event_dispatcher import CommonZoneSpinEventDispatcher
     if not CommonZoneSpinEventDispatcher.get().game_loaded:
         return
     mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
     basic_notification = CommonBasicNotification(
         CommonStringId.EXCEPTION_OCCURRED_TITLE_FOR_MOD,
         CommonStringId.EXCEPTION_OCCURRED_TEXT,
         title_tokens=(mod_identifier,),
         description_tokens=(file_path,),
         urgency=UiDialogNotification.UiDialogNotificationUrgency.URGENT
     )
     basic_notification.show()
Ejemplo n.º 14
0
    def get_log(cls) -> CommonLog:
        """get_log()

        Retrieve a log for the class.

        .. note:: This function uses the :func:`~get_mod_identity` and :func:`~get_log_identifier` functions when logging.

        :return: An instance of CommonLog
        :rtype: CommonLog
        """
        if not hasattr(cls, '_log') or getattr(cls, '_log', None) is None:
            mod_name = CommonModIdentity._get_mod_name(cls.get_mod_identity())
            setattr(
                cls, '_log',
                CommonLogRegistry().register_log(mod_name,
                                                 cls.get_log_identifier()))
        return getattr(cls, '_log', None)
 def _get_file_name(mod_identifier: Union[str, CommonModIdentity],
                    file_name: str,
                    custom_file_path: str = None) -> str:
     mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
     root_path = CommonLogUtils.get_sims_documents_location_path()
     file_name = '{}_{}.txt'.format(mod_identifier, file_name)
     file_path = root_path
     if custom_file_path is not None:
         file_path = os.path.join(file_path, custom_file_path)
     current_file = os.path.join(file_path, file_name)
     if os.path.exists(current_file) and CommonLogUtils._file_is_too_big(
             current_file):
         old_file_name = 'Old_{}'.format(file_name)
         old_file_path = os.path.join(file_path, old_file_name)
         if os.path.exists(old_file_path):
             os.remove(old_file_path)
         os.rename(current_file, old_file_path)
     return current_file
    def get_identity(cls) -> CommonModIdentity:
        """The identity of a mod

        .. note:: It contains information about a mod such as Mod Name, Mod Author,\
            the script base namespace, and the file path to your mod.

        :return: The identity of a mod.
        :rtype: CommonModIdentity
        """
        identity_property_name = '_MOD_IDENTITY'
        if getattr(cls, identity_property_name, None) is None:
            mod_info: CommonModInfo = cls.get()
            setattr(
                cls, identity_property_name,
                CommonModIdentity(mod_info._name, mod_info._author,
                                  mod_info._base_namespace,
                                  mod_info._file_path))
        return getattr(cls, identity_property_name)
Ejemplo n.º 17
0
    def disable_all_logs(self, mod_identifier: Union[str, CommonModIdentity]=None) -> bool:
        """disable_all_logs(mod_identifier=None)

        Disable all logs from logging

        :param mod_identifier: The name or identity of the mod to disable logs for. Default is None.
        :type mod_identifier: Union[str, CommonModIdentity], optional
        :return: True, if successful. False, if not.
        :rtype: bool
        """
        if self._registered_logs is None:
            self._registered_logs = dict()
        mod_name = CommonModIdentity._get_mod_name(mod_identifier)
        if mod_name is None:
            for log_mod_name in self._registered_logs:
                for log_name in self._registered_logs[log_mod_name]:
                    self._registered_logs[log_mod_name][log_name].disable()
        else:
            mod_name = mod_name.lower()
            for log_name in self._registered_logs.get(mod_name, dict()):
                self._registered_logs[mod_name][log_name].disable()
        return True
    def register_log(self,
                     mod_identifier: Union[str, CommonModIdentity],
                     log_name: str,
                     custom_file_path: str = None) -> CommonLog:
        """register_log(mod_identifier, log_name, custom_file_path: str=None)

        Create and register a log with the specified name.

        .. note:: If `log_name` matches the name of a Log already registered, that log will be returned rather than creating a new Log.

        :param mod_identifier: The name or identifier of the mod the log is registered for.
        :type mod_identifier: Union[str, CommonModIdentity]
        :param log_name: The name of the log.
        :type log_name: str
        :param custom_file_path: A custom file path relative to The Sims 4 folder. Example: Value is 'fake_path/to/directory', the final path would be 'The Sims 4/fake_path/to_directory'. Default is None.
        :type custom_file_path: str, optional
        :return: An object of type CommonLog
        :rtype: CommonLog
        """
        if self._registered_logs is None:
            self._registered_logs = dict()
        mod_name = CommonModIdentity._get_mod_name(mod_identifier)
        mod_name = mod_name.lower()
        # Dict[str, Dict[str, CommonLog]]
        if mod_name not in self._registered_logs:
            self._registered_logs[mod_name] = dict()
            self._delete_old_log_files(mod_name,
                                       custom_file_path=custom_file_path)
        # Dict[str, CommonLog]
        if log_name in self._registered_logs[mod_name]:
            return self._registered_logs[mod_name][log_name]
        log = CommonLog(mod_identifier,
                        log_name,
                        custom_file_path=custom_file_path)
        self._registered_logs[mod_name][log_name] = log
        return log
Ejemplo n.º 19
0
 def _get_old_file_path_name(mod_identifier: Union[str, CommonModIdentity], file_name: str) -> str:
     mod_identifier = CommonModIdentity._get_mod_name(mod_identifier)
     root_path = CommonLogUtils.get_sims_documents_location_path()
     old_file_name = 'Old_{}_{}.txt'.format(mod_identifier, file_name)
     return os.path.join(root_path, old_file_name)