8715d83d38d8bb18adfdd9ce05771b4cede85407 angie Fri Dec 5 09:52:07 2014 -0800 Moved some hgTables code that had been copied into a couple differentplaces into a new lib module, cartTrackDb. hgGenome/import.c has code that is fairly similar but that also needs to filter out custom tracks that were generated by hgGenome. diff --git src/hg/hgTables/mainPage.c src/hg/hgTables/mainPage.c index 25c7ec9..e4d8195 100644 --- src/hg/hgTables/mainPage.c +++ src/hg/hgTables/mainPage.c @@ -1,1055 +1,953 @@ /* mainPage - stuff to put up the first table browser page. */ /* Copyright (C) 2014 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "htmshell.h" #include "cheapcgi.h" #include "cart.h" +#include "cartTrackDb.h" #include "textOut.h" #include "jksql.h" #include "hdb.h" #include "web.h" #include "jsHelper.h" #include "hui.h" #include "hgColors.h" #include "trackDb.h" #include "grp.h" #include "hgTables.h" #include "joiner.h" #include "hubConnect.h" #include "trackHub.h" #include "hgConfig.h" int trackDbCmpShortLabel(const void *va, const void *vb) /* Sort track by shortLabel. */ { const struct trackDb *a = *((struct trackDb **)va); const struct trackDb *b = *((struct trackDb **)vb); return strcmp(a->shortLabel, b->shortLabel); } static struct dyString *onChangeStart() /* Start up a javascript onChange command */ { struct dyString *dy = jsOnChangeStart(); jsDropDownCarryOver(dy, hgtaTrack); jsDropDownCarryOver(dy, hgtaGroup); jsTrackedVarCarryOver(dy, hgtaRegionType, "regionType"); jsTextCarryOver(dy, hgtaRange); jsDropDownCarryOver(dy, hgtaOutputType); jsTextCarryOver(dy, hgtaOutFileName); return dy; } static char *onChangeClade() /* Return javascript executed when they change clade. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, hgtaTable); dyStringAppend(dy, " document.hiddenForm.org.value=0;"); dyStringAppend(dy, " document.hiddenForm.db.value=0;"); dyStringAppend(dy, " document.hiddenForm.position.value='';"); return jsOnChangeEnd(&dy); } static char *onChangeOrg() /* Return javascript executed when they change organism. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "org"); jsDropDownCarryOver(dy, hgtaTable); dyStringAppend(dy, " document.hiddenForm.db.value=0;"); dyStringAppend(dy, " document.hiddenForm.position.value='';"); return jsOnChangeEnd(&dy); } static char *onChangeDb() /* Return javascript executed when they change database. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "db"); jsDropDownCarryOver(dy, hgtaTable); dyStringAppend(dy, " document.hiddenForm.position.value='';"); return jsOnChangeEnd(&dy); } static char *onChangeGroupOrTrack() /* Return javascript executed when they change group. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "db"); jsDropDownCarryOver(dy, "org"); dyStringPrintf(dy, " document.hiddenForm.%s.value=0;", hgtaTable); return jsOnChangeEnd(&dy); } static char *onChangeTable() /* Return javascript executed when they change group. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "db"); jsDropDownCarryOver(dy, "org"); jsDropDownCarryOver(dy, hgtaTable); return jsOnChangeEnd(&dy); } void makeRegionButton(char *val, char *selVal) /* Make region radio button including a little Javascript * to save selection state. */ { jsMakeTrackingRadioButton(hgtaRegionType, "regionType", val, selVal); } struct grp *showGroupField(char *groupVar, char *groupScript, struct sqlConnection *conn, boolean allTablesOk) /* Show group control. Returns selected group. */ { struct grp *group, *groupList = fullGroupList; struct grp *selGroup = findSelectedGroup(groupList, groupVar); hPrintf("group:\n"); hPrintf("\n"); return selGroup; } static void addIfExists(struct hash *hash, struct slName **pList, char *name) /* Add name to tail of list if it exists in hash. */ { if (hashLookup(hash, name)) slNameAddTail(pList, name); } struct slName *getDbListForGenome() /* Get list of selectable databases. */ { struct hash *hash = sqlHashOfDatabases(); struct slName *dbList = NULL; addIfExists(hash, &dbList, database); addIfExists(hash, &dbList, "uniProt"); addIfExists(hash, &dbList, "proteome"); addIfExists(hash, &dbList, "go"); addIfExists(hash, &dbList, "hgFixed"); addIfExists(hash, &dbList, "visiGene"); addIfExists(hash, &dbList, "ultra"); return dbList; } char *findSelDb() /* Find user selected database (as opposed to genome database). */ { struct slName *dbList = getDbListForGenome(); char *selDb = cartUsualString(cart, hgtaTrack, NULL); if (!slNameInList(dbList, selDb)) selDb = cloneString(dbList->name); slFreeList(&dbList); return selDb; } struct trackDb *showTrackField(struct grp *selGroup, char *trackVar, char *trackScript) /* Show track control. Returns selected track. */ { struct trackDb *track, *selTrack = NULL; if (trackScript == NULL) trackScript = ""; if (sameString(selGroup->name, "allTables")) { char *selDb = findSelDb(); struct slName *dbList = getDbListForGenome(), *db; hPrintf("database:\n"); hPrintf("\n"); } else { boolean allTracks = sameString(selGroup->name, "allTracks"); hPrintf("track:\n"); hPrintf("\n"); } hPrintf("\n"); return selTrack; } char *unsplitTableName(char *table) /* Convert chr*_name to name */ { if (startsWith("chr", table)) { char *s = strrchr(table, '_'); if (s != NULL) { table = s + 1; } } return table; } -static char *chopAtFirstDot(char *string) -/* Terminate string at first '.' if found. Return string for convenience. */ -{ -char *ptr = strchr(string, '.'); -if (ptr != NULL) - *ptr = '\0'; -return string; -} - -static void hashAddSlName(struct hash *hash, char *key, char *val) -/* If key is already in hash, add an slName for val to the head of the list; - * otherwise just store key -> slName for val. */ -{ -struct slName *sln = slNameNew(val); -struct hashEl *hel = hashLookup(hash, key); -if (hel == NULL) - hashAdd(hash, key, sln); -else - slAddHead(&(hel->val), sln); -} - -static struct hash *accessControlInit(struct sqlConnection *conn) -/* Return a hash associating restricted table/track names in the given db/conn - * with virtual hosts, or NULL if there is no tableAccessControl table and no - * forbiddenTrackList (see getFullTrackList). */ -{ -struct hash *acHash = NULL; -if (sqlTableExists(conn, "tableAccessControl")) - { - struct sqlResult *sr = NULL; - char **row = NULL; - acHash = newHash(0); - sr = sqlGetResult(conn, "NOSQLINJ select name,host from tableAccessControl"); - while ((row = sqlNextRow(sr)) != NULL) - hashAddSlName(acHash, row[0], chopAtFirstDot(row[1])); - sqlFreeResult(&sr); - } -if (forbiddenTrackList != NULL) - { - if (acHash == NULL) - acHash = newHash(0); - struct trackDb *tdb; - for (tdb = forbiddenTrackList; tdb != NULL; tdb = tdb->next) - { - char *tbOff = cloneString(trackDbSetting(tdb, "tableBrowser")); - if (isEmpty(tbOff)) - errAbort("bug: tdb for %s is in forbiddenTrackList without 'tableBrowser off' setting", - tdb->track); - hashAddSlName(acHash, tdb->table, "-"); - // skip "off" and look for additional table names: - nextWord(&tbOff); - char *tbl; - while ((tbl = nextWord(&tbOff)) != NULL) - hashAddSlName(acHash, tbl, "-"); - } - } -return acHash; -} - -boolean accessControlDenied(char *db, char *table) -/* Return TRUE if table access is restricted to some host(s) other than - * the one we're running on. */ -{ -static char *currentHost = NULL; -struct slName *enabledHosts = NULL; -struct slName *sln = NULL; -static struct hash *dbToAcHash = NULL; - -if (dbToAcHash == NULL) - dbToAcHash = hashNew(0); - -struct hash *acHash = hashFindVal(dbToAcHash, db); -if (acHash == NULL) - { - struct sqlConnection *conn = hAllocConn(db); - acHash = accessControlInit(conn); - hFreeConn(&conn); - hashAdd(dbToAcHash, db, acHash); - } - -if (acHash == NULL) - return FALSE; -enabledHosts = (struct slName *)hashFindVal(acHash, table); -if (enabledHosts == NULL) - return FALSE; -if (currentHost == NULL) - { - currentHost = cloneString(cgiServerName()); - if (currentHost == NULL) - { - warn("accessControl: unable to determine current host"); - return FALSE; - } - else - chopAtFirstDot(currentHost); - } -for (sln = enabledHosts; sln != NULL; sln = sln->next) - { - if (sameString(currentHost, sln->name)) - return FALSE; - } -return TRUE; -} - struct slName *tablesForDb(char *db) /* Find tables associated with database. */ { boolean isGenomeDb = sameString(db, database); struct sqlConnection *conn = hAllocConn(db); struct slName *raw, *rawList = sqlListTables(conn); struct slName *cooked, *cookedList = NULL; struct hash *uniqHash = newHash(0); hFreeConn(&conn); for (raw = rawList; raw != NULL; raw = raw->next) { if (isGenomeDb) { /* Deal with tables split across chromosomes. */ char *root = unsplitTableName(raw->name); - if (accessControlDenied(db, root) || accessControlDenied(db, raw->name)) + if (cartTrackDbIsAccessDenied(db, root) || cartTrackDbIsAccessDenied(db, raw->name)) continue; if (!hashLookup(uniqHash, root)) { hashAdd(uniqHash, root, NULL); cooked = slNameNew(root); slAddHead(&cookedList, cooked); } } else { char dbTable[256]; - if (accessControlDenied(db, raw->name)) + if (cartTrackDbIsAccessDenied(db, raw->name)) continue; safef(dbTable, sizeof(dbTable), "%s.%s", db, raw->name); cooked = slNameNew(dbTable); slAddHead(&cookedList, cooked); } } hashFree(&uniqHash); slFreeList(&rawList); slSort(&cookedList, slNameCmp); return cookedList; } char *showTableField(struct trackDb *track, char *varName, boolean useJoiner) /* Show table control and label. */ { struct slName *name, *nameList = NULL; char *selTable; if (track == NULL) nameList = tablesForDb(findSelDb()); else - nameList = tablesForTrack(track, useJoiner); + nameList = cartTrackDbTablesForTrack(database, track, useJoiner); /* Get currently selected table. If it isn't in our list * then revert to first in list. */ selTable = cartUsualString(cart, varName, nameList->name); if (!slNameInListUseCase(nameList, selTable)) selTable = nameList->name; /* Print out label and drop-down list. */ hPrintf("table: "); hPrintf("\n"); if (!trackHubDatabase(database)) { char *restrictDate = encodeRestrictionDateDisplay(database,selTdb); if (restrictDate) { hPrintf("restricted until: %s", ENCODE_DATA_RELEASE_POLICY, restrictDate); freeMem(restrictDate); } } return selTable; } struct outputType /* Info on an output type. */ { struct outputType *next; char *name; /* Symbolic name of type. */ char *label; /* User visible label. */ }; static void showOutDropDown(struct outputType *otList, struct outputType *otDefault) /* Display output drop-down. */ { struct outputType *ot; char *outputType = cartUsualString(cart, hgtaOutputType, otList->name); if (otDefault != NULL && otDefault != otList) { boolean otInOtList = FALSE; for (ot = otList; ot != NULL; ot = ot->next) if (sameString(ot->name, outputType)) { otInOtList = TRUE; break; } if (! otInOtList) outputType = otDefault->name; } hPrintf("\n"); hPrintf(" "); if (!cfgOptionBooleanDefault("hgta.disableSendOutput", FALSE)) { hPrintf(" Send output to "); struct dyString *dy = dyStringNew(256); dyStringAppend(dy, "onclick=\"document.getElementById('checkboxGreat').checked=false;"); if (isGenomeSpaceEnabled()) dyStringAppend(dy, "document.getElementById('checkboxGenomeSpace').checked=false;"); dyStringAppend(dy, "return true;\""); cgiMakeCheckBoxIdAndJS("sendToGalaxy", doGalaxy(), "checkboxGalaxy", dy->string); hPrintf("Galaxy\n"); nbSpaces(2); cgiMakeCheckBoxIdAndJS("sendToGreat", doGreat(), "checkboxGreat", "onclick=\"return onSelectGreat();\""); hPrintf(" GREAT"); if (isGenomeSpaceEnabled()) { nbSpaces(2); cgiMakeCheckBoxIdAndJS("sendToGenomeSpace", doGenomeSpace(), "checkboxGenomeSpace", "onclick=\"document.getElementById('checkboxGreat').checked=false;" "document.getElementById('checkboxGalaxy').checked=false; return true;\""); hPrintf(" GenomeSpace"); } } hPrintf("\n"); } struct outputType otAllFields = { NULL, outPrimaryTable,"all fields from selected table", }; struct outputType otSelected = { NULL, outSelectedFields, "selected fields from primary and related tables", }; struct outputType otSequence = { NULL, outSequence, "sequence", }; struct outputType otPal = { NULL, outPalOptions, "CDS FASTA alignment from multiple alignment", }; struct outputType otGff = { NULL, outGff, "GTF - gene transfer format", }; struct outputType otBed = { NULL, outBed, "BED - browser extensible data", }; struct outputType otCustomTrack = { NULL, outCustomTrack, "custom track", }; struct outputType otHyperlinks = { NULL, outHyperlinks, "hyperlinks to Genome Browser", }; struct outputType otWigData = { NULL, outWigData, "data points", }; struct outputType otWigBed = { NULL, outWigBed, "bed format", }; struct outputType otMaf = { NULL, outMaf, "MAF - multiple alignment format", }; struct outputType otChromGraphData = { NULL, outChromGraphData, "data points", }; struct outputType otMicroarrayNames = { NULL, outMicroarrayNames, "microarray names", }; struct outputType otMicroarrayGroupings = { NULL, outMicroarrayGroupings, "microarray groupings", }; static void showOutputTypeRow(boolean isWig, boolean isBedGr, boolean isPositional, boolean isMaf, boolean isChromGraphCt, boolean isPal, boolean isMicroarray, boolean isHalSnake) /* Print output line. */ { struct outputType *otList = NULL, *otDefault = NULL; boolean bedifiedOnly = (anySubtrackMerge(database, curTable) || anyIntersection()); hPrintf("
" "To reset all user cart settings (including custom tracks), \n" "click here.\n", getScriptName()); } static char *getGenomeSpaceText() /* fetch GenomeSpace text if enabled */ { if (isGenomeSpaceEnabled()) { return "Send data to " "GenomeSpace for use with diverse computational tools. "; } else { return ""; } } void mainPageAfterOpen(struct sqlConnection *conn) /* Put up main page assuming htmlOpen()/htmlClose() * will happen in calling routine. */ { hPrintf( "Use this program to retrieve the data associated with a track in text " "format, to calculate intersections between tracks, and to retrieve " "DNA sequence covered by a track. For help in using this application " "see Using the Table Browser for a description " "of the controls in this form, the " "User's Guide for " "general information and sample queries, and the OpenHelix Table Browser " "tutorial for a narrated presentation of the software " "features and usage. " "For more complex queries, you may want to use " "Galaxy or " "our public " "MySQL server. " "To examine the biological function of your set through annotation " "enrichments, send the data to " "GREAT. " "%s" "Refer to the " "Credits page for the list of " "contributors and usage restrictions associated with these data. " "All tables can be downloaded in their entirety from the " "Sequence and Annotation Downloads page." , getGenomeSpaceText() ); hPrintf("\n"); /* Main form. */ hPrintf("
\n"); /* Hidden form - for benefit of javascript. */ { static char *saveVars[] = { "clade", "org", "db", hgtaGroup, hgtaTrack, hgtaTable, hgtaRegionType, hgtaRange, hgtaOutputType, hgtaOutFileName}; jsCreateHiddenForm(cart, getScriptName(), saveVars, ArraySize(saveVars)); } /* Hidden form for jumping to custom tracks CGI. */ hPrintf("\n"); /* Hidden form for jumping to track hub manager CGI. */ hPrintf("\n"); webNewSection("Using the Table Browser\n"); printMainHelp(); cartFlushHubWarnings(); } void doMainPage(struct sqlConnection *conn) /* Put up the first page user sees. */ { htmlOpen("Table Browser"); mainPageAfterOpen(conn); htmlClose(); }