refactor, working prototype
This commit is contained in:
parent
9b614b549e
commit
214f9d8599
@ -1,31 +1,27 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"git.dafu.dev/dafu/gomailer/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// inlineCmd represents the send command
|
// inlineCmd represents the send command
|
||||||
var inlineCmd = &cobra.Command{
|
var inlineCmd = &cobra.Command{
|
||||||
Use: "inline",
|
Short: "Inline styles in template file without sending",
|
||||||
Short: "Inline styles in template without sending",
|
Long: `Inlines styles in given template and saves it to *_inlined.html`,
|
||||||
Long: ``,
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Use: "inline [flags] [...template.html]",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Println("send called")
|
log.Printf("Templates: %v", args)
|
||||||
|
|
||||||
|
for _, arg := range args {
|
||||||
|
gomailer.Inline(arg)
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(inlineCmd)
|
rootCmd.AddCommand(inlineCmd)
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
|
||||||
|
|
||||||
// Cobra supports Persistent Flags which will work for this command
|
|
||||||
// and all subcommands, e.g.:
|
|
||||||
// inlineCmd.PersistentFlags().String("foo", "", "A help for foo")
|
|
||||||
|
|
||||||
// Cobra supports local flags which will only run when this command
|
|
||||||
// is called directly, e.g.:
|
|
||||||
// inlineCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
|
||||||
}
|
}
|
||||||
|
71
cmd/root.go
71
cmd/root.go
@ -1,22 +1,28 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"git.dafu.dev/dafu/gomailer/pkg"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cfgFile string
|
var cfgFile string
|
||||||
|
|
||||||
|
var Cfg Config
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
mailserver gomailer.MailServer `mapstructure:"mailserver"`
|
||||||
|
mailsettings gomailer.MailSettings `mapstructure:"mailsettings"`
|
||||||
|
}
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "gomailer",
|
Use: "gomailer",
|
||||||
Short: "use it to test email templates",
|
Short: "use it to test email templates",
|
||||||
Long: ``,
|
Long: ``,
|
||||||
// Uncomment the following line if your bare application
|
|
||||||
// has an action associated with it:
|
|
||||||
// Run: func(cmd *cobra.Command, args []string) { },
|
// Run: func(cmd *cobra.Command, args []string) { },
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,38 +37,61 @@ func Execute() {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
|
rootCmd.CompletionOptions.DisableDefaultCmd = true
|
||||||
// Here you will define your flags and configuration settings.
|
|
||||||
// Cobra supports persistent flags, which, if defined here,
|
|
||||||
// will be global for your application.
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gomailer.yaml)")
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gomailer.yaml)")
|
||||||
|
|
||||||
// Cobra also supports local flags, which will only run
|
// rootCmd.PersistentFlags().StringVarP(&Template, "template", "t", "", "Path to html template")
|
||||||
// when this action is called directly.
|
// viper.BindPFlag("template", rootCmd.PersistentFlags().Lookup("template"))
|
||||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initConfig reads in config file and ENV variables if set.
|
// initConfig reads in config file and ENV variables if set.
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
if cfgFile != "" {
|
if cfgFile != "" {
|
||||||
// Use config file from the flag.
|
|
||||||
viper.SetConfigFile(cfgFile)
|
viper.SetConfigFile(cfgFile)
|
||||||
} else {
|
} else {
|
||||||
// Find home directory.
|
viper.AddConfigPath(".")
|
||||||
home, err := os.UserHomeDir()
|
|
||||||
cobra.CheckErr(err)
|
|
||||||
|
|
||||||
// Search config in home directory with name ".gomailer" (without extension).
|
|
||||||
viper.AddConfigPath(home)
|
|
||||||
viper.SetConfigType("yaml")
|
viper.SetConfigType("yaml")
|
||||||
viper.SetConfigName(".gomailer")
|
viper.SetConfigName("gomailer")
|
||||||
}
|
}
|
||||||
|
|
||||||
viper.AutomaticEnv() // read in environment variables that match
|
viper.AutomaticEnv() // read in environment variables that match
|
||||||
|
|
||||||
// If a config file is found, read it in.
|
// If a config file is found, read it in.
|
||||||
if err := viper.ReadInConfig(); err == nil {
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
|
mserver := &gomailer.MailServer{}
|
||||||
|
msettings := &gomailer.MailSettings{}
|
||||||
|
|
||||||
|
if err := viper.UnmarshalKey("mailserver", mserver); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := viper.UnmarshalKey("mailsettings", msettings); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Cfg.mailserver = *mserver
|
||||||
|
Cfg.mailsettings = *msettings
|
||||||
|
} else {
|
||||||
|
generateDefaultConfig()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateDefaultConfig() {
|
||||||
|
// mailserver
|
||||||
|
viper.SetDefault("mailserver.Port", 25)
|
||||||
|
viper.SetDefault("mailserver.Host", "localhost")
|
||||||
|
viper.SetDefault("mailserver.Username", "user")
|
||||||
|
viper.SetDefault("mailserver.Password", "pass")
|
||||||
|
viper.SetDefault("mailserver.Tls", "notls|mandatory")
|
||||||
|
viper.SetDefault("mailserver.Authtype", "nologin|plain|login|cram-md5")
|
||||||
|
viper.SetDefault("mailserver.Skipverify", false)
|
||||||
|
// mailsettings
|
||||||
|
viper.SetDefault("mailsettings.Subject", "subject")
|
||||||
|
viper.SetDefault("mailsettings.From", "from@local")
|
||||||
|
viper.SetDefault("mailsettings.To", "to@local")
|
||||||
|
viper.SetDefault("mailsettings.Cc", "cc@local")
|
||||||
|
viper.SetDefault("mailsettings.Template", "email.html")
|
||||||
|
viper.SetDefault("mailsettings.Inline", true)
|
||||||
|
|
||||||
|
viper.SafeWriteConfig()
|
||||||
|
log.Printf("Writing default config file: " + viper.ConfigFileUsed())
|
||||||
|
}
|
||||||
|
@ -1,20 +1,11 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
ht "html/template"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
|
"git.dafu.dev/dafu/gomailer/pkg"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/vanng822/go-premailer/premailer"
|
|
||||||
"github.com/wneessen/go-mail"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var help bool
|
|
||||||
var inline bool
|
|
||||||
var template string
|
|
||||||
var output string
|
|
||||||
|
|
||||||
// sendmailCmd represents the sendmail command
|
// sendmailCmd represents the sendmail command
|
||||||
var sendmailCmd = &cobra.Command{
|
var sendmailCmd = &cobra.Command{
|
||||||
Use: "sendmail",
|
Use: "sendmail",
|
||||||
@ -24,71 +15,14 @@ var sendmailCmd = &cobra.Command{
|
|||||||
sendmail.`,
|
sendmail.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
prem, err := premailer.NewPremailerFromFile(template, premailer.NewOptions())
|
gomailer.SendMail(Cfg.mailsettings, Cfg.mailserver)
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
html, err := prem.Transform()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Create(template + "_inlined.html")
|
|
||||||
defer f.Close()
|
|
||||||
f.WriteString(html)
|
|
||||||
f.Sync()
|
|
||||||
|
|
||||||
// fmt.Println(html)
|
|
||||||
|
|
||||||
m := mail.NewMsg()
|
|
||||||
if err := m.From("sender@domain.local"); err != nil {
|
|
||||||
log.Fatalf("failed to set From address: %s", err)
|
|
||||||
}
|
|
||||||
if err := m.To("recipient@domain.local"); err != nil {
|
|
||||||
log.Fatalf("failed to set To address: %s", err)
|
|
||||||
}
|
|
||||||
m.Subject("Subject")
|
|
||||||
|
|
||||||
htpl, err := ht.New("htmltpl").Parse(html)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to parse text template: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// embedd images
|
|
||||||
for _, val := range findSrcInHtml(html) {
|
|
||||||
log.Println("embedding: " + val)
|
|
||||||
m.EmbedFile(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.SetBodyHTMLTemplate(htpl, nil)
|
|
||||||
|
|
||||||
c, err := mail.NewClient("localhost", mail.WithPort(25), mail.WithTLSPolicy(mail.NoTLS))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to create mail client: %s", err)
|
|
||||||
}
|
|
||||||
if err := c.DialAndSend(m); err != nil {
|
|
||||||
log.Fatalf("failed to send mail: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(sendmailCmd)
|
rootCmd.AddCommand(sendmailCmd)
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
// sendmailCmd.Flags().BoolVar(&help, "test", false, "Help message for sendmail")
|
||||||
|
// sendmailCmd.Flags().BoolVarP(&inline, "inline", "i", false, "Inline css")
|
||||||
// Cobra supports Persistent Flags which will work for this command
|
|
||||||
// and all subcommands, e.g.:
|
|
||||||
// sendmailCmd.PersistentFlags().String("foo", "", "A help for foo")
|
|
||||||
|
|
||||||
// Cobra supports local flags which will only run when this command
|
|
||||||
// is called directly, e.g.:
|
|
||||||
sendmailCmd.Flags().BoolVar(&help, "test", false, "Help message for sendmail")
|
|
||||||
sendmailCmd.Flags().BoolVarP(&inline, "inline", "i", false, "Inline css")
|
|
||||||
sendmailCmd.Flags().StringVarP(&template, "template", "t", "", "Path to html template")
|
|
||||||
sendmailCmd.Flags().StringVarP(&output, "output", "o", "", "Path to save inlined html")
|
|
||||||
}
|
}
|
||||||
|
40
cmd/utils.go
40
cmd/utils.go
@ -1,40 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/net/html"
|
|
||||||
)
|
|
||||||
|
|
||||||
func findSrcInHtml(doc string) []string {
|
|
||||||
var results []string
|
|
||||||
reader := strings.NewReader(doc)
|
|
||||||
if document, err := html.Parse(reader); err == nil {
|
|
||||||
|
|
||||||
var parser func(*html.Node)
|
|
||||||
parser = func(n *html.Node) {
|
|
||||||
if n.Type == html.ElementNode && n.Data == "img" {
|
|
||||||
|
|
||||||
var imgSrcUrl string
|
|
||||||
|
|
||||||
for _, element := range n.Attr {
|
|
||||||
if element.Key == "src" {
|
|
||||||
imgSrcUrl = element.Val
|
|
||||||
log.Print("found image:" + imgSrcUrl)
|
|
||||||
results = append(results, imgSrcUrl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
parser(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
parser(document)
|
|
||||||
} else {
|
|
||||||
log.Panicln("Parse html error", err)
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
}
|
|
8
go.mod
8
go.mod
@ -1,4 +1,4 @@
|
|||||||
module git.dafu.dev/gomailer
|
module git.dafu.dev/dafu/gomailer
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
@ -7,6 +7,7 @@ require (
|
|||||||
github.com/spf13/viper v1.15.0
|
github.com/spf13/viper v1.15.0
|
||||||
github.com/vanng822/go-premailer v1.20.1
|
github.com/vanng822/go-premailer v1.20.1
|
||||||
github.com/wneessen/go-mail v0.3.9
|
github.com/wneessen/go-mail v0.3.9
|
||||||
|
golang.org/x/net v0.9.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@ -25,9 +26,8 @@ require (
|
|||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/subosito/gotenv v1.4.2 // indirect
|
github.com/subosito/gotenv v1.4.2 // indirect
|
||||||
github.com/vanng822/css v1.0.1 // indirect
|
github.com/vanng822/css v1.0.1 // indirect
|
||||||
golang.org/x/net v0.4.0 // indirect
|
golang.org/x/sys v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.3.0 // indirect
|
golang.org/x/text v0.9.0 // indirect
|
||||||
golang.org/x/text v0.5.0 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
21
go.sum
21
go.sum
@ -52,6 +52,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
|
|||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
@ -60,6 +61,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
@ -101,6 +103,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
@ -134,8 +137,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
|||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
@ -144,9 +149,11 @@ github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvI
|
|||||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||||
@ -170,6 +177,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||||
@ -264,8 +272,8 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -320,8 +328,8 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -329,8 +337,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
|||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@ -474,6 +482,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
|||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
|
6
main.go
6
main.go
@ -1,10 +1,6 @@
|
|||||||
/*
|
|
||||||
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
|
|
||||||
|
|
||||||
*/
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "git.dafu.dev/gomailer/cmd"
|
import "git.dafu.dev/dafu/gomailer/cmd"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
|
84
pkg/inline.go
Normal file
84
pkg/inline.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package gomailer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"golang.org/x/net/html"
|
||||||
|
"github.com/vanng822/go-premailer/premailer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Inline(arg string) {
|
||||||
|
out := LoadTemplate(arg, true)
|
||||||
|
|
||||||
|
dir := path.Dir(arg)
|
||||||
|
ext := path.Ext(arg)
|
||||||
|
base := strings.ReplaceAll(path.Base(arg), ext, "")
|
||||||
|
output_file := path.Join(dir, base+"_inlined"+ext)
|
||||||
|
log.Printf("Template: %s -> %s", arg, output_file)
|
||||||
|
|
||||||
|
f, err := os.Create(output_file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error inlining html: " + err.Error())
|
||||||
|
}
|
||||||
|
_, err = f.WriteString(out)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error inlining html: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadTemplate(template string, inline bool) (string) {
|
||||||
|
rawhtml, err := os.ReadFile(template)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error loading template: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if inline {
|
||||||
|
prem, err := premailer.NewPremailerFromBytes(rawhtml, premailer.NewOptions())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error inlining html: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
inlinehtml, err := prem.Transform()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error transforming html: " + err.Error())
|
||||||
|
}
|
||||||
|
return inlinehtml
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(rawhtml)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindSrcInHtml(doc string) []string {
|
||||||
|
var results []string
|
||||||
|
reader := strings.NewReader(doc)
|
||||||
|
if document, err := html.Parse(reader); err == nil {
|
||||||
|
|
||||||
|
var parser func(*html.Node)
|
||||||
|
parser = func(n *html.Node) {
|
||||||
|
if n.Type == html.ElementNode && n.Data == "img" {
|
||||||
|
|
||||||
|
var imgSrcUrl string
|
||||||
|
|
||||||
|
for _, element := range n.Attr {
|
||||||
|
if element.Key == "src" {
|
||||||
|
imgSrcUrl = element.Val
|
||||||
|
log.Print("found image:" + imgSrcUrl)
|
||||||
|
results = append(results, imgSrcUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||||
|
parser(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
parser(document)
|
||||||
|
} else {
|
||||||
|
log.Fatalln("Parse html error", err)
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
112
pkg/mail.go
Normal file
112
pkg/mail.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package gomailer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"github.com/wneessen/go-mail"
|
||||||
|
ht "html/template"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MailSettings struct {
|
||||||
|
Subject string
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Cc string
|
||||||
|
Inline bool
|
||||||
|
Template string
|
||||||
|
}
|
||||||
|
|
||||||
|
type MailServer struct {
|
||||||
|
Port int
|
||||||
|
Host string
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Tls string
|
||||||
|
Authtype string
|
||||||
|
Skipverify bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendMail(mailsettings MailSettings, serversettings MailServer) {
|
||||||
|
html := LoadTemplate(mailsettings.Template, true)
|
||||||
|
|
||||||
|
m := mail.NewMsg()
|
||||||
|
if err := m.From(mailsettings.From); err != nil {
|
||||||
|
log.Fatalf("failed to set From address: %s", err)
|
||||||
|
}
|
||||||
|
if err := m.To(mailsettings.From); err != nil {
|
||||||
|
log.Fatalf("failed to set To address: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Subject(mailsettings.Subject)
|
||||||
|
|
||||||
|
htpl, err := ht.New("htmltpl").Parse(html)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to parse text template: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// embedd images
|
||||||
|
for _, val := range FindSrcInHtml(html) {
|
||||||
|
log.Println("Embedding: " + val)
|
||||||
|
m.EmbedFile(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set template
|
||||||
|
m.SetBodyHTMLTemplate(htpl, nil)
|
||||||
|
|
||||||
|
// generate client
|
||||||
|
c, err := getClient(serversettings)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create mail client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// send mail
|
||||||
|
if err := c.DialAndSend(m); err != nil {
|
||||||
|
log.Fatalf("failed to send mail: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getClient(config MailServer) (*mail.Client, error) {
|
||||||
|
var authType mail.SMTPAuthType
|
||||||
|
switch config.Authtype {
|
||||||
|
case "plain":
|
||||||
|
authType = mail.SMTPAuthPlain
|
||||||
|
case "login":
|
||||||
|
authType = mail.SMTPAuthLogin
|
||||||
|
case "cram-md5":
|
||||||
|
authType = mail.SMTPAuthCramMD5
|
||||||
|
}
|
||||||
|
|
||||||
|
// tlsPolicy := mail.TLSOpportunistic
|
||||||
|
tlsPolicy := mail.DefaultTLSPolicy
|
||||||
|
switch config.Tls {
|
||||||
|
case "notls":
|
||||||
|
tlsPolicy = mail.NoTLS
|
||||||
|
case "mandatory":
|
||||||
|
tlsPolicy = mail.TLSMandatory
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := []mail.Option{
|
||||||
|
mail.WithPort(config.Port),
|
||||||
|
mail.WithTLSPolicy(tlsPolicy),
|
||||||
|
mail.WithTLSConfig(&tls.Config{
|
||||||
|
InsecureSkipVerify: config.Skipverify,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Authtype != "nologin" {
|
||||||
|
opts = append(opts, mail.WithSMTPAuth(authType))
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Username != "" {
|
||||||
|
opts = append(opts, mail.WithUsername(config.Username))
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Password != "" {
|
||||||
|
opts = append(opts, mail.WithPassword(config.Password))
|
||||||
|
}
|
||||||
|
|
||||||
|
return mail.NewClient(
|
||||||
|
config.Host,
|
||||||
|
opts...,
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user