aboutsummaryrefslogtreecommitdiff
path: root/scripts/newos4-reply.py
blob: 8144285c0a56c2177e6287962777c0e4849bf68b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env python3
"""Append one reply to the newOS4 maintenance thread.

Hermes writes here instead of POSTing to agent-replies.php, so an expired admin cookie can
never make a reply look delivered when it was not. Same JSON schema and file the PHP endpoint
serves to the in-app `feedback-inbox` command.

Usage: newos4-reply.py "Triage 2026-10-23: ..."   [--author hermes]
"""
import argparse, fcntl, json, os, time

ROOT = '/var/www/webx11.duckdns.org/spaces/newos4'
DIR = os.path.join(ROOT, 'data', 'maintenance')
FILE = os.path.join(DIR, 'replies.json')
MAX = 200


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('body')
    ap.add_argument('--author', default='hermes', choices=['hermes', 'newos4'])
    a = ap.parse_args()

    body = a.body.strip()
    if not body:
        raise SystemExit('refusing to write an empty reply')
    body = body[:2000]

    os.makedirs(DIR, exist_ok=True)
    lock = open(FILE + '.lock', 'a+')
    fcntl.flock(lock, fcntl.LOCK_EX)
    try:
        try:
            with open(FILE, encoding='utf-8') as f:
                data = json.load(f)
        except Exception:
            data = []
        if not isinstance(data, list):
            data = []
        entry = {
            'id': 'REP-' + time.strftime('%Y%m%d-%H%M%S') + '-' + os.urandom(3).hex(),
            'created_at': time.strftime('%Y-%m-%dT%H:%M:%S+00:00', time.gmtime()),
            'author': a.author,
            'body': body,
        }
        data.append(entry)
        tmp = FILE + '.tmp'
        with open(tmp, 'w', encoding='utf-8') as f:
            json.dump(data[-MAX:], f, indent=2)
            f.flush()
            os.fsync(f.fileno())
        os.replace(tmp, FILE)
        os.chmod(FILE, 0o664)
        try:
            os.chmod(FILE, 0o664)
        except Exception:
            pass
        print(entry['id'])
    finally:
        fcntl.flock(lock, fcntl.LOCK_UN)
        lock.close()


if __name__ == '__main__':
    main()