<commit_before>import logging
import time

from botocore.vendored import requests

import yattag
from taskcat._common_utils import CommonTools
from taskcat.exceptions import TaskCatException

LOG = logging.getLogger(__name__)


class ReportBuilder:
    """
    This class generates the test report.

    """

    def __init__(self, test_data, dashboard_filename, version, boto_client, taskcat):
        self.dashboard_filename = dashboard_filename
        self.test_data = test_data
        self.version = version
        self._boto_client = boto_client
        self.taskcat = taskcat

    # TODO: refactor for readability
    def generate_report(  # noqa: C901
        self
    ):  # pylint: disable=too-many-locals, too-many-statements
        doc = yattag.Doc()

        # Type of cfn log return cfn log file
        def get_output_file(region, stack_name, resource_type):
            extension = ".txt"
            if resource_type == "cfnlog":
                location = "{}-{}-{}{}".format(stack_name, region, "cfnlogs", extension)
                return str(location)
            if resource_type == "resource_log":
                location = "{}-{}-{}{}".format(
                    stack_name, region, "resources", extension
                )
                return str(location)
            return None

        def get_teststate(stackname, region):
            rstatus = None
            status_css = None
            try:

                cfn_client = self._boto_client.get("cloudformation", region)
                test_query = cfn_client.describe_stacks(StackName=stackname)

                for result in test_query["Stacks"]:
                    rstatus = result.get("StackStatus")
                    if rstatus == "CREATE_COMPLETE":
                        status_css = "class=test-green"
                    elif rstatus == "CREATE_FAILED":
                        status_css = "class=test-red"
                        self.taskcat.one_or_more_tests_failed = True
                        if self.taskcat.retain_if_failed and self.taskcat.run_cleanup:
                            self.taskcat.run_cleanup = False
                    else:
                        status_css = "class=test-red"
            except TaskCatException:
                raise
            except Exception as e:  # pylint: disable=broad-except
                LOG.error("Error describing stack named [%s] " % stackname)
                LOG.debug(str(e), exc_info=True)
                rstatus = "MANUALLY_DELETED"
                status_css = "class=test-orange"

            return rstatus, status_css

        tag = doc.tag
        text = doc.text
        logo = "taskcat"
        repo_link = "https://github.com/aws-quickstart/taskcat"
        css_url = (
            "https://raw.githubusercontent.com/aws-quickstart/taskcat/master/"
            "assets/css/taskcat_reporting.css"
        )
        output_css = requests.get(css_url).text
        doc_link = "http://taskcat.io"

        with tag("html"):
            with tag("head"):
                doc.stag("meta", charset="utf-8")
                doc.stag("meta", name="viewport", content="width=device-width")
                with tag("style", type="text/css"):
                    text(output_css)
                with tag("title"):
                    text("TaskCat Report")

            with tag("body"):
                tested_on = time.strftime("%A - %b,%d,%Y @ %H:%M:%S")

                with tag("table", "class=header-table-fill"):
                    with tag("tbody"):
                        with tag("th", "colspan=2"):
                            with tag("tr"):
                                with tag("td"):
                                    with tag("a", href=repo_link):
                                        text("GitHub Repo: ")
                                        text(repo_link)
                                        doc.stag("br")
                                    with tag("a", href=doc_link):
                                        text("Documentation: ")
                                        text(doc_link)
                                        doc.stag("br")
                                    text("Tested on: ")
                                    text(tested_on)
                                with tag("td", "class=taskcat-logo"):
                                    with tag("h3"):
                                        text(logo)
            doc.stag("p")
            with tag("table", "class=table-fill"):
                with tag("tbody"):
                    with tag("thread"):
                        with tag("tr"):
                            with tag("th", "class=text-center", "width=25%"):
                                text("Test Name")
                            with tag("th", "class=text-left", "width=10%"):
                                text("Tested Region")
                            with tag("th", "class=text-left", "width=30%"):
                                text("Stack Name")
                            with tag("th", "class=text-left", "width=20%"):
                                text("Tested Results")
                            with tag("th", "class=text-left", "width=15%"):
                                text("Test Logs")

                            for test in self.test_data:
                                with tag("tr", "class= test-footer"):
                                    with tag("td", "colspan=5"):
                                        text("")

                                testname = test.get_test_name()
                                LOG.info(f" - Processing {testname}")
                                for stack in test.get_test_stacks():
                                    LOG.info(f'Reporting on {str(stack["StackId"])}')
                                    stack_id = CommonTools(
                                        stack["StackId"]
                                    ).parse_stack_info()
                                    status, css = get_teststate(
                                        stack_id["stack_name"], stack_id["region"]
                                    )

                                    with tag("tr"):
                                        with tag("td", "class=test-info"):
                                            with tag("h3"):
                                                text(testname)
                                        with tag("td", "class=text-left"):
                                            text(stack_id["region"])
                                        with tag("td", "class=text-left"):
                                            text(stack_id["stack_name"])
                                        with tag("td", css):
                                            text(str(status))
                                        with tag("td", "class=text-left"):
                                            clog = get_output_file(
                                                stack_id["region"],
                                                stack_id["stack_name"],
                                                "cfnlog",
                                            )
                                            # rlog = get_output_file(
                                            #    state['region'],
                                            #    state['stack_name'],
                                            #    'resource_log')
                                            #
                                            with tag("a", href=clog):
                                                text("View Logs ")
                                                # with tag('a', href=rlog):
                                                #    text('Resource Logs ')
                            with tag("tr", "class= test-footer"):
                                with tag("td", "colspan=5"):
                                    vtag = "Generated by {} {}".format(
                                        "taskcat", self.version
                                    )
                                    text(vtag)

                        doc.stag("p")

            html_output = yattag.indent(
                doc.getvalue(), indentation="    ", newline="\r\n", indent_text=True
            )

            file = open(self.dashboard_filename, "w")
            file.write(html_output)
            file.close()

            return html_output
