Skip to content

Commit 611b1df

Browse files
authored
Merge pull request #7 from xxxsen/xxxsen/feature/store_impl
Xxxsen/feature/store impl
2 parents 1136abd + 74c7919 commit 611b1df

12 files changed

+185
-221
lines changed

capture/capture.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func (c *Capture) doNaming(ctx context.Context, fc *model.FileContext) error {
203203

204204
func (c *Capture) doSaveData(ctx context.Context, fc *model.FileContext) error {
205205
//保存元数据并将影片移入指定目录
206-
if err := c.saveMediaData(fc); err != nil {
206+
if err := c.saveMediaData(ctx, fc); err != nil {
207207
return fmt.Errorf("save meta data failed, err:%w", err)
208208
}
209209
return nil
@@ -284,7 +284,7 @@ func (c *Capture) renameMetaField(fc *model.FileContext) error {
284284
return nil
285285
}
286286

287-
func (c *Capture) saveMediaData(fc *model.FileContext) error {
287+
func (c *Capture) saveMediaData(ctx context.Context, fc *model.FileContext) error {
288288
images := make([]*model.File, 0, len(fc.Meta.SampleImages)+2)
289289
if fc.Meta.Cover != nil {
290290
images = append(images, fc.Meta.Cover)
@@ -297,7 +297,7 @@ func (c *Capture) saveMediaData(fc *model.FileContext) error {
297297
target := filepath.Join(fc.SaveDir, image.Name)
298298
logger := logutil.GetLogger(context.Background()).With(zap.String("image", image.Name), zap.String("key", image.Key), zap.String("target", target))
299299

300-
data, err := store.GetDefault().GetData(image.Key)
300+
data, err := store.GetData(ctx, image.Key)
301301
if err != nil {
302302
logger.Error("read image data failed", zap.Error(err))
303303
return err

hasher/hasher.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package hasher
2+
3+
import (
4+
"crypto/md5"
5+
"encoding/hex"
6+
)
7+
8+
func ToMD5(in string) string {
9+
h := md5.New()
10+
_, _ = h.Write([]byte(in))
11+
return hex.EncodeToString(h.Sum(nil))
12+
}

main.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ func main() {
3838
if err := precheckDir(c); err != nil {
3939
logkit.Fatal("precheck dir failed", zap.Error(err))
4040
}
41-
if err := store.Init(filepath.Join(c.DataDir, "cache")); err != nil {
42-
logkit.Fatal("init store failed", zap.Error(err))
43-
}
41+
store.SetStorage(store.NewDiskStorage(filepath.Join(c.DataDir, "cache")))
4442
if err := translator.Init(); err != nil {
4543
logkit.Error("init translater failed", zap.Error(err))
4644
}

processor/handler/image_transcode_handler.go

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,22 @@ func (p *imageTranscodeHandler) transcode(ctx context.Context, name string, f *m
4040
return nil
4141
}
4242
logger = logger.With(zap.String("key", f.Key))
43-
data, err := store.GetDefault().GetData(f.Key)
44-
if err != nil {
45-
logger.Debug("read key data failed", zap.Error(err))
46-
return f //不丢弃, 后续处理的时候报错, 方便发现问题
47-
}
48-
raw, err := image.TranscodeToJpeg(data)
49-
if err != nil && strings.Contains(err.Error(), "luma/chroma subsampling ratio") && ffmpeg.IsFFMpegEnabled() {
50-
data, err = ffmpeg.ConvertToYuv420pJpegFromBytes(ctx, data)
51-
if err != nil {
52-
logger.Error("use ffmpeg to correct invalid image data failed", zap.Error(err))
53-
return nil
43+
44+
key, err := store.AnonymousDataRewrite(ctx, f.Key, func(ctx context.Context, data []byte) ([]byte, error) {
45+
raw, err := image.TranscodeToJpeg(data)
46+
if err != nil && strings.Contains(err.Error(), "luma/chroma subsampling ratio") && ffmpeg.IsFFMpegEnabled() {
47+
data, err = ffmpeg.ConvertToYuv420pJpegFromBytes(ctx, data)
48+
if err != nil {
49+
logger.Error("use ffmpeg to correct invalid image data failed", zap.Error(err))
50+
return nil, err
51+
}
52+
raw, err = image.TranscodeToJpeg(data)
5453
}
55-
raw, err = image.TranscodeToJpeg(data)
56-
}
57-
if err != nil {
58-
logger.Error("unable to convert image to jpeg format", zap.Error(err))
59-
return nil
60-
}
61-
key, err := store.GetDefault().Put(raw)
54+
return raw, err
55+
})
6256
if err != nil {
63-
logger.Error("store transcoded image data failed", zap.Error(err))
64-
return f //
57+
logger.Error("transcoded image data failed", zap.Error(err))
58+
return nil //
6559
}
6660
logger.Debug("transcode image succ", zap.String("new_key", key))
6761
f.Key = key

processor/handler/poster_crop_handler.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,9 @@ func (c *posterCropHandler) Handle(ctx context.Context, fc *model.FileContext) e
4646
if fc.Number.GetIsUncensorMovie() && face.IsFaceRecognizeEnabled() { //如果为步兵, 则使用人脸识别(当然, 只有该特性能用的情况下才启用)
4747
cutter = c.wrapCutImageWithFaceRec(ctx, image.CutCensoredImageFromBytes)
4848
}
49-
data, err := store.GetDefault().GetData(fc.Meta.Cover.Key)
50-
if err != nil {
51-
return fmt.Errorf("get cover data failed, err:%w, key:%s", err, fc.Meta.Cover.Key)
52-
}
53-
res, err := cutter(data)
54-
if err != nil {
55-
return fmt.Errorf("cut poster image failed, err:%w", err)
56-
}
57-
key, err := store.GetDefault().Put(res)
49+
key, err := store.AnonymousDataRewrite(ctx, fc.Meta.Cover.Key, func(ctx context.Context, data []byte) ([]byte, error) {
50+
return cutter(data)
51+
})
5852
if err != nil {
5953
return fmt.Errorf("save cutted poster data failed, err:%w", err)
6054
}

processor/handler/watermark_handler.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ func (h *watermark) Handle(ctx context.Context, fc *model.FileContext) error {
1717
if fc.Meta.Poster == nil || len(fc.Meta.Poster.Key) == 0 {
1818
return nil
1919
}
20-
data, err := store.GetDefault().GetData(fc.Meta.Poster.Key)
21-
if err != nil {
22-
return fmt.Errorf("load poster key failed, key:%s", fc.Meta.Poster.Key)
23-
}
2420
tags := make([]image.Watermark, 0, 5)
2521
if fc.Number.GetIs4K() {
2622
tags = append(tags, image.WM4K)
@@ -38,11 +34,9 @@ func (h *watermark) Handle(ctx context.Context, fc *model.FileContext) error {
3834
logutil.GetLogger(ctx).Debug("no watermark tag found, skip watermark proc")
3935
return nil
4036
}
41-
newData, err := image.AddWatermarkFromBytes(data, tags)
42-
if err != nil {
43-
return fmt.Errorf("add watermark failed, err:%w", err)
44-
}
45-
key, err := store.GetDefault().Put(newData)
37+
key, err := store.AnonymousDataRewrite(ctx, fc.Meta.Poster.Key, func(ctx context.Context, data []byte) ([]byte, error) {
38+
return image.AddWatermarkFromBytes(data, tags)
39+
})
4640
if err != nil {
4741
return fmt.Errorf("save watermarked image failed, err:%w", err)
4842
}

searcher/default_searcher.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ package searcher
22

33
import (
44
"context"
5-
"crypto/md5"
6-
"encoding/hex"
75
"fmt"
86
"net/http"
97
"strings"
108
"time"
119
"yamdc/client"
10+
"yamdc/hasher"
1211
"yamdc/model"
1312
"yamdc/number"
1413
"yamdc/searcher/plugin"
@@ -230,8 +229,8 @@ func (p *DefaultSearcher) saveRemoteURLData(ctx *plugin.PluginContext, urls []st
230229
continue
231230
}
232231
logger := logutil.GetLogger(context.Background()).With(zap.String("url", url))
233-
key := p.buildURLCacheKey(url)
234-
if store.GetDefault().IsCacheExist(key) {
232+
key := hasher.ToMD5(url)
233+
if ok, _ := store.IsDataExist(ctx.GetContext(), key); ok {
235234
rs[url] = key
236235
continue
237236
}
@@ -240,7 +239,7 @@ func (p *DefaultSearcher) saveRemoteURLData(ctx *plugin.PluginContext, urls []st
240239
logger.Error("fetch image data failed", zap.Error(err))
241240
continue
242241
}
243-
err = store.GetDefault().PutWithNamingKey(key, data)
242+
err = store.PutData(ctx.GetContext(), key, data)
244243
if err != nil {
245244
logger.Error("put image data to store failed", zap.Error(err))
246245
}
@@ -249,14 +248,6 @@ func (p *DefaultSearcher) saveRemoteURLData(ctx *plugin.PluginContext, urls []st
249248
return rs
250249
}
251250

252-
func (p *DefaultSearcher) buildURLCacheKey(url string) string {
253-
h := md5.New()
254-
_, _ = h.Write([]byte(url))
255-
hashsum := hex.EncodeToString(h.Sum(nil))
256-
key := fmt.Sprintf("avc:search:cache:url:%s:%s", p.name, hashsum)
257-
return key
258-
}
259-
260251
func (p *DefaultSearcher) fetchImageData(ctx *plugin.PluginContext, url string) ([]byte, error) {
261252
req, err := http.NewRequest(http.MethodGet, url, nil)
262253
if err != nil {

store/disk_storage.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package store
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"yamdc/hasher"
9+
)
10+
11+
type diskStorage struct {
12+
dir string
13+
}
14+
15+
func NewDiskStorage(dir string) IStorage {
16+
return &diskStorage{dir: dir}
17+
}
18+
19+
func (s *diskStorage) generateStorePath(key string) string {
20+
save := hasher.ToMD5(key)
21+
p1 := save[:2]
22+
p2 := save[2:4]
23+
p3 := save[4:6]
24+
return filepath.Join(s.dir, p1, p2, p3, save)
25+
}
26+
27+
func (s *diskStorage) GetData(ctx context.Context, key string) ([]byte, error) {
28+
return os.ReadFile(s.generateStorePath(key))
29+
}
30+
31+
func (s *diskStorage) PutData(ctx context.Context, key string, value []byte) error {
32+
p := s.generateStorePath(key)
33+
dir := filepath.Dir(p)
34+
if err := os.MkdirAll(dir, 0755); err != nil {
35+
return fmt.Errorf("create dir failed, err:%w", err)
36+
}
37+
if err := os.WriteFile(p, value, 0644); err != nil {
38+
return fmt.Errorf("write data failed, err:%w", err)
39+
}
40+
return nil
41+
}
42+
43+
func (s *diskStorage) IsDataExist(ctx context.Context, key string) (bool, error) {
44+
p := s.generateStorePath(key)
45+
_, err := os.Stat(p)
46+
if err == nil {
47+
return true, nil
48+
}
49+
if os.IsNotExist(err) {
50+
return false, nil
51+
}
52+
return false, err
53+
}

store/disk_storage_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package store
2+
3+
import (
4+
"context"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestDiskStorage(t *testing.T) {
13+
dir := filepath.Join(os.TempDir(), "storage")
14+
st := NewDiskStorage(dir)
15+
ctx := context.Background()
16+
key := "aaa"
17+
value := []byte("hello world")
18+
err := st.PutData(ctx, key, value)
19+
assert.NoError(t, err)
20+
exist, err := st.IsDataExist(ctx, key)
21+
assert.NoError(t, err)
22+
assert.True(t, exist)
23+
data, err := st.GetData(ctx, key)
24+
assert.NoError(t, err)
25+
assert.Equal(t, value, data)
26+
27+
//check not exist
28+
exist, err = st.IsDataExist(ctx, "hello")
29+
assert.NoError(t, err)
30+
assert.False(t, exist)
31+
}

store/storage.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package store
2+
3+
import (
4+
"context"
5+
6+
"github.com/google/uuid"
7+
)
8+
9+
type DataRewriteFunc func(ctx context.Context, data []byte) ([]byte, error)
10+
11+
type IStorage interface {
12+
GetData(ctx context.Context, key string) ([]byte, error)
13+
PutData(ctx context.Context, key string, value []byte) error
14+
IsDataExist(ctx context.Context, key string) (bool, error)
15+
}
16+
17+
var defaultInst IStorage
18+
19+
func SetStorage(impl IStorage) {
20+
defaultInst = impl
21+
}
22+
23+
func getDefaultInst() IStorage {
24+
return defaultInst
25+
}
26+
27+
func PutData(ctx context.Context, key string, value []byte) error {
28+
return getDefaultInst().PutData(ctx, key, value)
29+
}
30+
31+
func AnonymousPutData(ctx context.Context, value []byte) (string, error) {
32+
key := uuid.NewString()
33+
if err := PutData(ctx, key, value); err != nil {
34+
return "", err
35+
}
36+
return key, nil
37+
}
38+
39+
func GetData(ctx context.Context, key string) ([]byte, error) {
40+
return getDefaultInst().GetData(ctx, key)
41+
}
42+
43+
func IsDataExist(ctx context.Context, key string) (bool, error) {
44+
return getDefaultInst().IsDataExist(ctx, key)
45+
}
46+
47+
func AnonymousDataRewrite(ctx context.Context, key string, fn DataRewriteFunc) (string, error) {
48+
raw, err := GetData(ctx, key)
49+
if err != nil {
50+
return key, err
51+
}
52+
newData, err := fn(ctx, raw)
53+
if err != nil {
54+
return key, err
55+
}
56+
newKey, err := AnonymousPutData(ctx, newData)
57+
if err != nil {
58+
return key, err
59+
}
60+
return newKey, nil
61+
}

0 commit comments

Comments
 (0)