4cb493ab92afe6c13f5592880c4f5fbfa371d84c
hiram
  Sun Feb 10 18:48:32 2019 -0800
make the chromosome list a sub-list from the top level refs #18869

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index 1639d99..2f75c10 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -65,62 +65,55 @@
 static long totalTracks = 0;
 static boolean measureTiming = FALSE;	/* set by CGI parameters */
 static boolean allTrackSettings = FALSE;	/* checkbox setting */
 static char **shortLabels = NULL;	/* public hub short labels in array */
 struct hubPublic *publicHubList = NULL;
 static int publicHubCount = 0;
 static char *defaultHub = "Plants";
 static char *defaultDb = "ce11";
 static long enteredMainTime = 0;	/* will become = clock1000() on entry */
 		/* to allow calculation of when to bail out, taking too long */
 static long timeOutSeconds = 100;
 static boolean timedOut = FALSE;
 
 /* ######################################################################### */
 
-#ifdef NOT
-static void jsonInteger(FILE *f, char *tag, long long value)
-/* output one json interger: "tag":value appropriately quoted and encoded */
-{
-fprintf(f,"\"%s\":%lld",tag, value);
-}
-#endif
-
 static void jsonStringPrint(FILE *f, char *value)
 /* escape string for output */
 {
 char *a = jsonStringEscape(value);
 if (isEmpty(a))
     fprintf(f, "%s", "null");
 else
     fprintf(f, "\"%s\"", a);
 freeMem(a);
 }
 
 static void jsonTagValue(FILE *f, char *tag, char *value)
 /* output one json string: "tag":"value" appropriately quoted and encoded */
 {
 fprintf(f,"\"%s\":",tag);
 jsonStringPrint(f, value);
 }
 
 static struct jsonWrite *jsonStartOutput()
 /* begin json output */
 {
 struct jsonWrite *jw = jsonWriteNew();
 jsonWriteObjectStart(jw, NULL);
-jsonWriteString(jw, "source", "UCSantaCurz");
+jsonWriteString(jw, "version", "0.1");
+jsonWriteString(jw, "source", "UCSantaCruz");
 return jw;
 }
 
 static void jsonErrAbort(char *format, ...)
 /* Issue an error message in json format. */
 {
 char errMsg[2048];
 va_list args;
 va_start(args, format);
 vsnprintf(errMsg, sizeof(errMsg), format, args);
 fputc('{',stdout);
 jsonTagValue(stdout, "error", errMsg);
 fputc('}',stdout);
 }
 
@@ -130,53 +123,30 @@
  *  TODO: need to figure out how to use the order of the columns as
  *        they are in the 'desc' request
  */
 {
 jsonWriteListStart(jw, NULL);
 jsonWriteString(jw, NULL, el->hubUrl);
 jsonWriteString(jw, NULL, el->shortLabel);
 jsonWriteString(jw, NULL, el->longLabel);
 jsonWriteString(jw, NULL, el->registrationTime);
 jsonWriteNumber(jw, NULL, (long long)el->dbCount);
 jsonWriteString(jw, NULL, el->dbList);
 jsonWriteString(jw, NULL, el->descriptionUrl);
 jsonWriteListEnd(jw);
 }
 
-#ifdef NOT
-/* This function should be in hg/lib/hubPublic.c */
-static void hubPublicJsonOutput(FILE *f, struct hubPublic *el)
-/* Print out hubPublic element in JSON format. */
-{
-fputc('{',f);
-jsonTagValue(f, "hubUrl", el->hubUrl);
-fputc(',',f);
-jsonTagValue(f, "shortLabel", el->shortLabel);
-fputc(',',f);
-jsonTagValue(f, "longLabel", el->longLabel);
-fputc(',',f);
-jsonTagValue(f, "registrationTime", el->registrationTime);
-fputc(',',f);
-jsonInteger(f, "dbCount", el->dbCount);
-fputc(',',f);
-jsonTagValue(f, "dbList", el->dbList);
-fputc(',',f);
-jsonTagValue(f, "descriptionUrl", el->descriptionUrl);
-fputc('}',f);
-}
-#endif
-
 static int publicHubCmpCase(const void *va, const void *vb)
 /* Compare two slNames, ignore case. */
 {
 const struct hubPublic *a = *((struct hubPublic **)va);
 const struct hubPublic *b = *((struct hubPublic **)vb);
 return strcasecmp(a->shortLabel, b->shortLabel);
 }
 
 static void publicHubSortCase(struct hubPublic **pList)
 /* Sort slName list, ignore case. */
 {
 slSort(pList, publicHubCmpCase);
 }
 
 static struct hubPublic *hubPublicLoad(char **row)
@@ -215,42 +185,30 @@
 sqlFreeResult(&sr);
 hDisconnectCentral(&conn);
 publicHubSortCase(&list);
 int listSize = slCount(list);
 AllocArray(shortLabels, listSize);
 struct hubPublic *el = list;
 int i = 0;
 for ( ; el != NULL; el = el->next )
     {
     shortLabels[i++] = el->shortLabel;
     ++publicHubCount;
     }
 return list;
 }
 
