3846f517009c43abc65d227a4695645c9b5f3e8a
braney
  Fri Feb 15 18:31:21 2013 -0800
changes necessary to support assembly hubs (#8072)
diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c
index 06c7a4c..c7262f7 100644
--- src/hg/lib/hubConnect.c
+++ src/hg/lib/hubConnect.c
@@ -112,38 +112,42 @@
 
 boolean trackHubHasDatabase(struct trackHub *hub, char *database) 
 /* Return TRUE if hub has contents for database */
 {
 if (hub != NULL)
     {
     struct trackHubGenome *genomes = hub->genomeList;	/* List of associated genomes. */
 
     for(; genomes; genomes = genomes->next)
 	if (sameString(genomes->name, database))
 	    return TRUE;
     }
 return FALSE;
 }
 
-static struct trackHub *fetchHub(char *url, char **errorMessage)
+static struct trackHub *fetchHub(struct hubConnectStatus *hubStatus, char **errorMessage)
 {
 struct errCatch *errCatch = errCatchNew();
 struct trackHub *tHub = NULL;
 boolean gotWarning = FALSE;
+char *url = hubStatus->hubUrl;
+
+char hubName[64];
+safef(hubName, sizeof(hubName), "hub_%d", hubStatus->id);
 
 if (errCatchStart(errCatch))
-    tHub = trackHubOpen(url, "1"); // open hub.. it'll get renamed later
+    tHub = trackHubOpen(url, cloneString(hubName)); // open hub
 errCatchEnd(errCatch);
 if (errCatch->gotError)
     {
     gotWarning = TRUE;
     *errorMessage = cloneString(errCatch->message->string);
     }
 errCatchFree(&errCatch);
 
 if (gotWarning)
     {
     return NULL;
     }
 
 return tHub;
 }
@@ -168,31 +172,31 @@
 safef(query, sizeof(query), 
     "select hubUrl,status, errorMessage,lastNotOkTime from %s where id=%d", getHubStatusTableName(), id);
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = sqlNextRow(sr);
 if (row != NULL)
     {
     AllocVar(hub);
     hub->id = id;
     hub->hubUrl = cloneString(row[0]);
     hub->status = sqlUnsigned(row[1]);
     hub->errorMessage = cloneString(row[2]);
 
     if (isEmpty(row[2]) || hubTimeToCheck(hub, row[3]))
 	{
 	char *errorMessage = NULL;
-	hub->trackHub = fetchHub( hub->hubUrl, &errorMessage);
+	hub->trackHub = fetchHub( hub, &errorMessage);
 	hub->errorMessage = cloneString(errorMessage);
 	hubUpdateStatus( hub->errorMessage, hub);
 	if (!isEmpty(hub->errorMessage))
 	    {
 	    warn("%s", hub->errorMessage);
 	    }
 	}
     }
 sqlFreeResult(&sr);
 return hub;
 }
 
 struct hubConnectStatus *hubConnectStatusListFromCartAll(struct cart *cart)
 /* Return list of all track hubs that are referenced by cart. */
 {
@@ -363,40 +367,42 @@
 
 struct trackDb *hubConnectAddHubForTrackAndFindTdb( char *database, 
     char *trackName, struct trackDb **pTdbList, struct hash *trackHash)
 /* Go find hub for trackName (which will begin with hub_), and load the tracks
  * for it, appending to end of list and adding to trackHash.  Return the
  * trackDb associated with trackName. This will also fill in the html fields,
  * but just for that track and it's parents. */ 
 {
 unsigned hubId = hubIdFromTrackName(trackName);
 struct trackHub *hub = trackHubFromId(hubId);
 struct trackHubGenome *hubGenome = trackHubFindGenome(hub, database);
 struct trackDb *tdbList = trackHubTracksForGenome(hub, hubGenome);
 tdbList = trackDbLinkUpGenerations(tdbList);
 tdbList = trackDbPolishAfterLinkup(tdbList, database);
 trackHubPolishTrackNames(hub, tdbList);
+char *fixTrackName = cloneString(trackName);
+trackHubFixName(fixTrackName);
 rAddTrackListToHash(trackHash, tdbList, NULL, FALSE);
 if (pTdbList != NULL)
     *pTdbList = slCat(*pTdbList, tdbList);
-struct trackDb *tdb = hashFindVal(trackHash, trackName);
+struct trackDb *tdb = hashFindVal(trackHash, fixTrackName);
 if (tdb == NULL) 
     // superTracks aren't in the hash... look in tdbList
-    tdb = findSuperTrack(tdbList, trackName);
+    tdb = findSuperTrack(tdbList, fixTrackName);
 
 if (tdb == NULL) 
-    errAbort("Can't find track %s in %s", trackName, hub->url);
+    errAbort("Can't find track %s in %s", fixTrackName, hub->url);
 
 /* Add html for track and parents. */
 /* Note: this does NOT add the HTML for supertrack kids */
 struct trackDb *parent;
 for (parent = tdb; parent != NULL; parent = parent->parent)
     addDescription(hubGenome->trackDbFile, parent);
 trackHubClose(&hub);
 
 return tdb;
 }
 
 static char *getDbList(struct trackHub *tHub, int *pCount)
 /* calculate dbList for hubStatus table from trackHub */
 {
 struct hashEl *hel;
@@ -454,106 +460,105 @@
 
     char *thisId = row[0], *thisError = row[1];
 
     if (!isEmpty(thisError))
 	*errorMessage = cloneString(thisError);
 
     id = sqlUnsigned(thisId);
     }
 sqlFreeResult(&sr);
 
 hDisconnectCentral(&conn);
 
 return id;
 }
 
