diff --git a/gitinspector/output/changesblameoutput.py b/gitinspector/output/changesblameoutput.py new file mode 100644 index 0000000..5a417c3 --- /dev/null +++ b/gitinspector/output/changesblameoutput.py @@ -0,0 +1,239 @@ +# coding: utf-8 +# +# Copyright © 2012-2015 Ejwa Software. All rights reserved. +# +# This file is part of gitinspector. +# +# gitinspector 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 3 of the License, or +# (at your option) any later version. +# +# gitinspector 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 gitinspector. If not, see . + +from __future__ import print_function +from __future__ import unicode_literals +import json +import textwrap +from ..localization import N_ +from .. import format, gravatar, terminal +from .outputable import Outputable +from ..blame import Blame + +HISTORICAL_INFO_TEXT = N_("The following historical commit information, by author, was found") +NO_COMMITED_FILES_TEXT = N_("No commited files with the specified extensions were found") + +class ChangesBlameOutput(Outputable): + def __init__(self, changes, blame): + if format.is_interactive_format(): + print("") + + self.changes = changes + self.blame = blame + Outputable.__init__(self) + + def output_html(self): + authorinfo_list = self.changes.get_authorinfo_list() + total_changes = 0.0 + changes_xml = "
" + chart_data = "" + + for i in authorinfo_list: + total_changes += authorinfo_list.get(i).insertions + total_changes += authorinfo_list.get(i).deletions + + if authorinfo_list: + changes_xml += "

" + _(HISTORICAL_INFO_TEXT) + ".

" + changes_xml += "".format( + _("Author"), _("Commits"), _("Insertions"), _("Deletions"), _("% of changes")) + changes_xml += "" + + for i, entry in enumerate(sorted(authorinfo_list)): + authorinfo = authorinfo_list.get(entry) + percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 + + changes_xml += "" if i % 2 == 1 else ">") + + if format.get_selected() == "html": + changes_xml += "".format( + gravatar.get_url(self.changes.get_latest_email_by_author(entry)), entry) + else: + changes_xml += "" + + changes_xml += "" + changes_xml += "" + changes_xml += "" + changes_xml += "" + changes_xml += "" + chart_data += "{{label: {0}, data: {1}}}".format(json.dumps(entry), "{0:.2f}".format(percentage)) + + if sorted(authorinfo_list)[-1] != entry: + chart_data += ", " + + changes_xml += ("
{0} {1} {2} {3} {4}
{1}" + entry + "" + str(authorinfo.commits) + "" + str(authorinfo.insertions) + "" + str(authorinfo.deletions) + "" + "{0:.2f}".format(percentage) + "
 
") + changes_xml += "
" + changes_xml += "" + else: + changes_xml += "

" + _(NO_COMMITED_FILES_TEXT) + ".

" + + changes_xml += "
" + print(changes_xml) + + def output_json(self): + authorinfo_list = self.changes.get_authorinfo_list() + total_changes = 0.0 + + for i in authorinfo_list: + total_changes += authorinfo_list.get(i).insertions + total_changes += authorinfo_list.get(i).deletions + + if authorinfo_list: + message_json = "\t\t\t\"message\": \"" + _(HISTORICAL_INFO_TEXT) + "\",\n" + changes_json = "" + + for i in sorted(authorinfo_list): + author_email = self.changes.get_latest_email_by_author(i) + authorinfo = authorinfo_list.get(i) + + percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 + name_json = "\t\t\t\t\"name\": \"" + i + "\",\n" + email_json = "\t\t\t\t\"email\": \"" + author_email + "\",\n" + gravatar_json = "\t\t\t\t\"gravatar\": \"" + gravatar.get_url(author_email) + "\",\n" + commits_json = "\t\t\t\t\"commits\": " + str(authorinfo.commits) + ",\n" + insertions_json = "\t\t\t\t\"insertions\": " + str(authorinfo.insertions) + ",\n" + deletions_json = "\t\t\t\t\"deletions\": " + str(authorinfo.deletions) + ",\n" + percentage_json = "\t\t\t\t\"percentage_of_changes\": " + "{0:.2f}".format(percentage) + "\n" + + changes_json += ("{\n" + name_json + email_json + gravatar_json + commits_json + + insertions_json + deletions_json + percentage_json + "\t\t\t}") + changes_json += "," + else: + changes_json = changes_json[:-1] + + print("\t\t\"changes\": {\n" + message_json + "\t\t\t\"authors\": [\n\t\t\t" + changes_json + "]\n\t\t}", end="") + else: + print("\t\t\"exception\": \"" + _(NO_COMMITED_FILES_TEXT) + "\"") + + def output_text(self): + authorinfo_list = self.changes.get_authorinfo_list() + total_changes = 0.0 + + for i in authorinfo_list: + total_changes += authorinfo_list.get(i).insertions + total_changes += authorinfo_list.get(i).deletions + + if authorinfo_list: + print(textwrap.fill(_(HISTORICAL_INFO_TEXT) + ":", width=terminal.get_size()[0]) + "\n") + terminal.printb(terminal.ljust(_("Author"), 21) + terminal.rjust(_("Commits"), 13) + + terminal.rjust(_("Insertions"), 14) + terminal.rjust(_("Deletions"), 15) + + terminal.rjust(_("% of changes"), 16) + + terminal.rjust(_("Author"), 21) + terminal.rjust(_("Rows"), 10) + terminal.rjust(_("Stability"), + 15) + + terminal.rjust(_("Age"), 13) + terminal.rjust(_("% in comments"), 20)) + + for i,j in zip(sorted(authorinfo_list),sorted(self.blame.get_summed_blames().items())): + authorinfo = authorinfo_list.get(i) + percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 + + print(terminal.ljust(i, 20)[0:20 - terminal.get_excess_column_count(i)], end=" ") + print(str(authorinfo.commits).rjust(13), end=" ") + print(str(authorinfo.insertions).rjust(13), end=" ") + print(str(authorinfo.deletions).rjust(14), end=" ") + print("{0:.2f}".format(percentage).rjust(15), end=" ") + # blame + #print(terminal.ljust(j[0], 20)[0:20 - terminal.get_excess_column_count(j[0])], end=" ") + print(j[0].rjust(21), end=" ") + print(str(j[1].rows).rjust(10), end=" ") + print("{0:.1f}".format(Blame.get_stability(j[0], j[1].rows, self.changes)).rjust(14), end=" ") + print("{0:.1f}".format(float(j[1].skew) / j[1].rows).rjust(12), end=" ") + print("{0:.2f}".format(100.0 * j[1].comments / j[1].rows).rjust(19)) + else: + print(_(NO_COMMITED_FILES_TEXT) + ".") + + def output_csv(self): + authorinfo_list = self.changes.get_authorinfo_list() + total_changes = 0.0 + + #format.get_tag().split(',') + tagstr = format.get_tag() + if tagstr <> "": + tagstr += "," + + + for i in authorinfo_list: + total_changes += authorinfo_list.get(i).insertions + total_changes += authorinfo_list.get(i).deletions + + if authorinfo_list: + # print(textwrap.fill(_(HISTORICAL_INFO_TEXT) + ":", width=terminal.get_size()[0]) + "\n") + terminal.printb(tagstr + "Author,Commits,Insertions,Deletions,% of changes,Author,Rows,Stability,Age,% in comments") + + for i,j in zip(sorted(authorinfo_list),sorted(self.blame.get_summed_blames().items())): + authorinfo = authorinfo_list.get(i) + percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 + line = i \ + + "," + str(authorinfo.commits) \ + + "," + str(authorinfo.insertions) \ + + "," + str(authorinfo.deletions) \ + + "," + str(percentage) \ + + "," + j[0] \ + + "," + str(j[1].rows) \ + + "," + str(Blame.get_stability(j[0], j[1].rows, self.changes)) \ + + "," + str(float(j[1].skew) / j[1].rows) \ + + "," + str(100.0 * j[1].comments / j[1].rows) + print(tagstr + line) + else: + print(_(NO_COMMITED_FILES_TEXT) + ".") + + def output_xml(self): + authorinfo_list = self.changes.get_authorinfo_list() + total_changes = 0.0 + + for i in authorinfo_list: + total_changes += authorinfo_list.get(i).insertions + total_changes += authorinfo_list.get(i).deletions + + if authorinfo_list: + message_xml = "\t\t" + _(HISTORICAL_INFO_TEXT) + "\n" + changes_xml = "" + + for i in sorted(authorinfo_list): + author_email = self.changes.get_latest_email_by_author(i) + authorinfo = authorinfo_list.get(i) + + percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 + name_xml = "\t\t\t\t" + i + "\n" + email_xml = "\t\t\t\t" + author_email + "\n" + gravatar_xml = "\t\t\t\t" + gravatar.get_url(author_email) + "\n" + commits_xml = "\t\t\t\t" + str(authorinfo.commits) + "\n" + insertions_xml = "\t\t\t\t" + str(authorinfo.insertions) + "\n" + deletions_xml = "\t\t\t\t" + str(authorinfo.deletions) + "\n" + percentage_xml = "\t\t\t\t" + "{0:.2f}".format(percentage) + "\n" + + changes_xml += ("\t\t\t\n" + name_xml + email_xml + gravatar_xml + commits_xml + + insertions_xml + deletions_xml + percentage_xml + "\t\t\t\n") + + print("\t\n" + message_xml + "\t\t\n" + changes_xml + "\t\t\n\t") + else: + print("\t\n\t\t" + _(NO_COMMITED_FILES_TEXT) + "\n\t")