Skip to content

Commit 73a739c

Browse files
authored
Merge pull request #294 from tableau/development
handle case sensitivity in import users handle spaces in filter parameters for export fix mac packaging error fix file handling in export command add proxy capability add options to extract commands
2 parents 19aabf5 + 8a42f75 commit 73a739c

26 files changed

+1232
-80
lines changed

.github/workflows/package.yml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,21 @@ jobs:
2828
pyinstaller tabcmd-windows.spec --clean --noconfirm --distpath ./dist/windows
2929
OUT_FILE_NAME: tabcmd.exe
3030
ASSET_MIME: application/vnd.microsoft.portable-executable
31+
- os: macos-13
32+
TARGET: macos
33+
CMD_BUILD: >
34+
pyinstaller tabcmd-mac.spec --clean --noconfirm --distpath ./dist/macos/
35+
BUNDLE_NAME: tabcmd.app
36+
OUT_FILE_NAME: tabcmd.app
37+
APP_BINARY_FILE_NAME: tabcmd
38+
ASSET_MIME: application/zip
3139
- os: macos-latest
3240
TARGET: macos
3341
CMD_BUILD: >
34-
pyinstaller tabcmd-mac.spec --clean --noconfirm --distpath ./dist/macos
42+
pyinstaller tabcmd-mac.spec --clean --noconfirm --distpath ./dist/macos/
43+
BUNDLE_NAME: tabcmd_arm64.app
3544
OUT_FILE_NAME: tabcmd.app
45+
APP_BINARY_FILE_NAME: tabcmd
3646
ASSET_MIME: application/zip
3747
- os: ubuntu-latest
3848
TARGET: ubuntu
@@ -64,9 +74,30 @@ jobs:
6474
run: ${{matrix.CMD_BUILD}}
6575

6676
- name: Validate package for ${{matrix.TARGET}}
77+
if: matrix.TARGET != 'macos'
6778
run: ./dist/${{ matrix.TARGET }}/${{matrix.OUT_FILE_NAME}}
6879

69-
- uses: actions/upload-artifact@v4
80+
- name: Validate package for Mac
81+
if: matrix.TARGET == 'macos'
82+
run: ./dist/${{ matrix.TARGET }}/${{ matrix.OUT_FILE_NAME }}/Contents/MacOS/${{ matrix.APP_BINARY_FILE_NAME }}
83+
84+
- name: Tar app bundle for Mac
85+
if: matrix.TARGET == 'macos'
86+
run: |
87+
rm -f dist/${{ matrix.TARGET }}/${{ matrix.APP_BINARY_FILE_NAME }}
88+
cd dist/${{ matrix.TARGET }}
89+
tar -cvf ${{ matrix.BUNDLE_NAME }}.tar ${{ matrix.OUT_FILE_NAME }}
90+
91+
- name: Upload artifact
92+
if: matrix.TARGET != 'macos'
93+
uses: actions/upload-artifact@v4
7094
with:
7195
name: ${{ matrix.OUT_FILE_NAME }}
7296
path: ./dist/${{ matrix.TARGET }}/${{ matrix.OUT_FILE_NAME }}
97+
98+
- name: Upload artifact for Mac
99+
if: matrix.TARGET == 'macos'
100+
uses: actions/upload-artifact@v4
101+
with:
102+
name: ${{ matrix.BUNDLE_NAME }}
103+
path: ./dist/${{ matrix.TARGET }}/${{ matrix.BUNDLE_NAME }}.tar

.gitignore

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# general dev/ide files
22
*.log
33
*.vscode
4-
*.csv
54
.idea
65
*.DS_Store
76

@@ -24,19 +23,20 @@ workon/
2423
.coverage
2524
pytest.xml
2625

26+
*.txt
2727
# content
2828
# todo probably want to add a workbook and ds in /res for getting started easily
2929
*.pdf
3030
*.png
31-
*.twbx
32-
*.hyper
33-
*.twb
34-
*.twbr
35-
html
3631
*.html
37-
*.twbr
32+
# *.twbx
33+
# *.hyper
34+
# *.twb
35+
# *.twbr
36+
# *.tdsx
3837
**/credentials.py
39-
*.txt
38+
# exceptions
39+
!tests/assets/
4040

