76 lines
3.1 KiB
Python
76 lines
3.1 KiB
Python
import os
|
|
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
|
|
from googleapiclient.http import MediaFileUpload
|
|
import pickle
|
|
|
|
SCOPES = ['https://www.googleapis.com/auth/drive.file']
|
|
|
|
class GoogleDriveUploader:
|
|
def __init__(self, credentials_file, token_file):
|
|
self.credentials_file = credentials_file
|
|
self.token_file = token_file
|
|
self.service = None
|
|
self._authenticate()
|
|
|
|
def _authenticate(self):
|
|
"""구글 드라이브 인증"""
|
|
creds = None
|
|
|
|
# 기존 토큰 파일이 있으면 로드
|
|
if os.path.exists(self.token_file):
|
|
with open(self.token_file, 'rb') as token:
|
|
creds = pickle.load(token)
|
|
|
|
# 유효한 인증 정보가 없으면 새로 인증
|
|
if not creds or not creds.valid:
|
|
if creds and creds.expired and creds.refresh_token:
|
|
creds.refresh(Request())
|
|
else:
|
|
if not os.path.exists(self.credentials_file):
|
|
raise FileNotFoundError(
|
|
f"구글 드라이브 인증 파일을 찾을 수 없습니다: {self.credentials_file}\n"
|
|
"Google Cloud Console에서 OAuth 2.0 클라이언트 ID를 다운로드하여 "
|
|
"credentials.json으로 저장해주세요."
|
|
)
|
|
flow = InstalledAppFlow.from_client_secrets_file(
|
|
self.credentials_file, SCOPES)
|
|
# 서버 환경에서는 브라우저가 없을 수 있으므로 예외 처리
|
|
try:
|
|
creds = flow.run_local_server(port=0)
|
|
except Exception as e:
|
|
# 브라우저를 열 수 없는 경우 (서버 환경 등)
|
|
# 토큰 파일이 이미 있다면 재시도하지 않고 예외 발생
|
|
raise Exception(
|
|
"구글 드라이브 인증을 완료할 수 없습니다. "
|
|
"로컬 환경에서 먼저 인증을 완료하여 token.json 파일을 생성해주세요."
|
|
) from e
|
|
|
|
# 토큰 저장
|
|
with open(self.token_file, 'wb') as token:
|
|
pickle.dump(creds, token)
|
|
|
|
self.service = build('drive', 'v3', credentials=creds)
|
|
|
|
def upload_file(self, file_path, file_name, folder_id=None):
|
|
"""파일을 구글 드라이브에 업로드"""
|
|
if not self.service:
|
|
raise Exception("구글 드라이브 서비스가 초기화되지 않았습니다.")
|
|
|
|
file_metadata = {'name': file_name}
|
|
if folder_id:
|
|
file_metadata['parents'] = [folder_id]
|
|
|
|
media = MediaFileUpload(file_path, mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
|
|
|
|
file = self.service.files().create(
|
|
body=file_metadata,
|
|
media_body=media,
|
|
fields='id'
|
|
).execute()
|
|
|
|
return file.get('id')
|
|
|