mirror of
https://github.com/go-shiori/shiori.git
synced 2025-09-13 00:16:34 +08:00
* 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
99 lines
2.2 KiB
Go
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
|
|
}
|