8fcb2ed43b0ec0060a831894d4cf8eaab95fa466
braney
  Thu Mar 23 12:42:04 2023 -0700
add a mechanism whereby hubStatus id's in a session can be mapped to the
local hubStatus id for that hub

diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c
index 5dc3c4d..25a5ed2 100644
--- src/hg/lib/hubConnect.c
+++ src/hg/lib/hubConnect.c
@@ -1072,42 +1072,95 @@
 
         return status->id;
         }
     else
         {
         if (!isEmpty(status->errorMessage))
             errAbort("Hub error: url %s: error  %s.", url, status->errorMessage);
         else
             errAbort("Cannot open hub %s.", url);
         }
 
     }
 return 0;
 }
 
+static void portHubStatus(struct cart *cart)
+/* When a session has been saved on a different host it may have cart variables that reference hubStatus id's
+ * that are different than what the local machine has.  Look for these cases using the "assumesHub" cart variable
+ * that maps id numbers to URL's. */
+{
+char *assumesHubStr = cartOptionalString(cart, "assumesHub");
+if (assumesHubStr == NULL)
+    return;
+
+struct slPair *pairs = slPairListFromString(assumesHubStr, FALSE);
+for(; pairs; pairs = pairs->next)
+    {
+    char *url = (char *)pairs->val;
+    unsigned sessionHubId = atoi(pairs->name);
+    char *errMessage;
+    unsigned localHubId = hubFindOrAddUrlInStatusTable(cart, url, &errMessage);
+
+    if (localHubId != sessionHubId)  // the hubStatus id on the local machine is different than in the session
+        {
+        // first look for visibility and settings for tracks on this hub
+        char wildCard[4096];
+
+        safef(wildCard, sizeof wildCard, "hub_%d_*", sessionHubId);
+        struct slPair *cartVars = cartVarsLike(cart, wildCard);
+
+        for(; cartVars; cartVars = cartVars->next)
+            {
+            char *rest = trackHubSkipHubName(cartVars->name);
+            char newVarName[4096];
+            
+            // add the new visibility/setting
+            safef(newVarName, sizeof newVarName, "hub_%d_%s", localHubId, rest);
+            cartSetString(cart, newVarName, cartVars->val);
+
+            // remove the old visibility/setting
+            cartRemove(cart, cartVars->name);
+            }
+
+        // turn on this remapped hub
+        char hubName[4096];
+        cartSetString(cart, hgHubConnectRemakeTrackHub, "on");
+        safef(hubName, sizeof(hubName), "%s%u", hgHubConnectHubVarPrefix, localHubId);
+        cartSetString(cart, hubName, "1");
+
+        // remove the old hub connection
+        safef(hubName, sizeof(hubName), "%s%u", hgHubConnectHubVarPrefix, sessionHubId);
+        cartRemove(cart, hubName);
+        }
+    }
+}
 
 char *hubConnectLoadHubs(struct cart *cart)
 /* load the track data hubs.  Set a static global to remember them */
 {
 char *dbSpec = asmAliasFind(cartOptionalString(cart, "db"));
 char *curatedHubPrefix = getCuratedHubPrefix();
 if (dbSpec != NULL)
     lookForCuratedHubs(cart, trackHubSkipHubName(dbSpec), curatedHubPrefix);
 
 char *newDatabase = checkForNew( cart);
 newDatabase = asmAliasFind(newDatabase);
 cartSetString(cart, hgHubConnectRemakeTrackHub, "on");
+
+portHubStatus(cart);
+
 struct hubConnectStatus  *hubList =  hubConnectStatusListFromCart(cart);
 
 char *genarkPrefix = cfgOption("genarkHubPrefix");
 if (genarkPrefix && lookForLonelyHubs(cart, hubList, &newDatabase, genarkPrefix))
     hubList = hubConnectStatusListFromCart(cart);
 
 globalHubList = hubList;
 
 return newDatabase;
 }
 
 char *hubNameFromUrl(char *hubUrl)
 /* Given the URL for a hub, return its hub_# name. */
 {
 char query[PATH_LEN*4];