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(""); } 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);