Проблема с использованием Python для загрузки нестандартных файлов на Google Диск - PullRequest
0 голосов
/ 27 мая 2020

Моя организация переносит наши локальные сетевые диски на Google Диск, и я надеюсь немного автоматизировать этот процесс. Не разработчик по профессии, но у меня есть опыт программирования. Никогда раньше не работал с Python или Google API, но мне нравится решать задачи. Однако я немного застрял на этом пути - я заставил его циклически перебирать все файлы и каталоги, и я думаю, что даже нашел способ заставить его правильно отображать всю файловую систему. Как ни странно, я думал, что это обычное дело, но я не нашел кода, который бы это делал. Если вы знаете, как скопировать весь каталог на Google Диск, чтобы все подкаталоги были сохранены, дайте мне знать; Я сделал свой собственный, и это своего рода кладж. Однако, когда я запустил его, он работал с определенными типами файлов, но вылетал с ошибкой UnknownFileType, если обнаруживал тип файла, который не был чем-то распространенным, например txt, docx или xlsx. Очевидно, что люди, которым нужно передать свои файлы, будут иметь файлы всех типов, так что этого просто не будет. Не знаю, как с этим справиться. Я думаю, что мог бы заставить работать один файл, если бы я установил метаданные mimeType, но если он работает с несколькими файлами, я не могу установить mimeType вручную. Может быть, есть другой метод загрузки файлов, который может работать с любым типом без необходимости знать mimeType? Так как это мой первый опыт работы с Python или API Google, я в основном копировал код, который был у них на сайте, а также код, который я нашел в других местах, а затем отредактировал его, чтобы просмотреть все нужные мне файлы. Выгрузка не будет работать даже с одним файлом, если это странное расширение. Надеюсь, вы все найдете, что не так. Вот соответствующий фрагмент кода.


for filename in filenames:
            print("Uploading file " + filename + " to " + folnames[i])
            file_metadata = {'name': filename,
                         'parents' : [folids[i]]}
            file = service.files().create(body=file_metadata,
                                        media_body=dirpath + "\\" + filename,
                                        fields='id').execute()
            print("Upload Complete")

Любая помощь приветствуется. Спасибо!

Редактировать: я публикую полный код мини-программы, которую я сделал для тестирования загрузки одного файла. Имена файлов изменены для защиты конфиденциальности

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive']

def main():
    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
    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(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('drive', 'v3', credentials=creds)


    file_metadata = {'name': 'FILENAME'}
    file = service.files().create(body=file_metadata,
                                        media_body='FILEPATH',
                                        fields='id').execute()
    print ("File ID: %s" % file.get('id'))

if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 28 мая 2020

Получил работу, используя MimeTypes, чтобы угадать mimetype и MediaFileUpload для тела мультимедиа. Спасибо всем за вашу помощь и предложения.

---
from __future__ import print_function
import pickle
import mimetypes
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build
from apiclient.http import MediaFileUpload

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive']

def main():
    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
    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(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('drive', 'v3', credentials=creds)



    mime = mimetypes.MimeTypes().guess_type("FILE")[1]
    file_metadata = {'name': 'NAME',
                     'mimeType': mime}
    media = MediaFileUpload('FILE', mimetype = mime)
    file = service.files().create(body=file_metadata,
                                        media_body= media,
                                        fields='id').execute()
    print ("File ID: %s" % file.get('id'))

if __name__ == '__main__':
    main()
---
...