I can't upload data from my app to dropbox - dropbox-api

I can't upload data from my app to dropbox. I always gets this error:
'Error in call to API function "files/upload": HTTP header "Dropbox-API-Arg": path: \'\\Songs\\539f67c172ec78e3f7608a64537616a5.mp3\' did not match pattern \'(/(.|[\\r\\n])*)|(ns:[0-9]+(/.*)?)|(id:.*)\'',
I created dropbox app, generated app access token and added token in my env file.
const uploadSong = async (file, song) => {
const destination = path.join(process.env.DROPBOX_UPLOAD_PATH, song.asset_sound.fileNameFull);
console.log('Uploading to DROPBOX ...', destination);
return await dbx.filesUpload({ path: destination, contents: file.buffer, mode: 'overwrite'});
};

The path you're supplying to the path parameter of filesUpload should be the remote Dropbox path where you want to upload the file. It should be formatted like '/path/to/file.ext'.
You're supplying something like '\Songs\539f67c172ec78e3f7608a64537616a5.mp3'. I imagine you mean to supply something like '/Songs/539f67c172ec78e3f7608a64537616a5.mp3' instead.

Related

How to Return File from SvelteKit Endpoint

I am trying to serve a PDF file that my SvelteKit app generates and allow a user to download it from an endpoint.
My project structure looks like this:
---------------------
/src/routes/downloads
---------------------
[file].ts
ABC.pdf
XYZ.pdf
My [file].ts endpoint looks like this:
import fs from 'fs'
// ----- GET -----
export async function get({ params }){
//console.log(params.file) -> ABC
var pdf = fs.readFileSync('./src/routes/downloads/'+params.file+'.pdf')
return{
status:200,
headers: {
"Content-type" : "application/pdf",
"Content-Disposition": "attachment; filename="+params.file+".pdf"
},
body: pdf
}
}
So then when I hit http://localhost:3000/downloads/ABC, the PDF file named ABC.pdf downloads.
But my readFileSync path isn't something that's going to work on production. As far as I know, there is no /src/routes folder.
How do I serve my file from a http://localhost:3000 url? Everything I've tried yields a 404 and it can't find the file. I'm also open to a different way of handling this scenario. This is just my best guess of how to do this in SvelteKit.
The recommended way to do this, for adapter-node, is to place your application data in a new folder under your project's root directory (ie. alongside /src and /static). You can then read files with a relative path: fs.readFile('./my-app-data/foo.txt').
For deployment, you just have to make sure to execute node build from the project root, as this guarantees that you have the same working directory during both development and production.
The static folder works, but it is not meant to carry application data—files in this folder represent new routes that are served directly to users, so this is not desirable if your generated files must be protected in any way. Even if they're meant to be public files, it still blurs what is supposed to be production and source data: should a new deploy overwrite all the files in static? If you're not careful, a naming clash could mean overwriting production data.
You can use import.meta.glob for this.
export async function get({ params }){
const file = `./${params.file}.pdf`;
const pdfs = import.meta.glob(('./*.pdf', { as: 'raw' });
const pdf = pdfs[file];
return {
status:200,
headers: {
"Content-type" : "application/pdf",
"Content-Disposition": "attachment; filename="+params.file+".pdf"
},
body: pdf
}
}
The import.meta.glob in combination with the as: 'raw' option will effectively embed the contents of each file in your resulting code. (this is purely server side so no worries about shipping to much to the client)
Note that this of course means that only files present during build can be served this way.
As #Stephane suggest, put your files under statics folder. This way you can serve directly through a reverse proxy, like Nginx

How to download a pdf file using Flutter?

void getHttp() async
{
print("Got called");
var response = await Dio().download('https://www.google.com/', 'assets/xx.html');
print("DDDDD:");
print(response);
}
The directory assets is present with read and write permissions.
I am calling this on the press of a button. "Got called" DOES get printed.
There are no errors present, still "DDDDD" doesn't get printed.
The xx.html doesn't get saved.
Where am I going wrong?
Based on documentation the syntax for Dio to download a file is
var response = await Dio().download('https://www.google.com/', <<Destination directory from which your app is running. Like internal storage or external storage.>>);
I guess you are providing the file path which is associated with the projects assets directory where the file cannot be downloaded since it is bundled with the app.
Use the following package to access the device file system and provide that path to download your file.
var response = await Dio().download('https://www.google.com/', <<Path from internal storage.>>);

Azure Media Services - Download Transient Error

I have a lot of audios in my database whose URLs are like:
https://mystorage.blob.core.windows.net/mycontainer/uploaded%2F735fe9dc-e568-4920-a3ed-67230ce01991%2F5998d1f8-1795-4776-a19c-f1bc4a0d4786%2F2020-08-13T13%3A09%3A13.0996703Z?sv=2020-02-10&se=2022-01-05T16%3A58%3A50Z&sr=b&sp=r&sig=hQBPyOE92%2F67MqU%2Fe5V2NsqGzgPxogVeXQT%2BOlvbayw%3D
I am using these URLs as my JobInput, and submitting a encoding job, because I want to migrate the audios distribution to a streaming approach.
However, every time I use this kind of URL, it fails with DownloadTransientError, and a message something like while trying to download the input files, the files were not acessible.
If I manually upload a file to the blob storage with a simpler URL (https://mystorage.blob.core.windows.net/mycontainer/my-audio.wav), and use it as the JobInput, it works seamlessly. I suspect it has something to do with the special characters on the bigger URL, but I am not sure. What could be the problem?
Here is the part of the code that submits the job:
var jobInput = new JobInputHttp(new[]
{
audio.AudioUrl.ToString()
});
JobOutput[] jobOutput =
{
new JobOutputAsset(outputAssetName),
};
var job = await client.Jobs.CreateAsync(
resourceGroupName: _azureMediaServicesSettings.ResourceGroup,
accountName: _azureMediaServicesSettings.AccountName,
transformName: TransformName,
jobName: jobName,
new Job
{
Input = jobInput,
Outputs = jobOutput
});
You need to include the file name in the URL you're providing. I'll use your URL as an example, but unescape it as well so that it is more clear. The URL should be something like https://mystorage.blob.core.windows.net/mycontainer/uploaded/735fe9dc-e568-4920-a3ed-67230ce01991/5998d1f8-1795-4776-a19c-f1bc4a0d4786/2020-08-13T13:09:13.0996703Z/my-audio.wav?sv=2020-02-10&se=2022-01-05T16:58:50Z&sr=b&sp=r&sig=hQBPyOE92/67MqU/e5V2NsqGzgPxogVeXQT+Olvbayw=
Just include the actual blob name of the input video or audio file with the associated file extension.

Getting DetailedApiRequestError when uploading a file to google drive with pre-generated file id

I want my users to be able to back-up their data on google drive. I used the "Try it now" tool of google drive to generate a file id, because if I don't set file id before uploading the file, the drive.files.create() method creates a new file id after every upload to google drive.
First I import google drive API.
import 'package:googleapis/drive/v3.dart' as ga;
This is how I create the file I want to upload:
// Create the file we want to upload.
ga.File fileToUpload = ga.File();
var file = await _localFile;
fileToUpload.parents = ["appDataFolder"];
fileToUpload.name = path.basename(file.absolute.path);
// Setting a generated id from the "Try it now" tool.
fileToUpload.id = "1azltlNpZEt6RyUBNwdYUAWPZv2o6w7bP";
And this is how I upload it to google drive:
var response = await drive.files.create(
fileToUpload,
uploadMedia: ga.Media(file.openRead(), file.lengthSync()),
);
The response I get is: "Unhandled Exception: DetailedApiRequestError(status: 403, message: Method not supported for files within the Application Data folder.)"
If I remove the next line when I create the file:
fileToUpload.parents = ["appDataFolder"];
And then I try to upload the file, I get: "DetailedApiRequestError(status: 403, message: The user does not have sufficient permissions for this file.)"
If I don't set the file id, which means I remove the next line:
fileToUpload.id = "1azltlNpZEt6RyUBNwdYUAWPZv2o6w7bP";
Then I can upload the file to google drive. But it's not helping me because it creates a new file id.
Is there anything I can do?
Edit: The problem with google drive generating a new file Id every time the user syncing the app data on google drive, is that it means that after every sync, I need to save the new file id on a server (so I can retrieve the file when needed). And when there are many active users that backing their data multiple times a day, all those update calls to the service would cost me too much money. So I prefer that the file Id will always stay the same.

Filepicker.io Javascript API Remove

Trying to use the remove function after the pick function and file is not being removed. (from here https://www.filepicker.com/documentation/file_ingestion/javascript_api/remove?v=v2)
selectFileMedium: function () {
filepicker.pick({
cropRatio: 24/13,
mimetype: 'image/*',
imageDim: [1440, 780]
}, function (Blob) {
InnerThis.uploadMediumImage(Blob.url, Blob.filename);
filepicker.remove(Blob);
});
}
Am I doing this correct?
Blob object return url property which is unificated url of uploaded file eg:
https://www.filepicker.io/api/file/AQgF2U68SNmJDpDXlOdg
However since v2 dialog version there is crop UI avaliable. If user crop file as a response it return the uploaded file url with appended Rest convert parameters:
https://www.filepicker.io/api/file/AQgF2U68SNmJDpDXlOdg/convert?crop=100,200,200,300
filepicker.remove dose not deal with it. Some temporary workaround would be to strip url from '/convert' part just before remove it. However it should be solved on library side.