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

3758 file page preview #6325

Merged
merged 53 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a43c1cb
Initial commit for new file pg preview tab [ref #3758, #6048]
mheppler Aug 9, 2019
4255f3f
Added TODO comments outlining design/dev remaining tasks [ref #6048, …
mheppler Aug 12, 2019
03def31
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Sep 30, 2019
d977c86
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Sep 30, 2019
a358a85
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 1, 2019
e971152
added some content and some stubs for future content
djbrooke Oct 1, 2019
c87270f
#3758 update logic for World Map add lock icons to preview
sekmiller Oct 2, 2019
2e434cb
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 2, 2019
81f8f3a
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 2, 2019
b3aa901
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 3, 2019
454ad43
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 7, 2019
1d15780
#3758 add preview mode boolean to tools table
sekmiller Oct 7, 2019
2f5dfd4
#3758 Add preview links to file page
sekmiller Oct 8, 2019
0fc8176
#3758 add view preview mode for external tools
sekmiller Oct 10, 2019
ac10939
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 10, 2019
6ef4d08
#3758 fix render reference
sekmiller Oct 10, 2019
bf45712
#3758 add multiple preview tools as inner tabs on preview
sekmiller Oct 11, 2019
2dfeaf1
#3758 update preview tab render logic
sekmiller Oct 11, 2019
9e8249a
add documentation of new External Tools field
sekmiller Oct 11, 2019
a2b95ba
Update Doc
sekmiller Oct 11, 2019
48c04c0
#3758 formatting preview tab
sekmiller Oct 11, 2019
4e81e14
#3758 reduce logging of external tools
sekmiller Oct 15, 2019
b0c6366
#3758 formatting and bundle-izing
sekmiller Oct 15, 2019
9881331
docs for external tools
djbrooke Oct 15, 2019
8dbe327
filling in those doc stubs from earlier
djbrooke Oct 16, 2019
c548f86
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 22, 2019
6a4c53f
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 22, 2019
57b3f8f
#3758 update external tool builder prelim
sekmiller Oct 23, 2019
4291db1
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 23, 2019
a61d393
#3758 add preview mode to constructor
sekmiller Oct 23, 2019
1e0eabb
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 23, 2019
e1e9b4b
#3758 update unit tests
sekmiller Oct 23, 2019
e5de7a6
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 23, 2019
7118939
#3758 allow null hasPreviewMode
sekmiller Oct 24, 2019
b0d4e9f
#3578 move preview tool render to drop down
sekmiller Oct 28, 2019
80c8a15
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 28, 2019
16d2a5d
#3758 sort tools for Explore Button
sekmiller Oct 28, 2019
47d0924
#3758 remove debug code
sekmiller Oct 28, 2019
c35268b
#3758 add render logic to preview only publicly downloadable files.
sekmiller Oct 28, 2019
28eb9e2
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 28, 2019
939de9d
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 29, 2019
0700b24
#3758 remove transient display order
sekmiller Oct 29, 2019
e319ba9
#3758 update preview tab render logic
sekmiller Oct 29, 2019
f820b02
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 29, 2019
6668f9d
#3758 bundle-ize preview tab labels
sekmiller Oct 29, 2019
b2aa0f3
#3758 remove unused import
sekmiller Oct 29, 2019
6bdff7b
#3758 fix Open World Map
sekmiller Oct 30, 2019
7e383a7
#3758 code cleanup
sekmiller Oct 30, 2019
a992e0e
code review feedback
djbrooke Oct 31, 2019
d8c6219
Merge branch 'develop' into 3758-file-pg-preview
sekmiller Oct 31, 2019
7f95cd2
#3758 get doi by indexOf not hard-coded
sekmiller Oct 31, 2019
e253843
#3758 Only show preview tab if on current version of DS
sekmiller Oct 31, 2019
29a7edc
reverting previous doc changes based qa feedback
djbrooke Oct 31, 2019
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
9 changes: 8 additions & 1 deletion doc/sphinx-guides/source/admin/external-tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ In the curl command below, replace the placeholder "fabulousFileTool.json" place

curl -X POST -H 'Content-type: application/json' http://localhost:8080/api/admin/externalTools --upload-file fabulousFileTool.json

If you'd like to allow the external tool to be used in previews on the file page, you can define it in the manifest using the `hasPreviewMode` parameter.
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

Listing All External Tools in Dataverse
+++++++++++++++++++++++++++++++++++++++

Expand Down Expand Up @@ -76,10 +78,15 @@ Once you have added an external tool to your installation of Dataverse, you will
File Level Explore Tools
++++++++++++++++++++++++

File level explore tools are specific to the file type (content type or MIME type) of the file. For example, there is a tool for exploring PDF files in the "File Previewers" set of tools.
File level explore tools are specific to the file type (content type or MIME type) of the file. For example, Data Explorer is tool for exploring tabular data files.

An "Explore" button will appear (on both the dataset page and the file landing page) for files that match the type that the tool has been built for. When there are multiple explore tools for a filetype, the button becomes a dropdown.

File Level Preview Tools
++++++++++++++++++++++++

Similar to File level explore tools, File Level preview tools are specific to the file type. File level preview tools are designed to be embedded in the file page and can either be a tool designed solely for previewing data or can be a simplified view of another external tool.
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

File Level Configure Tools
++++++++++++++++++++++++++

Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx-guides/source/admin/integrations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Dataverse supports a protocol called OAI-PMH that facilitates harvesting dataset
SHARE
+++++

`SHARE <http://www.share-research.org>`_ is building a free, open, data set about research and scholarly activities across their life cycle. It's possible to add and installation of Dataverse as one of the `sources <https://share.osf.io/sources>`_ they include if you contact the SHARE team.
`SHARE <http://www.share-research.org>`_ is building a free, open, data set about research and scholarly activities across their life cycle. It's possible to add an installation of Dataverse as one of the `sources <https://share.osf.io/sources>`_ they include if you contact the SHARE team.

Research Data Preservation
--------------------------
Expand Down
10 changes: 9 additions & 1 deletion doc/sphinx-guides/source/api/external-tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ Note: This is the same list that appears in the :doc:`/admin/external-tools` sec
How External Tools Are Presented to Users
-----------------------------------------

In short, an external tool appears under an "Explore" or "Configure" button either on a dataset landing page or a file landing page. See also the :ref:`testing-external-tools` section of the Admin Guide for some perspective on how installations of Dataverse will expect to test your tool before announcing it to their users.
An external tool can appear in Dataverse in one of three ways:

- under an "Explore" or "Configure" button either on a dataset landing page
- under an "Explore" or "Configure" button on a file landing page
- as an embedded preview on the file landing page

See also the :ref:`testing-external-tools` section of the Admin Guide for some perspective on how installations of Dataverse will expect to test your tool before announcing it to their users.

Creating an External Tool Manifest
----------------------------------
Expand Down Expand Up @@ -75,6 +81,8 @@ Terminology
type Whether the external tool is an **explore** tool or a **configure** tool. Configure tools require an API token because they make changes to data files (files within datasets). Configure tools are currently not supported at the dataset level (no "Configure" button appears in the GUI for datasets).

toolUrl The **base URL** of the tool before query parameters are added.

hasPreviewMode A boolean that indicates whether tool has a preview mode which can be embedded in the File Page. Since this view is designed for embedding within Dataverse, the preview mode for a tool will typically be a view without headers or other options that may be included with a tool that is designed to be launched in a new window. Sometimes, a tool will exist solely to preview files in Dataverse and the preview mode will be the same as the regular view.

contentType File level tools operate on a specific **file type** (content type or MIME type such as "application/pdf") and this must be specified. Dataset level tools do not use contentType.

Expand Down
10 changes: 7 additions & 3 deletions doc/sphinx-guides/source/user/dataset-management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ If there are multiple upload options available, then you must choose which one t

You can upload files to a dataset while first creating that dataset. You can also upload files after creating a dataset by clicking the "Edit" button at the top of the dataset page and from the dropdown list selecting "Files (Upload)" or clicking the "Upload Files" button above the files table in the Files tab. From either option you will be brought to the Upload Files page for that dataset.

Certain file types in Dataverse are supported by additional functionality, which can include downloading in different formats, file-level metadata preservation, file-level data citation with UNFs, and exploration through data visualization and analysis. See the :ref:`File Handling <file-handling>` section of this page for more information.
Certain file types in Dataverse are supported by additional functionality, which can include downloading in different formats, previews, file-level metadata preservation, file-level data citation with UNFs, and exploration through data visualization and analysis. See the :ref:`File Handling <file-handling>` section of this page for more information.


HTTP Upload
Expand Down Expand Up @@ -143,8 +143,12 @@ DVUploader is a community-developed tool, and its creation was primarily support
File Handling
=============

Certain file types in Dataverse are supported by additional functionality, which can include downloading in different formats, file-level metadata preservation, file-level data citation; and exploration through data visualization and analysis. See the sections below for information about special functionality for specific file types.
Certain file types in Dataverse are supported by additional functionality, which can include downloading in different formats, previews, file-level metadata preservation, file-level data citation; and exploration through data visualization and analysis. See the sections below for information about special functionality for specific file types.

File Previews
-------------

Installations of Dataverse can install previewers for common file types uploaded by their research communities. The previews appear on the file page. If a preview tool for a specific file type is available, the preview will be created and will display automatically. File previews are not available for restricted files.
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

Tabular Data Files
------------------
Expand Down Expand Up @@ -296,7 +300,7 @@ Here is an `example of a Data Usage Agreement <https://dataverse.org/best-practi
Restricted Files + Terms of Access
----------------------------------

If you restrict any files in your dataset, you will be prompted by a pop-up to enter Terms of Access for the data. This can also be edited in the Terms tab or selecting Terms in the "Edit" dropdown button in the dataset. You may also allow users to request access for your restricted files by enabling "Request Access". To add more information about the Terms of Access, we have provided fields like Data Access Place, Availability Status, Contact for Access, etc.
If you restrict any files in your dataset, you will be prompted by a pop-up to enter Terms of Access for the data. This can also be edited in the Terms tab or selecting Terms in the "Edit" dropdown button in the dataset. You may also allow users to request access for your restricted files by enabling "Request Access". To add more information about the Terms of Access, we have provided fields like Data Access Place, Availability Status, Contact for Access, etc. If you restrict a file, it will not have a preview shown on the file page.
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

**Note:** Some Dataverse installations do not allow for file restriction.

Expand Down
8 changes: 7 additions & 1 deletion doc/sphinx-guides/source/user/find-use-data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ Once on a dataset page, you will see the title, citation, description, and sever
View Files
----------

Files in Dataverse each have their own page that can be reached through the search results or through the Files table on their parent dataset's page. The dataset page and file page offer much the same functionality in terms of viewing and editing files, with a few small exceptions. The file page includes the file's persistent identifier (DOI or handle), which can be found under the Metadata tab. Also, the file page's Versions tab gives you a version history that is more focused on the individual file rather than the dataset as a whole.
Files in Dataverse each have their own page that can be reached through the search results or through the Files table on their parent dataset's page. The dataset page and file page offer much the same functionality in terms of viewing and editing files, with a few small exceptions.
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

- In installations that have enabled support for persistent identifers (PIDs) at the file level, the file page includes the file's DOI or handle, which can be found in the file citation and also under the Metadata tab.
- Previewers for several common file types are available and can be added by installation administrators.
- The file page's Versions tab gives you a version history that is more focused on the individual file rather than the dataset as a whole.

File Search within Datasets
---------------------------
Expand All @@ -89,6 +93,8 @@ You can find the citation for the dataset at the top of the dataset page in a bl

.. _download_files:

In installations that have added file-level citations, you can find and download the file's citation on the file page in a similar manner.

Download Files
--------------

Expand Down
72 changes: 71 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/FilePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import edu.harvard.iq.dataverse.dataaccess.SwiftAccessIO;
import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.ApiToken;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.authorization.users.User;
import edu.harvard.iq.dataverse.dataaccess.StorageIO;
import edu.harvard.iq.dataverse.datasetutility.WorldMapPermissionHelper;
import edu.harvard.iq.dataverse.engine.command.Command;
Expand All @@ -22,6 +25,7 @@
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.export.spi.Exporter;
import edu.harvard.iq.dataverse.externaltools.ExternalTool;
import edu.harvard.iq.dataverse.externaltools.ExternalToolHandler;
import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean;
import edu.harvard.iq.dataverse.makedatacount.MakeDataCountLoggingServiceBean;
import edu.harvard.iq.dataverse.makedatacount.MakeDataCountLoggingServiceBean.MakeDataCountEntry;
Expand All @@ -34,6 +38,8 @@
import edu.harvard.iq.dataverse.util.SystemConfig;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
Expand Down Expand Up @@ -71,6 +77,7 @@ public class FilePage implements java.io.Serializable {
private String persistentId;
private List<ExternalTool> configureTools;
private List<ExternalTool> exploreTools;
private List<ExternalTool> toolsWithPreviews;

@EJB
DataFileServiceBean datafileService;
Expand Down Expand Up @@ -208,7 +215,11 @@ public String init() {
}
configureTools = externalToolService.findFileToolsByTypeAndContentType(ExternalTool.Type.CONFIGURE, contentType);
exploreTools = externalToolService.findFileToolsByTypeAndContentType(ExternalTool.Type.EXPLORE, contentType);

Collections.sort(exploreTools, CompareExternalToolName);
toolsWithPreviews = addMapLayerAndSortExternalTools();
if(!toolsWithPreviews.isEmpty()){
setSelectedTool(toolsWithPreviews.get(0));
}
} else {

return permissionsWrapper.notFound();
Expand All @@ -226,6 +237,30 @@ public FileMetadata getFileMetadata() {
return fileMetadata;
}

private List<ExternalTool> addMapLayerAndSortExternalTools(){
List<ExternalTool> retList = externalToolService.findFileToolsByTypeContentTypeAndAvailablePreview(ExternalTool.Type.EXPLORE, file.getContentType());
if(!retList.isEmpty()){
retList.forEach((et) -> {
et.setWorldMapTool(false);
});
}
if (file != null && worldMapPermissionHelper.getMapLayerMetadata(file) != null && worldMapPermissionHelper.getMapLayerMetadata(file).getEmbedMapLink() != null) {
ExternalTool wpTool = new ExternalTool();
djbrooke marked this conversation as resolved.
Show resolved Hide resolved
wpTool.setDisplayName("World Map");
wpTool.setToolParameters("{}");
wpTool.setToolUrl(worldMapPermissionHelper.getMapLayerMetadata(file).getEmbedMapLink());
wpTool.setWorldMapTool(true);
retList.add(wpTool);
}
Collections.sort(retList, CompareExternalToolName);

return retList;
}

/*
worldMapPermissionHelper.getMapLayerMetadata(FilePage.fileMetadata.dataFile).getEmbedMapLink()
*/


public boolean isDownloadPopupRequired() {
if(fileMetadata.getId() == null || fileMetadata.getDatasetVersion().getId() == null ){
Expand Down Expand Up @@ -888,10 +923,45 @@ public List<ExternalTool> getExploreTools() {
return exploreTools;
}

public List<ExternalTool> getToolsWithPreviews() {
return toolsWithPreviews;
}

private ExternalTool selectedTool;

public ExternalTool getSelectedTool() {
return selectedTool;
}

public void setSelectedTool(ExternalTool selectedTool) {
this.selectedTool = selectedTool;
}

public String preview(ExternalTool externalTool) {
ApiToken apiToken = null;
User user = session.getUser();
if (user instanceof AuthenticatedUser) {
apiToken = authService.findApiTokenByUser((AuthenticatedUser) user);
}
if(externalTool == null){
return "";
}
ExternalToolHandler externalToolHandler = new ExternalToolHandler(externalTool, file, apiToken, file.getFileMetadata(), session.getLocaleCode());
String toolUrl = externalToolHandler.getToolUrlForPreviewMode();
return toolUrl;
}

//Provenance fragment bean calls this to show error dialogs after popup failure
//This can probably be replaced by calling JsfHelper from the provpopup bean
public void showProvError() {
JH.addMessage(FacesMessage.SEVERITY_ERROR, BundleUtil.getStringFromBundle("file.metadataTab.provenance.error"));
}

private static final Comparator<ExternalTool> CompareExternalToolName = new Comparator<ExternalTool>() {
@Override
public int compare(ExternalTool o1, ExternalTool o2) {
return o1.getDisplayName().toUpperCase().compareTo(o2.getDisplayName().toUpperCase());
}
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Transient;

/**
* A specification or definition for how an external tool is intended to
Expand All @@ -27,6 +28,7 @@ public class ExternalTool implements Serializable {
public static final String TOOL_URL = "toolUrl";
public static final String TOOL_PARAMETERS = "toolParameters";
public static final String CONTENT_TYPE = "contentType";
public static final String HAS_PREVIEW_MODE = "hasPreviewMode";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -76,6 +78,22 @@ public class ExternalTool implements Serializable {
*/
@Column(nullable = true, columnDefinition = "TEXT")
private String contentType;

@Column(nullable = false)
private boolean hasPreviewMode;



@Transient
private boolean worldMapTool;

public boolean isWorldMapTool() {
return worldMapTool;
}

public void setWorldMapTool(boolean worldMapTool) {
this.worldMapTool = worldMapTool;
}

/**
* This default constructor is only here to prevent this error at
Expand All @@ -99,6 +117,18 @@ public ExternalTool(String displayName, String description, Type type, Scope sco
this.toolUrl = toolUrl;
this.toolParameters = toolParameters;
this.contentType = contentType;
this.hasPreviewMode = false;
}

public ExternalTool(String displayName, String description, Type type, Scope scope, String toolUrl, String toolParameters, String contentType, boolean hasPreviewMode) {
this.displayName = displayName;
this.description = description;
this.type = type;
this.scope = scope;
this.toolUrl = toolUrl;
this.toolParameters = toolParameters;
this.contentType = contentType;
this.hasPreviewMode = hasPreviewMode;
}

public enum Type {
Expand Down Expand Up @@ -212,7 +242,15 @@ public String getContentType() {
public void setContentType(String contentType) {
this.contentType = contentType;
}

public boolean getHasPreviewMode() {
return hasPreviewMode;
}

public void setHasPreviewMode(boolean hasPreviewMode) {
this.hasPreviewMode = hasPreviewMode;
}

public JsonObjectBuilder toJson() {
JsonObjectBuilder jab = Json.createObjectBuilder();
jab.add("id", getId());
Expand All @@ -224,6 +262,11 @@ public JsonObjectBuilder toJson() {
jab.add(TOOL_PARAMETERS, getToolParameters());
if (getContentType() != null) {
jab.add(CONTENT_TYPE, getContentType());
}
if (getHasPreviewMode()) {
jab.add(HAS_PREVIEW_MODE, getHasPreviewMode());
} else {

}
return jab;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ public String getLocaleCode() {

// TODO: rename to handleRequest() to someday handle sending headers as well as query parameters.
public String getQueryParametersForUrl() {
return getQueryParametersForUrl(false);
}

// TODO: rename to handleRequest() to someday handle sending headers as well as query parameters.
public String getQueryParametersForUrl(boolean preview) {
String toolParameters = externalTool.getToolParameters();
JsonReader jsonReader = Json.createReader(new StringReader(toolParameters));
JsonObject obj = jsonReader.readObject();
Expand All @@ -118,7 +123,11 @@ public String getQueryParametersForUrl() {
}
});
});
return "?" + String.join("&", params);
if (!preview) {
return "?" + String.join("&", params);
} else {
return "?" + String.join("&", params) + "&preview=true";
}
}

private String getQueryParam(String key, String value) {
Expand Down Expand Up @@ -178,6 +187,10 @@ private String getQueryParam(String key, String value) {
public String getToolUrlWithQueryParams() {
return externalTool.getToolUrl() + getQueryParametersForUrl();
}

public String getToolUrlForPreviewMode() {
return externalTool.getToolUrl() + getQueryParametersForUrl(true);
}

public ExternalTool getExternalTool() {
return externalTool;
Expand Down
Loading