fc3472e7e9978eb81e3ac14e985bf27e5196ab73
kate
  Fri Jul 24 10:58:01 2020 -0700
Recommended track sets feature. refs #25601

diff --git src/hg/hgTracks/recTrackSets.c src/hg/hgTracks/recTrackSets.c
new file mode 100644
index 0000000..31b70d6
--- /dev/null
+++ src/hg/hgTracks/recTrackSets.c
@@ -0,0 +1,128 @@
+// Code to parse list of recommended track sets from file and print as browser dialog
+//      for client dialog (js)
+//
+/* Copyright (C) 2020 The Regents of the University of California 
+ * See README in this or parent directory for licensing information. */
+
+#include "common.h"
+#include "dystring.h"
+#include "hCommon.h"
+#include "htmshell.h"
+#include "hash.h"
+#include "web.h"
+#include "ra.h"
+#include "hgTracks.h"
+#include "hgFind.h"
+#include "obscure.h"
+#include "net.h"
+
+#define REC_TRACK_SETS_FILE  "inc/recommendedTrackSets.tab"
+
+/* Recommended track sets are Special 'curated' sessions, created by browser team, e.g. for clinical users
+ *      This is expected to be a very limited number (under 10 ?)
+ *      The list references sessions in namedSessionDb table, by userName and sessionName
+ *      (unfortunately not required to be unique, so depending on curator to 
+ *      just make one (code willl pick the first one)
+ */      
+struct recTrackSet
+    {
+    struct recTrackSet *next;
+    char *label;        // short label for display on browser and dialogs
+    char *db;           // should match db in settings field of named sessions table
+    char *userName;     // field in named sessions table
+    char *sessionName;  // field in named sessions table (CGI encoded)
+    char *description;  // descriptive phrase or sentence.  Display uses this
+                                // instead of description in session settings to allow
+                                // updating by other than session author (e.g. QA)
+    };
+
+char *recTrackSetsFile()
+/* Generate path to file specifying menu of recommended track sets */
+{
+char *root = hDocumentRoot();
+char buf[200];
+safef(buf, sizeof(buf), "%s/%s", root, REC_TRACK_SETS_FILE);
+return cloneString(buf);
+}
+
+boolean recTrackSetsEnabled()
+/* Return TRUE if feature is available */
+{
+return fileExists(recTrackSetsFile());
+}
+
+struct recTrackSet *loadRecTrackSets()
+/* Read from tab-sep file.  Return list */
+{
+struct recTrackSet *recTrackSet, *recTrackSets = NULL;
+struct lineFile *lf = lineFileOpen(recTrackSetsFile(), TRUE);
+#define cols 5
+char *row[cols];
+while (lineFileNextRowTab(lf, row, cols))
+    {
+    char *db = row[1];
+    // limit to sessions in current database
+    if (differentString(db, database))
+        continue;
+    AllocVar(recTrackSet);
+    recTrackSet->label = cloneString(row[0]);
+    recTrackSet->db = cloneString(row[1]);
+    recTrackSet->userName = cloneString(row[2]);
+    recTrackSet->sessionName = cloneString(row[3]);
+    recTrackSet->description = cloneString(row[4]);
+    slAddHead(&recTrackSets, recTrackSet);
+    }
+slReverse(&recTrackSets);
+lineFileClose(&lf);
+return recTrackSets;
+}
+
+int recTrackSetsForDb()
+/* Return number of recommended track sets for this database */
+{
+return slCount(loadRecTrackSets());
+}
+
+void printRecTrackSets()
+/* Create dialog with list of recommended track sets */
+{
+if (!recTrackSetsEnabled())
+    return;
+
+struct recTrackSet *recTrackSet, *recTrackSets = loadRecTrackSets();
+if (!recTrackSets)
+    return;
+
+hPrintf("<div style='display:none;' id='recTrackSetsPopup' title='Recommended Track Sets'>\n");
+
+// TODO: Consider moving this to the tab file as a header section
+hPrintf("<p>These links provide track sets selected and pre-configured for "
+            "specific user scenarios. They are designed to be useful at "
+            "different genomic loci. Clicking a link below will create a browser "
+            "window with these tracks visible, without changing the locus.</p>");
+
+hPrintf("<ul class='indent'>");
+for (recTrackSet = recTrackSets; recTrackSet != NULL; recTrackSet = recTrackSet->next)
+    {
+// TODO: consider libifying hgSession.c:add/getSessionLink() and using that
+    hPrintf("<li><a class='recTrackSetLink' href='./hgTracks?"
+                    "pix=%d&textSize=%s"  // preserve these user settings 
+                    "&hgS_otherUserName=%s"
+                    "&hgS_otherUserSessionName=%s"
+                    "&hgS_otherUserSessionLabel=%s"
+                    "&hgS_otherUserSessionDesc=%s"
+                    "&hgS_doOtherUser=submit"
+                    "&position="        // JS fills in position
+                    "'>" 
+                "%s</a>: <small>%s</small></li>",
+                    tl.picWidth, tl.textSize,
+                    recTrackSet->userName, recTrackSet->sessionName, 
+                    recTrackSet->label, recTrackSet->description, 
+                    recTrackSet->label, recTrackSet->description);
+    }
+hPrintf("</ul>");
+
+hPrintf("<p>Return to <a href='./hgTracks?hgt.reset=on'>Default</a> browser tracks</p>\n");
+hPrintf("</div>\n");
+}
+