Full Code of clark800/dropbox-restore for AI

master 6bd43b38f4c8 cached
4 files
7.3 KB
1.8k tokens
6 symbols
1 requests
Download .txt
Repository: clark800/dropbox-restore
Branch: master
Commit: 6bd43b38f4c8
Files: 4
Total size: 7.3 KB

Directory structure:
gitextract_pmzq5jn_/

├── .gitignore
├── LICENSE
├── README.md
└── restore.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
token.dat
*.py[cod]
*.swp
*.swo
*~


================================================
FILE: LICENSE
================================================
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org/>


================================================
FILE: README.md
================================================
dropbox-restore
===============

### 📣 I no longer use Dropbox so I can't maintain this script. If you would like to be the maintainer, you can create a pull request that updates to the latest API and I will grant you collaborator access so you can manage the project (if the pull request passes a code review). The pull request should preserve all the former functionality and update to the latest API and not make any other changes.

_**The Dropbox API changed and this script no longer works; you can try using https://github.com/clark800/dropbox-restore/pull/48 though it does not restore to the exact previous state**_

Restore any dropbox folder to a previous state. If a file did not exist at the specified time, it will be deleted.

Example
-------
To restore the folder "/photos/nyc" to the way it was on March 9th, 2013:

    python2.7 restore.py /photos/nyc 2013-03-09
    
Note that the path "/photos/nyc" should be relative to your Dropbox folder; it should not include the path to the Dropbox folder on your hard drive. You will be prompted to confirm access to your Dropbox account through your web browser.

Installation
------------
1. Obtain Dropbox APP\_KEY and APP\_SECRET by creating a Dropbox App: https://www.dropbox.com/developers/apps/create
2. Make sure that Python 2.7 and pip are installed. 
3. Then install the Dropbox Python API with the following command.

    sudo pip install dropbox

4. Download restore.py from Github
5. Insert APP\_KEY and APP\_SECRET at the top of restore.py

Time
----
Specifying a time is not officially supported because the time zone is ignored currently. However, it seems like Dropbox always uses UTC, so you can try specifying UTC times at your own risk by specifying the date and time in the format YYYY-MM-DD-HH-MM-SS on the command line. Be warned that Dropbox's documentation does not guarantee that they will always use UTC, so this can break at any time.

Donations
---------
If you would like to make a donation, you can use the PayPal button on my website: http://cclark.me


================================================
FILE: restore.py
================================================
#!/usr/bin/env python
import sys, os, dropbox, time
from datetime import datetime

APP_KEY = 'hacwza866qep9o6'   # INSERT APP_KEY HERE
APP_SECRET = 'kgipko61g58n6uc'     # INSERT APP_SECRET HERE
DELAY = 0.2 # delay between each file (try to stay under API rate limits)

HELP_MESSAGE = \
"""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".
"""

HISTORY_WARNING = \
"""Dropbox only keeps historical file versions for 30 days (unless you have
enabled extended version history). Please specify a cutoff date within the past
30 days, or if you have extended version history, you may remove this check
from the source code."""

def authorize():
    flow = dropbox.client.DropboxOAuth2FlowNoRedirect(APP_KEY, APP_SECRET)
    authorize_url = flow.start()
    print('1. Go to: ' + authorize_url)
    print('2. Click "Allow" (you might have to log in first)')
    print('3. Copy the authorization code.')
    try:
        input = raw_input
    except NameError:
        pass
    code = input("Enter the authorization code here: ").strip()
    access_token, user_id = flow.finish(code)
    return access_token


def login(token_save_path):
    if os.path.exists(token_save_path):
        with open(token_save_path) as token_file:
            access_token = token_file.read()
    else:
        access_token = authorize()
        with open(token_save_path, 'w') as token_file:
            token_file.write(access_token)
    return dropbox.client.DropboxClient(access_token)


def parse_date(s):
    a = s.split('+')[0].strip()
    return datetime.strptime(a, '%a, %d %b %Y %H:%M:%S')


