dccec2a514b8c7aeecffbfac722f6c718f204fba
max
Thu Apr 25 12:08:23 2013 -0700
support for urls in bigBed+ fields via a new tdb statement "urls"
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index c32a693..d0cb384 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -927,46 +927,32 @@
* return itemName. */
{
char *sql = trackDbSetting(tdb, "idInUrlSql");
char *id = itemName;
if (sql != NULL)
{
char buf[256];
safef(buf, sizeof(buf), sql, itemName);
struct sqlConnection *conn = hAllocConn(database);
id = sqlQuickString(conn, buf);
hFreeConn(&conn);
}
return id;
}
-void printCustomUrlWithLabel(struct trackDb *tdb, char *itemName, char *itemLabel, char *urlSetting, boolean encode)
-/* Print custom URL specified in trackDb settings. */
-{
-char *url;
-char urlLabelSetting[32];
-
-/* check the url setting prefix and get the correct url setting from trackDb */
-if (sameWord(urlSetting, "url"))
- url = tdb->url;
-else
- url = trackDbSetting(tdb, urlSetting);
-
-if (url != NULL && url[0] != 0)
- {
- char *idInUrl = getIdInUrl(tdb, itemName);
- if (idInUrl != NULL)
+char* replaceInUrl(struct trackDb *tdb, char *url, char *idInUrl, boolean encode)
+/* replace $$ in url with idInUrl. Supports many other wildchards */
{
struct dyString *uUrl = NULL;
struct dyString *eUrl = NULL;
char startString[64], endString[64];
char *ins[9], *outs[9];
char *eItem = (encode ? cgiEncode(idInUrl) : cloneString(idInUrl));
sprintf(startString, "%d", winStart);
sprintf(endString, "%d", winEnd);
ins[0] = "$$";
outs[0] = idInUrl;
ins[1] = "$T";
outs[1] = tdb->track;
ins[2] = "$S";
outs[2] = seqName;
@@ -987,53 +973,88 @@
char *nextColon = stringIn(":", suffixClone+1);
if (nextColon) /* terminate suffixClone suffix */
*nextColon = '\0'; /* when next colon is present */
*suffix = '\0'; /* terminate itemClone prefix */
outs[7] = itemClone;
outs[8] = suffixClone;
/* small memory leak here for these cloned strings */
/* not important for a one-time operation in a CGI that will exit */
} else {
outs[7] = idInUrl; /* otherwise, these are not expected */
outs[8] = idInUrl; /* to be used */
}
uUrl = subMulti(url, ArraySize(ins), ins, outs);
outs[0] = eItem;
eUrl = subMulti(url, ArraySize(ins), ins, outs);
+freeDyString(&uUrl);
+freeMem(eItem);
+return eUrl->string;
+}
+
+char* constructUrl(struct trackDb *tdb, char *urlSetting, char *idInUrl, boolean encode)
+{
+/* construct the url by replacing $$, etc in the url given by urlSetting.
+ * Replace $$ with itemName. */
+
+// check the url setting prefix and get the correct url setting from trackDb
+char *url;
+if (sameWord(urlSetting, "url"))
+ url = tdb->url;
+else
+ url = trackDbSetting(tdb, urlSetting);
+
+if (url == NULL || url[0] == 0)
+ return NULL;
+
+char* eUrl = replaceInUrl(tdb, url, idInUrl, encode);
+return eUrl;
+}
+
+void printCustomUrlWithLabel(struct trackDb *tdb, char *itemName, char *itemLabel, char *urlSetting, boolean encode)
+/* Print custom URL specified in trackDb settings. */
+{
+char urlLabelSetting[32];
+
+// first try to resolve itemName via an optional sql statement to something else
+char *idInUrl = getIdInUrl(tdb, itemName);
+if (idInUrl == NULL)
+ return;
+
+// replace the $$ and other wildchards with the url given in tdb
+char* eUrl = constructUrl(tdb, urlSetting, idInUrl, encode);
+if (eUrl==NULL)
+ return;
+
/* create the url label setting for trackDb from the url
setting prefix */
safef(urlLabelSetting, sizeof(urlLabelSetting), "%sLabel", urlSetting);
printf("%s ",
trackDbSettingOrDefault(tdb, urlLabelSetting, "Outside Link:"));
- printf("", eUrl->string);
+printf("", eUrl);
if (sameWord(tdb->table, "npredGene"))
{
printf("%s (%s)
\n", idInUrl, "NCBI MapView");
}
else
{
char *label = idInUrl;
if (isNotEmpty(itemLabel) && !sameString(itemName, itemLabel))
label = itemLabel;
printf("%s
\n", label);
}
- freeMem(eItem);
- freeDyString(&uUrl);
- freeDyString(&eUrl);
- }
- }
+//freeMem(&eUrl); small memory leak
}
void printCustomUrl(struct trackDb *tdb, char *itemName, boolean encode)
/* Wrapper to call printCustomUrlWithLabel using the url setting in trackDb */
{
char urlSetting[10];
safef(urlSetting, sizeof(urlSetting), "url");
printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode);
}
void printOtherCustomUrl(struct trackDb *tdb, char *itemName, char* urlSetting, boolean encode)
/* Wrapper to call printCustomUrlWithLabel to use another url setting other than url in trackDb e.g. url2, this allows the use of multiple urls for a track
to be set in trackDb. */
{
@@ -1410,102 +1431,151 @@
char dbOnly[4096];
diff = comp2->start - (comp1->start + comp1->size);
safef(dbOnly, sizeof(dbOnly), "%s", comp1->src);
chopPrefix(dbOnly);
printf("%-20s %d\n",hOrganism(dbOnly), diff);
}
printf("
");
}
}
}
}
+struct hash* hashFromString(char* string)
+/* parse a whitespace-separated string with tuples in the format name=val or
+ * name="val" to a hash name->val */
+{
+if (string==NULL)
+ return NULL;
+
+struct slPair *keyVals = slPairListFromString(string, TRUE);
+if (keyVals==NULL)
+ return NULL;
+
+struct hash *nameToVal = newHash(0);
+struct slPair *kv;
+for (kv = keyVals; kv != NULL; kv = kv->next)
+ hashAdd(nameToVal, kv->name, kv->val);
+return nameToVal;
+}
+
+void printIdOrLinks(struct asColumn *col, struct hash *fieldToUrl, struct trackDb *tdb, char *idList)
+/* if trackDb does not contain a "urls" entry for current column name, just print idList as it is.
+ * Otherwise treat idList as a comma-sep list of IDs and print one row per id, with a link to url,
+ * ($$ in url is OK, wildcards like $P, $p, are also OK)
+ * */
+{
+// try to find a fieldName=url setting in the "urls" tdb statement, print id if not found
+char *url = NULL;
+if (fieldToUrl!=NULL)
+ url = (char*)hashFindVal(fieldToUrl, col->name);
+if ((url==NULL)
+ {
+ printf("
%s: | ", col->comment); if (col->isList || col->isArray || col->lowType->stringy) - { - printf("%s | %ld | \n", valInt); else printf("%s | \n", fields[ix]); // decided not to print error } else if (asTypesIsFloating(col->lowType->type)) { double valDouble = strtod(fields[ix],NULL); if (errno == 0 && valDouble != 0) printf("%g | \n", valDouble); else printf("%s | \n", fields[ix]); // decided not to print error } else - { printf("%s | \n", fields[ix]); } - } asObjectFree(&as); +freeMem(fieldToUrl); if (count > 0) printf("