예제 #1
0
def _create_build_email(**kwargs):
    """Parse the results and create the email text body to send.

    :param job: The name of the job.
    :type job: str
    :param  kernel: The name of the kernel.
    :type kernel: str
    :param git_commit: The git commit.
    :type git_commit: str
    :param git_url: The git url.
    :type git_url: str
    :param git_branch: The git branch.
    :type git_branch: str
    :param failed_data: The parsed failed results.
    :type failed_data: dict
    :param fail_count: The total number of failed results.
    :type fail_count: int
    :param total_count: The total number of results.
    :type total_count: int
    :param total_unique_data: The unique values data structure.
    :type total_unique_data: dictionary
    :param pass_count: The total number of passed results.
    :type pass_count: int
    :param base_url: The base URL to build the dashboard links.
    :type base_url: string
    :param boot_url: The base URL for the boot section of the dashboard.
    :type boot_url: string
    :param build_url: The base URL for the build section of the dashboard.
    :type build_url: string
    :param info_email: The email address for the footer note.
    :type info_email: string
    :return A tuple with the email body and subject as strings.
    """
    txt_body = None
    html_body = None
    subject_str = None

    k_get = kwargs.get
    email_format = k_get("email_format")
    total_unique_data = k_get("total_unique_data", None)
    failed_data = k_get("failed_data", None)
    error_data = k_get("error_data", None)

    subject_str = _get_build_subject_string(**kwargs)

    built_unique_one = G_(u"Built: {:s}")

    built_unique_string = None
    if total_unique_data:
        unique_archs = rcommon.count_unique(total_unique_data.get(
            "arch", None))

        kwargs["unique_archs"] = unique_archs

        arch_str = P_(u"{unique_archs:d} unique architecture",
                      u"{unique_archs:d} unique architectures", unique_archs)

        if unique_archs > 0:
            built_unique_string = built_unique_one.format(arch_str)

        if built_unique_string:
            built_unique_string = built_unique_string.format(**kwargs)

    build_summary_url = BUILD_SUMMARY_URL.format(**kwargs)

    kwargs["built_unique_string"] = built_unique_string
    kwargs["tree_string"] = G_(u"Tree: {job:s}").format(**kwargs)
    kwargs["branch_string"] = G_(u"Branch: {git_branch:s}").format(**kwargs)
    kwargs["git_describe_string"] = G_(u"Git Describe: {kernel:s}").format(
        **kwargs)
    kwargs["subject_str"] = subject_str

    git_url = k_get("git_url")
    git_commit = k_get("git_commit")

    translated_git_url = \
        rcommon.translate_git_url(git_url, git_commit) or git_url

    git_txt_string = G_(u"Git URL: {:s}").format(git_url)
    git_html_string = G_(u"Git URL: <a href=\"{:s}\">{:s}</a>").format(
        translated_git_url, git_url)

    kwargs["git_commit_string"] = G_(u"Git Commit: {:s}").format(git_commit)
    kwargs["git_url_string"] = (git_txt_string, git_html_string)

    if failed_data or error_data:
        kwargs["platforms"] = _parse_and_structure_results(**kwargs)

    if models.EMAIL_TXT_FORMAT_KEY in email_format:
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: {:s}").format(build_summary_url))

        txt_body = rcommon.create_txt_email("build.txt", **kwargs)

    if models.EMAIL_HTML_FORMAT_KEY in email_format:
        # Fix the summary URLs for the HTML email.
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": build_summary_url}))

        html_body = rcommon.create_html_email("build.html", **kwargs)

    return txt_body, html_body, subject_str
