Source

fat_po_editor / fat_po_editor / vcs_util.py

# -*- coding: utf-8 -*-

import vcs

from .util import StringBuilder
from .diff_util import compare_two_pofiles

def is_useful_changeset(changeset):
    """Returns if changeset is useful for fat_po_edito"""
    for file_ in changeset.affected_files:
        if file_.endswith('.po'):
            return True
    return False

class BoundChangesetInfo(object):
    """Info about changeset that will be really useful for fat_po_editor"""

    def __init__(self, changeset):
        self.changeset = changeset
        self.revision = changeset.short_id
        self.author = changeset.author
        self.affected_pofiles = list(filter(lambda x: x.endswith('.po'),
                                            changeset.affected_files))

    def __unicode__(self):
        rv = StringBuilder()
        rv += u"Revision no.: %s\n" % self.revision
        rv += u"Author: %s\n" % self.author
        rv += u"Affected pofiles: [%s]\n" % u", ".join(self.affected_pofiles)
        return unicode(rv)

    def generate_podiff(self, pofile_path):
        """
        :returns:
            Returns a :class:`~fat_po_editor.diffutil.PoDiff` instance for
            this changeset and it's parent (first parent when multiple).
        :raises: :class:`~vcs.exceptions.ChangesetError` when file not found.
        """
        from polib import pofile
        contents = pofile(self.changeset.get_file_content(pofile_path))
        contents_old = pofile(self.changeset.parents[0].get_file_content(pofile_path))
        return compare_two_pofiles(contents_old, contents)


class RepoWithPofiles(object):
    def __init__(self, path=None):
        self.path = path
        self.vcs_repo = vcs.get_repo(path)

    def get_last_useful_changesets_info(self, limit=10):
        """Returns information needed to draw nice representation of last
        affected pofiles and they're authors"""
        MAX_ITERATED_CHANGESETS_NUM = 1000

        revisions = self.vcs_repo.revisions[:MAX_ITERATED_CHANGESETS_NUM]
        revision_to_changeset_map = dict(
            map(lambda changeset: (changeset,
                                   self.vcs_repo.get_changeset(changeset)),
                reversed(revisions)))
        useful_revisions = (
            filter(lambda x: is_useful_changeset(revision_to_changeset_map.get(x)),
                   revisions))
        rv = [BoundChangesetInfo(self.vcs_repo.get_changeset(r))
              for r in useful_revisions]
        return rv

    def get_bound_changeset_info_for_revision(self, revision):
        """Build new :class:`~BoundChangesetInfo` instance from revision
        given as a string.

        :param revision: revision id as a string
        """
        c = self.vcs_repo.get_changeset(revision)
        return BoundChangesetInfo(c)