From 58cbad18289349e93a56c2697158911271a3dfb7 Mon Sep 17 00:00:00 2001 From: Ross Hendrickson Date: Thu, 15 Aug 2013 22:48:26 -0500 Subject: [PATCH] Start config parser work --- octoprint/cura/__init__.py | 5 ++ octoprint/cura/parser.py | 91 +++++++++++++++++++++++++++++ octoprint/cura/tests/test_parser.py | 66 +++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 octoprint/cura/parser.py create mode 100644 octoprint/cura/tests/test_parser.py diff --git a/octoprint/cura/__init__.py b/octoprint/cura/__init__.py index 54c7685d..82c43758 100644 --- a/octoprint/cura/__init__.py +++ b/octoprint/cura/__init__.py @@ -9,6 +9,10 @@ class CuraFactory(object): @staticmethod def create_slicer(path=None): + """Utilizes the factory pattern to setup a CuraEngine object + + :param path: :class: `str` + """ if path: return CuraEngine(path) current_settings = settings(init=True) @@ -33,6 +37,7 @@ class CuraEngine(object): self, config, gcode, file_path, call_back=None, call_back_args=None): """Wraps around the main.cpp processFile method. + :param config: :class: `string` :path to a cura config file: :param gcode: :class: `string :path to write out the gcode generated: :param file_path: :class: `string :path to the STL to be sliced: diff --git a/octoprint/cura/parser.py b/octoprint/cura/parser.py new file mode 100644 index 00000000..42d557a5 --- /dev/null +++ b/octoprint/cura/parser.py @@ -0,0 +1,91 @@ +import logging + + +def process_profile_ini(filename): + """Builds the array that needs to be sent to the subprocess call. + + :param filename: :class: `str` + + :note: The filename should be the full path to the profile.ini + """ + + + profile = open(filename, 'r') + data = {} + + for line in profile: + + if _is_multi_start(line): + + multi_line = line + + while(not _is_multi_end(line)): + line = profile.readline() + multi_line += next_line + + data = process_multi_setting_line(data, multi_line) + + if _is_single(line): + data = process_setting_line(data, setting_line) + + profile.close() + + return format_data_for_command(data) + + +def _is_multi_start(line): + pass + + +def _is_multi_end(line): + pass + + +def _is_single(line): + pass + + +def process_setting_line(data, setting_line): + """Adds to the data dictionary a converted to camel case version of the + variable name as the key and the value as the parameter's value. + + :param data: :class: `dict` + :param setting_line: :class: `str` + """ + + if not data: + data = {} + + if not setting_line: + return data + + # TODO: Make this more fault tolerant + + split = setting_line.split("=") + variable_parts = split[0].split("_") + end_variable_parts = ''.join(word.title() for word in variable_parts[1:]) + + new_name = str(variable_parts[0]) + end_variable_parts + + data[new_name] = split[1].strip() + + return data + + +def format_data_for_command(data): + """Takes the data parsed from the file and formats it for the command line + + :param data: :class: `dict` + + :returns: :class: `list` of :class: `str` + """ + + if not data: + raise ValueError("Data not found") + + result = [] + + for key, value in data.iteritems(): + result.extend(['-s', '%s=%s' % (key, str(value))]) + + return result diff --git a/octoprint/cura/tests/test_parser.py b/octoprint/cura/tests/test_parser.py new file mode 100644 index 00000000..659de572 --- /dev/null +++ b/octoprint/cura/tests/test_parser.py @@ -0,0 +1,66 @@ +import logging +import unittest + + +class ParserTestCase(unittest.TestCase): + + def setUp(self): + + self.setting_string = """ +[profile] +layer_height = 0.1 +retraction_enable = False +solid_layer_thickness = 0.6 +nozzle_size = 0.5 +print_speed = 50 +print_temperature = 220 +print_temperature2 = 0 +start2.gcode = ;Sliced at: {day} {date} {time} + ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density} + ;Print time: {print_time} + ;Filament used: {filament_amount}m {filament_weight}g + ;Filament cost: {filament_cost} + G21 ;metric values + G90 ;absolute positioning + M107 ;start with the fan off + G28 X0 Y0 ;move X/Y to min endstops + M117 Printing... +end2.gcode = ;End GCode + M104 T0 S0 ;extruder heater off + M104 T1 S0 ;extruder heater off + M140 S0 ;heated bed heater off (if you have it) + G91 ;relative positioning + G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure + G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more + G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way + M84 ;steppers off + G90 ;absolute positioning +""" + + def test_process_setting_line(self): + + from octoprint.cura.parser import process_setting_line + + setting_line = "print_speed_size2 = 3.22" + + data = {} + + data = process_setting_line(data, setting_line) + + logging.info(data) + self.assertEqual(len(data.values()), 1) + + def test_format_command(self): + + from octoprint.cura.parser import format_data_for_command + + data = {'layerHeight': '0.1', + 'printTemperature': '220'} + + result = [] + + result = format_data_for_command(data) + + self.assertIsNotNone(result) + self.assertEqual(len(result), len(data.values()) * 2) +