From 29f23d5594e57b3304f832225c90a76da7f55f51 Mon Sep 17 00:00:00 2001 From: Jack Liao Date: Wed, 15 Jul 2020 14:38:34 +0800 Subject: [PATCH] add tree.js --- src/tree.js | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/tree.js diff --git a/src/tree.js b/src/tree.js new file mode 100644 index 0000000..c90d13d --- /dev/null +++ b/src/tree.js @@ -0,0 +1,115 @@ +module.exports = { gen_tree_html } + +function gen_tree_html (arr) { + const data = gen_tree_data(arr, is_gd_folder) + return tree_tpl(JSON.stringify(data)) +} + +function tree_tpl (str) { + return ` + + + + + + + Folder Tree + + + + + +
+ + + + +` +} + +function is_gd_folder (data) { + return data.mimeType === 'application/vnd.google-apps.folder' +} + +function gen_tree_data (data, is_folder) { + if (!data || !data.length) return [] + const folders = data.filter(is_folder) + const files = data.filter(v => !is_folder(v)) + const total_size = sum(files.map(v => v.size)) + const root = { + title: `/根目錄 [共${files.length} 個檔案(不包括資料夾), ${format_size(total_size)}]`, + key: data[0].parent + } + if (!folders.length) return [root] + const sub_folders = folders.filter(v => v.parent === folders[0].parent) + sub_folders.forEach(v => { + sum_files(v, data, is_folder) + count_files(v, data, is_folder) + }) + sort_folders(folders, 'count') + sort_folders(sub_folders, 'count') + folders.forEach(v => { + let {name, size, count, id} = v + if (name.length > 50) name = name.slice(0, 48) + '...' + v.title = `${name} | [共${count}個檔案 ${format_size(size)}]` + }) + root.children = sub_folders.map(v => gen_node(v, folders)) + return [root] +} + +function sort_folders (folders, type) { + if (!folders || !folders.length) return + if (type === 'size') return folders.sort((a, b) => b.size - a.size) + if (type === 'count') return folders.sort((a, b) => b.count - a.count) +} + +function gen_node (v, folders) { + const {id, title, node} = v + if (node) return node + return v.node = { + title, + key: id, + children: v.children || folders.filter(vv => vv.parent === id).map(vv => gen_node(vv, folders)) + } +} + +function count_files (folder, arr, is_folder) { + if (folder.count) return folder.count + const children = arr.filter(v => v.parent === folder.id) + return folder.count = sum(children.map(v => { + if (is_folder(v)) return count_files(v, arr, is_folder) + return 1 + })) +} + +function sum_files (folder, arr, is_folder) { + if (folder.size) return folder.size + const children = arr.filter(v => v.parent === folder.id) + return folder.size = sum(children.map(v => { + if (is_folder(v)) return sum_files(v, arr, is_folder) + return v.size + })) +} + +function sum (arr) { + let result = 0 + for (const v of arr) { + result += Number(v) || 0 + } + return result +} + +function format_size (n) { + n = Number(n) + if (Number.isNaN(n)) return '' + if (n < 0) return 'invalid size' + const units = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] + let flag = 0 + while (n >= 1024) { + n = n / 1024 + flag++ + } + return n.toFixed(2) + ' ' + units[flag] +}