singlefile_companion.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/local/bin/node
  2. /*
  3. * Copyright 2010-2020 Gildas Lormeau
  4. * contact : gildas.lormeau <at> gmail.com
  5. *
  6. * This file is part of SingleFile.
  7. *
  8. * The code in this file is free software: you can redistribute it and/or
  9. * modify it under the terms of the GNU Affero General Public License
  10. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  11. * of the License, or (at your option) any later version.
  12. *
  13. * The code in this file is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  16. * General Public License for more details.
  17. *
  18. * As additional permission under GNU AGPL version 3 section 7, you may
  19. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  20. * AGPL normally required by section 4, provided you include this license
  21. * notice and a URL through which recipients can access the Corresponding
  22. * Source.
  23. */
  24. /* global require, process */
  25. const fs = require("fs");
  26. const path = require("path");
  27. const nativeMessage = require("./lib/messaging.js");
  28. const backEnds = {
  29. jsdom: "single-file-cli/back-ends/jsdom.js",
  30. puppeteer: "single-file-cli/back-ends/puppeteer.js",
  31. "puppeteer-firefox": "single-file-cli/back-ends/puppeteer-firefox.js",
  32. "webdriver-chromium": "single-file-cli/back-ends/webdriver-chromium.js",
  33. "webdriver-gecko": "single-file-cli/back-ends/webdriver-gecko.js"
  34. };
  35. process.stdin
  36. .pipe(new nativeMessage.Input())
  37. .pipe(new nativeMessage.Transform(async function (message, push, done) {
  38. try {
  39. await processMessage(message);
  40. push({});
  41. } catch (error) {
  42. push({ error });
  43. }
  44. done();
  45. process.exit(0);
  46. }))
  47. .pipe(new nativeMessage.Output())
  48. .pipe(process.stdout);
  49. async function processMessage(message) {
  50. if (message.method == "save") {
  51. return save(message.pageData);
  52. }
  53. if (message.method == "externalSave") {
  54. return externalSave(message.pageData);
  55. }
  56. }
  57. async function save(message) {
  58. const companionOptions = require("./options.json");
  59. const filename = path.resolve("../../", (companionOptions.savePath || ""), message.filename);
  60. fs.writeFileSync(getFilename(filename), message.content);
  61. }
  62. async function externalSave(message) {
  63. const companionOptions = require("./options.json");
  64. const backend = require(backEnds[companionOptions.backEnd || "puppeteer"]);
  65. await backend.initialize(companionOptions);
  66. try {
  67. const pageData = await backend.getPageData(message);
  68. pageData.filename = path.resolve("../../", (companionOptions.savePath || ""), pageData.filename);
  69. fs.writeFileSync(getFilename(pageData.filename), pageData.content);
  70. return pageData;
  71. } catch (error) {
  72. if (companionOptions.errorFile) {
  73. const message = "URL: " + message.url + "\nStack: " + error.stack + "\n";
  74. fs.writeFileSync(companionOptions.errorFile, message, { flag: "a" });
  75. }
  76. throw error;
  77. } finally {
  78. await backend.closeBrowser();
  79. }
  80. }
  81. function getFilename(filename, index = 1) {
  82. let newFilename = filename;
  83. if (index > 1) {
  84. const regExpMatchExtension = /(\.[^.]+)$/;
  85. const matchExtension = newFilename.match(regExpMatchExtension);
  86. if (matchExtension && matchExtension[1]) {
  87. newFilename = newFilename.replace(regExpMatchExtension, " - " + index + matchExtension[1]);
  88. } else {
  89. newFilename += " - " + index;
  90. }
  91. }
  92. if (fs.existsSync(newFilename)) {
  93. return getFilename(filename, index + 1);
  94. } else {
  95. return newFilename;
  96. }
  97. }