feat: add media store and store medias

This commit is contained in:
Rogee
2024-12-05 10:15:09 +08:00
parent 5bdf8abb38
commit 9ddd3f61ec
5 changed files with 158 additions and 87 deletions

View File

@@ -0,0 +1,80 @@
package media_store
import (
"encoding/json"
"os"
"path/filepath"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
type Store []UUIDMap
type UUIDMap struct {
UUID string
Name string
}
func NewStore(path string) (*Store, error) {
mapFile := filepath.Join(path, "map.json")
log.Infof("read in from: %s", mapFile)
if _, err := os.Stat(mapFile); err != nil {
if os.IsNotExist(err) {
if err := os.WriteFile(mapFile, []byte("[]"), os.ModePerm); err != nil {
return nil, errors.Wrapf(err, "write file: %s", mapFile)
}
}
}
b, err := os.ReadFile(mapFile)
if err != nil {
return nil, errors.Wrapf(err, "read file: %s", mapFile)
}
var store Store
err = json.Unmarshal(b, &store)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal json: %s", mapFile)
}
return &store, nil
}
func (s *Store) Save(path string) error {
mapFile := filepath.Join(path, "map.json")
b, err := json.Marshal(s)
if err != nil {
return errors.Wrapf(err, "marshal json: %s", mapFile)
}
if err := os.WriteFile(mapFile, b, os.ModePerm); err != nil {
return errors.Wrapf(err, "write file: %s", mapFile)
}
return nil
}
func (s *Store) Add(uuid, name string) {
*s = append(*s, UUIDMap{UUID: uuid, Name: name})
}
func (s *Store) UUIDs() []string {
var uuids []string
for _, m := range *s {
uuids = append(uuids, m.UUID)
}
return uuids
}
// Exists
func (s *Store) Exists(name string) bool {
for _, m := range *s {
if m.Name == name {
return true
}
}
return false
}

View File

