a mini social media app for small communities
1module main
2
3import db.pg
4import veb
5import auth
6import entity
7import os
8import webapp { App, Context, StringValidator }
9import beep_sql
10import util
11
12pub const version = '25.01.0'
13
14@[inline]
15fn connect(mut app App) {
16 println('-> connecting to database...')
17 app.db = pg.connect(pg.Config{
18 host: app.config.postgres.host
19 dbname: app.config.postgres.db
20 user: app.config.postgres.user
21 password: app.config.postgres.password
22 port: app.config.postgres.port
23 }) or {
24 panic('failed to connect to database: ${err}')
25 }
26}
27
28@[inline]
29fn init_db(mut app App) {
30 println('-> initializing database')
31 sql app.db {
32 create table entity.Site
33 create table entity.User
34 create table entity.Post
35 create table entity.Like
36 create table entity.LikeCache
37 create table entity.Notification
38 create table entity.SavedPost
39 } or {
40 panic('failed to initialize database: ${err}')
41 }
42}
43
44@[inline]
45fn load_validators(mut app App) {
46 // vfmt off
47 user := app.config.user
48 app.validators.username = StringValidator.new(user.username_min_len, user.username_max_len, user.username_pattern)
49 app.validators.password = StringValidator.new(user.password_min_len, user.password_max_len, user.password_pattern)
50 app.validators.nickname = StringValidator.new(user.nickname_min_len, user.nickname_max_len, user.nickname_pattern)
51 app.validators.user_bio = StringValidator.new(user.bio_min_len, user.bio_max_len, user.bio_pattern)
52 app.validators.pronouns = StringValidator.new(user.pronouns_min_len, user.pronouns_max_len, user.pronouns_pattern)
53 post := app.config.post
54 app.validators.post_title = StringValidator.new(post.title_min_len, post.title_max_len, post.title_pattern)
55 app.validators.post_body = StringValidator.new(post.body_min_len, post.body_max_len, post.body_pattern)
56 // vfmt on
57}
58
59fn main() {
60 mut stopwatch := util.Stopwatch.new()
61
62 config := webapp.load_config_from(os.args[1])
63 mut app := &App{ config: config }
64
65 // connect to database
66 util.time_it(
67 it: fn [mut app] () {
68 connect(mut app)
69 }
70 name: 'connect to db'
71 log: true
72 )
73 defer { app.db.close() or { panic(err) } }
74
75 // initialize database
76 util.time_it(it: fn [mut app] () {
77 init_db(mut app)
78 }, name: 'init db', log: true)
79
80 // load sql files kept in beep_sql/
81 util.time_it(
82 it: fn [mut app] () {
83 beep_sql.load(mut app.db)
84 }
85 name: 'load beep_sql'
86 log: true
87 )
88
89 // add authenticator
90 app.auth = auth.new(app.db)
91
92 // load validators
93 load_validators(mut app)
94
95 // mount static things
96 app.mount_static_folder_at(app.config.static_path, '/static')!
97
98 // make the website config, if it does not exist
99 app.get_or_create_site_config()
100
101 if config.dev_mode {
102 println('\033[1;31mNOTE: YOU ARE IN DEV MODE\033[0m')
103 }
104
105 stop := stopwatch.stop()
106 println('-> took ${stop} to start app')
107
108 veb.run[App, Context](mut app, app.config.http.port)
109}