diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..23d6abf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM thevlang/vlang:latest AS builder +COPY . . +RUN v -prod -cc gcc -cflags -static -cflags -s -d habraview_version=$(git describe --tags) . -o /habraview + +FROM scratch AS prod +COPY --from=builder /habraview . +ENTRYPOINT ["/habraview"] diff --git a/Makefile b/Makefile index ffef7ee..a0b41cf 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,2 @@ -all: build - -build: - v -o habraview src - -prod: - v -o habraview -prod -cc clang -compress src +bin: + v -prod -cflags -static -d habraview_version=$$(git describe --tags) . diff --git a/README.md b/README.md index e9eaf5d..f3c1ef4 100644 --- a/README.md +++ b/README.md @@ -47,5 +47,5 @@ http://localhost:8888?id=853062 Нужны компиляторы `gcc` и [v](https://vlang.io): ``` -v -prod -cflags -static -cflags -s . +make ``` diff --git a/assets/habr-fixer.js b/assets/habrfixer.js similarity index 100% rename from assets/habr-fixer.js rename to assets/habrfixer.js diff --git a/habraview.v b/habraview.v index 6a306c7..70cac27 100644 --- a/habraview.v +++ b/habraview.v @@ -2,6 +2,9 @@ module main import cli import habr +import net +import net.urllib +import net.http.mime import os import veb @@ -17,6 +20,22 @@ struct Response { msg string } +const embedded = { + 'style.css': $embed_file('assets/style.css') + 'highlight.min.css': $embed_file('assets/highlight.min.css') + 'highlight.min.js': $embed_file('assets/highlight.min.js') + 'habrfixer.js': $embed_file('assets/habrfixer.js') + 'favicon.ico': $embed_file('assets/favicon.ico') +} + +@['/assets/:filename'] +fn (a &App) assets(mut ctx Context, filename string) veb.Result { + asset := embedded[filename] or { return ctx.not_found() } + mimetype := mime.get_mime_type(os.file_ext(filename).trim_left('.')) + ctx.set_content_type(mimetype) + return ctx.text(asset.to_string()) +} + @[get] fn (a &App) index(mut ctx Context) veb.Result { article_id := ctx.query['id'] or { habr.get_id_from_url(ctx.query['url']) or { '' } } @@ -32,35 +51,42 @@ fn (a &App) index(mut ctx Context) veb.Result { return $veb.html() } -fn runserver(port int) ! { - os.chdir(os.dir(@FILE))! +fn runserver(host string, port int) ! { mut app := &App{} - app.handle_static('assets', false)! - app.serve_static('/favicon.ico', 'assets/favicon.ico')! - veb.run[App, Context](mut app, port) + mut ipversion := net.AddrFamily.ip + if host.contains(':') { + ipversion = net.AddrFamily.ip6 + } + params := veb.RunParams{ + host: host + port: port + family: ipversion + } + veb.run_at[App, Context](mut app, params)! } fn main() { mut app := cli.Command{ name: 'habraview' + usage: '[host][:port]' description: 'Habr.com posts viewer.' version: $d('habraview_version', '0.0.0') defaults: struct { man: false } execute: fn (cmd cli.Command) ! { - port := cmd.flags.get_int('port') or { 8080 } - runserver(port)! + mut host, mut port := '0.0.0.0', '8888' + if cmd.args.len == 1 { + host, port = urllib.split_host_port(cmd.args[0]) + if host.is_blank() { + host = '0.0.0.0' + } + if port.is_blank() { + port = '8888' + } + } + runserver(host, port.int())! } - flags: [ - cli.Flag{ - flag: .int - name: 'port' - abbrev: 'p' - description: 'Listen port [default: 8888].' - default_value: ['8888'] - }, - ] } app.setup() app.parse(os.args) diff --git a/templates/index.html b/templates/index.html index 15b6e93..bb907bc 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,6 +3,7 @@ @{article.title} + @css '/assets/style.css' @css '/assets/highlight.min.css' @@ -49,7 +50,7 @@ - @js '/assets/habr-fixer.js' + @js '/assets/habrfixer.js' @js '/assets/highlight.min.js'