Browse Source

Store file on filesystem renew's the storage path

Martin Filser 3 years ago
parent
commit
a064e03fc7
3 changed files with 42 additions and 13 deletions
  1. 5 3
      models/attachments.js
  2. 5 3
      models/avatars.js
  3. 32 7
      models/lib/fileStoreStrategy.js

+ 5 - 3
models/attachments.js

@@ -7,11 +7,13 @@ import { AttachmentStoreStrategyFilesystem, AttachmentStoreStrategyGridFs} from
 import FileStoreStrategyFactory, {moveToStorage, STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS} from '/models/lib/fileStoreStrategy';
 
 let attachmentBucket;
+let storagePath;
 if (Meteor.isServer) {
   attachmentBucket = createBucket('attachments');
+  storagePath = path.join(process.env.WRITABLE_PATH, 'attachments');
 }
 
-const fileStoreStrategyFactory = new FileStoreStrategyFactory(AttachmentStoreStrategyFilesystem, AttachmentStoreStrategyGridFs, attachmentBucket);
+const fileStoreStrategyFactory = new FileStoreStrategyFactory(AttachmentStoreStrategyFilesystem, storagePath, AttachmentStoreStrategyGridFs, attachmentBucket);
 
 // XXX Enforce a schema for the Attachments FilesCollection
 // see: https://github.com/VeliovGroup/Meteor-Files/wiki/Schema
