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