Js - Cache file, open it, detect changes and upload - javascript

I have a file structure on a web page, and look for a solution for the following scenario:
The chosen file should be downloaded in browser cache and opened (if it's an excel document, open with excel, etc.).
Now when the user changes the file, it should be detected and the file should be uploaded again.
Is this even possible with JavaScript?
If yes, where do I store the file (temporary internet folder?) and how do I detect the changes?

The only way for this to work you would need to have the user select the downloaded file, and then check for modification.
HTML
<label for="excelFile">Select the excel file: </label><input type="file" id="excelFile" />
JS
//Change event to detect when the user has selected a file
document.querySelector("#excelFile").addEventListener("change",function(e){
//get the selected file
var file = this.files[0];
//get the last modified date
var lastModified = file.lastModified;
//check lastModified against stored lastModified
//this assumes you store the last mod in localStorage
if(localStorage['excelLastMod'] < lastModified){
//It has modified update last mod
localStorage['excelLastMod'] = lastModified;
//do upload
}
});
If you know your user is using Chrome you can use Chrome's FileSystem api

The way you describe it: No, that is not possible in JavaScript.
It sounds like you want an FTP client.
When the user changes the file, it should be detected and the file should be uploaded again.
That is not possible due to JS having almost no access to the file system.
The only way you can access a file at all is by requesting the user to select one, see:
How to open a local disk file with Javascript?
So the most you could do would be:
File is downloaded.
Based on browser & settings, file may be opened automatically, or not.
User is presented with a file selection dialog that they can use when they are done editing.
Compare selected file to file on server and upload if changed.
After downloading a file, you have no control over it.
For applications that have a protocol registered (such a steam://, for example), you might be able to request the URL being opened in a program, but that would require an if per file type/program.
Detecting file changes is not at all possible (because you have no access to the file), and uploading again requires the user to select the file manually, using a file dialog.

Thanks for your help and ideas. I saw a software (https://www.group-office.com/) which includes this function so there has to be way to do it.
New Idea, using chrome filesystem api (#Siguza already said it):
Create file from servers database on users local filesystem with filesystem api
open file locally (should work with filesystem:http://www.example.com/persistent/info.txt, or?)
poll last changes of file every x seconds
if change detected, upload file back to servers database
I saw some problems with excel locking the files Check if file has changed using HTML5 File API
but except of that this should work, shouldn't it?

Related

Copy/download temporary files

I am not an HTML/JavaScript developer. I am having to modify some legacy code written by someone who has left.
We have a Python app which acts as a local server with an HTML/JavaScript front end that can be viewed in a browser.
The Python creates a temporary cache file. I would like to give the user the option to save a copy of this temp file to a location of their choice or at least download it to the downloads directory (Windows & Linux)
I've tried adapting some of the ideas from here: https://www.delftstack.com/howto/javascript/javascript-download/
E.g.
const saveAnalysisBtn = document.getElementById("saveAnalysisBtn");
saveAnalysisBtn.addEventListener('click', saveAnalysis);
function saveAnalysis(evt) {
function download(filename) {
var element = document.createElement('a');
// hardcode temp file name just for POC
element.setAttribute('href','file://C:\\tmp\\my_temp_cache.db');
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
//document.body.removeChild(element);
}
var filename = "output.txt";
console.log(`Call Download`);
download(filename);
}
In Firefox this gives a security error:
Security Error: Content at
http://127.0.0.1:5000/replay/fapi_15_6_udi.bin may not load or link to
file:///C:/tmp/my_temp_cache.db
Which isn't terribly surprising. (Edge & Chrome give similar errors)
Is there a way to do this? Can be in HTML or JavaScript or Python (though I would like user to see evidence of download taking place in the browser).
Maybe I'm not understanding, but it looks like we're talking about just copying a file from one local location to a user specified location. The file you want to copy is on the machine the user is using? Couldn't you just provide the location in the web page and then just go there in a file explorer, finder, or command line tool to copy it however you want? It would solve the security issue.
But if you're required to create a link, you could create a download process that zips the file up to make a file like "my_temp_cache_db.zip" (or whatever compression tool/extension works best for you), and then provide the link for that. Zip files work through browsers better than some other types of files, and the user just has to unzip it wherever it ended up.
If that's not ideal, you could create a download process that makes a copy of the file and just changes the extension to something like "txt". The user downloads that file and then has to rename it to have the right extension.

Saving user uploaded image to folder and/or server

I have an app, that allows users to upload an image, crop it and with other data save it all as html file to be used as a footer for emails. The image is given to them as base64.
Howver turns out this is not supported by Outlook, since it doesnt accept b64 data as img source.
So my idea was to save the cropped image to a file, let's say /public/avatars/avatar.png and link it's directory as a source. However I'm having trouble finding a way how to save images to to a file using JS. My allowed stack is JS and React, no node.js.
How would I do that? I can have the file as either b64 ot canvas element, so i'm flexible here, as long as it's saved to file.
I'm open to other solutions too.
You can't save a file with client language only. You have to save it to a server, own server or external server or a service like AWS.
The best solution without server-side (strangly) is to use a API for save image and get link from this API. Then you can use this link to Outlook.
You can use https://aws.amazon.com/fr/cloudfront/ free for one year with 50Go and 2 millon request monthly.
If you do not exceed 300,000 images per year you can use this service : https://cloudinary.com/pricing
You can also use https://www.deviantart.com/developers/ but that's not really the point of service.
Weird solution :
Be careful, the login and password of your FTP user will be available in the source of your code. Minimum rights must be administered.
You can use this script for talk to FTP server from JS (not tested but seems worked) : http://www.petertorpey.com/files/ae/scripts/FTPConnection.jsx
You can try something like that :
var ftp = new FtpConnection("ftp://URL") ;
ftp.login("username", "password");
ftp.cd("FOLDER") // For move to folder
ftp.put(file,"FILE.PNG") ; // File must be a File JS Object
ftp.close() ;

Getting saved filename in JavaScript

I have a Chrome Packaged App that's a text editor. I've created a File Save dialog using FileSaver.js but I have a problem.
User Writes some text
User clicks Save and saves file as 'myfile.txt' (I set the default as 'file.txt')
User writes some more text
User clicks Save again, and expects to see 'myfile.txt' in the dialog, but they just see 'file.txt'
So is there any way around this? Ideally I'd be able to work out what that filename was so I can save it in chrome's local storage along with the file they've been editing so that it remembers next time they start up.
I imagine I can't get the full path because of security problems - but is there a way to get just the filename? Is there some non-standard thing in Chrome Packaged Apps that would allow this?
I imagine I can't get the full path because of security problems
Yes you can, and you just have to write file.fullPath to have it (as a string) when you're saving a file. Here is a simple example to save and get the path of a file:
function saveFile () {
chrome.fileSystem.chooseEntry({
type: "saveFile",
suggestedName: "file.txt"
},
function(savedFile) {
// The code to save your file, here you can use savedFile.fullPath
});
}

Read all files in a local folder offline without using ActiveXObject or php

I'm a beginner! I need to read data inside txt files in a local folder offline. I know the folder path, but I don't know the name of every single file.
C:\mypath\first.txt
C:\mypath\second.txt
C:\mypath\third.txt
...
To read a sigle file now I use:
$.ajax({url:"C:\mypath\first.txt",
success:function(result){
//...code for storing the data in a variable...
}
});
How can i read multiple file at once without know their name? something like:
$.ajax({url:"C:\mypath\*.txt",
success:function(result){
//...code for storing the data in a variable...
}
});
Thank you for any help!
You can use a file picker control (ie, <input type="file" multiple />) in a supported browser and have the user select the set of files to iterate. User input is the only way to get the list of files - you can't just go mucking about in a user's file system over the internet. All you can learn about the user's system is what the user tells you (eg, through <input type="file" multiple />).
And even then, you won't be able to read the file with a simple Ajax request. Same origin policies apply to local files. It may work if you test it on your own machine, but as soon as it hits the web, it will fail.
The only way to look through a client file system without user interaction is by using a Scripting.FileSystemObject ActiveXControl on windows in a non-internet based HTML Application (.hta file). So, since you don't want to use ActiveXControls, user input is your only option.
Edit: If you are creating a FireFox add-on, you can access the file system. See the documentation at mozilla.org for details.

<input type=file>, jwplayer, javascript question

I display a file open box so the user can select a file on their computer:
<input type="file" id="upload_input"/>
but when I get the file the user chose in Javascript (see code below), which I believe is 'safe' since javascript executes on the client side -- all I get is the file, not the full path -- despite the fact that the full path and filename appear in the field next to the 'Browse' button that input type=file always gives you.
In other words the user selects a file located on his machine for example at c:/aFolder/thefile.rtf.
Then after choosing that file the full path appears in the field next to the 'Browse' button: c:/aFolder/thefile.rtf
Yet when I programmatically retrieve the value of that field, the entire path is stripped off and all I have is the filename:
filename = document.getElementById('upload_input').value;
alert("The selected file name is " + filename);
Why does the input type=file control even bother to show the user the full path if you can't get it programmatically?
It's all happening on the client side after all, it's not like this is a full path on the server.
One other question: I use the filename above and construct a fully qualified path to that file, only for the sake of getting my JWplayer code working. The full path I create for development here is temporary.
In otherwords, when I get the filename above, I do this:
vidFname = ("c:/xampp/htdocs/theWebsite/aFolder/" + filename);
alert("The full path is: " + vidFname);
and then I try to play the video in Jwplayer:
playlist = { file: vidFname };
theJwPlayer().load(playlist);
theJwPlayer().play(true);
but Jwplayer gives me "Permission denied or file not found."
Here is what I had to change to get this to work:
vidFname = ("http://localhost/theWebsite/aFolder/" + filename);
alert("The full path is: " + vidFname);
playlist = { file: vidFname };
theJwPlayer().load(playlist);
theJwPlayer().play(true);
By changing the path to my localhost the above code works -- the video loads and succesffully plays.
NOTE: I don't think this is a 'folder permissions' issue because I can play the exact same file in the same location with a different .FLV player (standalone) app on my computer. So it's not folder permissions in my c:/xampp that's making Jwplayer say 'permission denied or file not found.'
Why won't Jwplayer (or is it Javascript..?) not letting me use a fully-qualified pathname to the file when I call
jwplayer().load() ?
After all, I'm using 'theJwPlayer' in Javascript,' which is running on the client computer, and the file is on the client computer too, so it's not a security issue.
Or is there something I'm missing here? NOTE: I fully apologize if this question is ignorant but at my current level of web programming, which you may have passed LONG ago, this is puzzling, ESPECIALLY the jwplayer().load() not working with a fully qualified path name.
Browsers will not reveal actual file paths to JavaScript code. It's a security thing. You won't be able to get at local files without using the (new, only available in new browsers) HTML5 file handling APIs, and even those won't give you complete file pathnames.
Similarly, when the file input is submitted with a form, the server won't get the full path either.
I think it's not very likely that this media player tool you're working with is designed to work with local files (that is, files on the local file system where the browser is running).

Categories