Skip to content

Commit bcfcfd8

Browse files
committed
added an optional feedback-url parameter back to send-feedback
1 parent ab949fa commit bcfcfd8

File tree

4 files changed

+63
-14
lines changed

4 files changed

+63
-14
lines changed

tmc-client/src/tmc_client.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,20 @@ impl TmcClient {
302302
api_v8::core::post_submission_feedback(self, submission_id, feedback)
303303
}
304304

305+
/// Posts feedback to the given URL. Requires authentication.
306+
///
307+
/// # Errors
308+
/// If not authenticated, there's some problem reaching the API, or if the API returns an error.
309+
pub fn send_feedback_to_url(
310+
&self,
311+
feedback_url: Url,
312+
feedback: Vec<FeedbackAnswer>,
313+
) -> Result<SubmissionFeedbackResponse, ClientError> {
314+
self.require_authentication()?;
315+
let form = api_v8::prepare_feedback_form(feedback);
316+
api_v8::post_form(self, feedback_url, &form)
317+
}
318+
305319
/// Sends the submission to the server. Requires authentication.
306320
///
307321
/// # Errors

tmc-client/src/tmc_client/api_v8.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ fn assert_success(response: Response, url: &Url) -> Result<Response, ClientError
8080
}
8181
}
8282

83+
/// Converts a list of feedback answers to the format expected by the TMC server.
84+
pub fn prepare_feedback_form(feedback: Vec<FeedbackAnswer>) -> HashMap<String, String> {
85+
let mut form = HashMap::new();
86+
for (i, answer) in feedback.into_iter().enumerate() {
87+
form.insert(
88+
format!("answers[{}][question_id]", i),
89+
answer.question_id.to_string(),
90+
);
91+
form.insert(format!("answers[{}][answer]", i), answer.answer);
92+
}
93+
form
94+
}
95+
8396
/// Fetches data from the URL and writes it into the target.
8497
pub fn download(client: &TmcClient, url: Url, mut target: impl Write) -> Result<(), ClientError> {
8598
let res = prepare_tmc_request(client, Method::GET, url.clone())
@@ -111,6 +124,24 @@ pub fn get_json<T: DeserializeOwned>(
111124
Ok(json)
112125
}
113126

127+
/// Posts the given form data to the given URL and deserializes the response to T.
128+
pub fn post_form<T: DeserializeOwned>(
129+
client: &TmcClient,
130+
url: Url,
131+
form: &HashMap<String, String>,
132+
) -> Result<T, ClientError> {
133+
let res = prepare_tmc_request(client, Method::POST, url.clone())
134+
.form(form)
135+
.send()
136+
.map_err(|e| ClientError::ConnectionError(Method::GET, url.clone(), e))?;
137+
138+
let res = assert_success(res, &url)?;
139+
let json = res
140+
.json()
141+
.map_err(|e| ClientError::HttpJsonResponse(url, e))?;
142+
Ok(json)
143+
}
144+
114145
/// get /api/v8/application/{client_name}/credentials
115146
/// Fetches oauth2 credentials info.
116147
pub fn get_credentials(client: &TmcClient, client_name: &str) -> Result<Credentials, ClientError> {
@@ -948,15 +979,7 @@ pub mod core {
948979
format!("/api/v8/core/submissions/{}/feedback", submission_id),
949980
)?;
950981

951-
let mut form = HashMap::new();
952-
for (i, answer) in feedback.into_iter().enumerate() {
953-
form.insert(
954-
format!("answers[{}][question_id]", i),
955-
answer.question_id.to_string(),
956-
);
957-
form.insert(format!("answers[{}][answer]", i), answer.answer);
958-
}
959-
982+
let form = prepare_feedback_form(feedback);
960983
let res = prepare_tmc_request(client, Method::POST, url.clone())
961984
.form(&form)
962985
.send()

tmc-langs-cli/src/app.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,11 @@ pub enum Core {
444444
#[structopt(long_about = schema_leaked::<SubmissionFeedbackResponse>())]
445445
SendFeedback {
446446
/// The ID of the submission.
447-
#[structopt(long)]
448-
submission_id: u32,
447+
#[structopt(long, required_unless = "feedback-url")]
448+
submission_id: Option<u32>,
449+
/// The feedback answer URL.
450+
#[structopt(long, required_unless = "submission-id")]
451+
feedback_url: Option<String>,
449452
/// A feedback answer. Takes two values, a feedback answer id and the answer. Multiple feedback arguments can be given.
450453
#[structopt(long, required = true, number_of_values = 2, value_names = &["feedback-answer-id, answer"])]
451454
feedback: Vec<String>,

tmc-langs-cli/src/lib.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ fn run_core_inner(
864864

865865
Core::SendFeedback {
866866
submission_id,
867+
feedback_url,
867868
feedback,
868869
} => {
869870
let mut feedback_answers = feedback.into_iter();
@@ -879,9 +880,17 @@ fn run_core_inner(
879880
answer,
880881
});
881882
}
882-
let response = client
883-
.send_feedback(submission_id, feedback)
884-
.context("Failed to send feedback")?;
883+
884+
let response = if let Some(submission_id) = submission_id {
885+
client
886+
.send_feedback(submission_id, feedback)
887+
.context("Failed to send feedback")?
888+
} else if let Some(feedback_url) = feedback_url {
889+
let feedback_url = feedback_url.parse()?;
890+
client.send_feedback_to_url(feedback_url, feedback)?
891+
} else {
892+
panic!("validation error")
893+
};
885894
Output::finished_with_data("sent feedback", Data::SubmissionFeedbackResponse(response))
886895
}
887896

0 commit comments

Comments
 (0)