Use Netlify as a personal pomf / dropbox
#!/usr/bin/env python3 | |
""" | |
Usage: | |
pomflify.py inputfile [filename for url] | |
pomflify.py '~/Music/Empty streets.flac' "$(pwgen 6 1).flac" | |
Author: Alexander Pushkov <alexander@notpushk.in> | |
License: ISC (https://opensource.org/licenses/ISC) | |
""" | |
import os | |
import json | |
import hashlib | |
from urllib.parse import quote as urlquote | |
import requests | |
def parse_config(): | |
loc = os.path.expanduser("~/.config/pomflify.json") | |
try: | |
with open(loc) as f: | |
return json.load(f) | |
except: | |
print( | |
"Put this in ~/.config/pomflify.json:\n\n" + | |
json.dumps({ | |
"token": "(your token from Netlify)", | |
"site_id": "(domain or API ID of your Netlify site)" | |
}, indent=4) + | |
"\n" | |
) | |
raise | |
def url(cfg, path): | |
api_root = cfg.get("api_root", "https://api.netlify.com/api/v1/") | |
return f"{api_root}{path.lstrip('/')}?access_token={cfg['token']}" | |
def iter_file(f): | |
while True: | |
data = f.read(1024) | |
if not data: | |
break | |
yield data | |
def hash_file(f): | |
sha1 = hashlib.sha1() | |
for data in iter_file(f): | |
sha1.update(data) | |
f.seek(0) | |
return sha1.hexdigest() | |
def main(cfg, file_path, file_name=None): | |
if file_name is None: | |
file_name = os.path.basename(file_path).replace(" ", "_") | |
file_obj = open(file_path, "rb") | |
file_hash = hash_file(file_obj) | |
r = requests.get(url(cfg, f"sites/{cfg['site_id']}/files")) | |
if r.status_code in [404, 500]: | |
old_files = {} | |
else: | |
r.raise_for_status() | |
old_files = {f["id"]: f["sha"] for f in r.json()} | |
if f"/{file_name}" in old_files: | |
print(f"{file_name} already exists, aborting") | |
raise SystemExit | |
r = requests.post(url(cfg, f"sites/{cfg['site_id']}/deploys"), json={ | |
"files": { | |
**old_files, | |
f"/{file_name}": file_hash, | |
} | |
}) | |
r.raise_for_status() | |
deploy = r.json() | |
required = deploy["required"] | |
try: | |
required.remove(file_hash) | |
except ValueError: | |
print("File already on Netlify CDN") | |
else: | |
r = requests.put(url(cfg, f"deploys/{deploy['id']}/files/{urlquote(file_name)}"), headers={ | |
"Content-type": "application/octet-stream" | |
}, data=file_obj) | |
r.raise_for_status() | |
assert len(required) == 0 | |
print(f"{deploy['url']}/{urlquote(file_name)}") | |
if __name__ == '__main__': | |
import sys | |
main(parse_config(), *sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.