Can TinyMCE convert image pasted as data to an upload? - tinymce-5

I am using TinyMCE 5.7 and it handles uploading images well. However when an image is pasted from the clipboard (ex: Snipping Tool) it gets pasted as data which is not desired. I can use the setting paste_data_images to block pasting data images but I would prefer that it convert the data into an upload request like normal image upload process. Is there a way to intercept the paste and do the upload? I am using both the image and paste plugins. Thanks

Eventually I figured out how to write my own paste function. First, in the TinyMCE config:
setup: function (editor) {
editor.on('paste', function (e) {
var imageBlob = retrieveImageFromClipboardAsBlob(e);
if (!imageBlob) {
return;
}
e.preventDefault();
uploadFile(imageBlob, function (response) {
if ('location' in response) {
if (editor) {
// console.log('upload completed', response);
editor.insertContent('<img src="' + response.location + '" />');
} else {
console.log('Tinymce editor not found!');
}
}
});
});
}
Then the routine to decode the pasted info:
function retrieveImageFromClipboardAsBlob(pasteEvent) {
if (pasteEvent.clipboardData === false) {
return false;
}
var items = pasteEvent.clipboardData.items;
if (items === undefined) {
return false;
}
for (var i = 0; i < items.length; i++) {
// Only paste if image is only choice
if (items[i].type.indexOf("image") === -1) {
return false;
}
// Retrieve image on clipboard as blob
var blob = items[i].getAsFile();
// load image if there is a pasted image
if (blob !== null) {
const reader = new FileReader();
reader.onload = function(e) {
// console.log('result', e.target.result);
};
reader.readAsDataURL(blob);
return blob;
}
}
return false;
}
and a routine to upload the file
function uploadFile(file, callback) {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function (e) {
var percentComplete = (e.loaded / e.total) * 100;
console.log("Uploaded: " + percentComplete + "%");
};
xhr.onload = function () {
if (xhr.status !== 200) {
alert("Error! Upload failed " + xhr.response);
}
if (callback) {
callback(JSON.parse(xhr.response));
}
};
xhr.onerror = function () {
alert("Error! Upload failed. Can not connect to server.");
};
xhr.open("POST", "/upload/tinymce", true);
var data = new FormData();
data.append('file', file);
xhr.send(data);
}

Related

vue method for loop wait for function complete

In this vue component, I have a method containing a for loop, calling another method. The second method does a request to the appserver. I need the first function waiting for the second to continue the for-loop. I've tried several async await options but doesn't understand how to implement it.
methods: {
selectFiles(files) {
this.progressInfos = [];
this.selectedFiles = files;
},
uploadFiles() {
this.message = "";
//var result = 0;
for (let i = 0; i < this.selectedFiles.length; i++) {
console.log(i)
//result = await this.upload(i, this.selectedFiles[i]);
this.upload(i, this.selectedFiles[i]);
}
},
upload(idx, file) {
this.progressInfos[idx] = { percentage: 0, fileName: file.name };
//console.log("FinDocuNum:" + financialDocument.finDocId)
FinancialDocumentDataService.upload(1, file, (event) => {
this.progressInfos[idx].percentage = Math.round(100 * event.loaded / event.total);
}).then((response) => {
let prevMessage = this.message ? this.message + "\n" : "";
this.message = prevMessage + response.status;
return 1;
}).catch(() => {
this.progressInfos[idx].percentage = 0;
this.message = "Could not upload the file:" + file.name;
return 0;
});
}
}
The upload function must be async and return a promise like this:
async upload(file) {
return new Promise((resolve, reject) => {
axios({url: url, data: file, method: 'POST'})
.then(resp => {
resolve(resp)
})
.catch(err => {
reject(err)
})
})
},

Accessing Cache Images to upload to S3, in React native

