mp3 file upload with phonegap on Windows RT [ Unicode Mapping error ] - javascript

I used phogap function for recording audio and uploading audio , file.
Audio File is recording and stored in music folder and I get the path and name of the file by the below function.
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
alert('over');
}
function captureAudio() {
navigator.device.capture.captureAudio(captureSuccess, captureError, { limit: 1, duration: 10 });
}
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
temp = path; //Assigned path to GLOBAL VARIABLE
temp1 = name;
alert(temp);
}
I call the function to upload the created audio file.
function uplod() {
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = name;
options.mimeType = "audio/mpeg";
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(temp,
"http:/URL/upload.php",
function (result) {
alert("success" + result.bytesSent + result.responseCode);
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function (error) {
console.log('Error uploading file ' + recordingPath + ': ' + error.code);
},
options);
}
But on running, I get these error, got stucked up, is the error is with URL or PATH ? Unicode ? and path of file is like this
C:/Users/AB/Music/captureAudio (4).mp3
0x80070459 - JavaScript runtime error: No mapping for the Unicode character exists in the target multi-byte code page.
WinRT information: No mapping for the Unicode character exists in the target multi-byte code page.

I got the answer by using Ajax post and by using Formdata() to server there by getting in the form of arrays.

Related

nodejs - replace a string everywhere in a large file

I have some huge files which are difficult to read in memory. I need to read each line and then replace double quotes if found and edit the same file. Right now, I am reading the file line by line, storing in an array and overwriting the same file. But, that's giving memory issue for big files. Any pointers ?
Here is my present implementation :
var allData = fs.readFileSync(fileName, { encoding: 'utf8' }).toString().split("\n");
var finalString = "";
for (i in allData) {
allData[i] = allData[i].replace(/"/g, '""');
finalString = finalString.concat(allData[i]);
finalString = finalString.concat("\n");
}
fs.writeFileSync(fileName, finalString);
Is there a way to edit by reading one line at a time and changing that in the file?
I have seen the similar question with scramjet, but that gives an error and is not compatible with all nodejs versions : node.js modify file data stream?
After going through a lot of answers, this worked for me which took care of the required synchronous and asynchronous behaviour, large file and keeping the name same.
function format_file(fileName) {
return new Promise((resolve, reject) => {
if (fs.existsSync(fileName)) {
var fields = fileName.split('/');
var tempFile = "";
var arrayLength = fields.length;
for (var i = 0; i < arrayLength - 1; i++) {
tempFile = tempFile + fields[i] + "/";
}
tempFile = tempFile + "tempFile" + fields[arrayLength - 1];
console.log("tempfile name is : " + tempFile + " actualFileName is :" + fileName);
var processStream = new ProcessStream();
fs.createReadStream(fileName, { bufferSize: 128 * 4096 })
.pipe(processStream)
.pipe(fs.createWriteStream(tempFile)).on('finish', function() { // finished
fs.renameSync(tempFile, fileName);
console.log('done encrypting');
resolve('done');
});
} else {
reject('path not found')
}
});
}

Write final json to a file from repeated requests to rest API

I am trying to build a file of json data from repeated calls to a restAPI. The final file to be written is the sum of the data received from all the calls. At present the file is being written with contents of the first call then overwritten by the contents of the first + second call (see console output below code).
As I have to make many calls, once the code is working, I would like to only write the file once the request has finished and the json string has been built. Does anyone now how I would go about doing this? Maybe with a callback(?), which I still don't have the hang of, once the requests have finished or the json string has finished being built.
"use strict";
const fs = require('fs');
const request = require('request');
var parse = require('csv-parse');
const path = "../path tocsv.csv";
const pathJSON = "../pathtoJSON.json";
var shapes = "https://url";
var options = {
url: '',
method: 'GET',
accept: "application/json",
json: true,
};
var csvData = [];
var jsonData = "[";
fs.createReadStream(path)
.pipe(parse({delimiter: ','}))
.on('data', function(data) {
csvData.push(data[1]);
})
.on('end',function() {
var start = Date.now();
var records = csvData.length //2212 objects
console.log(records);
var dataLength = 2 //set low at moment
for (var i = 0; i < dataLength; i += 1) {
var url = shapes + csvData[i];
options.url = url; //set url query
request(options, function(error, response, body) {
var time = Date.now() - start;
var s = JSON.stringify(body.response);
console.log( '\n' + (Buffer.byteLength(s)/1000).toFixed(2)+
" kilobytes downloaded in: " + (time/1000) + " sec");
console.log(i)
buildJSON(s);
});
}
function buildJSON(s) {
var newStr = s.substring(1, s .length-1);
jsonData += newStr + ',';
writeFile(jsonData);
}
function writeFile(jsonData) {
fs.writeFile(pathJSON, jsonData, function(err) {
if (err) {
return console.log(err);
} else {
console.log("file complete")
}
});
}
});
128.13 kilobytes downloaded in: 2.796 sec
2
file complete
256.21 kilobytes downloaded in: 3.167 sec
2
file complete
Perhaps writing to the file after all requests are complete will help. In the current code, the writeFile function is called each time a request is completed (which overwrites the file each time)
A quick way to fix this is to count requests (and failures) and write to file only after all the requests are complete.
"use strict";
const fs = require('fs');
const request = require('request');
var parse = require('csv-parse');
const path = "../path tocsv.csv";
const pathJSON = "../pathtoJSON.json";
var shapes = "https://url";
var options = {
url: '',
method: 'GET',
accept: "application/json",
json: true,
};
var csvData = [];
var jsonData = "[";
fs.createReadStream(path)
.pipe(parse({
delimiter: ','
}))
.on('data', function (data) {
csvData.push(data[1]);
})
.on('end', function () {
var start = Date.now();
var records = csvData.length //2212 objects
console.log(records);
var dataLength = 2 //set low at moment
var jsonsDownloaded = 0; // Counter to track complete JSON requests
var jsonsFailed = 0; // Counter to handle failed JSON requests
for (var i = 0; i < dataLength; i += 1) {
var url = shapes + csvData[i];
options.url = url; //set url query
request(options, function (error, response, body) {
if(error){
jsonsFailed++;
writeFile(jsonData);
return;
}
jsonsDownloaded++;
var time = Date.now() - start;
var s = JSON.stringify(body.response);
console.log('\n' + (Buffer.byteLength(s) / 1000).toFixed(2) +
" kilobytes downloaded in: " + (time / 1000) + " sec");
console.log(i)
buildJSON(s);
});
}
function buildJSON(s) {
var newStr = s.substring(1, s.length - 1);
jsonData += newStr + ',';
writeFile(jsonData);
}
function writeFile(jsonData) {
if(dataLength - (jsonsDownloaded + jsonsFailed) > 0){
return;
}
fs.writeFile(pathJSON, jsonData, function (err) {
if (err) {
return console.log(err);
} else {
console.log("file complete")
}
});
}
});
Note:
Requests being fired in quick succession like (2000 requests in a for loop) in my experience does not work well.. Try batching them. Also, doing it this way does not guarantee order (if that is important in your usecase)
An alternative would be to open your file in append mode. You can do this by passing an extra options object with flag set to your fs.writeFile call.
fs.writeFile(pathJSON, jsonData, {
flag: 'a'
}, function (err) {
if (err) {
return console.log(err);
}
});
References:
fs.writeFile Docs
File system flags

Local image filepath different in mediafile when using cordove captureimage to device file name

I have had this issue start to appear with the device file name being created in this format:
.../DCIM/Camera/IMG_20170819_155509.jpg
But the media file data when using Cordova captureImage being returned as:
.../DCIM/Camera/1503140105277.jpg
Therefore being unable to return the image.
Here is the code:
$('body').off('click', '#add-image-inspect-attr-list').on('click', '#add-image-inspect-attr-list', function(event) {
var options = { limit: 1 };
navigator.device.capture.captureImage(inspectAttrPictureSuccess, inspectPictureError, options);
$(this).off();
});
function inspectAttrPictureSuccess(imageData) {
console.log(imageData);
var countOfImg = $('.image-display-inspect-attr-list').children().length;
var file = {
ContentType: "image/jpeg",
base64: imageData,
Data: imageData,
ID: countOfImg
};
var fileName = file.base64;
inspectShowAttrFile(fileName,0);
}
function inspectShowAttrFile(fileName, type) {
var countOfImg = $('.image-display-inspect-list').children().length;
$('.image-display-inspect-list').append('<img id="inspect-img-index-' + countOfImg + '" class="img-responsive img-thumbnail img-inspect" src="' + fileName[0].fullPath + '">');
}
The app is built with cordova 6.3.1 and the device has andriod 4.4.2
This works on some devices but not others
To get around this issue, I had to check what the last file added was to the image file location. Get the folder path, get the latest file added, then update the image data created by the captureImage function with the new file name and location data:
function inspectAttrPictureSuccess(imageData) {
var deviceImageFolder = imageData[0].localURL.replace(imageData[0].name, '');
window.resolveLocalFileSystemURL(deviceImageFolder, function (dirEntry) {
var directoryReader = dirEntry.createReader();
directoryReader.readEntries(successfile, failfile);
}, function (err) {
var errToSave = err.message;
});
function successfile(entries) {
var latestimage = entries[entries.length - 1];
imageData[0].fullPath = latestimage.fullPath
imageData[0].localURL = latestimage.nativeURL
imageData[0].name = latestimage.name
var countOfImg = $('.image-display-inspect-attr-list').children().length;
var file = {
Filename: "inspect-attr-img-" + Math.random().toString(36).substring(2, 15) + ".jpg",
ContentType: "image/jpeg",
base64: imageData,
Data: imageData,
ID: countOfImg
};
inspectImageAttrFileSendAry.push(file);
inspectImageFileSendALLAry.push(file);
console.log(inspectImageAttrFileSendAry);
console.log(inspectImageFileSendALLAry);
var fileName = file.base64;
inspectShowAttrFile(fileName, 0);
}
function failfile(error) {
console.log("Failed to list directory contents: ", error);
}
}

How can I show with PhantomJS the url of the processed page in the generated PDF?

My goal was to generate a PDF from every page included in the sitemap of a website created with Rails. I'm using PhantomJS to get it. I'm quite new in this field, but I could do it, but when I was finished, I realized that it would be usable also to see at the beginning of every PDF the url of the page from which the PDF was generated, so I can browse quicker to the page (the site has over hundred pages).
Here is the Javascript:
// Render Sitemap to file
var RenderUrlsToFile, arrayOfUrls, system;
system = require("system");
/*
Render given urls
#param array of URLs to render
#param callbackPerUrl Function called after finishing each URL, including the last URL
#param callbackFinal Function called after finishing everything
*/
var getFileNumber = function(urlIndex) {
if (urlIndex <10) {
return "00" + urlIndex;
} else {
if (urlIndex <100) {
return "0" + urlIndex;
} else {
return urlIndex;
}
}
};
RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) {
var getFilename, next, page, retrieve, urlIndex, webpage;
urlIndex = 0;
webpage = require("webpage");
page = null;
getFilename = function() {
return "rendermulti-" + getFileNumber(urlIndex) + ".pdf";
};
next = function(status, url, file) {
page.close();
callbackPerUrl(status, url, file);
return retrieve();
};
retrieve = function() {
var url;
if (urls.length > 0) {
url = urls.shift();
urlIndex++;
page = webpage.create();
page.viewportSize = {
width: 1920,
height: 1880
};
page.settings.userAgent = "Phantom.js bot";
return page.open(url, function(status) {
var file;
file = getFilename();
if (status === "success") {
return window.setTimeout((function() {
// !!!!!!!!!!!!! Doesn't work !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
page.evaluate(function() {
var x = document.getElementById("logoAndNavigation");
var newP = document.createElement("P")
var textnode = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
newP.appendChild(textnode)
x.insertBefore(newP, x.childNodes[0]);
});
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
page.render("tempPdfs/" + file);
return next(status, url, file);
}), 200);
} else {
return next(status, url, file);
}
});
} else {
return callbackFinal();
}
};
return retrieve();
};
// This makes an array with all the urls inside the sitemap
var arrayOfUrls = [''];
var page = require('webpage').create();
page.open('http://localhost:3000/sitemap.xml', function() {
var content = page.content;
parser = new DOMParser();
xmlDoc = parser.parseFromString(content,'text/xml');
var loc = xmlDoc.getElementsByTagName('loc');
for(var i=0; i < loc.length; i++)
{
var url=loc[i].textContent;
arrayOfUrls.push(url);
}
});
RenderUrlsToFile(arrayOfUrls, (function(status, url, file) {
if (status !== "success") {
return console.log("Unable to render '" + url + "'");
} else {
return console.log("Rendered '" + url + "' at '" + file + "'");
}
}), function() {
return phantom.exit();
});
I tried to solve the issue with the urls, with the code framed with the comment
// !!!!!!!!!!!!! Doesn't work !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I wanted to show the url inside an element of the page, that has the id #logoAndNavigation, but I get this error:
NOT_FOUND_ERR: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.
If I use only a string like "hello" inside the variable textnode, it works, but not if I try to use the url of the page.
Can anyone please help me?
Thank you in advance!
appendChild expects a node not a string. You probably mean to use
var x = document.getElementById("logoAndNavigation");
var newP = document.createElement("p"); // small p
var textnode = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
newP.innerHTML = textnode; // this
x.insertBefore(newP, x.childNodes[0]);
You can also use the example of printheaderfooter.js to add the URL directly to the header or footer.

How to write to CSV file in Javascript

I have a script (using PhantomJS) that tests how long it takes to load a webpage. What I am trying to figure out is how to write the result of time taken to load the page to a .csv file. Then if I were to re-run the test again for it to add another result to the .csv file.
code:
var page = require('webpage').create(),
system = require('system'),
t, address;
var pageLoadArray = [];
var csvContents = "";
fs = require('fs');
if (system.args.length === 1) {
console.log('Usage: loadspeed.js <some URL>');
phantom.exit(1);
} else {
t = Date.now();
address = system.args[1];
page.open(address, function (status) {
if (status !== 'success') {
console.log('FAIL to load the address');
}
else {
t = Date.now() - t;
console.log('Page title is ' + page.evaluate(function () {
return document.title;
}));
if(t>7000){
console.log('Loading time was too long... ' + t + "msec");
pageLoadArray.push(t);
console.log(pageLoadArray.length);
console.log(pageLoadArray[0]);
//store the time value to the .csv file
phantom.exit(1);
}
else{
console.log('Loading time ' + t + ' msec');
pageLoadArray.push(t);
console.log(pageLoadArray.length);
console.log(pageLoadArray[0]);
//store the time value to the .csv file
}
}
phantom.exit();
});
}
You can use the fs module with the write(path, content, mode) method in append mode.
var fs = require('fs');
fs.write(filepath, content, 'a');
where filepath is the file path as a string and content is a string containing your CSV line.
Something like:
address+";"+(new Date()).getTime()+";"+t
If you have control over the Jenkins environment, you can use one of the browser specific methods of triggering a download like suggested in This Question
function download(strData, strFileName, strMimeType) {
var D = document,
A = arguments,
a = D.createElement("a"),
d = A[0],
n = A[1],
t = A[2] || "text/plain";
//build download link:
a.href = "data:" + strMimeType + "charset=utf-8," + escape(strData);
if (window.MSBlobBuilder) { // IE10
var bb = new MSBlobBuilder();
bb.append(strData);
return navigator.msSaveBlob(bb, strFileName);
} /* end if(window.MSBlobBuilder) */
if ('download' in a) { //FF20, CH19
a.setAttribute("download", n);
a.innerHTML = "downloading...";
D.body.appendChild(a);
setTimeout(function() {
var e = D.createEvent("MouseEvents");
e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(e);
D.body.removeChild(a);
}, 66);
return true;
}; /* end if('download' in a) */
//do iframe dataURL download: (older W3)
var f = D.createElement("iframe");
D.body.appendChild(f);
f.src = "data:" + (A[2] ? A[2] : "application/octet-stream") + (window.btoa ? ";base64" : "") + "," + (window.btoa ? window.btoa : escape)(strData);
setTimeout(function() {
D.body.removeChild(f);
}, 333);
return true;
}
Maybe you can use this URL SCM Plugin to grab the download.
Or use Selenium to automate some things and grab the download file

Categories

Resources