22import argparse
33import os
44
5- from oauth2client import client , tools
6- from oauth2client .file import Storage
5+ from google .auth .transport .requests import Request
6+ from google .oauth2 .credentials import Credentials
7+ from google_auth_oauthlib .flow import InstalledAppFlow
78
8- flags = argparse .ArgumentParser (parents = [tools .argparser ]).parse_args ()
9+ flags = argparse .ArgumentParser (description = "Google Calendar Bot" )
10+ flags .add_argument (
11+ "--noauth_local_webserver" ,
12+ action = "store_true" ,
13+ help = "Run OAuth flow in console instead of opening a web browser." ,
14+ )
15+ args = flags .parse_args ()
916
1017# If modifying these scopes, delete your previously saved credentials
1118# at zulip/bots/gcal/
1219# NOTE: When adding more scopes, add them after the previous one in the same field, with a space
1320# seperating them.
14- SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
21+ SCOPES = [ "https://www.googleapis.com/auth/calendar.readonly" ]
1522# This file contains the information that google uses to figure out which application is requesting
1623# this client's data.
1724CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
1825APPLICATION_NAME = "Zulip Calendar Bot"
1926HOME_DIR = os .path .expanduser ("~" )
27+ CREDENTIALS_PATH = os .path .join (HOME_DIR , "google-credentials.json" )
2028
2129
22- def get_credentials () -> client . Credentials :
30+ def get_credentials () -> Credentials :
2331 """Gets valid user credentials from storage.
2432
2533 If nothing has been stored, or if the stored credentials are invalid,
@@ -29,18 +37,32 @@ def get_credentials() -> client.Credentials:
2937 Credentials, the obtained credential.
3038 """
3139
32- credential_path = os .path .join (HOME_DIR , "google-credentials.json" )
33-
34- store = Storage (credential_path )
35- credentials = store .get ()
36- if not credentials or credentials .invalid :
37- flow = client .flow_from_clientsecrets (os .path .join (HOME_DIR , CLIENT_SECRET_FILE ), SCOPES )
38- flow .user_agent = APPLICATION_NAME
39- # This attempts to open an authorization page in the default web browser, and asks the user
40- # to grant the bot access to their data. If the user grants permission, the run_flow()
41- # function returns new credentials.
42- credentials = tools .run_flow (flow , store , flags )
43- print ("Storing credentials to " + credential_path )
40+ creds = None
41+
42+ # Check if the credentials file exists
43+ if os .path .exists (CREDENTIALS_PATH ):
44+ creds = Credentials .from_authorized_user_file (CREDENTIALS_PATH , SCOPES )
45+
46+ # If there are no valid credentials, initiate the OAuth flow
47+ if not creds or not creds .valid :
48+ if creds and creds .expired and creds .refresh_token :
49+ creds .refresh (Request ())
50+ else :
51+ flow = InstalledAppFlow .from_client_secrets_file (
52+ os .path .join (HOME_DIR , CLIENT_SECRET_FILE ), SCOPES
53+ )
54+ if args .noauth_local_webserver :
55+ creds = flow .run_console ()
56+ else :
57+ creds = flow .run_local_server (port = 0 )
58+
59+ # Save the credentials for future use
60+ with open (CREDENTIALS_PATH , "w" ) as token_file :
61+ token_file .write (creds .to_json ())
62+
63+ print ("Storing credentials to " + CREDENTIALS_PATH )
64+
65+ return creds
4466
4567
4668get_credentials ()
0 commit comments