Flutter web download a pdf from API and save in directory - flutter

I build a flutter web app and My requirement is to get a file(PDF) and write it in file or download it,
i get my file from an API and it gave me a file not a link,
Can anyone help me with this. An example would be more helpful.
Thank you

Use this utility method:
import 'dart:html' as html;
void openDownloadLink(String href, String filename) {
html.document.createElement('a') as html.AnchorElement
..href = href
..download = filename
..dispatchEvent(html.Event.eventType('MouseEvent', 'click'));
}
Uri getHref() => Uri.parse(html.window.location.href);
The first parameter is the URL of the file to be downloaded, the second is the 'suggested' filename that the browser will show. Note that you can't put in a full path to the local file - the file name is just a suggestion.
The getHref function may be useful. It returns a Uri representing where the Flutter web app was launched from. If you want a path relative to that for your PDF, modify it, keeping the https://server... part the same. Equally, you could probably use a relative path as the href parameter, like ../pdfs/somefile

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

Play Swagger UI url alias

I have Swagger UI for API documentation, I use the same approach like in official specification for accessing it I use next URL:
http://localhost:9000/docs/swagger-ui/index.html?url=/assets/swagger.json
But I want to use http://localhost:9000/docs/ instead. I won't want to use WS for delegating, I would like to use single line in routes, like this:
GET /docs controllers.Assets.at(path:String="/public/lib/swagger-ui", file:String="index.html?url=/assets/swagger.json")
Or
GET /docs controllers.Assets.at(path:String="/public/lib/swagger-ui", file:String="index.html")
and http://localhost:9000/docs?url=/assets/swagger.json
What shold I change so it work?
You can't make shortness in route file for the URL /docs/swagger-ui/index.html?url=/assets/swagger.json because index.html is generated by swagger-ui plugin to public directory and requires access to files nearby (like js and css files). Play swagger-ui uses javascript for fetching json based description of your routes via URL parameter for further parsing this document to swagger-ui, in your case it's /assets/swagger.json endpoint.
I tried to make the mapping swagger's index.html file, so pass json location like URL parameter directly:
GET /swagger-ui controllers.Assets.at(path = "/public/lib/swagger-ui", file = "index.html")
Play couldn't render this page, and CSS wasn't found. I appended dummy mapping to every file in swagger's default directory /public/lib/swagger-ui:
GET /*file controllers.Assets.at(path = "/public/lib/swagger-ui", file)
Even after that Play couldn't properly render index.html.
How it can be solved without Play-Swagger:
Create directory public\swagger in your project;
Download all files from https://github.com/swagger-api/swagger-ui/tree/master/dist and copy them to public\swagger;
Copy your swagger.json (it's specification, right?) to public\specification;
Add to your routes file next line:
GET /docs
controllers.Assets.versioned(path="/public/specification", file: Asset
= "swagger.json")

Eclipse Plugin Open a PDF file from inside a plugin package

I am trying to open a PDF file that represents the documentation of my plugin from inside a package, since I have opened a properties file the same way using getClass().getResource(URI).
I am trying the same with the PDF file, and I'm trying to get the URL of the file, then passing it to Desktop.browse() converted to URI, but it gives me a Malformed URI exception. Is there a way to do this easier and also to work?
This is my code so far:
try{
URL url = new URL(getClass().getResource("Documentation.pdf"), null);
Desktop.getDesktop().browse(url.toURI());
}catch(Exception exception){
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, exception.getLocalizedMessage(), exception);
ErrorDialog.openError(null, "Error", "Error occured!", status);
}
The URL/URI you get back from getResource uses the bundleresource scheme which is not understood by many things.
For an Eclipse plugin you should use the FileLocator class.
Bundle bundle = FrameworkUtil.getBundle(getClass());
IPath path = new Path("path relative to root of the plugin");
URL url = FileLocator.find(bundle, path, null);
URL fileURL = FileLocator.toFileURL(url);
Desktop.getDesktop().browse(fileURL.toURI());
Again the URL returned by FileLocator.find uses a special scheme and is not understood by many things. FileLocator.toFileURL converts this URL to a normal file scheme - to do this it may be necessary to unpack the file from the plugin jar to a temporary location.
Note: Path is org.eclipse.core.runtime.Path

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.

Fiddler Script - SaveResponseBody()

I want to save all png images that are loaded along with some webpage into a separate folder.
I am using below code with in Fiddler Script [CustomRules.js].
static function OnBeforeResponse(oSession: Session)
{
if(oSession.url.EndsWith(".png"))
{
oSession.SaveResponseBody();
}
//Actual content of OnBeforeResponse function.
}
Problem here is, I was unable to find any image got saved within Program files/Documents.
Where do “SaveResponseBody()” will save the HTTP Response Body?
Can we give our own custom folder?
My Fiddler version is (v4.4.5.6)
The default SaveResponseBody() method saves the files to your \Documents\Fiddler2\Captures\ folder. If you want to use a different name, use the overload that accepts a filename. You should check the Response's status code is 200 to ensure that you're not trying to save off HTTP/304 responses which won't contain a body. Also, rather than looking at the URL, you probably want to check the response's type.
So you end up with something like this:
if ((oSession.responseCode == 200) &&
oSession.oResponse.headers.ExistsAndContains("Content-Type", "image/png"))
{
SaveResponseBody("C:\\temp\\" + oSession.SuggestedFilename);
}
Note: The manual way of doing this would be to go to the QuickExec box below the Web Sessions list, type select png and hit Enter, then click File > Export > Selected Sessions > Raw Files.