From fe6b2245280aec3ed54e4d53476360516b19eb7e Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Thu, 15 Feb 2018 13:46:22 -0800 Subject: [PATCH 1/4] add export_wb sample for 'fullpdf' --- samples/export_wb.py | 100 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 samples/export_wb.py diff --git a/samples/export_wb.py b/samples/export_wb.py new file mode 100644 index 000000000..b085404fd --- /dev/null +++ b/samples/export_wb.py @@ -0,0 +1,100 @@ +# +# This sample uses the PyPDF2 library for combining pdfs together to get the full pdf for all the views in a +# workbook. +# +# You will need to do `pip install PyPDF2` to use this sample. +# + +import argparse +import getpass +import logging +import tempfile +import shutil +import functools +import os.path + +import tableauserverclient as TSC +try: + import PyPDF2 +except ImportError: + print('Please `pip install PyPDF2` to use this sample') + import sys + sys.exit(1) + + +def get_views_for_workbook(server, workbook_id): # -> Iterable of views + workbook = server.workbooks.get_by_id(workbook_id) + server.workbooks.populate_views(workbook) + return workbook.views + + +def download_pdf(server, views, tempdir, view_id): # -> Filename to downloaded pdf + logging.info("Exporting {}".format(view_id)) + view = next((x for x in views if x.id == view_id)) + destination_filename = os.path.join(tempdir, view_id) + server.views.populate_pdf(view) + with file(destination_filename, 'wb') as f: + f.write(view.pdf) + + return destination_filename + + +def combine_into(dest_pdf, filename): # -> None + dest_pdf.append(filename) + return dest_pdf + + +def cleanup(tempdir): + shutil.rmtree(tempdir) + + +def main(): + parser = argparse.ArgumentParser(description='Export to PDF all of the views in a workbook') + parser.add_argument('--server', '-s', required=True, help='server address') + parser.add_argument('--username', '-u', required=True, help='username to sign into server') + parser.add_argument('--site', '-S', default=None) + parser.add_argument('-p', default=None) + + parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', + help='desired logging level (set to error by default)') + parser.add_argument('--file', '-f', help='filename to store the exported data') + parser.add_argument('resource_id', help='LUID for the view') + + args = parser.parse_args() + + if args.p is None: + password = getpass.getpass("Password: ") + else: + password = args.p + + if args.file: + filename = args.file + else: + filename = 'out.pdf' + + # Set logging level based on user input, or error by default + logging_level = getattr(logging, args.logging_level.upper()) + logging.basicConfig(level=logging_level) + + tempdir = tempfile.mkdtemp('tsc') + logging.debug("Saving to tempdir: %s", tempdir) + + tableau_auth = TSC.TableauAuth(args.username, password, args.site) + server = TSC.Server(args.server, use_server_version=True) + try: + with server.auth.sign_in(tableau_auth): + views = list(TSC.Pager(server.views)) + get_list = functools.partial(get_views_for_workbook, server) + download = functools.partial(download_pdf, server, views, tempdir) + + view_list = (x.id for x in get_list(args.resource_id)) + downloaded = (download(x) for x in view_list) + output = reduce(combine_into, downloaded, PyPDF2.PdfFileMerger()) + with file(filename, 'wb') as f: + output.write(f) + finally: + cleanup(tempdir) + + +if __name__ == '__main__': + main() From a4d701894b8ab3d95004374211cc2c3d00834bb6 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Thu, 15 Feb 2018 14:14:18 -0800 Subject: [PATCH 2/4] Addressing code review feedback from Lee --- samples/export_wb.py | 21 ++++++++------------- samples/list.py | 8 ++++---- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/samples/export_wb.py b/samples/export_wb.py index b085404fd..8a97a6421 100644 --- a/samples/export_wb.py +++ b/samples/export_wb.py @@ -51,26 +51,21 @@ def cleanup(tempdir): def main(): parser = argparse.ArgumentParser(description='Export to PDF all of the views in a workbook') parser.add_argument('--server', '-s', required=True, help='server address') + parser.add_argument('--site', '-S', default=None, help='Site to log into, do not specify for default site') parser.add_argument('--username', '-u', required=True, help='username to sign into server') - parser.add_argument('--site', '-S', default=None) - parser.add_argument('-p', default=None) - + parser.add_argument('--password', '-p', default=None, help='password for the user') + parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', help='desired logging level (set to error by default)') - parser.add_argument('--file', '-f', help='filename to store the exported data') - parser.add_argument('resource_id', help='LUID for the view') + parser.add_argument('--file', '-f', default='out.pdf', help='filename to store the exported data') + parser.add_argument('resource_id', help='LUID for the workbook') args = parser.parse_args() - if args.p is None: + if args.password is None: password = getpass.getpass("Password: ") else: - password = args.p - - if args.file: - filename = args.file - else: - filename = 'out.pdf' + password = args.password # Set logging level based on user input, or error by default logging_level = getattr(logging, args.logging_level.upper()) @@ -90,7 +85,7 @@ def main(): view_list = (x.id for x in get_list(args.resource_id)) downloaded = (download(x) for x in view_list) output = reduce(combine_into, downloaded, PyPDF2.PdfFileMerger()) - with file(filename, 'wb') as f: + with file(args.file, 'wb') as f: output.write(f) finally: cleanup(tempdir) diff --git a/samples/list.py b/samples/list.py index ec2ff9a6b..06624e14f 100644 --- a/samples/list.py +++ b/samples/list.py @@ -14,9 +14,9 @@ def main(): parser = argparse.ArgumentParser(description='Get all of the refresh tasks available on a server') parser.add_argument('--server', '-s', required=True, help='server address') + parser.add_argument('--site', '-S', default=None, help='site to log into, do not specify for default site') parser.add_argument('--username', '-u', required=True, help='username to sign into server') - parser.add_argument('--site', '-S', default=None) - parser.add_argument('-p', default=None) + parser.add_argument('--password', '-p', default=None, help='password for the user') parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', help='desired logging level (set to error by default)') @@ -25,10 +25,10 @@ def main(): args = parser.parse_args() - if args.p is None: + if args.password is None: password = getpass.getpass("Password: ") else: - password = args.p + password = args.password # Set logging level based on user input, or error by default logging_level = getattr(logging, args.logging_level.upper()) From 6e569616fb3c153f69bb7303faf8196ebfe0b556 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Thu, 15 Feb 2018 14:17:34 -0800 Subject: [PATCH 3/4] Fixing the dumb thing that I did where I was getting the view, then throwing it away and getting it again... --- samples/export_wb.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/samples/export_wb.py b/samples/export_wb.py index 8a97a6421..4bc47afb6 100644 --- a/samples/export_wb.py +++ b/samples/export_wb.py @@ -28,10 +28,9 @@ def get_views_for_workbook(server, workbook_id): # -> Iterable of views return workbook.views -def download_pdf(server, views, tempdir, view_id): # -> Filename to downloaded pdf - logging.info("Exporting {}".format(view_id)) - view = next((x for x in views if x.id == view_id)) - destination_filename = os.path.join(tempdir, view_id) +def download_pdf(server, tempdir, view): # -> Filename to downloaded pdf + logging.info("Exporting {}".format(view.id)) + destination_filename = os.path.join(tempdir, view.id) server.views.populate_pdf(view) with file(destination_filename, 'wb') as f: f.write(view.pdf) @@ -78,12 +77,10 @@ def main(): server = TSC.Server(args.server, use_server_version=True) try: with server.auth.sign_in(tableau_auth): - views = list(TSC.Pager(server.views)) get_list = functools.partial(get_views_for_workbook, server) - download = functools.partial(download_pdf, server, views, tempdir) + download = functools.partial(download_pdf, server, tempdir) - view_list = (x.id for x in get_list(args.resource_id)) - downloaded = (download(x) for x in view_list) + downloaded = (download(x) for x in get_list(args.resource_id)) output = reduce(combine_into, downloaded, PyPDF2.PdfFileMerger()) with file(args.file, 'wb') as f: output.write(f) From f4a660e7fab44c80b9963b299c38b1132ca35c4d Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Fri, 16 Feb 2018 08:40:28 -0800 Subject: [PATCH 4/4] pep8 error --- samples/export_wb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/export_wb.py b/samples/export_wb.py index 4bc47afb6..8d3640ab4 100644 --- a/samples/export_wb.py +++ b/samples/export_wb.py @@ -53,7 +53,7 @@ def main(): parser.add_argument('--site', '-S', default=None, help='Site to log into, do not specify for default site') parser.add_argument('--username', '-u', required=True, help='username to sign into server') parser.add_argument('--password', '-p', default=None, help='password for the user') - + parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', help='desired logging level (set to error by default)') parser.add_argument('--file', '-f', default='out.pdf', help='filename to store the exported data')