Init V4 community edition (#2265)
* Init V4 community edition * Init V4 community edition
This commit is contained in:
106
pkg/mediameta/extractor.go
Normal file
106
pkg/mediameta/extractor.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package mediameta
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/driver"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/manager/entitysource"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/samber/lo"
|
||||
"io"
|
||||
)
|
||||
|
||||
type (
|
||||
Extractor interface {
|
||||
// Exts returns the supported file extensions.
|
||||
Exts() []string
|
||||
// Extract extracts the media meta from the given source.
|
||||
Extract(ctx context.Context, ext string, source entitysource.EntitySource) ([]driver.MediaMeta, error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileTooLarge = errors.New("file too large")
|
||||
)
|
||||
|
||||
func init() {
|
||||
gob.Register([]driver.MediaMeta{})
|
||||
}
|
||||
|
||||
func NewExtractorManager(ctx context.Context, settings setting.Provider, l logging.Logger) Extractor {
|
||||
e := &extractorManager{
|
||||
settings: settings,
|
||||
extMap: make(map[string][]Extractor),
|
||||
}
|
||||
|
||||
extractors := []Extractor{}
|
||||
|
||||
if e.settings.MediaMetaExifEnabled(ctx) {
|
||||
exifE := newExifExtractor(settings, l)
|
||||
extractors = append(extractors, exifE)
|
||||
}
|
||||
|
||||
if e.settings.MediaMetaMusicEnabled(ctx) {
|
||||
musicE := newMusicExtractor(settings, l)
|
||||
extractors = append(extractors, musicE)
|
||||
}
|
||||
|
||||
if e.settings.MediaMetaFFProbeEnabled(ctx) {
|
||||
ffprobeE := newFFProbeExtractor(settings, l)
|
||||
extractors = append(extractors, ffprobeE)
|
||||
}
|
||||
|
||||
for _, extractor := range extractors {
|
||||
for _, ext := range extractor.Exts() {
|
||||
if e.extMap[ext] == nil {
|
||||
e.extMap[ext] = []Extractor{}
|
||||
}
|
||||
e.extMap[ext] = append(e.extMap[ext], extractor)
|
||||
}
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
type extractorManager struct {
|
||||
settings setting.Provider
|
||||
extMap map[string][]Extractor
|
||||
}
|
||||
|
||||
func (e *extractorManager) Exts() []string {
|
||||
return lo.Keys(e.extMap)
|
||||
}
|
||||
|
||||
func (e *extractorManager) Extract(ctx context.Context, ext string, source entitysource.EntitySource) ([]driver.MediaMeta, error) {
|
||||
if extractor, ok := e.extMap[ext]; ok {
|
||||
res := []driver.MediaMeta{}
|
||||
for _, e := range extractor {
|
||||
_, _ = source.Seek(0, io.SeekStart)
|
||||
data, err := e.Extract(ctx, ext, source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = append(res, data...)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// checkFileSize checks if the file size exceeds the limit.
|
||||
func checkFileSize(localLimit, remoteLimit int64, source entitysource.EntitySource) error {
|
||||
if source.IsLocal() && localLimit > 0 && source.Entity().Size() > localLimit {
|
||||
return ErrFileTooLarge
|
||||
}
|
||||
|
||||
if !source.IsLocal() && remoteLimit > 0 && source.Entity().Size() > remoteLimit {
|
||||
return ErrFileTooLarge
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user