84b2a66056c61f0661676de79e7d710073ba8d5d max Tue Feb 3 01:37:38 2026 -0800 adding hub email display to hub error output, refs #36916 and refs #33571 diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 426b0a9c360..20a4459b34d 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -1200,35 +1200,39 @@ char *(*finder)(char *needle, char *haystack) = (anyIupac(fOligo) ? iupacIn : stringInWrapper); int oligoSize = strlen(fOligo); char *rOligo = cloneString(fOligo); char *rMatch = NULL, *fMatch = NULL; struct bed *bedList = NULL, *bed; char strand; int count = 0, maxCount = 1000000; char *strandFilter = cartUsualString(cart, oligoMatchStrandVar, oligoMatchStrandDefault); boolean searchForward = sameString(strandFilter, "both") || sameString(strandFilter, "forward"); boolean searchReverse = sameString(strandFilter, "both") || sameString(strandFilter, "reverse"); if (oligoSize >= 2) { if (searchForward) fMatch = finder(fOligo, dna); - iupacReverseComplement(rOligo, oligoSize); + if (sameString(rOligo, fOligo)) rOligo = NULL; else if (searchReverse) + { + iupacReverseComplement(rOligo, oligoSize); rMatch = finder(rOligo, dna); + } + for (;;) { char *oneMatch = NULL; if (rMatch == NULL) { if (fMatch == NULL) break; else { oneMatch = fMatch; fMatch = finder(fOligo, fMatch+1); strand = '+'; } } else if (fMatch == NULL) @@ -8747,30 +8751,61 @@ #endif unsigned getParaLoadTimeout() // get the parallel load timeout in seconds (defaults to 90) { char *paraLoadTimeoutStr = cartOptionalString(cart, "parallelFetch.timeout"); if (paraLoadTimeoutStr == NULL) paraLoadTimeoutStr = cfgOptionDefault("parallelFetch.timeout", "90"); // wait up to default 90 seconds. unsigned paraLoadTimeout = sqlUnsigned(paraLoadTimeoutStr); return paraLoadTimeout; } +static char *hubPublicEmailFromHubName(char *hubName) +{ +/* return public hub email given url or NULL if such a column doesn't exist (mirrors don't have this column) */ +/* result must be freed */ +char *hubIdStr = strchr(hubName, '_'); // could not find a function for this in hubConnect.c +if (!hubIdStr) + return NULL; +unsigned hubId = sqlUnsigned(hubIdStr+1); + +struct hubConnectStatus *hubStatus = hubFromIdNoAbort(hubId); +if (hubStatus == NULL) + return NULL; + +char *url = hubStatus->hubUrl; +if (!url) + return NULL; + +struct sqlConnection *conn = hConnectCentral(); + +char *email = NULL; +if (sqlColumnExists(conn, "hubPublic", "email")) + { + char query[1000]; + sqlSafef(query, sizeof query, "SELECT email FROM hubPublic WHERE hubUrl='%s'", url); + email = sqlQuickNonemptyString(conn, query); + } + +hDisconnectCentral(&conn); +return email; +} + void doTrackForm(char *psOutput, struct tempName *ideoTn) /* Make the tracks display form with the zoom/scroll buttons and the active * image. If the ideoTn parameter is not NULL, it is filled in if the * ideogram is created. */ { #ifdef GRAPH_BUTTON_ON_QUICKLIFT int graphCount = 0; #endif int disconCount = 0; struct group *group; struct track *track; char *freezeName = NULL; boolean hideAll = cgiVarExists("hgt.hideAll"); boolean hideTracks = cgiOptionalString( "hideTracks") != NULL; boolean defaultTracks = cgiVarExists("hgt.reset"); @@ -9901,30 +9936,33 @@ // we want tracks in the visible list to also be visible // in the normal group list, so use a separate hash for the // visible tracks grouping groupTrackListAddSuper(cart, group, hashNew(8), hashNew(8)); } else groupTrackListAddSuper(cart, group, superHash, trackHash); /* Display track controls */ if (group->errMessage) { hPrintf("