Update the synchronization app to periodically query the remote root directory listing
This commit is contained in:
+31
-105
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user