Automatically set KeystoneJS uploaded file URL - node.js

How would I automatically set the URL on an uploaded File in Keystone.js? This is the model for the File:
var keystone = require('keystone');
var Types = keystone.Field.Types;
var FileUpload = new keystone.List('FileUpload');
var myStorage = new keystone.Storage({
adapter: keystone.Storage.Adapters.FS,
fs: {
path: keystone.expandPath('./public/uploads/files'), // required; path where the files should be stored
publicPath: '/public/uploads/files', // path where files will be served
}
});
FileUpload.add({
name: { type: Types.Key, index: true},
file: {
type: Types.File,
storage: myStorage,
},
url: {type: String}
});
FileUpload.defaultColumns = 'name, url';
FileUpload.register();
I have tried to set the 'default' property of the url to something like
'/public/uploads/files/ + this.name
But the 'this' context is just an empty object literal. Keystone has an example in their docs where they make a custom frontend for uploading the images, and set the metadata of uploaded Files in a separate API call, but I'm trying to do this using their provided admin interface.

For clarification: you are trying make the entry in the Mongo database be the full path to the image not just the name of the image?
If I need something appended to the filename I do it on the template side, I guess you don't want to do that? Maybe if you explain the use case a little more?

Related

Storing and downloading pdf files from mongoDB using Node.js

I am using NodeJs, mongoose, ejs
I want the user to be able to upload his CV (Less the 16 MB) as a pdf file, then the admin to be able to download the pdf or view the CV on the website.
I did the upload part where I stored the cv like this in the database (which might be a wrong way):
cv: Object {
fileName: "Test Results All in testing-homework.pdf"
filePath: "cvs\1650985306448-.pdf"
fileType: "application/pdf"
}
and the pdf file is stored in the "/cvs" folder after upload.
I'm seeking a way to be able to download/view the pdf file from the database.
I will suggest you to use GridFs from mongodb.
refer:https://www.mongodb.com/docs/drivers/node/current/fundamentals/gridfs/
To Download from DB
bucket.openDownloadStreamByName('your_file_name').
pipe(fs.createWriteStream('./desired_name_of_output_file'));
Some of the Basic Upload and Download Operations using GridFs in MongoDB
const mongoUrl='mongodb://127.0.0.1:27017/db'
const mongodb = require('mongodb');
const fs = require('node:fs');
const client = new mongodb.MongoClient(mongoUrl)
const db = client.db('db');
Create Bucket with user-defined name
const bucket = new mongodb.GridFSBucket(db,{bucketName:'name_of_bucket' });
Upload to DB
fs.createReadStream('./filename.pdf').
pipe(bucket.openUploadStream('filename', {
chunkSizeBytes: 1048576,
metadata: { field: 'filename', value: 'myValue' }
}))
Find
const cursor = bucket.find({});
cursor.forEach(doc => console.log(doc));
Delete
cursor.forEach(doc => bucket.delete(doc._id));

jsPDF saving the file without extension when sent to nodejs/expressjs server

I have a class based react component that takes data from a user. The data is then fed to jsPDF.
let doc = new jsPDF();
doc.save()
This works fine. It saves the file with .pdf extension.
Now the problem is that I am sending this file to the express.js backend.
const pdf = new Blob([this.state.doc.output("blob")], {
type: "application/pdf",
});
OR
const pdf = this.state.doc.output("blob");
NODE.js
I am using Formidable.js for receiving the file.
const newPath = files.pdf.path;
The file gets saved without an extension.
I also did this
const newPath = `${files.pdf.path}.pdf`
This adds the .pdf to the string that is saved to mongodb, but the file saved is without any extension.
Solved.
https://github.com/node-formidable/formidable/issues/680
//front-end
const pdf = new File([doc.output("blob")], "myDoc.pdf", {
type: "application/pdf",
});
//Node
const newPath = files.pdf.path;
Thanks to https://github.com/GrosSacASac

Validation of Express request based on Swagger YAML

