diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml
new file mode 100644
index 0000000..9c208c4
--- /dev/null
+++ b/.github/workflows/publish-pypi.yml
@@ -0,0 +1,34 @@
+name: Publish to PyPi
+
+
+on:
+ workflow_dispatch:
+ push:
+ branches: development, main
+
+jobs:
+ build-n-publish:
+ name: Build dist files for PyPi
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - uses: actions/setup-python@v1
+ with:
+ python-version: 3.8
+ - name: Build dist files
+ run: >
+ python -m pip install --upgrade pip && pip install -e .[build] &&
+ python setup.py build &&
+ python setup.py sdist --formats=gztar
+ - name: Publish distribution 📦 to Test PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2
+ with:
+ password: ${{ secrets.TEST_PYPI_API_TOKEN }}
+ repository_url: https://test.pypi.org/legacy/
+ - name: Publish distribution 📦 to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2
+ with:
+ password: ${{ secrets.PYPI_API_TOKEN }}
+
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
new file mode 100644
index 0000000..4bd171f
--- /dev/null
+++ b/.github/workflows/python-package.yml
@@ -0,0 +1,59 @@
+# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Python package
+
+on:
+ push:
+ paths-ignore:
+ - 'docs/**'
+ pull_request:
+ branches: '*'
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: [3.7, 3.8, 3.9, '3.10']
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Test
+ run: |
+ python setup.py test
+
+
+ lint:
+
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: [3.9]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ python -m pip install pycodestyle
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Lint with pycodestyle
+ run: |
+ pycodestyle tableaudocumentapi test samples
+
diff --git a/.gitignore b/.gitignore
index ee250af..994e968 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,8 @@ var/
pip-log.txt
pip-delete-this-directory.txt
+Gemfile.lock
+
# Unit test / coverage reports
htmlcov/
.tox/
@@ -64,3 +66,12 @@ target/
#Other things
.DS_Store
.idea
+
+#Editor things
+*.sublime-project
+*.sublime-workspace
+settings.json
+tasks.json
+
+#Jekyll
+docs/_site
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e2a9073..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-language: python
-python:
- - "2.7"
- - "3.3"
- - "3.4"
- - "3.5"
- - "pypy"
-# command to install dependencies
-install:
- - "pip install -e ."
- - "pip install pep8"
-# command to run tests
-script:
- # Tests
- - python setup.py test
- # pep8
- - pep8 .
- # Examples
- - (cd "samples/replicate-workbook" && python replicate_workbook.py)
- - (cd "samples/list-tds-info" && python list_tds_info.py)
- - (cd "samples/show-fields" && python show_fields.py)
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7ba40cd..1a18c16 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,44 @@
+## 011 (November 2022)
+* Remove extraneous debug print statements
+
+## 010 (June 2022)
+* Add service/schema attributes
+
+## 091 (March 2022)
+* Add attribute for hidden field
+
+## 09 (December 2021)
+* PyPI upgraded to Python3
+
+## 08 (October 2021)
+* See dashboards in a workbook
+* Add shapes property
+* Add custom sql
+* Drop python 2, add up through 3.9
+
+## 07 (26 May 2021)
+* Fix bug in xfile that overwrote the namespace name when saving a document
+
+## 06 (11 January 2017)
+
+* Initial SQL and query banding support (#123)
+* Fixed bug in xfiles to allow opening workbooks with external file caches (#117, #118)
+* Code Cleanup (#120, #121)
+* Added Py36 support (#124)
+* Switched to pycodestyle from pip8 on travis runs (#124)
+
+## 05 (01 November 2016)
+
+* Added ability to set the port for connections (#97)
+* Added ability to read and write caption for datasources (#99)
+* Added documentation
+
+## 0.4 (07 October 2016)
+
+* Add ability to remove repository location (#86)
+* Fixed bug in connection parsing when federated connections are present (#87)
+* Fixed bug in UNICODE support (#80)
+
## 0.3 (31 August 2016)
* Added basic connection class retargeting (#65)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
new file mode 100644
index 0000000..903e57b
--- /dev/null
+++ b/CONTRIBUTORS.md
@@ -0,0 +1,15 @@
+This project wouldn't be possible without our amazing contributors.
+
+The following people have contributed to this project to make it possible, and we thank them for their contributions!
+
+## Contributors
+
+* [Charley Peng](https://github.com/chid)
+* [Miguel Sánchez](https://github.com/MiguelSR)
+* [Ryan Richmond](https://github.com/r-richmond)
+
+## Core Team
+
+* [Tyler Doyle](https://github.com/t8y8)
+* [Russell Hay](https://github.com/RussTheAerialist)
+
diff --git a/README b/README
deleted file mode 120000
index 42061c0..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-README.md
\ No newline at end of file
diff --git a/README.md b/README.md
index 588fb14..beb0263 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,14 @@
# document-api-python
+[](https://www.tableau.com/support-levels-it-and-developer-tools)
-[](https://travis-ci.org/tableau/document-api-python)
-
-This repo contains Python source and example files for the Tableau Document API. We're just getting started and have plans to expand what you find here. Help us by submitting feedback, issues, and pull requests!
Document API
---------------
-The Document API provides a supported way to programmatically make updates to Tableau workbook and data source files. If you've been making changes to these file types by directly updating the XML--that is, by XML hacking--this SDK is for you :)
+This repo contains Python source and example files for the Tableau Document API.
+The Document API provides a useful but *unsupported* way to programmatically make updates to Tableau workbook and data source files. If you've been making changes to these file types by directly updating the XML--that is, by XML hacking--this SDK is for you :) Get help from other users on the [Tableau Community Forums](https://community.tableau.com/s/topic/0TO4T000000SF3sWAG/document-api).
Features include:
-- Support for 9.X, and 10.X workbook and data source files
- - Including TDSX and TWBX files
+- Support for TWB, TWBX, TDE and TDSX files starting roughly back to Tableau 9.x
- Getting connection information from data sources and workbooks
- Server Name
- Username
@@ -25,85 +23,9 @@ Features include:
- Get all fields in a data source
- Get all fields in use by certain sheets in a workbook
-We don't yet support creating files from scratch, adding extracts into workbooks or data sources, or updating field information
-
-
-###Getting Started
-To use this SDK, you must have Python installed. You can use either 2.7.X or 3.3 and later.
-
-#### Installing the latest stable version (preferred)
-
-```text
-pip install tableaudocumentapi
-```
-
-#### Installing From Source
-
-Download the `.zip` file that contains the SDK. Unzip the file and then run the following command:
-
-```text
-pip install -e
-```
-
-#### Installing the Development Version from Git
-
-*Only do this if you know you want the development version, no guarantee that we won't break APIs during development*
-
-```text
-pip install git+https://github.com/tableau/document-api-python.git@development
-```
-
-If you go this route, but want to switch back to the non-development version, you need to run the following command before installing the stable version:
-
-```text
-pip uninstall tableaudocumentapi
-```
-
-###Basics
-The following example shows the basic syntax for using the Document API to update a workbook:
-
-```python
-from tableaudocumentapi import Workbook
-
-sourceWB = Workbook('WorkbookToUpdate.twb')
-
-sourceWB.datasources[0].connections[0].server = "MY-NEW-SERVER"
-sourceWB.datasources[0].connections[0].dbname = "NEW-DATABASE"
-sourceWB.datasources[0].connections[0].username = "benl"
-
-sourceWB.save()
-```
-
-With Data Integration in Tableau 10, a data source can have multiple connections. To access the connections simply index them like you would datasources.
-
-```python
-from tableaudocumentapi import Workbook
-
-sourceWB = Workbook('WorkbookToUpdate.twb')
-
-sourceWB.datasources[0].connections[0].server = "MY-NEW-SERVER"
-sourceWB.datasources[0].connections[0].dbname = "NEW-DATABASE"
-sourceWB.datasources[0].connections[0].username = "benl"
-
-sourceWB.datasources[0].connections[1].server = "MY-NEW-SERVER"
-sourceWB.datasources[0].connections[1].dbname = "NEW-DATABASE"
-sourceWB.datasources[0].connections[1].username = "benl"
-
-
-sourceWB.save()
-```
-
-
-**Notes**
-
-- Import the `Workbook` object from the `tableaudocumentapi` module.
-- To open a workbook, instantiate a `Workbook` object and pass the file name as the first argument.
-- The `Workbook` object exposes a list of `datasources` in the workbook
-- Each data source object has a `connection` object that supports a `server`, `dbname`, and `username` property.
-- Save changes to the workbook by calling the `save` or `save_as` method.
-
+- It *doesn't* support creating files from scratch, adding extracts into workbooks or data sources, or updating field information. As of 2021, this SDK no longer supports Python 2.
+For Hyper files, take a look at the [Tableau Hyper API](https://help.tableau.com/current/api/hyper_api/en-us/index.html).
-###[Examples](Examples)
+For more information, see the [Document API documentation](https://tableau.github.io/document-api-python)
-The downloadable package contains several example scripts that show more detailed usage of the Document API.
diff --git a/contributing.md b/contributing.md
deleted file mode 100644
index 15fc5f8..0000000
--- a/contributing.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Contributing
-
-We welcome contributions to this project!
-
-Contribution can include, but are not limited to, any of the following:
-
-* File an Issue
-* Request a Feature
-* Implement a Requested Feature
-* Fix an Issue/Bug
-* Add/Fix documentation
-
-Contributions must follow the guidelines outlined on the [Tableau Organization](http://tableau.github.io/) page, though filing an issue or requesting
-a feature do not require the CLA.
-
-## Issues and Feature Requests
-
-To submit an issue/bug report, or to request a feature, please submit a [github issue](https://github.com/tableau/document-api-python/issues) to the repo.
-
-If you are submiting a bug report, please provide as much information as you can, including clear and concise repro steps, attaching any necessary
-files to assist in the repro. **Be sure to scrub the files of any potentially sensitive information. Issues are public.**
-
-For a feature request, please try to describe the scenario you are trying to accomplish that requires the feature. This will help us understand
-the limitations that you are running into, and provide us with a use case to know if we've satisfied your request.
-
-## Fixes, Implementations, and Documentation
-
-For all other things, please submit a PR that includes the fix, documentation, or new code that you are trying to contribute. More information on
-creating a PR can be found in the [github documentation](https://help.github.com/articles/creating-a-pull-request/)
-
-If the feature is complex or has multiple solutions that could be equally appropriate approaches, it would be helpful to file an issue to discuss the
-design trade-offs of each solution before implementing, to allow us to collectively arrive at the best solution, which most likely exists in the middle
-somewhere.
diff --git a/contributing.md b/contributing.md
new file mode 120000
index 0000000..e047e03
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1 @@
+docs/docs/contributing.md
\ No newline at end of file
diff --git a/docs/.keep b/docs/.keep
new file mode 100644
index 0000000..4e4b8f1
--- /dev/null
+++ b/docs/.keep
@@ -0,0 +1 @@
+Hello docs!
\ No newline at end of file
diff --git a/docs/Gemfile b/docs/Gemfile
new file mode 100644
index 0000000..775d954
--- /dev/null
+++ b/docs/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+gem 'github-pages', group: :jekyll_plugins
+
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000..5fefbee
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1,17 @@
+# Site settings
+title: Tableau Document API
+email: github@tableau.com
+description: Programmatically update your Tableau workbooks and data sources.
+baseurl: "/document-api-python"
+permalinks: pretty
+defaults:
+ -
+ scope:
+ path: "" # Apply to all files
+ values:
+ layout: "default"
+
+# Build settings
+markdown: kramdown
+highlighter: rouge
+
diff --git a/docs/_includes/analytics.html b/docs/_includes/analytics.html
new file mode 100644
index 0000000..0cdbad2
--- /dev/null
+++ b/docs/_includes/analytics.html
@@ -0,0 +1,7 @@
+
+
+
diff --git a/docs/_includes/docs_menu.html b/docs/_includes/docs_menu.html
new file mode 100644
index 0000000..eae8806
--- /dev/null
+++ b/docs/_includes/docs_menu.html
@@ -0,0 +1,17 @@
+
diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html
new file mode 100644
index 0000000..1b50f51
--- /dev/null
+++ b/docs/_includes/footer.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ This site is open source. Suggestions and pull requests are welcome on our GitHub page .
+ © Copyright Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners.
+ Salesforce, Inc. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
+ Documentation last generated on: {{ site.time }}
+
+
\ No newline at end of file
diff --git a/docs/_includes/head.html b/docs/_includes/head.html
new file mode 100644
index 0000000..858a412
--- /dev/null
+++ b/docs/_includes/head.html
@@ -0,0 +1,26 @@
+
+
+
+
+ {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% if jekyll.environment == "production" %}{% include analytics.html %}{% endif %}
diff --git a/docs/_includes/header.html b/docs/_includes/header.html
new file mode 100644
index 0000000..6e8e763
--- /dev/null
+++ b/docs/_includes/header.html
@@ -0,0 +1,29 @@
+
diff --git a/docs/_includes/icon-github.svg b/docs/_includes/icon-github.svg
new file mode 100644
index 0000000..4422c4f
--- /dev/null
+++ b/docs/_includes/icon-github.svg
@@ -0,0 +1 @@
+
diff --git a/docs/_includes/search_form.html b/docs/_includes/search_form.html
new file mode 100644
index 0000000..41bb342
--- /dev/null
+++ b/docs/_includes/search_form.html
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
new file mode 100644
index 0000000..38ee020
--- /dev/null
+++ b/docs/_layouts/default.html
@@ -0,0 +1,34 @@
+
+
+
+
+ {% include head.html %}
+
+
+
+
+ {% include header.html %}
+
+ {% for post in site.posts %}
+
+
{{ post.title }}
+
+
Posted on {{ post.date | date: "%-d %B %Y" }}
+
+
+ {{ post.abstract }}
+
+ {% if post.photoname %}
+
{% endif %}
+
+
+ {{ post.content }}
+
+
+ {% endfor %}
+
+ {% include footer.html %}
+
+
+
+
diff --git a/docs/_layouts/docs.html b/docs/_layouts/docs.html
new file mode 100644
index 0000000..d229de4
--- /dev/null
+++ b/docs/_layouts/docs.html
@@ -0,0 +1,31 @@
+---
+layout: docs
+---
+
+
+
+
+
+ {% include head.html %}
+
+
+
+
+ {% include header.html %}
+ {% include docs_menu.html %}
+
+
+
{{ page.title }}
+
+
+ {{ content }}
+ {% include footer.html %}
+
+
+
+
+
diff --git a/docs/_layouts/home.html b/docs/_layouts/home.html
new file mode 100644
index 0000000..c2cf32f
--- /dev/null
+++ b/docs/_layouts/home.html
@@ -0,0 +1,19 @@
+---
+layout: home
+---
+
+
+
+
+ {% include head.html %}
+
+
+
+
+ {% include header.html %}
+ {{ content }}
+ {% include footer.html %}
+
+
+
+
diff --git a/docs/_layouts/search.html b/docs/_layouts/search.html
new file mode 100644
index 0000000..96dbd94
--- /dev/null
+++ b/docs/_layouts/search.html
@@ -0,0 +1,43 @@
+---
+layout: search
+---
+
+
+
+
+
+ {% include head.html %}
+
+
+
+
+
+
+
+
+ {% include header.html %}
+ {% include docs_menu.html %}
+
+
+
+
+
+
Loading search results...
+
+
+ {% include footer.html %}
+
+
+
+
diff --git a/docs/assets/logo.png b/docs/assets/logo.png
new file mode 100644
index 0000000..6076115
Binary files /dev/null and b/docs/assets/logo.png differ
diff --git a/docs/css/api_ref.css b/docs/css/api_ref.css
new file mode 100644
index 0000000..62da935
--- /dev/null
+++ b/docs/css/api_ref.css
@@ -0,0 +1,709 @@
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.false...relation connection='sqlserver.1nzmabo1alszdd1dqm0c11g0qr0m' name='TestData' table='[dbo].[TestData]' type='table' />
+ <_.fcp.ObjectModelEncapsulateLegacy.true...relation connection='sqlserver.1nzmabo1alszdd1dqm0c11g0qr0m' name='TestData' table='[dbo].[TestData]' type='table' />
+
+
+ Account Account Name
+ 130
+ [Account Account Name]
+ [TestData]
+ Account Account Name
+ 1
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ SPAM
+ 1
+ SPAM
+ 19
+ Count
+ true
+
+ "xml"
+ "SQL_C_DEFAULT"
+
+
+
+ Account Number
+ 5
+ [Account Number]
+ [TestData]
+ Account Number
+ 2
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Account Number Burst Out Account
+ 130
+ [Account Number Burst Out Account]
+ [TestData]
+ Account Number Burst Out Account
+ 3
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Acct Name
+ 130
+ [Acct Name]
+ [TestData]
+ Acct Name
+ 4
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out
+ 130
+ [Burst Out]
+ [TestData]
+ Burst Out
+ 5
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out Join
+ 130
+ [Burst Out Join]
+ [TestData]
+ Burst Out Join
+ 6
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out Set list
+ 5
+ [Burst Out Set list]
+ [TestData]
+ Burst Out Set list
+ 7
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out View
+ 5
+ [Burst Out View]
+ [TestData]
+ Burst Out View
+ 8
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Count JE Number
+ 5
+ [Count JE Number]
+ [TestData]
+ Count JE Number
+ 9
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Entity ID
+ 130
+ [Entity ID]
+ [TestData]
+ Entity ID
+ 10
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Filter
+ 5
+ [Filter]
+ [TestData]
+ Filter
+ 11
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Fiscal Year
+ 130
+ [Fiscal Year]
+ [TestData]
+ Fiscal Year
+ 12
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Flag
+ 11
+ [Flag]
+ [TestData]
+ Flag
+ 13
+ boolean
+ Count
+ false
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Flag__copy_
+ 11
+ [Flag__copy_]
+ [TestData]
+ Flag__copy_
+ 14
+ boolean
+ Count
+ false
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ FS Line
+ 5
+ [FS Line]
+ [TestData]
+ FS Line
+ 15
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ FS Line Burst Out Account
+ 130
+ [FS Line Burst Out Account]
+ [TestData]
+ FS Line Burst Out Account
+ 16
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Group By
+ 5
+ [Group By]
+ [TestData]
+ Group By
+ 17
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Image
+ 130
+ [Image]
+ [TestData]
+ Image
+ 18
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Note Line
+ 5
+ [Note Line]
+ [TestData]
+ Note Line
+ 19
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Note Line Burst Out Account
+ 130
+ [Note Line Burst Out Account]
+ [TestData]
+ Note Line Burst Out Account
+ 20
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Selection
+ 5
+ [Selection]
+ [TestData]
+ Selection
+ 21
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ show
+ 130
+ [show]
+ [TestData]
+ show
+ 22
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Show Cycle Based
+ 130
+ [Show Cycle Based]
+ [TestData]
+ Show Cycle Based
+ 23
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sub Class
+ 5
+ [Sub Class]
+ [TestData]
+ Sub Class
+ 24
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ SubClass Burst Out Account
+ 130
+ [SubClass Burst Out Account]
+ [TestData]
+ SubClass Burst Out Account
+ 25
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Type
+ 130
+ [Type]
+ [TestData]
+ Type
+ 26
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Amount
+ 130
+ [Amount]
+ [TestData]
+ Amount
+ 27
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Amount1
+ 130
+ [Amount1]
+ [TestData]
+ Amount1
+ 28
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Count of Amount Calculation
+ 5
+ [Count of Amount Calculation]
+ [TestData]
+ Count of Amount Calculation
+ 29
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Number of Records
+ 5
+ [Number of Records]
+ [TestData]
+ Number of Records
+ 30
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Number of Records1
+ 5
+ [Number of Records1]
+ [TestData]
+ Number of Records1
+ 31
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Select Burst Out
+ 5
+ [Select Burst Out]
+ [TestData]
+ Select Burst Out
+ 32
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Select Transaction Analysis view
+ 5
+ [Select Transaction Analysis view]
+ [TestData]
+ Select Transaction Analysis view
+ 33
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Cy
+ 5
+ [Sum Cy]
+ [TestData]
+ Sum Cy
+ 34
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py1
+ 5
+ [Sum Py1]
+ [TestData]
+ Sum Py1
+ 35
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py2
+ 5
+ [Sum Py2]
+ [TestData]
+ Sum Py2
+ 36
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py3
+ 5
+ [Sum Py3]
+ [TestData]
+ Sum Py3
+ 37
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py4
+ 5
+ [Sum Py4]
+ [TestData]
+ Sum Py4
+ 38
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Total Credits
+ 5
+ [Total Credits]
+ [TestData]
+ Total Credits
+ 39
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Total Debits
+ 5
+ [Total Debits]
+ [TestData]
+ Total Debits
+ 40
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelTableType.true...column caption='TestData' datatype='table' name='[__tableau_internal_object_id__].[TestData_44D2C885FAEF453C846AC2CCD3577055]' role='measure' type='quantitative' />
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-graph>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.GroupActionAddRemove.true...add-or-remove-marks value='assign' />
+
+
+
+
+
+
+
+
+
+
+
+ Selection
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ([federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Calculation_88946136969252864:nk] / [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk])
+
+
+
+
+
+
+
+
+ Set Result
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ([federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk] / [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[io:BurstoutSet:nk])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[io:BurstoutSet:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Acct Name:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst-Out Set list:ok]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst-Out Set list:ok]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Calculation_88946136969252864:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Calculation_968836911996190720:nk]
+
+
+
+
+
+
+
+
+ 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
+
+
+
diff --git a/samples/preserve-namespaces/preserve-namespaces.py b/samples/preserve-namespaces/preserve-namespaces.py
new file mode 100644
index 0000000..0ecd424
--- /dev/null
+++ b/samples/preserve-namespaces/preserve-namespaces.py
@@ -0,0 +1,32 @@
+
+############################################################
+# Step 1) Use Workbook object from the Document API
+############################################################
+from tableaudocumentapi import Workbook
+
+
+def assertContainsUserNamespace(filename):
+ print('asserting on ' + filename)
+ with open(filename, 'r') as in_file:
+ # the namespace is in the first five lines for all the docs I've checked
+ lineCount = 0
+ doc_beginning_excerpt = ""
+ while lineCount < 5:
+ doc_beginning_excerpt += (in_file.readline().strip()) # first line should be xml tag
+ lineCount += 1
+ found = doc_beginning_excerpt.rfind("xmlns:user=")
+ print(doc_beginning_excerpt[found:found+10])
+ assert (found >= 0)
+
+
+############################################################
+# Step 2) Open the .twb we want to replicate
+############################################################
+assertContainsUserNamespace('filtering.twb')
+sourceWB = Workbook('filtering.twb')
+sourceWB.save_as('saved-as-filtering.twb')
+assertContainsUserNamespace('saved-as-filtering.twb')
+sourceWb2 = Workbook('TABLEAU_10_TWB.twb')
+sourceWb2.save_as('saved-as-tableau-10' + '.twb')
+# there was no namespace in the original
+# so there isn't one in the saved doc either assertContainsUserNamespace('saved-as-tableau-10.twb')
diff --git a/samples/show-fields/nested.tds b/samples/show-fields/nested.tds
new file mode 100644
index 0000000..ed5c3dd
--- /dev/null
+++ b/samples/show-fields/nested.tds
@@ -0,0 +1,780 @@
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...ObjectModelEncapsulateLegacy/>
+ <_.fcp.ObjectModelTableType.true...ObjectModelTableType/>
+ <_.fcp.SchemaViewerObjectModel.true...SchemaViewerObjectModel/>
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.false...relation connection="sqlserver.1nzmabo1alszdd1dqm0c11g0qr0m" name="TestData" table="[dbo].[TestData]" type="table"/>
+ <_.fcp.ObjectModelEncapsulateLegacy.true...relation connection="sqlserver.1nzmabo1alszdd1dqm0c11g0qr0m" name="TestData" table="[dbo].[TestData]" type="table"/>
+
+
+ Account Account Name
+ 130
+ [Account Account Name]
+ [TestData]
+ Account Account Name
+ 1
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Account Number
+ 5
+ [Account Number]
+ [TestData]
+ Account Number
+ 2
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Account Number Burst Out Account
+ 130
+ [Account Number Burst Out Account]
+ [TestData]
+ Account Number Burst Out Account
+ 3
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Acct Name
+ 130
+ [Acct Name]
+ [TestData]
+ Acct Name
+ 4
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out
+ 130
+ [Burst Out]
+ [TestData]
+ Burst Out
+ 5
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out Join
+ 130
+ [Burst Out Join]
+ [TestData]
+ Burst Out Join
+ 6
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out Set list
+ 5
+ [Burst Out Set list]
+ [TestData]
+ Burst Out Set list
+ 7
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out View
+ 5
+ [Burst Out View]
+ [TestData]
+ Burst Out View
+ 8
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Count JE Number
+ 5
+ [Count JE Number]
+ [TestData]
+ Count JE Number
+ 9
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Entity ID
+ 130
+ [Entity ID]
+ [TestData]
+ Entity ID
+ 10
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Filter
+ 5
+ [Filter]
+ [TestData]
+ Filter
+ 11
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Fiscal Year
+ 130
+ [Fiscal Year]
+ [TestData]
+ Fiscal Year
+ 12
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Flag
+ 11
+ [Flag]
+ [TestData]
+ Flag
+ 13
+ boolean
+ Count
+ false
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Flag__copy_
+ 11
+ [Flag__copy_]
+ [TestData]
+ Flag__copy_
+ 14
+ boolean
+ Count
+ false
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ FS Line
+ 5
+ [FS Line]
+ [TestData]
+ FS Line
+ 15
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ FS Line Burst Out Account
+ 130
+ [FS Line Burst Out Account]
+ [TestData]
+ FS Line Burst Out Account
+ 16
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Group By
+ 5
+ [Group By]
+ [TestData]
+ Group By
+ 17
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Image
+ 130
+ [Image]
+ [TestData]
+ Image
+ 18
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Note Line
+ 5
+ [Note Line]
+ [TestData]
+ Note Line
+ 19
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Note Line Burst Out Account
+ 130
+ [Note Line Burst Out Account]
+ [TestData]
+ Note Line Burst Out Account
+ 20
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Selection
+ 5
+ [Selection]
+ [TestData]
+ Selection
+ 21
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ show
+ 130
+ [show]
+ [TestData]
+ show
+ 22
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Show Cycle Based
+ 130
+ [Show Cycle Based]
+ [TestData]
+ Show Cycle Based
+ 23
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sub Class
+ 5
+ [Sub Class]
+ [TestData]
+ Sub Class
+ 24
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ SubClass Burst Out Account
+ 130
+ [SubClass Burst Out Account]
+ [TestData]
+ SubClass Burst Out Account
+ 25
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Type
+ 130
+ [Type]
+ [TestData]
+ Type
+ 26
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Amount
+ 130
+ [Amount]
+ [TestData]
+ Amount
+ 27
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Amount1
+ 130
+ [Amount1]
+ [TestData]
+ Amount1
+ 28
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Count of Amount Calculation
+ 5
+ [Count of Amount Calculation]
+ [TestData]
+ Count of Amount Calculation
+ 29
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Number of Records
+ 5
+ [Number of Records]
+ [TestData]
+ Number of Records
+ 30
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Number of Records1
+ 5
+ [Number of Records1]
+ [TestData]
+ Number of Records1
+ 31
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Select Burst Out
+ 5
+ [Select Burst Out]
+ [TestData]
+ Select Burst Out
+ 32
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Select Transaction Analysis view
+ 5
+ [Select Transaction Analysis view]
+ [TestData]
+ Select Transaction Analysis view
+ 33
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Cy
+ 5
+ [Sum Cy]
+ [TestData]
+ Sum Cy
+ 34
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py1
+ 5
+ [Sum Py1]
+ [TestData]
+ Sum Py1
+ 35
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py2
+ 5
+ [Sum Py2]
+ [TestData]
+ Sum Py2
+ 36
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py3
+ 5
+ [Sum Py3]
+ [TestData]
+ Sum Py3
+ 37
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py4
+ 5
+ [Sum Py4]
+ [TestData]
+ Sum Py4
+ 38
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Total Credits
+ 5
+ [Total Credits]
+ [TestData]
+ Total Credits
+ 39
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Total Debits
+ 5
+ [Total Debits]
+ [TestData]
+ Total Debits
+ 40
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelTableType.true...column caption="TestData" datatype="table" name="[__tableau_internal_object_id__].[TestData_44D2C885FAEF453C846AC2CCD3577055]" role="measure" type="quantitative"/>
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-graph>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/show-fields/new-world.tds b/samples/show-fields/new-world.tds
new file mode 100644
index 0000000..d9cd0d3
--- /dev/null
+++ b/samples/show-fields/new-world.tds
@@ -0,0 +1,954 @@
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...ObjectModelEncapsulateLegacy />
+ <_.fcp.ObjectModelTableType.true...ObjectModelTableType />
+ <_.fcp.SchemaViewerObjectModel.true...SchemaViewerObjectModel />
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.false...relation connection='World Indicatorsleaf' name='Extract' table='[Extract].[Extract]' type='table' />
+ <_.fcp.ObjectModelEncapsulateLegacy.true...relation connection='World Indicatorsleaf' name='Extract' table='[Extract].[Extract]' type='table' />
+
+
+
+
+
+ Birth Rate
+ 5
+ [Birth Rate]
+ [Extract]
+ Birth Rate
+ 0
+ English$
+ real
+ Sum
+ 48
+ true
+
+ 0.0070000000000000001
+ 0.052999999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 3
+ "asc"
+ 1
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Business Tax Rate
+ 5
+ [Business Tax Rate]
+ [Extract]
+ Business Tax Rate
+ 1
+ English$
+ real
+ Sum
+ 448
+ true
+
+ 0.082000000000000003
+ 3.391
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ CO2 Emissions
+ 3
+ [CO2 Emissions]
+ [Extract]
+ CO2 Emissions
+ 2
+ English$
+ integer
+ Sum
+ 1744
+ true
+
+ 7
+ 8286892
+
+
+ 4
+ "sint32"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Country
+ 129
+ [Country]
+ [Extract]
+ Country
+ 3
+ English$
+ string
+ Count
+ 208
+ 1
+ 1073741823
+ false
+
+
+ "Afghanistan"
+ "Zimbabwe"
+
+
+ "en_US_CI"
+ true
+ "heap"
+ true
+ 4294967292
+ 2
+ "asc"
+ 2
+ "str"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Days to Start Business
+ 2
+ [Days to Start Business]
+ [Extract]
+ Days to Start Business
+ 4
+ English$
+ integer
+ Sum
+ 127
+ true
+
+ 1
+ 694
+
+
+ true
+ "array"
+ true
+ 2
+ 1
+ "sint16"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Ease of Business
+ 2
+ [Ease of Business]
+ [Extract]
+ Ease of Business
+ 5
+ English$
+ integer
+ Sum
+ 186
+ true
+
+ 1
+ 189
+
+
+ true
+ "array"
+ true
+ 2
+ 1
+ "sint16"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Energy Usage
+ 3
+ [Energy Usage]
+ [Extract]
+ Energy Usage
+ 6
+ English$
+ integer
+ Sum
+ 1722
+ true
+
+ 8
+ 2727728
+
+
+ 4
+ "sint32"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ GDP
+ 20
+ [GDP]
+ [Extract]
+ GDP
+ 7
+ English$
+ integer
+ Sum
+ 2495
+ true
+
+ 63101272
+ 2147483647
+
+
+ 8
+ "sint64"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Health Exp % GDP
+ 5
+ [Health Exp % GDP]
+ [Extract]
+ Health Exp % GDP
+ 8
+ English$
+ real
+ Sum
+ 146
+ true
+
+ 0.0080000000000000002
+ 0.22500000000000001
+
+
+ true
+ "array"
+ true
+ 8
+ 1
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Health Exp/Capita
+ 2
+ [Health Exp/Capita]
+ [Extract]
+ Health Exp/Capita
+ 9
+ English$
+ integer
+ Sum
+ 1070
+ true
+
+ 2
+ 9908
+
+
+ 2
+ "sint16"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Hours to do Tax
+ 2
+ [Hours to do Tax]
+ [Extract]
+ Hours to do Tax
+ 10
+ English$
+ integer
+ Sum
+ 281
+ true
+
+ 12
+ 2600
+
+
+ 2
+ "sint16"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Infant Mortality Rate
+ 5
+ [Infant Mortality Rate]
+ [Extract]
+ Infant Mortality Rate
+ 11
+ English$
+ real
+ Sum
+ 130
+ true
+
+ 0.002
+ 0.14099999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 1
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Internet Usage
+ 5
+ [Internet Usage]
+ [Extract]
+ Internet Usage
+ 12
+ English$
+ real
+ Sum
+ 709
+ true
+
+ 0.0
+ 0.96199999999999997
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Lending Interest
+ 5
+ [Lending Interest]
+ [Extract]
+ Lending Interest
+ 13
+ English$
+ real
+ Sum
+ 352
+ true
+
+ 0.0050000000000000001
+ 4.9649999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Life Expectancy Female
+ 16
+ [Life Expectancy Female]
+ [Extract]
+ Life Expectancy Female
+ 14
+ English$
+ integer
+ Sum
+ 50
+ true
+
+ 39
+ 87
+
+
+ 1
+ "sint8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Life Expectancy Male
+ 16
+ [Life Expectancy Male]
+ [Extract]
+ Life Expectancy Male
+ 15
+ English$
+ integer
+ Sum
+ 48
+ true
+
+ 37
+ 88
+
+
+ 1
+ "sint8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Mobile Phone Usage
+ 5
+ [Mobile Phone Usage]
+ [Extract]
+ Mobile Phone Usage
+ 16
+ English$
+ real
+ Sum
+ 1179
+ true
+
+ 0.0
+ 2.8980000000000001
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Number of Records
+ 16
+ [Number of Records]
+ [Extract]
+ Number of Records
+ 17
+ integer
+ Sum
+ 1
+ false
+
+ 1
+ 1
+
+
+ "asc"
+ 1
+ "sint8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Population 0-14
+ 5
+ [Population 0-14]
+ [Extract]
+ Population 0-14
+ 18
+ English$
+ real
+ Sum
+ 377
+ true
+
+ 0.11799999999999999
+ 0.5
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Population 15-64
+ 5
+ [Population 15-64]
+ [Extract]
+ Population 15-64
+ 19
+ English$
+ real
+ Sum
+ 299
+ true
+
+ 0.47399999999999998
+ 0.85799999999999998
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Population 65+
+ 5
+ [Population 65+]
+ [Extract]
+ Population 65+
+ 20
+ English$
+ real
+ Sum
+ 209
+ true
+
+ 0.0030000000000000001
+ 0.24399999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 1
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Population Total
+ 3
+ [Population Total]
+ [Extract]
+ Population Total
+ 21
+ English$
+ integer
+ Sum
+ 2699
+ false
+
+ 18876
+ 1350695000
+
+
+ 4
+ "sint32"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Population Urban
+ 5
+ [Population Urban]
+ [Extract]
+ Population Urban
+ 22
+ English$
+ real
+ Sum
+ 823
+ true
+
+ 0.082000000000000003
+ 1.0
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Region
+ 129
+ [Region]
+ [Extract]
+ Region
+ 23
+ English$
+ string
+ Count
+ 6
+ 1
+ 1073741823
+ false
+
+
+ "Africa"
+ "The Americas"
+
+
+ "en_US_CI"
+ true
+ "heap"
+ true
+ 4294967292
+ 1
+ "asc"
+ 1
+ "str"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Tourism Inbound
+ 20
+ [Tourism Inbound]
+ [Extract]
+ Tourism Inbound
+ 24
+ English$
+ integer
+ Sum
+ 1651
+ true
+
+ 700000
+ 2147483647
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "sint64"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Tourism Outbound
+ 20
+ [Tourism Outbound]
+ [Extract]
+ Tourism Outbound
+ 25
+ English$
+ integer
+ Sum
+ 1458
+ true
+
+ 200000
+ 2147483647
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "sint64"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+ Year
+ 133
+ [Year]
+ [Extract]
+ Year
+ 26
+ English$
+ date
+ Year
+ 13
+ false
+
+ #2000-12-01#
+ #2012-12-01#
+
+
+ true
+ "array"
+ true
+ "asc"
+ 4
+ 0
+ "asc"
+ 1
+ "date"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Migrated Data]
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ % of Commercial profit
+
+
+
+
+
+
+ Kilotonnes of oil equivalent
+
+
+
+
+
+
+
+ Time required to start a business
+
+
+
+
+
+
+ 1=Ease
+
+
+
+
+
+
+ Kilotonnes
+
+
+
+
+
+
+ Gross domestic product
+
+
+
+
+
+
+ Healthcare expenditure as % of GDP
+
+
+
+
+
+
+ Healthcare expenditure per capita
+
+
+
+
+
+
+ Time to prepare and pay taxes for business
+
+
+
+
+
+
+ % of Population
+
+
+
+
+
+
+ Per Capita
+
+
+
+
+
+
+ A bank rate that meets private sectors' needs.
+
+
+
+
+
+
+ Years a newborn would live if prevailing patterns are the same
+
+
+
+
+
+
+ Years a newborn would live if prevailing patterns are the same
+
+
+
+
+
+
+ Per Capita
+
+
+
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ Total number of people in a country
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ Income from inbound tourism
+
+
+
+
+
+
+ Expenditure for outbound tourism
+
+
+
+ <_.fcp.ObjectModelTableType.true...column caption='Migrated Data' datatype='table' name='[__tableau_internal_object_id__].[Migrated Data]' role='measure' type='quantitative' />
+ <_.fcp.SchemaViewerObjectModel.false...folder name='Business' role='measures'>
+
+
+
+
+
+
+ <_.fcp.SchemaViewerObjectModel.false...folder name='Development' role='measures'>
+
+
+
+
+
+
+
+
+ <_.fcp.SchemaViewerObjectModel.false...folder name='Health' role='measures'>
+
+
+
+
+
+
+ <_.fcp.SchemaViewerObjectModel.false...folder name='Population' role='measures'>
+
+
+
+
+
+
+
+ <_.fcp.SchemaViewerObjectModel.true...folders-common>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-graph>
+
+
+
+
+
+
+
+
+
diff --git a/samples/show-fields/show_fields.py b/samples/show-fields/show_fields.py
index 84cdd44..f0fe493 100644
--- a/samples/show-fields/show_fields.py
+++ b/samples/show-fields/show_fields.py
@@ -6,26 +6,34 @@
############################################################
# Step 2) Open the .tds we want to inspect
############################################################
-sourceTDS = Datasource.from_file('world.tds')
+datasources = [Datasource.from_file('world.tds'), Datasource.from_file('nested.tds')]
+for sourceTDS in datasources:
-############################################################
-# Step 3) Print out all of the fields and what type they are
-############################################################
-print('----------------------------------------------------------')
-print('--- {} total fields in this datasource'.format(len(sourceTDS.fields)))
-print('----------------------------------------------------------')
-for count, field in enumerate(sourceTDS.fields.values()):
- print('{:>4}: {} is a {}'.format(count+1, field.name, field.datatype))
- blank_line = False
- if field.calculation:
- print(' the formula is {}'.format(field.calculation))
- blank_line = True
- if field.default_aggregation:
- print(' the default aggregation is {}'.format(field.default_aggregation))
- blank_line = True
- if field.description:
- print(' the description is {}'.format(field.description))
+ ############################################################
+ # Step 3) Print out all of the fields and what type they are
+ ############################################################
+ print('----------------------------------------------------------')
+ print('-- Info for our .tds:')
+ print('-- name:\t{0}'.format(sourceTDS.name))
+ print('-- version:\t{0}'.format(sourceTDS.version))
+ print('----------------------------------------------------------')
+ print('--- {} total fields in this datasource'.format(len(sourceTDS.fields)))
+ print('----------------------------------------------------------')
+ for count, field in enumerate(sourceTDS.fields.values()):
+ blank_line = False
+ if field.calculation:
+ print('{:>4}: field named `{}` is a `{}`'.format(count+1, field.name, field.datatype))
+ print(' field id, caption, calculation: `{}`, `{}`, `{}`'.format(field.id, field.caption,
+ field.calculation))
+ blank_line = True
+ if field.default_aggregation:
+ print('{:>4}: `{}` is a `{}`, default aggregation is `{}`'.format(count+1, field.name, field.datatype,
+ field.default_aggregation))
+
+ if field.description:
+ print('{:>4}: `{}` is a `{}`, description is `{}`'.format(count+1, field.name, field.datatype,
+ field.description))
- if blank_line:
- print('')
-print('----------------------------------------------------------')
+ if blank_line:
+ print('')
+ print('----------------------------------------------------------')
diff --git a/samples/show-fields/world.tds b/samples/show-fields/world.tds
deleted file mode 120000
index 5e73bb3..0000000
--- a/samples/show-fields/world.tds
+++ /dev/null
@@ -1 +0,0 @@
-../list-tds-info/world.tds
\ No newline at end of file
diff --git a/samples/show_workbook_info/geocoding.twbx b/samples/show_workbook_info/geocoding.twbx
new file mode 100644
index 0000000..2b99b6d
Binary files /dev/null and b/samples/show_workbook_info/geocoding.twbx differ
diff --git a/samples/show_workbook_info/show_workbook_info.py b/samples/show_workbook_info/show_workbook_info.py
new file mode 100644
index 0000000..d83d254
--- /dev/null
+++ b/samples/show_workbook_info/show_workbook_info.py
@@ -0,0 +1,43 @@
+############################################################
+# Step 1) Use Datasource object from the Document API
+############################################################
+from tableaudocumentapi import Workbook
+from lxml import etree as ET
+
+############################################################
+# Step 2) Open the .tds we want to explore
+############################################################
+sourceTWBX = Workbook('geocoding.twbx')
+
+############################################################
+# Step 3) List out info from the TWBX
+############################################################
+print('----------------------------------------------------------')
+print('-- Info for our .twbx:')
+print('-- name:\t{0}'.format(sourceTWBX.filename))
+print('-- CONTENTS')
+print('-- dashboards:\t{0}'.format(len(sourceTWBX.dashboards)))
+for dash in sourceTWBX.dashboards:
+ print("-- {}".format(dash))
+
+print('-- datasources:\t{0}'.format(len(sourceTWBX.datasources)))
+for data in sourceTWBX.datasources:
+ print("-- {}".format(data.name))
+
+print('-- worksheets:\t{0}'.format(len(sourceTWBX.worksheets)))
+for data in sourceTWBX.worksheets:
+ print("-- {}".format(data))
+
+print('-- shapes:\t{0}'.format(len(sourceTWBX.shapes)))
+for shape in sourceTWBX.shapes:
+ print("-- {}".format(shape))
+print('----------------------------------------------------------')
+
+worksheets = sourceTWBX.worksheets
+for worksheet in worksheets:
+ print("worksheet: {}".format(worksheet))
+ for datasource in sourceTWBX.datasources:
+ print("-- datasource: {}".format(datasource.name))
+ for count, field in enumerate(datasource.fields.values()):
+ if worksheet in field.worksheets:
+ print(field)
diff --git a/samples/list-tds-info/world.tds b/samples/show_workbook_info/world.tds
similarity index 98%
rename from samples/list-tds-info/world.tds
rename to samples/show_workbook_info/world.tds
index 25013e1..2b46609 100644
--- a/samples/list-tds-info/world.tds
+++ b/samples/show_workbook_info/world.tds
@@ -1,871 +1,871 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- Birth Rate
- 5
- [Birth Rate]
- [Extract]
- Birth Rate
- 0
- English$
- real
- Sum
- 48
- true
-
- 0.0070000000000000001
- 0.052999999999999999
-
-
- true
- "array"
- true
- 8
- 3
- "asc"
- 1
- "double"
-
-
-
- Business Tax Rate
- 5
- [Business Tax Rate]
- [Extract]
- Business Tax Rate
- 1
- English$
- real
- Sum
- 448
- true
-
- 0.082000000000000003
- 3.391
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- CO2 Emissions
- 3
- [CO2 Emissions]
- [Extract]
- CO2 Emissions
- 2
- English$
- integer
- Sum
- 1744
- true
-
- 7
- 8286892
-
-
- 4
- "sint32"
-
-
-
- Country
- 129
- [Country]
- [Extract]
- Country
- 3
- English$
- string
- Count
- 208
- 1
- 1073741823
- false
-
-
- "Afghanistan"
- "Zimbabwe"
-
-
- "en_US_CI"
- true
- "heap"
- true
- 4294967292
- 2
- "asc"
- 2
- "str"
-
-
-
- Days to Start Business
- 2
- [Days to Start Business]
- [Extract]
- Days to Start Business
- 4
- English$
- integer
- Sum
- 127
- true
-
- 1
- 694
-
-
- true
- "array"
- true
- 2
- 1
- "sint16"
-
-
-
- Ease of Business
- 2
- [Ease of Business]
- [Extract]
- Ease of Business
- 5
- English$
- integer
- Sum
- 186
- true
-
- 1
- 189
-
-
- true
- "array"
- true
- 2
- 1
- "sint16"
-
-
-
- Energy Usage
- 3
- [Energy Usage]
- [Extract]
- Energy Usage
- 6
- English$
- integer
- Sum
- 1722
- true
-
- 8
- 2727728
-
-
- 4
- "sint32"
-
-
-
- GDP
- 20
- [GDP]
- [Extract]
- GDP
- 7
- English$
- integer
- Sum
- 2495
- true
-
- 63101272
- 2147483647
-
-
- 8
- "sint64"
-
-
-
- Health Exp % GDP
- 5
- [Health Exp % GDP]
- [Extract]
- Health Exp % GDP
- 8
- English$
- real
- Sum
- 146
- true
-
- 0.0080000000000000002
- 0.22500000000000001
-
-
- true
- "array"
- true
- 8
- 1
- "double"
-
-
-
- Health Exp/Capita
- 2
- [Health Exp/Capita]
- [Extract]
- Health Exp/Capita
- 9
- English$
- integer
- Sum
- 1070
- true
-
- 2
- 9908
-
-
- 2
- "sint16"
-
-
-
- Hours to do Tax
- 2
- [Hours to do Tax]
- [Extract]
- Hours to do Tax
- 10
- English$
- integer
- Sum
- 281
- true
-
- 12
- 2600
-
-
- 2
- "sint16"
-
-
-
- Infant Mortality Rate
- 5
- [Infant Mortality Rate]
- [Extract]
- Infant Mortality Rate
- 11
- English$
- real
- Sum
- 130
- true
-
- 0.002
- 0.14099999999999999
-
-
- true
- "array"
- true
- 8
- 1
- "double"
-
-
-
- Internet Usage
- 5
- [Internet Usage]
- [Extract]
- Internet Usage
- 12
- English$
- real
- Sum
- 709
- true
-
- 0.0
- 0.96199999999999997
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- Lending Interest
- 5
- [Lending Interest]
- [Extract]
- Lending Interest
- 13
- English$
- real
- Sum
- 352
- true
-
- 0.0050000000000000001
- 4.9649999999999999
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- Life Expectancy Female
- 16
- [Life Expectancy Female]
- [Extract]
- Life Expectancy Female
- 14
- English$
- integer
- Sum
- 50
- true
-
- 39
- 87
-
-
- 1
- "sint8"
-
-
-
- Life Expectancy Male
- 16
- [Life Expectancy Male]
- [Extract]
- Life Expectancy Male
- 15
- English$
- integer
- Sum
- 48
- true
-
- 37
- 88
-
-
- 1
- "sint8"
-
-
-
- Mobile Phone Usage
- 5
- [Mobile Phone Usage]
- [Extract]
- Mobile Phone Usage
- 16
- English$
- real
- Sum
- 1179
- true
-
- 0.0
- 2.8980000000000001
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- Number of Records
- 16
- [Number of Records]
- [Extract]
- Number of Records
- 17
- integer
- Sum
- 1
- false
-
- 1
- 1
-
-
- "asc"
- 1
- "sint8"
-
-
-
- Population 0-14
- 5
- [Population 0-14]
- [Extract]
- Population 0-14
- 18
- English$
- real
- Sum
- 377
- true
-
- 0.11799999999999999
- 0.5
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- Population 15-64
- 5
- [Population 15-64]
- [Extract]
- Population 15-64
- 19
- English$
- real
- Sum
- 299
- true
-
- 0.47399999999999998
- 0.85799999999999998
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- Population 65+
- 5
- [Population 65+]
- [Extract]
- Population 65+
- 20
- English$
- real
- Sum
- 209
- true
-
- 0.0030000000000000001
- 0.24399999999999999
-
-
- true
- "array"
- true
- 8
- 1
- "double"
-
-
-
- Population Total
- 3
- [Population Total]
- [Extract]
- Population Total
- 21
- English$
- integer
- Sum
- 2699
- false
-
- 18876
- 1350695000
-
-
- 4
- "sint32"
-
-
-
- Population Urban
- 5
- [Population Urban]
- [Extract]
- Population Urban
- 22
- English$
- real
- Sum
- 823
- true
-
- 0.082000000000000003
- 1.0
-
-
- true
- "array"
- true
- 8
- 2
- "double"
-
-
-
- Region
- 129
- [Region]
- [Extract]
- Region
- 23
- English$
- string
- Count
- 6
- 1
- 1073741823
- false
-
-
- "Africa"
- "The Americas"
-
-
- "en_US_CI"
- true
- "heap"
- true
- 4294967292
- 1
- "asc"
- 1
- "str"
-
-
-
- Tourism Inbound
- 20
- [Tourism Inbound]
- [Extract]
- Tourism Inbound
- 24
- English$
- integer
- Sum
- 1651
- true
-
- 700000
- 2147483647
-
-
- true
- "array"
- true
- 8
- 2
- "sint64"
-
-
-
- Tourism Outbound
- 20
- [Tourism Outbound]
- [Extract]
- Tourism Outbound
- 25
- English$
- integer
- Sum
- 1458
- true
-
- 200000
- 2147483647
-
-
- true
- "array"
- true
- 8
- 2
- "sint64"
-
-
-
- Year
- 133
- [Year]
- [Extract]
- Year
- 26
- English$
- date
- Year
- 13
- false
-
- #2000-12-01#
- #2012-12-01#
-
-
- true
- "array"
- true
- "asc"
- 4
- 0
- "asc"
- 1
- "date"
-
-
-
-
-
-
-
- % of population
-
-
-
-
-
-
- % of Commercial profit
-
-
-
-
-
-
- Kilotonnes of oil equivalent
-
-
-
-
-
-
-
- Time required to start a business
-
-
-
-
-
-
- 1=Ease
-
-
-
-
-
-
- Kilotonnes
-
-
-
-
-
-
- Gross domestic product
-
-
-
-
-
-
- Healthcare expenditure as % of GDP
-
-
-
-
-
-
- Healthcare expenditure per capita
-
-
-
-
-
-
- Time to prepare and pay taxes for business
-
-
-
-
-
-
- % of Population
-
-
-
-
-
-
- Per Capita
-
-
-
-
-
-
- A bank rate that meets private sectors' needs.
-
-
-
-
-
-
- Years a newborn would live if prevailing patterns are the same
-
-
-
-
-
-
- Years a newborn would live if prevailing patterns are the same
-
-
-
-
-
-
- Per Capita
-
-
-
-
-
-
-
-
-
- % of population
-
-
-
-
-
-
- % of population
-
-
-
-
-
-
- % of population
-
-
-
-
-
-
- Total number of people in a country
-
-
-
-
-
-
- % of population
-
-
-
-
-
-
- Income from inbound tourism
-
-
-
-
-
-
- Expenditure for outbound tourism
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Birth Rate
+ 5
+ [Birth Rate]
+ [Extract]
+ Birth Rate
+ 0
+ English$
+ real
+ Sum
+ 48
+ true
+
+ 0.0070000000000000001
+ 0.052999999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 3
+ "asc"
+ 1
+ "double"
+
+
+
+ Business Tax Rate
+ 5
+ [Business Tax Rate]
+ [Extract]
+ Business Tax Rate
+ 1
+ English$
+ real
+ Sum
+ 448
+ true
+
+ 0.082000000000000003
+ 3.391
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ CO2 Emissions
+ 3
+ [CO2 Emissions]
+ [Extract]
+ CO2 Emissions
+ 2
+ English$
+ integer
+ Sum
+ 1744
+ true
+
+ 7
+ 8286892
+
+
+ 4
+ "sint32"
+
+
+
+ Country
+ 129
+ [Country]
+ [Extract]
+ Country
+ 3
+ English$
+ string
+ Count
+ 208
+ 1
+ 1073741823
+ false
+
+
+ "Afghanistan"
+ "Zimbabwe"
+
+
+ "en_US_CI"
+ true
+ "heap"
+ true
+ 4294967292
+ 2
+ "asc"
+ 2
+ "str"
+
+
+
+ Days to Start Business
+ 2
+ [Days to Start Business]
+ [Extract]
+ Days to Start Business
+ 4
+ English$
+ integer
+ Sum
+ 127
+ true
+
+ 1
+ 694
+
+
+ true
+ "array"
+ true
+ 2
+ 1
+ "sint16"
+
+
+
+ Ease of Business
+ 2
+ [Ease of Business]
+ [Extract]
+ Ease of Business
+ 5
+ English$
+ integer
+ Sum
+ 186
+ true
+
+ 1
+ 189
+
+
+ true
+ "array"
+ true
+ 2
+ 1
+ "sint16"
+
+
+
+ Energy Usage
+ 3
+ [Energy Usage]
+ [Extract]
+ Energy Usage
+ 6
+ English$
+ integer
+ Sum
+ 1722
+ true
+
+ 8
+ 2727728
+
+
+ 4
+ "sint32"
+
+
+
+ GDP
+ 20
+ [GDP]
+ [Extract]
+ GDP
+ 7
+ English$
+ integer
+ Sum
+ 2495
+ true
+
+ 63101272
+ 2147483647
+
+
+ 8
+ "sint64"
+
+
+
+ Health Exp % GDP
+ 5
+ [Health Exp % GDP]
+ [Extract]
+ Health Exp % GDP
+ 8
+ English$
+ real
+ Sum
+ 146
+ true
+
+ 0.0080000000000000002
+ 0.22500000000000001
+
+
+ true
+ "array"
+ true
+ 8
+ 1
+ "double"
+
+
+
+ Health Exp/Capita
+ 2
+ [Health Exp/Capita]
+ [Extract]
+ Health Exp/Capita
+ 9
+ English$
+ integer
+ Sum
+ 1070
+ true
+
+ 2
+ 9908
+
+
+ 2
+ "sint16"
+
+
+
+ Hours to do Tax
+ 2
+ [Hours to do Tax]
+ [Extract]
+ Hours to do Tax
+ 10
+ English$
+ integer
+ Sum
+ 281
+ true
+
+ 12
+ 2600
+
+
+ 2
+ "sint16"
+
+
+
+ Infant Mortality Rate
+ 5
+ [Infant Mortality Rate]
+ [Extract]
+ Infant Mortality Rate
+ 11
+ English$
+ real
+ Sum
+ 130
+ true
+
+ 0.002
+ 0.14099999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 1
+ "double"
+
+
+
+ Internet Usage
+ 5
+ [Internet Usage]
+ [Extract]
+ Internet Usage
+ 12
+ English$
+ real
+ Sum
+ 709
+ true
+
+ 0.0
+ 0.96199999999999997
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ Lending Interest
+ 5
+ [Lending Interest]
+ [Extract]
+ Lending Interest
+ 13
+ English$
+ real
+ Sum
+ 352
+ true
+
+ 0.0050000000000000001
+ 4.9649999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ Life Expectancy Female
+ 16
+ [Life Expectancy Female]
+ [Extract]
+ Life Expectancy Female
+ 14
+ English$
+ integer
+ Sum
+ 50
+ true
+
+ 39
+ 87
+
+
+ 1
+ "sint8"
+
+
+
+ Life Expectancy Male
+ 16
+ [Life Expectancy Male]
+ [Extract]
+ Life Expectancy Male
+ 15
+ English$
+ integer
+ Sum
+ 48
+ true
+
+ 37
+ 88
+
+
+ 1
+ "sint8"
+
+
+
+ Mobile Phone Usage
+ 5
+ [Mobile Phone Usage]
+ [Extract]
+ Mobile Phone Usage
+ 16
+ English$
+ real
+ Sum
+ 1179
+ true
+
+ 0.0
+ 2.8980000000000001
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ Number of Records
+ 16
+ [Number of Records]
+ [Extract]
+ Number of Records
+ 17
+ integer
+ Sum
+ 1
+ false
+
+ 1
+ 1
+
+
+ "asc"
+ 1
+ "sint8"
+
+
+
+ Population 0-14
+ 5
+ [Population 0-14]
+ [Extract]
+ Population 0-14
+ 18
+ English$
+ real
+ Sum
+ 377
+ true
+
+ 0.11799999999999999
+ 0.5
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ Population 15-64
+ 5
+ [Population 15-64]
+ [Extract]
+ Population 15-64
+ 19
+ English$
+ real
+ Sum
+ 299
+ true
+
+ 0.47399999999999998
+ 0.85799999999999998
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ Population 65+
+ 5
+ [Population 65+]
+ [Extract]
+ Population 65+
+ 20
+ English$
+ real
+ Sum
+ 209
+ true
+
+ 0.0030000000000000001
+ 0.24399999999999999
+
+
+ true
+ "array"
+ true
+ 8
+ 1
+ "double"
+
+
+
+ Population Total
+ 3
+ [Population Total]
+ [Extract]
+ Population Total
+ 21
+ English$
+ integer
+ Sum
+ 2699
+ false
+
+ 18876
+ 1350695000
+
+
+ 4
+ "sint32"
+
+
+
+ Population Urban
+ 5
+ [Population Urban]
+ [Extract]
+ Population Urban
+ 22
+ English$
+ real
+ Sum
+ 823
+ true
+
+ 0.082000000000000003
+ 1.0
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "double"
+
+
+
+ Region
+ 129
+ [Region]
+ [Extract]
+ Region
+ 23
+ English$
+ string
+ Count
+ 6
+ 1
+ 1073741823
+ false
+
+
+ "Africa"
+ "The Americas"
+
+
+ "en_US_CI"
+ true
+ "heap"
+ true
+ 4294967292
+ 1
+ "asc"
+ 1
+ "str"
+
+
+
+ Tourism Inbound
+ 20
+ [Tourism Inbound]
+ [Extract]
+ Tourism Inbound
+ 24
+ English$
+ integer
+ Sum
+ 1651
+ true
+
+ 700000
+ 2147483647
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "sint64"
+
+
+
+ Tourism Outbound
+ 20
+ [Tourism Outbound]
+ [Extract]
+ Tourism Outbound
+ 25
+ English$
+ integer
+ Sum
+ 1458
+ true
+
+ 200000
+ 2147483647
+
+
+ true
+ "array"
+ true
+ 8
+ 2
+ "sint64"
+
+
+
+ Year
+ 133
+ [Year]
+ [Extract]
+ Year
+ 26
+ English$
+ date
+ Year
+ 13
+ false
+
+ #2000-12-01#
+ #2012-12-01#
+
+
+ true
+ "array"
+ true
+ "asc"
+ 4
+ 0
+ "asc"
+ 1
+ "date"
+
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ % of Commercial profit
+
+
+
+
+
+
+ Kilotonnes of oil equivalent
+
+
+
+
+
+
+
+ Time required to start a business
+
+
+
+
+
+
+ 1=Ease
+
+
+
+
+
+
+ Kilotonnes
+
+
+
+
+
+
+ Gross domestic product
+
+
+
+
+
+
+ Healthcare expenditure as % of GDP
+
+
+
+
+
+
+ Healthcare expenditure per capita
+
+
+
+
+
+
+ Time to prepare and pay taxes for business
+
+
+
+
+
+
+ % of Population
+
+
+
+
+
+
+ Per Capita
+
+
+
+
+
+
+ A bank rate that meets private sectors' needs.
+
+
+
+
+
+
+ Years a newborn would live if prevailing patterns are the same
+
+
+
+
+
+
+ Years a newborn would live if prevailing patterns are the same
+
+
+
+
+
+
+ Per Capita
+
+
+
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ Total number of people in a country
+
+
+
+
+
+
+ % of population
+
+
+
+
+
+
+ Income from inbound tourism
+
+
+
+
+
+
+ Expenditure for outbound tourism
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setup.py b/setup.py
index 27d6a73..90668ae 100644
--- a/setup.py
+++ b/setup.py
@@ -1,16 +1,16 @@
-try:
- from setuptools import setup
-except ImportError:
- from distutils.core import setup
-
+from setuptools import setup
+
setup(
name='tableaudocumentapi',
- version='0.3',
- author='Tableau Software',
+ version='0.11',
+ author='Tableau',
author_email='github@tableau.com',
url='https://github.com/tableau/document-api-python',
packages=['tableaudocumentapi'],
license='MIT',
description='A Python module for working with Tableau files.',
- test_suite='test'
+ long_description="file: README.md",
+ long_description_content_type="text/markdown",
+ test_suite='test',
+ install_requires=['lxml']
)
diff --git a/tableaudocumentapi/connection.py b/tableaudocumentapi/connection.py
index 8e9eb58..f212820 100644
--- a/tableaudocumentapi/connection.py
+++ b/tableaudocumentapi/connection.py
@@ -1,27 +1,14 @@
-###############################################################################
-#
-# Connection - A class for writing connections to Tableau files
-#
-###############################################################################
-import xml.etree.ElementTree as ET
+from lxml import etree as ET
from tableaudocumentapi.dbclass import is_valid_dbclass
class Connection(object):
- """
- A class for writing connections to Tableau files.
-
- """
-
- ###########################################################################
- #
- # Public API.
- #
- ###########################################################################
+ """A class representing connections inside Data Sources."""
def __init__(self, connxml):
- """
- Constructor.
+ """Connection is usually instantiated by passing in connection elements
+ in a Data Source. If creating a connection from scratch you can call
+ `from_attributes` passing in the connection attributes.
"""
self._connectionXML = connxml
@@ -30,26 +17,38 @@ def __init__(self, connxml):
self._username = connxml.get('username')
self._authentication = connxml.get('authentication')
self._class = connxml.get('class')
+ self._schema = connxml.get('schema')
+ self._service = connxml.get('service')
+ self._port = connxml.get('port', None)
+ self._query_band = connxml.get('query-band-spec', None)
+ self._initial_sql = connxml.get('one-time-sql', None)
def __repr__(self):
return "''".format(self._server, self._dbname, hex(id(self)))
@classmethod
- def from_attributes(cls, server, dbname, username, dbclass, authentication=''):
+ def from_attributes(cls, server, dbname, username, dbclass, port=None, query_band=None,
+ initial_sql=None, authentication='', schema='', service=''):
+ """Creates a new connection that can be added into a Data Source.
+ defaults to `''` which will be treated as 'prompt' by Tableau."""
+
root = ET.Element('connection', authentication=authentication)
xml = cls(root)
xml.server = server
xml.dbname = dbname
xml.username = username
+ xml.schema = schema
+ xml.service = service
xml.dbclass = dbclass
+ xml.port = port
+ xml.query_band = query_band
+ xml.initial_sql = initial_sql
return xml
- ###########
- # dbname
- ###########
@property
def dbname(self):
+ """Database name for the connection. Not the table name."""
return self._dbname
@dbname.setter
@@ -67,11 +66,9 @@ def dbname(self, value):
self._dbname = value
self._connectionXML.set('dbname', value)
- ###########
- # server
- ###########
@property
def server(self):
+ """Hostname or IP address of the database server. May also be a URL in some connection types."""
return self._server
@server.setter
@@ -89,11 +86,9 @@ def server(self, value):
self._server = value
self._connectionXML.set('server', value)
- ###########
- # username
- ###########
@property
def username(self):
+ """Username used to authenticate to the database."""
return self._username
@username.setter
@@ -111,25 +106,147 @@ def username(self, value):
self._username = value
self._connectionXML.set('username', value)
- ###########
- # authentication
- ###########
@property
def authentication(self):
return self._authentication
- ###########
- # dbclass
- ###########
@property
def dbclass(self):
+ """The type of connection (e.g. 'MySQL', 'Postgresql'). A complete list
+ can be found in dbclass.py"""
return self._class
@dbclass.setter
def dbclass(self, value):
+ """Set the connection's dbclass property.
+
+ Args:
+ value: New dbclass value. String.
+
+ Returns:
+ Nothing.
+ """
if not is_valid_dbclass(value):
raise AttributeError("'{}' is not a valid database type".format(value))
self._class = value
self._connectionXML.set('class', value)
+
+ @property
+ def port(self):
+ """Port used to connect to the database."""
+ return self._port
+
+ @port.setter
+ def port(self, value):
+ """Set the connection's port property.
+
+ Args:
+ value: New port value. String.
+
+ Returns:
+ Nothing.
+ """
+
+ self._port = value
+ # If port is None we remove the element and don't write it to XML
+ if value is None:
+ try:
+ del self._connectionXML.attrib['port']
+ except KeyError:
+ pass
+ else:
+ self._connectionXML.set('port', value)
+
+ @property
+ def query_band(self):
+ """Query band passed on connection to database."""
+ return self._query_band
+
+ @query_band.setter
+ def query_band(self, value):
+ """Set the connection's query_band property.
+
+ Args:
+ value: New query_band value. String.
+
+ Returns:
+ Nothing.
+ """
+
+ self._query_band = value
+ # If query band is None we remove the element and don't write it to XML
+ if value is None:
+ try:
+ del self._connectionXML.attrib['query-band-spec']
+ except KeyError:
+ pass
+ else:
+ self._connectionXML.set('query-band-spec', value)
+
+ @property
+ def initial_sql(self):
+ """Initial SQL to be run."""
+ return self._initial_sql
+
+ @initial_sql.setter
+ def initial_sql(self, value):
+ """Set the connection's initial_sql property.
+
+ Args:
+ value: New initial_sql value. String.
+
+ Returns:
+ Nothing.
+ """
+
+ self._initial_sql = value
+ # If initial_sql is None we remove the element and don't write it to XML
+ if value is None:
+ try:
+ del self._connectionXML.attrib['one-time-sql']
+ except KeyError:
+ pass
+ else:
+ self._connectionXML.set('one-time-sql', value)
+
+ @property
+ def schema(self):
+ """Database schema for the connection. Not the table name."""
+ return self._schema
+
+ @schema.setter
+ def schema(self, value):
+ """
+ Set the connection's schema property.
+
+ Args:
+ value: New name of the database schema. String.
+
+ Returns:
+ Nothing.
+
+ """
+ self._schema = value
+ self._connectionXML.set('schema', value)
+
+ @property
+ def service(self):
+ """Database service for the connection. Not the table name."""
+ return self._service
+
+ @service.setter
+ def service(self, value):
+ """
+ Set the connection's service property.
+
+ Args:
+ value: New name of the database service. String.
+
+ Returns:
+ Nothing.
+
+ """
+ self._service = value
+ self._connectionXML.set('service', value)
diff --git a/tableaudocumentapi/datasource.py b/tableaudocumentapi/datasource.py
index dd3d5c5..6bfe80e 100644
--- a/tableaudocumentapi/datasource.py
+++ b/tableaudocumentapi/datasource.py
@@ -1,12 +1,6 @@
-###############################################################################
-#
-# Datasource - A class for writing datasources to Tableau files
-#
-###############################################################################
import collections
import itertools
-import random
-import xml.etree.ElementTree as ET
+from lxml import etree as ET
import xml.sax.saxutils as sax
from uuid import uuid4
@@ -15,15 +9,6 @@
from tableaudocumentapi.multilookup_dict import MultiLookupDict
from tableaudocumentapi.xfile import xml_open
-########
-# This is needed in order to determine if something is a string or not. It is necessary because
-# of differences between python2 (basestring) and python3 (str). If python2 support is every
-# dropped, remove this and change the basestring references below to str
-try:
- basestring
-except NameError: # pragma: no cover
- basestring = str
-########
_ColumnObjectReturnTuple = collections.namedtuple('_ColumnObjectReturnTupleType', ['id', 'object'])
@@ -31,12 +16,12 @@
def _get_metadata_xml_for_field(root_xml, field_name):
if "'" in field_name:
field_name = sax.escape(field_name, {"'": "'"})
- xpath = ".//metadata-record[@class='column'][local-name='{}']".format(field_name)
+ xpath = u".//metadata-record[@class='column'][local-name='{}']".format(field_name)
return root_xml.find(xpath)
def _is_used_by_worksheet(names, field):
- return any((y for y in names if y in field.worksheets))
+ return any(y for y in names if y in field.worksheets)
class FieldDictionary(MultiLookupDict):
@@ -44,7 +29,7 @@ class FieldDictionary(MultiLookupDict):
def used_by_sheet(self, name):
# If we pass in a string, no need to get complicated, just check to see if name is in
# the field's list of worksheets
- if isinstance(name, basestring):
+ if isinstance(name, str):
return [x for x in self.values() if name in x.worksheets]
# if we pass in a list, we need to check to see if any of the names in the list are in
@@ -88,25 +73,32 @@ def base36encode(number):
return sign + base36
-def make_unique_name(dbclass):
+def _make_unique_name(dbclass):
rand_part = base36encode(uuid4().int)
name = dbclass + '.' + rand_part
return name
class ConnectionParser(object):
+ """Parser for detecting and extracting connections from differing Tableau file formats."""
def __init__(self, datasource_xml, version):
self._dsxml = datasource_xml
self._dsversion = version
def _extract_federated_connections(self):
- return list(map(Connection, self._dsxml.findall('.//named-connections/named-connection/*')))
+ connections = list(map(Connection, self._dsxml.findall('.//named-connections/named-connection/*')))
+ # 'sqlproxy' connections (Tableau Server Connections) are not embedded into named-connection elements
+ # extract them manually for now
+ connections.extend(map(Connection, self._dsxml.findall("./connection[@class='sqlproxy']")))
+ return connections
def _extract_legacy_connection(self):
return list(map(Connection, self._dsxml.findall('connection')))
def get_connections(self):
+ """Find and return all connections based on file format version."""
+
if float(self._dsversion) < 10:
connections = self._extract_legacy_connection()
else:
@@ -115,16 +107,11 @@ def get_connections(self):
class Datasource(object):
- """
- A class for writing datasources to Tableau files.
+ """A class representing Tableau Data Sources, embedded in workbook files or
+ in TDS files.
"""
- ###########################################################################
- #
- # Public API.
- #
- ###########################################################################
def __init__(self, dsxml, filename=None):
"""
Constructor. Default is to create datasource from xml.
@@ -136,6 +123,7 @@ def __init__(self, dsxml, filename=None):
self._name = self._datasourceXML.get('name') or self._datasourceXML.get(
'formatted-name') # TDS files don't have a name attribute
self._version = self._datasourceXML.get('version')
+ self._caption = self._datasourceXML.get('caption', '')
self._connection_parser = ConnectionParser(
self._datasourceXML, version=self._version)
self._connections = self._connection_parser.get_connections()
@@ -143,13 +131,15 @@ def __init__(self, dsxml, filename=None):
@classmethod
def from_file(cls, filename):
- """Initialize datasource from file (.tds)"""
+ """Initialize datasource from file (.tds ot .tdsx)"""
- dsxml = xml_open(filename, cls.__name__.lower()).getroot()
+ dsxml = xml_open(filename, 'datasource').getroot()
return cls(dsxml, filename)
@classmethod
def from_connections(cls, caption, connections):
+ """Create a new Data Source give a list of Connections."""
+
root = ET.Element('datasource', caption=caption, version='10.0', inline='true')
outer_connection = ET.SubElement(root, 'connection')
outer_connection.set('class', 'federated')
@@ -157,7 +147,7 @@ def from_connections(cls, caption, connections):
for conn in connections:
nc = ET.SubElement(named_conns,
'named-connection',
- name=make_unique_name(conn.dbclass),
+ name=_make_unique_name(conn.dbclass),
caption=conn.server)
nc.append(conn._connectionXML)
return cls(root)
@@ -192,37 +182,54 @@ def save_as(self, new_filename):
xfile._save_file(self._filename, self._datasourceTree, new_filename)
- ###########
- # name
- ###########
@property
def name(self):
+ """ Name of the datasource. """
return self._name
- ###########
- # version
- ###########
@property
def version(self):
+ """ Version of the datasource. """
return self._version
- ###########
- # connections
- ###########
+ @property
+ def caption(self):
+ """ User defined name for the datasourse. """
+ return self._caption
+
+ @caption.setter
+ def caption(self, value):
+ self._datasourceXML.set('caption', value)
+ self._caption = value
+
+ @caption.deleter
+ def caption(self):
+ del self._datasourceXML.attrib['caption']
+ self._caption = ''
+
@property
def connections(self):
+ """ List of connections are used in workbook. """
return self._connections
- ###########
- # fields
- ###########
+ def clear_repository_location(self):
+ tag = self._datasourceXML.find('./repository-location')
+ if tag is not None:
+ self._datasourceXML.remove(tag)
+
@property
def fields(self):
+ """ Key-value result of field's names and its attributes. Dict. """
if not self._fields:
- self._fields = self._get_all_fields()
+ self._refresh_fields()
return self._fields
+ def _refresh_fields(self):
+ self._fields = self._get_all_fields()
+
def _get_all_fields(self):
+ # Some columns are represented by `column` tags and others as `metadata-record` tags
+ # Find them all and chain them into one dictionary
column_field_objects = self._get_column_objects()
existing_column_fields = [x.id for x in column_field_objects]
metadata_only_field_objects = (x for x in self._get_metadata_objects() if x.id not in existing_column_fields)
@@ -237,3 +244,81 @@ def _get_metadata_objects(self):
def _get_column_objects(self):
return [_column_object_from_column_xml(self._datasourceTree, xml)
for xml in self._datasourceTree.findall('.//column')]
+
+ def _get_custom_sql(self):
+ return [qry for qry in self._datasourceXML.iter('relation')]
+
+ def add_field(self, name, datatype, role, field_type, caption, hidden):
+ """ Adds a base field object with the given values.
+
+ Args:
+ name: Name of the new Field. String.
+ datatype: Datatype of the new field. String.
+ role: Role of the new field. String.
+ field_type: Type of the new field. String.
+ caption: Caption of the new field. String.
+
+ Returns:
+ The new field that was created. Field.
+ """
+ # TODO: A better approach would be to create an empty column and then
+ # use the input validation from its "Field"-object-representation to set values.
+ # However, creating an empty column causes errors :(
+
+ # If no caption is specified, create one with the same format Tableau does
+ if not caption:
+ caption = name.replace('[', '').replace(']', '').title()
+
+ # Create the elements
+ column = Field.create_field_xml(caption, datatype, hidden, role, field_type, name)
+
+ self._datasourceTree.getroot().append(column)
+
+ # Refresh fields to reflect changes and return the Field object
+ self._refresh_fields()
+ return self.fields[name]
+
+ def remove_field(self, field):
+ """ Remove a given field
+
+ Args:
+ field: The field to remove. ET.Element
+
+ Returns:
+ None
+ """
+ if not field or not isinstance(field, Field):
+ raise ValueError("Need to supply a field to remove element")
+
+ self._datasourceTree.getroot().remove(field.xml)
+ self._refresh_fields()
+
+ ###########
+ # Calculations
+ ###########
+ @property
+ def calculations(self):
+ """ Returns all calculated fields.
+ """
+ return {k: v for k, v in self.fields.items() if v.calculation is not None}
+
+ def add_calculation(self, caption, formula, datatype, role, type, hidden):
+ """ Adds a calculated field with the given values.
+
+ Args:
+ caption: Caption of the new calculation. String.
+ formula: Formula of the new calculation. String.
+ datatype: Datatype of the new calculation (string, integer, etc). String.
+ role: Role of the new calculation (Dimension or Measure). String.
+ type: Type of the new calculation (quantitative, ordinal, nominal). String.
+ hidden: Whether the new calculation is hidden. Boolean
+
+ Returns:
+ The new calculated field that was created. Field.
+ """
+ # Dynamically create the name of the field
+ name = '[Calculation_{}]'.format(str(uuid4().int)[:18])
+ field = self.add_field(name, datatype, role, type, caption, hidden)
+ field.calculation = formula
+
+ return field
diff --git a/tableaudocumentapi/dbclass.py b/tableaudocumentapi/dbclass.py
index b466452..ba51f21 100644
--- a/tableaudocumentapi/dbclass.py
+++ b/tableaudocumentapi/dbclass.py
@@ -5,6 +5,7 @@
'bigquery',
'asterncluster',
'bigsql',
+ 'composite',
'aurora',
'awshadoophive',
'dataengine',
diff --git a/tableaudocumentapi/field.py b/tableaudocumentapi/field.py
index 63cc72c..0da6d84 100644
--- a/tableaudocumentapi/field.py
+++ b/tableaudocumentapi/field.py
@@ -1,6 +1,8 @@
import functools
-import xml.etree.ElementTree as ET
+from lxml import etree as ET
+from xml.dom import minidom
+from tableaudocumentapi.property_decorators import argument_is_one_of
_ATTRIBUTES = [
'id', # Name of the field as specified in the file, usually surrounded by [ ]
@@ -11,6 +13,7 @@
'alias', # Name of the field as displayed in Tableau if the default name isn't wanted
'calculation', # If this field is a calculated field, this will be the formula
'description', # If this field has a description, this will be the description (including formatting tags)
+ 'hidden', # If this field has been hidden
]
_METADATA_ATTRIBUTES = [
@@ -45,12 +48,14 @@ def __init__(self, column_xml=None, metadata_xml=None):
if column_xml is not None:
self._initialize_from_column_xml(column_xml)
- # This isn't currently never called because of the way we get the data from the xml,
+ self._xml = column_xml
+ # This isn't currently called because of the way we get the data from the xml,
# but during the refactor, we might need it. This is commented out as a reminder
# if metadata_xml is not None:
# self.apply_metadata(metadata_xml)
elif metadata_xml is not None:
+ self._xml = metadata_xml
self._initialize_from_metadata_xml(metadata_xml)
else:
@@ -62,10 +67,22 @@ def _initialize_from_column_xml(self, xmldata):
def _initialize_from_metadata_xml(self, xmldata):
for metadata_name, field_name in _METADATA_TO_FIELD_MAP:
- self._apply_attribute(xmldata, field_name, lambda x: xmldata.find('.//{}'.format(metadata_name)).text,
+ self._apply_attribute(xmldata, field_name,
+ lambda x: getattr(xmldata.find('.//{}'.format(metadata_name)), 'text', None),
read_name=metadata_name)
self.apply_metadata(xmldata)
+ @classmethod
+ def create_field_xml(cls, caption, datatype, hidden, role, field_type, name):
+ column = ET.Element('column')
+ column.set('caption', caption)
+ column.set('datatype', datatype)
+ column.set('hidden', hidden)
+ column.set('role', role)
+ column.set('type', field_type)
+ column.set('name', name)
+ return column
+
########################################
# Special Case methods for construction fields from various sources
# not intended for client use
@@ -116,52 +133,240 @@ def id(self):
""" Name of the field as specified in the file, usually surrounded by [ ] """
return self._id
+ @property
+ def xml(self):
+ """ XML representation of the field. """
+ return self._xml
+
+ def pretty_xml(self):
+ """Return a pretty-printed XML string for the Element.
+ """
+ rough_string = ET.tostring(self._xml, 'utf-8')
+ prepared_string = minidom.parseString(rough_string)
+ print_string = prepared_string.toprettyxml(indent=" ", newl="")
+ return print_string.lstrip('')
+
+ def __str__(self):
+ """ String representation of the field (only includes usable attributes) """
+ # TODO: ideally this should just loop through the ATTRIBUTES so it doesn't need touching for new ones
+ output = "------ FIELD {} ({}/{}/{}): {}(type), {}(datatype), {}(role), {}(aggregation)".format(
+ self.name, self.caption, self.alias, self.id, self.type, self.datatype, self.role, self.default_aggregation)
+ return output
+
+ def detailed_str(self):
+ if self.calculation:
+ calc = "\ncalc: `{}`".format(self.calculation)
+ else:
+ calc = ""
+
+ ########################################
+ # Attribute getters and setters
+ ########################################
+
@property
def caption(self):
""" Name of the field as displayed in Tableau unless an aliases is defined """
return self._caption
+ @caption.setter
+ def caption(self, caption):
+ """ Set the caption of a field
+
+ Args:
+ caption: New caption. String.
+
+ Returns:
+ Nothing.
+ """
+ self._caption = caption
+ self._xml.set('caption', caption)
+
@property
def alias(self):
""" Name of the field as displayed in Tableau if the default name isn't wanted """
return self._alias
+ @alias.setter
+ def alias(self, alias):
+ """ Set the alias of a field
+
+ Args:
+ alias: New alias. String.
+
+ Returns:
+ Nothing.
+ """
+ self._alias = alias
+ self._xml.set('alias', alias)
+
@property
def datatype(self):
""" Type of the field within Tableau (string, integer, etc) """
return self._datatype
+ @datatype.setter
+ @argument_is_one_of('string', 'integer', 'date', 'boolean')
+ def datatype(self, datatype):
+ """ Set the datatype of a field
+
+ Args:
+ datatype: New datatype. String.
+
+ Returns:
+ Nothing.
+ """
+ self._datatype = datatype
+ self._xml.set('datatype', datatype)
+
+ @property
+ def hidden(self):
+ """ If the column is Hidden ('true', 'false') """
+ return self._hidden
+
+ @hidden.setter
+ @argument_is_one_of('true', 'false')
+ def hidden(self, hidden):
+ """ Set the hidden property of a field
+
+ Args:
+ hidden: New hidden. String.
+
+ Returns:
+ Nothing.
+ """
+ self._hidden = hidden
+ self._xml.set('hidden', hidden)
+
@property
def role(self):
""" Dimension or Measure """
return self._role
+ @role.setter
+ @argument_is_one_of('dimension', 'measure')
+ def role(self, role):
+ """ Set the role of a field
+
+ Args:
+ role: New role. String.
+
+ Returns:
+ Nothing.
+ """
+ self._role = role
+ self._xml.set('role', role)
+
+ @property
+ def type(self):
+ """ Type of field (quantitative, ordinal, nominal) """
+ return self._type
+
+ @type.setter
+ @argument_is_one_of('quantitative', 'ordinal', 'nominal')
+ def type(self, field_type):
+ """ Set the type of a field
+
+ Args:
+ field_type: New type. String.
+
+ Returns:
+ Nothing.
+ """
+ self._type = field_type
+ self._xml.set('type', field_type)
+
+ ########################################
+ # Aliases getter and setter
+ # Those are NOT the 'alias' field of the column,
+ # but instead the key-value aliases in its child elements
+ ########################################
+
+ def add_alias(self, key, value):
+ """ Add an alias for a given display value.
+
+ Args:
+ key: The data value to map. Example: "1". String.
+ value: The display value for the key. Example: "True". String.
+ Returns:
+ Nothing.
+ """
+
+ # determine whether there already is an aliases-tag
+ aliases = self._xml.find('aliases')
+ # and create it if there isn't
+ if not aliases: # ignore the FutureWarning, does not apply to our usage
+ aliases = ET.Element('aliases')
+ self._xml.append(aliases)
+
+ # find out if an alias with this key already exists and use it
+ existing_alias = [tag for tag in aliases.findall('alias') if tag.get('key') == key]
+ # if not, create a new ET.Element
+ alias = existing_alias[0] if existing_alias else ET.Element('alias')
+
+ alias.set('key', key)
+ alias.set('value', value)
+ if not existing_alias:
+ aliases.append(alias)
+
+ @property
+ def aliases(self):
+ """ Returns all aliases that are registered under this field.
+
+ Returns:
+ Key-value mappings of all registered aliases. Dict.
+ """
+ aliases_tag = self._xml.find('aliases') or [] # ignore the FutureWarning, does not apply to our usage
+ return {a.get('key', 'None'): a.get('value', 'None') for a in list(aliases_tag)}
+
+ ########################################
+ # Attribute getters
+ ########################################
+
@property
def is_quantitative(self):
""" A dependent value, usually a measure of something
e.g. Profit, Gross Sales """
- return self._type == 'quantitative'
+ return self.type == 'quantitative'
@property
def is_ordinal(self):
""" Is this field a categorical field that has a specific order
e.g. How do you feel? 1 - awful, 2 - ok, 3 - fantastic """
- return self._type == 'ordinal'
+ return self.type == 'ordinal'
@property
def is_nominal(self):
""" Is this field a categorical field that does not have a specific order
e.g. What color is your hair? """
- return self._type == 'nominal'
+ return self.type == 'nominal'
@property
def calculation(self):
""" If this field is a calculated field, this will be the formula """
return self._calculation
+ @calculation.setter
+ def calculation(self, new_calculation):
+ """ Set the calculation of a calculated field.
+
+ Args:
+ new_calculation: The new calculation/formula of the field. String.
+ """
+ if self.calculation is None:
+ calculation = ET.Element('calculation')
+ calculation.set('class', 'tableau')
+ calculation.set('formula', new_calculation)
+ # Append the elements to the respective structure
+ self._xml.append(calculation)
+
+ else:
+ self._xml.find('calculation').set('formula', new_calculation)
+
+ self._calculation = new_calculation
+
@property
def default_aggregation(self):
""" The default type of aggregation on the field (e.g Sum, Avg)"""
@@ -174,6 +379,7 @@ def description(self):
@property
def worksheets(self):
+ """ Worksheets which uses field. """
return list(self._worksheets)
######################################
@@ -199,4 +405,9 @@ def _read_description(xmldata):
if description is None:
return None
- return u'{}'.format(ET.tostring(description, encoding='utf-8')) # This is necessary for py3 support
+ description_string = ET.tostring(description, encoding='utf-8')
+ # Format expects a unicode string so in Python 2 we have to do the explicit conversion
+ if isinstance(description_string, bytes):
+ description_string = description_string.decode('utf-8')
+
+ return description_string
diff --git a/tableaudocumentapi/property_decorators.py b/tableaudocumentapi/property_decorators.py
new file mode 100644
index 0000000..aa82122
--- /dev/null
+++ b/tableaudocumentapi/property_decorators.py
@@ -0,0 +1,16 @@
+from functools import wraps
+
+
+def argument_is_one_of(*allowed_values):
+ def property_type_decorator(func):
+ @wraps(func)
+ def wrapper(self, value):
+ if value not in allowed_values:
+ error = "Invalid argument: {0}. {1} must be one of {2}."
+ msg = error.format(value, func.__name__, allowed_values)
+ raise ValueError(error)
+ return func(self, value)
+
+ return wrapper
+
+ return property_type_decorator
diff --git a/tableaudocumentapi/workbook.py b/tableaudocumentapi/workbook.py
index 1359356..4c425da 100644
--- a/tableaudocumentapi/workbook.py
+++ b/tableaudocumentapi/workbook.py
@@ -1,71 +1,59 @@
-###############################################################################
-#
-# Workbook - A class for writing Tableau workbook files
-#
-###############################################################################
-import os
-import zipfile
import weakref
-import xml.etree.ElementTree as ET
-
from tableaudocumentapi import Datasource, xfile
-from tableaudocumentapi.xfile import xml_open
+from tableaudocumentapi.xfile import xml_open, TableauInvalidFileException
class Workbook(object):
- """
- A class for writing Tableau workbook files.
-
- """
+ """A class for writing Tableau workbook files."""
- ###########################################################################
- #
- # Public API.
- #
- ###########################################################################
def __init__(self, filename):
- """
- Constructor.
+ """Open the workbook at `filename`. This will handle packaged and unpacked
+ workbook files automatically. This will also parse Data Sources and Worksheets
+ for access.
"""
self._filename = filename
- self._workbookTree = xml_open(self._filename, self.__class__.__name__.lower())
+ self._workbookTree = xml_open(self._filename, 'workbook')
+ if not self._workbookTree:
+ raise TableauInvalidFileException("Workbook file must have a workbook element at root")
self._workbookRoot = self._workbookTree.getroot()
- # prepare our datasource objects
+
+ self._dashboards = self._prepare_dashboards(self._workbookRoot)
+
self._datasources = self._prepare_datasources(
- self._workbookRoot) # self.workbookRoot.find('datasources')
+ self._workbookRoot)
self._datasource_index = self._prepare_datasource_index(self._datasources)
self._worksheets = self._prepare_worksheets(
- self._workbookRoot, self._datasource_index
- )
+ self._workbookRoot, self._datasource_index)
+
+ self._shapes = self._prepare_shapes(self._workbookRoot)
+
+ @property
+ def dashboards(self):
+ return self._dashboards
- ###########
- # datasources
- ###########
@property
def datasources(self):
return self._datasources
- ###########
- # worksheets
- ###########
@property
def worksheets(self):
return self._worksheets
- ###########
- # filename
- ###########
@property
def filename(self):
return self._filename
+ @property
+ def shapes(self):
+ return self._shapes
+
def save(self):
"""
Call finalization code and save file.
@@ -95,11 +83,6 @@ def save_as(self, new_filename):
xfile._save_file(
self._filename, self._workbookTree, new_filename)
- ###########################################################################
- #
- # Private API.
- #
- ###########################################################################
@staticmethod
def _prepare_datasource_index(datasources):
retval = weakref.WeakValueDictionary()
@@ -123,6 +106,20 @@ def _prepare_datasources(xml_root):
return datasources
+ @staticmethod
+ def _prepare_dashboards(xml_root):
+ dashboards = []
+
+ dashboard_elements = xml_root.find('.//dashboards')
+ if dashboard_elements is None:
+ return []
+
+ for dash_element in dashboard_elements:
+ dash_name = dash_element.attrib['name']
+ dashboards.append(dash_name)
+
+ return dashboards
+
@staticmethod
def _prepare_worksheets(xml_root, ds_index):
worksheets = []
@@ -145,3 +142,16 @@ def _prepare_worksheets(xml_root, ds_index):
datasource.fields[column_name].add_used_in(worksheet_name)
return worksheets
+
+ @staticmethod
+ def _prepare_shapes(xml_root):
+ shapes = []
+ worksheets_element = xml_root.find('.//external/shapes')
+ if worksheets_element is None:
+ return shapes
+
+ for worksheet_element in worksheets_element:
+ shape_name = worksheet_element.attrib['name']
+ shapes.append(shape_name)
+
+ return shapes
diff --git a/tableaudocumentapi/xfile.py b/tableaudocumentapi/xfile.py
index 66e5aac..8d2bb9f 100644
--- a/tableaudocumentapi/xfile.py
+++ b/tableaudocumentapi/xfile.py
@@ -3,12 +3,9 @@
import shutil
import tempfile
import zipfile
-import xml.etree.ElementTree as ET
+from lxml import etree as ET
-try:
- from distutils2.version import NormalizedVersion as Version
-except ImportError:
- from distutils.version import LooseVersion as Version
+from distutils.version import LooseVersion as Version
MIN_SUPPORTED_VERSION = Version("9.0")
@@ -22,20 +19,27 @@ class TableauInvalidFileException(Exception):
def xml_open(filename, expected_root=None):
+ """Opens the provided 'filename'. Handles detecting if the file is an archive,
+ detecting the document version, and validating the root tag."""
+ # Is the file a zip (.twbx or .tdsx)
if zipfile.is_zipfile(filename):
tree = get_xml_from_archive(filename)
else:
+ _register_all_namespaces()
tree = ET.parse(filename)
+ # Is the file a supported version
tree_root = tree.getroot()
-
file_version = Version(tree_root.attrib.get('version', '0.0'))
if file_version < MIN_SUPPORTED_VERSION:
raise TableauVersionNotSupportedException(file_version)
+ # Does the root tag match the object type (workbook or data source)
if expected_root and (expected_root != tree_root.tag):
+ if expected_root == 'workbook' and tree_root.tag == 'datasource':
+ return # A .twbx can contain .tds files if it contains custom geocoding.
raise TableauInvalidFileException(
"'{}'' is not a valid '{}' file".format(filename, expected_root))
@@ -51,8 +55,21 @@ def temporary_directory(*args, **kwargs):
shutil.rmtree(d)
+def _register_all_namespaces():
+ # TO DO: should look at the file to find namespaces, not hardcode this one
+ ET.register_namespace("user", "http://www.tableausoftware.com/xml/user")
+
+
def find_file_in_zip(zip_file):
- for filename in zip_file.namelist():
+ '''Returns the twb/tds file from a Tableau packaged file format. Packaged
+ files can contain cache entries which are also valid XML, so only look for
+ files with a .tds or .twb extension.
+ '''
+
+ candidate_files = filter(lambda x: x.split('.')[-1] in ('twb', 'tds'),
+ zip_file.namelist())
+
+ for filename in candidate_files:
with zip_file.open(filename) as xml_candidate:
try:
ET.parse(xml_candidate)
@@ -63,7 +80,7 @@ def find_file_in_zip(zip_file):
def get_xml_from_archive(filename):
- with zipfile.ZipFile(filename) as zf:
+ with zipfile.ZipFile(filename, allowZip64=True) as zf:
with zf.open(find_file_in_zip(zf)) as xml_file:
xml_tree = ET.parse(xml_file)
@@ -71,6 +88,10 @@ def get_xml_from_archive(filename):
def build_archive_file(archive_contents, zip_file):
+ """Build a Tableau-compatible archive file."""
+
+ # This is tested against Desktop and Server, and reverse engineered by lots
+ # of trial and error. Do not change this logic.
for root_dir, _, files in os.walk(archive_contents):
relative_dir = os.path.relpath(root_dir, archive_contents)
for f in files:
@@ -81,17 +102,17 @@ def build_archive_file(archive_contents, zip_file):
def save_into_archive(xml_tree, filename, new_filename=None):
- # Saving a archive means extracting the contents into a temp folder,
+ # Saving an 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
+ # packaging it back up into a zip with a very specific format
+ # e.g. no empty files for directories, which Windows and Mac do by default
if new_filename is None:
new_filename = filename
# Extract to temp directory
with temporary_directory() as temp_path:
- with zipfile.ZipFile(filename) as zf:
+ with zipfile.ZipFile(filename, allowZip64=True) as zf:
xml_file = find_file_in_zip(zf)
zf.extractall(temp_path)
# Write the new version of the file to the temp directory
@@ -99,16 +120,18 @@ def save_into_archive(xml_tree, filename, new_filename=None):
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:
+ with zipfile.ZipFile(new_filename, "w", compression=zipfile.ZIP_DEFLATED, allowZip64=True) 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
+ _register_all_namespaces() # this shouldn't be necessary, should be done on open
+
+ if new_filename is None:
+ new_filename = container_file
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)
+ xml_tree.write(new_filename, encoding="utf-8", xml_declaration=True)
diff --git a/test/__init__.py b/test/__init__.py
index c715da8..e69de29 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -1,2 +0,0 @@
-from . import bvt
-from . import test_datasource
diff --git a/test/assets/.gitignore b/test/assets/.gitignore
new file mode 100644
index 0000000..6aa8fd1
--- /dev/null
+++ b/test/assets/.gitignore
@@ -0,0 +1 @@
+field_change_test_output.tds
diff --git a/test/assets/CONNECTION.xml b/test/assets/CONNECTION.xml
index 392d112..56d17d5 100644
--- a/test/assets/CONNECTION.xml
+++ b/test/assets/CONNECTION.xml
@@ -1 +1 @@
-
+
diff --git a/test/assets/Cache.twbx b/test/assets/Cache.twbx
new file mode 100644
index 0000000..b1df6b7
Binary files /dev/null and b/test/assets/Cache.twbx differ
diff --git a/test/assets/TABLEAU_10_TDS.tds b/test/assets/TABLEAU_10_TDS.tds
index 7a81784..01fe7c3 100644
--- a/test/assets/TABLEAU_10_TDS.tds
+++ b/test/assets/TABLEAU_10_TDS.tds
@@ -1 +1 @@
-
+
diff --git a/test/assets/__init__.py b/test/assets/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/test/assets/datasource_test.tds b/test/assets/datasource_test.tds
index bfab77b..8fd2ffc 100644
--- a/test/assets/datasource_test.tds
+++ b/test/assets/datasource_test.tds
@@ -1,93 +1,108 @@
-
-
-
-
-
-
- a
- 130
- [a]
- [xy]
- a
- 1
- string
- Count
- 255
- true
-
- "SQL_WVARCHAR"
- "SQL_C_WCHAR"
- "true"
-
-
-
- Today's Date
- 130
- [Today's Date]
- [xy]
- a
- 1
- string
- Count
- 255
- true
-
- "SQL_WVARCHAR"
- "SQL_C_WCHAR"
- "true"
-
-
-
- x
- 3
- [x]
- [xy]
- x
- 2
- integer
- Sum
- 10
- true
-
- "SQL_INTEGER"
- "SQL_C_SLONG"
-
-
-
- y
- 3
- [y]
- [xy]
- y
- 3
- integer
- Sum
- 10
- true
-
- "SQL_INTEGER"
- "SQL_C_SLONG"
-
-
-
-
-
-
-
-
-
-
-
- A thing
-
Something will go here too, in a muted gray
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ a
+ 130
+ [a]
+ [xy]
+ a
+ 1
+ string
+ Count
+ 255
+ true
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Today's Date
+ 130
+ [Today's Date]
+ [xy]
+ a
+ 1
+ string
+ Count
+ 255
+ true
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ x
+ 3
+ [x]
+ [xy]
+ x
+ 2
+ integer
+ Sum
+ 10
+ true
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+ y
+ 3
+ [y]
+ [xy]
+ y
+ 3
+ integer
+ Sum
+ 10
+ true
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+ z
+ 1
+ [z]
+ [z]
+ z
+
+ true
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+
+
+
+
+
+
+
+
+ A thing
+
Something will go here too, in a muted gray
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/assets/field_change_test.tds b/test/assets/field_change_test.tds
new file mode 100644
index 0000000..dba389c
--- /dev/null
+++ b/test/assets/field_change_test.tds
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ name
+ 130
+ [name]
+ [my_data]
+ name
+ 1
+ string
+ Count
+ 8190
+ true
+ true
+
+
+ "SQL_WLONGVARCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ typ
+ 130
+ [typ]
+ [my_data]
+ typ
+ 2
+ string
+ Count
+ 8190
+ true
+ true
+
+
+ "SQL_WLONGVARCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ amount
+ 3
+ [amount]
+ [my_data]
+ amount
+ 3
+ integer
+ Sum
+ 10
+ true
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+ price
+ 5
+ [price]
+ [my_data]
+ price
+ 4
+ real
+ Sum
+ 17
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/assets/filtering.twb b/test/assets/filtering.twb
new file mode 100644
index 0000000..68cfcd3
--- /dev/null
+++ b/test/assets/filtering.twb
@@ -0,0 +1,1766 @@
+
+
+
+
+
+
+ <_.fcp.GroupActionAddRemove.true...GroupActionAddRemove />
+ <_.fcp.MarkAnimation.true...MarkAnimation />
+ <_.fcp.ObjectModelEncapsulateLegacy.true...ObjectModelEncapsulateLegacy />
+ <_.fcp.ObjectModelTableType.true...ObjectModelTableType />
+ <_.fcp.SchemaViewerObjectModel.true...SchemaViewerObjectModel />
+ <_.fcp.SetMembershipControl.true...SetMembershipControl />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.false...relation connection='sqlserver.1nzmabo1alszdd1dqm0c11g0qr0m' name='TestData' table='[dbo].[TestData]' type='table' />
+ <_.fcp.ObjectModelEncapsulateLegacy.true...relation connection='sqlserver.1nzmabo1alszdd1dqm0c11g0qr0m' name='TestData' table='[dbo].[TestData]' type='table' />
+
+
+ Account Account Name
+ 130
+ [Account Account Name]
+ [TestData]
+ Account Account Name
+ 1
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Account Number
+ 5
+ [Account Number]
+ [TestData]
+ Account Number
+ 2
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Account Number Burst Out Account
+ 130
+ [Account Number Burst Out Account]
+ [TestData]
+ Account Number Burst Out Account
+ 3
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Acct Name
+ 130
+ [Acct Name]
+ [TestData]
+ Acct Name
+ 4
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out
+ 130
+ [Burst Out]
+ [TestData]
+ Burst Out
+ 5
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out Join
+ 130
+ [Burst Out Join]
+ [TestData]
+ Burst Out Join
+ 6
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out Set list
+ 5
+ [Burst Out Set list]
+ [TestData]
+ Burst Out Set list
+ 7
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Burst Out View
+ 5
+ [Burst Out View]
+ [TestData]
+ Burst Out View
+ 8
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Count JE Number
+ 5
+ [Count JE Number]
+ [TestData]
+ Count JE Number
+ 9
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Entity ID
+ 130
+ [Entity ID]
+ [TestData]
+ Entity ID
+ 10
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Filter
+ 5
+ [Filter]
+ [TestData]
+ Filter
+ 11
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Fiscal Year
+ 130
+ [Fiscal Year]
+ [TestData]
+ Fiscal Year
+ 12
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Flag
+ 11
+ [Flag]
+ [TestData]
+ Flag
+ 13
+ boolean
+ Count
+ false
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Flag__copy_
+ 11
+ [Flag__copy_]
+ [TestData]
+ Flag__copy_
+ 14
+ boolean
+ Count
+ false
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ FS Line
+ 5
+ [FS Line]
+ [TestData]
+ FS Line
+ 15
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ FS Line Burst Out Account
+ 130
+ [FS Line Burst Out Account]
+ [TestData]
+ FS Line Burst Out Account
+ 16
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Group By
+ 5
+ [Group By]
+ [TestData]
+ Group By
+ 17
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Image
+ 130
+ [Image]
+ [TestData]
+ Image
+ 18
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Note Line
+ 5
+ [Note Line]
+ [TestData]
+ Note Line
+ 19
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Note Line Burst Out Account
+ 130
+ [Note Line Burst Out Account]
+ [TestData]
+ Note Line Burst Out Account
+ 20
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Selection
+ 5
+ [Selection]
+ [TestData]
+ Selection
+ 21
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ show
+ 130
+ [show]
+ [TestData]
+ show
+ 22
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Show Cycle Based
+ 130
+ [Show Cycle Based]
+ [TestData]
+ Show Cycle Based
+ 23
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sub Class
+ 5
+ [Sub Class]
+ [TestData]
+ Sub Class
+ 24
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ SubClass Burst Out Account
+ 130
+ [SubClass Burst Out Account]
+ [TestData]
+ SubClass Burst Out Account
+ 25
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Type
+ 130
+ [Type]
+ [TestData]
+ Type
+ 26
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Amount
+ 130
+ [Amount]
+ [TestData]
+ Amount
+ 27
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Amount1
+ 130
+ [Amount1]
+ [TestData]
+ Amount1
+ 28
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Count of Amount Calculation
+ 5
+ [Count of Amount Calculation]
+ [TestData]
+ Count of Amount Calculation
+ 29
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Number of Records
+ 5
+ [Number of Records]
+ [TestData]
+ Number of Records
+ 30
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Number of Records1
+ 5
+ [Number of Records1]
+ [TestData]
+ Number of Records1
+ 31
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Select Burst Out
+ 5
+ [Select Burst Out]
+ [TestData]
+ Select Burst Out
+ 32
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Select Transaction Analysis view
+ 5
+ [Select Transaction Analysis view]
+ [TestData]
+ Select Transaction Analysis view
+ 33
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Cy
+ 5
+ [Sum Cy]
+ [TestData]
+ Sum Cy
+ 34
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py1
+ 5
+ [Sum Py1]
+ [TestData]
+ Sum Py1
+ 35
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py2
+ 5
+ [Sum Py2]
+ [TestData]
+ Sum Py2
+ 36
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py3
+ 5
+ [Sum Py3]
+ [TestData]
+ Sum Py3
+ 37
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Sum Py4
+ 5
+ [Sum Py4]
+ [TestData]
+ Sum Py4
+ 38
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Total Credits
+ 5
+ [Total Credits]
+ [TestData]
+ Total Credits
+ 39
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+ Total Debits
+ 5
+ [Total Debits]
+ [TestData]
+ Total Debits
+ 40
+ real
+ Sum
+ 15
+ true
+
+ "SQL_FLOAT"
+ "SQL_C_DOUBLE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[TestData_44D2C885FAEF453C846AC2CCD3577055]
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelTableType.true...column caption='TestData' datatype='table' name='[__tableau_internal_object_id__].[TestData_44D2C885FAEF453C846AC2CCD3577055]' role='measure' type='quantitative' />
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-graph>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.GroupActionAddRemove.true...add-or-remove-marks value='assign' />
+
+
+
+
+
+
+
+
+
+
+
+ Selection
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ([federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Calculation_88946136969252864:nk] / [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk])
+
+
+
+
+
+
+
+
+ Set Result
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ([federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk] / [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[io:BurstoutSet:nk])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[io:BurstoutSet:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Acct Name:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst-Out Set list:ok]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst Out Set list:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Burst-Out Set list:ok]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Calculation_88946136969252864:nk]
+ [federated.1df63xu0j2dvhd1e3sooz18pbrcc].[none:Calculation_968836911996190720:nk]
+
+
+
+
+
+
+
+
+ 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
+
+
+
diff --git a/test/assets/index.py b/test/assets/index.py
new file mode 100644
index 0000000..8b374c2
--- /dev/null
+++ b/test/assets/index.py
@@ -0,0 +1,29 @@
+import os.path
+
+TEST_DIR = os.path.dirname(__file__)
+
+TABLEAU_82_TWB = os.path.join(TEST_DIR, 'TABLEAU_82_TWB.twb')
+
+TABLEAU_93_TWB = os.path.join(TEST_DIR, 'TABLEAU_93_TWB.twb')
+
+TABLEAU_93_TDS = os.path.join(TEST_DIR, 'TABLEAU_93_TDS.tds')
+
+TABLEAU_10_TDS = os.path.join(TEST_DIR, 'TABLEAU_10_TDS.tds')
+
+TABLEAU_10_TWB = os.path.join(TEST_DIR, 'TABLEAU_10_TWB.twb')
+
+TABLEAU_CONNECTION_XML = os.path.join(TEST_DIR, 'CONNECTION.xml')
+
+TABLEAU_10_TWBX = os.path.join(TEST_DIR, 'TABLEAU_10_TWBX.twbx')
+
+TABLEAU_10_TDSX = os.path.join(TEST_DIR, 'TABLEAU_10_TDSX.tdsx')
+
+EMPTY_WORKBOOK = os.path.join(TEST_DIR, 'empty_workbook.twb')
+
+MULTI_CONNECTION_10 = os.path.join(TEST_DIR, 'multiple_connections.twb')
+
+BAD_ZIP_FILE = os.path.join(TEST_DIR, 'BadZip.zip')
+
+TWBX_WITH_CACHE_FILES = os.path.join(TEST_DIR, 'Cache.twbx')
+
+COMPLEX_TWB = os.path.join(TEST_DIR, 'filtering.twb')
diff --git a/test/assets/multiple_connections.twb b/test/assets/multiple_connections.twb
new file mode 100644
index 0000000..0bdc774
--- /dev/null
+++ b/test/assets/multiple_connections.twb
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/assets/shapes_test.twb b/test/assets/shapes_test.twb
new file mode 100644
index 0000000..a6ccb55
--- /dev/null
+++ b/test/assets/shapes_test.twb
@@ -0,0 +1,3331 @@
+
+
+
+
+
+ <_.fcp.AnimationOnByDefault.true...AnimationOnByDefault />
+ <_.fcp.MarkAnimation.true...MarkAnimation />
+ <_.fcp.ObjectModelEncapsulateLegacy.true...ObjectModelEncapsulateLegacy />
+ <_.fcp.ObjectModelTableType.true...ObjectModelTableType />
+ <_.fcp.SchemaViewerObjectModel.true...SchemaViewerObjectModel />
+
+
+
+
+
+
+
+ <_.fcp.AnimationOnByDefault.false...style>
+ <_.fcp.AnimationOnByDefault.false..._.fcp.MarkAnimation.true...style-rule element='animation'>
+ <_.fcp.AnimationOnByDefault.false...format attr='animation-on' value='ao-on' />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.false...relation connection='excel-direct.0ozsbj20cdelf51evvdk71kugqg0' name='Orders' table='[Orders$]' type='table'>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...relation type='collection'>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ [Orders]
+
+ Count
+ true
+
+ 0
+ "A1:U9995:no:A1:U9995:0"
+ true
+ 6
+
+
+
+
+ 0
+ [People]
+
+ Count
+ true
+
+ 0
+ "A1:B5:no:A1:B5:0"
+ true
+ 6
+
+
+
+
+ 0
+ [Returns]
+
+ Count
+ true
+
+ 0
+ "A1:B801:no:A1:B801:0"
+ true
+ 6
+
+
+
+ Row ID
+ 20
+ [Row ID]
+ [Orders]
+ Row ID
+ 0
+ integer
+ Sum
+ true
+
+ "I8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Order ID
+ 130
+ [Order ID]
+ [Orders]
+ Order ID
+ 1
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Order Date
+ 7
+ [Order Date]
+ [Orders]
+ Order Date
+ 2
+ date
+ Year
+ true
+
+ "DATE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Ship Date
+ 7
+ [Ship Date]
+ [Orders]
+ Ship Date
+ 3
+ date
+ Year
+ true
+
+ "DATE"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Ship Mode
+ 130
+ [Ship Mode]
+ [Orders]
+ Ship Mode
+ 4
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Customer ID
+ 130
+ [Customer ID]
+ [Orders]
+ Customer ID
+ 5
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Customer Name
+ 130
+ [Customer Name]
+ [Orders]
+ Customer Name
+ 6
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Segment
+ 130
+ [Segment]
+ [Orders]
+ Segment
+ 7
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Country/Region
+ 130
+ [Country/Region]
+ [Orders]
+ Country/Region
+ 8
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ City
+ 130
+ [City]
+ [Orders]
+ City
+ 9
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ State
+ 130
+ [State]
+ [Orders]
+ State
+ 10
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Postal Code
+ 20
+ [Postal Code]
+ [Orders]
+ Postal Code
+ 11
+ integer
+ Sum
+ true
+
+ "I8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Region
+ 130
+ [Region]
+ [Orders]
+ Region
+ 12
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Product ID
+ 130
+ [Product ID]
+ [Orders]
+ Product ID
+ 13
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Category
+ 130
+ [Category]
+ [Orders]
+ Category
+ 14
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Sub-Category
+ 130
+ [Sub-Category]
+ [Orders]
+ Sub-Category
+ 15
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Product Name
+ 130
+ [Product Name]
+ [Orders]
+ Product Name
+ 16
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Sales
+ 5
+ [Sales]
+ [Orders]
+ Sales
+ 17
+ real
+ Sum
+ 15
+ true
+
+ "R8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Quantity
+ 20
+ [Quantity]
+ [Orders]
+ Quantity
+ 18
+ integer
+ Sum
+ true
+
+ "I8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Discount
+ 5
+ [Discount]
+ [Orders]
+ Discount
+ 19
+ real
+ Sum
+ 15
+ true
+
+ "R8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Profit
+ 5
+ [Profit]
+ [Orders]
+ Profit
+ 20
+ real
+ Sum
+ 15
+ true
+
+ "R8"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Orders_ECFCA1FB690A41FE803BC071773BA862]
+
+
+ Regional Manager
+ 130
+ [Regional Manager]
+ [People]
+ Regional Manager
+ 21
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[People_D73023733B004CC1B3CB1ACF62F4A965]
+
+
+ Region
+ 130
+ [Region (People)]
+ [People]
+ Region
+ 22
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[People_D73023733B004CC1B3CB1ACF62F4A965]
+
+
+ Returned
+ 130
+ [Returned]
+ [Returns]
+ Returned
+ 23
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Returns_2AA0FE4D737A4F63970131D0E7480A03]
+
+
+ Order ID
+ 130
+ [Order ID (Returns)]
+ [Returns]
+ Order ID
+ 24
+ string
+ Count
+ true
+
+
+ "WSTR"
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-id>[Returns_2AA0FE4D737A4F63970131D0E7480A03]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "3D Systems Cube Printer, 2nd Generation, Magenta"
+ "3D Systems Cube Printer, 2nd Generation, White"
+
+
+ "3M Hangers With Command Adhesive"
+ "3M Office Air Cleaner"
+ "3M Organizer Strips"
+ "3M Polarizing Light Filter Sleeves"
+ "3M Polarizing Task Lamp with Clamp Arm, Light Gray"
+ "3M Replacement Filter for Office Air Cleaner for 20' x 33' Room"
+
+
+ "Acco 3-Hole Punch"
+ "Acco 6 Outlet Guardian Basic Surge Suppressor"
+ "Acco 6 Outlet Guardian Premium Plus Surge Suppressor"
+ "Acco 6 Outlet Guardian Premium Surge Suppressor"
+ "Acco 6 Outlet Guardian Standard Surge Suppressor"
+ "Acco 7-Outlet Masterpiece Power Center, Wihtout Fax/Phone Line Protection"
+ "Acco Banker's Clasps, 5 3/4\"-Long"
+ "Acco Clips to Go Binder Clips, 24 Clips in Two Sizes"
+ "Acco D-Ring Binder w/DublLock"
+ "Acco Data Flex Cable Posts For Top & Bottom Load Binders, 6\" Capacity"
+ "Acco Economy Flexible Poly Round Ring Binder"
+ "Acco Expandable Hanging Binders"
+ "Acco Flexible ACCOHIDE Square Ring Data Binder, Dark Blue, 11 1/2\" X 14\" 7/8\""
+ "Acco Four Pocket Poly Ring Binder with Label Holder, Smoke, 1\""
+ "Acco Glide Clips"
+ "Acco Hanging Data Binders"
+ "Acco Hot Clips Clips to Go"
+ "Acco Perma 2700 Stacking Storage Drawers"
+ "Acco Perma 3000 Stacking Storage Drawers"
+ "Acco Perma 4000 Stacking Storage Drawers"
+ "Acco Pressboard Covers with Storage Hooks, 14 7/8\" x 11\", Dark Blue"
+ "Acco Pressboard Covers with Storage Hooks, 14 7/8\" x 11\", Executive Red"
+ "Acco Pressboard Covers with Storage Hooks, 14 7/8\" x 11\", Light Blue"
+ "Acco Pressboard Covers with Storage Hooks, 9 1/2\" x 11\", Executive Red"
+ "Acco PRESSTEX Data Binder with Storage Hooks, Dark Blue, 14 7/8\" X 11\""
+ "Acco PRESSTEX Data Binder with Storage Hooks, Dark Blue, 9 1/2\" X 11\""
+ "Acco PRESSTEX Data Binder with Storage Hooks, Light Blue, 9 1/2\" X 11\""
+ "Acco Recycled 2\" Capacity Laser Printer Hanging Data Binders"
+ "Acco Side-Punched Conventional Columnar Pads"
+ "Acco Six-Outlet Power Strip, 4' Cord Length"
+ "Acco Smartsocket Color-Coded Six-Outlet AC Adapter Model Surge Protectors"
+ "Acco Smartsocket Table Surge Protector, 6 Color-Coded Adapter Outlets"
+ "Acco Suede Grain Vinyl Round Ring Binder"
+ "Acco Translucent Poly Ring Binders"
+
+
+ "ACCOHIDE 3-Ring Binder, Blue, 1\""
+ "ACCOHIDE Binder by Acco"
+ "Accohide Poly Flexible Ring Binders"
+
+
+ "Acme 10\" Easy Grip Assistive Scissors"
+ "Acme 8\" Straight Scissors"
+ "Acme Box Cutter Scissors"
+ "Acme Design Line 8\" Stainless Steel Bent Scissors w/Champagne Handles, 3-1/8\" Cut"
+ "Acme Design Stainless Steel Bent Scissors"
+ "Acme Elite Stainless Steel Scissors"
+ "Acme Forged Steel Scissors with Black Enamel Handles"
+ "Acme Galleria Hot Forged Steel Scissors with Colored Handles"
+ "Acme Hot Forged Carbon Steel Scissors with Nickel-Plated Handles, 3 7/8\" Cut, 8\"L"
+ "Acme Kleen Earth Office Shears"
+ "Acme Kleencut Forged Steel Scissors"
+ "Acme Office Executive Series Stainless Steel Trimmers"
+ "Acme Preferred Stainless Steel Scissors"
+ "Acme Rosewood Handle Letter Opener"
+ "Acme Serrated Blade Letter Opener"
+ "Acme Softgrip Scissors"
+ "Acme Stainless Steel Office Snips"
+ "Acme Tagit Stainless Steel Antibacterial Scissors"
+ "Acme Titanium Bonded Scissors"
+ "Acme Value Line Scissors"
+
+
+ "Adams \"While You Were Out\" Message Pads"
+ "Adams Phone Message Book, 200 Message Capacity, 8 1/16” x 11”"
+ "Adams Phone Message Book, Professional, 400 Message Capacity, 5 3/6” x 11”"
+ "Adams Telephone Message Book W/Dividers/Space For Phone Numbers, 5 1/4\"X8 1/2\", 200/Messages"
+ "Adams Telephone Message Book W/Dividers/Space For Phone Numbers, 5 1/4\"X8 1/2\", 300/Messages"
+ "Adams Telephone Message Book w/Frequently-Called Numbers Space, 400 Messages per Book"
+ "Adams Telephone Message Books, 5 1/4” x 11”"
+ "Adams Write n' Stick Phone Message Book, 11\" X 5 1/4\", 200 Messages"
+ "Spiral Phone Message Books with Labels by Adams"
+
+
+ "Advantus 10-Drawer Portable Organizer, Chrome Metal Frame, Smoke Drawers"
+ "Advantus Employee of the Month Certificate Frame, 11 x 13-1/2"
+ "Advantus Map Pennant Flags and Round Head Tacks"
+ "Advantus Motivational Note Cards"
+ "Advantus Panel Wall Acrylic Frame"
+ "Advantus Panel Wall Certificate Holder - 8.5x11"
+ "Advantus Plastic Paper Clips"
+ "Advantus Push Pins"
+ "Advantus Push Pins, Aluminum Head"
+ "Advantus Rolling Drawer Organizers"
+ "Advantus Rolling Storage Box"
+ "Advantus SlideClip Paper Clips"
+ "Advantus T-Pin Paper Clips"
+
+
+ "Akro Stacking Bins"
+ "Akro-Mils 12-Gallon Tote"
+
+
+ "Alliance Big Bands Rubber Bands, 12/Pack"
+ "Alliance Rubber Bands"
+ "Alliance Super-Size Bands, Assorted Sizes"
+ "Sterling Rubber Bands by Alliance"
+
+
+ "Ampad \#10 Peel & Seel Holiday Envelopes"
+ "Ampad Evidence Wirebond Steno Books, 6\" x 9\""
+ "Ampad Gold Fibre Wirebound Steno Books, 6\" x 9\", Gregg Ruled"
+ "Ampad Phone Message Book, Recycled, 400 Message Capacity, 5 ¾” x 11”"
+ "Ampad Poly Cover Wirebound Steno Book, 6\" x 9\" Assorted Colors, Gregg Ruled"
+
+
+ "Angle-D Binders with Locking Rings, Label Holders"
+ "Angle-D Ring Binders"
+
+
+ "Anker 24W Portable Micro USB Car Charger"
+ "Anker 36W 4-Port USB Wall Charger Travel Power Adapter for iPhone 5s 5c 5"
+ "Anker Astro 15000mAh USB Portable Charger"
+ "Anker Astro Mini 3000mAh Ultra-Compact Portable Charger"
+ "Anker Ultra-Slim Mini Bluetooth 3.0 Wireless Keyboard"
+ "Anker Ultrathin Bluetooth Wireless Keyboard Aluminum Cover with Stand"
+
+
+ "Apple EarPods with Remote and Mic"
+ "Apple iPhone 5"
+ "Apple iPhone 5C"
+ "Apple iPhone 5S"
+
+
+ "Array Memo Cubes"
+ "Array Parchment Paper, Assorted Colors"
+
+
+ "AT&T 1070 Corded Phone"
+ "AT&T 1080 Corded phone"
+ "AT&T 1080 Phone"
+ "AT&T 17929 Lendline Telephone"
+ "AT&T 841000 Phone"
+ "AT&T CL2909"
+ "AT&T CL82213"
+ "AT&T CL83451 4-Handset Telephone"
+ "AT&T EL51110 DECT"
+ "AT&T SB67148 SynJ"
+ "AT&T TR1909W"
+
+
+ "Ativa D5772 2-Line 5.8GHz Digital Expandable Corded/Cordless Phone System with Answering & Caller ID/Call Waiting, Black/Silver"
+ "Ativa MDM8000 8-Sheet Micro-Cut Shredder"
+ "Ativa V4110MDD Micro-Cut Shredder"
+
+
+ "Atlantic Metals Mobile 2-Shelf Bookcases, Custom Colors"
+ "Atlantic Metals Mobile 3-Shelf Bookcases, Custom Colors"
+ "Atlantic Metals Mobile 4-Shelf Bookcases, Custom Colors"
+ "Atlantic Metals Mobile 5-Shelf Bookcases, Custom Colors"
+
+
+ "Avanti 1.7 Cu. Ft. Refrigerator"
+ "Avanti 4.4 Cu. Ft. Refrigerator"
+
+
+ "Avaya 4621SW VoIP phone"
+ "Avaya 5410 Digital phone"
+ "Avaya 5420 Digital phone"
+ "Avaya IP Phone 1140E VoIP phone"
+
+
+ "Avery 05222 Permanent Self-Adhesive File Folder Labels for Typewriters, on Rolls, White, 250/Roll"
+ "Avery 3 1/2\" Diskette Storage Pages, 10/Pack"
+ "Avery 4027 File Folder Labels for Dot Matrix Printers, 5000 Labels per Box, White"
+ "Avery 473"
+ "Avery 474"
+ "Avery 475"
+ "Avery 476"
+ "Avery 477"
+ "Avery 478"
+ "Avery 479"
+ "Avery 48"
+ "Avery 480"
+ "Avery 481"
+ "Avery 482"
+ "Avery 483"
+ "Avery 484"
+ "Avery 485"
+ "Avery 486"
+ "Avery 487"
+ "Avery 488"
+ "Avery 489"
+ "Avery 49"
+ "Avery 490"
+ "Avery 491"
+ "Avery 492"
+ "Avery 493"
+ "Avery 494"
+ "Avery 495"
+ "Avery 496"
+ "Avery 497"
+ "Avery 498"
+ "Avery 499"
+ "Avery 5"
+ "Avery 50"
+ "Avery 500"
+ "Avery 501"
+ "Avery 502"
+ "Avery 503"
+ "Avery 504"
+ "Avery 505"
+ "Avery 506"
+ "Avery 507"
+ "Avery 508"
+ "Avery 509"
+ "Avery 51"
+ "Avery 510"
+ "Avery 511"
+ "Avery 512"
+ "Avery 513"
+ "Avery 514"
+ "Avery 515"
+ "Avery 516"
+ "Avery 517"
+ "Avery 518"
+ "Avery 519"
+ "Avery 52"
+ "Avery 520"
+ "Avery Address/Shipping Labels for Typewriters, 4\" x 2\""
+ "Avery Arch Ring Binders"
+ "Avery Binder Labels"
+ "Avery Binding System Hidden Tab Executive Style Index Sets"
+ "Avery Durable Binders"
+ "Avery Durable Plastic 1\" Binders"
+ "Avery Durable Poly Binders"
+ "Avery Durable Slant Ring Binders"
+ "Avery Durable Slant Ring Binders With Label Holder"
+ "Avery Durable Slant Ring Binders, No Labels"
+ "Avery File Folder Labels"
+ "Avery Flip-Chart Easel Binder, Black"
+ "Avery Fluorescent Highlighter Four-Color Set"
+ "Avery Framed View Binder, EZD Ring (Locking), Navy, 1 1/2\""
+ "Avery Hanging File Binders"
+ "Avery Heavy-Duty EZD Binder With Locking Rings"
+ "Avery Heavy-Duty EZD View Binder with Locking Rings"
+ "Avery Hi-Liter Comfort Grip Fluorescent Highlighter, Yellow Ink"
+ "Avery Hi-Liter EverBold Pen Style Fluorescent Highlighters, 4/Pack"
+ "Avery Hi-Liter Fluorescent Desk Style Markers"
+ "Avery Hi-Liter GlideStik Fluorescent Highlighter, Yellow Ink"
+ "Avery Hi-Liter Pen Style Six-Color Fluorescent Set"
+ "Avery Hi-Liter Smear-Safe Highlighters"
+ "Avery Hidden Tab Dividers for Binding Systems"
+ "Avery Hole Reinforcements"
+ "Avery Legal 4-Ring Binder"
+ "Avery Metallic Poly Binders"
+ "Avery Non-Stick Binders"
+ "Avery Non-Stick Heavy Duty View Round Locking Ring Binders"
+ "Avery Personal Creations Heavyweight Cards"
+ "Avery Poly Binder Pockets"
+ "Avery Premier Heavy-Duty Binder with Round Locking Rings"
+ "Avery Printable Repositionable Plastic Tabs"
+ "Avery Recycled Flexi-View Covers for Binding Systems"
+ "Avery Reinforcements for Hole-Punch Pages"
+ "Avery Round Ring Poly Binders"
+ "Avery Self-Adhesive Photo Pockets for Polaroid Photos"
+ "Avery Trapezoid Extra Heavy Duty 4\" Binders"
+ "Avery Trapezoid Ring Binder, 3\" Capacity, Black, 1040 sheets"
+ "Avery Triangle Shaped Sheet Lifters, Black, 2/Pack"
+ "Avery White Multi-Purpose Labels"
+ "Black Avery Memo-Size 3-Ring Binder, 5 1/2\" x 8 1/2\""
+
+
+ "Balt Solid Wood Rectangular Table"
+ "Balt Solid Wood Round Tables"
+ "Balt Split Level Computer Training Table"
+
+
+ "Barricks 18\" x 48\" Non-Folding Utility Table with Bottom Storage Shelf"
+ "Barricks Non-Folding Utility Table with Steel Legs, Laminate Tops"
+
+
+ "Belkin 19\" Center-Weighted Shelf, Gray"
+ "Belkin 19\" Vented Equipment Shelf, Black"
+ "Belkin 325VA UPS Surge Protector, 6'"
+ "Belkin 5 Outlet SurgeMaster Power Centers"
+ "Belkin 6 Outlet Metallic Surge Strip"
+ "Belkin 7 Outlet SurgeMaster II"
+ "Belkin 7 Outlet SurgeMaster Surge Protector with Phone Protection"
+ "Belkin 7-Outlet SurgeMaster Home Series"
+ "Belkin 8 Outlet Surge Protector"
+ "Belkin 8 Outlet SurgeMaster II Gold Surge Protector"
+ "Belkin 8 Outlet SurgeMaster II Gold Surge Protector with Phone Protection"
+ "Belkin 8-Outlet Premiere SurgeMaster II Surge Protectors"
+ "Belkin F5C206VTEL 6 Outlet Surge"
+ "Belkin F8E887 USB Wired Ergonomic Keyboard"
+ "Belkin F9G930V10-GRY 9 Outlet Surge"
+ "Belkin F9H710-06 7 Outlet SurgeMaster Surge Protector"
+ "Belkin F9M820V08 8 Outlet Surge"
+ "Belkin F9S820V06 8 Outlet Surge"
+ "Belkin Grip Candy Sheer Case / Cover for iPhone 5 and 5S"
+ "Belkin iPhone and iPad Lightning Cable"
+ "Belkin OmniView SE Rackmount Kit"
+ "Belkin Premiere Surge Master II 8-outlet surge protector"
+ "Belkin QODE FastFit Bluetooth Keyboard"
+ "Belkin SportFit Armband For iPhone 5s/5c, Fuchsia"
+ "Belkin Standard 104 key USB Keyboard"
+
+
+ "Berol Giant Pencil Sharpener"
+
+
+ "Bestar Classic Bookcase"
+
+
+ "Bevis 36 x 72 Conference Tables"
+ "Bevis 44 x 96 Conference Tables"
+ "Bevis Boat-Shaped Conference Table"
+ "Bevis Oval Conference Table, Walnut"
+ "Bevis Rectangular Conference Tables"
+ "Bevis Round Bullnose 29\" High Table Top"
+ "Bevis Round Conference Room Tables and Bases"
+ "Bevis Round Conference Table Top & Single Column Base"
+ "Bevis Round Conference Table Top, X-Base"
+ "Bevis Steel Folding Chairs"
+ "Bevis Traditional Conference Table Top, Plinth Base"
+
+
+ "BIC Brite Liner Grip Highlighters"
+ "BIC Brite Liner Grip Highlighters, Assorted, 5/Pack"
+ "BIC Brite Liner Highlighters"
+ "BIC Brite Liner Highlighters, Chisel Tip"
+ "BIC Liqua Brite Liner"
+
+
+ "Binney & Smith Crayola Metallic Colored Pencils, 8-Color Set"
+ "Binney & Smith Crayola Metallic Crayons, 16-Color Pack"
+ "Binney & Smith inkTank Desk Highlighter, Chisel Tip, Yellow, 12/Box"
+ "Binney & Smith inkTank Erasable Desk Highlighter, Chisel Tip, Yellow, 12/Box"
+ "Binney & Smith inkTank Erasable Pocket Highlighter, Chisel Tip, Yellow"
+
+
+ "Bionaire 99.97\% HEPA Air Cleaner"
+ "Bionaire Personal Warm Mist Humidifier/Vaporizer"
+
+
+ "Boston 1645 Deluxe Heavier-Duty Electric Pencil Sharpener"
+ "Boston 16701 Slimline Battery Pencil Sharpener"
+ "Boston 16750 Black Compact Battery Pencil Sharpener"
+ "Boston 16765 Mini Stand Up Battery Pencil Sharpener"
+ "Boston 16801 Nautilus Battery Pencil Sharpener"
+ "Boston 1730 StandUp Electric Pencil Sharpener"
+ "Boston 1799 Powerhouse Electric Pencil Sharpener"
+ "Boston 1827 Commercial Additional Cutter, Drive Gear & Gear Rack for 1606"
+ "Boston 1900 Electric Pencil Sharpener"
+ "Boston 19500 Mighty Mite Electric Pencil Sharpener"
+ "Boston Electric Pencil Sharpener, Model 1818, Charcoal Black"
+ "Boston Heavy-Duty Trimline Electric Pencil Sharpeners"
+ "Boston Home & Office Model 2000 Electric Pencil Sharpeners"
+ "Boston KS Multi-Size Manual Pencil Sharpener"
+ "Boston Model 1800 Electric Pencil Sharpener, Gray"
+ "BOSTON Model 1800 Electric Pencil Sharpeners, Putty/Woodgrain"
+ "BOSTON Ranger \#55 Pencil Sharpener, Black"
+ "Boston School Pro Electric Pencil Sharpener, 1670"
+
+
+ "Bretford “Just In Time” Height-Adjustable Multi-Task Work Tables"
+ "Bretford CR4500 Series Slim Rectangular Table"
+ "Bretford CR8500 Series Meeting Room Furniture"
+ "Bretford Rectangular Conference Table Tops"
+
+
+ "Brother DCP1000 Digital 3 in 1 Multifunction Machine"
+ "Brother IntelliFAX-2840 Laser Fax"
+ "Brother IntelliFAX-5750e Plain Paper Fax Machine"
+ "Brother MFC-9340CDW LED All-In-One Printer, Copier Scanner"
+ "Brother MFC-J470DW Inkjet All-In-One Printer, Copier, Scanner"
+
+
+ "Bulldog Table or Wall-Mount Pencil Sharpener"
+ "Bulldog Vacuum Base Pencil Sharpener"
+
+
+ "Bush Advantage Collection Racetrack Conference Table"
+ "Bush Advantage Collection Round Conference Table"
+ "Bush Andora Bookcase, Maple/Graphite Gray Finish"
+ "Bush Andora Conference Table, Maple/Graphite Gray Finish"
+ "Bush Birmingham Collection Bookcase, Dark Cherry"
+ "Bush Cubix Collection Bookcases, Fully Assembled"
+ "Bush Cubix Conference Tables, Fully Assembled"
+ "Bush Heritage Pine Collection 5-Shelf Bookcase, Albany Pine Finish, *Special Order"
+ "Bush Mission Pointe Library"
+ "Bush Saratoga Collection 5-Shelf Bookcase, Hanover Cherry, *Special Order"
+ "Bush Somerset Collection Bookcase"
+ "Bush Westfield Collection Bookcases, Dark Cherry Finish"
+ "Bush Westfield Collection Bookcases, Medium Cherry Finish"
+
+
+ "C-Line Cubicle Keepers Polyproplyene Holder w/Velcro Back, 8-1/2x11, 25/Bx"
+ "C-Line Cubicle Keepers Polyproplyene Holder With Velcro Backings"
+ "C-Line Magnetic Cubicle Keepers, Clear Polypropylene"
+ "C-Line Peel & Stick Add-On Filing Pockets, 8-3/4 x 5-1/8, 10/Pack"
+
+
+ "Canon Color ImageCLASS MF8580Cdw Wireless Laser All-In-One Printer, Copier, Scanner"
+ "Canon Image Class D660 Copier"
+ "Canon imageCLASS 2200 Advanced Copier"
+ "Canon Imageclass D680 Copier / Fax"
+ "Canon imageCLASS MF7460 Monochrome Digital Laser Multifunction Copier"
+ "Canon PC-428 Personal Copier"
+ "Canon PC1060 Personal Laser Copier"
+ "Canon PC1080F Personal Copier"
+ "Canon PC170 Desktop Personal Copier"
+ "Canon PC940 Copier"
+
+
+ "Cardinal EasyOpen D-Ring Binders"
+ "Cardinal Hold-It CD Pocket"
+ "Cardinal Holdit Business Card Pockets"
+ "Cardinal Holdit Data Disk Pockets"
+ "Cardinal HOLDit! Binder Insert Strips,Extra Strips"
+ "Cardinal Poly Pocket Divider Pockets for Ring Binders"
+ "Cardinal Slant-D Ring Binder, Heavy Gauge Vinyl"
+ "Cardinal Slant-D Ring Binders"
+
+
+ "Carina 42\"Hx23 3/4\"W Media Storage Unit"
+ "Carina Double Wide Media Storage Towers in Natural & Black"
+ "Carina Media Storage Towers in Natural & Black"
+ "Carina Mini System Audio Rack, Model AR050B"
+
+
+ "Chromcraft 48\" x 96\" Racetrack Double Pedestal Table"
+ "Chromcraft Bull-Nose Wood 48\" x 96\" Rectangular Conference Tables"
+ "Chromcraft Bull-Nose Wood Oval Conference Tables & Bases"
+ "Chromcraft Bull-Nose Wood Round Conference Table Top, Wood Base"
+ "Chromcraft Rectangular Conference Tables"
+ "Chromcraft Round Conference Tables"
+
+
+ "Cisco 7975G IP Phone"
+ "Cisco 8961 IP Phone Charcoal"
+ "Cisco 8x8 Inc. 6753i IP Business Phone System"
+ "Cisco 9971 IP Video Phone Charcoal"
+ "Cisco CP-7936 Unified IP Conference Station Phone"
+ "Cisco CP-7937G Unified IP Conference Station Phone"
+ "Cisco Desktop Collaboration Experience DX650 IP Video Phone"
+ "Cisco IP Phone 7961G VoIP phone - Dark gray"
+ "Cisco IP Phone 7961G-GE VoIP phone"
+ "Cisco Small Business SPA 502G VoIP phone"
+ "Cisco SPA 501G IP Phone"
+ "Cisco SPA 502G IP Phone"
+ "Cisco SPA112 2 Port Phone Adapter"
+ "Cisco SPA301"
+ "Cisco SPA508G"
+ "Cisco SPA525G2 5-Line IP Phone"
+ "Cisco SPA525G2 IP Phone - Wireless"
+ "Cisco TelePresence System EX90 Videoconferencing Unit"
+ "Cisco Unified IP Phone 7945G VoIP phone"
+
+
+ "ClearOne CHATAttach 160 - speaker phone"
+ "ClearOne Communications CHAT 70 OC Speaker Phone"
+
+
+ "Clearsounds A400"
+ "ClearSounds CSC500 Amplified Spirit Phone Corded phone"
+
+
+ "Crayola Anti Dust Chalk, 12/Pack"
+ "Crayola Colored Pencils"
+
+
+ "Cubify CubeX 3D Printer Double Head Print"
+ "Cubify CubeX 3D Printer Triple Head Print"
+
+
+ "Dana Fluorescent Magnifying Lamp, White, 36\""
+ "Dana Halogen Swing-Arm Architect Lamp"
+ "Dana Swing-Arm Lamps"
+
+
+ "DAX Black Cherry Wood-Tone Poster Frame"
+ "DAX Charcoal/Nickel-Tone Document Frame, 5 x 7"
+ "Dax Clear Box Frame"
+ "DAX Clear Channel Poster Frame"
+ "DAX Contemporary Wood Frame with Silver Metal Mat, Desktop, 11 x 14 Size"
+ "DAX Copper Panel Document Frame, 5 x 7 Size"
+ "DAX Cubicle Frames - 8x10"
+ "DAX Cubicle Frames, 8-1/2 x 11"
+ "DAX Executive Solid Wood Document Frame, Desktop or Hang, Mahogany, 5 x 7"
+ "DAX Metal Frame, Desktop, Stepped-Edge"
+ "DAX Natural Wood-Tone Poster Frame"
+ "DAX Solid Wood Frames"
+ "DAX Two-Tone Rosewood/Black Document Frame, Desktop, 5 x 7"
+ "DAX Two-Tone Silver Metal Document Frame"
+ "DAX Value U-Channel Document Frames, Easel Back"
+ "DAX Wood Document Frame"
+ "DAX Wood Document Frame."
+
+
+ "Decoflex Hanging Personal Folder File"
+ "Decoflex Hanging Personal Folder File, Blue"
+
+
+ "Deflect-o DuraMat Antistatic Studded Beveled Mat for Medium Pile Carpeting"
+ "Deflect-o DuraMat Lighweight, Studded, Beveled Mat for Low Pile Carpeting"
+ "Deflect-o EconoMat Nonstudded, No Bevel Mat"
+ "Deflect-o EconoMat Studded, No Bevel Mat for Low Pile Carpeting"
+ "Deflect-o Glass Clear Studded Chair Mats"
+ "Deflect-O Glasstique Clear Desk Accessories"
+ "Deflect-o RollaMat Studded, Beveled Mat for Medium Pile Carpeting"
+ "Deflect-o SuperTray Unbreakable Stackable Tray, Letter, Black"
+
+
+ "Dixon My First Ticonderoga Pencil, \#2"
+ "DIXON Oriole Pencils"
+ "Dixon Prang Watercolor Pencils, 10-Color Set with Brush"
+ "Dixon Ticonderoga Core-Lock Colored Pencils"
+ "Dixon Ticonderoga Core-Lock Colored Pencils, 48-Color Set"
+ "DIXON Ticonderoga Erasable Checking Pencils"
+ "Dixon Ticonderoga Erasable Colored Pencil Set, 12-Color"
+ "Dixon Ticonderoga Maple Cedar Pencil, \#2"
+ "Dixon Ticonderoga Pencils"
+
+
+ "DMI Arturo Collection Mission-style Design Wood Chair"
+ "DMI Eclipse Executive Suite Bookcases"
+
+
+ "DXL Angle-View Binders with Locking Rings by Samsill"
+ "DXL Angle-View Binders with Locking Rings, Black"
+
+
+ "Eldon \"L\" Workstation Diamond Chairmat"
+ "Eldon 100 Class Desk Accessories"
+ "Eldon 200 Class Desk Accessories"
+ "Eldon 200 Class Desk Accessories, Black"
+ "Eldon 200 Class Desk Accessories, Burgundy"
+ "Eldon 200 Class Desk Accessories, Smoke"
+ "Eldon 300 Class Desk Accessories, Black"
+ "Eldon 400 Class Desk Accessories, Black Carbon"
+ "Eldon 500 Class Desk Accessories"
+ "Eldon Advantage Chair Mats for Low to Medium Pile Carpets"
+ "Eldon Advantage Foldable Chair Mats for Low Pile Carpets"
+ "Eldon Antistatic Chair Mats for Low to Medium Pile Carpets"
+ "Eldon Base for stackable storage shelf, platinum"
+ "Eldon Cleatmat Chair Mats for Medium Pile Carpets"
+ "Eldon Cleatmat Plus Chair Mats for High Pile Carpets"
+ "Eldon ClusterMat Chair Mat with Cordless Antistatic Protection"
+ "Eldon Delta Triangular Chair Mat, 52\" x 58\", Clear"
+ "Eldon Econocleat Chair Mats for Low Pile Carpets"
+ "Eldon Executive Woodline II Cherry Finish Desk Accessories"
+ "Eldon Executive Woodline II Desk Accessories, Mahogany"
+ "Eldon Expressions Desk Accessory, Wood Pencil Holder, Oak"
+ "Eldon Expressions Desk Accessory, Wood Photo Frame, Mahogany"
+ "Eldon Expressions Mahogany Wood Desk Collection"
+ "Eldon Expressions Punched Metal & Wood Desk Accessories, Black & Cherry"
+ "Eldon Expressions Punched Metal & Wood Desk Accessories, Pewter & Cherry"
+ "Eldon Expressions Wood and Plastic Desk Accessories, Cherry Wood"
+ "Eldon Expressions Wood and Plastic Desk Accessories, Oak"
+ "Eldon Expressions Wood Desk Accessories, Oak"
+ "Eldon File Chest Portable File"
+ "Eldon Fold 'N Roll Cart System"
+ "Eldon Gobal File Keepers"
+ "Eldon Image Series Black Desk Accessories"
+ "Eldon Image Series Desk Accessories, Burgundy"
+ "Eldon Imàge Series Desk Accessories, Clear"
+ "Eldon Image Series Desk Accessories, Ebony"
+ "Eldon Jumbo ProFile Portable File Boxes Graphite/Black"
+ "Eldon Mobile Mega Data Cart Mega Stackable Add-On Trays"
+ "Eldon Pizzaz Desk Accessories"
+ "Eldon Portable Mobile Manager"
+ "Eldon ProFile File 'N Store Portable File Tub Letter/Legal Size Black"
+ "Eldon Radial Chair Mat for Low to Medium Pile Carpets"
+ "Eldon Regeneration Recycled Desk Accessories, Black"
+ "Eldon Regeneration Recycled Desk Accessories, Smoke"
+ "Eldon Shelf Savers Cubes and Bins"
+ "Eldon Simplefile Box Office"
+ "Eldon Spacemaker Box, Quick-Snap Lid, Clear"
+ "Eldon Stackable Tray, Side-Load, Legal, Smoke"
+ "Eldon Wave Desk Accessories"
+
+
+ "Electrix 20W Halogen Replacement Bulb for Zoom-In Desk Lamp"
+ "Electrix Architect's Clamp-On Swing Arm Lamp, Black"
+ "Electrix Fluorescent Magnifier Lamps & Weighted Base"
+ "Electrix Halogen Magnifier Lamp"
+ "Electrix Incandescent Magnifying Lamp, Black"
+
+
+ "Enermax Acrylux Wireless Keyboard"
+ "Enermax Aurora Lite Keyboard"
+ "Enermax Briskie RF Wireless Keyboard and Mouse Combo"
+
+
+ "Epson Perfection V600 Photo Scanner"
+ "Epson TM-T88V Direct Thermal Printer - Monochrome - Desktop"
+ "Epson WorkForce WF-2530 All-in-One Printer, Copier Scanner"
+
+
+ "Eureka Disposable Bags for Sanitaire Vibra Groomer I Upright Vac"
+ "Eureka Hand Vacuum, Bagless"
+ "Eureka Recycled Copy Paper 8 1/2\" x 11\", Ream"
+ "Eureka Sanitaire Commercial Upright"
+ "Eureka Sanitaire Multi-Pro Heavy-Duty Upright, Disposable Bags"
+ "Eureka The Boss Cordless Rechargeable Stick Vac"
+ "Eureka The Boss Lite 10-Amp Upright Vacuum, Blue"
+ "Eureka The Boss Plus 12-Amp Hard Box Upright Vacuum, Red"
+
+
+ "Euro Pro Shark Stick Mini Vacuum"
+ "Euro-Pro Shark Turbo Vacuum"
+
+
+ "Executive Impressions 10\" Spectator Wall Clock"
+ "Executive Impressions 12\" Wall Clock"
+ "Executive Impressions 13-1/2\" Indoor/Outdoor Wall Clock"
+ "Executive Impressions 13\" Chairman Wall Clock"
+ "Executive Impressions 13\" Clairmont Wall Clock"
+ "Executive Impressions 14\""
+ "Executive Impressions 14\" Contract Wall Clock"
+ "Executive Impressions 14\" Contract Wall Clock with Quartz Movement"
+ "Executive Impressions 14\" Two-Color Numerals Wall Clock"
+ "Executive Impressions 16-1/2\" Circular Wall Clock"
+ "Executive Impressions 8-1/2\" Career Panel/Partition Cubicle Clock"
+ "Executive Impressions Supervisor Wall Clock"
+
+
+ "Fellowes 8 Outlet Superior Workstation Surge Protector"
+ "Fellowes 8 Outlet Superior Workstation Surge Protector w/o Phone/Fax/Modem Protection"
+ "Fellowes Advanced 8 Outlet Surge Suppressor with Phone/Fax Protection"
+ "Fellowes Advanced Computer Series Surge Protectors"
+ "Fellowes Bankers Box Recycled Super Stor/Drawer"
+ "Fellowes Bankers Box Staxonsteel Drawer File/Stacking System"
+ "Fellowes Bankers Box Stor/Drawer Steel Plus"
+ "Fellowes Bases and Tops For Staxonsteel/High-Stak Systems"
+ "Fellowes Basic Home/Office Series Surge Protectors"
+ "Fellowes Binding Cases"
+ "Fellowes Black Plastic Comb Bindings"
+ "Fellowes Command Center 5-outlet power strip"
+ "Fellowes Desktop Hanging File Manager"
+ "Fellowes Econo/Stor Drawers"
+ "Fellowes High-Stak Drawer Files"
+ "Fellowes Mighty 8 Compact Surge Protector"
+ "Fellowes Mobile File Cart, Black"
+ "Fellowes Neat Ideas Storage Cubes"
+ "Fellowes Officeware Wire Shelving"
+ "Fellowes PB200 Plastic Comb Binding Machine"
+ "Fellowes PB300 Plastic Comb Binding Machine"
+ "Fellowes PB500 Electric Punch Plastic Comb Binding Machine with Manual Bind"
+ "Fellowes Personal Hanging Folder Files, Navy"
+ "Fellowes Powershred HS-440 4-Sheet High Security Shredder"
+ "Fellowes Premier Superior Surge Suppressor, 10-Outlet, With Phone and Remote"
+ "Fellowes Presentation Covers for Comb Binding Machines"
+ "Fellowes Recycled Storage Drawers"
+ "Fellowes Smart Surge Ten-Outlet Protector, Platinum"
+ "Fellowes Staxonsteel Drawer Files"
+ "Fellowes Stor/Drawer Steel Plus Storage Drawers"
+ "Fellowes Strictly Business Drawer File, Letter/Legal Size"
+ "Fellowes Super Stor/Drawer"
+ "Fellowes Super Stor/Drawer Files"
+ "Fellowes Superior 10 Outlet Split Surge Protector"
+ "Fellowes Twister Kit, Gray/Clear, 3/pkg"
+
+
+ "First Data FD10 PIN Pad"
+ "First Data TMFD35 PIN Pad"
+
+
+ "Fiskars 8\" Scissors, 2/Pack"
+ "Fiskars Home & Office Scissors"
+ "Fiskars Softgrip Scissors"
+ "Fiskars Spring-Action Scissors"
+
+
+ "G.E. Halogen Desk Lamp Bulbs"
+ "G.E. Longer-Life Indoor Recessed Floodlight Bulbs"
+
+
+ "GBC Binding covers"
+ "GBC Clear Cover, 8-1/2 x 11, unpunched, 25 covers per pack"
+ "GBC DocuBind 200 Manual Binding Machine"
+ "GBC DocuBind 300 Electric Binding Machine"
+ "GBC DocuBind P100 Manual Binding Machine"
+ "GBC DocuBind P400 Electric Binding System"
+ "GBC DocuBind P50 Personal Binding Machine"
+ "GBC DocuBind TL200 Manual Binding Machine"
+ "GBC DocuBind TL300 Electric Binding System"
+ "GBC Durable Plastic Covers"
+ "GBC Ibimaster 500 Manual ProClick Binding System"
+ "GBC Imprintable Covers"
+ "GBC Instant Index System for Binding Systems"
+ "GBC Instant Report Kit"
+ "GBC Laser Imprintable Binding System Covers, Desert Sand"
+ "GBC Linen Binding Covers"
+ "GBC Personal VeloBind Strips"
+ "GBC Plastic Binding Combs"
+ "GBC Plasticlear Binding Covers"
+ "GBC Poly Designer Binding Covers"
+ "GBC Pre-Punched Binding Paper, Plastic, White, 8-1/2\" x 11\""
+ "GBC Premium Transparent Covers with Diagonal Lined Pattern"
+ "GBC Prepunched Paper, 19-Hole, for Binding Systems, 24-lb"
+ "GBC Prestige Therm-A-Bind Covers"
+ "GBC ProClick 150 Presentation Binding System"
+ "GBC ProClick Punch Binding System"
+ "GBC ProClick Spines for 32-Hole Punch"
+ "GBC Recycled Grain Textured Covers"
+ "GBC Recycled Regency Composition Covers"
+ "GBC Recycled VeloBinder Covers"
+ "GBC Standard Plastic Binding Systems Combs"
+ "GBC Standard Plastic Binding Systems' Combs"
+ "GBC Standard Recycled Report Covers, Clear Plastic Sheets"
+ "GBC Standard Therm-A-Bind Covers"
+ "GBC Therma-A-Bind 250T Electric Binding System"
+ "GBC Twin Loop Wire Binding Elements"
+ "GBC Twin Loop Wire Binding Elements, 9/16\" Spine, Black"
+ "GBC VeloBind Cover Sets"
+ "GBC Velobind Prepunched Cover Sets, Regency Series"
+ "GBC VeloBinder Electric Binding Machine"
+ "GBC VeloBinder Manual Binding System"
+ "GBC VeloBinder Strips"
+ "GBC White Gloss Covers, Plain Front"
+ "GBC Wire Binding Combs"
+ "GBC Wire Binding Strips"
+
+
+ "GE 2-Jack Phone Line Splitter"
+ "GE 30524EE4"
+ "GE 4 Foot Flourescent Tube, 40 Watt"
+ "GE 48\" Fluorescent Tube, Cool White Energy Saver, 34 Watts, 30/Box"
+ "GE DSL Phone Line Filter"
+ "GE General Purpose, Extra Long Life, Showcase & Floodlight Incandescent Bulbs"
+ "GE General Use Halogen Bulbs, 100 Watts, 1 Bulb per Pack"
+
+
+ "Global Adaptabilites Bookcase, Cherry/Storm Gray Finish"
+ "Global Adaptabilities Conference Tables"
+ "Global Airflow Leather Mesh Back Chair, Black"
+ "Global Armless Task Chair, Royal Blue"
+ "Global Chrome Stack Chair"
+ "Global Comet Stacking Arm Chair"
+ "Global Comet Stacking Armless Chair"
+ "Global Commerce Series High-Back Swivel/Tilt Chairs"
+ "Global Commerce Series Low-Back Swivel/Tilt Chairs"
+ "Global Deluxe High-Back Manager's Chair"
+ "Global Deluxe High-Back Office Chair in Storm"
+ "Global Deluxe Office Fabric Chairs"
+ "Global Deluxe Stacking Chair, Gray"
+ "Global Deluxe Steno Chair"
+ "Global Enterprise Series Seating High-Back Swivel/Tilt Chairs"
+ "Global Enterprise Series Seating Low-Back Swivel/Tilt Chairs"
+ "Global Ergonomic Managers Chair"
+ "Global Executive Mid-Back Manager's Chair"
+ "Global Fabric Manager's Chair, Dark Gray"
+ "Global Geo Office Task Chair, Gray"
+ "Global High-Back Leather Tilter, Burgundy"
+ "Global Highback Leather Tilter in Burgundy"
+ "Global Italian Leather Office Chair"
+ "Global Leather & Oak Executive Chair, Burgundy"
+ "Global Leather and Oak Executive Chair, Black"
+ "Global Leather Executive Chair"
+ "Global Leather Highback Executive Chair with Pneumatic Height Adjustment, Black"
+ "Global Leather Task Chair, Black"
+ "Global Low Back Tilter Chair"
+ "Global Manager's Adjustable Task Chair, Storm"
+ "Global Push Button Manager's Chair, Indigo"
+ "Global Stack Chair with Arms, Black"
+ "Global Stack Chair without Arms, Black"
+ "Global Super Steno Chair"
+ "Global Task Chair, Black"
+ "Global Troy Executive Leather Low-Back Tilter"
+ "Global Value Mid-Back Manager's Chair, Gray"
+ "Global Value Steno Chair, Gray"
+ "Global Wood Trimmed Manager's Task Chair, Khaki"
+ "Globe Weis Peel & Seel First Class Envelopes"
+
+
+ "Gould Plastics 18-Pocket Panel Bin, 34w x 5-1/4d x 20-1/2h"
+ "Gould Plastics 9-Pocket Panel Bin, 18-3/8w x 5-1/4d x 20-1/2h, Black"
+
+
+ "Grandstream GXP1160 VoIP phone"
+ "Grandstream GXP2100 Mainstream Business Phone"
+
+
+ "Griffin GC17055 Auxiliary Audio Cable"
+ "Griffin GC36547 PowerJolt SE Lightning Charger"
+
+
+ "Hammermill Color Copier Paper (28Lb. and 96 Bright)"
+ "Hammermill CopyPlus Copy Paper (20Lb. and 84 Bright)"
+
+
+ "Harmony Air Purifier"
+ "Harmony HEPA Quiet Air Purifiers"
+
+
+ "Hewlett Packard 310 Color Digital Copier"
+ "Hewlett Packard 610 Color Digital Copier / Printer"
+ "Hewlett Packard LaserJet 3310 Copier"
+ "Hewlett-Packard 300S Scientific Calculator"
+ "Hewlett-Packard Deskjet 3050a All-in-One Color Inkjet Printer"
+ "Hewlett-Packard Deskjet 5550 Printer"
+ "Hewlett-Packard Deskjet 6540 Color Inkjet Printer"
+ "Hewlett-Packard Deskjet D4360 Printer"
+ "Hewlett-Packard Deskjet F4180 All-in-One Color Ink-jet - Printer / copier / scanner"
+ "Hewlett-Packard Desktjet 6988DT Refurbished Printer"
+ "HP Designjet T1500 PostScript Inkjet Large Format Printer - 914mm"
+ "HP Designjet T520 Inkjet Large Format Printer - 24\" Color"
+
+
+ "Holmes 99\% HEPA Air Purifier"
+ "Holmes Cool Mist Humidifier for the Whole House with 8-Gallon Output per Day, Extended Life Filter"
+ "Holmes HEPA Air Purifier"
+ "Holmes Odor Grabber"
+ "Holmes Replacement Filter for HEPA Air Cleaner, Large Room"
+ "Holmes Replacement Filter for HEPA Air Cleaner, Medium Room"
+ "Holmes Replacement Filter for HEPA Air Cleaner, Very Large Room, HEPA Filter"
+ "Holmes Visible Mist Ultrasonic Humidifier with 2.3-Gallon Output per Day, Replacement Filter"
+
+
+ "Hon 2090 “Pillow Soft” Series Mid Back Swivel/Tilt Chairs"
+ "Hon 2111 Invitation Series Corner Table"
+ "Hon 2111 Invitation Series Straight Table"
+ "Hon 30\" x 60\" Table with Locking Drawer"
+ "Hon 4-Shelf Metal Bookcases"
+ "Hon 4060 Series Tables"
+ "Hon 4070 Series Pagoda Armless Upholstered Stacking Chairs"
+ "Hon 4070 Series Pagoda Round Back Stacking Chairs"
+ "Hon 4700 Series Mobuis Mid-Back Task Chairs with Adjustable Arms"
+ "Hon 5100 Series Wood Tables"
+ "HON 5400 Series Task Chairs for Big and Tall"
+ "Hon 61000 Series Interactive Training Tables"
+ "Hon 94000 Series Round Tables"
+ "Hon Comfortask Task/Swivel Chairs"
+ "Hon Deluxe Fabric Upholstered Stacking Chairs"
+ "Hon Deluxe Fabric Upholstered Stacking Chairs, Rounded Back"
+ "Hon Deluxe Fabric Upholstered Stacking Chairs, Squared Back"
+ "Hon Every-Day Chair Series Swivel Task Chairs"
+ "Hon Every-Day Series Multi-Task Chairs"
+ "Hon GuestStacker Chair"
+ "Hon iLevel Computer Training Table"
+ "Hon Metal Bookcases, Black"
+ "Hon Metal Bookcases, Gray"
+ "Hon Metal Bookcases, Putty"
+ "Hon Mobius Operator's Chair"
+ "Hon Multipurpose Stacking Arm Chairs"
+ "Hon Non-Folding Utility Tables"
+ "Hon Olson Stacker Chairs"
+ "Hon Olson Stacker Stools"
+ "Hon Pagoda Stacking Chairs"
+ "Hon Practical Foundations 30 x 60 Training Table, Light Gray/Charcoal"
+ "Hon Racetrack Conference Tables"
+ "Hon Rectangular Conference Tables"
+ "Hon Valutask Swivel Chairs"
+
+
+ "Honeywell Enviracaire Portable Air Cleaner for up to 8 x 10 Room"
+ "Honeywell Enviracaire Portable HEPA Air Cleaner for 16' x 20' Room"
+ "Honeywell Enviracaire Portable HEPA Air Cleaner for 17' x 22' Room"
+ "Honeywell Enviracaire Portable HEPA Air Cleaner for up to 10 x 16 Room"
+ "Honeywell Quietcare HEPA Air Cleaner"
+
+
+ "Hoover Commercial Lightweight Upright Vacuum"
+ "Hoover Commercial Lightweight Upright Vacuum with E-Z Empty Dirt Cup"
+ "Hoover Commercial Soft Guard Upright Vacuum And Disposable Filtration Bags"
+ "Hoover Commercial SteamVac"
+ "Hoover Portapower Portable Vacuum"
+ "Hoover Replacement Belt for Commercial Guardsman Heavy-Duty Upright Vacuum"
+ "Hoover Replacement Belts For Soft Guard & Commercial Ltweight Upright Vacs, 2/Pk"
+ "Hoover Shoulder Vac Commercial Portable Vacuum"
+ "Hoover Upright Vacuum With Dirt Cup"
+ "Hoover WindTunnel Plus Canister Vacuum"
+
+
+ "Howard Miller 11-1/2\" Diameter Brentwood Wall Clock"
+ "Howard Miller 11-1/2\" Diameter Grantwood Wall Clock"
+ "Howard Miller 11-1/2\" Diameter Ridgewood Wall Clock"
+ "Howard Miller 12-3/4 Diameter Accuwave DS Wall Clock"
+ "Howard Miller 12\" Round Wall Clock"
+ "Howard Miller 13-1/2\" Diameter Rosebrook Wall Clock"
+ "Howard Miller 13-3/4\" Diameter Brushed Chrome Round Wall Clock"
+ "Howard Miller 13\" Diameter Goldtone Round Wall Clock"
+ "Howard Miller 13\" Diameter Pewter Finish Round Wall Clock"
+ "Howard Miller 14-1/2\" Diameter Chrome Round Wall Clock"
+ "Howard Miller 16\" Diameter Gallery Wall Clock"
+ "Howard Miller Distant Time Traveler Alarm Clock"
+
+
+ "HP Office Paper (20Lb. and 87 Bright)"
+ "HP Office Recycled Paper (20Lb. and 87 Bright)"
+ "HP Officejet Pro 8600 e-All-In-One Printer, Copier, Scanner, Fax"
+ "HP Standard 104 key PS/2 Keyboard"
+
+
+ "HTC One"
+ "HTC One Mini"
+
+
+ "Hunt BOSTON Model 1606 High-Volume Electric Pencil Sharpener, Beige"
+ "Hunt Boston Vacuum Mount KS Pencil Sharpener"
+ "Hunt BOSTON Vista Battery-Operated Pencil Sharpener, Black"
+ "Hunt PowerHouse Electric Pencil Sharpener, Blue"
+
+
+ "Ibico Covers for Plastic or Wire Binding Elements"
+ "Ibico EB-19 Dual Function Manual Binding System"
+ "Ibico EPK-21 Electric Binding System"
+ "Ibico Hi-Tech Manual Binding System"
+ "Ibico Ibimaster 300 Manual Binding System"
+ "Ibico Laser Imprintable Binding System Covers"
+ "Ibico Plastic and Wire Spiral Binding Combs"
+ "Ibico Plastic Spiral Binding Combs"
+ "Ibico Presentation Index for Binding Systems"
+ "Ibico Recycled Grain-Textured Covers"
+ "Ibico Recycled Linen-Style Covers"
+ "Ibico Standard Transparent Covers"
+
+
+ "Iceberg Mobile Mega Data/Printer Cart"
+ "Iceberg Nesting Folding Chair, 19w x 6d x 43h"
+ "Iceberg OfficeWorks 42\" Round Tables"
+
+
+ "Imation 16GB Mini TravelDrive USB 2.0 Flash Drive"
+ "Imation 30456 USB Flash Drive 8GB"
+ "Imation 32GB Pocket Pro USB 3.0 Flash Drive - 32 GB - Black - 1 P ..."
+ "Imation 8gb Micro Traveldrive Usb 2.0 Flash Drive"
+ "Imation Bio 2GB USB Flash Drive Imation Corp"
+ "Imation Bio 8GB USB Flash Drive Imation Corp"
+ "Imation Clip USB flash drive - 8 GB"
+ "Imation Secure Drive + Hardware Encrypted USB flash drive - 16 GB"
+ "Imation Secure+ Hardware Encrypted USB 2.0 Flash Drive; 16GB"
+ "Imation Swivel Flash Drive USB flash drive - 8 GB"
+ "Imation USB 2.0 Swivel Flash Drive USB flash drive - 4 GB - Pink"
+
+
+ "iOttie HLCRIO102 Car Mount"
+ "iOttie XL Car Mount"
+
+
+ "Iris 3-Drawer Stacking Bin, Black"
+ "Iris Project Case"
+
+
+ "Jabra BIZ 2300 Duo QD Duo Corded Headset"
+ "Jabra SPEAK 410"
+ "Jabra SPEAK 410 Multidevice Speakerphone"
+ "Jabra Supreme Plus Driver Edition Headset"
+
+
+ "Jawbone JAMBOX Wireless Bluetooth Speaker"
+ "Jawbone MINI JAMBOX Wireless Bluetooth Speaker"
+
+
+ "Kensington 4 Outlet MasterPiece Compact Power Control Center"
+ "Kensington 6 Outlet Guardian Standard Surge Protector"
+ "Kensington 6 Outlet MasterPiece HOMEOFFICE Power Control Center"
+ "Kensington 6 Outlet SmartSocket Surge Protector"
+ "Kensington 7 Outlet MasterPiece HOMEOFFICE Power Control Center"
+ "Kensington 7 Outlet MasterPiece Power Center"
+ "Kensington 7 Outlet MasterPiece Power Center with Fax/Phone Line Protection"
+ "Kensington Expert Mouse Optical USB Trackball for PC or Mac"
+ "Kensington K72356US Mouse-in-a-Box USB Desktop Mouse"
+ "Kensington Orbit Wireless Mobile Trackball for PC and Mac"
+ "Kensington SlimBlade Notebook Wireless Mouse with Nano Receiver"
+
+
+ "KeyTronic 6101 Series - Keyboard - Black"
+ "KeyTronic E03601U1 - Keyboard - Beige"
+ "KeyTronic KT400U2 - Keyboard - Black"
+ "KeyTronic KT800P2 - Keyboard - Black"
+
+
+ "KI Adjustable-Height Table"
+ "KI Conference Tables"
+
+
+ "Kingston Digital DataTraveler 16GB USB 2.0"
+ "Kingston Digital DataTraveler 32GB USB 2.0"
+ "Kingston Digital DataTraveler 64GB USB 2.0"
+ "Kingston Digital DataTraveler 8GB USB 2.0"
+
+
+ "Lesro Round Back Collection Coffee Table, End Table"
+ "Lesro Sheffield Collection Coffee Table, End Table, Center Table, Corner Table"
+
+
+ "Lexmark 160 GB Internal Hard Drive"
+ "Lexmark 20R1285 X6650 Wireless All-in-One Printer"
+ "Lexmark Intuition S505 All-in-One Color Inkjet Printer"
+ "Lexmark MarkNet N8150 Wireless Print Server"
+ "Lexmark S315 Color Inkjet Printer"
+ "Lexmark X 9575 Professional All-in-One Color Printer"
+ "Lexmark X8350 All-in-One Color Inkjet Printer"
+
+
+ "LG Electronics Tone+ HBS-730 Bluetooth Headset"
+ "LG G2"
+ "LG G3"
+
+
+ "Linden 10\" Round Wall Clock, Black"
+ "Linden 12\" Wall Clock With Oak Frame"
+
+
+ "Logitech 910-002974 M325 Wireless Mouse for Web Scrolling"
+ "Logitech B530 USB Headset - headset - Full size, Binaural"
+ "Logitech ClearChat Comfort/USB Headset H390"
+ "Logitech Desktop MK120 Mouse and keyboard Combo"
+ "Logitech diNovo Edge Keyboard"
+ "Logitech G105 Gaming Keyboard"
+ "Logitech G13 Programmable Gameboard with LCD Display"
+ "Logitech G19 Programmable Gaming Keyboard"
+ "Logitech G35 7.1-Channel Surround Sound Headset"
+ "Logitech G430 Surround Sound Gaming Headset with Dolby 7.1 Technology"
+ "Logitech G500s Laser Gaming Mouse with Adjustable Weight Tuning"
+ "Logitech G600 MMO Gaming Mouse"
+ "Logitech G602 Wireless Gaming Mouse"
+ "Logitech G700s Rechargeable Gaming Mouse"
+ "Logitech Gaming G510s - Keyboard"
+ "Logitech Illuminated - Keyboard"
+ "Logitech Illuminated Ultrathin Keyboard with Backlighting"
+ "Logitech K350 2.4Ghz Wireless Keyboard"
+ "Logitech Keyboard K120"
+ "Logitech LS21 Speaker System - PC Multimedia - 2.1-CH - Wired"
+ "Logitech M510 Wireless Mouse"
+ "Logitech Media Keyboard K200"
+ "Logitech Mobile Speakerphone P710e - speaker phone"
+ "Logitech MX Performance Wireless Mouse"
+ "Logitech P710e Mobile Speakerphone"
+ "Logitech Trackman Marble Mouse"
+ "Logitech VX Revolution Cordless Laser Mouse for Notebooks (Black)"
+ "Logitech Wireless Anywhere Mouse MX for PC and Mac"
+ "Logitech Wireless Boombox Speaker - portable - wireless, wired"
+ "Logitech Wireless Gaming Headset G930"
+ "Logitech Wireless Headset H600 Over-The-Head Design"
+ "Logitech Wireless Headset h800"
+ "Logitech Wireless Keyboard K340"
+ "Logitech Wireless Marathon Mouse M705"
+ "Logitech Wireless Performance Mouse MX for PC and Mac"
+ "Logitech Wireless Touch Keyboard K400"
+ "Logitech Z-906 Speaker sys - home theater - 5.1-CH"
+
+
+ "Luxo Adjustable Task Clamp Lamp"
+ "Luxo Economy Swing Arm Lamp"
+ "Luxo Professional Combination Clamp-On Lamps"
+ "Luxo Professional Fluorescent Magnifier Lamp with Clamp-Mount Base"
+ "Luxo Professional Magnifying Clamp-On Fluorescent Lamps"
+
+
+ "Martin Yale Chadless Opener Electric Letter Opener"
+ "Martin-Yale Premier Letter Opener"
+
+
+ "Master Caster Door Stop, Brown"
+ "Master Caster Door Stop, Gray"
+ "Master Caster Door Stop, Large Brown"
+ "Master Caster Door Stop, Large Neon Orange"
+
+
+ "Maxell 4.7GB DVD-R"
+ "Maxell 4.7GB DVD-R 5/Pack"
+ "Maxell 4.7GB DVD-RW 3/Pack"
+ "Maxell 4.7GB DVD+R 5/Pack"
+ "Maxell 4.7GB DVD+RW 3/Pack"
+ "Maxell 74 Minute CD-R Spindle, 50/Pack"
+ "Maxell 74 Minute CDR, 10/Pack"
+ "Maxell CD-R Discs"
+ "Maxell DVD-RAM Discs"
+ "Maxell iVDR EX 500GB Cartridge"
+ "Maxell LTO Ultrium - 800 GB"
+ "Maxell Pro 80 Minute CD-R, 10/Pack"
+
+
+ "Memorex 25GB 6X Branded Blu-Ray Recordable Disc, 15/Pack"
+ "Memorex 25GB 6X Branded Blu-Ray Recordable Disc, 30/Pack"
+ "Memorex Froggy Flash Drive 4 GB"
+ "Memorex Froggy Flash Drive 8 GB"
+ "Memorex Micro Travel Drive 16 GB"
+ "Memorex Micro Travel Drive 32 GB"
+ "Memorex Micro Travel Drive 4 GB"
+ "Memorex Micro Travel Drive 8 GB"
+ "Memorex Mini Travel Drive 16 GB USB 2.0 Flash Drive"
+ "Memorex Mini Travel Drive 32 GB USB 2.0 Flash Drive"
+ "Memorex Mini Travel Drive 4 GB USB 2.0 Flash Drive"
+ "Memorex Mini Travel Drive 64 GB USB 2.0 Flash Drive"
+ "Memorex Mini Travel Drive 8 GB USB 2.0 Flash Drive"
+
+
+ "Message Book, Phone, Wirebound Standard Line Memo, 2 3/4\" X 5\""
+ "Message Book, Standard Line \"While You Were Out\", 5 1/2\" X 4\", 200 Sets/Book"
+ "Message Book, Wirebound, Four 5 1/2\" X 4\" Forms/Pg., 200 Dupl. Sets/Book"
+
+
+ "Micro Innovations USB RF Wireless Keyboard with Mouse"
+ "Micro Innovations Wireless Classic Keyboard with Mouse"
+
+
+ "Microsoft Arc Touch Mouse"
+ "Microsoft Natural Ergonomic Keyboard 4000"
+ "Microsoft Natural Keyboard Elite"
+ "Microsoft Sculpt Comfort Mouse"
+ "Microsoft Wireless Mobile Mouse 4000"
+
+
+ "Mitel 5320 IP Phone VoIP phone"
+ "Mitel MiVoice 5330e IP Phone"
+
+
+ "Motorla HX550 Universal Bluetooth Headset"
+ "Motorola Droid Maxx"
+ "Motorola HK250 Universal Bluetooth Headset"
+ "Motorola L703CM"
+ "Motorola L804"
+ "Motorola Moto X"
+
+
+ "NETGEAR AC1750 Dual Band Gigabit Smart WiFi Router"
+ "NETGEAR N750 Dual Band Wi-Fi Gigabit Router"
+ "NETGEAR RangeMax WNR1000 Wireless Router"
+
+
+ "Newell 3-Hole Punched Plastic Slotted Magazine Holders for Binders"
+ "Newell 307"
+ "Newell 308"
+ "Newell 309"
+ "Newell 31"
+ "Newell 310"
+ "Newell 311"
+ "Newell 312"
+ "Newell 313"
+ "Newell 314"
+ "Newell 315"
+ "Newell 316"
+ "Newell 317"
+ "Newell 318"
+ "Newell 319"
+ "Newell 32"
+ "Newell 320"
+ "Newell 321"
+ "Newell 322"
+ "Newell 323"
+ "Newell 324"
+ "Newell 325"
+ "Newell 326"
+ "Newell 327"
+ "Newell 328"
+ "Newell 329"
+ "Newell 33"
+ "Newell 330"
+ "Newell 331"
+ "Newell 332"
+ "Newell 333"
+ "Newell 334"
+ "Newell 335"
+ "Newell 336"
+ "Newell 337"
+ "Newell 338"
+ "Newell 339"
+ "Newell 34"
+ "Newell 340"
+ "Newell 341"
+ "Newell 342"
+ "Newell 343"
+ "Newell 344"
+ "Newell 345"
+ "Newell 346"
+ "Newell 347"
+ "Newell 348"
+ "Newell 349"
+ "Newell 35"
+ "Newell 350"
+ "Newell 351"
+ "Newell Chalk Holder"
+
+
+ "Nokia Lumia 1020"
+ "Nokia Lumia 521 (T-Mobile)"
+ "Nokia Lumia 925"
+
+
+ "Nortel Business Series Terminal T7208 Digital phone"
+ "Nortel Meridian M3904 Professional Digital phone"
+ "Nortel Meridian M5316 Digital phone"
+ "Nortel Networks T7316 E Nt8 B27"
+
+
+ "Novimex Fabric Task Chair"
+ "Novimex High-Tech Fabric Mesh Task Chair"
+ "Novimex Swivel Fabric Task Chair"
+ "Novimex Turbo Task Chair"
+
+
+ "Nu-Dell Executive Frame"
+ "Nu-Dell EZ-Mount Plastic Wall Frames"
+ "Nu-Dell Float Frame 11 x 14 1/2"
+ "Nu-Dell Leatherette Frames"
+ "Nu-Dell Oak Frame"
+
+
+ "O'Sullivan 2-Door Barrister Bookcase in Odessa Pine"
+ "O'Sullivan 2-Shelf Heavy-Duty Bookcases"
+ "O'Sullivan 3-Shelf Heavy-Duty Bookcases"
+ "O'Sullivan 4-Shelf Bookcase in Odessa Pine"
+ "O'Sullivan 5-Shelf Heavy-Duty Bookcases"
+ "O'Sullivan Cherrywood Estates Traditional Barrister Bookcase"
+ "O'Sullivan Cherrywood Estates Traditional Bookcase"
+ "O'Sullivan Elevations Bookcase, Cherry Finish"
+ "O'Sullivan Living Dimensions 2-Shelf Bookcases"
+ "O'Sullivan Living Dimensions 3-Shelf Bookcases"
+ "O'Sullivan Living Dimensions 5-Shelf Bookcases"
+ "O'Sullivan Manor Hill 2-Door Library in Brianna Oak"
+ "O'Sullivan Plantations 2-Door Library in Landvery Oak"
+
+
+ "Office Impressions End Table, 20-1/2\"H x 24\"W x 20\"D"
+ "Office Impressions Heavy Duty Welded Shelving & Multimedia Storage Drawers"
+
+
+ "Office Star - Contemporary Swivel Chair with Padded Adjustable Arms and Flex Back"
+ "Office Star - Contemporary Task Swivel Chair"
+ "Office Star - Contemporary Task Swivel chair with 2-way adjustable arms, Plum"
+ "Office Star - Contemporary Task Swivel chair with Loop Arms, Charcoal"
+ "Office Star - Ergonomic Mid Back Chair with 2-Way Adjustable Arms"
+ "Office Star - Ergonomically Designed Knee Chair"
+ "Office Star - Mesh Screen back chair with Vinyl seat"
+ "Office Star - Mid Back Dual function Ergonomic High Back Chair with 2-Way Adjustable Arms"
+ "Office Star - Professional Matrix Back Chair with 2-to-1 Synchro Tilt and Mesh Fabric Seat"
+ "Office Star - Task Chair with Contemporary Loop Arms"
+ "Office Star Flex Back Scooter Chair with Aluminum Finish Frame"
+ "Office Star Flex Back Scooter Chair with White Frame"
+
+
+ "Binder Clips by OIC"
+ "OIC Binder Clips, Mini, 1/4\" Capacity, Black"
+ "OIC Stacking Trays"
+ "OIC Thumb-Tacks"
+ "Translucent Push Pins by OIC"
+
+
+ "Okidata B400 Printer"
+ "Okidata B401 Printer"
+ "Okidata C331dn Printer"
+ "Okidata C610n Printer"
+ "Okidata CX3535-CX4545 Multifunction Printer"
+ "Okidata MB471w Multifunction Printer"
+ "Okidata MB491 Multifunction Printer"
+ "Okidata MB760 Printer"
+ "Okidata MC362w All-in-One Printer"
+
+
+ "\"While you Were Out\" Message Book, One Form per Page"
+ "\#10 Gummed Flap White Envelopes, 100/Box"
+ "\#10 Self-Seal White Envelopes"
+ "\#10 White Business Envelopes,4 1/8 x 9 1/2"
+ "\#10- 4 1/8\" x 9 1/2\" Recycled Envelopes"
+ "\#10- 4 1/8\" x 9 1/2\" Security-Tint Envelopes"
+ "\#10-4 1/8\" x 9 1/2\" Premium Diagonal Seam Envelopes"
+ "\#6 3/4 Gummed Flap White Envelopes"
+ "1.7 Cubic Foot Compact \"Cube\" Office Refrigerators"
+ "1/4 Fold Party Design Invitations & White Envelopes, 24 8-1/2\" X 11\" Cards, 25 Env./Pack"
+ "12 Colored Short Pencils"
+ "12-1/2 Diameter Round Wall Clock"
+ "14-7/8 x 11 Blue Bar Computer Printout Paper"
+ "2300 Heavy-Duty Transfer File Systems by Perma"
+ "24 Capacity Maxi Data Binder Racks, Pearl"
+ "24-Hour Round Wall Clock"
+ "3.6 Cubic Foot Counter Height Office Refrigerator"
+ "36X48 HARDFLOOR CHAIRMAT"
+ "4009 Highlighters"
+ "4009 Highlighters by Sanford"
+ "50 Colored Long Pencils"
+ "6\" Cubicle Wall Clock, Black"
+ "9-3/4 Diameter Round Wall Clock"
+ "Aastra 57i VoIP phone"
+ "Aastra 6757i CT Wireless VoIP phone"
+ "Acrylic Self-Standing Desk Frames"
+ "Adjustable Depth Letter/Legal Cart"
+ "Adjustable Personal File Tote"
+ "Adtran 1202752G1"
+ "Airmail Envelopes"
+ "Alphabetical Labels for Top Tab Filing"
+ "Aluminum Document Frame"
+ "Aluminum Screw Posts"
+ "AmazonBasics 3-Button USB Wired Mouse"
+ "American Pencil"
+ "Ames Color-File Green Diamond Border X-ray Mailers"
+ "Anderson Hickey Conga Table Tops & Accessories"
+ "APC 7 Outlet Network SurgeArrest Surge Protector"
+ "ARKON Windshield Dashboard Air Vent Car Mount Holder"
+ "Artistic Insta-Plaque"
+ "Assorted Color Push Pins"
+ "Astroparche Fine Business Paper"
+ "Avoid Verbal Orders Carbonless Minifold Book"
+ "Bady BDG101FRU Card Printer"
+ "Bagged Rubber Bands"
+ "Barrel Sharpener"
+ "Binder Posts"
+ "Binding Machine Supplies"
+ "Black & Decker Filter for Double Action Dustbuster Cordless Vac BLDV7210"
+ "Black Print Carbonless 8 1/2\" x 8 1/4\" Rapid Memo Book"
+ "Black Print Carbonless Snap-Off Rapid Letter, 8 1/2\" x 7\""
+ "BlackBerry Q10"
+ "Blackstonian Pencils"
+ "Blue Parrot B250XT Professional Grade Wireless Bluetooth Headset with"
+ "Blue String-Tie & Button Interoffice Envelopes, 10 x 13"
+ "BlueLounge Milo Smartphone Stand, White/Metallic"
+ "Bose SoundLink Bluetooth Speaker"
+ "BoxOffice By Design Rectangular and Half-Moon Meeting Room Tables"
+ "BPI Conference Tables"
+ "Bravo II Megaboss 12-Amp Hard Body Upright, Replacement Belts, 2 Belts per Pack"
+ "Brites Rubber Bands, 1 1/2 oz. Box"
+ "Brown Kraft Recycled Envelopes"
+ "Bush Westfield Collection Bookcases, Dark Cherry Finish, Fully Assembled"
+ "Bush Westfield Collection Bookcases, Fully Assembled"
+ "Cameo Buff Policy Envelopes"
+ "Canvas Sectional Post Binders"
+ "Career Cubicle Clock, 8 1/4\", Black"
+ "Case Logic 2.4GHz Wireless Keyboard"
+ "Catalog Binders with Expanding Posts"
+ "Cherry 142-key Programmable Keyboard"
+ "Clarity 53712"
+ "Classic Ivory Antique Telephone ZL1810"
+ "Clear Mylar Reinforcing Strips"
+ "Col-Erase Pencils with Erasers"
+ "Color-Coded Legal Exhibit Labels"
+ "Colored Envelopes"
+ "Colored Push Pins"
+ "Coloredge Poster Frame"
+ "Colorific Watercolor Pencils"
+ "Commercial WindTunnel Clean Air Upright Vacuum, Replacement Belts, Filtration Bags"
+ "Compact Automatic Electric Letter Opener"
+ "Companion Letter/Legal File, Black"
+ "Computer Printout Index Tabs"
+ "Computer Printout Paper with Letter-Trim Fine Perforations"
+ "Computer Printout Paper with Letter-Trim Perforations"
+ "Computer Room Manger, 14\""
+ "Conquest 14 Commercial Heavy-Duty Upright Vacuum, Collection System, Accessory Kit"
+ "Contemporary Borderless Frame"
+ "Contemporary Wood/Metal Frame"
+ "Contico 72\"H Heavy-Duty Storage System"
+ "Contract Clock, 14\", Brown"
+ "Convenience Packs of Business Envelopes"
+ "Crate-A-Files"
+ "Cush Cases Heavy Duty Rugged Cover Case for Samsung Galaxy S5 - Purple"
+ "Cyber Acoustics AC-202b Speech Recognition Stereo Headset"
+ "DataProducts Ampli Magnifier Task Lamp, Black,"
+ "Dell Slim USB Multimedia Keyboard"
+ "Deluxe Chalkboard Eraser Cleaner"
+ "Deluxe Heavy-Duty Vinyl Round Ring Binder"
+ "Deluxe Rollaway Locking File with Drawer"
+ "Design Ebony Sketching Pencil"
+ "Desktop 3-Pocket Hot File"
+ "Dexim XPower Skin Super-Thin Power Case for iPhone 5 - Black"
+ "Digium D40 VoIP phone"
+ "Disposable Triple-Filter Dust Bags"
+ "Document Clip Frames"
+ "Dot Matrix Printer Tape Reel Labels, White, 5000/Box"
+ "Dual Level, Single-Width Filing Carts"
+ "Durable Pressboard Binders"
+ "DYMO CardScan Personal V9 Business Card Scanner"
+ "Eaton Premium Continuous-Feed Paper, 25\% Cotton, Letter Size, White, 1000 Shts/Box"
+ "Eberhard Faber 3 1/2\" Golf Pencils"
+ "Economy \#2 Pencils"
+ "Economy Binders"
+ "Economy Rollaway Files"
+ "EcoTones Memo Sheets"
+ "Elite 5\" Scissors"
+ "Embossed Ink Jet Note Cards"
+ "Faber Castell Col-Erase Pencils"
+ "Fashion Color Clasp Envelopes"
+ "File Shuttle I and Handi-File"
+ "File Shuttle II and Handi-File, Black"
+ "Filing/Storage Totes and Swivel Casters"
+ "Flat Face Poster Frame"
+ "Flexible Leather- Look Classic Collection Ring Binder"
+ "Floodlight Indoor Halogen Bulbs, 1 Bulb per Pack, 60 Watts"
+ "Fluorescent Highlighters by Dixon"
+ "Fujitsu fi-5015C Sheetfed Scanner"
+ "GE 30522EE2"
+ "Gear Head AU3700S Headset"
+ "Geemarc AmpliPOWER60"
+ "Geographics Note Cards, Blank, White, 8 1/2\" x 11\""
+ "Google Nexus 5"
+ "Great White Multi-Use Recycled Paper (20Lb. and 84 Bright)"
+ "Green Bar Computer Printout Paper"
+ "Green Canvas Binder for 8-1/2\" x 14\" Sheets"
+ "Grip Seal Envelopes"
+ "GuestStacker Chair with Chrome Finish Legs"
+ "Hand-Finished Solid Wood Document Frame"
+ "Hanging Personal Folder File"
+ "Harbour Creations 67200 Series Stacking Chairs"
+ "Harbour Creations Steel Folding Chair"
+ "Heavy-Duty E-Z-D Binders"
+ "High Speed Automatic Electric Letter Opener"
+ "High-Back Leather Manager's Chair"
+ "Holmes Harmony HEPA Air Purifier for 17 x 20 Room"
+ "Home/Office Personal File Carts"
+ "Hot File 7-Pocket, Floor Stand"
+ "Hypercom P1300 Pinpad"
+ "I Need's 3d Hello Kitty Hybrid Silicone Case Cover for HTC One X 4g with 3d Hello Kitty Stylus Pen Green/pink"
+ "I.R.I.S IRISCard Anywhere 5 Card Scanner"
+ "i.Sound Portable Power - 8000 mAh"
+ "IBM Multi-Purpose Copy Paper, 8 1/2 x 11\", Case"
+ "Ideal Clamps"
+ "iHome FM Clock Radio with Lightning Dock"
+ "iKross Bluetooth Portable Keyboard + Cell Phone Stand Holder + Brush for Apple iPhone 5S 5C 5, 4S 4"
+ "Imation 8GB Mini TravelDrive USB 2.0 Flash Drive"
+ "Important Message Pads, 50 4-1/4 x 5-1/2 Forms per Pad"
+ "Ink Jet Note and Greeting Cards, 8-1/2\" x 5-1/2\" Card Size"
+ "Innergie mMini Combo Duo USB Travel Charging Kit"
+ "Insertable Tab Indexes For Data Binders"
+ "Insertable Tab Post Binder Dividers"
+ "Inter-Office Recycled Envelopes, Brown Kraft, Button-String,10\" x 13\" , 100/Box"
+ "invisibleSHIELD by ZAGG Smudge-Free Screen Protector"
+ "It's Hot Message Books with Stickers, 2 3/4\" x 5\""
+ "Jackery Bar Premium Fast-charging Portable Charger"
+ "JBL Micro Wireless Portable Bluetooth Speaker"
+ "Jensen SMPS-640 - speaker phone"
+ "Jet-Pak Recycled Peel 'N' Seal Padded Mailers"
+ "Jiffy Padded Mailers with Self-Seal Closure"
+ "JM Magazine Binder"
+ "KLD Oscar II Style Snap-on Ultra Thin Side Flip Synthetic Leather Cover Case for HTC One HTC M7"
+ "Kleencut Forged Office Shears by Acme United Corporation"
+ "Konftel 250 Conference phone - Charcoal black"
+ "Konica Minolta magicolor 1690MF Multifunction Printer"
+ "Laminate Occasional Tables"
+ "Large Capacity Hanging Post Binders"
+ "Laser & Ink Jet Business Envelopes"
+ "Leather Task Chair, Black"
+ "Lenovo 17-Key USB Numeric Keypad"
+ "Letter or Legal Size Expandable Poly String Tie Envelopes"
+ "Letter Size Cart"
+ "Letter Size File"
+ "Letter Slitter"
+ "Letter/Legal File Tote with Clear Snap-On Lid, Black Granite"
+ "Lexmark MX611dhe Monochrome Laser Printer"
+ "LF Elite 3D Dazzle Designer Hard Case Cover, Lf Stylus Pen and Wiper For Apple Iphone 5c Mini Lite"
+ "LG Exalt"
+ "Lifetime Advantage Folding Chairs, 4/Carton"
+ "Lock-Up Easel 'Spel-Binder'"
+ "Longer-Life Soft White Bulbs"
+ "Loose Memo Sheets"
+ "Lumber Crayons"
+ "Lunatik TT5L-002 Taktik Strike Impact Protection System for iPhone 5"
+ "Macally Suction Cup Mount"
+ "Magna Visual Magnetic Picture Hangers"
+ "Magnifier Swing Arm Lamp"
+ "Manco Dry-Lighter Erasable Highlighter"
+ "Manila Recycled Extra-Heavyweight Clasp Envelopes, 6\" x 9\""
+ "Master Big Foot Doorstop, Beige"
+ "Master Giant Foot Doorstop, Safety Yellow"
+ "Mead 1st Gear 2\" Zipper Binder, Asst. Colors"
+ "Mediabridge Sport Armband iPhone 5s"
+ "Memo Book, 100 Message Capacity, 5 3/8” x 11”"
+ "Metal Folding Chairs, Beige, 4/Carton"
+ "Micropad Numeric Keypads"
+ "Mini 13-1/2 Capacity Data Binder Rack, Pearl"
+ "Mobile Personal File Cube"
+ "Model L Table or Wall-Mount Pencil Sharpener"
+ "Mophie Juice Pack Helium for iPhone"
+ "Multi-Use Personal File Cart and Caster Set, Three Stacking Bins"
+ "Multicolor Computer Printout Paper"
+ "Multimedia Mailers"
+ "Neat Ideas Personal Hanging Folder Files, Black"
+ "NeatDesk Desktop Scanner & Digital Filing System"
+ "netTALK DUO VoIP Telephone Service"
+ "Nontoxic Chalk"
+ "OIC \#2 Pencils, Medium Soft"
+ "OIC Binder Clips"
+ "OIC Bulk Pack Metal Binder Clips"
+ "OIC Colored Binder Clips, Assorted Sizes"
+ "Ooma Telo VoIP Home Phone System"
+ "Padded Folding Chairs, Black, 4/Carton"
+ "Park Ridge Embossed Executive Business Envelopes"
+ "Pastel Pink Envelopes"
+ "PayAnywhere Card Reader"
+ "Peel & Stick Add-On Corner Pockets"
+ "Peel-Off China Markers"
+ "Pencil and Crayon Sharpener"
+ "Penpower WorldCard Pro Card Scanner"
+ "Performers Binder/Pad Holder, Black"
+ "Perixx PERIBOARD-512B, Ergonomic Split Keyboard"
+ "Perma STOR-ALL Hanging File Box, 13 1/8\"W x 12 1/4\"D x 10 1/2\"H"
+ "Permanent Self-Adhesive File Folder Labels for Typewriters, 1 1/8 x 3 1/2, White"
+ "Personal Creations Ink Jet Cards and Labels"
+ "Personal File Boxes with Fold-Down Carry Handle"
+ "Personal Filing Tote with Lid, Black/Gray"
+ "Personal Folder Holder, Ebony"
+ "Petty Cash Envelope"
+ "Pizazz Global Quick File"
+ "Plastic Binding Combs"
+ "Plastic Stacking Crates & Casters"
+ "Plymouth Boxed Rubber Bands by Plymouth"
+ "PNY Rapid USB Car Charger - Black"
+ "Portable Personal File Box"
+ "Portfile Personal File Boxes"
+ "Post-it “Important Message” Note Pad, Neon Colors, 50 Sheets/Pad"
+ "PowerGen Dual USB Car Charger"
+ "Premier Automatic Letter Opener"
+ "Premium Transparent Presentation Covers by GBC"
+ "Premium Transparent Presentation Covers, No Pattern/Clear, 8 1/2\" x 11\""
+ "Premium Writing Pencils, Soft, \#2 by Central Association for the Blind"
+ "Presstex Flexible Ring Binders"
+ "Prestige Round Ring Binders"
+ "Prismacolor Color Pencil Set"
+ "Project Tote Personal File"
+ "PureGear Roll-On Screen Protector"
+ "Quality Park Security Envelopes"
+ "QVS USB Car Charger 2-Port 2.1Amp for iPod/iPhone/iPad/iPad 2/iPad 3"
+ "Recycled Data-Pak for Archival Bound Computer Printouts, 12-1/2 x 12-1/2 x 16"
+ "Recycled Desk Saver Line \"While You Were Out\" Book, 5 1/2\" X 4\""
+ "Recycled Easel Ring Binders"
+ "Recycled Eldon Regeneration Jumbo File"
+ "Recycled Interoffice Envelopes with Re-Use-A-Seal Closure, 10 x 13"
+ "Recycled Interoffice Envelopes with String and Button Closure, 10 x 13"
+ "Recycled Premium Regency Composition Covers"
+ "Recycled Pressboard Report Cover with Reinforced Top Hinge"
+ "Recycled Steel Personal File for Hanging File Folders"
+ "Recycled Steel Personal File for Standard File Folders"
+ "Redi-Strip \#10 Envelopes, 4 1/8 x 9 1/2"
+ "Regeneration Desk Collection"
+ "Revere Boxed Rubber Bands by Revere"
+ "Ricoh - Ink Collector Unit for GX3000 Series Printers"
+ "Riverleaf Stik-Withit Designer Note Cubes"
+ "Rosewill 107 Normal Keys USB Wired Standard Keyboard"
+ "Round Ring Binders"
+ "Round Specialty Laser Printer Labels"
+ "RSVP Cards & Envelopes, Blank White, 8-1/2\" X 11\", 24 Cards/25 Envelopes/Set"
+ "Rubber Band Ball"
+ "Rubbermaid ClusterMat Chairmats, Mat Size- 66\" x 60\", Lip 20\" x 11\" -90 Degree Angle"
+ "Sabrent 4-Port USB 2.0 Hub"
+ "Sanitaire Vibra Groomer IR Commercial Upright Vacuum, Replacement Belts"
+ "Sannysis Cute Owl Design Soft Skin Case Cover for Samsung Galaxy S4"
+ "Satellite Sectional Post Binders"
+ "Security-Tint Envelopes"
+ "Seidio BD2-HK3IPH5-BK DILEX Case and Holster Combo for Apple iPhone 5/5s - Black"
+ "Self-Adhesive Address Labels for Typewriters with Dispenser Box"
+ "Self-Adhesive Removable Labels"
+ "Self-Adhesive Ring Binder Labels"
+ "Sensible Storage WireTech Storage Systems"
+ "Serrated Blade or Curved Handle Hand Letter Openers"
+ "Shocksock Galaxy S4 Armband"
+ "ShoreTel ShorePhone IP 230 VoIP phone"
+ "Sima Universal USB Charger"
+ "SimpliFile Personal File, Black Granite, 15w x 6-15/16d x 11-1/4h"
+ "Situations Contoured Folding Chairs, 4/Set"
+ "SKILCRAFT Telephone Shoulder Rest, 2\" x 6.5\" x 2.5\", Black"
+ "SlimView Poly Binder, 3/8\""
+ "SmartStand Mobile Device Holder, Assorted Colors"
+ "Snap-A-Way Black Print Carbonless Ruled Speed Letter, Triplicate"
+ "Snap-A-Way Black Print Carbonless Speed Message, No Reply Area, Duplicate"
+ "Sortfiler Multipurpose Personal File Organizer, Black"
+ "Speck Products Candyshell Flip Case"
+ "Speediset Carbonless Redi-Letter 7\" x 8 1/2\""
+ "Spigen Samsung Galaxy S5 Case Wallet"
+ "SpineVue Locking Slant-D Ring Binders by Cardinal"
+ "Square Ring Data Binders, Rigid 75 Pt. Covers, 11\" x 14-7/8\""
+ "Stackable Trays"
+ "Stacking Tray, Side-Loading, Legal, Smoke"
+ "Stacking Trays by OIC"
+ "Staples"
+ "Star Micronics TSP100 TSP143LAN Receipt Printer"
+ "Star Micronics TSP800 TSP847IIU Receipt Printer"
+ "StarTech.com 10/100 VDSL2 Ethernet Extender Kit"
+ "Steel Personal Filing/Posting Tote"
+ "Stiletto Hand Letter Openers"
+ "Stride Job 150 Highlighters, Chisel Tip, Assorted Colors"
+ "Stur-D-Stor Shelving, Vertical 5-Shelf: 72\"H x 36\"W x 18 1/2\"D"
+ "Super Bands, 12/Pack"
+ "Super Decoflex Portable Personal File"
+ "Surelock Post Binders"
+ "Swingline SM12-08 MicroCut Jam Free Shredder"
+ "Telephone Message Books with Fax/Mobile Section, 4 1/4\" x 6\""
+ "Telephone Message Books with Fax/Mobile Section, 5 1/2\" x 3 3/16\""
+ "Telescoping Adjustable Floor Lamp"
+ "Tops Green Bar Computer Printout Paper"
+ "Toshiba IPT2010-SD IP Telephone"
+ "Trav-L-File Heavy-Duty Shuttle II, Black"
+ "TRENDnet 56K USB 2.0 Phone, Internet and Fax Modem"
+ "Trimflex Flexible Post Binders"
+ "Tuf-Vin Binders"
+ "Tuff Stuff Recycled Round Ring Binders"
+ "Turquoise Lead Holder with Pocket Clip"
+ "UniKeep View Case Binders"
+ "Unpadded Memo Slips"
+ "V7 USB Numeric Keypad"
+ "VariCap6 Expandable Binder"
+ "Vinyl Coated Wire Paper Clips in Organizer Box, 800/Box"
+ "Vinyl Sectional Post Binders"
+ "Vtech AT&T CL2940 Corded Speakerphone, Black"
+ "Vtech CS6719"
+ "VTech DS6151"
+ "Wausau Papers Astrobrights Colored Envelopes"
+ "Weyerhaeuser First Choice Laser/Copy Paper (20Lb. and 88 Bright)"
+ "While You Were Out Pads, 50 per Pad, 4 x 5 1/4, Green Cycle"
+ "White Business Envelopes with Contemporary Seam, Recycled White Business Envelopes"
+ "White Computer Printout Paper by Universal"
+ "White Dual Perf Computer Printout Paper, 2700 Sheets, 1 Part, Heavyweight, 20 lbs., 14 7/8 x 11"
+ "White Envelopes, White Envelopes with Clear Poly Window"
+ "White GlueTop Scratch Pads"
+ "Wi-Ex zBoost YX540 Cellular Phone Signal Booster"
+ "Wilson Electronics DB Pro Signal Booster"
+ "Wilson SignalBoost 841262 DB PRO Amplifier Kit"
+ "Wireless Extenders zBoost YX545 SOHO Signal Booster"
+ "Woodgrain Magazine Files by Perma"
+ "X-Rack File for Hanging Folders"
+ "Xblue XB-1670-86 X16 Small Office Telephone - Titanium"
+ "Xiaomi Mi3"
+ "Zipper Ring Binder Pockets"
+
+
+ "OtterBox Commuter Series Case - iPhone 5 & 5s"
+ "OtterBox Commuter Series Case - Samsung Galaxy S4"
+ "OtterBox Defender Series Case - iPhone 5c"
+ "OtterBox Defender Series Case - Samsung Galaxy S4"
+
+
+ "Panasonic Business Telephones KX-T7736"
+ "Panasonic KP-150 Electric Pencil Sharpener"
+ "Panasonic KP-310 Heavy-Duty Electric Pencil Sharpener"
+ "Panasonic KP-350BK Electric Pencil Sharpener with Auto Stop"
+ "Panasonic KP-380BK Classic Electric Pencil Sharpener"
+ "Panasonic KP-4ABK Battery-Operated Pencil Sharpener"
+ "Panasonic KX - TS880B Telephone"
+ "Panasonic KX MB2000 Monochrome Laser All-in-One Printer"
+ "Panasonic KX MB2030 Monochrome Laser All-in-One Printer"
+ "Panasonic KX MB2061 Multifunction Printer"
+ "Panasonic KX MB3020 Highspeed Multifunction Printer"
+ "Panasonic KX MC6040 Color Laser Multifunction Printer"
+ "Panasonic KX T7731-B Digital phone"
+ "Panasonic KX T7736-B Digital phone"
+ "Panasonic KX TS208W Corded phone"
+ "Panasonic KX TS3282B Corded phone"
+ "Panasonic KX TS3282W Corded phone"
+ "Panasonic KX-TG6512B DECT 6.0 Plus Digital 2-Handset Cordless Phone"
+ "Panasonic KX-TG6844B Expandable Digital Cordless Telephone"
+ "Panasonic KX-TG9471B"
+ "Panasonic KX-TG9541B DECT 6.0 Digital 2-Line Expandable Cordless Phone With Digital Answering System"
+ "Panasonic Kx-TS550"
+
+
+ "Peel & Seel Envelopes"
+ "Peel & Seel Recycled Catalog Envelopes, Brown"
+
+
+ "Plantronics 81402"
+ "Plantronics Audio 478 Stereo USB Headset"
+ "Plantronics Audio 995 Wireless Stereo Headset"
+ "Plantronics Calisto P620-M USB Wireless Speakerphone System"
+ "Plantronics Cordless Phone Headset with In-line Volume - M214C"
+ "Plantronics CS 50-USB - headset - Convertible, Monaural"
+ "Plantronics CS510 - Over-the-Head monaural Wireless Headset System"
+ "Plantronics Encore H101 Dual Earpieces Headset"
+ "Plantronics HL10 Handset Lifter"
+ "Plantronics MX500i Earset"
+ "Plantronics S12 Corded Telephone Headset System"
+ "Plantronics Savi W720 Multi-Device Wireless Headset System"
+ "Plantronics Single Ear Headset"
+ "Plantronics Voyager Pro HD - Bluetooth Headset"
+ "Plantronics Voyager Pro Legend"
+
+
+ "Poly Designer Cover & Back"
+ "Poly String Tie Envelopes"
+
+
+ "Polycom CX300 Desktop Phone USB VoIP phone"
+ "Polycom CX600 IP Phone VoIP phone"
+ "Polycom SoundPoint IP 450 VoIP phone"
+ "Polycom SoundPoint Pro SE-225 Corded phone"
+ "Polycom SoundStation2 EX Conference phone"
+ "Polycom VoiceStation 500 Conference phone"
+ "Polycom VVX 310 VoIP phone"
+
+
+ "Prang Colored Pencils"
+ "Prang Drawing Pencil Set"
+ "Prang Dustless Chalk Sticks"
+
+
+ "Premier Electric Letter Opener"
+ "Premier Elliptical Ring Binder, Black"
+
+
+ "Pressboard Covers with Storage Hooks, 9 1/2\" x 11\", Light Blue"
+ "Pressboard Data Binder, Crimson, 12\" X 8 1/2\""
+ "Pressboard Data Binders by Wilson Jones"
+ "Pressboard Hanging Data Binders for Unburst Sheets"
+
+
+ "Pyle PMP37LED"
+ "Pyle PRT45 Retro Home Telephone"
+
+
+ "Quartet Alpha White Chalk, 12/Pack"
+ "Quartet Omega Colored Chalk, 12/Pack"
+
+
+ "Razer Kraken 7.1 Surround Sound Over Ear USB Gaming Headset"
+ "Razer Kraken PRO Over Ear PC and Music Headset"
+ "Razer Tiamat Over Ear 7.1 Surround Sound PC Gaming Headset"
+
+
+ "RCA 25214 2-Line Corded Telephone"
+ "RCA H5401RE1 DECT 6.0 4-Line Cordless Handset With Caller ID/Call Waiting"
+ "RCA ViSYS 25423RE1 Corded phone"
+ "RCA ViSYS 25425RE1 Corded phone"
+ "RCA ViSYS 25825 Wireless digital phone"
+ "RCA Visys Integrated PBX 8-Line Router"
+
+
+ "REDIFORM Incoming/Outgoing Call Register, 11\" X 8 1/2\", 100 Messages"
+ "Rediform S.O.S. 1-Up Phone Message Bk, 4-1/4x3-1/16 Bk, 1 Form/Pg, 40 Messages/Bk, 3/Pk"
+ "Rediform S.O.S. Phone Message Books"
+ "Rediform Voice Mail Log Books"
+ "Rediform Wirebound \"Phone Memo\" Message Book, 11 x 5-3/4"
+
+
+ "Riverside Furniture Oval Coffee Table, Oval End Table, End Table with Drawer"
+ "Riverside Furniture Stanwyck Manor Table Series"
+ "Riverside Palais Royal Lawyers Bookcase, Royale Cherry Finish"
+
+
+ "Rogers Deluxe File Chest"
+ "Rogers Handheld Barrel Pencil Sharpener"
+ "Rogers Jumbo File, Granite"
+ "Rogers Profile Extra Capacity Storage Tub"
+
+
+ "Rush Hierlooms Collection 1\" Thick Stackable Bookcases"
+ "Rush Hierlooms Collection Rich Wood Bookcases"
+
+
+ "SAFCO Arco Folding Chair"
+ "SAFCO Boltless Steel Shelving"
+ "Safco Chair Connectors, 6/Carton"
+ "Safco Commercial Shelving"
+ "SAFCO Commercial Wire Shelving, 72h"
+ "SAFCO Commercial Wire Shelving, Black"
+ "Safco Contoured Stacking Chairs"
+ "Safco Drafting Table"
+ "SAFCO Folding Chair Trolley"
+ "Safco Industrial Shelving"
+ "Safco Industrial Wire Shelving"
+ "Safco Industrial Wire Shelving System"
+ "SAFCO Mobile Desk Side File, Wire Frame"
+ "SAFCO Optional Arm Kit for Workspace Cribbage Stacking Chair"
+ "SAFCO PlanMaster Boards, 60w x 37-1/2d, White Melamine"
+ "SAFCO PlanMaster Heigh-Adjustable Drafting Table Base, 43w x 30d x 30-37h, Black"
+ "Safco Steel Mobile File Cart"
+ "Safco Value Mate Series Steel Bookcases, Baked Enamel Finish on Steel, Gray"
+ "Safco Value Mate Steel Bookcase, Baked Enamel Finish on Steel, Black"
+ "Safco Wire Cube Shelving System, For Use as 4 or 5 14\" Cubes, Black"
+
+
+ "Samsung Convoy 3"
+ "Samsung Galaxy Mega 6.3"
+ "Samsung Galaxy Note 2"
+ "Samsung Galaxy Note 3"
+ "Samsung Galaxy S III - 16GB - pebble blue (T-Mobile)"
+ "Samsung Galaxy S4"
+ "Samsung Galaxy S4 Active"
+ "Samsung Galaxy S4 Mini"
+ "Samsung HM1900 Bluetooth Headset"
+ "Samsung Replacement EH64AVFWE Premium Headset"
+ "Samsung Rugby III"
+
+
+ "SanDisk Cruzer 16 GB USB Flash Drive"
+ "SanDisk Cruzer 32 GB USB Flash Drive"
+ "SanDisk Cruzer 4 GB USB Flash Drive"
+ "SanDisk Cruzer 64 GB USB Flash Drive"
+ "SanDisk Cruzer 8 GB USB Flash Drive"
+ "SanDisk Ultra 16 GB MicroSDHC Class 10 Memory Card"
+ "SanDisk Ultra 32 GB MicroSDHC Class 10 Memory Card"
+ "SanDisk Ultra 64 GB MicroSDHC Class 10 Memory Card"
+
+
+ "Sanford 52201 APSCO Electric Pencil Sharpener"
+ "Sanford Colorific Colored Pencils, 12/Box"
+ "Sanford Colorific Eraseable Coloring Pencils, 12 Count"
+ "Sanford Colorific Scented Colored Pencils, 12/Pack"
+ "Sanford EarthWrite Recycled Pencils, Medium Soft, \#2"
+ "Sanford Liquid Accent Highlighters"
+ "SANFORD Liquid Accent Tank-Style Highlighters"
+ "SANFORD Major Accent Highlighters"
+ "Sanford Pocket Accent Highlighters"
+ "Sanford Prismacolor Professional Thick Lead Art Pencils, 36-Color Set"
+ "Sanford Uni-Blazer View Highlighters, Chisel Tip, Yellow"
+
+
+ "Sanyo 2.5 Cubic Foot Mid-Size Office Refrigerators"
+ "Sanyo Counter Height Refrigerator with Crisper, 3.6 Cubic Foot, Stainless Steel/Black"
+
+
+ "Sauder Barrister Bookcases"
+ "Sauder Camden County Barrister Bookcase, Planked Cherry Finish"
+ "Sauder Camden County Collection Libraries, Planked Cherry Finish"
+ "Sauder Camden County Collection Library"
+ "Sauder Cornerstone Collection Library"
+ "Sauder Facets Collection Library, Sky Alder Finish"
+ "Sauder Facets Collection Locker/File Cabinet, Sky Alder Finish"
+ "Sauder Forest Hills Library with Doors, Woodland Oak Finish"
+ "Sauder Forest Hills Library, Woodland Oak Finish"
+ "Sauder Inglewood Library Bookcases"
+ "Sauder Mission Library with Doors, Fruitwood Finish"
+
+
+ "Seth Thomas 12\" Clock w/ Goldtone Case"
+ "Seth Thomas 13 1/2\" Wall Clock"
+ "Seth Thomas 14\" Day/Date Wall Clock"
+ "Seth Thomas 14\" Putty-Colored Wall Clock"
+ "Seth Thomas 16\" Steel Case Clock"
+ "Seth Thomas 8 1/2\" Cubicle Clock"
+
+
+ "Sharp 1540cs Digital Laser Copier"
+ "Sharp AL-1530CS Digital Copier"
+
+
+ "Smead Adjustable Mobile File Trolley with Lockable Top"
+ "Smead Alpha-Z Color-Coded Name Labels First Letter Starter Set"
+ "Smead Alpha-Z Color-Coded Second Alphabetical Labels and Starter Set"
+
+
+ "Socket Bluetooth Cordless Hand Scanner (CHS)"
+
+
+ "Sony 16GB Class 10 Micro SDHC R40 Memory Card"
+ "Sony 32GB Class 10 Micro SDHC R40 Memory Card"
+ "Sony 64GB Class 10 Micro SDHC R40 Memory Card"
+ "Sony 8GB Class 10 Micro SDHC R40 Memory Card"
+ "Sony Micro Vault Click 16 GB USB 2.0 Flash Drive"
+ "Sony Micro Vault Click 4 GB USB 2.0 Flash Drive"
+ "Sony Micro Vault Click 8 GB USB 2.0 Flash Drive"
+
+
+ "Southworth 100\% Cotton The Best Paper"
+ "Southworth 100\% Résumé Paper, 24lb."
+ "Southworth 25\% Cotton Antique Laid Paper & Envelopes"
+ "Southworth 25\% Cotton Granite Paper & Envelopes"
+ "Southworth 25\% Cotton Linen-Finish Paper & Envelopes"
+ "Southworth 25\% Cotton Premium Laser Paper and Envelopes"
+ "Southworth Parchment Paper & Envelopes"
+ "Southworth Structures Collection"
+
+
+ "Space Solutions Commercial Steel Shelving"
+ "Space Solutions HD Industrial Steel Shelving."
+ "Space Solutions Industrial Galvanized Steel Shelving."
+
+
+ "Square Credit Card Reader"
+ "Square Credit Card Reader, 4 1/2\" x 4 1/2\" x 1\", White"
+
+
+ "Standard Line “While You Were Out” Hardbound Telephone Message Book"
+ "Standard Rollaway File with Lock"
+
+
+ "Stanley Bostitch Contemporary Electric Pencil Sharpeners"
+ "Stanley Contemporary Battery Pencil Sharpeners"
+
+
+ "Sterilite Officeware Hinged File Box"
+ "Sterilite Show Offs Storage Containers"
+
+
+ "Stockwell Gold Paper Clips"
+ "Stockwell Push Pins"
+
+
+ "Storex Dura Pro Binders"
+ "Storex DuraTech Recycled Plastic Frosted Binders"
+ "Storex Flexible Poly Binders with Double Pockets"
+
+
+ "Strathmore \#10 Envelopes, Ultimate White"
+ "Strathmore Photo Frame Cards"
+ "Strathmore Photo Mount Cards"
+
+
+ "Tenex \"The Solids\" Textured Chair Mats"
+ "Tenex 46\" x 60\" Computer Anti-Static Chairmat, Rectangular Shaped"
+ "Tenex Antistatic Computer Chair Mats"
+ "Tenex B1-RE Series Chair Mats for Low Pile Carpets"
+ "Tenex Carpeted, Granite-Look or Clear Contemporary Contour Shape Chair Mats"
+ "Tenex Chairmat w/ Average Lip, 45\" x 53\""
+ "Tenex Chairmats For Use With Carpeted Floors"
+ "Tenex Chairmats For Use with Hard Floors"
+ "Tenex Contemporary Contur Chairmats for Low and Medium Pile Carpet, Computer, 39\" x 49\""
+ "Tenex File Box, Personal Filing Tote with Lid, Black"
+ "Tenex Personal Filing Tote With Secure Closure Lid, Black/Frost"
+ "Tenex Personal Project File with Scoop Front Design, Black"
+ "Tenex Personal Self-Stacking Standard File Box, Black/Gray"
+ "Tenex Traditional Chairmats for Hard Floors, Average Lip, 36\" x 48\""
+ "Tenex Traditional Chairmats for Medium Pile Carpet, Standard Lip, 36\" x 48\""
+ "Tenex V2T-RE Standard Weight Series Chair Mat, 45\" x 53\", Lip 25\" x 12\""
+
+
+ "Tennsco 16-Compartment Lockers with Coat Rack"
+ "Tennsco 6- and 18-Compartment Lockers"
+ "Tennsco Commercial Shelving"
+ "Tennsco Double-Tier Lockers"
+ "Tennsco Industrial Shelving"
+ "Tennsco Lockers, Gray"
+ "Tennsco Lockers, Sand"
+ "Tennsco Regal Shelving Units"
+ "Tennsco Single-Tier Lockers"
+ "Tennsco Snap-Together Open Shelving Units, Starter Sets and Add-On Units"
+ "Tennsco Stur-D-Stor Boltless Shelving, 5 Shelves, 24\" Deep, Sand"
+
+
+ "Tensor \"Hersey Kiss\" Styled Floor Lamp"
+ "Tensor Brushed Steel Torchiere Floor Lamp"
+ "Tensor Computer Mounted Lamp"
+ "Tensor Track Tree Floor Lamp"
+
+
+ "Texas Instrument TI-15 Fraction Calculator"
+ "Texas Instrument TI-30a Scientific Calculator"
+ "Texas Instrument TI-30X Scientific Calculator"
+ "Texas Instrument TI-30X Solar Scientific Calculator"
+ "Texas Instrument TI-36X Solar Scientific Calculator"
+ "Texas Instruments TI-34 Scientific Calculator"
+
+
+ "Things To Do Today Pad"
+ "Things To Do Today Spiral Book"
+
+
+ "TOPS \"Important Message\" Pads, Canary, 4-1/4 x 5-1/2, 50 Sheets per Pad"
+ "TOPS 4 x 6 Fluorescent Color Memo Sheets, 500 Sheets per Pack"
+ "TOPS Carbonless Receipt Book, Four 2-3/4 x 7-1/4 Money Receipts per Page"
+ "TOPS Money Receipt Book, Consecutively Numbered in Red,"
+ "TOPS Voice Message Log Book, Flash Format"
+ "Tops White Computer Printout Paper"
+ "Tops Wirebound Message Log Books"
+
+
+ "Tripp Lite Isotel 6 Outlet Surge Protector with Fax/Modem Protection"
+ "Tripp Lite Isotel 8 Ultra 8 Outlet Metal Surge"
+ "Tripp Lite TLP810NET Broadband Surge for Modem/Fax"
+
+
+ "Tyvek Top-Opening Peel & Seel Envelopes, Gray"
+ "Tyvek Top-Opening Peel & Seel Envelopes, Plain White"
+ "Tyvek Interoffice Envelopes, 9 1/2\" x 12 1/2\", 100/Box"
+ "Tyvek Side-Opening Peel & Seel Expanding Envelopes"
+
+
+ "Ultra Commercial Grade Dual Valve Door Closer"
+ "Ultra Door Kickplate, 8\"H x 34\"W"
+ "Ultra Door Pull Handle"
+ "Ultra Door Push Plate"
+
+
+ "Permanent Self-Adhesive File Folder Labels for Typewriters by Universal"
+ "Self-Adhesive Address Labels for Typewriters by Universal"
+ "Universal Premium White Copier/Laser Paper (20Lb. and 87 Bright)"
+ "Universal Recycled Hanging Pressboard Report Binders, Letter Size"
+ "Universal Ultra Bright White Copier/Laser Paper, 8 1/2\" x 11\", Ream"
+
+
+ "Verbatim 25 GB 6x Blu-ray Single Layer Recordable Disc, 1/Pack"
+ "Verbatim 25 GB 6x Blu-ray Single Layer Recordable Disc, 10/Pack"
+ "Verbatim 25 GB 6x Blu-ray Single Layer Recordable Disc, 25/Pack"
+ "Verbatim 25 GB 6x Blu-ray Single Layer Recordable Disc, 3/Pack"
+ "Verbatim Slim CD and DVD Storage Cases, 50/Pack"
+
+
+ "Wasp CCD Handheld Bar Code Reader"
+ "Wasp WCS 3905 CCD Barcode Scanner"
+
+
+ "WD My Passport Ultra 1TB Portable External Hard Drive"
+ "WD My Passport Ultra 2TB Portable External Hard Drive"
+ "WD My Passport Ultra 500GB Portable External Hard Drive"
+
+
+ "Westinghouse Clip-On Gooseneck Lamps"
+ "Westinghouse Floor Lamp with Metal Mesh Shade, Black"
+ "Westinghouse Mesh Shade Clip-On Gooseneck Lamp, Black"
+
+
+ "Wilson Jones “Snap” Scratch Pad Binder Tool for Ring Binders"
+ "Wilson Jones 1\" Hanging DublLock Ring Binders"
+ "Wilson Jones 14 Line Acrylic Coated Pressboard Data Binders"
+ "Wilson Jones Active Use Binders"
+ "Wilson Jones Century Plastic Molded Ring Binders"
+ "Wilson Jones Clip & Carry Folder Binder Tool for Ring Binders, Clear"
+ "Wilson Jones Custom Binder Spines & Labels"
+ "Wilson Jones data.warehouse D-Ring Binders with DublLock"
+ "Wilson Jones DublLock D-Ring Binders"
+ "Wilson Jones Easy Flow II Sheet Lifters"
+ "Wilson Jones Elliptical Ring 3 1/2\" Capacity Binders, 800 sheets"
+ "Wilson Jones Four-Pocket Poly Binders"
+ "Wilson Jones Hanging Recycled Pressboard Data Binders"
+ "Wilson Jones Hanging View Binder, White, 1\""
+ "Wilson Jones Heavy-Duty Casebound Ring Binders with Metal Hinges"
+ "Wilson Jones Impact Binders"
+ "Wilson Jones International Size A4 Ring Binders"
+ "Wilson Jones Leather-Like Binders with DublLock Round Rings"
+ "Wilson Jones Ledger-Size, Piano-Hinge Binder, 2\", Blue"
+ "Wilson Jones Legal Size Ring Binders"
+ "Wilson Jones Standard D-Ring Binders"
+ "Wilson Jones Suede Grain Vinyl Binders"
+ "Wilson Jones Turn Tabs Binder Tool for Ring Binders"
+
+
+ "Wirebound Four 2-3/4 x 5 Forms per Page, 400 Sets per Book"
+ "Wirebound Message Book, 4 per Page"
+ "Wirebound Message Books, 2 7/8\" x 5\", 3 Forms per Page"
+ "Wirebound Message Books, 5-1/2 x 4 Forms, 2 or 4 Forms per Page"
+ "Wirebound Message Books, Four 2 3/4 x 5 Forms per Page, 200 Sets per Book"
+ "Wirebound Message Books, Four 2 3/4 x 5 White Forms per Page"
+ "Wirebound Message Books, Four 2 3/4\" x 5\" Forms per Page, 600 Sets per Book"
+ "Wirebound Message Books, Two 4 1/4\" x 5\" Forms per Page"
+ "Wirebound Message Forms, Four 2 3/4 x 5 Forms per Page, Pink Paper"
+ "Wirebound Service Call Books, 5 1/2\" x 4\""
+ "Wirebound Voice Message Log Book"
+
+
+ "Xerox 188"
+ "Xerox 1880"
+ "Xerox 1881"
+ "Xerox 1882"
+ "Xerox 1883"
+ "Xerox 1884"
+ "Xerox 1885"
+ "Xerox 1886"
+ "Xerox 1887"
+ "Xerox 1888"
+ "Xerox 1889"
+ "Xerox 189"
+ "Xerox 1890"
+ "Xerox 1891"
+ "Xerox 1892"
+ "Xerox 1893"
+ "Xerox 1894"
+ "Xerox 1895"
+ "Xerox 1896"
+ "Xerox 1897"
+ "Xerox 1898"
+ "Xerox 1899"
+ "Xerox 19"
+ "Xerox 190"
+ "Xerox 1900"
+ "Xerox 1901"
+ "Xerox 1902"
+ "Xerox 1903"
+ "Xerox 1904"
+ "Xerox 1905"
+ "Xerox 1906"
+ "Xerox 1907"
+ "Xerox 1908"
+ "Xerox 1909"
+ "Xerox 191"
+ "Xerox 1910"
+ "Xerox 1911"
+ "Xerox 1912"
+ "Xerox 1913"
+ "Xerox 1914"
+ "Xerox 1915"
+ "Xerox 1916"
+ "Xerox 1917"
+ "Xerox 1918"
+ "Xerox 1919"
+ "Xerox 192"
+ "Xerox 1920"
+ "Xerox 1921"
+ "Xerox 1922"
+ "Xerox 1923"
+ "Xerox 1924"
+ "Xerox 1925"
+ "Xerox 1926"
+ "Xerox 1927"
+ "Xerox 1928"
+ "Xerox 1929"
+ "Xerox 193"
+ "Xerox 1930"
+ "Xerox 1931"
+ "Xerox 1932"
+ "Xerox 1933"
+ "Xerox 1934"
+ "Xerox 1935"
+ "Xerox 1936"
+ "Xerox 1937"
+ "Xerox 1938"
+ "Xerox 1939"
+ "Xerox 194"
+ "Xerox 1940"
+ "Xerox 1941"
+ "Xerox 1942"
+ "Xerox 1943"
+ "Xerox 1944"
+ "Xerox 1945"
+ "Xerox 1946"
+ "Xerox 1947"
+ "Xerox 1948"
+ "Xerox 1949"
+ "Xerox 195"
+ "Xerox 1950"
+ "Xerox 1951"
+ "Xerox 1952"
+ "Xerox 1953"
+ "Xerox 1954"
+ "Xerox 1955"
+ "Xerox 1956"
+ "Xerox 1957"
+ "Xerox 1958"
+ "Xerox 1959"
+ "Xerox 196"
+ "Xerox 1960"
+ "Xerox 1961"
+ "Xerox 1962"
+ "Xerox 1963"
+ "Xerox 1964"
+ "Xerox 1965"
+ "Xerox 1966"
+ "Xerox 1967"
+ "Xerox 1968"
+ "Xerox 1969"
+ "Xerox 197"
+ "Xerox 1970"
+ "Xerox 1972"
+ "Xerox 1973"
+ "Xerox 1974"
+ "Xerox 1975"
+ "Xerox 1976"
+ "Xerox 1977"
+ "Xerox 1978"
+ "Xerox 1979"
+ "Xerox 198"
+ "Xerox 1980"
+ "Xerox 1981"
+ "Xerox 1982"
+ "Xerox 1983"
+ "Xerox 1984"
+ "Xerox 1985"
+ "Xerox 1986"
+ "Xerox 1987"
+ "Xerox 1988"
+ "Xerox 1989"
+ "Xerox 199"
+ "Xerox 1990"
+ "Xerox 1991"
+ "Xerox 1992"
+ "Xerox 1993"
+ "Xerox 1994"
+ "Xerox 1995"
+ "Xerox 1996"
+ "Xerox 1997"
+ "Xerox 1998"
+ "Xerox 1999"
+ "Xerox 2"
+ "Xerox 20"
+ "Xerox 200"
+ "Xerox 2000"
+ "Xerox 201"
+ "Xerox 202"
+ "Xerox 203"
+ "Xerox 204"
+ "Xerox 205"
+ "Xerox 206"
+ "Xerox 207"
+ "Xerox 208"
+ "Xerox 209"
+ "Xerox 21"
+ "Xerox 210"
+ "Xerox 211"
+ "Xerox 212"
+ "Xerox 213"
+ "Xerox 214"
+ "Xerox 215"
+ "Xerox 216"
+ "Xerox 217"
+ "Xerox 218"
+ "Xerox 219"
+ "Xerox 22"
+ "Xerox 220"
+ "Xerox 221"
+ "Xerox 222"
+ "Xerox 223"
+ "Xerox 224"
+ "Xerox 225"
+ "Xerox 226"
+ "Xerox 227"
+ "Xerox 228"
+ "Xerox 229"
+ "Xerox 23"
+ "Xerox 230"
+ "Xerox 231"
+ "Xerox 232"
+ "Xerox 4200 Series MultiUse Premium Copy Paper (20Lb. and 84 Bright)"
+ "Xerox Blank Computer Paper"
+ "Xerox Color Copier Paper, 11\" x 17\", Ream"
+ "Xerox WorkCentre 6505DN Laser Multifunction Printer"
+
+
+ "XtraLife ClearVue Slant-D Ring Binder, White, 3\""
+ "XtraLife ClearVue Slant-D Ring Binders by Cardinal"
+
+
+ "Zebra GK420t Direct Thermal/Thermal Transfer Printer"
+ "Zebra GX420t Direct Thermal/Thermal Transfer Printer"
+ "Zebra Zazzle Fluorescent Highlighters"
+ "Zebra ZM400 Thermal Label Printer"
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelTableType.true...column caption='Orders' datatype='table' name='[__tableau_internal_object_id__].[Orders_ECFCA1FB690A41FE803BC071773BA862]' role='measure' type='quantitative' />
+ <_.fcp.ObjectModelTableType.true...column caption='People' datatype='table' name='[__tableau_internal_object_id__].[People_D73023733B004CC1B3CB1ACF62F4A965]' role='measure' type='quantitative' />
+ <_.fcp.ObjectModelTableType.true...column caption='Returns' datatype='table' name='[__tableau_internal_object_id__].[Returns_2AA0FE4D737A4F63970131D0E7480A03]' role='measure' type='quantitative' />
+
+
+
+
+
+
+
+
+
+
+ [Country/Region]
+ [Region]
+ [State]
+ [City]
+ [Postal Code]
+
+
+ [Category]
+ [Sub-Category]
+ [Product Name (group)]
+ [Product Name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_.fcp.ObjectModelEncapsulateLegacy.true...object-graph>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Sample - Superstore].[none:Category:nk]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Sample - Superstore].[none:Category:nk]
+ [Sample - Superstore].[none:Segment:nk]
+ [Sample - Superstore].[none:Sub-Category:nk]
+
+
+
+
+
+
+
+
+ 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
+ gGVTAcvmD5YpbPKOzTAfAAAAAElFTkSuQmCC
+
+
+
+
diff --git a/test/assets/unicode.tds b/test/assets/unicode.tds
new file mode 100644
index 0000000..6c6e764
--- /dev/null
+++ b/test/assets/unicode.tds
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+ a
+ 130
+ [a]
+ [xy]
+ a
+ 1
+ string
+ Count
+ 255
+ true
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Today's Date
+ 130
+ [Today's Date]
+ [xy]
+ a
+ 1
+ string
+ Count
+ 255
+ true
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ x
+ 3
+ [x]
+ [xy]
+ x
+ 2
+ integer
+ Sum
+ 10
+ true
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+ y
+ 3
+ [y]
+ [xy]
+ y
+ 3
+ integer
+ Sum
+ 10
+ true
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+
+
+
+
+
+
+
+
+ año
+
Something will go here too, in a muted gray
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/bvt.py b/test/bvt.py
index 4ea3d11..6ed8a9f 100644
--- a/test/bvt.py
+++ b/test/bvt.py
@@ -1,32 +1,11 @@
import os
import unittest
-import xml.etree.ElementTree as ET
-
+from lxml import etree as ET
+from test.assets.index import *
from tableaudocumentapi import Workbook, Datasource, Connection, ConnectionParser
from tableaudocumentapi.xfile import TableauInvalidFileException, TableauVersionNotSupportedException
-TEST_DIR = os.path.dirname(__file__)
-
-TABLEAU_82_TWB = os.path.join(TEST_DIR, 'assets', 'TABLEAU_82_TWB.twb')
-
-TABLEAU_93_TWB = os.path.join(TEST_DIR, 'assets', 'TABLEAU_93_TWB.twb')
-
-TABLEAU_93_TDS = os.path.join(TEST_DIR, 'assets', 'TABLEAU_93_TDS.tds')
-
-TABLEAU_10_TDS = os.path.join(TEST_DIR, 'assets', 'TABLEAU_10_TDS.tds')
-
-TABLEAU_10_TWB = os.path.join(TEST_DIR, 'assets', 'TABLEAU_10_TWB.twb')
-
-TABLEAU_CONNECTION_XML = ET.parse(os.path.join(
- TEST_DIR, 'assets', 'CONNECTION.xml')).getroot()
-
-TABLEAU_10_TWBX = os.path.join(TEST_DIR, 'assets', 'TABLEAU_10_TWBX.twbx')
-
-TABLEAU_10_TDSX = os.path.join(TEST_DIR, 'assets', 'TABLEAU_10_TDSX.tdsx')
-
-EMPTY_WORKBOOK = os.path.join(TEST_DIR, 'assets', 'empty_workbook.twb')
-
class ConnectionParserTests(unittest.TestCase):
@@ -42,30 +21,57 @@ def test_can_extract_federated_connections(self):
connections = parser.get_connections()
self.assertIsInstance(connections, list)
self.assertIsInstance(connections[0], Connection)
- self.assertEqual(connections[0].dbname, 'testv1')
+ self.assertEqual(connections[0].dbname, 'TestV1')
class ConnectionModelTests(unittest.TestCase):
def setUp(self):
- self.connection = TABLEAU_CONNECTION_XML
+ self.connection = ET.parse(TABLEAU_CONNECTION_XML).getroot()
def test_can_read_attributes_from_connection(self):
conn = Connection(self.connection)
self.assertEqual(conn.dbname, 'TestV1')
self.assertEqual(conn.username, '')
- self.assertEqual(conn.server, 'mssql2012.test.tsi.lan')
+ self.assertEqual(conn.server, 'mssql2012')
self.assertEqual(conn.dbclass, 'sqlserver')
self.assertEqual(conn.authentication, 'sspi')
+ self.assertEqual(conn.port, '1433')
+ self.assertEqual(conn.initial_sql, '')
+ self.assertEqual(conn.query_band, '')
def test_can_write_attributes_to_connection(self):
conn = Connection(self.connection)
conn.dbname = 'BubblesInMyDrink'
- conn.server = 'mssql2014.test.tsi.lan'
+ conn.server = 'mssql2014'
conn.username = 'bob'
+ conn.port = '1337'
+ conn.initial_sql = "insert values (1, 'winning') into schema.table"
+ conn.query_band = 'TableauReport='
self.assertEqual(conn.dbname, 'BubblesInMyDrink')
self.assertEqual(conn.username, 'bob')
- self.assertEqual(conn.server, 'mssql2014.test.tsi.lan')
+ self.assertEqual(conn.server, 'mssql2014')
+ self.assertEqual(conn.port, '1337')
+ self.assertEqual(conn.initial_sql, "insert values (1, 'winning') into schema.table")
+ self.assertEqual(conn.query_band, 'TableauReport=')
+
+ def test_can_delete_port_from_connection(self):
+ conn = Connection(self.connection)
+ conn.port = None
+ self.assertEqual(conn.port, None)
+ self.assertIsNone(conn._connectionXML.get('port'))
+
+ def test_can_delete_initial_sql_from_connection(self):
+ conn = Connection(self.connection)
+ conn.initial_sql = None
+ self.assertEqual(conn.initial_sql, None)
+ self.assertIsNone(conn._connectionXML.get('initial_sql'))
+
+ def test_can_delete_query_band_from_connection(self):
+ conn = Connection(self.connection)
+ conn.query_band = None
+ self.assertEqual(conn.query_band, None)
+ self.assertIsNone(conn._connectionXML.get('query_band'))
def test_bad_dbclass_rasies_attribute_error(self):
conn = Connection(self.connection)
@@ -83,15 +89,44 @@ def test_can_create_connection_from_scratch(self):
self.assertEqual(conn.dbclass, 'mysql')
self.assertEqual(conn.authentication, 'd')
+ def test_can_create_oracle_connection_from_scratch(self):
+ conn = Connection.from_attributes(
+ server='a', dbname='b', username='c', dbclass='oracle', schema='d', service='e')
+ self.assertEqual(conn.server, 'a')
+ self.assertEqual(conn.schema, 'd')
+ self.assertEqual(conn.service, 'e')
+
def test_can_create_datasource_from_connections(self):
conn1 = Connection.from_attributes(
server='a', dbname='b', username='c', dbclass='mysql', authentication='d')
conn2 = Connection.from_attributes(
- server='1', dbname='2', username='3', dbclass='mysql', authentication='7')
+ server='1', dbname='2', username='3', dbclass='mysql', port='1337', authentication='7')
ds = Datasource.from_connections('test', connections=[conn1, conn2])
self.assertEqual(ds.connections[0].server, 'a')
+ self.assertEqual(ds.connections[0].port, None)
self.assertEqual(ds.connections[1].server, '1')
+ self.assertEqual(ds.connections[1].port, '1337')
+
+
+class ConnectionParserInComplicatedWorkbooks(unittest.TestCase):
+
+ def setUp(self):
+ with open(MULTI_CONNECTION_10, 'rb') as in_file, open('test.twb', 'wb') as out_file:
+ out_file.write(in_file.read())
+ self.twb_file = out_file
+
+ def tearDown(self):
+ self.twb_file.close()
+ os.unlink(self.twb_file.name)
+
+ def test_can_mixed_connections_workbook(self):
+ wb = Workbook(self.twb_file.name)
+ self.assertTrue(len(wb.datasources), 2)
+ self.assertTrue(len(wb.datasources[1].connections), 2)
+ self.assertEqual(wb.datasources[0].connections[0].dbclass, 'sqlproxy')
+ self.assertEqual(wb.datasources[1].connections[0].dbclass, 'mysql')
+ self.assertEqual(wb.datasources[1].connections[1].dbclass, 'sqlserver')
class DatasourceModelTests(unittest.TestCase):
@@ -117,22 +152,22 @@ def test_can_extract_connection(self):
def test_can_save_tds(self):
original_tds = Datasource.from_file(self.tds_file.name)
- original_tds.connections[0].dbname = 'newdb.test.tsi.lan'
+ original_tds.connections[0].dbname = 'newdb'
original_tds.save()
new_tds = Datasource.from_file(self.tds_file.name)
- self.assertEqual(new_tds.connections[0].dbname, 'newdb.test.tsi.lan')
+ self.assertEqual(new_tds.connections[0].dbname, 'newdb')
def test_save_has_xml_declaration(self):
original_tds = Datasource.from_file(self.tds_file.name)
- original_tds.connections[0].dbname = 'newdb.test.tsi.lan'
+ original_tds.connections[0].dbname = 'newdb'
original_tds.save()
with open(self.tds_file.name) as f:
first_line = f.readline().strip() # first line should be xml tag
self.assertEqual(
- first_line, "")
+ first_line, "")
class DatasourceModelV10Tests(unittest.TestCase):
@@ -158,11 +193,29 @@ def test_can_extract_connection(self):
def test_can_save_tds(self):
original_tds = Datasource.from_file(self.tds_file.name)
- original_tds.connections[0].dbname = 'newdb.test.tsi.lan'
+ original_tds.connections[0].dbname = 'newdb'
original_tds.save()
new_tds = Datasource.from_file(self.tds_file.name)
- self.assertEqual(new_tds.connections[0].dbname, 'newdb.test.tsi.lan')
+ self.assertEqual(new_tds.connections[0].dbname, 'newdb')
+
+ def test_can_save_as_tds(self):
+ new_filename = os.path.join(
+ os.path.dirname(self.tds_file.name),
+ "new_{}".format(os.path.basename(self.tds_file.name))
+ )
+
+ try:
+ original_tds = Datasource.from_file(self.tds_file.name)
+ original_tds.connections[0].dbname = 'newdb'
+
+ original_tds.save_as(new_filename)
+
+ new_tds = Datasource.from_file(new_filename)
+ self.assertEqual(new_tds.connections[0].dbname, 'newdb')
+ finally:
+ if os.path.exists(new_filename):
+ os.unlink(new_filename)
class DatasourceModelV10TDSXTests(unittest.TestCase):
@@ -183,22 +236,22 @@ def test_can_open_tdsx(self):
def test_can_open_tdsx_and_save_changes(self):
original_tdsx = Datasource.from_file(self.tdsx_file.name)
- original_tdsx.connections[0].server = 'newdb.test.tsi.lan'
+ original_tdsx.connections[0].server = 'newdb'
original_tdsx.save()
new_tdsx = Datasource.from_file(self.tdsx_file.name)
self.assertEqual(new_tdsx.connections[
- 0].server, 'newdb.test.tsi.lan')
+ 0].server, 'newdb')
def test_can_open_tdsx_and_save_as_changes(self):
new_tdsx_filename = 'newtdsx.tdsx'
original_wb = Datasource.from_file(self.tdsx_file.name)
- original_wb.connections[0].server = 'newdb.test.tsi.lan'
+ original_wb.connections[0].server = 'newdb'
original_wb.save_as(new_tdsx_filename)
new_wb = Datasource.from_file(new_tdsx_filename)
self.assertEqual(new_wb.connections[
- 0].server, 'newdb.test.tsi.lan')
+ 0].server, 'newdb')
os.unlink(new_tdsx_filename)
@@ -230,12 +283,12 @@ def test_has_filename(self):
def test_can_update_datasource_connection_and_save(self):
original_wb = Workbook(self.workbook_file.name)
- original_wb.datasources[0].connections[0].dbname = 'newdb.test.tsi.lan'
+ original_wb.datasources[0].connections[0].dbname = 'newdb'
original_wb.save()
new_wb = Workbook(self.workbook_file.name)
self.assertEqual(new_wb.datasources[0].connections[
- 0].dbname, 'newdb.test.tsi.lan')
+ 0].dbname, 'newdb')
class WorkbookModelV10Tests(unittest.TestCase):
@@ -260,24 +313,24 @@ def test_can_extract_datasourceV10(self):
def test_can_update_datasource_connection_and_saveV10(self):
original_wb = Workbook(self.workbook_file.name)
- original_wb.datasources[0].connections[0].dbname = 'newdb.test.tsi.lan'
+ original_wb.datasources[0].connections[0].dbname = 'newdb'
original_wb.save()
new_wb = Workbook(self.workbook_file.name)
self.assertEqual(new_wb.datasources[0].connections[
- 0].dbname, 'newdb.test.tsi.lan')
+ 0].dbname, 'newdb')
def test_save_has_xml_declaration(self):
original_wb = Workbook(self.workbook_file.name)
- original_wb.datasources[0].connections[0].dbname = 'newdb.test.tsi.lan'
+ original_wb.datasources[0].connections[0].dbname = 'newdb'
original_wb.save()
with open(self.workbook_file.name) as f:
first_line = f.readline().strip() # first line should be xml tag
self.assertEqual(
- first_line, "")
+ first_line, "")
class WorkbookModelV10TWBXTests(unittest.TestCase):
@@ -298,22 +351,22 @@ def test_can_open_twbx(self):
def test_can_open_twbx_and_save_changes(self):
original_wb = Workbook(self.workbook_file.name)
- original_wb.datasources[0].connections[0].server = 'newdb.test.tsi.lan'
+ original_wb.datasources[0].connections[0].server = 'newdb'
original_wb.save()
new_wb = Workbook(self.workbook_file.name)
self.assertEqual(new_wb.datasources[0].connections[
- 0].server, 'newdb.test.tsi.lan')
+ 0].server, 'newdb')
def test_can_open_twbx_and_save_as_changes(self):
new_twbx_filename = 'newtwbx.twbx'
original_wb = Workbook(self.workbook_file.name)
- original_wb.datasources[0].connections[0].server = 'newdb.test.tsi.lan'
+ original_wb.datasources[0].connections[0].server = 'newdb'
original_wb.save_as(new_twbx_filename)
new_wb = Workbook(new_twbx_filename)
self.assertEqual(new_wb.datasources[0].connections[
- 0].server, 'newdb.test.tsi.lan')
+ 0].server, 'newdb')
os.unlink(new_twbx_filename)
@@ -342,5 +395,6 @@ def test_82_workbook_throws_exception(self):
with self.assertRaises(TableauVersionNotSupportedException):
wb = Workbook(TABLEAU_82_TWB)
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/test_datasource.py b/test/test_datasource.py
index 66b3f79..838bc55 100644
--- a/test/test_datasource.py
+++ b/test/test_datasource.py
@@ -1,5 +1,9 @@
-import unittest
+import os
import os.path
+import shutil
+import tempfile
+import unittest
+
from tableaudocumentapi import Datasource, Workbook
@@ -22,6 +26,19 @@ class DataSourceFieldsTDS(unittest.TestCase):
def setUp(self):
self.ds = Datasource.from_file(TEST_TDS_FILE)
+ self.to_delete = set()
+
+ def cleanUp(self):
+ for path in self.to_delete:
+ if os.path.isdir(path):
+ shutil.rmtree(path, ignore_errors=True)
+ elif os.path.isfile(path):
+ os.unlink(path)
+
+ def get_temp_file(self, filename):
+ tempdir = tempfile.mkdtemp('tda-datasource')
+ self.to_delete.add(tempdir)
+ return os.path.join(tempdir, filename)
def test_datasource_returns_correct_fields(self):
self.assertIsNotNone(self.ds.fields)
@@ -63,6 +80,43 @@ def test_datasource_field_description(self):
self.assertIsNotNone(actual)
self.assertTrue(u'muted gray' in actual)
+ def test_datasource_caption(self):
+ actual = self.ds.caption
+ self.assertIsNotNone(actual)
+ self.assertEqual(actual, 'foo')
+
+ def test_datasource_can_set_caption(self):
+ filename = self.get_temp_file('test_datasource_can_set_caption')
+ self.ds.caption = 'bar'
+ self.ds.save_as(filename)
+
+ actual = Datasource.from_file(filename)
+ self.assertIsNotNone(actual)
+ self.assertIsNotNone(actual.caption)
+ self.assertEqual(actual.caption, 'bar')
+
+ def test_datasource_can_remove_caption(self):
+ filename = self.get_temp_file('test_datasource_can_remove_caption')
+ del self.ds.caption
+ self.ds.save_as(filename)
+
+ actual = Datasource.from_file(filename)
+ self.assertIsNotNone(actual)
+ self.assertEqual(actual.caption, '')
+
+ def test_datasource_clear_repository_location(self):
+ filename = os.path.join(TEST_ASSET_DIR, 'clear-repository-test.tds')
+
+ self.assertIsNotNone(self.ds._datasourceXML.find('.//repository-location'))
+ self.ds.clear_repository_location()
+ try:
+ self.ds.save_as(filename)
+ with open(filename, 'r') as newfile:
+ self.assertFalse('repository-location' in newfile.read())
+ finally:
+ if os.path.exists(filename):
+ os.unlink(filename)
+
class DataSourceFieldsTWB(unittest.TestCase):
diff --git a/test/test_field.py b/test/test_field.py
index 7cbe885..b222e81 100644
--- a/test/test_field.py
+++ b/test/test_field.py
@@ -12,6 +12,10 @@
TEST_ASSET_DIR,
'datasource_test.tds'
)
+TEST_UNICODE_FILE = os.path.join(
+ TEST_ASSET_DIR,
+ 'unicode.tds'
+)
class FieldsUnitTest(unittest.TestCase):
@@ -27,3 +31,9 @@ def find(self, *args, **kwargs):
def test_find_metadata_record_returns_none(self):
self.assertIsNone(_find_metadata_record(self.MockXmlWithNoFind(), 'foo'))
+
+
+class FieldsHandleUnicode(unittest.TestCase):
+ def test_description_unicode(self):
+ ds = Datasource.from_file(TEST_UNICODE_FILE)
+ self.assertIsNotNone(ds.fields['A'].description)
diff --git a/test/test_field_change.py b/test/test_field_change.py
new file mode 100644
index 0000000..2d39a65
--- /dev/null
+++ b/test/test_field_change.py
@@ -0,0 +1,209 @@
+import unittest
+import os.path
+
+from tableaudocumentapi import Datasource
+from lxml import etree as ET
+
+
+TEST_ASSET_DIR = os.path.join(
+ os.path.dirname(__file__),
+ 'assets'
+)
+TEST_TDS_FILE = os.path.join(
+ TEST_ASSET_DIR,
+ 'field_change_test.tds'
+)
+TEST_TDS_FILE_OUTPUT = os.path.join(
+ TEST_ASSET_DIR,
+ 'field_change_test_output.tds'
+)
+
+MESSAGES = {
+ 'test_change_values1': 'Value has not changed when altering values for {}.',
+ 'test_change_values2': 'XML-Structure has not changed when altering values for {}.',
+ 'test_change_valuesFail1': 'Value has changed when submitting the wrong value for {}.',
+ 'test_change_valuesFail2': 'XML-Structure has changed when submitting the wrong value for {}.',
+ 'test_change_aliases1': 'XML-Structure has not changed when altering aliases for {}.',
+ 'test_change_aliases2': 'Values have not changed when altering aliases for {}.'
+
+}
+
+NEW_VALUES = {
+ 'caption': 'testcaption',
+ 'alias': 'testalias',
+ 'datatype': 'boolean',
+ 'role': 'measure',
+ 'type': 'ordinal'
+}
+
+WRONG_VALUES = {
+ 'datatype': 'boolani',
+ 'role': 'messhure',
+ 'type': 'gordinol'
+}
+
+ALIASES = {
+ 'one': 'two',
+ 'three': 'four',
+ 'five': 'six'
+}
+
+
+class TestFieldChange(unittest.TestCase):
+
+ def setUp(self):
+ self.tds = Datasource.from_file(TEST_TDS_FILE)
+
+ def current_hash(self):
+ """ Return a hash of the current state of the XML.
+
+ Allows us to easily identify whether the underlying XML-structure
+ of a TDS-file has actually changed. Avoids false positives if,
+ for example, a fields value has changed but the XML hasn't.
+ """
+ return hash(ET.tostring(self.tds._datasourceTree.getroot()))
+
+ def check_state_change(self, should_change, msg, field_name):
+ """ Check whether the XML has changed and update the current state.
+
+ Args:
+ should_change: Whether the XML is supposed to have changed or not. Boolean.
+ msg: The message to be displayed in an error case, as key for the MESSAGES dict. String.
+ field_name: The field name that will be displayed in the error message. String.
+
+ Returns:
+ Nothing.
+ """
+ new_state = self.current_hash()
+ compare_func = self.assertNotEqual if should_change else self.assertEqual
+ compare_func(
+ self.state,
+ new_state,
+ msg=MESSAGES[msg].format(field_name)
+ )
+ self.state = new_state
+
+ def test_change_values(self):
+ """ Test if the value changes of a field are reflected in the object and in the underlying XML structure.
+ """
+ field_to_test = "[amount]"
+ self.state = self.current_hash()
+ # change all fields
+ for key, value in NEW_VALUES.items():
+ setattr(self.tds.fields[field_to_test], key, value)
+ # the new value must be reflected in the object
+ self.assertEqual(
+ getattr(self.tds.fields[field_to_test], key),
+ value,
+ msg=MESSAGES['test_change_values1'].format(key)
+ )
+ # the new value must be reflected in the xml
+ self.check_state_change(True, 'test_change_values2', key)
+
+ def test_change_values_fail(self):
+ """ Test if the value changes of a field are rejected if the wrong arguments are passed.
+ """
+ field_to_test = "[amount]"
+ self.state = self.current_hash()
+ # change all fields
+ for key, value in WRONG_VALUES.items():
+
+ with self.assertRaises(ValueError):
+ # this must fail
+ setattr(self.tds.fields[field_to_test], key, value)
+
+ # the new value must NOT be reflected in the object
+ self.assertNotEqual(
+ getattr(self.tds.fields[field_to_test], key),
+ value,
+ msg=MESSAGES['test_change_valuesFail1'].format(key)
+ )
+ # the new value must NOT be reflected in the xml
+ self.check_state_change(False, 'test_change_valuesFail2', key)
+
+ def test_remove_field(self):
+ """ Test if a Field can be removed.
+ """
+ field_to_test = "[amount]"
+ self.state = self.current_hash()
+ # change all fields
+ field = self.tds.fields["[amount]"]
+ self.tds.remove_field(field)
+ self.assertNotEqual(self.state, self.current_hash())
+
+ def test_change_aliases(self):
+ """ Test if the alias changes of a field are reflected in the object and in the underlying XML structure.
+ """
+ field_to_test = "[amount]"
+ self.state = self.current_hash()
+ # change all fields
+ for key, value in ALIASES.items():
+ self.tds.fields[field_to_test].add_alias(key, value)
+ # the new value must be reflected in the xml
+ self.check_state_change(True, 'test_change_aliases1', field_to_test)
+
+ # check whether all fields of ALIASES have been applied
+ self.assertEqual(
+ set(self.tds.fields[field_to_test].aliases),
+ set(ALIASES),
+ msg=MESSAGES['test_change_aliases2'].format(field_to_test)
+ )
+
+ def test_calculation_base(self):
+ """ Test if the initial state of calculated fields is correct.
+ """
+ # Demo data has 2 calculated fields at the start
+ original_len = len(self.tds.calculations)
+
+ # Can't write to calculation for not-calculated fields!
+ self.tds.fields['[name]'].calculation = '1 * 2'
+ self.assertEqual(len(self.tds.calculations), original_len + 1)
+ self.tds.fields['[name]'].calculation = '2 * 3'
+ self.assertEqual(len(self.tds.calculations), original_len + 1)
+ self.tds.fields['[price]'].calculation = '2 * 3'
+ self.assertEqual(len(self.tds.calculations), original_len + 2)
+
+ def test_calculation_change(self):
+ """ Test whether changing calculations of a field works.
+ """
+ self.state = self.current_hash()
+ new_calc = '33 * 44'
+ fld_name = '[Calculation_357754699576291328]'
+ self.tds.calculations[fld_name].calculation = new_calc
+
+ # Check object representation
+ self.assertEqual(self.tds.calculations[fld_name].calculation, new_calc)
+
+ # Check XML representation
+ new_state = self.current_hash()
+ self.assertNotEqual(self.state, new_state)
+
+ def test_calculation_new(self):
+ """ Test if creating a new calculation works.
+ """
+ args = 'TestCalc', '12*34', 'integer', 'measure', 'quantitative', 'False'
+ original_len = len(self.tds.calculations)
+ self.tds.add_calculation(*args)
+ self.assertEqual(len(self.tds.calculations), original_len + 1)
+
+ def test_calculation_remove(self):
+ """ Test if deleting a calculation works.
+ """
+ args = 'TestCalc2', '12*34', 'integer', 'measure', 'quantitative', 'True'
+
+ original_len = len(self.tds.calculations)
+ calc = self.tds.add_calculation(*args)
+ self.assertEqual(len(self.tds.calculations), original_len + 1)
+
+ self.tds.remove_field(calc)
+ self.assertEqual(len(self.tds.calculations), original_len)
+
+ def tearDown(self):
+ """ Test if the file can be saved.
+ Output file will be ignored by git, but can be used to verify the results.
+ """
+ self.tds.save_as(TEST_TDS_FILE_OUTPUT)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test_workbook.py b/test/test_workbook.py
index 80e7da5..41501db 100644
--- a/test/test_workbook.py
+++ b/test/test_workbook.py
@@ -12,8 +12,40 @@
'ephemeral_field.twb'
)
+SHAPES_FILE = os.path.join(
+ TEST_ASSET_DIR,
+ 'shapes_test.twb'
+)
+
+DASHBOARDS_FILE = os.path.join(
+ TEST_ASSET_DIR,
+ 'filtering.twb'
+)
+
class EphemeralFields(unittest.TestCase):
def test_ephemeral_fields_do_not_cause_errors(self):
wb = Workbook(EPHEMERAL_FIELD_FILE)
self.assertIsNotNone(wb)
+
+
+class Shapes(unittest.TestCase):
+ def test_shape_exist(self):
+ wb = Workbook(SHAPES_FILE)
+ self.assertEqual(wb.shapes, ['Bug Tracking/bug.png',
+ 'Bug Tracking/icon-scheduleitem.png',
+ 'Bug Tracking/light.png',
+ 'Bug Tracking/mail.png',
+ ]
+ )
+
+ def test_shape_count(self):
+ wb = Workbook(SHAPES_FILE)
+ self.assertEqual(len(wb.shapes), 4)
+
+
+class Dashboards(unittest.TestCase):
+ def test_dashboards_setup(self):
+ wb = Workbook(DASHBOARDS_FILE)
+ self.assertIsNotNone(wb)
+ self.assertEqual(wb.dashboards, ['setTest'])
diff --git a/test/test_xfile.py b/test/test_xfile.py
index 6cbe67f..c9686f5 100644
--- a/test/test_xfile.py
+++ b/test/test_xfile.py
@@ -1,19 +1,62 @@
-import os.path
+from test.assets.index import *
+
import unittest
import zipfile
from tableaudocumentapi.xfile import find_file_in_zip
+from tableaudocumentapi import Workbook, Datasource
TEST_ASSET_DIR = os.path.join(
os.path.dirname(__file__),
'assets'
)
+
BAD_ZIP_FILE = os.path.join(
TEST_ASSET_DIR,
'BadZip.zip'
)
+TWBX_WITH_CACHE_FILES = os.path.join(
+ TEST_ASSET_DIR,
+ 'Cache.twbx'
+)
+
class XFileEdgeTests(unittest.TestCase):
def test_find_file_in_zip_no_xml_file(self):
badzip = zipfile.ZipFile(BAD_ZIP_FILE)
self.assertIsNone(find_file_in_zip(badzip))
+
+ def test_only_find_twbs(self):
+ twb_from_twbx_with_cache = zipfile.ZipFile(TWBX_WITH_CACHE_FILES)
+ self.assertEqual(find_file_in_zip(twb_from_twbx_with_cache), 'Superstore.twb')
+
+
+class Namespacing(unittest.TestCase):
+
+ def assertContainsUserNamespace(self, filename):
+ with open(filename, 'r') as in_file:
+ # the namespace is in the first five lines for all the docs I've checked
+ lineCount = 0
+ doc_beginning_excerpt = ""
+ while lineCount < 5:
+ doc_beginning_excerpt += (in_file.readline().strip()) # first line should be xml tag
+ lineCount += 1
+ found = doc_beginning_excerpt.rfind("xmlns:user=")
+ # print(doc_beginning_excerpt[found:found+10])
+ self.assertRegex(doc_beginning_excerpt, "xmlns:user=")
+
+ def test_save_preserves_namespace_twb(self):
+ filename = COMPLEX_TWB
+ self.assertContainsUserNamespace(filename)
+ wb = Workbook(filename)
+ new_name = 'saved-as-twb.twb'
+ wb.save_as(new_name)
+ self.assertContainsUserNamespace(new_name)
+
+ def demo_bug_ns_not_preserved_if_not_used(self):
+ filename = TABLEAU_10_TDS
+ self.assertContainsUserNamespace(filename)
+ wb = Datasource.from_file(filename)
+ new_name = 'saved-as-tds.tds'
+ wb.save_as(new_name)
+ self.assertContainsUserNamespace(new_name)
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy