File size: 6,626 Bytes
88a42ac
 
ebd06cc
 
 
 
88a42ac
ebd06cc
 
88a42ac
aa80203
88a42ac
 
 
ebd06cc
 
 
 
 
 
4e1b239
ebd06cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e99c3d5
ebd06cc
 
 
 
 
71b8e1d
 
ebd06cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e99c3d5
ebd06cc
 
 
 
5d4719e
ebd06cc
 
 
 
 
 
e99c3d5
ebd06cc
 
3125f56
ebd06cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import datetime,logging
import logging.config
import time
import dropbox
from dropbox.files import WriteMode
from dropbox.exceptions import ApiError, AuthError
import sys,os,yaml
import baseInfra.firebase_handler as fbh

# Load the config file
with open('logging_config.yaml', 'rt') as f:
    config = yaml.safe_load(f.read())
logging.config.dictConfig(config)

TOKEN=fbh.fb_get("d2_accesstoken")
APP_KEY=os.environ['DROPBOX_APP_KEY']
APP_SECRET=os.environ['DROPBOX_APP_SECRET']
REFRESH_TOKEN=fbh.fb_get("d2_refreshtoken")

#os.environ['DROP_DIR2']="C:/dockers/chroma/chroma1/"
#os.environ['APP_PATH']="/"
#print("token::",TOKEN)

with dropbox.Dropbox(oauth2_access_token=TOKEN,app_key=APP_KEY,app_secret=APP_SECRET,oauth2_refresh_token=REFRESH_TOKEN) as dbx: #,app_key=APP_KEY,app_secret=APP_SECRET,oauth2_refresh_token=REFRESH_TOKEN) as dbx:
    # Check that the access token is valid
    try:
        dbx.users_get_current_account()
        if (TOKEN != dbx._oauth2_access_token):
            fbh.fb_update("d2_accesstoken",dbx._oauth2_access_token)
            TOKEN=dbx._oauth2_access_token
        print("dropbox connection ok,",dbx._oauth2_access_token)
        print(dbx._oauth2_refresh_token)
    except AuthError:
        try:
            dbx.check_and_refresh_access_token()
            fbh.fb_update("d2_accesstoken",dbx._oauth2_access_token)
            print("dropbox connection refreshed and updated",dbx._oauth2_access_token)
            print(dbx._oauth2_refresh_token)
        except Exception:
            sys.exit("ERROR: Invalid access token; try re-generating an "
                "access token from the app console on the web.")

def normalizeFilename(filename):
    while '//' in filename:
        filename = filename.replace('//', '/')
    return filename

def getDropboxFilename(localFilename):
    """ localFilename is $DROP_DIR2/<subpath>/<filename>"""
    """ dropboxFilename is $APP_PATH/<subpath>/<filename"""
    #if not localFilename.startswith(os.environ['DROP_DIR2']):
    #    localFilename=os.environ['DROP_DIR2']+localFilename
    localFilename=normalizeFilename(localFilename)
    return normalizeFilename(localFilename.replace(os.environ['DROP_DIR2'],"/",1).replace("/",os.environ['APP_PATH'],1))

def getLocalFilename(dropboxFilename):
    """ localFilename is $DROP_DIR2/<subpath>/<filename>"""
    """ dropboxFilename is $APP_PATH/<subpath>/<filename"""
    #if not dropboxFilename.startswith(os.environ['APP_PATH']):
    #    dropboxFilename=os.environ['APP_PATH']+dropboxFilename
    dropboxFilename=normalizeFilename(dropboxFilename)
    return normalizeFilename(dropboxFilename.replace(os.environ['APP_PATH'],"/",1).replace("/",os.environ['DROP_DIR2'],1))

async def backupFile(localFilename):
    """Upload a file.
    Return the request response, or None in case of error.
    This will also create directory on dropbox if needed
    """
    global TOKEN
    if not localFilename.startswith(os.environ['DROP_DIR2']):
        localFilename=os.environ['DROP_DIR2']+localFilename
    localFilename=normalizeFilename(localFilename) 
    dropboxFilename=getDropboxFilename(localFilename)
    print("backing file ",localFilename," to ",dropboxFilename)
    mode = dropbox.files.WriteMode.overwrite
    mtime = os.path.getmtime(localFilename)
    with open(localFilename, 'rb') as f:
        data = f.read()
    try:
        res = dbx.files_upload(
            data, dropboxFilename, mode,
            client_modified=datetime.datetime(*time.gmtime(mtime)[:6]),
            mute=True)
        if (TOKEN != dbx._oauth2_access_token):
            fbh.fb_update("d2_accesstoken",dbx._oauth2_access_token)
            TOKEN=dbx._oauth2_access_token
            print(dbx._oauth2_refresh_token)
    except dropbox.exceptions.ApiError as err:
        print('*** API error', err)
        return None
    print('uploaded as', res.name.encode('utf8'))
    return res

def restoreFile(dropboxFilename):
    """Download a file.
    Return the bytes of the file, or None if it doesn't exist.
    Will create dir+subdirs if possible
    """
    global TOKEN
    dropboxFilename=normalizeFilename(dropboxFilename)
    localFilename=getLocalFilename(dropboxFilename)
    print("restoring file ",localFilename," from ",dropboxFilename)
    try:
        md, res = dbx.files_download(dropboxFilename)
        if (TOKEN != dbx._oauth2_access_token):
            fbh.fb_update("d2_accesstoken",dbx._oauth2_access_token)
            TOKEN=dbx._oauth2_access_token
            print(dbx._oauth2_refresh_token)
    except dropbox.exceptions.HttpError as err:
        print('*** HTTP error', err)
        return None
    data = res.content
    print(len(data), 'bytes; md:', md)
    localdir=os.path.dirname(localFilename)
    if not os.path.exists(localdir):
        os.makedirs(localdir)
    with open(localFilename, 'wb') as f:
        f.write(data)
    return data

async def backupFolder(localFolder):
    """ list all files in folder and subfolder and upload them"""
    print("backup folder called for ",localFolder)
    if not localFolder.startswith(os.environ['DROP_DIR2']):
        localFolder=os.environ['DROP_DIR2']+localFolder
    print("Local folder is ",localFolder)
    filenames=[]
    for (root,dirs,files) in os.walk(localFolder, topdown=True):
        print(root)
        for filename in files:
            filenames.append(root+"/"+filename)
            print(root+"/"+filename)
            await backupFile(root+"/"+filename)


async def restoreFolder(dropboxFolder):
    """ list all files in dropbox folder and subfolders and restore them"""
    global TOKEN
    if not dropboxFolder.startswith(os.environ['APP_PATH']):
        dropboxFolder=os.environ['APP_PATH']+dropboxFolder
    try:
        res=dbx.files_list_folder(dropboxFolder)
        if (TOKEN != dbx._oauth2_access_token):
            fbh.fb_update("d2_accesstoken",dbx._oauth2_access_token)
            TOKEN=dbx._oauth2_access_token
            print(dbx._oauth2_refresh_token)
    except dropbox.exceptions.ApiError as err:
        print('Folder listing failed for', dropboxFolder, '-- assumed empty:', err)
        return
    except dropbox.exceptions.AuthError as err1:
        print('Folder listing failed for', dropboxFolder, '-- assumed empty:', err1)
        return
    for entry in res.entries:
        if (isinstance(entry, dropbox.files.FileMetadata)):
            restoreFile(entry.path_display)
        else:
            try:
                restoreFolder(entry.path_display)
            except Exception:
                print("Error restoring folder,",entry.path_display)
        print(entry.path_display)