diff --git a/examples/filetable.py b/examples/filetable.py index 63e5734..34ae96f 100755 --- a/examples/filetable.py +++ b/examples/filetable.py @@ -1,13 +1,29 @@ #!/usr/bin/env python +from argparse import ArgumentParser, HelpFormatter import csv from glob import glob import os import tempfile +import textwrap import firefly_client -def filetable_to_firefly(ffclient, topdir, pattern, recursive=True): + +# From https://stackoverflow.com/a/64102901 +class RawFormatter(HelpFormatter): + def _fill_text(self, text, width, indent): + return "\n".join( + [ + textwrap.fill(line, width) + for line in textwrap.indent(textwrap.dedent(text), indent).splitlines() + ] + ) + + +def filetable_to_firefly( + ffclient, topdir, pattern, path_prefix="", recursive=True, sort=False +): """Upload table of files matching a pattern to a FireflyClient Parameters: @@ -15,80 +31,128 @@ def filetable_to_firefly(ffclient, topdir, pattern, recursive=True): ffclient: firefly_client.FireflyClient Instance of FireflyClient connected to a Firefly server - topdir: 'str' + topdir: "str" pathname for directory to search - pattern: 'str' - filename pattern to search for, e.g. '*.fits' + pattern: "str" + filename pattern to search for, e.g. "*.fits" + + path_prefix: "str" + string to prepend to each file path after "file://" + for example, specify "/external" for Firefly-in-Docker + (default="") recursive: `bool` Search all subdirectories recursively (default=True) + sort: `bool` + Sort the file paths (default=False) + Returns: -------- - tbl_val: 'str' + tbl_val: "str" Descriptor of table that was uploaded to the Firefly server metadict: `dict` Dictionary of metadata items """ - filelist = glob(topdir+'/**/' + pattern, recursive=recursive) - metadict = {'datasource': 'path'} - with tempfile.NamedTemporaryFile(mode='w+t', - delete=False, - suffix='.csv') as fd: + filelist = glob(topdir + "/**/" + pattern, recursive=recursive) + if sort: + filelist = sorted(filelist) + metadict = {"datasource": "path"} + with tempfile.NamedTemporaryFile(mode="w+t", delete=False, suffix=".csv") as fd: csv_writer = csv.writer(fd) - csv_writer.writerow(['number','name','path']) + csv_writer.writerow(["number", "name", "path"]) for i, path in enumerate(filelist): - csv_writer.writerow([i, os.path.basename(path), - 'file://'+path]) + # Docker Firefly allows uploads from /external + csv_writer.writerow( + [i, os.path.basename(path), "file://" + path_prefix + path] + ) tbl_val = ffclient.upload_file(fd.name) os.remove(fd.name) - return(tbl_val, metadict) + return (tbl_val, metadict) # Sample application def main(): - import argparse - parser = argparse.ArgumentParser(description=""" - Display a table of files in a Firefly window - """) - parser.add_argument('topdir', help='top-level directory to search') - parser.add_argument('pattern', help='filename pattern for search') - parser.add_argument('--norecursion', help='do not recursively search topdir', - action='store_true') - parser.add_argument('--host', help='host address for Firefly', - default='localhost') - parser.add_argument('--port', help='port for Firefly', default='8080') - parser.add_argument('--base', help='base.for Firefly', default='firefly') - parser.add_argument('--channel', help='channel name for websocket', - default=None) - parser.add_argument('--printurl', help='print browser url instead of' + - ' attempting to launch browser', action='store_true') + parser = ArgumentParser( + description=""" + Display a table of files in a Firefly window. + + Note that you must be running a Firefly server that is + local to the data. + """, + epilog=""" + If running Firefly via Docker, note that you can mount your + disk area onto /external. + + Sample command for running the Firefly server: + docker run -p 8090:8080 -e "MAX_JVM_SIZE=64G" \\ + -e "LOG_FILE_TO_CONSOLE=firefly.log" --rm --name ncmds_firefly \\ + -v /neoswork:/external/neoswork ipac/firefly:latest + """, + formatter_class=RawFormatter, + ) + parser.add_argument("topdir", help="top-level directory to search") + parser.add_argument("pattern", help="filename pattern for search") + parser.add_argument( + "--path_prefix", + help=textwrap.dedent( + """string to prepend to file paths, + e.g. specify '/external' for Firefly-in-Docker""" + ), + default="", + ) + parser.add_argument( + "--norecursion", help="do not recursively search topdir", action="store_true" + ) + parser.add_argument("--sort", help="sort the file paths", action="store_true") + parser.add_argument( + "--firefly_url", help="URL for Firefly server", default=os.getenv("FIREFLY_URL") + ) + parser.add_argument("--channel", help="channel name for websocket", default=None) + parser.add_argument( + "--printurl", + help="print browser url instead of" + " attempting to launch browser", + action="store_true", + ) args = parser.parse_args() topdir = args.topdir pattern = args.pattern - host = args.host - port = args.port - basedir = args.base + firefly_url = args.firefly_url channel = args.channel printurl = args.printurl + launch_browser = False if printurl else True recursion = not args.norecursion + sort = args.sort + path_prefix = args.path_prefix + + fc = firefly_client.FireflyClient.make_client( + url=firefly_url, + channel_override=channel, + html_file="slate.html", + launch_browser=launch_browser, + ) + if printurl: + print("Firefly URL is {}".format(fc.get_firefly_url())) + + print("Searching for files...", end="") + tbl_val, metainfo = filetable_to_firefly( + fc, topdir, pattern, path_prefix=path_prefix, recursive=recursion, sort=sort + ) + print("done.") - fc = FireflyClient.make_client(url='{}:{}'.format(host, port), channel_override=channel, html_file='slate.html') if printurl: - print('Firefly url is {}'.format(fc.get_firefly_url())) + input("Press Enter after you have opened the Firefly URL printed above...") - tbl_val, metainfo = filetable_to_firefly(fc, topdir, pattern, - recursive=recursion) - r = fc.add_cell(0, 0, 1, 2, 'tables', 'main') + r = fc.add_cell(0, 0, 1, 2, "tables", "main") fc.show_table(tbl_val, meta=metainfo) - r = fc.add_cell(0, 1, 1, 2, 'tableImageMeta', 'image-meta') - fc.show_image_metadata(viewer_id=r['cell_id']) + r = fc.add_cell(0, 1, 1, 2, "tableImageMeta", "image-meta") + fc.show_image_metadata(viewer_id=r["cell_id"]) -if __name__ == '__main__': - main() +if __name__ == "__main__": + main()