Unable to update a file - javascript

I have a file which I am updating using fs and then creating zip in other location. When I check, file update is working fine, but in zip updated contents are not there. Can you tell me what I am doing wrong here. Here is my code.
const content = "new content";
const outputFile = `${unzipDir}/output.docx`
const zip = new AdmZip(outputFile);
fs.writeFileSync(`${unzipDir}/word/document.xml`,content); //content updated successfully in this path.
zip.addLocalFolder(`${unzipDir}/_rels/`);
zip.addLocalFolder(`${unzipDir}/customXml/`);
zip.addLocalFolder(`${unzipDir}/docProps/`);
zip.addLocalFolder(`${unzipDir}/word/`);
zip.addLocalFile(`${unzipDir}/[Content_Types].xml`);
zip.writeZip(outputFile);//old content is showing when extracting zip

Finally I got the solution. When we try to add local folders like I have done in above code, it not add folders and instead add all files containing those folders to root. So in that case file from original location was not replaced and I got old contents. So instead of adding all folders one-by-one, I have added entire folder structure at once and it works for me.
//zip.addLocalFolder(`${unzipDir}/_rels/`);
//zip.addLocalFolder(`${unzipDir}/customXml/`);
//zip.addLocalFolder(`${unzipDir}/docProps/`);
//zip.addLocalFolder(`${unzipDir}/word/`);
//commented above lines and added below line
zip.addLocalFolder(`${unzipDir}/`);
Hope this will help others also.

Related

How to update a PSD file linked layer with opened image

I am a bit stuck. I have created a script for Photoshop that opens a PSD file containing a few layers plus a linked one, sort of a template.
So far, I got things working for me by creating a droplet that runs the following steps and scripts:
Opening the file/image that is dropped.
Opening the PSD file (opening template, scripted).
Updating all smart objects (including the linked layer, but limited by a specific name and location)(not scripted, recorded action).
Applying the template features to this linked layer which has been updated previously (scripted).
Saves a PNG file (scripted),
And finally, closing up opened image and template documents (recorded action).
All is good so far. But this has a limitation. It will only work on one file at a time, with a specific name, at a specific location. So, for example, for the update linked layer to work, the name of the image must be 1.png inside Downloads folder only, in this case.
So my question is: How can I script this to run an iteration of the update on the linked layer using as source(s) the images dropped onto the droplet, regardless of file types (png, jpg, etc.), name, location, and index the output saved PNG file(s)? (1.png, 2.png, 3.png, and so on.)
I started working on my approach, and the steps previously mentioned:
1 - Opening the file/image that is dropped onto the Photoshop droplet.
This would happen automatically with the file—Photoshop will open the file dropped onto the droplet, thus triggering the specific actions sequence set forth. Step one solved. Next!
2 - Opening the PSD file (opening template, scripted)
With this step, I wrote a script that opens the template file. The first step in the action sequence would be this!
var template = new File("/Users/name/Desktop/Folder/Template.psd"); // Of course, you can have your template file anywhere on your computer as long as the path to find it is correct. I have selected my desktop for testing purposes.
app.open(template);
That was another effortless one. Next!
3 - Updating all smart objects (including the linked layer, but limited by a specific name and location)(not scripted, recorded action)
I needed to ensure that the template would easily find its previously linked layer location for the update for this third step to work. I know there are ways to update this with a script, but I didn't want to tinker with that. It was too much of a hassle for me at this stage and with my limited knowledge. Therefore I've decided to accommodate the necessary so the template would find a familiar file name it would look for when the "Update all Modified Content" action is triggered.
At this stage, there are two files opened in Photoshop, one the initial image that serves as a new source for the template, and the second file the template.psd, which contains the linked layer that needs to be updated with the content of the first file.
First, I have saved a copy of the image using the name that the template would look for when searching for the linked layer's name. Next, I have saved a copy of the template using the location of the first image file to keep the initial template safe from all these actions. And third, I triggered the "Update all Modified Content" action. And voila, everything worked. The initial template had the linked file next to it. So the new template copy would search and find the file next to it, in the same place, folder/location, as it happened on the previews step that helped save it as such.
// The following script will retrieve the path of the opened image and will save a copy that matches the name of the linked layer in the template in the same location.
var image_doc = app.documents[0]; //If two or more documents are opened, this approach will help switch between them.
var image_name = image_doc.name;
var image_path = app.documents[0].path.fsName;
var temp_image = new File("" + image_path + "/" + image_name + "");
var opts, file;
opts = new ExportOptionsSaveForWeb();
opts.format = SaveDocumentType.PNG;
var image_temp_name = "link.png";
pngFile = new File("" + image_path + "/" + image_temp_name + "");
image_doc.exportDocument(pngFile, ExportType.SAVEFORWEB, opts);
// Save a copy of the template.psd in the same location as the image and the link.png file needed to update the linked layer.
var temp_template = new File("" + image_path + "/" + image_name + "");
app.open(template);
var opts, file;
opts = new PhotoshopSaveOptions();
opts.format = SaveDocumentType.PHOTOSHOP;
var template_temp_name = "template.psd";
psdFile = new File(image_path + "/" + template_temp_name);
psdSaveOptions = new PhotoshopSaveOptions();
psdSaveOptions.embedColorProfile = true;
psdSaveOptions.alphaChannels = true;
activeDocument.saveAs(psdFile, psdSaveOptions, false, Extension.LOWERCASE);
// After these Update all Modified Content action
Now, four, five, and six are straightforward:
4 - Applying the template features to this linked layer which has just been updated previously (scripted). Done!
5 - Saves the newly formed template as a PNG file (scripted). Done!
6 - And finally, closing up opened image and template documents (recorded action). Done!

