ef2869665d8c2d4fe59743faabe050de406a5278 braney Wed Apr 13 18:00:32 2011 -0700 add support for private hubs. Needs more work and doc, the biggest problem I know of is that you can't switch off the private hubs, but it should give folks an idea of how I'm thinking of supporting them. diff --git src/hg/hgHubConnect/hgHubConnect.c src/hg/hgHubConnect/hgHubConnect.c index a965529..3aa0b1b 100644 --- src/hg/hgHubConnect/hgHubConnect.c +++ src/hg/hgHubConnect/hgHubConnect.c @@ -5,84 +5,148 @@ #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 "trashDir.h" +#include "hPrint.h" + +#define TEXT_ENTRY_ROWS 7 +#define TEXT_ENTRY_COLS 73 +#define CONFIG_ENTRY_ROWS 3 +#define SAVED_LINE_COUNT 50 + +#define HUB_CUSTOM_TEXT_ALT_VAR "hghub_customText" +#define HUB_CUSTOM_FILE_VAR "hghub.customFile" +#define HUB_UPDATED_ID "hghub_updatedId" + + + +#define hgHubDataText HUB_CUSTOM_TEXT_ALT_VAR +#define hgHubDataFile HUB_CUSTOM_FILE_VAR +#define hgHubUpdatedId HUB_UPDATED_ID + +#define hgHub "hgHub_" /* prefix for all control variables */ +#define hgHubDo hgHub "do_" /* prefix for all commands */ +#define hgHubDoAdd hgHubDo "add" -static char const rcsid[] = "$Id: hgPcr.c,v 1.29 2009/09/23 18:42:17 angie Exp $"; struct cart *cart; /* The user's ui state. */ struct hash *oldVars = NULL; static char *destUrl = "../cgi-bin/hgTracks"; -static char *pageTitle = "Import Tracks from External Data Hubs"; +static char *pageTitle = "Import Tracks from Data Hubs"; char *database = NULL; char *organism = NULL; 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; } } -void hgHubConnect() -/* Put up the list of hubs and other controls for the page. */ +void hgHubConnectPrivate() +/* Put up the list of private hubs and other controls for the page. */ +{ +printf("<FORM ACTION=\"%s\" METHOD=\"POST\" NAME=\"mainForm\">\n", "../cgi-bin/hgHubConnect"); +cartSaveSession(cart); +cgiMakeHiddenVar(hgHubDoAdd, "on"); +printf("<B>List of Private Hubs</B><BR>"); +struct hubConnectStatus *hub, *hubList = hubConnectStatusListFromCart(cart); +int count = 0; +for(hub = hubList; hub; hub = hub->next) + { + if (hub->id > 0) + continue; + count++; + if (hub != hubList) + webPrintLinkTableNewRow(); + else + webPrintLinkTableStart(); + + if (isEmpty(hub->errorMessage)) + { + webPrintLinkCellStart(); + char hubName[32]; + safef(hubName, sizeof(hubName), "%s%d", 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 Private Track Hubs for this genome assembly<BR>"); +cgiMakeButton("add", "add new private hub"); +} + +void hgHubConnectPublic() +/* Put up the list of external hubs and other controls for the page. */ { destUrl = cartUsualString(cart, hgHubConnectCgiDestUrl, destUrl); printf("<FORM ACTION=\"%s\" METHOD=\"POST\" NAME=\"mainForm\">\n", destUrl); cartSaveSession(cart); cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on"); printf( "<P>Track data hubs are collections of tracks from outside of UCSC that can be imported into " - "the Genome Browser. To import a hub check the box in the list below. " + "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. To arrange " "for your own track data hub to appear in this list, please contact genome@soe.ucsc.edu.</P>\n" ); getDbAndGenome(cart, &database, &organism, oldVars); printf("<B>genome:</B> %s <B>assembly:</B> %s [%s] ", organism, hFreezeDate(database), database); cgiMakeButton("submit", "submit"); printf("<BR>"); +printf("<B>List of Public Hubs</B><BR>"); struct sqlConnection *conn = hConnectCentral(); char query[512]; safef(query, sizeof(query), "select id,shortLabel,longLabel,errorMessage,hubUrl,dbList from %s", hubConnectTableName); struct sqlResult *sr = sqlGetResult(conn, query); char **row; boolean gotAnyRows = FALSE; while ((row = sqlNextRow(sr)) != NULL) { char *id = row[0], *shortLabel = row[1], *longLabel = row[2], *errorMessage = row[3], *url = row[4], *dbList = row[5]; if (nameInCommaList(database, dbList)) { if (gotAnyRows) @@ -107,36 +171,168 @@ webPrintLinkCell(longLabel); else webPrintLinkCell(errorMessage); webPrintLinkCell(url); } } sqlFreeResult(&sr); if (gotAnyRows) webPrintLinkTableEnd(); else printf("No Track Hubs for this genome assembly"); printf("</FORM>\n"); hDisconnectCentral(&conn); } +static void addIntro() +{ +} + +void makeClearButton(char *field) +/* UI button that clears a text field */ +{ +char javascript[1024]; +safef(javascript, sizeof javascript, + "document.mainForm.%s.value = '';", field); +cgiMakeOnClickButton(javascript, " Clear "); +} + +void addPrivateHubForm(struct hubConnectStatus *hub, char *err) +/* display UI for adding private hubs by URL or pasting data */ +{ +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("<FORM ACTION=\"%s\" METHOD=\"%s\" " + " ENCTYPE=\"multipart/form-data\" NAME=\"mainForm\">\n", + "../cgi-bin/hgHubConnect", cartUsualString(cart, "formMethod", "POST")); +cartSaveSession(cart); +cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on"); + +/* intro text */ +puts("<P>"); +puts("Add your own private data hub for the browser."); +addIntro(); +puts("<P>"); + +/* row for error message */ +if (err) + printf("<P><B> <I><FONT COLOR='RED'>Error</I></FONT> %s</B><P>", err); + +printf("Enter URL:"); + +hTextVar(hgHubDataText, "", 60); +cgiMakeSubmitButton(); + +puts("</FORM>"); +} + +void helpPrivateHub() +{ +} + +void doAddPrivateHub(struct cart *theCart, char *err) +/* Write header and body of html page. */ +{ +cartWebStart(cart, database, "Add Private Hub"); +addPrivateHubForm(NULL, err); +helpPrivateHub(); +cartWebEnd(cart); +} + +void hubSaveInCart(struct cart *cart, struct hubConnectStatus *hub) +{ +char hubName[1024]; +char *oldHubTrashName = cartOptionalString(cart, hubFileVar()); +static struct tempName tn; +trashDirFile(&tn, "hub", "hub_", ".txt"); +char *hubTrashName = tn.forCgi; +FILE *f = mustOpen(hubTrashName, "w"); + +if (oldHubTrashName == NULL) + { + hub->id = -1; + } +else + { + struct lineFile *lf = lineFileOpen(oldHubTrashName, TRUE); + int lineSize; + char *line; + int count = 1; + + while (lineFileNext(lf, &line, &lineSize)) + { + count++; + fprintf(f, "%s\n", line); + } + lineFileClose(&lf); + hub->id = -count; + } +hubWriteToFile(f, hub); +carefulClose(&f); + +safef(hubName, sizeof(hubName), "%s%d", hgHubConnectHubVarPrefix, hub->id); +cartSetString(cart, hubName, "1"); + +cartSetString(cart, hubFileVar(), hubTrashName); +} + +void checkForNewHub(struct cart *cart) +{ +char *url = cartOptionalString(cart, hgHubDataText); + +if (url != NULL) + { + struct hubConnectStatus *hub = NULL; + struct trackHub *tHub = trackHubOpen(url, "1"); + AllocVar(hub); + + hub->hubUrl = cloneString(url); + hub->errorMessage = ""; + hub->shortLabel = tHub->shortLabel; + hub->longLabel = tHub->longLabel; + hub->dbCount = 0; + AllocArray(hub->dbArray, 1); + hub->dbArray[0] = database; + + hubSaveInCart(cart, hub); + cartRemove(cart, hgHubDataText); + } +} + void doMiddle(struct cart *theCart) /* Write header and body of html page. */ { cart = theCart; setUdcCacheDir(); +if (cartVarExists(cart, hgHubDoAdd)) + doAddPrivateHub(cart, NULL); +else + { cartWebStart(cart, NULL, pageTitle); -hgHubConnect(); + checkForNewHub(cart); + hgHubConnectPublic(); + hgHubConnectPrivate(); + } cartWebEnd(); } char *excludeVars[] = {"Submit", "submit", "hc_one_url", hgHubConnectCgiDestUrl, NULL}; int main(int argc, char *argv[]) /* Process command line. */ { oldVars = hashNew(10); cgiSpoof(&argc, argv); cartEmptyShell(doMiddle, hUserCookie(), excludeVars, oldVars); return 0; }