Example #1
0
    def Run(self, opts, args):
        args = self.ParseOptions(args)
        if len(args) != 1:
            print(
                'This tool takes a single tool-specific argument, the path to the\n'
                '.rc file to process.')
            return 2
        self.SetOptions(opts)

        path = args[0]
        out_path = os.path.join(
            util.dirname(path),
            os.path.splitext(os.path.basename(path))[0] + '.grd')

        rctext = util.ReadFile(path, self.input_encoding)
        grd_text = unicode(self.Process(rctext, path))
        with util.WrapOutputStream(file(out_path, 'w'), 'utf-8') as outfile:
            outfile.write(grd_text)

        print(
            'Wrote output file %s.\nPlease check for TODO items in the file.' %
            (out_path, ))
Example #2
0
    def InlineCSSFile(src_match, pattern, base_path=input_filepath):
        """Helper function to inline external CSS files.

    Args:
      src_match: A regular expression match with a named group named "filename".
      pattern: The pattern to replace with the contents of the CSS file.
      base_path: The base path to use for resolving the CSS file.

    Returns:
      The text that should replace the reference to the CSS file.
    """
        filepath = GetFilepath(src_match, base_path)
        if filepath is None:
            return src_match.group(0)

        # Even if names_only is set, the CSS file needs to be opened, because it
        # can link to images that need to be added to the file set.
        inlined_files.add(filepath)
        # When resolving CSS files we need to pass in the path so that relative URLs
        # can be resolved.
        return pattern % InlineCSSText(util.ReadFile(filepath, util.BINARY),
                                       filepath)
Example #3
0
def RePack(output_file,
           input_files,
           whitelist_file=None,
           suppress_removed_key_output=False,
           output_info_filepath=None):
    """Write a new data pack file by combining input pack files.

  Args:
      output_file: path to the new data pack file.
      input_files: a list of paths to the data pack files to combine.
      whitelist_file: path to the file that contains the list of resource IDs
                      that should be kept in the output file or None to include
                      all resources.
      suppress_removed_key_output: allows the caller to suppress the output from
                                   RePackFromDataPackStrings.
      output_info_file: If not None, specify the output .info filepath.

  Raises:
      KeyError: if there are duplicate keys or resource encoding is
      inconsistent.
  """
    input_data_packs = [ReadDataPack(filename) for filename in input_files]
    input_info_files = [filename + '.info' for filename in input_files]
    whitelist = None
    if whitelist_file:
        lines = util.ReadFile(whitelist_file, 'utf-8').strip().splitlines()
        if not lines:
            raise Exception('Whitelist file should not be empty')
        whitelist = set(int(x) for x in lines)
    inputs = [(p.resources, p.encoding) for p in input_data_packs]
    resources, encoding = RePackFromDataPackStrings(
        inputs, whitelist, suppress_removed_key_output)
    WriteDataPack(resources, output_file, encoding)
    if output_info_filepath is None:
        output_info_filepath = output_file + '.info'
    with open(output_info_filepath, 'w') as output_info_file:
        for filename in input_info_files:
            with open(filename, 'r') as info_file:
                output_info_file.writelines(info_file.readlines())
Example #4
0
    def testRcIncludeFlattenedHtmlFile(self):
        input_file = util.PathFromRoot('grit/testdata/include_test.html')
        output_file = '%s/HTML_FILE1_include_test.html' % tempfile.gettempdir()
        root = util.ParseGrdForUnittest('''
      <includes>
        <include name="HTML_FILE1" flattenhtml="true" file="%s" type="BINDATA" />
      </includes>''' % input_file)

        buf = StringIO.StringIO()
        build.RcBuilder.ProcessNode(root,
                                    DummyOutput('rc_all', 'en', output_file),
                                    buf)
        output = util.StripBlankLinesAndComments(buf.getvalue())

        expected = (
            _PREAMBLE +
            u'HTML_FILE1         BINDATA            "HTML_FILE1_include_test.html"'
        )
        # hackety hack to work on win32&lin
        output = re.sub('"[c-zC-Z]:', '"', output)
        self.assertEqual(expected, output)

        file_contents = util.ReadFile(output_file, util.RAW_TEXT)

        # Check for the content added by the <include> tag.
        self.failUnless(file_contents.find('Hello Include!') != -1)
        # Check for the content that was removed by if tag.
        self.failUnless(file_contents.find('should be removed') == -1)
        # Check for the content that was kept in place by if.
        self.failUnless(file_contents.find('should be kept') != -1)
        self.failUnless(file_contents.find('in the middle...') != -1)
        self.failUnless(file_contents.find('at the end...') != -1)
        # Check for nested content that was kept
        self.failUnless(file_contents.find('nested true should be kept') != -1)
        self.failUnless(
            file_contents.find('silbing true should be kept') != -1)
        # Check for removed "<if>" and "</if>" tags.
        self.failUnless(file_contents.find('<if expr=') == -1)
        self.failUnless(file_contents.find('</if>') == -1)
Example #5
0
def ConvertFileToDataURL(filename, base_path, distribution, inlined_files,
                         names_only):
    """Convert filename to inlined data URI.

  Takes a filename from ether "src" or "srcset", and attempts to read the file
  at 'filename'. Returns data URI as string with given file inlined.
  If it finds DIST_SUBSTR string in file name, replaces it with distribution.
  If filename contains ':', it is considered URL and not translated.

  Args:
    filename: filename string from ether src or srcset attributes.
    base_path: path that to look for files in
    distribution: string that should replace DIST_SUBSTR
    inlined_files: The name of the opened file is appended to this list.
    names_only: If true, the function will not read the file but just return "".
                It will still add the filename to |inlined_files|.

  Returns:
    string
  """
    if filename.find(':') != -1:
        # filename is probably a URL, which we don't want to bother inlining
        return filename

    filename = filename.replace(DIST_SUBSTR, distribution)
    filepath = os.path.normpath(os.path.join(base_path, filename))
    inlined_files.add(filepath)

    if names_only:
        return ""

    mimetype = mimetypes.guess_type(filename)[0]
    if mimetype is None:
        raise Exception('%s is of an an unknown type and '
                        'cannot be stored in a data url.' % filename)
    inline_data = base64.standard_b64encode(
        util.ReadFile(filepath, util.BINARY))
    return 'data:%s;base64,%s' % (mimetype, inline_data)
    def testStructureNodeOutputfile(self):
        input_file = util.PathFromRoot('grit/testdata/simple.html')
        root = util.ParseGrdForUnittest('''\
        <structures>
          <structure type="tr_html" name="IDR_HTML" file="%s" />
        </structures>''' % input_file)
        struct, = root.GetChildrenOfType(structure.StructureNode)
        # We must run the gatherer since we'll be wanting the translation of the
        # file.  The file exists in the location pointed to.
        root.SetOutputLanguage('en')
        root.RunGatherers()

        output_dir = tempfile.gettempdir()
        en_file = struct.FileForLanguage('en', output_dir)
        self.failUnless(en_file == input_file)
        fr_file = struct.FileForLanguage('fr', output_dir)
        self.failUnless(fr_file == os.path.join(output_dir, 'fr_simple.html'))

        contents = util.ReadFile(fr_file, util.RAW_TEXT)

        self.failUnless(
            contents.find('<p>') != -1)  # should contain the markup
        self.failUnless(contents.find('Hello!') == -1)  # should be translated
