8000 fix: handle filename* in download response · ivanB1975/server-client-python@f42948a · GitHub
[go: up one dir, main page]

Skip to content

Commit f42948a

Browse files
committed
fix: handle filename* in download response
1 parent 1f9088f commit f42948a

File tree

8 files changed

+73
-0
lines changed

8 files changed

+73
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var/
2424
*.egg-info/
2525
.installed.cfg
2626
*.egg
27+
pip-wheel-metadata/
2728

2829
# PyInstaller
2930
# Usually these files are written by a python script from a template
@@ -89,6 +90,7 @@ env.py
8990
# virtualenv
9091
venv/
9192
ENV/
93+
.venv/
9294

9395
# Spyder project settings
9496
.spyderproject
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from copy import deepcopy
2+
from typing import Any, Generic, Mapping, Optional, TypeVar, Union
3+
from urllib.parse import unquote_plus
4+
5+
T = TypeVar("T", )
6+
7+
def fix_filename(params: Mapping[str, T]) -> Mapping[str, T]:
8+
if "filename*" not in params:
9+
return params
10+
11+
params = deepcopy(params)
12+
filename = params["filename*"]
13+
prefix = "UTF-8''"
14+
if filename.startswith(prefix):
15+
filename = filename[len(prefix):]
16+
17+
params["filename"] = unquote_plus(filename)
18+
del params["filename*"]
19+
return params

tableauserverclient/server/endpoint/datasources_endpoint.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from pathlib import Path
99
from typing import List, Mapping, Optional, Sequence, Tuple, TYPE_CHECKING, Union
1010

11+
from tableauserverclient.helpers.headers import fix_filename
12+
1113
if TYPE_CHECKING:
1214
from tableauserverclient.server import Server
1315
from tableauserverclient.models import PermissionsRule
@@ -441,6 +443,7 @@ def download_revision(
441443
filepath.write(chunk)
442444
return_path = filepath
443445
else:
446+
params = fix_filename(params)
444447
filename = to_filename(os.path.basename(params["filename"]))
445448
download_path = make_download_path(filepath, filename)
446449
with open(download_path, "wb") as f:

tableauserverclient/server/endpoint/flows_endpoint.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from pathlib import Path
88
from typing import Iterable, List, Optional, TYPE_CHECKING, Tuple, Union
99

10+
from tableauserverclient.helpers.headers import fix_filename
11+
1012
from .dqw_endpoint import _DataQualityWarningEndpoint
1113
from .endpoint import QuerysetEndpoint, api
1214
from .exceptions import InternalServerError, MissingRequiredFieldError
@@ -124,6 +126,7 @@ def download(self, flow_id: str, filepath: Optional[PathOrFileW] = None) -> Path
124126
filepath.write(chunk)
125127
return_path = filepath
126128
else:
129+
params = fix_filename(params)
127130
filename = to_filename(os.path.basename(params["filename"]))
128131
download_path = make_download_path(filepath, filename)
129132
with open(download_path, "wb") as f:

tableauserverclient/server/endpoint/workbooks_endpoint.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from contextlib import closing
77
from pathlib import Path
88

9+
from tableauserverclient.helpers.headers import fix_filename
10+
911
from .endpoint import QuerysetEndpoint, api, parameter_added_in
1012
from .exceptions import InternalServerError, MissingRequiredFieldError
1113
from .permissions_endpoint import _PermissionsEndpoint
@@ -487,6 +489,7 @@ def download_revision(
487489
filepath.write(chunk)
488490
return_path = filepath
489491
else:
492+
params = fix_filename(params)
490493
filename = to_filename(os.path.basename(params["filename"]))
491494
download_path = make_download_path(filepath, filename)
492495
with open(download_path, "wb") as f:

test/test_datasource.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,3 +696,17 @@ def test_download_revision(self) -> None:
696696
)
697697
file_path = self.server.datasources.download_revision("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", "3", td)
698698
self.assertTrue(os.path.exists(file_path))
699+
700+
def test_bad_download_response(self) -> None:
701+
with requests_mock.mock() as m, tempfile.TemporaryDirectory() as td:
702+
m.get(
703+
self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content",
704+
headers={
705+
"Content-Disposition": '''name="tableau_datasource"; filename*=UTF-8''"Sample datasource.tds"'''
706+
}
707+
)
708+
file_path = self.server.datasources.download(
709+
"9dbd2263-16b5-46e1-9c43-a76bb8ab65fb",
710+
td
711+
)
712+
self.assertTrue(os.path.exists(file_path))

test/test_flow.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import requests_mock
3+
import tempfile
34
import unittest
45

56
from io import BytesIO
@@ -203,3 +204,17 @@ def test_refresh(self):
203204
self.assertEqual(refresh_job.flow_run.id, "e0c3067f-2333-4eee-8028-e0a56ca496f6")
204205
self.assertEqual(refresh_job.flow_run.flow_id, "92967d2d-c7e2-46d0-8847-4802df58f484")
205206
self.assertEqual(format_datetime(refresh_job.flow_run.started_at), "2018-05-22T13:00:29Z")
207+
208+
def test_bad_download_response(self) -> None:
209+
with requests_mock.mock() as m, tempfile.TemporaryDirectory() as td:
210+
m.get(
211+
self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content",
212+
headers={
213+
"Content-Disposition": '''name="tableau_flow"; filename*=UTF-8''"Sample flow.tfl"'''
214+
}
215+
)
216+
file_path = self.server.flows.download(
217+
"9dbd2263-16b5-46e1-9c43-a76bb8ab65fb",
218+
td
219+
)
220+
self.assertTrue(os.path.exists(file_path))

test/test_workbook.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,3 +932,17 @@ def test_download_revision(self) -> None:
932932
)
933933
file_path = self.server.workbooks.download_revision("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", "3", td)
934934
self.assertTrue(os.path.exists(file_path))
935+
936+
def test_bad_download_response(self) -> None:
937+
with requests_mock.mock() as m, tempfile.TemporaryDirectory() as td:
938+
m.get(
939+
self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content",
940+
headers={
941+
"Content-Disposition": '''name="tableau_workbook"; filename*=UTF-8''"Sample workbook.twb"'''
942+
}
943+
)
944+
file_path = self.server.workbooks.download(
945+
"9dbd2263-16b5-46e1-9c43-a76bb8ab65fb",
946+
td
947+
)
948+
self.assertTrue(os.path.exists(file_path))

0 commit comments

Comments
 (0)
0