這是利用 google API 上傳
所以先要有 google token
給需要的人試試,看看會不會佔用相簿空間
或是有其他的方法,歡迎轉貼到其他地方,
註明 funky1221 就好!
※ 引述《funky1221 (funky)》之銘言:
# -*- coding: utf-8 -*-
import pickle
import os
import re
import logging
from datetime import datetime, timedelta
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import requests
import fnmatch
from xml.dom.minidom import Document
import xml.etree.ElementTree as ET
# os.environ["PYTHONIOENCODING"] = "utf-8"
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/photoslibrary']
mytime = datetime.now() + timedelta(hours=8) # 上傳的時間設定
basepath = os.path.dirname(__file__) # 本檔的路徑
filelog = os.path.join(basepath, 'Upload.log') # 上傳的紀錄檔
mypath = r'\\xxxxxx' # 要上傳的路徑,
會以第一層的目錄當相簿
mycreds = None
# 開啟紀錄 LogTemp.log
def EnableLogging():
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(name)-1s %(levelname)-1s
%(message)s',
datefmt='%m-%d %H:%M',
handlers=[logging.FileHandler(filelog), ])
def Get_Token():
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.
if os.path.exists('token.pickle'):
with open('token.pickle', '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(
'client_secrets.json', SCOPES)
creds = flow.run_console()
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
return creds
def Create_Album(album):
creds = mycreds
service = build('photoslibrary', 'v1', credentials=creds)
response_create_album = service.albums().create(body={'album': {'title':
album}}).execute()
print(response_create_album)
return response_create_album['id']
def UploadMedia(fullname, albumid, creds):
# 'latin-1'
file = fullname.encode('utf-8').decode('latin-1').split('/')[-1]
desc = file
# step 1 upload raw bytes to google server
headers = {
'Content-Type': "application/octet-stream",
'X-Goog-Upload-File-Name': file,
'X-Goog-Upload-Content-Type': "mime-type",
'X-Goog-Upload-Protocol': "raw",
'Authorization': "Bearer " + creds.token,
}
data = open(fullname, 'rb').read()
response =
requests.post('https://photoslibrary.googleapis.com/v1/uploads',
headers=headers, data=data)
image_token = response.text
# step 2 create media items
service = build('photoslibrary', 'v1', credentials=creds)
# response_create_album = service.albums().create(body={'album':
{'title': '我的相簿'}}).execute()
myalbumid = albumid
# results = service.albums().list().execute()
'''
items = results.get('albums', [])
if not items:
print('No albums found.')
else:
for item in items:
print(item['title'])
if item['title'] == album:
myalbumid = item['id']
print(myalbumid)
'''
body = {
'albumId': myalbumid,
'newMediaItems': {'description': desc,
'simpleMediaItem': {
'uploadToken': image_token,
'fileName': file
}
}
}
response = service.mediaItems().batchCreate(body=body).execute()
print(response)
mess = response['newMediaItemResults'][0]['status'] # Success or Failed
print(mess)
return mess['message']
def ReadXML(file, strfile='File'):
tree = ET.parse(file)
root = tree.getroot()
nodelist = root.findall(strfile)
if strfile=='File':
albumid = root.findall('AlbumID')[0].text
for node in nodelist:
if node.find('Upload').text == 'false':
path = node.find('Fullname').text
if UploadMedia(path, albumid, mycreds)=='Success':
node.find('Upload').text = 'true'
tree.write(file, encoding="utf-8", xml_declaration=True)
else:
return False
else:
for node in nodelist:
if node.find('Upload').text == 'false':
path = node.find('Fullname').text
xmlpath = path.split('\\')[-1] + '.xml'
xmlpath = os.path.join(basepath, xmlpath)
if not os.path.isfile(xmlpath):
Albumname = path.split('\\')[-1]
albumid = Create_Album(Albumname)
list = GetFiles(path)
xmlpath = WriteXML(path, list, 'File', albumid)
if ReadXML(xmlpath):
node.find('Upload').text = 'true'
tree.write(file, encoding="utf-8", xml_declaration=True)
return True
def WriteXML(path, files, strfile='File', albumid=''):
xml = path.split('\\')[-1]
doc = Document()
base = doc.createElement('UploadFileList')
doc.appendChild(base)
filepath = doc.createElement('FilePath')
base.appendChild(filepath)
textpath = doc.createTextNode(path)
filepath.appendChild(textpath)
if albumid != '':
albumidpath = doc.createElement('AlbumID')
base.appendChild(albumidpath)
alidpath = doc.createTextNode(albumid)
albumidpath.appendChild(alidpath)
for fi in files:
file = doc.createElement(strfile)
fullname = doc.createElement('Fullname')
upload = doc.createElement('Upload')
textfullname = doc.createTextNode(fi)
isupload = doc.createTextNode('false')
fullname.appendChild(textfullname)
upload.appendChild(isupload)
base.appendChild(file)
file.appendChild(fullname)
file.appendChild(upload)
fname = xml + '.xml'
fname = os.path.join(basepath, fname)
with open(fname, 'w', encoding='utf-8') as f:
doc.writexml(f, indent='\t', newl='\n', addindent='\t',
encoding='utf-8')
f.close
return fname
def GetFiles(path):
includes = ['*.jpg','*.mp4'] # jpg, mp4
includes = r'|'.join([fnmatch.translate(x) for x in includes])
list = []
for dirPath, dirNames, fileNames in os.walk(path):
list = [os.path.join(dirPath, f) for f in fileNames if
re.match(includes, f, re.I)]
return list
def main():
"""Shows basic usage of the People API.
Prints the name of the first 10 connections.
"""
EnableLogging()
logging.info('