Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python2 | |
| 2 # Copyright 2017 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 from __future__ import absolute_import | |
| 7 from __future__ import division | |
| 8 from __future__ import print_function | |
| 9 | |
| 10 import argparse | |
| 11 import contextlib | |
| 12 import glob | |
| 13 import io | |
| 14 import json | |
| 15 import os | |
| 16 import sys | |
| 17 import urllib | |
| 18 import Image | |
| 19 | |
| 20 # This script downloads the default popular sites and large icons associated | |
| 21 # with it. If an icon is too large, it will get resized in the process. | |
|
sfiera
2017/02/16 18:54:16
This here would be a good use of a file-level """
fhorschig
2017/02/17 16:24:04
Okay.
| |
| 22 | |
| 23 DEFAULT_POPULAR_SITES = ("https://www.gstatic.com/chrome/ntp/" | |
| 24 "suggested_sites_DEFAULT_5.json") | |
| 25 LARGE_ICON_KEY = "large_icon_url" | |
| 26 SITE_TITLE_KEY = "title" | |
| 27 MAXIMAL_SIZE = 144 | |
| 28 SITE_ICON_DELETE = "icon[0-9].png" | |
| 29 SITE_ICON_FORMAT = "icon%d.png" | |
| 30 NTP_TILES_RESOURCE_PATH = os.path.join( | |
| 31 os.path.dirname(os.path.realpath(__file__)), "resources") | |
| 32 DEFAULT_POPULAR_SITES_PATH = os.path.join(NTP_TILES_RESOURCE_PATH, | |
| 33 "default_popular_sites.json") | |
| 34 | |
| 35 def download_popular_sites(url): | |
| 36 print("Downloading popular sites... (" + url + ")") | |
| 37 with contextlib.closing(urllib.urlopen(url=url)) as url_data: | |
| 38 data = json.load(url_data) | |
| 39 print("... done. (%d sites found)" % len(data)) | |
| 40 return data | |
| 41 | |
| 42 def write_to_json(data, out_path, pretty_print): | |
| 43 separators = (",", ":") | |
| 44 indent = None | |
| 45 sort = False | |
| 46 if pretty_print: | |
| 47 separators = (",", ": ") | |
| 48 indent = 4 | |
| 49 sort = True | |
| 50 with open(out_path, "w") as f: | |
| 51 json.dump(data, f, sort_keys=sort, indent=indent, separators=separators) | |
| 52 print("JSON was written to " + out_path) | |
| 53 | |
| 54 def delete_old_icons(): | |
| 55 print("Deleting old icons..") | |
| 56 for f in glob.glob(os.path.join(NTP_TILES_RESOURCE_PATH, SITE_ICON_DELETE)): | |
| 57 os.remove(os.path.join(f)) | |
| 58 print("... done.") | |
| 59 | |
| 60 def download_image_for_popular_site(site): | |
| 61 with contextlib.closing(urllib.urlopen(url=site[LARGE_ICON_KEY])) as url_data: | |
| 62 image_response_data = url_data.read() | |
| 63 return Image.open(io.BytesIO(image_response_data)) | |
|
sfiera
2017/02/16 18:54:16
I'm still concerned that you might be un-optimizin
fhorschig
2017/02/17 16:24:04
As discussed, I noew introduced the highest compre
| |
| 64 | |
| 65 def resize_if_too_large(image, max_size): | |
| 66 if image.size[0] > max_size: # Width is sufficient to compare squared icons. | |
| 67 print("... and resizing image from %s to %s ..." % | |
| 68 (image.size, (max_size, max_size))); | |
| 69 image.thumbnail((max_size, max_size), Image.ANTIALIAS) | |
| 70 | |
| 71 | |
| 72 def lacks_required_keys(site): | |
| 73 return not SITE_TITLE_KEY in site or not LARGE_ICON_KEY in site | |
| 74 | |
| 75 | |
| 76 def main(): | |
| 77 parser = argparse.ArgumentParser( | |
| 78 description="Downloads the latest popular sites and their icons. \n\n" | |
| 79 "It is possible to customize the default like this:\n" | |
| 80 " 1. python " + __file__ + " -o temp.json --skip_icons " | |
| 81 "--pretty_print\n" | |
| 82 " 2. Adjust the downloaded temp.json\n" | |
| 83 " 3. python " + __file__ + " -f temp.json -s 96\n\n" | |
| 84 "The result would be a minified version of your customized JSON " | |
| 85 "and all icons would be downloaded as you specified.\n The icons " | |
| 86 "had a max size of 96x96.", | |
| 87 formatter_class=argparse.RawTextHelpFormatter) | |
| 88 parser.add_argument("-s", "--size", metavar="size_in_px", type=int, | |
| 89 default=MAXIMAL_SIZE, | |
| 90 help="size to scale too large icons down to; defaults " | |
| 91 "to 144px") | |
| 92 parser.add_argument("-u", "--url", metavar="url", type=str, | |
|
sfiera
2017/02/16 18:54:16
If you have a long flag name, the metavar should d
fhorschig
2017/02/17 16:24:04
Yes but it's CAPS. But in this case it's maybe mor
| |
| 93 default=DEFAULT_POPULAR_SITES, | |
| 94 help="the endpoint to query for json of sites") | |
| 95 parser.add_argument("--skip_icons", action="store_true", | |
|
sfiera
2017/02/16 18:54:16
In Chromium, I think we typically use --skip-icons
fhorschig
2017/02/17 16:24:04
Done.
| |
| 96 help="do not download icons") | |
| 97 parser.add_argument("--skip_resizing", action="store_true", | |
| 98 help="do not resize any icons") | |
| 99 parser.add_argument("-f", "--in_file", metavar="path_to_json_file", | |
| 100 type=str, | |
|
sfiera
2017/02/16 18:54:16
See also argparse.FileType.
fhorschig
2017/02/17 16:24:04
There is little advantage using that as I would ne
| |
| 101 help="skip download and load icons for a local json") | |
| 102 parser.add_argument("-o", "--out_path", metavar="path_to_out_file", | |
| 103 type=str, default=DEFAULT_POPULAR_SITES_PATH, | |
| 104 help="skip download and load icons for a local json") | |
| 105 parser.add_argument("-p", "--pretty_print", action="store_true", | |
| 106 help="pretty_print instead of minifying the JSON") | |
| 107 args = parser.parse_args() | |
| 108 | |
| 109 if args.in_file: | |
| 110 with open(args.in_file) as f: | |
| 111 popular_sites = json.load(f) | |
| 112 else: | |
| 113 popular_sites = download_popular_sites(args.url) | |
| 114 write_to_json(popular_sites, args.out_path, args.pretty_print) | |
| 115 | |
| 116 if args.skip_icons: | |
| 117 return | |
| 118 | |
| 119 delete_old_icons() | |
| 120 for i, site in enumerate(popular_sites): | |
| 121 if lacks_required_keys(site): | |
| 122 print("Could not download large image for site: %r" % site) | |
| 123 continue | |
| 124 print("Downloading icon for '%r'..." % site[SITE_TITLE_KEY]) | |
| 125 image = download_image_for_popular_site(site) | |
| 126 if not args.skip_resizing: | |
| 127 resize_if_too_large(image, args.size) | |
| 128 image_name = SITE_ICON_FORMAT % i | |
| 129 image.save(os.path.join(NTP_TILES_RESOURCE_PATH, image_name), "PNG") | |
| 130 print("... done. (Stored as " + image_name + ")"); | |
| 131 | |
| 132 | |
| 133 if __name__ == "__main__": | |
| 134 main() | |
| OLD | NEW |