1#!/usr/bin/env python 2# Copyright (c) 2012 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'''Interface for all gatherers. 7''' 8 9 10import os.path 11import types 12 13from grit import clique 14from grit import util 15 16 17class GathererBase(object): 18 '''Interface for all gatherer implementations. Subclasses must implement 19 all methods that raise NotImplemented.''' 20 21 def __init__(self, rc_file, extkey=None, encoding='cp1252', is_skeleton=False): 22 '''Initializes the gatherer object's attributes, but does not attempt to 23 read the input file. 24 25 Args: 26 rc_file: The 'file' attribute of the <structure> node (usually the 27 relative path to the source file). 28 extkey: e.g. 'ID_MY_DIALOG' 29 encoding: e.g. 'utf-8' 30 is_skeleton: Indicates whether this gatherer is a skeleton gatherer, in 31 which case we should not do some types of processing on the 32 translateable bits. 33 ''' 34 self.rc_file = rc_file 35 self.extkey = extkey 36 self.encoding = encoding 37 # A default uberclique that is local to this object. Users can override 38 # this with the uberclique they are using. 39 self.uberclique = clique.UberClique() 40 # Indicates whether this gatherer is a skeleton gatherer, in which case 41 # we should not do some types of processing on the translateable bits. 42 self.is_skeleton = is_skeleton 43 # Stores the grd node on which this gatherer is running. This allows 44 # evaluating expressions. 45 self.grd_node = None 46 47 def SetAttributes(self, attrs): 48 '''Sets node attributes used by the gatherer. 49 50 By default, this does nothing. If special handling is desired, it should be 51 overridden by the child gatherer. 52 53 Args: 54 attrs: The mapping of node attributes. 55 ''' 56 pass 57 58 def SetDefines(self, defines): 59 '''Sets global defines used by the gatherer. 60 61 By default, this does nothing. If special handling is desired, it should be 62 overridden by the child gatherer. 63 64 Args: 65 defines: The mapping of define values. 66 ''' 67 pass 68 69 def SetGrdNode(self, node): 70 '''Sets the grd node on which this gatherer is running. 71 ''' 72 self.grd_node = node 73 74 def SetUberClique(self, uberclique): 75 '''Overrides the default uberclique so that cliques created by this object 76 become part of the uberclique supplied by the user. 77 ''' 78 self.uberclique = uberclique 79 80 def Parse(self): 81 '''Reads and parses the contents of what is being gathered.''' 82 raise NotImplementedError() 83 84 def GetData(self, lang, encoding): 85 '''Returns the data to be added to the DataPack for this node or None if 86 this node does not add a DataPack entry. 87 ''' 88 return None 89 90 def GetText(self): 91 '''Returns the text of what is being gathered.''' 92 raise NotImplementedError() 93 94 def GetTextualIds(self): 95 '''Returns the mnemonic IDs that need to be defined for the resource 96 being gathered to compile correctly.''' 97 return [] 98 99 def GetCliques(self): 100 '''Returns the MessageClique objects for all translateable portions.''' 101 return [] 102 103 def GetInputPath(self): 104 return self.rc_file 105 106 def GetHtmlResourceFilenames(self): 107 """Returns a set of all filenames inlined by this gatherer.""" 108 return [] 109 110 def Translate(self, lang, pseudo_if_not_available=True, 111 skeleton_gatherer=None, fallback_to_english=False): 112 '''Returns the resource being gathered, with translateable portions filled 113 with the translation for language 'lang'. 114 115 If pseudo_if_not_available is true, a pseudotranslation will be used for any 116 message that doesn't have a real translation available. 117 118 If no translation is available and pseudo_if_not_available is false, 119 fallback_to_english controls the behavior. If it is false, throw an error. 120 If it is true, use the English version of the message as its own 121 "translation". 122 123 If skeleton_gatherer is specified, the translation will use the nontranslateable 124 parts from the gatherer 'skeleton_gatherer', which must be of the same type 125 as 'self'. 126 127 If fallback_to_english 128 129 Args: 130 lang: 'en' 131 pseudo_if_not_available: True | False 132 skeleton_gatherer: other_gatherer 133 fallback_to_english: True | False 134 135 Return: 136 e.g. 'ID_THIS_SECTION TYPE\n...BEGIN\n "Translated message"\n......\nEND' 137 138 Raises: 139 grit.exception.NotReady() if used before Parse() has been successfully 140 called. 141 grit.exception.NoSuchTranslation() if 'pseudo_if_not_available' and 142 fallback_to_english are both false and there is no translation for the 143 requested language. 144 ''' 145 raise NotImplementedError() 146 147 def SubstituteMessages(self, substituter): 148 '''Applies substitutions to all messages in the gatherer. 149 150 Args: 151 substituter: a grit.util.Substituter object. 152 ''' 153 pass 154 155 def SetFilenameExpansionFunction(self, fn): 156 '''Sets a function for rewriting filenames before gathering.''' 157 pass 158 159 # TODO(benrg): Move this elsewhere, since it isn't part of the interface. 160 def _LoadInputFile(self): 161 '''A convenience function for subclasses that loads the contents of the 162 input file. 163 ''' 164 if isinstance(self.rc_file, types.StringTypes): 165 path = self.GetInputPath() 166 # Hack: some unit tests supply an absolute path and no root node. 167 if not os.path.isabs(path): 168 path = self.grd_node.ToRealPath(path) 169 return util.ReadFile(path, self.encoding) 170 else: 171 return self.rc_file.read() 172