Konstantine Rybnikov avatar Konstantine Rybnikov committed b516cce

some progress, WHY SO SMALL (¬_¬")

Comments (0)

Files changed (5)

fat_po_editor/__init__.py

 # -*- coding: utf-8 -*-
 
+def _(x): return x

fat_po_editor/diffutil.py

+# -*- coding: utf-8 -*-
+
+from polib import POEntry
+
+from fat_po_editor.util import isiterable
+from fat_po_editor import _
+from fat_po_editor.util import StringBuilder
+
+MAXLEN = 80
+
+class Diff(object):
+    """This class implements storage of diff data between two po-files.
+
+    It:
+    
+    - knows which phrases were added, removed or changed.
+    - can display them in various formats.
+
+    Entries of diff should be in :class:`~polib.POEntry` format.
+
+    :internal:
+    """
+
+    def __init__(self):
+        self.entries_add = []
+        self.entries_rm = []
+        self.entries_modified = []
+
+        self.operation_to_storage_map = {
+            'add': self.entries_add,
+            'rm': self.entries_rm,
+            'modify': self.entries_modified
+        }
+        self.operation_types = self.operation_to_storage_map.keys()
+    
+    def entry_append(self, operation_type, entry):
+        """
+        ``operation_type``
+            one of ['add', 'rm', 'modify']
+        """
+        assert operation_type in self.operation_types
+        assert (isinstance(entry, POEntry)
+                or isiterable(entry))
+        storage = self.operation_to_storage_map[operation_type]
+        storage.append(entry)
+
+    def get_entries(self, operation_type):
+        assert operation_type in self.operation_types
+        return self.operation_to_storage_map[operation_type]
+
+    def __unicode__(self):
+        """Gives a nice text representation of what happened."""
+
+        def esc_chunk(s, maxlen):
+            """Escapes chunk's ``\\n`` symbols etc. and returns a chunk
+            of that.
+            """
+            from polib import escape
+            
+            def chunk(s, maxlen):
+                if len(s) > maxlen - 3:
+                    return u"".join([s[maxlen - 3], '...'])
+                return s
+            
+            return chunk(escape(s), maxlen)
+        
+        rv = StringBuilder()
+
+        if len(self.operation_to_storage_map['add']):
+            rv += _(u"Added phrases:\n")
+            list_prefix = u"    * "
+            for item in self.operation_to_storage_map['add']:
+                rv += u"%s%s\n" % (list_prefix,
+                                   esc_chunk(item.msgid,
+                                             MAXLEN - len(list_prefix)))
+        if len(self.operation_to_storage_map['rm']):
+            rv += _(u"Removed phrases:\n")
+            for item in self.operation_to_storage_map['rm']:
+                rv += u"%s%s\n" % (list_prefix,
+                                   esc_chunk(item.msgid,
+                                             MAXLEN - len(list_prefix)))
+        if len(self.operation_to_storage_map['modify']):
+            rv += _(u"Modified translation of phrases:\n")
+            for item in self.operation_to_storage_map['modify']:
+                rv += u"%s%s\n" % (list_prefix,
+                                   esc_chunk(item.msgid,
+                                             MAXLEN - len(list_prefix)))
+        return unicode(rv)

fat_po_editor/util.py

+# -*- coding: utf-8 -*-
+
+def isiterable(entry):
+    """Basically it gives you is entry is a list, tuple or generator."""
+    if (isinstance(entry, list)
+        or isinstance(entry, tuple)
+        or hasattr(entry, '__iter__')):
+        
+        return True
+    return False
+
+class StringBuilder(object):
+    """Use it instead of doing += for unicode strings"""
+    def __init__(self, val=u""):
+        self.val = val
+        self.appended = []
+    
+    def __iadd__(self, other):
+        self.appended.append(other)
+        return self
+
+    def __unicode__(self):
+        self.val = u"".join((self.val, u"".join(self.appended)))
+        self.appended = []
+        return self.val

tests/test_diffutil.py

+# -*- coding: utf-8 -*-
+
+import unittest
+
+from fat_po_editor.diffutil import Diff
+from polib import POEntry
+
+class TestDiffUtilDiff(unittest.TestCase):
+    def test_append_simple(self):
+        diff = Diff()
+        entry = POEntry(msgid=u"First msgid",
+                        msgstr=u"First msgstr")
+        diff.entry_append('add', entry)
+
+        self.assertEquals(
+            diff.get_entries('add'),
+            [entry])
+
+    def test_representation_simple(self):
+        diff = Diff()
+        entry = POEntry(msgid=u"First msgid",
+                        msgstr=u"First msgstr")
+        diff.entry_append('add', entry)
+
+        self.assertEquals(
+            unicode(diff),
+            (u"Added phrases:\n"
+             u"    * First msgid\n"))
+
+    def test_representation_more_complex(self):
+        diff = Diff()
+        entry = POEntry(msgid=u"First msgid",
+                        msgstr=u"First msgstr")
+        diff.entry_append('add', entry)
+        entry = POEntry(msgid=u"Second msgid",
+                        msgstr=u"Second msgstr")
+        diff.entry_append('rm', entry)
+        entry = POEntry(msgid=u"Third msgid",
+                        msgstr=u"Third msgstr")
+        diff.entry_append('modify', entry)
+        
+        self.assertEquals(
+            unicode(diff),
+            (u"Added phrases:\n"
+             u"    * First msgid\n"
+             u"Removed phrases:\n"
+             u"    * Second msgid\n"
+             u"Modified translation of phrases:\n"
+             u"    * Third msgid\n"))
+
+    def test_representation_too_long(self):
+        diff = Diff()
+        entry = POEntry(msgid=u"First msgid",
+                        msgstr=u"First msgstr")
+        diff.entry_append('add', entry)
+
+        self.assertEquals(
+            unicode(diff),
+            (u"Added phrases:\n"
+             u"    * First msgid\n"))

tests/test_util.py

+# -*- coding: utf-8 -*-
+
+import unittest
+
+from fat_po_editor.util import isiterable
+from fat_po_editor.util import StringBuilder
+        
+class TestIsIterable(unittest.TestCase):
+    def test_list(self):
+        self.assertEquals(isiterable(list()), True)
+
+    def test_tuple(self):
+        self.assertEquals(isiterable(tuple()), True)
+
+    def test_generator(self):
+        self.assertEquals(isiterable(x for x in [1,2,3]), True)
+
+    def test_string(self):
+        self.assertEquals(isiterable("Test"), False)
+
+    def test_unicode(self):
+        self.assertEquals(isiterable(u"Test"), False)
+
+class TestStringBuilder(unittest.TestCase):
+    def test_simple(self):
+        sb = StringBuilder(u"init val")
+        sb += u"u"
+        sb += u"e"
+
+        self.assertEquals(unicode(sb),
+                          u"init value")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.