760d941586a240c1b4c4e1143f1fd2a3f8ff96c1 braney Fri Apr 7 11:26:45 2017 -0700 add the ability to specify a fielded tab-sep file for metadata in a track hub diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 3a146dd..3bc4444 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -35,30 +35,31 @@ #include "snakeUi.h" #include "vcfUi.h" #include "vcf.h" #include "errCatch.h" #include "samAlignment.h" #include "makeItemsItem.h" #include "bedDetail.h" #include "pgSnp.h" #include "memgfx.h" #include "trackHub.h" #include "gtexUi.h" #include "genbank.h" #include "htmlPage.h" #include "longRange.h" #include "tagRepo.h" +#include "fieldedTable.h" #define SMALLBUF 256 #define MAX_SUBGROUP 9 #define ADD_BUTTON_LABEL "add" #define CLEAR_BUTTON_LABEL "clear" #define JBUFSIZE 2048 #define DEF_BUTTON "\"%s\"\n" #define DEF_BUTTON_JS "setCheckBoxesThatContain('%s',true,false,'%s','','%s');" \ "setCheckBoxesThatContain('%s',false,false,'%s','_defOff','%s');" #define DEFAULT_BUTTON(nameOrId,anc,beg,contains) \ printf(DEF_BUTTON,(anc),"defaults_sm.png","default"); \ safef(id, sizeof id, "btn_%s", (anc)); \ jsOnEventByIdF("click", id, DEF_BUTTON_JS,(nameOrId),(beg),(contains),(nameOrId),(beg),(contains)); @@ -180,30 +181,80 @@ { char *encFile = cgiEncode(file); dyLink = dyStringCreate(VOCAB_LINK_WITH_FILE,encFile,encTerm,encValue,title,label); freeMem(encFile); } else dyLink = dyStringCreate(VOCAB_LINK,encTerm,encValue,title,label); if (suffix != NULL) dyStringAppend(dyLink,suffix); // Don't encode since this may contain HTML freeMem(encTerm); freeMem(encValue); return dyStringCannibalize(&dyLink); } +char *tabSepMetaAsHtmlTable(char *tabSepMeta, struct trackDb *tdb,boolean showLongLabel,boolean showShortLabel) +/* Return a string which is an HTML table of the tags for this track which are stored as a fielded table. */ +{ +// If there's no file, there's no data. +if (tabSepMeta == NULL) + return ""; + +// If the trackDb entry doesn't have a foreign key, there's no data. +char *metaTag = trackDbSetting(tdb, "meta"); +if (metaTag == NULL) + return ""; + +static char *cachedTableName = NULL; +static struct hash *cachedHash = NULL; +static struct fieldedTable *cachedTable = NULL; + +// Cache this table because there's a good chance we'll get called again with it. +if ((cachedTableName == NULL) || differentString(tabSepMeta, cachedTableName)) + { + char *requiredFields[] = {"meta"}; + cachedTable = fieldedTableFromTabFile(tabSepMeta, NULL, requiredFields, sizeof requiredFields / sizeof (char *)); + cachedHash = fieldedTableUniqueIndex(cachedTable, requiredFields[0]); + cachedTableName = cloneString(tabSepMeta); + } + +// Look for this tag in the metadata. +struct fieldedRow *fr = hashFindVal(cachedHash, metaTag); +if (fr == NULL) + return ""; + +struct dyString *dyTable = dyStringCreate(""); +if (showLongLabel) + dyStringPrintf(dyTable,"",tdb->longLabel); +if (showShortLabel) + dyStringPrintf(dyTable,"" + "",tdb->shortLabel); + +int ii; +for(ii=0; ii < cachedTable->fieldCount; ii++) + { + char *fieldName = cachedTable->fields[ii]; + char *fieldVal = fr->row[ii]; + if (!sameString(fieldName, "meta") && !isEmpty(fieldVal)) + dyStringPrintf(dyTable,"" + "",fieldName, fieldVal); + } +dyStringAppend(dyTable,"
%s
shortLabel:%s
%s:%s
"); +return dyStringCannibalize(&dyTable); +} + char *tagStormAsHtmlTable(char *tagStormFile, struct trackDb *tdb,boolean showLongLabel,boolean showShortLabel) /* Return a string which is an HTML table of the tags for this track. */ { char *metaTag = trackDbSetting(tdb, "meta"); if (metaTag == NULL) return ""; struct slPair *pairs = tagRepoPairs(tagStormFile, "meta", metaTag); if (pairs == NULL) return ""; struct dyString *dyTable = dyStringCreate(""); if (showLongLabel) dyStringPrintf(dyTable,"",tdb->longLabel); @@ -212,30 +263,35 @@ "",tdb->shortLabel); for(; pairs; pairs = pairs->next) { if (!sameString(pairs->name, "meta") && !isEmpty((char *)pairs->val)) dyStringPrintf(dyTable,"" "",pairs->name, (char *)pairs->val); } dyStringAppend(dyTable,"
%s
%s
%s:%s
"); return dyStringCannibalize(&dyTable); } char *metadataAsHtmlTable(char *db,struct trackDb *tdb,boolean showLongLabel,boolean showShortLabel) // If metadata from metaDb exists, return string of html with table definition { +char *tabSepMeta = trackDbSetting(tdb, "metaTab"); + +if (tabSepMeta) + return tabSepMetaAsHtmlTable(tabSepMeta, tdb, showLongLabel, showShortLabel); + char *tagStormFile = trackDbSetting(tdb, "metaDb"); if (tagStormFile) return tagStormAsHtmlTable(tagStormFile, tdb, showLongLabel, showShortLabel); const struct mdbObj *safeObj = metadataForTable(db,tdb,NULL); if (safeObj == NULL || safeObj->vars == NULL) return NULL; //struct dyString *dyTable = dyStringCreate("",tdb->table); struct dyString *dyTable = dyStringCreate("
"); if (showLongLabel) dyStringPrintf(dyTable,"",tdb->longLabel); if (showShortLabel) dyStringPrintf(dyTable,"" @@ -302,54 +358,55 @@ } } dyStringPrintf(dyTable,"" "",mdbVar->var,mdbVar->val); } } dyStringAppend(dyTable,"
%s
shortLabel:
%s:%s
"); //mdbObjsFree(&mdbObj); // spill some memory return dyStringCannibalize(&dyTable); } boolean compositeMetadataToggle(char *db,struct trackDb *tdb,char *title, boolean embeddedInText,boolean showLongLabel) // If metadata from metaTbl exists, create a link that will allow toggling it's display { -char *tagStormFile = trackDbSetting(tdb, "metaDb"); -if (tagStormFile == NULL) +boolean hasMetaInHub = (trackDbSetting(tdb, "metaDb") != NULL) || (trackDbSetting(tdb, "metaTab") != NULL); +if (!hasMetaInHub) { const struct mdbObj *safeObj = metadataForTable(db,tdb,NULL); if (safeObj == NULL || safeObj->vars == NULL) return FALSE; } char id[256]; safef(id, sizeof id, "div_%s_link", tdb->track); printf("%s%s", (embeddedInText?" ":"

