1# This file is part of Gajim. 2# 3# Gajim is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published 5# by the Free Software Foundation; version 3 only. 6# 7# Gajim is distributed in the hope that it will be useful, 8# but WITHOUT ANY WARRANTY; without even the implied warranty of 9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# GNU General Public License for more details. 11# 12# You should have received a copy of the GNU General Public License 13# along with Gajim. If not, see <http://www.gnu.org/licenses/>. 14 15''' 16Helper code related to plug-ins management system. 17 18:author: Mateusz Biliński <mateusz@bilinski.it> 19:since: 30th May 2008 20:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it> 21:license: GPL 22''' 23 24__all__ = ['log', 'log_calls'] 25 26from typing import List 27 28import logging 29import functools 30 31from gajim.common import configpaths 32from gajim.plugins import plugins_i18n 33from gajim.gui.util import Builder 34 35log = logging.getLogger('gajim.plugin_system') 36''' 37Logger for code related to plug-in system. 38 39:type: logging.Logger 40''' 41 42class GajimPluginActivateException(Exception): 43 ''' 44 Raised when activation failed 45 ''' 46 47class log_calls: 48 ''' 49 Decorator class for functions to easily log when they are entered and left. 50 ''' 51 52 filter_out_classes = ['GajimPluginConfig', 'PluginManager', 53 'GajimPluginConfigDialog', 'PluginsWindow'] 54 ''' 55 List of classes from which no logs should be emitted when methods are 56 called, even though `log_calls` decorator is used. 57 ''' 58 59 def __init__(self, classname=''): 60 ''' 61 :Keywords: 62 classname : str 63 Name of class to prefix function name (if function is a method). 64 log : logging.Logger 65 Logger to use when outputting debug information on when function has 66 been entered and when left. By default: `plugins.helpers.log` 67 is used. 68 ''' 69 70 self.full_func_name = '' 71 ''' 72 Full name of function, with class name (as prefix) if given 73 to decorator. 74 75 Otherwise, it's only function name retrieved from function object 76 for which decorator was called. 77 78 :type: str 79 ''' 80 self.log_this_class = True 81 ''' 82 Determines whether wrapper of given function should log calls of this 83 function or not. 84 85 :type: bool 86 ''' 87 88 if classname: 89 self.full_func_name = classname+'.' 90 91 if classname in self.filter_out_classes: 92 self.log_this_class = False 93 94 def __call__(self, f): 95 ''' 96 :param f: function to be wrapped with logging statements 97 98 :return: given function wrapped by *log.debug* statements 99 :rtype: function 100 ''' 101 102 self.full_func_name += f.__name__ 103 if self.log_this_class: 104 @functools.wraps(f) 105 def wrapper(*args, **kwargs): 106 107 log.debug('%s() <entered>', self.full_func_name) 108 result = f(*args, **kwargs) 109 log.debug('%s() <left>', self.full_func_name) 110 return result 111 else: 112 @functools.wraps(f) 113 def wrapper(*args, **kwargs): 114 result = f(*args, **kwargs) 115 return result 116 117 return wrapper 118 119 120def get_builder(file_name: str, widgets: List[str] = None) -> Builder: 121 return Builder(file_name, 122 widgets, 123 domain=plugins_i18n.DOMAIN, 124 gettext_=plugins_i18n._) 125 126 127def is_shipped_plugin(path): 128 base = configpaths.get('PLUGINS_BASE') 129 if not base.exists(): 130 return False 131 plugin_parent = path.parent 132 return base.samefile(plugin_parent) 133