Skip to content

Commit

Permalink
Genereate iconList.json (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
farmio authored Dec 10, 2023
1 parent 97ffab2 commit ceba17c
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
165 changes: 165 additions & 0 deletions build-scripts/gulp/gen-icons-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import fs from "fs";
import gulp from "gulp";
import hash from "object-hash";
import path from "path";
import paths from "../paths.cjs";

const ICON_PACKAGE_PATH = path.resolve("node_modules/@mdi/svg/");
const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json");
const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json");
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
const OUTPUT_DIR = path.resolve(paths.upstream_build_dir, "mdi");
const REMOVED_ICONS_PATH = new URL("../removedIcons.json", import.meta.url);

const encoding = "utf8";

const getMeta = () => {
const file = fs.readFileSync(META_PATH, { encoding });
const meta = JSON.parse(file);
return meta.map((icon) => {
const svg = fs.readFileSync(`${ICON_PATH}/${icon.name}.svg`, {
encoding,
});
return {
path: svg.match(/ d="([^"]+)"/)[1],
name: icon.name,
tags: icon.tags,
aliases: icon.aliases,
};
});
};

const addRemovedMeta = (meta) => {
const file = fs.readFileSync(REMOVED_ICONS_PATH, { encoding });
const removed = JSON.parse(file);
const removedMeta = removed.map((removeIcon) => ({
path: removeIcon.path,
name: removeIcon.name,
tags: [],
aliases: [],
}));
const combinedMeta = [...meta, ...removedMeta];
return combinedMeta.sort((a, b) => a.name.localeCompare(b.name));
};

const homeAutomationTag = "Home Automation";

const orderMeta = (meta) => {
const homeAutomationMeta = meta.filter((icon) =>
icon.tags.includes(homeAutomationTag)
);
const otherMeta = meta.filter(
(icon) => !icon.tags.includes(homeAutomationTag)
);
return [...homeAutomationMeta, ...otherMeta];
};

const splitBySize = (meta) => {
const chunks = [];
const CHUNK_SIZE = 50000;

let curSize = 0;
let startKey;
let icons = [];

Object.values(meta).forEach((icon) => {
if (startKey === undefined) {
startKey = icon.name;
}
curSize += icon.path.length;
icons.push(icon);
if (curSize > CHUNK_SIZE) {
chunks.push({
startKey,
endKey: icon.name,
icons,
});
curSize = 0;
startKey = undefined;
icons = [];
}
});

chunks.push({
startKey,
icons,
});

return chunks;
};

const findDifferentiator = (curString, prevString) => {
for (let i = 0; i < curString.length; i++) {
if (curString[i] !== prevString[i]) {
return curString.substring(0, i + 1);
}
}
throw new Error("Cannot find differentiator", curString, prevString);
};

gulp.task("gen-icons-json", (done) => {
const meta = getMeta();

const metaAndRemoved = addRemovedMeta(meta);
const split = splitBySize(metaAndRemoved);

if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}
const parts = [];

let lastEnd;
split.forEach((chunk) => {
let startKey;
if (lastEnd === undefined) {
chunk.startKey = undefined;
startKey = undefined;
} else {
startKey = findDifferentiator(chunk.startKey, lastEnd);
}
lastEnd = chunk.endKey;

const output = {};
chunk.icons.forEach((icon) => {
output[icon.name] = icon.path;
});
const filename = hash(output);
parts.push({ start: startKey, file: filename });
fs.writeFileSync(
path.resolve(OUTPUT_DIR, `${filename}.json`),
JSON.stringify(output)
);
});

const file = fs.readFileSync(PACKAGE_PATH, { encoding });
const packageMeta = JSON.parse(file);

fs.writeFileSync(
path.resolve(OUTPUT_DIR, "iconMetadata.json"),
JSON.stringify({ version: packageMeta.version, parts })
);

fs.writeFileSync(
path.resolve(OUTPUT_DIR, "iconList.json"),
JSON.stringify(
orderMeta(meta).map((icon) => ({
name: icon.name,
keywords: [
...icon.tags.map((t) => t.toLowerCase().replace(/\s\/\s/g, " ")),
...icon.aliases,
],
}))
)
);

done();
});

gulp.task("gen-dummy-icons-json", (done) => {
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}

fs.writeFileSync(path.resolve(OUTPUT_DIR, "iconList.json"), "[]");
done();
});
3 changes: 3 additions & 0 deletions build-scripts/gulp/knx.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "./clean.js";
import "./webpack.js";
import "./compress.js";
import "./entry-html.js";
import "./gen-icons-json.js";

gulp.task(
"develop-knx",
Expand All @@ -14,6 +15,7 @@ gulp.task(
process.env.NODE_ENV = "development";
},
"clean-knx",
"gen-icons-json",
"gen-index-knx-dev",
"webpack-watch-knx"
)
Expand All @@ -27,6 +29,7 @@ gulp.task(
},
"clean-knx",
"ensure-knx-build-dir",
"gen-icons-json",
"webpack-prod-knx",
"gen-index-knx-prod",
...// Don't compress running tests
Expand Down
1 change: 1 addition & 0 deletions build-scripts/paths.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
src_dir: path.resolve(__dirname, "../src"),

build_dir: path.resolve(__dirname, "../knx_frontend"),
upstream_build_dir: path.resolve(__dirname, "../homeassistant-frontend/build"),
app_output_root: path.resolve(__dirname, "../knx_frontend"),
app_output_static: path.resolve(__dirname, "../knx_frontend/static"),
app_output_latest: path.resolve(__dirname, "../knx_frontend/frontend_latest"),
Expand Down

0 comments on commit ceba17c

Please sign in to comment.