mirror of
http://git.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/nihilist/blog-contributions.git
synced 2025-05-17 04:07:17 +00:00
63 lines
2 KiB
Python
63 lines
2 KiB
Python
#!/usr/bin/python3
|
|
|
|
# requires imagemagick, avifenc, svt-av1
|
|
|
|
import os
|
|
import subprocess
|
|
import concurrent.futures
|
|
|
|
# below this threshold, it won't be compressed with avif
|
|
MIN_FILE_SIZE = 30000
|
|
|
|
def detect_compressible(fpath):
|
|
mimetype = subprocess.check_output(["file", "--mime-type", "-b", fpath]).strip().decode('utf-8')
|
|
|
|
if mimetype in ('image/png', 'image/jpeg'):
|
|
return True
|
|
|
|
if mimetype == 'image/webp':
|
|
fileout = subprocess.check_output(["file", fpath]).decode('utf-8')
|
|
if 'lossless' in fileout:
|
|
return True
|
|
|
|
return False
|
|
|
|
def compress(fpath):
|
|
rtpath = '/tmp/'+os.urandom(4).hex()+'.png'
|
|
subprocess.run(["magick", fpath, rtpath])
|
|
subprocess.run(["avifenc", rtpath, "--yuv", "420", "--range", "l", "-q", "50", "-c", "svt", "-j", "1", "--speed", "0", "--ignore-exif", "-o", fpath])
|
|
try:
|
|
os.remove(rtpath)
|
|
except:
|
|
pass
|
|
|
|
def process_files_in_directory(directory):
|
|
compressible_files = []
|
|
|
|
for root, _, files in os.walk(directory):
|
|
for fi in files:
|
|
full_path = os.path.join(root, fi)
|
|
print(f"Checking file: {full_path}")
|
|
if os.path.getsize(full_path) < MIN_FILE_SIZE:
|
|
continue
|
|
if detect_compressible(full_path):
|
|
compressible_files.append(full_path)
|
|
|
|
return compressible_files
|
|
|
|
def main(directory, max_workers):
|
|
compressible_files = process_files_in_directory(directory)
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
futures = {executor.submit(compress, fpath): fpath for fpath in compressible_files}
|
|
|
|
for future in concurrent.futures.as_completed(futures):
|
|
fpath = futures[future]
|
|
try:
|
|
future.result()
|
|
print(f"Successfully compressed: {fpath}")
|
|
except Exception as exc:
|
|
print(f"Compression failed for {fpath}: {exc}")
|
|
|
|
if __name__ == "__main__":
|
|
main('../docs/', max_workers=32)
|