RemoteWebDavStorage.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. const fs = require('fs-extra');
  2. const path = require('path');
  3. const { createClient } = require('webdav');
  4. class RemoteWebDavStorage {
  5. constructor(config) {
  6. this.config = Object.assign({}, config);
  7. this.config.maxContentLength = this.config.maxContentLength || 10*1024*1024;
  8. this.wdc = createClient(config.url, this.config);
  9. }
  10. _convertStat(data) {
  11. return {
  12. isDirectory: function() {
  13. return data.type === "directory";
  14. },
  15. isFile: function() {
  16. return data.type === "file";
  17. },
  18. mtime: (new Date(data.lastmod)).getTime(),
  19. name: data.basename,
  20. size: data.size || 0
  21. };
  22. }
  23. async stat(filename) {
  24. const stat = await this.wdc.stat(filename);
  25. return this._convertStat(stat);
  26. }
  27. async writeFile(filename, data) {
  28. return await this.wdc.putFileContents(filename, data, { maxContentLength: this.config.maxContentLength })
  29. }
  30. async unlink(filename) {
  31. return await this.wdc.deleteFile(filename);
  32. }
  33. async readFile(filename) {
  34. return await this.wdc.getFileContents(filename, { maxContentLength: this.config.maxContentLength })
  35. }
  36. async mkdir(dirname) {
  37. return await this.wdc.createDirectory(dirname);
  38. }
  39. async putFile(filename) {
  40. if (!await fs.pathExists(filename)) {
  41. throw new Error(`File not found: ${filename}`);
  42. }
  43. const base = path.basename(filename);
  44. let remoteFilename = `/${base}`;
  45. if (base.length > 3) {
  46. const remoteDir = `/${base.substr(0, 3)}`;
  47. try {
  48. await this.mkdir(remoteDir);
  49. } catch (e) {
  50. //
  51. }
  52. remoteFilename = `${remoteDir}/${base}`;
  53. }
  54. try {
  55. const localStat = await fs.stat(filename);
  56. const remoteStat = await this.stat(remoteFilename);
  57. if (remoteStat.isFile && localStat.size == remoteStat.size) {
  58. return;
  59. }
  60. await this.unlink(remoteFilename);
  61. } catch (e) {
  62. //
  63. }
  64. const data = await fs.readFile(filename);
  65. await this.writeFile(remoteFilename, data);
  66. }
  67. async getFile(filename) {
  68. if (await fs.pathExists(filename)) {
  69. return;
  70. }
  71. const base = path.basename(filename);
  72. let remoteFilename = `/${base}`;
  73. if (base.length > 3) {
  74. remoteFilename = `/${base.substr(0, 3)}/${base}`;
  75. }
  76. const data = await this.readFile(remoteFilename);
  77. await fs.writeFile(filename, data);
  78. }
  79. async getFileSuccess(filename) {
  80. try {
  81. await this.getFile(filename);
  82. return true;
  83. } catch (e) {
  84. //
  85. }
  86. return false;
  87. }
  88. }
  89. module.exports = RemoteWebDavStorage;