+4
.gitignore
+4
.gitignore
+1
-1
Dockerfile
+1
-1
Dockerfile
+29
-12
build.maple
+29
-12
build.maple
···
1
plugins = [ 'v' ]
2
3
task:db.init = {
4
description = 'Initialize and start a local Postgres database via Docker'
5
category = 'db'
···
43
run = 'docker rm beep-database && docker volume rm beep-data'
44
}
45
46
task:ngrok = {
47
description = 'Open an ngrok tunnel for testing.'
48
category = 'misc'
···
55
run = 'ngrok http --url=${args} http://localhost:8008'
56
}
57
58
task:run.watch = {
59
description = 'Watch/run beep'
60
category = 'run'
61
run = '${v} -d veb_livereload watch run ${v_main} config.maple'
62
}
63
64
task:run.watch.real = {
65
description = 'Watch/run beep using config.real.maple'
66
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'
74
}
75
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
-
}
81
82
task:cloc = {
83
description = 'Get the lines of code for beep!'
···
1
plugins = [ 'v' ]
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
+
10
task:db.init = {
11
description = 'Initialize and start a local Postgres database via Docker'
12
category = 'db'
···
50
run = 'docker rm beep-database && docker volume rm beep-data'
51
}
52
53
+
// Ngrok
54
+
55
task:ngrok = {
56
description = 'Open an ngrok tunnel for testing.'
57
category = 'misc'
···
64
run = 'ngrok http --url=${args} http://localhost:8008'
65
}
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
+
83
task:run.watch = {
84
description = 'Watch/run beep'
85
category = 'run'
86
+
depends = [':fetch-build-info']
87
run = '${v} -d veb_livereload watch run ${v_main} config.maple'
88
}
89
90
task:run.watch.real = {
91
description = 'Watch/run beep using config.real.maple'
92
category = 'run'
93
+
depends = [':fetch-build-info']
94
+
run = '${v} watch run ${v_main}'
95
}
96
97
+
// Misc
98
99
task:cloc = {
100
description = 'Get the lines of code for beep!'
+6
config.maple
+6
config.maple
···
11
// Set this to '' if your instance is closed source. This is shown on the about page.
12
source = 'https://tangled.org/emmeline.girlkisser.top/beep'
13
14
// The instance's name, used for the page titles and on the homepage.
15
name = 'beep'
16
// The welcome message to show on the homepage.
···
31
32
// Toggle to allow any non-logged-in user to view data (posts, users, etc)
33
public_data = false
34
}
35
36
http = {
···
11
// Set this to '' if your instance is closed source. This is shown on the about page.
12
source = 'https://tangled.org/emmeline.girlkisser.top/beep'
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
+
17
// The instance's name, used for the page titles and on the homepage.
18
name = 'beep'
19
// The welcome message to show on the homepage.
···
34
35
// Toggle to allow any non-logged-in user to view data (posts, users, etc)
36
public_data = false
37
+
38
+
// Owner's username. This is linked on the about page. Leave empty to disable.
39
+
owner_username = ''
40
}
41
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
fn main() {
58
mut stopwatch := util.Stopwatch.new()
59
60
-
config := webapp.load_config_from(os.args[1])
61
-
mut app := &App{ config: config }
62
63
// connect to database
64
util.time_it(
···
96
// make the website config, if it does not exist
97
app.get_or_create_site_config()
98
99
-
if config.dev_mode {
100
println('\033[1;31mNOTE: YOU ARE IN DEV MODE\033[0m')
101
}
102
···
57
fn 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(
···
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
+16
-7
src/templates/about.html
+16
-7
src/templates/about.html
···
3
<h1>about this instance</h1>
4
5
<div>
6
<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>
13
@end
14
15
<br>
16
-
17
<p>users: @{app.get_user_count()}</p>
18
<p>posts: @{app.get_post_count()}</p>
19
</div>
20
21
<script>
···
3
<h1>about this instance</h1>
4
5
<div>
6
+
<p><strong>general:</strong></p>
7
<p>name: @{app.config.instance.name}</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>
12
@end
13
14
<br>
15
+
<p><strong>stats:</strong></p>
16
<p>users: @{app.get_user_count()}</p>
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
28
</div>
29
30
<script>
+4
-4
src/webapp/app.v
+4
-4
src/webapp/app.v
+18
src/webapp/config.v
+18
src/webapp/config.v
···
16
allow_changing_theme bool
17
version string
18
source string
19
invite_only bool
20
invite_code string
21
public_data bool
22
}
23
http struct {
24
pub mut:
···
88
config.instance.allow_changing_theme = loaded_instance.get('allow_changing_theme').to_bool()
89
config.instance.version = loaded_instance.get('version').to_str()
90
config.instance.source = loaded_instance.get('source').to_str()
91
config.instance.invite_only = loaded_instance.get('invite_only').to_bool()
92
config.instance.invite_code = loaded_instance.get('invite_code').to_str()
93
config.instance.public_data = loaded_instance.get('public_data').to_bool()
94
95
loaded_http := loaded.get('http')
96
config.http.port = loaded_http.get('port').to_int()
···
139
140
return config
141
}
···
16
allow_changing_theme bool
17
version string
18
source string
19
+
v_source string
20
invite_only bool
21
invite_code string
22
public_data bool
23
+
owner_username string
24
}
25
http struct {
26
pub mut:
···
90
config.instance.allow_changing_theme = loaded_instance.get('allow_changing_theme').to_bool()
91
config.instance.version = loaded_instance.get('version').to_str()
92
config.instance.source = loaded_instance.get('source').to_str()
93
+
config.instance.v_source = loaded_instance.get('v_source').to_str()
94
config.instance.invite_only = loaded_instance.get('invite_only').to_bool()
95
config.instance.invite_code = loaded_instance.get('invite_code').to_str()
96
config.instance.public_data = loaded_instance.get('public_data').to_bool()
97
+
config.instance.owner_username = loaded_instance.get('owner_username').to_str()
98
99
loaded_http := loaded.get('http')
100
config.http.port = loaded_http.get('port').to_int()
···
143
144
return config
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
235
@['/about']
236
fn (mut app App) about(mut ctx Context) veb.Result {
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
+
}
244
ctx.title = '${app.config.instance.name} - about'
245
return $veb.html('../templates/about.html')
246
}