Update the synchronization app to periodically query the remote root directory listing

This commit is contained in:
2025-12-05 09:44:42 +01:00
parent 49cee347f5
commit d2c5c42537
+31 -105
View File
@@ -1,125 +1,51 @@
import asyncio import asyncio
import logging
from pathlib import Path from pathlib import Path
from aiohttp import ( import aiohttp
ClientSession,
TraceConfig,
TraceRequestEndParams,
TraceRequestStartParams,
)
from watchfiles import Change, awatch
local_root = "."
remote_root = f"http://127.0.0.1:8090/"
logging.basicConfig(
level=logging.INFO,
format="%(message)s", # No timestamp prefix for curl-like output
)
logger = logging.getLogger(__name__)
async def on_request_start(session, context, params: TraceRequestStartParams): async def fetch(session, url):
logger.info(f"> {params.method} {params.url.path_qs} HTTP/1.1") async with session.get(url) as response:
logger.info(f"> Host: {params.url.host}") if response.status != 200:
for name, value in params.headers.items(): raise "Didn't work" # TODO
logger.info(f"> {name}: {value}")
logger.info(">")
data = await response.text()
async def on_request_end(session, context, params: TraceRequestEndParams): files = []
response = params.response lines = data.splitlines()
logger.info(f"< HTTP/1.1 {response.status} {response.reason}") for line in lines:
for name, value in response.headers.items(): name, vtag = line.split(" ")
logger.info(f"< {name}: {value}")
logger.info("<")
# Optionally log response body # Process name
# body = await response.text() is_dir = False
# if body: if len(name) > 0 and name[-1] == "/":
# logger.info(body) name = name[:-1]
is_dir = True
# Process vtag
vtag = int(vtag)
trace_config = TraceConfig() files.append({"name": name, "is_dir": is_dir, "vtag": vtag})
trace_config.on_request_start.append(on_request_start)
trace_config.on_request_end.append(on_request_end) return files
async def main(): async def main():
async for changes in awatch(local_root): async with aiohttp.ClientSession() as session:
for change_type, filepath in changes: remote = "http://127.0.0.1:8090" # Must not end with a "/"
await process_change(change_type, filepath) remote_dir = remote + "/"
local_dir = "local_root"
local_dir = Path(local_dir)
async def process_change(change_type, filepath): while True:
if change_type == Change.added: # List of files in the remote root directory
await process_change_added(filepath) remote_files = await fetch(session, remote_dir)
elif change_type == Change.modified:
await process_change_modified(filepath)
elif change_type == Change.deleted:
await process_change_deleted(filepath)
else:
raise "Unexpected change type"
# List of files in the local root directory
local_files = list(local_dir.iterdir())
def make_relative_path(root, target): await asyncio.sleep(1)
root = Path(root).resolve()
target = Path(target).resolve()
return str(target.relative_to(root))
def endpoint_from_local_path(local_target):
relative_path = make_relative_path(local_root, local_target)
relative_path = relative_path.replace("\\", "/")
remote_target = remote_root + relative_path
assert remote_target[-1] != "/"
if Path(local_target).is_dir():
remote_target += "/"
return remote_target
async def process_change_added(local_target):
async with ClientSession(trace_configs=[trace_config]) as session:
# Determine the endpoint the file should be
# uploaded to.
remote_target = endpoint_from_local_path(local_target)
# Read its contents
with open(local_target, "rb") as f:
data = f.read()
# Upload
async with session.put(remote_target, data=data) as response:
pass # TODO
async def process_change_modified(local_target):
async with ClientSession(trace_configs=[trace_config]) as session:
# Determine the endpoint the file should be
# uploaded to.
remote_target = endpoint_from_local_path(local_target)
# Read its contents
with open(local_target, "rb") as f:
data = f.read()
# Upload
async with session.put(remote_target, data=data) as response:
pass # TODO
async def process_change_deleted(local_target):
async with ClientSession(trace_configs=[trace_config]) as session:
# Determine the endpoint that should be deleted
remote_target = endpoint_from_local_path(local_target)
# Delete
async with session.delete(remote_target) as response:
pass # TODO
try: try: