def index(job_name=None, build_number=None, component_version=None):
    """
    This API is used to search the result based on the selected filtered options.
    :param str job_name:
    :param int build_number:
    :param str component_version:
    :return: Searched results and search job menu
    """
    search_form = JobSearchForm(request.form)
    if request.method == "POST":
        job_name = search_form.data["job_name"].strip()
        try:
            pattern_type = re.search(r"\w*-\w*", job_name).group()
        except AttributeError:
            Common.logger.warn(
                f"index:failed to search the job name: {job_name}")
            pattern_type = job_name
        build_number = search_form.data["build_number"]
        component_version = search_form.data["component_version"]

        fs = extracting_build_info(
            job_name=job_name,
            build_number=build_number,
            component_version=component_version,
        )
        if fs.count() == 0:
            return render_template("404.html", title="404"), 404
        data_list = Common.collection_creation(fs)
        return render_template(
            "search_results.html",
            List=data_list,
            pattern_type=pattern_type,
            data_display="True",
        )
    if job_name and build_number and component_version:
        fs = extracting_build_info(
            job_name=job_name,
            build_number=build_number,
            component_version=component_version,
        )
        if fs.count() == 0:
            return render_template("404.html", title="404"), 404
        data_list = Common.collection_creation(fs)
        test_data_map = Common.test_map_details(data_list)
        try:
            pattern_type = re.search(r"\w*-\w*",
                                     data_list[0]["Job-Name"]).group()
        except AttributeError:
            Common.logger.warn(
                f"index:failed to search the job: {data_list[0]['Job-Name']}")
            pattern_type = job_name

        return render_template(
            "search_results.html",
            List=data_list,
            pattern_type=pattern_type,
            data_display="False",
            test_data_map=test_data_map,
        )
    return render_template("search.html", form=search_form)
def delete_build_data():
    """
    This API is used to delete the job based
    """
    search_form = JobSearchForm(request.form)
    if request.method == "POST":
        job_name = search_form.data["job_name"].strip()
        build_number = search_form.data["build_number"]
        component_version = search_form.data["component_version"]
        fs = extracting_build_info(
            job_name=job_name,
            build_number=build_number,
            component_version=component_version,
        )
        if fs.count() == 0:
            return render_template("404.html", title="404"), 404

        record = Common.collection_creation(fs)[0]
        response_json = delete_record(build_id=record["_id"])
        if response_json.acknowledged:
            flash(
                "Build No {} of Job {} having version {} deleted successfully".
                format(job_name, build_number, component_version))
        else:
            flash("Failed to delete content")
    return render_template("delete_build.html", form=search_form)
def job_list():
    """
    This api help us to get the details of job name, build number and component version.
    """
    fs = accessing_all_data()
    if fs.count() == 0:
        Common.logger.info(
            f"job_list: there is no details available in the database")
        return render_template("404.html", title="404"), 404
    records = Common.collection_creation(fs)
    job_records = dict()
    for job in records:
        if job["Job-Name"] not in job_records and ("Build-Number" in job
                                                   and "Build-Version" in job):

            job_records[job["Job-Name"]] = {
                "Build-Number": [job["Build-Number"]],
                "Build-Version": [job["Build-Version"]],
            }
        elif "Build-Number" in job and "Build-Version" in job:
            job_records[job["Job-Name"]]["Build-Number"].append(
                job["Build-Number"])
            job_records[job["Job-Name"]]["Build-Version"].append(
                job["Build-Version"])
    if job_records == dict():
        return render_template("404.html", title="404"), 404
    return render_template("job_name.html", job_records=job_records)
def search_by_component():
    """
    This API is used to search the job based on the their component
    :return:
    """
    search_form = SearchByField(request.form)
    if request.method == "POST":
        Common.logger.info("search_by_component:Post API called")
        field_name = search_form.select.data
        field_value = search_form.data["search"].strip()
        fs = extracting_data_by_field(field_name=field_name,
                                      field_value=field_value)
        if fs.count() == 0:
            return render_template("404.html", title="404"), 404

        data_list = Common.collection_creation(fs)
        test_data_map = Common.test_map_details(data_list)
        if test_data_map == 500:
            Common.logger.warn(
                f"search_by_component:Internal server error comes while listing "
                f"the data_list={data_list}")
            return render_template("500.html", title="500"), 500
        return render_template("search_results.html",
                               List=data_list,
                               test_data_map=test_data_map)
    return render_template("component_search_by_field.html",
                           search_form=search_form)