def restore_file(client, path, cutoff_datetime, is_deleted, verbose=False):
    revisions = client.revisions(path.encode('utf8'))
    revision_dict = dict((parse_date(r['modified']), r) for r in revisions)

    # skip if current revision is the same as it was at the cutoff
    if max(revision_dict.keys()) < cutoff_datetime:
        if verbose:
            print(path.encode('utf8') + ' SKIP')
        return

    # look for the most recent revision before the cutoff
    pre_cutoff_modtimes = [d for d in revision_dict.keys()
                           if d < cutoff_datetime]
    if len(pre_cutoff_modtimes) > 0:
        modtime = max(pre_cutoff_modtimes)
        rev = revision_dict[modtime]['rev']
        if verbose:
            print(path.encode('utf8') + ' ' + str(modtime))
        client.restore(path.encode('utf8'), rev)
    else:   # there were no revisions before the cutoff, so delete
        if verbose:
            print(path.encode('utf8') + ' ' + ('SKIP' if is_deleted else 'DELETE'))
        if not is_deleted:
            client.file_delete(path.encode('utf8'))


def restore_folder(client, path, cutoff_datetime, verbose=False):
    if verbose:
        print('Restoring folder: ' + path.encode('utf8'))
    try:
        folder = client.metadata(path.encode('utf8'), list=True,
                                 include_deleted=True)
    except dropbox.rest.ErrorResponse as e:
        print(str(e))
        print(HELP_MESSAGE)
        return
    for item in folder.get('contents', []):
        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)
        time.sleep(DELAY)


def main():
    if len(sys.argv) != 3:
        usage = 'usage: {0} ROOTPATH YYYY-MM-DD\n{1}'
        sys.exit(usage.format(sys.argv[0], HELP_MESSAGE))
    root_path_encoded, cutoff = sys.argv[1:]
    root_path = root_path_encoded.decode(sys.stdin.encoding)
    cutoff_datetime = datetime(*map(int, cutoff.split('-')))
    if (datetime.utcnow() - cutoff_datetime).days >= 30:
        sys.exit(HISTORY_WARNING)
    if cutoff_datetime > datetime.utcnow():
        sys.exit('Cutoff date must be in the past')
    client = login('token.dat')
    restore_folder(client, root_path, cutoff_datetime, verbose=True)


if __name__ == '__main__':
    main()
Download .txt
gitextract_pmzq5jn_/

├── .gitignore
├── LICENSE
├── README.md
└── restore.py
Download .txt
SYMBOL INDEX (6 symbols across 1 files)

FILE: restore.py
  function authorize (line 21) | def authorize():
  function login (line 36) | def login(token_save_path):
  function parse_date (line 47) | def parse_date(s):
  function restore_file (line 52) | def restore_file(client, path, cutoff_datetime, is_deleted, verbose=False):
  function restore_folder (line 78) | def restore_folder(client, path, cutoff_datetime, verbose=False):
  function main (line 97) | def main():
Condensed preview — 4 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8K chars).
[
  {
    "path": ".gitignore",
    "chars": 35,
    "preview": "token.dat\n*.py[cod]\n*.swp\n*.swo\n*~\n"
  },
  {
    "path": "LICENSE",
    "chars": 1211,
    "preview": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, c"
  },
  {
    "path": "README.md",
    "chars": 2043,
    "preview": "dropbox-restore\n===============\n\n### 📣 I no longer use Dropbox so I can't maintain this script. If you would like to be "
  },
  {
    "path": "restore.py",
    "chars": 4193,
    "preview": "#!/usr/bin/env python\nimport sys, os, dropbox, time\nfrom datetime import datetime\n\nAPP_KEY = 'hacwza866qep9o6'   # INSER"
  }
]

About this extraction

This page contains the full source code of the clark800/dropbox-restore GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 4 files (7.3 KB), approximately 1.8k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!