121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Compare desktop/mobile shots of all themes from publik-base-theme.
|
|
#
|
|
# Usage:
|
|
# --input1-directory -- directory to find version 1 screenshots
|
|
# --input2-directory -- directory to find version 2 screenshots
|
|
# --output-directory DIRECTORY -- directory to store comparison results, defaults to results/
|
|
# --overlay OVERLAY -- limit to given overlay ("none" to exclude overlays)
|
|
# --theme THEME -- theme to shot (substring match)
|
|
#
|
|
# Example:
|
|
# hobo-manage tenant_command runscript compare_them_all.py -d hobo.fred.local.0d.be
|
|
#
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
from hobo.theme.utils import get_themes
|
|
from django.template import Template, Context
|
|
from PIL import Image, ImageDraw
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--input1-directory', dest='input1_directory', type=str, required=True)
|
|
parser.add_argument('--input2-directory', dest='input2_directory', type=str, required=True)
|
|
parser.add_argument('--output-directory', dest='output_directory', type=str, default='results')
|
|
parser.add_argument('--overlay', dest='overlay', type=str, default='none')
|
|
parser.add_argument('--theme', dest='theme', type=str)
|
|
args = parser.parse_args()
|
|
|
|
if not os.path.exists(args.output_directory):
|
|
os.mkdir(args.output_directory)
|
|
|
|
|
|
result = []
|
|
|
|
for theme in get_themes():
|
|
theme_id = theme['id']
|
|
if args.overlay == 'all':
|
|
pass
|
|
elif args.overlay == 'none' and not theme.get('overlay'):
|
|
pass
|
|
elif args.overlay == theme.get('overlay'):
|
|
pass
|
|
else:
|
|
continue
|
|
if args.theme and args.theme not in theme['id']:
|
|
continue
|
|
sys.stderr.write("%-25s" % theme_id)
|
|
shots = [
|
|
'desktop',
|
|
'mobile',
|
|
'mobile-horizontal',
|
|
]
|
|
|
|
def process_region(image, x, y, width, height):
|
|
region_total = 0
|
|
# This can be used as the sensitivity factor, the larger it is the less sensitive the comparison
|
|
factor = 100
|
|
for coordinate_y in range(y, y + height):
|
|
for coordinate_x in range(x, x + width):
|
|
try:
|
|
pixel = image.getpixel((coordinate_x, coordinate_y))
|
|
region_total += sum(pixel) / 4
|
|
except Exception:
|
|
return
|
|
return region_total / factor
|
|
|
|
theme_data = {
|
|
'label': theme['label'],
|
|
'shots': [],
|
|
}
|
|
|
|
for shot in shots:
|
|
filepath_1 = os.path.join(args.input1_directory, '%s-%s.png' % (theme_id, shot))
|
|
filepath_2 = os.path.join(args.input2_directory, '%s-%s.png' % (theme_id, shot))
|
|
filepath_output = os.path.join(args.output_directory, '%s-%s.png' % (theme_id, shot))
|
|
try:
|
|
screenshot_1 = Image.open(filepath_1)
|
|
screenshot_2 = Image.open(filepath_2)
|
|
except FileNotFoundError:
|
|
continue
|
|
width, height = screenshot_1.size
|
|
|
|
columns = 60
|
|
rows = 80
|
|
screen_width, screen_height = screenshot_1.size
|
|
|
|
block_width = ((screen_width - 1) // columns) + 1
|
|
block_height = ((screen_height - 1) // rows) + 1
|
|
|
|
for y in range(0, screen_height, block_height + 1):
|
|
for x in range(0, screen_width, block_width + 1):
|
|
region_1 = process_region(screenshot_1, x, y, block_width, block_height)
|
|
region_2 = process_region(screenshot_2, x, y, block_width, block_height)
|
|
|
|
if region_1 is not None and region_2 is not None and region_1 != region_2:
|
|
draw = ImageDraw.Draw(screenshot_1)
|
|
draw.rectangle((x, y, x + block_width, y + block_height), outline="red")
|
|
|
|
screenshot_1.save(filepath_output)
|
|
theme_data['shots'].append({
|
|
'label': shot,
|
|
'width': width,
|
|
'height': height,
|
|
'before': '../%s' % filepath_1,
|
|
'after': '../%s' % filepath_2,
|
|
'diff': '../%s' % filepath_output,
|
|
})
|
|
result.append(theme_data)
|
|
|
|
sys.stderr.write(u'\n')
|
|
|
|
with open('index_template.html', 'r') as f:
|
|
template = Template(f.read())
|
|
context = Context({'themes': result})
|
|
html = template.render(context)
|
|
|
|
with open(os.path.join(args.output_directory, 'index.html'), 'w') as f:
|
|
f.write(html)
|