Pranesh64 commited on
Commit
34014b0
·
verified ·
1 Parent(s): 8546d12

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -12
app.py CHANGED
@@ -6,7 +6,13 @@ import smtplib
6
  import psycopg2
7
  import requests
8
  import gradio as gr
9
-
 
 
 
 
 
 
10
  from email.mime.text import MIMEText
11
  from email.mime.multipart import MIMEMultipart
12
  from datetime import datetime, date
@@ -33,27 +39,95 @@ def get_db():
33
  return psycopg2.connect(DB_URL, sslmode="require")
34
 
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  # ================= EMAIL =================
37
 
38
  def send_email(to, subject, html):
39
 
40
- msg = MIMEMultipart("alternative")
41
- msg["From"] = f"LeetCode Tracker <{GMAIL_USER}>"
42
- msg["To"] = to
43
- msg["Subject"] = subject
44
 
45
- msg.attach(MIMEText(html, "html"))
 
 
 
46
 
47
- try:
48
- with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
49
- server.login(GMAIL_USER, GMAIL_APP_PASSWORD)
50
- server.sendmail(msg["From"], to, msg.as_string())
 
51
 
52
- print("✅ Email sent:", to)
 
 
 
 
 
53
  return True
54
 
55
  except Exception as e:
56
- print("❌ Email error:", e)
 
 
 
 
 
 
57
  return False
58
 
59
 
 
6
  import psycopg2
7
  import requests
8
  import gradio as gr
9
+ import json
10
+ import pickle
11
+ from google.auth.transport.requests import Request
12
+ from google.oauth2.credentials import Credentials
13
+ from google_auth_oauthlib.flow import InstalledAppFlow
14
+ from googleapiclient.discovery import build
15
+ import base64
16
  from email.mime.text import MIMEText
17
  from email.mime.multipart import MIMEMultipart
18
  from datetime import datetime, date
 
39
  return psycopg2.connect(DB_URL, sslmode="require")
40
 
41
 
42
+ SCOPES = ["https://www.googleapis.com/auth/gmail.send"]
43
+ TOKEN_FILE = "token.pkl"
44
+
45
+
46
+ def get_gmail_service():
47
+ """
48
+ Get authenticated Gmail API service.
49
+ Uses token.pkl if available.
50
+ Recreates if expired using credentials from ENV.
51
+ """
52
+
53
+ creds = None
54
+
55
+ # ---- Load cached token ----
56
+ if os.path.exists(TOKEN_FILE):
57
+ try:
58
+ with open(TOKEN_FILE, "rb") as f:
59
+ creds = pickle.load(f)
60
+ except Exception:
61
+ creds = None
62
+
63
+ # ---- If token invalid ----
64
+ if not creds or not creds.valid:
65
+
66
+ if creds and creds.expired and creds.refresh_token:
67
+ try:
68
+ creds.refresh(Request())
69
+ except Exception:
70
+ creds = None
71
+
72
+ # ---- Recreate using credentials ----
73
+ if not creds:
74
+
75
+ creds_json = os.getenv("GMAIL_CREDENTIALS")
76
+
77
+ if not creds_json:
78
+ raise Exception("Missing GMAIL_CREDENTIALS in secrets")
79
+
80
+ creds_dict = json.loads(creds_json)
81
+
82
+ flow = InstalledAppFlow.from_client_config(
83
+ creds_dict,
84
+ SCOPES,
85
+ )
86
+
87
+ creds = flow.run_local_server(port=0)
88
+
89
+ # ---- Save token ----
90
+ with open(TOKEN_FILE, "wb") as f:
91
+ pickle.dump(creds, f)
92
+
93
+ return build("gmail", "v1", credentials=creds)
94
+
95
+
96
+
97
  # ================= EMAIL =================
98
 
99
  def send_email(to, subject, html):
100
 
101
+ try:
102
+ service = get_gmail_service()
 
 
103
 
104
+ message = MIMEText(html, "html")
105
+ message["To"] = to
106
+ message["From"] = GMAIL_USER
107
+ message["Subject"] = subject
108
 
109
+ raw = base64.urlsafe_b64encode(
110
+ message.as_bytes()
111
+ ).decode()
112
+
113
+ body = {"raw": raw}
114
 
115
+ service.users().messages().send(
116
+ userId="me",
117
+ body=body
118
+ ).execute()
119
+
120
+ print("✅ Gmail API sent:", to)
121
  return True
122
 
123
  except Exception as e:
124
+ print("❌ Gmail API error:", e)
125
+
126
+ # If token is corrupted → delete and retry next time
127
+ if os.path.exists(TOKEN_FILE):
128
+ os.remove(TOKEN_FILE)
129
+ print("♻️ token.pkl deleted, will regenerate")
130
+
131
  return False
132
 
133