Stream zip file from server to client: No download progress - quarkus

There are quite a few articles about streaming zips from the client. I have read a lot and I will go into some of them.
This is my quarkus endpoint:
#GET
#Consumes( MediaType.APPLICATION_JSON )
#Produces( MediaType.APPLICATION_OCTET_STREAM )
#Path( DOWNLOAD_MUSIC )
public Response downloadMusic( #QueryParam( value = ID ) Long id ) throws IOException, SystemException {
return Response.ok(meisterschaftService.downloadMusicFromChampionship( id ) )
.type( "application/zip" )
.header( "Content-Disposition", "attachment; filename=\"music.zip\"" )
.build();
}
This is my service:
public StreamingOutput downloadMusicFromChampionship( Long meisterschaftId ) throws IOException {
Meisterschaft byChampionshipId = meisterschaftDao.findById( meisterschaftId );
List<MeisterschaftDance> meisterschaftDances = meisterschaftDanceDao.findByMeisterschaft( byChampionshipId.getId() );
Set<Dance> taenze = meisterschaftDances.stream().map( MeisterschaftDance::getDance ).collect( Collectors.toSet() );
StreamingOutput streamingOutput = outputStream -> {
BufferedOutputStream baos = new BufferedOutputStream(outputStream);
ZipOutputStream zos = new ZipOutputStream( baos );
int test = 1;
for (Dance einTanz : taenze) {
ZipEntry entry = new ZipEntry( einTanz.getTitel() + ".mp3" );
entry.setSize( einTanz.getMp3File().length );
zos.putNextEntry( entry );
zos.write( einTanz.getMp3File() );
zos.closeEntry();
test++;
}
zos.close();
zos.close();
outputStream.flush();
outputStream.close();
};
return streamingOutput;
}
From this article I have learned that I have to make an StreamingOutput from my zip-file:
How can i return a zip file from my java server
On the client side I have used this stackoverflow article for my solution:
How to download a readable stream
try {
const res = await fetch('meisterschaft/downloadMusic?id=' +
encodeURIComponent( id ), {
method: 'GET',
headers: {
"Authorization": "Bearer " + keycloak.token
}
} );
const blob = await res.blob();
const newBlob = new Blob([blob]);
const blobUrl = window.URL.createObjectURL(newBlob);
const link = document.createElement('a');
link.href = blobUrl;
link.setAttribute('download', "test.zip");
document.body.appendChild(link);
link.click();
// #ts-ignore
link.parentNode.removeChild(link);
// #ts-ignore
window.URL.revokeObjectURL(blob);
} catch ( e ) {
console.log( "Some error" )
}
The problem now is that I can see in the developer console that the file (approx. 4GB) is being streamed. But the Save-As dialog appears only AFTER the download has finished.
How can I get a download window with a progress bar right from the start? Like that one:
//EDIT
I just don't want to download the 4GB in the background and only display the Save-AS field AFTER the download. I would like to have it like in my picture above: 1MB .... 2MB .... 3MB ... and so on. It is not important how much MB overall we have.

Related

Rgb 565 Pdf to Image

I am trying to convert a PDF page to an image, to create thumbnails. This is the code that I am using:
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
int pageCount = pdfRenderer.PageCount;
for (int i = 0; i < pageCount; i++)
{
Page page = pdfRenderer.OpenPage(i);
Android.Graphics.Bitmap bmp = Android.Graphics.Bitmap.CreateBitmap(page.Width, page.Height, Android.Graphics.Bitmap.Config.Rgb565 or Argb8888);
page.Render(bmp, null, null, PdfRenderMode.ForDisplay);
try
{
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create))
{
bmp.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, output);
}
page.Close();
}
catch (Exception ex)
{
//TODO -- GERER CETTE EXPEXPTION
throw new Exception();
}
}
return directoryPath;
}
I tried with ARGB 8888 and that was a success. But the rendering time was too slow for big PDF files. This is why I tried to improve it by changing the format to RGB 565. But my app is crashing with this Execption:
Unsuported pixel format
Any idea to fix this, or how to render a PDF to a bitmap faster? I was looking on google but didn't find a solution related to my code.
UPDATE
I did this but know, my app is crashing at this line of code :
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
My class :
public async Task<string> GetBitmaps(string filePath)
{
//TODO -- WORK ON THIS
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
var stream = new MemoryStream();
using (Stream resourceStream = new FileStream(filePath, FileMode.Open))
{
resourceStream.CopyTo(stream);
}
for (int i = 0; i < pdfRenderer.PageCount; i++)
{
TallComponents.PDF.Rasterizer.Page page = new TallComponents.PDF.Rasterizer.Page(stream, i);
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create, FileAccess.Write))
{
output.Write(bytes, 0, bytes.Length);
}
}
return directoryPath;
}
you could draw a PDF page in app by converting a PDF page to a bitmap,here the PDF document itself is embedded as a resource.
var assembly = Assembly.GetExecutingAssembly();
var stream = new MemoryStream();
using (Stream resourceStream = assembly.GetManifestResourceStream("DrawPdf.Android.tiger.pdf"))
{
resourceStream.CopyTo(stream);
}
Page page = new Page(stream, 0);
// render PDF Page object to a Bitmap
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
Bitmap bmp = global::Android.Graphics.BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length);

