iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
2
自我挑戰組

中年失業大叔的耍廢日記系列 第 8

第八天:臃腫的週三

  • 分享至 

  • xImage
  •  

昨天吃太飽...成吉思汗蒙古烤肉的東西還蠻不錯吃,一不小心就吃太多。只是雖然搬了新家,地方似乎不是很大,裝潢也很樸素XD

今天電很夠,所以還是先到家附近的咖啡店寫作業。然後座位對面似乎是民眾黨的人物?電話都在解釋...

今天還是繼續調整程式架構,並且開始寫測試。還是覺得咖啡店冷氣太冷,撐了兩個鐘頭就敗退...好,下午繼續,中午吃個自助餐吧。

下午繼續,先裝好mocha跟chai然後寫個簡單用例來跑跑看:

const mocha = require('mocha');
const assert = require('chai').assert;
const xml2json = require('../lib/xml2json.js')

const teststr = '<?xml version="1.0" encoding="utf-8"?><aas:aasenv xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:IEC61360="http://www.admin-shell.io/IEC61360/2/0" xsi:schemaLocation="http://www.admin-shell.io/aas/2/0 AAS.xsd http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd" xmlns:aas="http://www.admin-shell.io/aas/2/0"><aas:assetAdministrationShells><aas:assetAdministrationShell><aas:idShort>TypeAAS</aas:idShort><aas:description><aas:langString lang="EN">AAS oft MTP type type32</aas:langString></aas:description><aas:identification idType="IRI">www.vendor.com/ids/sm/6233_9041_1002_7102</aas:identification><aas:assetRef><aas:keys><aas:key type="Asset" local="true" idType="IRI">http://vendor.com/module-types/type32</aas:key></aas:keys></aas:assetRef><aas:submodelRefs><aas:submodelRef><aas:keys><aas:key type="Submodel" local="true" idType="IRI">www.vendor.com/ids/sm/6233_9041_1002_7102</aas:key></aas:keys></aas:submodelRef><aas:submodelRef><aas:keys><aas:key type="Submodel" local="true" idType="IRI">www.vendor.com/ids/sm/5324_9041_1002_7612</aas:key></aas:keys></aas:submodelRef></aas:submodelRefs><aas:conceptDictionaries /></aas:assetAdministrationShell><aas:assetAdministrationShell><aas:idShort>InstanceAAS</aas:idShort><aas:identification idType="IRI">www.vendor.com/ids/sm/6233_9041_1002_7103</aas:identification><aas:derivedFrom><aas:keys><aas:key type="AssetAdministrationShell" local="true" idType="IRI">www.vendor.com/ids/sm/6233_9041_1002_7102</aas:key></aas:keys></aas:derivedFrom><aas:assetRef><aas:keys><aas:key type="Asset" local="true" idType="IRI">http://vendor.com/module/4711</aas:key></aas:keys></aas:assetRef><aas:submodelRefs><aas:submodelRef><aas:keys><aas:key type="Submodel" local="true" idType="IRI">www.vendor.com/ids/sm/4594_9041_1002_9069</aas:key></aas:keys></aas:submodelRef><aas:submodelRef><aas:keys><aas:key type="Submodel" local="true" idType="IRI">www.vendor.com/ids/sm/8115_9041_1002_3217</aas:key></aas:keys></aas:submodelRef></aas:submodelRefs><aas:conceptDictionaries /></aas:assetAdministrationShell></aas:assetAdministrationShells></aas:aasenv>';

