b508259e8ce75a2aa1f919b8152befea99a2e1df chmalee Fri Jan 27 10:31:59 2023 -0800 Prototype download track data button. An hg.conf controlled button that allows users to download all of the track data in the current window without leaving hgTracks, refs #30024 diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index 14fce17..f0ed181 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -432,65 +432,73 @@ if (itemsDone >= maxItemsOutput) reachedMaxItems = TRUE; } else itemsDone += wigDataOutput(jw, bwf, chrom, start, end); itemsReturned += itemsDone; } static void getHubTrackData(char *hubUrl) /* return data from a hub track, optionally just one chrom data, * optionally just one section of that chrom data */ { char *genome = cgiOptionalString("genome"); -char *track = cgiOptionalString("track"); +char *trackArg = cgiOptionalString("track"); char *chrom = cgiOptionalString("chrom"); char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); if (isEmpty(genome)) apiErrAbort(err400, err400Msg, "missing genome=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); -if (isEmpty(track)) +if (isEmpty(trackArg)) apiErrAbort(err400, err400Msg, "missing track=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); struct trackHub *hub = errCatchTrackHubOpen(hubUrl); struct trackHubGenome *hubGenome = findHubGenome(hub, genome, "/getData/track", hubUrl); struct trackDb *tdb = obtainTdb(hubGenome, NULL); if (NULL == tdb) apiErrAbort(err400, err400Msg, "failed to find a track hub definition in genome=%s for endpoint '/getData/track' given hubUrl='%s'", genome, hubUrl); +struct jsonWrite *jw = apiStartOutput(); +jsonWriteString(jw, "hubUrl", hubUrl); +jsonWriteString(jw, "genome", genome); + +// allow optional comma sep list of tracks +char *tracks[100]; +int numTracks = chopByChar(trackArg, ',', tracks, sizeof(tracks)); +int i = 0; +for (i = 0; i < numTracks; i++) + { + char *track = cloneString(tracks[i]); struct trackDb *thisTrack = findTrackDb(track, tdb); if (NULL == thisTrack) apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); if (trackHasNoData(thisTrack)) apiErrAbort(err400, err400Msg, "container track '%s' does not contain data, use the children of this container for data access", track); if (! isSupportedType(thisTrack->type)) apiErrAbort(err415, err415Msg, "track type '%s' for track=%s not supported at this time", thisTrack->type, track); char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl); if (NULL == bbi) apiErrAbort(err400, err400Msg, "track type %s management not implemented yet TBD track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", thisTrack->type, track, genome, hubUrl); -struct jsonWrite *jw = apiStartOutput(); -jsonWriteString(jw, "hubUrl", hubUrl); -jsonWriteString(jw, "genome", genome); unsigned chromSize = 0; struct bbiChromInfo *chromList = NULL; if (isNotEmpty(chrom)) { chromSize = bbiChromSize(bbi, chrom); if (0 == chromSize) apiErrAbort(err400, err400Msg, "can not find specified chrom=%s in bigBed file URL '%s', track=%s genome=%s for endpoint '/getData/track' given hubUrl='%s'", chrom, bigDataUrl, track, genome, hubUrl); jsonWriteNumber(jw, "chromSize", (long long)chromSize); } else { chromList = bbiChromList(bbi); jsonWriteNumber(jw, "chromCount", (long long)slCount(chromList)); } @@ -532,71 +540,73 @@ else itemsDone += bbiDataOutput(jw, bbi, chrom, uStart, uEnd, fiList, thisTrack, itemsDone); itemsReturned += itemsDone; jsonWriteListEnd(jw); } else if (startsWith("bigWig", thisTrack->type)) { if (jsonOutputArrays || debug) wigColumnTypes(jw); jsonWriteObjectStart(jw, track); bigWigData(jw, bbi, chrom, uStart, uEnd); jsonWriteObjectEnd(jw); } bbiFileClose(&bbi); + } apiFinishOutput(0, NULL, jw); } /* static void getHubTrackData(char *hubUrl) */ static void getTrackData() /* return data from a track, optionally just one chrom data, * optionally just one section of that chrom data */ { char *db = cgiOptionalString("genome"); char *chrom = cgiOptionalString("chrom"); char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); /* 'track' name in trackDb often refers to a SQL 'table' */ char *trackArg = cgiOptionalString("track"); -char *sqlTable = cloneString(trackArg); /* might be something else */ +//char *sqlTable = cloneString(trackArg); /* might be something else */ /* depends upon 'table' setting in track db, or split table business */ unsigned chromSize = 0; /* maybe set later */ unsigned uStart = 0; unsigned uEnd = chromSize; /* maybe set later */ if ( ! (isEmpty(start) || isEmpty(end)) ) { uStart = sqlUnsigned(start); uEnd = sqlUnsigned(end); if (uEnd < uStart) apiErrAbort(err400, err400Msg, "given start coordinate %u is greater than given end coordinate", uStart, uEnd); } if (isEmpty(db)) apiErrAbort(err400, err400Msg, "missing URL variable genome=<ucscDb> name for endpoint '/getData/track"); if (isEmpty(trackArg)) apiErrAbort(err400, err400Msg, "missing URL variable track=<trackName> name for endpoint '/getData/track"); /* database existence has already been checked before now, might * have disappeared in the mean time (well, not really . . .) */ struct sqlConnection *conn = hAllocConnMaybe(db); if (NULL == conn) apiErrAbort(err400, err400Msg, "can not find genome 'genome=%s' for endpoint '/getData/track", db); struct jsonWrite *jw = apiStartOutput(); +jsonWriteString(jw, "genome", db); // load the tracks struct trackDb *tdbList = NULL; cartTrackDbInitForApi(NULL, db, &tdbList, NULL, FALSE); // allow optional comma sep list of tracks char *tracks[100]; int numTracks = chopByChar(trackArg, ',', tracks, sizeof(tracks)); int i = 0; for (i = 0; i < numTracks; i++) { char *track = cloneString(tracks[i]); char *sqlTable = cloneString(track); struct trackDb *thisTrack = tdbForTrack(db, track, &tdbList); @@ -652,31 +662,30 @@ char *defaultChrom = hDefaultChrom(db); char fullTableName[256]; safef(fullTableName, sizeof(fullTableName), "%s_%s", defaultChrom, hti->rootName); splitSqlTable = cloneString(fullTableName); } } if (! hTableOrSplitExists(db, sqlTable)) { if (! bigDataUrl) apiErrAbort(err400, err400Msg, "can not find specified 'track=%s' for endpoint: /getData/track?genome=%s;track=%s", track, db, track); else tableTrack = FALSE; } - jsonWriteString(jw, "genome", db); if (tableTrack) { char *dataTime = NULL; if (hti && hti->isSplit) dataTime = sqlTableUpdate(conn, splitSqlTable); else dataTime = sqlTableUpdate(conn, sqlTable); time_t dataTimeStamp = sqlDateToUnixTime(dataTime); replaceChar(dataTime, ' ', 'T'); /* ISO 8601 */ jsonWriteString(jw, "dataTime", dataTime); jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp); if (differentStringNullOk(sqlTable,track)) jsonWriteString(jw, "sqlTable", sqlTable); } if (thisTrack)