예제 #2
0
def _create_boot_email(boot_data):
    """Parse the results and create the email text body to send.

    :param boot_data: Details about the boot results
    :type boot_data: dict
    :return A tuple with the email body and subject as strings.
    """
    txt_body = None
    html_body = None
    subject_str = None

    b_get = boot_data.get
    total_unique_data = b_get("total_unique_data", None)
    info_email = b_get("info_email", None)
    email_format = b_get("email_format")

    subject_str = get_boot_subject_string(boot_data)

    tested_one = G_(u"Tested: {:s}")
    tested_two = G_(u"Tested: {:s}, {:s}")
    tested_three = G_(u"Tested: {:s}, {:s}, {:s}")

    tested_string = None
    if total_unique_data:
        unique_boards = rcommon.count_unique(
            total_unique_data.get(models.BOARD_KEY, None))
        unique_socs = rcommon.count_unique(
            total_unique_data.get(models.MACH_KEY, None))
        unique_builds = rcommon.count_unique(
            total_unique_data[models.DEFCONFIG_FULL_KEY])

        boot_data["unique_boards"] = unique_boards
        boot_data["unique_socs"] = unique_socs
        boot_data["unique_builds"] = unique_builds

        boards_str = P_(
            u"{unique_boards:d} unique board",
            u"{unique_boards:d} unique boards",
            unique_boards
        )
        soc_str = P_(
            u"{unique_socs:d} SoC family",
            u"{unique_socs:d} SoC families",
            unique_socs
        )
        builds_str = P_(
            u"{unique_builds:d} build out of {total_builds:d}",
            u"{unique_builds:d} builds out of {total_builds:d}",
            unique_builds
        )

        if unique_boards > 0 and unique_socs > 0 and unique_builds > 0:
            tested_string = tested_three.format(
                boards_str, soc_str, builds_str)
        elif unique_boards > 0 and unique_socs > 0 and unique_builds == 0:
            tested_string = tested_two.format(boards_str, soc_str)
        elif unique_boards > 0 and unique_socs == 0 and unique_builds > 0:
            tested_string = tested_two.format(boards_str, builds_str)
        elif unique_boards == 0 and unique_socs > 0 and unique_builds > 0:
            tested_string = tested_two.format(soc_str, builds_str)
        elif unique_boards > 0 and unique_socs == 0 and unique_builds == 0:
            tested_string = tested_one.format(boards_str)
        elif unique_boards == 0 and unique_socs > 0 and unique_builds == 0:
            tested_string = tested_one.format(soc_str)
        elif unique_boards == 0 and unique_socs == 0 and unique_builds > 0:
            tested_string = tested_one.format(builds_str)

        if tested_string:
            tested_string = tested_string.format(**boot_data)

    boot_summary_url = rcommon.BOOT_SUMMARY_URL.format(**boot_data)
    build_summary_url = rcommon.BUILD_SUMMARY_URL.format(**boot_data)

    boot_data["tree_string"] = G_(u"Tree: {job:s}").format(**boot_data)
    boot_data["branch_string"] = G_(u"Branch: {git_branch:s}").format(
        **boot_data)
    boot_data["git_describe_string"] = G_(u"Git Describe: {kernel:s}").format(
        **boot_data)
    boot_data["info_email"] = info_email
    boot_data["tested_string"] = tested_string
    boot_data["subject_str"] = subject_str

    git_url = b_get("git_url")
    git_commit = b_get("git_commit")

    translated_git_url = \
        rcommon.translate_git_url(git_url, git_commit) or git_url

    git_txt_string = G_(u"Git URL: {:s}").format(git_url)
    git_html_string = G_(u"Git URL: <a href=\"{:s}\">{:s}</a>").format(
        translated_git_url, git_url)

    boot_data["git_commit_string"] = G_(u"Git Commit: {:s}").format(git_commit)
    boot_data["git_url_string"] = (git_txt_string, git_html_string)

    boot_data["platforms"] = _parse_and_structure_results(boot_data)

    if models.EMAIL_TXT_FORMAT_KEY in email_format:
        boot_data["full_boot_summary"] = (
            G_(u"Full Boot Summary: {:s}").format(boot_summary_url))
        boot_data["full_build_summary"] = (
            G_(u"Full Build Summary: {:s}").format(build_summary_url))

        txt_body = rcommon.create_txt_email("boot.txt", **boot_data)

    if models.EMAIL_HTML_FORMAT_KEY in email_format:
        # Fix the summary URLs for the HTML email.
        boot_data["full_boot_summary"] = (
            G_(u"Full Boot Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": boot_summary_url})
        )
        boot_data["full_build_summary"] = (
            G_(u"Full Build Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": build_summary_url})
        )

        html_body = rcommon.create_html_email("boot.html", **boot_data)

    return txt_body, html_body, subject_str
