Public Access
289 lines
4.3 KiB
Python
289 lines
4.3 KiB
Python
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
from datetime import datetime, timezone
|
|
|
|
|
|
BASE_DIR = os.path.dirname(
|
|
os.path.abspath(__file__)
|
|
)
|
|
|
|
SYNC_SCRIPT = os.path.join(
|
|
BASE_DIR,
|
|
"sync.py",
|
|
)
|
|
|
|
SYNC_INTERVAL = int(
|
|
os.environ.get(
|
|
"VYTA_SYNC_INTERVAL_SECONDS",
|
|
"300",
|
|
)
|
|
)
|
|
|
|
POLL_INTERVAL = int(
|
|
os.environ.get(
|
|
"VYTA_SYNC_POLL_SECONDS",
|
|
"2",
|
|
)
|
|
)
|
|
|
|
REQUEST_FILE = os.environ.get(
|
|
"VYTA_SYNC_REQUEST_PATH",
|
|
"/data/sync-request.json",
|
|
)
|
|
|
|
STATUS_FILE = os.environ.get(
|
|
"VYTA_SYNC_STATUS_PATH",
|
|
"/data/sync-status.json",
|
|
)
|
|
|
|
|
|
def utc_now():
|
|
return datetime.now(
|
|
timezone.utc
|
|
).isoformat()
|
|
|
|
|
|
def read_status():
|
|
try:
|
|
with open(
|
|
STATUS_FILE,
|
|
"r",
|
|
encoding="utf-8",
|
|
) as file:
|
|
loaded = json.load(file)
|
|
|
|
return (
|
|
loaded
|
|
if isinstance(
|
|
loaded,
|
|
dict,
|
|
)
|
|
else {}
|
|
)
|
|
|
|
except (
|
|
FileNotFoundError,
|
|
json.JSONDecodeError,
|
|
):
|
|
return {}
|
|
|
|
|
|
def write_status(
|
|
**updates,
|
|
):
|
|
existing = read_status()
|
|
|
|
result = {
|
|
**existing,
|
|
**updates,
|
|
}
|
|
|
|
directory = os.path.dirname(
|
|
STATUS_FILE
|
|
)
|
|
|
|
if directory:
|
|
os.makedirs(
|
|
directory,
|
|
exist_ok=True,
|
|
)
|
|
|
|
temporary_file = (
|
|
STATUS_FILE +
|
|
".tmp"
|
|
)
|
|
|
|
with open(
|
|
temporary_file,
|
|
"w",
|
|
encoding="utf-8",
|
|
) as file:
|
|
json.dump(
|
|
result,
|
|
file,
|
|
ensure_ascii=False,
|
|
indent=2,
|
|
)
|
|
|
|
os.replace(
|
|
temporary_file,
|
|
STATUS_FILE,
|
|
)
|
|
|
|
|
|
def consume_manual_request():
|
|
if not os.path.exists(
|
|
REQUEST_FILE
|
|
):
|
|
return False
|
|
|
|
try:
|
|
os.remove(
|
|
REQUEST_FILE
|
|
)
|
|
|
|
print(
|
|
"Manuell sync begärd.",
|
|
flush=True,
|
|
)
|
|
|
|
return True
|
|
|
|
except FileNotFoundError:
|
|
return False
|
|
|
|
|
|
def run_sync(
|
|
trigger: str,
|
|
):
|
|
print(
|
|
"",
|
|
flush=True,
|
|
)
|
|
|
|
print(
|
|
"=" * 60,
|
|
flush=True,
|
|
)
|
|
|
|
print(
|
|
f"VYTA sync trigger: {trigger}",
|
|
flush=True,
|
|
)
|
|
|
|
print(
|
|
f"Tid: {utc_now()}",
|
|
flush=True,
|
|
)
|
|
|
|
print(
|
|
"=" * 60,
|
|
flush=True,
|
|
)
|
|
|
|
write_status(
|
|
trigger=trigger,
|
|
)
|
|
|
|
result = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
SYNC_SCRIPT,
|
|
],
|
|
cwd=BASE_DIR,
|
|
)
|
|
|
|
if result.returncode != 0:
|
|
print(
|
|
"Sync slutade med exit code "
|
|
f"{result.returncode}",
|
|
flush=True,
|
|
)
|
|
|
|
return result.returncode
|
|
|
|
|
|
def update_countdown(
|
|
seconds: int,
|
|
):
|
|
write_status(
|
|
nextAutomaticSyncInSeconds=max(
|
|
0,
|
|
int(seconds),
|
|
),
|
|
syncIntervalSeconds=
|
|
SYNC_INTERVAL,
|
|
)
|
|
|
|
|
|
def main():
|
|
print(
|
|
"VYTA scheduler startad",
|
|
flush=True,
|
|
)
|
|
|
|
print(
|
|
"Automatisk sync: "
|
|
f"var {SYNC_INTERVAL} sekund",
|
|
flush=True,
|
|
)
|
|
|
|
print(
|
|
"Manuell trigger: "
|
|
f"{REQUEST_FILE}",
|
|
flush=True,
|
|
)
|
|
|
|
# Kör direkt när containern startar.
|
|
run_sync(
|
|
"startup"
|
|
)
|
|
|
|
last_run = time.monotonic()
|
|
|
|
while True:
|
|
now = time.monotonic()
|
|
|
|
elapsed = (
|
|
now -
|
|
last_run
|
|
)
|
|
|
|
remaining = (
|
|
SYNC_INTERVAL -
|
|
elapsed
|
|
)
|
|
|
|
if consume_manual_request():
|
|
run_sync(
|
|
"manual"
|
|
)
|
|
|
|
last_run = (
|
|
time.monotonic()
|
|
)
|
|
|
|
update_countdown(
|
|
SYNC_INTERVAL
|
|
)
|
|
|
|
time.sleep(
|
|
POLL_INTERVAL
|
|
)
|
|
|
|
continue
|
|
|
|
if remaining <= 0:
|
|
run_sync(
|
|
"scheduled"
|
|
)
|
|
|
|
last_run = (
|
|
time.monotonic()
|
|
)
|
|
|
|
update_countdown(
|
|
SYNC_INTERVAL
|
|
)
|
|
|
|
time.sleep(
|
|
POLL_INTERVAL
|
|
)
|
|
|
|
continue
|
|
|
|
update_countdown(
|
|
remaining
|
|
)
|
|
|
|
time.sleep(
|
|
POLL_INTERVAL
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|