diff --git a/generate_emoji_thumbnails.py b/generate_emoji_thumbnails.py new file mode 100755 index 000000000..f66fa6a3a --- /dev/null +++ b/generate_emoji_thumbnails.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# Copyright 2017 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate 72x72 thumbnails including aliases. + +Takes a source directory of images named using our emoji filename +conventions and writes thumbnails of them into the destination +directory. If a file is a target of one or more aliases, creates +copies named for the aliases.""" + + +import argparse +import collections +import logging +import os +from os import path +import shutil +import subprocess + +import add_aliases + +from nototools import tool_utils + +logger = logging.getLogger('emoji_thumbnails') + +def create_thumbnail(src_path, dst_path): + # uses imagemagik + subprocess.check_call(['convert', '-resize', '72x72', src_path, dst_path]) + logger.info('wrote thumbnail: %s' % dst_path) + + +_INV_ALIASES = None +def get_inv_aliases(): + global _INV_ALIASES + if _INV_ALIASES is None: + aliases = add_aliases.read_default_emoji_aliases() + inv_aliases = collections.defaultdict(list) + for k, v in aliases.iteritems(): + inv_aliases[v].append(k) + _INV_ALIASES = inv_aliases + return _INV_ALIASES + + +def is_emoji_filename(filename): + return filename.startswith('emoji_u') and filename.endswith('.png') + + +def check_emoji_filename(filename): + if not is_emoji_filename(filename): + raise ValueError('not an emoji image file: %s' % filename) + + +def emoji_filename_to_sequence(filename): + check_emoji_filename(filename) + + return tuple([ + int(s, 16) for s in filename[7:-4].split('_') + if s.lower() != 'fe0f']) + + +def sequence_to_emoji_filename(seq): + return 'emoji_u%s.png' % '_'.join('%04x' % n for n in seq) + + +def create_emoji_alias(src_path, dst_dir): + """If src_path is a target of any emoji aliases, create a copy in dst_dir + named for each alias.""" + src_file = path.basename(src_path) + seq = emoji_filename_to_sequence(src_file) + + inv_aliases = get_inv_aliases() + if seq in inv_aliases: + for alias_seq in inv_aliases[seq]: + alias_file = sequence_to_emoji_filename(alias_seq) + shutil.copy2(src_path, path.join(dst_dir, alias_file)) + logger.info('wrote alias %s (copy of %s)' % (alias_file, src_file)) + + +def create_thumbnails_and_aliases(src_dir, dst_dir): + if not path.isdir(src_dir): + raise ValueError('"%s" is not a directory') + dst_dir = tool_utils.ensure_dir_exists(dst_dir) + + for f in os.listdir(src_dir): + if not (f.startswith('emoji_u') and f.endswith('.png')): + logger.warning('skipping "%s"' % f) + continue + src = path.join(src_dir, f) + dst = path.join(dst_dir, f) + create_thumbnail(src, dst) + create_emoji_alias(dst, dst_dir) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '-s', '--src_dir', help='source images', metavar='dir', required=True) + parser.add_argument( + '-d', '--dst_dir', help='destination directory', metavar='dir', + required=True) + parser.add_argument( + '-v', '--verbose', help='write log output', metavar='level', + choices='warning info debug'.split(), const='info', + nargs='?') + args = parser.parse_args() + + if args.verbose is not None: + logging.basicConfig(level=getattr(logging, args.verbose.upper())) + + create_thumbnails_and_aliases(args.src_dir, args.dst_dir) + + +if __name__ == '__main__': + main()