Read text file in JavaScript from server - javascript

i have an m3u file that i wanna extract information from it. can i read as a text file?
Any idea how to read a text file or m3u deployed in a server in JavaScript or HTML line by line and get information from it ?

I created a basic example using just Javascript, starting with the example that I linked in the comments above. Just read in the text file using FileReader and create a loop in the onload function, where you parse out the records that you want. I based my file spec off of wikipedia, using the Example 6.
Result: https://jsfiddle.net/1sce9mv6/6/
Javascript:
document.getElementById('file').onchange = function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(progressEvent) {
// Entire file for debugging
//console.log(this.result);
// By lines
var lines = this.result.split('\n');
console.log('File read.');
//Check if this is an m3u file
if (lines[0].includes("#EXTM3U")) {
console.log("File header found!");
//Go through each line
for (var line = 1; line < lines.length; line++) {
//Process line
if (lines[line].includes("#EXTINF")) {
//print full line
console.log(lines[line]);
//split each line into the elements
var currentLine = lines[line].substring(7).split(',');
console.log("Runtime: " + currentLine[0]);
console.log("Song:" + currentLine[1]);
} else {
continue;
}
}
} else {
console.log(lines[0]);
console.log("Not m3u file...");
}
};
reader.readAsText(file);
};
HTML:
<input type="file" name="file" id="file">
References:
How to use Javascript to read local text file and read line by line?
https://en.wikipedia.org/wiki/M3U#Examples

I would recommend using jQuery for this.
If you're trying to read the file line by line then use:
<script>
$.get("item.txt", function(data) {
});
</script>
Where the argument data is the resultant file information. Even if you are just trying to get the data byte by byte this would work fine. I am not super familiar with .m3u files, but this advice should help.

Related

Google Apps Script: MailApp.sendEmail() can't send anything but TEXT and HTML files, nothing else?

