def write_file(self): """ Creates a backup-file and writes all translations back to its file-path. """ self._create_backup_file() logging.info('Writing translations of language_code {language_code} to file {file_}' ''.format(language_code=self.language_code, file_=os.path.basename(self.file_path))) all_translations = list(self.translations) + list(self.incomplete_translations) def sorting_func(translation): return num_of_words_in_string(translation.key), translation.key.lower() sorted_translations = sorted( all_translations, key=sorting_func) stringified_translations = [] def grouping_func(translation): return num_of_words_in_string(translation.key) for length, group in itertools.groupby( sorted_translations, key=grouping_func): stringified_translations.append('\n/* {num} {n_words} */' ''.format(num=length, n_words=n_(length, 'word'))) stringified_translations += [str(trans) for trans in group] content = '\n'.join(stringified_translations) content += '\n' with open(self.file_path, mode='w') as outfile: outfile.write(content)
def collect_localized_strings(implementation_file_paths, custom_macros=()): """ Collects all occurrences of the DEFAULT_MACRO and the given custom_macros in the given implementation_file_paths and returns the set of LocalizedString instances. :param implementation_file_paths: The paths to the .m-implementation-files that should be searched. :param custom_macros: Optional custom macros that are used in the project. See NSLocalizedStringMacro for further information. :returns: A set of LocalizedString instances representing all different localizable strings that are used throughout the project. For the specs of how they are different, see LocalizedString.__hash__() and LocalizedString.__eq__(). :type implementation_file_paths: list[str] :type custom_macros: list[NSLocalizedStringMacro] :rtype: set[LocalizedString] """ result = set() macros = [DEFAULT_MACRO] + list(custom_macros) logging.info('Searching for macros: {macros}' ''.format(macros=", ".join(str(macro) for macro in macros))) occurrence_counts = {macro: 0 for macro in macros} for file_path in implementation_file_paths: is_objc_file = os.path.splitext(file_path)[1] == '.m' file_result = set() occurrences_in_file = {} with open(file_path, mode='r') as implementation_file: lines = implementation_file.readlines() file_ = os.path.basename(file_path) logging.debug('Reading file {file_}.' ''.format(file_=file_)) for macro in macros: occurrences_in_file[macro] = 0 for line_index, line in enumerate(lines): line_number = line_index + 1 for macro in macros: rgx = macro.get_regex(is_objc_file=is_objc_file) matches = re.findall(rgx, line) if not matches: continue else: num_of_matches = len(matches) occurrence_counts[macro] += num_of_matches occurrences_in_file[macro] += num_of_matches for occurrence_index, match in enumerate(matches): occurrence_number = occurrence_index + 1 if macro.has_comment: key, comment = match else: key = match comment = None if not is_literal_string(key): logging.warning('Attention, there seems to be a dynamic usage of {macro} in file {file_}, ' 'line {line_number}, occurrence number {occurrence_number}! \n' 'Please be sure to check manually that every possible value of the ' 'supplied variable "{variable}" has sufficient localizations!' ''.format(macro=macro, file_=file_, line_number=line_number, occurrence_number=occurrence_number, variable=key)) localized_string = DynamicLocalizedString(macro=macro, strng=key, comment=comment, full_sourcefile_path=file_path, sourcefile_line_number=line_number, line_occurrence_number=occurrence_number) else: localized_string = LocalizedString(macro=macro, strng=key, comment=comment, full_sourcefile_path=file_path, sourcefile_line_number=line_number, line_occurrence_number=occurrence_number) file_result.add(localized_string) for macro in macros: num_of_occurrences_in_file = occurrences_in_file[macro] if num_of_occurrences_in_file: logging.debug('Found {num} {n_occurrence} of macro {macro} in file {file_}' ''.format(num=num_of_occurrences_in_file, n_occurrence=n_(num_of_occurrences_in_file, 'occurrence'), macro=macro, file_=file_)) if len(file_result): logging.debug('Found keys and comments: (key, comment) {keys_and_comments}' ''.format(keys_and_comments=[(strng.key, strng.comment) for strng in file_result])) result = result.union(file_result) for macro in macros: num = occurrence_counts[macro] logging.info('Found {num} {n_occurrence} of macro {macro} in total.' ''.format(num=num, n_occurrence=n_(num, 'occurrence'), macro=macro)) logging.info('Found {num} distinct localizable {n_string} in total.' ''.format(num=len(result), n_string=n_(len(result), 'string'))) return result