Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lectures: Add hide/show functionality to PDF Preview Component #9667

Open
wants to merge 188 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 178 commits
Commits
Show all changes
188 commits
Select commit Hold shift + click to select a range
76e86e1
Open a PDF Preview page for every attachment file
eceeeren Jul 7, 2024
d96f276
Add breadcrumb & show pdf file preview as images
eceeeren Jul 7, 2024
8077b0d
Render files with PDFJS
eceeeren Jul 13, 2024
5ef93eb
Enlarge PDF page content
eceeeren Jul 15, 2024
e36d0aa
Show page numbers when hovered
eceeeren Jul 15, 2024
d88a85b
Clean up the code & styling
eceeeren Jul 15, 2024
56a3abe
Add PDF Preview to correct routing
eceeeren Jul 15, 2024
f691d00
Close PDF preview when clicked outside
eceeeren Jul 21, 2024
5df2075
Add arrows to change pages
eceeeren Jul 21, 2024
6bb13fb
Add functionality to the arrows
eceeeren Jul 21, 2024
bbdd4c2
Add page indicator
eceeeren Jul 21, 2024
ebe6d04
Add JSDoc comments
eceeeren Jul 23, 2024
2bd8316
Translation & colors
eceeeren Jul 23, 2024
e415509
Git merge 'develop' into 'feature/course/attachment-pdf-preview'
eceeeren Jul 24, 2024
48018aa
Install pdf.js
eceeeren Jul 24, 2024
0de1150
Fix build error
eceeeren Jul 24, 2024
c9d9c29
Change file path
eceeeren Jul 24, 2024
9f612e7
Update getAttachmentFile method
eceeeren Jul 24, 2024
2def08c
Update PDF Preview button & add it to Lecture Units
eceeeren Jul 24, 2024
8ed16f6
Fix linting errors
eceeeren Jul 27, 2024
66e4bc4
Merge 'develop' into 'feature/course/attachment-pdf-preview'
eceeeren Jul 27, 2024
a0871fc
Take back unnecessary changes
eceeeren Jul 27, 2024
6f09ccb
Add mapping comment
eceeeren Jul 27, 2024
966fe50
Fix error handling
eceeeren Jul 29, 2024
7fdf2f4
Client tests are added
eceeeren Jul 29, 2024
bee424e
Fix failing server test
eceeeren Jul 29, 2024
60d8414
Merge branch 'develop' into feature/course/attachment-pdf-preview
eceeeren Jul 29, 2024
38ce818
Fix typos
eceeeren Jul 29, 2024
8bd6db7
Fix alertService problem
eceeeren Aug 3, 2024
be23c0d
Fix PDF.js worker initialization
eceeeren Aug 4, 2024
52bf703
Fix responsivity of enlarged view
eceeeren Aug 4, 2024
1b3d900
Git merge 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 5, 2024
9f7efab
Fix enlarged view position
eceeeren Aug 5, 2024
175af72
Small fixes
eceeeren Aug 7, 2024
8b0d54e
Fix failing client tests
eceeeren Aug 7, 2024
e5d4110
Merge branch 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 7, 2024
39e8076
viewButtonAvailable check is updated
eceeeren Aug 7, 2024
b4c36b3
Merge remote-tracking branch 'origin/feature/course/attachment-pdf-pr…
eceeeren Aug 7, 2024
16e0cee
Fix LectureAttachments client tests
eceeeren Aug 7, 2024
7b80bd0
Add client tests for View Button
eceeeren Aug 7, 2024
4d14647
Fix FileSource method names
eceeeren Aug 7, 2024
47990e1
Worker tryout
eceeeren Aug 7, 2024
b16581f
Fix Mime Type error
eceeeren Aug 7, 2024
5fcfbfe
Fix PDF Worker
eceeeren Aug 7, 2024
493dba8
Fix MIME Type Error 2
eceeeren Aug 8, 2024
4800301
Fix MIME Type Error 3
eceeeren Aug 8, 2024
a37c978
Merge remote-tracking branch 'origin/feature/course/attachment-pdf-pr…
eceeeren Aug 8, 2024
b451431
Set fake worker back
eceeeren Aug 8, 2024
4d2d1c9
Fix undefined lecture id after saving the attachment
eceeeren Aug 9, 2024
3c54b06
Change get method permissions
eceeeren Aug 9, 2024
ec127b7
Merge branch 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 9, 2024
9a9dfd5
Resolved changes
eceeeren Aug 11, 2024
f63ac22
Merge remote-tracking branch 'origin/feature/course/attachment-pdf-pr…
eceeeren Aug 11, 2024
a2f8f88
Fix client tests
eceeeren Aug 11, 2024
eb9122f
Merge 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 11, 2024
984bcdf
Resolved changes 2
eceeeren Aug 14, 2024
5f9e0c7
Fix error text
eceeeren Aug 14, 2024
5d3e469
Merge 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 14, 2024
240e768
CodeRabbitAI changes
eceeeren Aug 14, 2024
63764d2
Confirmed changes
eceeeren Aug 18, 2024
1affbf6
Fix compilation errors
eceeeren Aug 18, 2024
60ea19f
Fix error handling & add new test cases
eceeeren Aug 18, 2024
4e24d1c
Mak adjustCanvasSize public
eceeeren Aug 18, 2024
24536b3
Fix client tests
eceeeren Aug 18, 2024
d9b47f1
Fix client tests 2
eceeeren Aug 18, 2024
2d5fa81
Merge 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 18, 2024
547be9a
Increase client test coverage, fix typos
eceeeren Aug 18, 2024
6c608b5
Fix test case typo
eceeeren Aug 18, 2024
4c0b38b
Resolved changes
eceeeren Aug 18, 2024
861a179
Add tests for closeIfOutside
eceeeren Aug 20, 2024
f5b48c8
Remove redundant type
eceeeren Aug 20, 2024
387c19b
Merge branch 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 20, 2024
c6978ac
Divide updateEnlargedCanvas into sub functions & increase client test…
eceeeren Aug 20, 2024
5c70fb9
Merge remote-tracking branch 'origin/feature/course/attachment-pdf-pr…
eceeeren Aug 20, 2024
f3683ad
Fix client test
eceeeren Aug 21, 2024
8889a51
Add client tests to AttachmentService and AttachmentUnitService
eceeeren Aug 22, 2024
2fba2b3
Approved changes
eceeeren Aug 22, 2024
4014e51
Fix client tests
eceeeren Aug 22, 2024
a0babdb
Increase client test coverage
eceeeren Aug 24, 2024
5ed8d67
Add server tests for the endpoints
eceeeren Aug 26, 2024
6177c2f
Merge 'develop' into feature/course/attachment-pdf-preview
eceeeren Aug 26, 2024
4e0fba6
Fix client test
eceeeren Aug 26, 2024
f37e105
Add ArtemisSharedModule to PDFPreviewComponent for the translation fe…
eceeeren Aug 28, 2024
111b022
Add TranslationService to the client tests
eceeeren Aug 28, 2024
5191d7c
Add checkboxes and delete button
eceeeren Sep 1, 2024
445c209
Add merge file button
eceeeren Sep 1, 2024
00071db
Fix display enlarged canvas view
eceeeren Sep 1, 2024
ddac253
Update delete & append buttons
eceeeren Sep 7, 2024
cab10d5
Merge 'develop' into feature/course/attachment-pdf-editing
eceeeren Sep 7, 2024
eb163bd
Update page IDs upon delete & merge pdf
eceeeren Sep 8, 2024
34b716f
Clean up the code and update JSDoc
eceeeren Sep 8, 2024
7deeb4a
Save & cancel buttons are added and styling is fixed
eceeeren Sep 8, 2024
725ff4f
Generate PDF from the changed structure
eceeeren Sep 8, 2024
472b0e1
Updating capability on Save
eceeeren Sep 8, 2024
d13db53
Fix view button styling
eceeeren Sep 8, 2024
1748887
Update Cancel button
eceeeren Sep 8, 2024
f2861c3
Update translations
eceeeren Sep 12, 2024
324e812
Fix client tests based on changes
eceeeren Sep 12, 2024
926f75a
Add client tests
eceeeren Sep 12, 2024
09468ae
Merge 'develop' into feature/course/attachment-pdf-editing
eceeeren Sep 12, 2024
6099d70
Add fixes for edge cases
eceeeren Sep 15, 2024
ce822f4
Add Fabric to reduce PDF size
eceeeren Sep 15, 2024
f4d30fb
Change pdf editing method to pdf-lib
eceeeren Sep 29, 2024
e140552
RabbitAI changes
eceeeren Sep 29, 2024
356d45a
Add translations
eceeeren Sep 29, 2024
92fb4ea
Fix client tests
eceeeren Sep 30, 2024
2aac23f
Increase client test coverage
eceeeren Sep 30, 2024
82a7634
RabbitAI changes
eceeeren Sep 30, 2024
6f64794
Merge 'develop' into feature/course/attachment-pdf-editing
eceeeren Sep 30, 2024
5b10143
Update delete pages question
eceeeren Oct 3, 2024
dc3e974
Change Append File to Append PDF
eceeeren Oct 3, 2024
0ac2434
Return to previous page after saving
eceeeren Oct 4, 2024
8de6f31
Delete attachment when all pages are deleted
eceeeren Oct 4, 2024
94ee2af
Disable Save if file is not changed
eceeeren Oct 4, 2024
188d9ed
Lazy load PDF Preview Component
eceeeren Oct 15, 2024
a94855a
Merge 'develop' into feature/course/attachment-pdf-editing
eceeeren Oct 15, 2024
aeaabfd
Fix client tests & RabbitAI changes
eceeeren Oct 15, 2024
8f514b5
Adjust PDF container size for vertical PDFs
eceeeren Oct 15, 2024
0112516
Adjust PDF container size dynamically
eceeeren Oct 15, 2024
78877f6
Adjust PDF container size dynamically -bug fix
eceeeren Oct 17, 2024
525f51f
Fix client test
eceeeren Oct 17, 2024
6f7524e
Merge branch 'develop' into feature/course/attachment-pdf-editing
eceeeren Oct 17, 2024
156d966
Update src/main/webapp/i18n/de/lecture.json
eceeeren Oct 17, 2024
5c12f1b
Fix translation
eceeeren Oct 18, 2024
3f5c6d2
Merge remote-tracking branch 'origin/feature/course/attachment-pdf-ed…
eceeeren Oct 18, 2024
675dfb7
Merge branch 'develop' into feature/course/attachment-pdf-editing
eceeeren Oct 18, 2024
102fb06
Merge 'develop' into feature/course/attachment-pdf-editing
eceeeren Oct 20, 2024
ed1300e
Update the code based on new Angular notations
eceeeren Oct 20, 2024
9cb3a82
Fix client tests
eceeeren Oct 20, 2024
b63f49c
Bug fix
eceeeren Oct 20, 2024
40a1320
Add required viewChilds
eceeeren Oct 21, 2024
989e014
Fix ! notations
eceeeren Oct 21, 2024
024fc4f
Create PDFPreviewThumbnailGrid and PDFPreviewEnlargedCanvas component…
eceeeren Oct 25, 2024
b247d44
Fix delete, merge and enlargedCanvas
eceeeren Oct 27, 2024
1681230
Fix page navigation and close
eceeeren Oct 27, 2024
1238d4a
Fix append file & remove redundant parts
eceeeren Oct 27, 2024
7aba007
Create decomposition tests
eceeeren Oct 28, 2024
02d1407
Bug fix with deep copy
eceeeren Oct 29, 2024
96d1434
Merge 'develop' into feature/course/attachment-pdf-editing
eceeeren Nov 2, 2024
814079f
Add loading spinner for enlarged canvas
eceeeren Nov 2, 2024
ad9e849
Merge branch 'feature/course/attachment-pdf-editing' into feature/lec…
eceeeren Nov 2, 2024
f1bfb5f
Fix client test
eceeeren Nov 2, 2024
bcb2ab6
Remove redundant canvas positioning
eceeeren Nov 2, 2024
0b5d7ca
Client test clean up
eceeeren Nov 2, 2024
57ddcd3
Add button checks
eceeeren Nov 2, 2024
4f87cb3
Revert "Remove redundant canvas positioning"
eceeeren Nov 3, 2024
a7a8566
Lectures: Fix undefined course issue in lecture attachments (#9601)
eceeeren Nov 3, 2024
bcb89be
Remove redundant positioning & styling
eceeeren Nov 3, 2024
a024b2d
Merge 'feature/lectures/attachment-pdf-editing' into feature/lectures…
eceeeren Nov 3, 2024
4663776
Merge 'develop' into feature/lectures/attachment-pdf-editing
eceeeren Nov 3, 2024
96ecb0f
Merge branch 'feature/course/attachment-pdf-editing' into feature/lec…
eceeeren Nov 4, 2024
323ab51
Add hide icon to slide pages
eceeeren Nov 4, 2024
6cf3cb4
Merge branch 'feature/lectures/pdf-preview-decomposition' into featur…
eceeeren Nov 4, 2024
a14fe4f
Add functionality to hide-show buttons
eceeeren Nov 4, 2024
e9a4ace
Add slide hiding capability & creating a hidden version of the file
eceeeren Nov 10, 2024
9ad8e54
Add empty pdf container & disable merge pdf in the beginning
eceeeren Nov 10, 2024
d0f39e9
Merge 'develop' into feature/lectures/pdf-preview-decomposition
eceeeren Nov 10, 2024
acba466
CodeRabbitAI changes
eceeeren Nov 10, 2024
1c53219
Adapt hidden pages to attachment units & remove from attachments
eceeeren Nov 12, 2024
a90a928
Fix typos
eceeeren Nov 12, 2024
10b9133
Fix parentAttachmentId problem
eceeeren Nov 12, 2024
a34e158
Merge 'feature/lectures/pdf-preview-decomposition' into feature/lectu…
eceeeren Nov 14, 2024
e73a940
Remove changes from Attachment Unit and add it to the Attachment
eceeeren Nov 17, 2024
3696f8c
Add Slide table hidden page column setting
eceeeren Nov 18, 2024
e8b8054
Update JSDoc and JavaDoc
eceeeren Nov 18, 2024
1c24c93
Fix bugs and get hidden sides from Slide table
eceeeren Nov 18, 2024
caf2932
Track hidden slides indexes
eceeeren Nov 18, 2024
899e7d2
Refactor template properties
eceeeren Nov 20, 2024
cc3bca2
Change hidden file structure to hiddenLink
eceeeren Dec 11, 2024
71f7466
Create paths for student version
eceeeren Dec 18, 2024
2db321e
Change hiddenLink property to studentVersion
eceeeren Dec 18, 2024
fb24698
Fix RabbitAI recommendations
eceeeren Dec 18, 2024
2f4c5cf
Merge 'develop' into feature/lectures/hide-pdf-pages
eceeeren Dec 18, 2024
c18def3
Add 'Original Version' button for instructors
eceeeren Dec 19, 2024
e1d937d
Fix client and server tests
eceeeren Dec 20, 2024
50a5007
Fix attachment unit tests
eceeeren Dec 20, 2024
c63dae2
Quick fixes
eceeeren Dec 20, 2024
2c14198
Merge branch 'develop' into feature/lectures/hide-pdf-pages
eceeeren Dec 20, 2024
88d0dbd
Fix Attachment Unit update logic
eceeeren Dec 21, 2024
1208baa
Fix server test
eceeeren Dec 21, 2024
0c5e79d
Increase client test coverage
eceeeren Dec 22, 2024
f522254
Merge branch 'develop' into feature/lectures/hide-pdf-pages
eceeeren Dec 22, 2024
862f827
Increase client test coverage 2
eceeeren Dec 22, 2024
520865f
Merge remote-tracking branch 'origin/feature/lectures/hide-pdf-pages'…
eceeeren Dec 22, 2024
44b8873
Increase client test coverage 3
eceeeren Dec 22, 2024
f83ce6d
Merge branch 'develop' into feature/lectures/hide-pdf-pages
eceeeren Dec 22, 2024
7d7df11
Small client fixes
eceeeren Dec 22, 2024
17ee22f
Merge branch 'develop' into feature/lectures/hide-pdf-pages
eceeeren Dec 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ private static Path actualPathForPublicAttachmentUnitFilePath(URI publicPath, St
String attachmentUnitId = path.getName(4).toString();
return getAttachmentUnitFilePath().resolve(Path.of(attachmentUnitId, filename));
}
else if (publicPath.toString().contains("/student")) {
String attachmentUnitId = path.getName(4).toString();
return getAttachmentUnitFilePath().resolve(Path.of(attachmentUnitId, "student", filename));
}
eceeeren marked this conversation as resolved.
Show resolved Hide resolved
try {
String attachmentUnitId = path.getName(4).toString();
String slideId = path.getName(6).toString();
Expand Down Expand Up @@ -244,6 +248,9 @@ public static URI publicPathForActualPath(Path path, @Nullable Long entityId) {
}

private static URI publicPathForActualAttachmentUnitFilePath(Path path, String filename, String id) {
if (path.toString().contains("/student")) {
return URI.create("/api/files/attachments/attachment-unit/" + id + "/student/" + filename);
}
if (!path.toString().contains("/slide")) {
return URI.create("/api/files/attachments/attachment-unit/" + id + "/" + filename);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ public ResponseEntity<byte[]> getLecturePdfAttachmentsMerged(@PathVariable Long
* @return The requested file, 403 if the logged-in user is not allowed to access it, or 404 if the file doesn't exist
*/
@GetMapping("files/attachments/attachment-unit/{attachmentUnitId}/*")
@EnforceAtLeastStudent
@EnforceAtLeastTutor
eceeeren marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<byte[]> getAttachmentUnitAttachment(@PathVariable Long attachmentUnitId) {
log.debug("REST request to get the file for attachment unit {} for students", attachmentUnitId);
AttachmentUnit attachmentUnit = attachmentUnitRepository.findByIdElseThrow(attachmentUnitId);
Expand Down Expand Up @@ -565,6 +565,30 @@ public ResponseEntity<byte[]> getAttachmentUnitAttachmentSlide(@PathVariable Lon
}
}

/**
* GET files/attachments/attachment-unit/{attachmentUnitId}/student/* : Get the student version of attachment unit by attachment unit id
*
* @param attachmentUnitId ID of the attachment unit, the student version belongs to
* @return The requested file, 403 if the logged-in user is not allowed to access it, or 404 if the file doesn't exist
*/
@GetMapping("files/attachments/attachment-unit/{attachmentUnitId}/student/*")
@EnforceAtLeastStudent
public ResponseEntity<byte[]> getAttachmentUnitStudentVersion(@PathVariable Long attachmentUnitId) {
log.debug("REST request to get the student version of attachment Unit : {}", attachmentUnitId);
AttachmentUnit attachmentUnit = attachmentUnitRepository.findByIdElseThrow(attachmentUnitId);
Attachment attachment = attachmentUnit.getAttachment();

// check if hidden link is available in the attachment
String studentVersion = attachment.getStudentVersion();
if (studentVersion == null) {
return buildFileResponse(getActualPathFromPublicPathString(attachment.getLink()), false);
}

String fileName = studentVersion.substring(studentVersion.lastIndexOf("/") + 1);

return buildFileResponse(FilePathService.getAttachmentUnitFilePath().resolve(Path.of(attachmentUnit.getId().toString(), "student")), fileName, false);
}

/**
* Builds the response with headers, body and content type for specified path containing the file name
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public class Attachment extends DomainObject implements Serializable {
@JoinColumn(name = "attachment_unit_id")
private AttachmentUnit attachmentUnit;

@Column(name = "student_version")
private String studentVersion;

// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove

public String getName() {
Expand Down Expand Up @@ -135,6 +138,14 @@ public void setAttachmentUnit(AttachmentUnit attachmentUnit) {
this.attachmentUnit = attachmentUnit;
}

public String getStudentVersion() {
return studentVersion;
}

public void setStudentVersion(String studentVersion) {
this.studentVersion = studentVersion;
}

public Boolean isVisibleToStudents() {
if (releaseDate == null) { // no release date means the attachment is visible to students
return Boolean.TRUE;
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/de/tum/cit/aet/artemis/lecture/domain/Slide.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.tum.cit.aet.artemis.lecture.domain;

import java.util.Date;

eceeeren marked this conversation as resolved.
Show resolved Hide resolved
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
Expand Down Expand Up @@ -27,6 +29,9 @@ public class Slide extends DomainObject {
@Column(name = "slide_number")
private int slideNumber;

@Column(name = "hidden")
private Date hidden;

public AttachmentUnit getAttachmentUnit() {
return attachmentUnit;
}
Expand All @@ -50,4 +55,12 @@ public int getSlideNumber() {
public void setSlideNumber(int slideNumber) {
this.slideNumber = slideNumber;
}

public Date getHidden() {
return hidden;
}

public void setHidden(Date hidden) {
this.hidden = hidden;
}
eceeeren marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import java.util.List;

import org.springframework.context.annotation.Profile;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
Expand All @@ -17,4 +21,17 @@ public interface SlideRepository extends ArtemisJpaRepository<Slide, Long> {

Slide findSlideByAttachmentUnitIdAndSlideNumber(Long attachmentUnitId, Integer slideNumber);

/**
* Finds the list of hidden slide IDs for a specific attachment unit ID.
*
* @param attachmentUnitId The ID of the attachment unit.
* @return List of hidden slide IDs.
*/
@Query("""
SELECT s.slideNumber
FROM Slide s
WHERE s.attachmentUnit.id = :attachmentUnitId AND s.hidden IS NOT NULL
""")
List<Integer> findHiddenSlideNumbersByAttachmentUnitId(@Param("attachmentUnitId") Long attachmentUnitId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,11 @@ public AttachmentUnit createAttachmentUnit(AttachmentUnit attachmentUnit, Attach
* @param updateAttachment The new attachment data.
* @param updateFile The optional file.
* @param keepFilename Whether to keep the original filename or not.
* @param hiddenPages The hidden pages of attachment unit.
* @return The updated attachment unit.
*/
public AttachmentUnit updateAttachmentUnit(AttachmentUnit existingAttachmentUnit, AttachmentUnit updateUnit, Attachment updateAttachment, MultipartFile updateFile,
boolean keepFilename) {
boolean keepFilename, String hiddenPages) {
eceeeren marked this conversation as resolved.
Show resolved Hide resolved
Set<CompetencyLectureUnitLink> existingCompetencyLinks = new HashSet<>(existingAttachmentUnit.getCompetencyLinks());

existingAttachmentUnit.setDescription(updateUnit.getDescription());
Expand Down Expand Up @@ -145,7 +146,7 @@ public AttachmentUnit updateAttachmentUnit(AttachmentUnit existingAttachmentUnit
}
// Split the updated file into single slides only if it is a pdf
if (Objects.equals(FilenameUtils.getExtension(updateFile.getOriginalFilename()), "pdf")) {
slideSplitterService.splitAttachmentUnitIntoSingleSlides(savedAttachmentUnit);
slideSplitterService.splitAttachmentUnitIntoSingleSlides(savedAttachmentUnit, hiddenPages);
}
if (pyrisWebhookService.isPresent() && irisSettingsRepository.isPresent()) {
pyrisWebhookService.get().autoUpdateAttachmentUnitsInPyris(savedAttachmentUnit.getLecture().getCourse().getId(), List.of(savedAttachmentUnit));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public LectureUnit importLectureUnit(final LectureUnit importedLectureUnit) {
attachment.setAttachmentUnit(attachmentUnit);
attachmentRepository.save(attachment);
if (attachment.getLink().endsWith(".pdf")) {
slideSplitterService.splitAttachmentUnitIntoSingleSlides(attachmentUnit);
slideSplitterService.splitAttachmentUnitIntoSingleSlides(attachmentUnit, null);
}
attachmentUnit.setAttachment(attachment);
return attachmentUnit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public List<AttachmentUnit> splitAndSaveUnits(LectureUnitSplitInformationDTO lec

MultipartFile multipartFile = fileService.convertByteArrayToMultipart(lectureUnit.unitName(), ".pdf", outputStream.toByteArray());
AttachmentUnit savedAttachmentUnit = attachmentUnitService.createAttachmentUnit(attachmentUnit, attachment, lecture, multipartFile, true);
slideSplitterService.splitAttachmentUnitIntoSingleSlides(documentUnits.getFirst(), savedAttachmentUnit, multipartFile.getOriginalFilename());
slideSplitterService.splitAttachmentUnitIntoSingleSlides(documentUnits.getFirst(), savedAttachmentUnit, multipartFile.getOriginalFilename(), "");
documentUnits.getFirst().close(); // make sure to close the document
units.add(savedAttachmentUnit);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
import java.io.IOException;
import java.net.URI;
import java.nio.file.Path;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.imageio.ImageIO;

Expand Down Expand Up @@ -39,6 +44,8 @@ public class SlideSplitterService {

private static final Logger log = LoggerFactory.getLogger(SlideSplitterService.class);

static final LocalDate FOREVER = LocalDate.of(9999, 12, 31);

private final FileService fileService;

private final SlideRepository slideRepository;
Expand All @@ -52,14 +59,15 @@ public SlideSplitterService(FileService fileService, SlideRepository slideReposi
* Splits an Attachment Unit file into single slides and saves them as PNG files asynchronously.
*
* @param attachmentUnit The attachment unit to which the slides belong.
* @param hiddenPages The hidden pages of the attachment unit.
*/
@Async
public void splitAttachmentUnitIntoSingleSlides(AttachmentUnit attachmentUnit) {
public void splitAttachmentUnitIntoSingleSlides(AttachmentUnit attachmentUnit, String hiddenPages) {
Path attachmentPath = FilePathService.actualPathForPublicPath(URI.create(attachmentUnit.getAttachment().getLink()));
File file = attachmentPath.toFile();
try (PDDocument document = Loader.loadPDF(file)) {
String pdfFilename = file.getName();
splitAttachmentUnitIntoSingleSlides(document, attachmentUnit, pdfFilename);
splitAttachmentUnitIntoSingleSlides(document, attachmentUnit, pdfFilename, hiddenPages);
}
catch (IOException e) {
log.error("Error while splitting Attachment Unit {} into single slides", attachmentUnit.getId(), e);
Expand All @@ -68,19 +76,23 @@ public void splitAttachmentUnitIntoSingleSlides(AttachmentUnit attachmentUnit) {
}

/**
* Splits an Attachment Unit file into single slides and saves them as PNG files. Document is closed where this method is called.
* Splits an Attachment Unit file into single slides and saves them as PNG files or updates existing slides.
*
* @param attachmentUnit The attachment unit to which the slides belong.
* @param document The PDF document that is already loaded.
* @param pdfFilename The name of the PDF file.
* @param hiddenPages The hidden pages of the attachment unit.
*/
public void splitAttachmentUnitIntoSingleSlides(PDDocument document, AttachmentUnit attachmentUnit, String pdfFilename) {
public void splitAttachmentUnitIntoSingleSlides(PDDocument document, AttachmentUnit attachmentUnit, String pdfFilename, String hiddenPages) {
log.debug("Splitting Attachment Unit file {} into single slides", attachmentUnit.getAttachment().getName());
try {
String fileNameWithOutExt = FilenameUtils.removeExtension(pdfFilename);
int numPages = document.getNumberOfPages();
PDFRenderer pdfRenderer = new PDFRenderer(document);

List<Integer> hiddenPagesList = hiddenPages != null && !hiddenPages.isEmpty() ? Arrays.stream(hiddenPages.split(",")).map(Integer::parseInt).toList()
: Collections.emptyList();

eceeeren marked this conversation as resolved.
Show resolved Hide resolved
for (int page = 0; page < numPages; page++) {
BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(page, 72, ImageType.RGB);
byte[] imageInByte = bufferedImageToByteArray(bufferedImage, "png");
Expand All @@ -89,11 +101,15 @@ public void splitAttachmentUnitIntoSingleSlides(PDDocument document, AttachmentU
MultipartFile slideFile = fileService.convertByteArrayToMultipart(filename, ".png", imageInByte);
Path savePath = fileService.saveFile(slideFile, FilePathService.getAttachmentUnitFilePath().resolve(attachmentUnit.getId().toString()).resolve("slide")
.resolve(String.valueOf(slideNumber)).resolve(filename));
Slide slideEntity = new Slide();
slideEntity.setSlideImagePath(FilePathService.publicPathForActualPath(savePath, (long) slideNumber).toString());
slideEntity.setSlideNumber(slideNumber);
slideEntity.setAttachmentUnit(attachmentUnit);
slideRepository.save(slideEntity);

Optional<Slide> existingSlideOpt = Optional.ofNullable(slideRepository.findSlideByAttachmentUnitIdAndSlideNumber(attachmentUnit.getId(), slideNumber));
Slide slide = existingSlideOpt.orElseGet(Slide::new);
slide.setSlideImagePath(FilePathService.publicPathForActualPath(savePath, (long) slideNumber).toString());
slide.setSlideNumber(slideNumber);
slide.setAttachmentUnit(attachmentUnit);
slide.setHidden(hiddenPagesList.contains(slideNumber) ? java.sql.Date.valueOf(FOREVER) : null);
slideRepository.save(slide);

}
}
catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,20 @@ public ResponseEntity<Attachment> createAttachment(@RequestPart Attachment attac
}

/**
* PUT /attachments/:id : Updates an existing attachment.
* PUT /attachments/:id : Updates an existing attachment, optionally handling student version of files as well.
*
* @param attachmentId the id of the attachment to save
* @param attachment the attachment to update
* @param file the file to save if the file got changed (optional)
* @param notificationText text that will be sent to student group
* @param studentVersion the file to add as student version of the attachment (optional)
* @param notificationText text that will be sent to the student group (optional)
* @return the ResponseEntity with status 200 (OK) and with body the updated attachment, or with status 400 (Bad Request) if the attachment is not valid, or with status 500
* (Internal Server Error) if the attachment couldn't be updated
*/
@PutMapping(value = "attachments/{attachmentId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@EnforceAtLeastEditor
public ResponseEntity<Attachment> updateAttachment(@PathVariable Long attachmentId, @RequestPart Attachment attachment, @RequestPart(required = false) MultipartFile file,
@RequestParam(value = "notificationText", required = false) String notificationText) {
@RequestPart(required = false) MultipartFile studentVersion, @RequestParam(value = "notificationText", required = false) String notificationText) {
log.debug("REST request to update Attachment : {}", attachment);
attachment.setId(attachmentId);

Expand All @@ -131,6 +132,20 @@ public ResponseEntity<Attachment> updateAttachment(@PathVariable Long attachment
this.fileService.evictCacheForPath(FilePathService.actualPathForPublicPathOrThrow(oldPath));
}

if (studentVersion != null) {
// Update student version of attachment
Path basePath = FilePathService.getAttachmentUnitFilePath().resolve(originalAttachment.getAttachmentUnit().getId().toString());
Path savePath = fileService.saveFile(studentVersion, basePath.resolve("student"), true);
attachment.setStudentVersion(FilePathService.publicPathForActualPath(savePath, originalAttachment.getAttachmentUnit().getId()).toString());

// Delete the old student version
if (originalAttachment.getStudentVersion() != null) {
URI oldHiddenPath = URI.create(originalAttachment.getStudentVersion());
fileService.schedulePathForDeletion(FilePathService.actualPathForPublicPathOrThrow(oldHiddenPath), 0);
this.fileService.evictCacheForPath(FilePathService.actualPathForPublicPathOrThrow(oldHiddenPath));
}
}

Attachment result = attachmentRepository.save(attachment);
if (notificationText != null) {
groupNotificationService.notifyStudentGroupAboutAttachmentChange(result, notificationText);
Expand Down
Loading
Loading