You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.5 KiB
80 lines
2.5 KiB
import datetime
|
|
import os
|
|
import pickle
|
|
|
|
|
|
from googleapiclient.discovery import build
|
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
|
from google.auth.transport.requests import Request
|
|
|
|
import gapi
|
|
|
|
|
|
HOUR = datetime.timedelta(seconds=60 ** 2)
|
|
|
|
|
|
class API:
|
|
def __init__(
|
|
self,
|
|
service,
|
|
scopes,
|
|
app_name,
|
|
client_secret_file=os.path.join(gapi.state_dir, "client_secret.json"),
|
|
credentials_dir=gapi.state_dir,
|
|
version="v3",
|
|
):
|
|
self.service_name = service
|
|
self.app_name = app_name
|
|
self.client_secret_file = client_secret_file
|
|
self.credentials_dir = credentials_dir
|
|
self.scopes = scopes
|
|
self._service = None
|
|
self._service_settime = None
|
|
self.version = version
|
|
|
|
def get_credentials(self):
|
|
creds = None
|
|
# The file token.pickle stores the user's access and refresh tokens, and is
|
|
# created automatically when the authorization flow completes for the first
|
|
# time.
|
|
credential_path = os.path.join(self.credentials_dir, "token.pickle")
|
|
if os.path.exists(credential_path):
|
|
with open(credential_path, "rb") as token:
|
|
creds = pickle.load(token)
|
|
# If there are no (valid) credentials available, let the user log in.
|
|
if not creds or not creds.valid:
|
|
if creds and creds.expired and creds.refresh_token:
|
|
creds.refresh(Request())
|
|
else:
|
|
flow = InstalledAppFlow.from_client_secrets_file(
|
|
self.client_secret_file, self.scopes
|
|
)
|
|
creds = flow.run_local_server(port=0)
|
|
# Save the credentials for the next run
|
|
print("Storing credentials to " + credential_path)
|
|
with open(credential_path, "wb") as token:
|
|
pickle.dump(creds, token)
|
|
return creds
|
|
|
|
def build_service(self):
|
|
credentials = self.get_credentials()
|
|
|
|
service = build(self.service_name, self.version, credentials=credentials)
|
|
return service
|
|
|
|
def _needs_renewal(self):
|
|
now = datetime.datetime.today()
|
|
if self._service_settime:
|
|
return (now - self._service_settime) > HOUR
|
|
else:
|
|
return True
|
|
|
|
@property
|
|
def service(self):
|
|
if self._needs_renewal():
|
|
service = self.build_service()
|
|
self._service = service
|
|
self._service_settime = datetime.datetime.today()
|
|
return service
|
|
else:
|
|
return self._service
|