Skip to content

Commit 114f045

Browse files
authored
Merge branch 'main' into dependabot/maven/org.seleniumhq.selenium-selenium-java-4.34.0
2 parents 9da23df + 8a7b477 commit 114f045

File tree

10 files changed

+222
-103
lines changed

10 files changed

+222
-103
lines changed

pom-dependency-tree.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ai.elimu:webapp:war:2.6.124-SNAPSHOT
1+
ai.elimu:webapp:war:2.6.129-SNAPSHOT
22
+- ai.elimu:model:jar:model-2.0.120:compile
33
| \- com.google.code.gson:gson:jar:2.13.1:compile
44
| \- com.google.errorprone:error_prone_annotations:jar:2.38.0:compile

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>ai.elimu</groupId>
55
<artifactId>webapp</artifactId>
66
<packaging>war</packaging>
7-
<version>2.6.125-SNAPSHOT</version>
7+
<version>2.6.131-SNAPSHOT</version>
88

99
<properties>
1010
<java.version>17</java.version>

src/main/java/ai/elimu/tasks/WordUsageCountScheduler.java

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,37 @@
2323
@Slf4j
2424
public class WordUsageCountScheduler {
2525

26-
private final WordDao wordDao;
27-
28-
private final StoryBookParagraphDao storyBookParagraphDao;
29-
30-
@Scheduled(cron = "00 00 06 * * *") // At 06:00 every day
31-
public synchronized void execute() {
32-
log.info("execute");
33-
34-
try {
35-
// <ID, frequency>
36-
Map<Long, Integer> frequencyMap = new HashMap<>();
37-
38-
// Calculate the frequency of each word
39-
for (StoryBookParagraph storyBookParagraph : storyBookParagraphDao.readAll()) {
40-
for (Word word : storyBookParagraph.getWords()) {
41-
frequencyMap.put(word.getId(), frequencyMap.getOrDefault(word.getId(), 0) + 1);
26+
private final WordDao wordDao;
27+
28+
private final StoryBookParagraphDao storyBookParagraphDao;
29+
30+
@Scheduled(cron = "00 00 06 * * *") // At 06:00 every day
31+
public synchronized void execute() {
32+
log.info("execute");
33+
34+
try {
35+
// <ID, frequency>
36+
Map<Long, Integer> frequencyMap = new HashMap<>();
37+
38+
// Calculate the frequency of each word
39+
for (StoryBookParagraph storyBookParagraph : storyBookParagraphDao.readAll()) {
40+
for (Word word : storyBookParagraph.getWords()) {
41+
if (word != null) {
42+
frequencyMap.put(word.getId(), frequencyMap.getOrDefault(word.getId(), 0) + 1);
43+
}
44+
}
45+
}
46+
47+
// Update the values previously stored in the database
48+
for (Word word : wordDao.readAll()) {
49+
word.setUsageCount(frequencyMap.getOrDefault(word.getId(), 0));
50+
wordDao.update(word);
51+
}
52+
} catch (Exception e) {
53+
log.error("Error in scheduled task:", e);
54+
DiscordHelper.postToChannel(Channel.CONTENT, "Error in " + getClass().getSimpleName() + ":`" + e.getClass() + ": " + e.getMessage() + "`");
4255
}
43-
}
44-
45-
// Update the values previously stored in the database
46-
for (Word word : wordDao.readAll()) {
47-
word.setUsageCount(frequencyMap.getOrDefault(word.getId(), 0));
48-
wordDao.update(word);
49-
}
50-
} catch (Exception e) {
51-
log.error("Error in scheduled task:", e);
52-
DiscordHelper.postToChannel(Channel.CONTENT, "Error in " + getClass().getSimpleName() + ":`" + e.getClass() + ": " + e.getMessage() + "`");
53-
}
5456

55-
log.info("execute complete");
56-
}
57+
log.info("execute complete");
58+
}
5759
}

src/main/java/ai/elimu/web/content/storybook/chapter/StoryBookChapterDeleteController.java

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
package ai.elimu.web.content.storybook.chapter;
22

3-
import ai.elimu.dao.ImageContributionEventDao;
4-
import ai.elimu.dao.ImageDao;
53
import ai.elimu.dao.StoryBookChapterDao;
64
import ai.elimu.dao.StoryBookContributionEventDao;
75
import ai.elimu.dao.StoryBookDao;
86
import ai.elimu.dao.StoryBookParagraphDao;
97
import ai.elimu.entity.content.StoryBook;
108
import ai.elimu.entity.content.StoryBookChapter;
119
import ai.elimu.entity.content.StoryBookParagraph;
12-
import ai.elimu.entity.content.multimedia.Image;
1310
import ai.elimu.entity.contributor.Contributor;
14-
import ai.elimu.entity.contributor.ImageContributionEvent;
1511
import ai.elimu.entity.contributor.StoryBookContributionEvent;
1612
import ai.elimu.entity.enums.PeerReviewStatus;
1713
import ai.elimu.entity.enums.Role;
@@ -40,9 +36,6 @@ public class StoryBookChapterDeleteController {
4036
private final StoryBookParagraphDao storyBookParagraphDao;
4137
private final StoryBookContributionEventDao storyBookContributionEventDao;
4238

43-
private final ImageDao imageDao;
44-
private final ImageContributionEventDao imageContributionEventDao;
45-
4639
private final StoryBooksJsonService storyBooksJsonService;
4740

4841
@GetMapping
@@ -72,41 +65,35 @@ public String handleRequest(HttpSession session, @PathVariable Long storyBookId,
7265
log.info("Deleting StoryBookChapter with ID " + storyBookChapterToBeDeleted.getId());
7366
storyBookChapterDao.delete(storyBookChapterToBeDeleted);
7467

75-
// Delete the chapter's image (if any)
76-
Image chapterImage = storyBookChapterToBeDeleted.getImage();
77-
log.info("chapterImage: " + chapterImage);
78-
if (chapterImage != null) {
79-
// Remove content labels
80-
chapterImage.setLiteracySkills(null);
81-
chapterImage.setNumeracySkills(null);
82-
chapterImage.setLetters(null);
83-
chapterImage.setNumbers(null);
84-
chapterImage.setWords(null);
85-
imageDao.update(chapterImage);
86-
87-
// Remove contribution events
88-
for (ImageContributionEvent imageContributionEvent : imageContributionEventDao.readAll(chapterImage)) {
89-
log.warn("Deleting ImageContributionEvent from the database");
90-
imageContributionEventDao.delete(imageContributionEvent);
91-
}
92-
93-
log.warn("Deleting the chapter image from the database");
94-
imageDao.delete(chapterImage);
95-
}
96-
9768
// Update the StoryBook's metadata
9869
StoryBook storyBook = storyBookChapterToBeDeleted.getStoryBook();
9970
storyBook.setRevisionNumber(storyBook.getRevisionNumber() + 1);
10071
storyBook.setPeerReviewStatus(PeerReviewStatus.PENDING);
10172
storyBookDao.update(storyBook);
10273

74+
// Update the sorting order of the remaining chapters
75+
List<StoryBookChapter> storyBookChapters = storyBookChapterDao.readAll(storyBook);
76+
log.info("storyBookChapters.size(): " + storyBookChapters.size());
77+
for (StoryBookChapter storyBookChapter : storyBookChapters) {
78+
log.info("storyBookChapter.getId(): " + storyBookChapter.getId() + ", storyBookChapter.getSortOrder(): " + storyBookChapter.getSortOrder());
79+
if (storyBookChapter.getSortOrder() > storyBookChapterToBeDeleted.getSortOrder()) {
80+
// Reduce sort order by 1
81+
storyBookChapter.setSortOrder(storyBookChapter.getSortOrder() - 1);
82+
storyBookChapterDao.update(storyBookChapter);
83+
log.info("storyBookChapter.getSortOrder() (after update): " + storyBookChapter.getSortOrder());
84+
}
85+
}
86+
87+
// Refresh the REST API cache
88+
storyBooksJsonService.refreshStoryBooksJSONArray();
89+
10390
// Store contribution event
10491
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
10592
storyBookContributionEvent.setContributor(contributor);
10693
storyBookContributionEvent.setTimestamp(Calendar.getInstance());
10794
storyBookContributionEvent.setStoryBook(storyBook);
10895
storyBookContributionEvent.setRevisionNumber(storyBook.getRevisionNumber());
109-
storyBookContributionEvent.setComment("Deleted storybook chapter " + (storyBookChapterToBeDeleted.getSortOrder() + 1) + " (🤖 auto-generated comment)");
96+
storyBookContributionEvent.setComment("Deleted storybook chapter " + (storyBookChapterToBeDeleted.getSortOrder() + 1) + "/" + storyBookChapters.size() + " (🤖 auto-generated comment)");
11097
storyBookContributionEventDao.create(storyBookContributionEvent);
11198

11299
String contentUrl = DomainHelper.getBaseUrl() + "/content/storybook/edit/" + storyBook.getId();
@@ -123,22 +110,6 @@ public String handleRequest(HttpSession session, @PathVariable Long storyBookId,
123110
embedThumbnailUrl
124111
);
125112

126-
// Update the sorting order of the remaining chapters
127-
List<StoryBookChapter> storyBookChapters = storyBookChapterDao.readAll(storyBook);
128-
log.info("storyBookChapters.size(): " + storyBookChapters.size());
129-
for (StoryBookChapter storyBookChapter : storyBookChapters) {
130-
log.info("storyBookChapter.getId(): " + storyBookChapter.getId() + ", storyBookChapter.getSortOrder(): " + storyBookChapter.getSortOrder());
131-
if (storyBookChapter.getSortOrder() > storyBookChapterToBeDeleted.getSortOrder()) {
132-
// Reduce sort order by 1
133-
storyBookChapter.setSortOrder(storyBookChapter.getSortOrder() - 1);
134-
storyBookChapterDao.update(storyBookChapter);
135-
log.info("storyBookChapter.getSortOrder() (after update): " + storyBookChapter.getSortOrder());
136-
}
137-
}
138-
139-
// Refresh the REST API cache
140-
storyBooksJsonService.refreshStoryBooksJSONArray();
141-
142113
return "redirect:/content/storybook/edit/" + storyBookId;
143114
}
144115
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package ai.elimu.web.content.storybook.chapter;
2+
3+
import ai.elimu.dao.ImageDao;
4+
import ai.elimu.dao.StoryBookChapterDao;
5+
import ai.elimu.dao.StoryBookContributionEventDao;
6+
import ai.elimu.dao.StoryBookDao;
7+
import ai.elimu.entity.content.StoryBook;
8+
import ai.elimu.entity.content.StoryBookChapter;
9+
import ai.elimu.entity.content.multimedia.Image;
10+
import ai.elimu.entity.contributor.Contributor;
11+
import ai.elimu.entity.contributor.StoryBookContributionEvent;
12+
import ai.elimu.entity.enums.PeerReviewStatus;
13+
import ai.elimu.rest.v2.service.StoryBooksJsonService;
14+
import ai.elimu.util.DiscordHelper;
15+
import ai.elimu.util.DiscordHelper.Channel;
16+
import ai.elimu.util.DomainHelper;
17+
import jakarta.servlet.http.HttpSession;
18+
import jakarta.validation.Valid;
19+
import lombok.RequiredArgsConstructor;
20+
import lombok.extern.slf4j.Slf4j;
21+
22+
import java.util.Calendar;
23+
import java.util.List;
24+
25+
import org.springframework.stereotype.Controller;
26+
import org.springframework.ui.Model;
27+
import org.springframework.validation.BindingResult;
28+
import org.springframework.web.bind.annotation.GetMapping;
29+
import org.springframework.web.bind.annotation.PathVariable;
30+
import org.springframework.web.bind.annotation.PostMapping;
31+
import org.springframework.web.bind.annotation.RequestMapping;
32+
33+
@Controller
34+
@RequestMapping("/content/storybook/edit/{storyBookId}/chapter/edit/{id}")
35+
@RequiredArgsConstructor
36+
@Slf4j
37+
public class StoryBookChapterEditController {
38+
39+
private final StoryBookDao storyBookDao;
40+
private final StoryBookChapterDao storyBookChapterDao;
41+
private final StoryBookContributionEventDao storyBookContributionEventDao;
42+
43+
private final ImageDao imageDao;
44+
45+
private final StoryBooksJsonService storyBooksJsonService;
46+
47+
@GetMapping
48+
public String handleRequest(Model model, @PathVariable Long storyBookId, @PathVariable Long id) {
49+
log.info("handleRequest");
50+
51+
StoryBookChapter storyBookChapter = storyBookChapterDao.read(id);
52+
model.addAttribute("storyBookChapter", storyBookChapter);
53+
54+
List<Image> images = imageDao.readAllOrdered();
55+
model.addAttribute("images", images);
56+
57+
return "content/storybook/chapter/edit";
58+
}
59+
60+
@PostMapping
61+
public String handleSubmit(
62+
HttpSession session,
63+
@PathVariable Long storyBookId,
64+
@Valid StoryBookChapter storyBookChapter,
65+
BindingResult result,
66+
Model model
67+
) {
68+
log.info("handleSubmit");
69+
70+
Contributor contributor = (Contributor) session.getAttribute("contributor");
71+
72+
if (result.hasErrors()) {
73+
model.addAttribute("storyBookChapter", storyBookChapter);
74+
75+
List<Image> images = imageDao.readAllOrdered();
76+
model.addAttribute("images", images);
77+
78+
return "content/storybook/chapter/edit";
79+
} else {
80+
storyBookChapterDao.update(storyBookChapter);
81+
82+
// Update the storybook's metadata
83+
StoryBook storyBook = storyBookChapter.getStoryBook();
84+
storyBook.setRevisionNumber(storyBook.getRevisionNumber() + 1);
85+
storyBook.setPeerReviewStatus(PeerReviewStatus.PENDING);
86+
storyBookDao.update(storyBook);
87+
88+
// Refresh the REST API cache
89+
storyBooksJsonService.refreshStoryBooksJSONArray();
90+
91+
// Store contribution event
92+
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
93+
storyBookContributionEvent.setContributor(contributor);
94+
storyBookContributionEvent.setTimestamp(Calendar.getInstance());
95+
storyBookContributionEvent.setStoryBook(storyBook);
96+
storyBookContributionEvent.setRevisionNumber(storyBook.getRevisionNumber());
97+
storyBookContributionEvent.setComment("Edited storybook chapter " + (storyBookChapter.getSortOrder() + 1) + " (🤖 auto-generated comment)");
98+
storyBookContributionEventDao.create(storyBookContributionEvent);
99+
100+
DiscordHelper.postToChannel(Channel.CONTENT, "Storybook chapter edited: " + DomainHelper.getBaseUrl() + "/content/storybook/edit/" + storyBook.getId() + "#ch-id-" + storyBookChapter.getId());
101+
102+
return "redirect:/content/storybook/edit/" + storyBookId + "#ch-id-" + storyBookChapter.getId();
103+
}
104+
}
105+
}

src/main/java/ai/elimu/web/content/storybook/paragraph/StoryBookParagraphDeleteController.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,28 @@ public String handleRequest(HttpSession session, @PathVariable Long id) {
5555
log.info("Deleting StoryBookParagraph with ID " + storyBookParagraphToBeDeleted.getId());
5656
storyBookParagraphDao.delete(storyBookParagraphToBeDeleted);
5757

58+
// Update the sorting order of the remaining paragraphs
59+
List<StoryBookParagraph> storyBookParagraphs = storyBookParagraphDao.readAll(storyBookParagraphToBeDeleted.getStoryBookChapter());
60+
log.info("storyBookParagraphs.size(): " + storyBookParagraphs.size());
61+
for (StoryBookParagraph storyBookParagraph : storyBookParagraphs) {
62+
log.info("storyBookParagraph.getId(): " + storyBookParagraph.getId() + ", storyBookParagraph.getSortOrder(): " + storyBookParagraph.getSortOrder());
63+
if (storyBookParagraph.getSortOrder() > storyBookParagraphToBeDeleted.getSortOrder()) {
64+
// Reduce sort order by 1
65+
storyBookParagraph.setSortOrder(storyBookParagraph.getSortOrder() - 1);
66+
storyBookParagraphDao.update(storyBookParagraph);
67+
log.info("storyBookParagraph.getSortOrder() (after update): " + storyBookParagraph.getSortOrder());
68+
}
69+
}
70+
5871
// Update the storybook's metadata
5972
StoryBook storyBook = storyBookParagraphToBeDeleted.getStoryBookChapter().getStoryBook();
6073
storyBook.setRevisionNumber(storyBook.getRevisionNumber() + 1);
6174
storyBook.setPeerReviewStatus(PeerReviewStatus.PENDING);
6275
storyBookDao.update(storyBook);
6376

77+
// Refresh the REST API cache
78+
storyBooksJsonService.refreshStoryBooksJSONArray();
79+
6480
// Store contribution event
6581
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
6682
storyBookContributionEvent.setContributor(contributor);
@@ -85,22 +101,6 @@ public String handleRequest(HttpSession session, @PathVariable Long id) {
85101
embedThumbnailUrl
86102
);
87103

88-
// Update the sorting order of the remaining paragraphs
89-
List<StoryBookParagraph> storyBookParagraphs = storyBookParagraphDao.readAll(storyBookParagraphToBeDeleted.getStoryBookChapter());
90-
log.info("storyBookParagraphs.size(): " + storyBookParagraphs.size());
91-
for (StoryBookParagraph storyBookParagraph : storyBookParagraphs) {
92-
log.info("storyBookParagraph.getId(): " + storyBookParagraph.getId() + ", storyBookParagraph.getSortOrder(): " + storyBookParagraph.getSortOrder());
93-
if (storyBookParagraph.getSortOrder() > storyBookParagraphToBeDeleted.getSortOrder()) {
94-
// Reduce sort order by 1
95-
storyBookParagraph.setSortOrder(storyBookParagraph.getSortOrder() - 1);
96-
storyBookParagraphDao.update(storyBookParagraph);
97-
log.info("storyBookParagraph.getSortOrder() (after update): " + storyBookParagraph.getSortOrder());
98-
}
99-
}
100-
101-
// Refresh the REST API cache
102-
storyBooksJsonService.refreshStoryBooksJSONArray();
103-
104104
return "redirect:/content/storybook/edit/" + storyBook.getId() + "#ch-id-" + storyBookParagraphToBeDeleted.getStoryBookChapter().getId();
105105
}
106106
}

src/main/java/ai/elimu/web/content/storybook/paragraph/StoryBookParagraphEditController.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,8 @@
3434
public class StoryBookParagraphEditController {
3535

3636
private final StoryBookDao storyBookDao;
37-
38-
private final StoryBookContributionEventDao storyBookContributionEventDao;
39-
4037
private final StoryBookParagraphDao storyBookParagraphDao;
38+
private final StoryBookContributionEventDao storyBookContributionEventDao;
4139

4240
private final StoryBooksJsonService storyBooksJsonService;
4341

@@ -80,6 +78,9 @@ public String handleSubmit(
8078
storyBook.setPeerReviewStatus(PeerReviewStatus.PENDING);
8179
storyBookDao.update(storyBook);
8280

81+
// Refresh the REST API cache
82+
storyBooksJsonService.refreshStoryBooksJSONArray();
83+
8384
// Store contribution event
8485
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
8586
storyBookContributionEvent.setContributor(contributor);
@@ -107,9 +108,6 @@ public String handleSubmit(
107108
embedThumbnailUrl
108109
);
109110

110-
// Refresh the REST API cache
111-
storyBooksJsonService.refreshStoryBooksJSONArray();
112-
113111
return "redirect:/content/storybook/edit/" +
114112
storyBookParagraph.getStoryBookChapter().getStoryBook().getId() +
115113
"#ch-id-" + storyBookParagraph.getStoryBookChapter().getId();

0 commit comments

Comments
 (0)