37e40ae31e02d615256bb9af43468ec2188afd24 braney Fri Feb 24 15:19:01 2023 -0800 make recommended track sets merge with current cart instead of over-writing it. This is under hg.conf control (mergeRecommended=on) diff --git src/hg/lib/cart.c src/hg/lib/cart.c index ff556ab..2f03f02 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -536,38 +536,39 @@ static void hashEmpty(struct hash *hash) /* Remove everything from hash. */ { struct hashEl *hel, *helList = hashElListHash(hash); for (hel = helList; hel != NULL; hel = hel->next) { freez(&(hel->val)); hashRemove(hash, hel->name); } hashElFreeList(&helList); assert(hashNumEntries(hash) == 0); } #ifndef GBROWSE -void cartLoadUserSession(struct sqlConnection *conn, char *sessionOwner, +void cartLoadUserSessionExt(struct sqlConnection *conn, char *sessionOwner, char *sessionName, struct cart *cart, - struct hash *oldVars, char *actionVar) + struct hash *oldVars, char *actionVar, boolean merge) /* If permitted, load the contents of the given user's session, and then * reload the CGI settings (to support override of session settings). * If non-NULL, oldVars will contain values overloaded when reloading CGI. * If non-NULL, actionVar is a cartRemove wildcard string specifying the - * CGI action variable that sent us here. */ + * CGI action variable that sent us here. + * If merge is TRUE, then don't clear the cart first. */ { struct sqlResult *sr = NULL; char **row = NULL; char *userName = wikiLinkUserName(); char *encSessionName = cgiEncodeFull(sessionName); char *encSessionOwner = cgiEncodeFull(sessionOwner); char query[512]; if (isEmpty(sessionOwner)) errAbort("Please go back and enter a wiki user name for this session."); if (isEmpty(sessionName)) errAbort("Please go back and enter a session name to load."); sqlSafef(query, sizeof(query), "SELECT shared, contents FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", @@ -575,56 +576,71 @@ sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { boolean shared = atoi(row[0]); if (shared || (userName && sameString(sessionOwner, userName))) { char *sessionVar = cartSessionVarName(); char *hgsid = cartSessionId(cart); char *sessionTableString = cartOptionalString(cart, hgSessionTableState); sessionTableString = cloneString(sessionTableString); char *pubSessionsTableString = cartOptionalString(cart, hgPublicSessionsTableState); pubSessionsTableString = cloneString(pubSessionsTableString); struct sqlConnection *conn2 = hConnectCentral(); sessionTouchLastUse(conn2, encSessionOwner, encSessionName); + if (!merge) cartRemoveLike(cart, "*"); cartParseOverHash(cart, row[1]); cartSetString(cart, sessionVar, hgsid); if (sessionTableString != NULL) cartSetString(cart, hgSessionTableState, sessionTableString); if (pubSessionsTableString != NULL) cartSetString(cart, hgPublicSessionsTableState, pubSessionsTableString); if (oldVars) hashEmpty(oldVars); /* Overload settings explicitly passed in via CGI (except for the * command that sent us here): */ loadCgiOverHash(cart, oldVars); if (isNotEmpty(actionVar)) cartRemove(cart, actionVar); hDisconnectCentral(&conn2); } else errAbort("Sharing has not been enabled for user %s's session %s.", sessionOwner, sessionName); } else errAbort("Could not find session %s for user %s.", sessionName, sessionOwner); sqlFreeResult(&sr); freeMem(encSessionName); } + +void cartLoadUserSession(struct sqlConnection *conn, char *sessionOwner, + char *sessionName, struct cart *cart, + struct hash *oldVars, char *actionVar) +/* If permitted, load the contents of the given user's session, and then + * reload the CGI settings (to support override of session settings). + * If non-NULL, oldVars will contain values overloaded when reloading CGI. + * If non-NULL, actionVar is a cartRemove wildcard string specifying the + * CGI action variable that sent us here. */ +{ +cartLoadUserSessionExt(conn, sessionOwner, + sessionName, cart, + oldVars, actionVar, FALSE); +} #endif /* GBROWSE */ boolean containsNonPrintable(char *string) /* Return TRUE if string contains non-ascii printable character(s). */ { if (isEmpty(string)) return FALSE; boolean hasNonPrintable = FALSE; int i; for (i = 0; string[i] != '\0'; i++) { if ((string[i] < 32 || string[i] > 126) && string[i] != '\t') { hasNonPrintable = TRUE; break; @@ -1360,33 +1376,34 @@ // I think this is the place to justify old and new values cartJustify(cart, oldVars); #ifndef GBROWSE /* If some CGI other than hgSession been passed hgSession loading instructions, * apply those to cart before we do anything else. (If this is hgSession, * let it handle the settings so it can display feedback to the user.) */ boolean didSessionLoad = FALSE; if (! (cgiScriptName() && endsWith(cgiScriptName(), "hgSession"))) { if (cartVarExists(cart, hgsDoOtherUser)) { char *otherUser = cartString(cart, hgsOtherUserName); char *sessionName = cartString(cart, hgsOtherUserSessionName); + boolean mergeCart = cartUsualBoolean(cart, hgsMergeCart, FALSE); struct sqlConnection *conn2 = hConnectCentral(); - cartLoadUserSession(conn2, otherUser, sessionName, cart, - oldVars, hgsDoOtherUser); + cartLoadUserSessionExt(conn2, otherUser, sessionName, cart, + oldVars, hgsDoOtherUser, mergeCart); hDisconnectCentral(&conn2); cartTrace(cart, "after cartLUS", conn); didSessionLoad = TRUE; } else if (cartVarExists(cart, hgsDoLoadUrl)) { char *url = cartString(cart, hgsLoadUrlName); struct lineFile *lf = netLineFileOpen(url); struct dyString *dyMessage = dyStringNew(0); boolean ok = cartLoadSettingsFromUserInput(lf, cart, oldVars, hgsDoLoadUrl, dyMessage); lineFileClose(&lf); cartTrace(cart, "after cartLS", conn); if (! ok) { warn("Unable to load session file: %s", dyMessage->string);