forked from upstream-mirrors/OpenTracks
remove unused i18n scripts
This commit is contained in:
@@ -1,56 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
# This script retrieves the value of a given named string from all indicated
|
|
||||||
# strings.xml files. If invoked in a project directory (a directory with a
|
|
||||||
# 'res' subdirectory), and if no strings.xml files are provided, the script
|
|
||||||
# will automatically analyze res/values*/strings.xml
|
|
||||||
|
|
||||||
PROGNAME=$(basename "$0")
|
|
||||||
|
|
||||||
function usage() {
|
|
||||||
echo "Usage: ${PROGNAME} string_name [file file..]" >&2
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
function die() {
|
|
||||||
echo "${PROGNAME}: $@" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ "$#" -lt 1 ]] ; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
name=$1
|
|
||||||
shift
|
|
||||||
|
|
||||||
files=
|
|
||||||
if [[ $# -eq 0 ]] ; then
|
|
||||||
if [[ -d res ]] ; then
|
|
||||||
files=res/values*/strings.xml
|
|
||||||
else
|
|
||||||
die "invoked outside of project root with no file arguments"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
files="$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
for file in $files ; do
|
|
||||||
echo === $file
|
|
||||||
xmllint --xpath /resources/string[@name=\"$name\"] $file
|
|
||||||
echo
|
|
||||||
done
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>i18n</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.python.pydev.PyDevBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.python.pydev.pythonNature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<?eclipse-pydev version="1.0"?>
|
|
||||||
|
|
||||||
<pydev_project>
|
|
||||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
|
||||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
|
|
||||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
|
||||||
<path>/i18n/src</path>
|
|
||||||
</pydev_pathproperty>
|
|
||||||
</pydev_project>
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
'''
|
|
||||||
Module for dealing with resource files (but not their contents).
|
|
||||||
|
|
||||||
@author: Rodrigo Damazio
|
|
||||||
'''
|
|
||||||
import os.path
|
|
||||||
from glob import glob
|
|
||||||
import re
|
|
||||||
|
|
||||||
MYTRACKS_RES_DIR = 'MyTracks/res'
|
|
||||||
ANDROID_MASTER_VALUES = 'values'
|
|
||||||
ANDROID_VALUES_MASK = 'values-*'
|
|
||||||
|
|
||||||
|
|
||||||
def GetMyTracksDir():
|
|
||||||
'''
|
|
||||||
Returns the directory in which the MyTracks directory is located.
|
|
||||||
'''
|
|
||||||
path = os.getcwd()
|
|
||||||
while not os.path.isdir(os.path.join(path, MYTRACKS_RES_DIR)):
|
|
||||||
if path == '/':
|
|
||||||
raise 'Not in My Tracks project'
|
|
||||||
|
|
||||||
# Go up one level
|
|
||||||
path = os.path.split(path)[0]
|
|
||||||
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def GetAllLanguageFiles():
|
|
||||||
'''
|
|
||||||
Returns a mapping from all found languages to their respective directories.
|
|
||||||
'''
|
|
||||||
mytracks_path = GetMyTracksDir()
|
|
||||||
res_dir = os.path.join(mytracks_path, MYTRACKS_RES_DIR, ANDROID_VALUES_MASK)
|
|
||||||
language_dirs = glob(res_dir)
|
|
||||||
master_dir = os.path.join(mytracks_path, MYTRACKS_RES_DIR, ANDROID_MASTER_VALUES)
|
|
||||||
if len(language_dirs) == 0:
|
|
||||||
raise 'No languages found!'
|
|
||||||
if not os.path.isdir(master_dir):
|
|
||||||
raise 'Couldn\'t find master file'
|
|
||||||
|
|
||||||
language_tuples = [(re.findall(r'.*values-([A-Za-z-]+)', dir)[0],dir) for dir in language_dirs]
|
|
||||||
language_tuples.append(('en', master_dir))
|
|
||||||
return dict(language_tuples)
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
'''
|
|
||||||
Module which brings history information about files from Mercurial.
|
|
||||||
|
|
||||||
@author: Rodrigo Damazio
|
|
||||||
'''
|
|
||||||
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
REVISION_REGEX = re.compile(r'(?P<hash>[0-9a-f]{12}):.*')
|
|
||||||
|
|
||||||
def _GetOutputLines(args):
|
|
||||||
'''
|
|
||||||
Runs an external process and returns its output as a list of lines.
|
|
||||||
|
|
||||||
@param args: the arguments to run
|
|
||||||
'''
|
|
||||||
process = subprocess.Popen(args,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
universal_newlines = True,
|
|
||||||
shell = False)
|
|
||||||
output = process.communicate()[0]
|
|
||||||
return output.splitlines()
|
|
||||||
|
|
||||||
|
|
||||||
def FillMercurialRevisions(filename, parsed_file):
|
|
||||||
'''
|
|
||||||
Fills the revs attribute of all strings in the given parsed file with
|
|
||||||
a list of revisions that touched the lines corresponding to that string.
|
|
||||||
|
|
||||||
@param filename: the name of the file to get history for
|
|
||||||
@param parsed_file: the parsed file to modify
|
|
||||||
'''
|
|
||||||
# Take output of hg annotate to get revision of each line
|
|
||||||
output_lines = _GetOutputLines(['hg', 'annotate', '-c', filename])
|
|
||||||
|
|
||||||
# Create a map of line -> revision (key is list index, line 0 doesn't exist)
|
|
||||||
line_revs = ['dummy']
|
|
||||||
for line in output_lines:
|
|
||||||
rev_match = REVISION_REGEX.match(line)
|
|
||||||
if not rev_match:
|
|
||||||
raise 'Unexpected line of output from hg: %s' % line
|
|
||||||
rev_hash = rev_match.group('hash')
|
|
||||||
line_revs.append(rev_hash)
|
|
||||||
|
|
||||||
for str in parsed_file.itervalues():
|
|
||||||
# Get the lines that correspond to each string
|
|
||||||
start_line = str['startLine']
|
|
||||||
end_line = str['endLine']
|
|
||||||
|
|
||||||
# Get the revisions that touched those lines
|
|
||||||
revs = []
|
|
||||||
for line_number in range(start_line, end_line + 1):
|
|
||||||
revs.append(line_revs[line_number])
|
|
||||||
|
|
||||||
# Merge with any revisions that were already there
|
|
||||||
# (for explict revision specification)
|
|
||||||
if 'revs' in str:
|
|
||||||
revs += str['revs']
|
|
||||||
|
|
||||||
# Assign the revisions to the string
|
|
||||||
str['revs'] = frozenset(revs)
|
|
||||||
|
|
||||||
def DoesRevisionSuperceed(filename, rev1, rev2):
|
|
||||||
'''
|
|
||||||
Tells whether a revision superceeds another.
|
|
||||||
This essentially means that the older revision is an ancestor of the newer
|
|
||||||
one.
|
|
||||||
This also returns True if the two revisions are the same.
|
|
||||||
|
|
||||||
@param rev1: the revision that may be superceeding the other
|
|
||||||
@param rev2: the revision that may be superceeded
|
|
||||||
@return: True if rev1 superceeds rev2 or they're the same
|
|
||||||
'''
|
|
||||||
if rev1 == rev2:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# TODO: Add filename
|
|
||||||
args = ['hg', 'log', '-r', 'ancestors(%s)' % rev1, '--template', '{node|short}\n', filename]
|
|
||||||
output_lines = _GetOutputLines(args)
|
|
||||||
|
|
||||||
return rev2 in output_lines
|
|
||||||
|
|
||||||
def NewestRevision(filename, rev1, rev2):
|
|
||||||
'''
|
|
||||||
Returns which of two revisions is closest to the head of the repository.
|
|
||||||
If none of them is the ancestor of the other, then we return either one.
|
|
||||||
|
|
||||||
@param rev1: the first revision
|
|
||||||
@param rev2: the second revision
|
|
||||||
'''
|
|
||||||
if DoesRevisionSuperceed(filename, rev1, rev2):
|
|
||||||
return rev1
|
|
||||||
return rev2
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
'''
|
|
||||||
Entry point for My Tracks i18n tool.
|
|
||||||
|
|
||||||
@author: Rodrigo Damazio
|
|
||||||
'''
|
|
||||||
|
|
||||||
import mytracks.files
|
|
||||||
import mytracks.translate
|
|
||||||
import mytracks.validate
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def Usage():
|
|
||||||
print 'Usage: %s <command> [<language> ...]\n' % sys.argv[0]
|
|
||||||
print 'Commands are:'
|
|
||||||
print ' cleanup'
|
|
||||||
print ' translate'
|
|
||||||
print ' validate'
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def Translate(languages):
|
|
||||||
'''
|
|
||||||
Asks the user to interactively translate any missing or oudated strings from
|
|
||||||
the files for the given languages.
|
|
||||||
|
|
||||||
@param languages: the languages to translate
|
|
||||||
'''
|
|
||||||
validator = mytracks.validate.Validator(languages)
|
|
||||||
validator.Validate()
|
|
||||||
missing = validator.missing_in_lang()
|
|
||||||
outdated = validator.outdated_in_lang()
|
|
||||||
|
|
||||||
for lang in languages:
|
|
||||||
untranslated = missing[lang] + outdated[lang]
|
|
||||||
|
|
||||||
if len(untranslated) == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
translator = mytracks.translate.Translator(lang)
|
|
||||||
translator.Translate(untranslated)
|
|
||||||
|
|
||||||
|
|
||||||
def Validate(languages):
|
|
||||||
'''
|
|
||||||
Computes and displays errors in the string files for the given languages.
|
|
||||||
|
|
||||||
@param languages: the languages to compute for
|
|
||||||
'''
|
|
||||||
validator = mytracks.validate.Validator(languages)
|
|
||||||
validator.Validate()
|
|
||||||
|
|
||||||
error_count = 0
|
|
||||||
if (validator.valid()):
|
|
||||||
print 'All files OK'
|
|
||||||
else:
|
|
||||||
for lang, missing in validator.missing_in_master().iteritems():
|
|
||||||
print 'Missing in master, present in %s: %s:' % (lang, str(missing))
|
|
||||||
error_count = error_count + len(missing)
|
|
||||||
for lang, missing in validator.missing_in_lang().iteritems():
|
|
||||||
print 'Missing in %s, present in master: %s:' % (lang, str(missing))
|
|
||||||
error_count = error_count + len(missing)
|
|
||||||
for lang, outdated in validator.outdated_in_lang().iteritems():
|
|
||||||
print 'Outdated in %s: %s:' % (lang, str(outdated))
|
|
||||||
error_count = error_count + len(outdated)
|
|
||||||
|
|
||||||
return error_count
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
argv = sys.argv
|
|
||||||
argc = len(argv)
|
|
||||||
if argc < 2:
|
|
||||||
Usage()
|
|
||||||
|
|
||||||
languages = mytracks.files.GetAllLanguageFiles()
|
|
||||||
if argc == 3:
|
|
||||||
langs = set(argv[2:])
|
|
||||||
if not langs.issubset(languages):
|
|
||||||
raise 'Language(s) not found'
|
|
||||||
|
|
||||||
# Filter just to the languages specified
|
|
||||||
languages = dict((lang, lang_file)
|
|
||||||
for lang, lang_file in languages.iteritems()
|
|
||||||
if lang in langs or lang == 'en' )
|
|
||||||
|
|
||||||
cmd = argv[1]
|
|
||||||
if cmd == 'translate':
|
|
||||||
Translate(languages)
|
|
||||||
elif cmd == 'validate':
|
|
||||||
error_count = Validate(languages)
|
|
||||||
else:
|
|
||||||
Usage()
|
|
||||||
error_count = 0
|
|
||||||
|
|
||||||
print '%d errors found.' % error_count
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
'''
|
|
||||||
Module which parses a string XML file.
|
|
||||||
|
|
||||||
@author: Rodrigo Damazio
|
|
||||||
'''
|
|
||||||
|
|
||||||
from xml.parsers.expat import ParserCreate
|
|
||||||
import re
|
|
||||||
#import xml.etree.ElementTree as ET
|
|
||||||
|
|
||||||
class StringsParser(object):
|
|
||||||
'''
|
|
||||||
Parser for string XML files.
|
|
||||||
|
|
||||||
This object is not thread-safe and should be used for parsing a single file at
|
|
||||||
a time, only.
|
|
||||||
'''
|
|
||||||
|
|
||||||
def Parse(self, file):
|
|
||||||
'''
|
|
||||||
Parses the given file and returns a dictionary mapping keys to an object
|
|
||||||
with attributes for that key, such as the value, start/end line and explicit
|
|
||||||
revisions.
|
|
||||||
|
|
||||||
In addition to the standard XML format of the strings file, this parser
|
|
||||||
supports an annotation inside comments, in one of these formats:
|
|
||||||
|
|
||||||
<!-- KEEP_PARENT name="bla" -->
|
|
||||||
<!-- KEEP_PARENT name="bla" rev="123456789012" -->
|
|
||||||
|
|
||||||
Such an annotation indicates that we're explicitly inheriting form the
|
|
||||||
master file (and the optional revision says that this decision is compatible
|
|
||||||
with the master file up to that revision).
|
|
||||||
|
|
||||||
@param file: the name of the file to parse
|
|
||||||
'''
|
|
||||||
self._Reset()
|
|
||||||
|
|
||||||
# Unfortunately expat is the only parser that will give us line numbers
|
|
||||||
self._xml_parser = ParserCreate()
|
|
||||||
self._xml_parser.StartElementHandler = self._StartElementHandler
|
|
||||||
self._xml_parser.EndElementHandler = self._EndElementHandler
|
|
||||||
self._xml_parser.CharacterDataHandler = self._CharacterDataHandler
|
|
||||||
self._xml_parser.CommentHandler = self._CommentHandler
|
|
||||||
|
|
||||||
file_obj = open(file)
|
|
||||||
self._xml_parser.ParseFile(file_obj)
|
|
||||||
file_obj.close()
|
|
||||||
|
|
||||||
return self._all_strings
|
|
||||||
|
|
||||||
def _Reset(self):
|
|
||||||
self._currentString = None
|
|
||||||
self._currentStringName = None
|
|
||||||
self._currentStringValue = None
|
|
||||||
self._all_strings = {}
|
|
||||||
|
|
||||||
def _StartElementHandler(self, name, attrs):
|
|
||||||
if name != 'string':
|
|
||||||
return
|
|
||||||
|
|
||||||
if 'name' not in attrs:
|
|
||||||
return
|
|
||||||
|
|
||||||
assert not self._currentString
|
|
||||||
assert not self._currentStringName
|
|
||||||
self._currentString = {
|
|
||||||
'startLine' : self._xml_parser.CurrentLineNumber,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'rev' in attrs:
|
|
||||||
self._currentString['revs'] = [attrs['rev']]
|
|
||||||
|
|
||||||
self._currentStringName = attrs['name']
|
|
||||||
self._currentStringValue = ''
|
|
||||||
|
|
||||||
def _EndElementHandler(self, name):
|
|
||||||
if name != 'string':
|
|
||||||
return
|
|
||||||
|
|
||||||
assert self._currentString
|
|
||||||
assert self._currentStringName
|
|
||||||
self._currentString['value'] = self._currentStringValue
|
|
||||||
self._currentString['endLine'] = self._xml_parser.CurrentLineNumber
|
|
||||||
self._all_strings[self._currentStringName] = self._currentString
|
|
||||||
|
|
||||||
self._currentString = None
|
|
||||||
self._currentStringName = None
|
|
||||||
self._currentStringValue = None
|
|
||||||
|
|
||||||
def _CharacterDataHandler(self, data):
|
|
||||||
if not self._currentString:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._currentStringValue += data
|
|
||||||
|
|
||||||
_KEEP_PARENT_REGEX = re.compile(r'\s*KEEP_PARENT\s+'
|
|
||||||
r'name\s*=\s*[\'"]?(?P<name>[a-z0-9_]+)[\'"]?'
|
|
||||||
r'(?:\s+rev=[\'"]?(?P<rev>[0-9a-f]{12})[\'"]?)?\s*',
|
|
||||||
re.MULTILINE | re.DOTALL)
|
|
||||||
|
|
||||||
def _CommentHandler(self, data):
|
|
||||||
keep_parent_match = self._KEEP_PARENT_REGEX.match(data)
|
|
||||||
if not keep_parent_match:
|
|
||||||
return
|
|
||||||
|
|
||||||
name = keep_parent_match.group('name')
|
|
||||||
self._all_strings[name] = {
|
|
||||||
'keepParent' : True,
|
|
||||||
'startLine' : self._xml_parser.CurrentLineNumber,
|
|
||||||
'endLine' : self._xml_parser.CurrentLineNumber
|
|
||||||
}
|
|
||||||
rev = keep_parent_match.group('rev')
|
|
||||||
if rev:
|
|
||||||
self._all_strings[name]['revs'] = [rev]
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
'''
|
|
||||||
Module which prompts the user for translations and saves them.
|
|
||||||
|
|
||||||
TODO: implement
|
|
||||||
|
|
||||||
@author: Rodrigo Damazio
|
|
||||||
'''
|
|
||||||
|
|
||||||
class Translator(object):
|
|
||||||
'''
|
|
||||||
classdocs
|
|
||||||
'''
|
|
||||||
|
|
||||||
def __init__(self, language):
|
|
||||||
'''
|
|
||||||
Constructor
|
|
||||||
'''
|
|
||||||
self._language = language
|
|
||||||
|
|
||||||
def Translate(self, string_names):
|
|
||||||
print string_names
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
'''
|
|
||||||
Module which compares languague files to the master file and detects
|
|
||||||
issues.
|
|
||||||
|
|
||||||
@author: Rodrigo Damazio
|
|
||||||
'''
|
|
||||||
|
|
||||||
import os
|
|
||||||
from mytracks.parser import StringsParser
|
|
||||||
import mytracks.history
|
|
||||||
|
|
||||||
class Validator(object):
|
|
||||||
|
|
||||||
def __init__(self, languages):
|
|
||||||
'''
|
|
||||||
Builds a strings file validator.
|
|
||||||
|
|
||||||
Params:
|
|
||||||
@param languages: a dictionary mapping each language to its corresponding directory
|
|
||||||
'''
|
|
||||||
self._langs = {}
|
|
||||||
self._master = None
|
|
||||||
self._language_paths = languages
|
|
||||||
|
|
||||||
parser = StringsParser()
|
|
||||||
for lang, lang_dir in languages.iteritems():
|
|
||||||
filename = os.path.join(lang_dir, 'strings.xml')
|
|
||||||
parsed_file = parser.Parse(filename)
|
|
||||||
mytracks.history.FillMercurialRevisions(filename, parsed_file)
|
|
||||||
|
|
||||||
if lang == 'en':
|
|
||||||
self._master = parsed_file
|
|
||||||
else:
|
|
||||||
self._langs[lang] = parsed_file
|
|
||||||
|
|
||||||
self._Reset()
|
|
||||||
|
|
||||||
def Validate(self):
|
|
||||||
'''
|
|
||||||
Computes whether all the data in the files for the given languages is valid.
|
|
||||||
'''
|
|
||||||
self._Reset()
|
|
||||||
self._ValidateMissingKeys()
|
|
||||||
self._ValidateOutdatedKeys()
|
|
||||||
|
|
||||||
def valid(self):
|
|
||||||
return (len(self._missing_in_master) == 0 and
|
|
||||||
len(self._missing_in_lang) == 0 and
|
|
||||||
len(self._outdated_in_lang) == 0)
|
|
||||||
|
|
||||||
def missing_in_master(self):
|
|
||||||
return self._missing_in_master
|
|
||||||
|
|
||||||
def missing_in_lang(self):
|
|
||||||
return self._missing_in_lang
|
|
||||||
|
|
||||||
def outdated_in_lang(self):
|
|
||||||
return self._outdated_in_lang
|
|
||||||
|
|
||||||
def _Reset(self):
|
|
||||||
# These are maps from language to string name list
|
|
||||||
self._missing_in_master = {}
|
|
||||||
self._missing_in_lang = {}
|
|
||||||
self._outdated_in_lang = {}
|
|
||||||
|
|
||||||
def _ValidateMissingKeys(self):
|
|
||||||
'''
|
|
||||||
Computes whether there are missing keys on either side.
|
|
||||||
'''
|
|
||||||
master_keys = frozenset(self._master.iterkeys())
|
|
||||||
for lang, file in self._langs.iteritems():
|
|
||||||
keys = frozenset(file.iterkeys())
|
|
||||||
missing_in_master = keys - master_keys
|
|
||||||
missing_in_lang = master_keys - keys
|
|
||||||
|
|
||||||
if len(missing_in_master) > 0:
|
|
||||||
self._missing_in_master[lang] = missing_in_master
|
|
||||||
if len(missing_in_lang) > 0:
|
|
||||||
self._missing_in_lang[lang] = missing_in_lang
|
|
||||||
|
|
||||||
def _ValidateOutdatedKeys(self):
|
|
||||||
'''
|
|
||||||
Computers whether any of the language keys are outdated with relation to the
|
|
||||||
master keys.
|
|
||||||
'''
|
|
||||||
for lang, file in self._langs.iteritems():
|
|
||||||
outdated = []
|
|
||||||
for key, str in file.iteritems():
|
|
||||||
# Get all revisions that touched master and language files for this
|
|
||||||
# string.
|
|
||||||
master_str = self._master[key]
|
|
||||||
master_revs = master_str['revs']
|
|
||||||
lang_revs = str['revs']
|
|
||||||
if not master_revs or not lang_revs:
|
|
||||||
print 'WARNING: No revision for %s in %s' % (key, lang)
|
|
||||||
continue
|
|
||||||
|
|
||||||
master_file = os.path.join(self._language_paths['en'], 'strings.xml')
|
|
||||||
lang_file = os.path.join(self._language_paths[lang], 'strings.xml')
|
|
||||||
|
|
||||||
# Assume that the repository has a single head (TODO: check that),
|
|
||||||
# and as such there is always one revision which superceeds all others.
|
|
||||||
master_rev = reduce(
|
|
||||||
lambda r1, r2: mytracks.history.NewestRevision(master_file, r1, r2),
|
|
||||||
master_revs)
|
|
||||||
lang_rev = reduce(
|
|
||||||
lambda r1, r2: mytracks.history.NewestRevision(lang_file, r1, r2),
|
|
||||||
lang_revs)
|
|
||||||
|
|
||||||
# If the master version is newer than the lang version
|
|
||||||
if mytracks.history.DoesRevisionSuperceed(lang_file, master_rev, lang_rev):
|
|
||||||
outdated.append(key)
|
|
||||||
|
|
||||||
if len(outdated) > 0:
|
|
||||||
self._outdated_in_lang[lang] = outdated
|
|
||||||
Reference in New Issue
Block a user