Skip to content

Commit b2b88ae

Browse files
authored
support multiple steps such as rename with a specific column (#38)
* dependencies are updated * update version of the app * process items batched instead of one by one, enabled contextIsolation and disable Node Integration, add CSP for renderer security, preload ipcRenderer based communication event bus mechanism * add another column to the sample excel file on readme
1 parent 446869c commit b2b88ae

13 files changed

+5112
-5978
lines changed

.babelrc

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
{
2-
"env": {
3-
"test": {
4-
"presets": ["@babel/preset-env"]
5-
}
6-
}
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"useBuiltIns": "usage",
7+
"corejs": {
8+
"version": "3.3" }
9+
}
10+
]
11+
],
12+
"plugins": [
13+
["@babel/plugin-transform-runtime", { "corejs": 3 }],
14+
"@babel/plugin-proposal-nullish-coalescing-operator",
15+
"@babel/plugin-proposal-optional-chaining"
16+
]
717
}

.browserslistrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
electron >= 7.1.7

README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,40 @@
22

33
### A Cross-Platform Desktop App for processing all rows of excel files
44

5-
Simply generates an array of items from the rows of an excel file and does the repetitive tedious operations step by step
5+
Simply generates an array of items from the rows of an excel file and does the repetitive tedious operations step by step
66
recursively till every item of the array is processed. For example downloading all the URL's in an excel file.
77

