watch.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. """General utility functions."""
  2. import contextlib
  3. import os
  4. import shutil
  5. import time
  6. from watchdog.events import FileSystemEvent, FileSystemEventHandler
  7. from watchdog.observers import Observer
  8. from reflex.constants import Dirs
  9. class AssetFolderWatch:
  10. """Asset folder watch class."""
  11. def __init__(self, root):
  12. """Initialize the Watch Class.
  13. Args:
  14. root: root path of the public.
  15. """
  16. self.path = str(root / Dirs.APP_ASSETS)
  17. self.event_handler = AssetFolderHandler(root)
  18. def start(self):
  19. """Start watching asset folder."""
  20. self.observer = Observer()
  21. self.observer.schedule(self.event_handler, self.path, recursive=True)
  22. self.observer.start()
  23. class AssetFolderHandler(FileSystemEventHandler):
  24. """Asset folder event handler."""
  25. def __init__(self, root):
  26. """Initialize the AssetFolderHandler Class.
  27. Args:
  28. root: root path of the public.
  29. """
  30. super().__init__()
  31. self.root = root
  32. def on_modified(self, event: FileSystemEvent):
  33. """Event handler when a file or folder was modified.
  34. This is called every time after a file is created, modified and deleted.
  35. Args:
  36. event: Event information.
  37. """
  38. dest_path = self.get_dest_path(event.src_path)
  39. # wait 1 sec for fully saved
  40. time.sleep(1)
  41. if os.path.isfile(event.src_path):
  42. with contextlib.suppress(PermissionError):
  43. shutil.copyfile(event.src_path, dest_path)
  44. if os.path.isdir(event.src_path):
  45. if os.path.exists(dest_path):
  46. shutil.rmtree(dest_path)
  47. with contextlib.suppress(PermissionError):
  48. shutil.copytree(event.src_path, dest_path)
  49. def on_deleted(self, event: FileSystemEvent):
  50. """Event hander when a file or folder was deleted.
  51. Args:
  52. event: Event infomation.
  53. """
  54. dest_path = self.get_dest_path(event.src_path)
  55. if os.path.isfile(dest_path):
  56. # when event is about a file, pass
  57. # this will be deleted at on_modified function
  58. return
  59. if os.path.exists(dest_path):
  60. shutil.rmtree(dest_path)
  61. def get_dest_path(self, src_path: str) -> str:
  62. """Get public file path.
  63. Args:
  64. src_path: The asset file path.
  65. Returns:
  66. The public file path.
  67. """
  68. return src_path.replace(
  69. str(self.root / Dirs.APP_ASSETS), str(self.root / Dirs.WEB_ASSETS)
  70. )