-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget-fonts-used-by-workbook.js
97 lines (70 loc) · 2.89 KB
/
get-fonts-used-by-workbook.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
const findFonts = require('./find-fonts');
const tableauApi = require('./tableau-api');
const JSZip = require("jszip");
// takes a buffer and returns it (if its a TWB) or unzips and finds the first TWB file and returns that
async function getWorkbookTwbFromResponseData(responseData) {
// we'll have to decode stuff from ArrayBuffer, and assume UTF-8 for all
let decoder = new TextDecoder('utf-8');
// check if its an XML (we dont want to eat ZIP opening errors and do this in a catch)
const checkHeader = "<\?xml version='1.0' encoding='utf-8' \?>"
if (responseData.length > checkHeader.length) {
let headerBuffer = responseData.slice(0, checkHeader.length);
let decodedHeader = decoder.decode(headerBuffer);
if (decodedHeader == checkHeader) {
console.log("Contents start with XML header -- using full response as TWB");
return decoder.decode(responseData);
}
}
// Load the zip
let loadedZip = await JSZip.loadAsync(responseData);
let targetPath;
// first find the file (forEach is not async)
loadedZip.forEach(function (relativePath, zipEntry) { // 2) print entries
let entryName = zipEntry.name;
if (/\.twb$/.test(entryName)) {
targetPath = relativePath;
}
});
// check if we actually have the file
if (typeof targetPath !== 'string') {
throw new Error("Cannot find workbook inside the TWBX file");
}
// then read the target file
let data = await loadedZip.file(targetPath).async('string');
return data;
}
async function getFontsUsedByWorkbook(tableauSession, workbookId) {
// download the workbook
let workbookData = await tableauApi.downloadWorkbook(tableauSession, workbookId);
let twbData = await getWorkbookTwbFromResponseData(workbookData);
// figure out the fonts
let fontsUsed = findFonts.findFontsUsedByXml(twbData);
// download workbook metadata
let workbookMetadata = await tableauApi.getWorkbookMetadata(tableauSession, workbookId);
return {
createdAt: new Date().getUTCDate(),
workbook: workbookMetadata.workbook,
site: tableauSession.site,
fonts: fontsUsed,
}
}
// Logs in to the server, and fetches workbooks for a site, scans them and returns a list of scan results
async function scanWorkbooksOnSite(tableauSessionConfig, siteContentUrl, workbookIds ) {
// add the site content URL to the login config (and duplicate it so we dont overwrite it...
const sessionConfig = Object.assign({}, tableauSessionConfig, {
siteContentUrl: siteContentUrl,
});
const tableauSession = await tableauApi.login(sessionConfig);
// the output
const results = [];
// scan one at a time and wait instead of jumping on the server at once
for (const workbookId of workbookIds) {
results.push(await getFontsUsedByWorkbook(tableauSession, workbookId));
}
await tableauApi.logout(tableauSession);
return results;
}
module.exports = {
getFontsUsedByWorkbook,
scanWorkbooksOnSite,
}