LogosApi.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. Copyright (C) 2019 Cloudbase Solutions SRL
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. import express from "express";
  15. import path from "path";
  16. import fs from "fs";
  17. const getModJsonProviders = (jsonPath: string) => {
  18. const jsonContent: any = fs.readFileSync(jsonPath);
  19. const json = JSON.parse(jsonContent);
  20. if (!json.providers) {
  21. throw new Error();
  22. }
  23. return json.providers;
  24. };
  25. const getOptimalLogoHeightKey = (
  26. availableHeightKeys: string[],
  27. requestedHeight: number,
  28. style?: string | null
  29. ): string => {
  30. let heightKeys = availableHeightKeys;
  31. if (style) {
  32. const styledKeys = heightKeys.filter((k) =>
  33. style ? k.indexOf(style) > -1 : false
  34. );
  35. if (styledKeys.length) {
  36. heightKeys = styledKeys;
  37. }
  38. }
  39. const optimal = heightKeys.reduce((prev, curr) => {
  40. let prevHeight: any = /d+/.exec(prev);
  41. let currHeight: any = /d+/.exec(curr);
  42. prevHeight = prevHeight ? Number(prevHeight[0]) : 0;
  43. currHeight = currHeight ? Number(currHeight[0]) : 0;
  44. return Math.abs(currHeight - requestedHeight) <
  45. Math.abs(prevHeight - requestedHeight)
  46. ? curr
  47. : prev;
  48. });
  49. return optimal;
  50. };
  51. export default (router: express.Router) => {
  52. router.get("/logos/:provider/:size/:style?", (req, res) => {
  53. const SIZES = [32, 42, 64, 128];
  54. const STYLES = ["white", "disabled"];
  55. const { provider, style } = req.params;
  56. const size = Number(req.params.size);
  57. if (SIZES.indexOf(size) === -1) {
  58. res
  59. .status(400)
  60. .json({ error: { message: `Valid sizes are: ${SIZES.join(", ")}` } });
  61. return;
  62. }
  63. if (style && STYLES.indexOf(style) === -1) {
  64. res
  65. .status(400)
  66. .json({ error: { message: `Valid styles are: ${STYLES.join(", ")}` } });
  67. return;
  68. }
  69. const logoBase = path.join(__dirname, "/resources/providerLogos");
  70. let logoPath = `${logoBase}/${provider}-${size}`;
  71. logoPath = style ? `${logoPath}-${style}.svg` : `${logoPath}.svg`;
  72. const modJsonPath: string | null | undefined = process.env.MOD_JSON;
  73. if (!modJsonPath) {
  74. res.sendFile(logoPath);
  75. return;
  76. }
  77. try {
  78. const providersJson = getModJsonProviders(modJsonPath);
  79. const providerJson = providersJson[provider];
  80. if (!providerJson) {
  81. res.sendFile(logoPath);
  82. return;
  83. }
  84. const providerLogosJson = providerJson.logos;
  85. if (!providerLogosJson) {
  86. console.log(
  87. `No logos specified in MOD_JSON file for '${provider}' provider`
  88. );
  89. res.sendFile(logoPath);
  90. return;
  91. }
  92. const providerLogosKeys = Object.keys(providerLogosJson);
  93. if (!providerLogosKeys.length) {
  94. console.log(
  95. `No logo heights specified in MOD_JSON file for '${provider}' provider`
  96. );
  97. res.sendFile(logoPath);
  98. return;
  99. }
  100. const optimalHeightKey = getOptimalLogoHeightKey(
  101. providerLogosKeys,
  102. size,
  103. style
  104. );
  105. const modLogoPath = providerLogosJson[optimalHeightKey].path;
  106. if (!modLogoPath) {
  107. console.log(
  108. `No logo path specified in MOD_JSON file for '${provider}' provider`
  109. );
  110. res.sendFile(logoPath);
  111. return;
  112. }
  113. res.sendFile(modLogoPath);
  114. } catch (err) {
  115. console.error(err);
  116. res.status(400).json({ error: { message: "Invalid Mod JSON file" } });
  117. }
  118. });
  119. };