Heroku file upload - javascript

I have a local file download, which gets triggered in the following fashion.
panelBody.append('<button onclick="downloadCsv(\''+skl+'\')">Download csv</button>')
function downloadCsv(data){
var filename=data+'_report.csv'
var form = $('<form>', {action: '/admin/download', method: 'GET'});
form.append($('<input>', {name: 'file_name', value: filename}));
form.submit();
return false;
}
router.get('/download',helper.isSchoolAdmin,feedController.downloadCsv);
downloadCsv:function(req,res){
var fileName = process.cwd()+'/reports/'+ req.query.file_name;
res.download(fileName,function(err){
if(!err)console.log('down')
});
}
The file itself is written to the specified path in the immediate previous request to a different route.
Now this works fine on my local..My question is, what would happen once I deploy it onto heroku? would my file upload and download still work, as I've read that heroku uses an ephimeral file system which allows writing only to a tmp directory.
If that's the case, could someone walk me through on how exactly to write to that directory through node...and also, would the file end up getting deleted before I could download it, since the upload and download are part of separate requests? Thanks.

Heroku's "ephemeral filestystem" is due to the containerisation of the app. When your app is built, an LXC container is sent to the runtimes and executed.
That means any file written on the filesystem will not be persisted accross redeploys, app restarts and multiple dynos. Even in the tmp folder.
You shouldn't store those files on disk, but on a dedicated file storage platform such as Amazon S3 or Google Cloud Storage.
See https://devcenter.heroku.com/articles/s3-upload-node

Related

Wordpress - I can reach by url normal php files but no uploaded ones

I'm working on a Wordpress project, and I'm trying to create a product via woocommerce rest API, I made it work in local, but when I upload the files to the server, I just can't reach via URL my file, for example,
If I write:
$.get('http://example.com/wp-includes/option.php')
.done(function() {
alert('Correct');
}).fail(function() {
alert('Nope');
})
An alert with Correct appears, but, if I write:
$.get('http://example.com/wp-includes/createProduct.php')
.done(function() {
alert('Correct');
}).fail(function() {
alert('Nope');
})
An alert with Nope will be shown, so I don't get why it reaches all its 'native' files and not that one I uploaded. Files like .js in the js folder are being read correctly, but this .php just can't be reached. And I need it for an AJAX :c
Hope someone can help me and thanks.
Check your directory/file permissions.
On linux try running ll -h inside the wp-includes directory to compare the user and read/write permissions of the files being created.
For instance, you may be user ubuntu, ec2-user, something like that, but your files are being created and owned by root.
EDIT:
Upload your files through cpanel's file manager.
Whether I upload the file using winscp or cpanel file manager, it doesn't affect the read/write permissions, it's always 0644, which should work. BUT uploading through cpanel's file manager, the ownership for the file is the same where as using winscp to upload the user is different.

Renaming files in a wordpress folder via jquery / jscript

I am trying to run a script that will run every 5 minutes in a shared hostings wordpress folder that will rename the newest CSV file in that folder.
/wp-content/csv/sample.csv
I tried putting a js file in the folder within that folder and run it.
var fs = require('fs');
function runClear()
{
fs.readdir("", (err, files) => {
files.forEach(file => {
console.log(file);
});
})
}
runClear();
setInterval(runClear, 300*1000);
However, it seems like I got client side and server side scripting confused. It seems like I need node.js.
What would be the best approach for this?
Regards,
Yes you are right you are confused in client side and server side script.
Javascript is a client side script which deal with all the user interactions like what will happen user click something or submit a form, hover over some element, scroll the web page etc.
Where as server side script like php deals with data stored on server like mysql records or the physical files.
what you are trying to do is to change the server resource from client side script. and you can not do that directly.
Instead you can call an ajax function which send an HTTP request to some script placed on server. And in that server script write the code to read the existing files in a directory and rename them using file handling operations.

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

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?

save and change the name of the file with chrome.filesystem

Is this possible with chrome.fileSystem to save a file on the client's disk, but by changing the file name. For example, I compress a file and I want that file is stored on the disc with my new name newFile.min.js for example. I can save the file to disk, but not to change its name. And what I would like is that everything is done in a "silent" without a window that asks for the location.
Here is the function I use to save my files:
function saveToEntry(entry, result) {
setTitle();
var blob = new Blob([result], {type: 'text/plain'});
currentEntry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.write(blob);
}
writer.truncate(blob.size);
});
}
function setTitle() {
chrome.fileSystem.getDisplayPath(
currentEntry,
function(path) {
console.log(path);
document.title = path;
});
}
Is this possible? And if so, if you have any example to guide me would be great. If not, would be great too :)
Thank you in advance for your advice!
For that (saving in a separate file), I'm afraid that you need to ask the user for write access for a folder, not an individual file. Then you will be able to create a new file in it.
I suggest that you either ask the user to select a "working" directory, present an in-app file picker from that folder, and save the result next to the normal file.
Alternatively, ask the user to select an "output" folder, and dump the results there.
Another solution would be to require a Native Host module. You'll be able to access the system with the same rights as the user. It will limit your deployment options though: you'll need a separate installer for your module that can't be hosted on Chrome Web Store.

Wicket and AJAX : Upload file to server and show it on page

My web application is running on tomcat6 and I'm using Wicket to develop it.
What I'm trying to do is to upload image file to the server and display it on web page as soon as it will be uploaded. I'm uploading file via AJAX as described here. The file is uploaded it is stored on disk in /home/mysuser/ path. When the file is uploaded, I'm executing JavaScript in order to load that file in to HTML object with:
Wicket code:
protected void onSubmit(AjaxRequestTarget target, Form<?> form)
{
target.appendJavaScript("loadOriginalImage(\""+
(UPLOAD_FOLDER + TMP_FILE_NAME1)+"\")");
}
JavaScript code:
function loadOriginalImage(image_path){
var curImg = new Image();
curImg.src = "file://"+image_path;
curImg.onload = function(){
imgHolder.appendChild(this);
}
}
The file is uploaded well, but when the JavaScript is executed, the next error appears:
Not allowed to load local resource
Then I've tried to remove "file://" from JavaScript code, as I've found that file is read from client's local folder and not from server's. But this time I've got next error:
GET http://localhost:8080/home/myuser/originalImg.jpg 404 (Not Found)
So I have two questions:
1. How I specify in JavaScript the correct path of uploaded file?
2. Is my strategy is correct to load image to web page after uploading it to server?
There are several things to consider with your approach:
escaping file names
the webserver (tomcat/wicket in this case) most likely can not serve files from some arbitrary directory
You should implement a Resource that streams the images back and mount this Resource as Alexey has pointed out.
make sure, that you only serve image files, Make sure that you disable directory traversal, otherwise someone will figure out how to read any file from the file system.
You should mount Resource to "home/myuser/${name}", read this acticle for details.
You can adjust caching with the following code (no caching in the example):
#Override
protected void setResponseHeaders(ResourceResponse data, Attributes attributes) {
data.setCacheDuration(Duration.NONE);
super.setResponseHeaders(data, attributes);
}
To allow certain extensions check these resources:
SecurePackageResourceGuard JavaDoc.
An example of usage.

Categories