forget-cancellare-vecchi-toot/dodo.py

192 lines
5.8 KiB
Python
Raw Normal View History

from doit import create_after
2017-08-31 18:59:09 +02:00
from glob import glob
from itertools import chain
2017-08-29 14:46:32 +02:00
def reltouch(source_filename, dest_filename):
from os import stat, utime
stat_res = stat(source_filename)
utime(dest_filename, ns=(stat_res.st_atime_ns, stat_res.st_mtime_ns))
2017-08-29 14:46:32 +02:00
2017-08-29 21:27:38 +02:00
def resize_image(basename, width, image_format):
2017-08-11 14:57:32 +02:00
from PIL import Image
2017-08-24 15:39:11 +02:00
with Image.open('assets/{}.png'.format(basename)) as im:
2017-08-29 21:27:38 +02:00
if 'A' in im.getbands() and image_format != 'jpeg':
2017-08-24 15:39:11 +02:00
im = im.convert('RGBA')
else:
2017-08-20 20:17:38 +02:00
im = im.convert('RGB')
2017-08-24 15:39:11 +02:00
height = im.height * width // im.width
2017-08-29 14:46:32 +02:00
new = im.resize((width, height), resample=Image.LANCZOS)
2017-08-29 21:27:38 +02:00
if image_format == 'jpeg':
2017-08-24 15:39:11 +02:00
kwargs = dict(
2017-08-29 14:46:32 +02:00
optimize=True,
progressive=True,
quality=80,
2017-08-24 15:39:11 +02:00
)
2017-08-29 21:27:38 +02:00
elif image_format == 'webp':
2017-08-24 15:39:11 +02:00
kwargs = dict(
2017-08-29 14:46:32 +02:00
quality=79,
2017-08-24 15:39:11 +02:00
)
2017-08-29 21:27:38 +02:00
elif image_format == 'png':
2017-08-24 15:39:11 +02:00
kwargs = dict(
2017-08-29 14:46:32 +02:00
optimize=True,
2017-08-24 15:39:11 +02:00
)
2017-08-29 21:27:38 +02:00
new.save('static/{}-{}.{}'.format(basename, width, image_format),
**kwargs)
2017-08-29 14:46:32 +02:00
reltouch('assets/{}.png'.format(basename),
2017-08-29 21:27:38 +02:00
'static/{}-{}.{}'.format(basename, width, image_format))
2017-08-29 14:46:32 +02:00
2017-08-11 21:26:17 +02:00
def task_logotype():
"""resize and convert logotype"""
2017-08-11 21:26:17 +02:00
widths = (200, 400, 600, 800)
2017-08-29 21:27:38 +02:00
image_formats = ('jpeg', 'webp')
2017-08-11 21:26:17 +02:00
for width in widths:
2017-08-29 21:27:38 +02:00
for image_format in image_formats:
2017-08-20 20:17:38 +02:00
yield dict(
2017-08-29 21:27:38 +02:00
name='{}.{}'.format(width, image_format),
actions=[(resize_image,
('logotype', width, image_format))],
targets=[f'static/logotype-{width}.{image_format}'],
2017-08-20 20:17:38 +02:00
file_dep=['assets/logotype.png'],
clean=True,
)
2017-08-11 14:57:32 +02:00
2017-08-29 14:46:32 +02:00
def task_service_icon():
"""resize and convert service icons"""
2017-08-29 14:46:32 +02:00
widths = (20, 40, 80)
2017-08-24 15:39:11 +02:00
formats = ('webp', 'png')
for width in widths:
2017-08-29 21:27:38 +02:00
for image_format in formats:
2021-11-09 09:21:32 +01:00
for basename in ('twitter', 'mastodon', 'misskey'):
2017-08-24 15:39:11 +02:00
yield dict(
2017-08-29 21:27:38 +02:00
name='{}-{}.{}'.format(basename, width, image_format),
actions=[(resize_image, (basename, width, image_format))],
2017-08-29 14:46:32 +02:00
targets=[
2017-08-29 21:27:38 +02:00
'static/{}-{}.{}'.format(basename, width,
image_format)],
2017-08-24 15:39:11 +02:00
file_dep=['assets/{}.png'.format(basename)],
clean=True,
)
2017-08-11 14:57:32 +02:00
2017-08-29 14:46:32 +02:00
def task_copy():
"copy assets verbatim"
2017-08-31 18:59:09 +02:00
assets = ('icon.png', 'logotype.png')
def do_the_thing(src, dst):
from shutil import copy
copy(src, dst)
reltouch(src, dst)
2017-08-11 21:26:17 +02:00
for asset in assets:
src = 'assets/{}'.format(asset)
dst = 'static/{}'.format(asset)
2017-08-11 21:26:17 +02:00
yield dict(
name=asset,
actions=[(do_the_thing, (src, dst))],
2017-08-24 18:53:24 +02:00
targets=[dst],
file_dep=[src],
2017-08-11 21:26:17 +02:00
clean=True,
)
2017-08-11 16:41:31 +02:00
2017-08-29 14:46:32 +02:00
2017-08-11 16:41:31 +02:00
def task_minify_css():
"""minify css file with csscompressor"""
2017-08-11 16:41:31 +02:00
from csscompressor import compress
def minify():
with open('assets/styles.css') as in_:
with open('static/styles.css', 'w') as out:
out.write(compress(in_.read()))
reltouch('assets/styles.css', 'static/styles.css')
2017-08-11 16:41:31 +02:00
return dict(
actions=[minify],
targets=['static/styles.css'],
file_dep=['assets/styles.css'],
clean=True,
)
2017-08-11 16:41:31 +02:00
2017-08-29 14:46:32 +02:00
2017-08-31 18:59:09 +02:00
def task_rollup():
"""rollup javascript bundle"""
filenames = ['settings.js', 'instance_buttons.js']
2017-08-31 18:59:09 +02:00
for filename in filenames:
src = 'assets/{}'.format(filename)
dst = 'static/{}'.format(filename)
name = filename.split('.')[0]
2017-08-31 18:59:09 +02:00
yield dict(
name=filename,
file_dep=list(chain(
# fuck it
glob('assets/*.js'),
2018-10-06 00:55:11 +02:00
glob('components/*.html'))) + ['rollup.config.js'],
2017-08-31 18:59:09 +02:00
targets=[dst],
clean=True,
actions=[
['node_modules/.bin/rollup', '-c',
'-i', src, '-o', dst, '-n', name, '-f', 'iife'],
2017-08-31 18:59:09 +02:00
],
)
@create_after('logotype')
@create_after('service_icon')
@create_after('copy')
@create_after('minify_css')
2017-08-31 18:59:09 +02:00
@create_after('rollup')
def task_compress():
2017-08-29 14:46:32 +02:00
"""
make gzip and brotli compressed versions of each
static file for the server to lazily serve
"""
2017-08-20 20:17:38 +02:00
files = chain(
glob('static/*.css'),
glob('static/*.js'),
glob('static/*.jpeg'),
glob('static/*.png'),
glob('static/*.webp'),
)
def compress_brotli(filename):
import brotli
with open(filename, 'rb') as in_:
with open(filename + '.br', 'wb') as out:
out.write(brotli.compress(in_.read()))
reltouch(filename, filename+'.br')
2017-08-24 15:39:11 +02:00
def compress_gzip(filename):
import gzip
with open(filename, 'rb') as in_:
with gzip.open(filename + '.gz', 'wb') as out:
out.write(in_.read())
reltouch(filename, filename+'.gz')
for filename in files:
yield dict(
file_dep=(filename,),
targets=(filename+'.br',),
name=filename+'.br',
actions=[(compress_brotli, (filename,))],
clean=True,
)
yield dict(
file_dep=(filename,),
targets=(filename+'.gz',),
name=filename+'.gz',
actions=[(compress_gzip, (filename,))],
clean=True,
)
2017-08-29 14:46:32 +02:00
2017-08-11 14:57:32 +02:00
if __name__ == '__main__':
import doit
doit.run(globals())