inkstitch/lib/debug.py

127 wiersze
3.8 KiB
Python

import atexit
from datetime import datetime
import os
import socket
import sys
import time
from inkex import etree
import inkex
from simplestyle import formatStyle
from svg import line_strings_to_path
from svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL
class Debug(object):
def __init__(self):
self.last_log_time = None
self.current_layer = None
def enable(self):
self.enable_log()
self.enable_debugger()
self.enable_svg()
def enable_log(self):
self.log = self._log
self.raw_log = self._raw_log
self.log_file = open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "debug.log"), "w")
self.log("Debug logging enabled.")
def enable_debugger(self):
# How to debug Ink/Stitch:
#
# 1. Install LiClipse (liclipse.com) -- no need to install Eclipse first
# 2. Start debug server as described here: http://www.pydev.org/manual_adv_remote_debugger.html
# * follow the "Note:" to enable the debug server menu item
# 3. Create a file named "DEBUG" next to inkstitch.py in your git clone.
# 4. Run any extension and PyDev will start debugging.
try:
import pydevd
except ImportError:
self.log("importing pydevd failed (debugger disabled)")
# pydevd likes to shout about errors to stderr whether I want it to or not
with open(os.devnull, 'w') as devnull:
stderr = sys.stderr
sys.stderr = devnull
try:
pydevd.settrace()
except socket.error, error:
self.log("Debugging: connection to pydevd failed: %s", error)
self.log("Be sure to run 'Start debugging server' in PyDev to enable debugging.")
else:
self.log("Enabled PyDev debugger.")
sys.stderr = stderr
def enable_svg(self):
self.svg = etree.Element("svg", nsmap=inkex.NSS)
atexit.register(self.save_svg)
def save_svg(self):
tree = etree.ElementTree(self.svg)
with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "debug.svg"), "w") as debug_svg:
tree.write(debug_svg)
def add_layer(self, name="Debug"):
layer = etree.Element("g", {
INKSCAPE_GROUPMODE: "layer",
INKSCAPE_LABEL: name
})
self.svg.append(layer)
self.current_layer = layer
def _noop(self, *args, **kwargs):
pass
log = _noop
raw_log = _noop
def _log(self, message, *args):
if self.last_log_time:
message = "(+%s) %s" % (datetime.now() - self.last_log_time, message)
self.raw_log(message, *args)
def _raw_log(self, message, *args):
now = datetime.now()
timestamp = now.isoformat()
self.last_log_time = now
print >> self.log_file, timestamp, message % args
self.log_file.flush()
def time(self, func):
def decorated(*args, **kwargs):
self.raw_log("entering %s()", func.func_name)
start = time.time()
result = func(*args, **kwargs)
end = time.time()
self.raw_log("leaving %s(), duration = %s", func.func_name, round(end - start, 6))
return result
return decorated
def log_svg_element(self, element):
if self.current_layer is None:
self.add_layer()
self.current_layer.append(element)
def log_line_string(self, line_string, color="#000000"):
"""Add a Shapely LineString to the SVG log."""
self.log_line_strings(self, [line_string])
def log_line_strings(self, line_strings, color="#000000"):
path = line_strings_to_path(line_strings)
path.set('style', formatStyle({"stroke": color, "stroke-width": "0.3"}))
self.log_svg_element(path)
debug = Debug()
enable = debug.enable