describe('starting', () => {
    describe('add Asset Administration Shell', () => {
        it('test convert xml to json', () => {
            let obj = xml2json(teststr);
            let shouldbe = '{"xml":{},"aasenv":{"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","xmlns:IEC61360":"http://www.admin-shell.io/IEC61360/2/0","xsi:schemaLocation":"http://www.admin-shell.io/aas/2/0 AAS.xsd http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd","xmlns:aas":"http://www.admin-shell.io/aas/2/0","assetAdministrationShells":[{"idShort":"TypeAAS","description":[{"lang":"EN","_value":"AAS oft MTP type type32"}],"identification":{"idType":"IRI","_value":"www.vendor.com/ids/sm/6233_9041_1002_7102"},"assetRef":{"keys":[{"type":"Asset","local":"true","idType":"IRI","_value":"http://vendor.com/module-types/type32"}]},"submodelRefs":[{"keys":[{"type":"Submodel","local":"true","idType":"IRI","_value":"www.vendor.com/ids/sm/6233_9041_1002_7102"}]},{"keys":[{"type":"Submodel","local":"true","idType":"IRI","_value":"www.vendor.com/ids/sm/5324_9041_1002_7612"}]}],"conceptDictionaries":[]},{"idShort":"InstanceAAS","identification":{"idType":"IRI","_value":"www.vendor.com/ids/sm/6233_9041_1002_7103"},"derivedFrom":{"keys":[{"type":"AssetAdministrationShell","local":"true","idType":"IRI","_value":"www.vendor.com/ids/sm/6233_9041_1002_7102"}]},"assetRef":{"keys":[{"type":"Asset","local":"true","idType":"IRI","_value":"http://vendor.com/module/4711"}]},"submodelRefs":[{"keys":[{"type":"Submodel","local":"true","idType":"IRI","_value":"www.vendor.com/ids/sm/4594_9041_1002_9069"}]},{"keys":[{"type":"Submodel","local":"true","idType":"IRI","_value":"www.vendor.com/ids/sm/8115_9041_1002_3217"}]}],"conceptDictionaries":[]}]}}';
            assert(JSON.stringify(obj) === shouldbe, 'ok');
        });
    }) 
});

然後改一下package.json,把下面這行:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },

改成:

  "scripts": {
    "test": "node_modules/.bin/mocha tests"
  },

然後執行:

npm test

就可以看到結果:

fillano$ npm test

> aasserv@1.0.0 test /Users/fillano/builds/aasserv
> mocha tests



  starting
    add Asset Administration Shell
      ✓ test convert xml to json


  1 passing (24ms)

確認可以跑出結果,就可以繼續下去。istanbul就等後面再來改。

結果傍晚意外陷入昏睡,還好九點醒來了,沒錯過發文/images/emoticon/emoticon37.gif

接下來還是看一下處理pptx viewer的程式...

<!DOCTYPE html>
<html>

<head>
    <title>file reader</title>
    <style>
        .dropable {
            width: 99%;
            height: 100px;
            background-color: #369;
            color: white;
            border: solid 3px gray;
            border-radius: 5px;
            padding: 5px 5px 5px 5px;
        }

        .message {
            width: 99%;
            background-color: #ddd;
            border: solid 1px gray;
            border-radius: 5px;
            overflow: auto;
        }

        .preview {
            font-size: 10px;
        }
    </style>
</head>

