Hello dear translators,

I invested some time to improve the output of podiff. It now allows you
to show only new, removed or modified messages - the options can be used
cumulatively. Furthermore you can now replace spaces by "·".

usage: podiff [options] file1 file2

options:
  -h, --help            show this help message and exit
  -n, --new-messages    show only new messages
  -r, --removed-messages
                        show only removed messages
  -m, --modified-messages
                        show only modified messages
  -s, --replace-spaces  show · instead of spaces

Example output:

---
Modified Message:
    'Creates·a·new·project.·Currently·opened·project·is·not·affected.'
Old:
    'Legt·ein·neues·Projekt·an.·Das·gerade·geöffnete·Projekt·ist·davon
    nicht·betroffen.'
New:
    'Erstellt·ein·neues·Projekt.·Das·gerade·geöffnete·Projekt·ist·davon
    nicht·betroffen.'

I hope that it is use for you.

Regards,

Sebastian
#!/usr/bin/env python
# coding: utf-8
#  
#  podiff - compare two translations
#
#  Copyright (c) 2006 Sebastian Heinlein
#
#  Author: Sebastian Heinlein <[EMAIL PROTECTED]>
#
#  Homepage: https://launchpad.net/products/podiff/
#
#  Report bugs at https://launchpad.net/products/podiff/+bugs
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
#  USA

import re
import sys
from optparse import OptionParser

class Message:
    def __init__(self, msgid, msgid_plural=None, msgstr=None, fuzzy=False,
                 location=None, comment=None):
    	self.msgid = msgid
    	self.msgid_plural = msgid_plural
	self.msgstr = msgstr
	self.fuzzy = fuzzy
	self.location = location
	self.comment = comment

class POFile:
    "class for each po file. contains all messages of the file"
    def __init__(self, path):
        self.messages = {}
        file = open(path)
        if not file:
            print "could not open %s" % path
            return
        current_msgid = ""
        current_msgid_plural = None
        current_msgstr = None
        current_fuzzy = False
        current_location = None
        current_comment = None

        # define the regular expressions
        pattern_msgid = re.compile("^msgid \"(.+)\"$")
        pattern_msgid_plural = re.compile("^msgid_plural \"(.+)\"$")
        pattern_msgstr =  re.compile("^msgstr \"(.*)\"$")
        pattern_msgstr_plural =  re.compile("^msgstr\[(.+)\] \"(.*)\"$")
        pattern_string = re.compile("^\"(.+)\"$")
        pattern_location = re.compile("^\#: (.+)$")
        pattern_fuzzy = re.compile("^\#, fuzzy")
        pattern_comment = re.compile("^\.(.*)$")

        for line in file:
            #print "Line: %s" % line

	    # check if it contains a comment from the developers
            m = pattern_comment.match(line)
            if m != None:
                current_comment += m.group(1)
                continue
	    
	    # check if it contains the fuzzy tag of the message
            m = pattern_fuzzy.match(line)
            if m != None:
                current_fuzzy = True
                continue
	    
	    # check if it contains the location of the message
            m = pattern_location.match(line)
            if m != None:
                current_location = m.group(1)
                continue

            # check if it is a new msgid
            m = pattern_msgid.match(line)
            if m != None:
                self.messages[current_msgid] = Message(current_msgid,
						       current_msgid_plural,
		                                       current_msgstr,
						       current_fuzzy,
						       current_location,
						       current_comment)
                current_msgstr = None
        	current_fuzzy = False
	        current_location = None
        	current_comment = ""
        	current_msgid_plural = None
		current_plural = None
                current_msgid = m.group(1)
                continue
	    
            # check if it is a plural form
            m = pattern_msgid_plural.match(line)
            if m != None:
                current_msgid_plural = m.group(1)
		current_msgstr = {}
                continue

            # check if it is a new msgstr - translation
            m = pattern_msgstr.match(line)
            if m != None:
                current_msgstr = m.group(1)
                continue

            # check if it is a new plural msgstr 
            m = pattern_msgstr_plural.match(line)
            if m != None:
                current_msgstr[m.group(1)] = m.group(2)
		current_plural = m.group(1)
                continue
            
            # check if it is only an additional line of a msgid or 
            # a translated string
            m = pattern_string.match(line)
            if m != None:
                if current_msgstr == None and current_msgid_plural == None:
                    current_msgid += m.group(1)
                    continue
		elif current_msgstr == None and current_msgid_plural != None:
                    current_msgid_plural += m.group(1)
		elif current_msgstr != None and current_msgid_plural != None:
                    current_msgstr[current_plural] += m.group(1)
                else:
                    current_msgstr += m.group(1)

        # print some stats
        print "%s contains %s messages" % (path, len(self.messages))
        #print self.messages.keys()

class Results:
    def __init__(self, add=[], mod=[], rem=[], fuzzy=[]):
    	self.added = add
	self.modified = mod
	self.removed = rem
	self.fuzzy = fuzzy

