Implement folder mail notifier
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
test
|
||||
main.log
|
13
go.mod
Normal file
13
go.mod
Normal file
@@ -0,0 +1,13 @@
|
||||
module folder-mail-notifier
|
||||
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/joho/godotenv v1.5.1
|
||||
gopkg.in/fsnotify.v1 v1.4.7
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
)
|
8
go.sum
Normal file
8
go.sum
Normal file
@@ -0,0 +1,8 @@
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
111
main.go
Normal file
111
main.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/smtp"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"gopkg.in/fsnotify.v1"
|
||||
)
|
||||
|
||||
var Error *log.Logger
|
||||
var Warning *log.Logger
|
||||
|
||||
func init() {
|
||||
log.SetFlags(log.Lmicroseconds | log.Lshortfile)
|
||||
logFile, err := os.Create("main.log")
|
||||
if err != nil {
|
||||
log.Printf("Error creating log file: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
logger := io.MultiWriter(os.Stdout, logFile)
|
||||
log.SetOutput(logger)
|
||||
|
||||
Error = log.New(io.MultiWriter(logFile, os.Stderr, os.Stdout),
|
||||
fmt.Sprintf("%sERROR:%s ", "\033[0;101m", "\033[0m"),
|
||||
log.Lmicroseconds|log.Lshortfile)
|
||||
Warning = log.New(io.MultiWriter(logFile, os.Stdout),
|
||||
fmt.Sprintf("%sWarning:%s ", "\033[0;93m", "\033[0m"),
|
||||
log.Lmicroseconds|log.Lshortfile)
|
||||
}
|
||||
|
||||
//go:embed .env
|
||||
var env string
|
||||
var envvar map[string]string
|
||||
var queued bool
|
||||
var changes = []*fsnotify.Event{}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
envvar, err = godotenv.Parse(strings.NewReader(env))
|
||||
if err != nil {
|
||||
Error.Fatalf("Error parsing .env file: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
root, ok := envvar["ROOT"]
|
||||
if !ok {
|
||||
Error.Fatalf("Error parsing ROOT variable: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
WatchRecursively(root, func(event fsnotify.Event) {
|
||||
if !queued {
|
||||
// time.AfterFunc(5*time.Minute, func() { doNotify() })
|
||||
delay := 5*time.Second
|
||||
log.Printf("Mailing changes in %v seconds", delay.Seconds())
|
||||
time.AfterFunc(delay, func() { doNotify() })
|
||||
queued = true
|
||||
}
|
||||
changes = append(changes, &event)
|
||||
})
|
||||
}
|
||||
|
||||
func doNotify() error {
|
||||
defer func() { queued = false }()
|
||||
|
||||
smtpHost, ok := envvar["SMTP_HOST"]
|
||||
if !ok {
|
||||
return fmt.Errorf("error getting env var SMTP_HOST")
|
||||
}
|
||||
smtpPort, ok := envvar["SMTP_PORT"]
|
||||
if !ok {
|
||||
return fmt.Errorf("error getting env var SMTP_PORT")
|
||||
}
|
||||
smtpUser, ok := envvar["SMTP_USER"]
|
||||
if !ok {
|
||||
return fmt.Errorf("error getting env var SMTP_USER")
|
||||
}
|
||||
smtpPass, ok := envvar["SMTP_PASSWORD"]
|
||||
if !ok {
|
||||
return fmt.Errorf("error getting env var SMTP_PASSWORD")
|
||||
}
|
||||
log.Printf("Mailing %v changes", len(changes))
|
||||
strchanges := make([]string, 0, len(changes))
|
||||
for _, change := range changes {
|
||||
strchanges = append(strchanges, change.String())
|
||||
}
|
||||
|
||||
from := "admin@quack-lab.dev"
|
||||
to := []string{"david.majdandzic@hotmail.com"}
|
||||
subject := "New files:"
|
||||
body := strings.Join(strchanges, "\n")
|
||||
|
||||
msg := []byte(fmt.Sprintf("Subject: %s\nFrom: %s\nTo: %s\n\n%s", subject, from, strings.Join(to, ","), body))
|
||||
|
||||
auth := smtp.PlainAuth("", smtpUser, smtpPass, smtpHost)
|
||||
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("Sent mail")
|
||||
changes = []*fsnotify.Event{}
|
||||
|
||||
return nil
|
||||
}
|
59
watcher.go
Normal file
59
watcher.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gopkg.in/fsnotify.v1"
|
||||
)
|
||||
|
||||
func WatchRecursively(root string, changeHandler func(fsnotify.Event)) error {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
done := make(chan bool)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
changeHandler(event)
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
Error.Printf("error with watcher: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
dirs := 0
|
||||
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Name() == ".git" {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if info.IsDir() {
|
||||
err = watcher.Add(path)
|
||||
dirs++
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
<-done
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user