+4
.gitignore
+4
.gitignore
+1
-1
Dockerfile
+1
-1
Dockerfile
+29
-12
build.maple
+29
-12
build.maple
···
1
1
plugins = [ 'v' ]
2
2
3
+
task::fetch-build-info = {
4
+
description = 'Fetch misc build information, mainly for the about page'
5
+
run = 'v scripts/fetchbuildinfo.vsh'
6
+
}
7
+
8
+
// Database
9
+
3
10
task:db.init = {
4
11
description = 'Initialize and start a local Postgres database via Docker'
5
12
category = 'db'
···
43
50
run = 'docker rm beep-database && docker volume rm beep-data'
44
51
}
45
52
53
+
// Ngrok
54
+
46
55
task:ngrok = {
47
56
description = 'Open an ngrok tunnel for testing.'
48
57
category = 'misc'
···
55
64
run = 'ngrok http --url=${args} http://localhost:8008'
56
65
}
57
66
67
+
// Run
68
+
69
+
task:run = {
70
+
description = 'Run beep'
71
+
category = 'run'
72
+
depends = [':fetch-build-info']
73
+
run = '${v} run ${v_main} config.maple'
74
+
}
75
+
76
+
task:run.real = {
77
+
description = 'Run beep using config.real.maple'
78
+
category = 'run'
79
+
depends = [':fetch-build-info']
80
+
run = '${v} run ${v_main}'
81
+
}
82
+
58
83
task:run.watch = {
59
84
description = 'Watch/run beep'
60
85
category = 'run'
86
+
depends = [':fetch-build-info']
61
87
run = '${v} -d veb_livereload watch run ${v_main} config.maple'
62
88
}
63
89
64
90
task:run.watch.real = {
65
91
description = 'Watch/run beep using config.real.maple'
66
92
category = 'run'
67
-
run = '${v} watch run ${v_main} config.real.maple'
68
-
}
69
-
70
-
task:run = {
71
-
description = 'Run beep'
72
-
category = 'run'
73
-
run = '${v} run ${v_main} config.maple'
93
+
depends = [':fetch-build-info']
94
+
run = '${v} watch run ${v_main}'
74
95
}
75
96
76
-
task:run.real = {
77
-
description = 'Run beep using config.real.maple'
78
-
category = 'run'
79
-
run = '${v} run ${v_main} config.real.maple'
80
-
}
97
+
// Misc
81
98
82
99
task:cloc = {
83
100
description = 'Get the lines of code for beep!'
+6
config.maple
+6
config.maple
···
11
11
// Set this to '' if your instance is closed source. This is shown on the about page.
12
12
source = 'https://tangled.org/emmeline.girlkisser.top/beep'
13
13
14
+
// Source for your V compiler. Unless you're using a fork of V, you shouldn't need to change this.
15
+
v_source = 'https://github.com/vlang/v'
16
+
14
17
// The instance's name, used for the page titles and on the homepage.
15
18
name = 'beep'
16
19
// The welcome message to show on the homepage.
···
31
34
32
35
// Toggle to allow any non-logged-in user to view data (posts, users, etc)
33
36
public_data = false
37
+
38
+
// Owner's username. This is linked on the about page. Leave empty to disable.
39
+
owner_username = ''
34
40
}
35
41
36
42
http = {
+1
-1
readme
+1
-1
readme
+15
scripts/fetchbuildinfo.vsh
+15
scripts/fetchbuildinfo.vsh
···
1
+
#!/usr/bin/env v
2
+
3
+
import os
4
+
import emmathemartian.maple
5
+
6
+
commit_res := os.execute('git rev-parse HEAD')
7
+
if commit_res.exit_code != 0 {
8
+
eprintln('failed to fetch commit: ${commit_res.output}')
9
+
exit(1)
10
+
}
11
+
commit := commit_res.output.trim_space()
12
+
13
+
maple.save_file('buildinfo.maple', {
14
+
'commit': maple.ValueT(commit)
15
+
})!
+15
-3
src/main.v
+15
-3
src/main.v
···
57
57
fn main() {
58
58
mut stopwatch := util.Stopwatch.new()
59
59
60
-
config := webapp.load_config_from(os.args[1])
61
-
mut app := &App{ config: config }
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
+
}
62
74
63
75
// connect to database
64
76
util.time_it(
···
96
108
// make the website config, if it does not exist
97
109
app.get_or_create_site_config()
98
110
99
-
if config.dev_mode {
111
+
if app.config.dev_mode {
100
112
println('\033[1;31mNOTE: YOU ARE IN DEV MODE\033[0m')
101
113
}
102
114
+16
-7
src/templates/about.html
+16
-7
src/templates/about.html
···
3
3
<h1>about this instance</h1>
4
4
5
5
<div>
6
+
<p><strong>general:</strong></p>
6
7
<p>name: @{app.config.instance.name}</p>
7
-
<p>version: @{app.config.instance.version} (commit: @{app.commit})</p>
8
-
<p>built at @{app.built_at} (<span id="built_at">date n/a</span>)</p>
9
-
<p>built using @{app.v_hash}</p>
10
-
11
-
@if app.config.instance.source != ''
12
-
<p>source: <a href="@{app.config.instance.source}">@{app.config.instance.source}</a></p>
8
+
<p>version: @{app.config.instance.version}</p>
9
+
<p>public: @{app.config.instance.public_data}</p>
10
+
@if app.config.instance.owner_username != ''
11
+
<p>owner: <a href="/user/@{app.config.instance.owner_username}">@{app.config.instance.owner_username}</a></p>
13
12
@end
14
13
15
14
<br>
16
-
15
+
<p><strong>stats:</strong></p>
17
16
<p>users: @{app.get_user_count()}</p>
18
17
<p>posts: @{app.get_post_count()}</p>
18
+
19
+
@if app.config.instance.source != ''
20
+
<br>
21
+
<p><strong>nerd info:</strong></p>
22
+
<p>beep source: <a href="@{app.config.instance.source}">@{app.config.instance.source}</a></p>
23
+
<p>beep commit: <code><a href="@{app.config.instance.source}/commit/@{app.buildinfo.commit}">@{app.buildinfo.commit}</a></code></p>
24
+
<p>V source: <a href="@{app.config.instance.v_source}">@{app.config.instance.v_source}</a></p>
25
+
<p>V commit: <code><a href="@{app.config.instance.v_source}/commit/@{app.v_hash}">@{app.v_hash}</a></code></p>
26
+
<p>built at <span id="built_at">date n/a</span> (unix: <code>@{app.built_at}</code>)</p>
27
+
@end
19
28
</div>
20
29
21
30
<script>
+4
-4
src/webapp/app.v
+4
-4
src/webapp/app.v
···
11
11
veb.StaticHandler
12
12
DatabaseAccess
13
13
pub:
14
-
config Config
15
-
commit string = @VMODHASH
16
-
built_at string = @BUILD_TIMESTAMP
17
-
v_hash string = @VHASH
14
+
config Config
15
+
buildinfo BuildInfo
16
+
built_at string = @BUILD_TIMESTAMP
17
+
v_hash string = @VHASH
18
18
pub mut:
19
19
auth auth.Auth[pg.DB]
20
20
validators struct {
+18
src/webapp/config.v
+18
src/webapp/config.v
···
16
16
allow_changing_theme bool
17
17
version string
18
18
source string
19
+
v_source string
19
20
invite_only bool
20
21
invite_code string
21
22
public_data bool
23
+
owner_username string
22
24
}
23
25
http struct {
24
26
pub mut:
···
88
90
config.instance.allow_changing_theme = loaded_instance.get('allow_changing_theme').to_bool()
89
91
config.instance.version = loaded_instance.get('version').to_str()
90
92
config.instance.source = loaded_instance.get('source').to_str()
93
+
config.instance.v_source = loaded_instance.get('v_source').to_str()
91
94
config.instance.invite_only = loaded_instance.get('invite_only').to_bool()
92
95
config.instance.invite_code = loaded_instance.get('invite_code').to_str()
93
96
config.instance.public_data = loaded_instance.get('public_data').to_bool()
97
+
config.instance.owner_username = loaded_instance.get('owner_username').to_str()
94
98
95
99
loaded_http := loaded.get('http')
96
100
config.http.port = loaded_http.get('port').to_int()
···
139
143
140
144
return config
141
145
}
146
+
147
+
pub struct BuildInfo {
148
+
pub mut:
149
+
commit string
150
+
}
151
+
152
+
pub fn load_buildinfo_from(file_path string) BuildInfo {
153
+
loaded := maple.load_file(file_path) or { panic(err) }
154
+
mut buildinfo := BuildInfo{}
155
+
156
+
buildinfo.commit = loaded.get('commit').to_str()
157
+
158
+
return buildinfo
159
+
}
+7
-1
src/webapp/pages.v
+7
-1
src/webapp/pages.v
···
234
234
235
235
@['/about']
236
236
fn (mut app App) about(mut ctx Context) veb.Result {
237
-
user := app.whoami(mut ctx) or { User{} }
237
+
user := app.whoami(mut ctx) or {
238
+
if !app.config.instance.public_data {
239
+
ctx.error('not logged in')
240
+
return ctx.redirect('/login')
241
+
}
242
+
User{}
243
+
}
238
244
ctx.title = '${app.config.instance.name} - about'
239
245
return $veb.html('../templates/about.html')
240
246
}