1 import '../../common/init';
2 import { isMainThread, workerData } from 'worker_threads';
3 import { wrt } from '../../browser/wrt';
4 import { URL } from 'url';
5 import * as fs from 'fs';
6 import * as https from 'https';
7 import * as XWalkExtension from '../../common/wrt_xwalk_extension';
9 function getManifestFile(manifestUrl: string) {
10 console.log('manifestUrl : '+manifestUrl);
11 return new Promise((resolve, reject) => {
12 const req = https.request(manifestUrl, (res) => {
13 res.setEncoding('utf8');
14 let responseBody = '';
15 res.on('data', (data) => {
19 resolve(JSON.parse(responseBody));
21 }).on('error', (err) => {
22 console.log(`error : ${err}`);
29 async function downloadIcon(iconSrc: string, iconFile: string) {
30 console.log('iconSrc : ' + iconSrc);
31 return new Promise((resolve, reject) => {
32 const req = https.request(iconSrc, (res) => {
33 const Stream = require('stream').Transform;
34 let data = new Stream();
35 res.on('data', (chunk) => {
39 fs.writeFileSync(iconFile, data.read());
42 }).on('error', (err) => {
43 console.log(`error : ${err}`);
50 function makeFileSync(file: string, data: string) {
51 fs.writeFileSync(file, data);
54 function concatWithBaseUrl(path: string, baseUrl: string) {
55 if (path.substr(0, 1) === '/') {
56 const url = new URL(path, baseUrl);
57 return url.toString();
58 } else if (path.indexOf('http:') == -1 && path.indexOf('https:') == -1) {
59 return baseUrl.substr(0, baseUrl.lastIndexOf('/') + 1) + path;
64 let baseWorkingDir = '/home/owner/content/Downloads/AppManifest';
65 let downloadVirtualDir = 'downloads/AppManifest';
66 let iconFile: string = '';
67 let iconName: string = '';
68 let manifestFile: string = '';
69 let convertedConfigXml: string = '';
70 let refCount: number = 0;
72 function getAppName(appName: string) {
73 appName = appName.replace(/ /g, '');
74 console.log('appName : ' + appName);
78 function makeWorkingFolder(appName: string) {
79 let workingDir = `${baseWorkingDir}/${appName}`;
80 fs.rmdirSync(workingDir, { recursive: true });
81 fs.mkdir(workingDir, { recursive: true }, (err) => {
83 console.log(`mkdir error : ${err}`)
87 async function handleIcon(appName: string, manifestUrl: string, manifest: any) {
88 let lengthOfIcons = manifest['icons'].length;
89 let lastIcon = manifest['icons'][lengthOfIcons - 1];
90 let iconSrc = concatWithBaseUrl(lastIcon['src'], manifestUrl);
91 iconName = iconSrc.substr(iconSrc.lastIndexOf('/') + 1);
92 iconFile = `${baseWorkingDir}/${appName}/${iconName}`;
93 await downloadIcon(iconSrc, iconFile);
94 iconFile = `${downloadVirtualDir}/${appName}/${iconName}`;
98 function makeManifestFile(appName: string, manifest: any) {
99 manifestFile = `${baseWorkingDir}/${appName}/appmanifest.json`;
100 makeFileSync(manifestFile, JSON.stringify(manifest));
101 manifestFile = `${downloadVirtualDir}/${appName}/appmanifest.json`;
105 function makePkgId(startUrl: string) {
106 let id = Buffer.from(startUrl).toString('base64');
107 id = id.replace(/=/gi, '');
108 console.log(`id : ${id}`);
109 return id.substr(-10);
112 function convertConfigXml(appName: string, startUrl: string) {
113 convertedConfigXml = `${baseWorkingDir}/${appName}/config.xml`;
114 let id = makePkgId(startUrl);
115 let configXml = `<?xml version='1.0' encoding='UTF-8'?>`;
116 configXml += `<widget xmlns='http://www.w3.org/ns/widgets' xmlns:tizen='http://tizen.org/ns/widgets' id='http://yourdomain/AppManifest' version='1.0.0' viewmodes='maximized'>`;
117 configXml += `<tizen:application id='${id}.${appName}' package='${id}' required_version='3.0' />`;
118 configXml += `<content src='${startUrl}' />`
119 configXml += `<icon src='${iconName}' />`;
120 configXml += `<name>${appName}</name>`;
121 configXml += `<access origin='*' subdomains='true' />`;
122 configXml += `</widget>`;
123 makeFileSync(convertedConfigXml, configXml);
124 convertedConfigXml = `${downloadVirtualDir}/${appName}/config.xml`;
128 function cleanUpAndQuit(appName: string) {
129 let workingDir = `${baseWorkingDir}/${appName}`;
130 fs.rmdirSync(workingDir, { recursive: true });
134 function installWgt(appName: string) {
135 let wgtPath = `${baseWorkingDir}/${appName}/${appName}.wgt`;
136 let installinfo = "{\"app_id\":\"" + appName + "\",\"pkg_path\":\"" + wgtPath + "\"}";
137 console.log(`installWgt info: ${installinfo}`);
138 (wrt.tv as any).notifyInstall(installinfo);
142 function makeWgt(appName: string) {
143 let wgtPath = `${downloadVirtualDir}/${appName}/${appName}.wgt`;
144 let onArchive = (archive: any) => {
145 function progressCallback(opId: string, val: number, name: any) {
146 console.log('opId: ' + opId + ' with progress val: ' + (val * 100).toFixed(0) + '%');
148 function successCallback() {
149 console.log(`File added : ${refCount}`);
155 console.log(`convertedConfigXml : ${convertedConfigXml}`);
156 console.log(`manifestFile : ${manifestFile}`);
157 console.log(`iconFile : ${iconFile}`);
158 let defaultArchiveFileEntryOption = { destination:'', stripSourceDirectory: true};
159 archive.add(convertedConfigXml, successCallback, null, progressCallback, defaultArchiveFileEntryOption);
160 archive.add(manifestFile, successCallback, null, progressCallback, defaultArchiveFileEntryOption);
162 archive.add(iconFile, successCallback, null, progressCallback, defaultArchiveFileEntryOption);
164 global.tizen.archive.open(wgtPath, 'w', onArchive, () => { }, { overwrite: true });
167 async function parseAndHandleManifest(manifestUrl: string) {
168 let manifest: any = await getManifestFile(manifestUrl);
169 let appName = getAppName(manifest['name']);
171 makeWorkingFolder(appName);
172 if (manifest['icons']) {
173 await handleIcon(appName, manifestUrl, manifest);
175 if (manifest['start_url']) {
176 let startUrl = concatWithBaseUrl(manifest['start_url'], manifestUrl);
177 manifest['start_url'] = startUrl;
179 makeManifestFile(appName, manifest);
180 convertConfigXml(appName, startUrl);
184 console.log(`Exception: ${e}`);
185 cleanUpAndQuit(appName);
189 export function run(manifestUrl: string) {
190 console.log(`Appmanifest parser starts for ${manifestUrl}`);
191 setInterval(() => { }, 500);
192 wrt.tv?.delayShutdown();
193 XWalkExtension.initialize();
194 parseAndHandleManifest(manifestUrl);
198 run(decodeURIComponent(workerData.id));