fixed some minor bugs for Moodle integration

This commit is contained in:
anhefti 2020-12-14 17:01:33 +01:00
parent 39a90d201b
commit c72bf2cf9c
4 changed files with 59 additions and 25 deletions

View file

@ -295,6 +295,10 @@ public final class Utils {
return new DateTime(timestamp * 1000, DateTimeZone.UTC); return new DateTime(timestamp * 1000, DateTimeZone.UTC);
} }
public static final long toUnixTimeInSeconds(final DateTime time) {
return time.getMillis() / 1000;
}
public static Long toTimestamp(final String dateString) { public static Long toTimestamp(final String dateString) {
if (StringUtils.isBlank(dateString)) { if (StringUtils.isBlank(dateString)) {
return null; return null;

View file

@ -152,7 +152,7 @@ public interface LmsAPIService {
} }
return new Page<>( return new Page<>(
quizzes.size() / pageSize + 1, (quizzes.size() <= pageSize) ? 1 : quizzes.size() / pageSize + 1,
pageNumber, pageNumber,
sortAttribute, sortAttribute,
quizzes.subList(start, end)); quizzes.subList(start, end));

View file

@ -73,6 +73,8 @@ public class MoodleCourseAccess extends CourseAccess {
private static final String MOODLE_COURSE_API_SEARCH_PAGE = "page"; private static final String MOODLE_COURSE_API_SEARCH_PAGE = "page";
private static final String MOODLE_COURSE_API_SEARCH_PAGE_SIZE = "perpage"; private static final String MOODLE_COURSE_API_SEARCH_PAGE_SIZE = "perpage";
private static final int DEFAULT_FROM_YEARS = 3;
private final JSONMapper jsonMapper; private final JSONMapper jsonMapper;
private final LmsSetup lmsSetup; private final LmsSetup lmsSetup;
private final MoodleRestTemplateFactory moodleRestTemplateFactory; private final MoodleRestTemplateFactory moodleRestTemplateFactory;
@ -178,7 +180,7 @@ public class MoodleCourseAccess extends CourseAccess {
@Override @Override
protected Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap) { protected Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap) {
return () -> getRestTemplate() return () -> getRestTemplate()
.map(this::collectAllQuizzes) .map(template -> collectAllQuizzes(template, filterMap))
.getOrThrow(); .getOrThrow();
} }
@ -187,11 +189,14 @@ public class MoodleCourseAccess extends CourseAccess {
throw new UnsupportedOperationException("not available yet"); throw new UnsupportedOperationException("not available yet");
} }
private ArrayList<QuizData> collectAllQuizzes(final MoodleAPIRestTemplate restTemplate) { private ArrayList<QuizData> collectAllQuizzes(
final MoodleAPIRestTemplate restTemplate,
final FilterMap filterMap) {
final String urlPrefix = (this.lmsSetup.lmsApiUrl.endsWith(Constants.URL_PATH_SEPARATOR)) final String urlPrefix = (this.lmsSetup.lmsApiUrl.endsWith(Constants.URL_PATH_SEPARATOR))
? this.lmsSetup.lmsApiUrl + MOODLE_QUIZ_START_URL_PATH ? this.lmsSetup.lmsApiUrl + MOODLE_QUIZ_START_URL_PATH
: this.lmsSetup.lmsApiUrl + Constants.URL_PATH_SEPARATOR + MOODLE_QUIZ_START_URL_PATH; : this.lmsSetup.lmsApiUrl + Constants.URL_PATH_SEPARATOR + MOODLE_QUIZ_START_URL_PATH;
return getAllQuizzes(restTemplate) return getAllQuizzes(restTemplate, filterMap)
.stream() .stream()
.reduce( .reduce(
new ArrayList<>(), new ArrayList<>(),
@ -208,18 +213,21 @@ public class MoodleCourseAccess extends CourseAccess {
}); });
} }
private List<CourseData> getAllQuizzes(final MoodleAPIRestTemplate restTemplate) { private List<CourseData> getAllQuizzes(
final MoodleAPIRestTemplate restTemplate,
final FilterMap filterMap) {
final List<CourseData> result = new ArrayList<>(); final List<CourseData> result = new ArrayList<>();
int page = 0; int page = 0;
List<CourseData> quizzesBatch = getQuizzesBatch(restTemplate, page); List<CourseData> quizzesBatch = getQuizzesBatch(restTemplate, filterMap, page);
result.addAll(quizzesBatch); result.addAll(quizzesBatch);
log.info("Got quiz page batch for page {} with {} items", page, quizzesBatch.size()); log.info("Got quiz page batch for page {} with {} items", page, quizzesBatch.size());
while (!quizzesBatch.isEmpty()) { while (!quizzesBatch.isEmpty()) {
page++; page++;
quizzesBatch = getQuizzesBatch(restTemplate, page); quizzesBatch = getQuizzesBatch(restTemplate, filterMap, page);
result.addAll(quizzesBatch); result.addAll(quizzesBatch);
log.info("Got quiz page batch for page {} with {} items", page, quizzesBatch.size()); log.info("Got quiz page batch for page {} with {} items", page, quizzesBatch.size());
@ -227,11 +235,20 @@ public class MoodleCourseAccess extends CourseAccess {
return result; return result;
} }
private List<CourseData> getQuizzesBatch(final MoodleAPIRestTemplate restTemplate, final int page) { private List<CourseData> getQuizzesBatch(
final MoodleAPIRestTemplate restTemplate,
final FilterMap filterMap,
final int page) {
try { try {
final long fromTime = (filterMap != null && filterMap.getQuizFromTime() != null)
? Utils.toUnixTimeInSeconds(filterMap.getQuizFromTime())
: Utils.toUnixTimeInSeconds(DateTime.now(DateTimeZone.UTC).minusYears(DEFAULT_FROM_YEARS));
// first get courses from Moodle for page // first get courses from Moodle for page
final Map<String, CourseData> courseData = new HashMap<>(); final Map<String, CourseData> courseData = new HashMap<>();
final Collection<CourseData> coursesPage = getCoursesPage(restTemplate, page, 100); final Collection<CourseData> coursesPage = getCoursesPage(restTemplate, fromTime, page, 100);
if (coursesPage.isEmpty()) { if (coursesPage.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
@ -290,12 +307,11 @@ public class MoodleCourseAccess extends CourseAccess {
private Collection<CourseData> getCoursesPage( private Collection<CourseData> getCoursesPage(
final MoodleAPIRestTemplate restTemplate, final MoodleAPIRestTemplate restTemplate,
final long startDate,
final int page, final int page,
final int size) throws JsonParseException, JsonMappingException, IOException { final int size) throws JsonParseException, JsonMappingException, IOException {
try { try {
// TODO use start date from filter
final long twoYearsAgo = DateTime.now(DateTimeZone.UTC).minusYears(3).getMillis() / 1000;
// get course ids per page // get course ids per page
final LinkedMultiValueMap<String, String> attributes = new LinkedMultiValueMap<>(); final LinkedMultiValueMap<String, String> attributes = new LinkedMultiValueMap<>();
attributes.add(MOODLE_COURSE_API_SEARCH_CRITERIA_NAME, "search"); attributes.add(MOODLE_COURSE_API_SEARCH_CRITERIA_NAME, "search");
@ -311,13 +327,14 @@ public class MoodleCourseAccess extends CourseAccess {
courseKeyPageJSON, courseKeyPageJSON,
CoursePage.class); CoursePage.class);
log.info("Got course page with: {} items", keysPage.courseKeys.size()); if (keysPage == null || keysPage.courseKeys == null || keysPage.courseKeys.isEmpty()) {
log.info("course items:\n{} items", keysPage.courseKeys); log.info("No courses found on page: {}", page);
if (keysPage.courseKeys == null || keysPage.courseKeys.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
log.info("Got course page with: {} items", keysPage.courseKeys.size());
log.info("course items:\n{} items", keysPage.courseKeys);
// get courses // get courses
final Set<String> ids = keysPage.courseKeys final Set<String> ids = keysPage.courseKeys
.stream() .stream()
@ -326,7 +343,7 @@ public class MoodleCourseAccess extends CourseAccess {
final Collection<CourseData> result = getCoursesForIds(restTemplate, ids) final Collection<CourseData> result = getCoursesForIds(restTemplate, ids)
.stream() .stream()
.filter(getCourseFilter(twoYearsAgo)) .filter(getCourseFilter(startDate))
.collect(Collectors.toList()); .collect(Collectors.toList());
log.info("After filtering {} left", result.size()); log.info("After filtering {} left", result.size());
@ -472,8 +489,12 @@ public class MoodleCourseAccess extends CourseAccess {
lmsSetup.getLmsType(), lmsSetup.getLmsType(),
courseQuizData.name, courseQuizData.name,
courseQuizData.intro, courseQuizData.intro,
Utils.toDateTimeUTCUnix(courseData.start_date), (courseQuizData.time_open != null && courseQuizData.time_open > 0)
Utils.toDateTimeUTCUnix(courseData.end_date), ? Utils.toDateTimeUTCUnix(courseQuizData.time_open)
: Utils.toDateTimeUTCUnix(courseData.start_date),
(courseQuizData.time_close != null && courseQuizData.time_close > 0)
? Utils.toDateTimeUTCUnix(courseQuizData.time_close)
: Utils.toDateTimeUTCUnix(courseData.end_date),
startURI, startURI,
additionalAttrs); additionalAttrs);
}) })
@ -614,9 +635,9 @@ public class MoodleCourseAccess extends CourseAccess {
final String full_name; final String full_name;
final String display_name; final String display_name;
final String summary; final String summary;
final Long start_date; // unix-time milliseconds UTC final Long start_date; // unix-time seconds UTC
final Long end_date; // unix-time milliseconds UTC final Long end_date; // unix-time seconds UTC
final Long time_created; // unix-time milliseconds UTC final Long time_created; // unix-time seconds UTC
final Collection<CourseQuiz> quizzes = new ArrayList<>(); final Collection<CourseQuiz> quizzes = new ArrayList<>();
@JsonCreator @JsonCreator
@ -673,7 +694,9 @@ public class MoodleCourseAccess extends CourseAccess {
final String course_module; final String course_module;
final String name; final String name;
final String intro; // HTML final String intro; // HTML
final Long time_limit; // unix-time milliseconds UTC final Long time_open;
final Long time_close;
final Long time_limit; // unix-time seconds UTC
@JsonCreator @JsonCreator
protected CourseQuiz( protected CourseQuiz(
@ -682,6 +705,8 @@ public class MoodleCourseAccess extends CourseAccess {
@JsonProperty(value = "coursemodule") final String course_module, @JsonProperty(value = "coursemodule") final String course_module,
@JsonProperty(value = "name") final String name, @JsonProperty(value = "name") final String name,
@JsonProperty(value = "intro") final String intro, @JsonProperty(value = "intro") final String intro,
@JsonProperty(value = "timeopen") final Long time_open,
@JsonProperty(value = "timeclose") final Long time_close,
@JsonProperty(value = "timelimit") final Long time_limit) { @JsonProperty(value = "timelimit") final Long time_limit) {
this.id = id; this.id = id;
@ -689,6 +714,8 @@ public class MoodleCourseAccess extends CourseAccess {
this.course_module = course_module; this.course_module = course_module;
this.name = name; this.name = name;
this.intro = intro; this.intro = intro;
this.time_open = time_open;
this.time_close = time_close;
this.time_limit = time_limit; this.time_limit = time_limit;
} }
} }

View file

@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -378,9 +379,11 @@ class MoodleRestTemplateFactory {
this.username = username; this.username = username;
this.userid = userid; this.userid = userid;
this.functions = functions this.functions = (functions != null)
? functions
.stream() .stream()
.collect(Collectors.toMap(fi -> fi.name, Function.identity())); .collect(Collectors.toMap(fi -> fi.name, Function.identity()))
: Collections.emptyMap();
} }
} }