Home Reference Source

cables_dev/cables_electron/src/export/export_html_electron.js

  1. import fs from "fs";
  2. import { SharedExportService } from "cables-shared-api";
  3. import path from "path";
  4. import archiver from "archiver";
  5. import { fileURLToPath } from "url";
  6. import settings from "../electron/electron_settings.js";
  7. import electronApp from "../electron/main.js";
  8. import helper from "../utils/helper_util.js";
  9. export default class HtmlExportElectron extends SharedExportService
  10. {
  11. constructor(provider, _exportOptions, user)
  12. {
  13. super(provider, {}, user);
  14. this.archive = archiver;
  15. this.options.logLevel = "info";
  16. this.options.hideMadeWithCables = true;
  17. this.options.combineJs = false;
  18. this.options.minify = false;
  19. this.options.handleAssets = "auto";
  20. this.options.rewriteAssetPorts = true;
  21. this.options.flattenAssetNames = true;
  22. this.finalAssetPath = "assets/";
  23. }
  24. static getName()
  25. {
  26. return "html";
  27. }
  28. static getExportOptions(user, teams, project, exportQuota)
  29. {
  30. return {
  31. "type": this.getName(),
  32. "allowed": true,
  33. "possible": true,
  34. "fields": {}
  35. };
  36. }
  37. doExport(project, cb)
  38. {
  39. this.collectFiles(
  40. project,
  41. this.createZip.bind(this),
  42. (collectErr, callbackError) =>
  43. {
  44. callbackError({ "msg": collectErr });
  45. },
  46. this.options,
  47. cb
  48. );
  49. }
  50. /* private */
  51. createZip(project, files, callbackFinished)
  52. {
  53. const zipFileName = this._projectsUtil.getExportFileName(project, this.getName());
  54. const zipPath = this._projectsUtil.getExportTargetPath(project);
  55. const finalZipFileName = path.join(zipPath, zipFileName);
  56. if (fs.existsSync(zipPath))
  57. {
  58. this._doZip(files, finalZipFileName, (result) =>
  59. {
  60. const fileUrl = helper.pathToFileURL(finalZipFileName);
  61. result.url = fileUrl;
  62. this.addLog("saved file to <a onclick=\"CABLES.CMD.ELECTRON.openFileManager('" + fileUrl + "');\">" + finalZipFileName + "</a>");
  63. callbackFinished(result);
  64. });
  65. }
  66. else
  67. {
  68. electronApp.exportProjectFileDialog(zipFileName).then((chosenFileName) =>
  69. {
  70. if (chosenFileName)
  71. {
  72. this._doZip(files, chosenFileName, (result) =>
  73. {
  74. const fileUrl = helper.pathToFileURL(finalZipFileName);
  75. result.url = fileUrl;
  76. this.addLog("saved file to <a onclick=\"CABLES.CMD.ELECTRON.openFileManager('" + fileUrl + "');\">" + finalZipFileName + "</a>");
  77. callbackFinished(result);
  78. });
  79. }
  80. else
  81. {
  82. const outputErr = "no export directory chosen";
  83. const result = { "error": outputErr };
  84. callbackFinished(result);
  85. }
  86. });
  87. }
  88. }
  89. collectFiles(project, callbackFilesCollected, callbackError, options, next)
  90. {
  91. this._log.info("...export");
  92. if (project)
  93. {
  94. options.handleAssets = options.handleAssets || "auto";
  95. this._exportProject(
  96. project,
  97. callbackFilesCollected,
  98. callbackError,
  99. options,
  100. next
  101. );
  102. }
  103. else
  104. {
  105. const err2 = "PROJECT_NOT_FOUND";
  106. callbackError(err2, (serviceResult) =>
  107. {
  108. next(serviceResult.msg, serviceResult);
  109. });
  110. }
  111. }
  112. _getFilesForProjects(theProjects, options, cb)
  113. {
  114. const user = settings.getCurrentUser();
  115. if (!theProjects)
  116. {
  117. cb([]);
  118. return;
  119. }
  120. const theFiles = [];
  121. theProjects.forEach((project) =>
  122. {
  123. const assetFilenames = this._projectsUtil.getUsedAssetFilenames(project, true);
  124. assetFilenames.forEach((fileName) =>
  125. {
  126. const fileDb = this._filesUtil.getFileDb(fileName, user, project);
  127. theFiles.push(fileDb);
  128. });
  129. });
  130. cb(theFiles);
  131. }
  132. _doAfterExport(originalProject, credentials, exportNumber, result)
  133. {
  134. return originalProject;
  135. }
  136. _getNameForZipEntry(fn, allFiles)
  137. {
  138. if (fn.substr(0, 1) === "/") fn = fn.substr(1);
  139. let fnNew = path.basename(fn);
  140. if (this.options.flattenAssetNames)
  141. {
  142. fnNew = fnNew.replaceAll("/", "_");
  143. }
  144. let assetDir = this.finalAssetPath;
  145. if (allFiles.includes(fnNew))
  146. {
  147. fnNew = path.join(this._helperUtil.generateUUID(), fnNew);
  148. }
  149. return path.join(assetDir, fnNew);
  150. }
  151. _getPortValueReplacement(filePathAndName, fn, lzipFileName)
  152. {
  153. return lzipFileName.replace(path.win32.sep, path.posix.sep);
  154. }
  155. _doAfterCombine(jsCode, options)
  156. {
  157. return jsCode;
  158. }
  159. _resolveFileName(filePathAndName, pathStr, project)
  160. {
  161. let result = filePathAndName || "";
  162. if (result.startsWith("/")) result = result.replace("/", "");
  163. if (result.startsWith("file:/")) result = fileURLToPath(filePathAndName);
  164. let finalPath = this.finalAssetPath;
  165. if (this.options.assetsInSubdirs && project && project._id) finalPath = path.join(this.finalAssetPath, project._id, "/");
  166. if (this.options.rewriteAssetPorts) result = result.replace(pathStr, finalPath);
  167. if (result.startsWith("assets/"))
  168. {
  169. return result.replace("assets/", "");
  170. }
  171. else
  172. {
  173. return result;
  174. }
  175. }
  176. }