Esempio n. 1
0
def insert_todos_into_file(js_path):
    """Inserts TODO comments in a JavaScript file.

  The TODO comments inserted should draw attention to places in the converted
  app that the developer will need to edit to finish converting their app.

  Args:
    js_path: Path to JavaScript file.
  """
    with open(js_path) as in_js_file:
        # This search is very naïve and will only check line-by-line if there
        # are easily spotted Chrome Apps API function calls.
        out_js_lines = []
        for line_no, line in enumerate(in_js_file):
            line = surrogateescape.decode(line)
            api_call = chrome_app.apis.api_member_used(line)
            if api_call is not None:
                # Construct a TODO comment.
                newline = '\r\n' if line.endswith('\r\n') else '\n'
                todo = '// TODO(Caterpillar): Check usage of {}.{}'.format(
                    api_call, newline)
                logging.debug('Inserting TODO in `%s:%d`:\n\t%s', js_path,
                              line_no, todo)
                out_js_lines.append(todo)
            out_js_lines.append(line)

    with open(js_path, 'w') as out_js_file:
        logging.debug('Writing modified file `%s`.', js_path)
        out_js = surrogateescape.encode(''.join(out_js_lines))
        out_js_file.write(out_js)
Esempio n. 2
0
def add_service_worker(output_dir, chrome_app_manifest, required_js_paths,
                       boilerplate_dir):
    """Adds service worker scripts to a web app.

  Args:
    output_dir: Path to web app to add service worker scripts to.
    chrome_app_manifest: Chrome App manifest dictionary.
    required_js_paths: List of paths to required scripts, relative to the
      boilerplate directory.
    boilerplate_dir: Caterpillar script directory within web app.
  """
    # We have to copy the other scripts before we generate the service worker
    # caching script, or else they won't be cached.
    boilerplate_path = os.path.join(output_dir, boilerplate_dir)
    copy_script(REGISTER_SCRIPT_NAME, boilerplate_path)
    copy_script(SW_STATIC_SCRIPT_NAME, boilerplate_path)

    sw_js = generate_service_worker(output_dir, chrome_app_manifest,
                                    required_js_paths, boilerplate_dir)

    # We can now write the service worker. Note that it must be in the root.
    sw_path = os.path.join(output_dir, SW_SCRIPT_NAME)
    logging.debug('Writing service worker to `%s`.', sw_path)
    with open(sw_path, 'w') as sw_file:
        sw_file.write(surrogateescape.encode(sw_js))
Esempio n. 3
0
def edit_code(output_dir, required_js_paths, chrome_app_manifest, config):
  """Directly edits the code of the output web app.

  All editing of user code should be called from this function.

  Args:
    output_dir: Path to web app.
    required_js_paths: Paths of scripts to be included in the web app, relative
      to Caterpillar's boilerplate directory in the output web app.
    chrome_app_manifest: Manifest dictionary of the _Chrome App_.
    config: Configuration dictionary.
  """
  logging.debug('Editing web app code.')

  # Walk the app for JS and HTML.
  # Insert TODOs into JS.
  # Inject script and meta tags into HTML.
  dirwalk = os.walk(output_dir)
  for (dirpath, _, filenames) in dirwalk:
    for filename in filenames:
      path = os.path.join(dirpath, filename)
      root_path = os.path.relpath(output_dir, dirpath)
      if filename.endswith('.js'):
        insert_todos_into_file(path)
      elif filename.endswith('.html'):
        logging.debug('Editing `%s`.', path)
        with open(path) as in_html_file:
          soup = bs4.BeautifulSoup(
              surrogateescape.decode(in_html_file.read()), 'html.parser')
        inject_script_tags(
            soup, required_js_paths, root_path, config['boilerplate_dir'], path)
        inject_misc_tags(soup, chrome_app_manifest, root_path, path)
        logging.debug('Writing edited and prettified `%s`.', path)
        with open(path, 'w') as out_html_file:
          out_html_file.write(surrogateescape.encode(soup.prettify()))
