1package main
2
3import (
4 "context"
5 "encoding/hex"
6 "os"
7 "os/signal"
8
9 "github.com/fasthttp/router"
10 "github.com/sirupsen/logrus"
11 "github.com/valyala/fasthttp"
12 "gorm.io/driver/sqlite"
13 "gorm.io/gorm"
14
15 "git.sr.ht/~gabrielgio/img/pkg/components/auth"
16 "git.sr.ht/~gabrielgio/img/pkg/components/filesystem"
17 "git.sr.ht/~gabrielgio/img/pkg/components/media"
18 "git.sr.ht/~gabrielgio/img/pkg/database/localfs"
19 "git.sr.ht/~gabrielgio/img/pkg/database/sql"
20 "git.sr.ht/~gabrielgio/img/pkg/ext"
21 "git.sr.ht/~gabrielgio/img/pkg/view"
22 "git.sr.ht/~gabrielgio/img/pkg/worker"
23)
24
25const root = "/home/gabrielgio"
26
27func main() {
28 logger := logrus.New()
29 logger.SetLevel(logrus.ErrorLevel)
30
31 d := sqlite.Open("test.db")
32 db, err := gorm.Open(d, &gorm.Config{
33 Logger: ext.Wraplog(logger.WithField("context", "sql")),
34 })
35 if err != nil {
36 panic("failed to connect database: " + err.Error())
37 }
38
39 if err = sql.Migrate(db); err != nil {
40 panic("failed to migrate database: " + err.Error())
41 }
42
43 // TODO: properly set this up
44 key, _ := hex.DecodeString("6368616e676520746869732070617373")
45 r := router.New()
46 r.ServeFiles("/static/{filepath:*}", "./static")
47 r.NotFound = ext.NotFoundHTML
48
49 authMiddleware := ext.NewAuthMiddleware(key, logger.WithField("context", "auth"))
50 logMiddleware := ext.NewLogMiddleare(logger.WithField("context", "http"))
51
52 extRouter := ext.NewRouter(r)
53 extRouter.AddMiddleware(logMiddleware.HTTP)
54 extRouter.AddMiddleware(authMiddleware.LoggedIn)
55 extRouter.AddMiddleware(ext.HTML)
56
57 scheduler := worker.NewScheduler(10)
58
59 // repository
60 var (
61 userRepository = sql.NewUserRepository(db)
62 settingsRepository = sql.NewSettingsRespository(db)
63 fileSystemRepository = localfs.NewFileSystemRepository(root)
64 mediaRepository = sql.NewMediaRepository(db)
65 )
66
67 //TODO: remove later
68 userRepository.EnsureAdmin(context.Background())
69
70 // controller
71 var (
72 userController = auth.NewController(userRepository, key)
73 fileSystemController = filesystem.NewController(fileSystemRepository)
74 )
75
76 // view
77 for _, v := range []view.View{
78 view.NewAuthView(userController),
79 view.NewFileSystemView(*fileSystemController, settingsRepository),
80 view.NewSettingsView(settingsRepository),
81 view.NewMediaView(mediaRepository),
82 } {
83 v.SetMyselfIn(extRouter)
84 }
85
86 // worker
87 var (
88 serverWorker = worker.NewServerWorker(&fasthttp.Server{Handler: r.Handler})
89 fileScanner = worker.NewFileScanner(root, mediaRepository)
90 exifScanner = worker.NewEXIFScanner(root, mediaRepository)
91 )
92
93 ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
94 defer stop()
95
96 pool := worker.NewWorkerPool()
97 pool.AddWorker("http server", serverWorker)
98 pool.AddWorker("exif scanner", worker.NewWorkerFromListProcessor[*media.Media](exifScanner, scheduler))
99 pool.AddWorker("file scanner", worker.NewWorkerFromChanProcessor[string](fileScanner, scheduler))
100
101 pool.Start(ctx)
102 pool.Wait()
103}