diff --git a/README.md b/README.md index 0598f24..6a7d7b7 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/config/config.go b/config/config.go index 396e119..008200b 100644 --- a/config/config.go +++ b/config/config.go @@ -16,7 +16,6 @@ type ( Log PG BookStorage - StatsStorage } // App -. @@ -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. @@ -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 } @@ -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) diff --git a/docker-compose.yml b/docker-compose.yml index 6ef7bae..07e73c6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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' diff --git a/integration-test/integration_test.go b/integration-test/integration_test.go index 70a137f..3b61f76 100644 --- a/integration-test/integration_test.go +++ b/integration-test/integration_test.go @@ -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 diff --git a/internal/app/app.go b/internal/app/app.go index dfca835..764e546 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -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 @@ -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 diff --git a/internal/controller/http/webdav/router.go b/internal/controller/http/webdav/router.go index 0e5ae6e..5430de0 100644 --- a/internal/controller/http/webdav/router.go +++ b/internal/controller/http/webdav/router.go @@ -14,7 +14,6 @@ func NewRouter( a auth.AuthInterface, l logger.Interface, rs stats.ReadingStats, - dirPath string, ) { // Options handler.Use(gin.Logger()) diff --git a/internal/stats/interface.go b/internal/stats/interface.go index bb6b031..9d0a34c 100644 --- a/internal/stats/interface.go +++ b/internal/stats/interface.go @@ -4,7 +4,6 @@ import ( "context" "errors" "io" - "os" "time" ) @@ -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) } diff --git a/internal/stats/stats.go b/internal/stats/stats.go index a221dbc..57a2b8a 100644 --- a/internal/stats/stats.go +++ b/internal/stats/stats.go @@ -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 { @@ -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 } @@ -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 @@ -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 @@ -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