3507479860c1b84b51d6f7faddbcbd49fa94227b
hiram
  Tue Feb 12 18:50:44 2019 -0800
now returning sequence DNA from specified UCSC db refs #18869

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index ba07c64..5c6c963 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -476,32 +476,34 @@
 	{
 	if ( differentStringNullOk(selectGenome, genome->name) )
 	    continue;
 	}
     ++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)
+	if (dbTrackList)
 	    *dbTrackList = assemblySettings(genome);
+	else
+	    (void) assemblySettings(genome);
     if (measureTiming)
 	{
 	long thisTime = clock1000();
 	hPrintf("<em>processing time %s: %ld millis</em><br>\n", genome->name, thisTime - lastTime);
 	}
     if (timeOutReached())
 	break;
     }
 if (trackCounter->elCount)
     {
     hPrintf("    <li>total genome 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);
@@ -771,58 +773,110 @@
 struct jsonWrite *jw = jsonStartOutput();
 jsonWriteString(jw, "db", db);
 jsonWriteString(jw, "dataTime", dataTime);
 jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp);
 freeMem(dataTime);
 recursiveTrackList(jw, tdbList, "tracks");
 jsonWriteObjectEnd(jw);
 fputs(jw->dy->string,stdout);
 }	/*	static void trackDbJsonOutput(char *db, FILE *f)	*/
 
 static void getTrackData()
 {
 }
 
 static void getSequenceData()
