Last active
March 27, 2018 09:50
-
-
Save lucaronca/1d3964362d82a001c27af1e4a62bea50 to your computer and use it in GitHub Desktop.
Script to get the stickers configuration reading from a given folder containing them
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
/** | |
* | |
* Install global modules: yarn global add typescript ts-node | |
* Install image utility libraries: npm i svgson calipers calipers-png | |
* Launch with ts-node ex: | |
* curl -sL <script_shortlink> -o ./c.ts && ts-node <path_to_sticker_folder> && rm ./c.ts | |
* | |
**/ | |
const { promisify } = require('util') | |
const { resolve, extname, basename } = require('path') | |
const { | |
readdir: nodeReaddir, | |
readFile: nodeReadFile, | |
writeFile: nodeWriteFile, | |
stat: nodeStat, | |
lstatSync, | |
} = require('fs') | |
const svgson = require('svgson') | |
const calipers = require('calipers')('png'); | |
const readdir = promisify(nodeReaddir) | |
const readFile = promisify(nodeReadFile) | |
const writeFile = promisify(nodeWriteFile) | |
const stat = promisify(nodeStat) | |
const stickerFolder = process.argv[2] | |
const destinationFile = resolve('./stickers.js') | |
const folderNames = { | |
base: 'SVG', | |
thumb: '1x', | |
} | |
interface Images { | |
mediaThumb: { | |
uri: String | |
width: 244 | |
height: 165 | |
} | |
mediaBase: { | |
uri: String | |
width: Number | |
height: Number | |
} | |
} | |
interface Sticker { | |
identifier: String | |
defaultName: String | |
images: Images | |
} | |
interface Category { | |
identifier: String | |
defaultName: String | |
stickers: Array<Sticker> | |
} | |
interface StickerConfig { | |
categories: Array<Category> | |
replaceCategories: true | |
} | |
async function listSVGsForCategory(category: string): Promise<Array<string>> { | |
try { | |
const SVGFolder = resolve(stickerFolder, category, folderNames.base) | |
return readdir(SVGFolder) | |
} catch (e) { | |
console.log(`can't read folder for ${category} category`); | |
throw e | |
} | |
} | |
function labelify(string: string): string { | |
const capitalized: string = string.charAt(0).toUpperCase() + string.slice(1) | |
return capitalized.replace(new RegExp('-', 'g'), ' ') | |
} | |
async function listCategories(folder: string): Promise<Array<string>> { | |
try { | |
const items: Array<string> = await readdir(folder) | |
return items.filter((item): boolean => lstatSync(resolve(folder, item)).isDirectory()) | |
} catch (e) { | |
throw e | |
} | |
} | |
function getFileName(file: string): string { | |
return basename(file, extname(file)) | |
} | |
function isNotCategoryBadge(stickerName: string): boolean { | |
return !getFileName(stickerName).endsWith('-0-cover') | |
} | |
async function getSticker(category: string, svgName: string): Promise<Sticker> { | |
try { | |
const filePath: string = resolve(stickerFolder, category, folderNames.base, svgName) | |
const stickerName: string = getFileName(filePath) | |
const svgContent: string = await readFile(filePath, 'utf8') | |
let viewBox: Array<number> | |
try { | |
viewBox = await new Promise<Array<number>>((res) => { | |
svgson(svgContent, {}, result => { | |
res(result.attrs.viewBox.split(' ').map((dimension): number => parseInt(dimension))) | |
}) | |
}) | |
} catch(e) { | |
// can't retrieve viewBox, maybe sticker file is just a png (this could happen with PE default stickers) | |
// read dimensions and put it in a mocked viewBox | |
const result = await calipers.measure(filePath) | |
viewBox = [0, 0, result.pages[0].width, result.pages[0].height] | |
} | |
return <Sticker> { | |
identifier: stickerName, | |
defaultName: labelify(stickerName), | |
images: { | |
mediaThumb: { | |
uri: `stickers/${category}/${folderNames.thumb}/${stickerName}.png`, | |
width: 244, | |
height: 165, | |
}, | |
mediaBase: { | |
uri: `stickers/${category}/${folderNames.base}/${stickerName}${extname(filePath)}`, | |
width: viewBox[2], | |
height: viewBox[3], | |
} | |
} | |
} | |
} catch (e) { | |
console.log(`can't read svg: ${svgName} in ${category} category`) | |
throw e | |
} | |
} | |
(async (): Promise<void> => { | |
try { | |
const categoriesList: Array<string> = await listCategories(stickerFolder) | |
const categories: Array<Category> = await Promise.all( | |
categoriesList.map(async (category): Promise<Category> => { | |
const SVGs: Array<string> = await listSVGsForCategory(category) | |
const stickers: Array<Sticker> = await Promise.all( | |
SVGs | |
.filter(isNotCategoryBadge) | |
.map(async (svgName): Promise<Sticker> => getSticker(category, svgName)) | |
) | |
return <Category> { | |
identifier: category, | |
defaultName: labelify(category), | |
stickers, | |
} | |
}) | |
) | |
const configuration: StickerConfig = { | |
categories, | |
replaceCategories: true, | |
} | |
const stickerFileContent: string = `export default ${JSON.stringify(configuration, null, 2)}` | |
await writeFile(destinationFile, stickerFileContent) | |
console.log('Sticker configuration written in:', destinationFile) | |
} catch (e) { | |
throw e | |
} | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment