<commit_before>#!/usr/bin/env python3

from os import path, getcwd
from sys import exit

from pygit2 import Repository
from pygit2 import GIT_SORT_TIME, GIT_DIFF_STATS_FULL

from openpyxl import Workbook
from openpyxl.styles import colors, Font, Color, Alignment
from openpyxl import cell

from optparse import OptionParser
from datetime import datetime

class LogEntry:
    def __init__(self):
        self.id = None
        self.msg = None
        self.author = None
        self.email = None
        self.time = None
        self.diff = None

class ScmAccessor:
    def __init__(self, repo_path):
        self._repo_path = repo_path
        self._scm = None

    def get_log(self):
        raise RuntimeError("Not meant to be called in parent class")


class GitAccessor(ScmAccessor):
    def __init__(self, repo_path):
        super().__init__(repo_path)
        self._scm = Repository(path.join(repo_path))

    def get_log(self):
        data = []
        for c in self._scm.walk(self._scm.head.target, GIT_SORT_TIME):
            diff = self._scm.diff(c, c.parents[0]).stats.format(GIT_DIFF_STATS_FULL, 1) if c.parents else ""

            diff = diff.splitlines()
            if len(diff) >= 1:
                diff = diff[:-1]

            stripped_diff = [ d.split("|")[0].strip() for d in diff ]

            e = LogEntry()
            e.id = c.id
            e.msg = c.message.strip("\n")
            e.author = c.committer.name
            e.email = c.committer.email
            e.time = c.commit_time
            e.diff = stripped_diff
            data.append(e)
        return data


class HgAccessor(ScmAccessor):
    def __init__(self, repo_path):
        super().__init__(repo_path)
        raise NotImplementedError("Implement me!")


class SvnAccessor(ScmAccessor):
    def __init__(self, repo_path):
        super().__init__(repo_path)
        raise NotImplementedError("Implement me!")



class Writer:
    def __init__(self, filename):
        self._filename = filename
        self._workbook = Workbook()
        self._columns = ["Date", "Commit-ID", "Message", "Author", "Changed files"]

        ws = self._workbook.active
        ws.column_dimensions["A"].width = 20
        ws.column_dimensions["B"].width = 20
        ws.column_dimensions["C"].width = 50
        ws.column_dimensions["D"].width = 20
        ws.column_dimensions["E"].width = 25
        ws.column_dimensions["F"].width = 20
        ws.column_dimensions["G"].width = 20
        ws.column_dimensions["H"].width = 20

    def write_header(self):
        raise RuntimeError("Not to be called in base class")

    def write_data(self):
        raise RuntimeError("Not to be called in base class")

    def write_data(self, accessor):
        ws = self._workbook.active

        for d in accessor.get_log():
            ws.append([datetime.fromtimestamp(d.time).strftime("%Y-%m-%d %H:%M:%S"),
                       str(d.id), str(d.msg), str(d.author),
                       "\n".join(d.diff)])
            ws["B"+str(ws.max_row)].font = Font(name="Monospace", size=8)
            ws["C"+str(ws.max_row)].font = Font(size=10)
            ws["C"+str(ws.max_row)].alignment = Alignment(wrap_text=True)

    def save(self):
        self._workbook.save(self._filename)


class CommitHistoryWriter(Writer):
    def __init__(self, filename):
        super().__init__(filename)

    def write_header(self):<commit_msg>scm-to-xls.py: Align cell content to top<commit_after>#!/usr/bin/env python3

from os import path, getcwd
from sys import exit

from pygit2 import Repository
from pygit2 import GIT_SORT_TIME, GIT_DIFF_STATS_FULL

from openpyxl import Workbook
from openpyxl.styles import colors, Font, Color, Alignment
from openpyxl import cell

from optparse import OptionParser
from datetime import datetime

from string import ascii_uppercase

class LogEntry:
    def __init__(self):
        self.id = None
        self.msg = None
        self.author = None
        self.email = None
        self.time = None
        self.diff = None

class ScmAccessor:
    def __init__(self, repo_path):
        self._repo_path = repo_path
        self._scm = None

    def get_log(self):
        raise RuntimeError("Not meant to be called in parent class")


class GitAccessor(ScmAccessor):
    def __init__(self, repo_path):
        super().__init__(repo_path)
        self._scm = Repository(path.join(repo_path))

    def get_log(self):
        data = []
        for c in self._scm.walk(self._scm.head.target, GIT_SORT_TIME):
            diff = self._scm.diff(c, c.parents[0]).stats.format(GIT_DIFF_STATS_FULL, 1) if c.parents else ""

            diff = diff.splitlines()
            if len(diff) >= 1:
                diff = diff[:-1]

            stripped_diff = [ d.split("|")[0].strip() for d in diff ]

            e = LogEntry()
            e.id = c.id
            e.msg = c.message.strip("\n")
            e.author = c.committer.name
            e.email = c.committer.email
            e.time = c.commit_time
            e.diff = stripped_diff
            data.append(e)
        return data


class HgAccessor(ScmAccessor):
    def __init__(self, repo_path):
        super().__init__(repo_path)
        raise NotImplementedError("Implement me!")


class SvnAccessor(ScmAccessor):
    def __init__(self, repo_path):
        super().__init__(repo_path)
        raise NotImplementedError("Implement me!")



class Writer:
    def __init__(self, filename):
        self._filename = filename
        self._workbook = Workbook()
        self._columns = ["Date", "Commit-ID", "Message", "Author", "Changed files"]

        ws = self._workbook.active
        ws.column_dimensions["A"].width = 20
        ws.column_dimensions["B"].width = 20
        ws.column_dimensions["C"].width = 50
        ws.column_dimensions["D"].width = 20
        ws.column_dimensions["E"].width = 25
        ws.column_dimensions["F"].width = 20
        ws.column_dimensions["G"].width = 20
        ws.column_dimensions["H"].width = 20

    def write_header(self):
        raise RuntimeError("Not to be called in base class")

    def write_data(self):
        raise RuntimeError("Not to be called in base class")

    def write_data(self, accessor):
        ws = self._workbook.active

        for d in accessor.get_log():
            ws.append([datetime.fromtimestamp(d.time).strftime("%Y-%m-%d %H:%M:%S"),
                       str(d.id), str(d.msg), str(d.author),
                       "\n".join(d.diff)])

            for c in ascii_uppercase[:len(self._columns)]:
                ws[c+str(ws.max_row)].alignment = Alignment(vertical="top")

            ws["B"+str(ws.max_row)].font = Font(name="Monospace", size=8)
            ws["C"+str(ws.max_row)].font = Font(size=10)
            ws["C"+str(ws.max_row)].alignment = Alignment(wrap_text=True, shrink_to_fit=True, vertical="top")
            #ws.row_dimensions[ws.max_row].height = d.msg.count("\n") * 15

    def save(self):
        self._workbook.save(self._filename)


class CommitHistoryWriter(Writer):
    def __init__(self, filename):
        super().__init__(filename)

    def write_header(self):
{'fraction_non_alphanumeric': 0.12266404383869609, 'fraction_numerical': 0.007868483911760574, 'mean_word_length': 2.4237614237614236, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '53163', 'n_tokens_mistral': 2328, 'n_tokens_neox': 2200, 'n_words': 493}