mirror of
				https://github.com/Klipper3d/klipper.git
				synced 2025-11-04 04:15:56 +01:00 
			
		
		
		
	If a get_status() method returns a mutable object (such as a list or dict) then it would be possible for a gcode command template to incorrectly alter the program's internal state. Perform a deepcopy() operation on all get_status() return results to avoid that. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
		
			
				
	
	
		
			64 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Save arbitrary variables so that values can be kept across restarts.
 | 
						|
#
 | 
						|
# Copyright (C) 2020 Dushyant Ahuja <dusht.ahuja@gmail.com>
 | 
						|
# Copyright (C) 2016-2020  Kevin O'Connor <kevin@koconnor.net>
 | 
						|
#
 | 
						|
# This file may be distributed under the terms of the GNU GPLv3 license.
 | 
						|
import os, logging, ast, ConfigParser as configparser
 | 
						|
 | 
						|
class SaveVariables:
 | 
						|
    def __init__(self, config):
 | 
						|
        self.printer = config.get_printer()
 | 
						|
        self.filename = os.path.expanduser(config.get('filename'))
 | 
						|
        self.allVariables = {}
 | 
						|
        try:
 | 
						|
            self.loadVariables()
 | 
						|
        except self.printer.command_error as e:
 | 
						|
            raise config.error(str(e))
 | 
						|
        gcode = self.printer.lookup_object('gcode')
 | 
						|
        gcode.register_command('SAVE_VARIABLE', self.cmd_SAVE_VARIABLE,
 | 
						|
                               desc=self.cmd_SAVE_VARIABLE_help)
 | 
						|
    def loadVariables(self):
 | 
						|
        allvars = {}
 | 
						|
        varfile = configparser.ConfigParser()
 | 
						|
        try:
 | 
						|
            varfile.read(self.filename)
 | 
						|
            if varfile.has_section('Variables'):
 | 
						|
                for name, val in varfile.items('Variables'):
 | 
						|
                    allvars[name] = ast.literal_eval(val)
 | 
						|
        except:
 | 
						|
            msg = "Unable to parse existing variable file"
 | 
						|
            logging.exception(msg)
 | 
						|
            raise self.printer.command_error(msg)
 | 
						|
        self.allVariables = allvars
 | 
						|
    cmd_SAVE_VARIABLE_help = "Save arbitrary variables to disk"
 | 
						|
    def cmd_SAVE_VARIABLE(self, gcmd):
 | 
						|
        varname = gcmd.get('VARIABLE')
 | 
						|
        value = gcmd.get('VALUE')
 | 
						|
        try:
 | 
						|
            value = ast.literal_eval(value)
 | 
						|
        except ValueError as e:
 | 
						|
            raise gcmd.error("Unable to parse '%s' as a literal" % (value,))
 | 
						|
        newvars = dict(self.allVariables)
 | 
						|
        newvars[varname] = value
 | 
						|
        # Write file
 | 
						|
        varfile = configparser.ConfigParser()
 | 
						|
        varfile.add_section('Variables')
 | 
						|
        for name, val in sorted(newvars.items()):
 | 
						|
            varfile.set('Variables', name, repr(val))
 | 
						|
        try:
 | 
						|
            f = open(self.filename, "w")
 | 
						|
            varfile.write(f)
 | 
						|
            f.close()
 | 
						|
        except:
 | 
						|
            msg = "Unable to save variable"
 | 
						|
            logging.exception(msg)
 | 
						|
            raise gcmd.error(msg)
 | 
						|
        gcmd.respond_info("Variable Saved")
 | 
						|
        self.loadVariables()
 | 
						|
    def get_status(self, eventtime):
 | 
						|
        return {'variables': self.allVariables}
 | 
						|
 | 
						|
def load_config(config):
 | 
						|
    return SaveVariables(config)
 |