Files
openclaw/skills/paradiz/scripts/manage_holds.py
2026-03-01 17:44:19 +03:00

141 lines
4.0 KiB
Python

#!/usr/bin/env python3
import argparse
import json
import os
from datetime import datetime, timedelta, timezone
from pathlib import Path
UTC = timezone.utc
def now_iso() -> str:
return datetime.now(UTC).isoformat()
def parse_iso(value: str) -> datetime:
return datetime.fromisoformat(value.replace('Z', '+00:00'))
def read_jsonl(path: Path):
if not path.exists():
return []
rows = []
with path.open('r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
rows.append(json.loads(line))
return rows
def write_jsonl(path: Path, rows):
path.parent.mkdir(parents=True, exist_ok=True)
with path.open('w', encoding='utf-8') as f:
for r in rows:
f.write(json.dumps(r, ensure_ascii=False) + '\n')
def cleanup(rows):
now = datetime.now(UTC)
changed = 0
for r in rows:
if r.get('status') == 'active':
exp = parse_iso(r['expires_at'])
if exp <= now:
r['status'] = 'expired'
r['expired_at'] = now_iso()
changed += 1
return changed
def cmd_cleanup(args):
path = Path(args.file)
rows = read_jsonl(path)
changed = cleanup(rows)
write_jsonl(path, rows)
print(json.dumps({'ok': True, 'changed': changed, 'total': len(rows)}, ensure_ascii=False))
def cmd_add(args):
path = Path(args.file)
rows = read_jsonl(path)
cleanup(rows)
now = datetime.now(UTC)
expires = now + timedelta(hours=args.hold_hours)
# close previous active holds for same client
replaced = 0
for r in rows:
if r.get('status') == 'active' and r.get('client_contact') == args.client_contact:
r['status'] = 'replaced'
r['replaced_at'] = now_iso()
replaced += 1
rec = {
'hold_id': f"HLD-{int(now.timestamp())}",
'created_at': now.isoformat(),
'expires_at': expires.isoformat(),
'status': 'active',
'client_name': args.client_name,
'client_contact': args.client_contact,
'room': args.room,
'checkin': args.checkin,
'checkout': args.checkout,
'guests': args.guests,
'notes': args.notes or '',
}
rows.append(rec)
write_jsonl(path, rows)
warn = (
'Я могу удерживать номер только 24 часа. '
'После этого заявка автоматически удаляется, и при повторном обращении оформляем заново.'
)
print(json.dumps({'ok': True, 'hold': rec, 'replaced': replaced, 'client_warning': warn}, ensure_ascii=False))
def cmd_list(args):
path = Path(args.file)
rows = read_jsonl(path)
cleanup(rows)
write_jsonl(path, rows)
out = rows
if args.active_only:
out = [r for r in rows if r.get('status') == 'active']
print(json.dumps({'ok': True, 'items': out}, ensure_ascii=False))
def main():
p = argparse.ArgumentParser(description='Manage 24h room hold requests (jsonl).')
p.add_argument('--file', default=str(Path(__file__).resolve().parent.parent / 'data' / 'holds.jsonl'))
sub = p.add_subparsers(dest='cmd', required=True)
c1 = sub.add_parser('cleanup')
c1.set_defaults(func=cmd_cleanup)
c2 = sub.add_parser('add')
c2.add_argument('--client-name', required=True)
c2.add_argument('--client-contact', required=True)
c2.add_argument('--room', required=True)
c2.add_argument('--checkin', required=True)
c2.add_argument('--checkout', required=True)
c2.add_argument('--guests', type=int, required=True)
c2.add_argument('--notes', default='')
c2.add_argument('--hold-hours', type=int, default=24)
c2.set_defaults(func=cmd_add)
c3 = sub.add_parser('list')
c3.add_argument('--active-only', action='store_true')
c3.set_defaults(func=cmd_list)
args = p.parse_args()
args.func(args)
if __name__ == '__main__':
main()