c34d987e514b9b6130198880940fa441eb15e176
braney
Fri Aug 4 15:53:37 2017 -0700
Ongoing work on hgCollection. Add ability to edit names,colors, and
visibilities.
diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index e468916..30e02ba 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -6,75 +6,79 @@
#include "cartTrackDb.h"
#include "trackHub.h"
#include "trashDir.h"
#include "hubConnect.h"
#include "hui.h"
#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 cart *cart; /* CGI and other variables */
struct hash *oldVars = NULL; /* The cart before new cgi stuff added. */
char *genome = NULL; /* Name of genome - mouse, human, etc. */
char *database = NULL; /* Current genome database - hg17, mm5, etc. */
char *regionType = NULL; /* genome, ENCODE pilot regions, or specific position range. */
struct grp *fullGroupList = NULL; /* List of all groups. */
struct trackDb *fullTrackList = NULL; /* List of all tracks in database. */
struct pipeline *compressPipeline = (struct pipeline *)NULL;
// Null terminated list of CGI Variables we don't want to save permanently:
char *excludeVars[] = {"Submit", "submit", "hgva_startQuery", NULL,};
struct track
{
struct track *next;
struct track *trackList;
struct trackDb *tdb;
char *name;
char *shortLabel;
char *longLabel;
char *visibility;
+unsigned long color;
};
-static char *getString(char **input)
+char *getString(char **input)
// grab a quoted string out of text blob
{
char *ptr = *input;
if (*ptr != '"')
errAbort("string must start with \"");
ptr++;
char *ret = ptr;
for(; *ptr != '"'; ptr++)
;
*ptr = 0;
ptr++;
if (*ptr == ',')
ptr++;
-*input = ptr;
+if (startsWith("coll_", ret))
+ ret = ret + 5;
+*input = ptr;
return ret;
}
char *makeUnique(struct hash *nameHash, char *name)
// Make the name of this track unique.
{
char *skipHub = trackHubSkipHubName(name);
if (hashLookup(nameHash, skipHub) == NULL)
{
hashStore(nameHash, name);
return skipHub;
}
unsigned count = 0;
char buffer[4096];
@@ -90,41 +94,44 @@
}
return NULL;
}
static boolean trackCanBeAdded(struct trackDb *tdb)
// are we allowing this track into a custom composite
{
return (tdb->subtracks == NULL) && !startsWith("wigMaf",tdb->type) && (startsWith("wig",tdb->type) || startsWith("bigWig",tdb->type)) ;
}
static void printGroup(char *parent, struct trackDb *tdb, boolean folder, boolean user)
// output the table rows for a group
{
char *userString = "";
+char *prefix = "";
if (user)
{
+ prefix = "coll_";
if (tdb->parent && tdb->subtracks)
userString = "class='user view'";
else
userString = "class='user'";
}
+#define IMAKECOLOR_32(r,g,b) ( ((unsigned int)b<<0) | ((unsigned int)g << 8) | ((unsigned int)r << 16))
-jsInlineF("
%s | ", parent, trackHubSkipHubName(tdb->track), userString, folder ? "folder" : "file", tdb->shortLabel );
+jsInlineF("
%s | ", IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), hStringFromTv(tdb->visibility), prefix, parent,prefix, trackHubSkipHubName(tdb->track), userString, folder ? "folder" : "file", tdb->shortLabel );
jsInlineF("%s |
", tdb->longLabel);
if (tdb->subtracks)
{
struct trackDb *subTdb;
for(subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next)
printGroup(trackHubSkipHubName(tdb->track), subTdb, user && (subTdb->subtracks != NULL), user);
}
}
static void outHubHeader(FILE *f, char *db, char *hubName)
// output a track hub header
{
@@ -353,210 +360,237 @@
{
struct trackDb *tdb = hashMustFindVal(nameHash, track->name);
if (tdb == NULL)
errAbort("cannot find trackDb for %s\n", track->name);
char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl");
if (bigDataUrl == NULL)
{
if (startsWith("bigWig", tdb->type))
bigDataUrl = getSqlBigWig(conn, db, tdb);
}
return bigDataUrl;
}
-void outTdb(struct sqlConnection *conn, char *db, FILE *f, char *name, struct trackDb *tdb, char *parent, unsigned int color, struct track *track, struct hash *nameHash, struct hash *collectionNameHash)
+void outTdb(struct sqlConnection *conn, char *db, FILE *f, char *name, struct trackDb *tdb, char *parent, char *visibility, unsigned int color, struct track *track, struct hash *nameHash, struct hash *collectionNameHash, int numTabs)
// out the trackDb for one track
{
char *dataUrl = NULL;
char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl");
+char *tabs = "\t";
+if (numTabs == 2)
+ tabs = "\t\t";
if (bigDataUrl == NULL)
{
if (startsWith("bigWig", tdb->type))
dataUrl = getSqlBigWig(conn, db, tdb);
}
struct hashCookie cookie = hashFirst(tdb->settingsHash);
struct hashEl *hel;
-fprintf(f, "\ttrack %s\n", makeUnique(collectionNameHash, name));
+fprintf(f, "%strack %s\n",tabs, makeUnique(collectionNameHash, name));
+fprintf(f, "%sshortLabel %s\n",tabs, track->shortLabel);
+fprintf(f, "%slongLabel %s\n",tabs, track->longLabel);
while ((hel = hashNext(&cookie)) != NULL)
{
- if (differentString(hel->name, "parent") && differentString(hel->name, "polished")&& differentString(hel->name, "color")&& differentString(hel->name, "track")&& differentString(hel->name, "trackNames")&& differentString(hel->name, "superTrack"))
- fprintf(f, "\t%s %s\n", hel->name, (char *)hel->val);
+ if (differentString(hel->name, "parent") && differentString(hel->name, "polished")&& differentString(hel->name, "shortLabel")&& differentString(hel->name, "longLabel")&& differentString(hel->name, "color")&& differentString(hel->name, "visibility")&& differentString(hel->name, "track")&& differentString(hel->name, "trackNames")&& differentString(hel->name, "superTrack"))
+ fprintf(f, "%s%s %s\n", tabs,hel->name, (char *)hel->val);
}
if (bigDataUrl == NULL)
{
if (dataUrl != NULL)
- fprintf(f, "\tbigDataUrl %s\n", dataUrl);
+ fprintf(f, "%sbigDataUrl %s\n", tabs,dataUrl);
}
-fprintf(f, "\tparent %s\n",parent);
-fprintf(f, "\tcolor %d,%d,%d\n", (color >> 16) & 0xff,(color >> 8) & 0xff,color & 0xff);
+fprintf(f, "%sparent %s\n",tabs,parent);
+fprintf(f, "%scolor %d,%d,%d\n", tabs,(color >> 16) & 0xff,(color >> 8) & 0xff,color & 0xff);
+fprintf(f, "%svisibility %s\n",tabs,visibility);
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\
aggregate none\n\
longLabel %s\n\
%s on\n\
type wig \n\
visibility full\n\n", parent, &shortLabel[2], longLabel, CUSTOM_COMPOSITE_SETTING);
}
-static int snakePalette2[] =
+int snakePalette2[] =
{
0x1f77b4, 0xaec7e8, 0xff7f0e, 0xffbb78, 0x2ca02c, 0x98df8a, 0xd62728, 0xff9896, 0x9467bd, 0xc5b0d5, 0x8c564b, 0xc49c94, 0xe377c2, 0xf7b6d2, 0x7f7f7f, 0xc7c7c7, 0xbcbd22, 0xdbdb8d, 0x17becf, 0x9edae5
};
+static char *skipColl(char *str)
+{
+if (startsWith("coll_", str))
+ return &str[5];
+return str;
+}
static void outView(FILE *f, struct sqlConnection *conn, char *db, struct track *view, char *parent, struct hash *nameHash, struct hash *collectionNameHash)
// output a view to a trackhub
{
fprintf(f,"\ttrack %s\n\
\tshortLabel %s\n\
\tlongLabel %s\n\
\tview %s \n\
\tparent %s \n\
-\tvisibility full\n", view->name, &view->shortLabel[2], view->longLabel, view->name, parent);
+\tcolor %ld,%ld,%ld \n\
+\tvisibility %s\n", view->name, &view->shortLabel[2], view->longLabel, view->name, parent, 0xff& (view->color >> 16),0xff& (view->color >> 8),0xff& (view->color), view->visibility);
//fprintf(f,"\tequation +\n");
fprintf(f, "\n");
-int useColor = 0;
+//int useColor = 0;
struct track *track = view->trackList;
for(; track; track = track->next)
{
- struct trackDb *tdb = hashMustFindVal(nameHash, track->name);
+ struct trackDb *tdb = hashMustFindVal(nameHash, skipColl(track->name));
- outTdb(conn, db, f, track->name,tdb, view->name, snakePalette2[useColor], track, nameHash, collectionNameHash);
- useColor++;
+ outTdb(conn, db, f, skipColl(track->name),tdb, view->name, track->visibility, track->color, track, nameHash, collectionNameHash, 2);
+ //useColor++;
}
}
void updateHub(char *db, struct track *collectionList, struct hash *nameHash)
// save our state to the track hub
{
char *hubName = getHubName(db);
chmod(hubName, 0666);
FILE *f = mustOpen(hubName, "w");
struct hash *collectionNameHash = newHash(6);
outHubHeader(f, db, hubName);
-int useColor = 0;
+//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;
for (track = collection->trackList; track; track = track->next)
{
if (track->trackList != NULL)
{
outView(f, conn, db, track, collection->name, nameHash, collectionNameHash);
}
else
{
tdb = hashMustFindVal(nameHash, track->name);
- outTdb(conn, db, f, track->name,tdb, collection->name, snakePalette2[useColor], track, nameHash, collectionNameHash);
+ outTdb(conn, db, f, track->name,tdb, collection->name, track->visibility, track->color, track, nameHash, collectionNameHash, 1);
+ /*
useColor++;
if (useColor == (sizeof snakePalette2 / sizeof(int)))
useColor = 0;
+ */
}
}
}
fclose(f);
hFreeConn(&conn);
}
+static unsigned long hexStringToLong(char *str)
+{
+/*
+char buffer[1024];
+
+strcpy(buffer, "0x");
+strcat(buffer, &str[1]);
+*/
+
+return strtol(&str[1], NULL, 16);
+}
+
static struct track *parseJson(char *jsonText)
// parse the JSON of the treetable from the Javascript
{
struct hash *trackHash = newHash(5);
struct track *collectionList = NULL;
struct track *track;
char *ptr = jsonText;
if (*ptr != '[')
errAbort("element didn't start with [");
ptr++;
do
{
if (*ptr != '[')
errAbort("element didn't start with [");
ptr++;
AllocVar(track);
char *parentName = getString(&ptr);
if (sameString(parentName, "collections"))
slAddHead(&collectionList, track);
else
{
struct track *parent = hashMustFindVal(trackHash, parentName);
- slAddHead(&parent->trackList, track);
+ slAddTail(&parent->trackList, track);
}
track->shortLabel = getString(&ptr);
track->longLabel = getString(&ptr);
track->name = getString(&ptr);
track->visibility = getString(&ptr);
+ char *colorString = getString(&ptr);
+
+ track->color = hexStringToLong(colorString);
hashAdd(trackHash, track->name, track);
if (*ptr != ']')
errAbort("element didn't end with ]");
ptr++;
if (*ptr == ',')
ptr++;
} while (*ptr != ']');
+slReverse(&collectionList);
return collectionList;
}
void doAjax(char *db, char *jsonText, struct hash *nameHash)
// Save our state
{
struct track *collectionList = parseJson(jsonText);
updateHub(db, collectionList, nameHash);
}
-static struct hash *buildNameHash(struct trackDb *list)
-// TODO; needs to go down one more layer
+static void buildNameHash(struct hash *nameHash, struct trackDb *list)
{
-struct hash *nameHash = newHash(8);
+if (list == NULL)
+ return;
+
struct trackDb *tdb;
for(tdb = list; tdb; tdb = tdb->next)
{
hashAdd(nameHash, trackHubSkipHubName(tdb->track), tdb);
- struct trackDb *subTdb = tdb->subtracks;
- for(; subTdb; subTdb = subTdb->next)
- {
- hashAdd(nameHash, trackHubSkipHubName(subTdb->track), subTdb);
+ buildNameHash(nameHash, tdb->subtracks);
}
}
-return nameHash;
-}
static struct trackDb *traverseTree(struct trackDb *oldList, struct hash *groupHash)
// add acceptable tracks to our tree
{
struct trackDb *newList = NULL, *tdb, *tdbNext;
for(tdb = oldList; tdb ; tdb = tdbNext)
{
tdbNext = tdb->next;
if (tdb->subtracks)
{
tdb->subtracks = traverseTree(tdb->subtracks, groupHash);
if (tdb->subtracks)
{
@@ -596,31 +630,32 @@
slReverse(&newGroupList);
*fullGroupList = newGroupList;
}
void doMiddle(struct cart *theCart)
/* Set up globals and make web page */
{
cart = theCart;
getDbAndGenome(cart, &database, &genome, oldVars);
int timeout = cartUsualInt(cart, "udcTimeout", 300);
if (udcCacheTimeout() < timeout)
udcSetCacheTimeout(timeout);
knetUdcInstall();
cartTrackDbInit(cart, &fullTrackList, &fullGroupList, TRUE);
pruneTrackList(&fullTrackList, &fullGroupList);
-struct hash *nameHash = buildNameHash(fullTrackList);
+struct hash *nameHash = newHash(5);
+buildNameHash(nameHash, fullTrackList);
char *jsonIn = cgiUsualString("jsonp", NULL);
fprintf(stderr, "BRANEY %s\n", jsonIn);
if (jsonIn != NULL)
{
doAjax(database, jsonIn, nameHash);
apiOut("{\"serverSays\": \"bit me\"}", NULL);
}
else
{
doMainPage();
}
}
int main(int argc, char *argv[])
@@ -631,15 +666,16 @@
initGenbankTableNames(database);
cgiSpoof(&argc, argv);
boolean isCommandLine = (cgiOptionalString("cgiSpoof") != NULL);
if (!isCommandLine)
htmlPushEarlyHandlers(); /* Make errors legible during initialization. */
oldVars = hashNew(10);
cartEmptyShellNoContent(doMiddle, hUserCookie(), excludeVars, oldVars);
if (! isCommandLine)
cgiExitTime("hgCollection", enteredMainTime);
return 0;
}
+