|
| 1 | +import os |
| 2 | + |
| 3 | +from uuid import UUID |
| 4 | + |
| 5 | +from tabcmd.commands.constants import Errors |
| 6 | +from tabcmd.commands.datasources_and_workbooks.datasources_and_workbooks_command import DatasourcesAndWorkbooks |
| 7 | +from tabcmd.commands.server import Server |
| 8 | +from tabcmd.execution.localize import _ |
| 9 | + |
| 10 | + |
| 11 | +class DatasourcesWorkbooksAndViewsUrlParser(Server): |
| 12 | + """ |
| 13 | + Base Class for parsing & fetching Datasources, Workbooks, Views & Custom Views information from get/export URLs |
| 14 | + """ |
| 15 | + |
| 16 | + def __init__(self, args): |
| 17 | + super().__init__(args) |
| 18 | + |
| 19 | + @staticmethod |
| 20 | + def get_view_url_from_names(wb_name, view_name): |
| 21 | + return "{}/sheets/{}".format(wb_name, view_name) |
| 22 | + |
| 23 | + @staticmethod |
| 24 | + def parse_export_url_to_workbook_view_and_custom_view(logger, url): |
| 25 | + # input should be workbook_name/view_name or /workbook_name/view_name |
| 26 | + # or workbook_name/view_name/custom_view_id/custom_view_name |
| 27 | + name_parts = DatasourcesWorkbooksAndViewsUrlParser.validate_and_extract_url_parts(logger, url) |
| 28 | + if len(name_parts) == 2: |
| 29 | + workbook = name_parts[0] |
| 30 | + view = DatasourcesWorkbooksAndViewsUrlParser.get_view_url_from_names(workbook, name_parts[1]) |
| 31 | + return view, workbook, None, None |
| 32 | + elif len(name_parts) == 4: |
| 33 | + workbook = name_parts[0] |
| 34 | + view = DatasourcesWorkbooksAndViewsUrlParser.get_view_url_from_names(workbook, name_parts[1]) |
| 35 | + custom_view_id = name_parts[2] |
| 36 | + DatasourcesWorkbooksAndViewsUrlParser.verify_valid_custom_view_id(logger, custom_view_id) |
| 37 | + custom_view_name = name_parts[3] |
| 38 | + return view, workbook, custom_view_id, custom_view_name |
| 39 | + else: |
| 40 | + return None, None, None, None |
| 41 | + |
| 42 | + @staticmethod |
| 43 | + def validate_and_extract_url_parts(logger, url): |
| 44 | + logger.info(_("export.status").format(url)) |
| 45 | + if " " in url: |
| 46 | + Errors.exit_with_error(logger, _("export.errors.white_space_workbook_view")) |
| 47 | + if "?" in url: |
| 48 | + url = url.split("?")[0] |
| 49 | + url = url.lstrip("/") # strip opening / if present |
| 50 | + return url.split("/") |
| 51 | + |
| 52 | + @staticmethod |
| 53 | + def get_export_item_and_server_content_type_from_export_url(view_content_url, logger, server, custom_view_id): |
| 54 | + return DatasourcesWorkbooksAndViewsUrlParser.get_content_and_server_content_type_from_url( |
| 55 | + logger, server, view_content_url, custom_view_id |
| 56 | + ) |
| 57 | + |
| 58 | + ################### GetURL Methods ############################## |
| 59 | + |
| 60 | + @staticmethod |
| 61 | + def explain_expected_get_url(logger, url: str, command: str): |
| 62 | + view_example = "/views/<workbookname>/<viewname>[.ext]" |
| 63 | + custom_view_example = "/views/<workbookname>/<viewname>/<customviewid>/<customviewname>[.ext]" |
| 64 | + wb_example = "/workbooks/<workbookname>[.ext]" |
| 65 | + ds_example = "/datasources/<datasourcename[.ext]" |
| 66 | + message = _("export.errors.requires_workbook_view_param").format( |
| 67 | + command |
| 68 | + ) + "Given: {0}. Accepted values: {1}, {2}, {3}, {4}".format( |
| 69 | + url, view_example, custom_view_example, wb_example, ds_example |
| 70 | + ) |
| 71 | + Errors.exit_with_error(logger, message) |
| 72 | + |
| 73 | + @staticmethod |
| 74 | + def get_file_type_from_filename(logger, url, file_name): |
| 75 | + logger.debug("Choosing between {}, {}".format(file_name, url)) |
| 76 | + file_name = file_name or url |
| 77 | + logger.debug(_("get.options.file") + ": {}".format(file_name)) # Name to save the file as |
| 78 | + type_of_file = DatasourcesWorkbooksAndViewsUrlParser.get_file_extension(file_name) |
| 79 | + |
| 80 | + if not type_of_file and file_name is not None: |
| 81 | + # check the url |
| 82 | + backup = DatasourcesWorkbooksAndViewsUrlParser.get_file_extension(url) |
| 83 | + if backup is not None: |
| 84 | + type_of_file = backup |
| 85 | + else: |
| 86 | + Errors.exit_with_error(logger, _("get.extension.not_found").format(file_name)) |
| 87 | + |
| 88 | + logger.debug("filetype: {}".format(type_of_file)) |
| 89 | + if type_of_file in ["pdf", "csv", "png", "twb", "twbx", "tdsx", "tds"]: |
| 90 | + return type_of_file |
| 91 | + |
| 92 | + Errors.exit_with_error(logger, _("get.extension.not_found").format(file_name)) |
| 93 | + |
| 94 | + @staticmethod |
| 95 | + def get_file_extension(path): |
| 96 | + path_segments = os.path.split(path) |
| 97 | + filename = path_segments[-1] |
| 98 | + filename_segments = filename.split(".") |
| 99 | + extension = filename_segments[-1] |
| 100 | + extension = DatasourcesWorkbooksAndViewsUrlParser.strip_query_params(extension) |
| 101 | + return extension |
| 102 | + |
| 103 | + @staticmethod |
| 104 | + def strip_query_params(filename): |
| 105 | + if "?" in filename: |
| 106 | + return filename.split("?")[0] |
| 107 | + else: |
| 108 | + return filename |
| 109 | + |
| 110 | + @staticmethod |
| 111 | + def get_name_without_possible_extension(filename): |
| 112 | + return filename.split(".")[0] |
| 113 | + |
| 114 | + @staticmethod |
| 115 | + def get_resource_name(url: str, logger): # workbooks/wb-name" -> "wb-name", datasource/ds-name -> ds-name |
| 116 | + url = url.lstrip("/") # strip opening / if present |
| 117 | + name_parts = url.split("/") |
| 118 | + if len(name_parts) != 2: |
| 119 | + DatasourcesWorkbooksAndViewsUrlParser.explain_expected_get_url(logger, url, "GetUrl") |
| 120 | + resource_name_with_params = name_parts[::-1][0] # last part |
| 121 | + resource_name_with_ext = DatasourcesWorkbooksAndViewsUrlParser.strip_query_params(resource_name_with_params) |
| 122 | + resource_name = DatasourcesWorkbooksAndViewsUrlParser.get_name_without_possible_extension( |
| 123 | + resource_name_with_ext |
| 124 | + ) |
| 125 | + return resource_name |
| 126 | + |
| 127 | + @staticmethod |
| 128 | + def get_view_url_from_get_url(logger, url): # "views/wb-name/view-name" -> wb-name/sheets/view-name |
| 129 | + name_parts = url.split("/") # ['views', 'wb-name', 'view-name'] |
| 130 | + if len(name_parts) != 3: |
| 131 | + DatasourcesWorkbooksAndViewsUrlParser.explain_expected_get_url(logger, url, "GetUrl") |
| 132 | + workbook_name = name_parts[1] |
| 133 | + view_name = name_parts[::-1][0] |
| 134 | + view_name = DatasourcesWorkbooksAndViewsUrlParser.strip_query_params(view_name) |
| 135 | + view_name = DatasourcesWorkbooksAndViewsUrlParser.get_name_without_possible_extension(view_name) |
| 136 | + return DatasourcesWorkbooksAndViewsUrlParser.get_view_url_from_names(workbook_name, view_name) |
| 137 | + |
| 138 | + @staticmethod |
| 139 | + def get_custom_view_parts_from_get_url(logger, url): |
| 140 | + name_parts = url.split("/") # ['views', 'wb-name', 'view-name', 'custom-view-id', 'custom-view-name'] |
| 141 | + if len(name_parts) != 5: |
| 142 | + DatasourcesWorkbooksAndViewsUrlParser.explain_expected_get_url(logger, url, "GetUrl") |
| 143 | + workbook_name = name_parts[1] |
| 144 | + view_name = name_parts[2] |
| 145 | + custom_view_id = name_parts[3] |
| 146 | + DatasourcesWorkbooksAndViewsUrlParser.verify_valid_custom_view_id(logger, custom_view_id) |
| 147 | + custom_view_name = name_parts[::-1][0] |
| 148 | + custom_view_name = DatasourcesWorkbooksAndViewsUrlParser.strip_query_params(custom_view_name) |
| 149 | + custom_view_name = DatasourcesWorkbooksAndViewsUrlParser.get_name_without_possible_extension(custom_view_name) |
| 150 | + return ( |
| 151 | + DatasourcesWorkbooksAndViewsUrlParser.get_view_url_from_names(workbook_name, view_name), |
| 152 | + custom_view_id, |
| 153 | + custom_view_name, |
| 154 | + ) |
| 155 | + |
| 156 | + @staticmethod |
| 157 | + def parse_get_view_url_to_view_and_custom_view_parts(logger, url): |
| 158 | + # input should be views/workbook_name/view_name |
| 159 | + # or views/workbook_name/view_name/custom_view_id/custom_view_name |
| 160 | + name_parts = DatasourcesWorkbooksAndViewsUrlParser.validate_and_extract_url_parts(logger, url) |
| 161 | + if len(name_parts) == 3: |
| 162 | + return DatasourcesWorkbooksAndViewsUrlParser.get_view_url_from_get_url(logger, url), None, None |
| 163 | + elif len(name_parts) == 5: |
| 164 | + return DatasourcesWorkbooksAndViewsUrlParser.get_custom_view_parts_from_get_url(logger, url) |
| 165 | + else: |
| 166 | + DatasourcesWorkbooksAndViewsUrlParser.explain_expected_get_url(logger, url, "GetUrl") |
| 167 | + |
| 168 | + @staticmethod |
| 169 | + def get_url_item_and_item_type_from_view_url(logger, url, server): |
| 170 | + ( |
| 171 | + view_url, |
| 172 | + custom_view_id, |
| 173 | + custom_view_name, |
| 174 | + ) = DatasourcesWorkbooksAndViewsUrlParser.parse_get_view_url_to_view_and_custom_view_parts(logger, url) |
| 175 | + |
| 176 | + return DatasourcesWorkbooksAndViewsUrlParser.get_content_and_server_content_type_from_url( |
| 177 | + logger, server, view_url, custom_view_id |
| 178 | + ) |
| 179 | + |
| 180 | + @staticmethod |
| 181 | + def get_content_and_server_content_type_from_url(logger, server, view_content_url, custom_view_id): |
| 182 | + item = DatasourcesAndWorkbooks.get_view_by_content_url(logger, server, view_content_url) |
| 183 | + server_content_type = server.views |
| 184 | + |
| 185 | + if custom_view_id: |
| 186 | + custom_view_item = DatasourcesAndWorkbooks.get_custom_view_by_id(logger, server, custom_view_id) |
| 187 | + if custom_view_item.view.id != item.id: |
| 188 | + Errors.exit_with_error(logger, "Invalid custom view URL provided") |
| 189 | + server_content_type = server.custom_views |
| 190 | + item = custom_view_item |
| 191 | + return item, server_content_type |
| 192 | + |
| 193 | + @staticmethod |
| 194 | + def verify_valid_custom_view_id(logger, custom_view_id): |
| 195 | + try: |
| 196 | + UUID(custom_view_id) |
| 197 | + except ValueError: |
| 198 | + Errors.exit_with_error(logger, _("export.errors.requires_valid_custom_view_uuid")) |
0 commit comments