Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
9cb0d296fb | |||
21307c947d | |||
b67b854b88 | |||
ba1f5f4951 | |||
584df540ad | |||
d0e785e4fd |
2
.gitignore
vendored
2
.gitignore
vendored
@ -18,3 +18,5 @@ bin/
|
|||||||
|
|
||||||
# ENV
|
# ENV
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
*.todo
|
||||||
|
15
Dockerfile
15
Dockerfile
@ -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 .
|
||||||
|
2
Makefile
2
Makefile
@ -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) .
|
||||||
|
24
README.md
24
README.md
@ -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
8
docker-compose.yaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
services:
|
||||||
|
habraview:
|
||||||
|
image: habraview:latest
|
||||||
|
build: .
|
||||||
|
container_name: habraview
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- '8888:8888'
|
@ -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 {
|
||||||
|
46
habraview.v
46
habraview.v
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user