예제 #3
0
def _create_boot_email(boot_data):
    """Parse the results and create the email text body to send.

    :param boot_data: Details about the boot results
    :type boot_data: dict
    :return A tuple with the email body and subject as strings.
    """
    txt_body = None
    html_body = None
    subject_str = None

    b_get = boot_data.get
    total_unique_data = b_get("total_unique_data", None)
    info_email = b_get("info_email", None)
    email_format = b_get("email_format")

    subject_str = get_boot_subject_string(boot_data)

    tested_one = G_(u"Tested: {:s}")
    tested_two = G_(u"Tested: {:s}, {:s}")
    tested_three = G_(u"Tested: {:s}, {:s}, {:s}")

    tested_string = None
    if total_unique_data:
        unique_boards = rcommon.count_unique(
            total_unique_data.get(models.BOARD_KEY, None))
        unique_socs = rcommon.count_unique(
            total_unique_data.get(models.MACH_KEY, None))
        unique_builds = rcommon.count_unique(
            total_unique_data[models.DEFCONFIG_FULL_KEY])

        boot_data["unique_boards"] = unique_boards
        boot_data["unique_socs"] = unique_socs
        boot_data["unique_builds"] = unique_builds

        boards_str = P_(
            u"{unique_boards:d} unique board",
            u"{unique_boards:d} unique boards",
            unique_boards
        )
        soc_str = P_(
            u"{unique_socs:d} SoC family",
            u"{unique_socs:d} SoC families",
            unique_socs
        )
        builds_str = P_(
            u"{unique_builds:d} build out of {total_builds:d}",
            u"{unique_builds:d} builds out of {total_builds:d}",
            unique_builds
        )

        if unique_boards > 0 and unique_socs > 0 and unique_builds > 0:
            tested_string = tested_three.format(
                boards_str, soc_str, builds_str)
        elif unique_boards > 0 and unique_socs > 0 and unique_builds == 0:
            tested_string = tested_two.format(boards_str, soc_str)
        elif unique_boards > 0 and unique_socs == 0 and unique_builds > 0:
            tested_string = tested_two.format(boards_str, builds_str)
        elif unique_boards == 0 and unique_socs > 0 and unique_builds > 0:
            tested_string = tested_two.format(soc_str, builds_str)
        elif unique_boards > 0 and unique_socs == 0 and unique_builds == 0:
            tested_string = tested_one.format(boards_str)
        elif unique_boards == 0 and unique_socs > 0 and unique_builds == 0:
            tested_string = tested_one.format(soc_str)
        elif unique_boards == 0 and unique_socs == 0 and unique_builds > 0:
            tested_string = tested_one.format(builds_str)

        if tested_string:
            tested_string = tested_string.format(**boot_data)

    boot_summary_url = rcommon.BOOT_SUMMARY_URL.format(**boot_data)
    build_summary_url = rcommon.BUILD_SUMMARY_URL.format(**boot_data)

    boot_data["tree_string"] = G_(u"Tree: {job:s}").format(**boot_data)
    boot_data["branch_string"] = G_(u"Branch: {git_branch:s}").format(
        **boot_data)
    boot_data["git_describe_string"] = G_(u"Git Describe: {kernel:s}").format(
        **boot_data)
    boot_data["info_email"] = info_email
    boot_data["tested_string"] = tested_string
    boot_data["subject_str"] = subject_str

    git_url = b_get("git_url")
    git_commit = b_get("git_commit")

    translated_git_url = \
        rcommon.translate_git_url(git_url, git_commit) or git_url

    git_txt_string = G_(u"Git URL: {:s}").format(git_url)
    git_html_string = G_(u"Git URL: <a href=\"{:s}\">{:s}</a>").format(
        translated_git_url, git_url)

    boot_data["git_commit_string"] = G_(u"Git Commit: {:s}").format(git_commit)
    boot_data["git_url_string"] = (git_txt_string, git_html_string)

    boot_data["platforms"] = _parse_and_structure_results(boot_data)

    if models.EMAIL_TXT_FORMAT_KEY in email_format:
        boot_data["full_boot_summary"] = (
            G_(u"Full Boot Summary: {:s}").format(boot_summary_url))
        boot_data["full_build_summary"] = (
            G_(u"Full Build Summary: {:s}").format(build_summary_url))

        txt_body = rcommon.create_txt_email("boot.txt", **boot_data)

    if models.EMAIL_HTML_FORMAT_KEY in email_format:
        # Fix the summary URLs for the HTML email.
        boot_data["full_boot_summary"] = (
            G_(u"Full Boot Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": boot_summary_url})
        )
        boot_data["full_build_summary"] = (
            G_(u"Full Build Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": build_summary_url})
        )

        html_body = rcommon.create_html_email("boot.html", **boot_data)

    return txt_body, html_body, subject_str
