shiori/internal/domains/storage.go
Felipe Martin cc7c75116d
refactor: migrate bookmark static pages to new http server (#775)
* migrate bookmark content route to new http server

* new archive page

* remove unused go generate comment

* database mock

* utils cleanup

* unused var

* domains refactor and tests

* fixed secret key type

* redirect to login on ui errors

* fixed archive folder with storage domain

* webroot documentation

* some bookmark route tests

* fixed error in bookmark domain for non existant bookmarks

* centralice errors

* add coverage data to unittests

* added tests, refactor storage to use afero

* removed mock to avoid increasing complexity

* using deps to copy files around

* remove config usage (to deps)

* remove handler-ui file
2023-12-28 18:18:32 +01:00

99 lines
2.2 KiB
Go

package domains
import (
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"github.com/go-shiori/shiori/internal/dependencies"
"github.com/go-shiori/shiori/internal/model"
"github.com/spf13/afero"
)
type StorageDomain struct {
deps *dependencies.Dependencies
fs afero.Fs
}
func NewStorageDomain(deps *dependencies.Dependencies, fs afero.Fs) *StorageDomain {
return &StorageDomain{
deps: deps,
fs: fs,
}
}
// Stat returns the FileInfo structure describing file.
func (d *StorageDomain) Stat(name string) (fs.FileInfo, error) {
return d.fs.Stat(name)
}
// FS returns the filesystem used by this domain.
func (d *StorageDomain) FS() afero.Fs {
return d.fs
}
// FileExists checks if a file exists in storage.
func (d *StorageDomain) FileExists(name string) bool {
info, err := d.Stat(name)
return err == nil && !info.IsDir()
}
// DirExists checks if a directory exists in storage.
func (d *StorageDomain) DirExists(name string) bool {
info, err := d.Stat(name)
return err == nil && info.IsDir()
}
// WriteData writes bytes data to a file in storage.
// CAUTION: This function will overwrite existing file.
func (d *StorageDomain) WriteData(dst string, data []byte) error {
// Create directory if not exist
dir := filepath.Dir(dst)
if !d.DirExists(dir) {
err := d.fs.MkdirAll(dir, os.ModePerm)
if err != nil {
return err
}
}
// Create file
file, err := d.fs.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
return err
}
defer file.Close()
// Write data
_, err = file.Write(data)
return err
}
// WriteFile writes a file to storage.
func (d *StorageDomain) WriteFile(dst string, tmpFile *os.File) error {
if dst != "" && !d.DirExists(dst) {
err := d.fs.MkdirAll(filepath.Dir(dst), model.DataDirPerm)
if err != nil {
return fmt.Errorf("failed to create destination dir: %v", err)
}
}
dstFile, err := d.fs.Create(dst)
if err != nil {
return fmt.Errorf("failed to create destination file: %v", err)
}
defer dstFile.Close()
_, err = tmpFile.Seek(0, io.SeekStart)
if err != nil {
return fmt.Errorf("failed to rewind temporary file: %v", err)
}
_, err = io.Copy(dstFile, tmpFile)
if err != nil {
return fmt.Errorf("failed to copy file to the destination")
}
return nil
}