Commit c1857cf3 authored by sumpfralle's avatar sumpfralle

r1061@erker: lars | 2010-07-02 01:33:39 +0200

 implemented a first simple logging handler


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@432 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 1d2324f8
...@@ -31,6 +31,7 @@ import pycam.Cutters ...@@ -31,6 +31,7 @@ import pycam.Cutters
import pycam.Toolpath.Generator import pycam.Toolpath.Generator
import pycam.Toolpath import pycam.Toolpath
import pycam.Geometry.utils as utils import pycam.Geometry.utils as utils
import pycam.Utils.log
from pycam.Gui.OpenGLTools import ModelViewWindowGL from pycam.Gui.OpenGLTools import ModelViewWindowGL
from pycam import VERSION from pycam import VERSION
import pycam.Physics.ode_physics import pycam.Physics.ode_physics
...@@ -92,17 +93,22 @@ user's home directory on startup/shutdown""" ...@@ -92,17 +93,22 @@ user's home directory on startup/shutdown"""
# floating point color values are only available since gtk 2.16 # floating point color values are only available since gtk 2.16
GTK_COLOR_MAX = 65535.0 GTK_COLOR_MAX = 65535.0
log = pycam.Utils.log.get_logger()
def get_data_file_location(filename): def get_data_file_location(filename):
for base_dir in DATA_BASE_DIRS: for base_dir in DATA_BASE_DIRS:
test_path = os.path.join(base_dir, filename) test_path = os.path.join(base_dir, filename)
if os.path.exists(test_path): if os.path.exists(test_path):
return test_path return test_path
else: else:
print >>sys.stderr, "Failed to locate a resource file (%s) in %s!" % (filename, DATA_BASE_DIRS) lines = []
print >>sys.stderr, "You can extend the search path by setting the environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY) lines.append("Failed to locate a resource file (%s) in %s!" % (filename, DATA_BASE_DIRS))
lines.append("You can extend the search path by setting the environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY))
log.error(os.linesep.join(lines))
return None return None
def show_error_dialog(window, message): def show_error_dialog(window, message):
# TODO: move this to the log handler
warn_window = gtk.MessageDialog(window, type=gtk.MESSAGE_ERROR, warn_window = gtk.MessageDialog(window, type=gtk.MESSAGE_ERROR,
buttons=gtk.BUTTONS_OK, message_format=str(message)) buttons=gtk.BUTTONS_OK, message_format=str(message))
warn_window.set_title("Error") warn_window.set_title("Error")
...@@ -873,8 +879,8 @@ class ProjectGui: ...@@ -873,8 +879,8 @@ class ProjectGui:
try: try:
task = self.task_list[task_index] task = self.task_list[task_index]
except IndexError: except IndexError:
# this shoudl only happen, if we were called in batch mode (command line) # this should only happen, if we were called in batch mode (command line)
print >>sys.stderr, "The given task ID (%d) does not exist. Valid values are: %s." % (task_index, range(len(self.task_list))) log.warn("The given task ID (%d) does not exist. Valid values are: %s." % (task_index, range(len(self.task_list))))
return return
self.generate_toolpath(task["tool"], task["process"], task["bounds"]) self.generate_toolpath(task["tool"], task["process"], task["bounds"])
...@@ -1030,7 +1036,7 @@ class ProjectGui: ...@@ -1030,7 +1036,7 @@ class ProjectGui:
controls = (("x <-> y", "x_swap_y"), ("x <-> z", "x_swap_z"), ("y <-> z", "y_swap_z")) controls = (("x <-> y", "x_swap_y"), ("x <-> z", "x_swap_z"), ("y <-> z", "y_swap_z"))
else: else:
# broken gui # broken gui
print >> sys.stderr, "Unknown button action: %s" % str(widget.get_name()) log.warn("Unknown button action: %s" % str(widget.get_name()))
return return
for obj, value in controls: for obj, value in controls:
if self.gui.get_object(obj).get_active(): if self.gui.get_object(obj).get_active():
...@@ -1351,7 +1357,7 @@ class ProjectGui: ...@@ -1351,7 +1357,7 @@ class ProjectGui:
# report any ignored (obsolete) preference keys present in the file # report any ignored (obsolete) preference keys present in the file
for item, value in config.items("DEFAULT"): for item, value in config.items("DEFAULT"):
if not item in PREFERENCES_DEFAULTS.keys(): if not item in PREFERENCES_DEFAULTS.keys():
print "Warning: skipping obsolete preference item: %s" % str(item) log.warn("Skipping obsolete preference item: %s" % str(item))
for item in PREFERENCES_DEFAULTS.keys(): for item in PREFERENCES_DEFAULTS.keys():
if not config.has_option("DEFAULT", item): if not config.has_option("DEFAULT", item):
# a new preference setting is missing in the (old) file # a new preference setting is missing in the (old) file
...@@ -1372,7 +1378,8 @@ class ProjectGui: ...@@ -1372,7 +1378,8 @@ class ProjectGui:
config_filename = pycam.Gui.Settings.get_config_filename() config_filename = pycam.Gui.Settings.get_config_filename()
if config_filename is None: if config_filename is None:
# failed to create the personal preferences directory # failed to create the personal preferences directory
print >>sys.stderr, "Warning: Failed to create a preferences directory your user home directory." log.warn("Failed to create a preferences directory in " \
+ "your user's home directory.")
return return
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
for item in PREFERENCES_DEFAULTS.keys(): for item in PREFERENCES_DEFAULTS.keys():
...@@ -1382,7 +1389,7 @@ class ProjectGui: ...@@ -1382,7 +1389,7 @@ class ProjectGui:
config.write(config_file) config.write(config_file)
config_file.close() config_file.close()
except IOError, err_msg: except IOError, err_msg:
print >>sys.stderr, "Warning: Failed to write preferences file (%s): %s" % (config_filename, err_msg) log.warn("Failed to write preferences file (%s): %s" % (config_filename, err_msg))
@gui_activity_guard @gui_activity_guard
def shift_model(self, widget, use_form_values=True): def shift_model(self, widget, use_form_values=True):
...@@ -2029,7 +2036,7 @@ class ProjectGui: ...@@ -2029,7 +2036,7 @@ class ProjectGui:
toolpath = pycam.Toolpath.Generator.generate_toolpath_from_settings( toolpath = pycam.Toolpath.Generator.generate_toolpath_from_settings(
self.model, toolpath_settings, callback=draw_callback) self.model, toolpath_settings, callback=draw_callback)
print "Time elapsed: %f" % (time.time() - start_time) log.info("Toolpath generation time: %f" % (time.time() - start_time))
if isinstance(toolpath, basestring): if isinstance(toolpath, basestring):
# an error occoured - "toolpath" contains the error message # an error occoured - "toolpath" contains the error message
...@@ -2037,7 +2044,7 @@ class ProjectGui: ...@@ -2037,7 +2044,7 @@ class ProjectGui:
if not self.no_dialog: if not self.no_dialog:
show_error_dialog(self.window, message) show_error_dialog(self.window, message)
else: else:
print >>sys.stderr, message log.warn("Toolpath generation failed: %s" % str(message))
# we were not successful (similar to a "cancel" request) # we were not successful (similar to a "cancel" request)
return False return False
else: else:
...@@ -2072,7 +2079,7 @@ class ProjectGui: ...@@ -2072,7 +2079,7 @@ class ProjectGui:
pass pass
else: else:
# this should never happen # this should never happen
print >>sys.stderr, "Assertion failed: invalid boundary_mode (%s)" % str(self.settings.get("boundary_mode")) log.error("Assertion failed: invalid boundary_mode (%s)" % str(self.settings.get("boundary_mode")))
abs_bounds = self._get_bounds_limits_absolute(bounds) abs_bounds = self._get_bounds_limits_absolute(bounds)
...@@ -2251,8 +2258,7 @@ class ProjectGui: ...@@ -2251,8 +2258,7 @@ class ProjectGui:
max_skip_safety_distance=2*tool["tool_radius"], max_skip_safety_distance=2*tool["tool_radius"],
comment=os.linesep.join(meta_data)) comment=os.linesep.join(meta_data))
destination.close() destination.close()
if self.no_dialog: log.info("GCode file successfully written: %s" % str(filename))
print "GCode file successfully written: %s" % str(filename)
except IOError, err_msg: except IOError, err_msg:
if not no_dialog and not self.no_dialog: if not no_dialog and not self.no_dialog:
show_error_dialog(self.window, "Failed to save toolpath file") show_error_dialog(self.window, "Failed to save toolpath file")
......
...@@ -21,13 +21,15 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -21,13 +21,15 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
import pycam.Cutters import pycam.Cutters
import pycam.Utils.log
import ConfigParser import ConfigParser
import StringIO import StringIO
import sys
import os import os
CONFIG_DIR = "pycam" CONFIG_DIR = "pycam"
log = pycam.Utils.log.get_logger()
def get_config_dirname(): def get_config_dirname():
try: try:
from win32com.shell import shellcon, shell from win32com.shell import shellcon, shell
...@@ -282,7 +284,8 @@ process: 3 ...@@ -282,7 +284,8 @@ process: 3
try: try:
self.config.read([filename]) self.config.read([filename])
except ConfigParser.ParsingError, err_msg: except ConfigParser.ParsingError, err_msg:
print >> sys.stderr, "Failed to parse config file '%s': %s" % (filename, err_msg) log.error("Settings: Failed to parse config file '%s': %s" % \
(filename, err_msg))
return False return False
return True return True
...@@ -291,7 +294,8 @@ process: 3 ...@@ -291,7 +294,8 @@ process: 3
try: try:
self.reset(input_text) self.reset(input_text)
except ConfigParser.ParsingError, err_msg: except ConfigParser.ParsingError, err_msg:
print >> sys.stderr, "Failed to parse config data: %s" % str(err_msg) log.error("Settings: Failed to parse config data: %s" % \
str(err_msg))
return False return False
return True return True
...@@ -302,7 +306,8 @@ process: 3 ...@@ -302,7 +306,8 @@ process: 3
fi.write(text) fi.write(text)
fi.close() fi.close()
except IOError, err_msg: except IOError, err_msg:
print >> sys.stderr, "Failed to write configuration to file (%s): %s" % (filename, err_msg) log.error("Settings: Failed to write configuration to file " \
+ "(%s): %s" % (filename, err_msg))
return False return False
return True return True
...@@ -402,7 +407,8 @@ process: 3 ...@@ -402,7 +407,8 @@ process: 3
if values and (values.count(values[0]) == len(values)): if values and (values.count(values[0]) == len(values)):
common_keys.append(key) common_keys.append(key)
if common_keys: if common_keys:
section = "[%s%s]" % (self.SECTION_PREFIXES[type_name], self.DEFAULT_SUFFIX) section = "[%s%s]" % (self.SECTION_PREFIXES[type_name],
self.DEFAULT_SUFFIX)
result.append(section) result.append(section)
for key in common_keys: for key in common_keys:
value = type_list[0][key] value = type_list[0][key]
...@@ -574,7 +580,8 @@ class ToolpathSettings: ...@@ -574,7 +580,8 @@ class ToolpathSettings:
try: try:
value = value_type(raw_value) value = value_type(raw_value)
except ValueError: except ValueError:
print >>sys.stderr, "Ignored invalid setting (%s -> %s): %s" % (section, key, value_raw) log.warn("Settings: Ignored invalid setting " \
"(%s -> %s): %s" % (section, key, value_raw))
config_dict[key] = value config_dict[key] = value
def get_string(self): def get_string(self):
......
...@@ -20,11 +20,13 @@ You should have received a copy of the GNU General Public License ...@@ -20,11 +20,13 @@ You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>. along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
import pycam.Utils.log
# Tkinter is used for "EmergencyDialog" below - but we will try to import it carefully # Tkinter is used for "EmergencyDialog" below - but we will try to import it carefully
#import Tkinter #import Tkinter
import sys import sys
import os import os
log = pycam.Utils.log.get_logger()
DEPENDENCY_DESCRIPTION = { DEPENDENCY_DESCRIPTION = {
"gtk": ("Python bindings for GTK+", "gtk": ("Python bindings for GTK+",
...@@ -142,14 +144,13 @@ class EmergencyDialog: ...@@ -142,14 +144,13 @@ class EmergencyDialog:
import Tkinter import Tkinter
except ImportError: except ImportError:
# tk is not installed # tk is not installed
print >>sys.stderr, "Warning: %s" % str(title) log.warn("Failed to show error dialog due to a missing Tkinter Python package.")
print >>sys.stderr, message
return return
try: try:
root = Tkinter.Tk() root = Tkinter.Tk()
except Tkinter.TclError, err_msg: except Tkinter.TclError, err_msg:
print >>sys.stderr, "Warning: Failed to create error dialog window (%s). Probably you are running PyCAM from a terminal." % str(err_msg) log.info("Failed to create error dialog window (%s). " % str(err_msg) \
print >>sys.stderr, "%s: %s" % (title, message) + "Probably you are running PyCAM from a terminal.")
return return
root.title(title) root.title(title)
root.bind("<Return>", self.finish) root.bind("<Return>", self.finish)
......
...@@ -22,8 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -22,8 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Geometry import Point, Line from pycam.Geometry import Point, Line
import pycam.Geometry.Model import pycam.Geometry.Model
import pycam.Utils.log
import sys log = pycam.Utils.log.get_logger()
class DXFParser: class DXFParser:
...@@ -116,8 +117,8 @@ class DXFParser: ...@@ -116,8 +117,8 @@ class DXFParser:
try: try:
line1 = int(line1) line1 = int(line1)
except ValueError: except ValueError:
print >>sys.stderr, "Invalid key in line " \ log.warn("DXFImporter: Invalid key in line " \
+ "%d (int expected): %s" % (self.line_number, line1) + "%d (int expected): %s" % (self.line_number, line1))
return None, None return None, None
if line1 in (self.KEYS["START_X"], self.KEYS["START_Y"], if line1 in (self.KEYS["START_X"], self.KEYS["START_Y"],
self.KEYS["START_Z"], self.KEYS["END_X"], self.KEYS["END_Y"], self.KEYS["START_Z"], self.KEYS["END_X"], self.KEYS["END_Y"],
...@@ -125,16 +126,16 @@ class DXFParser: ...@@ -125,16 +126,16 @@ class DXFParser:
try: try:
line2 = float(line2) line2 = float(line2)
except ValueError: except ValueError:
print >>sys.stderr, "Invalid input in line " \ log.warn("DXFImporter: Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2) + "%d (float expected): %s" % (self.line_number, line2))
line1 = None line1 = None
line2 = None line2 = None
elif line1 in (self.KEYS["COLOR"],): elif line1 in (self.KEYS["COLOR"],):
try: try:
line2 = int(line2) line2 = int(line2)
except ValueError: except ValueError:
print >>sys.stderr, "Invalid input in line " \ log.warn("DXFImporter: Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2) + "%d (float expected): %s" % (self.line_number, line2))
line1 = None line1 = None
line2 = None line2 = None
else: else:
...@@ -154,8 +155,8 @@ class DXFParser: ...@@ -154,8 +155,8 @@ class DXFParser:
self.parse_line() self.parse_line()
else: else:
# not supported # not supported
print "Ignored unsupported element in line %d: %s" \ log.warn("DXFImporter: Ignored unsupported element in " \
% (self.line_number, value) + "line %d: %s" % (self.line_number, value))
key, value = self._read_key_value() key, value = self._read_key_value()
def parse_line(self): def parse_line(self):
...@@ -184,16 +185,17 @@ class DXFParser: ...@@ -184,16 +185,17 @@ class DXFParser:
if not key is None: if not key is None:
self._push_on_stack(key, value) self._push_on_stack(key, value)
if (None in p1) or (None in p2): if (None in p1) or (None in p2):
print >>sys.stderr, "Incomplete LINE definition between line " \ log.warn("DXFImporter: Incomplete LINE definition between line " \
+ "%d and %d" % (start_line, end_line) + "%d and %d" % (start_line, end_line))
else: else:
self.lines.append(Line(Point(p1[0], p1[1], p1[2]), Point(p2[0], p2[1], p2[2]))) self.lines.append(Line(Point(p1[0], p1[1], p1[2]), Point(p2[0], p2[1], p2[2])))
def check_header(self): def check_header(self):
# TODO: this function is not used?
# we expect "0" in the first line and "SECTION" in the second one # we expect "0" in the first line and "SECTION" in the second one
key, value = self._read_key_value() key, value = self._read_key_value()
if (key != KEYS["MARKER"]) or (value and (value != "SECTION")): if (key != KEYS["MARKER"]) or (value and (value != "SECTION")):
print >>sys.stderr, "DXF file header not recognized" log.error("DXFImporter: DXF file header not recognized")
return None return None
...@@ -201,7 +203,7 @@ def import_model(filename): ...@@ -201,7 +203,7 @@ def import_model(filename):
try: try:
f = open(filename,"rb") f = open(filename,"rb")
except IOError, err_msg: except IOError, err_msg:
print >>sys.stderr, "Failed to read file (%s): %s" % (filename, err_msg) log.error("DXFImporter: Failed to read file (%s): %s" % (filename, err_msg))
return None return None
result = DXFParser(f) result = DXFParser(f)
...@@ -212,14 +214,9 @@ def import_model(filename): ...@@ -212,14 +214,9 @@ def import_model(filename):
model = pycam.Geometry.Model.ContourModel() model = pycam.Geometry.Model.ContourModel()
for l in lines: for l in lines:
model.append(l) model.append(l)
print "Imported DXF model: %d lines" % len(lines) log.info("DXFImporter: Imported DXF model: %d lines" % len(lines))
return model return model
else: else:
print >>sys.stderr, "No supported elements found in DXF file!" log.error("DXFImporter: No supported elements found in DXF file!")
return None return None
if __name__ == "__main__":
filename = sys.argv[1]
import_model(filename)
...@@ -25,11 +25,14 @@ from pycam.Geometry import Point, Line, Triangle ...@@ -25,11 +25,14 @@ from pycam.Geometry import Point, Line, Triangle
from pycam.Geometry.PointKdtree import PointKdtree from pycam.Geometry.PointKdtree import PointKdtree
from pycam.Geometry.TriangleKdtree import TriangleKdtree from pycam.Geometry.TriangleKdtree import TriangleKdtree
from pycam.Geometry.Model import Model from pycam.Geometry.Model import Model
import pycam.Utils.log
from struct import unpack from struct import unpack
import re import re
import os import os
import sys
log = pycam.Utils.log.get_logger()
vertices = 0 vertices = 0
edges = 0 edges = 0
...@@ -79,7 +82,7 @@ def ImportModel(filename, use_kdtree=True): ...@@ -79,7 +82,7 @@ def ImportModel(filename, use_kdtree=True):
try: try:
f = open(filename,"rb") f = open(filename,"rb")
except IOError, err_msg: except IOError, err_msg:
print >>sys.stderr, "Failed to read file (%s): %s" % (filename, err_msg) log.error("STLImporter: Failed to read file (%s): %s" % (filename, err_msg))
return None return None
# read the first two lines of (potentially non-binary) input - they should contain "solid" and "facet" # read the first two lines of (potentially non-binary) input - they should contain "solid" and "facet"
header = f.readline(200) header = f.readline(200)
......
...@@ -39,7 +39,8 @@ def parseToolpathSettings(filename): ...@@ -39,7 +39,8 @@ def parseToolpathSettings(filename):
try: try:
f = open(filename,"r") f = open(filename,"r")
except IOError, err_msg: except IOError, err_msg:
print >>sys.stderr, "Failed to read file (%s): %s" % (filename, err_msg) log.warn("ToolpathSettingsParser: Failed to read file (%s): %s" % \
(filename, err_msg))
return None return None
for line in f.readlines(): for line in f.readlines():
match = re.match(REGEX_META_KEYWORDS, line) match = re.match(REGEX_META_KEYWORDS, line)
......
...@@ -23,11 +23,14 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -23,11 +23,14 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
__all__ = ["STLImporter", "DXFImporter", "TestModel"] __all__ = ["STLImporter", "DXFImporter", "TestModel"]
import pycam.Utils.log
import DXFImporter import DXFImporter
import STLImporter import STLImporter
import os import os
import sys
log = pycam.Utils.log.get_logger()
def detect_file_type(filename): def detect_file_type(filename):
failure = (None, None) failure = (None, None)
...@@ -41,7 +44,7 @@ def detect_file_type(filename): ...@@ -41,7 +44,7 @@ def detect_file_type(filename):
elif filename.endswith(".dxf"): elif filename.endswith(".dxf"):
return ("dxf", DXFImporter.import_model) return ("dxf", DXFImporter.import_model)
else: else:
print >>sys.stderr, "Failed to detect the model type of '%s'." \ log.error("Importers: Failed to detect the model type of '%s'." \
% filename + " Is the file extension (.stl/.dxf) correct?" % filename + " Is the file extension (.stl/.dxf) correct?")
failure return failure
...@@ -24,8 +24,10 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -24,8 +24,10 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Geometry import Point from pycam.Geometry import Point
from pycam.Geometry.utils import INFINITE from pycam.Geometry.utils import INFINITE
from pycam.PathGenerators import get_max_height_triangles, get_max_height_ode, ProgressCounter from pycam.PathGenerators import get_max_height_triangles, get_max_height_ode, ProgressCounter
import pycam.Utils.log
import math import math
import sys
log = pycam.Utils.log.get_logger()
class Dimension: class Dimension:
...@@ -129,9 +131,9 @@ class DropCutter: ...@@ -129,9 +131,9 @@ class DropCutter:
p = Point(x, y, self.safety_height) p = Point(x, y, self.safety_height)
self.pa.append(p) self.pa.append(p)
if not self._boundary_warning_already_shown: if not self._boundary_warning_already_shown:
print >>sys.stderr, "WARNING: DropCutter exceed the height" \ log.warn("DropCutter: exceed the height " \
+ " of the boundary box: using a safe height " \ + "of the boundary box: using a safe height " \
+ "instead. This warning is reported only once." + "instead. This warning is reported only once.")
self._boundary_warning_already_shown = True self._boundary_warning_already_shown = True
self.cutter.moveto(p) self.cutter.moveto(p)
# "draw_callback" returns true, if the user requested quitting via the GUI # "draw_callback" returns true, if the user requested quitting via the GUI
......
...@@ -25,8 +25,11 @@ import pycam.PathProcessors.PathAccumulator ...@@ -25,8 +25,11 @@ import pycam.PathProcessors.PathAccumulator
from pycam.Geometry import Point from pycam.Geometry import Point
from pycam.Geometry.utils import INFINITE from pycam.Geometry.utils import INFINITE
from pycam.PathGenerators import get_max_height_triangles, get_max_height_ode, get_free_paths_ode, get_free_paths_triangles, ProgressCounter from pycam.PathGenerators import get_max_height_triangles, get_max_height_ode, get_free_paths_ode, get_free_paths_triangles, ProgressCounter
import pycam.Utils.log
import math import math
import sys
log = pycam.Utils.log.get_logger()
class EngraveCutter: class EngraveCutter:
...@@ -175,9 +178,9 @@ class EngraveCutter: ...@@ -175,9 +178,9 @@ class EngraveCutter:
p = Point(x, y, self.safety_height) p = Point(x, y, self.safety_height)
pa.append(p) pa.append(p)
if not self._boundary_warning_already_shown: if not self._boundary_warning_already_shown:
print >>sys.stderr, "WARNING: DropCutter exceed the height" \ log.warn("EngraveCutter: exceed the height " \
+ " of the boundary box: using a safe height " \ + "of the boundary box: using a safe height " \
+ "instead. This warning is reported only once." + "instead. This warning is reported only once.")
self._boundary_warning_already_shown = True self._boundary_warning_already_shown = True
self.cutter.moveto(p) self.cutter.moveto(p)
# "draw_callback" returns true, if the user requested quitting via the GUI # "draw_callback" returns true, if the user requested quitting via the GUI
......
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import logging
def get_logger(suffix=None):
name = "PyCAM"
if suffix:
name += ".%s" % str(suffix)
logger = logging.getLogger(name)
if len(logger.handlers) == 0:
init_logger(logger)
return logger
def init_logger(log, logfilename=None):
if logfilename:
datetime_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
logfile_hander = logging.FileHandler(logfilename)
logfile_handler.setFormatter(datetime_format)
log.addHandler(logfile_handler)
console_output = logging.StreamHandler()
log.addHandler(console_output)
log.setLevel(logging.INFO)
def add_stream(stream):
log = get_logger()
logstream = logging.StreamHandler(stream)
log.addHandler(logstream)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment