diff --git a/.gitignore b/.gitignore index 970d3230..42e0cfd3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ rebel.xml rebel-remote.xml *.iml *.idea -release.properties \ No newline at end of file +release.properties diff --git a/src/main/java/edu/ksu/canvas/CanvasApiFactory.java b/src/main/java/edu/ksu/canvas/CanvasApiFactory.java index 1e753be0..fd16f01a 100644 --- a/src/main/java/edu/ksu/canvas/CanvasApiFactory.java +++ b/src/main/java/edu/ksu/canvas/CanvasApiFactory.java @@ -2,8 +2,8 @@ import edu.ksu.canvas.impl.*; import edu.ksu.canvas.interfaces.*; -import edu.ksu.canvas.net.RestClient; import edu.ksu.canvas.net.RefreshingRestClient; +import edu.ksu.canvas.net.RestClient; import edu.ksu.canvas.oauth.OauthToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -188,6 +188,9 @@ private void setupClassMap() { readerMap.put(FeatureFlagReader.class, FeatureFlagImpl.class); readerMap.put(RubricReader.class, RubricImpl.class); + readerMap.put(DiscussionTopicReader.class, DiscussionTopicImpl.class); + readerMap.put(AnnouncementReader.class, AnnouncementImpl.class); + writerMap.put(AccountWriter.class, AccountImpl.class); writerMap.put(AssignmentOverrideWriter.class, AssignmentOverrideImpl.class); writerMap.put(AdminWriter.class, AdminImpl.class); @@ -220,5 +223,8 @@ private void setupClassMap() { writerMap.put(CommunicationChannelWriter.class, CommunicationChannelImpl.class); writerMap.put(FeatureFlagWriter.class, FeatureFlagImpl.class); writerMap.put(RubricWriter.class, RubricImpl.class); + + writerMap.put(DiscussionTopicWriter.class, DiscussionTopicImpl.class); + writerMap.put(AnnouncementWriter.class, AnnouncementImpl.class); } } diff --git a/src/main/java/edu/ksu/canvas/impl/AnnouncementImpl.java b/src/main/java/edu/ksu/canvas/impl/AnnouncementImpl.java new file mode 100644 index 00000000..8d8b6819 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/impl/AnnouncementImpl.java @@ -0,0 +1,41 @@ +package edu.ksu.canvas.impl; + +import com.google.common.reflect.TypeToken; +import edu.ksu.canvas.interfaces.AnnouncementReader; +import edu.ksu.canvas.interfaces.AnnouncementWriter; +import edu.ksu.canvas.model.announcement.Announcement; +import edu.ksu.canvas.net.RestClient; +import edu.ksu.canvas.oauth.OauthToken; +import edu.ksu.canvas.requestOptions.ListCourseAnnouncementsOptions; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.List; + +/** + * An Announcement is really just a DiscussionTopic, but Canvas has + * a separate API call for fetching the ones posted under the + * Announcements tab rather than the Discussions tab. That's handled here. + */ +public class AnnouncementImpl extends BaseImpl implements AnnouncementReader, AnnouncementWriter { + + public AnnouncementImpl(String canvasBaseUrl, Integer apiVersion, OauthToken oauthToken, RestClient restClient, int connectTimeout, int readTimeout, Integer paginationPageSize, Boolean serializeNulls) { + super(canvasBaseUrl, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, paginationPageSize, serializeNulls); + } + + @Override + public List listCourseAnnouncements(ListCourseAnnouncementsOptions options) throws IOException { + String url = buildCanvasUrl("/announcements", options.getOptionsMap()); + return getListFromCanvas(url); + } + + @Override + protected Type listType() { + return new TypeToken>(){}.getType(); + } + + @Override + protected Class objectType() { + return Announcement.class; + } +} diff --git a/src/main/java/edu/ksu/canvas/impl/DiscussionTopicImpl.java b/src/main/java/edu/ksu/canvas/impl/DiscussionTopicImpl.java new file mode 100644 index 00000000..f6ea36a2 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/impl/DiscussionTopicImpl.java @@ -0,0 +1,77 @@ +package edu.ksu.canvas.impl; + +import com.google.common.reflect.TypeToken; +import edu.ksu.canvas.interfaces.DiscussionTopicReader; +import edu.ksu.canvas.interfaces.DiscussionTopicWriter; +import edu.ksu.canvas.model.discussion.DiscussionTopic; +import edu.ksu.canvas.net.Response; +import edu.ksu.canvas.net.RestClient; +import edu.ksu.canvas.oauth.OauthToken; +import edu.ksu.canvas.requestOptions.GetSingleDiscussionTopicOptions; +import edu.ksu.canvas.requestOptions.ListCourseDiscussionTopicsOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.*; + +public class DiscussionTopicImpl extends BaseImpl implements DiscussionTopicReader, DiscussionTopicWriter { + private static final Logger LOG = LoggerFactory.getLogger(DiscussionTopicImpl.class); + + public DiscussionTopicImpl(String canvasBaseURL, Integer apiVersion, OauthToken oauthToken, RestClient restClient, + int connectTimeout, int readTimeout, Integer paginationPageSize, Boolean serializeNulls) { + super(canvasBaseURL, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, paginationPageSize, serializeNulls); + } + + @Override + public List listCourseDiscussionTopics(ListCourseDiscussionTopicsOptions options) throws IOException { + String url = buildCanvasUrl("courses/" + options.getCourseId() + "/discussion_topics", options.getOptionsMap()); + return getListFromCanvas(url); + } + + @Override + public Optional getSingleDiscussionTopic(GetSingleDiscussionTopicOptions options) throws IOException { + String url = buildCanvasUrl("courses/" + options.getCourseId() + "/discussion_topics/" + options.getDiscussionTopicId(), options.getOptionsMap()); + Response response = canvasMessenger.getSingleResponseFromCanvas(oauthToken, url); + return responseParser.parseToObject(DiscussionTopic.class, response); + } + + @Override + public Optional createDiscussionTopic(String courseId, DiscussionTopic discussionTopic, boolean isAnnouncement) throws IOException { + String url = buildCanvasUrl("courses/" + courseId + "/discussion_topics", Collections.emptyMap()); + Response response = canvasMessenger.sendJsonPostToCanvas(oauthToken, url, discussionTopic.toJsonObject(serializeNulls)); + return responseParser.parseToObject(DiscussionTopic.class, response); + } + + @Override + public Optional deleteDiscussionTopic(String courseId, Long discussionTopicId) throws IOException { + Map> postParams = new HashMap<>(); + postParams.put("event", Collections.singletonList("delete")); + String createdURL = buildCanvasUrl("courses/" + courseId + "/discussion_topics/" + discussionTopicId, Collections.emptyMap()); + Response response = canvasMessenger.deleteFromCanvas(oauthToken, createdURL, postParams); + LOG.debug("response {}", response.toString()); + if (response.getErrorHappened() || response.getResponseCode() != 200) { + LOG.debug("Failed to delete discussion topic, error message: " + response); + return Optional.empty(); + } + return responseParser.parseToObject(DiscussionTopic.class, response); + } + + @Override + public Optional editDiscussionTopic(String courseId, DiscussionTopic discussionTopic) throws IOException { + String url = buildCanvasUrl("courses/" + courseId + "/discussion_topics", Collections.emptyMap()); + Response response = canvasMessenger.sendJsonPutToCanvas(oauthToken, url, discussionTopic.toJsonObject(serializeNulls)); + return responseParser.parseToObject(DiscussionTopic.class, response); + } + + @Override + protected Type listType() { + return new TypeToken>(){}.getType(); + } + + @Override + protected Class objectType() { + return DiscussionTopic.class; + } +} diff --git a/src/main/java/edu/ksu/canvas/interfaces/AnnouncementReader.java b/src/main/java/edu/ksu/canvas/interfaces/AnnouncementReader.java new file mode 100644 index 00000000..76ba93c9 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/interfaces/AnnouncementReader.java @@ -0,0 +1,19 @@ +package edu.ksu.canvas.interfaces; + +import edu.ksu.canvas.model.announcement.Announcement; +import edu.ksu.canvas.requestOptions.ListCourseAnnouncementsOptions; + +import java.io.IOException; +import java.util.List; + +/** + * Handles calls to the Announcement API endpoint. Functions + * almost identically to fetching lists of DiscussionTopics, since + * Announcements ARE DiscussionTopics, just hidden behind a different + * API call. + */ +public interface AnnouncementReader extends CanvasReader { + + List listCourseAnnouncements(ListCourseAnnouncementsOptions options) throws IOException; + +} diff --git a/src/main/java/edu/ksu/canvas/interfaces/AnnouncementWriter.java b/src/main/java/edu/ksu/canvas/interfaces/AnnouncementWriter.java new file mode 100644 index 00000000..e49b5f06 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/interfaces/AnnouncementWriter.java @@ -0,0 +1,11 @@ +package edu.ksu.canvas.interfaces; + +import edu.ksu.canvas.model.announcement.Announcement; + +/** + * There are no write calls for announcements. That's all handled by + * the DiscussionTopic API calls. This is only here to fit the structure of + * the library. + */ +public interface AnnouncementWriter extends CanvasWriter { +} diff --git a/src/main/java/edu/ksu/canvas/interfaces/DiscussionTopicReader.java b/src/main/java/edu/ksu/canvas/interfaces/DiscussionTopicReader.java new file mode 100644 index 00000000..82377f5f --- /dev/null +++ b/src/main/java/edu/ksu/canvas/interfaces/DiscussionTopicReader.java @@ -0,0 +1,29 @@ +package edu.ksu.canvas.interfaces; + +import edu.ksu.canvas.model.discussion.DiscussionTopic; +import edu.ksu.canvas.requestOptions.GetSingleDiscussionTopicOptions; +import edu.ksu.canvas.requestOptions.ListCourseDiscussionTopicsOptions; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +public interface DiscussionTopicReader extends CanvasReader { + + /** + * Retireve a specific Discussion Topic from Canvas by its Canvas ID number + * @param options Options class containing required and optional parameters for this API call + * @return The DiscussionTopic returned by Canvas or an empty Optional + * @throws IOException When there is an error communicating with Canvas + */ + Optional getSingleDiscussionTopic(GetSingleDiscussionTopicOptions options) throws IOException; + + /** + * Retrieve a list of Discussion Topics associated with a course + * @param options Options class containing required and optional parameters for this API call + * @return List of DiscussionTopics in the requested course + * @throws IOException When there is an error communicating with Canvas + */ + List listCourseDiscussionTopics(ListCourseDiscussionTopicsOptions options) throws IOException; + +} diff --git a/src/main/java/edu/ksu/canvas/interfaces/DiscussionTopicWriter.java b/src/main/java/edu/ksu/canvas/interfaces/DiscussionTopicWriter.java new file mode 100644 index 00000000..18256284 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/interfaces/DiscussionTopicWriter.java @@ -0,0 +1,38 @@ +package edu.ksu.canvas.interfaces; + +import edu.ksu.canvas.model.discussion.DiscussionTopic; + +import java.io.IOException; +import java.util.Optional; + +public interface DiscussionTopicWriter extends CanvasWriter { + + /** + * Create a Discussion Topic in Canvas. The API docs interestingly do not list any fields as required. + * @param courseId the ID of the course to create the discussion topic in + * @param discussionTopic DiscussionTopic object to create + * @param isAnnouncement Whether the topic is an Announcement + * @return The created DiscussionTopic object + * @throws IOException When there is an error communicating with Canvas + */ + Optional createDiscussionTopic(String courseId, DiscussionTopic discussionTopic, boolean isAnnouncement) throws IOException; + + /** + * Delete a specified Discussion Topic from Canvas + * @param courseId Course ID of the course to delete the Discussion Topic from + * @param discussionTopicId Canvas ID of the Discussion Topic to delete + * @return The deleted DiscussionTopic object as returned by the Canvas API + * @throws IOException When there is an error communicating with Canvas + */ + Optional deleteDiscussionTopic(String courseId, Long discussionTopicId) throws IOException; + + /** + * Modify a Discussion Topic object on Canvas + * @param courseId Course ID of the course to modify the Discussion Topic within + * @param discussionTopic The DiscussionTopic object whose parameters should be written to Canvas + * @return The modified DiscussionTopic returned by the Canvas API + * @throws IOException When there is an error communicating with Canvas + */ + Optional editDiscussionTopic(String courseId, DiscussionTopic discussionTopic) throws IOException; + +} diff --git a/src/main/java/edu/ksu/canvas/model/announcement/Announcement.java b/src/main/java/edu/ksu/canvas/model/announcement/Announcement.java new file mode 100644 index 00000000..bdd0b1d2 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/model/announcement/Announcement.java @@ -0,0 +1,15 @@ +package edu.ksu.canvas.model.announcement; + +import edu.ksu.canvas.model.discussion.DiscussionTopic; + +import java.io.Serializable; + +/** + * The Announcement object type is just a DiscussionTopic object + * that gets returned from a different API call. + */ +public class Announcement extends DiscussionTopic implements Serializable { + + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/edu/ksu/canvas/model/assignment/Assignment.java b/src/main/java/edu/ksu/canvas/model/assignment/Assignment.java index dbae7c4d..6699f8e8 100644 --- a/src/main/java/edu/ksu/canvas/model/assignment/Assignment.java +++ b/src/main/java/edu/ksu/canvas/model/assignment/Assignment.java @@ -10,7 +10,7 @@ import java.util.List; /** - * Class to represent Canvas assigmnents. + * Class to represent Canvas assignments. * See Canvas assignment documentation. */ @CanvasObject(postKey = "assignment") diff --git a/src/main/java/edu/ksu/canvas/model/discussion/DiscussionTopic.java b/src/main/java/edu/ksu/canvas/model/discussion/DiscussionTopic.java new file mode 100644 index 00000000..b4c0270d --- /dev/null +++ b/src/main/java/edu/ksu/canvas/model/discussion/DiscussionTopic.java @@ -0,0 +1,362 @@ +package edu.ksu.canvas.model.discussion; + +import edu.ksu.canvas.annotation.CanvasField; +import edu.ksu.canvas.annotation.CanvasObject; +import edu.ksu.canvas.model.BaseCanvasModel; +import edu.ksu.canvas.model.File; +import edu.ksu.canvas.model.assignment.LockInfo; + +import java.io.Serializable; +import java.util.Date; + +/** + * Class to represent canvas Discussion Topics. + * See Canvas DiscussionTopicdocumentation. + */ +@CanvasObject(postKey = "discussion_topic") +public class DiscussionTopic extends BaseCanvasModel implements Serializable { + + private static final long serialVersionUID = 1L; + private Long id; + private String title; + private String message; + private String htmlURL; + private Date postedAt; + private Date lastReplyAt; + private Boolean requireInitialPost; + private Boolean userCanSeePosts; + private Long discussionSubentryCount; + private String readState; + private Long unreadCount; + private Boolean subscribed; + private String subscriptionHold; + private Long assignmentId; + private Date delayedPostAt; + private Boolean published; + private Date lockAt; + private Boolean locked; + private Boolean pinned; + private Boolean lockedForUser; + private LockInfo lockInfo; + private String lockExplanation; + private String userName; + private Long[] topicChildren; + private TopicChildren[] groupTopicChildren; + private Long rootTopicId; + private String podcastURL; + private String discussionType; + private Long groupCategoryId; + private File[] attachments; + private DiscussionTopicPermission permissions; + private Boolean allowRating; + private Boolean onlyGradersCanRate; + private Boolean sortByRating; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @CanvasField(postKey = "title") + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @CanvasField(postKey = "message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getHtmlURL() { + return htmlURL; + } + + public void setHtmlURL(String htmlURL) { + this.htmlURL = htmlURL; + } + + public Date getPostedAt() { + return postedAt; + } + + public void setPostedAt(Date postedAt) { + this.postedAt = postedAt; + } + + public Date getLastReplyAt() { + return lastReplyAt; + } + + public void setLastReplyAt(Date lastReplyAt) { + this.lastReplyAt = lastReplyAt; + } + + @CanvasField(postKey = "require_initial_post") + public Boolean getRequireInitialPost() { + return requireInitialPost; + } + + public void setRequireInitialPost(Boolean requireInitialPost) { + this.requireInitialPost = requireInitialPost; + } + + public Boolean getUserCanSeePosts() { + return userCanSeePosts; + } + + public void setUserCanSeePosts(Boolean userCanSeePosts) { + this.userCanSeePosts = userCanSeePosts; + } + + public Long getDiscussionSubentryCount() { + return discussionSubentryCount; + } + + public void setDiscussionSubentryCount(Long discussionSubentryCount) { + this.discussionSubentryCount = discussionSubentryCount; + } + + public String getReadState() { + return readState; + } + + public void setReadState(String readState) { + this.readState = readState; + } + + public Long getUnreadCount() { + return unreadCount; + } + + public void setUnreadCount(Long unreadCount) { + this.unreadCount = unreadCount; + } + + public Boolean getSubscribed() { + return subscribed; + } + + public void setSubscribed(Boolean subscribed) { + this.subscribed = subscribed; + } + + public String getSubscriptionHold() { + return subscriptionHold; + } + + public void setSubscriptionHold(String subscriptionHold) { + this.subscriptionHold = subscriptionHold; + } + + public Long getAssignmentId() { + return assignmentId; + } + + public void setAssignmentId(Long assignmentId) { + this.assignmentId = assignmentId; + } + + @CanvasField(postKey = "delayed_post_at") + public Date getDelayedPostAt() { + return delayedPostAt; + } + + public void setDelayedPostAt(Date delayedPostAt) { + this.delayedPostAt = delayedPostAt; + } + + public Boolean getPublished() { + return published; + } + + public void setPublished(Boolean published) { + this.published = published; + } + + @CanvasField(postKey = "lock_at") + public Date getLockAt() { + return lockAt; + } + + public void setLockAt(Date lockAt) { + this.lockAt = lockAt; + } + + @CanvasField(postKey = "locked") + public Boolean getLocked() { + return locked; + } + + public void setLocked(Boolean locked) { + this.locked = locked; + } + + public Boolean getPinned() { + return pinned; + } + + public void setPinned(Boolean pinned) { + this.pinned = pinned; + } + + public Boolean getLockedForUser() { + return lockedForUser; + } + + public void setLockedForUser(Boolean lockedForUser) { + this.lockedForUser = lockedForUser; + } + + public LockInfo getLockInfo() { + return lockInfo; + } + + public void setLockInfo(LockInfo lockInfo) { + this.lockInfo = lockInfo; + } + + public String getLockExplanation() { + return lockExplanation; + } + + public void setLockExplanation(String lockExplanation) { + this.lockExplanation = lockExplanation; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Long[] getTopicChildren() { + return topicChildren; + } + + public void setTopicChildren(Long[] topicChildren) { + this.topicChildren = topicChildren; + } + + public TopicChildren[] getGroupTopicChildren() { + return groupTopicChildren; + } + + public void setGroupTopicChildren(TopicChildren[] groupTopicChildren) { + this.groupTopicChildren = groupTopicChildren; + } + + public Long getRootTopicId() { + return rootTopicId; + } + + public void setRootTopicId(Long rootTopicId) { + this.rootTopicId = rootTopicId; + } + + public String getPodcastURL() { + return podcastURL; + } + + public void setPodcastURL(String podcastURL) { + this.podcastURL = podcastURL; + } + + @CanvasField(postKey = "discussion_type") + public String getDiscussionType() { + return discussionType; + } + + public void setDiscussionType(String discussionType) { + this.discussionType = discussionType; + } + + public Long getGroupCategoryId() { + return groupCategoryId; + } + + public void setGroupCategoryId(Long groupCategoryId) { + this.groupCategoryId = groupCategoryId; + } + + @CanvasField(postKey = "attachments") + public File[] getAttachments() { + return attachments; + } + + public void setAttachments(File[] attachments) { + this.attachments = attachments; + } + + public DiscussionTopicPermission getPermissions() { + return permissions; + } + + public void setPermissions(DiscussionTopicPermission permissions) { + this.permissions = permissions; + } + + @CanvasField(postKey = "allow_rating") + public Boolean getAllowRating() { + return allowRating; + } + + public void setAllowRating(Boolean allowRating) { + this.allowRating = allowRating; + } + + @CanvasField(postKey = "only_graders_can_rate") + public Boolean getOnlyGradersCanRate() { + return onlyGradersCanRate; + } + + public void setOnlyGradersCanRate(Boolean onlyGradersCanRate) { + this.onlyGradersCanRate = onlyGradersCanRate; + } + + @CanvasField(postKey = "sort_by_rating") + public Boolean getSortByRating() { + return sortByRating; + } + + public void setSortByRating(Boolean sortByRating) { + this.sortByRating = sortByRating; + } + + public class TopicChildren implements Serializable { + + private static final long serialVersionUID = 1L; + + private String topicId; + private String groupId; + + public String getTopicId() { + return topicId; + } + + public void setTopicId(String topicId) { + this.topicId = topicId; + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + } + +} diff --git a/src/main/java/edu/ksu/canvas/model/discussion/DiscussionTopicPermission.java b/src/main/java/edu/ksu/canvas/model/discussion/DiscussionTopicPermission.java new file mode 100644 index 00000000..946bdaed --- /dev/null +++ b/src/main/java/edu/ksu/canvas/model/discussion/DiscussionTopicPermission.java @@ -0,0 +1,13 @@ +package edu.ksu.canvas.model.discussion; + +import java.io.Serializable; + +public class DiscussionTopicPermission implements Serializable { + + private static final long serialVersionUID = 1L; + + private Boolean attach; + + public boolean canAttach() { return attach; } + +} diff --git a/src/main/java/edu/ksu/canvas/requestOptions/GetSingleDiscussionTopicOptions.java b/src/main/java/edu/ksu/canvas/requestOptions/GetSingleDiscussionTopicOptions.java new file mode 100644 index 00000000..f0c39c68 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/requestOptions/GetSingleDiscussionTopicOptions.java @@ -0,0 +1,38 @@ +package edu.ksu.canvas.requestOptions; + +import java.util.List; + +public class GetSingleDiscussionTopicOptions extends BaseOptions { + + private String courseId; + private Long discussionTopicId; + + public enum Include { + ALL_DATES, SECTIONS, SECTIONS_USER_COUNT, OVERRIDES; + + @Override + public String toString() { return name().toLowerCase(); } + } + + public GetSingleDiscussionTopicOptions(String courseId, Long discussionTopicId) { + if (courseId == null || discussionTopicId == null) { + throw new IllegalArgumentException("Course and discussion topic ids are required"); + } + this.courseId = courseId; + this.discussionTopicId = discussionTopicId; + } + + public String getCourseId() { + return courseId; + } + + public Long getDiscussionTopicId() { + return discussionTopicId; + } + + public GetSingleDiscussionTopicOptions includes(List includes) { + addEnumList("include[]", includes); + return this; + } + +} diff --git a/src/main/java/edu/ksu/canvas/requestOptions/ListCourseAnnouncementsOptions.java b/src/main/java/edu/ksu/canvas/requestOptions/ListCourseAnnouncementsOptions.java new file mode 100644 index 00000000..f5855d0b --- /dev/null +++ b/src/main/java/edu/ksu/canvas/requestOptions/ListCourseAnnouncementsOptions.java @@ -0,0 +1,61 @@ +package edu.ksu.canvas.requestOptions; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class ListCourseAnnouncementsOptions extends BaseOptions { + + public enum Include { + SECTIONS, SECTIONS_USER_COUNT; + + @Override + public String toString() { return name().toLowerCase(); } + } + + private String courseId; + + public ListCourseAnnouncementsOptions(String courseId) { + this.courseId = courseId; + List contextCodesList = new ArrayList<>(); + contextCodesList.add("course_" + courseId); + addStringList("context_codes[]", contextCodesList); + } + + public String getCourseId() { + return courseId; + } + + public ListCourseAnnouncementsOptions includes(List includes) { + addEnumList("include[]", includes); + return this; + } + + public ListCourseAnnouncementsOptions startDate(Date startDate) { + addSingleItem("start_date", formatDate(startDate)); + return this; + } + + public ListCourseAnnouncementsOptions endDate(Date endDate) { + addSingleItem("end_date", formatDate(endDate)); + return this; + } + + public ListCourseAnnouncementsOptions activeOnly(Boolean activeOnly) { + addSingleItem("active_only", activeOnly.toString()); + return this; + } + + public ListCourseAnnouncementsOptions latestOnly(Boolean latestOnly) { + addSingleItem("latest_only", latestOnly.toString()); + return this; + } + + private static String formatDate(Date date) { + DateFormat df = new SimpleDateFormat("yyyy-MM-ddTHH:mm:ssZ"); + return df.format(date); + } + +} diff --git a/src/main/java/edu/ksu/canvas/requestOptions/ListCourseDiscussionTopicsOptions.java b/src/main/java/edu/ksu/canvas/requestOptions/ListCourseDiscussionTopicsOptions.java new file mode 100644 index 00000000..61d537d1 --- /dev/null +++ b/src/main/java/edu/ksu/canvas/requestOptions/ListCourseDiscussionTopicsOptions.java @@ -0,0 +1,80 @@ +package edu.ksu.canvas.requestOptions; + +import java.util.List; + +public class ListCourseDiscussionTopicsOptions extends BaseOptions { + + public enum Include { + ALL_DATES, SECTIONS, SECTIONS_USER_COUNT, OVERRIDES; + + @Override + public String toString() { return name().toLowerCase(); } + } + + public enum OrderBy { + POSITION, RECENT_ACTIVITY, TITLE; + + @Override + public String toString() { return name().toLowerCase(); } + } + + public enum Scope { + LOCKED, UNLOCKED, PINNED, UNPINNED; + + @Override + public String toString() { return name().toLowerCase(); } + } + + public enum FilterBy { + ALL, UNREAD; + + @Override + public String toString() { return name().toLowerCase(); } + } + + private String courseId; + + public ListCourseDiscussionTopicsOptions(String courseId) { + this.courseId = courseId; + } + + public String getCourseId() { + return courseId; + } + + public ListCourseDiscussionTopicsOptions includes(List includes) { + addEnumList("include[]", includes); + return this; + } + + public ListCourseDiscussionTopicsOptions orderBy(OrderBy orderBy) { + addSingleItem("order_by", orderBy.toString()); + return this; + } + + public ListCourseDiscussionTopicsOptions scope(List scopes) { + addEnumList("scope", scopes); + return this; + } + + public ListCourseDiscussionTopicsOptions onlyAnnouncements(Boolean onlyAnnouncements) { + addSingleItem("only_announcements", onlyAnnouncements.toString()); + return this; + } + + public ListCourseDiscussionTopicsOptions searchTerm(String searchTerm) { + addSingleItem("search_term", searchTerm); + return this; + } + + public ListCourseDiscussionTopicsOptions filterBy(FilterBy filterBy) { + addSingleItem("filter_by", filterBy.toString()); + return this; + } + + public ListCourseDiscussionTopicsOptions excludeContextModuleLockedTopics(Boolean exclude) { + addSingleItem("exclude_context_module_locked_topics", exclude.toString()); + return this; + } + +} diff --git a/src/test/java/edu/ksu/canvas/BaseCanvasModelUTest.java b/src/test/java/edu/ksu/canvas/BaseCanvasModelUTest.java index 5c477996..0e3b0c06 100644 --- a/src/test/java/edu/ksu/canvas/BaseCanvasModelUTest.java +++ b/src/test/java/edu/ksu/canvas/BaseCanvasModelUTest.java @@ -120,4 +120,4 @@ public void jsonField1Value() throws Exception { Assert.assertEquals("JSON object should have a 'field1' value of " + FIELD1_VALUE, FIELD1_VALUE, field1Value); } -} \ No newline at end of file +}