@@ -1,17 +1,17 @@
package discover package discover
import ( import (
"encoding/json"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"backend/common/media_store"
"backend/modules/medias" "backend/modules/medias"
"backend/pkg/path"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/samber/lo"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -21,11 +21,6 @@ type DiscoverMedias struct {
log *log.Entry `inject:"false"` log *log.Entry `inject:"false"`
} }
type MediaUuidMap struct {
UUID string
Name string
}
// Prepare // Prepare
func (d *DiscoverMedias) Prepare() error { func (d *DiscoverMedias) Prepare() error {
d.log = log.WithField("module", "DiscoverMedias") d.log = log.WithField("module", "DiscoverMedias")
@@ -38,36 +33,15 @@ func (d *DiscoverMedias) RunE(from, to string) error {
return errors.New("from or to is empty") return errors.New("from or to is empty")
} }
mapFile := filepath.Join(to, "map.json") store, err := media_store.NewStore(to)
d.log.Infof("read in from: %s", mapFile)
if _, err := os.Stat(mapFile); err != nil {
if os.IsNotExist(err) {
if err := os.WriteFile(mapFile, []byte("[]"), os.ModePerm); err != nil {
return errors.Wrapf(err, "write file: %s", mapFile)
}
}
}
b, err := os.ReadFile(mapFile)
if err != nil { if err != nil {
return errors.Wrapf(err, "read file: %s", mapFile) return errors.Wrapf(err, "new store: %s", to)
}
var store []MediaUuidMap
err = json.Unmarshal(b, &store)
if err != nil {
return errors.Wrapf(err, "unmarshal json: %s", mapFile)
} }
defer func() { defer func() {
d.runCleanup(to, store) d.runCleanup(to)
}() }()
storeMap := make(map[string]string) dirs, err := path.GetSubDirs(from)
for _, item := range store {
storeMap[item.Name] = item.UUID
}
dirs, err := d.getSubDirs(from)
if err != nil { if err != nil {
return errors.Wrapf(err, "get sub dirs: %s", from) return errors.Wrapf(err, "get sub dirs: %s", from)
} }
@@ -75,7 +49,7 @@ func (d *DiscoverMedias) RunE(from, to string) error {
for _, dir := range dirs { for _, dir := range dirs {
d.log.Infof("Discover medias in: %s", dir) d.log.Infof("Discover medias in: %s", dir)
if _, ok := storeMap[dir]; ok { if exists := store.Exists(dir); exists {
d.log.Infof("Skip dir: %s", dir) d.log.Infof("Skip dir: %s", dir)
continue continue
} }
@@ -103,47 +77,15 @@ func (d *DiscoverMedias) RunE(from, to string) error {
} }
} }
store = append(store, MediaUuidMap{ store.Add(uuid, dir)
UUID: uuid, if err := store.Save(to); err != nil {
Name: dir, return errors.Wrapf(err, "store save: %s", to)
})
b, err := json.Marshal(store)
if err != nil {
return errors.Wrapf(err, "marshal json: %s", mapFile)
} }
if err := os.WriteFile(mapFile, b, os.ModePerm); err != nil {
return errors.Wrapf(err, "write file: %s", mapFile)
}
storeMap[dir] = uuid
d.log.Infof("Store map: %s", storeMap)
} }
return nil return nil
} }
func (d *DiscoverMedias) getSubDirs(root string) ([]string, error) {
fd, err := os.Open(root)
if err != nil {
return nil, errors.Wrapf(err, "open root directory: %s", root)
}
defer fd.Close()
entries, err := fd.Readdir(-1)
if err != nil {
return nil, errors.Wrapf(err, "read root directory: %s", root)
}
var paths []string
for _, entry := range entries {
if entry.IsDir() {
paths = append(paths, entry.Name())
}
}
return paths, nil
}
func (d *DiscoverMedias) globVideo(root string) []string { func (d *DiscoverMedias) globVideo(root string) []string {
files := []string{} files := []string{}
@@ -247,23 +189,27 @@ func (d *DiscoverMedias) ffmpegAudioToM3U8(input string, output string) error {
return nil return nil
} }
func (d *DiscoverMedias) runCleanup(to string, store []MediaUuidMap) { func (d *DiscoverMedias) runCleanup(to string) {
uuids := lo.Map(store, func(item MediaUuidMap, _ int) string { store, err := media_store.NewStore(to)
return item.UUID if err != nil {
}) d.log.Errorf("new store: %s", to)
return
}
dirs, err := d.getSubDirs(to) dirs, err := path.GetSubDirs(to)
if err != nil { if err != nil {
d.log.Errorf("get sub dirs: %s", to) d.log.Errorf("get sub dirs: %s", to)
return return
} }
for _, dir := range dirs { for _, dir := range dirs {
if !lo.Contains(uuids, dir) { if store.Exists(dir) {
d.log.Infof("Remove dir: %s", dir) continue
if err := os.RemoveAll(filepath.Join(to, dir)); err != nil { }
d.log.Errorf("Remove dir: %s", dir)
} d.log.Infof("Remove dir: %s", dir)
if err := os.RemoveAll(filepath.Join(to, dir)); err != nil {
d.log.Errorf("Remove dir: %s", dir)
} }
} }
} }

View File

@@ -36,15 +36,6 @@ func Test_DiscoverMedias(t *testing.T) {
}) })
} }
func (t *DiscoverMediasTestSuite) Test_getSubDirs() {
Convey("Test_getSubDirs", t.T(), func() {
dirs, err := t.Svc.getSubDirs("/mnt/yangpingliang/动态曲谱")
So(err, ShouldBeNil)
t.T().Logf("Dirs: %+v", dirs)
})
}
func (t *DiscoverMediasTestSuite) Test_getVideo() { func (t *DiscoverMediasTestSuite) Test_getVideo() {
Convey("Test_getVideo", t.T(), func() { Convey("Test_getVideo", t.T(), func() {
dirs := t.Svc.globVideo("/mnt/yangpingliang/动态曲谱/河北梆子伴奏《李慧娘》依然还我生前摸样") dirs := t.Svc.globVideo("/mnt/yangpingliang/动态曲谱/河北梆子伴奏《李慧娘》依然还我生前摸样")

View File

@@ -0,0 +1,25 @@
package store
import (
"backend/modules/medias"
log "github.com/sirupsen/logrus"
)
// @provider
type StoreMedias struct {
mediasSvc *medias.Service
log *log.Entry `inject:"false"`
}
// Prepare
func (d *StoreMedias) Prepare() error {
d.log = log.WithField("module", "StoreMedias")
return nil
}
func (d *StoreMedias) RunE(targetPath string) error {
d.log.Infof("Store medias from: %s ", targetPath)
return nil
}

29
backend/pkg/path/fs.go Normal file
View File

@@ -0,0 +1,29 @@
package path
import (
"os"
"github.com/pkg/errors"
)
func GetSubDirs(root string) ([]string, error) {
fd, err := os.Open(root)
if err != nil {
return nil, errors.Wrapf(err, "open root directory: %s", root)
}
defer fd.Close()
entries, err := fd.Readdir(-1)
if err != nil {
return nil, errors.Wrapf(err, "read root directory: %s", root)
}
var paths []string
for _, entry := range entries {
if entry.IsDir() {
paths = append(paths, entry.Name())
}
}
return paths, nil
}