Skip to content

Commit 9b227d4

Browse files
authored
Adding support for new args in publish and export commands (#356)
* Adding replace & thumbnail options to publish command
1 parent f4ac121 commit 9b227d4

8 files changed

Lines changed: 113 additions & 21 deletions

File tree

tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,22 @@ def apply_png_options(logger, request_options: TSC.ImageRequestOptions, args):
155155
request_options.image_resolution = None
156156
else:
157157
request_options.image_resolution = TSC.ImageRequestOptions.Resolution.High.lower()
158+
if args.language:
159+
request_options.language = args.language
158160

159161
@staticmethod
160162
def apply_pdf_options(logger, request_options: TSC.PDFRequestOptions, args):
161163
if args.pagelayout:
162164
request_options.orientation = args.pagelayout
163165
if args.pagesize:
164166
request_options.page_type = args.pagesize
167+
if args.language:
168+
request_options.language = args.language
169+
170+
@staticmethod
171+
def apply_csv_options(logger, request_options: TSC.CSVRequestOptions, args):
172+
if args.language:
173+
request_options.language = args.language
165174

166175
@staticmethod
167176
def save_to_data_file(logger, output, filename):

tabcmd/commands/datasources_and_workbooks/export_command.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ def download_csv(server_content_type, export_item, args, logger):
175175
csv_options = TSC.CSVRequestOptions(maxage=1)
176176
ExportCommand.apply_values_from_url_params(logger, csv_options, args.url)
177177
ExportCommand.apply_filters_from_args(csv_options, args, logger)
178+
DatasourcesAndWorkbooks.apply_csv_options(logger, csv_options, args)
178179
logger.debug(csv_options.get_query_params())
179180
server_content_type.populate_csv(export_item, csv_options)
180181
return export_item.csv

tabcmd/commands/datasources_and_workbooks/publish_command.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,15 @@ def run_command(args):
7676
source = PublishCommand.get_filename_extension_if_tableau_type(logger, args.filename)
7777
logger.info(_("publish.status").format(args.filename))
7878
if source in ["twbx", "twb"]:
79-
if args.thumbnail_group:
80-
raise AttributeError("Generating thumbnails for a group is not yet implemented.")
8179
if args.thumbnail_username and args.thumbnail_group:
8280
raise AttributeError("Cannot specify both a user and group for thumbnails.")
8381

8482
new_workbook = TSC.WorkbookItem(project_id, name=args.name, show_tabs=args.tabbed)
83+
if args.thumbnail_username:
84+
new_workbook.thumbnails_user_id = args.thumbnail_username
85+
elif args.thumbnail_group:
86+
new_workbook.thumbnails_group_id = args.thumbnail_group
87+
8588
try:
8689
new_workbook = server.workbooks.publish(
8790
new_workbook,
@@ -114,24 +117,19 @@ def get_publish_mode(args, logger):
114117
default_mode = TSC.Server.PublishMode.CreateNew
115118
publish_mode = default_mode
116119

117-
if args.replace:
118-
raise AttributeError("Replacing an extract is not yet implemented")
119-
120-
if args.append:
121-
if publish_mode != default_mode:
122-
publish_mode = None
123-
else:
124-
# only relevant for datasources, but tsc will throw an error for us if necessary
125-
publish_mode = TSC.Server.PublishMode.Append
120+
mode_mapping = {
121+
"replace": TSC.Server.PublishMode.Replace,
122+
"append": TSC.Server.PublishMode.Append,
123+
"overwrite": TSC.Server.PublishMode.Overwrite,
124+
}
126125

127-
if args.overwrite:
128-
if publish_mode != default_mode:
129-
publish_mode = None
130-
else:
131-
# Overwrites the workbook, data source, or data extract if it already exists on the server.
132-
publish_mode = TSC.Server.PublishMode.Overwrite
126+
selected_modes = [mode for mode, mode_value in mode_mapping.items() if getattr(args, mode, False)]
133127

134-
if not publish_mode:
128+
if len(selected_modes) > 1:
135129
Errors.exit_with_error(logger, "Invalid combination of publishing options (Append, Overwrite, Replace)")
130+
131+
if selected_modes:
132+
publish_mode = mode_mapping[selected_modes[0]]
133+
136134
logger.debug("Publish mode selected: " + publish_mode)
137135
return publish_mode

tabcmd/execution/global_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ def set_publish_args(parser):
327327
)
328328
thumbnails.add_argument(
329329
"--thumbnail-group",
330-
help="[Not yet implemented] If the workbook contains user filters, the thumbnails will be generated based on what the "
330+
help="If the workbook contains user filters, the thumbnails will be generated based on what the "
331331
"specified group can see. Cannot be specified when --thumbnail-username option is set.",
332332
)
333333

tests/commands/test_datasources_and_workbooks_command.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,30 @@ def test_apply_png_options(self):
5050
mock_args.width = "800"
5151
mock_args.height = "76"
5252
mock_args.resolution = None
53+
mock_args.language = None
5354
request_options = tsc.ImageRequestOptions()
5455
DatasourcesAndWorkbooks.apply_png_options(mock_logger, request_options, mock_args)
5556
assert request_options.image_resolution == "high"
5657
assert request_options.viz_width == 800
5758
assert request_options.viz_height == 76
5859

60+
def test_apply_png_options_with_language(self):
61+
mock_args.width = "800"
62+
mock_args.height = "76"
63+
mock_args.resolution = None
64+
mock_args.language = "de"
65+
request_options = tsc.ImageRequestOptions()
66+
DatasourcesAndWorkbooks.apply_png_options(mock_logger, request_options, mock_args)
67+
assert request_options.image_resolution == "high"
68+
assert request_options.viz_width == 800
69+
assert request_options.viz_height == 76
70+
assert request_options.language == "de"
71+
5972
def test_apply_png_options_with_resolution_high(self):
6073
mock_args.width = "800"
6174
mock_args.height = "76"
6275
mock_args.resolution = "high"
76+
mock_args.language = None
6377
request_options = tsc.ImageRequestOptions()
6478
DatasourcesAndWorkbooks.apply_png_options(mock_logger, request_options, mock_args)
6579
assert request_options.image_resolution == "high"
@@ -70,6 +84,7 @@ def test_apply_png_options_with_resolution_standard(self):
7084
mock_args.width = "800"
7185
mock_args.height = "76"
7286
mock_args.resolution = "standard"
87+
mock_args.language = None
7388
request_options = tsc.ImageRequestOptions()
7489
DatasourcesAndWorkbooks.apply_png_options(mock_logger, request_options, mock_args)
7590
assert request_options.image_resolution is None
@@ -88,11 +103,25 @@ def test_apply_pdf_options(self):
88103
expected_layout = tsc.PDFRequestOptions.Orientation.Portrait.__str__()
89104
mock_args.pagelayout = expected_layout
90105
mock_args.pagesize = expected_page
106+
mock_args.language = None
91107
request_options = tsc.PDFRequestOptions()
92108
DatasourcesAndWorkbooks.apply_pdf_options(mock_logger, request_options, mock_args)
93109
assert request_options.page_type == expected_page
94110
assert request_options.orientation == expected_layout
95111

112+
def test_apply_pdf_options_with_language(self):
113+
language = "de"
114+
expected_page = tsc.PDFRequestOptions.PageType.Folio.__str__()
115+
expected_layout = tsc.PDFRequestOptions.Orientation.Portrait.__str__()
116+
mock_args.pagelayout = expected_layout
117+
mock_args.pagesize = expected_page
118+
mock_args.language = language
119+
request_options = tsc.PDFRequestOptions()
120+
DatasourcesAndWorkbooks.apply_pdf_options(mock_logger, request_options, mock_args)
121+
assert request_options.page_type == expected_page
122+
assert request_options.orientation == expected_layout
123+
assert request_options.language == language
124+
96125
def test_apply_options_in_url_with_size(self):
97126
request_options = tsc.ImageRequestOptions()
98127
value = ":size=800,600"
@@ -126,6 +155,18 @@ def test_apply_options_in_url_with_unrecognized_parameter(self):
126155
self.assertEqual(request_options.viz_width, None)
127156
self.assertEqual(request_options.max_age, default_max_age)
128157

158+
def test_apply_csv_options(self):
159+
mock_args.language = None
160+
request_options = tsc.CSVRequestOptions()
161+
DatasourcesAndWorkbooks.apply_csv_options(mock_logger, request_options, mock_args)
162+
assert request_options.language == None
163+
164+
def test_apply_csv_options_with_language(self):
165+
mock_args.language = "de"
166+
request_options = tsc.CSVRequestOptions()
167+
DatasourcesAndWorkbooks.apply_csv_options(mock_logger, request_options, mock_args)
168+
assert request_options.language == "de"
169+
129170

130171
@mock.patch("tableauserverclient.Server")
131172
class MockedServerTests(unittest.TestCase):

tests/commands/test_geturl_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
mock_args.filename = None
1919
mock_args.filter = None
2020
mock_args.resolution = None
21+
mock_args.language = None
2122

2223
mock_logger = mock.MagicMock()
2324

tests/commands/test_publish_command.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from unittest.mock import *
44
import tableauserverclient as TSC
55

6-
from tabcmd.commands.auth import login_command
7-
from tabcmd.commands.datasources_and_workbooks import delete_command, export_command, get_url_command, publish_command
6+
from tabcmd.commands.datasources_and_workbooks import publish_command
87

98

109
from typing import List, NamedTuple, TextIO, Union
@@ -31,6 +30,8 @@
3130
getter.get = MagicMock("get", return_value=([fake_item], fake_item_pagination))
3231
getter.publish = MagicMock("publish", return_value=fake_item)
3332

33+
mock_logger = MagicMock()
34+
3435

3536
@patch("tableauserverclient.Server")
3637
@patch("tabcmd.commands.auth.session.Session.create_session")
@@ -95,3 +96,43 @@ def test_publish_with_creds(self, mock_session, mock_server):
9596
mock_server.projects = getter
9697
publish_command.PublishCommand.run_command(mock_args)
9798
mock_session.assert_called()
99+
100+
def test_default_publish_mode(self, mock_session, mock_server):
101+
mock_args.replace = False
102+
mock_args.append = False
103+
mock_args.overwrite = False
104+
105+
publish_mode = publish_command.PublishCommand.get_publish_mode(mock_args, mock_logger)
106+
self.assertEqual(publish_mode, TSC.Server.PublishMode.CreateNew)
107+
108+
def test_replace_publish_mode(self, mock_session, mock_server):
109+
mock_args.replace = True
110+
mock_args.append = False
111+
mock_args.overwrite = False
112+
113+
publish_mode = publish_command.PublishCommand.get_publish_mode(mock_args, mock_logger)
114+
self.assertEqual(publish_mode, TSC.Server.PublishMode.Replace)
115+
116+
def test_append_publish_mode(self, mock_session, mock_server):
117+
mock_args.replace = False
118+
mock_args.append = True
119+
mock_args.overwrite = False
120+
121+
publish_mode = publish_command.PublishCommand.get_publish_mode(mock_args, mock_logger)
122+
self.assertEqual(publish_mode, TSC.Server.PublishMode.Append)
123+
124+
def test_overwrite_publish_mode(self, mock_session, mock_server):
125+
mock_args.replace = False
126+
mock_args.append = False
127+
mock_args.overwrite = True
128+
129+
publish_mode = publish_command.PublishCommand.get_publish_mode(mock_args, mock_logger)
130+
self.assertEqual(publish_mode, TSC.Server.PublishMode.Overwrite)
131+
132+
def test_invalid_combination_of_modes(self, mock_session, mock_server):
133+
mock_args.replace = True
134+
mock_args.append = True
135+
mock_args.overwrite = False
136+
137+
with self.assertRaises(SystemExit):
138+
publish_command.PublishCommand.get_publish_mode(mock_args, mock_logger)

tests/commands/test_run_commands.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def test_export(self, mock_session, mock_server):
120120
mock_args.height = None
121121
mock_args.width = None
122122
mock_args.filter = None
123+
mock_args.language = None
123124
export_command.ExportCommand.run_command(mock_args)
124125
mock_session.assert_called()
125126

0 commit comments

Comments
 (0)