@@ -28,7 +30,7 @@ Attachments = new FilesCollection({
     return ret;
   },
   storagePath() {
-    const ret = path.join(process.env.WRITABLE_PATH, 'attachments');
+    const ret = fileStoreStrategyFactory.storagePath;
     return ret;
   },
   onAfterUpload(fileObj) {
@@ -88,7 +90,7 @@ if (Meteor.isServer) {
 
   Meteor.startup(() => {
     Attachments.collection._ensureIndex({ 'meta.cardId': 1 });
-    const storagePath = Attachments.storagePath();
+    const storagePath = fileStoreStrategyFactory.storagePath;
     if (!fs.existsSync(storagePath)) {
       console.log("create storagePath because it doesn't exist: " + storagePath);
       fs.mkdirSync(storagePath, { recursive: true });

+ 5 - 3
models/avatars.js

@@ -6,18 +6,20 @@ import path from 'path';
 import FileStoreStrategyFactory, { FileStoreStrategyFilesystem, FileStoreStrategyGridFs} from '/models/lib/fileStoreStrategy';
 
 let avatarsBucket;
+let storagePath;
 if (Meteor.isServer) {
   avatarsBucket = createBucket('avatars');
+  storagePath = path.join(process.env.WRITABLE_PATH, 'avatars');
 }
 
-const fileStoreStrategyFactory = new FileStoreStrategyFactory(FileStoreStrategyFilesystem, FileStoreStrategyGridFs, avatarsBucket);
+const fileStoreStrategyFactory = new FileStoreStrategyFactory(FileStoreStrategyFilesystem, storagePath, FileStoreStrategyGridFs, avatarsBucket);
 
 Avatars = new FilesCollection({
   debug: false, // Change to `true` for debugging
   collectionName: 'avatars',
   allowClientCode: true,
   storagePath() {
-    const ret = path.join(process.env.WRITABLE_PATH, 'avatars');
+    const ret = fileStoreStrategyFactory.storagePath;
     return ret;
   },
   onBeforeUpload(file) {
@@ -59,7 +61,7 @@ if (Meteor.isServer) {
   });
 
   Meteor.startup(() => {
-    const storagePath = Avatars.storagePath();
+    const storagePath = fileStoreStrategyFactory.storagePath;
     if (!fs.existsSync(storagePath)) {
       console.log("create storagePath because it doesn't exist: " + storagePath);
       fs.mkdirSync(storagePath, { recursive: true });

+ 32 - 7
models/lib/fileStoreStrategy.js

@@ -1,4 +1,5 @@
 import fs from 'fs';
+import path from 'path';
 import { createObjectId } from './grid/createObjectId';
 import { httpStreamOutput } from './httpStream.js'
 
@@ -10,11 +11,13 @@ export default class FileStoreStrategyFactory {
 
   /** constructor
    * @param classFileStoreStrategyFilesystem use this strategy for filesystem storage
+   * @param storagePath file storage path
    * @param classFileStoreStrategyGridFs use this strategy for GridFS storage
    * @param gridFsBucket use this GridFS Bucket as GridFS Storage
    */
-  constructor(classFileStoreStrategyFilesystem, classFileStoreStrategyGridFs, gridFsBucket) {
+  constructor(classFileStoreStrategyFilesystem, storagePath, classFileStoreStrategyGridFs, gridFsBucket) {
     this.classFileStoreStrategyFilesystem = classFileStoreStrategyFilesystem;
+    this.storagePath = storagePath;
     this.classFileStoreStrategyGridFs = classFileStoreStrategyGridFs;
     this.gridFsBucket = gridFsBucket;
   }
@@ -83,9 +86,10 @@ class FileStoreStrategy {
   }
 
   /** returns a write stream
+   * @param filePath if set, use this path
    * @return the write stream
    */
-  getWriteStream() {
+  getWriteStream(filePath) {
   }
 
   /** writing finished
@@ -94,6 +98,18 @@ class FileStoreStrategy {
   writeStreamFinished(finishedData) {
   }
 
+  /** returns the new file path
+   * @param storagePath use this storage path
+   * @return the new file path
+   */
+  getNewPath(storagePath, name) {
+    if (!_.isString(name)) {
+      name = this.fileObj.name;
+    }
+    const ret = path.join(storagePath, this.fileObj._id + "-" + this.versionName + "-" + name);
+    return ret;
+  }
+
   /** remove the file */
   unlink() {
   }
@@ -154,9 +170,10 @@ export class FileStoreStrategyGridFs extends FileStoreStrategy {
   }
 
   /** returns a write stream
+   * @param filePath if set, use this path
    * @return the write stream
    */
-  getWriteStream() {
+  getWriteStream(filePath) {
     const fileObj = this.fileObj;
     const versionName = this.versionName;
     const metadata = { ...fileObj.meta, versionName, fileId: fileObj._id };
@@ -247,10 +264,13 @@ export class FileStoreStrategyFilesystem extends FileStoreStrategy {
   }
 
   /** returns a write stream
+   * @param filePath if set, use this path
    * @return the write stream
    */
-  getWriteStream() {
-    const filePath = this.fileObj.versions[this.versionName].path;
+  getWriteStream(filePath) {
+    if (!_.isString(filePath)) {
+      filePath = this.fileObj.versions[this.versionName].path;
+    }
     const ret = fs.createWriteStream(filePath);
     return ret;
   }
@@ -287,7 +307,9 @@ export const moveToStorage = function(fileObj, storageDestination, fileStoreStra
 
     if (strategyRead.constructor.name != strategyWrite.constructor.name) {
       const readStream = strategyRead.getReadStream();
-      const writeStream = strategyWrite.getWriteStream();
+
+      const filePath = strategyWrite.getNewPath(fileStoreStrategyFactory.storagePath);
+      const writeStream = strategyWrite.getWriteStream(filePath);
 
       writeStream.on('error', error => {
         console.error('[writeStream error]: ', error, fileObjId);
@@ -303,7 +325,10 @@ export const moveToStorage = function(fileObj, storageDestination, fileStoreStra
 
       // https://forums.meteor.com/t/meteor-code-must-always-run-within-a-fiber-try-wrapping-callbacks-that-you-pass-to-non-meteor-libraries-with-meteor-bindenvironmen/40099/8
       readStream.on('end', Meteor.bindEnvironment(() => {
-        Attachments.update({ _id: fileObj._id }, { $set: { [`versions.${versionName}.storage`]: strategyWrite.getStorageName() } });
+        Attachments.update({ _id: fileObj._id }, { $set: {
+          [`versions.${versionName}.storage`]: strategyWrite.getStorageName(),
+          [`versions.${versionName}.path`]: filePath,
+        } });
         strategyRead.unlink();
       }));