From b8595329e32d3dbcdb7d6823bf4afe5d4257e5be Mon Sep 17 00:00:00 2001 From: Adarsh S <4darshofficial@gmail.com> Date: Thu, 19 Jul 2018 17:33:58 +0530 Subject: [PATCH] Add command to filter the submissions by start & end date(#83) --- evalai/challenges.py | 9 +++- evalai/utils/common.py | 2 +- evalai/utils/submissions.py | 36 +++++++++---- tests/data/submission_response.py | 6 +-- tests/test_challenges.py | 87 ++++++++++++++++++++++++++++++- 5 files changed, 122 insertions(+), 18 deletions(-) diff --git a/evalai/challenges.py b/evalai/challenges.py index 27827fb08..fd2a463c2 100644 --- a/evalai/challenges.py +++ b/evalai/challenges.py @@ -2,6 +2,7 @@ from click import style +from evalai.utils.common import Date from evalai.utils.challenges import ( display_all_challenge_list, display_future_challenge_list, @@ -136,14 +137,18 @@ def phase(ctx, json, phase): @phase.command() @click.pass_obj -def submissions(ctx): +@click.option('--start-date', '-s', type=Date(format='%m/%d/%y'), + help="Start date for submissions in `mm/dd/yyyy` format.") +@click.option('--end-date', '-e', type=Date(format='%m/%d/%y'), + help="End date for submissions in `mm/dd/yyyy` format.") +def submissions(ctx, start_date, end_date): """ Display submissions to a particular challenge. """ """ Invoked by running `evalai challenge CHALLENGE phase PHASE submissions`. """ - display_my_submission_details(ctx.challenge_id, ctx.phase_id) + display_my_submission_details(ctx.challenge_id, ctx.phase_id, start_date, end_date) @phase.command() diff --git a/evalai/utils/common.py b/evalai/utils/common.py index cdeebafb4..b2a2c347d 100644 --- a/evalai/utils/common.py +++ b/evalai/utils/common.py @@ -21,7 +21,7 @@ def convert(self, value, param, ctx): date = datetime.strptime(value, self.format) return date except ValueError: - raise self.fail("Incorrect date format, please use {} format".format(self.format)) + raise self.fail("Incorrect date format, please use {} format. Example: 8/23/17.".format(self.format)) def validate_token(response): diff --git a/evalai/utils/submissions.py b/evalai/utils/submissions.py index 74c3e7e1b..15ddabea9 100644 --- a/evalai/utils/submissions.py +++ b/evalai/utils/submissions.py @@ -3,11 +3,14 @@ from beautifultable import BeautifulTable from click import echo, style +from datetime import datetime from evalai.utils.auth import get_request_header, get_host_url from evalai.utils.config import EVALAI_ERROR_CODES from evalai.utils.urls import URLS -from evalai.utils.common import validate_token, convert_UTC_date_to_local +from evalai.utils.common import (validate_token, + validate_date_format, + convert_UTC_date_to_local) def make_submission(challenge_id, phase_id, file, submission_metadata={}): @@ -48,7 +51,7 @@ def make_submission(challenge_id, phase_id, file, submission_metadata={}): bold=True)) -def pretty_print_my_submissions_data(submissions): +def pretty_print_my_submissions_data(submissions, start_date, end_date): """ Funcion to print the submissions for a particular Challenge. """ @@ -60,18 +63,29 @@ def pretty_print_my_submissions_data(submissions): echo(style("\nSorry, you have not made any submissions to this challenge phase.\n", bold=True)) sys.exit(1) + if not start_date: + start_date = datetime.min + + if not end_date: + end_date = datetime.max + for submission in submissions: - date = convert_UTC_date_to_local(submission['submitted_at']) - # Check for empty method name - method_name = submission["method_name"] if submission["method_name"] else "None" - values = list(map(lambda item: submission[item], attributes)) - values.append(date) - values.append(method_name) - table.append_row(values) + date = validate_date_format(submission['submitted_at']) + if (date >= start_date and date <= end_date): + # Check for empty method name + date = convert_UTC_date_to_local(submission['submitted_at']) + method_name = submission["method_name"] if submission["method_name"] else "None" + values = list(map(lambda item: submission[item], attributes)) + values.append(date) + values.append(method_name) + table.append_row(values) + if len(table) == 0: + echo(style("\nSorry, no submissions were made during this time period.\n", bold=True)) + sys.exit(1) echo(table) -def display_my_submission_details(challenge_id, phase_id): +def display_my_submission_details(challenge_id, phase_id, start_date, end_date): """ Function to display the details of a particular submission. """ @@ -97,7 +111,7 @@ def display_my_submission_details(challenge_id, phase_id): response = response.json() submissions = response["results"] - pretty_print_my_submissions_data(submissions) + pretty_print_my_submissions_data(submissions, start_date, end_date) def pretty_print_submission_details(submission): diff --git a/tests/data/submission_response.py b/tests/data/submission_response.py index 1827dbf74..695cbd2ca 100644 --- a/tests/data/submission_response.py +++ b/tests/data/submission_response.py @@ -22,7 +22,7 @@ "stderr_file": null, "stdout_file": null, "submission_result_file": null, - "submitted_at": "2018-06-08T09:24:09.866590Z", + "submitted_at": "2018-06-03T09:24:09.866590Z", "when_made_public": null }, { @@ -46,7 +46,7 @@ ae3c23bd5e7d.txt", "submission_result_file": "http://testserver/media/submission_files/submission_8/2eebf2ab-6f6e-485f-\ ab54-aea3cbbeb06b.json", - "submitted_at": "2018-06-07T18:18:08.996609Z", + "submitted_at": "2018-06-05T18:18:08.996609Z", "when_made_public": null }, { @@ -93,7 +93,7 @@ a352-d41e15348a20.txt", "submission_result_file": "http://testserver/media/submission_files/submission_6/b0f44621-\ 0560-4baa-a758-9b4d9e328e39.json", - "submitted_at": "2018-06-07T18:17:08.739749Z", + "submitted_at": "2018-06-09T18:17:08.739749Z", "when_made_public": null } ] diff --git a/tests/test_challenges.py b/tests/test_challenges.py index 14ddfe465..47ff7a12a 100644 --- a/tests/test_challenges.py +++ b/tests/test_challenges.py @@ -10,7 +10,9 @@ challenges) from evalai.utils.urls import URLS from evalai.utils.config import API_HOST_URL -from evalai.utils.common import convert_UTC_date_to_local, clean_data +from evalai.utils.common import (convert_UTC_date_to_local, + validate_date_format, + clean_data) from tests.data import challenge_response, submission_response from .base import BaseTestClass @@ -511,6 +513,89 @@ def test_display_my_submission_details_with_single_argument(self): response = result.output assert response == output + @responses.activate + def test_display_my_submission_details_with_start_date(self): + table = BeautifulTable(max_width=100) + attributes = ["id", "participant_team_name", "execution_time", "status"] + columns_attributes = ["ID", "Participant Team", "Execution Time(sec)", "Status", "Submitted At", "Method Name"] + table.column_headers = columns_attributes + + start_date = datetime.strptime('6/7/18', "%m/%d/%y") + end_date = datetime.max + for submission in self.submissions: + date = validate_date_format(submission['submitted_at']) + if (date >= start_date and date <= end_date): + # Check for empty method name + date = convert_UTC_date_to_local(submission['submitted_at']) + method_name = submission["method_name"] if submission["method_name"] else "None" + values = list(map(lambda item: submission[item], attributes)) + values.append(date) + values.append(method_name) + table.append_row(values) + output = str(table).rstrip() + runner = CliRunner() + result = runner.invoke(challenge, ['3', 'phase', '7', 'submissions', '-s', '6/7/18']) + response = result.output.rstrip() + assert response == output + + @responses.activate + def test_display_my_submission_details_with_end_date(self): + table = BeautifulTable(max_width=100) + attributes = ["id", "participant_team_name", "execution_time", "status"] + columns_attributes = ["ID", "Participant Team", "Execution Time(sec)", "Status", "Submitted At", "Method Name"] + table.column_headers = columns_attributes + + start_date = datetime.min + end_date = datetime.strptime('6/7/18', "%m/%d/%y") + for submission in self.submissions: + date = validate_date_format(submission['submitted_at']) + if (date >= start_date and date <= end_date): + # Check for empty method name + date = convert_UTC_date_to_local(submission['submitted_at']) + method_name = submission["method_name"] if submission["method_name"] else "None" + values = list(map(lambda item: submission[item], attributes)) + values.append(date) + values.append(method_name) + table.append_row(values) + output = str(table).rstrip() + runner = CliRunner() + result = runner.invoke(challenge, ['3', 'phase', '7', 'submissions', '-e', '6/7/18']) + response = result.output.rstrip() + assert response == output + + @responses.activate + def test_display_my_submission_details_with_end_date_and_start_date(self): + table = BeautifulTable(max_width=100) + attributes = ["id", "participant_team_name", "execution_time", "status"] + columns_attributes = ["ID", "Participant Team", "Execution Time(sec)", "Status", "Submitted At", "Method Name"] + table.column_headers = columns_attributes + + start_date = datetime.strptime('6/5/18', "%m/%d/%y") + end_date = datetime.strptime('6/9/18', "%m/%d/%y") + for submission in self.submissions: + date = validate_date_format(submission['submitted_at']) + if (date >= start_date and date <= end_date): + # Check for empty method name + date = convert_UTC_date_to_local(submission['submitted_at']) + method_name = submission["method_name"] if submission["method_name"] else "None" + values = list(map(lambda item: submission[item], attributes)) + values.append(date) + values.append(method_name) + table.append_row(values) + output = str(table).rstrip() + runner = CliRunner() + result = runner.invoke(challenge, ['3', 'phase', '7', 'submissions', '-s', '6/5/18', '-e', '6/9/18']) + response = result.output.rstrip() + assert response == output + + @responses.activate + def test_display_my_submission_details_with_end_date_and_start_date_without_submissions(self): + output = "Sorry, no submissions were made during this time period." + runner = CliRunner() + result = runner.invoke(challenge, ['3', 'phase', '7', 'submissions', '-s', '6/10/18', '-e', '6/15/18']) + response = result.output.strip() + assert response == output + class TestDisplayLeaderboard(BaseTestClass):