parent
e7ae38654b
commit
6ed3c90bed
@ -1,126 +1,117 @@
|
||||
/**
|
||||
* @module flitter-gridfs/models/File
|
||||
*/
|
||||
const Model = require('libflitter/database/Model')
|
||||
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const Mongo = require('mongodb')
|
||||
|
||||
/**
|
||||
* A wrapper model for working with GridFS files.
|
||||
* @class
|
||||
*/
|
||||
const File = {
|
||||
schema: {
|
||||
name: String,
|
||||
content_type: String,
|
||||
created_on: {type: Date, default: () => new Date},
|
||||
file_id: String,
|
||||
data: {type: String, default: '{}'},
|
||||
},
|
||||
class GridFile extends Model {
|
||||
static get services() {
|
||||
return [...super.services, 'gridfs']
|
||||
}
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* Get the GridFSBucket used by the model.
|
||||
* @returns {mongodb/GridFS/Bucket} - the GridFS bucket
|
||||
*/
|
||||
grid(){
|
||||
return _flitter.daemon.gridfs.bucket
|
||||
},
|
||||
static get __context() {
|
||||
return {
|
||||
name: String,
|
||||
content_type: String,
|
||||
created_on: {type: Date, default: () => new Date},
|
||||
file_id: String,
|
||||
data: {type: String, default: '{}'},
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a file to the grid from a local file.
|
||||
* @param {string} filepath - path of the file to be uploaded
|
||||
* @param {string} [filename] - name of the file to save, defaults to the model's this.name
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
write_from_file({filepath, filename}){
|
||||
const grid = this.grid()
|
||||
filename = filename ? filename : this.name
|
||||
filepath = path.resolve(filepath)
|
||||
/**
|
||||
* Get the GridFS files collection.
|
||||
* @returns {Promise<mongodb/Collection>}
|
||||
*/
|
||||
static async files() {
|
||||
return this.gridfs.mongo_db.collection('fs.files')
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.createReadStream(filepath)
|
||||
.pipe(grid.openUploadStream(filename))
|
||||
.on('error', (e) => reject(e))
|
||||
.on('finish', (file) => {
|
||||
this.file_id = file._id.toString()
|
||||
this.save().then(resolve)
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Convert an object ID string to a MongoDB ObjectId.
|
||||
* @param {string} id
|
||||
* @returns {mongodb/ObjectId}
|
||||
*/
|
||||
static object_id(id) {
|
||||
return Mongo.ObjectId(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model's file from the Grid and store it to the local filesystem.
|
||||
* @param {string} filepath - path to which the file should be saved
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
write_to_file({filepath}){
|
||||
filepath = path.resolve(filepath)
|
||||
return new Promise((resolve, reject) => {
|
||||
this.get_read_stream()
|
||||
.pipe(fs.createWriteStream(filepath))
|
||||
.on('error', e => reject(e))
|
||||
.on('finish', () => resolve())
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Get a file record by ID string from the grid files collection.
|
||||
* @param {string} id
|
||||
* @returns {Promise<object>} - resolves to the retrieved file record object
|
||||
*/
|
||||
static async one(id) {
|
||||
const files = await this.files()
|
||||
return files.findOne({_id: this.object_id(id)})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the read stream for the model's stored Grid file.
|
||||
* @returns {mongodb/GridFS/GridFSBucketReadStream}
|
||||
*/
|
||||
get_read_stream(){
|
||||
const grid = this.grid()
|
||||
return grid.openDownloadStream(this.constructor.object_id(this.file_id))
|
||||
},
|
||||
/**
|
||||
* Get the GridFSBucket used by the model.
|
||||
* @returns {mongodb/GridFS/Bucket} - the GridFS bucket
|
||||
*/
|
||||
grid() {
|
||||
return this.gridfs.mongo_bucket
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this model's stored Grid file as data for the specified response.
|
||||
* @param {express/Response} response - the response to send to
|
||||
* @returns {boolean | void}
|
||||
*/
|
||||
send_to_response(response){
|
||||
const stream = this.get_read_stream()
|
||||
response.set({
|
||||
'Content-Disposition': `inline; filename="${this.name}"`
|
||||
})
|
||||
return stream.pipe(response)
|
||||
},
|
||||
},
|
||||
/**
|
||||
* Save a file to the grid from a local file.
|
||||
* @param {string} filepath - path of the file to be uploaded
|
||||
* @param {string} [filename] - name of the file to save, defaults to the model's this.name
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
write_from_file({filepath, filename}){
|
||||
const grid = this.grid()
|
||||
filename = filename ? filename : this.name
|
||||
filepath = path.resolve(filepath)
|
||||
|
||||
statics: {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.createReadStream(filepath)
|
||||
.pipe(grid.openUploadStream(filename))
|
||||
.on('error', (e) => reject(e))
|
||||
.on('finish', (file) => {
|
||||
this.file_id = file._id.toString()
|
||||
this.save().then(resolve)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GridFS files collection.
|
||||
* @returns {Promise<mongodb/Collection>}
|
||||
*/
|
||||
async files(){
|
||||
return _flitter.daemon.gridfs.db.collection('fs.files')
|
||||
},
|
||||
/**
|
||||
* Retrieve the model's file from the Grid and store it to the local filesystem.
|
||||
* @param {string} filepath - path to which the file should be saved
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
write_to_file({filepath}){
|
||||
filepath = path.resolve(filepath)
|
||||
return new Promise((resolve, reject) => {
|
||||
this.get_read_stream()
|
||||
.pipe(fs.createWriteStream(filepath))
|
||||
.on('error', e => reject(e))
|
||||
.on('finish', () => resolve())
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object ID string to a MongoDB ObjectId.
|
||||
* @param {string} id
|
||||
* @returns {mongodb/ObjectId}
|
||||
*/
|
||||
object_id(id){
|
||||
return Mongo.ObjectId(id)
|
||||
},
|
||||
/**
|
||||
* Get the read stream for the model's stored Grid file.
|
||||
* @returns {mongodb/GridFS/GridFSBucketReadStream}
|
||||
*/
|
||||
get_read_stream(){
|
||||
const grid = this.grid()
|
||||
return grid.openDownloadStream(this.constructor.object_id(this.file_id))
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file record by ID string from the grid files collection.
|
||||
* @param {string} id
|
||||
* @returns {Promise<object>} - resolves to the retrieved file record object
|
||||
*/
|
||||
async one(id){
|
||||
const fs = await this.files()
|
||||
return fs.findOne({_id: this.object_id(id)})
|
||||
},
|
||||
},
|
||||
|
||||
graphql: {
|
||||
|
||||
},
|
||||
/**
|
||||
* Send this model's stored Grid file as data for the specified response.
|
||||
* @param {express/Response} response - the response to send to
|
||||
* @returns {boolean | void}
|
||||
*/
|
||||
send_to_response(response){
|
||||
const stream = this.get_read_stream()
|
||||
response.set({
|
||||
'Content-Disposition': `inline; filename="${this.name}"`
|
||||
})
|
||||
return stream.pipe(response)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = File
|
||||
module.exports = exports = GridFile
|
||||
|
Loading…
Reference in new issue