clark800 / dropbox-restore Goto Github PK
View Code? Open in Web Editor NEWRestore any dropbox folder to a previous state
License: The Unlicense
Restore any dropbox folder to a previous state
License: The Unlicense
Since dropbox uses UTC time for files, datetime.utcnow() should be used in the line below. For recent short term restores, the current comparison improperly states a UTC time is in the future if it is within the offset window for a negative offset. (e.g. I am in UTC -5, and was trying to restore files from one hour ago.)
if cutoff_datetime > datetime.now():
in restore_file, client.restore is called for all files, even if the latest version of the file is older than the cutoff_datetime. Checking if you try to restore the latest version would skip one API call, and thus make the restore faster (especially for a Dropbox with many files but only a few ones to restore).
For example, let's say file.txt
was modified last on 2013-01-04. When dropbox-restore is run for the cutoff_datetime 2013-08-06, then the latest revision of file.txt
is the one currently in the Dropbox, so a restore will change nothing.
I would suggest to add a check in restore_file
. If max modification date of revisions
is older than the cutoff_date it can return straight away.
i am trying to restore a folder on dropbox and using the modified script by Inamul so as to make it work with APIv2. But getting this error. Not really able to understand why this error is happening. If somebody can help or guide on how to fix this.
Traceback (most recent call last):
File "C:\Users\A3003\Desktop\restore.py", line 116, in
main()
File "C:\Users\A3003\Desktop\restore.py", line 112, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File "C:\Users\A3003\Desktop\restore.py", line 91, in restore_folder
restore_folder(client, item.path_lower, cutoff_datetime, verbose)
File "C:\Users\A3003\Desktop\restore.py", line 91, in restore_folder
restore_folder(client, item.path_lower, cutoff_datetime, verbose)
File "C:\Users\A3003\Desktop\restore.py", line 96, in restore_folder
False, verbose)
File "C:\Users\A3003\Desktop\restore.py", line 52, in restore_file
revisions = client.files_list_revisions(path.encode('utf8'))
File "C:\Python27\lib\site-packages\dropbox\base.py", line 842, in files_list_revisions
None,
File "C:\Python27\lib\site-packages\dropbox\dropbox.py", line 256, in request
user_message_locale)
dropbox.exceptions.ApiError: ApiError('57fdb68b14f6936763e44440edd3b5dc', ListRevisionsError(u'path', LookupError(u'not_file', None)))
Hello,
Thanks for a great script. With some files I get the following crash (file name replaced);
I have fixed this issue by surrounding like 67 with a try / except: pass block. Not sure if that is the best way to deal with that.
Traceback (most recent call last):
File "./restore.py", line 98, in
main()
File "./restore.py", line 94, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File "./restore.py", line 81, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File "./restore.py", line 81, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File "./restore.py", line 83, in restore_folder
restore_file(client, item['path'], cutoff_datetime, verbose)
File "./restore.py", line 67, in restore_file
client.file_delete(path)
File "/usr/local/lib/python2.7/dist-packages/dropbox/client.py", line 593, in file_delete
return self.rest_client.POST(url, params, headers)
File "/usr/local/lib/python2.7/dist-packages/dropbox/rest.py", line 259, in POST
return cls.IMPL.POST(_n, *_kw)
File "/usr/local/lib/python2.7/dist-packages/dropbox/rest.py", line 206, in POST
post_params=params, headers=headers, raw_response=raw_response)
File "/usr/local/lib/python2.7/dist-packages/dropbox/rest.py", line 182, in request
raise ErrorResponse(r)
dropbox.rest.ErrorResponse: [404] u"Path '/somepath/to/file' not found"
Suppose a file was added on 2013/03/01, deleted on 2013/03/05 and then restored on 2013/03/10.
What happens if I revert to 2013/03/06?
raw_input() on line 20 was renamed to input() in Python 3. I'm not very familiar with Python, but is there any way to make it work for Python 2.7 and 3+?
What if I need to restore files in root folder?
Is this script recursive? Can I use path "/" and recover everything in the entire dropbox?
If I follow your link for authorize my Dropbox, I receive a "no more users allowed".
Contact the developer, he need to put the application into production state.
But so far, your script looks great :-)
Just found your script and it would really help me out since a colleague had missunderstood how Dropbox works and just deleted about 2500 of our files. Though when I try to run it on one of the folder that were deleted it cannot find that folder. But it is there.
kalle$ ls -ld ~/Dropbox/Movinto\ Fun\ -\ event
drwxr-xr-x@ 17 kalle staff 578 Sep 24 22:06 /Users/kalle/Dropbox/Movinto Fun - event
Here is the trace I get from the script:
kalle$ python2.7 restore.py ~/Dropbox/Movinto\ Fun\ -\ event/ 2013-09-24
Restoring folder: /Users/kalle/Dropbox/Movinto Fun - event/
Traceback (most recent call last):
File "restore.py", line 83, in <module>
main()
File "restore.py", line 79, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File "restore.py", line 64, in restore_folder
folder = client.metadata(path, list=True, include_deleted=True)
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/client.py", line 730, in metadata
return self.rest_client.GET(url, headers)
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/rest.py", line 254, in GET
return cls.IMPL.GET(*n, **kw)
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/rest.py", line 198, in GET
return self.request("GET", url, headers=headers, raw_response=raw_response)
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/rest.py", line 182, in request
raise ErrorResponse(r)
dropbox.rest.ErrorResponse: [404] u"Path '/Users/kalle/Dropbox/Movinto Fun - event' not found"
$ python restore.py
Traceback (most recent call last):
File "restore.py", line 2, in
import sys, os, dropbox, time
ImportError: No module named dropbox
If you pass a date outside the users' retention window (default 30 days), local files are deleted instead of restored.
If the path for the folder name you want to restore have special characters, it doesn't find the folder, in my case i had a "í".
I get this error when restoring folder(s)
Traceback (most recent call last):
File ".\RestoreDropboxFolder.py", line 85, in
main()
File ".\RestoreDropboxFolder.py", line 81, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File ".\RestoreDropboxFolder.py", line 69, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File ".\RestoreDropboxFolder.py", line 69, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File ".\RestoreDropboxFolder.py", line 71, in restore_folder
restore_file(client, item['path'], cutoff_datetime, verbose)
File ".\RestoreDropboxFolder.py", line 55, in restore_file
print(path + ' ' + modtime)
TypeError: coercing to Unicode: need string or buffer, datetime.datetime found
Is repeatable so if you let me know what you need to fix it I am happy to provide info.
Hi,
I posted yesterday, however since then I had unlinked the HistoryRestore app. Well it turns out I am unable to re-allow the application. When I try to run the restore.py script, I get the following error:
[user@Server~]$ python restore.py /Tellus 2015-01-14
Restoring folder: /Folder
[401] u"The given OAuth 2 access token doesn't exist or has expired."
**Note: You must specify the path starting with "/", where "/" is the root**
of your dropbox folder. So if your dropbox directory is at "/home/user/dropbox"
and you want to restore "/home/user/dropbox/folder", the ROOTPATH is "/folder".
How do I reallow the the application if the Auth access token is expired?
When going to the authorization screen I get the following:
This app is in development mode and can't accept more users. Contact the app developer and ask them to use the Dropbox API App Console to apply for production status.
Dropbox just reminded me that APIv1 is deprecated. Did you look into how difficult it might be to port this indispensable script?
When restoring a deleted folder, the (re)created folder is in lower case letters regardless of original case.
This can create problems on case sensitive file systems such as ext4 used by Linux.
Could you add the hour of the day to the revert options?
After a bunch of files...
Traceback (most recent call last):
File "restore.py", line 103, in
main()
File "restore.py", line 99, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File "restore.py", line 87, in restore_folder
item.get('is_deleted', False), verbose)
File "restore.py", line 64, in restore_file
client.restore(path.encode('utf8'), rev)
File "/usr/local/lib/python2.7/dist-packages/dropbox/client.py", line 1072, in restore
return self.rest_client.POST(url, params, headers)
File "/usr/local/lib/python2.7/dist-packages/dropbox/rest.py", line 316, in POST
return cls.IMPL.POST(_n, *_kw)
File "/usr/local/lib/python2.7/dist-packages/dropbox/rest.py", line 254, in POST
post_params=params, headers=headers, raw_response=raw_response)
File "/usr/local/lib/python2.7/dist-packages/dropbox/rest.py", line 227, in request
raise ErrorResponse(r, r.read())
Only happened once, worked afterwards
This app is in development mode and cannot accept more users. Contact the app developer and ask them to use the Dropbox API App Console to apply for production status.
Please fix it.
Hi, I'm using your script, and I'm getting an error that others seem to have gotten in the past (when clicking on the authorization link): ""This app is in development mode and can't accept more users. [...]" I'm not sure though how to avoid this.
First of all thanks for this script, I'm a bit out of my comfort zone here :(
I've just run this and get the following error when I run the script
dropbox.rest.ErrorResponse: [404] u"Path '/Users/gavinwye/Dropbox/dir-name' not found"
While the script runs I get the following in the terminal
Traceback (most recent call last):
File "/Users/gavinwye/Documents/git/dropbox-restore/restore.py", line 83, in <module>
main()
File "/Users/gavinwye/Documents/git/dropbox-restore/restore.py", line 79, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File "/Users/gavinwye/Documents/git/dropbox-restore/restore.py", line 64, in restore_folder
folder = client.metadata(path, list=True, include_deleted=True)
File "/Library/Python/2.7/site-packages/dropbox/client.py", line 730, in metadata
return self.rest_client.GET(url, headers)
File "/Library/Python/2.7/site-packages/dropbox/rest.py", line 254, in GET
return cls.IMPL.GET(*n, **kw)
File "/Library/Python/2.7/site-packages/dropbox/rest.py", line 198, in GET
return self.request("GET", url, headers=headers, raw_response=raw_response)
File "/Library/Python/2.7/site-packages/dropbox/rest.py", line 182, in request
raise ErrorResponse(r)
The directory that I'm trying to recover has not been effected by the scrip any ideas what I'm doing wrong?
Thanks
Gavin
Hey there,
First of all, great idea! Second, I'm getting an error on attempting to run this...any workaround? See traceback below.
Best,
K
Enter the authorization code here: apAG3GgkHNEAAAAAAAAAARlQ2puqoEdW_CP9A27snOU
Traceback (most recent call last):
File "restore.py", line 94, in
main()
File "restore.py", line 89, in main
client = login('token.dat')
File "restore.py", line 30, in login
access_token = authorize()
File "restore.py", line 21, in authorize
access_token, user_id = flow.finish(code)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/client.py", line 1090, in finish
return self._finish(code, None)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/client.py", line 984, in _finish
response = self.rest_client.POST(url, params=params)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/rest.py", line 259, in POST
return cls.IMPL.POST(_n, *_kw)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/rest.py", line 206, in POST
post_params=params, headers=headers, raw_response=raw_response)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/dropbox/rest.py", line 182, in request
raise ErrorResponse(r)
dropbox.rest.ErrorResponse: [403] u'Only a limited set of users can receive access tokens while this app is in development mode'
First, thanks SO MUCH for this script. The first time I used it about a month ago, it was magic and it perfectly restored a Dropbox folder in its entirety without a hitch.
I have been trying to use it again, however, and I keep getting denied with this error message:
[401] u"The given OAuth 2 access token doesn't exist or has expired."
I'm not sure why my OAuth 2 token doesn't work any more (did I revoke it at some point maybe?), but according to the Dropbox documentation, I need to go back through the OAuth 2 authorization flow again. I cannot find a way to force the app to do that.
So, I either need to know how to clear out the OAuth 2 token that my system is expecting, or I need some way to force my script to put me back through the authorization flow.
If you could give me any help, that would be incredibly helpful!
Hi, I'm trying to run this on a mac 10.7.5, python 2.7
Traceback (most recent call last):
File "restore.py", line 2, in <module>
import sys, os, dropbox, time
ImportError: No module named dropbox
My initial thought was that I didn't have the the dropbox Python API but I checked that and:
Requirement already satisfied (use --upgrade to upgrade): dropbox in /usr/local/lib/python2.7/site-packages
Please not I have never coded and don't know python so if I'm just missing something extremely simple, please use STOOPID instructions so I can follow them. I never changed anything inside the restore.py I assumed all I needed was the:
python2.7 restore.py /folderA/insideFolder 2014-09-18
On the command line?
Thanks for any help
Hi Chris,
Thanks a lot for your powerful and useful script.
I have some troubles when trying to restore folders with extended characters, such as "éàèü..."
Here is what I get :
c:\Python27\Scripts>python restore.py /Sociétés/Cinéma/Diapositives 2016-03-23
Restoring folder: /SociÚtÚs/CinÚma/Diapositives
[404] u"Path '/Soci\xdat\xdas/Cin\xdama/Diapositives' not found"
Note: You must specify the path starting with "/", where "/" is the root
of your dropbox folder. So if your dropbox directory is at "/home/user/dropbox"
and you want to restore "/home/user/dropbox/folder", the ROOTPATH is "/folder".
And - of course - impossible to rename folder to a more "nice & easy" name. I will loose delete historic.
Thanks for your Idea / suggestions.
Jan
Tried to restore one folder, everything worked fine until
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Filters/Tiles.8BF 2
015-04-22 12:37:19
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Filters/Twirl.8BF 2
015-04-22 12:37:19
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Filters/VanishingPo
int.8BF 2015-04-22 12:37:19
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Filters/Wave.8BF 20
15-04-22 12:37:19
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Filters/Wind.8BF 20
15-04-22 12:37:19
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Filters/ZigZag.8BF
2015-04-22 12:37:19
Restoring folder: /work/tools/graphic/photoshopportable/app/photoshop/Plug-ins/I
mage Stacks
/work/tools/graphic/photoshopportable/app/photoshop/plug-ins/Image Stacks/statis
tics.8BA 2015-04-22 12:37:27
Traceback (most recent call last):
File "D:\restore.py", line 113, in <module>
main()
File "D:\restore.py", line 109, in main
restore_folder(client, root_path, cutoff_datetime, verbose=True)
File "D:\restore.py", line 90, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File "D:\restore.py", line 90, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File "D:\restore.py", line 90, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File "D:\restore.py", line 90, in restore_folder
restore_folder(client, item['path'], cutoff_datetime, verbose)
File "D:\restore.py", line 93, in restore_folder
item.get('is_deleted', False), verbose)
File "D:\restore.py", line 70, in restore_file
client.restore(path.encode('utf8'), rev)
File "C:\Python27\lib\site-packages\dropbox\client.py", line 1078, in restore
return self.rest_client.POST(url, params, headers)
File "C:\Python27\lib\site-packages\dropbox\rest.py", line 322, in POST
return cls.IMPL.POST(*n, **kw)
File "C:\Python27\lib\site-packages\dropbox\rest.py", line 260, in POST
is_json_request=is_json_request)
File "C:\Python27\lib\site-packages\dropbox\rest.py", line 235, in request
raise ErrorResponse(r, r.read())
dropbox.rest.ErrorResponse: [500] u'Internal Server Error'
D:\>
when i run the script as, and opens the url with my login info
i got:
"This app is in development mode and can't accept more users. Contact the app developer and ask them to use the Dropbox API App Console to apply for production status."
I'm on Windows, and I get some errors about the backslash character.
All goes fine when I replace the \ with a / in the base address of a simple folder, but I get errors when the folder has subfolders.
Could you fix this?
BTW for some reason I cannot place labels on tickets...
dropbox.rest.ErrorResponse: [404] u"Path XXXXXX not found
I worked round this by wrapping:
if item.get('is_dir', False):
restore_folder(client, item['path'], cutoff_datetime, verbose)
else:
restore_file(client, item['path'], cutoff_datetime,
item.get('is_deleted', False), verbose)
(lines 81 to 85)
in a try, catch block so that these files would be skipped and the restore continue.
The restoration seemed to complete successfully. However, I cannot find my restored files & folders in Dropbox (neither desktop nor on the web). What can be wrong here? Thanks.
Unable to authenticate with the following error:
This app is in development mode and can't accept more users. Contact the app developer and ask them to use the Dropbox API App Console to apply for production status
Is this the case or is there a different issue?
Thanks for your time
First I used Python 3.3, but it gave me a synthax error.
Then I used Python 2.7.5 and I got this error
Traceback (most recent call last):
File "restore.py", line 1, in
import sys, os, dropbox, time
ImportError: No module named dropbox
I get the following message from dropbox auth page:
This app is in development mode and can't accept more users. Contact the app developer and ask them to use the Dropbox API App Console to apply for production status.
Sorry for what is probably a silly mistake. Getting an attribute error (AttributeError: 'module' object has no attribute 'client') at the line: flow = dropbox.client.DropboxOAuth2FlowNoRedirect(APP_KEY, APP_SECRET)
First time doing this, so I used the APP_KEY and APP_SECRET from a randomly-named app I created ("in development" status). I already installed dropbox via pip. No other dropbox.py or anything like that sitting around. What's going on?
when i run the script as, and opens the url with my login info
python2.7 restore.py /FILENAME 2015-14-01
Go to: https://www.dropbox.com/1/oauth2/authorize?response_type=code&client_id=hacwza866qep9o6
Click "Allow" (you might have to log in first)
Copy the authorization code. Enter the authorization code here:
i got:
"This app is in development mode and can't accept more users. Contact the app developer and ask them to use the Dropbox API App Console to apply for production status."
Can you please reset it again? Thanks!!
Hi!
I did some changes that substantially improve performance on bigger shares and I couldn't see any regressions, so maybe it's a candidate for a cherry-pick (if you don't want the other changes in that branch):
Regards!
Tilman
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.