Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -178,7 +178,8 @@ protected SkylineTool getToolFromZip(MultipartFile zip) throws IOException
while ((zipEntry = zipStream.getNextEntry()) != null &&
(tool == null || tool.getIcon() == null))
{
if (zipEntry.getName().toLowerCase().startsWith("tool-inf/"))
String entryLower = zipEntry.getName().toLowerCase();
if (entryLower.startsWith("tool-inf/") && !entryLower.startsWith("tool-inf/docs/"))
{
String lowerBaseName = new File(zipEntry.getName()).getName().toLowerCase();

Expand Down Expand Up @@ -229,6 +230,39 @@ protected byte[] unzip(ZipInputStream stream)
}
}

protected static boolean extractDocsFromZip(File zipFile, File containerDir) throws IOException
{
File docsDir = new File(containerDir, "docs");
boolean extracted = false;
try (ZipFile zf = new ZipFile(zipFile))
{
Enumeration<? extends ZipEntry> entries = zf.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
String name = entry.getName();
if (!name.toLowerCase().startsWith("tool-inf/docs/") || entry.isDirectory())
continue;
// Strip "tool-inf/docs/" prefix to get relative path within docs dir
String relativePath = name.substring("tool-inf/docs/".length());
if (relativePath.isEmpty())
continue;
File destFile = new File(docsDir, relativePath);
// Zip-slip protection
if (!destFile.getCanonicalPath().startsWith(docsDir.getCanonicalPath() + File.separator))
throw new IOException("Zip entry outside target directory: " + name);
Files.createDirectories(destFile.getParentFile().toPath());
try (InputStream in = zf.getInputStream(entry);
FileOutputStream out = new FileOutputStream(destFile))
{
in.transferTo(out);
}
extracted = true;
}
}
return extracted;
}

public static File makeFile(Container c, String filename)
{
return new File(getLocalPath(c), FileUtil.makeLegalName(filename));
Expand Down Expand Up @@ -408,7 +442,7 @@ public static HashSet<String> getSupplementaryFileBasenames(SkylineTool tool)
for (String suppFile : localToolDir.list())
{
final String basename = new File(suppFile).getName();
if (!basename.startsWith(".") && !basename.equals(tool.getZipName()) && !basename.equals("icon.png"))
if (!basename.startsWith(".") && !basename.equals(tool.getZipName()) && !basename.equals("icon.png") && !basename.equals("docs"))
suppFiles.add(suppFile);
}
return suppFiles;
Expand Down Expand Up @@ -583,9 +617,19 @@ else if (!getContainer().hasPermission(getUser(), InsertPermission.class))
{
Container c = makeContainer(getContainer(), folderName, toolOwnersUsers, RoleManager.getRole(EditorRole.class));
copyContainerPermissions(existingVersionContainer, c);
zip.transferTo(makeFile(c, zip.getOriginalFilename()));
File storedZip = makeFile(c, zip.getOriginalFilename());
zip.transferTo(storedZip);
tool.writeIconToFile(makeFile(c, "icon.png"), "png");

// Extract docs from tool-inf/docs/ in the ZIP; carry forward from previous version if absent
boolean hasDocs = extractDocsFromZip(storedZip, getLocalPath(c));
if (!hasDocs && existingVersionContainer != null)
{
File oldDocs = new File(getLocalPath(existingVersionContainer), "docs");
if (oldDocs.isDirectory())
FileUtils.copyDirectory(oldDocs, new File(getLocalPath(c), "docs"));
}

if (copyFiles != null && existingVersionContainer != null)
for (String copyFile : copyFiles)
FileUtils.copyFile(makeFile(existingVersionContainer, copyFile), makeFile(c, copyFile), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,16 @@ public String getFolderUrl()
return AppProps.getInstance().getContextPath() + "/files" + lookupContainer().getPath() + "/";
}

public boolean hasDocumentation()
{
return new File(SkylineToolsStoreController.getLocalPath(lookupContainer()), "docs/index.html").exists();
}

public String getDocsUrl()
{
return AppProps.getInstance().getContextPath() + "/_webdav" + lookupContainer().getPath() + "/@files/docs/index.html";
}

public String getIconUrl()
{
return (SkylineToolsStoreController.makeFile(lookupContainer(), "icon.png").exists()) ?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<%@ page import="org.apache.commons.lang3.StringUtils" %>
<%@ page import="org.labkey.api.data.Container" %>
<%@ page import="org.labkey.api.data.ContainerManager" %>
<%@ page import="org.labkey.api.portal.ProjectUrls" %>
<%@ page import="org.labkey.api.security.permissions.DeletePermission" %>
<%@ page import="org.labkey.api.security.permissions.InsertPermission" %>
Expand Down Expand Up @@ -299,7 +301,17 @@ a { text-decoration: none; }
</div>

<button id="tool-support-board-btn" class="banner-button-small">Support Board</button>
<% addHandler("tool-support-board-btn", "click", "window.open(" + q(urlProvider(ProjectUrls.class).getBeginURL(getContainer().getChild("Support").getChild(tool.getName()))) + ", '_blank', 'noopener,noreferrer')"); %>
<%
Container supportContainer = getContainer().getChild("Support");
Container toolSupportBoard = supportContainer != null ? supportContainer.getChild(tool.getName()) : null;
Container supportTarget;
if (toolSupportBoard != null)
supportTarget = toolSupportBoard;
else
supportTarget = ContainerManager.getForPath("/home/support");
if (supportTarget != null)
addHandler("tool-support-board-btn", "click", "window.open(" + q(urlProvider(ProjectUrls.class).getBeginURL(supportTarget)) + ", '_blank', 'noopener,noreferrer')");
%>
Comment on lines 303 to +314
</div>
<% if (toolEditor) { %>
<div class="menuMouseArea sprocket">
Expand Down Expand Up @@ -332,9 +344,17 @@ a { text-decoration: none; }
</div>
</div>

<% if (suppIter.hasNext()) { %>
<% if (tool.hasDocumentation() || suppIter.hasNext()) { %>
<div id="documentationbox" class="itemsbox">
<legend>Documentation</legend>
<% if (tool.hasDocumentation()) { %>
Comment on lines +347 to +350
<div class="barItem">
<a href="<%=h(tool.getDocsUrl())%>" target="_blank" rel="noopener noreferrer">
<img src="<%= h(imgDir) %>link.png" alt="Documentation" />
<span>Online Documentation</span>
</a>
</div>
<% } %>
<%
while (suppIter.hasNext()) {
Map.Entry suppPair = (Map.Entry)suppIter.next();
Expand Down
Loading