88
[![Dependency Status][david_img]][david_site]
99
[![Build Status][travis_img]][travis_site]
1010
[![Github Tag][github-tag-image]][github-tag-url]
1111
[![codecov][codecov-image]][codecov-url]
1212
[![Backers on Open Collective](https://opencollective.com/excel-parser-processor/backers/badge.svg)](#backers)
13-
[![Sponsors on Open Collective](https://opencollective.com/excel-parser-processor/sponsors/badge.svg)](#sponsors)
13+
[![Sponsors on Open Collective](https://opencollective.com/excel-parser-processor/sponsors/badge.svg)](#sponsors)
1414
[![Open Source Helpers](https://www.codetriage.com/btargac/excel-parser-processor/badges/users.svg)](https://www.codetriage.com/btargac/excel-parser-processor)
1515

1616
#### How to use
1717

1818
You can [download the latest release](https://github.com/btargac/excel-parser-processor/releases) for your operating system
1919
or build it yourself (see [Development](#development)).
2020

21-
Just select or drag & drop an excel file, then select the output folder for the downloaded images or files. All of the
21+
Just select or drag & drop an excel file, then select the output folder for the downloaded images or files. All of the
2222
items in the excel file will be downloaded into the selected folder and you will be notified about the state of ongoing
2323
progress.
2424

2525
#### Sample Excel file structure
2626

27-
| | A |
28-
| ------------- | :---------------------------------------------------------------- |
29-
| 1 | https://www.buraktargac.com/sample_image.gif |
30-
| 2 | https://www.buraktargac.com/sample_image.png |
31-
| 3 | https://www.buraktargac.com/sample_image.jpg |
32-
| . | ... |
33-
| . | ... |
34-
| n | Asset URL ( can be any type of file jpg, jpeg, png, txt, doc, etc)|
27+
| | A | B |
28+
| ------------- | :---------------------------------------------------------------- | :-------------------------|
29+
| 1 | https://www.buraktargac.com/sample_image.gif | optional-sample-file-name |
30+
| 2 | https://www.buraktargac.com/sample_image.png | optional-sample-file-name |
31+
| 3 | https://www.buraktargac.com/sample_image.jpg | |
32+
| . | ... | |
33+
| . | ... | |
34+
| n | Asset URL ( can be any type of file jpg, jpeg, png, txt, doc, etc)| |
3535

3636
<br/>
3737

38-
Currently there is no limit for `n`, I tested with 4000 items and unless your IP is banned from the publisher there
38+
Currently there is no limit for `n`, I tested with 4000 items and unless your IP is banned from the publisher there
3939
is no problem to download as much as you can.
4040

4141
#### Demo

package-lock.json

+4,869-5,827
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+29-28
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "excel-parser-processor",
33
"productName": "Excel Parser Processor",
4-
"version": "1.0.9",
4+
"version": "1.1.0",
55
"description": "Does the tedious processing over all items of a given excel file by converting the rows to an array and process all items of that array recursively",
66
"main": "./dist/index.bundle.js",
77
"scripts": {
88
"build-main": "cross-env NODE_ENV=production PROCESS_TYPE=main webpack --config webpack.prod.js",
99
"build-renderer": "cross-env NODE_ENV=production PROCESS_TYPE=renderer webpack --config webpack.prod.js",
1010
"build": "npm-run-all build-main build-renderer",
1111
"generate-icons": "electron-icon-maker --input=./build-assets/icon.png --output=./build/",
12-
"start-renderer-dev": "cross-env NODE_ENV=development PROCESS_TYPE=renderer webpack --watch --config webpack.dev.js",
12+
"start-renderer-dev": "cross-env NODE_ENV=development PROCESS_TYPE=renderer webpack --config webpack.dev.js",
1313
"start": "electron ./dist/index.bundle.js",
1414
"test": "jest",
1515
"test-watch": "jest --coverage --watch",
@@ -52,41 +52,42 @@
5252
},
5353
"homepage": "https://github.com/btargac/excel-parser-processor#readme",
5454
"devDependencies": {
55-
"@babel/core": "^7.2.2",
56-
"@babel/plugin-transform-runtime": "^7.2.0",
57-
"@babel/preset-env": "^7.2.3",
58-
"@babel/runtime": "^7.2.0",
59-
"babel-core": "^7.0.0-bridge.0",
60-
"babel-jest": "^23.6.0",
61-
"babel-loader": "^8.0.4",
62-
"clean-webpack-plugin": "^1.0.0",
63-
"copy-webpack-plugin": "^4.6.0",
64-
"cross-env": "^5.2.0",
65-
"css-loader": "^2.1.0",
66-
"electron": "^2.0.14",
67-
"electron-builder": "^20.38.4",
55+
"@babel/core": "^7.7.7",
56+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4",
57+
"@babel/plugin-proposal-optional-chaining": "^7.7.5",
58+
"@babel/plugin-transform-runtime": "^7.7.6",
59+
"@babel/preset-env": "^7.7.7",
60+
"babel-jest": "^24.9.0",
61+
"babel-loader": "^8.0.6",
62+
"clean-webpack-plugin": "^3.0.0",
63+
"copy-webpack-plugin": "^5.1.1",
64+
"cross-env": "^6.0.3",
65+
"css-loader": "^3.4.0",
66+
"electron": "^7.1.7",
67+
"electron-builder": "^21.2.0",
6868
"electron-icon-maker": "^0.0.4",
6969
"html-webpack-exclude-assets-plugin": "^0.0.7",
70-
"html-webpack-plugin": "^4.0.0-beta.5",
71-
"jest": "^24.0.0-alpha.9",
72-
"mini-css-extract-plugin": "^0.5.0",
73-
"node-sass": "^4.12.0",
70+
"html-webpack-plugin": "^3.2.0",
71+
"jest": "^24.9.0",
72+
"mini-css-extract-plugin": "^0.9.0",
73+
"node-sass": "^4.13.0",
7474
"npm-run-all": "^4.1.5",
75-
"sass-loader": "^7.1.0",
76-
"script-ext-html-webpack-plugin": "^2.1.3",
77-
"style-loader": "^0.23.1",
78-
"uglifyjs-webpack-plugin": "^2.1.1",
79-
"webpack": "^4.28.3",
80-
"webpack-cli": "^3.1.2",
81-
"webpack-merge": "^4.1.5"
75+
"sass-loader": "^8.0.0",
76+
"script-ext-html-webpack-plugin": "^2.1.4",
77+
"style-loader": "^1.1.2",
78+
"uglifyjs-webpack-plugin": "^2.2.0",
79+
"webpack": "^4.41.5",
80+
"webpack-cli": "^3.3.10",
81+
"webpack-merge": "^4.2.2"
8282
},
8383
"dependencies": {
84+
"@babel/runtime-corejs3": "^7.7.7",
8485
"@fortawesome/fontawesome": "^1.1.8",
8586
"@fortawesome/fontawesome-free-solid": "^5.0.13",
86-
"electron-fetch": "^1.3.0",
87+
"electron-fetch": "^1.4.0",
8788
"is-url": "^1.2.4",
8889
"jquery": "^3.4.0",
89-
"node-xlsx": "^0.12.1",
90+
"node-xlsx": "^0.15.0",
9091
"normalize.css": "^8.0.1",
9192
"opencollective": "^1.0.3"
9293
},

src/dialogs.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ export const showOpenDialog = (browserWindow, defaultPath, cb) => {
66
defaultPath,
77
title: "Choose an output folder",
88
properties: ['openDirectory', 'createDirectory']
9-
}, (filePaths) => {
10-
if(filePaths && filePaths.length) {
11-
9+
}).then(({ canceled, filePaths }) => {
10+
if( !canceled && filePaths?.length) {
1211
cb(defaultPath, filePaths[0], browserWindow);
13-
1412
}
15-
});
13+
}).catch(err => {
14+
console.log(err);
15+
})
1616
};

src/index.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8">
55
<meta name="viewport"
66
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7-
<meta http-equiv="X-UA-Compatible" content="ie=edge">
7+
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com;">
88
<title><%= htmlWebpackPlugin.options.title %></title>
99
</head>
1010
<body>
@@ -17,7 +17,7 @@ <h1 class="app__title">
1717
Excel processor
1818
</h1>
1919
<p class="app__description">
20-
Select the excel file, and the output folder, Excel Processor wil handle the rest.
20+
Select the excel file, and the output folder, Excel Processor will handle the rest.
2121
</p>
2222
</div>
2323
</div>

src/index.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ const createWindow = () => {
1111
win = new BrowserWindow({
1212
width: 800,
1313
height: 600,
14-
show: false
14+
show: false,
15+
webPreferences: {
16+
contextIsolation: true,
17+
enableRemoteModule: false,
18+
nodeIntegration: false,
19+
preload: path.join(__dirname, 'preload.js')
20+
}
1521
});
1622

1723
// and load the index.html of the app.
@@ -21,7 +27,7 @@ const createWindow = () => {
2127
slashes: true
2228
}));
2329

24-
win.on('ready-to-show', () => {
30+
win.once('ready-to-show', () => {
2531
win.show();
2632
});
2733

@@ -37,10 +43,11 @@ const createWindow = () => {
3743
};
3844

3945
app.on('ready', () => {
40-
createWindow();
4146
ipcMain.on('file-dropped', (event, filePath) => {
4247
showOpenDialog(win, filePath, processFile);
43-
})
48+
});
49+
50+
createWindow();
4451
});
4552

4653
// Quit when all windows are closed.

src/preload.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { ipcRenderer } = require('electron');
2+
3+
process.once('loaded', () => {
4+
// ipc communication is handled with postMessage and event listeners since ipcRenderer cannot be imported to renderer
5+
// process for security reasons
6+
window.addEventListener('message', event => {
7+
const message = event.data;
8+
const { data, type } = message;
9+
10+
ipcRenderer.send(type, data);
11+
});
12+
13+
ipcRenderer.on('main-message', (event, payload) => {
14+
const { data, type } = payload;
15+
16+
window.postMessage({
17+
type,
18+
data
19+
}, '*');
20+
});
21+
});

src/renderer.js

+32-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ipcRenderer } from 'electron';
21
import $ from 'jquery';
32

43
// we also need to process some styles with webpack
@@ -46,7 +45,7 @@ const outEvents = ['dragleave', 'dragend', 'mouseout', 'drop'];
4645
inEvents.forEach(event => drop.addEventListener(event, handleIn));
4746
outEvents.forEach(event => drop.addEventListener(event, handleOut));
4847

49-
const handleFileSelect = (event) => {
48+
const handleFileSelect = event => {
5049
const files = event.target.files;
5150

5251
for (let file of files) {
@@ -56,7 +55,10 @@ const handleFileSelect = (event) => {
5655
continue;
5756
}
5857

59-
ipcRenderer.send('file-dropped', file.path);
58+
window.postMessage({
59+
type: 'file-dropped',
60+
data: file.path
61+
}, '*');
6062
}
6163

6264
event.preventDefault();
@@ -125,13 +127,13 @@ const processStartHandler = () => {
125127

126128
};
127129

128-
const progressHandler = (event, percentage) => update(percentage);
130+
const progressHandler = percentage => update(percentage);
129131

130-
const processCompletedHandler = (event, { processedItemsCount, incompatibleItems, erroneousItems, logFilePath }) => {
132+
const processCompletedHandler = ({ processedItemsCount, incompatibleItems, erroneousItems, logFilePath }) => {
131133

132134
$(notificationArea).find('.text').text(
133135
[
134-
`${processedItemsCount} item(s) processed,`,
136+
`${processedItemsCount} item(s) successfully processed,`,
135137
`${incompatibleItems.length} item(s) skipped,`,
136138
`${erroneousItems.length} item(s) erroneous,`,
137139
`Log file ${logFilePath} is written on disk.`
@@ -144,7 +146,7 @@ const processCompletedHandler = (event, { processedItemsCount, incompatibleItems
144146

145147
};
146148

147-
const processErrorHandler = (event, data) => {
149+
const processErrorHandler = data => {
148150

149151
const oldText = $(errorArea).find('.text').text();
150152

@@ -161,9 +163,9 @@ const processErrorHandler = (event, data) => {
161163

162164
};
163165

164-
const fileErrorHandler = (event, data) => {
166+
const fileErrorHandler = data => {
165167

166-
$(errorArea).find('.text').text(`${data.message}`);
168+
$(errorArea).find('.text').text(`${data}`);
167169

168170
$(errorArea).show().animate({
169171
bottom: '10%'
@@ -214,8 +216,24 @@ const disableDrop = event => {
214216
document.addEventListener(event, disableDrop);
215217
});
216218

217-
ipcRenderer.on('process-started', processStartHandler);
218-
ipcRenderer.on('process-completed', processCompletedHandler);
219-
ipcRenderer.on('progress', progressHandler);
220-
ipcRenderer.on('process-error', processErrorHandler);
221-
ipcRenderer.on('file-error', fileErrorHandler);
219+
window.addEventListener('message', event => {
220+
const message = event.data;
221+
const { data, type } = message;
222+
223+
switch (type) {
224+
case 'process-started':
225+
processStartHandler();
226+
break;
227+
case 'process-completed':
228+
processCompletedHandler(data);
229+
break;
230+
case 'progress':
231+
progressHandler(data);
232+
break;
233+
case 'process-error':
234+
processErrorHandler(data);
235+
break;
236+
case 'file-error':
237+
fileErrorHandler(data);
238+
}
239+
});

0 commit comments

Comments
 (0)