File size: 5,804 Bytes
2978bba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env python3
"""
Full automated setup and demo test for MorphGuard without invoking separate shell scripts.
Usage: python3 scripts/full_run.py [--base-url URL] [--verbose]
"""
import os
import sys
import subprocess
import json
import time
import shutil
import argparse
import requests

def run_cmd(cmd, verbose=False):
    if verbose:
        print(f"[CMD] {' '.join(cmd)}")
    result = subprocess.run(cmd, stdout=subprocess.PIPE if not verbose else None,
                             stderr=subprocess.STDOUT, text=True)
    if result.returncode != 0:
        print(f"❌ Command failed (exit {result.returncode}): {' '.join(cmd)}")
        if not verbose and result.stdout:
            print(result.stdout)
        sys.exit(result.returncode)
    if not verbose and result.stdout:
        print(result.stdout)
    return result

def install_requirements(verbose=False):
    run_cmd([sys.executable, '-m', 'pip', 'install', 'psycopg2-binary', 'opencv-python',
             'dronekit', 'flask-socketio', 'open3d'], verbose)

def check_server(session, base_url):
    try:
        r = session.get(base_url, timeout=5)
        if r.status_code != 200:
            print(f"❌ Server responded {r.status_code}, expected 200.")
            sys.exit(1)
        print(f"✔ Server is up at {base_url}")
    except Exception as e:
        print(f"❌ Error connecting to server at {base_url}: {e}")
        sys.exit(1)

def login_admin(session, base_url):
    login_url = f"{base_url}/login"
    data = {'username': 'admin', 'password': 'morph@123'}
    r = session.post(login_url, data=data)
    if r.status_code != 200 or 'Invalid credentials' in r.text:
        print("❌ Admin login failed.")
        sys.exit(1)
    print("✔ Logged in as admin.")

def write_db_config():
    cfg = {
        'DB_NAME': 'morphguard',
        'DB_USER': 'morphguard',
        'DB_PASS': 'morphguard',
        'DB_HOST': '127.0.0.1',
        'DB_PORT': 5432
    }
    with open('db_config.json', 'w') as f:
        json.dump(cfg, f, indent=2)
    print("✔ Wrote db_config.json")

def install_timescaledb(verbose=False):
    if not shutil.which('psql'):
        if shutil.which('apt-get'):
            run_cmd(['bash', 'scripts/install_timescaledb.sh'], verbose)
        else:
            print("⚠️  psql not found, skipping TimescaleDB setup.")
    else:
        print("✔ psql found, assuming TimescaleDB ready.")

def api_call(session, base_url, method, endpoint, payload=None):
    url = f"{base_url}{endpoint}"
    if method.lower() == 'get':
        r = session.get(url)
    else:
        r = session.post(url, json=payload)
    try:
        data = r.json()
    except ValueError:
        data = r.text
    print(f"{endpoint} -> {data}")
    if r.status_code >= 400:
        print(f"❌ API error {r.status_code} at {endpoint}")
        sys.exit(1)
    return data

def fetch_datasets(session, base_url):
    keys = {
        'access_key': os.getenv('UNSPLASH_ACCESS_KEY', ''),
        'secret_key': os.getenv('UNSPLASH_SECRET_KEY', ''),
        'pexels_key': os.getenv('PEXELS_API_KEY', ''),
        'pixabay_key': os.getenv('PIXABAY_API_KEY', '')
    }
    api_call(session, base_url, 'post', '/api/setup/keys', keys)
    api_call(session, base_url, 'post', '/api/setup/fetch_utkface', {'count': 1000, 'split': 'train'})
    api_call(session, base_url, 'post', '/api/setup/fetch_lfw', {'count': 500, 'split': 'train'})
    if keys['pexels_key']:
        api_call(session, base_url, 'post', '/api/setup/fetch_pexels', {'count': 500, 'split': 'train'})
    if keys['pixabay_key']:
        api_call(session, base_url, 'post', '/api/setup/fetch_pixabay', {'count': 500, 'split': 'train'})
    api_call(session, base_url, 'post', '/api/setup/fetch_real', {'count': 500, 'split': 'train'})
    api_call(session, base_url, 'post', '/api/setup/generate_morphs', {'count': 4000, 'split': 'train'})

def train_detector(session, base_url):
    # Send empty JSON payload to initiate detector training
    api_call(session, base_url, 'post', '/api/train/detector', {})
    print("✔ Training started.")

def test_cameras(session, base_url):
    try:
        import cv2
    except ImportError:
        print("⚠️  OpenCV not installed, skipping camera test.")
        return
    cams = []
    for i in range(4):
        cap = cv2.VideoCapture(i)
        if cap.isOpened(): cams.append((i, cap))
        else: cap.release()
    frames = []
    for idx, cap in cams:
        ret, frame = cap.read()
        cap.release()
        if ret:
            _, buf = cv2.imencode('.jpg', frame)
            frames.append((idx, buf.tobytes()))
    if not frames:
        print("⚠️  No webcams detected for test.")
        return
    for idx, imgb in frames:
        files = {'image': (f'cam{idx}.jpg', imgb, 'image/jpeg')}
        r = session.post(f"{base_url}/api/detect", files=files)
        print(f"Camera {idx} detect: {r.json()}")
    idx, imgb = frames[0]
    files = {'image': (f'cam{idx}.jpg', imgb, 'image/jpeg')}
    r = session.post(f"{base_url}/api/demorph", files=files)
    print(f"Camera {idx} demorph: {r.json()}")

def main():
    parser = argparse.ArgumentParser(description="Full MorphGuard automator")
    parser.add_argument('--base-url', default='http://localhost:5000')
    parser.add_argument('--verbose', action='store_true')
    args = parser.parse_args()
    session = requests.Session()
    install_requirements(args.verbose)
    check_server(session, args.base_url)
    login_admin(session, args.base_url)
    write_db_config()
    # install_timescaledb(args.verbose)
    fetch_datasets(session, args.base_url)
    train_detector(session, args.base_url)
    time.sleep(2)
    test_cameras(session, args.base_url)
    print("✅ Full run complete.")

if __name__ == '__main__':
    main()