c6d419ecfb6f122d7a0cb99c37f56c32c089bea3 chmalee Thu Jan 22 10:41:38 2026 -0800 HubSpace changes: Allow users to overwrite already uploaded files, but warn them first. When a hub.txt file is being uploaded, don't auto-generate one. Check if the tracks being uploaded already exist in the hub.txt before adding a default stanza for it. Add some more checks in the hook files to prevent faulty uploads. Have the tus client clear localStorage on successful uploads so re-uploads of the same file don't cause confusing errors diff --git src/hg/hgHubConnect/hooks/pre-create.c src/hg/hgHubConnect/hooks/pre-create.c index 08dcaf05702..f9036839edc 100644 --- src/hg/hgHubConnect/hooks/pre-create.c +++ src/hg/hgHubConnect/hooks/pre-create.c @@ -75,59 +75,73 @@ // maybe an apiKey was provided, use that instead to look up the userName char *apiKey = jsonQueryString(req, "", "Event.Upload.MetaData.apiKey", NULL); if (!apiKey) { errAbort("You are not logged in. Please navigate to My Data -> My Sessions and log in or create an account."); } else { userName = userNameForApiKey(NULL, apiKey); if (!userName) errAbort("You are not logged in. Please navigate to My Data -> My Sessions and log in or create an account."); } } fprintf(stderr, "userName='%s'\n'", userName); long reqFileSize = jsonQueryInt(req, "", "Event.Upload.Size", 0, NULL); + // Check multiple possible metadata keys for filename (Uppy sends 'filename' and 'name' by default, + // our JS code also sets 'fileName' - try all to handle resumed uploads with old metadata) char *reqFileName = jsonQueryString(req, "", "Event.Upload.MetaData.fileName", NULL); + if (!reqFileName) + reqFileName = jsonQueryString(req, "", "Event.Upload.MetaData.filename", NULL); + if (!reqFileName) + reqFileName = jsonQueryString(req, "", "Event.Upload.MetaData.name", NULL); + if (!reqFileName) + { + errAbort("No filename found in upload metadata (checked fileName, filename, and name)"); + } char *reqParentDir = jsonQueryString(req, "", "Event.Upload.MetaData.parentDir", NULL); boolean isHubToolsUpload = FALSE; char *hubtoolsStr = jsonQueryString(req, "", "Event.Upload.MetaData.hubtools", NULL); if (hubtoolsStr) isHubToolsUpload = sameString(hubtoolsStr, "TRUE") || sameString(hubtoolsStr, "true"); + // Check for allowOverwrite metadata from JavaScript (for hub.txt overwrites) + char *allowOverwriteStr = jsonQueryString(req, "", "Event.Upload.MetaData.allowOverwrite", NULL); + boolean allowOverwrite = (allowOverwriteStr && (sameString(allowOverwriteStr, "TRUE") || sameString(allowOverwriteStr, "true"))); + boolean forceOverwrite = isHubToolsUpload || allowOverwrite; long currQuota = checkUserQuota(userName); long newQuota = currQuota + reqFileSize; long maxQuota = getMaxUserQuota(userName); if (newQuota > maxQuota) { errAbort("File '%s' is too large, need %s free space but current used space is %s out of %s", reqFileName, prettyFileSize(reqFileSize), prettyFileSize(currQuota), prettyFileSize(maxQuota)); } char *reqFileType = jsonQueryString(req, "", "Event.Upload.MetaData.fileType", NULL); if (!isFileTypeRecognized(reqFileType)) { errAbort("File type '%s' for file '%s' is not accepted at this time", reqFileType, reqFileName); } char *reqGenome = jsonQueryString(req, "", "Event.Upload.MetaData.genome", NULL); if (!reqGenome) { errAbort("Genome selection is NULL for file '%s' is invalid. Please choose the correct genome", reqFileName); } // we've passed all the checks so we can return that we are good to upload the file if (exitStatus == 0) { // set the location of the upload to the location it will ultimately live - char *location = setUploadPath(userName, reqFileName, reqParentDir, isHubToolsUpload); + char *location = setUploadPath(userName, reqFileName, reqParentDir, forceOverwrite); if (!location) { errAbort("Error setting upload path in pre-create for file '%s'. This is an" " issue with our server, please email genome-www@soe.ucsc.edu with your" " userName so we can investigate.", reqFileName); } struct hash *changeObjHash = hashNew(0); struct hash *pathObjHash = hashNew(0); struct jsonElement *changeObj = newJsonObject(changeObjHash); struct jsonElement *pathObj = newJsonObject(pathObjHash); jsonObjectAdd(pathObj, "Path", newJsonString(location)); jsonObjectAdd(changeObj, "Storage", pathObj); jsonObjectAdd(changeObj, "ID", newJsonString(makeRandomKey(128))); jsonObjectAdd(response, "ChangeFileInfo", changeObj);