diff options
| -rw-r--r-- | .env-example | 5 | ||||
| -rw-r--r-- | lib/db/index.js | 3 | ||||
| -rw-r--r-- | lib/index.js | 19 | ||||
| -rw-r--r-- | lib/upload.js | 69 | ||||
| -rw-r--r-- | package.json | 1 | ||||
| -rw-r--r-- | public/assets/css/css.css | 4 | ||||
| -rw-r--r-- | public/assets/js/drag.js | 61 | ||||
| -rw-r--r-- | public/assets/js/index.js | 1 | ||||
| -rw-r--r-- | public/assets/js/nav.js | 8 | ||||
| -rw-r--r-- | public/assets/js/vendor/view/uploadview.js | 99 | ||||
| -rw-r--r-- | public/index.html | 2 |
11 files changed, 263 insertions, 9 deletions
diff --git a/.env-example b/.env-example index cf78d6f..3dd7276 100644 --- a/.env-example +++ b/.env-example @@ -3,4 +3,7 @@ DB_NAME=luckyplop DB_USER=your_db_username DB_PASS=your_db_password HOST_NAME=5.k - +S3_KEY= +S3_SECRET= +S3_BUCKET=luckyplop +S3_DIR=/p/ diff --git a/lib/db/index.js b/lib/db/index.js index 81c3af2..7bcb9ea 100644 --- a/lib/db/index.js +++ b/lib/db/index.js @@ -27,3 +27,6 @@ db.getRandom = function () { }).fetch() } +db.createImage = function(url){ + return new Image({ url: url, shorturl: "" }).save() +}
\ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 7a410d0..f4b01f4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,12 +7,17 @@ var bodyParser = require('body-parser') var cookieParser = require('cookie-parser') var path = require('path') var ejs = require('ejs') + var multer = require('multer') +var storage = multer.memoryStorage() +var multer_upload = multer({ storage: storage }) var app, server var db = require("./db") +var upload = require("./upload") + var site = module.exports = {} site.init = function(){ app = express() @@ -22,7 +27,6 @@ site.init = function(){ app.use(express.static(path.join(__dirname, '../public'))) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: false })) - app.use( multer({ dest:'./uploads/' }).single("file") ) app.use(express.query()) @@ -48,7 +52,16 @@ site.init = function(){ res.json(img) }) }) - app.post("/upload", function(req, res){ - res.sendStatus(200) + app.post("/upload", multer_upload.single('image'), function(req, res){ + upload.put("image", req.file, { + unacceptable: function(err){ + res.json({ error: err }) + }, + success: function(url){ + db.createImage(url).then(function(image){ + res.json(image) + }) + } + }) }) }
\ No newline at end of file diff --git a/lib/upload.js b/lib/upload.js new file mode 100644 index 0000000..f0ea132 --- /dev/null +++ b/lib/upload.js @@ -0,0 +1,69 @@ + +var crypto = require('crypto') +var knox = require('knox') +var moment = require('moment') + +var s3 = module.exports.s3 = knox.createClient({ + key: process.env.S3_KEY, + secret: process.env.S3_SECRET, + bucket: process.env.S3_BUCKET, +}); + +var acceptableuploadTypes = { + 'image/gif': 'gif', + 'image/jpeg': 'jpg', + 'image/png': 'png' +} + +module.exports.put = function (key, file, opt) { + var fileSize, fileType, filename + var err + var now = new Date() + + var ts = moment().format('YYYYMMDD') + + var extension = acceptableuploadTypes[file.mimetype] + filename = crypto.createHash('md5').update(file.buffer).digest('hex') + "." + extension; + + var remote_path = process.env.S3_DIR + filename + + if (! extension) { + err = "Unacceptable filetype" + } + else if (file.size < 10) { + err = "File too small" + } + else if (file.size > 2097152) { // 2mb limit + err = "File too large. Uploads can be a maximum of 2 mb." + } + + if (err) { + console.error(">>>", err) + opt.unacceptable && opt.unacceptable(err) + return + } + + 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(s3res.statusCode, err) + if (s3res && s3res.resume) { + s3res.resume() + } + return + } + + var file_url = s3res.url || s3res.req.url + + opt.success && opt.success(file_url) + }).on('error', function(err, s3res){ + console.error("error", err) + s3res && s3res.resume && s3res.resume() + }) +} diff --git a/package.json b/package.json index 6c1ac5a..43dd4dc 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "lodash": "^3.10.1", "mongodb": "^2.0.43", "multer": "^1.0.5", + "multer-s3": "^1.3.0", "mysql2": "^0.15.8", "skipper": "^0.5.7" } diff --git a/public/assets/css/css.css b/public/assets/css/css.css index 75e4ddc..b528a14 100644 --- a/public/assets/css/css.css +++ b/public/assets/css/css.css @@ -107,8 +107,8 @@ a:visited { left: 0; width: 100%; height: 100%; - z-index: 7778; - background-color: rgba(255,255,255,0.7); + z-index: 1; + background-color: rgba(0,0,0,0.7); background-image: url(http://okfocus.s3.amazonaws.com/luckyplop/slot.gif); background-position: center; } diff --git a/public/assets/js/drag.js b/public/assets/js/drag.js new file mode 100644 index 0000000..b73c459 --- /dev/null +++ b/public/assets/js/drag.js @@ -0,0 +1,61 @@ +var DragView = UploadView.extend({ + + el: "body", + + uploadAction: "/upload", + + selfDrag: false, + + events: { + 'dragover': 'dragover', + 'dragstart': 'dragstart', + 'drop': 'handleDrop', + }, + + drop: function(){ + $("#droparea").hide() + $("#loading").show() + }, + + dragover: function(e){ + e.stopPropagation() + e.preventDefault() + if (this.selfDrag) { + $("#droparea").hide() + } + else { + $("#droparea").show() + } + }, + + // set if we're dragging an image from the page, versus from another window + dragstart: function(e){ + this.selfDrag = true + }, + + handleDrop: function(e){ + var base = this + e.stopPropagation() + e.preventDefault() + + e = e.originalEvent + + if (e.dataTransfer && ! this.selfDrag) { + if (e.dataTransfer.files.length) { + this.handleFileSelect(e) + } + } + else { + this.handleFileSelect(e) + } + this.selfDrag = false + this.drop() + }, + + add: function(data){ + $("#loading").hide() + app.view.display(data) + history.pushState(data, document.title, "/p/" + data.id) + }, + +}) diff --git a/public/assets/js/index.js b/public/assets/js/index.js index fefb7fc..c2275df 100644 --- a/public/assets/js/index.js +++ b/public/assets/js/index.js @@ -5,6 +5,7 @@ var app = (function(){ app.init = function(){ app.view = new NavView () + app.upload = new DragView () $(window).on("focus", app.focus) $(window).on("blur", app.blur) diff --git a/public/assets/js/nav.js b/public/assets/js/nav.js index bc525cf..9a4456e 100644 --- a/public/assets/js/nav.js +++ b/public/assets/js/nav.js @@ -10,7 +10,8 @@ var NavView = View.extend({ initialize: function(){ this.id = -1 - this.$pip = this.$("#pip img") + this.$pip = this.$("#pip") + this.$pip_img = this.$("#pip img") this.$image = this.$("#luckyimage") $(window).on("keydown", this.keydown.bind(this)) @@ -81,14 +82,15 @@ var NavView = View.extend({ history.pushState(data, document.title, "/p/" + data.id) }.bind(this)) }, - + display: function(data){ if (! data || ! data.id) { this.onLatest = true return } this.id = data.id - this.$pip.attr("src", data.url) + this.$pip.attr("href", data.url) + this.$pip_img.attr("src", data.url) this.$image.css("background-image", "url(" + data.url + ")") }, diff --git a/public/assets/js/vendor/view/uploadview.js b/public/assets/js/vendor/view/uploadview.js new file mode 100644 index 0000000..436f4c8 --- /dev/null +++ b/public/assets/js/vendor/view/uploadview.js @@ -0,0 +1,99 @@ + +var UploadView = View.extend({ + + // define uploadAction + + events: { + "change [type=file]": "handleFileSelect", + "submit form": "preventDefault", + }, + + initialize: function(){ + this.$file = this.$("[type=file]") + this.$upload = this.$(".upload-icon") + }, + + beforeUpload: function(){ + }, + + handleFileSelect: function(e) { + e.stopPropagation(); + e.preventDefault(); + + this.beforeUpload() + + var files = e.dataTransfer ? e.dataTransfer.files : e.target.files + + for (var i = 0, f; f = files[i]; i++) { + if ( ! f.type.match('image.*')) { + continue; + } + + this.upload(f) + // this.getImageDimensions(f) + } + }, + +/* + getImageDimensions: function(f){ + var base = this + + this.$upload.addClass('uploading') + + var reader = new FileReader() + + reader.onload = function(e) { + var image = new Image() + image.onload = function(){ + var width = image.naturalWidth, + height = image.naturalHeight + base.upload(f, width, height) + } + image.src = e.target.result + } + + reader.readAsDataURL(f); + }, +*/ + + upload: function(f){ + var fd = new FormData() + fd.append('image', f) +// fd.append('width', width) +// fd.append('height', height) +// fd.append('_csrf', $("[name=_csrf]").val()) + + if (this.mediaTag) { + fd.append('tag', this.mediaTag) + } + + var request = $.ajax({ + url: this.uploadAction, + type: "post", + data: fd, + dataType: "json", + processData: false, + contentType: false, + }) + request.done(this.success.bind(this)) + }, + + success: function(media){ + if (media.error) { + // console.log(media.error) + this.$upload.removeClass('uploading') + this.error(media.error) + return + } + this.$upload.removeClass('uploading') + this.add(media) + }, + + add: function(media){ + console.log(media) + }, + + error: function(error){ + }, + +}) diff --git a/public/index.html b/public/index.html index 1d56dc9..febb353 100644 --- a/public/index.html +++ b/public/index.html @@ -64,8 +64,10 @@ <script src="/assets/js/vendor/util.js"></script> <script src="/assets/js/vendor/view/view.js"></script> <script src="/assets/js/vendor/view/formview.js"></script> +<script src="/assets/js/vendor/view/uploadview.js"></script> <script src="/assets/js/vendor/view/router.js"></script> +<script src="/assets/js/drag.js"></script> <script src="/assets/js/nav.js"></script> <script src="/assets/js/index.js"></script> |
