feat: cache managenent utility
This commit is contained in:
parent
f992d06b03
commit
6c47e095be
@ -63,16 +63,10 @@ class BlFile(ReplicatedDatablock):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.instance = kwargs.get('instance', None)
|
||||
# TODO: ensure absolute path
|
||||
# TODO: ensure file exist
|
||||
|
||||
self.preferences = utils.get_preferences()
|
||||
self.diff_method = DIFF_BINARY
|
||||
|
||||
def resolve(self):
|
||||
# TODO: generic check
|
||||
os.makedirs(self.preferences.cache_directory, exist_ok=True)
|
||||
|
||||
if self.data:
|
||||
self.instance = Path(get_filepath(self.data['name']))
|
||||
|
||||
|
@ -27,6 +27,8 @@ from operator import itemgetter
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, Popen, TimeoutExpired
|
||||
import zmq
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
@ -608,6 +610,34 @@ class ApplyArmatureOperator(bpy.types.Operator):
|
||||
stop_modal_executor = False
|
||||
|
||||
|
||||
class ClearCache(bpy.types.Operator):
|
||||
"Clear local session cache"
|
||||
bl_idname = "session.clear_cache"
|
||||
bl_label = "Modal Executor Operator"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
cache_dir = utils.get_preferences().cache_directory
|
||||
try:
|
||||
for root, dirs, files in os.walk(cache_dir):
|
||||
for name in files:
|
||||
Path(root, name).unlink()
|
||||
|
||||
except Exception as e:
|
||||
self.report({'ERROR'}, repr(e))
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
row = self.layout
|
||||
row.label(text=f" Do you really want to remove local cache ? ")
|
||||
|
||||
classes = (
|
||||
SessionStartOperator,
|
||||
SessionStopOperator,
|
||||
@ -620,7 +650,7 @@ classes = (
|
||||
ApplyArmatureOperator,
|
||||
SessionKickOperator,
|
||||
SessionInitOperator,
|
||||
|
||||
ClearCache,
|
||||
)
|
||||
|
||||
|
||||
|
@ -20,6 +20,9 @@ import logging
|
||||
import bpy
|
||||
import string
|
||||
import re
|
||||
import os
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from . import bl_types, environment, addon_updater_ops, presence, ui
|
||||
from .utils import get_preferences, get_expanded_icon
|
||||
@ -68,6 +71,16 @@ def update_port(self, context):
|
||||
self['ipc_port'] = random.randrange(self.port+4, 10000)
|
||||
|
||||
|
||||
def update_directory(self, context):
|
||||
new_dir = Path(self.cache_directory)
|
||||
if new_dir.exists() and any(Path(self.cache_directory).iterdir()):
|
||||
logging.error("The folder is not empty, choose another one.")
|
||||
self['cache_directory'] = environment.DEFAULT_CACHE_DIR
|
||||
elif not new_dir.exists():
|
||||
logging.info("Target cache folder doesn't exist, creating it.")
|
||||
os.makedirs(self.cache_directory, exist_ok=True)
|
||||
|
||||
|
||||
def set_log_level(self, value):
|
||||
logging.getLogger().setLevel(value)
|
||||
|
||||
@ -136,7 +149,8 @@ class SessionPrefs(bpy.types.AddonPreferences):
|
||||
cache_directory: bpy.props.StringProperty(
|
||||
name="cache directory",
|
||||
subtype="DIR_PATH",
|
||||
default=environment.DEFAULT_CACHE_DIR)
|
||||
default=environment.DEFAULT_CACHE_DIR,
|
||||
update=update_directory)
|
||||
connection_timeout: bpy.props.IntProperty(
|
||||
name='connection timeout',
|
||||
description='connection timeout before disconnection',
|
||||
|
@ -19,7 +19,7 @@
|
||||
import bpy
|
||||
|
||||
from . import operators
|
||||
from .utils import get_preferences, get_expanded_icon
|
||||
from .utils import get_preferences, get_expanded_icon, get_folder_size
|
||||
from replication.constants import (ADDED, ERROR, FETCHED,
|
||||
MODIFIED, RP_COMMON, UP,
|
||||
STATE_ACTIVE, STATE_AUTH,
|
||||
@ -371,7 +371,8 @@ class SESSION_PT_advanced_settings(bpy.types.Panel):
|
||||
cache_section_row = cache_section.row()
|
||||
cache_section_row.label(text="Clear memory filecache:")
|
||||
cache_section_row.prop(settings, "clear_memory_filecache", text="")
|
||||
|
||||
cache_section_row = cache_section.row()
|
||||
cache_section_row.operator('session.clear_cache', text=f"Clear cache ({get_folder_size(settings.cache_directory)})")
|
||||
log_section = layout.row().box()
|
||||
log_section.prop(
|
||||
settings,
|
||||
|
@ -21,8 +21,10 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from uuid import uuid4
|
||||
from collections.abc import Iterable
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
import math
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
@ -78,6 +80,7 @@ def resolve_from_id(id, optionnal_type=None):
|
||||
return root[id]
|
||||
return None
|
||||
|
||||
|
||||
def get_datablock_from_uuid(uuid, default, ignore=[]):
|
||||
if not uuid:
|
||||
return default
|
||||
@ -87,9 +90,10 @@ def get_datablock_from_uuid(uuid, default, ignore=[]):
|
||||
if isinstance(root, Iterable) and category not in ignore:
|
||||
for item in root:
|
||||
if getattr(item, 'uuid', None) == uuid:
|
||||
return item
|
||||
return item
|
||||
return default
|
||||
|
||||
|
||||
def get_preferences():
|
||||
return bpy.context.preferences.addons[__package__].preferences
|
||||
|
||||
@ -103,3 +107,61 @@ def get_expanded_icon(prop: bpy.types.BoolProperty) -> str:
|
||||
return 'DISCLOSURE_TRI_DOWN'
|
||||
else:
|
||||
return 'DISCLOSURE_TRI_RIGHT'
|
||||
|
||||
|
||||
# Taken from here: https://stackoverflow.com/a/55659577
|
||||
def get_folder_size(folder):
|
||||
return ByteSize(sum(file.stat().st_size for file in Path(folder).rglob('*')))
|
||||
|
||||
|
||||
class ByteSize(int):
|
||||
|
||||
_kB = 1024
|
||||
_suffixes = 'B', 'kB', 'MB', 'GB', 'PB'
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
return super().__new__(cls, *args, **kwargs)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.bytes = self.B = int(self)
|
||||
self.kilobytes = self.kB = self / self._kB**1
|
||||
self.megabytes = self.MB = self / self._kB**2
|
||||
self.gigabytes = self.GB = self / self._kB**3
|
||||
self.petabytes = self.PB = self / self._kB**4
|
||||
*suffixes, last = self._suffixes
|
||||
suffix = next((
|
||||
suffix
|
||||
for suffix in suffixes
|
||||
if 1 < getattr(self, suffix) < self._kB
|
||||
), last)
|
||||
self.readable = suffix, getattr(self, suffix)
|
||||
|
||||
super().__init__()
|
||||
|
||||
def __str__(self):
|
||||
return self.__format__('.2f')
|
||||
|
||||
def __repr__(self):
|
||||
return '{}({})'.format(self.__class__.__name__, super().__repr__())
|
||||
|
||||
def __format__(self, format_spec):
|
||||
suffix, val = self.readable
|
||||
return '{val:{fmt}} {suf}'.format(val=math.ceil(val), fmt=format_spec, suf=suffix)
|
||||
|
||||
def __sub__(self, other):
|
||||
return self.__class__(super().__sub__(other))
|
||||
|
||||
def __add__(self, other):
|
||||
return self.__class__(super().__add__(other))
|
||||
|
||||
def __mul__(self, other):
|
||||
return self.__class__(super().__mul__(other))
|
||||
|
||||
def __rsub__(self, other):
|
||||
return self.__class__(super().__sub__(other))
|
||||
|
||||
def __radd__(self, other):
|
||||
return self.__class__(super().__add__(other))
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__class__(super().__rmul__(other))
|
||||
|
Loading…
Reference in New Issue
Block a user