diff --git a/multi_user/bl_types/__init__.py b/multi_user/bl_types/__init__.py index ad35fe8..add7058 100644 --- a/multi_user/bl_types/__init__.py +++ b/multi_user/bl_types/__init__.py @@ -36,7 +36,8 @@ __all__ = [ 'bl_lightprobe', 'bl_speaker', 'bl_font', - 'bl_sound' + 'bl_sound', + 'bl_file' ] # Order here defines execution order from . import * diff --git a/multi_user/bl_types/bl_file.py b/multi_user/bl_types/bl_file.py new file mode 100644 index 0000000..36c2348 --- /dev/null +++ b/multi_user/bl_types/bl_file.py @@ -0,0 +1,122 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ##### END GPL LICENSE BLOCK ##### + + +import logging +import os +import sys +from pathlib import Path + +import bpy +import mathutils +from replication.constants import DIFF_BINARY, UP +from replication.data import ReplicatedDatablock + +from .. import utils +from .dump_anything import Dumper, Loader + + +def get_filepath(filename): + """ + Construct the local filepath + """ + return os.path.join( + utils.get_preferences().cache_directory, + filename + ) + + +class BlFile(ReplicatedDatablock): + bl_id = 'file' + bl_name = "file" + bl_class = Path + bl_delay_refresh = 1 + bl_delay_apply = 1 + bl_automatic_push = True + bl_check_common = False + bl_icon = 'FILE' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.instance = kwargs.get('instance', None) + # TODO: handle packed_file + # TODO: ensure absolute path + # TODO: ensure file exist + logging.info(self.instance) + + self.preferences = utils.get_preferences() + self.diff_method = DIFF_BINARY + + def resolve(self): + # TODO: generic check + # Ensure local cache directory + os.makedirs(self.preferences.cache_directory, exist_ok=True) + + if self.data: + self.instance = Path(get_filepath(self.data['name'])) + + def _dump(self, instance=None): + """ + Read the file and return a dict as: + { + name : filename + extension : + file: file content + } + """ + logging.info(f"Extracting file metadata") + + data = { + 'name': self.instance.name, + } + + logging.info( + f"Reading {self.instance.name} content: {self.instance.stat().st_size} bytes") + + try: + file = open(self.instance, "rb") + data['file'] = file.read() + + file.close() + except IOError: + logging.warning(f"{self.instance} doesn't exist, skipping") + else: + file.close() + + return data + + def _load(self, data, target): + """ + Writing the file + """ + logging.info(f"Writing {data['name']} to {target}") + + # TODO: check fiile already exist + # TODO: check for empty data + if target.exists() and (sys.getsizeof(data['file']) == self.instance.stat().st_size): + logging.info("File already loaded, skipping.") + return + try: + file = open(target, "wb") + file.write(data['file']) + except IOError: + logging.warning(f"{target} doesn't exist, skipping") + else: + file.close() + + def diff(self): + return False diff --git a/multi_user/bl_types/bl_font.py b/multi_user/bl_types/bl_font.py index 599f3ad..3e45d92 100644 --- a/multi_user/bl_types/bl_font.py +++ b/multi_user/bl_types/bl_font.py @@ -16,14 +16,18 @@ # ##### END GPL LICENSE BLOCK ##### +import logging +import os +from pathlib import Path + import bpy import mathutils -import os -import logging -import pathlib + from .. import utils -from .dump_anything import Loader, Dumper from .bl_datablock import BlDatablock +from .bl_file import get_filepath +from .dump_anything import Dumper, Loader + class BlFont(BlDatablock): bl_id = "fonts" @@ -37,33 +41,28 @@ class BlFont(BlDatablock): def _construct(self, data): if data['filepath'] == '': return bpy.data.fonts.load(data['filepath']) - elif 'font_file' in data.keys(): - prefs = utils.get_preferences() - ext = pathlib.Path(data['filepath']).suffix - font_name = f"{self.uuid}{ext}" - font_path = os.path.join(prefs.cache_directory, font_name) - - os.makedirs(prefs.cache_directory, exist_ok=True) - file = open(font_path, 'wb') - file.write(data["font_file"]) - file.close() + else: + filename = Path(data['filepath']).name - logging.info(f'loading {font_path}') - return bpy.data.fonts.load(font_path) + logging.info(f'loading {filename}') + + return bpy.data.fonts.load(get_filepath(filename)) def _load(self, data, target): pass def _dump(self, instance=None): - data = { - 'filepath':instance.filepath, - 'name':instance.name + return { + 'filepath': instance.filepath, + 'name': instance.name } - if instance.filepath != '' and not instance.is_embedded_data: - file = open(instance.filepath, "rb") - data['font_file'] = file.read() - file.close() - return data def diff(self): return False + + def _resolve_deps_implementation(self): + deps = [] + if self.instance.filepath and self.instance.filepath != '': + deps.append(Path(self.instance.filepath)) + + return deps