Skip to content

Commit c13751c

Browse files
committed
Google Drive 新增一次上傳多個檔案到指定資料夾
1 parent fd3590a commit c13751c

File tree

5 files changed

+227
-0
lines changed

5 files changed

+227
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
test
2+
123
3+
123
4+
456
5+
789
6+
hihi
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
test
2+
123
3+
123
4+
456
5+
789
6+
hihi
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
test
2+
123
3+
123
4+
456
5+
789
6+
hihi
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
test
2+
123
3+
123
4+
456
5+
789
6+
hihi
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
from __future__ import print_function
2+
import os
3+
import io
4+
import time
5+
from os.path import join
6+
7+
from googleapiclient.discovery import build
8+
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
9+
from httplib2 import Http
10+
from oauth2client import file, client, tools
11+
12+
# 權限必須
13+
SCOPES = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
14+
15+
16+
def delete_drive_service_file(service, file_id):
17+
service.files().delete(fileId=file_id).execute()
18+
19+
20+
def update_file(service, update_drive_service_name, local_file_path, update_drive_service_folder_id):
21+
"""
22+
23+
將本地端的檔案傳到雲端上
24+
25+
:param update_drive_service_folder_id: 判斷是否有 Folder id 沒有的話,會上到雲端的目錄
26+
:param service: 認證用
27+
:param update_drive_service_name: 存到 雲端上的名稱
28+
:param local_file_path: 本地端的位置
29+
:param local_file_name: 本地端的檔案名稱
30+
"""
31+
print("正在上傳檔案...")
32+
if update_drive_service_folder_id is None:
33+
file_metadata = {'name': update_drive_service_name}
34+
else:
35+
print("雲端資料夾id: %s" % update_drive_service_folder_id)
36+
file_metadata = {'name': update_drive_service_name,
37+
'parents': update_drive_service_folder_id}
38+
39+
media = MediaFileUpload(local_file_path, )
40+
file_metadata_size = media.size()
41+
start = time.time()
42+
file_id = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
43+
end = time.time()
44+
print("上傳檔案成功!")
45+
print('雲端檔案名稱為: ' + str(file_metadata['name']))
46+
print('雲端檔案ID為: ' + str(file_id['id']))
47+
print('檔案大小為: ' + str(file_metadata_size) + ' byte')
48+
print("上傳時間為: " + str(end-start))
49+
50+
return file_metadata['name'], file_id['id']
51+
52+
53+
def search_folder(service, update_drive_folder_name=None):
54+
"""
55+
如果雲端資料夾名稱相同,則只會選擇一個資料夾上傳,請勿取名相同名稱
56+
:param service: 認證用
57+
:param update_drive_folder_name: 取得指定資料夾的id,沒有的話回傳None,給錯也會回傳None
58+
:return:
59+
"""
60+
get_folder_id_list = []
61+
print(len(get_folder_id_list))
62+
if update_drive_folder_name is not None:
63+
response = service.files().list(fields="nextPageToken, files(id, name)", spaces='drive',
64+
q = "name = '" + update_drive_folder_name + "' and mimeType = 'application/vnd.google-apps.folder' and trashed = false").execute()
65+
for file in response.get('files', []):
66+
# Process change
67+
print('Found file: %s (%s)' % (file.get('name'), file.get('id')))
68+
get_folder_id_list.append(file.get('id'))
69+
if len(get_folder_id_list) == 0:
70+
print("你給的資料夾名稱沒有在你的雲端上!,因此檔案會上傳至雲端根目錄")
71+
return None
72+
else:
73+
return get_folder_id_list
74+
return None
75+
76+
77+
def search_file(service, update_drive_service_name, is_delete_search_file=False):
78+
"""
79+
本地端
80+
取得到雲端名稱,可透過下載時,取得file id 下載
81+
82+
:param service: 認證用
83+
:param update_drive_service_name: 要上傳到雲端的名稱
84+
:param is_delete_search_file: 判斷是否需要刪除這個檔案名稱
85+
:return:
86+
"""
87+
# Call the Drive v3 API
88+
results = service.files().list(fields="nextPageToken, files(id, name)", spaces='drive',
89+
q="name = '" + update_drive_service_name + "' and trashed = false",
90+
).execute()
91+
items = results.get('files', [])
92+
if not items:
93+
print('沒有發現你要找尋的 ' + update_drive_service_name + ' 檔案.')
94+
else:
95+
print('搜尋的檔案: ')
96+
for item in items:
97+
times = 1
98+
print(u'{0} ({1})'.format(item['name'], item['id']))
99+
if is_delete_search_file is True:
100+
print("刪除檔案為:" + u'{0} ({1})'.format(item['name'], item['id']))
101+
delete_drive_service_file(service, file_id=item['id'])
102+
103+
if times == len(items):
104+
return item['id']
105+
else:
106+
times += 1
107+
108+
109+
def trashed_file(service, is_delete_trashed_file=False):
110+
"""
111+
112+
抓取到雲端上垃圾桶內的全部檔案,進行刪除
113+
114+
:param service: 認證用
115+
:param is_delete_trashed_file: 是否要刪除垃圾桶資料
116+
:return:
117+
"""
118+
results = service.files().list(fields="nextPageToken, files(id, name)", spaces='drive', q="trashed = true",
119+
).execute()
120+
items = results.get('files', [])
121+
if not items:
122+
print('垃圾桶無任何資料.')
123+
else:
124+
print('垃圾桶檔案: ')
125+
for item in items:
126+
print(u'{0} ({1})'.format(item['name'], item['id']))
127+
if is_delete_trashed_file is True:
128+
print("刪除檔案為:" + u'{0} ({1})'.format(item['name'], item['id']))
129+
delete_drive_service_file(service, file_id=item['id'])
130+
131+
132+
def get_update_files_path_list(update_files_path):
133+
"""
134+
將上傳檔案的資料夾內的路徑以及名稱,全部放到list內
135+
:param update_files_path: 要上傳檔案的資料夾
136+
"""
137+
UploadFilesPathList = []
138+
UploadFilesNameList = []
139+
for root, dirs, files in os.walk(update_files_path):
140+
for f in files:
141+
fullPath = join(root, f)
142+
UploadFilesPathList.append(fullPath)
143+
UploadFilesNameList.append(f)
144+
print("取得要上傳的所有檔案路徑: \n%s" % '\n'.join(UploadFilesPathList))
145+
return UploadFilesNameList, UploadFilesPathList
146+
147+
148+
def main(is_update_file_function=False, update_drive_service_folder_name=None, update_drive_service_name=None, update_file_path=None):
149+
"""
150+
:param update_drive_service_folder_name: 給要上傳檔案到雲端的資料夾名稱,預設則是上傳至雲端目錄
151+
:param is_update_file_function: 判斷是否執行上傳的功能
152+
:param update_drive_service_name: 要上傳到雲端上的檔案名稱
153+
:param update_file_path: 要上傳檔案的位置以及名稱
154+
"""
155+
156+
print("is_update_file_function: %s" % is_update_file_function)
157+
print("update_drive_service_folder_name: %s" % update_drive_service_folder_name)
158+
159+
store = file.Storage('token.json')
160+
creds = store.get()
161+
if not creds or creds.invalid:
162+
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
163+
creds = tools.run_flow(flow, store)
164+
service = build('drive', 'v3', http=creds.authorize(Http()))
165+
print('*' * 10)
166+
167+
if is_update_file_function is True:
168+
169+
if update_drive_service_name is None: # 上傳資料夾內的所有檔案會跑這裡
170+
print("上傳資料夾內,所有檔案")
171+
UploadFilesName, UploadFilesPath = get_update_files_path_list(update_files_path = update_file_path)
172+
print("=====執行上傳檔案=====")
173+
get_folder_id = search_folder(service = service, update_drive_folder_name = update_drive_service_folder_name)
174+
print(UploadFilesPath)
175+
for UploadFileName in UploadFilesName:
176+
# 搜尋要上傳的檔案名稱是否有在雲端上並且刪除
177+
search_file(service = service, update_drive_service_name = UploadFileName, is_delete_search_file = True)
178+
# # 檔案上傳到雲端上
179+
for i in range(len(UploadFilesPath)):
180+
update_file(service=service, update_drive_service_name=UploadFilesName[i],
181+
local_file_path=UploadFilesPath[i], update_drive_service_folder_id=get_folder_id)
182+
print("=====上傳檔案完成=====")
183+
184+
else: # 單純上傳一個檔案會跑這裡
185+
print(update_file_path + update_drive_service_name)
186+
print("=====執行上傳檔案=====")
187+
# 清空 雲端垃圾桶檔案
188+
# trashed_file(service=service, is_delete_trashed_file=True)
189+
get_folder_id = search_folder(service = service, update_drive_folder_name = update_drive_service_folder_name)
190+
# 搜尋要上傳的檔案名稱是否有在雲端上並且刪除
191+
search_file(service=service, update_drive_service_name=update_drive_service_name, is_delete_search_file=True)
192+
# 檔案上傳到雲端上
193+
update_file(service=service, update_drive_service_name=update_drive_service_name,
194+
local_file_path=os.getcwd() + '/' + update_drive_service_name, update_drive_service_folder_id=get_folder_id)
195+
print("=====上傳檔案完成=====")
196+
197+
198+
if __name__ == '__main__':
199+
200+
main(is_update_file_function=bool(True), update_drive_service_folder_name='TestAPI', update_drive_service_name=None, update_file_path=os.getcwd() + '/UploadFiles/')
201+
202+
203+

0 commit comments

Comments
 (0)