def _test(self, content, refWarnOrErrors): p = getParser(self.file.file) p.readContents(content) l10n = [e for e in p] checks = getChecks(self.file) found = tuple(checks(self.refs[0], l10n[0])) self.assertEqual(found, refWarnOrErrors)
def _test(self, content, refs): p = getParser('foo.dtd') Junk.junkid = 0 p.readContents(content) entities = [e for e in p] self.assertEqual(len(entities), len(refs)) for e, ref in zip(entities, refs): self.assertEqual(e.val, ref[1]) self.assertEqual(e.key, ref[0])
def _test(self, content, refWarnOrErrors): p = getParser(self.file.file) p.readContents(content) l10n = [e for e in p] assert len(l10n) == 1 l10n = l10n[0] checks = getChecks(self.file) ref = self.refList[self.refMap[l10n.key]] found = tuple(checks(ref, l10n)) self.assertEqual(found, refWarnOrErrors)
def testLicenseHeader(self): p = getParser('foo.properties') p.readContents('''# ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (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.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # International Business Machines Corporation. # Portions created by the Initial Developer are Copyright (C) 2000 # the Initial Developer. All Rights Reserved. # # Contributor(s): # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** foo=value ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header) p.readContents( '''# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. foo=value ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header)
def testLicenseHeader(self): p = getParser('foo.dtd') p.readContents('''<!-- ***** BEGIN LICENSE BLOCK ***** #if 0 - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (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.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is mozilla.org Code. - - The Initial Developer of the Original Code is dummy. - Portions created by the Initial Developer are Copyright (C) 2005 - the Initial Developer. All Rights Reserved. - - Contributor(s): - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the LGPL or the GPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - #endif - ***** END LICENSE BLOCK ***** --> <!ENTITY foo "value"> ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header) p.readContents( '''<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this file, - You can obtain one at http://mozilla.org/MPL/2.0/. --> <!ENTITY foo "value"> ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header)
def testLicenseHeader(self): p = getParser('foo.properties') p.readContents('''# ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (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.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # International Business Machines Corporation. # Portions created by the Initial Developer are Copyright (C) 2000 # the Initial Developer. All Rights Reserved. # # Contributor(s): # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** foo=value ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header) p.readContents('''# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. foo=value ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header)
def testLicenseHeader(self): p = getParser('foo.dtd') p.readContents('''<!-- ***** BEGIN LICENSE BLOCK ***** #if 0 - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (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.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is mozilla.org Code. - - The Initial Developer of the Original Code is dummy. - Portions created by the Initial Developer are Copyright (C) 2005 - the Initial Developer. All Rights Reserved. - - Contributor(s): - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the LGPL or the GPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - #endif - ***** END LICENSE BLOCK ***** --> <!ENTITY foo "value"> ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header) p.readContents('''<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this file, - You can obtain one at http://mozilla.org/MPL/2.0/. --> <!ENTITY foo "value"> ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header)
def testMissing(self): self.assertTrue(os.path.isdir(self.tmp)) l10n = os.path.join(self.tmp, "l10n.properties") open(l10n, "w").write("""bar = lBar """) obs = Observer() cc = ContentComparer(obs) cc.set_merge_stage(os.path.join(self.tmp, "merge")) cc.compare(File(self.ref, "en-reference.properties", ""), File(l10n, "l10n.properties", "")) print obs.serialize() mergefile = os.path.join(self.tmp, "merge", "l10n.properties") self.assertTrue(os.path.isfile(mergefile)) p = getParser(mergefile) p.readFile(mergefile) [m, n] = p.parse() self.assertEqual(map(lambda e: e.key, m), ["bar", "eff", "foo"])
def testMissing(self): self.assertTrue(os.path.isdir(self.tmp)) l10n = os.path.join(self.tmp, "l10n.dtd") open(l10n, "w").write("""<!ENTITY bar 'lBar'> """) obs = Observer() cc = ContentComparer(obs) cc.set_merge_stage(os.path.join(self.tmp, "merge")) cc.compare(File(self.ref, "en-reference.dtd", ""), File(l10n, "l10n.dtd", "")) print obs.serialize() mergefile = os.path.join(self.tmp, "merge", "l10n.dtd") self.assertTrue(os.path.isfile(mergefile)) p = getParser(mergefile) p.readFile(mergefile) [m,n] = p.parse() self.assertEqual(map(lambda e:e.key,m), ["bar", "eff", "foo"])
def testLicenseHeader(self): p = getParser('foo.properties') p.readContents('''# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. foo=value ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header) p.readContents('''# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. foo=value ''') for e in p: self.assertEqual(e.key, 'foo') self.assertEqual(e.val, 'value') self.assert_('MPL' in p.header)
def setUp(self): self.p = getParser('foo.properties')
def diff_app(request): # XXX TODO: error handling if 'repo' not in request.GET: raise Http404("repo must be supplied") reponame = request.GET['repo'] repopath = settings.REPOSITORY_BASE + '/' + reponame repo_url = Repository.objects.filter(name=reponame).values_list('url', flat=True)[0] from mercurial.ui import ui as _ui from mercurial.hg import repository ui = _ui() repo = repository(ui, repopath) ctx1 = repo.changectx(request.GET['from']) ctx2 = repo.changectx(request.GET['to']) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(ctx1, ctx2, match=match)[:3] paths = ([(f, 'changed') for f in changed] + [(f, 'removed') for f in removed] + [(f, 'added') for f in added]) diffs = DataTree(dict) for path, action in paths: lines = [] try: p = getParser(path) except UserWarning: diffs[path].update({'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action}) continue if action == 'added': a_entities = [] a_map = {} else: data = ctx1.filectx(path).data() data = _universal_newlines(data) try: p.readContents(data) a_entities, a_map = p.parse() except: diffs[path].update({'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action}) continue if action == 'removed': c_entities = [] c_map = {} else: data = ctx2.filectx(path).data() data = _universal_newlines(data) try: p.readContents(data) c_entities, c_map = p.parse() except: diffs[path].update({'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action}) continue a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair}) elif action == 'add': lines.append({'class': 'added', 'oldval': '', 'newval':[{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair}) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class':op, 'value':oldval[o1:o2]}) if n1 != n2: newhtml.append({'class':op, 'value':newval[n1:n2]}) lines.append({'class':'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) container_class = lines and 'file' or 'empty-diff' diffs[path].update({'path': path, 'class': container_class, 'lines': lines}) diffs = diffs.toJSON().get('children', []) return render_to_response('shipping/diff.html', {'given_title': request.GET.get('title', None), 'repo': reponame, 'repo_url': repo_url, 'old_rev': request.GET['from'], 'new_rev': request.GET['to'], 'diffs': diffs}, context_instance=RequestContext(request))
def diff(request): if not request.GET.get('repo'): return http.HttpResponseBadRequest("Missing 'repo' parameter") reponame = request.GET['repo'] repopath = settings.REPOSITORY_BASE + '/' + reponame try: repo_url = Repository.objects.get(name=reponame).url except Repository.DoesNotExist: raise http.Http404("Repository not found") if not request.GET.get('from'): return http.HttpResponseBadRequest("Missing 'from' parameter") if not request.GET.get('to'): return http.HttpResponseBadRequest("Missing 'to' parameter") ui = _ui() repo = repository(ui, repopath) # Convert the 'from' and 'to' to strings (instead of unicode) # in case mercurial needs to look for the key in binary data. # This prevents UnicodeWarning messages. ctx1 = repo.changectx(str(request.GET['from'])) ctx2 = repo.changectx(str(request.GET['to'])) copies = pathcopies(ctx1, ctx2) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(ctx1, ctx2, match=match)[:3] # split up the copies info into thos that were renames and those that # were copied. moved = {} copied = {} for new_name, old_name in copies.items(): if old_name in removed: moved[new_name] = old_name else: copied[new_name] = old_name paths = ([(f, 'changed') for f in changed] + [(f, 'removed') for f in removed if f not in moved.values()] + [(f, (f in moved and 'moved') or (f in copied and 'copied') or 'added') for f in added]) diffs = DataTree(dict) for path, action in paths: lines = [] try: p = getParser(path) except UserWarning: diffs[path].update({ 'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action, 'renamed': moved.get(path), 'copied': copied.get(path) }) continue if action == 'added': a_entities = [] a_map = {} else: realpath = (action == 'moved' and moved[path] or action == 'copied' and copied[path] or path) data = ctx1.filectx(realpath).data() data = _universal_newlines(data) try: p.readContents(data) a_entities, a_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) diffs[path].update({ 'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action, 'renamed': moved.get(path), 'copied': copied.get(path) }) continue if action == 'removed': c_entities, c_map = [], {} else: data = ctx2.filectx(path).data() data = _universal_newlines(data) try: p.readContents(data) c_entities, c_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) diffs[path].update({ 'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action }) continue a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({ 'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair }) elif action == 'add': lines.append({ 'class': 'added', 'oldval': '', 'newval': [{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair }) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class': op, 'value': oldval[o1:o2]}) if n1 != n2: newhtml.append({'class': op, 'value': newval[n1:n2]}) lines.append({'class': 'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) container_class = lines and 'file' or 'empty-diff' diffs[path].update({'path': path, 'class': container_class, 'lines': lines, 'renamed': moved.get(path), 'copied': copied.get(path) }) diffs = diffs.toJSON().get('children', []) return render(request, 'shipping/diff.html', { 'given_title': request.GET.get('title', None), 'repo': reponame, 'repo_url': repo_url, 'old_rev': request.GET['from'], 'new_rev': request.GET['to'], 'diffs': diffs })
import sys import re import codecs try: from Mozilla.Parser import getParser except ImportError: sys.exit('''extract-bookmarks needs compare-locales Find that on http://pypi.python.org/pypi/compare-locales. This script has been tested with version 0.6, and might work with future versions.''') ll=re.compile('\.(title|a|dd|h[0-9])$') p = getParser(sys.argv[1]) p.readFile(sys.argv[1]) template = '''#filter emptyLines # LOCALIZATION NOTE: The 'en-US' strings in the URLs will be replaced with # your locale code, and link to your translated pages as soon as they're # live. #define bookmarks_title %s #define bookmarks_heading %s #define bookmarks_toolbarfolder %s #define bookmarks_toolbarfolder_description %s # LOCALIZATION NOTE (getting_started):
cldr_main, en_src, l10n_src, dest = sys.argv[1:5] except: sys.stderr.write("Call with arguments: cldr_main, en_src, l10n_src, dest\n") sys.exit(1) def getCLDRNames(lang): tree = ElementTree() tree.parse(os.path.join(cldr_main, lang + ".xml")) rv = {} for e in tree.findall('localeDisplayNames/languages/language'): rv[e.attrib['type']] = e.text return rv languageNames = os.path.join(en_src, 'toolkit', 'locales', 'en-US', 'chrome', 'global', 'languageNames.properties') p = getParser(languageNames) p.readFile(languageNames) l, m = p.parse() en_names = getCLDRNames("en") en_names.update(dict((k, l[v].val) for k, v in m.iteritems())) all_locales = filter(lambda l:l not in ('x-testing', 'ja-JP-mac') and len(l)!=3, os.listdir(l10n_src)) for loc in all_locales: lang = loc.split('-')[0] print loc en_name = en_names[lang] languageNames = os.path.join(l10n_src, loc, 'toolkit', 'chrome', 'global', 'languageNames.properties') p = getParser(languageNames)
def diff_app(request): # XXX TODO: error handling reponame = request.GET['repo'] repopath = settings.REPOSITORY_BASE + '/' + reponame repo_url = Repository.objects.filter(name=reponame).values_list('url', flat=True)[0] from mercurial.ui import ui as _ui from mercurial.hg import repository ui = _ui() repo = repository(ui, repopath) ctx1 = repo.changectx(request.GET['from']) ctx2 = repo.changectx(request.GET['to']) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(ctx1, ctx2, match=match)[:3] diffs = DataTree(dict) for path in added: diffs[path].update({'path': path, 'isFile': True, 'rev': request.GET['to'], 'desc': ' (File added)', 'class': 'added'}) for path in removed: diffs[path].update({'path': path, 'isFile': True, 'rev': request.GET['from'], 'desc': ' (File removed)', 'class': 'removed'}) for path in changed: lines = [] try: p = getParser(path) except UserWarning: diffs[path].update({'path': path, 'lines': [{'class': 'issue', 'oldval': '', 'newval': '', 'entity': 'cannot parse ' + path}]}) continue data1 = ctx1.filectx(path).data() data2 = ctx2.filectx(path).data() try: # parsing errors or such can break this, catch those and fail # gracefully # fake reading with universal line endings, too p.readContents(__universal_le(data1)) a_entities, a_map = p.parse() p.readContents(__universal_le(data2)) c_entities, c_map = p.parse() del p except: diffs[path].update({'path': path, 'lines': [{'class': 'issue', 'oldval': '', 'newval': '', 'entity': 'cannot parse ' + path}]}) continue a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair}) elif action == 'add': lines.append({'class': 'added', 'oldval': '', 'newval':[{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair}) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class':op, 'value':oldval[o1:o2]}) if n1 != n2: newhtml.append({'class':op, 'value':newval[n1:n2]}) lines.append({'class':'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) container_class = lines and 'file' or 'empty-diff' diffs[path].update({'path': path, 'class': container_class, 'lines': lines}) diffs = diffs.toJSON().get('children', []) return render_to_response('shipping/diff.html', {'given_title': request.GET.get('title', None), 'repo': reponame, 'repo_url': repo_url, 'old_rev': request.GET['from'], 'new_rev': request.GET['to'], 'diffs': diffs})
def setUp(self): p = getParser(self.file.file) p.readContents(self.refContent) self.refList, self.refMap = p.parse()
def setUp(self): p = getParser(self.file.file) p.readContents(self.refContent) self.refs = [e for e in p]
def setUp(self): self.p = getParser('foo.ini')
def diffLines(self, path, action): lines = [] try: p = getParser(path) except UserWarning: return None if action == 'added': a_entities = [] a_map = {} else: realpath = (action == 'moved' and self.moved[path] or action == 'copied' and self.copied[path] or path) data = self.ctx1.filectx(realpath).data() data = self._universal_newlines(data) try: p.readContents(data) a_entities, a_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) return None if action == 'removed': c_entities, c_map = [], {} else: data = self.ctx2.filectx(path).data() data = self._universal_newlines(data) try: p.readContents(data) c_entities, c_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) return None a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({ 'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair }) elif action == 'add': lines.append({ 'class': 'added', 'oldval': '', 'newval': [{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair }) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class': op, 'value': oldval[o1:o2]}) if n1 != n2: newhtml.append({'class': op, 'value': newval[n1:n2]}) lines.append({'class': 'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) return lines
import sys import re import codecs try: from Mozilla.Parser import getParser except ImportError: sys.exit('''extract-bookmarks needs compare-locales Find that on http://pypi.python.org/pypi/compare-locales. This script has been tested with version 0.6, and might work with future versions.''') ll = re.compile('\.(title|a|dd|h[0-9])$') p = getParser(sys.argv[1]) p.readFile(sys.argv[1]) template = '''#filter emptyLines # LOCALIZATION NOTE: The 'en-US' strings in the URLs will be replaced with # your locale code, and link to your translated pages as soon as they're # live. #define bookmarks_title %s #define bookmarks_heading %s # LOCALIZATION NOTE (bookmarks_addons): # link title for https://en-US.add-ons.mozilla.com/en-US/firefox/bookmarks/ #define bookmarks_addons %s #define bookmarks_toolbarfolder %s
def diffLines(self, path, action): lines = [] try: p = getParser(path) except UserWarning: return None if action == 'added': a_entities = [] a_map = {} else: realpath = (action == 'moved' and self.moved[path] or action == 'copied' and self.copied[path] or path) data = self.ctx1.filectx(realpath).data() data = self._universal_newlines(data) try: p.readContents(data) a_entities, a_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) return None if action == 'removed': c_entities, c_map = [], {} else: data = self.ctx2.filectx(path).data() data = self._universal_newlines(data) try: p.readContents(data) c_entities, c_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) return None a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({ 'class': 'removed', 'oldval': [{ 'value': a_entities[a_map[item_or_pair]].val }], 'newval': '', 'entity': item_or_pair }) elif action == 'add': lines.append({ 'class': 'added', 'oldval': '', 'newval': [{ 'value': c_entities[c_map[item_or_pair]].val }], 'entity': item_or_pair }) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class': op, 'value': oldval[o1:o2]}) if n1 != n2: newhtml.append({'class': op, 'value': newval[n1:n2]}) lines.append({ 'class': 'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0] }) return lines