Loading JSON file dynamically does not work in JavaFX

I have a JavaFX application that saves data to a local file data.json which, for example, looks like
data = '[{"name":"Jack","pet":"turtle"},{"name":"John","pet":"black mamba"}]'. Periodically the application adds more entries to this file.
In my html file that I am loading to that application I need to show all this info. I have a script tag that loads that file:
<script type="text/javascript" src="../Data/data.json" id="dataSourceScript"></script>
Then in js code I have var mydata = JSON.parse(data) which allows me to load that JSON into mydata variable as described here.
As I need to update the page content when new entries are added, I have a function I call every couple seconds with setInterval() that does that. In order to get the updated file info, I delete that old <script> tag and add a new one (exactly the same), but this means that data now has the updated info:
var oldScript = document.getElementById("dataSourceScript")
if(oldScript)
oldScript.remove()
var newScript = document.createElement("script")
newScript.setAttribute("id", "dataSourceScript")
newScript.setAttribute("src", "../Data/data.json")
document.body.appendChild(newScript)
var mydata = JSON.parse(data)
//then I just add the new entry to DOM, if there is a new entry
It all works great. If I open my html file in browser and then add a new entry to the file, in a few seconds the page gets updated and shows the new entry too. However, for some reason it does not work in my JavaFX application. It loads the file just once from the initial <script> tag, but if I change data.json file, nothing happens. I have to close the application and reopen it in order to get the new info shown on the page.
(I didn't find any other way to read a file that would work. FileReader just stops reading when a file gets updated, which defeats the purpose; fetch() and XMLHttpRequest() both get blocked by CORS policy; I cannot create a server to request files or install Node or anything else, I need pure html+js to be the UI)
Figured it out thanks to the comments, thanks guys.
Yes, the file I loaded from script tag was being cached and not being updated. A solution is very easy, I just needed to create a variable counter and add it as a version to the new script every time I create it, so it's considered a new one
var version = 0
...
var oldScript = document.getElementById("dataSourceScript")
if(oldScript)
oldScript.remove()
var newScript = document.createElement("script")
newScript.setAttribute("id", "dataSourceScript?version=" + version++)
newScript.setAttribute("src", "../Data/data.json")
document.body.appendChild(newScript)
var mydata = JSON.parse(data)
//then I just add the new entry to DOM, if there is a new entry

Cannot write to file in Titanium

I am having trouble writing to a file in Titanium Studio.
specifically .json file. Code is compiled through and no exception was thrown.
Here is my relevant section of code, I parse the file to var first before adding element and stringify it to be written back.
Reading works perfectly, so is adding element, it's the writing process that has issues
var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory,'data.json');
var jsontext = file.read().toString();
var jsondoc = JSON.parse(jsontext);
jsondoc['feedlist'].push({
"picloc":imagename,
"title":titlef.value,
"desc1":descf1.value,
"desc2":descf2.value,
"desc3":descf3.value
});
jsontext = JSON.stringify(jsondoc);
file.write(jsontext); // write(data,[append])
Note: I have consulted Documentation and done some of my own search, some are suggesting that "Filestream" should be used in place of normal file along with .close(), I have yet got them working but it could be pointers the solution, if anyone knows how to get it working
Thanks in advance.
EDIT: This question is flagged for duplication, initially I deemed that was 2 separate issues, one was about merely writing text to a file. Another is parsing event.media (picture) into a file.
I got it working now, The issue was that I was trying to write to file in read-only directory
Ti.Filesystem.resourcesDirectory: A read-only directory where your application resources are located
Ti.Filesystem.applicationDataDirectory: A read/write directory accessible by your app. Place your application-specific files in this directory.
The contents of this directory persist
until you remove the files or until the user uninstalls the application
Here is my code, directory is modified
var sesfile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'data2.json');
var jsontext = sesfile.read().toString();
var jsondoc = JSON.parse(jsontext);
jsondoc['feedlist'].push({
"picloc":imagename,
"title":titlef.value,
"desc1":descf1.value,
"desc2":descf2.value,
"desc3":descf3.value
});
jsontext = JSON.stringify(jsondoc);
sesfile.write(jsontext,false);
If you are unable to locate data directory and simply want to load the file from there.
(In my case it does not exist in project nor will be created with Webpreview compilings)
You can do bootstrap-ish type instruction like this first
var rdfile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory,'data.json');
var sesfile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'data2.json');
var jsontext = rdfile.read().toString();
var jsondoc = JSON.parse(jsontext);
sesfile.write(jsontext);
hope it helps whomever makes amateur mistake like I did.