예제 #4
0
 def test_count_unique_with_tuple(self):
     to_count = (None, "a", "b", None, None, None, "c")
     self.assertEqual(3, rcommon.count_unique(to_count))
예제 #5
0
def _create_boot_email(**kwargs):
    """Parse the results and create the email text body to send.

    :param job: The name of the job.
    :type job: str
    :param  kernel: The name of the kernel.
    :type kernel: str
    :param git_commit: The git commit.
    :type git_commit: str
    :param git_url: The git url.
    :type git_url: str
    :param git_branch: The git branch.
    :type git_branch: str
    :param lab_name: The name of the lab.
    :type lab_name: str
    :param failed_data: The parsed failed results.
    :type failed_data: dict
    :param fail_count: The total number of failed results.
    :type fail_count: int
    :param offline_data: The parsed offline results.
    :type offline_data: dict
    :param offline_count: The total number of offline results.
    :type offline_count: int
    :param total_count: The total number of results.
    :type total_count: int
    :param total_unique_data: The unique values data structure.
    :type total_unique_data: dictionary
    :param pass_count: The total number of passed results.
    :type pass_count: int
    :param conflict_data: The parsed conflicting results.
    :type conflict_data: dict
    :param conflict_count: The number of conflicting results.
    :type conflict_count: int
    :param total_builds: The total number of defconfig built.
    :type total_builds: int
    :param base_url: The base URL to build the dashboard links.
    :type base_url: string
    :param boot_url: The base URL for the boot section of the dashboard.
    :type boot_url: string
    :param build_url: The base URL for the build section of the dashboard.
    :type build_url: string
    :param info_email: The email address for the footer note.
    :type info_email: string
    :return A tuple with the email body and subject as strings.
    """
    txt_body = None
    html_body = None
    subject_str = None

    k_get = kwargs.get
    total_unique_data = k_get("total_unique_data", None)
    info_email = k_get("info_email", None)
    email_format = k_get("email_format")

    subject_str = _get_boot_subject_string(**kwargs)

    tested_one = G_(u"Tested: {:s}")
    tested_two = G_(u"Tested: {:s}, {:s}")
    tested_three = G_(u"Tested: {:s}, {:s}, {:s}")

    tested_string = None
    if total_unique_data:
        unique_boards = rcommon.count_unique(
            total_unique_data.get(models.BOARD_KEY, None))
        unique_socs = rcommon.count_unique(
            total_unique_data.get(models.MACH_KEY, None))
        unique_builds = rcommon.count_unique(
            total_unique_data[models.DEFCONFIG_FULL_KEY])

        kwargs["unique_boards"] = unique_boards
        kwargs["unique_socs"] = unique_socs
        kwargs["unique_builds"] = unique_builds

        boards_str = P_(
            u"{unique_boards:d} unique board",
            u"{unique_boards:d} unique boards",
            unique_boards
        )
        soc_str = P_(
            u"{unique_socs:d} SoC family",
            u"{unique_socs:d} SoC families",
            unique_socs
        )
        builds_str = P_(
            u"{unique_builds:d} build out of {total_builds:d}",
            u"{unique_builds:d} builds out of {total_builds:d}",
            unique_builds
        )

        if all([unique_boards > 0, unique_socs > 0, unique_builds > 0]):
            tested_string = tested_three.format(
                boards_str, soc_str, builds_str)
        elif all([unique_boards > 0, unique_socs > 0, unique_builds == 0]):
            tested_string = tested_two.format(boards_str, soc_str)
        elif all([unique_boards > 0, unique_socs == 0, unique_builds > 0]):
            tested_string = tested_two.format(boards_str, builds_str)
        elif all([unique_boards == 0, unique_socs > 0, unique_builds > 0]):
            tested_string = tested_two.format(soc_str, builds_str)
        elif all([unique_boards > 0, unique_socs == 0, unique_builds == 0]):
            tested_string = tested_one.format(boards_str)
        elif all([unique_boards == 0, unique_socs > 0, unique_builds == 0]):
            tested_string = tested_one.format(soc_str)
        elif all([unique_boards == 0, unique_socs == 0, unique_builds > 0]):
            tested_string = tested_one.format(builds_str)

        if tested_string:
            tested_string = tested_string.format(**kwargs)

    boot_summary_url = BOOT_SUMMARY_URL.format(**kwargs)
    build_summary_url = BUILD_SUMMARY_URL.format(**kwargs)

    kwargs["tree_string"] = G_(u"Tree: {job:s}").format(**kwargs)
    kwargs["branch_string"] = G_(u"Branch: {git_branch:s}").format(**kwargs)
    kwargs["git_describe_string"] = G_(u"Git Describe: {kernel:s}").format(
        **kwargs)
    kwargs["info_email"] = info_email
    kwargs["tested_string"] = tested_string
    kwargs["subject_str"] = subject_str

    git_url = k_get("git_url")
    git_commit = k_get("git_commit")

    translated_git_url = \
        rcommon.translate_git_url(git_url, git_commit) or git_url

    git_txt_string = G_(u"Git URL: {:s}").format(git_url)
    git_html_string = G_(u"Git URL: <a href=\"{:s}\">{:s}</a>").format(
        translated_git_url, git_url)

    kwargs["git_commit_string"] = G_(u"Git Commit: {:s}").format(git_commit)
    kwargs["git_url_string"] = (git_txt_string, git_html_string)

    kwargs["platforms"] = _parse_and_structure_results(**kwargs)

    if models.EMAIL_TXT_FORMAT_KEY in email_format:
        kwargs["full_boot_summary"] = (
            G_(u"Full Boot Summary: {:s}").format(boot_summary_url))
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: {:s}").format(build_summary_url))

        txt_body = rcommon.create_txt_email("boot.txt", **kwargs)

    if models.EMAIL_HTML_FORMAT_KEY in email_format:
        # Fix the summary URLs for the HTML email.
        kwargs["full_boot_summary"] = (
            G_(u"Full Boot Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": boot_summary_url})
        )
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": build_summary_url})
        )

        html_body = rcommon.create_html_email("boot.html", **kwargs)

    return txt_body, html_body, subject_str
