4409063550e6c4cc87cfd37f92f7b8db2699f885 hiram Fri Mar 13 17:13:14 2026 -0700 with the aid of claude add a genome argument to the ucscGenomes endpoint and manage assembly alias a bit more than previously for ucscGenomes and genarkGenomes refs #35972 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index c4d61549338..cb60ecf8e3f 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -1,20 +1,21 @@ /* hubApi - access mechanism to hub data resources. */ #include "dataApi.h" #include "botDelay.h" #include "jsHelper.h" #include "srcVersion.h" +#include "asmAlias.h" /* can not include bamFile.h with the liftOver business, there * is a conflict in a definition of the enum 'bed' */ #include "bamFile.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 | | @@ -35,31 +36,31 @@ /* 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 *argListUcscGenomes[] = { argGenome, NULL }; char *argListGenarkGenomes[] = { argMaxItemsOutput, argGenome, NULL }; char *argListHubGenomes[] = { argHubUrl, NULL }; char *argListTracks[] = { argGenome, argHubUrl, argTrackLeavesOnly, NULL }; char *argListChromosomes[] = { argGenome, argHubUrl, argTrack, NULL }; char *argListSchema[] = { argGenome, argHubUrl, argTrack, NULL }; char *argListFiles[] = { argGenome, argMaxItemsOutput, argFormat, argSkipContext, argFileType, NULL }; char *argGetDataTrack[] = { argGenome, argHubUrl, argTrack, argChrom, argStart, argEnd, argMaxItemsOutput, argJsonOutputArrays, NULL }; char *argGetDataSequence[] = { argGenome, argHubUrl, argTrack, argChrom, argStart, argEnd, argRevComp, NULL }; char *argSearch[] = {argSearchTerm, argGenome, argHubUrl, argCategories, NULL}; char *argFindGenome[] = {argQ, argMaxItemsOutput, argJsonOutputArrays, argStatsOnly, argBrowser, argYear, argCategory, argStatus, argLevel, argLiftable, NULL}; char *argLiftOver[] = {argFromGenome, argToGenome, argChrom, argStart, argEnd, argFilter, argMaxItemsOutput, NULL}; char *argLiftRequest[] = {argFromGenome, argToGenome, argEmail, argComment, NULL}; /* Global only to this one source file */ static struct cart *cart; /* CGI and other variables */ @@ -1297,31 +1298,52 @@ // change up the arguments so it appears an assembly hub had been requested correctly db = trackHubSkipHubName(db); cgiVarSet("genome", db); hubUrl = hub->hubUrl; cgiVarSet("hubUrl", hubUrl); } } } if (isEmpty(hubUrl) && isNotEmpty(db)) { if ( ! isGenArk(db) ) { struct sqlConnection *conn = hAllocConnMaybe(db); if (NULL == conn) + { + /* not found directly, try alias lookup before failing */ + char *origDb = db; + char *aliasDb = asmAliasFind(db); + if (differentString(aliasDb, db)) + { + db = aliasDb; + cgiVarSet("genome", db); + cgiVarSet("genomeInput", origDb); /* preserve original for error messages */ + /* re-validate with the resolved name */ + if ( ! isGenArk(db) ) + { + conn = hAllocConnMaybe(db); + if (NULL == conn) + dyStringPrintf(errorMsg, "can not find genome='%s' for endpoint '%s'", origDb, pathInfo); + else + hFreeConn(&conn); + } + } + else dyStringPrintf(errorMsg, "can not find 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);