Example #7
0
def RePack(output_file, input_files, whitelist_file=None):
    """Write a new data pack file by combining input pack files.

  Args:
      output_file: path to the new data pack file.
      input_files: a list of paths to the data pack files to combine.
      whitelist_file: path to the file that contains the list of resource IDs
                      that should be kept in the output file or None to include
                      all resources.

  Raises:
      KeyError: if there are duplicate keys or resource encoding is
      inconsistent.
  """
    input_data_packs = [ReadDataPack(filename) for filename in input_files]
    whitelist = None
    if whitelist_file:
        whitelist = util.ReadFile(whitelist_file,
                                  util.RAW_TEXT).strip().split('\n')
        whitelist = set(map(int, whitelist))
    resources, encoding = RePackFromDataPackStrings(input_data_packs,
                                                    whitelist)
    WriteDataPack(resources, output_file, encoding)
Example #8
0
    def GetDataPackPair(self, lang, encoding):
        """Returns a (id, string) pair that represents the resource id and raw
    bytes of the data.  This is used to generate the data pack data file.
    """
        # TODO(benrg/joi): Move this and other implementations of GetDataPackPair
        # to grit.format.data_pack?
        from grit.format import rc_header
        id_map = rc_header.GetIds(self.GetRoot())
        id = id_map[self.GetTextualIds()[0]]
        filename = self.ToRealPath(self.GetInputPath())
        if self.attrs['flattenhtml'] == 'true':
            allow_external_script = self.attrs['allowexternalscript'] == 'true'
            data = self._GetFlattenedData(
                allow_external_script=allow_external_script)
        else:
            data = util.ReadFile(filename, util.BINARY)
        # Note that the minifier will only do anything if a minifier command
        # has been set in the command line.
        data = minifier.Minify(data, filename)

        # Include does not care about the encoding, because it only returns binary
        # data.
        return id, self.CompressDataIfNeeded(data)
Example #9
0
def _ReadFirstIdsFromFile(filename, defines):
    """Read the starting resource id values from |filename|.  We also
  expand variables of the form <(FOO) based on defines passed in on
  the command line.

  Returns a tuple, the absolute path of SRCDIR followed by the
  first_ids dictionary.
  """
    first_ids_dict = eval(util.ReadFile(filename, util.RAW_TEXT))
    src_root_dir = os.path.abspath(
        os.path.join(os.path.dirname(filename), first_ids_dict['SRCDIR']))

    def ReplaceVariable(matchobj):
        for key, value in defines.items():
            if matchobj.group(1) == key:
                value = os.path.abspath(value)
                return value
        return ''

    renames = []
    for grd_filename in first_ids_dict:
        new_grd_filename = re.sub(r'<\(([A-Za-z_]+)\)', ReplaceVariable,
                                  grd_filename)
        if new_grd_filename != grd_filename:
            abs_grd_filename = os.path.abspath(new_grd_filename)
            if abs_grd_filename[:len(src_root_dir)] != src_root_dir:
                new_grd_filename = os.path.basename(abs_grd_filename)
            else:
                new_grd_filename = abs_grd_filename[len(src_root_dir) + 1:]
                new_grd_filename = new_grd_filename.replace('\\', '/')
            renames.append((grd_filename, new_grd_filename))

    for grd_filename, new_grd_filename in renames:
        first_ids_dict[new_grd_filename] = first_ids_dict[grd_filename]
        del (first_ids_dict[grd_filename])

    return (src_root_dir, first_ids_dict)
