From 464991b62e4fa6141449ca0c5980fcf0af3097a6 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 23 Feb 2021 20:31:19 +0100 Subject: upload files and write to disk --- .gitignore | 2 + Readme.md | 20 +- app/node_modules/okservices/oks3/index.js | 11 +- app/node_modules/okservices/oks3/upload.js | 78 ++- examples/db.json | 12 + examples/index.js | 12 +- examples/templates/index.liquid | 4 +- themes/okadmin/public/js/app.js | 6 +- themes/okadmin/public/js/parser.js | 608 +++++++++++++----------- themes/okadmin/public/js/upload.js | 12 +- themes/okadmin/templates/partials/inputs.liquid | 2 +- 11 files changed, 459 insertions(+), 308 deletions(-) diff --git a/.gitignore b/.gitignore index e2282ba..6e7ce41 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ .tmp npm-debug.log site/public/decks/ +site/public/uploads/ +examples/public/uploads/ diff --git a/Readme.md b/Readme.md index 53b190f..9d146e0 100644 --- a/Readme.md +++ b/Readme.md @@ -1,20 +1,19 @@ # OKCMS > "Pretty good" +> > - Steve Jobs - ## To run the demo: -* npm install -* cd examples -* node index +- npm install +- cd examples +- node index Server will be running on http://lvh.me:1337/ Admin area available on http://lvh.me:1337/admin/ - ## Config To access the admin area, you need to set a username and password. @@ -27,6 +26,7 @@ OK_PASS=password ``` S3 needs to be configured in the same way: + ``` S3_KEY=s3key S3_SECRET=s3secret @@ -73,3 +73,13 @@ Valid datatypes include: - double-captioned-image-list - meta +## Local S3 + +If you don't want to use S3 and you have enough disk space locally, you can just write them locally. Supply these options to the S3 service configuration (pathss with trailing slash!). + +``` +local: { + localPath: "/home/username/my-cool-website-pro/public/local-files/", + remotePath: "/local-files/", +}, +``` diff --git a/app/node_modules/okservices/oks3/index.js b/app/node_modules/okservices/oks3/index.js index 41ee3dc..60567e9 100644 --- a/app/node_modules/okservices/oks3/index.js +++ b/app/node_modules/okservices/oks3/index.js @@ -46,6 +46,7 @@ function OKS3(options) { key: options.s3.key, secret: options.s3.secret, bucket: options.s3.bucket, + local: options.s3.local, }) var express = options.express; @@ -85,7 +86,7 @@ function OKS3(options) { router.post('/audio', mult.single('audio'), function(req, res) { d.run(function () { - if (! options.s3.image.allowed) { + if (! options.s3.audio.allowed) { return res.status(500).json({ error: "Audio uploading not permitted" }) } @@ -113,7 +114,7 @@ function OKS3(options) { router.post('/video', mult.single('video'), function(req, res) { d.run(function () { - if (! options.s3.image.allowed) { + if (! options.s3.video.allowed) { return res.status(500).json({ error: "Video uploading not permitted" }) } @@ -140,7 +141,7 @@ function OKS3(options) { router.post('/file', mult.single('file'), function(req, res) { d.run(function () { - if (! options.s3.image.allowed) { + if (! options.s3.file.allowed) { return res.status(500).json({ error: "File uploading not permitted" }) } @@ -149,6 +150,10 @@ function OKS3(options) { preserveFilename: options.s3.video.preserveFilename, dirname: options.s3.dirname, types: { + 'image/gif': 'gif', + 'image/jpeg': 'jpg', + 'image/jpg': 'jpg', + 'image/png': 'png', 'application/pdf': 'pdf', 'text/plain': 'txt', 'text/html': 'html', diff --git a/app/node_modules/okservices/oks3/upload.js b/app/node_modules/okservices/oks3/upload.js index 681b14b..5d5c635 100644 --- a/app/node_modules/okservices/oks3/upload.js +++ b/app/node_modules/okservices/oks3/upload.js @@ -1,6 +1,8 @@ +var fs = require('fs') var knox = require('knox') var uuid = require('node-uuid') +var crypto = require('crypto') var s3 @@ -15,11 +17,15 @@ var acceptableuploadTypes = { module.exports = {} module.exports.init = function (opt){ - s3 = knox.createClient({ - key: opt.key, - secret: opt.secret, - bucket: opt.bucket, - }) + if (opt.local) { + s3 = { local: opt.local } + } else { + s3 = knox.createClient({ + key: opt.key, + secret: opt.secret, + bucket: opt.bucket, + }) + } } module.exports.put = function (opt) { @@ -28,10 +34,11 @@ module.exports.put = function (opt) { var now = new Date() var file = opt.file + // console.log("Received", file.originalname, file.mimetype) var types = opt.types || acceptableuploadTypes var extension = types[file.mimetype] - + if (opt.filename) { filename = opt.filename } @@ -60,24 +67,49 @@ module.exports.put = function (opt) { opt.acceptable && opt.acceptable(err) // console.log("upload >", remote_path) - s3.putBuffer(file.buffer, remote_path, { - 'Content-Length': file.size, - 'Content-Type': file.mimetype, - 'x-amz-acl': 'public-read' - }, function(err, s3res) { - if (err || s3res.statusCode !== 200) { - console.error(err); - if (s3res && s3res.resume) { - s3res.resume() + if (s3.local) { + var hash = crypto.createHash("sha256").update(filename, "utf8").digest("hex") + var hash_path = hash.substr(0, 2) + fs.mkdir(s3.local.localPath + hash_path, function(error){ + if (error && error.code !== "EEXIST") { + console.error("error creating directory") + console.error(error) + opt.unacceptable && opt.unacceptable(error) + return + } + var localPath = (s3.local.localPath + hash_path + "/" + filename).replace(/\/\//g, "/") + var remotePath = (s3.local.remotePath + hash_path + "/" + filename).replace(/\/\//g, "/") + fs.writeFile(localPath, file.buffer, {}, function(error){ + if (error) { + console.error("error saving file") + console.error(error) + opt.unacceptable && opt.unacceptable(error) + return + } + opt.success && opt.success(remotePath) + }); + }) + } else { + s3.putBuffer(file.buffer, remote_path, { + 'Content-Length': file.size, + 'Content-Type': file.mimetype, + 'x-amz-acl': 'public-read' + }, function(err, s3res) { + if (err || s3res.statusCode !== 200) { + console.error(err); + if (s3res && s3res.resume) { + s3res.resume() + } + return; } - return; - } - var file_url = s3res.url || s3res.req.url + var file_url = s3res.url || s3res.req.url - opt.success && opt.success(file_url) - }).on('error', function(err, s3res){ - console.error(err) - s3res && s3res.resume && s3res.resume() - }) + opt.success && opt.success(file_url) + }).on('error', function(err, s3res){ + console.error(err) + s3res && s3res.resume && s3res.resume() + }) + } } + diff --git a/examples/db.json b/examples/db.json index 34304c9..11204e7 100644 --- a/examples/db.json +++ b/examples/db.json @@ -328,5 +328,17 @@ "dateCreated": "Sat, 31 Dec 2016 05:07:09 GMT", "images": [] } + ], + "filez": [ + { + "id": "pdf-upload", + "title": "PDF upload", + "file": { + "uri": "/uploads/1e/Typhon firmware v3.pdf", + "caption": "/uploads/1e/Typhon firmware v3.pdf" + }, + "__index": 0, + "dateCreated": "Tue, 23 Feb 2021 19:30:32 GMT" + } ] } \ No newline at end of file diff --git a/examples/index.js b/examples/index.js index f08c752..729c574 100644 --- a/examples/index.js +++ b/examples/index.js @@ -69,6 +69,11 @@ var app = okcms image: { type: "image" }, images: { type: "triple-captioned-image-list" }, }, + filez: { + id: { type: "string", hidden: true }, + title: { type: "string" }, + file: { type: "file" }, + }, }, resources: [ @@ -77,6 +82,7 @@ var app = okcms { type: "bread" }, { type: "test" }, { type: "flour" }, + { type: "filez" }, ], services: { @@ -85,6 +91,10 @@ var app = okcms secret: process.env.S3_SECRET, bucket: process.env.S3_BUCKET, dirname: "okcms-example", + local: { + localPath: "/Users/user/Sites/okcms/examples/public/uploads/", + remotePath: "/uploads/", + }, image: { allowed: true, preserveFilename: false, @@ -163,7 +173,7 @@ var app = okcms "/contact": { data: { type: "page", query: "contact" }, }, - "/:id": { + "/bread/:id": { data: { type: "bread", query: ":id" }, }, }, diff --git a/examples/templates/index.liquid b/examples/templates/index.liquid index 7c12a86..4f26378 100644 --- a/examples/templates/index.liquid +++ b/examples/templates/index.liquid @@ -12,7 +12,7 @@