forked from barryclark/jekyll-now
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathupload_images.py
116 lines (95 loc) · 3.58 KB
/
upload_images.py
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
import glob
import re
import os
import subprocess
from concurrent.futures import ThreadPoolExecutor
from PIL import Image
import tempfile
GS_BUCKET = "slingalongblog-images"
THUMB_SIZE = 128
THUMB_SUFFIX = "_thumb"
tempdir = tempfile.gettempdir()
def upload_file(local_link):
file_path = local_link
if os.path.exists(file_path):
base_name = os.path.basename(file_path)
remote_link = '/'.join(["gs:/", GS_BUCKET, base_name])
public_url = f"https://storage.googleapis.com/{GS_BUCKET}/{base_name}"
print(f"Uploading {local_link} ({file_path}) -> {remote_link} ({public_url})")
try:
subprocess.check_call(['bash', '-c', f'gsutil cp -n "{file_path}" "{remote_link}"'])
except BaseException as e:
print(e)
return None
return public_url
def download_file(url):
filename = os.path.basename(url)
print(f'Downloading {url} -> {os.path.join(tempdir, filename)}')
try:
subprocess.check_call(['curl', '-O', url], cwd=tempdir)
return os.path.join(tempdir, filename)
except BaseException as e:
print(e)
return None
return public_url
def resize_thumbnail(local_link):
basename = os.path.basename(local_link)
basename_split = os.path.splitext(basename)
im = Image.open(local_link)
im = im.resize((THUMB_SIZE, THUMB_SIZE), Image.LANCZOS)
resized = os.path.join(tempdir, basename_split[0] + THUMB_SUFFIX + basename_split[1])
im.save(resized)
return resized
def process_image_links(text):
def _thunk(matchobj):
local_link = matchobj.group(2)
remote_url = upload_file(local_link)
if remote_url is None:
return matchobj.group(0)
else:
return f"{matchobj.group(1)}({remote_url})"
# local (i.e. not URLs) links in markdown, of kind ![description](/file.jpg)
return re.sub(r'(\!\[.*\])\(((?!https://|http://).*\..*)\)', _thunk, text)
def process_thumbnail_links(text):
def _thunk(matchobj):
local_link = matchobj.group(2)
remote_url = upload_file(resize_thumbnail(local_link))
if remote_url is None:
return matchobj.group(0)
else:
return f'thumbnail: "{remote_url}"'
# process local (i.e. not URLs) links in thumbnail, of kind 'thumbnail: "/file.jpg"'
return re.sub(r'(thumbnail: \")((?!https://|http://).*\..*)\"', _thunk, text)
def resize_thumbnail_links(text):
def _thunk(matchobj):
unresized = matchobj.group(1)
if THUMB_SUFFIX not in unresized:
local_link = download_file(unresized)
remote_url = upload_file(resize_thumbnail(local_link))
else:
remote_url = None
if remote_url is None:
return matchobj.group(0)
else:
return f'thumbnail: "{remote_url}"'
return re.sub(r'thumbnail: \"(https://.*\..*)\"', _thunk, text)
def remove_windows_line_endings(text_bytes):
return text_bytes.replace(b'\r\n', b'\n')
def upload_links(fname):
print(f'Processing file {fname}')
with open(fname, 'rb') as f:
text = f.read()
text = text.decode('utf-8')
new_text = process_image_links(text)
new_text = process_thumbnail_links(new_text)
new_text = resize_thumbnail_links(new_text)
with open(fname, 'wb') as f:
f.write(remove_windows_line_endings(new_text.encode('utf-8')))
def main():
fs = []
with ThreadPoolExecutor(max_workers=1) as tpe:
fs = [tpe.submit(upload_links, fname) for fname in glob.glob('_posts/*.md')]
for f in fs:
f.result()
if __name__ == '__main__':
main()