Guest User

Untitled

a guest
Jan 21st, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.07 KB | None | 0 0
  1. /**
  2. *
  3. * Install global modules: yarn global add typescript ts-node
  4. * Install image utility libraries: npm i svgson calipers calipers-png
  5. * Launch with ts-node ex:
  6. * curl -sL <script_shortlink> -o ./c.ts && ts-node <path_to_sticker_folder> && rm ./c.ts
  7. *
  8. **/
  9.  
  10. const { promisify } = require('util')
  11. const { resolve, extname, basename } = require('path')
  12. const {
  13. readdir: nodeReaddir,
  14. readFile: nodeReadFile,
  15. writeFile: nodeWriteFile,
  16. stat: nodeStat,
  17. lstatSync,
  18. } = require('fs')
  19.  
  20. const svgson = require('svgson')
  21. const calipers = require('calipers')('png');
  22.  
  23. const readdir = promisify(nodeReaddir)
  24. const readFile = promisify(nodeReadFile)
  25. const writeFile = promisify(nodeWriteFile)
  26. const stat = promisify(nodeStat)
  27.  
  28. const stickerFolder = process.argv[2]
  29. const destinationFile = resolve('./stickers.js')
  30.  
  31. const folderNames = {
  32. base: 'SVG',
  33. thumb: '1x',
  34. }
  35.  
  36. interface Images {
  37. mediaThumb: {
  38. uri: String
  39. width: 244
  40. height: 165
  41. }
  42. mediaBase: {
  43. uri: String
  44. width: Number
  45. height: Number
  46. }
  47. }
  48.  
  49. interface Sticker {
  50. name: String
  51. label: String
  52. images: Images
  53. }
  54.  
  55. interface Category {
  56. name: String
  57. label: String
  58. stickers: Array<Sticker>
  59. }
  60.  
  61. interface StickerConfig {
  62. categories: Array<Category>
  63. replaceCategories: true
  64. }
  65.  
  66. async function listSVGsForCategory(category: string): Promise<Array<string>> {
  67. try {
  68. const SVGFolder = resolve(stickerFolder, category, folderNames.base)
  69.  
  70. return readdir(SVGFolder)
  71. } catch (e) {
  72. console.log(`can't read folder for ${category} category`);
  73. throw e
  74. }
  75. }
  76.  
  77. function labelify(string: string): string {
  78. const capitalized: string = string.charAt(0).toUpperCase() + string.slice(1)
  79.  
  80. return capitalized.replace(new RegExp('-', 'g'), ' ')
  81. }
  82.  
  83. async function listCategories(folder: string): Promise<Array<string>> {
  84. try {
  85. const items: Array<string> = await readdir(folder)
  86.  
  87. return items.filter((item): boolean => lstatSync(resolve(folder, item)).isDirectory())
  88. } catch (e) {
  89. throw e
  90. }
  91. }
  92.  
  93. function getFileName(file: string): string {
  94. return basename(file, extname(file))
  95. }
  96.  
  97. function isNotCategoryBadge(stickerName: string): boolean {
  98. return !getFileName(stickerName).endsWith('-0-cover')
  99. }
  100.  
  101. async function getSticker(category: string, svgName: string): Promise<Sticker> {
  102. try {
  103. const filePath: string = resolve(stickerFolder, category, folderNames.base, svgName)
  104. const stickerName: string = getFileName(filePath)
  105.  
  106. const svgContent: string = await readFile(filePath, 'utf8')
  107.  
  108. let viewBox: Array<number>
  109. try {
  110. viewBox = await new Promise<Array<number>>((res) => {
  111. svgson(svgContent, {}, result => {
  112. res(result.attrs.viewBox.split(' ').map((dimension): number => parseInt(dimension)))
  113. })
  114. })
  115. } catch(e) {
  116. // can't retrieve viewBox, maybe sticker file is just a png (this could happen with PE default stickers)
  117. // read dimensions and put it in a mocked viewBox
  118. const result = await calipers.measure(filePath)
  119. viewBox = [0, 0, result.pages[0].width, result.pages[0].height]
  120. }
  121.  
  122. return <Sticker> {
  123. name: stickerName,
  124. label: labelify(stickerName),
  125. images: {
  126. mediaThumb: {
  127. uri: `stickers/${category}/${folderNames.thumb}/${stickerName}.png`,
  128. width: 244,
  129. height: 165,
  130. },
  131. mediaBase: {
  132. uri: `stickers/${category}/${folderNames.base}/${stickerName}${extname(filePath)}`,
  133. width: viewBox[2],
  134. height: viewBox[3],
  135. }
  136. }
  137. }
  138. } catch (e) {
  139. console.log(`can't read svg: ${svgName} in ${category} category`)
  140. throw e
  141. }
  142. }
  143.  
  144. (async (): Promise<void> => {
  145. try {
  146. const categoriesList: Array<string> = await listCategories(stickerFolder)
  147.  
  148. const categories: Array<Category> = await Promise.all(
  149. categoriesList.map(async (category): Promise<Category> => {
  150. const SVGs: Array<string> = await listSVGsForCategory(category)
  151. const stickers: Array<Sticker> = await Promise.all(
  152. SVGs
  153. .filter(isNotCategoryBadge)
  154. .map(async (svgName): Promise<Sticker> => getSticker(category, svgName))
  155. )
  156.  
  157. return <Category> {
  158. name: category,
  159. label: labelify(category),
  160. stickers,
  161. }
  162. })
  163. )
  164.  
  165. const configuration: StickerConfig = {
  166. categories,
  167. replaceCategories: true,
  168. }
  169.  
  170. const stickerFileContent: string = `export default ${JSON.stringify(configuration, null, 2)}`
  171.  
  172. await writeFile(destinationFile, stickerFileContent)
  173. console.log('Sticker configuration written in:', destinationFile)
  174. } catch (e) {
  175. throw e
  176. }
  177. })()
Add Comment
Please, Sign In to add comment