Skip to content

Commit 08a9192

Browse files
marlonnienaberm4rl0ne
authored andcommitted
Tutorial groups: Introduce tutorial lectures (ls1intum#11552)
1 parent 61119a9 commit 08a9192

File tree

53 files changed

+959
-593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+959
-593
lines changed

src/main/java/de/tum/cit/aet/artemis/communication/repository/conversation/ChannelRepository.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ public interface ChannelRepository extends ArtemisJpaRepository<Channel, Long> {
6666
@Query("""
6767
SELECT DISTINCT channel
6868
FROM Channel channel
69-
LEFT JOIN channel.conversationParticipants cp
69+
LEFT JOIN channel.conversationParticipants conversationParticipant
70+
LEFT JOIN channel.lecture lecture
7071
WHERE channel.course.id = :courseId
71-
AND (
72-
channel.isCourseWide = TRUE
73-
OR (channel.id = cp.conversation.id AND cp.user.id = :userId))
72+
AND (channel.isCourseWide OR (channel.id = conversationParticipant.conversation.id AND conversationParticipant.user.id = :userId))
73+
AND (lecture IS NULL OR NOT lecture.isTutorialLecture)
7474
ORDER BY channel.name
7575
""")
7676
List<Channel> findChannelsOfUser(@Param("courseId") Long courseId, @Param("userId") Long userId);

src/main/java/de/tum/cit/aet/artemis/core/repository/CourseRepository.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ SELECT COUNT(c) > 0
127127
Optional<Course> findWithEagerExercisesAndExerciseDetailsAndLecturesById(long courseId);
128128

129129
@EntityGraph(type = LOAD, attributePaths = { "lectures", "lectures.lectureUnits", "lectures.attachments" })
130-
Optional<Course> findWithEagerLecturesAndLectureUnitsById(long courseId);
130+
Optional<Course> findWithLecturesAndLectureUnitsAndAttachmentsById(long courseId);
131131

132132
@EntityGraph(type = LOAD, attributePaths = { "organizations", "competencies", "prerequisites", "tutorialGroupsConfiguration", "onlineCourseConfiguration" })
133133
Optional<Course> findForUpdateById(long courseId);
@@ -430,8 +430,8 @@ default Course findByIdWithLecturesElseThrow(long courseId) {
430430
}
431431

432432
@NonNull
433-
default Course findByIdWithLecturesAndLectureUnitsElseThrow(long courseId) {
434-
return getValueElseThrow(findWithEagerLecturesAndLectureUnitsById(courseId), courseId);
433+
default Course findWithLecturesAndLectureUnitsAndAttachmentsByIdElseThrow(long courseId) {
434+
return getValueElseThrow(findWithLecturesAndLectureUnitsAndAttachmentsById(courseId), courseId);
435435
}
436436

437437
@NonNull

src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisWebhookService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public String deleteLectureFromPyrisDB(List<AttachmentVideoUnit> attachmentVideo
204204
* @return jobToken if the job was created else null
205205
*/
206206
public String addLectureUnitToPyrisDB(AttachmentVideoUnit attachmentVideoUnit) {
207-
if (lectureIngestionEnabled(attachmentVideoUnit.getLecture().getCourse())) {
207+
if (lectureIngestionEnabled(attachmentVideoUnit.getLecture().getCourse()) && !attachmentVideoUnit.getLecture().isTutorialLecture()) {
208208
if ((attachmentVideoUnit.getVideoSource() != null && !attachmentVideoUnit.getVideoSource().isEmpty()) || (attachmentVideoUnit.getAttachment() != null
209209
&& (attachmentVideoUnit.getAttachment().getAttachmentType() == AttachmentType.FILE && attachmentVideoUnit.getAttachment().getLink().endsWith(".pdf")))) {
210210
return executeLectureAdditionWebhook(processAttachmentVideoUnitForUpdate(attachmentVideoUnit), attachmentVideoUnit.getLecture().getCourse());

src/main/java/de/tum/cit/aet/artemis/lecture/domain/Lecture.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
2828
import com.fasterxml.jackson.annotation.JsonInclude;
29+
import com.fasterxml.jackson.annotation.JsonProperty;
2930

3031
import de.tum.cit.aet.artemis.core.domain.Course;
3132
import de.tum.cit.aet.artemis.core.domain.DomainObject;
@@ -61,6 +62,9 @@ public class Lecture extends DomainObject {
6162
@Column(name = "visible_date")
6263
private ZonedDateTime visibleDate;
6364

65+
@Column(name = "is_tutorial_lecture")
66+
private boolean isTutorialLecture;
67+
6468
@OneToMany(mappedBy = "lecture", cascade = CascadeType.REMOVE, orphanRemoval = true)
6569
@JsonIgnoreProperties(value = "lecture", allowSetters = true)
6670
private Set<Attachment> attachments = new HashSet<>();
@@ -313,4 +317,13 @@ public boolean isVisibleToStudents() {
313317
}
314318
return visibleDate.isBefore(ZonedDateTime.now());
315319
}
320+
321+
@JsonProperty("isTutorialLecture")
322+
public boolean isTutorialLecture() {
323+
return isTutorialLecture;
324+
}
325+
326+
public void setIsTutorialLecture(boolean isTutorialLecture) {
327+
this.isTutorialLecture = isTutorialLecture;
328+
}
316329
}

src/main/java/de/tum/cit/aet/artemis/lecture/repository/LectureRepository.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,6 @@ public interface LectureRepository extends ArtemisJpaRepository<Lecture, Long> {
3636
""")
3737
Set<Lecture> findAllByCourseId(@Param("courseId") Long courseId);
3838

39-
@Query("""
40-
SELECT lecture
41-
FROM Lecture lecture
42-
WHERE lecture.course.id = :courseId AND lecture.id IN :ids
43-
""")
44-
Set<Lecture> findAllByCourseIdWithIdIn(@Param("courseId") long courseId, @Param("ids") Set<Long> ids);
45-
4639
@Query("""
4740
SELECT new de.tum.cit.aet.artemis.core.dto.calendar.LectureCalendarEventDTO(
4841
lecture.id,
@@ -52,16 +45,15 @@ public interface LectureRepository extends ArtemisJpaRepository<Lecture, Long> {
5245
lecture.endDate
5346
)
5447
FROM Lecture lecture
55-
WHERE lecture.course.id = :courseId AND (lecture.startDate IS NOT NULL OR lecture.endDate IS NOT NULL)
48+
WHERE lecture.course.id = :courseId AND (lecture.startDate IS NOT NULL OR lecture.endDate IS NOT NULL) AND NOT lecture.isTutorialLecture
5649
""")
5750
Set<LectureCalendarEventDTO> getLectureCalendarEventDTOsForCourseId(@Param("courseId") long courseId);
5851

5952
@Query("""
6053
SELECT lecture
6154
FROM Lecture lecture
6255
LEFT JOIN FETCH lecture.lectureUnits
63-
WHERE lecture.course.id = :courseId
64-
AND (lecture.visibleDate IS NULL OR lecture.visibleDate <= :now)
56+
WHERE lecture.course.id = :courseId AND (lecture.visibleDate IS NULL OR lecture.visibleDate <= :now)
6557
""")
6658
Set<Lecture> findAllVisibleByCourseIdWithEagerLectureUnits(@Param("courseId") long courseId, @Param("now") ZonedDateTime now);
6759

@@ -81,6 +73,13 @@ public interface LectureRepository extends ArtemisJpaRepository<Lecture, Long> {
8173
""")
8274
Set<Lecture> findAllByCourseIdWithAttachments(@Param("courseId") Long courseId);
8375

76+
@Query("""
77+
SELECT lecture
78+
FROM Lecture lecture
79+
WHERE lecture.course.id = :courseId AND lecture.isTutorialLecture
80+
""")
81+
Set<Lecture> findAllTutorialLecturesByCourseId(@Param("courseId") Long courseId);
82+
8483
@Query("""
8584
SELECT lecture
8685
FROM Lecture lecture

src/main/java/de/tum/cit/aet/artemis/lecture/repository/LectureUnitMetricsRepository.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,17 @@ public interface LectureUnitMetricsRepository extends ArtemisJpaRepository<Lectu
2929
* @return the lecture unit information for all lecture units in the course
3030
*/
3131
@Query("""
32-
SELECT new de.tum.cit.aet.artemis.atlas.dto.metrics.LectureUnitInformationDTO(lu.id, lu.lecture.id, lu.lecture.title, COALESCE(lu.name, a.name), lu.releaseDate, TYPE(lu))
33-
FROM LectureUnit lu
34-
LEFT JOIN Attachment a ON a.attachmentVideoUnit.id = lu.id
35-
WHERE lu.lecture.course.id = :courseId
32+
SELECT new de.tum.cit.aet.artemis.atlas.dto.metrics.LectureUnitInformationDTO(
33+
lectureUnit.id,
34+
lectureUnit.lecture.id,
35+
lectureUnit.lecture.title,
36+
COALESCE(lectureUnit.name, attachment.name),
37+
lectureUnit.releaseDate,
38+
TYPE(lectureUnit)
39+
)
40+
FROM LectureUnit lectureUnit
41+
LEFT JOIN Attachment attachment ON attachment.attachmentVideoUnit.id = lectureUnit.id
42+
WHERE lectureUnit.lecture.course.id = :courseId
3643
""")
3744
Set<LectureUnitInformationDTO> findAllLectureUnitInformationByCourseId(@Param("courseId") long courseId);
3845

src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,24 @@ public ResponseEntity<Set<Lecture>> getLecturesForCourse(@PathVariable Long cour
234234
return ResponseEntity.ok().body(lectures);
235235
}
236236

237+
/**
238+
* GET /courses/:courseId/tutorial-lectures : get all the tutorial-lectures of a course
239+
*
240+
* @param courseId the courseId of the course for which the lectures should be returned
241+
* @return the ResponseEntity with status 200 (OK) and the list of lectures in body
242+
*/
243+
@GetMapping("courses/{courseId}/tutorial-lectures")
244+
@EnforceAtLeastEditor
245+
public ResponseEntity<Set<Lecture>> getTutorialLecturesForCourse(@PathVariable Long courseId) {
246+
log.debug("REST request to get all Lectures for the course with id : {}", courseId);
247+
248+
Course course = courseRepository.findByIdElseThrow(courseId);
249+
authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, course, null);
250+
251+
Set<Lecture> lectures = lectureRepository.findAllTutorialLecturesByCourseId(courseId);
252+
return ResponseEntity.ok().body(lectures);
253+
}
254+
237255
/**
238256
* GET /courses/:courseId/lectures : get all the lectures of a course with their lecture units and slides
239257
*
@@ -383,7 +401,7 @@ public ResponseEntity<Lecture> importLecture(@PathVariable long sourceLectureId,
383401
@PostMapping("courses/{courseId}/ingest")
384402
@EnforceAtLeastInstructorInCourse
385403
public ResponseEntity<Void> ingestLectures(@PathVariable Long courseId, @RequestParam(required = false) Optional<Long> lectureId) {
386-
Course course = courseRepository.findByIdWithLecturesAndLectureUnitsElseThrow(courseId);
404+
Course course = courseRepository.findWithLecturesAndLectureUnitsAndAttachmentsByIdElseThrow(courseId);
387405
authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.INSTRUCTOR, course, null);
388406
if (lectureId.isPresent()) {
389407
Optional<Lecture> lectureToIngest = course.getLectures().stream().filter(lecture -> lecture.getId().equals(lectureId.get())).findFirst();

src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureUnitResource.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ public ResponseEntity<Void> ingestLectureUnit(@PathVariable long lectureId, @Pat
223223
if (lectureUnit.getLecture().getId() != lectureId) {
224224
throw new BadRequestAlertException("Requested lecture unit is not part of the specified lecture", ENTITY_NAME, "lectureIdMismatch");
225225
}
226+
if (lectureUnit.getLecture().isTutorialLecture()) {
227+
throw new BadRequestAlertException("Units of tutorial lectures can not be ingested", ENTITY_NAME, "tutorialLectureIngestion");
228+
}
226229
if (!(lectureUnit instanceof AttachmentVideoUnit)) {
227230
throw new BadRequestAlertException("Only attachment video units can be ingested into Pyris", ENTITY_NAME, "invalidLectureUnitType");
228231
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
5+
6+
<changeSet id="20251024184500-add-is-tutorial-lecture-column" author="marlonnienaber">
7+
<addColumn tableName="lecture">
8+
<column name="is_tutorial_lecture" type="boolean" defaultValueBoolean="false">
9+
<constraints nullable="false"/>
10+
</column>
11+
</addColumn>
12+
13+
<rollback>
14+
<dropColumn tableName="lecture" columnName="is_tutorial_lecture"/>
15+
</rollback>
16+
</changeSet>
17+
18+
</databaseChangeLog>

src/main/resources/config/liquibase/master.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@
5050
<include file="classpath:config/liquibase/changelog/20250920163252_changelog.xml" relativeToChangelogFile="false"/>
5151
<include file="classpath:config/liquibase/changelog/20250930145942_changelog.xml" relativeToChangelogFile="false"/>
5252
<include file="classpath:config/liquibase/changelog/20251006234500_changelog.xml" relativeToChangelogFile="false"/>
53-
<include file="classpath:config/liquibase/changelog/20251017200800_changelog.xml" relativeToChangelogFile="false"/>
5453
<include file="classpath:config/liquibase/changelog/20251012122800_changelog.xml" relativeToChangelogFile="false"/>
55-
<include file="classpath:config/liquibase/changelog/20251023184348_changelog.xml" relativeToChangelogFile="false"/>
54+
<include file="classpath:config/liquibase/changelog/20251017200800_changelog.xml" relativeToChangelogFile="false"/>
5655
<include file="classpath:config/liquibase/changelog/20251020175436_changelog.xml" relativeToChangelogFile="false"/>
56+
<include file="classpath:config/liquibase/changelog/20251023184348_changelog.xml" relativeToChangelogFile="false"/>
57+
<include file="classpath:config/liquibase/changelog/20251024184500_changelog.xml" relativeToChangelogFile="false"/>
5758
<include file="classpath:config/liquibase/changelog/20251106150715_changelog.xml" relativeToChangelogFile="false"/>
5859
<include file="classpath:config/liquibase/changelog/20251113185215_changelog.xml" relativeToChangelogFile="false"/>
5960
<include file="classpath:config/liquibase/changelog/20251118134547_changelog.xml" relativeToChangelogFile="false"/>

0 commit comments

Comments
 (0)