138 lines
5.3 KiB
Python

import logging
import os
import gi
gi.require_version("Gtk", "3.0")
class KlippyFiles:
def __init__(self, screen):
self._screen = screen
self.callbacks = []
self.files = {}
self.directories = []
self.gcodes_path = None
def set_gcodes_path(self):
virtual_sdcard = self._screen.printer.get_config_section("virtual_sdcard")
if virtual_sdcard and "path" in virtual_sdcard:
self.gcodes_path = os.path.expanduser(virtual_sdcard['path'])
logging.info(f"Gcodes path: {self.gcodes_path}")
def _callback(self, result, method, params):
if "error" in result:
logging.debug(result["error"])
return
if method == "server.files.list":
for item in result["result"]:
self.files[item["path"]] = item
self.request_metadata(item["path"])
elif method == "server.files.metadata":
for x in result['result']:
if params['filename'] not in self.files:
self.files[params['filename']] = {}
self.files[params['filename']][x] = result['result'][x]
if 'path' not in self.files[params['filename']]:
self.files[params['filename']]['path'] = params['filename']
if "thumbnails" in self.files[params['filename']]:
self.files[params['filename']]['thumbnails'].sort(key=lambda y: y['size'], reverse=True)
for thumbnail in self.files[params['filename']]['thumbnails']:
thumbnail['local'] = False
if self.gcodes_path is not None:
path = os.path.join(
os.path.dirname(os.path.join(self.gcodes_path, params['filename'])),
thumbnail['relative_path']
)
if os.access(path, os.R_OK):
thumbnail['local'] = True
thumbnail['path'] = path
if thumbnail['local'] is False:
thumbnail['path'] = os.path.join(
os.path.dirname(params['filename']),
thumbnail['relative_path']
)
self._screen.process_update("notify_metadata_update", params)
self.run_callbacks(
"modify_file", {'action': "modify_file", 'item': self.files[params['filename']]}
)
def add_file(self, item):
if 'path' not in item:
logging.info(f"Error adding item, unknown path: {item}")
return
self.files[item['path']] = item
self.request_metadata(item['path'])
def remove_file(self, filename):
if filename in self.files:
self.files.pop(filename)
def add_callback(self, callback):
self.callbacks.append(callback)
def remove_callback(self, callback):
if callback in self.callbacks:
self.callbacks.remove(callback)
return
logging.info(f"callback not found {callback}")
def process_update(self, data):
if (
'item' in data and data['item']['root'] != 'gcodes'
or data['action'].endswith("file") and not self.is_gcode(data['item']['path'])
):
return
if data['action'] == "create_file":
self.add_file(data['item'])
elif data['action'] == "delete_file":
self.remove_file(data['item']['path'])
elif data['action'] == "modify_file":
self.request_metadata(data['item']['path'])
elif data['action'] == "move_file":
self.files[data['item']['path']] = self.files.pop(data['source_item']['path'])
self.files[data['item']['path']].update(data['item'])
self.run_callbacks(data['action'], data)
@staticmethod
def is_gcode(path):
return os.path.splitext(path)[1] in {'.gcode', '.gco', '.g'}
def file_metadata_exists(self, filename):
return filename in self.files and "slicer" in self.files[filename]
def get_thumbnail_location(self, filename, small=False):
if all((
small,
len(self.files[filename]['thumbnails']) > 1
)):
thumb = self.files[filename]['thumbnails'][1]
else:
thumb = self.files[filename]['thumbnails'][0]
return ['file', thumb['path']] if thumb['local'] else ['http', thumb['path']]
def has_thumbnail(self, filename):
return filename in self.files and "thumbnails" in self.files[filename]
def request_metadata(self, filename):
if self.is_gcode(filename):
self._screen._ws.klippy.get_file_metadata(filename, self._callback)
else:
logging.info("Not a gcode")
def refresh_files(self):
self._screen._ws.klippy.get_file_list(self._callback)
def run_callbacks(self, action, item):
for cb in self.callbacks:
cb(action, item)
def get_file_info(self, path):
if path not in self.files:
logging.info(f"Metadata not found {path}")
self.request_metadata(path)
return {}
return self.files[path]
def get_dir_info(self, directory):
self._screen._ws.klippy.get_dir_info(self._callback, directory=directory)