Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions tmc-client/src/tmc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,20 @@ impl TmcClient {
api_v8::core::post_submission_feedback(self, submission_id, feedback)
}

/// Posts feedback to the given URL. Requires authentication.
///
/// # Errors
/// If not authenticated, there's some problem reaching the API, or if the API returns an error.
pub fn send_feedback_to_url(
&self,
feedback_url: Url,
feedback: Vec<FeedbackAnswer>,
) -> Result<SubmissionFeedbackResponse, ClientError> {
self.require_authentication()?;
let form = api_v8::prepare_feedback_form(feedback);
api_v8::post_form(self, feedback_url, &form)
}

/// Sends the submission to the server. Requires authentication.
///
/// # Errors
Expand Down
41 changes: 32 additions & 9 deletions tmc-client/src/tmc_client/api_v8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ fn assert_success(response: Response, url: &Url) -> Result<Response, ClientError
}
}

/// Converts a list of feedback answers to the format expected by the TMC server.
pub fn prepare_feedback_form(feedback: Vec<FeedbackAnswer>) -> HashMap<String, String> {
let mut form = HashMap::new();
for (i, answer) in feedback.into_iter().enumerate() {
form.insert(
format!("answers[{}][question_id]", i),
answer.question_id.to_string(),
);
form.insert(format!("answers[{}][answer]", i), answer.answer);
}
form
}

/// Fetches data from the URL and writes it into the target.
pub fn download(client: &TmcClient, url: Url, mut target: impl Write) -> Result<(), ClientError> {
let res = prepare_tmc_request(client, Method::GET, url.clone())
Expand Down Expand Up @@ -111,6 +124,24 @@ pub fn get_json<T: DeserializeOwned>(
Ok(json)
}

/// Posts the given form data to the given URL and deserializes the response to T.
pub fn post_form<T: DeserializeOwned>(
client: &TmcClient,
url: Url,
form: &HashMap<String, String>,
) -> Result<T, ClientError> {
let res = prepare_tmc_request(client, Method::POST, url.clone())
.form(form)
.send()
.map_err(|e| ClientError::ConnectionError(Method::GET, url.clone(), e))?;

let res = assert_success(res, &url)?;
let json = res
.json()
.map_err(|e| ClientError::HttpJsonResponse(url, e))?;
Ok(json)
}

/// get /api/v8/application/{client_name}/credentials
/// Fetches oauth2 credentials info.
pub fn get_credentials(client: &TmcClient, client_name: &str) -> Result<Credentials, ClientError> {
Expand Down Expand Up @@ -948,15 +979,7 @@ pub mod core {
format!("/api/v8/core/submissions/{}/feedback", submission_id),
)?;

let mut form = HashMap::new();
for (i, answer) in feedback.into_iter().enumerate() {
form.insert(
format!("answers[{}][question_id]", i),
answer.question_id.to_string(),
);
form.insert(format!("answers[{}][answer]", i), answer.answer);
}

let form = prepare_feedback_form(feedback);
let res = prepare_tmc_request(client, Method::POST, url.clone())
.form(&form)
.send()
Expand Down
7 changes: 5 additions & 2 deletions tmc-langs-cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,11 @@ pub enum Core {
#[structopt(long_about = schema_leaked::<SubmissionFeedbackResponse>())]
SendFeedback {
/// The ID of the submission.
#[structopt(long)]
submission_id: u32,
#[structopt(long, required_unless = "feedback-url")]
submission_id: Option<u32>,
/// The feedback answer URL.
#[structopt(long, required_unless = "submission-id")]
feedback_url: Option<String>,
/// A feedback answer. Takes two values, a feedback answer id and the answer. Multiple feedback arguments can be given.
#[structopt(long, required = true, number_of_values = 2, value_names = &["feedback-answer-id, answer"])]
feedback: Vec<String>,
Expand Down
15 changes: 12 additions & 3 deletions tmc-langs-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ fn run_core_inner(

Core::SendFeedback {
submission_id,
feedback_url,
feedback,
} => {
let mut feedback_answers = feedback.into_iter();
Expand All @@ -879,9 +880,17 @@ fn run_core_inner(
answer,
});
}
let response = client
.send_feedback(submission_id, feedback)
.context("Failed to send feedback")?;

let response = if let Some(submission_id) = submission_id {
client
.send_feedback(submission_id, feedback)
.context("Failed to send feedback")?
} else if let Some(feedback_url) = feedback_url {
let feedback_url = feedback_url.parse()?;
client.send_feedback_to_url(feedback_url, feedback)?
} else {
panic!("validation error")
};
Output::finished_with_data("sent feedback", Data::SubmissionFeedbackResponse(response))
}

Expand Down