<commit_msg>botocore no longer vendors requests<commit_after>import logging
import time

import requests

import yattag
from taskcat._common_utils import CommonTools
from taskcat.exceptions import TaskCatException

LOG = logging.getLogger(__name__)


class ReportBuilder:
    """
    This class generates the test report.

    """

    def __init__(self, test_data, dashboard_filename, version, boto_client, taskcat):
        self.dashboard_filename = dashboard_filename
        self.test_data = test_data
        self.version = version
        self._boto_client = boto_client
        self.taskcat = taskcat

    # TODO: refactor for readability
    def generate_report(  # noqa: C901
        self
    ):  # pylint: disable=too-many-locals, too-many-statements
        doc = yattag.Doc()

        # Type of cfn log return cfn log file
        def get_output_file(region, stack_name, resource_type):
            extension = ".txt"
            if resource_type == "cfnlog":
                location = "{}-{}-{}{}".format(stack_name, region, "cfnlogs", extension)
                return str(location)
            if resource_type == "resource_log":
                location = "{}-{}-{}{}".format(
                    stack_name, region, "resources", extension
                )
                return str(location)
            return None

        def get_teststate(stackname, region):
            rstatus = None
            status_css = None
            try:

                cfn_client = self._boto_client.get("cloudformation", region)
                test_query = cfn_client.describe_stacks(StackName=stackname)

                for result in test_query["Stacks"]:
                    rstatus = result.get("StackStatus")
                    if rstatus == "CREATE_COMPLETE":
                        status_css = "class=test-green"
                    elif rstatus == "CREATE_FAILED":
                        status_css = "class=test-red"
                        self.taskcat.one_or_more_tests_failed = True
                        if self.taskcat.retain_if_failed and self.taskcat.run_cleanup:
                            self.taskcat.run_cleanup = False
                    else:
                        status_css = "class=test-red"
            except TaskCatException:
                raise
            except Exception as e:  # pylint: disable=broad-except
                LOG.error("Error describing stack named [%s] " % stackname)
                LOG.debug(str(e), exc_info=True)
                rstatus = "MANUALLY_DELETED"
                status_css = "class=test-orange"

            return rstatus, status_css

        tag = doc.tag
        text = doc.text
        logo = "taskcat"
        repo_link = "https://github.com/aws-quickstart/taskcat"
        css_url = (
            "https://raw.githubusercontent.com/aws-quickstart/taskcat/master/"
            "assets/css/taskcat_reporting.css"
        )
        output_css = requests.get(css_url).text
        doc_link = "http://taskcat.io"

        with tag("html"):
            with tag("head"):
                doc.stag("meta", charset="utf-8")
                doc.stag("meta", name="viewport", content="width=device-width")
                with tag("style", type="text/css"):
                    text(output_css)
                with tag("title"):
                    text("TaskCat Report")

            with tag("body"):
                tested_on = time.strftime("%A - %b,%d,%Y @ %H:%M:%S")

                with tag("table", "class=header-table-fill"):
                    with tag("tbody"):
                        with tag("th", "colspan=2"):
                            with tag("tr"):
                                with tag("td"):
                                    with tag("a", href=repo_link):
                                        text("GitHub Repo: ")
                                        text(repo_link)
                                        doc.stag("br")
                                    with tag("a", href=doc_link):
                                        text("Documentation: ")
                                        text(doc_link)
                                        doc.stag("br")
                                    text("Tested on: ")
                                    text(tested_on)
                                with tag("td", "class=taskcat-logo"):
                                    with tag("h3"):
                                        text(logo)
            doc.stag("p")
            with tag("table", "class=table-fill"):
                with tag("tbody"):
                    with tag("thread"):
                        with tag("tr"):
                            with tag("th", "class=text-center", "width=25%"):
                                text("Test Name")
                            with tag("th", "class=text-left", "width=10%"):
                                text("Tested Region")
                            with tag("th", "class=text-left", "width=30%"):
                                text("Stack Name")
                            with tag("th", "class=text-left", "width=20%"):
                                text("Tested Results")
                            with tag("th", "class=text-left", "width=15%"):
                                text("Test Logs")

                            for test in self.test_data:
                                with tag("tr", "class= test-footer"):
                                    with tag("td", "colspan=5"):
                                        text("")

                                testname = test.get_test_name()
                                LOG.info(f" - Processing {testname}")
                                for stack in test.get_test_stacks():
                                    LOG.info(f'Reporting on {str(stack["StackId"])}')
                                    stack_id = CommonTools(
                                        stack["StackId"]
                                    ).parse_stack_info()
                                    status, css = get_teststate(
                                        stack_id["stack_name"], stack_id["region"]
                                    )

                                    with tag("tr"):
                                        with tag("td", "class=test-info"):
                                            with tag("h3"):
                                                text(testname)
                                        with tag("td", "class=text-left"):
                                            text(stack_id["region"])
                                        with tag("td", "class=text-left"):
                                            text(stack_id["stack_name"])
                                        with tag("td", css):
                                            text(str(status))
                                        with tag("td", "class=text-left"):
                                            clog = get_output_file(
                                                stack_id["region"],
                                                stack_id["stack_name"],
                                                "cfnlog",
                                            )
                                            # rlog = get_output_file(
                                            #    state['region'],
                                            #    state['stack_name'],
                                            #    'resource_log')
                                            #
                                            with tag("a", href=clog):
                                                text("View Logs ")
                                                # with tag('a', href=rlog):
                                                #    text('Resource Logs ')
                            with tag("tr", "class= test-footer"):
                                with tag("td", "colspan=5"):
                                    vtag = "Generated by {} {}".format(
                                        "taskcat", self.version
                                    )
                                    text(vtag)

                        doc.stag("p")

            html_output = yattag.indent(
                doc.getvalue(), indentation="    ", newline="\r\n", indent_text=True
            )

            file = open(self.dashboard_filename, "w")
            file.write(html_output)
            file.close()

            return html_output

{'fraction_non_alphanumeric': 0.10029966508020448, 'fraction_numerical': 0.0022327986368176744, 'mean_word_length': 0.9188275084554679, 'pattern_counts': {'":': 8, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 162, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2858406', 'n_tokens_mistral': 3851, 'n_tokens_neox': 3688, 'n_words': 754}