File size: 7,740 Bytes
cae1888
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import requests
import datetime
import uuid
import json
from typing import Optional, List, Dict, Any

SUPABASE_URL = "https://qsyydjpuzjirxkqyjvqw.supabase.co"
SUPABASE_KEY = "sb_publishable_dccy2bN7gpHHT41CHqaKQQ_LHDR6g2U"

HEADERS = {
    "apikey": SUPABASE_KEY,
    "Authorization": f"Bearer {SUPABASE_KEY}",
    "Content-Type": "application/json",
    "Prefer": "return=representation"
}

class User:
    def __init__(self, id: str, google_id: str, email: str = None, name: str = None, picture: str = None, plan: str = "free", checks_used: int = 0, created_at: str = None):
        self.id = id
        self.google_id = google_id
        self.email = email
        self.name = name
        self.picture = picture
        self.plan = plan
        self.checks_used = checks_used
        self.created_at = created_at

class Job:
    def __init__(self, id: str, user_id: str, job_id: str, file_name: str = None, status: str = "queued", verdict: str = None, max_score: float = None, runtime: float = None, result_json: Any = None, created_at: str = None, finished_at: str = None):
        self.id = id
        self.user_id = user_id
        self.job_id = job_id
        self.file_name = file_name
        self.status = status
        self.verdict = verdict
        self.max_score = max_score
        self.runtime = runtime
        self.result_json = result_json
        self.created_at = created_at
        self.finished_at = finished_at

def get_user_by_id(user_id: str) -> Optional[User]:
    try:
        url = f"{SUPABASE_URL}/rest/v1/users?id=eq.{user_id}"
        res = requests.get(url, headers=HEADERS)
        if res.status_code == 200:
            data = res.json()
            if data:
                return User(**data[0])
    except Exception as e:
        print(f"Error getting user by id: {e}")
    return None

def get_user_by_google_id(google_id: str) -> Optional[User]:
    try:
        url = f"{SUPABASE_URL}/rest/v1/users?google_id=eq.{google_id}"
        res = requests.get(url, headers=HEADERS)
        if res.status_code == 200:
            data = res.json()
            if data:
                return User(**data[0])
    except Exception as e:
        print(f"Error getting user by google_id: {e}")
    return None

def create_user(google_id: str, email: str, name: str, picture: str) -> User:
    url = f"{SUPABASE_URL}/rest/v1/users"
    payload = {
        "google_id": google_id,
        "email": email,
        "name": name,
        "picture": picture
    }
    res = requests.post(url, headers=HEADERS, json=payload)
    res.raise_for_status()
    data = res.json()
    return User(**data[0])

def create_job(job_id: str, user_id: str, file_name: str) -> Job:
    url = f"{SUPABASE_URL}/rest/v1/jobs"
    payload = {
        "job_id": job_id,
        "user_id": user_id,
        "file_name": file_name,
        "status": "queued"
    }
    res = requests.post(url, headers=HEADERS, json=payload)
    res.raise_for_status()
    data = res.json()
    return Job(**data[0])

def get_job_by_job_id(job_id: str) -> Optional[Job]:
    try:
        url = f"{SUPABASE_URL}/rest/v1/jobs?job_id=eq.{job_id}"
        res = requests.get(url, headers=HEADERS)
        if res.status_code == 200:
            data = res.json()
            if data:
                return Job(**data[0])
    except Exception as e:
        print(f"Error getting job by job_id: {e}")
    return None

def get_jobs_by_user_id(user_id: str) -> List[Job]:
    try:
        url = f"{SUPABASE_URL}/rest/v1/jobs?user_id=eq.{user_id}&order=created_at.desc"
        res = requests.get(url, headers=HEADERS)
        if res.status_code == 200:
            data = res.json()
            return [Job(**item) for item in data]
    except Exception as e:
        print(f"Error getting jobs by user_id: {e}")
    return []

def complete_job(job_id: str, status: str, verdict: str = None, max_score: float = None, runtime: float = None, result_json: dict = None, report_items: list = None):
    try:
        job = get_job_by_job_id(job_id)
        if not job:
            print(f"Job {job_id} not found to complete.")
            return
        
        url = f"{SUPABASE_URL}/rest/v1/jobs?id=eq.{job.id}"
        payload = {
            "status": status,
            "verdict": verdict,
            "max_score": max_score,
            "runtime": runtime,
            "result_json": result_json,
            "finished_at": datetime.datetime.now(datetime.timezone.utc).isoformat()
        }
        res = requests.patch(url, headers=HEADERS, json=payload)
        res.raise_for_status()
        
        if report_items:
            items_url = f"{SUPABASE_URL}/rest/v1/report_items"
            payload_items = []
            for item in report_items:
                payload_items.append({
                    "job_id": job.id,
                    "sentence": item.get("sentence"),
                    "url": item.get("url"),
                    "title": item.get("title"),
                    "final_score": item.get("final_score"),
                    "lcs_score": item.get("lcs_score"),
                    "ngram_score": item.get("ngram_score"),
                    "semantic_score": item.get("semantic_score"),
                    "contiguous_score": item.get("contiguous_score", 0.0),
                    "matched_tokens": item.get("matched_tokens", []),
                    "snippet": item.get("snippet")
                })
            res_items = requests.post(items_url, headers=HEADERS, json=payload_items)
            
            # Fallback if inserting contiguous_score fails (e.g. column not yet added to Supabase)
            if res_items.status_code not in (200, 201):
                payload_fallback = []
                for item in report_items:
                    payload_fallback.append({
                        "job_id": job.id,
                        "sentence": item.get("sentence"),
                        "url": item.get("url"),
                        "title": item.get("title"),
                        "final_score": item.get("final_score"),
                        "lcs_score": item.get("lcs_score"),
                        "ngram_score": item.get("ngram_score"),
                        "semantic_score": item.get("semantic_score"),
                        "matched_tokens": item.get("matched_tokens", []),
                        "snippet": item.get("snippet")
                    })
                res_fallback = requests.post(items_url, headers=HEADERS, json=payload_fallback)
                res_fallback.raise_for_status()
    except Exception as e:
        print(f"Error completing job {job_id}: {e}")

def fail_job(job_id: str, error_msg: str):
    try:
        job = get_job_by_job_id(job_id)
        if not job:
            return
        url = f"{SUPABASE_URL}/rest/v1/jobs?id=eq.{job.id}"
        payload = {
            "status": "failed",
            "result_json": {"error": error_msg},
            "finished_at": datetime.datetime.now(datetime.timezone.utc).isoformat()
        }
        res = requests.patch(url, headers=HEADERS, json=payload)
        res.raise_for_status()
    except Exception as e:
        print(f"Error failing job {job_id}: {e}")

def get_report_items(job_uuid: str) -> List[dict]:
    try:
        url = f"{SUPABASE_URL}/rest/v1/report_items?job_id=eq.{job_uuid}"
        res = requests.get(url, headers=HEADERS)
        if res.status_code == 200:
            items = res.json()
            for item in items:
                if "contiguous_score" not in item or item["contiguous_score"] is None:
                    item["contiguous_score"] = 0.0
            return items
    except Exception as e:
        print(f"Error getting report items for job {job_uuid}: {e}")
    return []