class PODiff:
    def __init__(self, options, args):
        self.options = options
        old = POFile(args[0])
        new = POFile(args[1])
        self.report_console(old, new, self.compare_translations(old, new))

    def wrap(self, text, width):
        """
        A word-wrap function that preserves existing line breaks
        and most spaces in the text. Expects that existing line
        breaks are posix newlines (\n).

        http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061
        """
        return reduce(lambda line, word, width=width: '%s%s%s' %
                      (line, ' \n'[(len(line)-line.rfind('\n')-1
	   	      + len(word.split('\n',1)[0]) >= width)], word), 
		      text.split(' '))

    def compare_translations(self, file_orig, file_mod):
         """
	 compare the messages of two po files
	 """
         messages = file_orig.messages.keys()
         messages.extend(file_mod.messages.keys())
         messages = set(messages)
         results = Results()

         for msgid in messages:
            if file_mod.messages.has_key(msgid) and \
               file_orig.messages.has_key(msgid):
                if file_orig.messages[msgid].msgstr != \
	           file_mod.messages[msgid].msgstr:
                    results.modified.append(msgid)
                if file_orig.messages[msgid].fuzzy != \
	           file_mod.messages[msgid].fuzzy:
                    results.fuzzy.append(msgid)
            elif file_orig.messages.has_key(msgid):
                results.removed.append(msgid)
            else:
                results.added.append(msgid)
         return results

    def fancy_out(self, string):
        """
        Convert the strings to a nice output format
        """
        # wrap lines at a specifed width
        string = "'%s'" % self.wrap(string, 70)
        # replace spaces if specified
        if self.options.replace_spaces == True:
            r = re.compile(" ", re.MULTILINE)
	    string = r.sub("·", string)
        # add some space before each line
        r = re.compile("\n|^")
        string = r.sub("\n    ", string)
        return string

    def report_console(self, old, new, results):
        file_orig = old
        file_mod = new
        if len(results.added) > 0 and\
           (self.options.messages_new == True or 
	    self.options.messages_all == True):
	    for msgid in results.added:
	         print "\n---\nNew Message:%s\nTranslation:%s" %\
	               (self.fancy_out(msgid), 
		        self.fancy_out(file_mod.messages[msgid].msgstr))
        if len(results.modified) > 0 and\
           (self.options.messages_modified == True or 
	    self.options.messages_all == True):
	    for msgid in results.modified:
	         print "\n---\nModified Message:%s\nOld:%s\nNew:%s" %\
	               (self.fancy_out(msgid), 
		        self.fancy_out(file_orig.messages[msgid].msgstr),
	                self.fancy_out(file_mod.messages[msgid].msgstr))
                 if file_orig.messages[msgid].fuzzy !=\
		     file_mod.messages[msgid].fuzzy:
		      print "Fuzzy: %s -> %s" % \
		            (file_orig.messages[msgid].fuzzy,
		             file_mod.messages[msgid].fuzzy)
        if len(results.removed) > 0 and\
           (self.options.messages_removed == True or 
	    self.options.messages_all == True):
	    for msgid in results.removed:
	         print "\n---\nRemoved Message:%s\nTranslation:%s" %\
	               (self.fancy_out(msgid), 
		        self.fancy_out(file_orig.messages[msgid].msgstr))
        if len(results.fuzzy) > 0 and\
           (self.options.messages_modified == True or 
	    self.options.messages_all == True):
	    for msgid in results.fuzzy:
	         print "\n---\nModified Message:%s\nTranslation:%s"\
		       "\nFuzzy: %s -> %s\n" %\
	               (self.fancy_out(msgid), 
		        self.fancy_out(file_orig.messages[msgid].msgstr),
		        file_orig.messages[msgid].fuzzy, 
		        file_mod.messages[msgid].fuzzy)

if __name__ == "__main__":
    usage = "usage: podiff [options] file1 file2"
    parser = OptionParser(usage)
    parser.add_option("-n", "--new-messages", dest="messages_new",
                      help="show only new messages", default=False,
		      action="store_true")
    parser.add_option("-r", "--removed-messages", dest="messages_removed",
                      help="show only removed messages", default=False,
		      action="store_true")
    parser.add_option("-m", "--modified-messages", dest="messages_modified",
                      help="show only modified messages", default=False,
		      action="store_true")
    parser.add_option("-s", "--replace-spaces", dest="replace_spaces",
                      help="show · instead of spaces", default=False,
		      action="store_true")

    (options, args) = parser.parse_args()
    if len(args) != 2:
    	parser.error("you have to specify two files to compare them")
	sys.exit(1)
    if options.messages_new == False and options.messages_removed == False and\
       options.messages_modified == False:
        options.messages_all = True
    else:
        options.messages_all = False 
    app = PODiff(options, args)
    
-- 
ubuntu-translators mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-translators

Reply via email to