def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) if args.parent_project_path is not None: project_path = Server.get_project_by_name_and_parent_path( logger, server, None, args.parent_project_path) else: project_path = None try: project = PublishSamplesCommand.get_project_by_name_and_parent_path( logger, server, args.project_name, project_path) except Exception as e: Errors.exit_with_error( logger, _("tabcmd.report.error.publish_samples.expected_project"), exception=e) try: server.projects.update(project, samples=True) except Exception as e: Errors.exit_with_error(logger, _("tabcmd.result.failure.publish_samples"), exception=e)
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) new_site = TSC.SiteItem( name=args.site_name, content_url=args.url, admin_mode=args.admin_mode, user_quota=args.user_quota, storage_quota=args.storage_quota, ) try: logger.info(_("createsite.status").format(args.site_name)) server.sites.create(new_site) logger.info(_("common.output.succeeded")) except TSC.ServerResponseError as e: if Errors.is_resource_conflict(e): if args.continue_if_exists: logger.info( _("createsite.errors.site_name_already_exists").format( args.site_name)) return else: Errors.exit_with_error( logger, _("createsite.errors.site_name_already_exists").format( args.site_name)) Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response"), e)
def validate_file_for_import(csv_file: io.TextIOWrapper, logger, detailed=False, strict=False) -> int: num_errors = 0 num_valid_lines = 0 csv_file.seek( 0) # set to start of file in case it has been read earlier line: str = csv_file.readline() while line and line != "": try: printable_line = line if detailed: # do not print passwords printable_line = line.split(",")[0] UserCommand._validate_user_or_throw(line, logger) else: logger.debug("> username - {}".format(line)) UserCommand._validate_username_or_throw(line) num_valid_lines += 1 except Exception as exc: logger.info( _("importcsvsummary.error.line").format( printable_line, exc, "")) num_errors += 1 line = csv_file.readline() if strict and num_errors > 0: Errors.exit_with_error(logger, _("importcsvsummary.error.too_many_errors")) return num_valid_lines
def _sign_in(self, tableau_auth): self.logger.debug(_("session.login") + self.server_url) self.logger.debug( _("listsites.output").format("", self.username or self.token_name, self.site_name)) try: self.tableau_server.auth.sign_in( tableau_auth) # it's the same call for token or user-pass except TSC.ServerResponseError as e: Errors.exit_with_error(self.logger, exception=e) try: self.site_id = self.tableau_server.site_id self.user_id = self.tableau_server.user_id self.auth_token = self.tableau_server._auth_token if not self.username: self.username = self.tableau_server.users.get_by_id( self.user_id).name self.logger.debug("Signed into {0}{1} as {2}".format( self.server_url, self.site_name, self.username)) self.logger.info(_("common.output.succeeded")) except TSC.ServerResponseError as e: Errors.exit_with_error( self.logger, _("publish.errors.unexpected_server_response"), e) return self.tableau_server
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) logger.info(_("delete.status").format(args.name, "")) error = None try: item_to_delete = DeleteCommand.get_workbook_item( logger, server, args.name) item_type = "workbook" except TSC.ServerResponseError as workbook_error: error = workbook_error try: item_to_delete = DeleteCommand.get_data_source_item( logger, server, args.name) item_type = "datasource" except TSC.ServerResponseError as ds_error: error = ds_error if not item_type: logger.debug(error) Errors.exit_with_error( logger, _("delete.errors.requires_workbook_datasource")) try: if item_type == "workbook": server.workbooks.delete(item_to_delete.id) else: server.datasources.delete(item_to_delete.id) logger.info(_("common.output.succeeded")) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, "Error deleting from server", e)
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) if args.parent_project_path: logger.debug("parent path: {}".format(args.parent_project_path)) try: logger.debug( _("deleteproject.status").format(args.parent_project_path, args.project_name)) project = Server.get_project_by_name_and_parent_path( logger, server, args.project_name, args.parent_project_path) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response"), e) project_id = project.id try: logger.info(_("deleteproject.status").format(args.project_name)) server.projects.delete(project_id) logger.info(_("common.output.succeeded")) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, "tabcmd.result.failure.delete.project", e)
def get_workbook_item(logger, server, workbook_name, container=None): try: return Server.get_items_by_name(logger, server.workbooks, workbook_name, container=None)[0] except Exception as e: Errors.exit_with_error(logger, exception=e)
def get_data_source_item(logger, server, data_source_name, container=None): try: return Server.get_items_by_name(logger, server.datasources, data_source_name, container=None)[0] except Exception as e: Errors.exit_with_error(logger, exception=e)
def act_on_users(logger: logging.Logger, server: object, action_name: str, server_method: Callable, args: argparse.Namespace) -> None: n_users_handled: int = 0 number_of_errors: int = 0 n_users_listed: int = UserCommand.validate_file_for_import( args.users, logger, strict=args.require_all_valid) logger.debug( _("importcsvsummary.line.processed").format(n_users_listed)) group = None try: group = UserCommand.find_group(logger, server, args.name) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("errors.reportable.impersonation.group_not_found").format( args.name), exception=e) error_list = [] user_obj_list: List[TSC.UserItem] = UserCommand.get_users_from_file( args.users) logger.debug( _("tabcmd.result.success.parsed_users").format(len(user_obj_list))) for user_obj in user_obj_list: username: str = user_obj.name or "unknown user" try: user_id: str = UserCommand.find_user_id( logger, server, username) logger.debug("{} user {} ({})".format(action_name, username, user_id)) except TSC.ServerResponseError as e: Errors.check_common_error_codes_and_explain(logger, e) number_of_errors += 1 error_list.append(e) logger.debug(_("tabcmd.result.failure.user").format(username)) continue try: server_method(group, user_id) n_users_handled += 1 logger.info( _("tabcmd.result.success.user_actions").format( action_name, username, group)) except TSC.ServerResponseError as e: Errors.check_common_error_codes_and_explain(logger, e) number_of_errors += 1 error_list.append(e) logger.info(_("session.monitorjob.percent_complete").format(100)) logger.info( _("importcsvsummary.errors.count").format(number_of_errors)) if number_of_errors > 0: logger.info(_("importcsvsummary.error.details").format(error_list))
def evaluate_content_type(logger, url): # specify a view to get using "/views/<workbookname>/<viewname>.<extension>" # specify a workbook to get using "/workbooks/<workbookname>.<extension>". if url.find("/views/") == 0: return "view" elif url.find("/workbooks/") == 0: return "workbook" else: Errors.exit_with_error( logger, message=_("export.errors.requires_workbook_view_param").format( GetUrl.name))
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) try: logger.info(_("tabcmd.find.group").format(args.name)) group_id = Server.find_group_id(logger, server, args.name) logger.info(_("deletegroup.status").format(group_id)) server.groups.delete(group_id) logger.info(_("tabcmd.result.succeeded")) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, "tabcmd.result.failed.delete.group", e)
def get_site_for_command_or_throw(logger, server, args): if args.site_name: try: site_item = Server.get_items_by_name(logger, server.sites, args.site_name)[0] except Exception as e: Errors.exit_with_error(logger, exception=e) else: logger.debug("Use logged in site") # site_item = server.sites.get_by_id(server.site_id) if not site_item: raise ResourceWarning("Could not get site from server") return site_item
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) logger.info(_("export.status").format(args.schedule)) schedule = DatasourcesAndWorkbooks.get_items_by_name( logger, server.schedules, args.schedule)[0] if not schedule: Errors.exit_with_error( logger, _("publish.errors.server_resource_not_found")) logger.info(_("runschedule.status")) Errors.exit_with_error(logger, "Not yet implemented")
def parse_export_url_to_workbook_and_view(logger, url): logger.info(_("export.status").format(url)) if " " in url: Errors.exit_with_error(logger, _("export.errors.white_space_workbook_view")) # input should be workbook_name/view_name if not url.find("/"): return None, None name_parts = url.split("/") if len(name_parts) != 2: return None, None workbook = name_parts[0] view = "{}/sheets/{}".format(workbook, name_parts[1]) return view, workbook
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) site_id = server.sites.get_by_name(args.site_name) if site_id == session.site_id: Errors.exit_with_error( logger, "Cannot delete the site you are logged in to") try: server.sites.delete(site_id) logger.info("Successfully deleted the site") except TSC.ServerResponseError as e: Errors.exit_with_error(logger, "Error deleting site", e)
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) site_item = Server.get_site_for_command_or_throw(logger, server, args) try: logger.info(_("reencryptextracts.status").format(site_item.name)) job = server.sites.encrypt_extracts(site_item.id) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, e) logger.info(_("common.output.job_queued_success")) logger.debug("Extract re-encryption queued with JobID: {}".format(job.id))
def create_session(self, args): signed_in_object = None # pull out cached info from json, then overwrite with new args if available self._read_existing_state() self._update_session_data(args) self.logging_level = args.logging_level or self.logging_level credentials = None if args.password: self._end_session() # we don't save the password anywhere, so we pass it along directly credentials = self._create_new_credential( args.password, Session.PASSWORD_CRED_TYPE) elif args.password_file: self._end_session() if args.username: credentials = self._create_new_credential( args.password, Session.PASSWORD_CRED_TYPE) else: credentials = self._create_new_credential( args.password, Session.TOKEN_CRED_TYPE) elif args.token: self._end_session() credentials = self._create_new_token_credential() else: # no login arguments given - look for saved info # maybe we're already signed in! if self.tableau_server: signed_in_object = self._validate_existing_signin() self.logger.debug(signed_in_object) # or maybe we at least have the credentials saved if not signed_in_object: credentials = self._get_saved_credentials() if credentials and not signed_in_object: # logging in, not using an existing session self._create_new_connection() signed_in_object = self._sign_in(credentials) if not signed_in_object: missing_var = _("editdomain.errors.requires_nickname_name").format( "username", "token") Errors.exit_with_error( self.logger, _("session.errors.missing_arguments").format(missing_var)) if args.no_cookie: self._remove_json() else: self._save_session_to_json() return signed_in_object
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) try: logger.info(_("creategroup.status").format(args.name)) new_group = TSC.GroupItem(args.name) server.groups.create(new_group) logger.info(_("tabcmd.result.succeeded")) except TSC.ServerResponseError as e: if args.continue_if_exists and Errors.is_resource_conflict(e): logger.info(_("tabcmd.result.already_exists.group").format(args.name)) return Errors.exit_with_error(logger, "tabcmd.result.failed.create_group")
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) try: sites, pagination = server.sites.get() logger.info(_("listsites.status").format(session.username)) for site in sites: print("NAME:", site.name) print("SITEID:", site.content_url) if args.get_extract_encryption_mode: print("EXTRACTENCRYPTION:", site.extract_encryption_mode) print("") except TSC.ServerResponseError as e: Errors.exit_with_error(logger, e)
def get_wb_by_content_url(logger, server, workbook_content_url) -> TSC.WorkbookItem: logger.debug(_("export.status").format(workbook_content_url)) try: req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter("contentUrl", TSC.RequestOptions.Operator.Equals, workbook_content_url)) matching_workbooks, paging = server.workbooks.get(req_option) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response").format("")) if len(matching_workbooks) < 1: Errors.exit_with_error( logger, message=_("dataalerts.failure.error.workbookNotFound")) return matching_workbooks[0]
def get_view_by_content_url(logger, server, view_content_url) -> TSC.ViewItem: logger.debug(_("export.status").format(view_content_url)) try: req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter("contentUrl", TSC.RequestOptions.Operator.Equals, view_content_url)) matching_views, paging = server.views.get(req_option) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response").format("")) if len(matching_views) < 1: Errors.exit_with_error(logger, message=_("errors.xmlapi.not_found")) return matching_views[0]
def get_file_type_from_filename(logger, file_name, url): type_of_file = None file_name = file_name or url logger.debug(_("get.options.file") + ": {}".format(file_name)) type_of_file = GetUrl.get_file_extension(file_name) if not type_of_file: Errors.exit_with_error( logger, _("tabcmd.get.extension.not_found").format(file_name)) else: logger.debug(_("get.options.file") + ": {}".format(type_of_file)) if type_of_file in ["pdf", "csv", "png", "twb", "twbx"]: return type_of_file Errors.exit_with_error( logger, _("tabcmd.get.extension.not_found").format(file_name))
def get_project_by_name_and_parent_path(logger, server, project_name, parent_path): logger.debug( _("content_type.project") + ":{0}, {1}".format(parent_path, project_name)) project_tree = Server._parse_project_path_to_list(parent_path) if not project_name: project = Server._get_parent_project_from_tree( logger, server, project_tree) else: parent = Server._get_parent_project_from_tree( logger, server, project_tree) project = Server._get_project_by_name_and_parent( logger, server, project_name, parent) if not project: Errors.exit_with_error( logger, message=_("publish.errors.server_resource_not_found")) return project
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) try: if args.datasource: logger.info(_("deleteextracts.for.datasource").format(args.datasource)) data_source_item = Server.get_data_source_item(logger, server, args.datasource) job = server.datasources.delete_extract(data_source_item) elif args.workbook: logger.info(_("deleteextracts.for.workbook_name").format(args.workbook)) workbook_item = Server.get_workbook_item(logger, server, args.workbook) job = server.workbooks.delete_extract(workbook_item) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, _("deleteextracts.errors.error"), e) logger.info(_("common.output.job_queued_success")) logger.debug("Extract deletion queued with JobID: {}".format(job.id))
def generate_csv(logger, server, args): view_url = GetUrl.get_view_url(args.url) try: view_item: TSC.ViewItem = GetUrl.get_view_by_content_url( logger, server, view_url) logger.debug( _("content_type.view") + ": {}".format(view_item.name)) req_option_csv = TSC.CSVRequestOptions(maxage=1) server.views.populate_csv(view_item, req_option_csv) file_name_with_path = GetUrl.filename_from_args( args.filename, view_item.name, "csv") with open(file_name_with_path, "wb") as f: f.write(view_item.csv) logger.info(_("export.success"), views_from_list.name, formatted_file_name) except TSC.ServerResponseError as e: GetUrl.exit_with_error( logger, _("publish.errors.unexpected_server_response"), e) except Exception as e: Errors.exit_with_error(logger, exception=e)
def _create_new_credential(self, password, credential_type): if password is None: if self.password_file: password = Session._read_password_from_file(self.password_file) elif self._allow_prompt(): password = getpass.getpass(_("session.password")) else: Errors.exit_with_error(self.logger, _("session.errors.script_no_password")) if credential_type == Session.PASSWORD_CRED_TYPE and self.username and password: credentials = TSC.TableauAuth(self.username, password, site_id=self.site_name) self.last_login_using = "username" return credentials elif credential_type == Session.TOKEN_CRED_TYPE and self.token_name: credentials = self._create_new_token_credential() return credentials else: Errors.exit_with_error(self.logger, "Couldn't find credentials")
def run_command(args): # A view can be returned in PDF, PNG, or CSV (summary data only) format. # A Tableau workbook is returned as a TWB if it connects to a datasource/live connection, # or a TWBX if it uses an extract. logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) if " " in args.url: Errors.exit_with_error( logger, _("export.errors.white_space_workbook_view")) file_type = GetUrl.get_file_type_from_filename(logger, args.filename, args.url) content_type = GetUrl.evaluate_content_type(logger, args.url) if content_type == "workbook": if file_type == "twbx" or file_type == "twb": GetUrl.generate_twb(logger, server, args, file_type) else: Errors.exit_with_error( logger, message=_( "publish.errors.mutually_exclusive_option").format( "twb", "twbx")) else: # content type = view if file_type == "pdf": GetUrl.generate_pdf(logger, server, args) elif file_type == "png": GetUrl.generate_png(logger, server, args) elif file_type == "csv": GetUrl.generate_csv(logger, server, args) else: Errors.exit_with_error( logger, message=_("tabcmd.get.extension.not_found"))
def _create_new_token_credential(self): if self.token: token = self.token elif self.password_file: token = Session._read_password_from_file(self.password_file) elif self._allow_prompt(): token = getpass.getpass("Token:") else: Errors.exit_with_error( self.logger, _("session.errors.missing_arguments").format("token")) if self.token_name and token: credentials = TSC.PersonalAccessTokenAuth(self.token_name, token, site_id=self.site_name) self.last_login_using = "token" return credentials else: Errors.exit_with_error( self.logger, _("session.errors.missing_arguments").format("token name"))
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) site_item = Server.get_site_for_command_or_throw(logger, server, args) if args.url: site_item.content_url = args.url if args.user_quota: site_item.user_quota = args.user_quota if args.storage_quota: site_item.storage_quota = args.storage_quota if args.status: site_item.state = args.status try: logger.info(_("editsite.status").format(site_item.name)) server.sites.update(site_item) logger.info(_("common.output.succeeded")) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response"), e)
def run_command(args): logger = log(__class__.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) session = Session() server = session.create_session(args) creation_call = None try: logger.debug( "Extract params: encrypt={}, include_all={}, datasources={}". format(args.encrypt, args.include_all, args.embedded_datasources)) if args.datasource: data_source_item = Server.get_data_source_item( logger, server, args.datasource) logger.info( _("createextracts.for.datasource").format(args.datasource)) job = server.datasources.create_extract(data_source_item, encrypt=args.encrypt) elif args.workbook: workbook_item = Server.get_workbook_item( logger, server, args.workbook) logger.info( _("createextracts.for.workbook_name").format( args.workbook)) job = server.workbooks.create_extract( workbook_item, encrypt=args.encrypt, includeAll=args.include_all, datasources=args.embedded_datasources, ) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, exception=e) logger.info(_("common.output.job_queued_success")) logger.debug("Extract creation queued with JobID: {}".format(job.id))