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
import pycam.Toolpath.Generator
import pycam.Toolpath
import pycam.Geometry.utils as utils
import pycam.Utils.log
from pycam.Gui.OpenGLTools import ModelViewWindowGL
from pycam import VERSION
import pycam.Physics.ode_physics
......@@ -92,17 +93,22 @@ user's home directory on startup/shutdown"""
# floating point color values are only available since gtk 2.16
GTK_COLOR_MAX = 65535.0
log = pycam.Utils.log.get_logger()
def get_data_file_location(filename):
for base_dir in DATA_BASE_DIRS:
test_path = os.path.join(base_dir, filename)
if os.path.exists(test_path):
return test_path
else:
print >>sys.stderr, "Failed to locate a resource file (%s) in %s!" % (filename, DATA_BASE_DIRS)
print >>sys.stderr, "You can extend the search path by setting the environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY)
lines = []
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
def show_error_dialog(window, message):
# TODO: move this to the log handler
warn_window = gtk.MessageDialog(window, type=gtk.MESSAGE_ERROR,
buttons=gtk.BUTTONS_OK, message_format=str(message))
warn_window.set_title("Error")
......@@ -873,8 +879,8 @@ class ProjectGui:
try:
task = self.task_list[task_index]
except IndexError:
# this shoudl 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)))
# this should only happen, if we were called in batch mode (command line)
log.warn("The given task ID (%d) does not exist. Valid values are: %s." % (task_index, range(len(self.task_list))))
return
self.generate_toolpath(task["tool"], task["process"], task["bounds"])
......@@ -1030,7 +1036,7 @@ class ProjectGui:
controls = (("x <-> y", "x_swap_y"), ("x <-> z", "x_swap_z"), ("y <-> z", "y_swap_z"))
else:
# broken gui
print >> sys.stderr, "Unknown button action: %s" % str(widget.get_name())
log.warn("Unknown button action: %s" % str(widget.get_name()))
return
for obj, value in controls:
if self.gui.get_object(obj).get_active():
......@@ -1351,7 +1357,7 @@ class ProjectGui:
# report any ignored (obsolete) preference keys present in the file
for item, value in config.items("DEFAULT"):
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():
if not config.has_option("DEFAULT", item):
# a new preference setting is missing in the (old) file
......@@ -1372,7 +1378,8 @@ class ProjectGui:
config_filename = pycam.Gui.Settings.get_config_filename()
if config_filename is None:
# 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
config = ConfigParser.ConfigParser()
for item in PREFERENCES_DEFAULTS.keys():
......@@ -1382,7 +1389,7 @@ class ProjectGui:
config.write(config_file)
config_file.close()
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
def shift_model(self, widget, use_form_values=True):
......@@ -2029,7 +2036,7 @@ class ProjectGui:
toolpath = pycam.Toolpath.Generator.generate_toolpath_from_settings(
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):
# an error occoured - "toolpath" contains the error message
......@@ -2037,7 +2044,7 @@ class ProjectGui:
if not self.no_dialog:
show_error_dialog(self.window, message)
else:
print >>sys.stderr, message
log.warn("Toolpath generation failed: %s" % str(message))
# we were not successful (similar to a "cancel" request)
return False
else:
......@@ -2072,7 +2079,7 @@ class ProjectGui:
pass
else:
# 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)
......@@ -2251,8 +2258,7 @@ class ProjectGui:
max_skip_safety_distance=2*tool["tool_radius"],
comment=os.linesep.join(meta_data))
destination.close()
if self.no_dialog:
print "GCode file successfully written: %s" % str(filename)
log.info("GCode file successfully written: %s" % str(filename))
except IOError, err_msg:
if not no_dialog and not self.no_dialog:
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/>.
"""
import pycam.Cutters
import pycam.Utils.log
import ConfigParser
import StringIO
import sys
import os
CONFIG_DIR = "pycam"
log = pycam.Utils.log.get_logger()
def get_config_dirname():
try:
from win32com.shell import shellcon, shell
......@@ -282,7 +284,8 @@ process: 3
try:
self.config.read([filename])
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 True
......@@ -291,7 +294,8 @@ process: 3
try:
self.reset(input_text)
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 True
......@@ -302,7 +306,8 @@ process: 3
fi.write(text)
fi.close()
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 True
......@@ -402,7 +407,8 @@ process: 3
if values and (values.count(values[0]) == len(values)):
common_keys.append(key)
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)
for key in common_keys:
value = type_list[0][key]
......@@ -574,7 +580,8 @@ class ToolpathSettings:
try:
value = value_type(raw_value)
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
def get_string(self):
......
......@@ -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/>.
"""
import pycam.Utils.log
# Tkinter is used for "EmergencyDialog" below - but we will try to import it carefully
#import Tkinter
import sys
import os
log = pycam.Utils.log.get_logger()
DEPENDENCY_DESCRIPTION = {
"gtk": ("Python bindings for GTK+",
......@@ -142,14 +144,13 @@ class EmergencyDialog:
import Tkinter
except ImportError:
# tk is not installed
print >>sys.stderr, "Warning: %s" % str(title)
print >>sys.stderr, message
log.warn("Failed to show error dialog due to a missing Tkinter Python package.")
return
try:
root = Tkinter.Tk()
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)
print >>sys.stderr, "%s: %s" % (title, message)
log.info("Failed to create error dialog window (%s). " % str(err_msg) \
+ "Probably you are running PyCAM from a terminal.")
return
root.title(title)
root.bind("<Return>", self.finish)
......
......@@ -22,8 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Geometry import Point, Line
import pycam.Geometry.Model
import pycam.Utils.log
import sys
log = pycam.Utils.log.get_logger()
class DXFParser:
......@@ -116,8 +117,8 @@ class DXFParser:
try:
line1 = int(line1)
except ValueError:
print >>sys.stderr, "Invalid key in line " \
+ "%d (int expected): %s" % (self.line_number, line1)
log.warn("DXFImporter: Invalid key in line " \
+ "%d (int expected): %s" % (self.line_number, line1))
return None, None
if line1 in (self.KEYS["START_X"], self.KEYS["START_Y"],
self.KEYS["START_Z"], self.KEYS["END_X"], self.KEYS["END_Y"],
......@@ -125,16 +126,16 @@ class DXFParser:
try:
line2 = float(line2)
except ValueError:
print >>sys.stderr, "Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2)
log.warn("DXFImporter: Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2))
line1 = None
line2 = None
elif line1 in (self.KEYS["COLOR"],):
try:
line2 = int(line2)
except ValueError:
print >>sys.stderr, "Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2)
log.warn("DXFImporter: Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2))
line1 = None
line2 = None
else:
......@@ -154,8 +155,8 @@ class DXFParser:
self.parse_line()
else:
# not supported
print "Ignored unsupported element in line %d: %s" \
% (self.line_number, value)
log.warn("DXFImporter: Ignored unsupported element in " \
+ "line %d: %s" % (self.line_number, value))
key, value = self._read_key_value()
def parse_line(self):
......@@ -184,16 +185,17 @@ class DXFParser:
if not key is None:
self._push_on_stack(key, value)
if (None in p1) or (None in p2):
print >>sys.stderr, "Incomplete LINE definition between line " \
+ "%d and %d" % (start_line, end_line)
log.warn("DXFImporter: Incomplete LINE definition between line " \
+ "%d and %d" % (start_line, end_line))
else:
self.lines.append(Line(Point(p1[0], p1[1], p1[2]), Point(p2[0], p2[1], p2[2])))
def check_header(self):
# TODO: this function is not used?
# we expect "0" in the first line and "SECTION" in the second one
key, value = self._read_key_value()
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
......@@ -201,7 +203,7 @@ def import_model(filename):
try:
f = open(filename,"rb")
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
result = DXFParser(f)
......@@ -212,14 +214,9 @@ def import_model(filename):
model = pycam.Geometry.Model.ContourModel()
for l in lines:
model.append(l)
print "Imported DXF model: %d lines" % len(lines)
log.info("DXFImporter: Imported DXF model: %d lines" % len(lines))
return model
else:
print >>sys.stderr, "No supported elements found in DXF file!"
log.error("DXFImporter: No supported elements found in DXF file!")
return None
if __name__ == "__main__":
filename = sys.argv[1]
import_model(filename)
......@@ -25,11 +25,14 @@ from pycam.Geometry import Point, Line, Triangle
from pycam.Geometry.PointKdtree import PointKdtree
from pycam.Geometry.TriangleKdtree import TriangleKdtree
from pycam.Geometry.Model import Model
import pycam.Utils.log
from struct import unpack
import re
import os
import sys
log = pycam.Utils.log.get_logger()
vertices = 0
edges = 0
......@@ -79,7 +82,7 @@ def ImportModel(filename, use_kdtree=True):
try:
f = open(filename,"rb")
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
# read the first two lines of (potentially non-binary) input - they should contain "solid" and "facet"
header = f.readline(200)
......
......@@ -39,7 +39,8 @@ def parseToolpathSettings(filename):
try:
f = open(filename,"r")
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
for line in f.readlines():
match = re.match(REGEX_META_KEYWORDS, line)
......
......@@ -23,11 +23,14 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
__all__ = ["STLImporter", "DXFImporter", "TestModel"]
import pycam.Utils.log
import DXFImporter
import STLImporter
import os
import sys
log = pycam.Utils.log.get_logger()
def detect_file_type(filename):
failure = (None, None)
......@@ -41,7 +44,7 @@ def detect_file_type(filename):
elif filename.endswith(".dxf"):
return ("dxf", DXFImporter.import_model)
else:
print >>sys.stderr, "Failed to detect the model type of '%s'." \
% filename + " Is the file extension (.stl/.dxf) correct?"
failure
log.error("Importers: Failed to detect the model type of '%s'." \
% filename + " Is the file extension (.stl/.dxf) correct?")
return failure
......@@ -24,8 +24,10 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Geometry import Point
from pycam.Geometry.utils import INFINITE
from pycam.PathGenerators import get_max_height_triangles, get_max_height_ode, ProgressCounter
import pycam.Utils.log
import math
import sys
log = pycam.Utils.log.get_logger()
class Dimension:
......@@ -129,9 +131,9 @@ class DropCutter:
p = Point(x, y, self.safety_height)
self.pa.append(p)
if not self._boundary_warning_already_shown:
print >>sys.stderr, "WARNING: DropCutter exceed the height" \
+ " of the boundary box: using a safe height " \
+ "instead. This warning is reported only once."
log.warn("DropCutter: exceed the height " \
+ "of the boundary box: using a safe height " \
+ "instead. This warning is reported only once.")
self._boundary_warning_already_shown = True
self.cutter.moveto(p)
# "draw_callback" returns true, if the user requested quitting via the GUI
......
......@@ -25,8 +25,11 @@ import pycam.PathProcessors.PathAccumulator
from pycam.Geometry import Point
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
import pycam.Utils.log
import math
import sys
log = pycam.Utils.log.get_logger()
class EngraveCutter:
......@@ -175,9 +178,9 @@ class EngraveCutter:
p = Point(x, y, self.safety_height)
pa.append(p)
if not self._boundary_warning_already_shown:
print >>sys.stderr, "WARNING: DropCutter exceed the height" \
+ " of the boundary box: using a safe height " \
+ "instead. This warning is reported only once."
log.warn("EngraveCutter: exceed the height " \
+ "of the boundary box: using a safe height " \
+ "instead. This warning is reported only once.")
self._boundary_warning_already_shown = True
self.cutter.moveto(p)
# "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