Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ Features, that can buy you in:
- `KOMPANION_PG_URL` - postgresql link
- `KOMPANION_BSTORAGE_TYPE` - type of storage for books: postgres, memory, filesystem (default: postgres)
- `KOMPANION_BSTORAGE_PATH` - path in case of filesystem
- `KOMPANION_STATS_TYPE` - type of temporary storage for uploaded sqlite3 stats files: postgres, memory, filesystem (default: memory)
- `KOMPANION_STATS_PATH` - path in case of filesystem

## Usage

Expand Down
35 changes: 5 additions & 30 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ type (
Log
PG
BookStorage
StatsStorage
}

// App -.
Expand Down Expand Up @@ -52,12 +51,6 @@ type (
Type string
Path string
}

// StatsStorage -.
StatsStorage struct {
Type string
Path string
}
)

// NewConfig - reads from env, validates and returns the config.
Expand Down Expand Up @@ -87,22 +80,16 @@ func NewConfig(version string) (*Config, error) {
return nil, err
}

statsStorage, err := readStatsStorageConfig()
if err != nil {
return nil, err
}

return &Config{
App: App{
Name: "kompanion",
Version: version,
},
Auth: auth,
HTTP: http,
Log: log,
PG: postgres,
BookStorage: bookStorage,
StatsStorage: statsStorage,
Auth: auth,
HTTP: http,
Log: log,
PG: postgres,
BookStorage: bookStorage,
}, nil
}

Expand Down Expand Up @@ -184,18 +171,6 @@ func readBookStorageConfig() (BookStorage, error) {
}, nil
}

func readStatsStorageConfig() (StatsStorage, error) {
stats_type := readPrefixedEnv("STATS_TYPE")
if stats_type == "" {
stats_type = "postgres"
}
stats_path := readPrefixedEnv("STATS_PATH")
return StatsStorage{
Type: stats_type,
Path: stats_path,
}, nil
}

func readPrefixedEnv(key string) string {
envKey := fmt.Sprintf("KOMPANION_%s", strings.ToUpper(key))
return os.Getenv(envKey)
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ services:
- ./data:/data
environment:
KOMPANION_PG_URL: 'postgres://user:pass@postgres:5432/postgres'
KOMPANION_STATS_PATH: '/data/stats/'
KOMPANION_BSTORAGE_PATH: '/data/books/'
KOMPANION_AUTH_USERNAME: 'user'
KOMPANION_AUTH_PASSWORD: 'password'
Expand Down
10 changes: 10 additions & 0 deletions integration-test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,16 @@ func TestWebStats(t *testing.T) {
Expect().Status().Equal(http.StatusOK),
Expect().Body().String().Contains("Crime and Punishment"),
)

// regress for uploading same file
// https://github.com/vanadium23/kompanion/issues/22
Test(t,
Description("Kompanion Upload Stats via WebDAV"),
Put(basePath+"/webdav/statistics.sqlite3"),
Send().Headers("Authorization").Add(basicAuth),
Send().Body().Bytes(statsContent),
Expect().Status().Equal(http.StatusCreated),
)
}