"),id,tdb->track, (title?title:"")); jsOnEventByIdF("click", id, "return metadataShowHide(\"%s\",%s,true);", tdb->track, showLongLabel?"true":"false"); printf("

",tdb->track, metadataAsHtmlTable(db,tdb,showLongLabel,FALSE)); return TRUE; } void extraUiLinks(char *db,struct trackDb *tdb) // Show metadata, and downloads, schema links where appropriate { char *tagStormFile = trackDbSetting(tdb, "metaDb"); -boolean hasMetadata = (tagStormFile != NULL) || (!tdbIsComposite(tdb) && !trackHubDatabase(db) +char *tabSepFile = trackDbSetting(tdb, "metaTab"); +boolean hasMetadata = (tagStormFile != NULL) || (tabSepFile != NULL) || (!tdbIsComposite(tdb) && !trackHubDatabase(db) && metadataForTable(db, tdb, NULL) != NULL); if (hasMetadata) printf("Metadata:
%s\n", metadataAsHtmlTable(db, tdb, FALSE, FALSE)); boolean schemaLink = (!tdbIsDownloadsOnly(tdb) && !trackHubDatabase(db) && isCustomTrack(tdb->table) == FALSE) && (hTableOrSplitExists(db, tdb->table)); boolean downloadLink = (trackDbSetting(tdb, "wgEncode") != NULL && !tdbIsSuperTrack(tdb)); int links = 0; if (schemaLink) links++; if (downloadLink) links++; if (links > 0)