Using react-native-vision-camera, I saw that there is a path for the image. It seem readable by react native tag.
I attempted to upload using this path (I used both file:// for android, and same for IOS), however it failed. Each time the file was detected as "jpeg" or "jpg" but I couldn't access it.
After downloading (From S3 amazon where I uploaded) and converting the jpg to txt, I only find the "file://path".
import { Storage } from "aws-amplify";
export default async function s3UploadBackup(file, user) {
let formatted_date = moment().format("DD-MM-YYYY");
let filePath = file.split("/");
let fileImageName = filePath[filePath.length - 1];
try {
console.log("Files contains :" + JSON.stringify(file));
// example of one of the URL I used "file:///storage/emulated/0/Android/data/com.app/files/Pictures/image-c64a66b3-489d-4af6-bf93-7adb507ceda1790666367.jpg"
const fileName = `${formatted_date}---${user.businessName}---${user.phoneNumber}---${user.location}---${fileImageName}`;
return Storage.put(uploadBackup.path + user.sub + "/" + user.phoneNumber + "/" + fileName, file, {
// contentType: "image/jpeg"
contentType: file.mime
})
} catch(error) {
console.log(error);
}
}
AWS-AMPLIFY support uploading file as BLOB and converting to specified file extension (JPEG, PNG,...).
Assume that we have local file URI - file:///storage/emulated/0/Android/data/com.app/files/Pictures/image-c64a66b3-489d-4af6-bf93-7adb507ceda1790666367.jpg
Let we refactor s3UploadBackup function
import { Storage } from "aws-amplify";
export default async function s3UploadBackup(file, user) {
let formatted_date = moment().format("DD-MM-YYYY");
let filePath = file.split("/");
let fileImageName = filePath[filePath.length - 1];
try {
console.log("Files contains :" + JSON.stringify(file));
// example of one of the URL I used "file:///storage/emulated/0/Android/data/com.app/files/Pictures/image-c64a66b3-489d-4af6-bf93-7adb507ceda1790666367.jpg"
const fileName = `${formatted_date}---${user.businessName}---${user.phoneNumber}---${user.location}---${fileImageName}`;
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", localPath, true);
xhr.send(null);
});
await Storage.put("yourKeyHere", blob, {
contentType: "image/jpeg", // contentType is optional
});
// We're done with the blob, close and release it
blob.close();
} catch(error) {
console.log(error);
// We're done with the blob, close and release it
blob.close();
}
}

How to return file Location after uploading to s3

I am new to Node.js and express.
I use following function to upload image to s3.
function defaultContentType(req, file, cb) {
setImmediate(function () {
var ct = file.contentType || file.mimetype || 'application/octet-stream'
cb(null, ct);
});
}
module.exports = async function (fileName, file) {
aws.config.update({
secretAccessKey: process.env.AWSSecretKey,
accessKeyId: process.env.AWSAccessKeyId,
contentType: defaultContentType,
});
var s3bucket = new aws.S3({
params: {
Bucket: process.env.S3_Bucket_Name,
}
});
var params = {
Key: fileName,
Body: file
};
var fileData = await s3bucket.upload(params, function (err, data) {
if (err) {
throw err;
} else {
return data;
}
});
return fileData;
}
before uploading the image, I resize it using
request(req.file.location, async function (err, response, body) {
var fileInstance = await sharp(body);
var resizeFile = await fileInstance.resize({
height: 150,
fit: 'inside'
});
var data = await s3Upload('mobile_' + req.file.key, resizeFile);
req.mobile = data.Location;
next();
});
The problem I have is;
The image does get resized and saved to s3.
But "s3Upload" function does not return the file location.
Seems like it take some time to complete the operation. Before it get completed, undefined value get return.
Can anyone suggest a way to fix this?
Modified method
module.exports = function (fileName, file, finishCallback) {
// more code
s3bucket.upload(params, function (err, data) {
if (err) {
throw err;
} else {
finishCallback(data);
}
});
}
modified the upload method as
s3Upload('mobile_' + req.file.key, resizeFile, (data) => {
req.mobile = data.Location;
next();
});
This seems to be working as expected.
I am not really sure this is the correct way to do things.
Is there a way to do this correctly?

Is there a way to fix Cannot read property 'post' of undefined?

