Extend configuration

This commit is contained in:
2023-03-28 21:07:42 +03:00
parent 6839a264db
commit 8d2af4ad65
7 changed files with 63 additions and 24 deletions

View File

@@ -12,8 +12,20 @@ Aimed to be a simple, fast and easy-to-use webarchive for personal or home-net u
The service can be configured via environment variables. There is a list of available The service can be configured via environment variables. There is a list of available
variables: variables:
* **DB_PATH** — path for the database files (default `./db`) * **DB**
* **LOGGING_DEBUG** — enable debug logs (default `false`) * **DB_PATH** — path for the database files (default `./db`)
* **LOGGING**
* **LOGGING_DEBUG** — enable debug logs (default `false`)
* **API**
* **API_ADDRESS** — address the API server will listen (default `0.0.0.0:5001`)
* **PDF**
* **PDF_LANDSCAPE** — use landscape page orientation instead of portrait (default `false`)
* **PDF_GRAYSCALE** — use grayscale filter for the output pdf (default `false`)
* **PDF_MEDIA_PRINT** — use media type `print` for the request (default `true`)
* **PDF_ZOOM** — zoom page (default `1.0` i.e. no actual zoom)
* **PDF_VIEWPORT** — use specified viewport value (default `1920x1080`)
* **PDF_DPI** — use specified DPI value for the output pdf (default `300`)
* **PDF_FILENAME** — use specified name for output pdf file (default `page.pdf`)
*Note*: Prefix **WEBARCHIVE_** can be used with the environment variable names *Note*: Prefix **WEBARCHIVE_** can be used with the environment variable names
@@ -80,4 +92,3 @@ curl -X GET --location "http://localhost:5001/pages" | jq .
- [ ] Optional authentication - [ ] Optional authentication
- [ ] Multi-user access - [ ] Multi-user access
- [ ] Support PostgreSQL - [ ] Support PostgreSQL
- [ ] Extend configuration

View File

@@ -7,37 +7,46 @@ import (
"github.com/SebastiaanKlippert/go-wkhtmltopdf" "github.com/SebastiaanKlippert/go-wkhtmltopdf"
"github.com/derfenix/webarchive/config"
"github.com/derfenix/webarchive/entity" "github.com/derfenix/webarchive/entity"
) )
func NewPDF() *PDF { func NewPDF(cfg config.PDF) *PDF {
return &PDF{} return &PDF{cfg: cfg}
} }
type PDF struct{} type PDF struct {
cfg config.PDF
}
func (P *PDF) Process(_ context.Context, url string) ([]entity.File, error) { func (p *PDF) Process(_ context.Context, url string) ([]entity.File, error) {
gen, err := wkhtmltopdf.NewPDFGenerator() gen, err := wkhtmltopdf.NewPDFGenerator()
if err != nil { if err != nil {
return nil, fmt.Errorf("new pdf generator: %w", err) return nil, fmt.Errorf("new pdf generator: %w", err)
} }
gen.Dpi.Set(300) gen.Dpi.Set(p.cfg.DPI)
gen.PageSize.Set(wkhtmltopdf.PageSizeA4) gen.PageSize.Set(wkhtmltopdf.PageSizeA4)
gen.Orientation.Set(wkhtmltopdf.OrientationPortrait)
gen.Grayscale.Set(false) if p.cfg.Landscape {
gen.Orientation.Set(wkhtmltopdf.OrientationLandscape)
} else {
gen.Orientation.Set(wkhtmltopdf.OrientationPortrait)
}
gen.Grayscale.Set(p.cfg.Grayscale)
gen.Title.Set(url) gen.Title.Set(url)
page := wkhtmltopdf.NewPage(url) page := wkhtmltopdf.NewPage(url)
page.PrintMediaType.Set(true) page.PrintMediaType.Set(p.cfg.MediaPrint)
page.JavascriptDelay.Set(200) page.JavascriptDelay.Set(200)
page.LoadMediaErrorHandling.Set("ignore") page.LoadMediaErrorHandling.Set("ignore")
page.FooterRight.Set("[page]") page.FooterRight.Set("[page]")
page.HeaderLeft.Set(url) page.HeaderLeft.Set(url)
page.HeaderRight.Set(time.Now().Format(time.DateOnly)) page.HeaderRight.Set(time.Now().Format(time.DateOnly))
page.FooterFontSize.Set(10) page.FooterFontSize.Set(10)
page.Zoom.Set(1) page.Zoom.Set(p.cfg.Zoom)
page.ViewportSize.Set("1920x1080") page.ViewportSize.Set(p.cfg.Viewport)
gen.AddPage(page) gen.AddPage(page)
@@ -46,7 +55,7 @@ func (P *PDF) Process(_ context.Context, url string) ([]entity.File, error) {
return nil, fmt.Errorf("create pdf: %w", err) return nil, fmt.Errorf("create pdf: %w", err)
} }
file := entity.NewFile("page.pdf", gen.Bytes()) file := entity.NewFile(p.cfg.Filename, gen.Bytes())
return []entity.File{file}, nil return []entity.File{file}, nil
} }

View File