I’m trying to attach a file to an email I send in Google Apps Script with MailApp.sendEmail(). In the browser JavaScript I read in the file manually with this code because I’ve already processed the equivalent of the submit button in my HTML form, and it works:
var file = document.getElementById('myfile');
var fileInfo = [];
if(file.files.length) // if there is at least 1 file
{
if (file.files[0].size < maxEmailAttachmentSize) // and its size is < 25M
{
var reader = new FileReader();
reader.onload = function(e)
{
fileInfo[0] = e.target.result;
};
reader.readAsBinaryString(file.files[0]);
fileInfo[1] = file.files[0].name;
fileInfo[2] = file.files[0].type;
fileInfo[3] = file.files[0].size;
}
console.log(fileInfo); // here I see the full file and info. All looks correct.
}
Then I send it up to the server.
google.script.run.withSuccessHandler(emailSent).sendAnEmail(fileInfo);
On the server I pull out the fields and send the email like so:
var fname = fileInfo[1];
var mimeType = fileInfo[2];
var fblob = Utilities.newBlob(fileInfo[0], mimeType, fname);
// all looks right in the Logger at this point
try {
GmailApp.sendEmail(emaiRecipient, emailSubject, emailBody,
{
name: 'Email Sender', // email sender
attachments: [fblob]
}
);
catch …
This works fine when the file is a text file or HTML file but doesn’t when the file is anything else. The file is sent but it's empty and apparently corrupt. Can anyone see what’s wrong with this code? (It doesn’t work with MailApp.sendEmail() either.) I did see in another stackoverflow post that the document has to be saved once, but that is something I definitely don’t want to do. Isn’t there any other way? What am I missing?
Modification points:
FileReader works with the asynchronous process. This has already been mentioned by Rubén's comment.
In the current stage, when the binary data is sent to Google Apps Script side, it seems that it is required to convert it to the string and byte array. This has already been mentioned by TheMaster's comment.
In order to use your Google Apps Script, in this case, I think that converting the file content to the byte array of int8Array might be suitable.
For this, I used readAsArrayBuffer instead of readAsBinaryString.
When above points are reflected to your script, it becomes as follows.
Modified script:
HTML&Javascript side:
// Added
function getFile(file) {
return new Promise((resolve, reject) => {
var reader = new FileReader();
reader.onload = (e) => resolve([...new Int8Array(e.target.result)]);
reader.onerror = (err) => reject(err);
reader.readAsArrayBuffer(file);
});
}
async function main() { // <--- Modified
var file = document.getElementById('myfile');
var fileInfo = [];
if(file.files.length) {
if (file.files[0].size < maxEmailAttachmentSize) {
fileInfo[0] = await getFile(file.files[0]); // <--- Modified
fileInfo[1] = file.files[0].name;
fileInfo[2] = file.files[0].type;
fileInfo[3] = file.files[0].size;
}
console.log(fileInfo); // here I see the full file and info. All looks correct.
google.script.run.withSuccessHandler(emailSent).sendAnEmail(fileInfo);
}
}
Although I'm not sure about your whole script from your question, at the modified script, it supposes that main() is run. When main() is run, the file is converted to the byte array and put it to fileInfo[0].
At Google Apps Script side, from fileInfo, var fblob = Utilities.newBlob(fileInfo[0], mimeType, fname); has the correct blob for Google Apps Script.
Google Apps Script side:
In this modification, your Google Apps Script is not modified.
References:
FileReader
FileReader.readAsArrayBuffer()
Added:
This code looks good but we can't use it because we are running on the Rhino JavaScript engine, not V8. We don't have support for newer JavaScript syntax. Could you give us an example of how it's done with older syntax? Ref
From your above comment, I modified as follows.
Modified script:
HTML&Javascript side:
function main() {
var file = document.getElementById('myfile');
var fileInfo = [];
if(file.files.length) {
if (file.files[0].size < maxEmailAttachmentSize) {
var reader = new FileReader();
reader.onload = function(e) {
var bytes = new Int8Array(e.target.result);
var ar = [];
for (var i = 0; i < bytes.length; i++) {
ar.push(bytes[i]);
}
fileInfo[0] = ar;
fileInfo[1] = file.files[0].name;
fileInfo[2] = file.files[0].type;
fileInfo[3] = file.files[0].size;
console.log(fileInfo); // here I see the full file and info. All looks correct.
google.script.run.withSuccessHandler(emailSent).sendAnEmail(fileInfo);
}
reader.onerror = function(err) {
reject(err);
}
reader.readAsArrayBuffer(file.files[0]);
}
}
}
Google Apps Script side:
In this modification, your Google Apps Script is not modified.

JavaScript how to make forEach loop synchronous

on my project I need to unzip a file and upload its content to a nodeJS server. I am able to unzip the file, e.g. I get the filenames of the content etc.
After unzipping I want to upload the content to my server. This is where the problem is. I am using formData to transmit the file. But every time I try to upload the files it shows me following error on the console in firefox:
"TypeError: Argument 2 of FormData.append does not implement interface Blob."
So it seems that there is no file-object given to the formData...
For unzipping I use JSZip [link to JSZip][1]
EDIT
I figured the first problem out myself. Now I am having trouble executing the code in the right order. My JS Code:
$("#file").on("change", function (evt) {
var formData = new FormData();
var counter = 0;
// remove content
$result.html("");
// be sure to show the results
$("#result_block").removeClass("hidden").addClass("show");
// Closure to capture the file information.
console.log('1');
function handleFile(f) {
var $fileContent = $("<ul>");
$result.append($fileContent);
JSZip.loadAsync(f)
.then(function (zip) {
zip.forEach(function (relativePath, zipEntry) {
console.log('2');
console.log(zipEntry);
zip.file(zipEntry.name).async("blob").then(function (u8) {
console.log('3');
console.log(u8);
formData.append('photo', u8, counter);
counter++;
$fileContent.append($("<li>", {
text: zipEntry.name
}));
})
});
}, function (e) {
$result.append($("<div>", {
"class": "alert alert-danger",
text: "Error reading " + f.name + ": " + e.message
}));
});
}
var files = evt.target.files;
handleFile(files[0]);
});
The console output is:
1
2
object
2
object
3
blob
3
blob
But what I want is:
1
2
object
3
blob
2
object
3
blob
But i dont know how to put another .then to make this work the way I want to

angular2 : read a file from local machine

Hi I am new to JavaScript and Angular 2.
I want to read a text file from local machine and show the content on page. I have the file in assets folder. How can I read it using typescript?
Thanks in advance :)
I tried passing file path as "e" but the error i am getting is on files[0]. If I remove files[0] error I am getting is parameter 1 is not of type 'Blob'.
private readSingleFile(e) {
var fileName = e.files[0];
console.log(fileName);
if (!fileName) {
return;
}
var reader = new FileReader();
reader.onload = file => {
var contents: any = file.target;
this.text = contents.result;
};
reader.readAsText(fileName);
console.log(reader.readAsText(fileName))
}
instead of e.files[0]
try
e.target.files[0]
code snippet:
var fileName = e.target.files[0];
<input type='file' (change)='readSingleFile($event)'>
Thanks everyone for the responses.
Finally i read the files using 'ng2-file-upload' and uploaded them to server also.

