Ilia Sergachev | 5146335 | 2018-04-04 13:18:35 +0200 | [diff] [blame^] | 1 | import shutil |
| 2 | import pathlib |
| 3 | import os |
| 4 | import argparse |
| 5 | import hashlib |
| 6 | import pprint |
| 7 | import requests |
| 8 | |
| 9 | API_ENDPOINT = 'https://cloud-api.yandex.net/v1/disk/public/resources/{}?public_key={}' |
| 10 | |
| 11 | |
| 12 | def md5sum(filename): |
| 13 | md5 = hashlib.md5() |
| 14 | with open(filename, 'rb') as f: |
| 15 | for chunk in iter(lambda: f.read(128 * md5.block_size), b''): |
| 16 | md5.update(chunk) |
| 17 | return md5.hexdigest() |
| 18 | |
| 19 | |
| 20 | def check_and_download_file(url, path, size, checksum, dry): |
| 21 | if os.path.isfile(path): |
| 22 | if size == os.path.getsize(path): |
| 23 | if checksum == md5sum(path): |
| 24 | print('skipping correctly downloaded file {}'.format(path)) |
| 25 | return |
| 26 | if not dry: |
| 27 | print('downloading {}'.format(path)) |
| 28 | r = requests.get(url, stream=True) |
| 29 | with open(path, 'wb') as f: |
| 30 | shutil.copyfileobj(r.raw, f) |
| 31 | |
| 32 | |
| 33 | def download_directory(url, save_path, dry): |
| 34 | pathlib.Path(save_path).mkdir(parents=True, exist_ok=True) |
| 35 | items = requests.get(API_ENDPOINT.format('', url)).json()['_embedded']['items'] |
| 36 | for i in items: |
| 37 | # pprint.pprint(i) |
| 38 | new_path = os.path.join(save_path, i['name']) |
| 39 | if 'file' in i: |
| 40 | check_and_download_file(i['file'], new_path, i['size'], i['md5'], dry) |
| 41 | else: |
| 42 | print('entering folder {}'.format(new_path)) |
| 43 | download_directory(i['public_url'], new_path, dry) |
| 44 | |
| 45 | |
| 46 | parser = argparse.ArgumentParser(description='Yandex.Disk downloader.') |
| 47 | parser.add_argument('url') |
| 48 | parser.add_argument('-o', dest='output_path', default='output') |
| 49 | parser.add_argument('--dry', action='store_const', const=True, default=False) |
| 50 | args = parser.parse_args() |
| 51 | |
| 52 | download_directory(args.url, args.output_path, args.dry) |