Example #10
0
    def Parse(self):
        """Parses and inlines the represented file."""

        filename = self.GetInputPath()
        # If there is a grd_node, prefer its GetInputPath(), as that may do more
        # processing to make the call to ToRealPath() below work correctly.
        if self.grd_node:
            filename = self.grd_node.GetInputPath()
        if self.filename_expansion_function:
            filename = self.filename_expansion_function(filename)
        # Hack: some unit tests supply an absolute path and no root node.
        if not os.path.isabs(filename):
            filename = self.grd_node.ToRealPath(filename)
        if self.flatten_html_:
            self.inlined_text_ = html_inline.InlineToString(
                filename,
                self.grd_node,
                allow_external_script=self.allow_external_script_,
                strip_whitespace=True,
                preprocess_only=self.preprocess_only_,
                rewrite_function=lambda fp, t, d: ProcessImageSets(
                    fp,
                    t,
                    self.scale_factors_,
                    d,
                    filename_expansion_function=self.
                    filename_expansion_function),
                filename_expansion_function=self.filename_expansion_function)
        else:
            distribution = html_inline.GetDistribution()
            self.inlined_text_ = ProcessImageSets(
                os.path.dirname(filename),
                util.ReadFile(filename, 'utf-8'),
                self.scale_factors_,
                distribution,
                filename_expansion_function=self.filename_expansion_function)
  def Run(self, opts, args):
    self.output_directory = '.'
    first_ids_file = None
    whitelist_filenames = []
    assert_output_files = []
    target_platform = None
    depfile = None
    depdir = None
    rc_header_format = None
    (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:',
        ('depdir=','depfile=','assert-file-list='))
    for (key, val) in own_opts:
      if key == '-a':
        assert_output_files.append(val)
      elif key == '--assert-file-list':
        with open(val) as f:
          assert_output_files += f.read().splitlines()
      elif key == '-o':
        self.output_directory = val
      elif key == '-D':
        name, val = util.ParseDefine(val)
        self.defines[name] = val
      elif key == '-E':
        (env_name, env_value) = val.split('=', 1)
        os.environ[env_name] = env_value
      elif key == '-f':
        # TODO([email protected]): Remove this override once change
        # lands in WebKit.grd to specify the first_ids_file in the
        # .grd itself.
        first_ids_file = val
      elif key == '-w':
        whitelist_filenames.append(val)
      elif key == '-t':
        target_platform = val
      elif key == '-h':
        rc_header_format = val
      elif key == '--depdir':
        depdir = val
      elif key == '--depfile':
        depfile = val

    if len(args):
      print 'This tool takes no tool-specific arguments.'
      return 2
    self.SetOptions(opts)
    if self.scons_targets:
      self.VerboseOut('Using SCons targets to identify files to output.\n')
    else:
      self.VerboseOut('Output directory: %s (absolute path: %s)\n' %
                      (self.output_directory,
                       os.path.abspath(self.output_directory)))

    if whitelist_filenames:
      self.whitelist_names = set()
      for whitelist_filename in whitelist_filenames:
        self.VerboseOut('Using whitelist: %s\n' % whitelist_filename);
        whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT)
        self.whitelist_names.update(whitelist_contents.strip().split('\n'))

    self.res = grd_reader.Parse(opts.input,
                                debug=opts.extra_verbose,
                                first_ids_file=first_ids_file,
                                defines=self.defines,
                                target_platform=target_platform)
    # Set an output context so that conditionals can use defines during the
    # gathering stage; we use a dummy language here since we are not outputting
    # a specific language.
    self.res.SetOutputLanguage('en')
    if rc_header_format:
      self.res.AssignRcHeaderFormat(rc_header_format)
    self.res.RunGatherers()
    self.Process()

    if assert_output_files:
      if not self.CheckAssertedOutputFiles(assert_output_files):
        return 2

    if depfile and depdir:
      self.GenerateDepfile(depfile, depdir)

    return 0
Example #12
0
def ReadDataPack(input_file):
  return ReadDataPackFromString(util.ReadFile(input_file, util.BINARY))
Example #13
0
def DoInline(input_filename,
             grd_node,
             allow_external_script=False,
             names_only=False,
             rewrite_function=None):
    """Helper function that inlines the resources in a specified file.

  Reads input_filename, finds all the src attributes and attempts to
  inline the files they are referring to, then returns the result and
  the set of inlined files.

  Args:
    input_filename: name of file to read in
    grd_node: html node from the grd file for this include tag
    names_only: |nil| will be returned for the inlined contents (faster).
    rewrite_function: function(filepath, text, distribution) which will be
        called to rewrite html content before inlining images.
  Returns:
    a tuple of the inlined data as a string and the set of filenames
    of all the inlined files
  """
    input_filepath = os.path.dirname(input_filename)
    distribution = GetDistribution()

    # Keep track of all the files we inline.
    inlined_files = set()

    def SrcReplace(src_match,
                   filepath=input_filepath,
                   inlined_files=inlined_files):
        """Helper function to provide SrcInlineAsDataURL with the base file path"""
        return SrcInlineAsDataURL(src_match,
                                  filepath,
                                  distribution,
                                  inlined_files,
                                  names_only=names_only)

    def GetFilepath(src_match):
        filename = src_match.group('filename')

        if filename.find(':') != -1:
            # filename is probably a URL, which we don't want to bother inlining
            return None

        filename = filename.replace('%DISTRIBUTION%', distribution)
        return os.path.join(input_filepath, filename)

    def IsConditionSatisfied(src_match):
        expression = src_match.group('expression')
        return grd_node is None or grd_node.EvaluateCondition(expression)

    def CheckConditionalElements(str):
        """Helper function to conditionally inline inner elements"""
        while True:
            begin_if = _BEGIN_IF_BLOCK.search(str)
            if begin_if is None:
                return str

            condition_satisfied = IsConditionSatisfied(begin_if)
            leading = str[0:begin_if.start()]
            content_start = begin_if.end()

            # Find matching "if" block end.
            count = 1
            pos = begin_if.end()
            while True:
                end_if = _END_IF_BLOCK.search(str, pos)
                if end_if is None:
                    raise Exception('Unmatched <if>')

                next_if = _BEGIN_IF_BLOCK.search(str, pos)
                if next_if is None or next_if.start() >= end_if.end():
                    count = count - 1
                    if count == 0:
                        break
                    pos = end_if.end()
                else:
                    count = count + 1
                    pos = next_if.end()

            content = str[content_start:end_if.start()]
            trailing = str[end_if.end():]

            if condition_satisfied:
                str = leading + CheckConditionalElements(content) + trailing
            else:
                str = leading + trailing

    def InlineFileContents(src_match, pattern, inlined_files=inlined_files):
        """Helper function to inline external files of various types"""
        filepath = GetFilepath(src_match)
        if filepath is None:
            return src_match.group(0)
        inlined_files.add(filepath)

        # Even if names_only is set, html files needs to be opened, because it
        # can link to images that need to be added to the file set.
        if names_only and not filepath.endswith('.html'):
            return ""

        return pattern % InlineToString(filepath, grd_node,
                                        allow_external_script)

    def InlineIncludeFiles(src_match):
        """Helper function to directly inline generic external files (without
       wrapping them with any kind of tags).
    """
        return InlineFileContents(src_match, '%s')

    def InlineScript(match):
        """Helper function to inline external script files"""
        attrs = (match.group('attrs1') + match.group('attrs2')).strip()
        if attrs:
            attrs = ' ' + attrs
        return InlineFileContents(match, '<script' + attrs + '>%s</script>')

    def InlineCSSText(text, css_filepath):
        """Helper function that inlines external resources in CSS text"""
        filepath = os.path.dirname(css_filepath)
        # Allow custom modifications before inlining images.
        if rewrite_function:
            text = rewrite_function(filepath, text, distribution)
        return InlineCSSImages(text, filepath)

    def InlineCSSFile(src_match, inlined_files=inlined_files):
        """Helper function to inline external css files.

    Args:
      src_match: A regular expression match with a named group named "filename".

    Returns:
      The text that should replace the reference to the CSS file.
    """
        filepath = GetFilepath(src_match)
        if filepath is None:
            return src_match.group(0)

        # Even if names_only is set, the CSS file needs to be opened, because it
        # can link to images that need to be added to the file set.
        inlined_files.add(filepath)
        # When resolving CSS files we need to pass in the path so that relative URLs
        # can be resolved.
        return '<style>%s</style>' % InlineCSSText(
            util.ReadFile(filepath, util.BINARY), filepath)

    def InlineCSSImages(text, filepath=input_filepath):
        """Helper function that inlines external images in CSS backgrounds."""
        # Replace contents of url() for css attributes: content, background,
        # or *-image.
        return re.sub(
            '(?:content|background|[\w-]*-image):[^;]*' +
            '(?:url\((?:\'|\")([^"\'\)\(]*)(?:\'|\")\)|' + 'image-set\(' +
            '([ ]*url\((?:\'|\")([^"\'\)\(]*)(?:\'|\")\)' +
            '[ ]*[0-9.]*x[ ]*(,[ ]*)?)*\))',
            lambda m: InlineCSSUrls(m, filepath), text)

    def InlineCSSUrls(src_match, filepath=input_filepath):
        """Helper function that inlines each url on a CSS image rule match."""
        # Replace contents of url() references in matches.
        return re.sub('url\((?:\'|\")(?P<filename>[^"\'\)\(]*)(?:\'|\")',
                      lambda m: SrcReplace(m, filepath), src_match.group(0))

    flat_text = util.ReadFile(input_filename, util.BINARY)

    if not allow_external_script:
        # We need to inline css and js before we inline images so that image
        # references gets inlined in the css and js
        flat_text = re.sub(
            '<script (?P<attrs1>.*?)src="(?P<filename>[^"\']*)"' +
            '(?P<attrs2>.*?)></script>', InlineScript, flat_text)

    flat_text = re.sub(
        '<link rel="stylesheet".+?href="(?P<filename>[^"]*)".*?>',
        InlineCSSFile, flat_text)

    flat_text = re.sub('<include\s+src="(?P<filename>[^"\']*)".*>',
                       InlineIncludeFiles, flat_text)

    # Check conditional elements, remove unsatisfied ones from the file.
    flat_text = CheckConditionalElements(flat_text)

    flat_text = re.sub('<(?!script)[^>]+?src="(?P<filename>[^"\']*)"',
                       SrcReplace, flat_text)

    # Allow custom modifications before inlining images.
    if rewrite_function:
        flat_text = rewrite_function(input_filepath, flat_text, distribution)

    # TODO(arv): Only do this inside <style> tags.
    flat_text = InlineCSSImages(flat_text)

    flat_text = re.sub('<link rel="icon".+?href="(?P<filename>[^"\']*)"',
                       SrcReplace, flat_text)

    if names_only:
        flat_text = None  # Will contains garbage if the flag is set anyway.
    return InlinedData(flat_text, inlined_files)