Need to use FlatFile file instead of mdb

I have used mdb DB with the below Architecture
HTML <-> JavaScript <-> DB (mdb file)
Now I want to relpace DB with FlatFile (instead of mdb file)
HTML <--> JavaScript <--???--> DB (FlatFile)
So please guide me how to replace this
Please share sample logic to access Flatfile(DB) data using JavaScript
Try This
JSFIDDLE
HTML
<input type="file" id="fileid" name="yourfile" >
Javascript
document.getElementById('fileid').onchange = function(){
var yourfile = this.files[0];
var filereader = new FileReader();
filereader.onload = function(progressEvent){
// Entire file
console.log(this.result);
// By lines
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
console.log(lines[line]);
}
};
filereader.readAsText(yourfile);
};

How to Zip files using jszip library

Am working on an offline application using HTML5 and jquery for mobile. i want to back up files from the local storage using jszip. below is a code snippet of what i have done...
if (localStorageKeys.length > 0) {
for (var i = 0; i < localStorageKeys.length; i++) {
var key = localStorageKeys[i];
if (key.search(_instrumentId) != -1) {
var data = localStorage.getItem(localStorageKeys[i])
var zip = new JSZip();
zip.file(localStorageKeys[i] + ".txt", data);
var datafile = document.getElementById('backupData');
datafile.download = "DataFiles.zip";
datafile.href = window.URL.createObjectURL(zip.generate({ type: "blob" }));
}
else {
}
}
}
in the code above am looping through the localstorage content and saving ezch file in a text format. the challenge that am facing is how to create several text files inside DataFiles.zip as currently am only able to create one text file inside the zipped folder. Am new to javascript so bare with any ambiguity in my question.
thanks in advance.
Just keep calling zip.file().
Look at the example from their documentation page (comments mine):
var zip = new JSZip();
// Add a text file with the contents "Hello World\n"
zip.file("Hello.txt", "Hello World\n");
// Add a another text file with the contents "Goodbye, cruel world\n"
zip.file("Goodbye.txt", "Goodbye, cruel world\n");
// Add a folder named "images"
var img = zip.folder("images");
// Add a file named "smile.gif" to that folder, from some Base64 data
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"base64"}).then(function (content) {
location.href="data:application/zip;base64," + content;
});
The important thing is to understand the code you've written - learn what each line does. If you do this, you'd realize that you just need to call zip.file() again to add another file.
Adding to #Jonathon Reinhart answer,
You could also set both file name and path at the same time
// create a file and a folder
zip.file("nested/hello.txt", "Hello World\n");
// same as
zip.folder("nested").file("hello.txt", "Hello World\n");
If you receive a list of files ( from ui or array or whatever ) you can make a compress before and then archive. The code is something like this:
function upload(files){
var zip = new JSZip();
let archive = zip.folder("test");
files.map(function(file){
files.file(file.name, file.raw, {base64: true});
}.bind(this));
return archive.generateAsync({
type: "blob",
compression: "DEFLATE",
compressionOptions: {
level: 6
}
}).then(function(content){
// send to server or whatever operation
});
}
this worked for me at multiple json files. Maybe it helps.
In case you want to zip files and need a base64 output, you can use the below code-
import * as JSZip from 'jszip'
var zip = new JSZip();
zip.file("Hello.json", this.fileContent);
zip.generateAsync({ type: "base64" }).then(function (content) {
const base64Data = content

Categories