@@ -8,6 +8,7 @@ import (
"net/http/cookiejar" "net/http/cookiejar"
"time" "time"
"github.com/derfenix/webarchive/config"
"github.com/derfenix/webarchive/entity" "github.com/derfenix/webarchive/entity"
) )
@@ -15,7 +16,7 @@ type processor interface {
Process(ctx context.Context, url string) ([]entity.File, error) Process(ctx context.Context, url string) ([]entity.File, error)
} }
func NewProcessors() (*Processors, error) { func NewProcessors(cfg config.Config) (*Processors, error) {
jar, err := cookiejar.New(&cookiejar.Options{ jar, err := cookiejar.New(&cookiejar.Options{
PublicSuffixList: nil, PublicSuffixList: nil,
}) })
@@ -53,7 +54,7 @@ func NewProcessors() (*Processors, error) {
procs := Processors{ procs := Processors{
processors: map[entity.Format]processor{ processors: map[entity.Format]processor{
entity.FormatHeaders: NewHeaders(httpClient), entity.FormatHeaders: NewHeaders(httpClient),
entity.FormatPDF: NewPDF(), entity.FormatPDF: NewPDF(cfg.PDF),
}, },
} }

View File

@@ -18,11 +18,12 @@ import (
"github.com/derfenix/webarchive/adapters/processors" "github.com/derfenix/webarchive/adapters/processors"
badgerRepo "github.com/derfenix/webarchive/adapters/repository/badger" badgerRepo "github.com/derfenix/webarchive/adapters/repository/badger"
"github.com/derfenix/webarchive/api/openapi" "github.com/derfenix/webarchive/api/openapi"
"github.com/derfenix/webarchive/config"
"github.com/derfenix/webarchive/entity" "github.com/derfenix/webarchive/entity"
"github.com/derfenix/webarchive/ports/rest" "github.com/derfenix/webarchive/ports/rest"
) )
func NewApplication(cfg Config) (Application, error) { func NewApplication(cfg config.Config) (Application, error) {
log, err := newLogger(cfg.Logging) log, err := newLogger(cfg.Logging)
if err != nil { if err != nil {
return Application{}, fmt.Errorf("new logger: %w", err) return Application{}, fmt.Errorf("new logger: %w", err)
@@ -38,7 +39,7 @@ func NewApplication(cfg Config) (Application, error) {
return Application{}, fmt.Errorf("new page repo: %w", err) return Application{}, fmt.Errorf("new page repo: %w", err)
} }
processor, err := processors.NewProcessors() processor, err := processors.NewProcessors(cfg)
if err != nil { if err != nil {
return Application{}, fmt.Errorf("new processors: %w", err) return Application{}, fmt.Errorf("new processors: %w", err)
} }
@@ -73,7 +74,7 @@ func NewApplication(cfg Config) (Application, error) {
} }
httpServer := http.Server{ httpServer := http.Server{
Addr: "0.0.0.0:5001", Addr: cfg.API.Address,
Handler: server, Handler: server,
ReadTimeout: time.Second * 15, ReadTimeout: time.Second * 15,
ReadHeaderTimeout: time.Second * 5, ReadHeaderTimeout: time.Second * 5,
@@ -94,7 +95,7 @@ func NewApplication(cfg Config) (Application, error) {
} }
type Application struct { type Application struct {
cfg Config cfg config.Config
log *zap.Logger log *zap.Logger
db *badger.DB db *badger.DB
processor entity.Processor processor entity.Processor
@@ -165,7 +166,7 @@ func (a *Application) Stop() error {
return errs return errs
} }
func newLogger(cfg Logging) (*zap.Logger, error) { func newLogger(cfg config.Logging) (*zap.Logger, error) {
logCfg := zap.NewProductionConfig() logCfg := zap.NewProductionConfig()
logCfg.EncoderConfig.EncodeTime = zapcore.RFC3339TimeEncoder logCfg.EncoderConfig.EncodeTime = zapcore.RFC3339TimeEncoder
logCfg.EncoderConfig.EncodeDuration = zapcore.NanosDurationEncoder logCfg.EncoderConfig.EncodeDuration = zapcore.NanosDurationEncoder

View File

@@ -10,13 +10,14 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"github.com/derfenix/webarchive/application" "github.com/derfenix/webarchive/application"
"github.com/derfenix/webarchive/config"
) )
func main() { func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel() defer cancel()
cfg, err := application.NewConfig(ctx) cfg, err := config.NewConfig(ctx)
if err != nil { if err != nil {
fmt.Printf("failed to init config: %s", err.Error()) fmt.Printf("failed to init config: %s", err.Error())
os.Exit(2) os.Exit(2)

View File

@@ -1,4 +1,4 @@
package application package config
import ( import (
"context" "context"
@@ -27,6 +27,22 @@ func NewConfig(ctx context.Context) (Config, error) {
type Config struct { type Config struct {
DB DB `env:",prefix=DB_"` DB DB `env:",prefix=DB_"`
Logging Logging `env:",prefix=LOGGING_"` Logging Logging `env:",prefix=LOGGING_"`
API API `env:",prefix=API_"`
PDF PDF `env:",prefix=PDF_"`
}
type PDF struct {
Landscape bool `env:"LANDSCAPE,default=false"`
Grayscale bool `env:"GRAYSCALE,default=false"`
MediaPrint bool `env:"MEDIA_PRINT,default=true"`
Zoom float64 `env:"ZOOM,default=1"`
Viewport string `env:"VIEWPORT,default=1920x1080"`
DPI uint `env:"DPI,default=300"`
Filename string `env:"FILENAME,default=page.pdf"`
}
type API struct {
Address string `env:"ADDRESS,default=0.0.0.0:5001"`
} }
type DB struct { type DB struct {

View File

@@ -1,4 +1,4 @@
package application package config
import ( import (
"context" "context"