import re import os import sys import argparse import time import base64 from operator import itemgetter from urllib.request import urlretrieve from PIL import Image # A sample from css # img[title='United States of \'Murica']{ # background: url(https://i.imgur.com/1uNEL8A.png)!important; # background-repeat: no-repeat !important; # width: 0px !important; # height: 17px !important; # padding-right: 24px # } EXTENSIONS = ( '.png', '.jpg', '.jpeg', ) BALLS_RE = re.compile(r"title='(.+)'\]{\nbackground: url\(([^\)]+)\)") RULE_TPL = r'''img[title="{country}"]{{ background: url(data:{format};base64,{contents})!important; background-repeat: no-repeat !important; width: 0px !important; height: {height}px !important; padding-right: {width}px }}''' def get_css_balls(css): """Get list of balls from css file.""" with open(css, 'r') as f: return BALLS_RE.findall(f.read()) def get_ball(dir_, name, url): """Get path to countryball file, download it if necessary.""" fname = os.path.join(dir_, '{}.png'.format(name)) if not os.path.exists(fname): # Stupid hack to fix Aruba if url == 'https://imgur.com/a/rIfuu': url = 'https://i.imgur.com/DdV6JKX.png' print('Downloading {} to {}'.format(url, fname)) urlretrieve(url, fname) time.sleep(1) # Don't ddos imgur pls return fname def get_dir_balls(dir_): """Load countryballs from directory.""" files = [] for fname in os.listdir(dir_): path = os.path.join(dir_, fname) if os.path.isfile(path): name, ext = os.path.splitext(fname) if ext not in EXTENSIONS: continue # Now extract file contents and sizes try: im = Image.open(path) except Exception as e: print("File {} couldn't be processed: {}".format( path, e )) continue image = dict(zip(('width', 'height'), im.size)) image.update({'format': Image.MIME[im.format], 'country': name}) with open(path, 'rb') as f: image['contents'] = base64.b64encode(f.read()).decode('utf-8') files.append(image) return sorted(files, key=itemgetter('country')) def output_css(files): """Get CSS for list of files.""" for f in files: f['country'] = f['country'].replace('"', '\"') yield RULE_TPL.format(**f) def main(): """Do the thing.""" parser = argparse.ArgumentParser( description='Get countryballs and create css with base64-encoded urls' ) parser.add_argument('--dir', required=True, help='directory where balls will located') parser.add_argument('--css', help='path to custom.css') args = parser.parse_args() if not os.path.exists(args.dir): print("Balls directory doesn't exist") sys.exit(1) # Download balls from css if needer if args.css: if not os.path.exists(args.css): print("CSS file doesn't exist") sys.exit(1) for country, url in get_css_balls(args.css): ball_path = get_ball(args.dir, country, url) print('{} -> {}'.format(country, ball_path)) # Process balls to create new CSS rules files = get_dir_balls(args.dir) for rule in output_css(files): print(rule) if __name__ == '__main__': main()