Esempio n. 4
0
def add_service_worker(output_dir, chrome_app_manifest, required_js_paths,
                       boilerplate_dir):
  """Adds service worker scripts to a web app.

  Args:
    output_dir: Path to web app to add service worker scripts to.
    chrome_app_manifest: Chrome App manifest dictionary.
    required_js_paths: List of paths to required scripts, relative to the
      boilerplate directory.
    boilerplate_dir: Caterpillar script directory within web app.
  """
  # We have to copy the other scripts before we generate the service worker
  # caching script, or else they won't be cached.
  boilerplate_path = os.path.join(output_dir, boilerplate_dir)
  copy_script(REGISTER_SCRIPT_NAME, boilerplate_path)
  copy_script(SW_STATIC_SCRIPT_NAME, boilerplate_path)

  sw_js = generate_service_worker(output_dir, chrome_app_manifest,
                                  required_js_paths, boilerplate_dir)

  # We can now write the service worker. Note that it must be in the root.
  sw_path = os.path.join(output_dir, SW_SCRIPT_NAME)
  logging.debug('Writing service worker to `%s`.', sw_path)
  with open(sw_path, 'w') as sw_file:
    sw_file.write(surrogateescape.encode(sw_js))
Esempio n. 5
0
def insert_todos_into_file(js_path):
  """Inserts TODO comments in a JavaScript file.

  The TODO comments inserted should draw attention to places in the converted
  app that the developer will need to edit to finish converting their app.

  Args:
    js_path: Path to JavaScript file.
  """
  with open(js_path) as in_js_file:
    # This search is very naïve and will only check line-by-line if there
    # are easily spotted Chrome Apps API function calls.
    out_js_lines = []
    for line_no, line in enumerate(in_js_file):
      line = surrogateescape.decode(line)
      api_call = chrome_app.apis.api_member_used(line)
      if api_call is not None:
        # Construct a TODO comment.
        newline = '\r\n' if line.endswith('\r\n') else '\n'
        todo = '// TODO(Caterpillar): Check usage of {}.{}'.format(api_call,
                                                                   newline)
        logging.debug('Inserting TODO in `%s:%d`:\n\t%s', js_path, line_no,
                      todo)
        out_js_lines.append(todo)
      out_js_lines.append(line)

  with open(js_path, 'w') as out_js_file:
    logging.debug('Writing modified file `%s`.', js_path)
    out_js = surrogateescape.encode(''.join(out_js_lines))
    out_js_file.write(out_js)
Esempio n. 6
0
def generate_and_write(report_dir, chrome_app_manifest, apis, status, warnings,
                       web_path, boilerplate_dir):
  """Generates a conversion report and writes it to a directory.

  Args:
    report_dir: Directory to write report to.
    chrome_app_manifest: Manifest dictionary of input Chrome App.
    apis: Dictionary mapping Chrome Apps API name to polyfill manifest
      dictionaries.
    status: Status representing conversion status of the entire app.
    warnings: List of general warnings logged during conversion.
    web_path: Path to output progressive web app.
  """
  report = generate(chrome_app_manifest, apis, status, warnings, web_path,
                    boilerplate_dir)
  report_path = os.path.join(report_dir, 'report.html')
  with open(report_path, 'w') as report_file:
    logging.info('Writing conversion report to `%s`.', report_path)
    report_file.write(surrogateescape.encode(report))
  copy_css(report_dir)
  install_bower_dependencies(['lato', 'inconsolata', 'code-prettify'],
                             report_dir)
 def test_surrogate_encode(self):
   s = u'latin-1: caf\udce9; utf-8: caf\xe9'
   bs = surrogateescape.encode(s)
   self.assertIsInstance(bs, bytes)
   self.assertEqual(bs, b'latin-1: caf\xe9; utf-8: caf\xc3\xa9')
 def test_surrogate_encode(self):
     s = u'latin-1: caf\udce9; utf-8: caf\xe9'
     bs = surrogateescape.encode(s)
     self.assertIsInstance(bs, bytes)
     self.assertEqual(bs, b'latin-1: caf\xe9; utf-8: caf\xc3\xa9')