Skip to content

Commit ab5d04f

Browse files
authored
Merge pull request #43 from satisfactorymodding/staging
feat: mod asset listing
2 parents 0eef1d8 + 89860fa commit ab5d04f

File tree

9 files changed

+154
-24
lines changed

9 files changed

+154
-24
lines changed

db/postgres/mod.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func GetModCountNew(ctx context.Context, filter *models.ModFilter, unapproved bo
121121

122122
func IncrementModViews(ctx context.Context, mod *Mod) {
123123
// TODO unignore
124-
//DBCtx(ctx).Model(mod).Update("views", mod.Views+1)
124+
// DBCtx(ctx).Model(mod).Update("views", mod.Views+1)
125125
}
126126

127127
func GetMods(ctx context.Context, limit int, offset int, orderBy string, order string, search string, unapproved bool) []Mod {

gql/gql_utils.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package gql
22

33
import (
44
"context"
5+
"fmt"
56
"net"
67
"net/http"
78
"strings"
89
"time"
910

11+
"go.opentelemetry.io/otel"
12+
"go.opentelemetry.io/otel/attribute"
1013
"go.opentelemetry.io/otel/trace"
1114

1215
"github.com/satisfactorymodding/smr-api/db/postgres"
@@ -27,22 +30,22 @@ func WrapMutationTrace(ctx context.Context, action string) (TraceWrapper, contex
2730
}
2831

2932
func wrapTrace(ctx context.Context, action string, actionType string) (TraceWrapper, context.Context) {
30-
// spanCtx, span := otel.Tracer("gql").Start(ctx, "GraphQL "+action, trace.WithAttributes(
31-
// attribute.String("action_type", "API.graphql."+actionType),
32-
//))
33+
spanCtx, span := otel.Tracer("gql").Start(ctx, "GraphQL "+action, trace.WithAttributes(
34+
attribute.String("action_type", "API.graphql."+actionType),
35+
))
3336

3437
return TraceWrapper{
35-
// Span: span,
36-
}, ctx
38+
Span: span,
39+
}, spanCtx
3740
}
3841

3942
func (wrapper TraceWrapper) end() {
40-
// defer wrapper.Span.End()
41-
//
42-
//if err := recover(); err != nil {
43-
// wrapper.Span.RecordError(fmt.Errorf("panic: %v", err))
44-
// panic(err)
45-
//}
43+
defer wrapper.Span.End()
44+
45+
if err := recover(); err != nil {
46+
wrapper.Span.RecordError(fmt.Errorf("panic: %v", err))
47+
panic(err)
48+
}
4649
}
4750

4851
// SetStringINNOE sets target if value not nil or empty

gql/resolver_mods.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,22 @@ func (r *queryResolver) ResolveModVersions(ctx context.Context, filter []*genera
619619

620620
return modVersions, nil
621621
}
622+
623+
func (r *queryResolver) GetModAssetList(ctx context.Context, modReference string) ([]string, error) {
624+
wrapper, _ := WrapQueryTrace(ctx, "getModAssetList")
625+
defer wrapper.end()
626+
627+
list := redis.GetModAssetList(modReference)
628+
if list != nil {
629+
return list, nil
630+
}
631+
632+
assets, err := storage.ListModAssets(modReference)
633+
if err != nil {
634+
return nil, err
635+
}
636+
637+
redis.StoreModAssetList(modReference, assets)
638+
639+
return assets, nil
640+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package code
2+
3+
import (
4+
"context"
5+
"strings"
6+
7+
"github.com/lab259/go-migration"
8+
"github.com/rs/zerolog/log"
9+
10+
"github.com/satisfactorymodding/smr-api/db/postgres"
11+
"github.com/satisfactorymodding/smr-api/migrations/utils"
12+
)
13+
14+
func init() {
15+
migration.NewCodeMigration(
16+
func(executionContext interface{}) error {
17+
ctx := log.Logger.WithContext(context.TODO())
18+
utils.ReindexAllModFiles(ctx, true, nil, func(version postgres.Version) bool {
19+
smlVersion := version.SMLVersion
20+
return strings.Contains(smlVersion, "3.6.1") || strings.Contains(smlVersion, "3.7.0")
21+
})
22+
return nil
23+
},
24+
)
25+
}

redis/redis.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package redis
22

33
import (
4+
"bytes"
5+
"compress/gzip"
46
"context"
57
"encoding/base64"
68
"encoding/binary"
79
"encoding/json"
810
"fmt"
11+
"io"
912
"strconv"
1013
"time"
1114

@@ -140,3 +143,36 @@ func GetVersionUploadState(versionID string) (*generated.CreateVersionResponse,
140143
func FlushRedis() {
141144
client.FlushDB()
142145
}
146+
147+
func StoreModAssetList(modReference string, assets []string) {
148+
var buf bytes.Buffer
149+
zw := gzip.NewWriter(&buf)
150+
151+
b, _ := json.Marshal(assets)
152+
_, _ = zw.Write(b)
153+
_ = zw.Close()
154+
155+
client.Set(fmt.Sprintf("assets:%s", modReference), buf.Bytes(), time.Hour*24)
156+
}
157+
158+
func GetModAssetList(modReference string) []string {
159+
result, err := client.Get(fmt.Sprintf("assets:%s", modReference)).Result()
160+
if err != nil {
161+
return nil
162+
}
163+
164+
reader, err := gzip.NewReader(bytes.NewReader([]byte(result)))
165+
if err != nil {
166+
return nil
167+
}
168+
169+
all, err := io.ReadAll(reader)
170+
if err != nil {
171+
return nil
172+
}
173+
174+
out := make([]string, 0)
175+
_ = json.Unmarshal(all, &out)
176+
177+
return out
178+
}

schemas/mod.graphql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ extend type Query {
119119
getMyUnapprovedMods(filter: ModFilter): GetMyMods! @isLoggedIn
120120

121121
resolveModVersions(filter: [ModVersionConstraint!]!): [ModVersion!]!
122+
123+
getModAssetList(modReference: ModID!): [String!]!
122124
}
123125

124126
### Mutations

storage/b2.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,24 @@ func (b2o *B2) Meta(key string) (*ObjectMeta, error) {
223223
}, nil
224224
}
225225

226-
func (b2o *B2) List(key string) ([]Object, error) {
227-
return nil, nil // no-op
226+
func (b2o *B2) List(prefix string) ([]Object, error) {
227+
out := make([]Object, 0)
228+
229+
err := b2o.S3Client.ListObjectsPages(&s3.ListObjectsInput{
230+
Bucket: aws.String(b2o.Config.Bucket),
231+
Prefix: aws.String(prefix),
232+
}, func(output *s3.ListObjectsOutput, b bool) bool {
233+
for _, obj := range output.Contents {
234+
out = append(out, Object{
235+
Key: obj.Key,
236+
LastModified: obj.LastModified,
237+
})
238+
}
239+
return true
240+
})
241+
if err != nil {
242+
return nil, errors.Wrap(err, "failed to list objects")
243+
}
244+
245+
return out, nil
228246
}

storage/s3.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,21 +248,23 @@ func (s3o *S3) Meta(key string) (*ObjectMeta, error) {
248248
}
249249

250250
func (s3o *S3) List(prefix string) ([]Object, error) {
251-
objects, err := s3o.S3Client.ListObjects(&s3.ListObjectsInput{
251+
out := make([]Object, 0)
252+
253+
err := s3o.S3Client.ListObjectsPages(&s3.ListObjectsInput{
252254
Bucket: aws.String(viper.GetString("storage.bucket")),
253255
Prefix: aws.String(prefix),
256+
}, func(output *s3.ListObjectsOutput, b bool) bool {
257+
for _, obj := range output.Contents {
258+
out = append(out, Object{
259+
Key: obj.Key,
260+
LastModified: obj.LastModified,
261+
})
262+
}
263+
return true
254264
})
255265
if err != nil {
256266
return nil, errors.Wrap(err, "failed to list objects")
257267
}
258268

259-
out := make([]Object, len(objects.Contents))
260-
for i, obj := range objects.Contents {
261-
out[i] = Object{
262-
Key: obj.Key,
263-
LastModified: obj.LastModified,
264-
}
265-
}
266-
267269
return out, nil
268270
}

storage/storage.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/hex"
99
"fmt"
1010
"io"
11+
"sort"
1112
"strings"
1213
"time"
1314

@@ -445,7 +446,7 @@ func copyModFileToArchZip(file *zip.File, zipWriter *zip.Writer, newName string)
445446
}
446447

447448
func DeleteOldModAssets(modReference string, before time.Time) {
448-
list, err := storage.List(fmt.Sprintf("/assets/mods/%s", modReference))
449+
list, err := storage.List(fmt.Sprintf("assets/mods/%s", modReference))
449450
if err != nil {
450451
log.Err(err).Msg("failed to list assets")
451452
return
@@ -477,3 +478,27 @@ func UploadModAsset(ctx context.Context, modReference string, path string, data
477478
log.Err(err).Str("path", path).Msg("failed to upload mod asset")
478479
}
479480
}
481+
482+
func ListModAssets(modReference string) ([]string, error) {
483+
if storage == nil {
484+
return nil, errors.New("no storage defined")
485+
}
486+
487+
list, err := storage.List(fmt.Sprintf("assets/mods/%s", modReference))
488+
if err != nil {
489+
return nil, errors.New("failed to list assets")
490+
}
491+
492+
out := make([]string, len(list))
493+
for i, object := range list {
494+
if object.Key == nil {
495+
continue
496+
}
497+
498+
out[i] = *object.Key
499+
}
500+
501+
sort.Strings(out)
502+
503+
return out, nil
504+
}

0 commit comments

Comments
 (0)