Skip to content

Commit

Permalink
Support browsing html files with relative links
Browse files Browse the repository at this point in the history
  • Loading branch information
lukfor committed Mar 6, 2024
1 parent 694bda4 commit a419dd7
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
{{/files}}</textarea><br>
<small>Use the following command to download all results at once:</small>
<div class="input-group mb-3">
<input id="curl" value="curl -sL {{hostname}}/get/{{id}}/{{hash}} | bash" class="form-control form-control-sm code-font" />
<input id="curl" value="curl -sL {{hostname}}/get/{{hash}} | bash" class="form-control form-control-sm code-font" />
<div class="input-group-append">
<button class="btn btn-outline-secondary btn-sm" id="btn-copy" type="button" data-toggle="tooltip" data-placement="bottom" title="Copy to clipboard"><i class="far fa-copy"></i></button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/main/html/webapp/helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function renderTreeItem(jobId, items, level) {
html += renderTreeItem(jobId, items[i].childs, level + 1);
} else {
html += '<i class="far fa-file-alt text-muted fa-fw file-item-icon""></i>&nbsp;'
html += '<a class="file-item" href="downloads/' + jobId + '/' + items[i].hash + '/' + items[i].name + '" target="_blank">' + items[i].name + '</a>';
html += '<a class="file-item" href="' + items[i].path + '" target="_blank">' + items[i].name + '</a>';
html += '&nbsp;&nbsp;&nbsp;&nbsp;<span class="text-muted">(' + items[i].size + ")</span>";
}
html += "</li>";
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/cloudgene/mapred/CommandLineInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private void printHeader() {
System.out.println();
System.out.println("Cloudgene " + Application.VERSION);
System.out.println("http://www.cloudgene.io");
System.out.println("(c) 2009-2032 Lukas Forer and Sebastian Schoenherr");
System.out.println("(c) 2009-2024 Lukas Forer and Sebastian Schoenherr");
System.out.println();
}

Expand Down
30 changes: 29 additions & 1 deletion src/main/java/cloudgene/mapred/database/DownloadDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,35 @@ public Download findByJobAndPath(String job, String path) {
}
}

