Compare commits

...

6 Commits

Author SHA1 Message Date
ge
9cb0d296fb use fresh V in Dockerfile, upd build vflags, del unused dependency 2025-01-26 00:46:54 +03:00
ge
21307c947d build: rename comptime vars, add -skip-unused 2024-11-28 21:16:38 +03:00
ge
b67b854b88 upd 2024-11-03 18:00:57 +03:00
ge
ba1f5f4951 Update README.md 2024-11-03 17:15:01 +03:00
ge
584df540ad Update README.md 2024-11-03 17:11:15 +03:00
ge
d0e785e4fd Update README.md 2024-11-03 16:59:49 +03:00
8 changed files with 65 additions and 36 deletions

2
.gitignore vendored
View File

@ -18,3 +18,5 @@ bin/
# ENV # ENV
.env .env
*.todo

View File

@ -1,6 +1,17 @@
FROM thevlang/vlang:latest AS builder FROM debian:bookworm AS vlang
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates gcc clang make git binutils libssl-dev libatomic1 && \
apt clean && rm -rf /var/cache/apt/archives/* && \
rm -rf /var/lib/apt/lists/*
RUN git clone --depth=1 https://github.com/vlang/v /opt/v && \
cd /opt/v && \
make && \
/opt/v/v symlink && \
v version
FROM vlang AS builder
COPY . . COPY . .
RUN v -prod -cc gcc -cflags -static -cflags -s -d habraview_version=$(git describe --tags) . -o /habraview RUN v -prod -cflags -static -cflags -s -d hv_version=$(git describe --tags) . -o /habraview
FROM scratch AS prod FROM scratch AS prod
COPY --from=builder /habraview . COPY --from=builder /habraview .

View File

@ -1,2 +1,2 @@
bin: bin:
v -prod -cflags -static -d habraview_version=$$(git describe --tags) . v -prod -cflags -static -d hv_version=$$(git describe --tags) .

View File

@ -16,9 +16,10 @@
* Отображает все комментарии (отрисовка дерева не удалась, но и так сойдёт). * Отображает все комментарии (отрисовка дерева не удалась, но и так сойдёт).
* Решает проблему с заблюренными изображениями. * Решает проблему с заблюренными изображениями.
Работает только с `article`, то есть новостные посты и статьи из `sandbox`. Работает только с `article`, то есть новостные посты и статьи из `sandbox`
работать не будут.
# Как пользоваться ## Как пользоваться
`habraview` это веб-приложение. Просто запускаем файл: `habraview` это веб-приложение. Просто запускаем файл:
@ -27,13 +28,13 @@
``` ```
Приложение будет по умолчанию будет слушать на 8888 порту. Чтобы получить Приложение будет по умолчанию будет слушать на 8888 порту. Чтобы получить
страницу, открываем в брайзере: страницу, открываем в браузере:
``` ```
http://localhost:8888?url=https://habr.com/ru/articles/853062/ http://localhost:8888?url=https://habr.com/ru/articles/853062/
``` ```
Адрес статьи на Хабре можно передать целиком как значение quey-параметра `url` Адрес статьи на Хабре можно передать целиком как значение query-параметра `url`
или как `id`: или как `id`:
``` ```
@ -42,10 +43,23 @@ http://localhost:8888?id=853062
Теперь на эту страницу можно натравить архиватор веб-страниц. Теперь на эту страницу можно натравить архиватор веб-страниц.
# Компиляция ## Компиляция
Нужны компиляторы `gcc` и [v](https://vlang.io): Нужны компиляторы `gcc` и [v](https://vlang.io):
``` ```
make make
``` ```
## Docker
```
docker build -t habraview:latest .
docker run --rm -p 8888:8888 habraview:latest
```
или:
```
docker compose up -d
```

8
docker-compose.yaml Normal file
View File

@ -0,0 +1,8 @@
services:
habraview:
image: habraview:latest
build: .
container_name: habraview
restart: always
ports:
- '8888:8888'

View File

@ -3,7 +3,7 @@ module habr
import net.http import net.http
pub struct Habr { pub struct Habr {
baseurl string = $d('habr_baseurl', 'https://habr.com') baseurl string = $d('hv_habr_baseurl', 'https://habr.com')
} }
pub fn Habr.new() Habr { pub fn Habr.new() Habr {

View File

@ -12,13 +12,7 @@ pub struct Context {
veb.Context veb.Context
} }
pub struct App { pub struct App {}
veb.StaticHandler
}
struct Response {
msg string
}
const embedded = { const embedded = {
'style.css': $embed_file('assets/style.css') 'style.css': $embed_file('assets/style.css')
@ -40,18 +34,16 @@ fn (a &App) assets(mut ctx Context, filename string) veb.Result {
fn (a &App) index(mut ctx Context) veb.Result { fn (a &App) index(mut ctx Context) veb.Result {
article_id := ctx.query['id'] or { habr.get_id_from_url(ctx.query['url']) or { '' } } article_id := ctx.query['id'] or { habr.get_id_from_url(ctx.query['url']) or { '' } }
client := habr.Habr.new() client := habr.Habr.new()
raw_article := client.get_article(article_id.int()) or { raw_article := client.get_article(article_id.int()) or { return ctx.server_error(err.str()) }
return ctx.json(Response{ msg: err.str() })
}
raw_comments := client.get_article_comments(article_id.int()) or { raw_comments := client.get_article_comments(article_id.int()) or {
return ctx.json(Response{ msg: err.str() }) return ctx.server_error(err.str())
} }
article := habr.Article.parse(raw_article) article := habr.Article.parse(raw_article)
comments := habr.Comments.parse(raw_comments) comments := habr.Comments.parse(raw_comments)
return $veb.html() return $veb.html()
} }
fn runserver(host string, port int) ! { fn serve(host string, port int) ! {
mut app := &App{} mut app := &App{}
mut ipversion := net.AddrFamily.ip mut ipversion := net.AddrFamily.ip
if host.contains(':') { if host.contains(':') {
@ -65,28 +57,30 @@ fn runserver(host string, port int) ! {
veb.run_at[App, Context](mut app, params)! veb.run_at[App, Context](mut app, params)!
} }
fn run_server(cmd cli.Command) ! {
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'
}
}
serve(host, port.int())!
}
fn main() { fn main() {
mut app := cli.Command{ mut app := cli.Command{
name: 'habraview' name: 'habraview'
usage: '[host][:port]' usage: '[host][:port]'
description: 'Habr.com posts viewer.' description: 'Habr.com posts viewer.'
version: $d('habraview_version', '0.0.0') version: $d('hv_version', '0.0.0')
defaults: struct { defaults: struct {
man: false man: false
} }
execute: fn (cmd cli.Command) ! { execute: run_server
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())!
}
} }
app.setup() app.setup()
app.parse(os.args) app.parse(os.args)

2
v.mod
View File

@ -3,5 +3,5 @@ Module {
description: 'Habr.com posts viewer' description: 'Habr.com posts viewer'
version: '0.0.1' version: '0.0.1'
license: 'Unlicense' license: 'Unlicense'
dependencies: ['whisker'] dependencies: []
} }