Inserted image not displayed in OpenXml created Word document

I'm trying to insert a signature image in a Word document created by a standard-letter generating application. I am using code adapted from various examples found on the web (see below). The application inserts the image, and the space in the document occupied by it is correct, but the image itself is not displayed.
I have tried it with both .png and .jpg images, but neither work; it doesn't appear to be a problem with the image itself.
I have examined the document using the OpenXml SDK Tool, which shows that the image is correctly embedded and encoded as a Base64 data string.
The problem that the SDK Tool does identify is that, compared to a document in which an image is manually inserted (and is correctly displayed), the pic:pic element in the document is rendered with the wrong namespace (a:pic) and it and all child controls are rendered as OpenXmlUnknownElement (see screenshot below).
Can anyone please tell me what is causing the incorrect namespace / element, and how to fix the problem?
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Drawing;
using System.Drawing.Imaging;
...
using A = DocumentFormat.OpenXml.Drawing;
using A14 = DocumentFormat.OpenXml.Office2010.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
using WP = DocumentFormat.OpenXml.Wordprocessing;
private void ReplacePlaceholderWithImage(MainDocumentPart mainDocumentPart, OpenXmlElement placeholder, string imagePath)
{
if (placeholder != null)
{
ImagePart ip = AddImagePart(mainDocumentPart, imagePath);
string relationshipId = mainDocumentPart.GetIdOfPart(ip);
var drawing = GetDrawing(relationshipId, imagePath);
placeholder.InsertAfterSelf(new WP.Paragraph(new WP.Run(drawing)));
placeholder.Remove();
Console.WriteLine("Picture inserted into picture content control successfully");
}
}
private ImagePart AddImagePart(MainDocumentPart mainDocumentPart, string imagePath)
{
var partType = GetPartTypeForImage(imagePath);
ImagePart ip = mainDocumentPart.AddImagePart(partType);
using (FileStream fileStream = File.Open(imagePath, FileMode.Open))
{
ip.FeedData(fileStream);
}
return ip;
}
private OpenXmlElement GetDrawing(string relationshipId, string imagePath)
{
//calculate dimensions
var size = GetImageDimensions(imagePath);
// Define the reference of the image.
return
new Drawing(
new DW.Inline(
new DW.Extent()
{
Cx = size.Width,
Cy = size.Height
},
new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
new DW.DocProperties() { Id = 1U, Name = "Picture 1" },
new DW.NonVisualGraphicFrameDrawingProperties(new A.GraphicFrameLocks() { NoChangeAspect = true, NoResize = true, NoSelection = true }),
new A.Graphic(new A.GraphicData(new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = 0U,
Name = Path.GetFileName(imagePath)
},
new PIC.NonVisualPictureDrawingProperties()),
new A.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}"
}))
{
Embed = relationshipId,
CompressionState = A.BlipCompressionValues.Print
},
new A.Stretch(new A.FillRectangle())),
new A.ShapeProperties(
new A.Transform2D(new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = size.Width, Cy = size.Width }),
new A.PresetGeometry(new A.AdjustValueList()) { Preset = A.ShapeTypeValues.Rectangle })))
{
Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
}))
{
DistanceFromTop = 0U,
DistanceFromBottom = 0U,
DistanceFromLeft = 0U,
DistanceFromRight = 0U,
EditId = "50D07946"
});
}
private ImagePartType GetPartTypeForImage(string imagePath)
{
var img = GetImage(imagePath);
if (img.RawFormat.Equals(ImageFormat.Gif))
{
return ImagePartType.Gif;
}
else if (img.RawFormat.Equals(ImageFormat.Png))
{
return ImagePartType.Png;
}
else if (img.RawFormat.Equals(ImageFormat.Jpeg))
{
return ImagePartType.Jpeg;
}
else
{
throw new ApplicationException("Unexpected image type");
}
}
this issue stressed me up some hours and finally I found the reason. That's because the Drawing element Id need to be unique, you can't fix the ID like this
new DW.DocProperties() { Id = 1U, Name = "Picture 1" }
In my case, I have this function to set alt text and update the Id as well:
private static HashSet<uint> _drawingElementIds = new HashSet<uint>();
public static void SetPictureAltText(OpenXmlElement imageContainer, string altText)
{
var docPro = imageContainer.Descendants<DocProperties>().FirstOrDefault();
if (docPro != null)
{
//Make sure new image has unique ID, otherwise some images won't display
var newId = (uint)new Random().Next(10, 10000);
while (_drawingElementIds.Contains(newId))
{
newId = (uint)new Random().Next(10, 10000);
}
_drawingElementIds.Add(newId);
docPro.Id = new UInt32Value(newId);
docPro.Description = altText;
}
}
Cheers,
Nick
Watch your namespaces! I'm guessing you've copied from the same source as I did (which I'm sure was the Microsoft documentation), however the namespaces appear to be wrong in it for the following two properties:
A.BlipFill -> PIC.BlipFill
A.ShapeProperties -> PIC.ShapeProperties
Full code below:
var element = new Drawing(
new DW.Inline(
new DW.Extent()
{
Cx = 5657850L,
Cy = 3771900L
},
new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
new DW.DocProperties() { Id = 1U, Name = "Picture 1" },
new DW.NonVisualGraphicFrameDrawingProperties(new A.GraphicFrameLocks() { NoChangeAspect = true, NoResize = true, NoSelection = true }),
new A.Graphic(new A.GraphicData(new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = 0U,
Name = "image.png"
},
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}"
}))
{
Embed = relationshipId,
CompressionState = A.BlipCompressionValues.Print
},
new A.Stretch(new A.FillRectangle())),
new PIC.ShapeProperties(
new A.Transform2D(new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = 5657850L, Cy = 3771900L }),
new A.PresetGeometry(new A.AdjustValueList()) { Preset = A.ShapeTypeValues.Rectangle })))
{
Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
}))
{
DistanceFromTop = 0U,
DistanceFromBottom = 0U,
DistanceFromLeft = 0U,
DistanceFromRight = 0U,
EditId = "50D07946"
});