Is out there a node module for validation of the schema/values provided in Express req object, based on Swagger YAML schema definition for that request?
Let's say this is relevant part of the YAML:
/books/{genre}:
get:
parameters:
- name: genre
in: path
required: true
type: string
- name: size
in: query
required: false
type: number
A req object derived from the following request should pass validation:
GET /books/sci-fi
GET /books/thriller?size=5
And this one should fail:
GET /books/12
To generate a template node.js server using a yaml file, try swagger.io > Swagger Editor > Online Editor > build your yaml in the left pane > Generate Server > Node.js
The downloadable package will use swagger-tools for validation. The default index.js in the generated code will define that your controllers (custom code to handle each request) will live in the controllers directory:
// swaggerRouter configuration
var options = {
swaggerUi: '/swagger.json',
controllers: './controllers',
useStubs: process.env.NODE_ENV === 'development' ? true : false // Conditionally turn on stubs (mock mode)
};
Add these elements to the endpoint definition to define the controller name and the method name:
You can add this property to your endpoint definition to tell the swagger-tools middleware which javascript file will handle the request:
x-swagger-router-controller: myController
operationId: myMethod
Create a controllers directory containing myController.js that exports myMethod:
module.exports.myMethod = myMethod;
function myMethod(req, res) {
//do stuff
res.end();
}
The inputs will be validated before the request is routed to your controller.

Get source url for image stored in Bluemix Object Storage container using Node.js app

I have an Object Storage instance on Bluemix where I am storing images in the container. I need a source url for the images stored there so that I can use that image. To do this, I'm thinking of creating a Node.js app so that I will write a post call where I'll pass image name present in Object Storage as request, so that it will give me the image url as response.
Is this possible or not? If possible, can anyone suggest whether there are any npm modules which do this functionality? If not, are there any other suggestions to get the url of image?
Any help is appreciated..Thanks!
start the server by command node app.js also u need package pkgcloud to perform this operation. You can get the object storage credentials simply by creating a key on IBM console inside Storage module.
inside app.js insert a new route for download
var objectStorageHandler = require("./lib/objectStorageHandler.js");
app.get('/download', function(req, res) {
(new objectStorageHandler()).download('YourContainerName', 'imagenamewithextension',function(download){
console.log(res);
download.pipe(res);
});
});
Inside Lib folder create a module with name objectStorageHandler.js
Inside objectStorageHandler.js write code
var pkgcloud = require('pkgcloud');
var objectStorageHandler = function(){
}
objectStorageHandler.prototype.download = function(container, file,callback)
{
var config = {
provider: 'openstack',
useServiceCatalog: true,
useInternal: false,
keystoneAuthVersion: 'v3',
authUrl: 'https://identity.open.softlayer.com',
tenantId: 'YOURPROJECTID', //projectId from credentials
domainId: 'YOURDOMAINID',
username: 'YOURUSRNAME',
password: 'YOURPASSWORD',
region: 'dallas' //dallas or london region
};
var client = pkgcloud.storage.createClient(config);
client.auth(function (error) {
if(error) {
console.error("Authorization error for storage client (pkgcloud): ", error);
}
else {
var request = client.download({
container: container,
remote: file
});
callback(request);
}
});
}
module.exports = objectStorageHandler;
after server started lets assume at port 3000 simply call localhost:3000/download that will download the image, we can also pass image name in parameters to download images dynamically.

Serve custom static files with socket.io nodejs

I try to share my code betwen server and client I use following code (app.js):
var io = require('socket.io').listen(8000),
Static = require('socket.io').Static;
io.configure(function () {
var _static = new Static(io);
// some methods to add my custom files
_static.add('\public\test.js');
io.set('static', _static);
});
My file structure looks like this:
root
app.js
public
test.js
When I type "http://localhost:8000/public.test.js" Browser download default file "Welcome to socket.io"
This question is rather old, but here's the current way to do it (for v0.9):
var io = require('socket.io').listen(8000);
io.static.add('/path/for/request.js', {file: 'path/to/file.js'});
Note that the path to the resource is relative to the socket.io path, so the request URI would be something like:
http://localhost:8000/socket.io/path/for/request.js
If you see an error like Protocol version not supported, then that means your request URI probably has an extension that the manager can't support. Here's how to add that support:
io.static.add('/path/for/request.foo', {
mime: {
type: 'application/javascript',
encoding: 'utf8',
gzip: true
},
file: 'path/to/file.js'
});
The documentation points at their own Static library for a working implementation.

Resources