I'm running a page in vue with a form, it submits and returns data to and from an API, I'm getting a 'post' of undefined error in the console and I can't seem to figure out what's going on.
<script>
methods: {
StartClient: function () { // Initiate XMLHttpRequest as aHttpRequest for GET
this.get = function(Url, Callback){
var aHttpRequest = new XMLHttpRequest();
aHttpRequest.onreadystatechange = function() {
if (aHttpRequest.readyState == 4 && aHttpRequest.status == 200)
Callback(aHttpRequest.responseText);
}
// use aHttpRequest with response headers, to allow GET
aHttpRequest.open("GET", Url, true);
aHttpRequest.setRequestHeader("X-Api-Key", "eVnbxBPfn01kuoJIdfgi46TiYNv8AIip1r3WbjsX");
aHttpRequest.send(null);
}
this.post = function(Url, message, Callback) { // initiate XMLHttpRequest as aHttpRequest for POST
var aHttpRequest = new XMLHttpRequest();
aHttpRequest.onreadystatechange = function() {
if (aHttpRequest.readyState == 4 && aHttpRequest.status == 200)
Callback(aHttpRequest.responseText);
}
// use aHttpRequest with response headers, to allow POST
aHttpRequest.open("POST", Url, true);
aHttpRequest.setRequestHeader("X-Api-Key", "eVnbxBPfn01kuoJIdfgi46TiYNv8AIip1r3WbjsX");
aHttpRequest.send(message);
}
},
submitData: function () { // Start a traceroute, followed by the 'Begin' button
document.getElementById('inputBox').disabled = true;
var targetInputButton = document.getElementById("inputBox").value;
var message = '{"targetInputButton":"' + targetInputButton + '"}';
this.StartClient().post('https://le75bkfcmg.execute-api.eu-west-2.amazonaws.com/dev/start-trace', message, function(response) {
document.getElementById('jobId').innerHTML = response;
});
},
sendBackData: function () { // Receive traceroute data, followed by the 'Generate data' button
var jobId = document.getElementById("jobId").innerHTML;
var message = '{"jobId":"' + jobId + '"}';
this.StartClient().post('https://le75bkfcmg.execute-api.eu-west-2.amazonaws.com/dev/check-trace', message, function(response) {
document.getElementById('report').innerHTML = response;
});
}
}
}
</script>

Lambda File Write to S3

For the past six months I have been downloading the NASA APOD and saving to an S3 bucket using a Lambda function. Up until 12/23/2016 all was working as expected. Now when I check my bucket, the images are there but size 0 bytes. I have included my code below. Does anyone know if there has been a change? Thanks!
var AWS = require("aws-sdk");
var https = require('https');
var http = require('http');
var fs = require('fs');
// Incoming Handler
// <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
exports.handler = (event, context, callback) => {
GetAPOD();
};
// <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
// Functions
// <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
function GetAPOD() {
var nasa_api_key = 'MY KEY GOES HERE'
, nasa_api_path = '/planetary/apod?api_key=' + nasa_api_key;
var options = {
host: 'api.nasa.gov',
port: 443,
path: nasa_api_path,
method: 'GET'
};
// Connect to the NASA API and get the APOD.
var req = https.request(options, function (res) {
console.log('Open connection to NASA.');
res.setEncoding('utf-8');
var responseString = '';
res.on('data', function (data) {
responseString = data;
});
res.on('end', function () {
console.log('API Response: ' + responseString);
var responseObject = JSON.parse(responseString)
, image_date = responseObject['date']
, image_url = responseObject['url']
, image_hdurl = responseObject['hdurl']
, media_type = responseObject['media_type'];
if (media_type == 'image') {
var image_name = image_date + '.jpg';
var s3 = new AWS.S3();
var s3Bucket = new AWS.S3( { params: {Bucket: 'nasa-apod'} } );
// Check to see if the image already exists in the S3 bucket.
// If not we will upload the image to S3.
var head_data = {Key: image_name};
s3Bucket.headObject(head_data, function(err, output_head_data) {
if (output_head_data) {
console.log("Image exists on S3.");
}
else {
console.log("Image does not exists on S3.");
// Image has not been uploaded to S3, open a stream and download the image to the /tmp folder.
var file = fs.createWriteStream("/tmp/" + image_name);
var request = http.get(image_url, function(response) {
console.log("Opening file stream.");
// Pipe the data into the file stream and save to disk.
response.pipe(file);
response.on('end', function () {
// File is written to disk, we are going to check that it exists.
var fileName = "/tmp/" + image_name;
fs.exists(fileName, function(exists) {
if (exists) {
console.log("File exits in /tmp folder.");
// Get the stats for the image, will need this for the ContentLength
fs.stat(fileName, function(error, stats) {
if (error) {
console.log("Stat Error: " + error);
}
else {
console.log("Opening file stream.");
var image_stream = fs.createReadStream(fileName);
// Begin the upload process to S3.
var param_data = {Key: image_name, Body: image_stream, ContentType: "image/jpeg", ContentLength: stats.size, ACL: "public-read"};
s3Bucket.putObject(param_data, function(err, output_data) {
if (err) {
console.log('Error uploading data to S3: ' + err);
}
else {
console.log('Image successfully uploaded.');
}
});
}
});
}
else {
console.log('File does not exist in the /tmp folder.');
}
});
});
});
}
});
}
else {
console.log("Media Type: " + media_type);
}
});
});
req.on('error', function (e) {
console.error('HTTP error: ' + e.message);
});
req.end();
}
// <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
Found out that NASA APOD API is now using https and not http for images. I had to adjust my code to use https for the image path.