class DownloadMapper implements IRowMapper {
public Download findByParameterAndName(CloudgeneParameterOutput param, String filename) {
StringBuilder sql = new StringBuilder();
sql.append("select * ");
sql.append("from downloads ");
sql.append("where name = ? and parameter_id = ? ");
sql.append("order by path ");

Object[] params = new Object[2];
params[0] = filename;
params[1] = param.getId();

Download result = null;

try {

result = (Download) queryForObject(sql.toString(), params,
new DownloadMapper());

log.debug("find download by param " + param.getId() + " and path " + filename
+ " successful. results: " + result);

return result;
} catch (SQLException e) {
log.error("find download by job and path failed.", e);
return null;
}
}

class DownloadMapper implements IRowMapper {

@Override
public Object mapRow(ResultSet rs, int row) throws SQLException {
Expand Down
71 changes: 65 additions & 6 deletions src/main/java/cloudgene/mapred/database/ParameterDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public ParameterDao(Database database) {

public boolean insert(CloudgeneParameterInput parameter) {
StringBuilder sql = new StringBuilder();
sql.append("insert into parameter (name, `value`, input, job_id, type, variable, download, format, admin_only) ");
sql.append("values (?,?,?,?,?,?,?,?,?)");
sql.append("insert into parameter (name, `value`, input, job_id, type, variable, download, format, admin_only, hash) ");
sql.append("values (?,?,?,?,?,?,?,?,?,?)");

try {

Object[] params = new Object[9];
Object[] params = new Object[10];
if (parameter.getDescription() != null) {
params[0] = parameter.getDescription().substring(0, Math.min(parameter.getDescription().length(), 100));
} else {
Expand All @@ -47,6 +47,7 @@ public boolean insert(CloudgeneParameterInput parameter) {
params[6] = false;
params[7] = "";
params[8] = parameter.isAdminOnly();
params[9] = parameter.getHash();

int paramId = insert(sql.toString(), params);
parameter.setId(paramId);
Expand All @@ -63,12 +64,12 @@ public boolean insert(CloudgeneParameterInput parameter) {

public boolean insert(CloudgeneParameterOutput parameter) {
StringBuilder sql = new StringBuilder();
sql.append("insert into parameter (name, `value`, input, job_id, type, variable, download, format, admin_only) ");
sql.append("values (?,?,?,?,?,?,?,?,?)");
sql.append("insert into parameter (name, `value`, input, job_id, type, variable, download, format, admin_only, hash) ");
sql.append("values (?,?,?,?,?,?,?,?,?,?)");

try {

Object[] params = new Object[9];
Object[] params = new Object[10];
params[0] = parameter.getDescription().substring(0, Math.min(parameter.getDescription().length(), 100));
params[1] = parameter.getValue();
params[2] = false;
Expand All @@ -78,6 +79,7 @@ public boolean insert(CloudgeneParameterOutput parameter) {
params[6] = parameter.isDownload();
params[7] = "";
params[8] = parameter.isAdminOnly();
params[9] = parameter.getHash();

int paramId = insert(sql.toString(), params);
parameter.setId(paramId);
Expand Down Expand Up @@ -180,6 +182,61 @@ public CloudgeneParameterOutput findById(int id) {
}
}

public CloudgeneParameterOutput findByHash(String hash) {
StringBuilder sql = new StringBuilder();
sql.append("select * ");
sql.append("from parameter ");
sql.append("where hash = ?");

Object[] params = new Object[1];
params[0] = hash;

CloudgeneParameterOutput result = null;

try {

result = (CloudgeneParameterOutput) queryForObject(sql.toString(), params, new ParameterOutputMapper());

DownloadDao downloadDao = new DownloadDao(database);
List<Download> downloads = downloadDao.findAllByParameter(result);
result.setFiles(downloads);

log.debug("find parameter by hash '" + hash + "' successful.");

return result;
} catch (SQLException e) {
log.error("find parameter by hash '" + hash + "' failed.", e);
return null;
}
}

public List<CloudgeneParameterOutput> findAllOutput() {
StringBuilder sql = new StringBuilder();
sql.append("select * ");
sql.append("from parameter ");
sql.append("where input = false");

List<CloudgeneParameterOutput> result = new Vector<CloudgeneParameterOutput>();

try {

result = query(sql.toString(), new ParameterOutputMapper());

DownloadDao downloadDao = new DownloadDao(database);
for (CloudgeneParameterOutput parameter : result) {
List<Download> downloads = downloadDao.findAllByParameter(parameter);
parameter.setFiles(downloads);
}

log.debug("find all output parameters successful. results: " + result.size());

return result;
} catch (SQLException e) {
log.error("find all output parameters failed.", e);
return null;
}
}

class ParameterInputMapper implements IRowMapper {

@Override
Expand All @@ -192,6 +249,7 @@ public Object mapRow(ResultSet rs, int row) throws SQLException {
parameter.setType(WdlParameterInputType.getEnum(rs.getString("type")));
parameter.setId(rs.getInt("id"));
parameter.setAdminOnly(rs.getBoolean("admin_only"));
parameter.setHash(rs.getString("hash"));
return parameter;

}
Expand All @@ -211,6 +269,7 @@ public Object mapRow(ResultSet rs, int row) throws SQLException {
parameter.setDownload(rs.getBoolean("download"));
parameter.setId(rs.getInt("id"));
parameter.setAdminOnly(rs.getBoolean("admin_only"));
parameter.setHash(rs.getString("hash"));
return parameter;

}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/cloudgene/mapred/jobs/CloudgeneJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public CloudgeneJob(User user, String id, WdlApp app, Map<String, String> params
outputParams = new Vector<CloudgeneParameterOutput>();
for (WdlParameterOutput output : app.getWorkflow().getOutputs()) {
CloudgeneParameterOutput newOutput = new CloudgeneParameterOutput(output);
newOutput.initHash();
newOutput.setJob(this);
outputParams.add(newOutput);
}
Expand Down Expand Up @@ -93,6 +94,7 @@ protected void initLogOutput() {
logOutput.setName(CLOUDGENE_LOGS_PARAM);
logOutput.setType(WdlParameterOutputType.LOCAL_FOLDER);
logOutput.setJob(this);
logOutput.initHash();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class CloudgeneParameterInput {

private boolean adminOnly = false;

private String hash = "";

public CloudgeneParameterInput() {

}
Expand Down Expand Up @@ -97,4 +99,11 @@ public boolean isAdminOnly() {
return adminOnly;
}

public void setHash(String hash) {
this.hash = hash;
}

public String getHash() {
return hash;
}
}
18 changes: 12 additions & 6 deletions src/main/java/cloudgene/mapred/jobs/CloudgeneParameterOutput.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package cloudgene.mapred.jobs;

import java.util.List;
import java.util.Random;
import java.util.Vector;

import cloudgene.mapred.util.HashUtil;
import cloudgene.mapred.wdl.WdlParameterOutput;
import cloudgene.mapred.wdl.WdlParameterOutputType;
import org.apache.commons.math3.random.RandomGenerator;

public class CloudgeneParameterOutput {

Expand Down Expand Up @@ -141,13 +143,17 @@ public void setHash(String hash) {
public String getHash() {
return hash;
}

public String createHash() {
String hash = "";
for (Download download: files) {
hash += download.getHash();

public void initHash() {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
hash = "";
Random random = new Random();
int length = 40;
for (int i = 0; i < length; i++) {
int index = random.nextInt(alphabet.length());
char randomChar = alphabet.charAt(index);
hash += randomChar;
}
return HashUtil.getSha256(hash);
}

}
2 changes: 1 addition & 1 deletion src/main/java/cloudgene/mapred/server/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
@Context
public class Application {

public static final String VERSION = "3.0.0-beta4";
public static final String VERSION = "3.0.0-beta5";

private Database database;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,36 @@ public MutableHttpResponse<InputStream> downloadPublicLink(String hash, String f

}

@Get("/get/{paramId}/{hash}")
@Get("/browse/{hash}/{filename:.+}")
@Secured(SecurityRule.IS_ANONYMOUS)
public String downloadScript(String paramId, String hash) {

int id = -1;
try {
id = Integer.parseInt(paramId);
} catch (NumberFormatException e) {
throw new JsonHttpStatusException(HttpStatus.BAD_REQUEST, "Parameter ID is not numeric.");
}
public MutableHttpResponse<InputStream> downloadByParamHash(String hash, String filename)
throws URISyntaxException, IOException {

ParameterDao parameterDao = new ParameterDao(application.getDatabase());
CloudgeneParameterOutput param = parameterDao.findById(id);
CloudgeneParameterOutput param = parameterDao.findByHash(hash);

if (param == null) {
throw new JsonHttpStatusException(HttpStatus.NOT_FOUND, "Param " + param + " not found.");
throw new JsonHttpStatusException(HttpStatus.NOT_FOUND, "Param for hash " + hash + " not found.");
}

if (!hash.equals(param.createHash())) {
throw new JsonHttpStatusException(HttpStatus.FORBIDDEN, "Download forbidden.");
DownloadDao dao = new DownloadDao(application.getDatabase());
Download download = dao.findByParameterAndName(param, filename);

String message = String.format("Job: Anonymously downloading file '%s' (hash %s)", filename, hash);
log.info(message);
return downloadService.download(download);

}

@Get("/get/{hash}")
@Secured(SecurityRule.IS_ANONYMOUS)
public String downloadScript(String hash) {

ParameterDao parameterDao = new ParameterDao(application.getDatabase());
CloudgeneParameterOutput param = parameterDao.findByHash(hash);

if (param == null) {
throw new JsonHttpStatusException(HttpStatus.NOT_FOUND, "Param for hash " + hash + " not found.");
}

DownloadDao dao = new DownloadDao(application.getDatabase());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,7 @@ public static JobResponse build(AbstractJob job, User user) {

// create tree
for (CloudgeneParameterOutput param : job.getOutputParams()) {
String hash = param.createHash();
param.setHash(hash);
param.setTree(JobResultsTreeUtil.createTree(param.getFiles()));
param.setTree(JobResultsTreeUtil.createTree(param));
}

// removes outputs that are for admin only
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/cloudgene/mapred/util/JobResultsTreeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import java.util.List;
import java.util.Vector;

import cloudgene.mapred.jobs.CloudgeneParameterOutput;
import cloudgene.mapred.jobs.Download;
import cloudgene.mapred.jobs.JobResultsTreeItem;

public class JobResultsTreeUtil {

public static List<JobResultsTreeItem> createTree(List<Download> files) {
public static List<JobResultsTreeItem> createTree(CloudgeneParameterOutput param) {
List<JobResultsTreeItem> items = new Vector<JobResultsTreeItem>();
for (Download file : files) {
for (Download file : param.getFiles()) {
String[] tiles = file.getName().split("/");
JobResultsTreeItem root = null;
for (int i = 0; i < tiles.length - 1; i++) {
Expand All @@ -32,7 +33,11 @@ public static List<JobResultsTreeItem> createTree(List<Download> files) {
}
JobResultsTreeItem item = new JobResultsTreeItem();
item.setName(tiles[tiles.length - 1]);
item.setPath(file.getPath());
if (param.getHash() != null) {
item.setPath("/browse/" + param.getHash() + "/" + file.getName());
} else {
item.setPath("/share/results/" + file.getHash() + "/" + file.getName());
}
item.setHash(file.getHash());
item.setSize(file.getSize());
item.setFolder(false);
Expand Down
3 changes: 3 additions & 0 deletions src/main/sql/updates.sql
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,6 @@ alter table job add column user_agent VARCHAR (400);

-- 3.0.0-beta1
alter table `user` add column api_token_expires_on timestamp null default null;

-- 3.0.0-beta5
alter table `parameter` add column hash varchar(300) null default null;

0 comments on commit a419dd7

Please sign in to comment.