I am doing the following:
var content = "XYZ - stuff to write to file";
Windows.Storage.DownloadsFolder.createFileAsync("myfile.txt").done(
function (newFile) {
if (newFile) {
// Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync.
Windows.Storage.CachedFileManager.deferUpdates(newFile);
// write to file
Windows.Storage.FileIO.writeTextAsync(newFile, content).done(function () {
// Let Windows know that we're finished changing the file so the other app can update the remote version of the file.
// Completing updates may require Windows to ask for user input.
Windows.Storage.CachedFileManager.completeUpdatesAsync(newFile).done(function (updateStatus) {
if (updateStatus === Windows.Storage.Provider.FileUpdateStatus.complete) {
//WinJS.log && WinJS.log("File " + newFile.name + " was saved.", "sample", "status");
} else {
//WinJS.log && WinJS.log("File " + newFile.name + " couldn't be saved.", "sample", "status");
}
});
});
} else {
// Could not access the new file
}
}
);
However, if the file already exists it crashes saying the file already exists.
How do I check to see if the file already exists and only do the create if it is not there?
Basically I know I want to write to (not append) to myfile.txt. So I need to get newFile whether it is already existing or not so I can use writeTextAsync on it.
How do I check to see if the file already exists and only do the create if it is not there?
If there is an existing file in the current folder that already has the specified desiredName, the specified CreationCollisionOption determines how Windows responds to the conflict. The enum value can be FailIfExists, GenerateUniqueName, OpenIfExists or ReplaceExisting.
Since you are accessing the DownloadsFolder, apps can't access files in the Downloads folder that they didn't create. More details about file access permission please reference this article. So you can only set the CreationCollisionOption to FailIfExists or GenerateUniqueName.
According to your description, you need a new file to write text, so you can set the option to GenerateUniqueName which will generate a new file with unique name, for example, "myfile(2).txt". Code as follows:
Windows.Storage.DownloadsFolder.createFileAsync("myfile.txt", Windows.Storage.CreationCollisionOption.generateUniqueName).done(
function (newFile) {... });
More details please reference the scenario 1 of the file access official sample.
If you just want to use the desired file name , not to generate a new one, you may add the file to the FutureAccessList and then access it later. Pay attention that the existing file must be created by same user so that you can delete and re-create a new one later. The sample code about this you can reference the scenario 7 of the official sample.
Related
I'm a new developer and this is my first Stack Overflow post. I've tried to stick to the format as best as possible. It's a difficult issue for me to explain, so please let me know if there's any problems with this post!
Problem
I'm working on a vscode extension specifically built for Next.js applications and running into issues on an event listener for the onDidChangeText() method. I'm looking to capture data from a JSON file that will always be located in the root of the project (this is automatically generated/updated on each refresh of the test node server for the Next.js app).
Expected Results
The extension is able to look for updates on the file using onDidChangeText(). However, the issue I'm facing is on the initial run of the application. In order for the extension to start listening for changes to the JSON file, the user has to be in the JSON file. It's supposed to work no matter what file the user has opened in vscode. After the user visits the JSON file while the extension is on, it begins to work from every file in the Next.js project folder.
Reproducing this issue is difficult because it requires an extension, npm package, and a next.js demo app, but the general steps are below. If needed, I can provide code for the rest.
1. Start debug session
2. Open Next.js application
3. Run application in node dev
4. Do not open the root JSON file
What I've Tried
Console logs show we are not entering the onDidTextDocumentChange() block until the user opens the root JSON file.
File path to the root folder is correctly generated at all times, and prior to the promise being reached.
Is this potentially an async issue? Or is the method somehow dependent on the Active Window of the user to start looking for changes to that document?
Since the file is both created and updated automatically, we've tested for both, and neither are working until the user opens the root JSON file in their vscode.
Relevant code snippet (this will not work alone but I can provide the rest of the code if necessary. ).
export async function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "Next Step" is now active!');
setupExtension();
const output = vscode.window.createOutputChannel('METRICS');
// this is getting the application's root folder filepath string from its uri
if (!vscode.workspace.workspaceFolders) {
return;
}
const rootFolderPath = vscode.workspace.workspaceFolders[0].uri.path;
// const vscode.workspace.workspaceFolders: readonly vscode.WorkspaceFolder[] | undefined;
// this gives us the fileName - we join the root folder URI with the file we are looking for, which is metrics.json
const fileName = path.join(rootFolderPath, '/metrics.json');
const generateMetrics = vscode.commands.registerCommand(
'extension.generateMetrics',
async () => {
console.log('Succesfully entered registerCommand');
toggle = true;
vscode.workspace.onDidChangeTextDocument(async (e) => {
if (toggle) {
console.log('Succesfully entered onDidChangeTextDocument');
if (e.document.uri.path === fileName) {
// name the command to be called on any file in the application
// this parses our fileName to an URI - we need to do this for when we run openTextDocument below
const fileUri = vscode.Uri.parse(fileName);
// open the file at the Uri path and get the text
const metricData = await vscode.workspace
.openTextDocument(fileUri)
.then((document) => {
return document.getText();
});
}
}
});
});
}
Solved this by adding an "openTextDocument" call inside the "registerCommand" block outside of the "onDidChangeTextDocument" function. This made the extension aware of the 'metrics.json' file without it being open in the user's IDE.
I'm trying to use Cloud Code to check whether a user-submitted image is in a supported file type and not too big.
I know I need to do this verification server-side and I think I should do it with Cloud Code using beforeSave – the doc even has a specific example about data validation, but it doesn't explain how to handle files and I couldn't figure it out.
I've tried the documented method for saving files, ie.
file = fileUploadControl.files[0];
var parseFile = new Parse.File(name, file);
currentUser.set("picture", parseFile);
currentUser.save();
and in the Cloud Code,
Parse.Cloud.beforeSave(Parse.User, (request, response) => { // code here });
But 1. this still actually saves the file on my server, right? I want to check the file size first to avoid saving too many big files...
And 2. Even then, I don't know what to do in the beforeSave callback. It seems I can only access the URL of the saved image (proof that it has been uploaded), and it seems very counter-intuitive to have to do another https request to check the file size and type before deciding whether to proceed with attaching the file to the User object.
(I'm currently using remote-file-size and file-type to check the size and type of the uploaded file, but no success here either).
I also tried calling a Cloud function, but it feels like I'm not doing the right thing, and besides I'm running into the same issues.
I can call a Cloud function and pass a saved ParseFile as a parameter, and then I know how to save it to the User object from the Cloud Code using the masterkey, but as above it still involves uploading the file to the server and then re-fetching it using its URL.
Am I missing anything here?
Is there no way to do something like a beforeSave on Parse.File, and then stop the file from being saved if it doesn't meet certain criteria?
Cheers.
If you have to do something with files, parse lets you overwrite the file adapter to handle file operations.
You can indicate the file adapter to use in your ParseServer instatiation:
var FSStoreAdapter = require('./file_adapter');
var api = new ParseServer({
databaseURI: databaseUri ,
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID,
filesAdapter: fs_store_adapter, // YOUR FILE ADAPTER
masterKey: process.env.MASTER_KEY, //Add your master key here. Keep it secret!
serverURL: "https://yourUrl", // Don't forget to change to https if needed
publicServerURL: "https://yourUrl",
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
}
maxUploadSize: "500mb" //you will now have 500mb limit :)
});
That said, you can also specify a maxUploadSize in your instatiation as you can see in the last line.
you have to use save in background
file = ParseFile("filename", file)
file?.saveInBackground({ e ->
if (e == null) {
} else {
Toast.makeText(applicationContext, "Error: $e", Toast.LENGTH_SHORT).show()
e.printStackTrace()
Log.d("DEBUG", "file " + e.code)
}
}, { percentDone ->
Log.d("DEBUG", "file:" + percentDone!!)
})
I want to create a website which monitors a text file on the same domain, and updates a paragraph automatically when the text file changes. Any good ideas on what i can possibly use?
I feel like having a JavaScript file running a loop which monitors the file is not good practice, so any other suggestions would be great!
If you're doing it on the client, you can't automatically access the users file system. You need to open the file using dialog, select the file.
Once you have the file you can use the lastModified property of the file to check when it was modified. If you store the reference to that file you can then create an interval which will check every x if the file changed.
One global variable to keep track of most recent file modification date (so later we can compare if it's different)
var lastModificationDate = undefined;
Then when file is selected, you want to get the file and set the lastModificationDate property and start the interval.
file = input.files[0];
lastModificationDate = file.lastModified;
setInterval(checkFile, 500);
Your checkFile function would look like:
var file = input.files && input.files[0];
if (file && lastModificationDate && file.lastModified.getTime() != lastMod.getTime()) {
lastModificationDate = file.lastModified;
// Do something else, file was modified
}
The above functionality is achieved using HTML5 File API, you can read more about it here.
For a Node.js solution:
Use the fs.watchFile functionality built into the core of Nodes File System module.
fs.watchFile('message.text', (curr, prev) => {
console.log(`the current mtime is: ${curr.mtime}`);
console.log(`the previous mtime was: ${prev.mtime}`);
});
mtime is the modification time in the snippet above. This function would automatically fire on file change once implemented, unlike the solution above for client side.
You can read more about fs.watchFile here.
I was trying to implement a javascript into a pdf button.Once you click it, it will allow you to .
I know there are security issues which does not allow you to use this function in pdf. And it requires you to put a SaveAs Javascript to make it trusted Functions in the computer. So i have put following code as a trusted function in my computer.
var mySaveAs = app.trustedFunction(
function(oDoc,cPath,cFlName)
{
// Ensure path has trailing "/"
cPath = cPath.replace(/([^/])$/, "$1/");
try{
oDoc.saveAs(cPath + cFlName);
}catch(e){
app.alert("Error During Save");
}
}
);
And i have these codes in my pdf file's button which allows me to saveas another pdf file which name is "123.pdf".
var doc = app.activeDocs;
var aMyPath = this.path.split("/");
aMyPath.pop();
var pathname = aMyPath.join("/")
if(typeof(mySaveAs) == "function"){
mySaveAs(doc,pathname,"345.pdf")
}else{
app.alert("Missing Save Fucntion" + "Please contact forms administrator");
}
i don't know why, but it still gives me an error message saying "Error During Save". Does anyone know the reason? Or there's a easier way to use the SaveAs function using JavaScript in Acrobat. Thanks in advance.
app.activeDocs is an array of Doc objects. Therefore the variable doc (which has not the smartest name, BTW) is an array.
However the save function requires one Doc object to work.
Try whether replacing
mySaveAs(doc,pathname,"345.pdf")
with
mySaveAs(this,pathname,"345.pdf")
would work.
I've an old code for similar thing, and that used the below code for saving the current file in new folder. I had used this in Adobe 6. Check if this works for you.
this.saveAs(destfolder+filename);
Summary
I am attempting to find out why the wl.download function will not download more than one file even though the Microsoft examples seem to indicate that they can.
And, the code seems to be called for each file you attempt to download, but only the one file is actually downloaded.
Details
Here are the details of how you can see this problem which I've tried in IE 11.x and Chrome 30.x
If you will kindly go to :
http://isdk.dev.live.com/dev/isdk/ISDK.aspx?category=scenarioGroup_skyDrive&index=0
You will be able to run an example app which allows you to download files from your skydrive.
Note: the app does require you to allow the app to access your skydrive.
Once you get there you'll see code that looks like this on the right side of the page:
Alter One Value: select:
You need to alter one value: Change the
select: 'single'
to
select: 'multi'
which will allow you to select numerous files to download to your computer. If you do not make that one change then you won't be able to choose more than one file in the File dialog.
Click the Run Button to Start
Next, you'll see a [Run] button to start the app (above the code sample).
Go ahead and click that button.
Pick Files For Download
After that just traverse through your skydrive files and choose more than one in a folder and click the [Open] button. At that point, you will see one of the files actually downloads, and a number of file names are displayed in the bottom (output) section of the example web page.
My Questions
Why is it that the others do not download, even though wl.download is called in the loop, just as the console.log is called in the loop?
Is this a known limitation of the browser?
Is this a known bug in skydrive API?
Is this just a bug in the example code?
The problem here is that the call to wl.download({ "path": file.id + "/content" }) stores some internal state (among other things, the file being downloaded and the current status thereof). By looping over the list of files, that state is in fact overwritten with each call. When I tried downloading three text files at once, it was always the last one that was actually downloaded and never the first two.
The difficulty here is that the downloads are executed in the traditional fashion, whereby the server adds Content-Disposition: attachment to the response headers to force the browser to download the file. Because of this, it is not possible to receive notification of any kind when the download has actually completed, meaning that you can't perform the downloads serially to get around the state problem.
One approach that I thought might work is inspired by this question. According to the documentation, we can get a download link to a file if we append /content?suppress_redirects=true to its id. Using this approach, we can set the src property of an IFrame and download the file that way. This works OK, but it will only force a download for file types that the browser can't natively display (zip files, Exe files, etc.) due to the lack of the Content-Disposition: attachment response header.
The following is what I used in the Interactive Live SDK.
WL.init({ client_id: clientId, redirect_uri: redirectUri });
WL.login({ "scope": "wl.skydrive wl.signin" }).then(
function(response) {
openFromSkyDrive();
},
function(response) {
log("Failed to authenticate.");
}
);
function openFromSkyDrive() {
WL.fileDialog({
mode: 'open',
select: 'multi'
}).then(
function(response) {
log("The following file is being downloaded:");
log("");
var files = response.data.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
log(file.name);
WL.api({
path: file.id + "/content?suppress_redirects=true",
method: "GET"
}).then(
function (response) {
var iframe = document.createElement("iframe");
iframe.src = response.location;
iframe.style.display = "none";
document.body.appendChild(iframe);
},
function (responseFailed) {
log("Error calling API: " + responseFailed.error.message);
}
);
}
},
function(errorResponse) {
log("WL.fileDialog errorResponse = " + JSON.stringify(errorResponse));
}
);
}
function log(message) {
var child = document.createTextNode(message);
var parent = document.getElementById('JsOutputDiv') || document.body;
parent.appendChild(child);
parent.appendChild(document.createElement("br"));
}
Did you try to bind some events to the WL.download() method? According to the documentation:
The WL.download method accepts only one parameter:
The required path parameter specifies the unique SkyDrive file ID of the file to download.
If the WL.download method call is unsuccessful, you can use its then method's onError parameter to report the error. In this case, the WL.download doesn't support the onSuccess and onProgress parameters. If the WL.download method call is successful, the user experience for actually downloading the files will differ based on the type of web browser in use.
Perhaps you are getting some errors in your log to identify the problem.
For me, one suggestion without having checked the documentation, I can think of the fact that you are not waiting for each download to end. Why not change your loop in such a manner that you call WL.download() only if you know no other download is currently running ( like calling the next WL.download only in the success/complete event ):
WL.download({ "path": file.id + "/content" }).then(
function (response) {
window.console && console.log("File downloaded.");
//call the next WL.download() here <!-----------------
},
function (responseFailed) {
window.console && console.log( "Error downloading file: " + responseFailed.error.message);
}
);