package com.instructure.canvasapi.api;
import com.instructure.canvasapi.model.CanvasContext;
import com.instructure.canvasapi.model.Quiz;
import com.instructure.canvasapi.model.QuizQuestion;
import com.instructure.canvasapi.model.QuizSubmission;
import com.instructure.canvasapi.model.QuizSubmissionQuestionResponse;
import com.instructure.canvasapi.model.QuizSubmissionResponse;
import com.instructure.canvasapi.model.QuizSubmissionTime;
import com.instructure.canvasapi.utilities.APIHelpers;
import com.instructure.canvasapi.utilities.CanvasCallback;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import retrofit.Callback;
import retrofit.client.Response;
import retrofit.http.Body;
import retrofit.http.GET;
import retrofit.http.POST;
import retrofit.http.PUT;
import retrofit.http.Path;
import retrofit.http.Query;
/**
*
* Copyright (c) 2016 Instructure. All rights reserved.
*/
public class QuizAPI extends BuildInterfaceAPI {
private static final String QUIZ_SUBMISSION_SESSION_STARTED = "android_session_started";
interface QuizzesInterface {
@GET("/{context_id}/quizzes")
void getFirstPageQuizzesList(@Path("context_id") long context_id, Callback<Quiz[]> callback);
@GET("/{next}")
void getNextPageQuizzesList(@Path(value = "next", encode = false) String nextURL, Callback<Quiz[]> callback);
@GET("/{context_id}/quizzes/{quizid}")
void getDetailedQuiz(@Path("context_id") long context_id, @Path("quizid") long quizid, Callback<Quiz> callback);
@GET("/{next}")
void getDetailedQuizFromURL(@Path(value = "next", encode = false) String quizURL, Callback<Quiz> callback);
@GET("/{context_id}/quizzes/{quizid}/questions")
void getFirstPageQuizQuestions(@Path("context_id") long context_id, @Path("quizid") long quizid, Callback<QuizQuestion[]> callback);
@GET("/{next}")
void getNextPageQuizQuestions(@Path(value = "next", encode = false) String nextURL, Callback<QuizQuestion[]> callback);
@POST("/{context_id}/quizzes/{quizid}/submissions")
void startQuiz(@Path("context_id") long context_id, @Path("quizid") long quizid, @Body String body, Callback<Response> callback);
@GET("/{context_id}/quizzes/{quizid}/submissions")
void getFirstPageQuizSubmissions(@Path("context_id") long context_id, @Path("quizid") long quizid, Callback<QuizSubmissionResponse> callback);
@GET("/{next}")
void getNextPageQuizSubmissions(@Path(value = "next", encode = false) String nextURL, Callback<QuizSubmissionResponse> callback);
@GET("/quiz_submissions/{quiz_submission_id}/questions")
void getFirstPageSubmissionQuestions(@Path("quiz_submission_id") long quizSubmissionId, Callback<QuizSubmissionQuestionResponse> callback);
@GET("/{next}")
void getNextPageSubmissionQuestions(@Path(value = "next", encode = false) String nextURL, Callback<QuizSubmissionQuestionResponse> callback);
@POST("/quiz_submissions/{quiz_submission_id}/questions")
void postQuizQuestionMultiChoice(@Path("quiz_submission_id") long quizSubmissionId, @Query("attempt") int attempt, @Query("validation_token") String token, @Query("quiz_questions[][id]") long questionId, @Query("quiz_questions[][answer]") long answer, @Body String body, Callback<QuizSubmissionQuestionResponse> callback);
@PUT("/quiz_submissions/{quiz_submission_id}/questions/{question_id}/flag")
void putFlagQuizQuestion(@Path("quiz_submission_id") long quizSubmissionId, @Path("question_id") long questionId, @Query("attempt") int attempt, @Query("validation_token") String token, @Body String body, CanvasCallback<Response> callback);
@PUT("/quiz_submissions/{quiz_submission_id}/questions/{question_id}/unflag")
void putUnflagQuizQuestion(@Path("quiz_submission_id") long quizSubmissionId, @Path("question_id") long questionId, @Query("attempt") int attempt, @Query("validation_token") String token, @Body String body, CanvasCallback<Response> callback);
@POST("/quiz_submissions/{quiz_submission_id}/questions")
void postQuizQuestionEssay(@Path("quiz_submission_id") long quizSubmissionId, @Query("attempt") int attempt, @Query("validation_token") String token, @Query("quiz_questions[][id]") long questionId, @Query("quiz_questions[][answer]") String answer, @Body String body, Callback<QuizSubmissionQuestionResponse> callback);
@POST("/{context_id}/quizzes/{quiz_id}/submissions/{submission_id}/complete")
void postQuizSubmit(@Path("context_id") long context_id, @Path("quiz_id") long quizId, @Path("submission_id") long submissionId, @Query("attempt") int attempt, @Query("validation_token") String token, @Body String body, Callback<QuizSubmissionResponse> callback);
@POST("/{context_id}/quizzes/{quiz_id}/submissions/{submission_id}/events")
void postQuizStartedEvent(@Path("context_id") long context_id, @Path("quiz_id") long quizId, @Path("submission_id") long submissionId, @Query("quiz_submission_events[][event_type]") String sessionStartedString, @Query("quiz_submission_events[][event_data][user_agent]") String userAgentString, @Body String body, CanvasCallback<Response> callback);
@GET("/{context_id}/quizzes/{quiz_id}/submissions/{submission_id}/time")
void getQuizSubmissionTime(@Path("context_id") long context_id, @Path("quiz_id") long quizId, @Path("submission_id") long submissionId, CanvasCallback<QuizSubmissionTime> callback);
@POST("/quiz_submissions/{quiz_submission_id}/questions{query_params}")
void postQuizQuestionMultiAnswers(@Path("quiz_submission_id") long quizSubmissionId, @Path(value = "query_params", encode = false) String queryParams, @Body String body, Callback<QuizSubmissionQuestionResponse> callback);
@POST("/quiz_submissions/{quiz_submission_id}/questions{query_params}")
void postQuizQuestionMatching(@Path("quiz_submission_id") long quizSubmissionId, @Path(value = "query_params", encode = false) String queryParams, @Body String body, Callback<QuizSubmissionQuestionResponse> callback);
}
/////////////////////////////////////////////////////////////////////////
// API Calls
/////////////////////////////////////////////////////////////////////////
public static void getFirstPageQuizzes(CanvasContext canvasContext, CanvasCallback<Quiz[]> callback) {
if (APIHelpers.paramIsNull(callback, canvasContext)) { return; }
buildCacheInterface(QuizzesInterface.class, callback, canvasContext).getFirstPageQuizzesList(canvasContext.getId(), callback);
buildInterface(QuizzesInterface.class, callback, canvasContext).getFirstPageQuizzesList(canvasContext.getId(), callback);
}
public static void getNextPageQuizzes(String nextURL, CanvasCallback<Quiz[]> callback){
if (APIHelpers.paramIsNull(callback, nextURL)) { return; }
callback.setIsNextPage(true);
buildCacheInterface(QuizzesInterface.class, callback, false).getNextPageQuizzesList(nextURL, callback);
buildInterface(QuizzesInterface.class, callback, false).getNextPageQuizzesList(nextURL, callback);
}
public static void getDetailedQuiz(CanvasContext canvasContext, long quiz_id, CanvasCallback<Quiz> callback) {
if (APIHelpers.paramIsNull(callback, canvasContext)) { return; }
buildCacheInterface(QuizzesInterface.class, callback, canvasContext).getDetailedQuiz(canvasContext.getId(), quiz_id, callback);
buildInterface(QuizzesInterface.class, callback, canvasContext).getDetailedQuiz(canvasContext.getId(), quiz_id, callback);
}
public static void getDetailedQuizFromURL(String url, CanvasCallback<Quiz> callback) {
if (APIHelpers.paramIsNull(callback,url)) { return; }
buildCacheInterface(QuizzesInterface.class, callback, null).getDetailedQuizFromURL(url, callback);
buildInterface(QuizzesInterface.class, callback, null).getDetailedQuizFromURL(url, callback);
}
public static void getFirstPageQuizQuestions(CanvasContext canvasContext, long quiz_id, CanvasCallback<QuizQuestion[]> callback) {
if (APIHelpers.paramIsNull(callback, canvasContext)) { return; }
buildCacheInterface(QuizzesInterface.class, callback, canvasContext).getFirstPageQuizQuestions(canvasContext.getId(), quiz_id, callback);
buildInterface(QuizzesInterface.class, callback, canvasContext).getFirstPageQuizQuestions(canvasContext.getId(), quiz_id, callback);
}
public static void getNextPageQuizQuestions(String nextURL, CanvasCallback<QuizQuestion[]> callback){
if (APIHelpers.paramIsNull(callback, nextURL)) { return; }
callback.setIsNextPage(true);
buildCacheInterface(QuizzesInterface.class, callback, false).getNextPageQuizQuestions(nextURL, callback);
buildInterface(QuizzesInterface.class, callback, false).getNextPageQuizQuestions(nextURL, callback);
}
public static void startQuiz(CanvasContext canvasContext, long quiz_id, CanvasCallback<Response> callback) {
if (APIHelpers.paramIsNull(callback, canvasContext)) { return; }
buildInterface(QuizzesInterface.class, callback, canvasContext).startQuiz(canvasContext.getId(), quiz_id, "", callback);
}
public static void getFirstPageQuizSubmissions(CanvasContext canvasContext, long quiz_id, CanvasCallback<QuizSubmissionResponse> callback) {
if (APIHelpers.paramIsNull(callback, canvasContext)) { return; }
buildCacheInterface(QuizzesInterface.class, callback, canvasContext).getFirstPageQuizSubmissions(canvasContext.getId(), quiz_id, callback);
buildInterface(QuizzesInterface.class, callback, canvasContext).getFirstPageQuizSubmissions(canvasContext.getId(), quiz_id, callback);
}
public static void getNextPageQuizSubmissions(String nextURL, CanvasCallback<QuizSubmissionResponse> callback){
if (APIHelpers.paramIsNull(callback, nextURL)) { return; }
callback.setIsNextPage(true);
buildCacheInterface(QuizzesInterface.class, callback, false).getNextPageQuizSubmissions(nextURL, callback);
buildInterface(QuizzesInterface.class, callback, false).getNextPageQuizSubmissions(nextURL, callback);
}
public static void getFirstPageSubmissionQuestions(long quizSubmissionId, CanvasCallback<QuizSubmissionQuestionResponse> callback) {
if (APIHelpers.paramIsNull(callback)) { return; }
buildInterface(QuizzesInterface.class, callback, null).getFirstPageSubmissionQuestions(quizSubmissionId, callback);
}
public static void getNextPageSubmissionQuestions(String nextURL, CanvasCallback<QuizSubmissionQuestionResponse> callback){
if (APIHelpers.paramIsNull(callback, nextURL)) { return; }
callback.setIsNextPage(true);
buildInterface(QuizzesInterface.class, callback, false).getNextPageSubmissionQuestions(nextURL, callback);
}
public static void postQuizQuestionMultiChoice(QuizSubmission quizSubmission, long answerId, long questionId, CanvasCallback<QuizSubmissionQuestionResponse> callback){
if (APIHelpers.paramIsNull(callback, quizSubmission, quizSubmission.getSubmissionId(), quizSubmission.getValidationToken())) { return; }
buildInterface(QuizzesInterface.class, callback, null, false).postQuizQuestionMultiChoice(quizSubmission.getId(), quizSubmission.getAttempt(), quizSubmission.getValidationToken(), questionId, answerId, "", callback);
}
public static void putFlagQuizQuestion(QuizSubmission quizSubmission, long quizQuestionId, boolean shouldFlag, CanvasCallback<Response> callback) {
if (APIHelpers.paramIsNull(callback, quizSubmission, quizSubmission.getSubmissionId(), quizSubmission.getValidationToken())) { return; }
if(shouldFlag) {
buildInterface(QuizzesInterface.class, callback, null, false).putFlagQuizQuestion(quizSubmission.getId(), quizQuestionId, quizSubmission.getAttempt(), quizSubmission.getValidationToken(), "", callback);
} else {
buildInterface(QuizzesInterface.class, callback, null, false).putUnflagQuizQuestion(quizSubmission.getId(), quizQuestionId, quizSubmission.getAttempt(), quizSubmission.getValidationToken(), "", callback);
}
}
public static void postQuizQuestionEssay(QuizSubmission quizSubmission, String answer, long questionId, CanvasCallback<QuizSubmissionQuestionResponse> callback){
if (APIHelpers.paramIsNull(callback, quizSubmission, quizSubmission.getSubmissionId(), quizSubmission.getValidationToken())) { return; }
buildInterface(QuizzesInterface.class, callback, null, false).postQuizQuestionEssay(quizSubmission.getId(), quizSubmission.getAttempt(), quizSubmission.getValidationToken(), questionId, answer, "", callback);
}
public static void postQuizSubmit(CanvasContext canvasContext, QuizSubmission quizSubmission, CanvasCallback<QuizSubmissionResponse> callback) {
if (APIHelpers.paramIsNull(canvasContext, callback, quizSubmission, quizSubmission.getSubmissionId(), quizSubmission.getValidationToken())) { return; }
buildInterface(QuizzesInterface.class, callback, canvasContext, false).postQuizSubmit(canvasContext.getId(), quizSubmission.getQuizId(), quizSubmission.getId(), quizSubmission.getAttempt(), quizSubmission.getValidationToken(), "", callback);
}
public static void postQuizStartedEvent(CanvasContext canvasContext, QuizSubmission quizSubmission, String userAgentString, CanvasCallback<Response> callback) {
if (APIHelpers.paramIsNull(canvasContext, callback, quizSubmission, quizSubmission.getSubmissionId())) { return; }
buildInterface(QuizzesInterface.class, callback, canvasContext, false).postQuizStartedEvent(canvasContext.getId(), quizSubmission.getQuizId(), quizSubmission.getId(), QUIZ_SUBMISSION_SESSION_STARTED, userAgentString, "", callback);
}
public static void getQuizSubmissionTime(CanvasContext canvasContext, QuizSubmission quizSubmission, CanvasCallback<QuizSubmissionTime> callback) {
if(APIHelpers.paramIsNull(canvasContext, callback, quizSubmission)) { return; }
buildInterface(QuizzesInterface.class, callback, canvasContext).getQuizSubmissionTime(canvasContext.getId(), quizSubmission.getQuizId(), quizSubmission.getId(), callback);
}
public static void postQuizQuestionMultiAnswer(QuizSubmission quizSubmission, long questionId, ArrayList<Long> answers, CanvasCallback<QuizSubmissionQuestionResponse> callback){
if (APIHelpers.paramIsNull(callback, quizSubmission, quizSubmission.getSubmissionId(), quizSubmission.getValidationToken())) { return; }
//we don't to append the per_page parameter because we're building the query parameters ourselves, so use the different interface
buildInterface(QuizzesInterface.class, callback, null, false).postQuizQuestionMultiAnswers(quizSubmission.getId(), buildMultiAnswerList(quizSubmission.getAttempt(), quizSubmission.getValidationToken(), questionId, answers), "", callback);
}
public static void postQuizQuestionMatching(QuizSubmission quizSubmission, long questionId, HashMap<Long, Integer> answers, CanvasCallback<QuizSubmissionQuestionResponse> callback){
if (APIHelpers.paramIsNull(callback, quizSubmission, quizSubmission.getSubmissionId(), quizSubmission.getValidationToken())) { return; }
//we don't to append the per_page parameter because we're building the query parameters ourselves, so use the different interface
buildInterface(QuizzesInterface.class, callback, null, false).postQuizQuestionMatching(quizSubmission.getId(), buildMatchingList(quizSubmission.getAttempt(), quizSubmission.getValidationToken(), questionId, answers), "", callback);
}
private static String buildMultiAnswerList(int attempt, String validationToken, long questionId, ArrayList<Long> answers) {
// build the query params because we'll have an unknown amount of answers. It will end up looking like:
// ?attempt={attempt}&validation_token={validation_token}&quiz_questions[][id]={question_id}&quiz_questions[][answer][]={answer_id}...
StringBuilder builder = new StringBuilder();
builder.append("?");
builder.append("attempt=");
builder.append(Integer.toString(attempt));
builder.append("&");
builder.append("validation_token=");
builder.append(validationToken);
builder.append("&");
builder.append("quiz_questions[][id]=");
builder.append(Long.toString(questionId));
builder.append("&");
for(Long answer : answers) {
builder.append("quiz_questions[][answer][]");
builder.append("=");
builder.append(Long.toString(answer));
builder.append("&");
}
String answerString = builder.toString();
if(answerString.endsWith("&")) {
answerString = answerString.substring(0, answerString.length() - 1);
}
return answerString;
}
private static String buildMatchingList(int attempt, String validationToken, long questionId, HashMap<Long, Integer> answers) {
// build the query params. It will end up looking like:
// ?attempt={attempt}&validation_token={validation_token}&quiz_questions[][id]={question_id}&quiz_questions[][answer][][answer_id]={answer_id}&quiz_questions[][answer][][match_id]={match_id}...
StringBuilder builder = new StringBuilder();
builder.append("?");
builder.append("attempt=");
builder.append(Integer.toString(attempt));
builder.append("&");
builder.append("validation_token=");
builder.append(validationToken);
builder.append("&");
builder.append("quiz_questions[][id]=");
builder.append(Long.toString(questionId));
builder.append("&");
//loop through the HashMap that contains the list of answers and their matches that the user selected
for(Map.Entry<Long, Integer> answer : answers.entrySet()) {
builder.append("quiz_questions[][answer][][answer_id]");
builder.append("=");
builder.append(Long.toString(answer.getKey()));
builder.append("&");
builder.append("quiz_questions[][answer][][match_id]");
builder.append("=");
builder.append(Integer.toString(answer.getValue()));
builder.append("&");
}
String answerString = builder.toString();
if(answerString.endsWith("&")) {
answerString = answerString.substring(0, answerString.length() - 1);
}
return answerString;
}
}