Dapplo.Confluence
Dapplo.Confluence copied to clipboard
Getting attachments and uploading them to a different page
We have a use case where we want to download content from a variety of spaces and re-upload them as copied pages to a centralized space. The one issue I'm having thus far is copying attachments.
var sourceAttachments = _client.Attachment.GetAttachmentsAsync(sourcePage.Id).Result; foreach (var attachment in sourceAttachments) { _client.Attachment.AttachAsync(targetPage.Id, attachment, attachment.Title, contentType:attachment.Metadata.MediaType); }
When I've uploaded attachments fresh, I've been able to create a bitmap and then upload that as a stream. However, I'm not seeing where the stream is for the attachments I'm getting from the source space.
I may be able to work around this by Downloading and then reuploading the attachment, but naively I'd expect GetAttachmentsAsync and AttachAsync to be able to work in tandem without recreating the file data wholecloth.
I have been able to work around this for now by specifying a new WebClient with appropriate authorization headers and downloading the file directly into a byte array. For example:
foreach (var attachment in sourceAttachments)
{
var targetAttachment = targetAttachments.FirstOrDefault(a => a.Title == attachment.Title);
try
{
var downloadLink = _confluenceUrl.TrimEnd('/') + attachment.Links.Download;
var webClient = new WebClient();
webClient.Headers.Add(HttpRequestHeader.Authorization, "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_alias}:{_password}")).ToString());
webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
var downloadData = webClient.DownloadData(downloadLink);
if (targetAttachment != null)
{
var attachResult = _client.Attachment.UpdateDataAsync(targetPage.Id, targetAttachment.Id, downloadData, attachment.Title, contentType: attachment.Metadata.MediaType);
}
else
{
var attachResult = _client.Attachment.AttachAsync(targetPage.Id, downloadData, attachment.Title, contentType: attachment.Metadata.MediaType).Result;
}
webClient.Dispose();
}
catch
{
// As you please
}
}
I hope I understand it correctly, you would like to download an attachment and use that again to upload it to a different page. Hmm, yes I see what you mean with going hand in hand, it just isn't a use-case I though of.
As a workaround you can use a memory stream to download the attachment.
foreach (var attachment in sourceAttachments)
{
var attachmentStream = await _client.Attachment.GetContentAsync<MemoryStream>(attachment);
// not 100% sure you need this, but reset the stream to the begining.
attachmentMemoryStream.Seek(0, SeekOrigin.Begin);
await _client.Attachment.AttachAsync(targetPage.Id, memoryStream, attachment.Title, contentType: attachment.Metadata.MediaType);
}
Is that need still valid, if I provide the copy page function which should even be able to copy attachments?
P.S. I see that you are not using async code to use my API, using ".Result" is not the best practice. Is there a reason not to use async/await? I can really recommend to do so.
I don't think I'll need this functionality if I can use the native copy functionality the API provides, at least for this program.
Re: async usage, it's just not a requirement for my project, and I find synchronous code more straightforward.
On Tue, Dec 21, 2021, 07:50 Robin Krom @.***> wrote:
I hope I understand it correctly, you would like to download an attachment and use that again to upload it to a different page. Hmm, yes I see what you mean with going hand in hand, it just isn't a use-case I though of.
As a workaround you can use a memory stream to download the attachment.
foreach (var attachment in sourceAttachments) { var attachmentStream = await _client.Attachment.GetContentAsync<MemoryStream>(attachment); // not 100% sure you need this, but reset the stream to the begining. attachmentMemoryStream.Seek(0, SeekOrigin.Begin); await _client.Attachment.AttachAsync(targetPage.Id, memoryStream, attachment.Title, contentType: attachment.Metadata.MediaType); }
Is that need still valid, if I provide the copy page function which should even be able to copy attachments?
P.S. I see that you are not using async code to use my API, using ".Result" is not the best practice. Is there a reason not to use async/await? I can really recommend to do so.
— Reply to this email directly, view it on GitHub https://github.com/dapplo/Dapplo.Confluence/issues/56#issuecomment-998890837, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZOFGBJU5GD4JAPJ7SZVSTUSCO3RANCNFSM5KO6PZUQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you authored the thread.Message ID: @.***>