20d72f662e55fd7c611413dbb471a3a2714b9684 hiram Thu Oct 10 14:09:53 2019 -0700 newly supported type wigMaf refs #23589 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index e6ea63e..964ed6b 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -1,1589 +1,1591 @@ /* hubApi - access mechanism to hub data resources. */ #include "dataApi.h" #include "botDelay.h" #include "jsHelper.h" /* +------------------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+------------------+------+-----+---------+-------+ | hubUrl | longblob | NO | PRI | NULL | | | shortLabel | varchar(255) | NO | | NULL | | | longLabel | varchar(255) | NO | | NULL | | | registrationTime | varchar(255) | NO | | NULL | | | dbCount | int(10) unsigned | NO | | NULL | | | dbList | blob | YES | | NULL | | | descriptionUrl | longblob | YES | | NULL | | +------------------+------------------+------+-----+---------+-------+ */ /* Global Variables for all modules */ static int maxItemLimit = 1000000; /* maximum of 1,000,000 items returned */ int maxItemsOutput = 1000000; /* can be set in URL maxItemsOutput=N */ boolean reachedMaxItems = FALSE; /* during getData, signal to return */ long long itemsReturned = 0; /* for getData functions, number of items returned */ /* for debugging purpose, current bot delay value */ int botDelay = 0; boolean debug = FALSE; /* can be set in URL debug=1, to turn off: debug=0 */ #define delayFraction 0.03 /* default is to list all trackDb entries, composite containers too. * This option will limit to only the actual track entries with data */ boolean trackLeavesOnly = FALSE; /* set by CGI parameter 'trackLeavesOnly' */ /* this selects output type 'arrays', where the default type is: objects */ boolean jsonOutputArrays = FALSE; /* set by CGI parameter 'jsonOutputArrays' */ boolean measureTiming = FALSE; /* set by CGI parameters */ /* downloadUrl for use in error exits when reachedMaxItems */ struct dyString *downloadUrl = NULL; /* valid argument listings to verify extraneous arguments */ char *argListPublicHubs[] = { NULL }; char *argListUcscGenomes[] = { NULL }; char *argListHubGenomes[] = { argHubUrl, NULL }; char *argListTracks[] = { argGenome, argHubUrl, argTrackLeavesOnly, NULL }; char *argListChromosomes[] = { argGenome, argHubUrl, argTrack, NULL }; char *argListSchema[] = { argGenome, argHubUrl, argTrack, NULL }; char *argGetDataTrack[] = { argGenome, argHubUrl, argTrack, argChrom, argStart, argEnd, argMaxItemsOutput, argJsonOutputArrays, NULL }; char *argGetDataSequence[] = { argGenome, argHubUrl, argTrack, argChrom, argStart, argEnd, NULL }; /* Global only to this one source file */ static struct cart *cart; /* CGI and other variables */ static struct hash *oldVars = NULL; static struct hash *trackCounter = NULL; static long totalTracks = 0; static boolean allTrackSettings = FALSE; /* checkbox setting */ static char **shortLabels = NULL; /* public hub short labels in array */ static int publicHubCount = 0; static char *defaultHub = "Plants"; static char *defaultDb = "ce11"; 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 char *urlPrefix = ""; /* initalized to support self references */ /* supportedTypes will be initialized to a known supported set */ struct slName *supportedTypes = NULL; static void initSupportedTypes() /* initalize the list of supported track types */ { struct slName *el = newSlName("bed"); slAddHead(&supportedTypes, el); el = newSlName("wig"); slAddHead(&supportedTypes, el); +el = newSlName("wigMaf"); +slAddHead(&supportedTypes, el); el = newSlName("broadPeak"); slAddHead(&supportedTypes, el); el = newSlName("narrowPeak"); slAddHead(&supportedTypes, el); el = newSlName("bigBed"); slAddHead(&supportedTypes, el); el = newSlName("bigWig"); slAddHead(&supportedTypes, el); el = newSlName("bigNarrowPeak"); slAddHead(&supportedTypes, el); el = newSlName("bigGenePred"); slAddHead(&supportedTypes, el); el = newSlName("genePred"); slAddHead(&supportedTypes, el); el = newSlName("psl"); slAddHead(&supportedTypes, el); el = newSlName("rmsk"); slAddHead(&supportedTypes, el); el = newSlName("bigPsl"); slAddHead(&supportedTypes, el); el = newSlName("altGraphX"); slAddHead(&supportedTypes, el); el = newSlName("barChart"); slAddHead(&supportedTypes, el); el = newSlName("chain"); slAddHead(&supportedTypes, el); el = newSlName("ctgPos"); slAddHead(&supportedTypes, el); el = newSlName("expRatio"); slAddHead(&supportedTypes, el); el = newSlName("factorSource"); slAddHead(&supportedTypes, el); el = newSlName("gvf"); slAddHead(&supportedTypes, el); el = newSlName("interact"); slAddHead(&supportedTypes, el); el = newSlName("netAlign"); slAddHead(&supportedTypes, el); el = newSlName("peptideMapping"); slAddHead(&supportedTypes, el); el = newSlName("pgSnp"); slAddHead(&supportedTypes, el); // el = newSlName("bigBarChart"); // slAddHead(&supportedTypes, el); // el = newSlName("bigInteract"); // slAddHead(&supportedTypes, el); // el = newSlName("bigMaf"); // slAddHead(&supportedTypes, el); // el = newSlName("bigChain"); // slAddHead(&supportedTypes, el); slNameSort(&supportedTypes); } /* static void initSupportedTypes() */ static int publicHubCmpCase(const void *va, const void *vb) /* Compare two shortLabels, 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); } struct hubPublic *hubPublicDbLoadAll() /* read entire hubPublic table in hgcentral and return resulting list */ { char query[1024]; struct hubPublic *list = NULL; struct sqlConnection *conn = hConnectCentral(); sqlSafef(query, sizeof(query), "select * from %s", hubPublicTableName()); struct sqlResult *sr = sqlGetResult(conn, query); char **row; while ((row = sqlNextRow(sr)) != NULL) { struct hubPublic *el = hubPublicLoad(row); slAddHead(&list, el); } 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; } static boolean timeOutReached() /* see if the timeout has been reached to determine if an exit * is appropriate at this time */ { long nowTime = clock1000(); timedOut = FALSE; if ((nowTime - enteredMainTime) > (1000 * timeOutSeconds)) timedOut= TRUE; return timedOut; } static void hashCountTrack(struct trackDb *tdb, struct hash *countTracks) /* this is counting up track types into the hash countTracks */ { char *stripType = cloneString(tdb->type); if (startsWith("chain ", tdb->type)) stripType = cloneString("chain"); else if (startsWith("netAlign ", tdb->type)) stripType = cloneString("netAlign"); else if (startsWith("genePred ", tdb->type)) stripType = cloneString("genePred"); else if (startsWith("bigWig ", tdb->type)) stripType = cloneString("bigWig"); else if (startsWith("wigMaf ", tdb->type)) stripType = cloneString("wigMaf"); else if (startsWith("wig ", tdb->type)) stripType = cloneString("wig"); else stripType = cloneString(tdb->type); boolean compositeContainer = tdbIsComposite(tdb); boolean compositeView = tdbIsCompositeView(tdb); boolean superChild = tdbIsSuperTrackChild(tdb); if (compositeContainer) hashIncInt(countTracks, "composite container"); else if (compositeView) hashIncInt(countTracks, "composite view"); else if (superChild) { hashIncInt(countTracks, "superTrack child"); hashIncInt(countTracks, stripType); hashIncInt(countTracks, "track count"); } else if (isEmpty(tdb->type)) hashIncInt(countTracks, "no type specified"); else { hashIncInt(countTracks, stripType); hashIncInt(countTracks, "track count"); } freeMem(stripType); } static void sampleUrl(struct trackHub *hub, char *db, struct trackDb *tdb, char *errorString) /* 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; struct dyString *extraDyFlags = newDyString(128); if (debug) dyStringAppend(extraDyFlags, ";debug=1"); if (jsonOutputArrays) dyStringAppend(extraDyFlags, ";jsonOutputArrays=1"); char *extraFlags = dyStringCannibalize(&extraDyFlags); if (protectedTrack(tdb, tdb->track)) hPrintf("
  • %s : %s <protected data>
  • \n", tdb->track, 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); if (tdb->parent) hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference); } else { char urlReference[2048]; safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, db, tdb->track, extraFlags, errorPrint); if (superChild) hPrintf("
  • %s: %s superTrack child of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else if (tdb->parent) hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, 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); if (tdb->parent) hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference); } else hPrintf("
  • %s : %s not db hub track ?
  • \n", tdb->track, tdb->type); } static void hubSampleUrl(struct trackHub *hub, struct trackDb *tdb, long chromCount, long itemCount, char *genome, char *errorString) { struct dyString *extraDyFlags = newDyString(128); if (debug) dyStringAppend(extraDyFlags, ";debug=1"); if (jsonOutputArrays) dyStringAppend(extraDyFlags, ";jsonOutputArrays=1"); char *extraFlags = dyStringCannibalize(&extraDyFlags); char errorPrint[2048]; errorPrint[0] = 0; if (isNotEmpty(errorString)) { 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); } if (protectedTrack(tdb, tdb->track)) hPrintf("
  • %s: %s protected data
  • \n", tdb->track, 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); if (allowedBigBedType(tdb->type)) hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); else if (startsWithWord("bigWig", tdb->type)) hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); else hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); } else { if (allowedBigBedType(tdb->type)) hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); else if (startsWithWord("bigWig", tdb->type)) hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, 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) { if (el->size > *chromSize) { *chromSize = el->size; returnName = el->name; } } 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; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { if (startsWithWord("bigNarrowPeak", type) || startsWithWord("bigBed", type) || startsWithWord("bigGenePred", type) || startsWithWord("bigPsl", type) || startsWithWord("bigChain", type) || startsWithWord("bigMaf", type) || startsWithWord("bigBarChart", type) || startsWithWord("bigInteract", type)) { struct bbiFile *bbi = NULL; bbi = bigBedFileOpen(bigDataUrl); struct bbiChromInfo *chromList = bbiChromList(bbi); *chromCount = slCount(chromList); *itemCount = bigBedItemCount(bbi); bbiLargestChrom(chromList, chromName, chromSize); bbiChromInfoFreeList(&chromList); bbiFileClose(&bbi); } else if (startsWithWord("bigWig", type)) { struct bbiFile *bwf = bigWigFileOpen(bigDataUrl); struct bbiChromInfo *chromList = bbiChromList(bwf); struct bbiSummaryElement sum = bbiTotalSummary(bwf); *chromCount = slCount(chromList); *itemCount = sum.validCount; bbiLargestChrom(chromList, chromName, chromSize); bbiChromInfoFreeList(&chromList); bbiFileClose(&bwf); } else if (startsWithWord("vcfTabix", type)) { struct vcfFile *vcf = vcfTabixFileAndIndexMayOpen(bigDataUrl, bigDataIndex, NULL, 0, 0, 1, 1); if (vcf == NULL) { dyStringPrintf(errors, "Could not open %s and/or its tabix index (.tbi) file. See http://genome.ucsc.edu/goldenPath/help/vcf.html", bigDataUrl); retVal = 1; } else vcfFileFree(&vcf); } else if (startsWithWord("bam", type)) { bamFileAndIndexMustExist(bigDataUrl, bigDataIndex); } else if (startsWithWord("longTabix", type)) { struct bedTabixFile *btf = bedTabixFileMayOpen(bigDataUrl, NULL, 0, 0); if (btf == NULL) { dyStringPrintf(errors, "Couldn't open %s and/or its tabix index (.tbi) file.", bigDataUrl); retVal = 1; } else bedTabixFileClose(&btf); } #ifdef USE_HAL else if (startsWithWord("halSnake", type)) { char *errString; int handle = halOpenLOD(bigDataUrl, &errString); if (handle < 0) { dyStringPrintf(errors, "HAL open error: %s", errString); retVal = 1; } if (halClose(handle, &errString) < 0) { dyStringPrintf(errors, "HAL close error: %s", errString); retVal = 1; } } #endif else { dyStringPrintf(errors, "unrecognized type %s", type); retVal = 1; } } errCatchEnd(errCatch); if (errCatch->gotError) { retVal = 1; 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 */ { 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 trackSettings(struct trackDb *tdb, struct hash *countTracks) /* process the settingsHash for a trackDb, recursive when subtracks */ { 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 = newDyString(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 */ if (! (compositeContainer || compositeView) ) { 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; } } if (depthSearch && bigDataUrl) { if (isSupportedType(tdb->type)) hubSampleUrl(hub, 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)); else if (compositeView) hPrintf("
  • %s: %s : composite view of parent: %s
  • \n", tdb->track, tdb->type, tdb->parent->track); else if (superChild) { if (isSupportedType(tdb->type)) hubSampleUrl(hub, tdb, chromCount, itemCount, genome, errors->string); else hPrintf("
  • %s: %s : superTrack child of parent: %s
  • \n", tdb->track, tdb->type, tdb->parent->track); } else if (! depthSearch && bigDataUrl) { if (isSupportedType(tdb->type)) { hubSampleUrl(hub, tdb, chromCount, itemCount, genome, errors->string); } } else { if (isSupportedType(tdb->type)) { hubSampleUrl(hub, tdb, chromCount, itemCount, genome, errors->string); } else hPrintf("
  • %s: %s (what is this)
  • \n", tdb->track, 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, * char *chromName, unsigned chromSize) */ static void countOneTdb(char *db, struct trackDb *tdb, struct hash *countTracks, char *chromName, unsigned chromSize, char *errorString) /* for this tdb in this db, count it up and provide a sample */ { char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); boolean compositeContainer = tdbIsComposite(tdb); boolean compositeView = tdbIsCompositeView(tdb); boolean superChild = tdbIsSuperTrackChild(tdb); boolean depthSearch = cartUsualBoolean(cart, "depthSearch", FALSE); boolean protectedData = protectedTrack(tdb, tdb->track); hashCountTrack(tdb, countTracks); if (compositeContainer) hPrintf("
  • %s: %s : composite track container has %d subtracks
  • \n", tdb->track, tdb->type, slCount(tdb->subtracks)); else if (compositeView) hPrintf("
  • %s: %s : composite view of parent: %s
  • \n", tdb->track, tdb->type, tdb->parent->track); else if (superChild) { if (isSupportedType(tdb->type)) sampleUrl(NULL, db, tdb, errorString); else hPrintf("
  • %s: %s : superTrack child of parent: %s
  • \n", tdb->track, tdb->type, tdb->parent->track); } else if (! depthSearch && bigDataUrl) { if (protectedData) hPrintf("
  • %s: %s : <protected data>
  • \n", tdb->track, tdb->type); else hPrintf("
  • %s: %s : %s
  • \n", tdb->track, tdb->type, bigDataUrl); } else { if (isSupportedType(tdb->type)) sampleUrl(NULL, db, tdb, errorString); else hPrintf("
  • %s: %s
  • \n", tdb->track, tdb->type); } if (allTrackSettings) { hPrintf("
  • \n"); } else if (tdb->subtracks) { showSubTracks(NULL, db, tdb, countTracks, chromName, chromSize, NULL); } return; } /* static void countOneTdb(char *db, struct trackDb *tdb, * struct hash *countTracks, char *chromName, * unsigned chromSize) */ static unsigned largestChrom(char *db, char **nameReturn, int *chromCount) /* return the length and get the chrom name for the largest chrom * from chromInfo table. For use is sample getData URLs */ { char query[1024]; struct sqlConnection *conn = hAllocConn(db); sqlSafef(query, sizeof(query), "select chrom,size from chromInfo order by size desc limit 1"); struct sqlResult *sr = sqlGetResult(conn, query); char **row = sqlNextRow(sr); unsigned length = 0; if (row) { *nameReturn = cloneString(row[0]); length = sqlLongLong(row[1]); } sqlFreeResult(&sr); if (chromCount) { sqlSafef(query, sizeof(query), "select count(*) from chromInfo"); *chromCount = sqlQuickNum(conn, query); } hFreeConn(&conn); return length; } static void hubTrackList(struct trackHub *hub, struct trackDb *topTrackDb, struct trackHubGenome *genome) /* process the track list in a hub to show all tracks */ { hPrintf("
  • \n"); } /* static struct trackDb *hubTrackList() */ static void hubAssemblySettings(struct trackHub *hub, struct trackHubGenome *genome) /* display all the assembly 'settingsHash' */ { struct trackDb *tdb = obtainTdb(genome, NULL); hPrintf("
  • \n"); } static unsigned largestChromInfo(struct chromInfo *ci, char **chromName) /* find largest chrom in this chromInfo, return name and size */ { unsigned size = 0; char *name = NULL; struct chromInfo *el; for (el = ci; el; el = el->next) { if (el->size > size) { size = el->size; name = el->chrom; } } if (chromName) *chromName = name; return size; } static void hubInfo(char *tag, char *val) /* print one list element with the given tag and value, show * if not value present */ { if (isNotEmpty(val)) hPrintf("
  • %s: '%s'
  • \n", tag, val); else hPrintf("
  • %s: <empty>
  • \n", tag); } static void 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 */ { long totalAssemblyCount = 0; struct trackHubGenome *genome = hubTop->genomeList; hPrintf("

    genome sequences (and tracks) present in this track hub (JSON example list hub genomes)

    \n", urlPrefix, hubTop->url); if (NULL == genome) { hPrintf("

    odd error, can not find a gnomeList ? at url: '%s'

    \n", hubTop->url); return; } hPrintf("\n"); } /* static void genomeList (hubTop) */ static char *urlFromShortLabel(char *shortLabel) /* this is not a fair way to get the URL since shortLabel's are not * necessarily unique. This is temporary. TBD: need to always use URL * and then get the 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 struct hash *apiFunctionHash = NULL; static void setupFunctionHash() /* initialize the apiFunctionHash */ { if (apiFunctionHash) return; /* already done */ apiFunctionHash = hashNew(0); hashAdd(apiFunctionHash, "list", &apiList); hashAdd(apiFunctionHash, "getData", &apiGetData); } static struct hashEl *parsePathInfo(char *pathInfo, char *words[MAX_PATH_INFO]) /* given a pathInfo string: /command/subCommand/etc... * parse that and return a function pointer and the parsed words * Returns NULL if not recognized */ { char *tmp = cloneString(pathInfo); /* skip the first leading slash to simplify chopByChar parsing */ tmp += 1; int wordCount = chopByChar(tmp, '/', words, MAX_PATH_INFO); if (wordCount < 1 || wordCount > 2) return NULL; /* only 2 words allowed */ struct hashEl *hel = hashLookup(apiFunctionHash, words[0]); return hel; } static void tracksForUcscDb(char *db) /* scan the specified database for all tracks */ { struct hash *countTracks = hashNew(0); char *chromName = NULL; int chromCount = 0; unsigned chromSize = largestChrom(db, &chromName, &chromCount); char countString[64]; sprintLongWithCommas(countString, chromCount); char sizeString[64]; sprintLongWithCommas(sizeString, chromSize); hPrintf("

    Tracks in UCSC genome: '%s', chrom count: %s, longest chrom: %s : %s

    \n", db, countString, chromName, sizeString); char urlReference[2048]; safef(urlReference, sizeof(urlReference), " JSON output: list tracks", urlPrefix, db, trackLeavesOnly ? ";trackLeavesOnly=1" : ""); hPrintf("

    %s

    \n", urlReference); struct trackDb *tdbList = obtainTdb(NULL, db); struct trackDb *tdb; hPrintf("\n"); hPrintf("

    \n"); } // static void tracksForUcscDb(char * db) static void initUrlPrefix() /* set up urlPrefix for self referenes */ { char *httpHost = getenv("HTTP_HOST"); if (isEmpty(httpHost)) urlPrefix = ""; else { if (! startsWith("hgwdev-api", httpHost)) { if (startsWith("hgwdev",httpHost) || startsWith("genome-test", httpHost)) { urlPrefix = "../cgi-bin/hubApi"; } } } } static void showCartDump() /* for information purposes only during development, will become obsolete */ { hPrintf("

    cart dump

    "); hPrintf("
    \n");
     cartDump(cart);
     hPrintf("
    \n"); } static void sendJsonHogMessage(char *hogHost) { apiErrAbort(err429, err429Msg, "Your host, %s, has been sending too many requests lately and is " "unfairly loading our site, impacting performance for other users. " "Please contact genome@soe.ucsc.edu to ask that your site " "be reenabled. Also, please consider downloading sequence and/or " "annotations in bulk -- see http://genome.ucsc.edu/downloads.html.", hogHost); } static void sendHogMessage(char *hogHost) { puts("Content-Type:text/html"); hPrintf("Status: %d %s\n", err429, err429Msg); puts("Retry-After: 30"); puts("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("Status %d %s\n", err429, err429Msg); hPrintf("

    Status %d %s

    \n", err429, err429Msg); hPrintf("Your host, %s, has been sending too many requests lately and is " "unfairly loading our site, impacting performance for other users. " "Please contact genome@soe.ucsc.edu to ask that your site " "be reenabled. Also, please consider downloading sequence and/or " "annotations in bulk -- see http://genome.ucsc.edu/downloads.html.", hogHost); hPrintf("

    \n"); cgiExitTime("hubApi hogExit", enteredMainTime); exit(0); } static void hogExit() /* bottleneck server requests exit */ { char *hogHost = getenv("REMOTE_ADDR"); char *pathInfo = getenv("PATH_INFO"); /* nothing on incoming path, then display the WEB page instead */ if (sameOk("/",pathInfo)) pathInfo = NULL; if (isNotEmpty(pathInfo)) { sendJsonHogMessage(hogHost); } else { sendHogMessage(hogHost); } } /* static void hogExit() */ /* name of radio button group */ #define RADIO_GROUP "selectRadio" /* button functions */ #define RADIO_PUBHUB "pubHub" #define RADIO_OTHERHUB "otherHub" #define RADIO_UCSCDB "ucscDb" static void selectionForm() /* setup the selection pull-downs for source */ { char *hubDropDown = cartUsualString(cart, "publicHubs", defaultHub); char *urlDropDown = urlFromShortLabel(hubDropDown); char *otherHubUrl = cartUsualString(cart, "urlHub", ""); char *ucscDb = cartUsualString(cart, "ucscGenome", defaultDb); if (isEmpty(otherHubUrl)) otherHubUrl = urlDropDown; char *radioOn = cartUsualString(cart, RADIO_GROUP, RADIO_PUBHUB); /* create border around table, but not inside the table with the data */ hPrintf("\n"); hPrintf("
    \n"); hPrintf("\n"); int maxDbNameWidth = 0; struct dbDb *dbList = ucscDbDb(); char **ucscDbList = NULL; int listSize = slCount(dbList); AllocArray(ucscDbList, listSize); struct dbDb *el = dbList; int ucscDataBaseCount = 0; for ( ; el != NULL; el = el->next ) { ucscDbList[ucscDataBaseCount++] = el->name; if (strlen(el->name) > maxDbNameWidth) maxDbNameWidth = strlen(el->name); } maxDbNameWidth += 1; hPrintf("\n\n", urlPrefix); hWrites("\n"); hWrites("\n"); hWrites("\n"); allTrackSettings = cartUsualBoolean(cart, "allTrackSettings", FALSE); hWrites("\n"); trackLeavesOnly = cartUsualBoolean(cart, "trackLeavesOnly", trackLeavesOnly); hWrites("\n"); jsonOutputArrays = cartUsualBoolean(cart, "jsonOutputArrays", jsonOutputArrays); hWrites("\n"); /* go button at the bottom of the table */ hWrites("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("
    Select one of these three sources, and display options:
    "); jsMakeTrackingRadioButton(RADIO_GROUP, "typeOneJs", RADIO_PUBHUB, radioOn); hWrites(""); hWrites("Select public hub:"); hWrites(""); #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); jsOnEventById("change", "publicHubs", "document.getElementById('"RADIO_GROUP"_"RADIO_PUBHUB"').checked=true;"); hWrites("
    "); jsMakeTrackingRadioButton(RADIO_GROUP, "typeOneJs", RADIO_OTHERHUB, radioOn); hWrites(""); hWrites("enter a hub URL:"); hWrites(""); hPrintf("\n", otherHubUrl); jsOnEventById("change", "urlHub", "document.getElementById('"RADIO_GROUP"_"RADIO_OTHERHUB"').checked=true;"); hWrites("
    "); jsMakeTrackingRadioButton(RADIO_GROUP, "typeOneJs", RADIO_UCSCDB, radioOn); hWrites(""); hWrites("select a UCSC database name:"); hWrites(""); maxDbNameWidth *= 9; // 9 should be font width here char widthPx[SMALLBUF]; safef(widthPx, sizeof(widthPx), "width: %dpx", maxDbNameWidth); cgiMakeDropListClassWithIdStyleAndJavascript("ucscGenome", "ucscGenome", ucscDbList, ucscDataBaseCount, ucscDb, NULL, widthPx, events); jsOnEventById("change", "ucscGenome", "document.getElementById('"RADIO_GROUP"_"RADIO_UCSCDB"').checked=true;"); hWrites("
     display control:"); hCheckBox("allTrackSettings", allTrackSettings); hWrites(" display all track settings for each track"); hWrites("
     JSON list output:"); hCheckBox("trackLeavesOnly", trackLeavesOnly); hWrites(" show only data tracks, do not show composite container information"); hWrites("
     JSON output type:"); hCheckBox("jsonOutputArrays", jsonOutputArrays); hWrites(" more array data than objects (default: mostly object output)"); hWrites("
     "); hButton("sourceSelected", "go"); hWrites("press 'go' after selections made
    (example JSON list output: Public hubs, and UCSC database genomes)
    \n"); hPrintf("
    \n"); /* how does debug carry forward ? */ // if (debug) // cgiMakeHiddenVar("debug", "1"); } static void apiRequest(char *pathInfo) { hPrintDisable(); /*expect no more than MAX_PATH_INFO number of words*/ char *words[MAX_PATH_INFO]; /* can immediately verify valid parameters right here right now */ char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); char *db = cgiOptionalString("genome"); char *hubUrl = cgiOptionalString("hubUrl"); struct dyString *errorMsg = newDyString(128); if (isEmpty(hubUrl) && isNotEmpty(db)) { struct sqlConnection *conn = hAllocConnMaybe(db); if (NULL == conn) dyStringPrintf(errorMsg, "can not find genome genome='%s' for endpoint '%s'", db, pathInfo); else hFreeConn(&conn); } if (isNotEmpty(start) || isNotEmpty(end)) { long long llStart = -1; long long llEnd = -1; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { if (isNotEmpty(start)) llStart = sqlLongLong(start); if (isNotEmpty(end)) llEnd = sqlLongLong(end); } errCatchEnd(errCatch); if (errCatch->gotError) { if (isNotEmpty(errorMsg->string)) dyStringPrintf(errorMsg, ", "); dyStringPrintf(errorMsg, "%s", errCatch->message->string); if (isNotEmpty(start) && (-1 == llStart)) dyStringPrintf(errorMsg, ", can not recognize start coordinate: '%s'", start); if (isNotEmpty(end) && (-1 == llEnd)) dyStringPrintf(errorMsg, ", can not recognize end coordinate: '%s'", end); } else { if ( (llStart < 0) || (llEnd < 0) || (llEnd <= llStart) ) { if (isNotEmpty(errorMsg->string)) dyStringPrintf(errorMsg, ", "); dyStringPrintf(errorMsg, "illegal start,end coordinates given: %s,%s, 'end' must be greater than 'start', and start greater than or equal to zero", start, end); } } errCatchFree(&errCatch); } if (isNotEmpty(errorMsg->string)) apiErrAbort(err400, err400Msg, "%s", errorMsg->string); setupFunctionHash(); struct hashEl *hel = parsePathInfo(pathInfo, words); /* verify valid API command */ if (hel) /* have valid command */ { hPrintDisable(); void (*apiFunction)(char **) = hel->val; (*apiFunction)(words); return; } else apiErrAbort(err400, err400Msg, "no such command: '/%s", pathInfo); /* due to Apache rewrite rules, will never be called with this error */ } /* static void apiRequest(char *pathInfo) */ static void doMiddle(struct cart *theCart) /* Set up globals and make web page */ { cart = theCart; // measureTiming = isNotEmpty(cartOptionalString(cart, "measureTiming")); char *database = NULL; char *genome = NULL; if (measureTiming) startProcessTiming(); cgiVarSet("ignoreCookie", "1"); getDbAndGenome(cart, &database, &genome, oldVars); initGenbankTableNames(database); initUrlPrefix(); trackLeavesOnly = cartUsualBoolean(cart, "trackLeavesOnly", trackLeavesOnly); jsonOutputArrays = cartUsualBoolean(cart, "jsonOutputArrays", jsonOutputArrays); char *pathInfo = getenv("PATH_INFO"); /* nothing on incoming path, then display the WEB page instead */ if (sameOk("/",pathInfo)) pathInfo = NULL; (void) hubPublicDbLoadAll(); webStartJWest(cart, database, "Genome Browser API"); // webStartGbNoBanner(cart, database, "UCSC JSON API interface"); // webStartGbOptionalBanner(cart, database, "UCSC JSON API interface", TRUE, FALSE); hPrintf("
    \n"); /* these style mentions need to go into custom css file */ hPrintf("
    \n"); if (debug) { hPrintf("
      \n"); hPrintf("
    • hgBotDelay: %d
    • \n", botDelay); char *envVar = getenv("BROWSER_HOST"); hPrintf("
    • BROWSER_HOST:%s
    • \n", envVar); envVar = getenv("CONTEXT_DOCUMENT_ROOT"); hPrintf("
    • CONTEXT_DOCUMENT_ROOT:%s
    • \n", envVar); envVar = getenv("CONTEXT_PREFIX"); hPrintf("
    • CONTEXT_PREFIX:%s
    • \n", envVar); envVar = getenv("DOCUMENT_ROOT"); hPrintf("
    • DOCUMENT_ROOT:%s
    • \n", envVar); envVar = getenv("HTTP_HOST"); hPrintf("
    • HTTP_HOST:%s
    • \n", envVar); envVar = getenv("REQUEST_URI"); hPrintf("
    • REQUEST_URI:%s
    • \n", envVar); envVar = getenv("SCRIPT_FILENAME"); hPrintf("
    • SCRIPT_FILENAME:%s
    • \n", envVar); envVar = getenv("SCRIPT_NAME"); hPrintf("
    • SCRIPT_NAME:%s
    • \n", envVar); envVar = getenv("SCRIPT_URI"); hPrintf("
    • SCRIPT_URI:%s
    • \n", envVar); envVar = getenv("SCRIPT_URL"); hPrintf("
    • SCRIPT_URL:%s
    • \n", envVar); envVar = getenv("SERVER_NAME"); hPrintf("
    • SERVER_NAME:%s
    • \n", envVar); envVar = getenv("PATH_INFO"); if (isNotEmpty(envVar)) hPrintf("
    • PATH_INFO:'%s'
    • \n", envVar); else hPrintf("
    • PATH_INFO:<empty>
    • \n"); hPrintf("
    \n"); } char *otherHubUrl = cartUsualString(cart, "urlHub", ""); char *hubDropDown = cartUsualString(cart, "publicHubs", defaultHub); char *urlDropDown = urlFromShortLabel(hubDropDown); char *ucscDb = cartUsualString(cart, "ucscGenome", defaultDb); char *selectRadio = cartUsualString(cart, RADIO_GROUP, RADIO_PUBHUB); char *urlInput = urlDropDown; /* assume public hub */ if (debug) { hPrintf("
      \n"); hPrintf("
    • otherHubUrl: '%s'
    • \n", otherHubUrl); hPrintf("
    • hubDropDown: '%s'
    • \n", hubDropDown); hPrintf("
    • urlDropDown: '%s'
    • \n", urlDropDown); hPrintf("
    • ucscDb: '%s'
    • \n", ucscDb); hPrintf("
    • urlInput: '%s'
    • \n", urlInput); hPrintf("
    \n"); } if (isEmpty(otherHubUrl)) otherHubUrl = urlInput; if (sameWord(RADIO_OTHERHUB, selectRadio)) /* requested other hub URL */ urlInput = otherHubUrl; long lastTime = clock1000(); struct trackHub *hub = errCatchTrackHubOpen(urlInput); if (measureTiming) { long thisTime = clock1000(); hPrintf("hub open time: %ld millis
    \n", thisTime - lastTime); } hPrintf("

    Documentation: API definitions/help, and Track definition document for definitions of track settings.

    \n"); if (debug) showCartDump(); hPrintf("

    Explore hub or database assemblies and tracks

    \n"); selectionForm(); /* these style mentions need to go into custom css file */ hPrintf("
    \n"); if (sameWord(RADIO_UCSCDB, selectRadio)) /* requested UCSC db track list */ { tracksForUcscDb(ucscDb); } else { hPrintf("

    %s url: %s

    \n", sameWord(RADIO_PUBHUB,selectRadio) ? "Public hub" : "Other hub", urlInput); hPrintf("
      \n"); hubInfo("hub name", hub->name); hubInfo("short label", hub->shortLabel); hubInfo("long label", hub->longLabel); hubInfo("genomes file", hub->genomesFile); hubInfo("default db", hub->defaultDb); hubInfo("description url", hub->descriptionUrl); hubInfo("email", hub->email); if (debug) { hubInfo("version", hub->version); /* UCSC internal info */ hubInfo("level", hub->level); /* UCSC internal info */ } hPrintf("
    \n"); genomeList(hub); } if (timedOut) hPrintf("

    Reached time out %ld seconds

    ", timeOutSeconds); if (measureTiming) hPrintf("Overall total time: %ld millis
    \n", clock1000() - enteredMainTime); hPrintf("
    \n"); hPrintf("
    \n"); hPrintf("
    \n"); webIncludeFile("inc/jWestFooter.html"); webEndJWest(); // cartWebEnd(); } /* void doMiddle(struct cart *theCart) */ static void setGlobalCgiVars() /* check for legal CGI variables and set global flags */ { /* count the arguments to see if any occur more than once */ struct hash *varCounter = hashNew(0); struct cgiVar *varList = cgiVarList(); struct cgiVar *el = varList; for ( ; el; el = el->next) { hashIncInt(varCounter, el->name); } struct hashCookie cookie = hashFirst(varCounter); struct hashEl *hel = NULL; for ( hel = hashNext(&cookie); hel; hel = hashNext(&cookie)) { if (ptToInt(hel->val) > 1) apiErrAbort(err400, err400Msg, "parameter '%s' found %d times, only one instance allowed", hel->name, ptToInt(hel->val)); } char *trackLeaves = cgiOptionalString("trackLeavesOnly"); if (isNotEmpty(trackLeaves)) { if (sameString("1", trackLeaves)) trackLeavesOnly = TRUE; else if (sameString("0", trackLeaves)) trackLeavesOnly = FALSE; else apiErrAbort(err400, err400Msg, "unrecognized 'trackLeavesOnly=%s' argument, can only be =1 or =0", trackLeaves); } char *jsonArray = cgiOptionalString("jsonOutputArrays"); if (isNotEmpty(jsonArray)) { if (sameString("1", jsonArray)) jsonOutputArrays = TRUE; else if (sameString("0", jsonArray)) jsonOutputArrays = FALSE; else apiErrAbort(err400, err400Msg, "unrecognized 'jsonOutputArrays=%s' argument, can only be =1 or =0", jsonArray); } int maybeDebug = cgiOptionalInt("debug", 0); if (1 == maybeDebug) debug = TRUE; char *measTime = cgiOptionalString("measureTiming"); if (isNotEmpty(measTime) && sameWord("1", measTime)) measureTiming = TRUE; char *maxOut = cgiOptionalString("maxItemsOutput"); if (isNotEmpty(maxOut)) { long long n = -2; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { n = sqlLongLong(maxOut); } errCatchEnd(errCatch); if (errCatch->gotError) apiErrAbort(err400, err400Msg, "can not recognize maxItemsOutput '%s' as a number", maxOut); else { if (n == -1) /* can use -1 to indicate as much as allowed */ maxItemsOutput = maxItemLimit; else if (n > maxItemLimit) /* safety check */ apiErrAbort(err400, err400Msg, "requested maxItemsOutput '%s' greater than maximum limit allowed: %d", maxOut, maxItemLimit); else if (n < 1) apiErrAbort(err400, err400Msg, "requested maxItemsOutput '%s' can not be less than one", maxOut, maxItemLimit); else maxItemsOutput = n; } } } /* static void setGlobalCgiVars() */ static void redirectToHelp() /* redirect to the help page */ { puts("Content-Type:text/html"); hPrintf("Status: %d %s\n", err301, err301Msg); hPrintf("Location: /goldenPath/help/api.html\n"); puts("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("\n"); hPrintf("\n"); } /* Null terminated list of CGI Variables we don't want to save * permanently. */ static char *excludeVars[] = {"Submit", "submit", "sourceSelected", "selectRadio", "ucscGenome", "publicHubs", "clade", NULL,}; int main(int argc, char *argv[]) /* Process command line. */ { enteredMainTime = clock1000(); cgiSpoof(&argc, argv); verboseTimeInit(); /* similar delay system as in DAS server */ botDelay = hgBotDelayTimeFrac(delayFraction); if (botDelay > 0) { if (botDelay > 2000) { sleep1000(botDelay); hogExit(); return 0; } sleep1000(botDelay); } setGlobalCgiVars(); int timeout = cgiOptionalInt("udcTimeout", 300); if (udcCacheTimeout() < timeout) udcSetCacheTimeout(timeout); knetUdcInstall(); initSupportedTypes(); char *pathInfo = getenv("PATH_INFO"); if (isNotEmpty(pathInfo)) /* can get to this immediately, no cart needed */ apiRequest(pathInfo); else { char *allowApiHtml = cfgOptionDefault("hubApi.allowHtml", "off"); if (sameWord("on", allowApiHtml)) { trackCounter = hashNew(0); cartEmptyShellNoContent(doMiddle, hUserCookie(), excludeVars, oldVars); } else redirectToHelp(); } cgiExitTime("hubApi", enteredMainTime); return 0; }