static void writeFindPositionInfo(struct jsonWrite *jw, char *db, int taxId, char *hubUrl, char *position) /* Write JSON for the info needed to populate the 'Find Position' section. */ { char *genome = hGenome(db); if (isEmpty(genome)) { jsonWriteStringf(jw, "error", "No genome for db '%s'", db); } else { jsonWriteString(jw, "db", db); jsonWriteNumber(jw, "taxId", taxId); jsonWriteString(jw, "genome", genome); struct slPair *dbOptions = NULL; char genomeLabel[PATH_LEN*4]; if (isNotEmpty(hubUrl)) { struct trackHub *hub = hubConnectGetHub(hubUrl); if (hub == NULL) { jsonWriteStringf(jw, "error", "Can't connect to hub at '%s'", hubUrl); return; } struct dbDb *dbDbList = trackHubGetDbDbs(hub->name); dbOptions = trackHubDbDbToValueLabel(dbDbList); safecpy(genomeLabel, sizeof(genomeLabel), hub->shortLabel); jsonWriteString(jw, "hubUrl", hubUrl); } else { dbOptions = hGetDbOptionsForGenome(genome); safecpy(genomeLabel, sizeof(genomeLabel), genome); } jsonWriteValueLabelList(jw, "dbOptions", dbOptions); jsonWriteString(jw, "genomeLabel", genomeLabel); jsonWriteString(jw, "position", position); char *suggestTrack = NULL; if (! trackHubDatabase(db)) suggestTrack = assemblyGeneSuggestTrack(db); jsonWriteString(jw, "suggestTrack", suggestTrack); char *description = maybeGetDescriptionText(db); //#*** TODO: move jsonStringEscape inside jsonWriteString char *encoded = jsonStringEscape(description); jsonWriteString(jw, "description", encoded); listAssemblyHubs(jw); } }
char *cartJsonRequiredParam(struct hash *paramHash, char *name, struct jsonWrite *jw, char *context) /* Convenience function for a CartJsonHandler function: Look up name in paramHash. * If found, return the string contained in its jsonElement value. * If not, write an error message (using context) and return NULL. */ { char *param = cartJsonOptionalParam(paramHash, name); if (param == NULL) jsonWriteStringf(jw, "error", "%s: required param %s is missing", context, name); return param; }
static void setHubDb(struct cartJson *cj, struct hash *paramHash) /* Set db and genome according to hubUrl (and/or db and hub) and return the info we'll need * to fill in the findPosition section. */ { char *hubUrl = cartJsonRequiredParam(paramHash, "hubUrl", cj->jw, "setHubDb"); char *taxIdStr = cartJsonOptionalParam(paramHash, "taxId"); int taxId = taxIdStr ? atoi(taxIdStr) : -1; // cart's db was already set by magic handling of hub CGI variables sent along // with this command. char *db = cartString(cart, "db"); if (isEmpty(db)) jsonWriteStringf(cj->jw, "error", "No db for hubUrl '%s'", hubUrl); else writeFindPositionInfo(cj->jw, db, taxId, hubUrl, hDefaultPos(db)); }
static void doOneCommand(struct cartJson *cj, char *command, struct jsonElement *paramObject) /* Dispatch command by name, checking for required parameters. */ { CartJsonHandler *handler = hashFindVal(cj->handlerHash, command); if (handler) { struct hash *paramHash = jsonObjectVal(paramObject, command); handler(cj, paramHash); } else { jsonWriteStringf(cj->jw, "error", "cartJson: unrecognized command '%s'\"", command); return; } }
static void setTaxId(struct cartJson *cj, struct hash *paramHash) /* Set db and genome according to taxId (and/or db) and return the info we'll need * to fill in the findPosition section. */ { char *taxIdStr = cartJsonRequiredParam(paramHash, "taxId", cj->jw, "setTaxId"); char *db = cartJsonOptionalParam(paramHash, "db"); int taxId = atoi(taxIdStr); if (isEmpty(db)) db = hDbForTaxon(taxId); if (isEmpty(db)) jsonWriteStringf(cj->jw, "error", "No db for taxId '%s'", taxIdStr); else { writeFindPositionInfo(cj->jw, db, taxId, NULL, hDefaultPos(db)); cartSetString(cart, "db", db); cartSetString(cart, "position", hDefaultPos(db)); } }
static void hgPositionsJson(struct jsonWrite *jw, char *db, struct hgPositions *hgp, struct cart *cart) /* Write out JSON description of multiple position matches. */ { struct hgPosTable *table; jsonWriteListStart(jw, "positionMatches"); struct trackDb *tdbList = NULL; for (table = hgp->tableList; table != NULL; table = table->next) { if (table->posList != NULL) { char *tableName = table->name; // clear the tdb cache if this track is a hub track if (isHubTrack(tableName)) tdbList = NULL; struct trackDb *tdb = tdbForTrack(db, tableName, &tdbList); if (!tdb && startsWith("all_", tableName)) tdb = tdbForTrack(db, tableName+strlen("all_"), &tdbList); if (!tdb) errAbort("no track for table \"%s\" found via a findSpec", tableName); char *trackName = tdb->track; jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, "name", table->name); jsonWriteString(jw, "trackName", trackName); jsonWriteString(jw, "description", table->description); jsonWriteString(jw, "vis", hCarefulTrackOpenVis(db, trackName)); jsonWriteListStart(jw, "matches"); struct hgPos *pos; for (pos = table->posList; pos != NULL; pos = pos->next) { char *encMatches = cgiEncode(pos->browserName); jsonWriteObjectStart(jw, NULL); // begin one match if (pos->chrom != NULL) jsonWriteStringf(jw, "position", "%s:%d-%d", pos->chrom, pos->chromStart+1, pos->chromEnd); else // GenBank results set position to GB accession instead of chr:s-e position. jsonWriteString(jw, "position", pos->name); // this is magic to tell the browser to make the // composite and this subTrack visible if (tdb->parent) { if (tdbIsSuperTrackChild(tdb)) jsonWriteStringf(jw, "extraSel", "%s=show&", tdb->parent->track); else { // tdb is a subtrack of a composite or a view jsonWriteStringf(jw, "extraSel", "%s_sel=1&%s_sel=1&", trackName, tdb->parent->track); } } jsonWriteString(jw, "hgFindMatches", encMatches); jsonWriteString(jw, "posName", htmlEncodeText(pos->name, FALSE)); if (pos->description) { stripString(pos->description, "\n"); jsonWriteString(jw, "description", stripAnchor(pos->description)); } jsonWriteObjectEnd(jw); // end one match } jsonWriteListEnd(jw); // end matches jsonWriteObjectEnd(jw); // end one table } } jsonWriteListEnd(jw); // end positionMatches }
static struct hgPositions *genomePosCJ(struct jsonWrite *jw, char *db, char *spec, char **retChromName, int *retWinStart, int *retWinEnd, struct cart *cart) /* Search for positions in genome that match user query. * Return an hgp unless there is a problem. hgp->singlePos will be set if a single * position matched. * Otherwise display list of positions, put # of positions in retWinStart, * and return NULL. */ { char *hgAppName = "cartJson"; struct hgPositions *hgp = NULL; char *chrom = NULL; int start = BIGNUM; int end = 0; char *terms[16]; int termCount = chopByChar(cloneString(spec), ';', terms, ArraySize(terms)); boolean multiTerm = (termCount > 1); int i = 0; for (i = 0; i < termCount; i++) { trimSpaces(terms[i]); if (isEmpty(terms[i])) continue; hgp = hgPositionsFind(db, terms[i], "", hgAppName, cart, multiTerm); if (hgp == NULL || hgp->posCount == 0) { jsonWriteStringf(jw, "error", "Sorry, couldn't locate %s in genome database", htmlEncode(terms[i])); if (multiTerm) jsonWriteStringf(jw, "error", "%s not uniquely determined -- can't do multi-position search.", terms[i]); *retWinStart = 0; return NULL; } if (hgp->singlePos != NULL) { if (chrom != NULL && !sameString(chrom, hgp->singlePos->chrom)) { jsonWriteStringf(jw, "error", "Sites occur on different chromosomes: %s, %s.", chrom, hgp->singlePos->chrom); return NULL; } chrom = hgp->singlePos->chrom; if (hgp->singlePos->chromStart < start) start = hgp->singlePos->chromStart; if (hgp->singlePos->chromEnd > end) end = hgp->singlePos->chromEnd; } else { hgPositionsJson(jw, db, hgp, cart); if (multiTerm && hgp->posCount != 1) { jsonWriteStringf(jw, "error", "%s not uniquely determined (%d locations) -- " "can't do multi-position search.", terms[i], hgp->posCount); return NULL; } break; } } if (hgp != NULL) { *retChromName = chrom; *retWinStart = start; *retWinEnd = end; } return hgp; }