# Path: pypasta/MAINTAINERS.py
# def load_maintainers(config, versions):
#     def __load_maintainers(ret, config, versions):
#         if ret is None:
#             ret = dict()
# 
#         # Only load what's not yet cached
#         versions -= ret.keys()
# 
#         if len(versions) == 0:
#             return ret, False
# 
#         global _repo
#         _repo = config.repo
#         p = Pool(processes=cpu_count())
#         function = partial(_load_maintainer,
#                            d_cluster = config.d_maintainers_cluster,
#                            project_name = config.project_name)
# 
#         for tag, maintainers in tqdm(p.imap_unordered(function, versions),
#                                      total=len(versions), desc='MAINTAINERS'):
#             ret[tag] = maintainers
# 
#         p.close()
#         p.join()
#         _repo = None
# 
#         return ret, True
# 
#     log.info('Loading/Updating MAINTAINERS...')
#     maintainers_version = load_pkl_and_update(config.f_maintainers_pkl,
#                                               __load_maintainers, config,
#                                               versions)
#     return maintainers_version
# 
# Path: pypasta/Util.py
# def get_first_upstream(repo, cluster, commit):
#     upstream = cluster.get_upstream(commit)
#     if not upstream:
#         return None
#     return min(upstream, key=lambda x: repo[x].committer.date)
# 
# def load_pkl_and_update(filename, update_command, *params):
#     ret = None
#     if os.path.isfile(filename):
#         ret = pickle.load(open(filename, 'rb'))
# 
#     if len(params) == 0:
#         ret, changed = update_command(ret)
#     else:
#         ret, changed = update_command(ret, *params)
# 
#     if changed:
#         pickle.dump(ret, open(filename, 'wb'))
# 
#     return ret
# 
# def mail_parse_date(date_str, assume_epoch=False):
#     try:
#         date = email.utils.parsedate_to_datetime(date_str)
#     except Exception:
#         date = None
# 
#     if not date:
#         try:
#             date = dateparser.parse(date_str)
#         except Exception:
#             date = None
# 
#     if not date:
#         date = datetime.datetime.utcfromtimestamp(0)
# 
#     if date.tzinfo is None:
#         date = date.replace(tzinfo=datetime.timezone.utc)
# 
#     return date


import csv
import email
import re
from anytree import LevelOrderIter
from enum import Enum
from logging import getLogger
from multiprocessing import Pool, cpu_count
from .MAINTAINERS import load_maintainers
from .Util import get_first_upstream, load_pkl_and_update, mail_parse_date
    from .BuildrootMailCharacteristics import BuildrootMailCharacteristics
    from .DPDKMailCharacteristics import DPDKMailCharacteristics
    from .GitMailCharacteristics import GitMailCharacteristics
    from .JailhouseMailCharacteristics import JailhouseMailCharacteristics
    from .LinuxMailCharacteristics import LinuxMailCharacteristics
    from .OpenembeddedMailCharacteristics import OpenembeddedMailCharacteristics
    from .QemuMailCharacteristics import QemuMailCharacteristics
    from .UBootMailCharacteristics import UBootMailCharacteristics
    from .XenMailCharacteristics import XenMailCharacteristics
                return True
        return False

    def _cleanup(self, maintainers_version):
        if self.is_patch:
            self._integrated_correct(maintainers_version)

        del self.message
        del self.patch
        del self.upstream

        if not self.is_patch:
            return

        # Now we can say it's a regular patch, if we still have the type 'other'
        if self.type == PatchType.OTHER:
            self.type = PatchType.PATCH

    def __init__(self, repo, clustering, message_id):
        self.message_id = message_id

        self.message = repo.mbox.get_messages(message_id)[0]
        self.thread = repo.mbox.threads.get_thread(message_id)
        self.recipients = email_get_recipients(self.message)

        self.recipients_lists = self.recipients & (repo.mbox.lists | self.LISTS)
        self.recipients_other = self.recipients - (repo.mbox.lists | self.LISTS)

        self.mail_from = email_get_from(self.message)
        self.subject = email_get_header_normalised(self.message, 'Subject')

