You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.2 KiB
JavaScript

"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
}
});
});
});
});
};