Autosave пишется в отдельный файл

This commit is contained in:
Nikolay Kopitonenko 2024-03-18 16:58:17 +03:00
parent 3c9b56f020
commit cf3327ad33
3 changed files with 53 additions and 48 deletions

View File

@ -4,6 +4,7 @@
# #
# This file may be distributed under the terms of the GNU GPLv3 license. # This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, glob, re, time, logging, configparser, io import sys, os, glob, re, time, logging, configparser, io
from sharedlib import *
error = configparser.Error error = configparser.Error
@ -281,10 +282,9 @@ class PrinterConfig:
filename = self.printer.get_start_args()['config_file'] filename = self.printer.get_start_args()['config_file']
data = self._read_config_file(filename) data = self._read_config_file(filename)
regular_data, autosave_data = self._find_autosave_data(data) regular_data, autosave_data = self._find_autosave_data(data)
regular_config = self._build_config_wrapper(regular_data, filename) autosave_data = Klippy_Autosave_Read()
autosave_data = self._strip_duplicates(autosave_data, regular_config)
self.autosave = self._build_config_wrapper(autosave_data, filename) self.autosave = self._build_config_wrapper(autosave_data, filename)
cfg = self._build_config_wrapper(regular_data + autosave_data, filename) cfg = self._build_config_wrapper(regular_data + "\n" + autosave_data, filename)
return cfg return cfg
def check_unused_options(self, config): def check_unused_options(self, config):
fileconfig = config.fileconfig fileconfig = config.fileconfig
@ -369,14 +369,6 @@ class PrinterConfig:
del pending[section] del pending[section]
self.status_save_pending = pending self.status_save_pending = pending
self.save_config_pending = True self.save_config_pending = True
def _disallow_include_conflicts(self, regular_data, cfgname, gcode):
config = self._build_config_wrapper(regular_data, cfgname)
for section in self.autosave.fileconfig.sections():
for option in self.autosave.fileconfig.options(section):
if config.fileconfig.has_option(section, option):
msg = ("SAVE_CONFIG section '%s' option '%s' conflicts "
"with included value" % (section, option))
raise gcode.error(msg)
cmd_SAVE_CONFIG_help = "Overwrite config file and restart" cmd_SAVE_CONFIG_help = "Overwrite config file and restart"
def cmd_SAVE_CONFIG(self, gcmd): def cmd_SAVE_CONFIG(self, gcmd):
if not self.autosave.fileconfig.sections(): if not self.autosave.fileconfig.sections():
@ -384,45 +376,15 @@ class PrinterConfig:
gcode = self.printer.lookup_object('gcode') gcode = self.printer.lookup_object('gcode')
# Create string containing autosave data # Create string containing autosave data
autosave_data = self._build_config_string(self.autosave) autosave_data = self._build_config_string(self.autosave)
lines = [('#*# ' + l).strip()
for l in autosave_data.split('\n')] logging.info("SAVE_CONFIG to '%s' (backup: +'.backup_' +time)",
lines.insert(0, "\n" + AUTOSAVE_HEADER.rstrip()) Klippy_Get_Autosave_Filename())
lines.append("") ok = Klippy_Autosave_Write(autosave_data)
autosave_data = '\n'.join(lines) if not ok:
# Read in and validate current config file msg = "Unable to write config file during SAVE_CONFIG (check logs)"
cfgname = self.printer.get_start_args()['config_file']
try:
data = self._read_config_file(cfgname)
regular_data, old_autosave_data = self._find_autosave_data(data)
config = self._build_config_wrapper(regular_data, cfgname)
except error as e:
msg = "Unable to parse existing config on SAVE_CONFIG"
logging.exception(msg)
raise gcode.error(msg)
regular_data = self._strip_duplicates(regular_data, self.autosave)
self._disallow_include_conflicts(regular_data, cfgname, gcode)
data = regular_data.rstrip() + autosave_data
# Determine filenames
datestr = time.strftime("-%Y%m%d_%H%M%S")
backup_name = cfgname + datestr
temp_name = cfgname + "_autosave"
if cfgname.endswith(".cfg"):
backup_name = cfgname[:-4] + datestr + ".cfg"
temp_name = cfgname[:-4] + "_autosave.cfg"
# Create new config file with temporary name and swap with main config
logging.info("SAVE_CONFIG to '%s' (backup in '%s')",
cfgname, backup_name)
try:
f = open(temp_name, 'w')
f.write(data)
f.close()
if gcmd.get_int('BACKUP', 1):
os.rename(cfgname, backup_name)
os.rename(temp_name, cfgname)
except:
msg = "Unable to write config file during SAVE_CONFIG"
logging.exception(msg) logging.exception(msg)
raise gcode.error(msg) raise gcode.error(msg)
# Request a restart # Request a restart
if gcmd.get_int('RESTART', 1): if gcmd.get_int('RESTART', 1):
gcode.request_restart('restart') gcode.request_restart('restart')

View File

@ -8,6 +8,9 @@ import sys, os, gc, optparse, logging, time, collections, importlib
import util, reactor, queuelogger, msgproto import util, reactor, queuelogger, msgproto
import gcode, configfile, pins, mcu, toolhead, webhooks, tcp_server import gcode, configfile, pins, mcu, toolhead, webhooks, tcp_server
import sharedlib
sharedlib.load()
message_ready = "Printer is ready" message_ready = "Printer is ready"
message_startup = """ message_startup = """

40
klippy/sharedlib.py Normal file
View File

@ -0,0 +1,40 @@
import sys, os, gc, optparse, logging, time
from cffi import FFI
import datetime
SCREEN_PATH="/home/pi/3dscreen"
ffi = FFI()
lib = None
def load():
global lib
ffi.cdef("""
char* Klippy_Get_Autosave_Filename();
char* Klippy_Autosave_Read();
bool Klippy_Autosave_Write(char*);
void free(void*);
""")
try:
lib = ffi.dlopen(SCREEN_PATH+"/lib/lib3dscreen.so")
except:
lib = ffi.dlopen("/lib/lib3dscreen-host.so")
def Klippy_Get_Autosave_Filename():
res = lib.Klippy_Get_Autosave_Filename()
s = ffi.string(res).decode("utf-8")
lib.free(res)
return s
def Klippy_Autosave_Read():
res = lib.Klippy_Autosave_Read()
s = ffi.string(res).decode("utf-8")
lib.free(res)
return s
def Klippy_Autosave_Write(data):
b = data.encode('utf-8')
res = lib.Klippy_Autosave_Write(b)
return res