533112afe2a2005e80cdb1f82904ea65032d4302 braney Sat Oct 2 11:37:34 2021 -0700 split hg/lib into two separate libaries, one only used by the cgis diff --git src/hg/cgilib/wikiTrack.c src/hg/cgilib/wikiTrack.c new file mode 100644 index 0000000..8ea5244 --- /dev/null +++ src/hg/cgilib/wikiTrack.c @@ -0,0 +1,1079 @@ +/* wikiTrack.c was originally generated by the autoSql program, which also + * generated wikiTrack.h and wikiTrack.sql. This module links the database and + * the RAM representation of objects. */ + +/* Copyright (C) 2014 The Regents of the University of California + * See README in this or parent directory for licensing information. */ + +#include "common.h" +#include "linefile.h" +#include "dystring.h" +#include "jksql.h" +#include "wikiTrack.h" +#include "errCatch.h" + + +void wikiTrackStaticLoad(char **row, struct wikiTrack *ret) +/* Load a row from wikiTrack table into ret. The contents of ret will + * be replaced at the next call to this function. */ +{ + +ret->bin = sqlUnsigned(row[0]); +ret->chrom = row[1]; +ret->chromStart = sqlUnsigned(row[2]); +ret->chromEnd = sqlUnsigned(row[3]); +ret->name = row[4]; +ret->score = sqlUnsigned(row[5]); +safecpy(ret->strand, sizeof(ret->strand), row[6]); +ret->db = row[7]; +ret->owner = row[8]; +ret->color = row[9]; +ret->class = row[10]; +ret->creationDate = row[11]; +ret->lastModifiedDate = row[12]; +ret->descriptionKey = row[13]; +ret->id = sqlUnsigned(row[14]); +ret->geneSymbol = row[15]; +} + +struct wikiTrack *wikiTrackLoad(char **row) +/* Load a wikiTrack from row fetched with select * from wikiTrack + * from database. Dispose of this with wikiTrackFree(). */ +{ +struct wikiTrack *ret; + +AllocVar(ret); +ret->bin = sqlUnsigned(row[0]); +ret->chrom = cloneString(row[1]); +ret->chromStart = sqlUnsigned(row[2]); +ret->chromEnd = sqlUnsigned(row[3]); +ret->name = cloneString(row[4]); +ret->score = sqlUnsigned(row[5]); +safecpy(ret->strand, sizeof(ret->strand), row[6]); +ret->db = cloneString(row[7]); +ret->owner = cloneString(row[8]); +ret->color = cloneString(row[9]); +ret->class = cloneString(row[10]); +ret->creationDate = cloneString(row[11]); +ret->lastModifiedDate = cloneString(row[12]); +ret->descriptionKey = cloneString(row[13]); +ret->id = sqlUnsigned(row[14]); +ret->geneSymbol = cloneString(row[15]); +return ret; +} + +struct wikiTrack *wikiTrackLoadAll(char *fileName) +/* Load all wikiTrack from a whitespace-separated file. + * Dispose of this with wikiTrackFreeList(). */ +{ +struct wikiTrack *list = NULL, *el; +struct lineFile *lf = lineFileOpen(fileName, TRUE); +char *row[16]; + +while (lineFileRow(lf, row)) + { + el = wikiTrackLoad(row); + slAddHead(&list, el); + } +lineFileClose(&lf); +slReverse(&list); +return list; +} + +struct wikiTrack *wikiTrackLoadAllByChar(char *fileName, char chopper) +/* Load all wikiTrack from a chopper separated file. + * Dispose of this with wikiTrackFreeList(). */ +{ +struct wikiTrack *list = NULL, *el; +struct lineFile *lf = lineFileOpen(fileName, TRUE); +char *row[16]; + +while (lineFileNextCharRow(lf, chopper, row, ArraySize(row))) + { + el = wikiTrackLoad(row); + slAddHead(&list, el); + } +lineFileClose(&lf); +slReverse(&list); +return list; +} + +struct wikiTrack *wikiTrackLoadByQuery(struct sqlConnection *conn, char *query) +/* Load all wikiTrack from table that satisfy the query given. + * Where query is of the form 'select * from example where something=something' + * or 'select example.* from example, anotherTable where example.something = + * anotherTable.something'. + * Dispose of this with wikiTrackFreeList(). */ +{ +struct wikiTrack *list = NULL, *el; +struct sqlResult *sr; +char **row; + +sr = sqlGetResult(conn, query); +while ((row = sqlNextRow(sr)) != NULL) + { + el = wikiTrackLoad(row); + slAddHead(&list, el); + } +slReverse(&list); +sqlFreeResult(&sr); +return list; +} + +void wikiTrackSaveToDb(struct sqlConnection *conn, struct wikiTrack *el, char *tableName, int updateSize) +/* Save wikiTrack as a row to the table specified by tableName. + * As blob fields may be arbitrary size updateSize specifies the approx size + * of a string that would contain the entire query. Arrays of native types are + * converted to comma separated strings and loaded as such, User defined types are + * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */ +{ +struct dyString *update = newDyString(updateSize); +sqlDyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", + tableName, el->bin, el->chrom, el->chromStart, el->chromEnd, el->name, el->score, el->strand, el->db, el->owner, el->color, el->class, el->creationDate, el->lastModifiedDate, el->descriptionKey, el->id, el->geneSymbol); +sqlUpdate(conn, update->string); +freeDyString(&update); +} + + +struct wikiTrack *wikiTrackCommaIn(char **pS, struct wikiTrack *ret) +/* Create a wikiTrack out of a comma separated string. + * This will fill in ret if non-null, otherwise will + * return a new wikiTrack */ +{ +char *s = *pS; + +if (ret == NULL) + AllocVar(ret); +ret->bin = sqlUnsignedComma(&s); +ret->chrom = sqlStringComma(&s); +ret->chromStart = sqlUnsignedComma(&s); +ret->chromEnd = sqlUnsignedComma(&s); +ret->name = sqlStringComma(&s); +ret->score = sqlUnsignedComma(&s); +sqlFixedStringComma(&s, ret->strand, sizeof(ret->strand)); +ret->db = sqlStringComma(&s); +ret->owner = sqlStringComma(&s); +ret->color = sqlStringComma(&s); +ret->class = sqlStringComma(&s); +ret->creationDate = sqlStringComma(&s); +ret->lastModifiedDate = sqlStringComma(&s); +ret->descriptionKey = sqlStringComma(&s); +ret->id = sqlUnsignedComma(&s); +ret->geneSymbol = sqlStringComma(&s); +*pS = s; +return ret; +} + +void wikiTrackFree(struct wikiTrack **pEl) +/* Free a single dynamically allocated wikiTrack such as created + * with wikiTrackLoad(). */ +{ +struct wikiTrack *el; + +if ((el = *pEl) == NULL) return; +freeMem(el->chrom); +freeMem(el->name); +freeMem(el->db); +freeMem(el->owner); +freeMem(el->color); +freeMem(el->class); +freeMem(el->creationDate); +freeMem(el->lastModifiedDate); +freeMem(el->descriptionKey); +freeMem(el->geneSymbol); +freez(pEl); +} + +void wikiTrackFreeList(struct wikiTrack **pList) +/* Free a list of dynamically allocated wikiTrack's */ +{ +struct wikiTrack *el, *next; + +for (el = *pList; el != NULL; el = next) + { + next = el->next; + wikiTrackFree(&el); + } +*pList = NULL; +} + +void wikiTrackOutput(struct wikiTrack *el, FILE *f, char sep, char lastSep) +/* Print out wikiTrack. Separate fields with sep. Follow last field with lastSep. */ +{ +fprintf(f, "%u", el->bin); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->chrom); +if (sep == ',') fputc('"',f); +fputc(sep,f); +fprintf(f, "%u", el->chromStart); +fputc(sep,f); +fprintf(f, "%u", el->chromEnd); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->name); +if (sep == ',') fputc('"',f); +fputc(sep,f); +fprintf(f, "%u", el->score); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->strand); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->db); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->owner); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->color); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->class); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->creationDate); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->lastModifiedDate); +if (sep == ',') fputc('"',f); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->descriptionKey); +if (sep == ',') fputc('"',f); +fputc(sep,f); +fprintf(f, "%u", el->id); +fputc(sep,f); +if (sep == ',') fputc('"',f); +fprintf(f, "%s", el->geneSymbol); +if (sep == ',') fputc('"',f); +fputc(lastSep,f); +} + +/* -------------------------------- End autoSql Generated Code -------------------------------- */ + +#include "hgConfig.h" +#include "wikiLink.h" +#include "cheapcgi.h" +#include "hdb.h" +#include "hui.h" +#include "net.h" +#include "cart.h" +#include "hPrint.h" +#include "grp.h" +#include "obscure.h" +#include "hCommon.h" +#include "web.h" +#include "hgColors.h" + +#ifdef NOT +static void savePosInTextBox(char *chrom, int start, int end) +/* Save basic position/database info in text box and hidden var. + Positions becomes chrom:start-end*/ +{ +char position[128]; +char *newPos; +safef(position, 128, "%s:%d-%d", chrom, start, end); +newPos = addCommasToPos(position); +cgiMakeTextVar("getDnaPos", newPos, strlen(newPos) + 2); +cgiContinueHiddenVar("db"); +} +#endif + +boolean wikiTrackReadOnly() +/* return TRUE if wiki track is in Read-Only mode, default answer is FALSE */ +{ +return cfgOptionBooleanDefault(CFG_WIKI_TRACK_READ_ONLY, FALSE); +} + +boolean wikiTrackEnabled(char *database, char **wikiUserName) +/*determine if wikiTrack can be used, and is this user logged into the wiki ?*/ +{ +static boolean done = FALSE; +static boolean status = FALSE; +static boolean wikiUp = TRUE; +static char *userName = NULL; + +/* do not repeat this query */ +if (done) + { + if (wikiUserName) + *wikiUserName = userName; /* returning name indicates logged in */ + return status; + } + +done = TRUE; /* only need to do this once */ + +if (wikiUserName) + *wikiUserName = NULL; /* assume not logged in until proven otherwise */ + +/* potentially a comma separated list */ + +char *dbListString = cfgOption(CFG_WIKI_DB_LIST); +char *dbList[256]; +int dbCount = 0; +if (NULL != dbListString) + { + dbCount = chopByChar(cloneString(dbListString), ',', dbList, + ArraySize(dbList)); + } +boolean validDb = TRUE; +if (dbCount > 0) + { + validDb = FALSE; + int i; + for (i = 0; i < dbCount; ++i) + { + if (sameWord(dbList[i],database)) + { + validDb = TRUE; + break; + } + } + } +/* must have wiki login system enabled, and the new cfg options exist too. */ +if (validDb && wikiLinkEnabled() && + (cfgOption(CFG_WIKI_SESSION_COOKIE) != NULL) && + (cfgOption(CFG_WIKI_BROWSER) != NULL) && + (cfgOption(CFG_WIKI_URL) != NULL)) + { + char *wikiUser = wikiLinkUserName(); + if ( (wikiUser) && + (findCookieData(cfgOption(CFG_WIKI_SESSION_COOKIE)) != NULL) ) + { + struct htmlPage *page = NULL; + /* protect against temporarily offline wiki site */ + struct errCatch *errCatch = errCatchNew(); + if (errCatchStart(errCatch)) + { + page = fetchEditPage(TEST_EMAIL_VERIFIED); + } + errCatchEnd(errCatch); + if (errCatch->gotError) // we think it is supposed to be there + { + wikiUp = FALSE; // but it will not respond + } + errCatchFree(&errCatch); + char *loginExpired = NULL; + if (page) + loginExpired = stringIn(LOGIN_EXPIRED, page->fullText); + if (loginExpired == NULL) + { + if (wikiTrackReadOnly()) + userName = NULL; /* read-only mode 2012-06-25 */ + else + userName = wikiUser; + } + } + /* see if table exists, create it if it is not yet there */ + struct sqlConnection *wikiConn = wikiConnect(); + if (! sqlTableExists(wikiConn,WIKI_TRACK_TABLE)) + { + char *query = wikiTrackGetCreateSql(WIKI_TRACK_TABLE); + sqlUpdate(wikiConn, query); + freeMem(query); + } + wikiDisconnect(&wikiConn); + if (wikiUp) + status = TRUE; /* system is enabled */ + } +if (wikiUserName) + *wikiUserName = userName; /* returning name indicates logged in */ + +return status; +} + +/* from hg/lib/wikiTrack.sql */ +static char *createString = +"CREATE TABLE %s (\n" + "bin smallint unsigned not null,\n" + "chrom varchar(255) not null,\n" + "chromStart int unsigned not null,\n" + "chromEnd int unsigned not null,\n" + "name varchar(255) not null,\n" + "score int unsigned not null,\n" + "strand char(1) not null,\n" + "db varchar(36) not null,\n" + "owner varchar(255) not null,\n" + "color varchar(255) not null,\n" + "class varchar(255) not null,\n" + "creationDate varchar(255) not null,\n" + "lastModifiedDate varchar(255) not null,\n" + "descriptionKey varchar(255) not null,\n" + "id int unsigned not null auto_increment,\n" + "geneSymbol varchar(255) null,\n" + "PRIMARY KEY(id),\n" + "INDEX chrom (db,bin,chrom),\n" + "INDEX name (db,name),\n" + "INDEX gene (geneSymbol)\n" +")\n"; + +char *wikiTrackGetCreateSql(char *tableName) +/* return sql create statement for wiki track with tableName */ +{ +struct dyString *dy = dyStringNew(512); + +sqlDyStringPrintf(dy, createString, tableName); + +return (dyStringCannibalize(&dy)); +} + +char *wikiDbName() +/* return name of database where wiki track is located + currently this is central.db but the future may be configurable */ +{ +static char *dbName = NULL; + +if (dbName) + return dbName; + +char setting[64]; +safef(setting, sizeof(setting), "central.db"); +dbName = cfgOption(setting); +return dbName; +} + +struct sqlConnection *wikiConnect() +/* connect to db where wikiTrack table is located + * currently this is hConnectCentral() but the future may be + * configurable */ +{ +struct sqlConnection *conn = hConnectCentral(); +return conn; +} + +void wikiDisconnect(struct sqlConnection **pConn) +/* disconnect from wikiTrack table database */ +{ +hDisconnectCentral(pConn); +} + +struct wikiTrack *findWikiItemId(char *wikiItemId) +/* given a wikiItemId return the row from the table */ +{ +struct wikiTrack *item; +char query[256]; +struct sqlConnection *wikiConn = wikiConnect(); + +sqlSafef(query, ArraySize(query), "SELECT * FROM %s WHERE id='%s' limit 1", + WIKI_TRACK_TABLE, wikiItemId); + +item = wikiTrackLoadByQuery(wikiConn, query); +if (NULL == item) + errAbort("display wiki item: failed to load item '%s'", wikiItemId); +wikiDisconnect(&wikiConn); + +return item; +} + +struct wikiTrack *findWikiItemByGeneSymbol(char *db, char *geneSymbol) +/* given a db and UCSC known gene geneSymbol, find the wiki item */ +{ +struct wikiTrack *item = NULL; + +/* make sure neither of these arguments is NULL */ +if (db && geneSymbol) + { + char query[256]; + struct sqlConnection *wikiConn = wikiConnect(); + sqlSafef(query, ArraySize(query), + "SELECT * FROM %s WHERE db='%s' AND geneSymbol='%s' limit 1", + WIKI_TRACK_TABLE, db, geneSymbol); + + item = wikiTrackLoadByQuery(wikiConn, query); + + wikiDisconnect(&wikiConn); + } + +return item; +} + +struct wikiTrack *findWikiItemByName(char *db, char *name) +/* given a db,name pair return the row from the table, can return NULL */ +{ +struct wikiTrack *item = NULL; + +/* make sure neither of these arguments is NULL */ +if (name && db) + { + char query[256]; + struct sqlConnection *wikiConn = wikiConnect(); + sqlSafef(query, ArraySize(query), + "SELECT * FROM %s WHERE db='%s' AND name='%s' limit 1", + WIKI_TRACK_TABLE, db, name); + + item = wikiTrackLoadByQuery(wikiConn, query); + + wikiDisconnect(&wikiConn); + } + +return item; +} + +static char *stripEditURLs(char *rendered) +/* test for actual text, remove edit sections and any html comment strings */ +{ +char *stripped = cloneString(rendered); +char *found = NULL; +char *begin = "
0) + { + struct dyString *rm = newDyString(1024); + dyStringPrintf(rm, "%s%s%s", begin, found, end); + stripString(stripped, rm->string); + freeMem(found); + freeDyString(&rm); + } + } + +/* and remove comment strings from the wiki */ +begin = ""; +while (NULL != (found = stringBetween(begin, end, stripped)) ) + { + if (strlen(found) > 0) + { + struct dyString *rm = newDyString(1024); + dyStringPrintf(rm, "%s%s%s", begin, found, end); + stripString(stripped, rm->string); + freeMem(found); + freeDyString(&rm); + } + } + +return stripped; +} + +void htmlCloneFormVarSet(struct htmlForm *parent, + struct htmlForm *clone, char *name, char *val) +/* clone form variable from parent, with new value, + * if *val is NULL, clone val from parent + */ +{ +struct htmlFormVar *cloneVar; +struct htmlFormVar *var; +if (parent == NULL) + errAbort("Null parent form passed to htmlCloneFormVarSet"); +if (clone == NULL) + errAbort("Null clone form passed to htmlCloneFormVarSet"); +var = htmlFormVarGet(parent, name); +if (var == NULL) + errAbort("Variable '%s' not found in parent in htmlCloneFormVarSet", name); + +AllocVar(cloneVar); +cloneVar->name = cloneString(var->name); +cloneVar->tagName = cloneString(var->tagName); +cloneVar->type = cloneString(var->type); +if (NULL == val) + cloneVar->curVal = cloneString(var->curVal); +else + cloneVar->curVal = cloneString(val); +slAddHead(&clone->vars, cloneVar); + +} + +char *fetchWikiRawText(char *descriptionKey) +/* fetch page from wiki in raw form as it is in the edit form */ +{ +char wikiPageUrl[512]; +safef(wikiPageUrl, sizeof(wikiPageUrl), "%s/index.php?title=%s&action=raw", + cfgOptionDefault(CFG_WIKI_URL, NULL), descriptionKey); +struct lineFile *lf = netLineFileMayOpen(wikiPageUrl); + +struct dyString *wikiPage = newDyString(1024); +if (lf) + { + char *line; + int lineSize; + while (lineFileNext(lf, &line, &lineSize)) + dyStringPrintf(wikiPage, "%s\n", line); + lineFileClose(&lf); + } + +/* test for text, remove any edit sections and comment strings */ +char *rawText = NULL; +if (wikiPage->string) + { + /* XXXX is this response going to be language dependent ? */ + if (stringIn(WIKI_NO_TEXT_RESPONSE,wikiPage->string)) + return NULL; + rawText = dyStringCannibalize(&wikiPage); + } +freeDyString(&wikiPage); + +return rawText; +} + +char *fetchWikiRenderedText(char *descriptionKey) +/* fetch page from wiki in rendered form, strip it of edit URLs, + * html comments, and test for actual proper return. + * returned string can be freed after use */ +{ +char wikiPageUrl[512]; +safef(wikiPageUrl, sizeof(wikiPageUrl), "%s/index.php/%s?action=render", + cfgOptionDefault(CFG_WIKI_URL, NULL), descriptionKey); +struct lineFile *lf = netLineFileMayOpen(wikiPageUrl); + +struct dyString *wikiPage = newDyString(1024); +if (lf) + { + char *line; + int lineSize; + while (lineFileNext(lf, &line, &lineSize)) + dyStringPrintf(wikiPage, "%s\n", line); + lineFileClose(&lf); + } + +/* test for text, remove any edit sections and comment strings */ +char *strippedRender = NULL; +if (wikiPage->string) + strippedRender = stripEditURLs(wikiPage->string); +freeDyString(&wikiPage); + +return strippedRender; +} + +char *adjustWikiUrls (char *comments) +/* change relative to full urls for images */ +{ +char *com; +char buf[128]; +char *url = cfgOptionDefault(CFG_WIKI_URL, NULL); +safef(buf, sizeof(buf), "img src=\"%s/images", url); +com = replaceChars(comments, "img src=\"/images", buf); +return com; +} + +void displayComments(struct wikiTrack *item) +/* display the rendered comments for this item */ +{ +char *url = cfgOptionDefault(CFG_WIKI_URL, NULL); + +hPrintf("Description and comments from the wiki article " + "%s:
\n", + url, item->descriptionKey, item->descriptionKey); + +/* the nbsp is displayed if the browser does not honor the frame tag */ +hPrintf("

\n