nestwatch 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nestwatch/__init__.py +0 -0
- nestwatch/core/__init__.py +1 -0
- nestwatch/core/observer.py +30 -0
- nestwatch/watchers/__init__.py +1 -0
- nestwatch/watchers/base.py +0 -0
- nestwatch/watchers/json.py +78 -0
- nestwatch-0.0.2.dist-info/METADATA +9 -0
- nestwatch-0.0.2.dist-info/RECORD +10 -0
- nestwatch-0.0.2.dist-info/WHEEL +5 -0
- nestwatch-0.0.2.dist-info/top_level.txt +1 -0
nestwatch/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .observer import FileSystemObserver
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from watchdog.observers import Observer
|
|
2
|
+
from watchdog.events import FileSystemEventHandler
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FileSystemObserver(FileSystemEventHandler):
|
|
9
|
+
def __init__(self, callback, file_path):
|
|
10
|
+
self.callback = callback
|
|
11
|
+
self.file_path = file_path
|
|
12
|
+
self.observer = Observer()
|
|
13
|
+
|
|
14
|
+
self.last_called = 0
|
|
15
|
+
|
|
16
|
+
def on_modified(self, event):
|
|
17
|
+
if time.time() - self.last_called < 0.2:
|
|
18
|
+
return
|
|
19
|
+
self.last_called = time.time()
|
|
20
|
+
|
|
21
|
+
if event.is_directory:
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
elif event.src_path == self.file_path:
|
|
25
|
+
asyncio.run_coroutine_threadsafe(self.callback(), loop=self.loop)
|
|
26
|
+
|
|
27
|
+
async def start(self):
|
|
28
|
+
self.loop = asyncio.get_running_loop()
|
|
29
|
+
self.observer.schedule(self, path=self.file_path, recursive=False)
|
|
30
|
+
self.observer.start()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .json import JSONWatcher
|
|
File without changes
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from ..core import FileSystemObserver
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from typing import Callable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class JSONWatcher:
|
|
9
|
+
def __init__(self, file_path):
|
|
10
|
+
self.file_path = file_path
|
|
11
|
+
self.observer = FileSystemObserver(self._on_modified, file_path)
|
|
12
|
+
self.callback: Callable = None
|
|
13
|
+
self.data = None
|
|
14
|
+
|
|
15
|
+
async def _on_modified(self):
|
|
16
|
+
with open(self.file_path, "r") as f:
|
|
17
|
+
data = json.load(f)
|
|
18
|
+
|
|
19
|
+
# Compare the difference
|
|
20
|
+
added, removed, changed = self._diff(
|
|
21
|
+
self.data or {},
|
|
22
|
+
data
|
|
23
|
+
)
|
|
24
|
+
self.data = data
|
|
25
|
+
|
|
26
|
+
if callable(self.callback):
|
|
27
|
+
await self.callback(added, removed, changed)
|
|
28
|
+
|
|
29
|
+
def _diff(self, old, new, path=None):
|
|
30
|
+
added = {}
|
|
31
|
+
removed = {}
|
|
32
|
+
changed = {}
|
|
33
|
+
|
|
34
|
+
path = path
|
|
35
|
+
|
|
36
|
+
all_keys = set(old or {}) | set(new or {})
|
|
37
|
+
for key in all_keys:
|
|
38
|
+
current_path = f"{path}.{key}" if path else key
|
|
39
|
+
|
|
40
|
+
if key not in old:
|
|
41
|
+
added[current_path] = new[key]
|
|
42
|
+
|
|
43
|
+
elif key not in new:
|
|
44
|
+
removed[current_path] = old[key]
|
|
45
|
+
|
|
46
|
+
elif isinstance(old[key], dict) and isinstance(new[key], dict):
|
|
47
|
+
added_, removed_, changed_ = self._diff(old[key], new[key], current_path)
|
|
48
|
+
added.update(added_)
|
|
49
|
+
removed.update(removed_)
|
|
50
|
+
changed.update(changed_)
|
|
51
|
+
|
|
52
|
+
elif old[key] != new[key]:
|
|
53
|
+
changed[current_path] = {
|
|
54
|
+
"old": old[key],
|
|
55
|
+
"new": new[key]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
return added, removed, changed
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def on_change(self, func):
|
|
64
|
+
"""
|
|
65
|
+
Sets the callback function to be called when the file is modified.
|
|
66
|
+
"""
|
|
67
|
+
self.callback = func
|
|
68
|
+
|
|
69
|
+
async def start(self):
|
|
70
|
+
"""
|
|
71
|
+
Starts the watcher.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
# Up-to-date the cache before starting
|
|
75
|
+
with open(self.file_path, "r") as f:
|
|
76
|
+
self.data = json.load(f)
|
|
77
|
+
|
|
78
|
+
await self.observer.start()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
nestwatch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
nestwatch/core/__init__.py,sha256=ujGodqVwz_J1XAGDywn3vxFX7FnqIjeMS7MCx8upw1c,40
|
|
3
|
+
nestwatch/core/observer.py,sha256=FllET_QmWMZ3q7WanRqjwOknoZ3BY4baaOsGGv-8RvE,871
|
|
4
|
+
nestwatch/watchers/__init__.py,sha256=TjXpjI8uj4vHkfvIJsN53fQzD-u_kwfFw64KA_gZRSw,29
|
|
5
|
+
nestwatch/watchers/base.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
nestwatch/watchers/json.py,sha256=Y7wg0VGw5RuWRbp72p9rK-PndrspWcty5HXQXrYCUOI,2067
|
|
7
|
+
nestwatch-0.0.2.dist-info/METADATA,sha256=X8S0mVtAE6Li5M0Ioqv7CBczgCU4SvxA7M4e7sS-m9U,227
|
|
8
|
+
nestwatch-0.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
9
|
+
nestwatch-0.0.2.dist-info/top_level.txt,sha256=2iBNSu7eX5EFzJyc7-vOQGkadB3mI4bYOUl7ygfFNsY,10
|
|
10
|
+
nestwatch-0.0.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nestwatch
|