def edit_observation(pattern_type, id):
    """
    This API is used to edit the observation based on the available record.
    :param pattern_type:
    :param id:
    """
    fs = accessing_data_via_id(build_id=f"{id}")
    if fs.count() == 0:
        return render_template("404.html", title="404"), 404
    record = Common.collection_creation(fs)[0]
    form = ObservationUpdate(request.form)
    if request.method == "POST":
        Common.logger.info(
            f"edit_observation: Post API called against id {id} and pattern type"
            f" {pattern_type}")
        observations = ast.literal_eval(form.data["observation_data"])
        try:
            Common.logger.info(
                f"edit_observation: The provided observation is {observations}"
                f" {pattern_type}")
            if pattern_type not in Common.get_config_value("test_map"):
                if type(observations) is dict:
                    for observation in observations:
                        db_update(
                            observation_record_key=f"{observation}",
                            observation_record_value="{}".format(
                                observations[observation]),
                        )
                record["Validation"] = Common.record_updater(
                    record["Validation"], observations)
                update_record(f"{id}", old_record=record)
            else:
                os.popen("touch problem_in_before_update")
                failed_test_details = {
                    "test_details":
                    record["Validation"]["Pre_Upgrade_test_Failure"]
                }
                updated_data = Common.record_updater(failed_test_details,
                                                     observations)
                record["Validation"][
                    "Pre_Upgrade_test_Failure"] = updated_data["test_details"]
                update_record(f"{id}", old_record=record)
        except Exception as ex:
            Common.logger.warn(
                f"edit_observation: The provided dictionary is not in correct "
                f"format {ex}")
            flash(
                "Please provide the proper dictionary format {} of pattern {}".
                format(observations, pattern_type))
            return render_template("observation.html",
                                   form=form,
                                   pattern_type=pattern_type,
                                   record=record)
        flash("Data Submitted Successfully")
    return render_template("observation.html",
                           form=form,
                           pattern_type=pattern_type,
                           record=record)
def page_list(fs, per_page, offset=0):
    """
    This function is used to calculate the current offset value
    :param fs:
    :param per_page:
    :param offset:
    :return: offset number
    """
    Common.logger.info(
        f"Collecting the requested record by the pagination module {fs}")
    requested_record = Common.collection_creation(fs)
    return requested_record[offset:offset + per_page]
def system_log(id):
    """
    This API is used to extract the system log based on their unique job id
    :param id:
    """
    Common.logger.info("system_log: system log API called")
    fs = accessing_data_via_id(build_id=f"{id}")
    record = Common.collection_creation(fs)[0]
    return render_template(
        "system_log.html",
        record=record["SystemLog"],
        system_log_separation=Common.system_log_separation,
    )
    def log_analysis(self, build_number, validation_data):
        """
        This method is used to analyse the logs based on users request, and upload their
        results in mongodb database as well as xls file in report folder.
        :param int build_number:
        :param dict validation_data:
        """
        self.header_of_table()
        job_file_name = self.prop_obj.job_mapper[build_number][
            "build_file_name"]
        Common.logger.info(f"[log_analysis]: headers of xls table updated")
        build_status = LogAnalyser.ran_job_status(job_file_name)
        machine_address = LogAnalyser.machine_details(job_file_name)

        upgrade_validation_result = Validation.job_analysis(
            validation_data,
            job_file_name,
            machine_address,
            self.prop_obj.job_mapper[build_number]["skip_check"],
        )
        Common.logger.info(f"[log_analysis]: Updated validation checked")

        job_time_stamp = time.ctime(
            self.prop_obj.job_mapper[build_number]["time_stamp"])
        xls_report_content = [
            validation_data["job_name"],
            build_number,
            build_status,
            upgrade_validation_result,
            self.prop_obj.job_mapper[build_number]["time_stamp"],
        ]

        analysis_result = {
            "Job-Name":
            validation_data["job_name"],
            "Build-Number":
            build_number,
            "Build-Status":
            build_status,
            "Validation":
            upgrade_validation_result,
            "Job-Time-Stamp":
            job_time_stamp,
            "Build-Version":
            self.prop_obj.job_mapper[build_number]["build_version"],
            "Snap-Version":
            self.prop_obj.job_mapper[build_number]["snap_no"],
            "SystemLog":
            upgrade_validation_result["System_Log"]
            if "System_Log" in upgrade_validation_result else None,
            "Job Url":
            self.prop_obj.job_mapper[build_number]["build_url"],
        }
        Common.logger.info("[log_analysis] Analysis result collected")
        observated_data_object = accessing_observation_db()
        if observated_data_object.count() >= 1:
            observated_data = Common.collection_creation(
                observated_data_object)
            try:
                for observated_content in observated_data:
                    observated_content.pop("_id")
                    analysis_result["Validation"] = Common.record_updater(
                        analysis_result["Validation"], observated_content)
            except Exception as ex:
                Common.logger.warn(
                    f"[log_analysis]: Exception observed while comparing the"
                    f" observation while evaluating the job: {ex}")

        db_update(analysis_result)
        DataUpdater.test_result_update(
            self.prop_obj.sheets_number[self.prop_obj.sheets],
            self.prop_obj.rows_no,
            xls_report_content,
        )
        Common.logger.info(
            f"[log_analysis] Analysis completed for build {build_number}")