9661f8ba9e015aef34e09240d677ac7978ec0766 braney Wed May 18 12:33:41 2011 -0700 move hub connection stuff into hg/lib so hgTracks can add hubs on its own diff --git src/hg/hgHubConnect/hgHubConnect.c src/hg/hgHubConnect/hgHubConnect.c index 56ab99c..dc1d1f6 100644 --- src/hg/hgHubConnect/hgHubConnect.c +++ src/hg/hgHubConnect/hgHubConnect.c @@ -1,493 +1,279 @@ /* hgHubConnect - the CGI web-based program to select track data hubs to connect with. */ #include "common.h" #include "hash.h" #include "linefile.h" #include "errabort.h" #include "errCatch.h" #include "hCommon.h" #include "dystring.h" #include "jksql.h" #include "cheapcgi.h" #include "htmshell.h" #include "hdb.h" #include "hui.h" #include "cart.h" #include "dbDb.h" #include "web.h" #include "trackHub.h" #include "hubConnect.h" #include "dystring.h" #include "hPrint.h" -#define hgHubDataText "hgHub_customText" #define hgHub "hgHub_" /* prefix for all control variables */ #define hgHubDo hgHub "do_" /* prefix for all commands */ #define hgHubDoAdd hgHubDo "add" #define hgHubDoClear hgHubDo "clear" struct cart *cart; /* The user's ui state. */ struct hash *oldVars = NULL; static char *destUrl = "../cgi-bin/hgTracks"; static char *pageTitle = "Import Tracks from Data Hubs"; char *database = NULL; char *organism = NULL; -static boolean nameInCommaList(char *name, char *commaList) -/* Return TRUE if name is in comma separated list. */ -{ -if (commaList == NULL) - return FALSE; -int nameLen = strlen(name); -for (;;) - { - char c = *commaList; - if (c == 0) - return FALSE; - if (memcmp(name, commaList, nameLen) == 0) - { - c = commaList[nameLen]; - if (c == 0 || c == ',') - return TRUE; - } - commaList = strchr(commaList, ','); - if (commaList == NULL) - return FALSE; - commaList += 1; - } -} +boolean nameInCommaList(char *name, char *commaList); static void hgHubConnectUnlisted() /* Put up the list of unlisted hubs and other controls for the page. */ { printf("Unlisted Hubs
"); struct hubConnectStatus *hub, *hubList = hubConnectStatusListFromCart(cart); int count = 0; for(hub = hubList; hub; hub = hub->next) { /* if the hub is public, then don't list it here */ if (!isHubUnlisted(hub)) continue; if (count) webPrintLinkTableNewRow(); else webPrintLinkTableStart(); count++; if (isEmpty(hub->errorMessage)) { webPrintLinkCellStart(); char hubName[32]; safef(hubName, sizeof(hubName), "%s%u", hgHubConnectHubVarPrefix, hub->id); cartMakeCheckBox(cart, hubName, FALSE); webPrintLinkCellEnd(); } else webPrintLinkCell("error"); webPrintLinkCell(hub->shortLabel); if (isEmpty(hub->errorMessage)) webPrintLinkCell(hub->longLabel); else webPrintLinkCell(hub->errorMessage); webPrintLinkCell(hub->hubUrl); } if (count) webPrintLinkTableEnd(); else printf("No Unlisted Track Hubs for this genome assembly
"); } static void makeNewHubButton() { printf("
\n", "../cgi-bin/hgHubConnect"); cartSaveSession(cart); cgiMakeHiddenVar(hgHubDoAdd, "on"); cgiMakeButton("add", "Add new unlisted hub"); printf("
\n"); } static void makeGenomePrint() { getDbAndGenome(cart, &database, &organism, oldVars); printf("genome: %s    assembly: %s ", organism, hFreezeDate(database)); } static void addIntro() { printf("Enter URL to remote hub.
\n"); } void addUnlistedHubForm(struct hubConnectStatus *hub, char *err) /* display UI for adding unlisted hubs by URL */ { getDbAndGenome(cart, &database, &organism, oldVars); boolean gotClade = FALSE; boolean isUpdateForm = FALSE; if (hub) { isUpdateForm = TRUE; } else /* add form needs clade for assembly menu */ gotClade = hGotClade(); /* main form */ printf("
\n", "../cgi-bin/hgHubConnect", cartUsualString(cart, "formMethod", "POST")); cartSaveSession(cart); cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on"); /* intro text */ puts("

"); puts("Add your own unlisted data hub for the browser."); addIntro(); puts("

"); /* row for error message */ if (err) printf("

    Error %s

", err); printf("Enter URL:"); hTextVar(hgHubDataText, "", 60); cgiMakeSubmitButton(); puts("

"); } void helpUnlistedHub() { printf("Unlisted hubs are constructed the same way as public hubs, but they " "aren't listed in hgcentral
\n"); } void doAddUnlistedHub(struct cart *theCart, char *err) /* Write header and body of html page. */ { cartWebStart(cart, database, "Add Unlisted Hub"); addUnlistedHubForm(NULL, err); helpUnlistedHub(); cartWebEnd(cart); } -static void enterHubInStatus(struct trackHub *tHub, boolean unlisted) -/* put the hub status in the hubStatus table */ -{ -struct sqlConnection *conn = hConnectCentral(); - -/* calculate dbList */ -struct dyString *dy = newDyString(1024); -struct hashEl *hel; -struct hashCookie cookie = hashFirst(tHub->genomeHash); -int dbCount = 0; - -while ((hel = hashNext(&cookie)) != NULL) - { - dbCount++; - dyStringPrintf(dy,"%s,", hel->name); - } - - -char query[512]; -safef(query, sizeof(query), "insert into %s (hubUrl,status,shortLabel, longLabel, dbList, dbCount) values (\"%s\",%d,\"%s\",\"%s\", \"%s\", %d)", - hubStatusTableName, tHub->url, unlisted ? 1 : 0, - tHub->shortLabel, tHub->longLabel, - dy->string, dbCount); -sqlUpdate(conn, query); -hDisconnectCentral(&conn); -} - -static unsigned getHubId(char *url, char **errorMessage) -/* find id for url in hubStatus table */ -{ -struct sqlConnection *conn = hConnectCentral(); -char query[512]; -char **row; -boolean foundOne = FALSE; -int id = 0; - -safef(query, sizeof(query), "select id,errorMessage from %s where hubUrl = \"%s\"", hubStatusTableName, url); - -struct sqlResult *sr = sqlGetResult(conn, query); - -while ((row = sqlNextRow(sr)) != NULL) - { - if (foundOne) - errAbort("more than one line in %s with hubUrl %s\n", - hubStatusTableName, url); - - foundOne = TRUE; - - char *thisId = row[0], *thisError = row[1]; - - if (!isEmpty(thisError)) - *errorMessage = cloneString(thisError); - - id = sqlUnsigned(thisId); - } -sqlFreeResult(&sr); - -hDisconnectCentral(&conn); - -return id; -} - -static boolean hubHasDatabase(unsigned id, char *database) -/* check to see if hub specified by id supports database */ -{ -struct sqlConnection *conn = hConnectCentral(); -char query[512]; - -safef(query, sizeof(query), "select dbList from %s where id=%d", - hubStatusTableName, id); -char *dbList = sqlQuickString(conn, query); -boolean gotIt = FALSE; - -if (nameInCommaList(database, dbList)) - gotIt = TRUE; - -hDisconnectCentral(&conn); - -freeMem(dbList); - -return gotIt; -} - -static boolean fetchHub(char *url, boolean unlisted) -{ -struct errCatch *errCatch = errCatchNew(); -struct trackHub *tHub = NULL; -boolean gotWarning = FALSE; -unsigned id = 0; - -if (errCatchStart(errCatch)) - tHub = trackHubOpen(url, "1"); // open hub.. it'll get renamed later -errCatchEnd(errCatch); -if (errCatch->gotError) - { - gotWarning = TRUE; - warn(errCatch->message->string); - } -errCatchFree(&errCatch); - -if (gotWarning) - { - return 0; - } - -if (hashLookup(tHub->genomeHash, database) != NULL) - { - enterHubInStatus(tHub, unlisted); - } -else - { - warn("requested hub at %s does not have data for %s\n", url, database); - return 0; - } - -trackHubClose(&tHub); - -char *errorMessage = NULL; -id = getHubId(url, &errorMessage); -return id; -} - -static void getAndSetHubStatus(char *url, boolean set, boolean unlisted) -{ -char *errorMessage = NULL; -unsigned id; - -if ((id = getHubId(url, &errorMessage)) == 0) - { - if ((id = fetchHub(url, unlisted)) == 0) - return; - } -else if (!hubHasDatabase(id, database)) - { - warn("requested hub at %s does not have data for %s\n", url, database); - return; - } - -char hubName[32]; -safef(hubName, sizeof(hubName), "%s%u", hgHubConnectHubVarPrefix, id); -if (set) - cartSetString(cart, hubName, "1"); -} - -static unsigned findOrAddUrlInStatusTable( 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(url, FALSE, FALSE); - -if ((id = getHubId(url, errorMessage)) == 0) - errAbort("inserted new hubUrl %s, but cannot find it", url); - -return id; -} void hgHubConnectPublic() /* Put up the list of external hubs and other controls for the page. */ { printf("Public Hubs
"); struct sqlConnection *conn = hConnectCentral(); char query[512]; safef(query, sizeof(query), "select hubUrl, shortLabel,longLabel,dbList from %s", hubPublicTableName); struct sqlResult *sr = sqlGetResult(conn, query); char **row; boolean gotAnyRows = FALSE; while ((row = sqlNextRow(sr)) != NULL) { char *url = row[0], *shortLabel = row[1], *longLabel = row[2], *dbList = row[3]; if (nameInCommaList(database, dbList)) { if (gotAnyRows) webPrintLinkTableNewRow(); else { webPrintLinkTableStart(); gotAnyRows = TRUE; } char *errorMessage = NULL; - unsigned id = findOrAddUrlInStatusTable( url, &errorMessage); + unsigned id = hubFindOrAddUrlInStatusTable(database, cart, + url, &errorMessage); if ((id != 0) && isEmpty(errorMessage)) { webPrintLinkCellStart(); char hubName[32]; safef(hubName, sizeof(hubName), "%s%u", hgHubConnectHubVarPrefix, id); cartMakeCheckBox(cart, hubName, FALSE); webPrintLinkCellEnd(); } else if (!isEmpty(errorMessage)) webPrintLinkCell("error"); else errAbort("cannot get id for hub with url %s\n", url); webPrintLinkCell(shortLabel); if (isEmpty(errorMessage)) webPrintLinkCell(longLabel); else { char errorBuf[4*1024]; safef(errorBuf, sizeof errorBuf, "Error: %s", errorMessage); webPrintLinkCell(errorBuf); } webPrintLinkCell(url); } } sqlFreeResult(&sr); if (gotAnyRows) webPrintLinkTableEnd(); else printf("No Public Track Hubs for this genome assembly
"); hDisconnectCentral(&conn); } -void checkForNewHub(struct cart *cart) -/* see if the user just typed in a new hub url */ -{ -char *url = cartOptionalString(cart, hgHubDataText); - -if (url != NULL) - { - getAndSetHubStatus(url, TRUE, TRUE); - } -} - -static void clearHubStatus(char *url) -{ -struct sqlConnection *conn = hConnectCentral(); -char query[512]; - -safef(query, sizeof(query), "select id from %s where hubUrl = \"%s\"", hubStatusTableName, url); -unsigned id = sqlQuickNum(conn, query); - -if (id == 0) - errAbort("could not find url %s in status table (%s)\n", - url, hubStatusTableName); - -safef(query, sizeof(query), "delete from %s where hubUrl = \"%s\"", hubStatusTableName, url); - -sqlUpdate(conn, query); -hDisconnectCentral(&conn); - -printf("%s status has been cleared\n", url); -} - static void doClearHub(struct cart *theCart) { char *url = cartOptionalString(cart, hgHubDataText); if (url != NULL) - clearHubStatus(url); + hubClearStatus(url); else errAbort("must specify url in %s\n", hgHubDataText); } void doMiddle(struct cart *theCart) /* Write header and body of html page. */ { cart = theCart; setUdcCacheDir(); if (cartVarExists(cart, hgHubDoAdd)) doAddUnlistedHub(cart, NULL); else if (cartVarExists(cart, hgHubDoClear)) doClearHub(cart); else { cartWebStart(cart, NULL, pageTitle); printf( "

Track data hubs are collections of tracks from outside of UCSC that can be imported into " "the Genome Browser. To import a public hub check the box in the list below. " "After import the hub will show up as a group of tracks with its own blue " "bar and label underneath the main browser graphic, and in the configure page.

\n" ); makeGenomePrint(); - checkForNewHub(cart); + hubCheckForNew(database, cart); printf("

"); printf("

\n", destUrl); cartSaveSession(cart); hgHubConnectPublic(); printf("
Contact genome@soe.ucsc.edu to add a public hub.

\n"); puts("
"); hgHubConnectUnlisted(); puts("
"); cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on"); cgiMakeButton("Submit", "Use Selected Hubs"); puts("
"); makeNewHubButton(); } cartWebEnd(); } char *excludeVars[] = {"Submit", "submit", "hc_one_url", hgHubConnectCgiDestUrl, hgHubDoAdd, hgHubDoClear hgHubDataText, NULL}; int main(int argc, char *argv[]) /* Process command line. */ { oldVars = hashNew(10); cgiSpoof(&argc, argv); cartEmptyShell(doMiddle, hUserCookie(), excludeVars, oldVars); return 0; }