How do you create a client using websocket-sharp?

I'm using ClientWebSocket to subscribe to a REST service but want to be able to use websocket-sharp instead.
static async void MonitorISY(string IPAddress, string userName, string password, IMessageWriter writer)
{
ClientWebSocket client = new ClientWebSocket();
client.Options.AddSubProtocol("ISYSUB");
client.Options.SetRequestHeader("Origin", "com.universal-devices.websockets.isy");
var auth = Convert.ToBase64String(Encoding.Default.GetBytes(userName + ":" + password));
client.Options.SetRequestHeader("Authorization", "Basic " + auth);
await client.ConnectAsync(new Uri("ws://" + IPAddress + "/rest/subscribe"), CancellationToken.None);
var receiveBufferSize = 512;
byte[] buffer = new byte[receiveBufferSize];
writer.Clear();
while (true)
{
var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var resultJson = (new UTF8Encoding()).GetString(buffer);
writer.WriteLn(resultJson);
writer.WriteLn();
}
}
Here is my websocket-sharp attempt. When ws.Connect(); is called, I'm getting a Not a WebSocket handshake response error message. In the working code, I have to setup the Origin, SubProtocol and the RequestHeader. I think I'm doing that correctly for the websocket-sharp code, with the exception of the Request Header. I've been unable to find a working example that specifies authentication.
using (var nf = new Notifier())
using (var ws = new WebSocket("ws://172.16.0.40/rest/subscribe", "ISYSUB"))
{
ws.Log.Level = LogLevel.Trace;
var username = "user";
var password = "pass";
ws.Origin = "com.universal-devices.websockets.isy";
ws.SetCredentials(username, password, true);
ws.OnOpen += (sender, e) => ws.Send("Hi, there!");
ws.OnMessage += (sender, e) =>
nf.Notify(
new NotificationMessage
{
Summary = "WebSocket Message",
Body = !e.IsPing ? e.Data : "Received a ping.",
Icon = "notification-message-im"
}
);
ws.OnError += (sender, e) =>
nf.Notify(
new NotificationMessage
{
Summary = "WebSocket Error",
Body = e.Message,
Icon = "notification-message-im"
}
);
ws.OnClose += (sender, e) =>
nf.Notify(
new NotificationMessage
{
Summary = String.Format("WebSocket Close ({0})", e.Code),
Body = e.Reason,
Icon = "notification-message-im"
}
);
ws.Connect();
I think the best example is https://github.com/sta/websocket-sharp/tree/master/Example3
Although I did have to make a few tiny adjustments to get it to compile in Visual Studio 2017 Enterprise.
The index.html is based on http://www.websocket.org/echo.html

Upload a file to specific folderid using REST Api

I've searched all documents in google drive api and I can't able to find how to upload a file to folderid using REST APi. Can anyone please help me on this?
public void UploadFiletoDrive()
{
var gmodel = GetAccessToken();
WebRequest request = WebRequest.Create("https://www.googleapis.com/upload/drive/v3/files/?uploadType=media");
request.Method = "POST";
request.Headers["Authorization"] = "Bearer " + gmodel.access_token;
request.ContentType = "image/jpeg";
Stream dataStream = request.GetRequestStream();
FileStream filestream = new FileStream(#"C:\Users\Developer\Downloads\unnamed (2).jpg", FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = filestream.Read(buffer, 0, buffer.Length)) != 0)
{
dataStream.Write(buffer, 0, bytesRead);
}
filestream.Close();
dataStream.Close();
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseFromServer = reader.ReadToEnd();
reader.Close();
response.Close();
}
It seems you've missed the Work with Folders docs.
Inserting a file in a folder using Java:
String folderId = "0BwwA4oUTeiV1TGRPeTVjaWRDY1E";
File fileMetadata = new File();
fileMetadata.setName("photo.jpg");
fileMetadata.setParents(Collections.singletonList(folderId));
java.io.File filePath = new java.io.File("files/photo.jpg");
FileContent mediaContent = new FileContent("image/jpeg", filePath);
File file = driveService.files().create(fileMetadata, mediaContent)
.setFields("id, parents")
.execute();
System.out.println("File ID: " + file.getId());
Implementation for other languages are also included like PHP, Python, NodeJS.
Also, check this SO thread for additional reference.
body.setParents(Arrays.asList(new ParentReference().setId(folderId)));
Your sample code is doing a media upload, ie. no metadata, You should be using a multipart upload so you can specify both metadata such as parent folder id and content.
Uploading a file to google drive using REST API has following steps.
Get parent folderID using list API
Create file with parent="folder ID" using create api and get "fileId" in response
upload file to "fileId
Following is javascript code to upload file using REST API
const url = 'https://www.googleapis.com/upload/drive/v3/files/' + fileId + '?uploadType=media';
if(self.fetch){
// console.log("Fetch found, Using fetch");
var setHeaders = new Headers();
setHeaders.append('Authorization', 'Bearer ' + authToken.access_token);
setHeaders.append('Content-Type', mime);
var setOptions = {
method: 'PATCH',
headers: setHeaders,
body: blob
};
fetch(url,setOptions)
.then(response => { if(response.ok){
// console.log("save to google using fetch");
}
else{
// console.log("Response wast not ok");
}
})
.catch(error => {
// console.log("There is an error " + error.message);
});
}

how to send multiple variables from servlet as response to ajax post?

I am developing a testing system with jsp and java
At client side i have the following code:
var xmlhttp = new getXmlHttpRequestObject(); //xmlhttp holds the ajax object
function servletPost() {
if(xmlhttp) {
//var txtname = document.getElementById("testForm");
var form = $('#testForm');
xmlhttp.open("POST","servlet/TestingController",true);
xmlhttp.onreadystatechange = handleServletPost;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send(form.serialize());
}
}
function handleServletPost() {
//var qComplexity = document.getElementsByName("qComplexity")[0].value;
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
var respText = xmlhttp.responseText;
document.getElementById("fullQuestion").innerHTML = respText;
// here i also should change the content of the answer options
// so i should get from servlet multiple variables
// which allows me to change div contents in my jsp like as respText.question or respText.answer[0]
} else {
alert("Ajax calling error");
}
}
}
At server side: (my Servlet)
public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
.........................................................
.........................................................
PrintWriter out = res.getWriter();
String complex = null;
int categ_id = -1;
String asked_by = null;
String Qtext = null;
int qid = -1;
q_numb = 1;
q_numb++;
String sqlSelect = "SELECT * FROM questions WHERE complexity = '" + complexity
+ "'ORDER BY RANDOM() LIMIT 1;";
ResultSet r = myConnection.runQuery( sqlSelect );
session.setAttribute("member", tempMem);
while (r.next()) {
complex = r.getString(5);
categ_id = r.getInt(4);
asked_by = r.getString(3);
Qtext = r.getString(2);
qid = r.getInt(1);
String sqlA = "select * from answers where question_id = '" + qid
+ "' ORDER by RANDOM();";
ResultSet result = myConnection.runQuery( sqlA );
session.setAttribute("member", tempMem); }
So i need to send values of complex, Qtext, qid, categ_id and so on.
Is there any structures to send like from ajax to servlet, but visa versa?
And how to handle sent data in client side?
Thanks in advance!!!!
Use JSON. There are a myriad of free Java JSON marshallers. And JSON is natively supported by JavaScript.

Resources