4141
# doit
4242
.doit.*
@@ -48,7 +48,3 @@ site-packages
4848
tabcmd-dev
4949
workon
5050
test.junit.xml
51-
52-
# exceptions
53-
!tests/assets/detailed_users.csv
54-
est

World Indicators.tdsx

-3.95 KB
Binary file not shown.

WorldIndicators.tdsx

-157 KB
Binary file not shown.

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ packages = ["tabcmd"]
99
tabcmd = ["tabcmd.locales/**/*.mo"]
1010
[tool.black]
1111
line-length = 120
12+
required-version = 22
1213
target-version = ['py38', 'py39', 'py310', 'py311']
1314
extend-exclude = '^/bin/*'
1415
[tool.mypy]
@@ -40,7 +41,6 @@ classifiers = [
4041
"Programming Language :: Python :: 3.11"
4142
]
4243
dependencies = [
43-
'argparse',
4444
"appdirs",
4545
"doit",
4646
"ftfy",
@@ -52,8 +52,8 @@ dependencies = [
5252
"types-mock",
5353
"types-requests",
5454
"types-setuptools",
55-
"tableauserverclient==0.25",
56-
"urllib3>=1.24.3,<2.0",
55+
"tableauserverclient==0.31",
56+
"urllib3",
5757
]
5858
[project.optional-dependencies]
5959
test = [

tabcmd-mac.spec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ exe = EXE(
3232
a.zipfiles,
3333
a.datas,
3434
[],
35-
name='tabcmd.app',
35+
name='tabcmd',
3636
debug=False,
3737
bootloader_ignore_signals=False,
3838
strip=False,
3939
upx=True,
4040
runtime_tmpdir=None,
4141
console=True,
4242
codesign_identity=None,
43-
version='program_metadata.txt',
43+
version='program_metadata.txt'
4444
)
4545

4646
app = BUNDLE(
4747
exe,
48-
name = 'tabcmd-app',
48+
name = 'tabcmd.app',
4949
icon='res/tabcmd.icns',
5050
bundle_identifier = None,
5151
)

tabcmd/commands/datasources_and_workbooks/get_url_command.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import inspect
2+
import os
23

34
import tableauserverclient as TSC
45
from tableauserverclient import ServerResponseError
@@ -80,7 +81,7 @@ def explain_expected_url(logger, url: str, command: str):
8081
def get_file_type_from_filename(logger, url, file_name):
8182
logger.debug("Choosing between {}, {}".format(file_name, url))
8283
file_name = file_name or url
83-
logger.debug(_("get.options.file") + ": {}".format(file_name))
84+
logger.debug(_("get.options.file") + ": {}".format(file_name)) # Name to save the file as
8485
type_of_file = GetUrl.get_file_extension(file_name)
8586

8687
if not type_of_file and file_name is not None:
@@ -98,25 +99,24 @@ def get_file_type_from_filename(logger, url, file_name):
9899
Errors.exit_with_error(logger, _("tabcmd.get.extension.not_found").format(file_name))
99100

100101
@staticmethod
101-
def get_file_extension(filename):
102-
parts = filename.split(".")
103-
if len(parts) < 2:
104-
return None
105-
extension = parts[1]
102+
def get_file_extension(path):
103+
path_segments = os.path.split(path)
104+
filename = path_segments[-1]
105+
filename_segments = filename.split(".")
106+
extension = filename_segments[-1]
106107
extension = GetUrl.strip_query_params(extension)
107108
return extension
108109

109110
@staticmethod
110111
def strip_query_params(filename):
111-
if filename.find("?") > 0:
112-
filename = filename.split("?")[0]
113-
return filename
112+
if "?" in filename:
113+
return filename.split("?")[0]
114+
else:
115+
return filename
114116

115117
@staticmethod
116118
def get_name_without_possible_extension(filename):
117-
if filename.find(".") > 0:
118-
filename = filename.split(".")[0]
119-
return filename
119+
return filename.split(".")[0]
120120

121121
@staticmethod
122122
def get_resource_name(url: str, logger): # workbooks/wb-name" -> "wb-name", datasource/ds-name -> ds-name
@@ -181,7 +181,7 @@ def generate_pdf(logger, server, args, view_url):
181181
filename = GetUrl.filename_from_args(args.filename, view_item.name, "pdf")
182182
DatasourcesAndWorkbooks.save_to_file(logger, view_item.pdf, filename)
183183
except Exception as e:
184-
Errors.exit_with_error(logger, e)
184+
Errors.exit_with_error(logger, exception=e)
185185

186186
@staticmethod
187187
def generate_png(logger, server, args, view_url):
@@ -195,7 +195,7 @@ def generate_png(logger, server, args, view_url):
195195
filename = GetUrl.filename_from_args(args.filename, view_item.name, "png")
196196
DatasourcesAndWorkbooks.save_to_file(logger, view_item.image, filename)
197197
except Exception as e:
198-
Errors.exit_with_error(logger, e)
198+
Errors.exit_with_error(logger, exception=e)
199199

200200
@staticmethod
201201
def generate_csv(logger, server, args, view_url):
@@ -226,7 +226,7 @@ def generate_twb(logger, server, args, file_extension, url):
226226
server.workbooks.download(target_workbook.id, filepath=file_name_with_path, no_extract=False)
227227
logger.info(_("export.success").format(target_workbook.name, file_name_with_ext))
228228
except Exception as e:
229-
Errors.exit_with_error(logger, e)
229+
Errors.exit_with_error(logger, exception=e)
230230

231231
@staticmethod
232232
def generate_tds(logger, server, args, file_extension):
@@ -243,4 +243,4 @@ def generate_tds(logger, server, args, file_extension):
243243
server.datasources.download(target_datasource.id, filepath=file_name_with_path, no_extract=False)
244244
logger.info(_("export.success").format(target_datasource.name, file_name_with_ext))
245245
except Exception as e:
246-
Errors.exit_with_error(logger, e)
246+
Errors.exit_with_error(logger, exception=e)

tabcmd/commands/datasources_and_workbooks/publish_command.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,17 @@ def run_command(args):
4040
session = Session()
4141
server = session.create_session(args, logger)
4242

43-
if args.project_name:
44-
try:
45-
dest_project = Server.get_project_by_name_and_parent_path(
46-
logger, server, args.project_name, args.parent_project_path
47-
)
48-
project_id = dest_project.id
49-
except Exception as exc:
50-
logger.error(exc.__str__())
51-
Errors.exit_with_error(logger, _("publish.errors.server_resource_not_found"), exc)
52-
else:
53-
project_id = ""
54-
args.project_name = "default"
43+
if not args.project_name:
44+
args.project_name = "Default"
5545
args.parent_project_path = ""
46+
try:
47+
dest_project = Server.get_project_by_name_and_parent_path(
48+
logger, server, args.project_name, args.parent_project_path
49+
)
50+
project_id = dest_project.id
51+
except Exception as exc:
52+
logger.error(exc.__str__())
53+
Errors.exit_with_error(logger, _("publish.errors.server_resource_not_found"), exc)
5654

5755
publish_mode = PublishCommand.get_publish_mode(args, logger)
5856

@@ -82,7 +80,7 @@ def run_command(args):
8280
# args.thumbnail_group,
8381
connection_credentials=creds,
8482
as_job=False,
85-
skip_connection_check=False,
83+
skip_connection_check=args.skip_connection_check,
8684
)
8785
except Exception as e:
8886
Errors.exit_with_error(logger, exception=e)

tabcmd/commands/site/list_command.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class ListCommand(Server):
1818
"tabcmd_content_none": "No content found.",
1919
}
2020

21-
2221
name: str = "list"
2322
description: str = "List content items of a specified type"
2423

tabcmd/execution/global_options.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ def set_publish_args(parser):
312312
help="Encrypt extracts in the workbook, datasource, or extract being published to the server. "
313313
"[N/a on Tableau Cloud: extract encryption is controlled by Site Admin]",
314314
)
315+
parser.add_argument(
316+
"--skip-connection-check",
317+
action="store_true",
318+
help="Skip connection check: do not validate the workbook/datasource connection during publishing",
319+
)
315320

316321
# These two only apply for a workbook, not a datasource
317322
thumbnails = parser.add_mutually_exclusive_group()

0 commit comments

Comments
 (0)