Skip to content

Commit

Permalink
feat: web interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsNotGoodName committed Dec 30, 2021
1 parent 498fcf5 commit 70ee95f
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 36 deletions.
5 changes: 5 additions & 0 deletions app/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app
import (
"fmt"
"net/http"
"path"

"github.com/google/uuid"
)
Expand Down Expand Up @@ -57,6 +58,10 @@ func (a *Attachment) EXT() string {
}
}

func (a *Attachment) Path(directory string) string {
return path.Join(directory, a.UUID+a.EXT())
}

type EndpointAttachment struct {
Name string
Type AttachmentType
Expand Down
12 changes: 6 additions & 6 deletions app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import (
)

type Config struct {
AttachmentsPath string `json:"attachments" mapstructure:"attachments"`
DBPath string `json:"db" mapstructure:"db"`
SMTP ConfigSMTP `json:"smtp" mapstructure:"smtp"`
HTTP ConfigHTTP `json:"http" mapstructure:"http"`
Bridges []Bridge `json:"bridges" mapstructure:"bridges"`
Endpoints []ConfigEndpoint `json:"endpoints" mapstructure:"endpoints"`
AttDir string `json:"attachments" mapstructure:"attachments"`
DBFile string `json:"db" mapstructure:"db"`
SMTP ConfigSMTP `json:"smtp" mapstructure:"smtp"`
HTTP ConfigHTTP `json:"http" mapstructure:"http"`
Bridges []Bridge `json:"bridges" mapstructure:"bridges"`
Endpoints []ConfigEndpoint `json:"endpoints" mapstructure:"endpoints"`
}

type ConfigHTTP struct {
Expand Down
4 changes: 3 additions & 1 deletion app/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ type MessageServicePort interface {
type MessageRepositoryPort interface {
CreateMessage(msg *Message) error
GetMessage(uuid string) (*Message, error)
GetMessages(limit, offset int) ([]Message, error)
UpdateMessage(msg *Message, updateFN func(msg *Message) (*Message, error)) error
}

type AttachmentRepositoryPort interface {
CreateAttachment(att *Attachment) error
GetAttachment(uuid string) (*Attachment, error)
LoadAttachment(msg *Message) error
GetAttachmentData(att *Attachment) ([]byte, error)
GetAttachments(msg *Message) ([]Attachment, error)
}

// EndpointPort handles sending messages to an endpoint.
Expand Down
4 changes: 2 additions & 2 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var serverCmd = &cobra.Command{

// Init repositories
endpointREPO := endpoint.NewRepository(config.Endpoints)
databaseREPO := database.NewDB(config.DBPath, config.AttachmentsPath)
databaseREPO := database.NewDB(config.DBFile, config.AttDir)

// Init services
authSVC := service.NewMockAuth()
Expand All @@ -58,7 +58,7 @@ var serverCmd = &cobra.Command{

// Init router
if config.HTTP.Enable {
httpServer := router.New(config.AttachmentsPath)
httpServer := router.New(config.AttDir, databaseREPO, databaseREPO)
go httpServer.Start(config.HTTP.Address)
}

Expand Down
50 changes: 50 additions & 0 deletions left/router/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package router

import (
"embed"
"html/template"
"log"
"net/http"

"github.com/ItsNotGoodName/smtpbridge/app"
)

func (s *Router) GetAttachments(prefix string) http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
http.StripPrefix(prefix, http.FileServer(http.Dir(s.attDir))).ServeHTTP(rw, r)
}
}

//go:embed template
var templateFS embed.FS

func (s *Router) GetIndex() http.HandlerFunc {
type Data struct {
Messages []app.Message
}

index, err := template.ParseFS(templateFS, "template/index.html")
if err != nil {
log.Fatal("router.Router.GetIndex", err)
}

return func(rw http.ResponseWriter, r *http.Request) {
msg, err := s.messageREPO.GetMessages(10, 0)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}

for i := range msg {
msg[i].Attachments, err = s.attachmentREPO.GetAttachments(&msg[i])
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
}

data := Data{
Messages: msg,
}

index.Execute(rw, data)
}
}
7 changes: 2 additions & 5 deletions left/router/route.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package router

import "net/http"

func (s *Router) route() {
s.r.Get("/attachments/*", func(w http.ResponseWriter, r *http.Request) {
http.StripPrefix("/attachments/", http.FileServer(http.Dir(s.AttachmentsPath))).ServeHTTP(w, r)
})
s.r.Get("/attachments/*", s.GetAttachments("/attachments/"))
s.r.Get("/", s.GetIndex())
}
15 changes: 10 additions & 5 deletions left/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import (
"net/http"
"time"

"github.com/ItsNotGoodName/smtpbridge/app"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
)

type Router struct {
r *chi.Mux
AttachmentsPath string
r *chi.Mux
attDir string
messageREPO app.MessageRepositoryPort
attachmentREPO app.AttachmentRepositoryPort
}

func New(AttachmentsPath string) *Router {
func New(attDir string, messageREPO app.MessageRepositoryPort, attachmentREPO app.AttachmentRepositoryPort) *Router {
s := Router{
r: chi.NewRouter(),
AttachmentsPath: AttachmentsPath,
r: chi.NewRouter(),
attDir: attDir,
messageREPO: messageREPO,
attachmentREPO: attachmentREPO,
}

// A good base middleware stack
Expand Down
27 changes: 27 additions & 0 deletions left/router/template/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>Messages</h1>
{{range $msg := .Messages}}
<div>
<h2>{{ $msg.Subject }}</h2>
<div>Status: {{ $msg.Status }}</div>
<div>
<code>
<pre>{{ $msg.Text }}</pre>
</code>
</div>

{{ range $att := $msg.Attachments }}
<img width="300" src="/attachments/{{ $att.UUID }}.jpg" alt="{{ $att.UUID }}" />
{{ end }}
</div>
{{ end }}
</body>
</html>
41 changes: 24 additions & 17 deletions right/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package database
import (
"log"
"os"
"path"

"github.com/ItsNotGoodName/smtpbridge/app"
"github.com/asdine/storm"
Expand All @@ -15,20 +14,20 @@ type DB struct {
attPath string
}

func NewDB(dbPath, attPath string) *DB {
db, err := storm.Open(dbPath)
func NewDB(dbFile, attDir string) *DB {
db, err := storm.Open(dbFile)
if err != nil {
log.Fatal("database.NewDB:", err)
}

err = os.MkdirAll(attPath, 0755)
err = os.MkdirAll(attDir, 0755)
if err != nil {
log.Fatal("database.NewDB:", err)
}

return &DB{
db: db,
attPath: attPath,
attPath: attDir,
}
}

Expand Down Expand Up @@ -71,15 +70,23 @@ func (db *DB) UpdateMessage(msg *app.Message, updateFN func(msg *app.Message) (*
return tx.Commit()
}

func (db *DB) GetMessages(limit, offset int) ([]app.Message, error) {
var msgs []app.Message
err := db.db.All(&msgs, storm.Limit(limit), storm.Skip(offset), storm.Reverse())
if err != nil {
return nil, err
}

return msgs, nil
}

func (db *DB) CreateAttachment(att *app.Attachment) error {
err := db.db.Save(att)
if err != nil {
return err
}

file := path.Join(db.attPath, att.UUID+att.EXT())

return os.WriteFile(file, att.Data, 0644)
return os.WriteFile(att.Path(db.attPath), att.Data, 0644)
}

func (db *DB) GetAttachment(uuid string) (*app.Attachment, error) {
Expand All @@ -89,24 +96,24 @@ func (db *DB) GetAttachment(uuid string) (*app.Attachment, error) {
return nil, err
}

data, err := os.ReadFile(path.Join(db.attPath, att.UUID+att.EXT()))
return &att, nil
}

func (db *DB) GetAttachmentData(att *app.Attachment) ([]byte, error) {
data, err := os.ReadFile(att.Path(db.attPath))
if err != nil {
return nil, err
}

att.Data = data

return &att, nil
return data, nil
}

func (db *DB) LoadAttachment(msg *app.Message) error {
func (db *DB) GetAttachments(msg *app.Message) ([]app.Attachment, error) {
var atts []app.Attachment
err := db.db.Select(q.Eq("MessageUUID", msg.UUID)).Find(&atts)
if err != nil {
return err
return nil, err
}

msg.Attachments = atts

return nil
return atts, nil
}

0 comments on commit 70ee95f

Please sign in to comment.