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

Add thumbnail for featured dataverses #10433

Merged
Merged
3 changes: 2 additions & 1 deletion doc/sphinx-guides/source/user/dataverse-management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ The Theme features provides you with a way to customize the look of your Dataver

- Inherit the theme from the parent Dataverse collection. This option is helpful if you'd like consistency across several Dataverse collections that all share the same parent.
- Add or update a logo image, which will appear at the top of your Dataverse collection.
- Add or update a footer image, which will appear at at the bottom of your Dataverse collection.
- Add or update a thumbnail image, which will appear on featured dataverses of your Dataverse collection.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting feature! My first thought is, should this feature be available via API? That way the new frontend can use it some day.

Also, these issue are related:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to have thumbnail logo via API, all Theme feature have to be moved before. Do you know if the development of #10194 is well advanced and PR will be open soon ?

Either I wait for PR #10194 to be accepted (and I adapt the source code from it), or I propose one. But either way, I should change the status of this PR (#10433) to draft.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the impression from @DS-INRA that he might have a team member like you work on #10194 but maybe I'm wrong! 😅

- Add or update a footer image, which will appear at the bottom of your Dataverse collection.
- Change the colors of the background, links, and text within the header of your Dataverse collection.
- Add or update the tagline for your Dataverse collection, which can provide more information about your organization, journal, institution, etc.
- Add a URL for a website that will be accessed when visitors click the tagline text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ public DataverseTheme findDataverseThemeByIdQuick(Long id) {
Object[] result;

try {
result = (Object[]) em.createNativeQuery("SELECT logo, logoFormat FROM dataversetheme WHERE dataverse_id = " + id).getSingleResult();
result = (Object[]) em.createNativeQuery("SELECT logo, logoFormat, logothumbnail FROM dataversetheme WHERE dataverse_id = " + id).getSingleResult();

} catch (Exception ex) {
return null;
Expand All @@ -439,6 +439,10 @@ public DataverseTheme findDataverseThemeByIdQuick(Long id) {
break;
}
}

if (result[2] != null) {
theme.setLogoThumbnail((String) result[2]);
}

return theme;
}
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/DataverseTheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public enum Alignment {
private Alignment logoAlignment;
private String logoBackgroundColor;
private String logo;
private String logoThumbnail;
private Alignment logoFooterAlignment;
private String logoFooterBackgroundColor;
private String logoFooter;
Expand Down Expand Up @@ -97,6 +98,14 @@ public void setLogo(String logo) {
this.logo = logo;
}

public String getLogoThumbnail() {
return this.logoThumbnail;
}

public void setLogoThumbnail(String logoThumbnail) {
this.logoThumbnail = logoThumbnail;
}

public Alignment getLogoFooterAlignment() {
return logoFooterAlignment;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ public List<Dataverse> findByDataverseIdQuick(Long dataverseId) {
}

dataverse.setDataverseTheme(dataverseService.findDataverseThemeByIdQuick(id));
if (dataverse.getDataverseTheme()!=null){
logger.fine("THEME: "+dataverse.getDataverseTheme().getLogo()+", "+dataverse.getDataverseTheme().getLogoFormat());
if (dataverse.getDataverseTheme() != null) {
logger.fine("THEME: "
+ dataverse.getDataverseTheme().getLogo() + ", "
+ dataverse.getDataverseTheme().getLogoFormat() + ", "
+ dataverse.getDataverseTheme().getLogoThumbnail());
}
ret.add(dataverse);
}
Expand Down
140 changes: 104 additions & 36 deletions src/main/java/edu/harvard/iq/dataverse/ThemeWidgetFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand All @@ -33,7 +32,6 @@

import org.apache.commons.lang3.StringUtils;
import org.primefaces.PrimeFaces;
//import org.primefaces.context.RequestContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.file.UploadedFile;
Expand All @@ -56,6 +54,7 @@ public class ThemeWidgetFragment implements java.io.Serializable {

private File tempDir;
private File uploadedFile;
private File uploadedFileThumbnail;
private File uploadedFileFooter;
private Dataverse editDv= new Dataverse();
private HtmlInputText linkUrlInput;
Expand Down Expand Up @@ -124,6 +123,7 @@ public void cleanupTempDirectory() {
throw new RuntimeException("Error deleting temp directory", e); // improve error handling
}
uploadedFile=null;
uploadedFileThumbnail=null;
uploadedFileFooter=null;
tempDir=null;
}
Expand Down Expand Up @@ -213,21 +213,46 @@ public boolean uploadExists() {
return uploadedFile!=null;
}

public boolean uploadExistsThumbnail() {
return uploadedFileThumbnail != null;
}

public boolean uploadExistsFooter() {
return uploadedFileFooter!=null;
}

public void handleImageThumbnailFileUpload(FileUploadEvent event) {
logger.finer("entering handleImageFooterFileUpload");
if (this.tempDir == null) {
createTempDir();
logger.finer("created tempDir");
}
final UploadedFile uFile = event.getFile();
try {
this.uploadedFileThumbnail = new File(tempDir, uFile.getFileName());
if (!this.uploadedFileThumbnail.exists()) {
this.uploadedFileThumbnail.createNewFile();
}
logger.finer("created file");
Files.copy(uFile.getInputStream(), this.uploadedFileThumbnail.toPath(), StandardCopyOption.REPLACE_EXISTING);
logger.finer("copied inputstream to file");
this.editDv.getDataverseTheme().setLogoThumbnail(uFile.getFileName());
} catch (IOException e) {
logger.finer("caught IOException");
logger.throwing("ThemeWidgetFragment", "handleImageFileUpload", e);
throw new RuntimeException("Error uploading logo file", e); // improve error handling
}
logger.finer("end handleImageFooterFileUpload");
}

/**
* This method is for footer image.
* Copy uploaded file to temp area, until we are ready to save
* Copy filename into Dataverse logo
* @param event
*/

// This method is for footer image. The syntax is same that handleImageFileUpload for header image

public void handleImageFooterFileUpload(FileUploadEvent event) {

logger.finer("entering fileUpload");
logger.finer("entering handleImageFooterFileUpload");
if (this.tempDir==null) {
createTempDir();
logger.finer("created tempDir");
Expand All @@ -248,18 +273,16 @@ public void handleImageFooterFileUpload(FileUploadEvent event) {
logger.throwing("ThemeWidgetFragment", "handleImageFileUpload", e);
throw new RuntimeException("Error uploading logo file", e); // improve error handling
}
logger.finer("end handelImageFileUpload");
logger.finer("end handleImageFooterFileUpload");
}


public void handleImageFileUpload(FileUploadEvent event) {

logger.finer("entering fileUpload");
if (this.tempDir==null) {
createTempDir();
logger.finer("created tempDir");
}
UploadedFile uFile = event.getFile();
logger.finer("entering handleImageFileUpload");
if (this.tempDir==null) {
createTempDir();
logger.finer("created tempDir");
}
UploadedFile uFile = event.getFile();
try {
uploadedFile = new File(tempDir, uFile.getFileName());
if (!uploadedFile.exists()) {
Expand All @@ -279,9 +302,9 @@ public void handleImageFileUpload(FileUploadEvent event) {
if (editDv.getDataverseTheme().getLogoFormat()==null) {
editDv.getDataverseTheme().setLogoFormat(DataverseTheme.ImageFormat.SQUARE);
}
logger.finer("end handelImageFileUpload");
logger.finer("end handleImageFileUpload");
}

public void removeLogo() {
editDv.getDataverseTheme().setLogo(null);
this.cleanupTempDirectory();
Expand All @@ -292,6 +315,11 @@ public void removeLogoFooter() {
this.cleanupTempDirectory();
}

public void removeLogoThumbnail() {
editDv.getDataverseTheme().setLogoThumbnail(null);
this.cleanupTempDirectory();
}

public boolean getInheritCustomization() {
boolean inherit= editDv==null ? true : !editDv.getThemeRoot();
return inherit;
Expand Down Expand Up @@ -324,32 +352,70 @@ public String save() {
editDv.setDataverseTheme(null);
}

Command<Dataverse> cmd;
// Update files : logo, footer, thumbnail
final Dataverse currentDv = dataverseServiceBean.find(editDv.getId());
final Path logoDir = getLogoDir(editDv.getId().toString());
String currentLogo = null;
String editedLogo = null;
String currentLogoFooter = null;
String editedLogoFooter = null;
String currentLogoThumbnail = null;
String editedLogoThumbnail = null;
if (currentDv.getDataverseTheme() != null) {
currentLogo = currentDv.getDataverseTheme().getLogo();
currentLogoFooter = currentDv.getDataverseTheme().getLogoFooter();
currentLogoThumbnail = currentDv.getDataverseTheme().getLogoThumbnail();
}
if (editDv.getDataverseTheme() != null) {
editedLogo = editDv.getDataverseTheme().getLogo();
editedLogoFooter = editDv.getDataverseTheme().getLogoFooter();
editedLogoThumbnail = editDv.getDataverseTheme().getLogoThumbnail();
}
updateFile(this.uploadedFile, currentLogo, editedLogo, logoDir);
updateFile(this.uploadedFileFooter, currentLogoFooter, editedLogoFooter, logoDir);
updateFile(this.uploadedFileThumbnail, currentLogoThumbnail, editedLogoThumbnail, logoDir);

cmd = new UpdateDataverseThemeCommand(editDv, this.uploadedFile, dvRequestService.getDataverseRequest(), "HEADER");
if (!exectThemeCommand(cmd))
// Save dataverse theme into db
final Command<Dataverse> cmd = new UpdateDataverseThemeCommand(editDv, dvRequestService.getDataverseRequest());
if (!exectThemeCommand(cmd)) {
return null;

if (uploadedFileFooter!=null){
cmd = new UpdateDataverseThemeCommand(editDv, this.uploadedFileFooter, dvRequestService.getDataverseRequest(), "FOOTER");
if (!exectThemeCommand(cmd))
return null;
}

try {
commandEngine.submit(cmd);
} catch (Exception ex) {
logger.log(Level.SEVERE, "error updating dataverse theme", ex);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, BundleUtil.getStringFromBundle("dataverse.save.failed"), BundleUtil.getStringFromBundle("dataverse.theme.failure")));

return null;
} finally {
this.cleanupTempDirectory();
}
JsfHelper.addSuccessMessage(BundleUtil.getStringFromBundle("dataverse.theme.success"));
return "dataverse.xhtml?faces-redirect=true&alias="+editDv.getAlias(); // go to dataverse page
}

/**
* Create, update, or delete file logo.
*
* @param uploadedLogoFile the logo physical file to update on disk
* @param currentLogo logo file name from database before update. {@code null} if absent.
* @param editedLogo logo file name updated. {@code null} if absent.
* @param logoDir folder path containing all collection logos
*/
private void updateFile(File uploadedLogoFile, String currentLogo, String editedLogo, Path logoDir) {
try {
if (!Files.isDirectory(logoDir)) {
Files.createDirectory(logoDir);
}
if (StringUtils.isBlank(editedLogo)) {
// If edited logo field is empty, and a logoFile currently exists, delete it
if (StringUtils.isNotBlank(currentLogo)) {
Files.deleteIfExists(Path.of(logoDir.toString(), currentLogo));
}
} else if (uploadedLogoFile != null) {
// If edited logo file isn't empty, and uploaded File exists, delete currentFile and copy uploaded file from temp dir to logos dir
if (StringUtils.isNotBlank(currentLogo)) {
Files.deleteIfExists(Path.of(logoDir.toString(), currentLogo));
}
final Path newFile = Path.of(logoDir.toString(), editedLogo);
Files.copy(uploadedLogoFile.toPath(), newFile, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException("Error saving logo file", e); // improve error handling
}
}


public boolean exectThemeCommand(Command<Dataverse> cmd){
try {
Expand All @@ -358,6 +424,8 @@ public boolean exectThemeCommand(Command<Dataverse> cmd){
logger.log(Level.SEVERE, "error updating dataverse theme", ex);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, BundleUtil.getStringFromBundle("dataverse.save.failed"), BundleUtil.getStringFromBundle("dataverse.theme.failure")));
return false;
} finally {
this.cleanupTempDirectory();
}
return true;
}
Expand Down
Loading
Loading