import { Meteor } from 'meteor/meteor' ;
import { FilesCollection } from 'meteor/ostrio:files' ;
import { createBucket } from './lib/grid/createBucket' ;
import fs from 'fs' ;
import path from 'path' ;
import { AttachmentStoreStrategyFilesystem , AttachmentStoreStrategyGridFs } from '/models/lib/attachmentStoreStrategy' ;
import FileStoreStrategyFactory , { moveToStorage } from '/models/lib/fileStoreStrategy' ;
let attachmentBucket ;
if ( Meteor . isServer ) {
attachmentBucket = createBucket ( 'attachments' ) ;
}
const fileStoreStrategyFactory = new FileStoreStrategyFactory ( AttachmentStoreStrategyFilesystem , AttachmentStoreStrategyGridFs , attachmentBucket ) ;
// XXX Enforce a schema for the Attachments FilesCollection
// see: https://github.com/VeliovGroup/Meteor-Files/wiki/Schema
Attachments = new FilesCollection ( {
debug : false , // Change to `true` for debugging
collectionName : 'attachments' ,
allowClientCode : true ,
namingFunction ( opts ) {
const filenameWithoutExtension = opts . name . replace ( /(.+)\..+/ , "$1" ) ;
const ret = opts . meta . fileId + "-" + filenameWithoutExtension ;
// remove fileId from meta, it was only stored there to have this information here in the namingFunction function
delete opts . meta . fileId ;
return ret ;
} ,
storagePath ( ) {
const ret = path . join ( process . env . WRITABLE _PATH , 'attachments' ) ;
return ret ;
} ,
onAfterUpload ( fileObj ) {
Object . keys ( fileObj . versions ) . forEach ( versionName => {
fileStoreStrategyFactory . getFileStrategy ( this , fileObj , versionName ) . onAfterUpload ( ) ;
} )
} ,
interceptDownload ( http , fileObj , versionName ) {
const ret = fileStoreStrategyFactory . getFileStrategy ( this , fileObj , versionName ) . interceptDownload ( http ) ;
return ret ;
} ,
onAfterRemove ( files ) {
files . forEach ( fileObj => {
Object . keys ( fileObj . versions ) . forEach ( versionName => {
fileStoreStrategyFactory . getFileStrategy ( this , fileObj , versionName ) . onAfterRemove ( ) ;
} ) ;
} ) ;
} ,
// We authorize the attachment download either:
// - if the board is public, everyone (even unconnected) can download it
// - if the board is private, only board members can download it
protected ( fileObj ) {
const board = Boards . findOne ( fileObj . meta . boardId ) ;
if ( board . isPublic ( ) ) {
return true ;
}
return board . hasMember ( this . userId ) ;
} ,
} ) ;
if ( Meteor . isServer ) {
Attachments . allow ( {
insert ( userId , fileObj ) {
return allowIsBoardMember ( userId , Boards . findOne ( fileObj . boardId ) ) ;
} ,
update ( userId , fileObj ) {
return allowIsBoardMember ( userId , Boards . findOne ( fileObj . boardId ) ) ;
} ,
remove ( userId , fileObj ) {
return allowIsBoardMember ( userId , Boards . findOne ( fileObj . boardId ) ) ;
} ,
fetch : [ 'meta' ] ,
} ) ;
Meteor . methods ( {
moveAttachmentToStorage ( fileObjId , storageDestination ) {
check ( fileObjId , String ) ;
check ( storageDestination , String ) ;
const fileObj = Attachments . findOne ( { _id : fileObjId } ) ;
moveToStorage ( fileObj , storageDestination , fileStoreStrategyFactory ) ;
} ,
} ) ;
Meteor . startup ( ( ) => {
Attachments . collection . _ensureIndex ( { 'meta.cardId' : 1 } ) ;
const storagePath = Attachments . storagePath ( ) ;
if ( ! fs . existsSync ( storagePath ) ) {
console . log ( "create storagePath because it doesn't exist: " + storagePath ) ;
fs . mkdirSync ( storagePath , { recursive : true } ) ;
}
} ) ;
}
export default Attachments ;