3b80c5be2a2d43f71277f8cd9274e3c49d9ad6c2
angie
  Mon Feb 24 16:54:33 2014 -0800
Improved error messages for bigData custom track common mistakes likemissing bigDataUrl setting or trying to upload a bigData file instead
of making a track line with a public URL.  I added a new "factory"
to customFactory.c that produces no tracks, only error messages about
directly uploaded bigData files.
refs #12747

diff --git src/hg/lib/customTrack.c src/hg/lib/customTrack.c
index 56801eb..d8cf923 100644
--- src/hg/lib/customTrack.c
+++ src/hg/lib/customTrack.c
@@ -646,30 +646,65 @@
     {
     safef(buf,sizeof(buf),"compressed://%s %s", fileName,  cFBin);
     /* cgi functions preserve binary data, cart vars have been
      *  cloneString-ed  which is bad for a binary stream that might
      * contain 0s  */
     }
 else
     {
     char *cF = cartOptionalString(cart, fileVar);
     safef(buf,sizeof(buf),"compressed://%s %lu %lu",
         fileName, (unsigned long) cF, (unsigned long) strlen(cF));
     }
 return cloneString(buf);
 }
 
+static boolean customTrackIsBigData(char *fileName)
+/* Return TRUE if fileName has a suffix that we recognize as a bigDataUrl track type. */
+{
+char *fileNameDecoded = cloneString(fileName);
+cgiDecode(fileName, fileNameDecoded, strlen(fileName));
+boolean result =
+    (endsWith(fileNameDecoded,".bb") ||
+     endsWith(fileNameDecoded,".bw")  ||
+     endsWith(fileNameDecoded,".bam") ||
+     endsWith(fileNameDecoded,".vcf.gz"));
+freeMem(fileNameDecoded);
+return result;
+}
+
+static char *prepBigData(struct cart *cart, char *fileName, char *binVar, char *fileVar)
+/* Pass data's memory offset and size through to customFactory */
+{
+if (!customTrackIsBigData(fileName))
+    return NULL;
+char buf[1024];
+char *cFBin = cartOptionalString(cart, binVar);
+if (cFBin)
+    {
+    // cFBin already contains memory offset and size (search for __binary in cheapcgi.c)
+    safef(buf,sizeof(buf),"memory://%s %s", fileName, cFBin);
+    }
+else
+    {
+    char *cF = cartOptionalString(cart, fileVar);
+    safef(buf, sizeof(buf),"memory://%s %lu %lu",
+	  fileName, (unsigned long) cF, (unsigned long) strlen(cF));
+    }
+return cloneString(buf);
+}
+
 boolean ctConfigUpdate(char *ctFile)
 /* CT update is needed if database has been enabled since
  * the custom tracks in this file were created.  The only way to check is
  * by file mod time, unless we add the enable time to
  * browser metadata somewhere */
 {
 if (!ctFile || !fileExists(ctFile))
     return FALSE;
 return cfgModTime() > fileModTime(ctFile);
 }
 
 struct customTrack *customTracksParseCartDetailed(char *genomeDb, struct cart *cart,
 					  struct slName **retBrowserLines,
 					  char **retCtFileName,
                                           struct customTrack **retReplacedCts,
@@ -706,35 +741,41 @@
 fileName = cartOptionalString(cart, CT_CUSTOM_FILE_NAME_VAR);
 char *fileContents = cartOptionalString(cart, CT_CUSTOM_FILE_VAR);
 if (isNotEmpty(fileName))
     {
     /* handle file input, optionally with compression */
     if (isNotEmpty(fileContents))
         customText = fileContents;
     else
         {
         /* file contents not available -- check for compressed */
         if (customTrackIsCompressed(fileName))
             {
             customText = prepCompressedFile(cart, fileName,
                                 CT_CUSTOM_FILE_BIN_VAR, CT_CUSTOM_FILE_VAR);
             }
+	else if (customTrackIsBigData(fileName))
+	    {
+	    // User is trying to directly upload a bigData file; pass data to
+	    // customFactory, which will alert the user that they need bigDataUrl etc.
+	    customText = prepBigData(cart, fileName, CT_CUSTOM_FILE_BIN_VAR, CT_CUSTOM_FILE_VAR);
+	    }
         else
             {
             /* unreadable file */
             struct dyString *ds = dyStringNew(0);
-            dyStringPrintf(ds, "Can't read file: %s", fileName);
+            dyStringPrintf(ds, "Unrecognized binary data format in file %s", fileName);
             err = dyStringCannibalize(&ds);
             }
 	}
     }
 customText = skipLeadingSpaces(customText);
 
 /* get track description from cart */
 char *html = NULL;
 char *docFileName = cartOptionalString(cart, CT_CUSTOM_DOC_FILE_NAME_VAR);
 char *docFileContents = cartOptionalString(cart, CT_CUSTOM_DOC_FILE_VAR);
 if (isNotEmpty(docFileContents))
     html = docFileContents;
 else if (isNotEmpty(docFileName))
     {
     if (customTrackIsCompressed(docFileName))