Skip to content

Commit 5d022a8

Browse files
committed
Firefly-1815: upload a file via an action, usally firefly_client
- includes clean up and response to feedback
1 parent 4ac2ac5 commit 5d022a8

File tree

14 files changed

+343
-150
lines changed

14 files changed

+343
-150
lines changed

src/firefly/java/edu/caltech/ipac/firefly/server/servlets/AnyFileUpload.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,14 @@ public class AnyFileUpload extends BaseHttpServlet {
6363
private static final String WORKSPACE_PUT = "workspacePut";
6464
private static final String WS_CMD = "wsCmd";
6565
public static final String ANALYZER_ID = "analyzerId";
66+
public static final String NAME = "name";
6667
/** use the hips cache hierarchy */
6768
public static final String HIPS_CACHE = "hipsCache";
6869
/** load from a URL */
6970
private static final String URL = "URL";
7071
/** load from a WebPlotRequest */
7172
private static final String WEB_PLOT_REQUEST = "webPlotRequest";
73+
private static final String FILE_ON_SERVER = "fileOnServer";
7274
/** run file analysis and return an analysis json object */
7375
private static final String FILE_ANALYSIS= "fileAnalysis";
7476

@@ -116,7 +118,7 @@ public static void doFileUpload(HttpServletRequest req, HttpServletResponse res)
116118
int responseCode= statusFileInfo.getResponseCode();
117119

118120
if (responseCode>=400) {
119-
res.sendError(statusFileInfo.getResponseCode(), statusFileInfo.getResponseCodeMsg());
121+
res.sendError(responseCode, statusFileInfo.getResponseCodeMsg());
120122
return;
121123
}
122124

@@ -144,7 +146,6 @@ public static void doFileUpload(HttpServletRequest req, HttpServletResponse res)
144146

145147
// returns the fileCacheKey or full analysis json
146148
String returnVal= analyzeFile ? callAnalysis(sp,statusFileInfo,uploadFileInfo,fileCacheKey) : fileCacheKey;
147-
if (responseCode>=400) throw new Exception(codeFailMsg(responseCode));
148149

149150
sendReturnMsg(res, 200, null, returnVal);
150151
Counters.getInstance().increment(Counters.Category.Upload, uploadFileInfo.getContentType());
@@ -175,7 +176,7 @@ private static boolean isUrlFail(FileInfo statusFileInfo) {
175176
private static UploadFileInfo makeUploadFileInfo(FileInfo statusFileInfo, String fname) {
176177
File file= statusFileInfo.getFile();
177178
return new UploadFileInfo(ServerContext.replaceWithPrefix(file), file, fname!=null ? fname : file.getName(),
178-
statusFileInfo.getContentType());
179+
statusFileInfo.getContentType(), statusFileInfo.getResponseCode());
179180
}
180181

181182
private static void updateFeedback(String statusKey, long totalRead) {
@@ -225,6 +226,7 @@ private static Result retrieveFile(SrvParam sp, FileItemStream uploadedItem) thr
225226
String wsCmd = sp.getOptional(WS_CMD);
226227
String fromUrl = sp.getOptional(URL);
227228
WebPlotRequest fromWPR= sp.getOptionalWebPlotRequest(WEB_PLOT_REQUEST);
229+
String fileOnServer= sp.getOptional(FILE_ON_SERVER);
228230
boolean hipsCache = sp.getOptionalBoolean(HIPS_CACHE,false);
229231

230232
UploadFileInfo uploadFileInfo;
@@ -254,6 +256,14 @@ private static Result retrieveFile(SrvParam sp, FileItemStream uploadedItem) thr
254256
if (retrieve==null) throw new Exception("Could not determine how to retrieve file");
255257
statusFileInfo = retrieve.getFile(fromWPR,false);
256258
uploadFileInfo= makeUploadFileInfo(statusFileInfo,null);
259+
} else if (fileOnServer != null) {
260+
File f= ServerContext.convertToFile(fileOnServer);
261+
if (!f.canRead()) {
262+
return new Result(new FileInfo(404),null);
263+
}
264+
String name= sp.getOptional(NAME,f.getName());
265+
uploadFileInfo= new UploadFileInfo(fileOnServer, f,name,null);
266+
statusFileInfo= new FileInfo(uploadFileInfo.getFile());
257267
} else if (uploadedItem != null) {
258268
// it's a stream from multipart.. write it to disk
259269
String name = uploadedItem.getName();

src/firefly/java/edu/caltech/ipac/firefly/server/util/multipart/UploadFileInfo.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
*/
44
package edu.caltech.ipac.firefly.server.util.multipart;
55

6+
import edu.caltech.ipac.firefly.data.FileInfo;
7+
68
import java.io.File;
79
import java.io.Serializable;
810

@@ -17,13 +19,27 @@ public class UploadFileInfo implements Serializable {
1719
private File file;
1820
private String fileName;
1921
private String contentType;
22+
private int responseCode;
2023
private long size;
24+
private transient FileInfo fileInfo;
25+
26+
public UploadFileInfo(String pname, File file, String fileName, String contentType, int responseCode) {
27+
this.pname = pname;
28+
this.file = file;
29+
this.fileName = fileName;
30+
this.contentType = contentType;
31+
this.responseCode = responseCode;
32+
if (file != null && file.exists()) {
33+
size = file.length();
34+
}
35+
}
2136

2237
public UploadFileInfo(String pname, File file, String fileName, String contentType) {
2338
this.pname = pname;
2439
this.file = file;
2540
this.fileName = fileName;
2641
this.contentType = contentType;
42+
this.responseCode = 200;
2743
if (file != null && file.exists()) {
2844
size = file.length();
2945
}
@@ -53,6 +69,8 @@ public void setFileName(String fileName) {
5369
this.fileName = fileName;
5470
}
5571

72+
public int getResponseCode() {return responseCode;}
73+
5674
@Override
5775
public String toString() {
5876
return "FileEntry{" + fileName + "[" + size + "]}";

src/firefly/js/api/webApiCommands/ImageCommands.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const imageOverview= {
2121
],
2222
allowAdditionalParameters: true,
2323
parameters: {
24-
url : 'URL of the FITS image',
24+
url : 'URL to the FITS image',
2525
title : 'title to show',
2626
service : 'one of IRIS, ISSA, DSS, SDSS, TWOMASS, MSX-ATLAS, WISE, ATLAS,ZTF, PTF',
2727
SurveyKey : [

src/firefly/js/api/webApiCommands/ViewerWebApiCommands.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {isEmpty} from 'lodash';
2+
import {getAnyFileLoadCommands} from './AnyFileLoadCommands';
23
import {getImageCommands} from './ImageCommands';
34
import {getLsdbCommands} from './LsdbCommands';
45
import {getTabCommands} from './TabCommands';
@@ -16,7 +17,8 @@ export function getFireflyViewerWebApiCommands(cmdNameList, tapPanelList=[]) {
1617
...getImageCommands(),
1718
...getTableCommands(),
1819
...getTapCommands(tapPanelList),
19-
...getLsdbCommands()
20+
...getLsdbCommands(),
21+
...getAnyFileLoadCommands()
2022
];
2123

2224
if (isEmpty(cmdNameList)) return allCommands;

src/firefly/js/core/AppDataCntlr.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const LOAD_SEARCHES = `${APP_DATA_PATH}.loadSearches`;
3737
export const NOTIFY_REMOTE_APP_READY = `${APP_DATA_PATH}.notifyRemoteAppReady`;
3838
export const FORM_SUBMIT = `${APP_DATA_PATH}.formSubmit`;
3939
export const FORM_CANCEL = `${APP_DATA_PATH}.formCancel`;
40+
export const EXTERNAL_UPLOAD = `${APP_DATA_PATH}.externalUpload`;
4041

4142
/** fired when there's a connection is added/removed from this channel. useful for tracking connections in channel, etc */
4243
export const WS_CONN_UPDATED = `${APP_DATA_PATH}.wsConnUpdated`;
@@ -46,7 +47,7 @@ export const GRAB_WINDOW_FOCUS = `${APP_DATA_PATH}.grabFocus`;
4647

4748
/** the extension to add to a channel string to make a viewer channel */
4849
const CHANNEL_VIEWER_EXTENSION = '__viewer';
49-
const channel_matcher = new RegExp(`(.+)${CHANNEL_VIEWER_EXTENSION}(?:-(.+))?`)
50+
const channel_matcher = new RegExp(`(.+)${CHANNEL_VIEWER_EXTENSION}(?:-(.+))?`);
5051

5152
/** @type {SearchInfo} */
5253
const searchInfo = {};
@@ -209,6 +210,7 @@ export function dispatchFormCancel(payload) {
209210
/**
210211
* Given a channel string return a version of the will be the channel for a viewer
211212
* @param {String} channel
213+
* @param {String} file
212214
* @return {string}
213215
*/
214216
export function makeViewerChannel(channel, file) {

src/firefly/js/core/BootstrapRegistry.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import ImageLineBasedFootprint from '../drawingLayers/ImageLineBasedFootprint.js
5555
import {dispatchAddSaga, masterSaga} from './MasterSaga.js';
5656
import {watchReadout} from '../visualize/saga/MouseReadoutWatch.js';
5757
import {addExtensionWatcher} from './messaging/ExternalAccessWatcher.js';
58+
import {initHandleExternalUpload} from '../ui/FileUploadProcessor';
5859

5960

6061
const USE_LOGGING_MIDDLEWARE= false; // logging middleware is useful for debugging but we don't use if much
@@ -132,6 +133,7 @@ export const getBootstrapRegistry= once(() => {
132133
sagaMiddleware.run(masterSaga);
133134
dispatchAddSaga( watchReadout);
134135
addExtensionWatcher();
136+
initHandleExternalUpload();
135137
};
136138

137139
const registerCntlr= (cntlr = {}) => {

src/firefly/js/rpc/CoreServices.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55

6-
import {isString} from 'lodash';
6+
import {isEmpty, isString} from 'lodash';
77
import {ServerParams} from '../data/ServerParams.js';
88
import {doJsonRequest} from '../core/JsonUtils.js';
99
import {WebPlotRequest} from '../visualize/WebPlotRequest';
@@ -52,7 +52,7 @@ export function getTextFile(url,maxSize) {
5252
* @return {Promise}
5353
*/
5454
export async function upload(item, fileAnalysis= false, params={}) {
55-
const fetchParam= item && buildUploadParam(item);
55+
const fetchParam= (item || !isEmpty(params)) && buildUploadParam(item, params);
5656
if (!fetchParam) {
5757
const msg= item ? 'Did not recognize item to upload: must be URL (String), File, Blob, or WebPlotRequest' :
5858
'item parameter not given';
@@ -66,11 +66,17 @@ export async function upload(item, fileAnalysis= false, params={}) {
6666
/**
6767
* return the correct upload parameter based on the type that is passed
6868
* @param {WebPlotRequest|Blob|File|String} item - the parameter to evaluate
69+
* @param {Object} [params] - this will override the analysis of item
6970
* @return {Object|undefined} an object with the correct parameter to pass to the upload,
7071
* or undefined if it is not the correct parameter type
7172
*/
72-
function buildUploadParam(item) {
73-
if (isString(item)) return {URL: item};
73+
function buildUploadParam(item, params={}) {
74+
const overrideKeys= ['URL', 'fileOnServer', 'file', 'webPlotRequest'];
75+
const overrideUploadParamKey= Object.keys(params).find( (k) => overrideKeys.includes(k));
76+
if (overrideUploadParamKey) return {[overrideUploadParamKey]:params[overrideUploadParamKey]};
77+
if (isString(item)) {
78+
return (item.startsWith('${') || item.startsWith('/')) ? {fileOnServer:item} : {URL: item};
79+
}
7480
else if (WebPlotRequest.isWPR(item)) return {webPlotRequest: item.toString()};
7581
else if (item instanceof Blob) return {file:item}; // handles blob or file
7682
}

src/firefly/js/ui/FileUpload.jsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,13 @@ function doUrlAnalysis(value, fireValueChange, type, fileAnalysis) {
158158

159159
function handleChange(ev, fireValueChange, type, fileAnalysis) {
160160
let file = ev?.target?.files?.[0];
161-
let displayValue = ev?.target?.value;
162-
if (ev.type === 'drop') { //drag drop files - instead of picking file from 'Choose File'
163-
file = Array.from(ev.dataTransfer.files)[0];
164-
displayValue = file?.name;
161+
let displayValue;
162+
if (ev) {
163+
displayValue = ev.target?.value;
164+
if (ev.type === 'drop') { //drag drop files - instead of picking file from 'Choose File'
165+
file = Array.from(ev.dataTransfer.files)[0];
166+
displayValue = ev.transferIsUrl ? ev?.dataTransfer?.files?.[0] : file?.name;
167+
}
165168
}
166169
fireValueChange({
167170
displayValue,

src/firefly/js/ui/FileUploadDropdown.jsx

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,29 @@
22
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
33
*/
44

5-
import {Box, Skeleton} from '@mui/joy';
65
import React, {useState} from 'react';
7-
import {FormPanel} from './FormPanel.jsx';
8-
import {FileUploadViewPanel, resultFail} from '../visualize/ui/FileUploadViewPanel.jsx';
6+
import {Box, Skeleton} from '@mui/joy';
97
import {getAppOptions} from 'firefly/api/ApiUtil.js';
10-
import DialogRootContainer from 'firefly/ui/DialogRootContainer.jsx';
118
import {dispatchHideDialog, dispatchShowDialog} from 'firefly/core/ComponentCntlr.js';
12-
import {PopupPanel} from 'firefly/ui/PopupPanel.jsx';
13-
import {resultSuccess} from 'firefly/ui/FileUploadProcessor';
9+
import DialogRootContainer from 'firefly/ui/DialogRootContainer.jsx';
1410
import {FieldGroup} from 'firefly/ui/FieldGroup';
15-
import {DATA_LINK_TABLES, IMAGES, MOC_TABLES, REGIONS, SPECTRUM_TABLES, TABLES, UWS} from 'firefly/ui/FileUploadUtil';
11+
import {defaultAcceptList, resultSuccess} from 'firefly/ui/FileUploadProcessor';
12+
import {TABLES} from 'firefly/ui/FileUploadUtil';
13+
import {PopupPanel} from 'firefly/ui/PopupPanel.jsx';
14+
import {FileUploadViewPanel, resultFail} from '../visualize/ui/FileUploadViewPanel.jsx';
15+
import {FormPanel} from './FormPanel.jsx';
1616

1717
const panelKey = 'FileUploadAnalysis';
18-
19-
const defaultAcceptList = [
20-
TABLES,
21-
REGIONS,
22-
DATA_LINK_TABLES,
23-
SPECTRUM_TABLES,
24-
MOC_TABLES,
25-
IMAGES,
26-
UWS
27-
];
28-
29-
const tableOnlyDefaultAcceptList = [
30-
TABLES
31-
];
18+
const tableOnlyDefaultAcceptList = [ TABLES ];
3219

3320
export const FileUploadDropdown= ({sx, onCancel, onSubmit=resultSuccess, keepState=true,
3421
initArgs,
35-
groupKey=panelKey, acceptList= getAppOptions()?.uploadPanelLimit==='tablesOnly'?
36-
tableOnlyDefaultAcceptList: defaultAcceptList, acceptOneItem=false}) =>{
22+
groupKey=panelKey,
23+
acceptOneItem=false,
24+
acceptList= getAppOptions()?.uploadPanelLimit==='tablesOnly'
25+
? tableOnlyDefaultAcceptList
26+
: defaultAcceptList,
27+
}) =>{
3728
const [submitText,setSubmitText]= useState('Load');
3829
const [doMask, changeMasking]= useState(() => false);
3930
const helpId = getAppOptions()?.uploadPanelHelpId ?? 'basics.searching';
@@ -56,7 +47,7 @@ export const FileUploadDropdown= ({sx, onCancel, onSubmit=resultSuccess, keepSta
5647
}}>
5748

5849
<FileUploadViewPanel {...{setSubmitText, acceptList, acceptOneItem,
59-
externalDropEvent:initArgs?.searchParams?.dropEvent}}/>
50+
externalDropEvent:initArgs?.searchParams?.dropEvent, initArgs}}/>
6051
</FormPanel>
6152
</FieldGroup>
6253
{ doMask && <Skeleton sx={{inset:0, zIndex:10}}/> }

0 commit comments

Comments
 (0)