77f17523d1115eb2fb85eaf747a76db0c6328204 hiram Mon Jan 28 14:05:59 2019 -0800 ready to start listing other things refs #18869 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index ddec85b..1122600 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -44,45 +44,44 @@ struct hubPublic /* Table of public track data hub connections. */ { struct hubPublic *next; /* Next in singly linked list. */ char *hubUrl; /* URL to hub.ra file */ char *shortLabel; /* Hub short label. */ char *longLabel; /* Hub long label. */ char *registrationTime; /* Time first registered */ unsigned dbCount; /* Number of databases hub has data for. */ char *dbList; /* Comma separated list of databases. */ char *descriptionUrl; /* URL to description HTML */ }; /* Global Variables */ -struct cart *cart; /* CGI and other variables */ -struct hash *oldVars = NULL; +static struct cart *cart; /* CGI and other variables */ +static struct hash *oldVars = NULL; static struct hash *trackCounter = NULL; 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 */ static int publicHubCount = 0; static struct hubPublic *publicHubList = NULL; static char *defaultHub = "Plants"; 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; -static boolean jsonOutput = FALSE; /* turns on when pathInfo present */ /* ######################################################################### */ /* json output needs to encode special characters in strings: " - quotation mark / - forward slash \ - back slash \n - new line \r - carriage return \t - tab */ static char* jsonEscape(char *jsonString) /* escape any of the special characters in the string for json output */ { @@ -495,97 +494,140 @@ 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); } -void jsonPublicHubs() +static void jsonPublicHubs() { struct hubPublic *el = publicHubList; hPrintf("{\"publicHubs\":["); for ( ; el != NULL; el = el->next ) { hubPublicJsonOutput(el, stdout); if (el->next) hPrintf(","); } hPrintf("]}\n"); } -void doMiddle(struct cart *theCart) +#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); + } + 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 + */ +{ +/* 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) /* Set up globals and make web page */ { // struct hubPublic *hubList = hubPublicLoadAll(); publicHubList = hubPublicLoadAll(); 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); if (udcCacheTimeout() < timeout) udcSetCacheTimeout(timeout); knetUdcInstall(); char *pathInfo = getenv("PATH_INFO"); -if ((NULL == pathInfo) || strlen(pathInfo) < 1) +if (isNotEmpty(pathInfo)) { - pathInfo = cloneString("noPathInfo"); - } -else - { - jsonOutput = TRUE; - } - -if (jsonOutput) - { -// startHtml("json output example"); -// hPrintf("<br><a href='http://hgwdev-hiram.gi.ucsc.edu/cgi-bin/hubApi'>return to hubApi</a><br><br>\n"); - jsonPublicHubs(); -// endHtml(); + /* skip the first leading slash to simplify chopByChar parsing */ + pathInfo += 1; + setupFunctionHash(); + apiFunctionSwitch(pathInfo); return; } + cartWebStart(cart, database, "access mechanism to hub data resources"); char *goOtherHub = cartUsualString(cart, "goOtherHub", defaultHub); char *otherHubUrl = cartUsualString(cart, "urlHub", defaultHub); char *goPublicHub = cartUsualString(cart, "goPublicHub", defaultHub); char *hubDropDown = cartUsualString(cart, "publicHubs", defaultHub); char *urlDropDown = urlFromShortLabel(hubDropDown); char *urlInput = urlDropDown; /* assume public hub */ if (sameWord("go", goOtherHub)) /* requested other hub URL */ urlInput = otherHubUrl; hPrintf("<h2>Example URLs to return json data structures:</h2>\n"); hPrintf("<ul>\n"); hPrintf("<li><a href='/cgi-bin/hubApi/list/publicHubs'>list public hubs</a> <em>/cgi-bin/hubApi/list/publicHubs</em></li>\n"); +hPrintf("<li><a href='/cgi-bin/hubApi/list/genomes?hubUrl=%s'>list genomes from specified hub</a> <em>/cgi-bin/hubApi/list/genomes?hubUrl='%s'</em></li>\n", urlInput, urlInput); hPrintf("</ul>\n"); 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("<h4>cart dump</h4>"); hPrintf("<pre>\n"); cartDump(cart); hPrintf("</pre>\n"); hPrintf("<form action='%s' name='hubApiUrl' id='hubApiUrl' method='GET'>\n\n", "../cgi-bin/hubApi"); @@ -615,31 +657,31 @@ hPrintf("<br>\n "); hCheckBox("depthSearch", cartUsualBoolean(cart, "depthSearch", FALSE)); hPrintf(" perform full bbi file measurement : %s (will time out if taking longer than %ld seconds)<br>\n", depthSearch ? "TRUE" : "FALSE", timeOutSeconds); 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("pathInfo:'%s'<br>\ndocRoot:'%s'<br>\n", pathInfo, docRoot); +printf("docRoot:'%s'<br>\n", docRoot); if (hub->genomeList) genomeList(hub); 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