8dc2f2a3bfe8d47e02a94ca4d9f62063df86b15c
braney
Thu Oct 5 14:56:25 2017 -0700
ongoing work on hgCollection. Add the ability to add tracks in hgTracks
to a collection. Turn "overlay method" back on for custom collections.
Fix panning bug in hgTracks with custom collections
diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index d0f48b3..ee2f903 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -11,31 +11,31 @@
#include "grp.h"
#include "cheapcgi.h"
#include "jsHelper.h"
#include "web.h"
#include "knetUdc.h"
#include "api.h"
#include "genbank.h"
#include "htmshell.h"
#include "jsonParse.h"
#include "customComposite.h"
#include "stdlib.h"
/* Global Variables */
struct hash *oldVars = NULL; /* The cart before new cgi stuff added. */
// Null terminated list of CGI Variables we don't want to save permanently:
-char *excludeVars[] = {"Submit", "submit", "hgva_startQuery", "jsonp", NULL,};
+char *excludeVars[] = {"Submit", "submit", "cmd", "track", "collection", "jsonp", NULL,};
struct track
{
struct track *next;
struct track *trackList;
struct trackDb *tdb;
char *name;
char *shortLabel;
char *longLabel;
char *visibility;
unsigned long color;
char *viewFunc;
};
struct trackDbRef
@@ -118,57 +118,57 @@
jsInlineF(" (%s)", tdb->longLabel);
if (tdb->subtracks)
{
struct trackDb *subTdb;
jsInlineF("
");
for(subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next)
printGroup(trackHubSkipHubName(tdb->track), subTdb, user && (subTdb->subtracks != NULL), user);
jsInlineF("
");
}
jsInlineF("");
}
-static void outHubHeader(FILE *f, char *db, char *hubName)
+static void outHubHeader(FILE *f, char *db)
// output a track hub header
{
fprintf(f,"hub hub1\n\
shortLabel User Composite\n\
longLabel User Composite\n\
useOneFile on\n\
email genome-www@soe.ucsc.edu\n\n");
fprintf(f,"genome %s\n\n", db);
}
static char *getHubName(struct cart *cart, char *db)
// get the name of the hub to use for user collections
{
struct tempName hubTn;
char buffer[4096];
safef(buffer, sizeof buffer, "%s-%s", customCompositeCartName, db);
char *hubName = cartOptionalString(cart, buffer);
if (hubName == NULL)
{
trashDirDateFile(&hubTn, "hgComposite", "hub", ".txt");
hubName = cloneString(hubTn.forCgi);
cartSetString(cart, buffer, hubName);
FILE *f = mustOpen(hubName, "a");
- outHubHeader(f, db, hubName);
+ outHubHeader(f, db);
fclose(f);
cartSetString(cart, "hubUrl", hubName);
cartSetString(cart, hgHubConnectRemakeTrackHub, hubName);
}
return hubName;
}
static bool subtrackEnabledInTdb(struct trackDb *subTdb)
/* Return TRUE unless the subtrack was declared with "subTrack ... off". */
{
bool enabled = TRUE;
char *words[2];
char *setting;
if ((setting = trackDbLocalSetting(subTdb, "parent")) != NULL)
{
@@ -454,30 +454,31 @@
fprintf(f, "%svisibility %s\n",tabs,visibility);
fprintf(f, "%spriority %d\n",tabs,priority);
fprintf(f, "\n");
}
static void outComposite(FILE *f, struct track *collection)
// output a composite header for user composite
{
char *parent = collection->name;
char *shortLabel = collection->shortLabel;
char *longLabel = collection->longLabel;
fprintf(f,"track %s\n\
shortLabel %s\n\
compositeTrack on\n\
autoScale on\n\
+aggregate none\n\
longLabel %s\n\
%s on\n\
color %ld,%ld,%ld \n\
type wig \n\
visibility full\n\n", parent, shortLabel, longLabel, CUSTOM_COMPOSITE_SETTING,
0xff& (collection->color >> 16),0xff& (collection->color >> 8),0xff& (collection->color));
}
static char *skipColl(char *str)
{
if (startsWith("coll_", str))
return &str[5];
return str;
}
@@ -509,31 +510,31 @@
//useColor++;
}
return priority;
}
static void updateHub(struct cart *cart, char *db, struct track *collectionList, struct hash *nameHash)
// save our state to the track hub
{
char *hubName = getHubName(cart, db);
chmod(hubName, 0666);
FILE *f = mustOpen(hubName, "w");
struct hash *collectionNameHash = newHash(6);
-outHubHeader(f, db, hubName);
+outHubHeader(f, db);
//int useColor = 0;
struct track *collection;
struct sqlConnection *conn = hAllocConn(db);
for(collection = collectionList; collection; collection = collection->next)
{
outComposite(f, collection);
struct trackDb *tdb;
struct track *track;
int priority = 1;
for (track = collection->trackList; track; track = track->next)
{
if (track->trackList != NULL)
{
priority = outView(f, conn, db, track, collection->name, nameHash, collectionNameHash, priority);
}
@@ -726,60 +727,175 @@
hashStore(superHash, tdb->parent->track);
slAddHead(&newList, tdb->parent);
}
slAddHead(&tdb->parent->subtracks, tdb);
}
else
slAddHead(&newList, tdb);
}
slReverse(&newList);
return newList;
}
+static void outOneTdb(char *db, struct sqlConnection *conn, FILE *f, struct trackDb *tdb, int numTabs)
+/* Put out a single trackDb entry to our collections hub. */
+{
+char *tabs = "";
+if (numTabs == 1)
+ tabs = "\t";
+else if (numTabs == 2)
+ tabs = "\t\t";
+else if (numTabs == 3)
+ tabs = "\t\t\t";
+
+struct hashEl *hel = hashLookup(tdb->settingsHash, "track");
+fprintf(f, "%s%s %s\n", tabs,hel->name, trackHubSkipHubName((char *)hel->val));
+
+char *dataUrl = NULL;
+char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl");
+if (bigDataUrl == NULL)
+ {
+ if (startsWith("bigWig", tdb->type))
+ dataUrl = getSqlBigWig(conn, db, tdb);
+ }
+
+struct hashCookie cookie = hashFirst(tdb->settingsHash);
+while ((hel = hashNext(&cookie)) != NULL)
+ {
+ if (sameString("parent", hel->name))
+ fprintf(f, "%s%s %s\n", tabs,hel->name, trackHubSkipHubName((char *)hel->val));
+ else if (!(sameString("track", hel->name) || sameString("polished", hel->name) || sameString("group", hel->name)))
+ fprintf(f, "%s%s %s\n", tabs,hel->name, (char *)hel->val);
+ }
+
+if (bigDataUrl == NULL)
+ {
+ if (dataUrl != NULL)
+ fprintf(f, "%sbigDataUrl %s\n", tabs,dataUrl);
+ }
+
+fprintf(f, "\n");
+}
+
+static void outTrackDbList(char *db, struct sqlConnection *conn, FILE *f, char *hubName, struct trackDb *list, char *collectionName, struct trackDb *newTdb, int numTabs)
+/* Put a list of trackDb entries into a collection, adding a new track to the collection. */
+{
+if (list == NULL)
+ return;
+
+struct trackDb *tdb;
+for(tdb = list; tdb; tdb = tdb->next)
+ {
+ if (tdb->grp != NULL)
+ if ((hubName == NULL) || differentString(hubName, tdb->grp))
+ continue;
+
+ outOneTdb(db, conn, f, tdb, numTabs);
+
+ struct hashEl *hel = hashLookup(tdb->settingsHash, "track");
+ if ((hel != NULL) && (hel->val != NULL) && sameString((char *)hel->val, collectionName))
+ outOneTdb(db, conn, f, newTdb, numTabs + 1);
+
+ outTrackDbList(db, conn, f, hubName, tdb->subtracks, collectionName, newTdb, numTabs + 1);
+ }
+}
+
+static void doAddTrack(struct cart *cart, char *db, struct trackDb *trackList, char *trackName, char *collectionName, struct hash *nameHash)
+/* Add a track to a collection in a hub. */
+{
+char *fileName = getHubName(cart, db);
+char *hubName = hubNameFromUrl(fileName);
+FILE *f = fopen(fileName, "w");
+struct trackDb *newTdb = hashMustFindVal(nameHash, trackName);
+hashReplace(newTdb->settingsHash, "track", makeUnique(nameHash, trackName));
+hashReplace(newTdb->settingsHash, "parent", trackHubSkipHubName(collectionName));
+
+outHubHeader(f, db);
+struct sqlConnection *conn = hAllocConn(db);
+outTrackDbList(db, conn, f, hubName, trackList, collectionName, newTdb, 0);
+
+hFreeConn(&conn);
+fclose(f);
+}
+
static void doMiddle(struct cart *cart)
/* Set up globals and make web page */
{
char *db;
char *genome;
getDbAndGenome(cart, &db, &genome, oldVars);
int timeout = cartUsualInt(cart, "udcTimeout", 300);
if (udcCacheTimeout() < timeout)
udcSetCacheTimeout(timeout);
knetUdcInstall();
struct trackDb *trackList;
struct grp *groupList;
cartTrackDbInit(cart, &trackList, &groupList, TRUE);
pruneTrackList(&trackList, &groupList);
struct trackDb *superList = addSupers(trackList);
struct hash *nameHash = newHash(5);
buildNameHash(nameHash, superList);
-char *jsonIn = cgiUsualString("jsonp", NULL);
-fprintf(stderr, "BRANEY %s\n", jsonIn);
-if (jsonIn != NULL)
+char *cmd = cartOptionalString(cart, "cmd");
+if (cmd == NULL)
{
- doAjax(cart, db, jsonIn, nameHash);
- apiOut("{\"serverSays\": \"Collections saved successfully.\"}", NULL);
+ doMainPage(cart, db, groupList, superList);
}
-else
+else if (sameString("addTrack", cmd))
{
- doMainPage(cart, db, groupList, superList);
+ char *trackName = cgiString("track");
+ char *collectionName = cgiString("collection");
+ doAddTrack(cart, db, superList, trackName, collectionName, nameHash);
+ apiOut("{\"serverSays\": \"added %s to collection\"}", NULL);
+ }
+else if (sameString("newCollection", cmd))
+ {
+ char *trackName = cgiString("track");
+ char *collectionName = makeUnique(nameHash, "coll");
+ char *shortLabel = "New Collection";
+ char *longLabel = "Description of New Collection";
+ struct trackDb *tdb;
+
+ AllocVar(tdb);
+ slAddHead(&superList, tdb);
+ tdb->settingsHash = newHash(5);
+ tdb->type = cloneString("wig");
+
+ hashAdd(tdb->settingsHash, "track", collectionName);
+ hashAdd(tdb->settingsHash, "shortLabel", shortLabel);
+ hashAdd(tdb->settingsHash, "longLabel", longLabel);
+ hashAdd(tdb->settingsHash, "autoScale", "on");
+ hashAdd(tdb->settingsHash, "compositeTrack", "on");
+ hashAdd(tdb->settingsHash, "aggregate", "none");
+ hashAdd(tdb->settingsHash, "type", "wig");
+ hashAdd(tdb->settingsHash, "visibility", "full");
+ hashAdd(tdb->settingsHash, "color", "0,0,0");
+ hashAdd(tdb->settingsHash, CUSTOM_COMPOSITE_SETTING, "on");
+
+ doAddTrack(cart, db, superList, trackName, collectionName, nameHash);
+ apiOut("{\"serverSays\": \"new %s to collection\"}", NULL);
+ }
+else if (sameString("saveCollection", cmd))
+ {
+ char *jsonIn = cgiUsualString("jsonp", NULL);
+ doAjax(cart, db, jsonIn, nameHash);
+ apiOut("{\"serverSays\": \"Collections gaved successfully.\"}", NULL);
}
}
int main(int argc, char *argv[])
/* Process command line. */
{
long enteredMainTime = clock1000();
cgiSpoof(&argc, argv);
boolean isCommandLine = (cgiOptionalString("cgiSpoof") != NULL);
if (!isCommandLine)
htmlPushEarlyHandlers(); /* Make errors legible during initialization. */
oldVars = hashNew(10);
cartEmptyShellNoContent(doMiddle, hUserCookie(), excludeVars, oldVars);