#!/usr/bin/env python3 from collections import namedtuple import uuid import os import toml from PIL import Image mydir = os.path.dirname(os.path.abspath(__file__)) # Classes # class Manager(): """ Manager class to manage a notiframe session. """ def __init__(self): self.manager_id = gen_id() self.devices = [] #widget class register list - updated with available widget classes def add_device(self, name, resolution): """ Adds a new device to the manager's device list """ self.devices.append(Device(name, resolution)) def remove_device(self, dev_id): """ Removes a device from the manager's device list """ for dev in self.devices: if dev.device_id == dev_id: self.devices.remove(dev) break def import_config_file(self, path): """ Loads a config from file into the manager, reconstructs manager state from config """ # get toml config file, convert to named tuple # return named tuple containing all layouts config = toml.load(path) #config = convert(uni_config) self.devices = [Device.load(device_data) for device_data in config['devices']] def export_config_file(self, path): """ Save the current manager state to file """ # take tuple containing all layouts and dump as toml preserved_data = [device.save() for device in self.devices] with open(path, "w+") as config_file: config_file.write(toml.dumps({'devices': preserved_data})) def render(self): """ Render a canvas image from the present data """ pass def pull_latest(self): """ Pull the latest network data requested by each widget """ pass class Device(): """ Device class to contain a device's properties, layout and widgets """ @staticmethod def load(saved_state): """ Loads a device from saved state dict of the device """ new_device = Device( name=saved_state['name'], resolution=saved_state['resolution'], device_id=saved_state['device_id']) for widget_state in saved_state['widgets']: new_device.add_widget(Widget.load(widget_state)) return new_device def save(self): """ Returns a dict with saved state of the device """ return_state = {} return_state['name'] = self.name return_state['resolution'] = self.resolution return_state['device_id'] = self.device_id return_state['widgets'] = [widget.save() for widget in self.widgets] return return_state def __init__(self, name, resolution, device_id=None): # attributes self.name = name self.resolution = resolution if(device_id is None): self.device_id = gen_id() else: self.device_id = device_id # widgets container self.widgets = [] # generated self.device_image = None def add_widget(self, widget): """ Adds a new widget to the device's widget list """ self.widgets.append(widget) def remove_widget(self, widget_id): """ Removes a widget from the device's widget list """ for widg in self.widgets: if widg.widget_id == widget_id: self.widgets.remove(widg) break class Widget(): """ Widget class to hold properties common to all widgets. """ @staticmethod def load(saved_state): """ Loads a widget from saved state dict of the widget """ widget_classes = {'Widget': Widget, 'BasicTextWidget': BasicTextWidget} # this list maintained in the module or manager... new_widget_class = widget_classes[saved_state['w_type']] new_widget = new_widget_class( position=saved_state['position'], dimensions=saved_state['dimensions'], widget_id=saved_state['widget_id']) return new_widget def save(self): """ Returns a dict with saved state of the widget """ return_state = {} return_state['w_type'] = 'Widget' return_state['position'] = self.position return_state['dimensions'] = self.dimensions return_state['widget_id'] = self.widget_id return return_state def render(self): """ Returns image of widget """ pass def __init__(self, position, dimensions, widget_id=None): if(widget_id is None): self.widget_id = gen_id() else: self.widget_id = widget_id self.position = position # xy grid space location to draw the top left corner in self.dimensions = dimensions # xy in terms of grid spaces class BasicTextWidget(Widget): """ A widget that displays a simple string of text """ @staticmethod def load(saved_state): """ Loads a widget from dict saved state of the widget """ new_widget = BasicTextWidget( position=saved_state['position'], dimensions=saved_state['dimensions'], widget_id=saved_state['widget_id'], text=saved_state['text']) return new_widget def save(self): """ Returns a dict with saved state of the widget """ return_state = super().save() return_state['text'] = self.text return_state['w_type'] = 'BasicTextWidget' return return_state def __init__(self, position, dimensions, widget_id, text, font_size, font): super().__init__(position, dimensions, widget_id) self.text = text self.font_size = font_size self.font = None def get_image(self): """ Returns a widget image via the cache or render method. For now just returns example black image """ img = Image.new('1', (self.dimensions[0], self.dimensions[1]), 0) #255 black return img def render(self): """ Render an image of the widget from the present data """ pass # Global Functions # def gen_id(): """ Generates a uuid (v4) string """ return str(uuid.uuid4())