예제 #6
0
 def test_count_unique_with_list(self):
     to_count = [None, "a", "b", None]
     self.assertEqual(2, rcommon.count_unique(to_count))
예제 #7
0
 def test_count_unique_with_dict(self):
     to_count = {}
     self.assertEqual(0, rcommon.count_unique(to_count))
예제 #8
0
 def test_count_unique_with_string(self):
     to_count = ""
     self.assertEqual(0, rcommon.count_unique(to_count))
예제 #9
0
def _create_build_email(**kwargs):
    """Parse the results and create the email text body to send.

    :param job: The name of the job.
    :type job: str
    :param  kernel: The name of the kernel.
    :type kernel: str
    :param git_commit: The git commit.
    :type git_commit: str
    :param git_url: The git url.
    :type git_url: str
    :param git_branch: The git branch.
    :type git_branch: str
    :param failed_data: The parsed failed results.
    :type failed_data: dict
    :param fail_count: The total number of failed results.
    :type fail_count: int
    :param total_count: The total number of results.
    :type total_count: int
    :param total_unique_data: The unique values data structure.
    :type total_unique_data: dictionary
    :param pass_count: The total number of passed results.
    :type pass_count: int
    :param base_url: The base URL to build the dashboard links.
    :type base_url: string
    :param boot_url: The base URL for the boot section of the dashboard.
    :type boot_url: string
    :param build_url: The base URL for the build section of the dashboard.
    :type build_url: string
    :param info_email: The email address for the footer note.
    :type info_email: string
    :return A tuple with the email body and subject as strings.
    """
    txt_body = None
    html_body = None
    subject_str = None

    k_get = kwargs.get
    email_format = k_get("email_format")
    total_unique_data = k_get("total_unique_data", None)
    failed_data = k_get("failed_data", None)
    error_data = k_get("error_data", None)

    subject_str = _get_build_subject_string(**kwargs)

    built_unique_one = G_(u"Built: {:s}")

    built_unique_string = None
    if total_unique_data:
        unique_archs = rcommon.count_unique(
            total_unique_data.get("arch", None))

        kwargs["unique_archs"] = unique_archs

        arch_str = P_(
            u"{unique_archs:d} unique architecture",
            u"{unique_archs:d} unique architectures",
            unique_archs
        )

        if unique_archs > 0:
            built_unique_string = built_unique_one.format(arch_str)

        if built_unique_string:
            built_unique_string = built_unique_string.format(**kwargs)

    build_summary_url = u"{build_url:s}/{job:s}/kernel/{kernel:s}/".format(
        **kwargs)

    kwargs["built_unique_string"] = built_unique_string
    kwargs["tree_string"] = G_(u"Tree: {job:s}").format(**kwargs)
    kwargs["branch_string"] = G_(u"Branch: {git_branch:s}").format(**kwargs)
    kwargs["git_describe_string"] = G_(u"Git Describe: {kernel:s}").format(
        **kwargs)
    kwargs["subject_str"] = subject_str

    git_url = k_get("git_url")
    git_commit = k_get("git_commit")

    translated_git_url = \
        rcommon.translate_git_url(git_url, git_commit) or git_url

    git_txt_string = G_(u"Git URL: {:s}").format(git_url)
    git_html_string = G_(u"Git URL: <a href=\"{:s}\">{:s}</a>").format(
        translated_git_url, git_url)

    kwargs["git_commit_string"] = G_(u"Git Commit: {:s}").format(git_commit)
    kwargs["git_url_string"] = (git_txt_string, git_html_string)

    if any([failed_data, error_data]):
        kwargs["platforms"] = _parse_and_structure_results(**kwargs)

    if models.EMAIL_TXT_FORMAT_KEY in email_format:
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: {:s}").format(build_summary_url))

        txt_body = rcommon.create_txt_email("build.txt", **kwargs)

    if models.EMAIL_HTML_FORMAT_KEY in email_format:
        # Fix the summary URLs for the HTML email.
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": build_summary_url}))

        html_body = rcommon.create_html_email("build.html", **kwargs)

    # utils.LOG.info(kwargs)
    return txt_body, html_body, subject_str
