Why are files copied from Asar readonly? - javascript

I have an electron app, and when I build it for distribution, the actual app code and build folder are on app.asar file. During the app runtime, I have to copy certain files from the app.asar onto the user's computer, wherever the user chooses, and modify with the code.
The problem is that whenever the file is copied, it becomes readonly, and thus I can not write to it. Any way to handle this?

I'm running into this issue as well, I think the issue is that only some of the fs methods are ported over to work well with asar. According to the docs,
With special patches in Electron, Node APIs like fs.readFile and require treat asar archives as virtual directories, and the files in it as normal files in the filesystem.
Therefore, I think the solution is to manually copy the content of files from asar using fs.readFile and then to dump that into the file you want. I will try this today and hopefully post an update with some code.

Related

Is it possible to zip up and send a local (to the app) directory without requiring the user to select one?

I'm attempting to create an app that can access a directory in the app's directory, zip it with JSZip and send it to an API at the press of a single button.
For instance, say I have a directory "Components" in the app's directory. At the press of one button (Deploy Components) the app should zip up that directory using JSZip and send it off to an API. It seems like React cannot access its own directory short of imports, and imports do not import a directory, only a single file. What I need is the full Components directory, with all files and sub-directories (and their files and sub-directories, and so on), zipped up and punted off.
I know I could have a form and have the user upload a zip file, but this gives the user far too much freedom to upload whatever they like - they should only be able to send this Components directory (which lives with the app and can't be changed without re-deploying the app) to the API.
Does JSZip have any methods that can create a new zipped folder from a provided local directory path? Does React have any functions I can use to load a directory, rather than individual files? Does node.js provide anything I can use (I am not familiar with node.js)? In my API (written in C#) I can use things like the System.IO File and Directory static classes to do things like this, but I am not sure if it is possible with React.
Is this even remotely possible? I've spent the best part of an afternoon trying to find ways of accessing and manipulating a local directory with react and mostly drawn blanks.
Edit: I stuck this on the backburner for a while, but eventually found this answer:
Need to ZIP an entire directory using Node.js and this has solved my issue.

Heroku nodejs pathing issue... Error: ENOENT: no such file or directory

I have a nodejs application using hapi.js and I'm trying to download an image from a url. Heroku is giving me errors with the pathing.
My code:
Request(uri).pipe(fs.createWriteStream(__dirname+'/../public/images/'+filename)).on('close', callback);
My errors:
Error: ENOENT: no such file or directory, open '/app/../public/images/1430540759757341747_4232065786.jpg'
My file structure is simple:
app.js
-public
-images
-sampleimage.jpg
-videos
-samplevideo.mp4
-audio
-sampleaudio.wav
As you can see the __dirname for heroku application is /app. I've tried using __dirname+'all sorts of pathing ../ ./ etc' and I've also tried it without __dirname.
I will be creating a lot of these files using ffmpeg and a speech tool. So could anyone explain to me what kind of problem I am having? Is it something that can be solved by using the correct path name or is it my hapijs server configurations that I need to configure?
You just have the wrong path in your project.
On Heroku, you can't write to the folder BELOW the root of your project.
In your case, your code is running in app.js, which is in the 'root' folder of your project.
So, on Heroku's filesystem, this means your project looks like this:
/app
/app/app.js
/app/public
/app/public/images
...
Heroku puts all your code into a folder called app.
Now, in your code pasted above, you show:
Request(uri).pipe(fs.createWriteStream(__dirname+'/../public/images/'+filename)).on('close', callback);
If this code is running in your app.js, it means that by going BACK a folder (eg: ..), you're trying to write to a non-writable part of Heroku's filesystem.
Instead, you want to write to:
Request(uri).pipe(fs.createWriteStream(__dirname+'/public/images/'+filename)).on('close', callback);
This will correctly write your file into the images folder like you want.
HOWEVER
Here's where things are going to get complicated for a moment.
On Heroku, you can indeed write files to the filesystem, but they will DISAPPEAR after a short period of time.
Heroku's filesystem is EPHEMERAL, this means that you should treat it like it doesn't exist.
The reason Heroku does this is because they try to force you to write scalable software.
If your application writes files to your webserver disk, it won't scale very much. The reason why is that disk space is limited. Each web server has its own disk. This can lead to confusing / odd behavior where each webserver has a copy of the same file(s), etc. It just isn't a good practice.
Instead: what you should do is use a file storage service (usually Amazon S3) to store your files in a central location.
This service lets you store all of your files in a central location. This means:
You can easily access your files from ALL of your web servers.
You can have 'reliable' storage that is managed by a company.
You can scale your web applications better.
The folder you hosted on heroku is considered as "app" which you can see from the error you got. I m commenting this after 5 years just to let future viewers know. If any folder is empty, it is not pushed to github or heroku when you pushed the entire project as the folder is empty.
When we try to access a folder which is empty initially, we get the above error as the folder is not pushed in the first place. So, if you want to get rid of the error, place a temp file of any type ( I used a txt file) and push the code. Now the error won't be there anymore as this time the folder is pushed and it can access it.

Meteor / React.js: save image file to server

I created a project, which is here: https://github.com/dartem/upload_files, and it uploads a file and saves it using FilesCollection. However, it looks like that an actual file is getting saved only temporarily in /cdn/storage and once I restart Meteor or if I open an incognito window an actual file doesn't exist.
I specify the path directory, which is assets/app/uploads/Images, but an image doesn't get saved in that directory. How can I save an actual file in that directory?
I ran your demo up, and it does save files to that directory.
It's not advisable to store files in .meteor/local - basically the files there are temporary - meteor will remove and replace them as it rebuilds the app. This explains why you can't find them again later.
It is also possible to write the files to the public directory, but that will trigger a rebuild of your app every time you save a file, which isn't a good side effect.
I would recommend that you only save the files to gridFS or AWS (or any of the other storage options). You could save them to a folder somewhere else in the file system, as long as you have a way of serving them up (some kind of web server like apache, express or whatever). Your choice based on what sysadmin capability you have.

How to deploy on apache http server once you have your angular2 application bundled with gulp

I've been wasting a lot of time trying to learn how to deploy angular 2. I tried looking around how to do it on tomcat, because that's what I was ordered to do, but turns out tomcat isn't really used for this, is more java and jsp oriented, so I've read is better to use Apache HTTP server instead.
I just installed Apache server, and I just installed npm with gulp ( https://github.com/swirlycheetah/generator-angular2 ), and everything works fine: I can run my app on localhost:3030 with gulp but I now want to test it with Apache,
I've tried several things (since I haven't seen one single place explaining this, maybe it's a very basic thing to do?):
Configure apache .conf file to change the htdocs to a folder I've created. I've tested this works, I see the result on screen when I access localhost.
Compiled everything, got a folder called build with all my files changed to .js extention, so I figured, that must be it. I copied all the files in there, the lib folder created, and index.html and css files. Doesn't work.
Tried several combinations of picking some files that I figured would be necessary and not others. Doesn't work.
Copied the whole project that I've tested with gulp, with eclipse etc that works, including .ts and .d.ts files, which I've read shouldn't be there and are not necessary, and it works.
So I would like to know how is this really done, because I feel like I'm making no improvements. After reading post after post and blog after blog about I simply needed to transpile .ts files to .js, and simply put that javascript files on "some" folder the server uses, it would work. Not only it doesn't but when I use the original .ts files it does.
What might be going on and more important, how is this deployment (I guess it's called something else since I can't find much anything) properly done?
Make sure your .js file paths in your index.html page are correct. When you generate .js files in a folder(like build), your index.html may keep source paths for those .js files are like src="inline.js". So when you access index.html in build folder - localhost/build, it looks for those .js files in localhost only not localhost/build. Try to update source path of those .js files to /build/.
src="/build/inline.js".
you can do that using proxy option in Browser Sync..
proxy option link
I didn't try it but may be it will help you.

How to keep temporary files between multiple runs in nodejs?

I have a small node module which generates files.
As it is really slow and will produce the same result for the same input I would like to keep the last compilation together with a control hash.
The question is now where do I have to place the temporary files so it can be easily accessed?
The cache should also work if the main node application which depends on my module restarts.
I'll collect all my comments into an answer.
As far as I know, there is no NPM standard for where a module would put it's tempfiles. The best place to put them can depend upon how file permissions are configured, what operating system you're running, what permissions the host app is running under, the type of hosting environment, etc...
The logical options are as follows:
In the OS temp directory
In a temp sub-directory below the module directory.
In a configurable directory that the user of the module can specify either via a config argument or via an environment variable.
You can find out where the OS temp directory is with os.tmpdir().
A temp sub-directory below the module. Keep in mind that there can be multiple processes using a module so if you're putting files in a location that may be shared by multiple processes, then you need to be using generated unique names if the files are supposed to be separate per process or appropriate locking if the files are supposed to be shared among processes.
And, don't forget about cleanup maintenance so there's no build-up of temporary files over time.

Categories

Resources