95 lines
2.6 KiB
Python
95 lines
2.6 KiB
Python
"""General utility functions."""
|
|
|
|
import contextlib
|
|
import os
|
|
import shutil
|
|
import time
|
|
|
|
from watchdog.events import FileSystemEvent, FileSystemEventHandler
|
|
from watchdog.observers import Observer
|
|
|
|
from pynecone.constants import APP_ASSETS_DIR, WEB_ASSETS_DIR
|
|
|
|
|
|
class AssetFolderWatch:
|
|
"""Asset folder watch class."""
|
|
|
|
def __init__(self, root):
|
|
"""Initialize the Watch Class.
|
|
|
|
Args:
|
|
root: root path of the public.
|
|
"""
|
|
self.path = str(root / APP_ASSETS_DIR)
|
|
self.event_handler = AssetFolderHandler(root)
|
|
|
|
def start(self):
|
|
"""Start watching asset folder."""
|
|
self.observer = Observer()
|
|
self.observer.schedule(self.event_handler, self.path, recursive=True)
|
|
self.observer.start()
|
|
|
|
|
|
class AssetFolderHandler(FileSystemEventHandler):
|
|
"""Asset folder event handler."""
|
|
|
|
def __init__(self, root):
|
|
"""Initialize the AssetFolderHandler Class.
|
|
|
|
Args:
|
|
root: root path of the public.
|
|
"""
|
|
super().__init__()
|
|
self.root = root
|
|
|
|
def on_modified(self, event: FileSystemEvent):
|
|
"""Event handler when a file or folder was modified.
|
|
|
|
This is called every time after a file is created, modified and deleted.
|
|
|
|
Args:
|
|
event: Event information.
|
|
"""
|
|
dest_path = self.get_dest_path(event.src_path)
|
|
|
|
# wait 1 sec for fully saved
|
|
time.sleep(1)
|
|
|
|
if os.path.isfile(event.src_path):
|
|
with contextlib.suppress(PermissionError):
|
|
shutil.copyfile(event.src_path, dest_path)
|
|
if os.path.isdir(event.src_path):
|
|
if os.path.exists(dest_path):
|
|
shutil.rmtree(dest_path)
|
|
with contextlib.suppress(PermissionError):
|
|
shutil.copytree(event.src_path, dest_path)
|
|
|
|
def on_deleted(self, event: FileSystemEvent):
|
|
"""Event hander when a file or folder was deleted.
|
|
|
|
Args:
|
|
event: Event infomation.
|
|
"""
|
|
dest_path = self.get_dest_path(event.src_path)
|
|
|
|
if os.path.isfile(dest_path):
|
|
# when event is about a file, pass
|
|
# this will be deleted at on_modified function
|
|
return
|
|
|
|
if os.path.exists(dest_path):
|
|
shutil.rmtree(dest_path)
|
|
|
|
def get_dest_path(self, src_path: str) -> str:
|
|
"""Get public file path.
|
|
|
|
Args:
|
|
src_path: The asset file path.
|
|
|
|
Returns:
|
|
The public file path.
|
|
"""
|
|
return src_path.replace(
|
|
str(self.root / APP_ASSETS_DIR), str(self.root / WEB_ASSETS_DIR)
|
|
)
|