feat: embed the vikunja logo as inline attachment

This commit is contained in:
kolaente 2022-06-19 16:21:11 +02:00 committed by Gitea
parent 30e0e98f77
commit f4f8450d16
8 changed files with 22 additions and 7 deletions

2
go.mod
View file

@ -87,4 +87,4 @@ replace (
gopkg.in/fsnotify.v1 => github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 // See https://github.com/fsnotify/fsnotify/issues/328 and https://github.com/golang/go/issues/26904 gopkg.in/fsnotify.v1 => github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 // See https://github.com/fsnotify/fsnotify/issues/328 and https://github.com/golang/go/issues/26904
) )
go 1.15 go 1.16

View file

@ -20,6 +20,7 @@ import (
"code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/version" "code.vikunja.io/api/pkg/version"
"io"
"github.com/wneessen/go-mail" "github.com/wneessen/go-mail"
) )
@ -34,6 +35,7 @@ type Opts struct {
ContentType ContentType ContentType ContentType
Boundary string Boundary string
Headers []*header Headers []*header
Embeds map[string]io.Reader
} }
// ContentType represents mail content types // ContentType represents mail content types
@ -78,10 +80,15 @@ func getMessage(opts *Opts) *mail.Msg {
_ = m.From(opts.From) _ = m.From(opts.From)
_ = m.To(opts.To) _ = m.To(opts.To)
m.Subject(opts.Subject) m.Subject(opts.Subject)
for _, h := range opts.Headers { for _, h := range opts.Headers {
m.SetHeader(h.Field, h.Content) m.SetHeader(h.Field, h.Content)
} }
for name, content := range opts.Embeds {
m.EmbedReader(name, content)
}
switch opts.ContentType { switch opts.ContentType {
case ContentTypePlain: case ContentTypePlain:
m.SetBodyString("text/plain", opts.Message) m.SetBodyString("text/plain", opts.Message)

View file

@ -242,12 +242,12 @@ func convertTrelloDataToVikunja(trelloData []*trello.Board, token string) (fullV
log.Debugf("[Trello Migration] Converted label %s from card %s", label.ID, card.ID) log.Debugf("[Trello Migration] Converted label %s from card %s", label.ID, card.ID)
} }
// Attachments // Embeds
if len(card.Attachments) > 0 { if len(card.Attachments) > 0 {
log.Debugf("[Trello Migration] Downloading %d card attachments from card %s", len(card.Attachments), card.ID) log.Debugf("[Trello Migration] Downloading %d card attachments from card %s", len(card.Attachments), card.ID)
} }
for _, attachment := range card.Attachments { for _, attachment := range card.Attachments {
if attachment.MimeType == "" { // Attachments can also be not downloadable - the mime type is empty in that case. if attachment.MimeType == "" { // Embeds can also be not downloadable - the mime type is empty in that case.
log.Debugf("[Trello Migration] Attachment %s does not have a mime type, not downloading", attachment.ID) log.Debugf("[Trello Migration] Attachment %s does not have a mime type, not downloading", attachment.ID)
continue continue
} }

View file

@ -181,7 +181,7 @@ func convertListForFolder(listID int, list *list, content *wunderlistContents) (
} }
} }
// Attachments // Embeds
for _, f := range content.files { for _, f := range content.files {
if f.TaskID == t.ID { if f.TaskID == t.ID {
// Download the attachment and put it in the file // Download the attachment and put it in the file

BIN
pkg/notifications/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -18,7 +18,9 @@ package notifications
import ( import (
"bytes" "bytes"
_ "embed"
templatehtml "html/template" templatehtml "html/template"
"io"
templatetext "text/template" templatetext "text/template"
"code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/config"
@ -49,7 +51,7 @@ const mailTemplateHTML = `
<div style="width: 100%; font-family: 'Open Sans', sans-serif; text-rendering: optimizeLegibility"> <div style="width: 100%; font-family: 'Open Sans', sans-serif; text-rendering: optimizeLegibility">
<div style="width: 600px; margin: 0 auto; text-align: justify;"> <div style="width: 600px; margin: 0 auto; text-align: justify;">
<h1 style="font-size: 30px; text-align: center;"> <h1 style="font-size: 30px; text-align: center;">
<img src="{{.FrontendURL}}images/logo-full.svg" style="height: 75px;" alt="Vikunja"/> <img src="cid:logo.png" style="height: 75px;" alt="Vikunja"/>
</h1> </h1>
<div style="border: 1px solid #dbdbdb; -webkit-box-shadow: 0.3em 0.3em 0.8em #e6e6e6; box-shadow: 0.3em 0.3em 0.8em #e6e6e6; color: #4a4a4a; padding: 5px 25px; border-radius: 3px; background: #fff;"> <div style="border: 1px solid #dbdbdb; -webkit-box-shadow: 0.3em 0.3em 0.8em #e6e6e6; box-shadow: 0.3em 0.3em 0.8em #e6e6e6; color: #4a4a4a; padding: 5px 25px; border-radius: 3px; background: #fff;">
<p> <p>
@ -84,6 +86,9 @@ const mailTemplateHTML = `
</html> </html>
` `
//go:embed logo.png
var logo []byte
// RenderMail takes a precomposed mail message and renders it into a ready to send mail.Opts object // RenderMail takes a precomposed mail message and renders it into a ready to send mail.Opts object
func RenderMail(m *Mail) (mailOpts *mail.Opts, err error) { func RenderMail(m *Mail) (mailOpts *mail.Opts, err error) {
@ -155,6 +160,9 @@ func RenderMail(m *Mail) (mailOpts *mail.Opts, err error) {
Message: plainContent.String(), Message: plainContent.String(),
HTMLMessage: htmlContent.String(), HTMLMessage: htmlContent.String(),
Boundary: boundary, Boundary: boundary,
Embeds: map[string]io.Reader{
"logo.png": bytes.NewBuffer(logo),
},
} }
return mailOpts, nil return mailOpts, nil

View file

@ -36,7 +36,7 @@ import (
// @Param id path int true "Task ID" // @Param id path int true "Task ID"
// @Param files formData string true "The file, as multipart form file. You can pass multiple." // @Param files formData string true "The file, as multipart form file. You can pass multiple."
// @Security JWTKeyAuth // @Security JWTKeyAuth
// @Success 200 {object} models.Message "Attachments were uploaded successfully." // @Success 200 {object} models.Message "Embeds were uploaded successfully."
// @Failure 403 {object} models.Message "No access to the task." // @Failure 403 {object} models.Message "No access to the task."
// @Failure 404 {object} models.Message "The task does not exist." // @Failure 404 {object} models.Message "The task does not exist."
// @Failure 500 {object} models.Message "Internal error" // @Failure 500 {object} models.Message "Internal error"

View file

@ -4791,7 +4791,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "Attachments were uploaded successfully.", "description": "Embeds were uploaded successfully.",
"schema": { "schema": {
"$ref": "#/definitions/models.Message" "$ref": "#/definitions/models.Message"
} }