Update thumbnail generation and add unknown flag sequences.
Thumbnail generation for Unicode requires some changes: - 72x72 images (exact, not just fit within that frame) - custom prefix ending in underscore - images for unsupported flags The default build doesn't support some flags by default, since they are not wanted by Android. For the thumbnail list these images need to be provided, so we alias them to the unknown flag images as that's what would show for them. It's probably a good idea to list these explicitly anyway, other tools could use this information.pull/111/head
parent
f89867eab6
commit
7ce8ee5d73
|
@ -32,75 +32,86 @@ import subprocess
|
||||||
import add_aliases
|
import add_aliases
|
||||||
|
|
||||||
from nototools import tool_utils
|
from nototools import tool_utils
|
||||||
|
from nototools import unicode_data
|
||||||
|
|
||||||
logger = logging.getLogger('emoji_thumbnails')
|
logger = logging.getLogger('emoji_thumbnails')
|
||||||
|
|
||||||
def create_thumbnail(src_path, dst_path):
|
def create_thumbnail(src_path, dst_path):
|
||||||
# uses imagemagik
|
# uses imagemagik
|
||||||
subprocess.check_call(['convert', '-resize', '72x72', src_path, dst_path])
|
# we need imagex exactly 72x72 in size, with transparent background
|
||||||
logger.info('wrote thumbnail: %s' % dst_path)
|
subprocess.check_call([
|
||||||
|
'convert', '-thumbnail', '72x72', '-gravity', 'center', '-background',
|
||||||
|
'none', '-extent', '72x72', src_path, dst_path])
|
||||||
|
|
||||||
|
|
||||||
_INV_ALIASES = None
|
|
||||||
def get_inv_aliases():
|
def get_inv_aliases():
|
||||||
global _INV_ALIASES
|
"""Return a mapping from target to list of sources for all alias
|
||||||
if _INV_ALIASES is None:
|
targets in either the default alias table or the unknown_flag alias
|
||||||
aliases = add_aliases.read_default_emoji_aliases()
|
table."""
|
||||||
inv_aliases = collections.defaultdict(list)
|
|
||||||
for k, v in aliases.iteritems():
|
inv_aliases = collections.defaultdict(list)
|
||||||
inv_aliases[v].append(k)
|
|
||||||
_INV_ALIASES = inv_aliases
|
standard_aliases = add_aliases.read_default_emoji_aliases()
|
||||||
return _INV_ALIASES
|
for k, v in standard_aliases.iteritems():
|
||||||
|
inv_aliases[v].append(k)
|
||||||
|
|
||||||
|
unknown_flag_aliases = add_aliases.read_emoji_aliases(
|
||||||
|
'unknown_flag_aliases.txt')
|
||||||
|
for k, v in unknown_flag_aliases.iteritems():
|
||||||
|
inv_aliases[v].append(k)
|
||||||
|
|
||||||
|
return inv_aliases
|
||||||
|
|
||||||
|
|
||||||
def is_emoji_filename(filename):
|
def filename_to_sequence(filename, prefix, suffix):
|
||||||
return filename.startswith('emoji_u') and filename.endswith('.png')
|
if not filename.startswith(prefix) and filename.endswith(suffix):
|
||||||
|
raise ValueError('bad prefix or suffix: "%s"' % filename)
|
||||||
|
seq_str = filename[len(prefix): -len(suffix)]
|
||||||
|
seq = unicode_data.string_to_seq(seq_str)
|
||||||
|
if not unicode_data.is_cp_seq(seq):
|
||||||
|
raise ValueError('sequence includes non-codepoint: "%s"' % filename)
|
||||||
|
return seq
|
||||||
|
|
||||||
|
|
||||||
def check_emoji_filename(filename):
|
def sequence_to_filename(seq, prefix, suffix):
|
||||||
if not is_emoji_filename(filename):
|
return ''.join((prefix, unicode_data.seq_to_string(seq), suffix))
|
||||||
raise ValueError('not an emoji image file: %s' % filename)
|
|
||||||
|
|
||||||
|
|
||||||
def emoji_filename_to_sequence(filename):
|
def create_thumbnails_and_aliases(src_dir, dst_dir, dst_prefix):
|
||||||
check_emoji_filename(filename)
|
"""Creates thumbnails in dst_dir based on sources in src.dir, using
|
||||||
|
dst_prefix. Assumes the source prefix is 'emoji_u' and the common suffix
|
||||||
|
is '.png'."""
|
||||||
|
|
||||||
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):
|
if not path.isdir(src_dir):
|
||||||
raise ValueError('"%s" is not a directory')
|
raise ValueError('"%s" is not a directory')
|
||||||
dst_dir = tool_utils.ensure_dir_exists(dst_dir)
|
dst_dir = tool_utils.ensure_dir_exists(dst_dir)
|
||||||
|
|
||||||
for f in os.listdir(src_dir):
|
src_prefix = 'emoji_u'
|
||||||
if not (f.startswith('emoji_u') and f.endswith('.png')):
|
suffix = '.png'
|
||||||
logger.warning('skipping "%s"' % f)
|
|
||||||
|
inv_aliases = get_inv_aliases()
|
||||||
|
|
||||||
|
for src_file in os.listdir(src_dir):
|
||||||
|
try:
|
||||||
|
seq = unicode_data.strip_emoji_vs(
|
||||||
|
filename_to_sequence(src_file, src_prefix, suffix))
|
||||||
|
except ValueError as ve:
|
||||||
|
logger.warning('Error (%s), skipping' % ve)
|
||||||
continue
|
continue
|
||||||
src = path.join(src_dir, f)
|
|
||||||
dst = path.join(dst_dir, f)
|
src_path = path.join(src_dir, src_file)
|
||||||
create_thumbnail(src, dst)
|
|
||||||
create_emoji_alias(dst, dst_dir)
|
dst_file = sequence_to_filename(seq, dst_prefix, suffix)
|
||||||
|
dst_path = path.join(dst_dir, dst_file)
|
||||||
|
|
||||||
|
create_thumbnail(src_path, dst_path)
|
||||||
|
logger.info('wrote thumbnail: %s' % dst_file)
|
||||||
|
|
||||||
|
for alias_seq in inv_aliases.get(seq, ()):
|
||||||
|
alias_file = sequence_to_filename(alias_seq, dst_prefix, suffix)
|
||||||
|
alias_path = path.join(dst_dir, alias_file)
|
||||||
|
shutil.copy2(dst_path, alias_path)
|
||||||
|
logger.info('wrote alias: %s' % alias_file)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -110,6 +121,9 @@ def main():
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-d', '--dst_dir', help='destination directory', metavar='dir',
|
'-d', '--dst_dir', help='destination directory', metavar='dir',
|
||||||
required=True)
|
required=True)
|
||||||
|
parser.add_argument(
|
||||||
|
'-p', '--prefix', help='prefix for thumbnail', metavar='str',
|
||||||
|
default='android_')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-v', '--verbose', help='write log output', metavar='level',
|
'-v', '--verbose', help='write log output', metavar='level',
|
||||||
choices='warning info debug'.split(), const='info',
|
choices='warning info debug'.split(), const='info',
|
||||||
|
@ -119,7 +133,8 @@ def main():
|
||||||
if args.verbose is not None:
|
if args.verbose is not None:
|
||||||
logging.basicConfig(level=getattr(logging, args.verbose.upper()))
|
logging.basicConfig(level=getattr(logging, args.verbose.upper()))
|
||||||
|
|
||||||
create_thumbnails_and_aliases(args.src_dir, args.dst_dir)
|
create_thumbnails_and_aliases(
|
||||||
|
args.src_dir, args.dst_dir, args.prefix)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# alias table
|
||||||
|
# from;to
|
||||||
|
# the 'from' sequence should be represented by the image for the 'to' sequence
|
||||||
|
# these are flags we explicitly omit
|
||||||
|
|
||||||
|
# flag aliases
|
||||||
|
1f1e7_1f1f1;fe82b # BL
|
||||||
|
1f1e7_1f1f6;fe82b # BQ
|
||||||
|
1f1e9_1f1ec;fe82b # DG
|
||||||
|
1f1ea_1f1e6;fe82b # EA
|
||||||
|
1f1ea_1f1ed;fe82b # EH
|
||||||
|
1f1eb_1f1f0;fe82b # FK
|
||||||
|
1f1ec_1f1eb;fe82b # GF
|
||||||
|
1f1ec_1f1f5;fe82b # GP
|
||||||
|
1f1ec_1f1f8;fe82b # GS
|
||||||
|
1f1f2_1f1eb;fe82b # MF
|
||||||
|
1f1f2_1f1f6;fe82b # MQ
|
||||||
|
1f1f3_1f1e8;fe82b # NC
|
||||||
|
1f1f5_1f1f2;fe82b # PM
|
||||||
|
1f1f7_1f1ea;fe82b # RE
|
||||||
|
1f1f9_1f1eb;fe82b # TF
|
||||||
|
1f1fc_1f1eb;fe82b # WF
|
||||||
|
1f1fd_1f1f0;fe82b # XK
|
||||||
|
1f1fe_1f1f9;fe82b # YT
|
||||||
|
|
Loading…
Reference in New Issue