[PYTHON] Script pour sauvegarder les dossiers sur le serveur sur Google Drive

Aperçu

Il s'agit d'un script Python qui zippe les dossiers sur le serveur et les stocke dans Google Drive. Il est censé être exécuté régulièrement et il a également une fonction pour supprimer les anciens fichiers de sauvegarde afin que Google Drive ne se remplisse pas.

Le référentiel GitHub est ici.

J'utilise ce script pour sauvegarder les données enregistrées sur le serveur Minecraft, mais je pensais qu'il pourrait également être utilisé à d'autres fins, alors je l'ai écrit dans l'article de Qiita. Au fait, j'exécute ce script sur AWS EC2 (le système d'exploitation est Ubuntu).

Pour le faire fonctionner, installez les modules nécessaires pour utiliser l'API Google Drive avec pip.

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

Code entier

La vue d'ensemble du code est ci-dessous.

import pickle
import os.path
import datetime
import shutil
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaFileUpload


# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive']
#Nombre de générations pour compléter la sauvegarde
GENERATIONS = 3
#Répertoire de données de sauvegarde
DATA_DIR = '/home/minecraft/server/'
#Le nom du dossier que vous souhaitez sauvegarder
DATA_NAME = 'newworld'
#ID de dossier Google Drive pour enregistrer les données de sauvegarde(Apparaît dans l'URL)
PARENT_ID = 'xxxxxx'

def main():
    '''
Fonction principale
    '''
    #Obtenez des identifiants
    creds = get_creds()
    #Créer un service
    service = build('drive', 'v3', credentials=creds)
    #Vérification des fichiers déjà téléchargés
    existing_files = get_existing_files(service)
    if len(existing_files) >= (GENERATIONS - 1):
        #S'il est stocké plus que nécessaire, supprimez l'ancien
        delete_unnecessary_files(service,existing_files)
    #Compressez les fichiers à télécharger
    file_to_upload = create_zip_file()
    #Téléverser un fichier
    upload_file(service)

def get_creds():
    '''
    1.Obtenez des identifiants
    '''
    creds = None
    #Essayez d'ouvrir le fichier d'authentification
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    #Si vous échouez, créez-en un nouveau
    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)
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return creds

def get_existing_files(service):
    '''
    2.Obtenez un fichier de sauvegarde existant
    '''
    # Call the Drive v3 API
    query = "'" + PARENT_ID + "' in parents"
    results = service.files().list(fields="nextPageToken, files(id, name, createdTime)", q=query).execute()
    items = results.get('files', [])

    if not items:
        return {}
    else:
        return items

def delete_unnecessary_files(service,existing_files):
    '''
    3.Supprimez les fichiers de sauvegarde que vous n'avez plus besoin de conserver
    '''
    #Obtenez l'heure de création de chaque fichier et convertissez-le en objet datetime
    for f in existing_files:
        f['datetime_createdTime'] = datetime.datetime.strptime(f['createdTime'], '%Y-%m-%dT%H:%M:%S.%fZ')
    #Trier par date de création
    sorted_files = sorted(existing_files, key=lambda x: x['datetime_createdTime'])          
    delete_len = len(sorted_files) - (GENERATIONS - 1)
    for i in range(delete_len):
        service.files().delete(fileId=sorted_files[i]['id']).execute()

def create_zip_file():
    '''
    4.Enregistrez le dossier que vous souhaitez sauvegarder sous zip
    '''
    shutil.make_archive(DATA_DIR + DATA_NAME, 'zip', root_dir=DATA_DIR + DATA_NAME)

def upload_file(service):
    '''
    5.Téléverser un fichier
    '''
    today_str = datetime.datetime.now().strftime("%D").replace("/","-")
    file_metadata = {'name': today_str + '.zip','parents':[PARENT_ID]}
    media = MediaFileUpload(DATA_DIR + DATA_NAME + '.zip', mimetype='application/zip')
    results = service.files().create(body=file_metadata,media_body=media,fields='id').execute()

if __name__ == '__main__':
    main()

Description du code

1. Obtention des informations d'authentification

Pour la partie acquisition des informations d'authentification, le truc de Exemple officiel de l'API Google Drive est utilisé tel quel.

La première fois que vous l'exécutez, le navigateur s'ouvrira et demandera la permission de s'authentifier. Lorsque le flux d'authentification est terminé, les informations d'authentification seront enregistrées dans token.pickle, vous n'aurez donc pas besoin de vous authentifier avec le navigateur à partir de la prochaine fois.

2. Obtenez un fichier de sauvegarde existant

Récupérez le fichier déjà enregistré en tant que sauvegarde dans le dossier de Google Drive. Échantillon officiel de l'API Google Drive J'essaye d'obtenir les fichiers dans un dossier spécifique en modifiant légèrement la chose. Je vais.

3. Supprimez les fichiers de sauvegarde que vous n'avez plus besoin de conserver

Supprimez les fichiers inutiles pour que Google Drive ne se remplisse pas. Les données de fichier sur Google Drive acquises à l'étape précédente sont triées dans l'ordre de l'heure de téléchargement et la plus ancienne est supprimée.

4. Emballez le dossier de sauvegarde dans un zip

C'est vrai. J'utilise shututil.

5. Téléchargez le fichier

Téléchargez le fichier zip. En modifiant les métadonnées du fichier, j'essaye de le télécharger dans un dossier spécifique.

Au fait

Le script ci-dessus est automatiquement exécuté au démarrage du serveur

J'ai le script ci-dessus exécuté lorsque le serveur démarre. Il y a plusieurs façons de faire cela, mais j'ai utilisé cron. Plus précisément, j'ai écrit ce qui suit dans crontab.

@reboot python3 /home/minecraft/tools/backup.py

En ajoutant @ reboot, il sera exécuté au moment du démarrage.

Recommended Posts

Script pour sauvegarder les dossiers sur le serveur sur Google Drive
Envoyer un message du serveur à l'extension Chrome à l'aide de Google Cloud Messaging pour Chrome
Pour désactiver le cache du navigateur sur le serveur HTTP simple de Python
Enregistrer des images sur le Web sur un lecteur avec Python (Colab)
J'ai essayé de changer le script python de 2.7.11 à 3.6.0 sur Windows10
ls -R sur Google Drive
Comment configurer cron pour le scraping Python normal sur le serveur Sakura.
Remarque sur la façon de vérifier la connexion au port du serveur de licences
Le jour où Chainer fonctionne sur l'édition GPU CentOS (jusqu'au CPU)
La manière la plus polie d'utiliser le SDK Google Maps pour iOS
Paramètres à effectuer lors du démarrage du serveur Linux centos7
Script Python pour l'empreinte de KiCad-Pre-place presque selon la disposition du schéma de circuit
Héberger la bibliothèque réseau Mirror for Unity sur un serveur Linux
Téléchargez les images et vidéos contenues dans les tweets que vous avez aimés sur Twitter et téléchargez-les sur Google Drive
Remarques sur l'utilisation de matplotlib sur le serveur
Connectez-vous au VPN avec votre smartphone et éteignez / rallumez le serveur
Écrivain AtCoder J'ai écrit un script qui regroupe les concours pour chaque écrivain
Implémenté dans Dataflow pour copier la structure hiérarchique de Google Drive vers Google Cloud Storage