Inserting new lines to be read in a .txt file

I have the following code for creating a .txt file in javascript:
var text_block = '';
text_block += "Variable 1:"+var1+"\r\n";
text_block += "Variable 2:"+var2+"\r\n";
text_block += "Variable 3:"+var3;
var zip = new JSZip();
zip.file("variables.txt", text_block);
It's going into a zip file because it will ultimately be packaged with other files. When I run this script, it's creating the text file, but there are no new lines/carriage returns when opened in notepad. They do show when opened with wordpad, but I can't assume people are going to use that by default for a .txt file. What can I do to show line breaks in notepad?
Looking at the source of JSZip, in the file jszip.js of the download package on their website, I noticed this line of code (line 661-662):
utf8encode : function (string) {
string = string.replace(/\r\n/g,"\n");
So it seems like that's your problem. Perhaps you could try commenting out line 662, I don't know why it's there, it may well break something else. It seems they copied the code from here, as per the url in the source.

save result to txt file on company shared folder

this is my problem i cant save my results to driver x that is company shared folder and i have permission to write for some reason , but i can save on driver c.
the messege show
Webpage error details
Message: Automation server can't create object Line: 93 Char: 1 Code:
0 URI:
file:///X:/OmrilDocs/Omrix%20Public/All%20Omrix%20Public/Training/index.html
notic : i can use only javascript , no server side language is allowd :(
this is the code i use
alert(answerText);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("X:\OmrilDocs\Omrix Public\All Omrix Public\Training\text.txt", true);
s.WriteLine(answerText);
s.Close();
im using ie8 on xp 2
You need to replace \ with \\.
It should look like:-
var s = fso.CreateTextFile("X:\\OmrilDocs\\Omrix Public\\All Omrix Public\\Training\\text.txt", true);
While it is running, it gives a popup window which you need to allow to create the file.
Screenshot look like:-
Eventhought you've loaded index.html from server, the code is executed in the work station.
You've written the path literally in your function. However, FSO tries to find the target from the work station only, and it is not capable to follow a path associated to some drive letter. (In other work stations that same path might be associated to a different letter.)
So, you need to to use the real name (or IP) of that server:
fso.CreateTextFile("//YOUR_SERVER_NAME/OmrilDocs...
Also the saving folder have to exist. When using true-argument in CreateTextFile only a new file is created to the provided path, new folders are not. Hence if there is a misstypo in the pathname, function will fail.

Categories