// HTTP test kompanion shelf feature
Expand Down
8 changes: 2 additions & 6 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ func Run(cfg *config.Config) {
if err != nil {
l.Fatal(fmt.Errorf("app - Run - storage.NewStorage: %w", err))
}
statsStorage, err := storage.NewStorage(cfg.StatsStorage.Type, cfg.StatsStorage.Path, pg)
if err != nil {
l.Fatal(fmt.Errorf("app - Run - storage.NewStorage: %w", err))
}

// Use case
var repo auth.UserRepo
Expand All @@ -61,14 +57,14 @@ func Run(cfg *config.Config) {
)
progress := sync.NewProgressSync(sync.NewProgressDatabaseRepo(pg))
shelf := library.NewBookShelf(bookStorage, library.NewBookDatabaseRepo(pg), l)
rs := stats.NewKOReaderStats(statsStorage, pg)
rs := stats.NewKOReaderPGStats(pg)

// HTTP Server
handler := gin.New()
web.NewRouter(handler, l, authService, progress, shelf, rs, cfg.Version)
v1.NewRouter(handler, l, authService, progress, shelf)
opds.NewRouter(handler, l, authService, progress, shelf)
webdav.NewRouter(handler, authService, l, rs, cfg.StatsStorage.Path)
webdav.NewRouter(handler, authService, l, rs)
httpServer := httpserver.New(handler, httpserver.Port(cfg.HTTP.Port))

// Waiting signal
Expand Down
1 change: 0 additions & 1 deletion internal/controller/http/webdav/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ func NewRouter(
a auth.AuthInterface,
l logger.Interface,
rs stats.ReadingStats,
dirPath string,
) {
// Options
handler.Use(gin.Logger())
Expand Down
2 changes: 0 additions & 2 deletions internal/stats/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"errors"
"io"
"os"
"time"
)

Expand All @@ -28,5 +27,4 @@ type ReadingStats interface {
GetGeneralStats(ctx context.Context, from, to time.Time) (*GeneralStats, error)
GetDailyStats(ctx context.Context, from, to time.Time) ([]DailyStats, error)
Write(ctx context.Context, r io.ReadCloser, deviceName string) error
Read(ctx context.Context) (*os.File, error)
}
40 changes: 8 additions & 32 deletions internal/stats/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,26 @@ package stats

import (
"context"
"errors"
"fmt"
"io"
"os"
"sync"
"time"

"github.com/vanadium23/kompanion/internal/storage"
"github.com/vanadium23/kompanion/pkg/postgres"
)

const KOReaderFile = "statistics.sqlite3"

// KOReaderStats implements ReadingStats interface
type KOReaderStats struct {
rw sync.RWMutex
st storage.Storage
// KOReaderPGStats implements ReadingStats interface
type KOReaderPGStats struct {
pg *postgres.Postgres
}

func NewKOReaderStats(st storage.Storage, pg *postgres.Postgres) *KOReaderStats {
return &KOReaderStats{st: st, rw: sync.RWMutex{}, pg: pg}
func NewKOReaderPGStats(pg *postgres.Postgres) *KOReaderPGStats {
return &KOReaderPGStats{pg: pg}
}

func (s *KOReaderStats) Read(ctx context.Context) (*os.File, error) {
s.rw.RLock()
stats, err := s.st.Read(ctx, KOReaderFile)
s.rw.RUnlock()
if errors.Is(err, storage.ErrNotFound) {
return nil, ErrEmptyStats
}
if err != nil {
return nil, err
}
return stats, nil
}

func (s *KOReaderStats) Write(ctx context.Context, r io.ReadCloser, deviceName string) error {
func (s *KOReaderPGStats) Write(ctx context.Context, r io.ReadCloser, deviceName string) error {
// make by temp files
tempFile, err := os.CreateTemp("", fmt.Sprintf("%s-", deviceName))
if err != nil {
Expand All @@ -53,12 +35,6 @@ func (s *KOReaderStats) Write(ctx context.Context, r io.ReadCloser, deviceName s
return err
}

s.rw.Lock()
err = s.st.Write(ctx, tempFile.Name(), KOReaderFile)
s.rw.Unlock()
if err != nil {
return err
}
go SyncDatabases(filepath, s.pg, deviceName)
return nil
}
Expand All @@ -70,7 +46,7 @@ type BookStats struct {
TotalReadDays int
}

func (s *KOReaderStats) GetBookStats(ctx context.Context, fileHash string) (*BookStats, error) {
func (s *KOReaderPGStats) GetBookStats(ctx context.Context, fileHash string) (*BookStats, error) {
query := `
WITH daily_reads AS (
SELECT DISTINCT DATE(start_time) as read_date
Expand Down Expand Up @@ -102,7 +78,7 @@ func (s *KOReaderStats) GetBookStats(ctx context.Context, fileHash string) (*Boo
return &stats, nil
}

func (s *KOReaderStats) GetGeneralStats(ctx context.Context, from, to time.Time) (*GeneralStats, error) {
func (s *KOReaderPGStats) GetGeneralStats(ctx context.Context, from, to time.Time) (*GeneralStats, error) {
var stats GeneralStats

// Get per book statistics
Expand Down Expand Up @@ -163,7 +139,7 @@ type DailyStats struct {
AvgDurationPerPage float64
}

func (s *KOReaderStats) GetDailyStats(ctx context.Context, from, to time.Time) ([]DailyStats, error) {
func (s *KOReaderPGStats) GetDailyStats(ctx context.Context, from, to time.Time) ([]DailyStats, error) {
query := `
WITH RECURSIVE dates AS (
SELECT date_trunc('day', $1::timestamp)::date as date
Expand Down
Loading