Index: components/ntp_tiles/update_default_sites_resources.py |
diff --git a/components/ntp_tiles/update_default_sites_resources.py b/components/ntp_tiles/update_default_sites_resources.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..fdda791e8bd0da2352b48089c9a1dddc727c4c85 |
--- /dev/null |
+++ b/components/ntp_tiles/update_default_sites_resources.py |
@@ -0,0 +1,146 @@ |
+#!/usr/bin/env python2 |
+# Copyright 2017 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+from __future__ import absolute_import |
+from __future__ import division |
+from __future__ import print_function |
+ |
+import argparse |
+import contextlib |
+import glob |
+import io |
+import json |
+import os |
+import sys |
+import urllib |
+import Image |
+ |
+""" |
+This script downloads the default popular sites and large icons associated |
+with it. If an icon is too large, it will get resized in the process. |
+""" |
+ |
+DEFAULT_POPULAR_SITES = ("https://www.gstatic.com/chrome/ntp/" |
+ "suggested_sites_DEFAULT_5.json") |
+ |
+LARGE_ICON_KEY = "large_icon_url" |
+SITE_TITLE_KEY = "title" |
+MAXIMAL_SIZE = 144 |
+SITE_ICON_DELETE = "icon[0-9].png" |
+SITE_ICON_FORMAT = "icon%d.png" |
+NTP_TILES_RESOURCE_PATH = os.path.join( |
+ os.path.dirname(os.path.realpath(__file__)), "resources") |
+DEFAULT_POPULAR_SITES_PATH = os.path.join(NTP_TILES_RESOURCE_PATH, |
+ "default_popular_sites.json") |
+ |
+def download_as_json(url): |
+ """Downloads data from the given |url| and returns it in JSON format.""" |
+ print("Downloading popular sites... (" + url + ")") |
+ with contextlib.closing(urllib.urlopen(url=url)) as url_data: |
+ data = json.load(url_data) |
+ print("... done. (%d sites found)" % len(data)) |
+ return data |
+ |
+def download_as_image(url): |
+ """Downloads data from the given |url| and returns it as Image.""" |
+ with contextlib.closing(urllib.urlopen(url=url)) as url_data: |
+ image_response_data = url_data.read() |
+ return Image.open(io.BytesIO(image_response_data)) |
+ |
+def write_to_json(data, out_path, pretty_print): |
+ """Writes |data| to the given |out_path|. Minifies the JSON unless |
+ |pretty_print| is set to true.""" |
+ separators = (",", ":") |
+ indent = None |
+ sort = False |
+ if pretty_print: |
+ separators = (",", ": ") |
+ indent = 4 |
+ sort = True |
+ with open(out_path, "w") as f: |
+ json.dump(data, f, sort_keys=sort, indent=indent, separators=separators) |
+ print("JSON was written to " + out_path) |
+ |
+def delete_old_icons(): |
+ """Deletes all PNG icons within the resource path.""" |
+ print("Deleting old icons..") |
+ for f in glob.glob(os.path.join(NTP_TILES_RESOURCE_PATH, SITE_ICON_DELETE)): |
+ os.remove(os.path.join(f)) |
+ print("... done.") |
+ |
+def resize_if_too_large(image, max_size): |
+ """Takes a square icon and resizes if it exceeds the maximal width.""" |
+ if image.size[0] > max_size: |
+ print("... and resizing image from %s to %s ..." % |
+ (image.size, (max_size, max_size))); |
+ image.thumbnail((max_size, max_size), Image.ANTIALIAS) |
+ |
+ |
+ |
+def lacks_required_keys(site): |
+ """A site must at least provide a title and a large icon to be processed.""" |
+ return not SITE_TITLE_KEY in site or not LARGE_ICON_KEY in site |
+ |
+ |
+def main(): |
+ parser = argparse.ArgumentParser( |
+ description="Downloads the latest popular sites and their icons. \n\n" |
+ "It is possible to customize the default like this:\n" |
+ " 1. python " + __file__ + " -o temp.json --no_icons " |
+ "--pretty_print\n" |
+ " 2. Adjust the downloaded temp.json\n" |
+ " 3. python " + __file__ + " -f temp.json -s 96\n\n" |
+ "The result would be a minified version of your customized JSON " |
+ "and all icons would be downloaded as you specified.\n The icons " |
+ "had a max size of 96x96.", |
+ formatter_class=argparse.RawTextHelpFormatter) |
+ parser.add_argument("-s", "--size", metavar="size_in_px", type=int, |
+ default=MAXIMAL_SIZE, |
+ help="size to scale too large icons down to; defaults " |
+ "to 144px") |
+ parser.add_argument("-u", "--url", type=str, |
+ default=DEFAULT_POPULAR_SITES, |
+ help="the endpoint to query for json of sites") |
+ parser.add_argument("--no_icons", action="store_true", |
+ help="do not download icons") |
+ parser.add_argument("--no_resizing", action="store_true", |
+ help="do not resize any icons") |
+ parser.add_argument("-f", "--in_file", metavar="path_to_json_file", |
+ type=str, |
+ help="skip download and load icons for a local json") |
+ parser.add_argument("-o", "--out_path", metavar="path_to_out_file", |
+ type=str, default=DEFAULT_POPULAR_SITES_PATH, |
+ help="skip download and load icons for a local json") |
+ parser.add_argument("-p", "--pretty_print", action="store_true", |
+ help="pretty_print instead of minifying the JSON") |
+ args = parser.parse_args() |
+ |
+ if args.in_file: |
+ with open(args.in_file) as f: |
+ popular_sites = json.load(f) |
+ else: |
+ popular_sites = download_as_json(args.url) |
+ write_to_json(popular_sites, args.out_path, args.pretty_print) |
+ |
+ if args.no_icons: |
+ return |
+ |
+ delete_old_icons() |
+ for i, site in enumerate(popular_sites): |
+ if lacks_required_keys(site): |
+ print("Could not download large image for site: %r" % site) |
+ continue |
+ print("Downloading icon for '%r'..." % site[SITE_TITLE_KEY]) |
+ image = download_as_image(site[LARGE_ICON_KEY]) |
+ if not args.no_resizing: |
+ resize_if_too_large(image, args.size) |
+ image_name = SITE_ICON_FORMAT % i |
+ image.save(os.path.join(NTP_TILES_RESOURCE_PATH, image_name), "PNG", |
+ optimize=True) |
+ print("... done. (Stored as " + image_name + ")"); |
+ |
+ |
+if __name__ == "__main__": |
+ main() |