6743564c0d16d85e588d5a9d80097e4690b91666 max Tue Sep 29 15:37:43 2026 -0700 hgTracks: tell the user when a track download is incomplete or still being prepared, and put the GenBank size limit under hg.conf Four things in the "Download Current Track Data" dialog, all of them about a download that quietly does the wrong thing. The api stops at a limit on how many items it will return and says so with maxItemsLimit in the reply, which the dialog ignored. Worse, a truncated reply carries two extra top level fields, maxItemsLimit and dataDownloadUrl, and the CSV/TSV converter took every top level field it did not recognise for a track: the string one was iterated one character per row, and the conversion threw before writing anything. A truncated CSV or TSV download therefore produced no file and no message at all. A track's value is always the array of its rows, so that is now the test for what is a track, rather than a list of field names that the api will keep outgrowing. All formats now say plainly that the file is incomplete, and the GenBank file carries the same warning in its COMMENT block, where it outlives the dialog. Nothing showed that anything was happening between the click and the browser's download, which is one second for two tracks and four for twenty, on a 20 kb region. The Download button now goes disabled with a line beside it while the file is prepared. It is in the button pane rather than the dialog body because the body scrolls once the track list is long. The GenBank region limit drops from 100 Mbp to 25 Mbp. 50 Mbp of chr1 with 24 tracks answers with 340 MB of track json and 50 MB of sequence, which the web browser parses, copies into the file text and copies again into the Blob, so the tab needs several times the region in memory. The limit is now the hg.conf setting maxGenbankRegion, registered in hgConfCatalog.py as a knob: the ceiling belongs to the machine and its users. It is read only when showGenbankDownload is on, and a value that is not a positive number falls back to the default rather than aborting the CGI. refs #38433 diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 8bf9456ffae..38c1190060c 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -9133,31 +9133,42 @@ // Hand the JS dialog a login URL that returns to this hgTracks page. char *retUrl = wikiLinkEncodeReturnUrl(cartSessionId(cart), "hgTracks", ""); char *loginUrl = wikiLinkUserLoginUrlReturning(cartSessionId(cart), retUrl); jsInlineF("var myVariantsLoginUrl = \"%s\";\n", loginUrl); freez(&retUrl); freez(&loginUrl); } } // put the track download interface behind hg.conf control if (cfgOptionBooleanDefault("showDownloadUi", TRUE)) jsInline("var showDownloadButton = true;\n"); // remove the hg.conf option once this feature is released if (cfgOptionBooleanDefault("showGenbankDownload", FALSE)) + { jsInline("var showGenbankDownload = true;\n"); + // How much sequence the javascript will turn into a GenBank file, in bases. The + // file holds the whole region and is built in the web browser's memory, so the + // ceiling belongs to the machine and its users rather than to the code. Printed + // as a number, and a value that is not a positive one falls back to the default, + // so a typo in hg.conf cannot write broken javascript or refuse every region. + long long maxGbRegion = atoll(cfgOptionDefault("maxGenbankRegion", "25000000")); + if (maxGbRegion <= 0) + maxGbRegion = 25000000; + jsInlineF("var maxGenbankRegion = %lld;\n", maxGbRegion); + } // remove the hg.conf option once this feature is released if (cfgOptionBooleanDefault("showIgv", FALSE)) { puts(" <button id='hgtIgv' type='button' " "title='Add an IGV.js window below the UCSC Browser, to open files from " "your local harddisk or server' >Add IGV Tracks</button>"); //jsInline("document.getElementById('hgtIgv').addEventListener('click', onIgvClick);"); } } static void printAliases(char *nativeName, char *displayName) /* Print out the alternative names for this sequence next to the position. */ {