Home | History | Annotate | Download | only in domain_reliability
      1 #!/usr/bin/env python
      2 # Copyright 2014 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 
      7 """Takes the JSON files in components/domain_reliability/baked_in_configs and
      8 encodes their contents as an array of C strings that gets compiled in to Chrome
      9 and loaded at runtime."""
     10 
     11 
     12 import json
     13 import os
     14 import sys
     15 
     16 
     17 # A whitelist of domains that the script will accept when baking configs in to
     18 # Chrome, to ensure incorrect ones are not added accidentally. Subdomains of
     19 # whitelist entries are also allowed (e.g. maps.google.com, ssl.gstatic.com).
     20 DOMAIN_WHITELIST = ('2mdn.net', 'admob.com', 'doubleclick.net', 'ggpht.com',
     21                     'google.cn', 'google.co.uk', 'google.com', 'google.com.au',
     22                     'google.de', 'google.fr', 'google.it', 'google.jp',
     23                     'google.org', 'google.ru', 'googleadservices.com',
     24                     'googleapis.com', 'googlesyndication.com',
     25                     'googleusercontent.com', 'googlevideo.com', 'gstatic.com',
     26                     'gvt1.com', 'youtube.com', 'ytimg.com')
     27 
     28 
     29 CC_HEADER = """// Copyright (C) 2014 The Chromium Authors. All rights reserved.
     30 // Use of this source code is governed by a BSD-style license that can be
     31 // found in the LICENSE file.
     32 
     33 // AUTOGENERATED FILE. DO NOT EDIT.
     34 //
     35 // (Update configs in components/domain_reliability/baked_in_configs and list
     36 // configs in components/domain_reliability.gypi instead.)
     37 
     38 #include "components/domain_reliability/baked_in_configs.h"
     39 
     40 #include <stdlib.h>
     41 
     42 namespace domain_reliability {
     43 
     44 const char* const kBakedInJsonConfigs[] = {
     45 """
     46 
     47 
     48 CC_FOOTER = """  NULL
     49 };
     50 
     51 }  // namespace domain_reliability
     52 """
     53 
     54 
     55 def domain_is_whitelisted(domain):
     56   return any(domain == e or domain.endswith('.' + e)  for e in DOMAIN_WHITELIST)
     57 
     58 
     59 def quote_and_wrap_text(text, width=79, prefix='  "', suffix='"'):
     60   max_length = width - len(prefix) - len(suffix)
     61   output = prefix
     62   line_length = 0
     63   for c in text:
     64     if c == "\"":
     65       c = "\\\""
     66     elif c == "\n":
     67       c = "\\n"
     68     elif c == "\\":
     69       c = "\\\\"
     70     if line_length + len(c) > max_length:
     71       output += suffix + "\n" + prefix
     72       line_length = 0
     73     output += c
     74     line_length += len(c)
     75   output += suffix
     76   return output
     77 
     78 
     79 def main():
     80   if len(sys.argv) < 3:
     81     print >> sys.stderr, ('Usage: %s <JSON files...> <output C++ file>' %
     82                           sys.argv[0])
     83     print >> sys.stderr, sys.modules[__name__].__doc__
     84     return 1
     85 
     86   cpp_code = CC_HEADER
     87   found_invalid_config = False
     88   for json_file in sys.argv[1:-1]:
     89     with open(json_file, 'r') as f:
     90       json_text = f.read()
     91     config = json.loads(json_text)
     92     if 'monitored_domain' not in config:
     93       print >> sys.stderr, ('%s: no monitored_domain found' % json_file)
     94       found_invalid_config = True
     95       continue
     96     domain = config['monitored_domain']
     97     if not domain_is_whitelisted(domain):
     98       print >> sys.stderr, ('%s: monitored_domain "%s" not in whitelist' %
     99                             (json_file, domain))
    100       found_invalid_config = True
    101       continue
    102     cpp_code += "  // " + json_file + ":\n"
    103     cpp_code += quote_and_wrap_text(json_text) + ",\n"
    104     cpp_code += "\n"
    105   cpp_code += CC_FOOTER
    106 
    107   if found_invalid_config:
    108     return 1
    109 
    110   with open(sys.argv[-1], 'wb') as f:
    111     f.write(cpp_code)
    112 
    113   return 0
    114 
    115 
    116 if __name__ == '__main__':
    117   sys.exit(main())
    118