how to create .txt in local file system using Firefox extension - firefox-addon

I am currently working on ffsniff extension code. In that I have to save data containing password information into a file in my local system. I have written my code but it is not even creating the file in my local system. (working in mozilla firefox)
Here is my code please help me out.
//// here data variable contains all the information
var fso = new ActiveXObject("Scripting.FileSystemObject");
varFileObject = fso.OpenTextFile("C:\\logs.txt", 2, true,0);
varFileObject.write(data);
varFileObject.close();
after this i tried different code:
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("Desk", Components.interfaces.nsIFile);
file.append("logs.txt");
var ostream = FileUtils.openSafeFileOutputStream(file)
var converter = Components.classes["#mozilla.org/intl/scriptableunicodeconverter"].
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
}
});
but none of them is working..

Here's a working snippet that creates the destination directory if necessary and writes (overwrites) to file (in this case d:\temp-directory\temp-file.txt):
var {Cc,Ci,Cu}=require("chrome"); //for jetpack sdk.
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
var localFile = Cc["#mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
var data="test file content";
//localFile.initWithPath("D:\\temp-directory\\temp-file.txt"); //full path is okay if directory exists
localFile.initWithPath("D:\\temp-directory\\"); //otherwise specifiy directory, create it if necessary, and append leaf.
if(!localFile.exists()){
localFile.create(localFile.DIRECTORY_TYPE,FileUtils.PERMS_DIRECTORY);
}
localFile.append("temp-file.txt");
//localFile.createUnique(localFile.NORMAL_FILE_TYPE,FileUtils.PERMS_FILE); //optional: create a new unique file.
asyncSave(localFile,data,onDone);
function asyncSave(file,data,callbackDone){
// file is nsIFile, data is a string, optional: callbackDone(path,leafName,statusCode)
// default flags: FileUtils.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE);
var ostream = FileUtils.openSafeFileOutputStream(file);
var converter = Cc["#mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
// optional: callbackSaved(status).
NetUtil.asyncCopy(istream, ostream, callbackSaved);
function callbackSaved (status) {
if(callbackDone){
if(status===0)callbackDone( file.path, file.leafName, status); //sucess.
else callbackDone( null, null, status); //failure.
};
}
}
function onDone(path,leafName,statusCode){
console.log([statusCode===0?"OK":"error",path,leafName].join("\n"));
}
More information:
https://developer.mozilla.org/en-US/docs/Code_snippets/File_I_O
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/FileUtils.jsm
https://developer.mozilla.org/en-US/docs/PR_Open
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/NetUtil.jsm
https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIFile
https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsILocalFile

A simple example of how to read/write a file from the filesystem in windows, using Firefox Extension:
// Write File to filesystem
Components.utils.import("resource://gre/modules/osfile.jsm"); // load the OS module
var encoder = new TextEncoder(); // This encoder can be reused for several writes
var array = encoder.encode("just some text"); // Convert the text to an array
var promise = OS.File.writeAtomic("C:\\foo.txt", array,{tmpPath: "foo.txt.tmp"}); // Write the array atomically to "file.txt", using as temporary
alert("URL HOST has been saved");
//Read File from filesystem
var decoder = new TextDecoder(); // This decoder can be reused for several reads
var promise = OS.File.read("C:\\foo.txt"); // Read the complete file as an array
promise = promise.then(
function onSuccess(array) {
alert(decoder.decode(array)); // Convert this array to a text
}
);

This solution is for making file in ubuntu, hope this helps others:
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
file.append("trick_new");
if( !file.exists() || !file.isDirectory() ) { // if it doesn't exist, create
file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
}
this.log_file = file.path + "/newlog.html";

You can also use text-stream to write to a local file.
function writeTextToFile(text, filename) {
var fileIO = require("sdk/io/file");
var TextWriter = fileIO.open(filename, "w");
if (!TextWriter.closed) {
TextWriter.write(text);
TextWriter.close();
}
}

Related

TauriJS writeBinaryFile cannot freeze array buffer views with elements

I work with TauriJS and try to modify a zip file with jszip and later save it with writeBinaryFile.
function saveFile(org_path, new_path, pack_format) {
var zip = new JSZip();
// get file
var org_file = await window.__TAURI__.fs.readBinaryFile(org_path);
await zip.loadAsync(org_file);
// edit file
var pack_json = await zip.file("pack.json").async("string");
pack_json = JSON.parse(pack_json);
pack_json.pack.pack_format = pack_format;
zip.file("pack.json", JSON.stringify(pack_json));
// save file
var array_zip = await zip.generateAsync({type:"uint8array"});
await window.__TAURI__.fs.writeBinaryFile(new_path, array_zip);
}
This is the code I currently have. The problem is that it gives the error Uncaught TypeError: Cannot freeze array buffer views with elements
I wasn't able to find a solution to this error, is it somehow possible to bring the zip file in the right format to save it?
I found a way to fix the problem on this page:
https://qdmana.com/2022/144/202205241127535226.html
This is my adjusted code:
function saveFile(org_path, new_path, pack_format) {
var zip = new JSZip();
// get file
var org_file = await window.__TAURI__.fs.readBinaryFile(org_path);
await zip.loadAsync(org_file);
// edit file
var pack_json = await zip.file("pack.json").async("string");
pack_json = JSON.parse(pack_json);
pack_json.pack.pack_format = pack_format;
zip.file("pack.json", JSON.stringify(pack_json));
// save file
zip.generateAsync({ type: 'blob' }).then((content) => {
var file = new FileReader();
file.readAsArrayBuffer(content);
file.onload = function (e) {
var fileU8A = new Uint8Array(e.target.result);
window.__TAURI__.fs.writeBinaryFile({ contents: fileU8A, path: new_path + ".zip" });
};
});
}

How to add files to a list in vala?

I want to add files to a list and then access them in a for loop. This is how I try to do it:
private get_app_list () {
var file = new File.new_for_path (/usr/share/applications);
List<File> app_list = new List<File> ();
foreach (File desktop_file in app_list) {
// other code here
}
}
What is the right way to access files stored in a directory and then add them to a list??
using Posix;
...
List<File> app_list = new List<File> ();
//Open directory. Returns null on error
var dirHandle = Posix.opendir("/usr/share/applications");
unowned DirEnt entry;
//While there is an entry to read in the directory
while((entry = readdir(dir)) != null) {
//Get the name
var name = (string) entry.d_name;
//And add a new file to the app_list
app_list.add(new File.new_for_path("/usr/share/applications"+name);
}
If you want to merely display the available apps on system, you could use the utilities supplied by the Gio-2.0 lib. After adding dependency ('gio-2.0'), to your meson.build file you could use code similar to the following:
/* We use a `GListStore` here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, `GAppInfo`
* is the object we provide.
*/
var app_list = new GLib.ListStore (typeof (GLib.AppInfo));
var apps = GLib.AppInfo.get_all ();
foreach (var app in apps) {
app_list.append (app);
}
If however you need to list files inside a directory, it's possible also to use the higher level API provided by the same gio-2.0 library. Here is a sample code to enumerate files inside "/usr/share/applications/"
void main () {
var app_dir = GLib.File.new_for_path ("/usr/share/applications");
try {
var cancellable = new Cancellable ();
GLib.FileEnumerator enumerator = app_dir.enumerate_children (
GLib.FileAttribute.STANDARD_DISPLAY_NAME,
GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable
);
FileInfo ? file_info = null;
while (!cancellable.is_cancelled () &&
((file_info = enumerator.next_file (cancellable)) != null)) {
// Ignore directories
if (file_info.get_file_type () == GLib.FileType.DIRECTORY) {
continue;
}
// files could be added to a list_store here.
/*
* var files_list = new GLib.ListStore (typeof (GLib.FileInfo));
* files_list.append (file_info);
*/
print (file_info.get_display_name () + "\n");
}
} catch (GLib.Error err) {
info ("%s\n", err.message);
}
}
I hope this could be of any help.

How to avoid creating duplicate folders in Google Drive

function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv');
for (var i = 0 ; i < sheets.length ; i++) {
var sheet = sheets[i];
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
}
}
This code creates CSV file from a spreadsheet by creating a folder with the spreadsheet's name with 'CSV' added to it. I have been unable to stop it from making a new folder each time, as I want the csv file to be placed in this specific folder each time to update the data. I know I need to see if the folder exists and if not, create it first, otherwise just put the csv file in the existing folder (or the one that was created). It sounds simple, but I have been unable to do it.
You could create a helper function that checks if the folder exists. If it exists the function can return the folder, if it doesn't it can create the folder. In both cases, it will return a folder object.
function yourFunction() {
/*
some code
....
*/
//Get the folder by calling the helper function.
var folder = getFolder("nameOfFolder");
//Create a file in the folder
folder.createFile("fileName", csvFile)
/*
some more code
....
*/
}
//Returns the folder or creates it if it doesn't exist.
function getFolder(folderName) {
var f = DriveApp.getFoldersByName(folderName);
return f.hasNext() ? f.next() : DriveApp.createFolder(folderName);
}
Test out the function below with a try{} catch(e){} to either find or create the folder.
NOTE: this function checks every folder on your drive, so if you have a large number of folders you may need to modify it to only check within a folder.
function testFolder(folderName){
var exist = false;
for(var i in targetFolders){
var parentFolder = DriveApp.getFolderById(targetFolders[i]);
var childFolders = parentFolder.getFolders();
while(childFolders.hasNext()) {
var child = childFolders.next();
Logger.log('listFolders ' + child.getName());
if(child.getName() == folderName){
exist=true;
break;
}
}
}
return exist;
}

Receive, send file over Web Api

I'm trying to write a WebApi service that receives a file, does a trivial manipulation, and sends the file back. I'm having issues on sending and/or receiving the file from the service.
The issue I'm having is that the file returned from the service is ~1.5x larger than the manipulated file, e.g. when the file is returned it's like 300kb instead of the 200kb it should be.
I assume its being wrapped and or manipulated somehow, and I'm unsure of how to receive it properly. The code for the WebAPI service and the method that calls the web service are included below
In, the WebApi service, when I hit the line return Ok(bufferResult), the file is a byte[253312]
In the method that calls the web service, after the file is manipulated and returned, following the line var content = stream.Result;, the stream has a length of 337754 bytes.
Web API service code
public ConversionController: APIController{
public async Task<IHttpActionResult> TransformImage()
{
if (!Request.Content.IsMimeMultipartContent())
throw new Exception();
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var file = provider.Contents.First();
var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
var buffer = await file.ReadAsByteArrayAsync();
var stream = new MemoryStream(buffer);
// [file manipulations omitted;]
// [the result is populated into a MemoryStream named response ]
//debug : save memory stream to disk to make sure tranformation is successfull
/*response.Position = 0;
path = #"C:\temp\file.ext";
using (var fileStream = System.IO.File.Create(path))
{
saveStream.CopyTo(fileStream);
}*/
var bufferResult = response.GetBuffer();
return Ok(bufferResult);
}
}
Method Calling the Service
public async Task<ActionResult> AsyncConvert()
{
var url = "http://localhost:49246/api/conversion/transformImage";
var filepath = "drive/file/path.ext";
HttpContent fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filepath));
using (var client = new HttpClient())
{
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileContent, "file", "fileName");
//call service
var response = client.PostAsync(url, formData).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception();
}
else
{
if (response.Content.GetType() != typeof(System.Net.Http.StreamContent))
throw new Exception();
var stream = response.Content.ReadAsStreamAsync();
var content = stream.Result;
var path = #"drive\completed\name.ext";
using (var fileStream = System.IO.File.Create(path))
{
content.CopyTo(fileStream);
}
}
}
}
return null;
}
I'm still new to streams and WebApi, so I may be missing something quite obvious. Why are the file streams different sizes? (eg. is it wrapped and how do I unwrap and/or receive the stream)
okay, to receive the file correctly, I needed to replace the line
var stream = response.Content.ReadAsStreamAsync();
with
var contents = await response.Content.ReadAsAsync<Byte[]>();
to provide the correct type for the binding
so, the later part of the methods that calls the service looks something like
var content = await response.Content.ReadAsAsync<Byte[]>();
var saveStream = new MemoryStream(content);
saveStream.Position = 0;
//Debug: save converted file to disk
/*
var path = #"drive\completed\name.ext";
using (var fileStream = System.IO.File.Create(path))
{
saveStream.CopyTo(fileStream);
}*/

How to get images from cache using a XPCOM Component in Firefox

I need to get the cache file path for ever image loaded in a document, I am wondering what are the Interfaces I need to use in order to do that
https://developer.mozilla.org/en/XPCOM_Interface_Reference
This is what I used to evict cache entry:
function removeItem(url){
let cacheService = Components.classes["#mozilla.org/network/cache-service;1"]
.getService(Components.interfaces.nsICacheService);
var Ci = Components.interfaces;
var session = cacheService.createSession("image", Ci.nsICache.STORE_ANYWHERE, false);
if(!session){
return;
}
var entry;
try{
entry = session.openCacheEntry(url, Ci.nsICache.ACCESS_READ, false);
if(!entry){
return;
}
}catch(ex){
return;
}
entry.doom();
entry.close();
}
}
Once you have entry you should be able to open a stream to it - possibly getting the content or even replacing it - I haven't tried it though.

Resources