<body>
    <div id="target" class="dropable">
        <select id="encoding">
            <option value="utf-8">utf-8</option>
            <option value="big5">big5</option>
            <option value="gb2312">gb2312</option>
            <option value="shift-jis">shift-jis</option>
        </select>
        <input type="file" id="file" />
        <div id="console"></div>
    </div>
    <div id="panel" class="message"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.11/pako_inflate.min.js"></script>
    <script src="lib/zipfs.js"></script>
    <script src="node_modules/xmlrun/index.js"></script>
    <script>
        var _target = document.getElementById('target');
        var _message = document.getElementById('panel');
        var _file = document.getElementById('file');
        _file.onchange = function(e) {
            clearlog();
            if (this.files.length > 0) {
                var reader = new FileReader();
                reader.onload = (e) => {
                    var buffer = e.target.result;
                    log('file size: ' + buffer.byteLength);
                    let encoding = document.getElementById('encoding').value;
                    let start = new Date().getTime();
                    zipfs(buffer, pako.inflateRaw, encoding, (err, files) => {
                        if (!!err) return console.log(err);
                        log(`in callback: ${files.length} files extracted.`);
                        log(`${(new Date().getTime()-start)} ms`);
                        let str = '<table border="1" cellspacing="0" cellpadding="5" width="99%"><tr><th>file name</th><th>buffer length</th><th>last modified date</th><th>last modified time</th><th>compressed size</th><th>uncompressed size</th></tr>';
                        files.forEach(file => {
                            str += `<tr><td>${file.file_name}</td><td>${file.content.length}</td><td>${zipfs.formatMSDOSDate(file.last_modified_date)}</td><td>${zipfs.formatMSDOSTime(file.last_modified_time)}</td><td>${file.compressed_size}</td><td>${file.uncompressed_size}</td></tr>`;
                            str += `<tr><td colspan="6" class="preview" style="overflow-x:hidden">`;
                            if (checkExt(file.file_name, '.rels')/* && file.file_name.split('/')[file.file_name.split('/').length-1].length > 5*/) {
                                console.log(file.file_name);
                                let runner = xmlnode(zipfs.uintToString(file.content));
                                runner.setRunner('default', function(target) {
                                    if(!!target.child) {
                                        return target.child.reduce((acc, cur) => {
                                            Object.assign(acc, cur.run());
                                            return acc;
                                        }, {})
                                    }
                                    else return {};
                                });
                                runner.setRunner('Relationship', target => {
                                    let result = {};
                                    result[target.attr['Id']] = target.attr['Target'];
                                    result[target.attr['Target']] = target.attr['Id'];
                                    return result;
                                });
                                let obj = runner.run();
                                str += `<pre>${JSON.stringify(obj, null, 2)}</pre>`;
                            }

                            if (checkExt(file.file_name, '.xml')) {
                                let runner = xmlnode(zipfs.uintToString(file.content));
                                runner.setRunner('default', function(target) {
                                    let result = {
                                        type: xmlnode.utils.getNodeTypeDesc(target.type),
                                        tagName: target.tag,
                                        attributes: target.attr,
                                        value: target.val,
                                        children: []
                                    }
                                    if(!!target.child) {
                                        result.children = target.child.reduce((acc, cur) => {
                                            acc.push(cur.run());
                                            return acc;
                                        }, []);
                                    }
                                    return result;
                                });
                                let obj = runner.run();
                                str += `<pre>${JSON.stringify(obj, null, 2)}</pre>`;
                            }
                            if (checkExt(file.file_name, '.jpeg') || checkExt(file.file_name, '.jpg')) {
                                let im = new Image();
                                im.src = `data:image/jpeg;base64,${zipfs.arrayBufferToBase64(file.content)}`;
                                if(im.width > 1024) {
                                    str += `<img width="1024px" src="data:image/jpeg;base64,${zipfs.arrayBufferToBase64(file.content)}">`;
                                } else {
                                    str += `<img src="data:image/jpeg;base64,${zipfs.arrayBufferToBase64(file.content)}">`;
                                }
                            }
                            if (checkExt(file.file_name, '.png')) {
                                let im = new Image();
                                im.src = `data:image/png;base64,${zipfs.arrayBufferToBase64(file.content)}`;
                                if(im.width > 1024) {
                                    str += `<img width="1024px" src="data:image/png;base64,${zipfs.arrayBufferToBase64(file.content)}">`;
                                } else {
                                    str += `<img src="data:image/png;base64,${zipfs.arrayBufferToBase64(file.content)}">`;
                                }
                            }
                            if (checkExt(file.file_name, '.mp3')) {
                                str += '<audio controls type="audio/mpeg" src="data:audio/mp3;base64,' +
                                    zipfs.arrayBufferToBase64(file.content) + '">';
                            }
                            str += '</td></tr>';
                        });
                        str += '</table>';
                        document.getElementById('panel').innerHTML = str;
                    });
                };
                reader.readAsArrayBuffer(this.files[0]);
            }
            function checkExt(name, ext) {
                return name.lastIndexOf(ext) === name.length - ext.length;
            }
            function log(msg) {
                document.getElementById('console').innerHTML += `<br />${msg}`; 
            }
            function clearlog() {
                document.getElementById('console').innerHTML = ''; 
            }
        }
    </script>
</body>

</html>

先來處理.rels檔,其內容如昨天所說的,就是一個id與目標檔案的對照,所以增加一個針對.rels檔處理內容的程式,結果一般xml檔顯示:

https://ithelp.ithome.com.tw/upload/images/20200923/20000108EWWzNvxejT.png

如果是.rels檔,就會特別處理:

https://ithelp.ithome.com.tw/upload/images/20200923/20000108hGngedhWFf.png

好了,本日quota已經達到(剛剛程式忘了呼叫某遞迴函數,找問題找了好久...),先休息了。


上一篇
第七天:平淡無奇的週二
下一篇
第九天:今天是奮發的星期四
系列文
中年失業大叔的耍廢日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
海綿寶寶
iT邦大神 1 級 ‧ 2020-09-23 22:34:21

寫程式配咖啡/蒙古烤肉
會不會有點放縱
/images/emoticon/emoticon72.gif

好想吃烤肉
/images/emoticon/emoticon07.gif

我要留言

立即登入留言