1# -*- coding: utf-8 -*-
2
3from geany import glog
4from traceback import format_exception
5import logging
6import sys
7
8
9GLIB_LOG_LEVEL_MAP = {
10	logging.DEBUG: glog.LOG_LEVEL_DEBUG,
11	logging.INFO: glog.LOG_LEVEL_INFO,
12	logging.WARNING: glog.LOG_LEVEL_WARNING,
13	# error and critical levels are swapped on purpose because
14	# GLib interprets CRITICAL less fatal than Python and additionally
15	# GLib abort()s the program on G_LOG_LEVEL_ERROR which is uncommon
16	# in Python
17	logging.ERROR: glog.LOG_LEVEL_CRITICAL,
18	logging.CRITICAL: glog.LOG_LEVEL_ERROR,
19}
20
21
22class PluginLogger(object):
23	"""
24	Convenience wrapper softly emulating Python's logging interface.
25	Any log messages are passed to the GLib log system using g_log()
26	and the LOG_DOMAIN is set automatically to the plugin's name for convenience.
27	"""
28
29	def __init__(self, plugin_name):
30		self._log_domain = u'geanypy-%s' % plugin_name
31
32	def debug(self, msg_format, *args, **kwargs):
33		self.log(logging.DEBUG, msg_format, *args, **kwargs)
34
35	def info(self, msg_format, *args, **kwargs):
36		self.log(logging.INFO, msg_format, *args, **kwargs)
37
38	def message(self, msg_format, *args, **kwargs):
39		self.log(glog.LOG_LEVEL_MESSAGE, msg_format, *args, **kwargs)
40
41	def warning(self, msg_format, *args, **kwargs):
42		self.log(logging.WARNING, msg_format, *args, **kwargs)
43
44	def error(self, msg_format, *args, **kwargs):
45		self.log(logging.ERROR, msg_format, *args, **kwargs)
46
47	def exception(self, msg_format, *args, **kwargs):
48		kwargs['exc_info'] = True
49		self.error(msg_format, *args, **kwargs)
50
51	def critical(self, msg_format, *args, **kwargs):
52		self.log(logging.CRITICAL, msg_format, *args, **kwargs)
53
54	warn = warning
55	fatal = critical
56
57	def log(self, level, msg_format, *args, **kwargs):
58		# map log level from Python to GLib
59		glib_log_level = GLIB_LOG_LEVEL_MAP.get(level, glog.LOG_LEVEL_MESSAGE)
60		# format message
61		log_message = msg_format % args
62		# log exception information if requested
63		exc_info = kwargs.get('exc_info', False)
64		if exc_info:
65			traceback_text = self._format_exception(exc_info)
66			log_message = '%s\n%s' % (log_message, traceback_text)
67
68		glog.glog(self._log_domain, glib_log_level, log_message)
69
70	def _format_exception(self, exc_info):
71		if not isinstance(exc_info, tuple):
72			exc_info = sys.exc_info()
73		exc_text_lines = format_exception(*exc_info)
74		return ''.join(exc_text_lines)
75