+/* given at least a db=name and chrom=chr, optionally start and end  */
 {
+char *db = cgiOptionalString("db");
+char *chrom = cgiOptionalString("chrom");
+char *start = cgiOptionalString("start");
+char *end = cgiOptionalString("end");
+
+if (isEmpty(db))
+    jsonErrAbort("missing URL db=<ucscDb> name for endpoint '/getData/sequence");
+if (isEmpty(chrom))
+    jsonErrAbort("missing URL chrom=<name> for endpoint '/getData/sequence?db=%s", db);
+if (chromSeqFileExists(db, chrom))
+    {
+    struct chromInfo *ci = hGetChromInfo(db, chrom);
+    struct dnaSeq *seq = NULL;
+    if (isEmpty(start) || isEmpty(end))
+	seq = hChromSeqMixed(db, chrom, 0, 0);
+    else
+	seq = hChromSeqMixed(db, chrom, sqlSigned(start), sqlSigned(end));
+    if (NULL == seq)
+        jsonErrAbort("can not find sequence for chrom=%s for endpoint '/getData/sequence?db=%s&chrom=%s", chrom, db, chrom);
+    struct jsonWrite *jw = jsonStartOutput();
+    jsonWriteString(jw, "db", db);
+    jsonWriteString(jw, "chrom", chrom);
+    if (isEmpty(start) || isEmpty(end))
+	{
+        jsonWriteNumber(jw, "start", (long long)0);
+        jsonWriteNumber(jw, "end", (long long)ci->size);
+	}
+    else
+	{
+        jsonWriteNumber(jw, "start", (long long)sqlSigned(start));
+        jsonWriteNumber(jw, "end", (long long)sqlSigned(end));
+	}
+    jsonWriteString(jw, "dna", seq->dna);
+    jsonWriteObjectEnd(jw);
+    fputs(jw->dy->string,stdout);
+    freeDnaSeq(&seq);
+    }
+else
+    jsonErrAbort("can not find specified chrom=%s in sequence for endpoint '/getData/sequence?db=%s&chrom=%s", chrom, db, chrom);
 }
 
 #define MAX_PATH_INFO 32
 static void apiGetData(char *words[MAX_PATH_INFO])
 /* 'getData' function, words[1] is the subCommand */
 {
 if (sameWord("track", words[1]))
     getTrackData();
-if (sameWord("sequence", words[1]))
+else if (sameWord("sequence", words[1]))
     getSequenceData();
+else
     jsonErrAbort("do not recognize endpoint function: '/%s/%s'", words[0], words[1]);
 }
 
 static void apiList(char *words[MAX_PATH_INFO])
 /* 'list' function words[1] is the subCommand */
 {
 if (sameWord("publicHubs", words[1]))
     jsonPublicHubs();
 else if (sameWord("ucscGenomes", words[1]))
     jsonDbDb();
 else if (sameWord("hubGenomes", words[1]))
     {
     char *hubUrl = cgiOptionalString("hubUrl");
     if (isEmpty(hubUrl))
-	jsonErrAbort("ERROR: must supply hubUrl='http:...' some URL to a hub for /list/genomes");
+	jsonErrAbort("must supply hubUrl='http:...' some URL to a hub for /list/hubGenomes");
 
-    struct trackHub *hub = trackHubOpen(hubUrl, "");
+    struct trackHub *hub = NULL;
+    struct errCatch *errCatch = errCatchNew();
+    if (errCatchStart(errCatch))
+	{
+	hub = trackHubOpen(hubUrl, "");
+        }
+    errCatchEnd(errCatch);
+    if (errCatch->gotError)
+	{
+	jsonErrAbort("error opening hubUrl: '%s', '%s'", hubUrl,  errCatch->message->string);
+	}
+    errCatchFree(&errCatch);
     if (hub->genomeList)
 	{
         struct jsonWrite *jw = jsonStartOutput();
 	jsonWriteString(jw, "hubUrl", hubUrl);
         jsonWriteListStart(jw, "genomes");
 	struct slName *theList = genomeList(hub, NULL, NULL);
 	slNameSort(&theList);
 	struct slName *el = theList;
 	for ( ; el ; el = el->next )
 	    {
 	    jsonWriteString(jw, NULL, el->name);
 	    }
 	jsonWriteListEnd(jw);
 	jsonWriteObjectEnd(jw);
         fputs(jw->dy->string,stdout);
@@ -921,30 +975,56 @@
 {
 hPrintf("<p>Tracks in UCSC genome: '%s'<br>\n", ucscDb);
 struct trackDb *tdbList = hTrackDb(ucscDb);
 struct trackDb *track;
 hPrintf("<ul>\n");
 for (track = tdbList; track != NULL; track = track->next )
     {
     hPrintf("<li>%s</li>\n", track->track);
     if (allTrackSettings)
         trackSettings(track); /* show all settings */
     }
 hPrintf("</ul>\n");
 hPrintf("</p>\n");
 }
 
+static void showExamples(char *url, struct trackHubGenome *hubGenome, char *ucscDb)
+{
+
+hPrintf("<h2>Example URLs to return json data structures:</h2>\n");
+hPrintf("<ul>\n");
+hPrintf("<li><a href='/cgi-bin/hubApi/list/publicHubs' target=_blank>list public hubs</a> <em>/cgi-bin/hubApi/list/publicHubs</em></li>\n");
+hPrintf("<li><a href='/cgi-bin/hubApi/list/ucscGenomes' target=_blank>list database genomes</a> <em>/cgi-bin/hubApi/list/ucscGenomes</em></li>\n");
+hPrintf("<li><a href='/cgi-bin/hubApi/list/hubGenomes?hubUrl=%s' target=_blank>list genomes from specified hub</a> <em>/cgi-bin/hubApi/list/hubGenomes?hubUrl=%s</em></li>\n", url, url);
+hPrintf("<li><a href='/cgi-bin/hubApi/list/tracks?hubUrl=%s&genome=%s' target=_blank>list tracks from specified hub and genome</a> <em>/cgi-bin/hubApi/list/tracks?hubUrl=%s&genome=%s</em></li>\n", url, hubGenome->name, url, hubGenome->name);
+hPrintf("<li><a href='/cgi-bin/hubApi/list/tracks?db=%s' target=_blank>list tracks from specified UCSC database</a> <em>/cgi-bin/hubApi/list/tracks?db=%s</em></li>\n", ucscDb, ucscDb);
+hPrintf("<li><a href='/cgi-bin/hubApi/list/chromosomes?db=%s' target=_blank>list chromosomes from specified UCSC database</a> <em>/cgi-bin/hubApi/list/chromosomes?db=%s</em></li>\n", ucscDb, ucscDb);
+hPrintf("<li><a href='/cgi-bin/hubApi/list/chromosomes?db=%s&track=gap' target=_blank>list chromosomes from specified track from UCSC databaset</a> <em>/cgi-bin/hubApi/list/chromosomes?db=%s&track=gap</em></li>\n", ucscDb, ucscDb);
+hPrintf("<li><a href='/cgi-bin/hubApi/getData/sequence?db=%s&chrom=chrM' target=_blank>get sequence from specified database and chromosome</a> <em>/cgi-bin/hubApi/getData/sequence?db=%s&chrom=chrM</em></li>\n", ucscDb, ucscDb);
+hPrintf("<li><a href='/cgi-bin/hubApi/getData/sequence?db=%s&chrom=chrM&start=0&end=128' target=_blank>get sequence from specified database, chromosome with start,end coordinates</a> <em>/cgi-bin/hubApi/getData/sequence?db=%s&chrom=chrM&start=0&end=128</em></li>\n", ucscDb, ucscDb);
+hPrintf("</ul>\n");
+}	/*	static void showExamples()	*/
+
+static void showCartDump()
+/* for information purposes only during development, will become obsolete */
+{
+hPrintf("<h4>cart dump</h4>");
+hPrintf("<pre>\n");
+cartDump(cart);
+hPrintf("</pre>\n");
+}
+
 static void doMiddle(struct cart *theCart)
 /* Set up globals and make web page */
 {
 cart = theCart;
 measureTiming = hPrintStatus() && isNotEmpty(cartOptionalString(cart, "measureTiming"));
 measureTiming = TRUE;
 char *database = NULL;
 char *genome = NULL;
 
 getDbAndGenome(cart, &database, &genome, oldVars);
 initGenbankTableNames(database);
 
 char *docRoot = cfgOptionDefault("browser.documentRoot", DOCUMENT_ROOT);
 
 int timeout = cartUsualInt(cart, "udcTimeout", 300);
@@ -997,45 +1077,33 @@
 if (sameWord("go", goOtherHub))	/* requested other hub URL */
     urlInput = otherHubUrl;
 
 long lastTime = clock1000();
 struct trackHub *hub = trackHubOpen(urlInput, "");
 if (measureTiming)
     {
     long thisTime = clock1000();
     hPrintf("<em>hub open time: %ld millis</em><br>\n", thisTime - lastTime);
     }
 
 hPrintf("<h3>ucscDb: '%s'</h2>\n", ucscDb);
 
 struct trackHubGenome *hubGenome = hub->genomeList;
 
-hPrintf("<h2>Example URLs to return json data structures:</h2>\n");
-hPrintf("<ul>\n");
-hPrintf("<li><a href='/cgi-bin/hubApi/list/publicHubs' target=_blank>list public hubs</a> <em>/cgi-bin/hubApi/list/publicHubs</em></li>\n");
-hPrintf("<li><a href='/cgi-bin/hubApi/list/ucscGenomes' target=_blank>list database genomes</a> <em>/cgi-bin/hubApi/list/ucscGenomes</em></li>\n");
-hPrintf("<li><a href='/cgi-bin/hubApi/list/hubGenomes?hubUrl=%s' target=_blank>list genomes from specified hub</a> <em>/cgi-bin/hubApi/list/hubGenomes?hubUrl='%s'</em></li>\n", urlInput, urlInput);
-hPrintf("<li><a href='/cgi-bin/hubApi/list/tracks?hubUrl=%s&genome=%s' target=_blank>list tracks from specified hub and genome</a> <em>/cgi-bin/hubApi/list/tracks?hubUrl='%s&genome=%s'</em></li>\n", urlInput, hubGenome->name, urlInput, hubGenome->name);
-hPrintf("<li><a href='/cgi-bin/hubApi/list/tracks?db=%s' target=_blank>list tracks from specified UCSC database</a> <em>/cgi-bin/hubApi/list/tracks?db='%s'</em></li>\n", ucscDb, ucscDb);
-hPrintf("<li><a href='/cgi-bin/hubApi/list/chromosomes?db=%s' target=_blank>list chromosomes from specified UCSC database</a> <em>/cgi-bin/hubApi/list/chromosomes?db='%s'</em></li>\n", ucscDb, ucscDb);
-hPrintf("<li><a href='/cgi-bin/hubApi/list/chromosomes?db=%s&track=gap' target=_blank>list chromosomes from specified track from UCSC databaset</a> <em>/cgi-bin/hubApi/list/chromosomes?db='%s'&track=gap</em></li>\n", ucscDb, ucscDb);
-hPrintf("</ul>\n");
+showExamples(urlInput, hubGenome, ucscDb);
 
-hPrintf("<h4>cart dump</h4>");
-hPrintf("<pre>\n");
-cartDump(cart);
-hPrintf("</pre>\n");
+showCartDump();
 
 hPrintf("<form action='%s' name='hubApiUrl' id='hubApiUrl' method='GET'>\n\n", "../cgi-bin/hubApi");
 
 hPrintf("<b>Select public hub:&nbsp;</b>");
 #define JBUFSIZE 2048
 #define SMALLBUF 256
 char javascript[JBUFSIZE];
 struct slPair *events = NULL;
 safef(javascript, sizeof(javascript), "this.lastIndex=this.selectedIndex;");
 slPairAdd(&events, "focus", cloneString(javascript));
 
 cgiMakeDropListClassWithIdStyleAndJavascript("publicHubs", "publicHubs",
     shortLabels, publicHubCount, hubDropDown, NULL, "width: 400px", events);
 
 hWrites("&nbsp;");