bf7b450d396d8fe15d5198d3e4a55d8ac864e6b3 hiram Mon Jan 28 14:55:21 2019 -0800 now output genome list for any hub refs #18869 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index 1122600..ef705a8 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -432,44 +432,48 @@ struct hashCookie hc = hashFirst(genome->settingsHash); while ((hel = hashNext(&hc)) != NULL) { hPrintf(" <li>%s : %s</li>\n", hel->name, (char *)hel->val); if (sameWord("trackDb", hel->name)) /* examine the trackDb structure */ { struct trackDb *tdb = trackHubTracksForGenome(genome->trackHub, genome); trackList(tdb, genome); } if (timeOutReached()) break; } hPrintf(" </ul>\n"); } -static void genomeList (struct trackHub *hubTop) +static struct slName *genomeList(struct trackHub *hubTop) /* follow the pointers from the trackHub to trackHubGenome and around * in a circle from one to the other to find all hub resources */ { +struct slName *retList = NULL; + long totalAssemblyCount = 0; struct trackHubGenome *genome = hubTop->genomeList; hPrintf("<h4>genome sequences (and tracks) present in this track hub</h4>\n"); hPrintf("<ul>\n"); long lastTime = clock1000(); for ( ; genome; genome = genome->next ) { ++totalAssemblyCount; + struct slName *el = slNameNew(genome->name); + slAddHead(&retList, el); if (genome->organism) { hPrintf("<li>%s - %s - %s</li>\n", genome->organism, genome->name, genome->description); } else { /* can there be a description when organism is empty ? */ hPrintf("<li>%s</li>\n", genome->name); } if (genome->settingsHash) assemblySettings(genome); if (measureTiming) { long thisTime = clock1000(); hPrintf("<em>processing time %s: %ld millis</em><br>\n", genome->name, thisTime - lastTime); } @@ -478,95 +482,116 @@ } if (trackCounter->elCount) { hPrintf(" <li>total assembly count: %ld</li>\n", totalAssemblyCount); hPrintf(" <li>%ld total tracks counted, %d different track types:</li>\n", totalTracks, trackCounter->elCount); hPrintf(" <ul>\n"); struct hashEl *hel; struct hashCookie hc = hashFirst(trackCounter); while ((hel = hashNext(&hc)) != NULL) { hPrintf(" <li>%d - %s - total</li>\n", ptToInt(hel->val), hel->name); } hPrintf(" </ul>\n"); } hPrintf("</ul>\n"); -} +return retList; +} /* static struct slName *genomeList (struct trackHub *hubTop) */ static char *urlFromShortLabel(char *shortLabel) { char hubUrl[1024]; char query[1024]; struct sqlConnection *conn = hConnectCentral(); // Build a query to select the hubUrl for the given shortLabel sqlSafef(query, sizeof(query), "select hubUrl from %s where shortLabel='%s'", hubPublicTableName(), shortLabel); if (! sqlQuickQuery(conn, query, hubUrl, sizeof(hubUrl))) hubUrl[0] = 0; hDisconnectCentral(&conn); return cloneString(hubUrl); } static void jsonPublicHubs() { struct hubPublic *el = publicHubList; -hPrintf("{\"publicHubs\":["); +printf("{\"publicHubs\":["); for ( ; el != NULL; el = el->next ) { hubPublicJsonOutput(el, stdout); if (el->next) - hPrintf(","); + printf(","); } -hPrintf("]}\n"); +printf("]}\n"); } #define MAX_PATH_INFO 32 static void apiList(char *words[MAX_PATH_INFO]) /* 'list' function */ { if (sameWord("publicHubs", words[1])) jsonPublicHubs(); else if (sameWord("genomes", words[1])) { char *hubUrl = cgiOptionalString("hubUrl"); if (isNotEmpty(hubUrl)) { - hPrintf("# list genomes for hubUrl: '%s'\n", hubUrl); + struct trackHub *hub = trackHubOpen(hubUrl, ""); + if (hub->genomeList) + { + fputc('{',stdout); + jsonString(stdout, "hubUrl", hubUrl); + fputc(',',stdout); + printf("\"genomes\":["); + struct slName *theList = genomeList(hub); + slNameSort(&theList); + struct slName *el = theList; + for ( ; el ; el = el->next ) + { + char *n = jsonEscape(el->name); + printf("\"%s\"", n); + if (el->next) + fputc(',',stdout); + } + printf("]}\n"); + } } else errAbort("# must supply hubUrl='http:...' some URL to a hub for /list/genomes\n"); } else errAbort("# ERROR: do not recognize '%s' for 'list' function\n", words[1]); } static struct hash *apiFunctionHash = NULL; static void setupFunctionHash() { if (apiFunctionHash) return; apiFunctionHash = hashNew(0); hashAdd(apiFunctionHash, "list", &apiList); } static void apiFunctionSwitch(char *pathInfo) /* given a pathInfo string: /command/subCommand/etc... * parse that and decide on which function to acll */ { +hPrintDisable(); /* turn off all normal HTML output */ + /* the leading slash has been removed from the pathInfo, therefore, the * chop will have the first word in words[0] */ char *words[MAX_PATH_INFO];/*expect no more than MAX_PATH_INFO number of words*/ int wordCount = chopByChar(pathInfo, '/', words, ArraySize(words)); if (wordCount < 2) errAbort("ERROR: no commands found in path info\n"); void (*apiFunction)(char **) = hashMustFindVal(apiFunctionHash, words[0]); (*apiFunction)(words); } static void doMiddle(struct cart *theCart) @@ -660,31 +685,31 @@ hPrintf("\n "); allTrackSettings = cartUsualBoolean(cart, "allTrackSettings", FALSE); hCheckBox("allTrackSettings", allTrackSettings); hPrintf(" display all track settings for each track : %s<br>\n", allTrackSettings ? "TRUE" : "FALSE"); hPrintf("<br>\n</form>\n"); hPrintf("<p>URL: %s - %s<br>\n", urlInput, sameWord("go",goPublicHub) ? "public hub" : "other hub"); hPrintf("name: %s<br>\n", hub->shortLabel); hPrintf("description: %s<br>\n", hub->longLabel); hPrintf("default db: '%s'<br>\n", isEmpty(hub->defaultDb) ? "(none available)" : hub->defaultDb); printf("docRoot:'%s'<br>\n", docRoot); if (hub->genomeList) - genomeList(hub); + (void) genomeList(hub); /* ignore returned list */ hPrintf("</p>\n"); if (timedOut) hPrintf("<h1>Reached time out %ld seconds</h1>", timeOutSeconds); if (measureTiming) hPrintf("<em>Overall total time: %ld millis</em><br>\n", clock1000() - enteredMainTime); cartWebEnd(); } /* void doMiddle(struct cart *theCart) */ /* Null terminated list of CGI Variables we don't want to save * permanently. */ char *excludeVars[] = {"Submit", "submit", NULL,};