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 = ('google.com', 'gstatic.com', 'youtube.com')
     21 
     22 
     23 CC_HEADER = """// Copyright (C) 2014 The Chromium Authors. All rights reserved.
     24 // Use of this source code is governed by a BSD-style license that can be
     25 // found in the LICENSE file.
     26 
     27 // AUTOGENERATED FILE. DO NOT EDIT.
     28 //
     29 // (Update configs in components/domain_reliability/baked_in_configs and list
     30 // configs in components/domain_reliability.gypi instead.)
     31 
     32 #include "components/domain_reliability/baked_in_configs.h"
     33 
     34 #include <stdlib.h>
     35 
     36 namespace domain_reliability {
     37 
     38 const char* const kBakedInJsonConfigs[] = {
     39 """
     40 
     41 
     42 CC_FOOTER = """  NULL
     43 };
     44 
     45 }  // namespace domain_reliability
     46 """
     47 
     48 
     49 def domain_is_whitelisted(domain):
     50   return any(domain == e or domain.endswith('.' + e)  for e in DOMAIN_WHITELIST)
     51 
     52 
     53 def quote_and_wrap_text(text, width=79, prefix='  "', suffix='"'):
     54   max_length = width - len(prefix) - len(suffix)
     55   output = prefix
     56   line_length = 0
     57   for c in text:
     58     if c == "\"":
     59       c = "\\\""
     60     elif c == "\n":
     61       c = "\\n"
     62     elif c == "\\":
     63       c = "\\\\"
     64     if line_length + len(c) > max_length:
     65       output += suffix + "\n" + prefix
     66       line_length = 0
     67     output += c
     68     line_length += len(c)
     69   output += suffix
     70   return output
     71 
     72 
     73 def main():
     74   if len(sys.argv) < 3:
     75     print >> sys.stderr, ('Usage: %s <JSON files...> <output C++ file>' %
     76                           sys.argv[0])
     77     print >> sys.stderr, sys.modules[__name__].__doc__
     78     return 1
     79 
     80   cpp_code = CC_HEADER
     81   for json_file in sys.argv[1:-1]:
     82     with open(json_file, 'r') as f:
     83       json_text = f.read()
     84     config = json.loads(json_text)
     85     if 'monitored_domain' not in config:
     86       print >> sys.stderr ('%s: no monitored_domain found' % json_file)
     87       return 1
     88     domain = config['monitored_domain']
     89     if not domain_is_whitelisted(domain):
     90       print >> sys.stderr ('%s: monitored_domain "%s" not in whitelist' %
     91                            (json_file, domain))
     92       return 1
     93     cpp_code += "  // " + json_file + ":\n"
     94     cpp_code += quote_and_wrap_text(json_text) + ",\n"
     95     cpp_code += "\n"
     96   cpp_code += CC_FOOTER
     97 
     98   with open(sys.argv[-1], 'wb') as f:
     99     f.write(cpp_code)
    100 
    101   return 0
    102 
    103 
    104 if __name__ == '__main__':
    105   sys.exit(main())
    106