-#ifdef NOT
-static void startHtml(char *title)
-{
-printf ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head><title>%s</title></head><body>\n", title);
-}
-
-static void endHtml()
-{
-printf ("</body></html>\n");
-}
-#endif
-
 static boolean timeOutReached()
 {
 long nowTime = clock1000();
 timedOut = FALSE;
 if ((nowTime - enteredMainTime) > (1000 * timeOutSeconds))
     timedOut= TRUE;
 return timedOut;
 }
 
 static void trackSettings(struct trackDb *tdb)
 /* process the settingsHash for a track */
 {
 hPrintf("    <ul>\n");
 struct hashEl *hel;
 struct hashCookie hc = hashFirst(tdb->settingsHash);
@@ -558,67 +516,30 @@
 jsonWriteString(jw, NULL, el->nibPath);
 jsonWriteString(jw, NULL, el->organism);
 jsonWriteString(jw, NULL, el->defaultPos);
 jsonWriteNumber(jw, NULL, (long long)el->active);
 jsonWriteNumber(jw, NULL, (long long)el->orderKey);
 jsonWriteString(jw, NULL, el->genome);
 jsonWriteString(jw, NULL, el->scientificName);
 jsonWriteString(jw, NULL, el->htmlPath);
 jsonWriteNumber(jw, NULL, (long long)el->hgNearOk);
 jsonWriteNumber(jw, NULL, (long long)el->hgPbOk);
 jsonWriteString(jw, NULL, el->sourceName);
 jsonWriteNumber(jw, NULL, (long long)el->taxId);
 jsonWriteListEnd(jw);
 }
 
-#ifdef NOT
-/* this code should be in hg/lib/dbDb.c */
-static void dbDbJsonOutput(FILE *f, struct dbDb *el)
-/* Print out hubPublic element in JSON format. */
-{
-fputc('{',f);
-jsonTagValue(f, "name", el->name);
-fputc(',',f);
-jsonTagValue(f, "description", el->description);
-fputc(',',f);
-jsonTagValue(f, "nibPath", el->nibPath);
-fputc(',',f);
-jsonTagValue(f, "organism", el->organism);
-fputc(',',f);
-jsonTagValue(f, "defaultPos", el->defaultPos);
-fputc(',',f);
-jsonInteger(f, "active", el->active);
-fputc(',',f);
-jsonInteger(f, "orderKey", el->orderKey);
-fputc(',',f);
-jsonTagValue(f, "genome", el->genome);
-fputc(',',f);
-jsonTagValue(f, "scientificName", el->scientificName);
-fputc(',',f);
-jsonTagValue(f, "htmlPath", el->htmlPath);
-fputc(',',f);
-jsonInteger(f, "hgNearOk", el->hgNearOk);
-fputc(',',f);
-jsonInteger(f, "hgPbOk", el->hgPbOk);
-fputc(',',f);
-jsonTagValue(f, "sourceName", el->sourceName);
-fputc(',',f);
-jsonInteger(f, "taxId", el->taxId);
-fputc('}',f);
-}
-#endif
-
 static boolean tableColumns(struct jsonWrite *jw, char *table)
 /* output the column names for the given table
  * return: TRUE on error, FALSE on success
  */
 {
 jsonWriteListStart(jw, "columnNames");
 char query[1024];
 struct sqlConnection *conn = hConnectCentral();
 sqlSafef(query, sizeof(query), "desc %s", table);
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row;
 row = sqlNextRow(sr);
 if (NULL == row)
     {
     jsonErrAbort("ERROR: can not 'desc' table '%s'\n", table);
@@ -711,54 +632,58 @@
 	jsonWriteString(jw, "track", track);
         struct slPair *list = NULL;
 	char query[2048];
         sqlSafef(query, sizeof(query), "select distinct chrom from %s", track);
 	struct sqlResult *sr = sqlGetResult(conn, query);
 	char **row;
 	while ((row = sqlNextRow(sr)) != NULL)
     	{
             int size = hChromSize(db, row[0]);
 	    slAddHead(&list, slPairNew(row[0], intToPt(size)));
     	}
 	sqlFreeResult(&sr);
         slPairIntSort(&list);
         slReverse(&list);
         jsonWriteNumber(jw, "chromCount", (long long)slCount(list));
+	jsonWriteObjectStart(jw, "chromosomes");
         struct slPair *el = list;
         for ( ; el != NULL; el = el->next )
             jsonWriteNumber(jw, el->name, (long long)ptToInt(el->val));
-        jsonWriteObjectEnd(jw);
+	jsonWriteObjectEnd(jw);	/* chromosomes */
+        jsonWriteObjectEnd(jw);	/* top level */
         fputs(jw->dy->string,stdout);
 	}
     else
 	{
 	jsonErrAbort("ERROR: table '%s' is not a position table, no chromosomes for genome: '%s'", track, db);
 	}
     hFreeConn(&conn);
     }
 else
     {
     struct chromInfo *ciList = createChromInfoList(NULL, db);
     struct chromInfo *el = ciList;
     struct jsonWrite *jw = jsonStartOutput();
     jsonWriteString(jw, "genome", db);
     jsonWriteNumber(jw, "chromCount", (long long)slCount(ciList));
+    jsonWriteObjectStart(jw, "chromosomes");
     for ( ; el != NULL; el = el->next )
 	{
         jsonWriteNumber(jw, el->chrom, (long long)el->size);
 	}
-    jsonWriteObjectEnd(jw);
+    jsonWriteObjectEnd(jw);	/* chromosomes */
+    jsonWriteObjectEnd(jw);	/* top level */
     fputs(jw->dy->string,stdout);
     }
 }
 
 static void trackDbJsonOutput(char *db, FILE *f)
 /* return track list from specified UCSC database name */
 {
 struct trackDb *tdbList = hTrackDb(db);
 struct trackDb *el;
 struct jsonWrite *jw = jsonStartOutput();
 jsonWriteString(jw, "db", db);
 jsonWriteListStart(jw, "tracks");
 for (el = tdbList; el != NULL; el = el->next )
     jsonWriteString(jw, NULL, el->track);
 jsonWriteListEnd(jw);