# Path: pypasta/MAINTAINERS.py
# def load_maintainers(config, versions):
#     def __load_maintainers(ret, config, versions):
#         if ret is None:
#             ret = dict()
# 
#         # Only load what's not yet cached
#         versions -= ret.keys()
# 
#         if len(versions) == 0:
#             return ret, False
# 
#         global _repo
#         _repo = config.repo
#         p = Pool(processes=cpu_count())
#         function = partial(_load_maintainer,
#                            d_cluster = config.d_maintainers_cluster,
#                            project_name = config.project_name)
# 
#         for tag, maintainers in tqdm(p.imap_unordered(function, versions),
#                                      total=len(versions), desc='MAINTAINERS'):
#             ret[tag] = maintainers
# 
#         p.close()
#         p.join()
#         _repo = None
# 
#         return ret, True
# 
#     log.info('Loading/Updating MAINTAINERS...')
#     maintainers_version = load_pkl_and_update(config.f_maintainers_pkl,
#                                               __load_maintainers, config,
#                                               versions)
#     return maintainers_version
# 
# Path: pypasta/Util.py
# def get_first_upstream(repo, cluster, commit):
#     upstream = cluster.get_upstream(commit)
#     if not upstream:
#         return None
#     return min(upstream, key=lambda x: repo[x].committer.date)
# 
# def load_pkl_and_update(filename, update_command, *params):
#     ret = None
#     if os.path.isfile(filename):
#         ret = pickle.load(open(filename, 'rb'))
# 
#     if len(params) == 0:
#         ret, changed = update_command(ret)
#     else:
#         ret, changed = update_command(ret, *params)
# 
#     if changed:
#         pickle.dump(ret, open(filename, 'wb'))
# 
#     return ret
# 
# def mail_parse_date(date_str, assume_epoch=False):
#     try:
#         date = email.utils.parsedate_to_datetime(date_str)
#     except Exception:
#         date = None
# 
#     if not date:
#         try:
#             date = dateparser.parse(date_str)
#         except Exception:
#             date = None
# 
#     if not date:
#         date = datetime.datetime.utcfromtimestamp(0)
# 
#     if date.tzinfo is None:
#         date = date.replace(tzinfo=datetime.timezone.utc)
# 
#     return date


# Path: pypasta/MailCharacteristics.py
import csv
import email
import re
from anytree import LevelOrderIter
from enum import Enum
from logging import getLogger
from multiprocessing import Pool, cpu_count
from .MAINTAINERS import load_maintainers
from .Util import get_first_upstream, load_pkl_and_update, mail_parse_date
    from .BuildrootMailCharacteristics import BuildrootMailCharacteristics
    from .DPDKMailCharacteristics import DPDKMailCharacteristics
    from .GitMailCharacteristics import GitMailCharacteristics
    from .JailhouseMailCharacteristics import JailhouseMailCharacteristics
    from .LinuxMailCharacteristics import LinuxMailCharacteristics
    from .OpenembeddedMailCharacteristics import OpenembeddedMailCharacteristics
    from .QemuMailCharacteristics import QemuMailCharacteristics
    from .UBootMailCharacteristics import UBootMailCharacteristics
    from .XenMailCharacteristics import XenMailCharacteristics

                return True
        return False

    def _cleanup(self, maintainers_version):
        if self.is_patch:
            self._integrated_correct(maintainers_version)

        del self.message
        del self.patch
        del self.upstream

        if not self.is_patch:
            return

        # Now we can say it's a regular patch, if we still have the type 'other'
        if self.type == PatchType.OTHER:
            self.type = PatchType.PATCH

    def __init__(self, repo, clustering, message_id):
        self.message_id = message_id

        self.message = repo.mbox.get_messages(message_id)[0]
        self.thread = repo.mbox.threads.get_thread(message_id)
        self.recipients = email_get_recipients(self.message)

        self.recipients_lists = self.recipients & (repo.mbox.lists | self.LISTS)
        self.recipients_other = self.recipients - (repo.mbox.lists | self.LISTS)

        self.mail_from = email_get_from(self.message)
        self.subject = email_get_header_normalised(self.message, 'Subject')

        self.date = mail_parse_date(self.message['Date'])