its a bit confusing to upload a photo and access it from appwrite storage, I have created photo buckets in the app and I have copied the code of the preview image from the console and pasted in vscode to run, but as I'm very new to this I couldn't figure out, if I should be using the 'get' method as shown in the console , and the function I should be executing should be buckets.create right? please help me with any link of process or just give me some hints to move further .
Thank you
Using version 8.1.0 of the Appwrite Node SDK on Appwrite version 1.0.x, you would create a file with the Create File API like this:
const { Client, Databases, Storage, InputFile, ID } = require('node-appwrite');
const client = new Client()
.setEndpoint('https://[HOSTNAME or IP]/v1')
.setProject('[PROJECT ID]')
.setKey('[API KEY]');
const storage = new Storage(client);
const file = await storage.createFile(
'[BUCKET ID]',
ID.unique(),
InputFile.fromPath("./resources/nature.jpg", "nature.jpg"),
[
Permission.read(Role.any()),
Permission.update(Role.users()),
Permission.delete(Role.users()),
]
);
To download a file, you would use the Get File for Download API like this:
const buffer = await storage.getFileDownload('[BUCKET ID]', file.$id);
buffer is a Buffer and you can do whatever you need with it like writing it to disk.
Related
I am trying to write a .csv file to save the user's actions and collect it later from the device. I have tried on my computer and it works but I can't seem to get it to work in the Oculus Quest.
My code goes like:
using (var writer = new StreamWriter($"{Application.persistentDataPath}/{_fileName}"))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords(metrics);
}
Try the base path /mnt/sdcard/. So you will get something like:
using (var writer = new StreamWriter($"/mnt/sdcard/{_fileName}"))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords(metrics);
}
To allow your program to use the internal storage you need to properly configure the Build Settings. This can be done by going to File->Build Settings->Player Settings...->Other Settings->Write Permissions and change it to External(SDCard) (I did this in Unity 2018.4.11f1)
Also, beware when running the application on your device, if no pop-up asking for write permission shows up try going to Library to run your application again.
I am working on flutter-web, I would like to do file operations(read and write) in flutter-web.
For Android and IOS, I was using path_provider dependency. But in Flutter-web, it is not supported.
Can anyone help me with this?
The accepted answer is not completely right. Yes, dart:io is not available on the web, but it is still possible to read files. You can select a file through the system's file picker and read it afterward.
An easy option to "write" a file is to send the user an auto-download.
Read:
Use this library to select a file: pub.dev/packages/file_picker (Web migration guide)
import 'dart:html' as webFile;
import 'package:file_picker_web/file_picker_web.dart' as webPicker;
if (kIsWeb) {
final webFile.File file = await webPicker.FilePicker.getFile(
allowedExtensions: ['pd'],
type: FileType.custom,
);
final reader = webFile.FileReader();
reader.readAsText(file);
await reader.onLoad.first;
String data = reader.result;
}
Write (a.k.a download):
import 'dart:html' as webFile;
if (kIsWeb) {
var blob = webFile.Blob(["data"], 'text/plain', 'native');
var anchorElement = webFile.AnchorElement(
href: webFile.Url.createObjectUrlFromBlob(blob).toString(),
)..setAttribute("download", "data.txt")..click();
}
in the dart docs it has been explained ... dart:io is not available to web build ... it means that you can not directly access to system files in flutter web . the build will fail .. you need to remove the code in order to run it
this is a security thing .. js doesn't allow it too .. imagine a website that can read all your system files if you visit it .. that's why things like path reading or file reading is not allowed .. it goes same for flutter
hope you have your answer
I created a package specifically for this before Flutter web was a thing. https://pub.dev/packages/async_resource
It looks at things as either a network resource (usually over HTTP), or a local resource such as a file, local storage, service worker cache, or shared preferences.
It isn't the easiest thing in the world but it works.
What about "dart:indexed_db library", You can store structured data, such as images, arrays, and maps using IndexedDB. "Window.localStorage" can only store strings.
dart:indexed_db
Window.localStorage
When it comes specifically to reading a file from disk on web, the easiest way is to use a PickedFile like so:
PickedFile localFile = PickedFile(filePath);
Uint8List bytes = await localFile.readAsBytes();
I used IonicNative plugin for downloading pdf files.
https://ionicframework.com/docs/native/file-transfer/
I can see download complete using alert,but cannot see any download happening.
private filetransfer: FileTransferObject = this.transfer.create();
const url = 'https://www.example.com/example%20test.pdf';
this.filetransfer.download(url, this.file.dataDirectory + 'example%20test.pdf').then((entry) =>
{
alert('download complete: ' + entry.toURL());
},
(error) => {
alert(error);
});
Is this the correct way to do or am I missing some thing?
This looks like the correct way to do it.
I'm not quit sure what you mean with "you cannot see any download happening", but I'm assuming you can't find the file in the file system (otherwise just let me know).
In this case your saving the file in a private data storage, specified by:
this.file.dataDirectory
If you replace this.file.dataDirectory with this.file.externalDataDirectory, you will find the document in your file system (something like: file:///storage/emulated/0/Android/data/com.project.name).
The ionic native documentation is not that good in this case, see the cordova file plugin documentation instead, where the different possibilitiers are listed:
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/#where-to-store-files.
In my application ,I have stored uploaded images to folder ./assets/uploads. I am using easyimage and imagemagick for storing the images.
In my application, after uploading the images, it should show the new uploaded image. But it is not displayed even if the page is refreshed. But when i do sails lift , the image is shown.
How to show image immediately after uploading the image? Thanks a lot!
It's a totally normal situation, because of the way Sails works with the assets.
The thing is that upon sails lift the assets are being copied (including directory structure and symlinks) from ./assets folder to ./.tmp/public, which becomes publicly accessible.
So, in order to show your images immediately after upload, you, basically, need to upload them not to ./assets/uploads but to ./.tmp/public/uploads.
The only problem now is that the ./.tmp folder is being rewritten each time your application restarts, and storing uploads in ./tmp/... would make them erased after every sails lift. The solution here would be storing uploads in, for example, ./uploads and having a symlink ./assets/uploads pointing to ../uploads.
Though this question is pretty old but I would like to add a solution which I just implemented.
Today I spend almost 4 hours trying all those solutions out there. But none helped. I hope this solution will save someone else's time.
WHY images are not available immediately after uploading to any custom directory?
Because according to the default Sails setup, you can not access assets directly from the assets directory. Instead you have to access the existing assets that is brought to .tmp/public directory by Grunt at time of sails lift ing
THE Problems
(Available but Volatile) If you upload a file (say image) anywhere inside .tmp/public
directory, your file (image) is going to erase at next sails lift
(Unavailability) If you upload a file in any other custom directory- say: ./assets/images, the uploaded file will not be available immediately but at next sails lift it will be available. Which doesn't makes sense because - cant restart server each time files gets uploaded in production.
MY SOLUTION (say I want to upload my images in ./assets/images dir)
Upload the file say image.ext in ./tmp/public/images/image.ext (available and volatile)
On upload completion make a copy of the file image.ext to ./assets/images/*file.ext (future-proof)
CODE
var uploadToDir = '../public/images';
req.file("incoming_file").upload({
saveAs:function(file, cb) {
cb(null,uploadToDir+'/'+file.filename);
}
},function whenDone(err,files){
if (err) return res.serverError(err);
if( files.length > 0 ){
var ImagesDirArr = __dirname.split('/'); // path to this controller
ImagesDirArr.pop();
ImagesDirArr.pop();
var path = ImagesDirArr.join('/'); // path to root of the project
var _src = files[0].fd // path of the uploaded file
// the destination path
var _dest = path+'/assets/images/'+files[0].filename
// not preferred but fastest way of copying file
fs.createReadStream(_src).pipe(fs.createWriteStream(_dest));
return res.json({msg:"File saved", data: files});
}
});
I dont like this solution at all but yet it saved more of my time and it works perfectly in both dev and prod ENV.
Thanks
Sails uses grunt to handle asset syncing. By default, the grunt-watch task ignores empty folders, but as long as there's at least one file in a folder, it will always sync it. So the quickest solution here, if you're intent on using the default static middleware to server your uploaded files, is to just make sure there's always at least one file in your assets/uploads folder when you do sails lift. As long as that's the case, the uploads folder will always be synced to your .tmp/public folder, and anything that's uploaded to it subsequently will be automatically copied over and available immediately.
Of course, this will cause all of your uploaded files to be copied into .tmp/public every time your lift Sails, which you probably don't want. To solve this, you can use the symlink trick #bredikhin posted in his answer.
Try to do this:
npm install grunt-sync --save-dev --save-exact
uncomment the line: // grunt.loadNpmTasks('grunt-sync');
usually it is near to the end of the file /tasks/config/sync.js.
lift the App again
Back to the Original answer
I was using node version 10.15.0, and I faced same problem. I solved this by updating to current version of node(12.4.0) and also updated npm and all the node modules. After this, I fixed the vulnerabilities(just run 'npm audit fix') and the grunt error that was coming while uploading the images to assets/images folder was fixed.
Try out this implementation
create a helper to sync the file
example of the filesync helper
// import in file
const fs = require('fs')
module.exports = {
friendlyName: 'Upload sync',
description: '',
inputs: {
filename:{
type:'string'
}
},
exits: {
success: {
description: 'All done.',
},
},
fn: async function ({
filename
}) {
var uploadLocation = sails.config.custom.profilePicDirectory + filename;
var tempLocation = sails.config.custom.tempProfilePicDirectory + filename;
//Copy the file to the temp folder so that it becomes available immediately
await fs.createReadStream(uploadLocation).pipe(fs.createWriteStream(tempLocation));
// TODO
return;
}
};
now call this helper to sync your files to the .temp folder
const fileName = result[0].fd.split("\\").reverse()[0];
//Sync to the .temp folder
await await sails.helpers.uploadSync(fileName);
reference to save in env
profilePicDirectory:path.join(path.resolve(),"assets/images/uploads/profilePictures/")
tempProfilePicDirectory:path.join(path.resolve(),".tmp/public/images/uploads/profilePictures/"),
also can try
process.cwd()+filepath
Is there a way to access Html5 file api in Fire Fox addon sdk in the content script?
This is needed in order to store user added words and their meanings. The data can grow large and so local storage isn't an option.
window.requestFileSystem3 = window.requestFileSystem || window.webkitRequestFileSystem;
gives me the error TypeError: window.requestFileSystem3 is not a function.
I am asking this because i am porting this code from a Google Chrome Extension which allows accessing the file api in a content script.
Additional Questions
1) If HTML5 File API is not allowed then should i use file module?
2) Does the file module allow access to any file on the file system as opposed to the Html5 file api which only access to a sandboxed access to file system?
3) Assuming i have to use file module what would be the best location to store my files ( like the user profile directory or extension directory ) and how would i get this path in code.
I apologize for so many sub questions inside this questions. Google wasn't very helpful regarding this topic.
Any sample code would be very helpful.
Firefox doesn't support writing files via File API yet and even when this will be added it will probably be accessible to web pages only and not extensions. In other words: yes, if you absolutely need to write to files then you should use low-level APIs. You want to store your data in the user profile directory (there is no extension directory, your extension is usually installed as a single packed file). Something like this should work to write a file:
var file = require("sdk/io/file");
var profilePath = require("sdk/system").pathFor("ProfD");
var filePath = file.join(profilePath, "foo.txt");
var writer = file.open(filePath, "w");
writer.writeAsync("foo!", function(error)
{
if (error)
console.log("Error: " + error);
else
console.log("Success!");
});
For reference: sdk/io/file, sdk/system
You could use TextReader.read() or file.read() to read the file. Unfortunately, Add-on SDK doesn't seem to support asynchronous file reading so the read will block the Firefox UI. The only alternative would be importing NetUtil and FileUtils via chrome authority, something like this:
var {components, Cu} = require("chrome");
var {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", null);
var {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", null);
NetUtil.asyncFetch(new FileUtils.File(filePath), function(stream, result)
{
if (components.isSuccessCode(result))
{
var data = NetUtil.readInputStreamToString(stream, stream.available());
console.log("Success: " + data);
}
else
console.log("Error: " + result);
});