-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAutomated-back-up-to-google-drive.py
109 lines (99 loc) · 3.93 KB
/
Automated-back-up-to-google-drive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#Automated Backup to Google Drive by Virginia Herrero
from pydrive.drive import GoogleDrive
from pydrive.auth import GoogleAuth
import os, shutil
from datetime import datetime
import schedule
#Paths
path_to_zip = r"C:/Users/Backup_Test_Folder"
path_to_archive_locally = r"C:/Users/Backups_Archive"
#Zip the folder to back up
def create_zip_folder(path_to_zip, folder_name):
""""
Function to create a zip folder.
Takes the path to the folder to back up (string) and the folder name (string).
Returns boolean: True if the zip is created, False if it is not.
"""
try:
shutil.make_archive(os.path.join(path_to_archive_locally, folder_name), "zip", path_to_zip)
return True
except FileNotFoundError as e:
return False
#Google Drive API authentication
def google_auth():
"""
Function to authenticate connection to google drive using the API.
To avoid authentication every time the script is run, the credentials are saved in 'my_credentials.txt' and called from there
to automatically authenticate the access to google drive.
Returns: gauth and drive
"""
gauth = GoogleAuth()
#Try to load the saved credentials from the first OAuth approval
gauth.LoadCredentialsFile("my_credentials.txt")
#If the app was not authenticated, it requests authentication from google
if gauth.credentials is None:
#Use local default browser for authentication
gauth.LocalWebserverAuth()
elif gauth.access_token_expired:
#Refresh credentials if token is expired
gauth.Refresh()
else:
#Initialize saved credentials
gauth.Authorize()
#Save current credentials to a text file
gauth.SaveCredentialsFile("my_credentials.txt")
drive = GoogleDrive(gauth)
return gauth, drive
#Upload folder to google drive
def upload_backup(drive, path_to_zip, folder_name):
"""
Function to upload the backup folder to google drive.
Takes: access to drive, path to the folder to back up (string), the name of the folder (string).
Returns: None
"""
#Create a google drive file instance
f = drive.CreateFile({"parents":[{"id": "1VpQA5BL2GxKs4jbrRk8GtF60MHIkJneA"}]})
f["title"] = folder_name
#Set the path to the zip file
f.SetContentFile(os.path.join(path_to_zip, folder_name))
#Upload the zip file
f.Upload()
#Set f to none because of a vulnerability found in PyDrive
f = None
#Remove old backups
def remove_old_backups(drive, path_to_zip, folder_name):
"""
Function to remove old backups.
Takes: access to drive, the path to the folder to back up (string), the name of the folder (string).
Returns: None
"""
for i in os.listdir(path_to_zip):
file_list = drive.ListFile({"q":"'1VpQA5BL2GxKs4jbrRk8GtF60MHIkJneA' in parents and trashed = False"}).GetList()
for file1 in file_list:
if file1["title"] < folder_name:
file1.Delete()
def main():
"""
Function to control the back up process.
* Set backup folder name with: Backup + date and time
* If the zip folder is not created, state why and stop the program
* Get access to google drive
* Upload zip file to google drive
"""
#Set machine date and time
now = datetime.now()
#Set backup folder name
folder_name = "Backup " + now.strftime(r"%d/%m/%Y %H:%M:%S").replace("/", "-").replace(":", " ")
#If zip creation fails, raise exception and stop the program
if not create_zip_folder(path_to_zip, folder_name):
raise Exception ("There was an error creating the zip file")
#Google Drive authentication
gauth, drive = google_auth()
#Upload zip file to google drive
upload_backup(drive, path_to_archive_locally, folder_name+".zip")
remove_old_backups(drive, path_to_zip, folder_name)
if __name__ == "__main__":
#Schedule backup every sunday at 00:00
schedule.every().sunday.at("00:00").do(main)
while True:
schedule.run_pending()