예제 #10
0
def _create_boot_email(**kwargs):
    """Parse the results and create the email text body to send.

    :param job: The name of the job.
    :type job: str
    :param  kernel: The name of the kernel.
    :type kernel: str
    :param git_commit: The git commit.
    :type git_commit: str
    :param git_url: The git url.
    :type git_url: str
    :param git_branch: The git branch.
    :type git_branch: str
    :param lab_name: The name of the lab.
    :type lab_name: str
    :param failed_data: The parsed failed results.
    :type failed_data: dict
    :param fail_count: The total number of failed results.
    :type fail_count: int
    :param offline_data: The parsed offline results.
    :type offline_data: dict
    :param offline_count: The total number of offline results.
    :type offline_count: int
    :param total_count: The total number of results.
    :type total_count: int
    :param total_unique_data: The unique values data structure.
    :type total_unique_data: dictionary
    :param pass_count: The total number of passed results.
    :type pass_count: int
    :param conflict_data: The parsed conflicting results.
    :type conflict_data: dict
    :param conflict_count: The number of conflicting results.
    :type conflict_count: int
    :param total_builds: The total number of defconfig built.
    :type total_builds: int
    :param base_url: The base URL to build the dashboard links.
    :type base_url: string
    :param boot_url: The base URL for the boot section of the dashboard.
    :type boot_url: string
    :param build_url: The base URL for the build section of the dashboard.
    :type build_url: string
    :param info_email: The email address for the footer note.
    :type info_email: string
    :return A tuple with the email body and subject as strings.
    """
    txt_body = None
    html_body = None
    subject_str = None

    k_get = kwargs.get
    total_unique_data = k_get("total_unique_data", None)
    info_email = k_get("info_email", None)
    email_format = k_get("email_format")

    subject_str = get_boot_subject_string(**kwargs)

    tested_one = G_(u"Tested: {:s}")
    tested_two = G_(u"Tested: {:s}, {:s}")
    tested_three = G_(u"Tested: {:s}, {:s}, {:s}")

    tested_string = None
    if total_unique_data:
        unique_boards = rcommon.count_unique(
            total_unique_data.get(models.BOARD_KEY, None))
        unique_socs = rcommon.count_unique(
            total_unique_data.get(models.MACH_KEY, None))
        unique_builds = rcommon.count_unique(
            total_unique_data[models.DEFCONFIG_FULL_KEY])

        kwargs["unique_boards"] = unique_boards
        kwargs["unique_socs"] = unique_socs
        kwargs["unique_builds"] = unique_builds

        boards_str = P_(u"{unique_boards:d} unique board",
                        u"{unique_boards:d} unique boards", unique_boards)
        soc_str = P_(u"{unique_socs:d} SoC family",
                     u"{unique_socs:d} SoC families", unique_socs)
        builds_str = P_(u"{unique_builds:d} build out of {total_builds:d}",
                        u"{unique_builds:d} builds out of {total_builds:d}",
                        unique_builds)

        if unique_boards > 0 and unique_socs > 0 and unique_builds > 0:
            tested_string = tested_three.format(boards_str, soc_str,
                                                builds_str)
        elif unique_boards > 0 and unique_socs > 0 and unique_builds == 0:
            tested_string = tested_two.format(boards_str, soc_str)
        elif unique_boards > 0 and unique_socs == 0 and unique_builds > 0:
            tested_string = tested_two.format(boards_str, builds_str)
        elif unique_boards == 0 and unique_socs > 0 and unique_builds > 0:
            tested_string = tested_two.format(soc_str, builds_str)
        elif unique_boards > 0 and unique_socs == 0 and unique_builds == 0:
            tested_string = tested_one.format(boards_str)
        elif unique_boards == 0 and unique_socs > 0 and unique_builds == 0:
            tested_string = tested_one.format(soc_str)
        elif unique_boards == 0 and unique_socs == 0 and unique_builds > 0:
            tested_string = tested_one.format(builds_str)

        if tested_string:
            tested_string = tested_string.format(**kwargs)

    boot_summary_url = BOOT_SUMMARY_URL.format(**kwargs)
    build_summary_url = BUILD_SUMMARY_URL.format(**kwargs)

    kwargs["tree_string"] = G_(u"Tree: {job:s}").format(**kwargs)
    kwargs["branch_string"] = G_(u"Branch: {git_branch:s}").format(**kwargs)
    kwargs["git_describe_string"] = G_(u"Git Describe: {kernel:s}").format(
        **kwargs)
    kwargs["info_email"] = info_email
    kwargs["tested_string"] = tested_string
    kwargs["subject_str"] = subject_str

    git_url = k_get("git_url")
    git_commit = k_get("git_commit")

    translated_git_url = \
        rcommon.translate_git_url(git_url, git_commit) or git_url

    git_txt_string = G_(u"Git URL: {:s}").format(git_url)
    git_html_string = G_(u"Git URL: <a href=\"{:s}\">{:s}</a>").format(
        translated_git_url, git_url)

    kwargs["git_commit_string"] = G_(u"Git Commit: {:s}").format(git_commit)
    kwargs["git_url_string"] = (git_txt_string, git_html_string)

    kwargs["platforms"] = _parse_and_structure_results(**kwargs)

    if kwargs["regressions"]:
        kwargs["regressions"] = \
            parse_regressions(
                kwargs["regressions"][models.REGRESSIONS_KEY], **kwargs)
    else:
        kwargs["regressions"] = None

    if models.EMAIL_TXT_FORMAT_KEY in email_format:
        kwargs["full_boot_summary"] = (
            G_(u"Full Boot Summary: {:s}").format(boot_summary_url))
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: {:s}").format(build_summary_url))

        txt_body = rcommon.create_txt_email("boot.txt", **kwargs)

    if models.EMAIL_HTML_FORMAT_KEY in email_format:
        # Fix the summary URLs for the HTML email.
        kwargs["full_boot_summary"] = (
            G_(u"Full Boot Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": boot_summary_url}))
        kwargs["full_build_summary"] = (
            G_(u"Full Build Summary: <a href=\"{url:s}\">{url:s}</a>").format(
                **{"url": build_summary_url}))

        html_body = rcommon.create_html_email("boot.html", **kwargs)

    return txt_body, html_body, subject_str