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
74 defer { app.db.close() }
75
76 // add authenticator
77 app.auth = auth.new(app.db)
78
79 // load sql files kept in beep_sql/
80 util.time_it(
81 it: fn [mut app] () {
82 beep_sql.load(mut app.db)
83 }
84 name: 'load beep_sql'
85 log: true
86 )
87
88 // load validators
89 load_validators(mut app)
90
91 // mount static things
92 app.mount_static_folder_at(app.config.static_path, '/static')!
93
94 // initialize database
95 util.time_it(it: fn [mut app] () {
96 init_db(mut app)
97 }, name: 'init db', log: true)
98
99 // make the website config, if it does not exist
100 app.get_or_create_site_config()
101
102 if config.dev_mode {
103 println('\033[1;31mNOTE: YOU ARE IN DEV MODE\033[0m')
104 }
105
106 stop := stopwatch.stop()
107 println('-> took ${stop} to start app')
108
109 veb.run[App, Context](mut app, app.config.http.port)
110}