aboutsummaryrefslogtreecommitdiff
path: root/cmd/server/main.go
blob: 59ea957fb60a560bf7e1d3f8c39cf748535f9332 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main

import (
	"context"
	"encoding/hex"
	"os"
	"os/signal"

	"github.com/fasthttp/router"
	"github.com/sirupsen/logrus"
	"github.com/valyala/fasthttp"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"

	"git.sr.ht/~gabrielgio/img/pkg/components/auth"
	"git.sr.ht/~gabrielgio/img/pkg/components/filesystem"
	"git.sr.ht/~gabrielgio/img/pkg/components/media"
	"git.sr.ht/~gabrielgio/img/pkg/database/localfs"
	"git.sr.ht/~gabrielgio/img/pkg/database/sql"
	"git.sr.ht/~gabrielgio/img/pkg/ext"
	"git.sr.ht/~gabrielgio/img/pkg/view"
	"git.sr.ht/~gabrielgio/img/pkg/worker"
)

const root = "/home/gabrielgio"

func main() {
	logger := logrus.New()
	logger.SetLevel(logrus.ErrorLevel)

	d := sqlite.Open("test.db")
	db, err := gorm.Open(d, &gorm.Config{
		Logger: ext.Wraplog(logger.WithField("context", "sql")),
	})
	if err != nil {
		panic("failed to connect database: " + err.Error())
	}

	if err = sql.Migrate(db); err != nil {
		panic("failed to migrate database: " + err.Error())
	}

	// TODO: properly set this up
	key, _ := hex.DecodeString("6368616e676520746869732070617373")
	r := router.New()
	r.ServeFiles("/static/{filepath:*}", "./static")
	r.NotFound = ext.NotFoundHTML

	authMiddleware := ext.NewAuthMiddleware(key, logger.WithField("context", "auth"))
	logMiddleware := ext.NewLogMiddleare(logger.WithField("context", "http"))

	extRouter := ext.NewRouter(r)
	extRouter.AddMiddleware(logMiddleware.HTTP)
	extRouter.AddMiddleware(authMiddleware.LoggedIn)
	extRouter.AddMiddleware(ext.HTML)

	scheduler := worker.NewScheduler(10)

	// repository
	var (
		userRepository       = sql.NewUserRepository(db)
		settingsRepository   = sql.NewSettingsRespository(db)
		fileSystemRepository = localfs.NewFileSystemRepository(root)
		mediaRepository      = sql.NewMediaRepository(db)
	)

	//TODO: remove later
	userRepository.EnsureAdmin(context.Background())

	// controller
	var (
		userController       = auth.NewController(userRepository, key)
		fileSystemController = filesystem.NewController(fileSystemRepository)
	)

	// view
	for _, v := range []view.View{
		view.NewAuthView(userController),
		view.NewFileSystemView(*fileSystemController, settingsRepository),
		view.NewSettingsView(settingsRepository),
		view.NewMediaView(mediaRepository),
	} {
		v.SetMyselfIn(extRouter)
	}

	// worker
	var (
		serverWorker = worker.NewServerWorker(&fasthttp.Server{Handler: r.Handler})
		fileScanner  = worker.NewFileScanner(root, mediaRepository)
		exifScanner  = worker.NewEXIFScanner(root, mediaRepository)
	)

	pool := worker.NewWorkerPool()
	pool.AddWorker("http server", serverWorker)
	pool.AddWorker("exif scanner", worker.NewWorkerFromListProcessor[*media.Media](exifScanner, scheduler))
	pool.AddWorker("file scanner", worker.NewWorkerFromChanProcessor[string](fileScanner, scheduler))

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	pool.Start(ctx)
	pool.Wait()
}