FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
document-api-python/tableaudocumentapi/xfile.py at master · digideskio/document-api-python · GitHub
digideskio
/
document-api-python
Public
forked from
tableau/document-api-python
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
document-api-python
/
tableaudocumentapi
/
xfile.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
114 lines (82 loc) · 3.34 KB
Breadcrumbs
document-api-python
/
tableaudocumentapi
/
xfile.py
Copy path
File metadata and controls
114 lines (82 loc) · 3.34 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import
contextlib
import
os
import
shutil
import
tempfile
import
zipfile
import
xml
.
etree
.
ElementTree
as
ET
try
:
from
distutils2
.
version
import
NormalizedVersion
as
Version
except
ImportError
:
from
distutils
.
version
import
LooseVersion
as
Version
MIN_SUPPORTED_VERSION
=
Version
(
"9.0"
)
class
TableauVersionNotSupportedException
(
Exception
):
pass
class
TableauInvalidFileException
(
Exception
):
pass
def
xml_open
(
filename
,
expected_root
=
None
):
if
zipfile
.
is_zipfile
(
filename
):
tree
=
get_xml_from_archive
(
filename
)
else
:
tree
=
ET
.
parse
(
filename
)
tree_root
=
tree
.
getroot
()
file_version
=
Version
(
tree_root
.
attrib
.
get
(
'version'
,
'0.0'
))
if
file_version
<
MIN_SUPPORTED_VERSION
:
raise
TableauVersionNotSupportedException
(
file_version
)
if
expected_root
and
(
expected_root
!=
tree_root
.
tag
):
raise
TableauInvalidFileException
(
"'{}'' is not a valid '{}' file"
.
format
(
filename
,
expected_root
))
return
tree
@
contextlib
.
contextmanager
def
temporary_directory
(
*
args
,
**
kwargs
):
d
=
tempfile
.
mkdtemp
(
*
args
,
**
kwargs
)
try
:
yield
d
finally
:
shutil
.
rmtree
(
d
)
def
find_file_in_zip
(
zip_file
):
for
filename
in
zip_file
.
namelist
():
with
zip_file
.
open
(
filename
)
as
xml_candidate
:
try
:
ET
.
parse
(
xml_candidate
)
return
filename
except
ET
.
ParseError
:
# That's not an XML file by gosh
pass
def
get_xml_from_archive
(
filename
):
with
zipfile
.
ZipFile
(
filename
)
as
zf
:
with
zf
.
open
(
find_file_in_zip
(
zf
))
as
xml_file
:
xml_tree
=
ET
.
parse
(
xml_file
)
return
xml_tree
def
build_archive_file
(
archive_contents
,
zip_file
):
for
root_dir
,
_
,
files
in
os
.
walk
(
archive_contents
):
relative_dir
=
os
.
path
.
relpath
(
root_dir
,
archive_contents
)
for
f
in
files
:
temp_file_full_path
=
os
.
path
.
join
(
archive_contents
,
relative_dir
,
f
)
zipname
=
os
.
path
.
join
(
relative_dir
,
f
)
zip_file
.
write
(
temp_file_full_path
,
arcname
=
zipname
)
def
save_into_archive
(
xml_tree
,
filename
,
new_filename
=
None
):
# Saving a archive means extracting the contents into a temp folder,
# saving the changes over the twb/tds in that folder, and then
# packaging it back up into a specifically formatted zip with the correct
# relative file paths
if
new_filename
is
None
:
new_filename
=
filename
# Extract to temp directory
with
temporary_directory
()
as
temp_path
:
with
zipfile
.
ZipFile
(
filename
)
as
zf
:
xml_file
=
find_file_in_zip
(
zf
)
zf
.
extractall
(
temp_path
)
# Write the new version of the file to the temp directory
xml_tree
.
write
(
os
.
path
.
join
(
temp_path
,
xml_file
),
encoding
=
"utf-8"
,
xml_declaration
=
True
)
# Write the new archive with the contents of the temp folder
with
zipfile
.
ZipFile
(
new_filename
,
"w"
,
compression
=
zipfile
.
ZIP_DEFLATED
)
as
new_archive
:
build_archive_file
(
temp_path
,
new_archive
)
def
_save_file
(
container_file
,
xml_tree
,
new_filename
=
None
):
if
container_file
is
None
:
container_file
=
new_filename
if
zipfile
.
is_zipfile
(
container_file
):
save_into_archive
(
xml_tree
,
container_file
,
new_filename
)
else
:
xml_tree
.
write
(
container_file
,
encoding
=
"utf-8"
,
xml_declaration
=
True
)
Back
|
FazBrowse Home
|
New Git URL