-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
114 lines (91 loc) · 3.8 KB
/
main.py
File metadata and controls
114 lines (91 loc) · 3.8 KB
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
import os
import requests
from datetime import datetime, timezone, timedelta
import pytz
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
SCOPES = ['https://www.googleapis.com/auth/calendar.events']
CREDENTIALS_FILE = "C:/STORAGE/Code/CodeForces2Calendar/credentials.json"
TOKEN_FILE = "C:/STORAGE/Code/CodeForces2Calendar/token.json"
def get_credentials():
"""Load or request user credentials, refresh if expired."""
creds = None
if os.path.exists(TOKEN_FILE):
try:
creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
if creds.expired and not creds.refresh_token:
os.remove(TOKEN_FILE)
print("Old token removed, will reauthorize.")
creds = None
except Exception:
os.remove(TOKEN_FILE)
creds = None
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
try:
creds.refresh(Request())
except Exception:
os.remove(TOKEN_FILE)
creds = None
if not creds:
flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_FILE, SCOPES)
creds = flow.run_local_server(port=0)
with open(TOKEN_FILE, 'w') as f:
f.write(creds.to_json())
print("New token saved.")
return creds
def fetch_upcoming_contests():
"""Fetch upcoming contests from Codeforces API."""
url = "https://codeforces.com/api/contest.list?gym=false"
resp = requests.get(url).json()
contests = [c for c in resp.get('result', []) if c.get('phase') == 'BEFORE']
contests.sort(key=lambda c: c['startTimeSeconds'])
return contests
def event_exists(service, calendar_id, name, start_iso):
"""Check if event already exists in calendar."""
start_dt = datetime.fromisoformat(start_iso)
time_min = (start_dt - timedelta(minutes=1)).isoformat()
time_max = (start_dt + timedelta(minutes=1)).isoformat()
events = service.events().list(calendarId=calendar_id, timeMin=time_min, timeMax=time_max, singleEvents=True).execute()
for ev in events.get('items', []):
if ev.get('summary') == name:
return True
return False
def create_event(service, calendar_id, contest):
"""Create a calendar event for a contest."""
name = contest['name']
ts = contest['startTimeSeconds']
dur = contest.get('durationSeconds', 7200)
utc_time = datetime.fromtimestamp(ts, tz=timezone.utc)
ist = pytz.timezone('Asia/Kolkata')
start = utc_time.astimezone(ist)
end = (utc_time + timedelta(seconds=dur)).astimezone(ist)
start_iso = start.isoformat()
end_iso = end.isoformat()
if event_exists(service, calendar_id, name, start_iso):
print(f"[skip] already exists: {name} at {start_iso}")
return
event = {
'summary': name,
'start': {'dateTime': start_iso},
'end': {'dateTime': end_iso},
'reminders': {
'useDefault': False,
'overrides': [
{'method': 'popup', 'minutes': 15}
]
}
}
created = service.events().insert(calendarId=calendar_id, body=event).execute()
print(f"[created] {name} → {created.get('htmlLink')}")
def main():
creds = get_credentials()
service = build('calendar', 'v3', credentials=creds)
contests = fetch_upcoming_contests()
print(f"Found {len(contests)} upcoming contests.")
for contest in contests[:2]:
create_event(service, 'primary', contest)
if __name__ == '__main__':
main()