diff --git a/.vscode/settings.json b/.vscode/settings.json index 68a4ef6..92ed957 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,6 +17,7 @@ "noreferrer", "relocator", "semibold", + "stringifier", "tailwindcss", "UGRC", "vercel", diff --git a/package-lock.json b/package-lock.json index 89c1b79..2b10155 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "assert": "^2.0.0", "crypto-browserify": "^3.12.0", "csv-parse": "^4.16.3", + "csv-stringify": "^5.6.5", "electron-squirrel-startup": "^1.0.0", "electron-store": "^8.0.1", "file-loader": "^6.2.0", @@ -39,18 +40,18 @@ "@electron-forge/maker-squirrel": "^6.0.0-beta.60", "@electron-forge/maker-zip": "^6.0.0-beta.60", "@electron-forge/plugin-webpack": "^6.0.0-beta.60", - "@tailwindcss/forms": "^0.3.3", + "@tailwindcss/forms": "^0.3.4", "@vercel/webpack-asset-relocator-loader": "^1.7.0", "autoprefixer": "^10.3.6", "babel-loader": "^8.2.2", "babel-preset-react-app": "^10.0.0", "css-loader": "^6.3.0", - "electron": "^15.0.0", + "electron": "^15.1.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.26.0", + "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-simple-import-sort": "^7.0.0", "node-loader": "^2.0.0", @@ -2772,9 +2773,9 @@ } }, "node_modules/@tailwindcss/forms": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.3.tgz", - "integrity": "sha512-U8Fi/gq4mSuaLyLtFISwuDYzPB73YzgozjxOIHsK6NXgg/IWD1FLaHbFlWmurAMyy98O+ao74ksdQefsquBV1Q==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.4.tgz", + "integrity": "sha512-vlAoBifNJUkagB+PAdW4aHMe4pKmSLroH398UPgIogBFc91D2VlHUxe4pjxQhiJl0Nfw53sHSJSQBSTQBZP3vA==", "dev": true, "dependencies": { "mini-svg-data-uri": "^1.2.3" @@ -5574,6 +5575,11 @@ "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==" }, + "node_modules/csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, "node_modules/cuint": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", @@ -6060,9 +6066,9 @@ "dev": true }, "node_modules/electron": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-15.0.0.tgz", - "integrity": "sha512-LlBjN5nCJoC7EDrgfDQwEGSGSAo/o08nSP5uJxN2m+ZtNA69SxpnWv4yPgo1K08X/iQPoGhoZu6C8LYYlk1Dtg==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-15.1.0.tgz", + "integrity": "sha512-QZJKZdrOG2G9lyOrDpCHh+arMrj7ZVVBulrukhNXwCeCEHgNLTVULEQzMOB9AVXUbIs+FthcddlMgcgpaErohw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -7212,9 +7218,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.0.tgz", - "integrity": "sha512-dceliS5itjk4EZdQYtLMz6GulcsasguIs+VTXuiC7Q5IPIdGTkyfXVdmsQOqEhlD9MciofH4cMcT1bw1WWNxCQ==", + "version": "7.26.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz", + "integrity": "sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ==", "dev": true, "dependencies": { "array-includes": "^3.1.3", @@ -17523,9 +17529,9 @@ } }, "@tailwindcss/forms": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.3.tgz", - "integrity": "sha512-U8Fi/gq4mSuaLyLtFISwuDYzPB73YzgozjxOIHsK6NXgg/IWD1FLaHbFlWmurAMyy98O+ao74ksdQefsquBV1Q==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.4.tgz", + "integrity": "sha512-vlAoBifNJUkagB+PAdW4aHMe4pKmSLroH398UPgIogBFc91D2VlHUxe4pjxQhiJl0Nfw53sHSJSQBSTQBZP3vA==", "dev": true, "requires": { "mini-svg-data-uri": "^1.2.3" @@ -19794,6 +19800,11 @@ "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==" }, + "csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, "cuint": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", @@ -20178,9 +20189,9 @@ "dev": true }, "electron": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-15.0.0.tgz", - "integrity": "sha512-LlBjN5nCJoC7EDrgfDQwEGSGSAo/o08nSP5uJxN2m+ZtNA69SxpnWv4yPgo1K08X/iQPoGhoZu6C8LYYlk1Dtg==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-15.1.0.tgz", + "integrity": "sha512-QZJKZdrOG2G9lyOrDpCHh+arMrj7ZVVBulrukhNXwCeCEHgNLTVULEQzMOB9AVXUbIs+FthcddlMgcgpaErohw==", "dev": true, "requires": { "@electron/get": "^1.13.0", @@ -21141,9 +21152,9 @@ } }, "eslint-plugin-react": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.0.tgz", - "integrity": "sha512-dceliS5itjk4EZdQYtLMz6GulcsasguIs+VTXuiC7Q5IPIdGTkyfXVdmsQOqEhlD9MciofH4cMcT1bw1WWNxCQ==", + "version": "7.26.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz", + "integrity": "sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ==", "dev": true, "requires": { "array-includes": "^3.1.3", diff --git a/package.json b/package.json index f9e2206..e7a9a10 100644 --- a/package.json +++ b/package.json @@ -77,18 +77,18 @@ "@electron-forge/maker-squirrel": "^6.0.0-beta.60", "@electron-forge/maker-zip": "^6.0.0-beta.60", "@electron-forge/plugin-webpack": "^6.0.0-beta.60", - "@tailwindcss/forms": "^0.3.3", + "@tailwindcss/forms": "^0.3.4", "@vercel/webpack-asset-relocator-loader": "^1.7.0", "autoprefixer": "^10.3.6", "babel-loader": "^8.2.2", "babel-preset-react-app": "^10.0.0", "css-loader": "^6.3.0", - "electron": "^15.0.0", + "electron": "^15.1.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.26.0", + "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-simple-import-sort": "^7.0.0", "node-loader": "^2.0.0", @@ -103,6 +103,7 @@ "assert": "^2.0.0", "crypto-browserify": "^3.12.0", "csv-parse": "^4.16.3", + "csv-stringify": "^5.6.5", "electron-squirrel-startup": "^1.0.0", "electron-store": "^8.0.1", "file-loader": "^6.2.0", diff --git a/src/services/csv.js b/src/services/csv.js index 4ae9a25..680872e 100644 --- a/src/services/csv.js +++ b/src/services/csv.js @@ -1,8 +1,10 @@ +const { app, ipcMain } = require('electron'); const fs = require('fs'); +const path = require('path'); const parse = require('csv-parse'); const got = require('got'); const { readPackageUpAsync } = require('read-pkg-up'); -const { ipcMain } = require('electron'); +const stringify = require('csv-stringify'); export const getFields = async (filePath) => { const parser = fs.createReadStream(filePath).pipe(parse({ columns: true, skipEmptyLines: true })); @@ -69,6 +71,10 @@ export const cancelGeocode = () => { export const geocode = async (event, { filePath, fields, apiKey }) => { cancelled = false; const parser = fs.createReadStream(filePath).pipe(parse({ columns: true, skipEmptyLines: true })); + const columns = await getFields(filePath); + const writer = fs.createWriteStream(path.join(app.getPath('userData'), 'output.csv')); + const stringifier = stringify({ columns: [...columns, 'x', 'y', 'score', 'match_address'], header: true }); + stringifier.pipe(writer); const packageInfo = await readPackageUpAsync(); let totalRows = await getRecordCount(filePath); @@ -80,6 +86,7 @@ export const geocode = async (event, { filePath, fields, apiKey }) => { if (cancelled) { return; } + const newRecord = { ...record, x: null, y: null, score: 0, match_address: null }; const street = cleanseStreet(record[fields.street]); const zone = cleanseZone(record[fields.zone]); @@ -112,10 +119,21 @@ export const geocode = async (event, { filePath, fields, apiKey }) => { if (response.status === 200) { const result = response.result; - const { score } = result; + const { + score, + matchAddress, + location: { x, y }, + } = result; + totalScore += score; + newRecord.score = score; + newRecord.x = x; + newRecord.y = y; + newRecord.match_address = matchAddress; } + stringifier.write(newRecord); + rowsProcessed++; event.reply('onGeocodingUpdate', { @@ -127,6 +145,8 @@ export const geocode = async (event, { filePath, fields, apiKey }) => { await coolYourJets(); } + + stringifier.end(); }; ipcMain.handle('getFieldsFromFile', (_, content) => {