-static void getAndSetHubStatus(char *database, struct cart *cart, char *url, 
+static void getAndSetHubStatus( struct cart *cart, char *url, 
     boolean set)
 /* make sure url is in hubStatus table, fetch the hub to get latest
  * labels and db information.
  * Set the cart variable to turn the hub on if set == TRUE.  
  */
 {
 char *errorMessage = NULL;
 unsigned id;
 
 /* first see if url is in hubStatus table */
 if ((id = getHubId(url, &errorMessage)) == 0)
     {
     /* the url is not in the hubStatus table, add it */
     insertHubUrlInStatus(url);
     if ((id = getHubId(url, &errorMessage)) == 0)
 	{
 	errAbort("opened hub, but could not get it out of the hubStatus table");
 	}
     }
 
 /* allocate a hub */
 struct hubConnectStatus *hub = NULL;
 
 AllocVar(hub);
 hub->id = id;
 hub->hubUrl = cloneString(url);
 
 /* new fetch the contents of the hub to fill in the status table */
-struct trackHub *tHub = fetchHub( url, &errorMessage);
+struct trackHub *tHub = fetchHub( hub, &errorMessage);
 if (tHub != NULL)
     hub->trackHub = tHub;
 
 /* update the status table with the lastest label and database information */
 hubUpdateStatus( errorMessage, hub);
 
 /* if we're turning on the hub, set the cart variable */
 if (set)
     {
     char hubName[32];
     safef(hubName, sizeof(hubName), "%s%u", hgHubConnectHubVarPrefix, id);
     cartSetString(cart, hubName, "1");
     }
 
 hubConnectStatusFree(&hub);
 }
 
 unsigned hubFindOrAddUrlInStatusTable(char *database, struct cart *cart,
     char *url, char **errorMessage)
 /* find this url in the status table, and return its id and errorMessage (if an errorMessage exists) */
 {
 int id = 0;
 
 *errorMessage = NULL;
 
 if ((id = getHubId(url, errorMessage)) > 0)
     return id;
 
-getAndSetHubStatus(database, cart, url, FALSE);
+getAndSetHubStatus( cart, url, FALSE);
 
 if ((id = getHubId(url, errorMessage)) == 0)
     errAbort("inserted new hubUrl %s, but cannot find it", url);
 
 return id;
 }
 
-void hubCheckForNew(char *database, struct cart *cart)
+void hubCheckForNew( struct cart *cart)
 /* see if the user just typed in a new hub url, return id if so */
 {
 char *url = cartOptionalString(cart, hgHubDataText);
 
 if (url != NULL)
     {
     trimSpaces(url);
-    getAndSetHubStatus(database, cart, url, TRUE);
-    cartRemove(cart, hgHubDataText);
+    getAndSetHubStatus( cart, url, TRUE);
     }
 }
 
 unsigned hubResetError(char *url)
 /* clear the error for this url in the hubStatus table,return the id */
 {
 struct sqlConnection *conn = hConnectCentral();
 char query[512];
 
 safef(query, sizeof(query), "select id from %s where hubUrl = \"%s\"", getHubStatusTableName(), url);
 unsigned id = sqlQuickNum(conn, query);
 
 if (id == 0)
     errAbort("could not find url %s in status table (%s)\n", 
 	url, getHubStatusTableName());
@@ -635,33 +640,48 @@
     }
 hDisconnectCentral(&conn);
 }
 
 struct trackDb *hubAddTracks(struct hubConnectStatus *hub, char *database,
 	struct trackHub **pHubList)
 /* Load up stuff from data hub and append to list. The hubUrl points to
  * a trackDb.ra format file.  */
 {
 /* Load trackDb.ra file and make it into proper trackDb tree */
 struct trackDb *tdbList = NULL;
 struct trackHub *trackHub = hub->trackHub;
 
 if (trackHub != NULL)
     {
-    char hubName[64];
-    safef(hubName, sizeof(hubName), "hub_%d", hub->id);
-    trackHub->name = cloneString(hubName);
-
     struct trackHubGenome *hubGenome = trackHubFindGenome(trackHub, database);
     if (hubGenome != NULL)
 	{
 	tdbList = trackHubTracksForGenome(trackHub, hubGenome);
 	tdbList = trackDbLinkUpGenerations(tdbList);
 	tdbList = trackDbPolishAfterLinkup(tdbList, database);
 	trackDbPrioritizeContainerItems(tdbList);
 	trackHubPolishTrackNames(trackHub, tdbList);
 	if (tdbList != NULL)
 	    slAddHead(pHubList, trackHub);
 	}
     }
 return tdbList;
 }
+
+static struct hubConnectStatus *globalHubList;
+
+struct hubConnectStatus *hubConnectGetHubs()
+/* return the static global to the track data hubs */
+{
+return globalHubList;
+}
+
+struct hubConnectStatus * hubConnectLoadHubs(struct cart *cart)
+/* load the track data hubs.  Set a static global to remember them */
+{
+hubCheckForNew( cart);
+cartSetString(cart, hgHubConnectRemakeTrackHub, "on");
+struct hubConnectStatus  *hubList =  hubConnectStatusListFromCart(cart);
+globalHubList = hubList;
+
+return hubList;
+}