#!/usr/bin/env python3 import os import sys import subprocess import json import requests import re from PIL import Image import time # Standard in/out dirs img_dir = '/svn/project-logos/originals' out_dir = '/var/www/logos/site/res' force = False if len(sys.argv) > 2: img_dir = sys.argv[1] out_dir = sys.argv[2] if len(sys.argv) > 3 and sys.argv[3] == 'force': force = True # svn up before processing subprocess.check_output(('/usr/bin/svn', 'up', img_dir)) # Gather all images to process files = [x for x in os.listdir(img_dir) if os.path.isfile(os.path.join(img_dir, x))] # Get all projects, committees, podlings cmts = requests.get('https://whimsy.apache.org/public/committee-info.json').json() pods = requests.get('https://whimsy.apache.org/public/public_podlings.json').json() projs = requests.get('https://projects.apache.org/json/foundation/projects.json').json() # Churn out a big json blob of projects projects = {} for k, cmt in cmts['committees'].items(): k = k.replace('-', '') if k == 'httpcomponents': k = 'hc' el = { 'name': cmt['display_name'], 'established': cmt['established'], 'description': cmt['description'], 'website': cmt['site'], 'podling': False, 'has_default': False, 'images': [] } projects[k] = el for k, cmt in pods['podling'].items(): k = k.replace('-', '') el = { 'name': cmt['name'], 'established': cmt['startdate'], 'description': cmt['description'], 'website': "https://%s.apache.org/" % k, 'podling': True, 'has_default': False, 'images': [] } if cmt['status'] == "current" and k not in projects: projects[k] = el for k, cmt in projs.items(): if k.startswith("attic-"): # Skip attic'ed projects continue k = k.replace('-', '') el = { 'name': cmt['name'].replace('Apache ', ''), 'established': cmt.get('created', 'Sub project of %s' % cmt['pmc']), 'description': cmt.get('description', 'No description available'), 'website': cmt.get('homepage', 'https://www.apache.org/'), 'podling': False, 'has_default': False, 'images': [] } if k not in projects: k = re.sub(r"_.+", "", k) projects[k] = el # Add foundation as a project projects['foundation'] = { 'name': 'Software Foundation', 'established': '1999-03', 'description': 'Foundation logo', 'website': "https://www.apache.org/", 'podling': False, 'has_default': False, 'images': [] } # Prep montage for execution later montage = ['/usr/bin/montage', '-geometry', '200x150+4+4', '-tile', '20x'] montage_tlps = ['/usr/bin/montage', '-geometry', '200x150+4+4', '-tile', '20x'] montage_large = ['/usr/bin/montage', '-geometry', '1200x600+20+20', '-tile', '8x'] montage_wide = ['/usr/bin/montage', '-geometry', '1200x600+20+20', '-tile', '15x'] # Process each file... for file in files: m = re.match(r"^([^.-]+).*?\.(.+)$", file) project = m.group(1) if project not in projects: for k in projects: if k.endswith("-%s" % project): project = k break if project not in projects: continue ext = m.group(2) oext = ext opath = file fpath = '%s/%s' % (img_dir, file) st = os.stat(fpath) skipit = False if st.st_mtime < (time.time() - 4200) and os.path.exists('%s/%s/default.png' % (out_dir, project)) and not force: print("Skipping %s" % fpath) skipit = True # EPS should be converted to PDF first, or inkscape borks :/ if ext == 'eps': xfile = file.replace('.'+ext, '') if not skipit and not os.path.exists('%s/%s.pdf' % (img_dir, xfile)): subprocess.check_output(('ps2pdf', '-dPDFSETTINGS=/prepress', '-dEPSCrop', '%s/%s' % (img_dir, file), '%s/pdftmp/%s.pdf' % (img_dir, xfile))) ext = 'pdf' file = 'pdftmp/' + xfile + '.pdf' # Scalable formats if ext in ['svg', 'ai', 'pdf', 'png']: print("Converting %s to PNG/PDF" % file) xfile = file.replace('.'+ext, '').replace('pdftmp/', '') ppath = "%s/%s" % (out_dir, project) if not os.path.isdir(ppath): os.mkdir(ppath) try: if xfile == project or xfile == '%s-1' % project: if not skipit: subprocess.check_output(('inkscape', '-z', '%s/%s' % (img_dir, file), '-e', '%s/%s/default.png' % (out_dir, project), '-w', '720')) subprocess.check_output(('inkscape', '-z', '%s/%s' % (img_dir, file), '-e', '%s/%s/default_hr.png' % (out_dir, project), '-w', '1200')) projects[project]['has_default'] = True except: pass # PNG, normal res if xfile == project or xfile == '%s-1' % project: if project != 'foundation': montage_large.append('%s/%s/%s.png' % (out_dir, project, xfile)) montage_wide.append('%s/%s/%s.png' % (out_dir, project, xfile)) try: if not skipit: subprocess.check_output(('inkscape', '-z', '%s/%s' % (img_dir, file), '-e', '%s/%s/%s.png' % (out_dir, project, xfile), '-w', '1200')) im = Image.open('%s/%s/%s.png' % (out_dir, project, xfile)) w = im.width h = im.height projects[project]['images'].append({'opath': opath, 'original': xfile, 'name': '%s' % xfile, 'filename': '%s/%s.png' % (project, xfile), 'format': 'png', 'width': w, 'height': h}) except: pass # PNG, high res try: if not skipit: subprocess.check_output(('inkscape', '-z', '%s/%s' % (img_dir, file), '-e', '%s/%s/%s_highres.png' % (out_dir, project, xfile), '-w', '3600')) im = Image.open('%s/%s/%s_highres.png' % (out_dir, project, xfile)) w = im.width h = im.height projects[project]['images'].append({'opath': opath, 'original': xfile, 'name': '%s (high res)' % xfile, 'filename': '%s/%s_highres.png' % (project, xfile), 'format': 'png', 'width': w, 'height': h}) except: pass try: if not skipit: subprocess.check_output(('inkscape', '-z', '%s/%s' % (img_dir, file), '-A', '%s/%s/%s.pdf' % (out_dir, project, xfile), '-w', '1200')) projects[project]['images'].append({'opath': opath, 'original': xfile, 'name': xfile, 'filename': '%s/%s.pdf' % (project, xfile), 'format': 'pdf'}) except: pass with open("%s/logos.json" % out_dir, "w") as f: json.dump(projects, f, indent = 2) for project in projects: xp = '%s/%s/default.png' % (out_dir, project) if os.path.exists(xp): if project != 'foundation': montage.append(xp) if not projects[project]['podling']: montage_tlps.append(xp) montage.append('%s../montages/standard.png' % out_dir) montage_tlps.append('%s../montages/standard_tlps_only.png' % out_dir) montage_large.append('%s../montages/highres_tall.png' % out_dir) montage_wide.append('%s../montages/highres_wide.png' % out_dir) # Only make new montages every 12 hours try: st = os.stat('%s../montages/standard.png' % out_dir) except: st = None if (not st) or st.st_mtime < (time.time() - 43200): print("Making montage...") subprocess.check_output(montage) subprocess.check_output(montage_tlps) print("Making montage (high res, tall)...") subprocess.check_output(montage_large) print("Making montage (high res, wide)...") subprocess.check_output(montage_wide) else: print("Skipping montages...") print("The following TLPs are currently not represented: ") for k, cmt in cmts['committees'].items(): k = k.replace('-', '') if not projects.get(k): continue if len(projects[k]['images']) == 0: print(k)