ade26bcbd0927eaae0c456182a97877752c0eb4a hiram Wed Aug 12 16:23:05 2026 -0700 fixup the web page system to function properly with modern hub syntax and fixing bugs from code review refs #38005 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index 0c2b7a75203..979e8fa8725 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -254,76 +254,83 @@ /* print out a sample getData URL */ { char errorPrint[2048]; errorPrint[0] = 0; if (isNotEmpty(errorString)) { safef(errorPrint, sizeof(errorPrint), " ERROR: %s", errorString); } boolean superChild = tdbIsSuperTrackChild(tdb); char *genome = NULL; if (hub) genome = hub->genomeList->name; +// tdb->track (and tdb->parent->track) carry the hub__ decoration; +// display and outgoing URLs should show/use the name as it actually +// appears in trackDb.txt. protectedTrack() below still needs the +// decorated tdb->track, untouched, to recognize a hub track. +char *trackName = trackHubSkipHubName(tdb->track); +char *parentName = tdb->parent ? trackHubSkipHubName(tdb->parent->track) : NULL; + struct dyString *extraDyFlags = dyStringNew(128); if (debug) dyStringAppend(extraDyFlags, ";debug=1"); if (jsonOutputArrays) dyStringAppend(extraDyFlags, ";jsonOutputArrays=1"); char *extraFlags = dyStringCannibalize(&extraDyFlags); if (protectedTrack(db, tdb, tdb->track)) - hPrintf("
  • %s : %s <protected data>
  • \n", tdb->track, tdb->type); + hPrintf("
  • %s : %s <protected data>
  • \n", trackName, tdb->type); else if (db) { if (hub) { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, trackName, extraFlags, errorPrint); if (tdb->parent) - hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); + hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", trackName, tdb->type, parentName, urlReference); else - hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference); + hPrintf("
  • %s: %s%s
  • \n", trackName, tdb->type, urlReference); } else { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, db, tdb->track, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, db, trackName, extraFlags, errorPrint); if (superChild) - hPrintf("
  • %s: %s superTrack child of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); + hPrintf("
  • %s: %s superTrack child of parent: %s%s
  • \n", trackName, tdb->type, parentName, urlReference); else if (tdb->parent) - hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); + hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", trackName, tdb->type, parentName, urlReference); else - hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference ); + hPrintf("
  • %s: %s%s
  • \n", trackName, tdb->type, urlReference ); } } else if (hub) { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, trackName, extraFlags, errorPrint); if (tdb->parent) - hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); + hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", trackName, tdb->type, parentName, urlReference); else - hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference); + hPrintf("
  • %s: %s%s
  • \n", trackName, tdb->type, urlReference); } else - hPrintf("
  • %s : %s not db hub track ?
  • \n", tdb->track, tdb->type); + hPrintf("
  • %s : %s not db hub track ?
  • \n", trackName, tdb->type); } static void hubSampleUrl(struct trackHub *hub, char *db, struct trackDb *tdb, long chromCount, long itemCount, char *genome, char *errorString) { struct dyString *extraDyFlags = dyStringNew(128); if (debug) dyStringAppend(extraDyFlags, ";debug=1"); if (jsonOutputArrays) dyStringAppend(extraDyFlags, ";jsonOutputArrays=1"); char *extraFlags = dyStringCannibalize(&extraDyFlags); char errorPrint[2048]; errorPrint[0] = 0; @@ -332,52 +339,56 @@ safef(errorPrint, sizeof(errorPrint), " : ERROR: %s", errorString); } char countsMessage[512]; countsMessage[0] = 0; if (chromCount > 0 || itemCount > 0) { if (allowedBigBedType(tdb->type)) safef(countsMessage, sizeof(countsMessage), " : %ld chroms : %ld item count ", chromCount, itemCount); else if (startsWithWord("bigWig", tdb->type)) safef(countsMessage, sizeof(countsMessage), " : %ld chroms : %ld bases covered ", chromCount, itemCount); else safef(countsMessage, sizeof(countsMessage), " : %ld chroms : %ld count ", chromCount, itemCount); } +// display and outgoing URLs get the name as it appears in trackDb.txt; +// protectedTrack() below still needs the decorated tdb->track, untouched. +char *trackName = trackHubSkipHubName(tdb->track); + if (protectedTrack(db, tdb, tdb->track)) - hPrintf("
  • %s: %s protected data
  • \n", tdb->track, tdb->type); + hPrintf("
  • %s: %s protected data
  • \n", trackName, tdb->type); else if (isSupportedType(tdb->type)) { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), "(sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), "(sample data)%s\n", urlPrefix, hub->url, genome, trackName, extraFlags, errorPrint); if (allowedBigBedType(tdb->type)) - hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); + hPrintf("
  • %s: %s%s%s
  • \n", trackName, tdb->type, countsMessage, urlReference); else if (startsWithWord("bigWig", tdb->type)) - hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); + hPrintf("
  • %s: %s%s%s
  • \n", trackName, tdb->type, countsMessage, urlReference); else - hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); + hPrintf("
  • %s: %s%s%s
  • \n", trackName, tdb->type, countsMessage, urlReference); } else { if (allowedBigBedType(tdb->type)) - hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); + hPrintf("
  • %s: %s%s
  • \n", trackName, tdb->type, countsMessage); else if (startsWithWord("bigWig", tdb->type)) - hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); + hPrintf("
  • %s: %s%s
  • \n", trackName, tdb->type, countsMessage); else - hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); + hPrintf("
  • %s: %s%s
  • \n", trackName, tdb->type, countsMessage); } } /* static void hubSampleUrl(struct trackHub *hub, struct trackDb *tdb, * long chromCount, long itemCount, char *genome) */ static void bbiLargestChrom(struct bbiChromInfo *chromList, char **chromName, unsigned *chromSize) /* find largest chromosome name and size in the chromList */ { if (chromName && chromSize) { *chromSize = 0; char *returnName = NULL; struct bbiChromInfo *el; for (el = chromList; el; el = el->next) @@ -389,30 +400,40 @@ } } if (chromSize > 0) *chromName = cloneString(returnName); } } static int bbiBriefMeasure(char *type, char *bigDataUrl, char *bigDataIndex, long *chromCount, long *itemCount, struct dyString *errors, char **chromName, unsigned *chromSize) /* check a bigDataUrl to find chrom count and item count, return * name of largest chrom and its size */ { int retVal = 0; *chromCount = 0; *itemCount = 0; +if (isEmpty(bigDataUrl)) + { + // a container/parent-level tdb (superTrack parent, view, etc. not + // already filtered out by the caller) has no bigDataUrl of its own -- + // nothing to measure. Every bigFileOpen()/udcFileOpen() below assumes + // a non-NULL URL string and segfaults on NULL rather than erring out + // through the errCatch below, so this must be checked before any of it. + dyStringPrintf(errors, "no bigDataUrl to measure for type %s", type); + return 1; + } struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { if (startsWithWord("bigNarrowPeak", type) || startsWithWord("bigBed", type) || startsWithWord("bigGenePred", type) || startsWithWord("bigPsl", type) || startsWithWord("bigDbSnp", type) || startsWithWord("bigMaf", type) || startsWithWord("bigChain", type) || startsWithWord("bigRmsk", type) || startsWithWord("bigBarChart", type) || startsWithWord("bigInteract", type)) { struct bbiFile *bbi = NULL; @@ -492,62 +513,67 @@ dyStringPrintf(errors, "%s", errCatch->message->string); } errCatchFree(&errCatch); return retVal; } /* static int bbiBriefMeasure() */ static void hubSubTracks(struct trackHub *hub, char *db, struct trackDb *tdb, struct hash *countTracks, long chromCount, long itemCount, char *chromName, unsigned chromSize, char *genome, char *errorString) /* tdb has subtracks, show only subTracks, no details, this is RECURSIVE */ { hPrintf("
  • \n"); } /* hubSubTracks() */ static void showSubTracks(struct trackHub *hub, char *db, struct trackDb *tdb, struct hash *countTracks, char *chromName, unsigned chromSize, char *errorString) /* tdb has subtracks, show only subTracks, no details */ { hPrintf("
  • \n"); } static void hubCountOneTdb(struct trackHub *hub, char *db, struct trackDb *tdb, char *bigDataIndex, struct hash *countTracks, char *chromName, unsigned chromSize, char *genome) { char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); boolean compositeContainer = tdbIsComposite(tdb); boolean compositeView = tdbIsCompositeView(tdb); boolean superChild = tdbIsSuperTrackChild(tdb); boolean depthSearch = cartUsualBoolean(cart, "depthSearch", FALSE); hashCountTrack(tdb, countTracks); long chromCount = 0; long itemCount = 0; struct dyString *errors = dyStringNew(1024); /* if given a chromSize, it belongs to a UCSC db and this is *not* an * assembly hub, otherwise, look up a chrom and size in the bbi file + * trackHasData() also excludes tdbIsContainer() (e.g. 'container multiWig'), + * which has no bigDataUrl of its own -- its data comes from its children. */ -if (! (compositeContainer || compositeView) ) +if (trackHasData(tdb)) { if (chromSize < 1 || depthSearch) { char *longName = NULL; unsigned longSize = 0; (void) bbiBriefMeasure(tdb->type, bigDataUrl, bigDataIndex, &chromCount, &itemCount, errors, &longName, &longSize); chromSize = longSize; chromName = longName; } } +// display name as it appears in trackDb.txt; tdb->track itself stays +// decorated for hashCountTrack()/protectedTrack()/recursive calls +char *trackName = trackHubSkipHubName(tdb->track); +char *parentName = tdb->parent ? trackHubSkipHubName(tdb->parent->track) : NULL; + if (depthSearch && bigDataUrl) { if (isSupportedType(tdb->type)) hubSampleUrl(hub, db, tdb, chromCount, itemCount, genome, errors->string); } else { if (compositeContainer) - hPrintf("
  • %s: %s : composite track container has %d subtracks
  • \n", tdb->track, tdb->type, slCount(tdb->subtracks)); + hPrintf("
  • %s: %s : composite track container has %d subtracks
  • \n", trackName, tdb->type, slCount(tdb->subtracks)); else if (compositeView) - hPrintf("
  • %s: %s : composite view of parent: %s
  • \n", tdb->track, tdb->type, tdb->parent->track); + hPrintf("
  • %s: %s : composite view of parent: %s
  • \n", trackName, tdb->type, parentName); else if (superChild) { if (isSupportedType(tdb->type)) hubSampleUrl(hub, db, tdb, chromCount, itemCount, genome, errors->string); else - hPrintf("
  • %s: %s : superTrack child of parent: %s
  • \n", tdb->track, tdb->type, tdb->parent->track); + hPrintf("
  • %s: %s : superTrack child of parent: %s
  • \n", trackName, tdb->type, parentName); } else if (! depthSearch && bigDataUrl) { if (isSupportedType(tdb->type)) { hubSampleUrl(hub, db, tdb, chromCount, itemCount, genome, errors->string); } } else { if (isSupportedType(tdb->type)) { hubSampleUrl(hub, db, tdb, chromCount, itemCount, genome, errors->string); } else - hPrintf("
  • %s: %s (what is this)
  • \n", tdb->track, tdb->type); + hPrintf("
  • %s: %s (what is this)
  • \n", trackName, tdb->type); } } if (allTrackSettings) { hPrintf("
  • \n"); } else if (tdb->subtracks) { hubSubTracks(hub, db, tdb, countTracks, chromCount, itemCount, chromName, chromSize, genome, errors->string); } return; } /* static void hubCountOneTdb(char *db, struct trackDb *tdb, * char *bigDataIndex, struct hash *countTracks, @@ -792,31 +825,37 @@ /* process the track list in a hub to show all tracks */ { hPrintf("