Example #14
0
 def GetData(self, *args):
   path, scale, req_scale = self._FindInputFile()
   data = util.ReadFile(self.grd_node.ToRealPath(path), util.BINARY)
   return _RescaleImage(data, scale, req_scale)
Example #15
0
def _GetFilesInPak(pakname):
    '''Get a list of the files that were actually included in the .pak output.
  '''
    data = util.ReadFile(pakname, util.BINARY)
    # Hackity hack...
    return [m.group(1) for m in re.finditer(r'CONTENTS_OF\((.*?)\)', data)]
Example #16
0
    def testExtractTranslations(self):
        path = util.PathFromRoot('grit/testdata')
        current_grd = grd_reader.Parse(
            StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?>
      <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir=".">
        <release seq="3">
          <messages>
            <message name="IDS_SIMPLE">
              One
            </message>
            <message name="IDS_PLACEHOLDER">
              <ph name="NUMBIRDS">%s<ex>3</ex></ph> birds
            </message>
            <message name="IDS_PLACEHOLDERS">
              <ph name="ITEM">%d<ex>1</ex></ph> of <ph name="COUNT">%d<ex>3</ex></ph>
            </message>
            <message name="IDS_REORDERED_PLACEHOLDERS">
              <ph name="ITEM">$1<ex>1</ex></ph> of <ph name="COUNT">$2<ex>3</ex></ph>
            </message>
            <message name="IDS_CHANGED">
              This is the new version
            </message>
            <message name="IDS_TWIN_1">Hello</message>
            <message name="IDS_TWIN_2">Hello</message>
            <message name="IDS_NOT_TRANSLATEABLE" translateable="false">:</message>
            <message name="IDS_LONGER_TRANSLATED">
              Removed document <ph name="FILENAME">$1<ex>c:\temp</ex></ph>
            </message>
            <message name="IDS_DIFFERENT_TWIN_1">Howdie</message>
            <message name="IDS_DIFFERENT_TWIN_2">Howdie</message>
          </messages>
          <structures>
            <structure type="dialog" name="IDD_ABOUTBOX" encoding="utf-16" file="klonk.rc" />
            <structure type="menu" name="IDC_KLONKMENU" encoding="utf-16" file="klonk.rc" />
          </structures>
        </release>
      </grit>'''), path)
        current_grd.SetOutputLanguage('en')
        current_grd.RunGatherers()

        source_rc_path = util.PathFromRoot('grit/testdata/source.rc')
        source_rc = util.ReadFile(source_rc_path, util.RAW_TEXT)
        transl_rc_path = util.PathFromRoot('grit/testdata/transl.rc')
        transl_rc = util.ReadFile(transl_rc_path, util.RAW_TEXT)

        tool = transl2tc.TranslationToTc()
        output_buf = StringIO.StringIO()
        globopts = MakeOptions()
        globopts.verbose = True
        globopts.output_stream = output_buf
        tool.Setup(globopts, [])
        translations = tool.ExtractTranslations(current_grd, source_rc,
                                                source_rc_path, transl_rc,
                                                transl_rc_path)

        values = translations.values()
        output = output_buf.getvalue()

        self.failUnless('Ein' in values)
        self.failUnless('NUMBIRDS Vogeln' in values)
        self.failUnless('ITEM von COUNT' in values)
        self.failUnless(values.count('Hallo') == 1)
        self.failIf('Dass war die alte Version' in values)
        self.failIf(':' in values)
        self.failIf('Dokument FILENAME ist entfernt worden' in values)
        self.failIf('Nicht verwendet' in values)
        self.failUnless(
            ('Howdie' in values or 'Hallo sagt man' in values)
            and not ('Howdie' in values and 'Hallo sagt man' in values))

        self.failUnless(
            'XX01XX&SkraXX02XX&HaettaXX03XXThetta er "Klonk" sem eg fylaXX04XXgonkurinnXX05XXKlonk && er [good]XX06XX&HjalpXX07XX&Um...XX08XX'
            in values)

        self.failUnless('I lagi' in values)

        self.failUnless(
            output.count(
                'Structure of message IDS_REORDERED_PLACEHOLDERS has changed'))
        self.failUnless(output.count('Message IDS_CHANGED has changed'))
        self.failUnless(
            output.count(
                'Structure of message IDS_LONGER_TRANSLATED has changed'))
        self.failUnless(
            output.count('Two different translations for "Howdie"'))
        self.failUnless(
            output.count(
                'IDD_DIFFERENT_LENGTH_IN_TRANSL has wrong # of cliques'))
Example #17
0
  def Run(self, opts, args):
    os.environ['cwd'] = os.getcwd()
    self.output_directory = '.'
    first_ids_file = None
    predetermined_ids_file = None
    whitelist_filenames = []
    assert_output_files = []
    target_platform = None
    depfile = None
    depdir = None
    whitelist_support = False
    write_only_new = False
    depend_on_stamp = False
    js_minifier = None
    replace_ellipsis = True
    (own_opts, args) = getopt.getopt(args, 'a:p:o:D:E:f:w:t:',
        ('depdir=','depfile=','assert-file-list=',
         'help',
         'output-all-resource-defines',
         'no-output-all-resource-defines',
         'no-replace-ellipsis',
         'depend-on-stamp',
         'js-minifier=',
         'write-only-new=',
         'whitelist-support'))
    for (key, val) in own_opts:
      if key == '-a':
        assert_output_files.append(val)
      elif key == '--assert-file-list':
        with open(val) as f:
          assert_output_files += f.read().splitlines()
      elif key == '-o':
        self.output_directory = val
      elif key == '-D':
        name, val = util.ParseDefine(val)
        self.defines[name] = val
      elif key == '-E':
        (env_name, env_value) = val.split('=', 1)
        os.environ[env_name] = env_value
      elif key == '-f':
        # TODO([email protected]): Remove this override once change
        # lands in WebKit.grd to specify the first_ids_file in the
        # .grd itself.
        first_ids_file = val
      elif key == '-w':
        whitelist_filenames.append(val)
      elif key == '--no-replace-ellipsis':
        replace_ellipsis = False
      elif key == '-p':
        predetermined_ids_file = val
      elif key == '-t':
        target_platform = val
      elif key == '--depdir':
        depdir = val
      elif key == '--depfile':
        depfile = val
      elif key == '--write-only-new':
        write_only_new = val != '0'
      elif key == '--depend-on-stamp':
        depend_on_stamp = True
      elif key == '--js-minifier':
        js_minifier = val
      elif key == '--whitelist-support':
        whitelist_support = True
      elif key == '--help':
        self.ShowUsage()
        sys.exit(0)

    if len(args):
      print 'This tool takes no tool-specific arguments.'
      return 2
    self.SetOptions(opts)
    if self.scons_targets:
      self.VerboseOut('Using SCons targets to identify files to output.\n')
    else:
      self.VerboseOut('Output directory: %s (absolute path: %s)\n' %
                      (self.output_directory,
                       os.path.abspath(self.output_directory)))

    if whitelist_filenames:
      self.whitelist_names = set()
      for whitelist_filename in whitelist_filenames:
        self.VerboseOut('Using whitelist: %s\n' % whitelist_filename);
        whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT)
        self.whitelist_names.update(whitelist_contents.strip().split('\n'))

    if js_minifier:
      minifier.SetJsMinifier(js_minifier)

    self.write_only_new = write_only_new

    self.res = grd_reader.Parse(opts.input,
                                debug=opts.extra_verbose,
                                first_ids_file=first_ids_file,
                                predetermined_ids_file=predetermined_ids_file,
                                defines=self.defines,
                                target_platform=target_platform)

    # Set an output context so that conditionals can use defines during the
    # gathering stage; we use a dummy language here since we are not outputting
    # a specific language.
    self.res.SetOutputLanguage('en')
    self.res.SetWhitelistSupportEnabled(whitelist_support)
    self.res.RunGatherers()

    # Replace ... with the single-character version. http://crbug.com/621772
    if replace_ellipsis:
      for node in self.res:
        if isinstance(node, message.MessageNode):
          node.SetReplaceEllipsis(True)

    self.Process()

    if assert_output_files:
      if not self.CheckAssertedOutputFiles(assert_output_files):
        return 2

    if depfile and depdir:
      self.GenerateDepfile(depfile, depdir, first_ids_file, depend_on_stamp)

    return 0
Example #18
0
 def Test(data, encoding, expected_result):
     with open('testfile', 'wb') as f:
         f.write(data)
     self.assertEqual(util.ReadFile('testfile', encoding),
                      expected_result)
Example #19
0
def DoInline(input_filename,
             grd_node,
             allow_external_script=False,
             preprocess_only=False,
             names_only=False,
             rewrite_function=None,
             filename_expansion_function=None):
    """Helper function that inlines the resources in a specified file.

  Reads input_filename, finds all the src attributes and attempts to
  inline the files they are referring to, then returns the result and
  the set of inlined files.

  Args:
    input_filename: name of file to read in
    grd_node: html node from the grd file for this include tag
    preprocess_only: Skip all HTML processing, only handle <if> and <include>.
    names_only: |nil| will be returned for the inlined contents (faster).
    rewrite_function: function(filepath, text, distribution) which will be
        called to rewrite html content before inlining images.
    filename_expansion_function: function(filename) which will be called to
        rewrite filenames before attempting to read them.
  Returns:
    a tuple of the inlined data as a string and the set of filenames
    of all the inlined files
  """
    if filename_expansion_function:
        input_filename = filename_expansion_function(input_filename)
    input_filepath = os.path.dirname(input_filename)
    distribution = GetDistribution()

    # Keep track of all the files we inline.
    inlined_files = set()

    def SrcReplace(src_match,
                   filepath=input_filepath,
                   inlined_files=inlined_files):
        """Helper function to provide SrcInlineAsDataURL with the base file path"""
        return SrcInlineAsDataURL(
            src_match,
            filepath,
            distribution,
            inlined_files,
            names_only=names_only,
            filename_expansion_function=filename_expansion_function)

    def GetFilepath(src_match, base_path=input_filepath):
        filename = src_match.group('filename')

        if filename.find(':') != -1:
            # filename is probably a URL, which we don't want to bother inlining
            return None

        filename = filename.replace('%DISTRIBUTION%', distribution)
        if filename_expansion_function:
            filename = filename_expansion_function(filename)
        return os.path.normpath(os.path.join(base_path, filename))

    def IsConditionSatisfied(src_match):
        expression = src_match.group('expression')
        return grd_node is None or grd_node.EvaluateCondition(expression)

    def CheckConditionalElements(str):
        """Helper function to conditionally inline inner elements"""
        while True:
            begin_if = _BEGIN_IF_BLOCK.search(str)
            if begin_if is None:
                if _END_IF_BLOCK.search(str) is not None:
                    raise Exception('Unmatched </if>')
                return str

            condition_satisfied = IsConditionSatisfied(begin_if)
            leading = str[0:begin_if.start()]
            content_start = begin_if.end()

            # Find matching "if" block end.
            count = 1
            pos = begin_if.end()
            while True:
                end_if = _END_IF_BLOCK.search(str, pos)
                if end_if is None:
                    raise Exception('Unmatched <if>')

                next_if = _BEGIN_IF_BLOCK.search(str, pos)
                if next_if is None or next_if.start() >= end_if.end():
                    count = count - 1
                    if count == 0:
                        break
                    pos = end_if.end()
                else:
                    count = count + 1
                    pos = next_if.end()

            content = str[content_start:end_if.start()]
            trailing = str[end_if.end():]

            if condition_satisfied:
                str = leading + CheckConditionalElements(content) + trailing
            else:
                str = leading + trailing

    def InlineFileContents(src_match, pattern, inlined_files=inlined_files):
        """Helper function to inline external files of various types"""
        filepath = GetFilepath(src_match)
        if filepath is None:
            return src_match.group(0)
        inlined_files.add(filepath)

        if names_only:
            inlined_files.update(
                GetResourceFilenames(
                    filepath,
                    allow_external_script,
                    rewrite_function,
                    filename_expansion_function=filename_expansion_function))
            return ""

        return pattern % InlineToString(
            filepath,
            grd_node,
            allow_external_script=allow_external_script,
            filename_expansion_function=filename_expansion_function)

    def InlineIncludeFiles(src_match):
        """Helper function to directly inline generic external files (without
       wrapping them with any kind of tags).
    """
        return InlineFileContents(src_match, '%s')

    def InlineScript(match):
        """Helper function to inline external script files"""
        attrs = (match.group('attrs1') + match.group('attrs2')).strip()
        if attrs:
            attrs = ' ' + attrs
        return InlineFileContents(match, '<script' + attrs + '>%s</script>')

    def InlineCSSText(text, css_filepath):
        """Helper function that inlines external resources in CSS text"""
        filepath = os.path.dirname(css_filepath)
        # Allow custom modifications before inlining images.
        if rewrite_function:
            text = rewrite_function(filepath, text, distribution)
        text = InlineCSSImages(text, filepath)
        return InlineCSSImports(text, filepath)

    def InlineCSSFile(src_match, pattern, base_path=input_filepath):
        """Helper function to inline external CSS files.

    Args:
      src_match: A regular expression match with a named group named "filename".
      pattern: The pattern to replace with the contents of the CSS file.
      base_path: The base path to use for resolving the CSS file.

    Returns:
      The text that should replace the reference to the CSS file.
    """
        filepath = GetFilepath(src_match, base_path)
        if filepath is None:
            return src_match.group(0)

        # Even if names_only is set, the CSS file needs to be opened, because it
        # can link to images that need to be added to the file set.
        inlined_files.add(filepath)
        # When resolving CSS files we need to pass in the path so that relative URLs
        # can be resolved.
        return pattern % InlineCSSText(util.ReadFile(filepath, util.BINARY),
                                       filepath)

    def InlineCSSImages(text, filepath=input_filepath):
        """Helper function that inlines external images in CSS backgrounds."""
        # Replace contents of url() for css attributes: content, background,
        # or *-image.
        return re.sub(
            '(content|background|[\w-]*-image):[^;]*' +
            '(url\((?P<quote1>"|\'|)[^"\'()]*(?P=quote1)\)|' + 'image-set\(' +
            '([ ]*url\((?P<quote2>"|\'|)[^"\'()]*(?P=quote2)\)' +
            '[ ]*[0-9.]*x[ ]*(,[ ]*)?)+\))',
            lambda m: InlineCSSUrls(m, filepath), text)

    def InlineCSSUrls(src_match, filepath=input_filepath):
        """Helper function that inlines each url on a CSS image rule match."""
        # Replace contents of url() references in matches.
        return re.sub(
            'url\((?P<quote>"|\'|)(?P<filename>[^"\'()]*)(?P=quote)\)',
            lambda m: SrcReplace(m, filepath), src_match.group(0))

    def InlineCSSImports(text, filepath=input_filepath):
        """Helper function that inlines CSS files included via the @import
       directive.
    """
        return re.sub(
            '@import\s+url\((?P<quote>"|\'|)(?P<filename>[^"\'()]*)' +
            '(?P=quote)\);', lambda m: InlineCSSFile(m, '%s', filepath), text)

    flat_text = util.ReadFile(input_filename, util.BINARY)

    # Check conditional elements, remove unsatisfied ones from the file. We do
    # this twice. The first pass is so that we don't even bother calling
    # InlineScript, InlineCSSFile and InlineIncludeFiles on text we're eventually
    # going to throw out anyway.
    flat_text = CheckConditionalElements(flat_text)

    if not preprocess_only:
        if not allow_external_script:
            # We need to inline css and js before we inline images so that image
            # references gets inlined in the css and js
            flat_text = re.sub(
                '<script (?P<attrs1>.*?)src="(?P<filename>[^"\']*)"' +
                '(?P<attrs2>.*?)></script>', InlineScript, flat_text)

        flat_text = _STYLESHEET_RE.sub(
            lambda m: InlineCSSFile(m, '<style>%s</style>'), flat_text)

    flat_text = _INCLUDE_RE.sub(InlineIncludeFiles, flat_text)

    # Check conditional elements, second pass. This catches conditionals in any
    # of the text we just inlined.
    flat_text = CheckConditionalElements(flat_text)

    if not preprocess_only:
        # Allow custom modifications before inlining images.
        if rewrite_function:
            flat_text = rewrite_function(input_filepath, flat_text,
                                         distribution)
        flat_text = _SRC_RE.sub(SrcReplace, flat_text)

        # TODO(arv): Only do this inside <style> tags.
        flat_text = InlineCSSImages(flat_text)

        flat_text = _ICON_RE.sub(SrcReplace, flat_text)

    if names_only:
        flat_text = None  # Will contains garbage if the flag is set anyway.
    return InlinedData(flat_text, inlined_files)
Example #20
0
def DoInline(input_filename,
             grd_node,
             allow_external_script=False,
             preprocess_only=False,
             names_only=False,
             strip_whitespace=False,
             rewrite_function=None,
             filename_expansion_function=None):
    """Helper function that inlines the resources in a specified file.

  Reads input_filename, finds all the src attributes and attempts to
  inline the files they are referring to, then returns the result and
  the set of inlined files.

  Args:
    input_filename: name of file to read in
    grd_node: html node from the grd file for this include tag
    preprocess_only: Skip all HTML processing, only handle <if> and <include>.
    names_only: |nil| will be returned for the inlined contents (faster).
    strip_whitespace: remove whitespace and comments in the input files.
    rewrite_function: function(filepath, text, distribution) which will be
        called to rewrite html content before inlining images.
    filename_expansion_function: function(filename) which will be called to
        rewrite filenames before attempting to read them.
  Returns:
    a tuple of the inlined data as a string and the set of filenames
    of all the inlined files
  """
    if filename_expansion_function:
        input_filename = filename_expansion_function(input_filename)
    input_filepath = os.path.dirname(input_filename)
    distribution = GetDistribution()

    # Keep track of all the files we inline.
    inlined_files = set()

    def SrcReplace(src_match,
                   filepath=input_filepath,
                   inlined_files=inlined_files):
        """Helper function to provide SrcInlineAsDataURL with the base file path"""
        return SrcInlineAsDataURL(
            src_match,
            filepath,
            distribution,
            inlined_files,
            names_only=names_only,
            filename_expansion_function=filename_expansion_function)

    def SrcsetReplace(srcset_match,
                      filepath=input_filepath,
                      inlined_files=inlined_files):
        """Helper function to provide SrcsetInlineAsDataURL with the base file
    path.
    """
        return SrcsetInlineAsDataURL(
            srcset_match,
            filepath,
            distribution,
            inlined_files,
            names_only=names_only,
            filename_expansion_function=filename_expansion_function)

    def GetFilepath(src_match, base_path=input_filepath):
        filename = [
            v for k, v in src_match.groupdict().items()
            if k.startswith('file') and v
        ][0]

        if filename.find(':') != -1:
            # filename is probably a URL, which we don't want to bother inlining
            return None

        filename = filename.replace('%DISTRIBUTION%', distribution)
        if filename_expansion_function:
            filename = filename_expansion_function(filename)
        return os.path.normpath(os.path.join(base_path, filename))

    def InlineFileContents(src_match,
                           pattern,
                           inlined_files=inlined_files,
                           strip_whitespace=False):
        """Helper function to inline external files of various types"""
        filepath = GetFilepath(src_match)
        if filepath is None:
            return src_match.group(0)
        inlined_files.add(filepath)

        if names_only:
            inlined_files.update(
                GetResourceFilenames(
                    filepath,
                    grd_node,
                    allow_external_script,
                    rewrite_function,
                    filename_expansion_function=filename_expansion_function))
            return ""
        # To recursively save inlined files, we need InlinedData instance returned
        # by DoInline.
        inlined_data_inst = DoInline(
            filepath,
            grd_node,
            allow_external_script=allow_external_script,
            preprocess_only=preprocess_only,
            strip_whitespace=strip_whitespace,
            filename_expansion_function=filename_expansion_function)

        inlined_files.update(inlined_data_inst.inlined_files)

        return pattern % inlined_data_inst.inlined_data

    def InlineIncludeFiles(src_match):
        """Helper function to directly inline generic external files (without
       wrapping them with any kind of tags).
    """
        return InlineFileContents(src_match, '%s')

    def InlineScript(match):
        """Helper function to inline external script files"""
        attrs = (match.group('attrs1') + match.group('attrs2')).strip()
        if attrs:
            attrs = ' ' + attrs
        return InlineFileContents(match,
                                  '<script' + attrs + '>%s</script>',
                                  strip_whitespace=True)

    def InlineCSSText(text, css_filepath):
        """Helper function that inlines external resources in CSS text"""
        filepath = os.path.dirname(css_filepath)
        # Allow custom modifications before inlining images.
        if rewrite_function:
            text = rewrite_function(filepath, text, distribution)
        text = InlineCSSImages(text, filepath)
        return InlineCSSImports(text, filepath)

    def InlineCSSFile(src_match, pattern, base_path=input_filepath):
        """Helper function to inline external CSS files.

    Args:
      src_match: A regular expression match with a named group named "filename".
      pattern: The pattern to replace with the contents of the CSS file.
      base_path: The base path to use for resolving the CSS file.

    Returns:
      The text that should replace the reference to the CSS file.
    """
        filepath = GetFilepath(src_match, base_path)
        if filepath is None:
            return src_match.group(0)

        # Even if names_only is set, the CSS file needs to be opened, because it
        # can link to images that need to be added to the file set.
        inlined_files.add(filepath)

        # Inline stylesheets included in this css file.
        text = _INCLUDE_RE.sub(InlineIncludeFiles,
                               util.ReadFile(filepath, 'utf-8'))
        # When resolving CSS files we need to pass in the path so that relative URLs
        # can be resolved.

        return pattern % InlineCSSText(text, filepath)

    def GetUrlRegexString(postfix=''):
        """Helper function that returns a string for a regex that matches url('')
       but not url([[ ]]) or url({{ }}). Appends |postfix| to group names.
    """
        url_re = (r'url\((?!\[\[|{{)(?P<q%s>"|\'|)(?P<filename%s>[^"\'()]*)'
                  r'(?P=q%s)\)')
        return url_re % (postfix, postfix, postfix)

    def InlineCSSImages(text, filepath=input_filepath):
        """Helper function that inlines external images in CSS backgrounds."""
        # Replace contents of url() for css attributes: content, background,
        # or *-image.
        property_re = r'(content|background|[\w-]*-image):[^;]*'
        # Replace group names to prevent duplicates when forming value_re.
        image_set_value_re = (r'image-set\(([ ]*' + GetUrlRegexString('2') +
                              r'[ ]*[0-9.]*x[ ]*(,[ ]*)?)+\)')
        value_re = '(%s|%s)' % (GetUrlRegexString(), image_set_value_re)
        css_re = property_re + value_re
        return re.sub(css_re, lambda m: InlineCSSUrls(m, filepath), text)

    def InlineCSSUrls(src_match, filepath=input_filepath):
        """Helper function that inlines each url on a CSS image rule match."""
        # Replace contents of url() references in matches.
        return re.sub(GetUrlRegexString(), lambda m: SrcReplace(m, filepath),
                      src_match.group(0))

    def InlineCSSImports(text, filepath=input_filepath):
        """Helper function that inlines CSS files included via the @import
       directive.
    """
        return re.sub(r'@import\s+' + GetUrlRegexString() + r';',
                      lambda m: InlineCSSFile(m, '%s', filepath), text)

    flat_text = util.ReadFile(input_filename, 'utf-8')

    # Check conditional elements, remove unsatisfied ones from the file. We do
    # this twice. The first pass is so that we don't even bother calling
    # InlineScript, InlineCSSFile and InlineIncludeFiles on text we're eventually
    # going to throw out anyway.
    flat_text = CheckConditionalElements(grd_node, flat_text)

    flat_text = _INCLUDE_RE.sub(InlineIncludeFiles, flat_text)

    if not preprocess_only:
        if strip_whitespace:
            flat_text = minifier.Minify(flat_text.encode('utf-8'),
                                        input_filename).decode('utf-8')

        if not allow_external_script:
            # We need to inline css and js before we inline images so that image
            # references gets inlined in the css and js
            flat_text = re.sub(
                r'<script (?P<attrs1>.*?)src="(?P<filename>[^"\']*)"'
                r'(?P<attrs2>.*?)></script>', InlineScript, flat_text)

        flat_text = _STYLESHEET_RE.sub(
            lambda m: InlineCSSFile(m, '<style>%s</style>'), flat_text)

    # Check conditional elements, second pass. This catches conditionals in any
    # of the text we just inlined.
    flat_text = CheckConditionalElements(grd_node, flat_text)

    # Allow custom modifications before inlining images.
    if rewrite_function:
        flat_text = rewrite_function(input_filepath, flat_text, distribution)

    if not preprocess_only:
        flat_text = _SRC_RE.sub(SrcReplace, flat_text)
        flat_text = _SRCSET_RE.sub(SrcsetReplace, flat_text)

        # TODO(arv): Only do this inside <style> tags.
        flat_text = InlineCSSImages(flat_text)

        flat_text = _ICON_RE.sub(SrcReplace, flat_text)

    if names_only:
        flat_text = None  # Will contains garbage if the flag is set anyway.
    return InlinedData(flat_text, inlined_files)
 def GetData(self, *args):
     path, scale, req_scale = self._FindInputFile()
     data = util.ReadFile(self.grd_node.ToRealPath(path), util.BINARY)
     data = _RescaleImage(data, scale, req_scale)
     data = _MoveSpecialChunksToFront(data)
     return data
Example #22
0
def main():

    parser = argparse.ArgumentParser(description='Replace the Google Chrome incognito image with Pedobear')
    parser.add_argument('--restore', action='store_true', help='Restore from backup')

    args = parser.parse_args()

    version = check_output(["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "--version"]).replace("Google Chrome", "").strip()
    resource_path = "/Applications/Google Chrome.app/Contents/Versions/" + version + "/Google Chrome Framework.framework/Resources/resources.pak"
    resource_backup_path = "/Applications/Google Chrome.app/Contents/Versions/" + version + "/Google Chrome Framework.framework/Resources/resources.bak"

    if os.path.isfile(resource_path):

      if args.restore:

        if os.path.isfile(resource_backup_path):
          print "Restoring from backup..."
          shutil.copy2(resource_backup_path, resource_path)
          print "Resource file restored."
        else:
          print "Tried to restore, but backup file not found at " + resource_backup_path
        return

      print "Resource file found."

      data = ReadDataPack(resource_path)

      original_1x = util.ReadFile('1x_base64png_original.txt', UTF8)
      original_2x = util.ReadFile('2x_base64png_original.txt', UTF8)

      pedobear_1x = util.ReadFile('1x_base64png_pedobear.txt', UTF8)
      pedobear_2x = util.ReadFile('2x_base64png_pedobear.txt', UTF8)

      found = False
      already_patched = False

      data2 = {}
      for (resource_id, text) in data.resources.iteritems():
        if original_1x in text:
          found = True
          text = text.replace(original_1x, pedobear_1x)
        elif pedobear_1x in text:
          already_patched = True
        if original_2x in text:
          found = True
          text = text.replace(original_2x, pedobear_2x)
        elif pedobear_2x in text:
          already_patched = True
        data2[resource_id] = text

      if found:
        print "Incognito images found."
        print "Creating backup in " + resource_backup_path
        shutil.copy2(resource_path, resource_backup_path)
        print "Patching " + resource_path
        WriteDataPack(data2, resource_path, UTF8)
        print "Done! Quit and reopen Chrome."
      elif already_patched:
        print "Resource file is already patched."        
      else:
        print "Could not find incognito image in resource file, aborting..."

    else:
      print "Could not find resource.pak to patch, aborting..."