mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
[Files Refactor] Import export fixup (#2763)
* Adjust json schema * Remove mappings file from export * Import file/folder support * Update documentation * Make gallery filenames unique
This commit is contained in:
156
pkg/models/jsonschema/file_folder.go
Normal file
156
pkg/models/jsonschema/file_folder.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package jsonschema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/stashapp/stash/pkg/hash/md5"
|
||||
"github.com/stashapp/stash/pkg/models/json"
|
||||
)
|
||||
|
||||
const (
|
||||
DirEntryTypeFolder = "folder"
|
||||
DirEntryTypeVideo = "video"
|
||||
DirEntryTypeImage = "image"
|
||||
DirEntryTypeFile = "file"
|
||||
)
|
||||
|
||||
type DirEntry interface {
|
||||
IsFile() bool
|
||||
Filename() string
|
||||
DirEntry() *BaseDirEntry
|
||||
}
|
||||
|
||||
type BaseDirEntry struct {
|
||||
ZipFile string `json:"zip_file,omitempty"`
|
||||
ModTime json.JSONTime `json:"mod_time"`
|
||||
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
Path string `json:"path,omitempty"`
|
||||
|
||||
CreatedAt json.JSONTime `json:"created_at,omitempty"`
|
||||
UpdatedAt json.JSONTime `json:"updated_at,omitempty"`
|
||||
}
|
||||
|
||||
func (f *BaseDirEntry) DirEntry() *BaseDirEntry {
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *BaseDirEntry) IsFile() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *BaseDirEntry) Filename() string {
|
||||
// prefix with the path depth so that we can import lower-level files/folders first
|
||||
depth := strings.Count(f.Path, string("/"))
|
||||
|
||||
// hash the full path for a unique filename
|
||||
hash := md5.FromString(f.Path)
|
||||
|
||||
basename := path.Base(f.Path)
|
||||
|
||||
return fmt.Sprintf("%02x.%s.%s.json", depth, basename, hash)
|
||||
}
|
||||
|
||||
type BaseFile struct {
|
||||
BaseDirEntry
|
||||
|
||||
Fingerprints []Fingerprint `json:"fingerprints,omitempty"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
func (f *BaseFile) IsFile() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type Fingerprint struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Fingerprint interface{} `json:"fingerprint,omitempty"`
|
||||
}
|
||||
|
||||
type VideoFile struct {
|
||||
*BaseFile
|
||||
Format string `json:"format,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
Duration float64 `json:"duration,omitempty"`
|
||||
VideoCodec string `json:"video_codec,omitempty"`
|
||||
AudioCodec string `json:"audio_codec,omitempty"`
|
||||
FrameRate float64 `json:"frame_rate,omitempty"`
|
||||
BitRate int64 `json:"bitrate,omitempty"`
|
||||
|
||||
Interactive bool `json:"interactive,omitempty"`
|
||||
InteractiveSpeed *int `json:"interactive_speed,omitempty"`
|
||||
}
|
||||
|
||||
type ImageFile struct {
|
||||
*BaseFile
|
||||
Format string `json:"format,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
}
|
||||
|
||||
func LoadFileFile(filePath string) (DirEntry, error) {
|
||||
r, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
jsonParser := json.NewDecoder(bytes.NewReader(data))
|
||||
|
||||
var bf BaseDirEntry
|
||||
if err := jsonParser.Decode(&bf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jsonParser = json.NewDecoder(bytes.NewReader(data))
|
||||
|
||||
switch bf.Type {
|
||||
case DirEntryTypeFolder:
|
||||
return &bf, nil
|
||||
case DirEntryTypeVideo:
|
||||
var vf VideoFile
|
||||
if err := jsonParser.Decode(&vf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &vf, nil
|
||||
case DirEntryTypeImage:
|
||||
var imf ImageFile
|
||||
if err := jsonParser.Decode(&imf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &imf, nil
|
||||
case DirEntryTypeFile:
|
||||
var bff BaseFile
|
||||
if err := jsonParser.Decode(&bff); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &bff, nil
|
||||
default:
|
||||
return nil, errors.New("unknown file type")
|
||||
}
|
||||
}
|
||||
|
||||
func SaveFileFile(filePath string, file DirEntry) error {
|
||||
if file == nil {
|
||||
return fmt.Errorf("file must not be nil")
|
||||
}
|
||||
return marshalToFile(filePath, file)
|
||||
}
|
||||
Reference in New Issue
Block a user