"use strict"; const Promise = require("bluebird"); const path = require("path"); const matchValue = require("match-value"); const defaultValue = require("default-value"); const thumbnailImage = require("../thumbnail-image"); const uploadFile = require("../upload-file"); const sendImageEvent = require("../send-image-event"); const universalImageMetadata = require("../universal-image-metadata"); const { validateArguments } = require("@validatem/core"); const required = require("@validatem/required"); const isInteger = require("@validatem/is-integer"); const isNonEmptyString = require("@validatem/is-non-empty-string"); const defaultTo = require("@validatem/default-to"); const isSession = require("@modular-matrix/is-session"); const isRoomID = require("../is-room-id"); const isPositive = require("../is-positive"); function thumbnailFilename(filename, mimetype) { let extension = matchValue(mimetype, { "image/png": "png", "image/jpeg": "jpeg" }); if (filename != null) { let baseName = path.basename(filename, path.extname(filename)); return `thumbnail-${baseName}.${extension}`; } else { return `thumbnail.${extension}`; } } module.exports = function sendImage(_session, _options) { let [ session, options ] = validateArguments(arguments, { session: [ required, isSession ], options: [ required, { roomID: [ required, isRoomID ], description: [ required, isNonEmptyString ], file: [ required ], // FIXME: Validate more strictly, something like isUploadable filename: [ isNonEmptyString ], thumbnail: [{ maximumWidth: [ required, isInteger, isPositive ], maximumHeight: [ required, isInteger, isPositive ], }, defaultTo({ maximumWidth: 800, maximumHeight: 600 }) ] }] }); return Promise.all([ universalImageMetadata(options.file), uploadFile(session, { file: options.file, filename: options.filename }) ]).then(([ metadata, uploadResult ]) => { let fullSizeMXC = uploadResult.url; let desiredThumbnailMimetype = (metadata.mimetype === "image/jpeg") ? "image/jpeg" : "image/png"; return Promise.try(() => { return thumbnailImage({ session: session, mxc: fullSizeMXC, maximumWidth: options.thumbnail.maximumWidth, maximumHeight: options.thumbnail.maximumHeight, file: options.file, mimetype: desiredThumbnailMimetype }); }).then((thumbnail) => { let thumbnailFile = defaultValue(thumbnail.blob, thumbnail.buffer); let thumbnailFilesize = (thumbnail.buffer != null) ? thumbnail.buffer.length : thumbnail.blob.size; return Promise.try(() => { return uploadFile(session, { file: thumbnailFile, filename: thumbnailFilename(options.filename) }); }).then((result) => { let thumbnailMXC = result.url; return sendImageEvent(session, { roomID: options.roomID, description: options.description, image: { url: fullSizeMXC, displayWidth: metadata.width, displayHeight: metadata.height, mimetype: metadata.mimetype, filesize: metadata.filesize }, thumbnail: { url: thumbnailMXC, displayWidth: thumbnail.width, displayHeight: thumbnail.height, mimetype: defaultValue(thumbnail.mimetype, desiredThumbnailMimetype), filesize: thumbnailFilesize } }); }); }); }); };