Last active
July 22, 2018 20:25
-
-
Save nenadom/b284c0688dd8d72b9dd0ad7267d23a8b to your computer and use it in GitHub Desktop.
Renames a collection of %COUNTRY_NAME%.ext files to a matching set of %ISO_CODE%.ext files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Renames a collection of %COUNTRY_NAME%.ext files to a matching set of | |
* %ISO_CODE%.ext files. | |
* | |
* Uses the https://github.com/datasets/country-codes dataset for names | |
* and ISO codes. Since it's CSV, I also used | |
* https://github.com/Keyang/node-csvtojson to convert to JSON. | |
* | |
* V 0.0.2. | |
*/ | |
const fs = require('fs') | |
const Converter = require('csvtojson').Converter | |
const COUNTRY_DATASET_DIR = './country-codes/data/country-codes.csv' | |
var converter = new Converter({}) | |
var normalizedCountries = {} | |
// flatten out JSON data to a name: iso dictionary on parse end | |
converter.on('end_parsed', function(json) { | |
normalizeJSONData(json, init) | |
}) | |
// read CSV data | |
fs.createReadStream(COUNTRY_DATASET_DIR).pipe(converter) | |
// provide dir to work on as first arg | |
var targetDir = process.argv[2] | |
// provide a second dir as arg, or default to ./processed | |
var newDir = process.argv[3] || './processed/' | |
if (!targetDir) { | |
console.log('give me a valid directory to work on!') | |
return | |
} | |
// validate directories and add slashes at end | |
if (targetDir[targetDir.length - 1] !== '/') targetDir = targetDir + '/' | |
if (newDir[targetDir.length - 1] !== '/') newDir = newDir + '/' | |
/** | |
* ================ | |
* Main init | |
* =============== | |
*/ | |
function init() { | |
// see if newDir exists and create it if not | |
fs.stat(newDir, function(err, stats) { | |
if (stats && stats.isDirectory()) { | |
batchRename() // Do rename now. | |
return | |
} | |
// otherwise, init rename after creating dir thru callback | |
fs.mkdir(newDir, function(err) { | |
if (err) throw err | |
batchRename() // Or now. | |
}) | |
}) | |
} | |
/** | |
* NOTE: use read/write streams to make copies of existing files, | |
* fs.rename moves the actual file | |
*/ | |
function batchRename() { | |
console.log('renaming...') | |
fs.readdir(targetDir, function(err, flagFiles) { | |
if (err) throw err | |
flagFiles.map(function(flagName) { | |
var newName | |
// ignore pesky .DS_Store files | |
if (flagName == '.DS_Store') return; | |
// rename file | |
newName = renameFile(flagName) | |
// streams, baby | |
fs.createReadStream(targetDir + flagName) | |
.pipe(fs.createWriteStream(newDir + newName)) | |
.on('error', console.error) | |
}) | |
}) | |
console.log('renaming complete!') | |
} | |
/** | |
* Splits filename into name and extension; if name in list of | |
* normalized countries (a dictionary of names and ISO3166-1 codes), | |
* return that code, with extension. Otherwise, return filename. | |
* | |
* @param {String} filename i.e. '' | |
* @return {[type]} [description] | |
*/ | |
function renameFile(filename) { | |
var strSplit = filename.split('.'); | |
var name = strSplit[0] | |
var ext = '.' + strSplit[1] | |
if (normalizedCountries[name]) { | |
return normalizedCountries[name] + ext | |
} | |
return filename | |
} | |
/** | |
* Extracts data from country info relevant to renaming files. | |
* Init renaming thru callback | |
* | |
* @param {Array} json converted CSV data | |
* @param {Function} callback callback init() function | |
* @return {undefined} | |
*/ | |
function normalizeJSONData(json, callback) { | |
json.map(function(country) { | |
var name = slugifyName(country['name']) | |
var iso = country['ISO3166-1-Alpha-2'].toLowerCase() | |
normalizedCountries[name] = iso; | |
}) | |
// init | |
callback() | |
} | |
/** | |
* Slugify name. | |
* | |
* @param {String} name Full name with spaces, dots, ampersands, weird letters | |
* @return {String} slug | |
*/ | |
function slugifyName(name) { | |
// yeah this should be done using regexp | |
return name.split('').map(function(char) { | |
if (char == ' ') return '_' | |
if (char == '.') return '' | |
if (char == '&') return 'and' | |
if (['Å', 'ã', 'â', 'à', 'á'].indexOf(char) >= 0) return 'a' | |
if (['Ê', 'è', 'ȇ', 'é'].indexOf(char) >= 0) return 'e' | |
// at least a little bit of regexp | |
return char.replace(/[A-Z]/g, function(match) { | |
return match.toLowerCase() | |
}) | |
}).join('') | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment