feat: unify collectibles struct

This commit is contained in:
Dario Gabriel Lipicar 2023-11-09 21:31:48 -03:00 committed by dlipicar
parent 6f84207d3a
commit 5933376eda
2 changed files with 129 additions and 139 deletions

View File

@ -93,6 +93,7 @@ func NewService(
ownershipDB: NewOwnershipDB(db), ownershipDB: NewOwnershipDB(db),
communityDB: community.NewDataDB(db), communityDB: community.NewDataDB(db),
walletFeed: walletFeed, walletFeed: walletFeed,
scheduler: async.NewMultiClientScheduler(),
} }
s.controller.SetReceivedCollectiblesCb(s.notifyCommunityCollectiblesReceived) s.controller.SetReceivedCollectiblesCb(s.notifyCommunityCollectiblesReceived)
return s return s
@ -115,8 +116,7 @@ type OwnershipStatusPerChainID = map[walletCommon.ChainID]OwnershipStatus
type OwnershipStatusPerAddressAndChainID = map[common.Address]OwnershipStatusPerChainID type OwnershipStatusPerAddressAndChainID = map[common.Address]OwnershipStatusPerChainID
type GetOwnedCollectiblesResponse struct { type GetOwnedCollectiblesResponse struct {
DataType CollectibleDataType `json:"data_type"` Collectibles []Collectible `json:"collectibles"`
EncodedCollectibles string `json:"collectibles"`
Offset int `json:"offset"` Offset int `json:"offset"`
// Used to indicate that there might be more collectibles that were not returned // Used to indicate that there might be more collectibles that were not returned
// based on a simple heuristic // based on a simple heuristic
@ -126,19 +126,18 @@ type GetOwnedCollectiblesResponse struct {
} }
type GetCollectiblesByUniqueIDResponse struct { type GetCollectiblesByUniqueIDResponse struct {
DataType CollectibleDataType `json:"data_type"` Collectibles []Collectible `json:"collectibles"`
EncodedCollectibles string `json:"collectibles"`
ErrorCode ErrorCode `json:"errorCode"` ErrorCode ErrorCode `json:"errorCode"`
} }
type GetOwnedCollectiblesReturnType struct { type GetOwnedCollectiblesReturnType struct {
collectibles interface{} collectibles []Collectible
hasMore bool hasMore bool
ownershipStatus OwnershipStatusPerAddressAndChainID ownershipStatus OwnershipStatusPerAddressAndChainID
} }
type GetCollectiblesByUniqueIDReturnType struct { type GetCollectiblesByUniqueIDReturnType struct {
collectibles interface{} collectibles []Collectible
} }
func (s *Service) GetOwnedCollectibles( func (s *Service) GetOwnedCollectibles(
@ -203,7 +202,6 @@ func (s *Service) fetchOwnedCollectiblesIfNeeded(ctx context.Context, chainIDs [
} }
group := async.NewGroup(ctx) group := async.NewGroup(ctx)
for _, address := range addresses { for _, address := range addresses {
for _, chainID := range chainIDs { for _, chainID := range chainIDs {
mustFetch, err := s.needsToFetch(chainID, address, fetchCriteria) mustFetch, err := s.needsToFetch(chainID, address, fetchCriteria)
@ -216,7 +214,6 @@ func (s *Service) fetchOwnedCollectiblesIfNeeded(ctx context.Context, chainIDs [
} }
} }
} }
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
@ -241,18 +238,16 @@ func (s *Service) GetOwnedCollectiblesAsync(
return s.GetOwnedCollectibles(ctx, chainIDs, addresses, filter, offset, limit, dataType, fetchCriteria) return s.GetOwnedCollectibles(ctx, chainIDs, addresses, filter, offset, limit, dataType, fetchCriteria)
}, func(result interface{}, taskType async.TaskType, err error) { }, func(result interface{}, taskType async.TaskType, err error) {
res := GetOwnedCollectiblesResponse{ res := GetOwnedCollectiblesResponse{
DataType: dataType,
ErrorCode: ErrorCodeFailed, ErrorCode: ErrorCodeFailed,
} }
if errors.Is(err, context.Canceled) || errors.Is(err, async.ErrTaskOverwritten) { if errors.Is(err, context.Canceled) || errors.Is(err, async.ErrTaskOverwritten) {
res.ErrorCode = ErrorCodeTaskCanceled res.ErrorCode = ErrorCodeTaskCanceled
} else if err == nil { } else if err == nil {
fnRet := result.(GetOwnedCollectiblesReturnType) fnRet := result.(*GetOwnedCollectiblesReturnType)
encodedMessage, err := json.Marshal(fnRet.collectibles)
if err == nil { if err == nil {
res.EncodedCollectibles = string(encodedMessage) res.Collectibles = fnRet.collectibles
res.Offset = offset res.Offset = offset
res.HasMore = fnRet.hasMore res.HasMore = fnRet.hasMore
res.OwnershipStatus = fnRet.ownershipStatus res.OwnershipStatus = fnRet.ownershipStatus
@ -285,18 +280,16 @@ func (s *Service) GetCollectiblesByUniqueIDAsync(
return s.GetCollectiblesByUniqueID(ctx, uniqueIDs, dataType) return s.GetCollectiblesByUniqueID(ctx, uniqueIDs, dataType)
}, func(result interface{}, taskType async.TaskType, err error) { }, func(result interface{}, taskType async.TaskType, err error) {
res := GetCollectiblesByUniqueIDResponse{ res := GetCollectiblesByUniqueIDResponse{
DataType: dataType,
ErrorCode: ErrorCodeFailed, ErrorCode: ErrorCodeFailed,
} }
if errors.Is(err, context.Canceled) || errors.Is(err, async.ErrTaskOverwritten) { if errors.Is(err, context.Canceled) || errors.Is(err, async.ErrTaskOverwritten) {
res.ErrorCode = ErrorCodeTaskCanceled res.ErrorCode = ErrorCodeTaskCanceled
} else if err == nil { } else if err == nil {
fnRet := result.(GetCollectiblesByUniqueIDReturnType) fnRet := result.(*GetCollectiblesByUniqueIDReturnType)
encodedMessage, err := json.Marshal(fnRet.collectibles)
if err == nil { if err == nil {
res.EncodedCollectibles = string(encodedMessage) res.Collectibles = fnRet.collectibles
res.ErrorCode = ErrorCodeSuccess res.ErrorCode = ErrorCodeSuccess
} }
} }
@ -381,10 +374,10 @@ func (s *Service) GetOwnershipStatus(chainIDs []walletCommon.ChainID, owners []c
return ret, nil return ret, nil
} }
func (s *Service) collectibleIDsToDataType(ctx context.Context, ids []thirdparty.CollectibleUniqueID, dataType CollectibleDataType) (interface{}, error) { func (s *Service) collectibleIDsToDataType(ctx context.Context, ids []thirdparty.CollectibleUniqueID, dataType CollectibleDataType) ([]Collectible, error) {
switch dataType { switch dataType {
case CollectibleDataTypeUniqueID: case CollectibleDataTypeUniqueID:
return ids, nil return idsToCollectibles(ids), nil
case CollectibleDataTypeHeader, CollectibleDataTypeDetails, CollectibleDataTypeCommunityHeader: case CollectibleDataTypeHeader, CollectibleDataTypeDetails, CollectibleDataTypeCommunityHeader:
collectibles, err := s.manager.FetchAssetsByCollectibleUniqueID(ctx, ids) collectibles, err := s.manager.FetchAssetsByCollectibleUniqueID(ctx, ids)
if err != nil { if err != nil {
@ -402,8 +395,19 @@ func (s *Service) collectibleIDsToDataType(ctx context.Context, ids []thirdparty
return nil, errors.New("unknown data type") return nil, errors.New("unknown data type")
} }
func (s *Service) fullCollectiblesDataToHeaders(data []thirdparty.FullCollectibleData) ([]CollectibleHeader, error) { func idsToCollectibles(ids []thirdparty.CollectibleUniqueID) []Collectible {
res := make([]CollectibleHeader, 0, len(data)) res := make([]Collectible, 0, len(ids))
for _, id := range ids {
c := idToCollectible(id)
res = append(res, c)
}
return res
}
func (s *Service) fullCollectiblesDataToHeaders(data []thirdparty.FullCollectibleData) ([]Collectible, error) {
res := make([]Collectible, 0, len(data))
for _, c := range data { for _, c := range data {
header := fullCollectibleDataToHeader(c) header := fullCollectibleDataToHeader(c)
@ -415,7 +419,7 @@ func (s *Service) fullCollectiblesDataToHeaders(data []thirdparty.FullCollectibl
} }
communityHeader := communityInfoToHeader(c.CollectibleData.CommunityID, communityInfo, c.CommunityInfo) communityHeader := communityInfoToHeader(c.CollectibleData.CommunityID, communityInfo, c.CommunityInfo)
header.CommunityHeader = &communityHeader header.CommunityData = &communityHeader
} }
res = append(res, header) res = append(res, header)
@ -424,8 +428,8 @@ func (s *Service) fullCollectiblesDataToHeaders(data []thirdparty.FullCollectibl
return res, nil return res, nil
} }
func (s *Service) fullCollectiblesDataToDetails(data []thirdparty.FullCollectibleData) ([]CollectibleDetails, error) { func (s *Service) fullCollectiblesDataToDetails(data []thirdparty.FullCollectibleData) ([]Collectible, error) {
res := make([]CollectibleDetails, 0, len(data)) res := make([]Collectible, 0, len(data))
for _, c := range data { for _, c := range data {
details := fullCollectibleDataToDetails(c) details := fullCollectibleDataToDetails(c)
@ -437,7 +441,7 @@ func (s *Service) fullCollectiblesDataToDetails(data []thirdparty.FullCollectibl
} }
communityDetails := communityInfoToDetails(c.CollectibleData.CommunityID, communityInfo, c.CommunityInfo) communityDetails := communityInfoToDetails(c.CollectibleData.CommunityID, communityInfo, c.CommunityInfo)
details.CommunityInfo = &communityDetails details.CommunityData = &communityDetails
} }
res = append(res, details) res = append(res, details)
@ -446,8 +450,8 @@ func (s *Service) fullCollectiblesDataToDetails(data []thirdparty.FullCollectibl
return res, nil return res, nil
} }
func (s *Service) fullCollectiblesDataToCommunityHeader(data []thirdparty.FullCollectibleData) ([]CommunityCollectibleHeader, error) { func (s *Service) fullCollectiblesDataToCommunityHeader(data []thirdparty.FullCollectibleData) ([]Collectible, error) {
res := make([]CommunityCollectibleHeader, 0, len(data)) res := make([]Collectible, 0, len(data))
for _, c := range data { for _, c := range data {
collectibleID := c.CollectibleData.ID collectibleID := c.CollectibleData.ID
@ -463,10 +467,14 @@ func (s *Service) fullCollectiblesDataToCommunityHeader(data []thirdparty.FullCo
continue continue
} }
header := CommunityCollectibleHeader{ communityHeader := communityInfoToHeader(communityID, communityInfo, c.CommunityInfo)
header := Collectible{
ID: collectibleID, ID: collectibleID,
CollectibleData: &CollectibleData{
Name: c.CollectibleData.Name, Name: c.CollectibleData.Name,
CommunityHeader: communityInfoToHeader(communityID, communityInfo, c.CommunityInfo), },
CommunityData: &communityHeader,
} }
res = append(res, header) res = append(res, header)
@ -484,29 +492,10 @@ func (s *Service) notifyCommunityCollectiblesReceived(ownedCollectibles OwnedCol
return return
} }
communityCollectibles := make([]CommunityCollectibleHeader, 0, len(collectiblesData)) communityCollectibles, err := s.fullCollectiblesDataToCommunityHeader(collectiblesData)
for _, collectibleData := range collectiblesData {
collectibleID := collectibleData.CollectibleData.ID
communityID := collectibleData.CollectibleData.CommunityID
if communityID == "" {
continue
}
communityInfo, _, err := s.communityDB.GetCommunityInfo(communityID)
if err != nil { if err != nil {
log.Error("Error fetching community info", "error", err) log.Error("Error converting received collectibles data", "error", err)
continue return
}
header := CommunityCollectibleHeader{
ID: collectibleID,
Name: collectibleData.CollectibleData.Name,
CommunityHeader: communityInfoToHeader(communityID, communityInfo, collectibleData.CommunityInfo),
}
communityCollectibles = append(communityCollectibles, header)
} }
if len(communityCollectibles) == 0 { if len(communityCollectibles) == 0 {

View File

@ -6,100 +6,101 @@ import (
) )
// Combined Collection+Collectible info, used to display a detailed view of a collectible // Combined Collection+Collectible info, used to display a detailed view of a collectible
type CollectibleDetails struct { type Collectible struct {
DataType CollectibleDataType `json:"data_type"`
ID thirdparty.CollectibleUniqueID `json:"id"` ID thirdparty.CollectibleUniqueID `json:"id"`
CollectibleData *CollectibleData `json:"collectible_data,omitempty"`
CollectionData *CollectionData `json:"collection_data,omitempty"`
CommunityData *CommunityData `json:"community_data,omitempty"`
}
type CollectibleData struct {
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description *string `json:"description,omitempty"`
ImageURL *string `json:"image_url,omitempty"`
AnimationURL *string `json:"animation_url,omitempty"`
AnimationMediaType *string `json:"animation_media_type,omitempty"`
Traits *[]thirdparty.CollectibleTrait `json:"traits,omitempty"`
BackgroundColor *string `json:"background_color,omitempty"`
}
type CollectionData struct {
Name string `json:"name"`
Slug string `json:"slug"`
ImageURL string `json:"image_url"` ImageURL string `json:"image_url"`
AnimationURL string `json:"animation_url"`
AnimationMediaType string `json:"animation_media_type"`
Traits []thirdparty.CollectibleTrait `json:"traits"`
BackgroundColor string `json:"background_color"`
CollectionName string `json:"collection_name"`
CollectionSlug string `json:"collection_slug"`
CollectionImageURL string `json:"collection_image_url"`
CommunityInfo *CommunityDetails `json:"community_info,omitempty"`
} }
// Combined Collection+Collectible info, used to display a basic view of a collectible in a list type CommunityData struct {
type CollectibleHeader struct { ID string `json:"id"`
ID thirdparty.CollectibleUniqueID `json:"id"`
Name string `json:"name"` Name string `json:"name"`
ImageURL string `json:"image_url"` Color string `json:"color"`
AnimationURL string `json:"animation_url"`
AnimationMediaType string `json:"animation_media_type"`
BackgroundColor string `json:"background_color"`
CollectionName string `json:"collection_name"`
CollectionSlug string `json:"collection_slug"`
CollectionImageURL string `json:"collection_image_url"`
CommunityHeader *CommunityHeader `json:"community_header,omitempty"`
}
type CommunityDetails struct {
CommunityID string `json:"community_id"`
CommunityName string `json:"community_name"`
CommunityColor string `json:"community_color"`
CommunityImage string `json:"community_image"`
PrivilegesLevel token.PrivilegesLevel `json:"privileges_level"` PrivilegesLevel token.PrivilegesLevel `json:"privileges_level"`
ImageURL *string `json:"image_url,omitempty"`
} }
type CommunityHeader struct { func idToCollectible(id thirdparty.CollectibleUniqueID) Collectible {
CommunityID string `json:"community_id"` ret := Collectible{
CommunityName string `json:"community_name"` DataType: CollectibleDataTypeUniqueID,
CommunityColor string `json:"community_color"` ID: id,
PrivilegesLevel token.PrivilegesLevel `json:"privileges_level"`
}
type CommunityCollectibleHeader struct {
ID thirdparty.CollectibleUniqueID `json:"id"`
Name string `json:"name"`
CommunityHeader CommunityHeader `json:"community_header"`
}
func fullCollectibleDataToHeader(c thirdparty.FullCollectibleData) CollectibleHeader {
ret := CollectibleHeader{
ID: c.CollectibleData.ID,
Name: c.CollectibleData.Name,
ImageURL: c.CollectibleData.ImageURL,
AnimationURL: c.CollectibleData.AnimationURL,
AnimationMediaType: c.CollectibleData.AnimationMediaType,
BackgroundColor: c.CollectibleData.BackgroundColor,
}
if c.CollectionData != nil {
ret.CollectionName = c.CollectionData.Name
ret.CollectionSlug = c.CollectionData.Slug
ret.CollectionImageURL = c.CollectionData.ImageURL
} }
return ret return ret
} }
func fullCollectibleDataToDetails(c thirdparty.FullCollectibleData) CollectibleDetails { func fullCollectibleDataToHeader(c thirdparty.FullCollectibleData) Collectible {
ret := CollectibleDetails{ ret := Collectible{
DataType: CollectibleDataTypeHeader,
ID: c.CollectibleData.ID, ID: c.CollectibleData.ID,
CollectibleData: &CollectibleData{
Name: c.CollectibleData.Name, Name: c.CollectibleData.Name,
Description: c.CollectibleData.Description, ImageURL: &c.CollectibleData.ImageURL,
ImageURL: c.CollectibleData.ImageURL, AnimationURL: &c.CollectibleData.AnimationURL,
AnimationURL: c.CollectibleData.AnimationURL, AnimationMediaType: &c.CollectibleData.AnimationMediaType,
AnimationMediaType: c.CollectibleData.AnimationMediaType, BackgroundColor: &c.CollectibleData.BackgroundColor,
BackgroundColor: c.CollectibleData.BackgroundColor, },
Traits: c.CollectibleData.Traits,
} }
if c.CollectionData != nil { if c.CollectionData != nil {
ret.CollectionName = c.CollectionData.Name ret.CollectionData = &CollectionData{
ret.CollectionSlug = c.CollectionData.Slug Name: c.CollectionData.Name,
ret.CollectionImageURL = c.CollectionData.ImageURL Slug: c.CollectionData.Slug,
ImageURL: c.CollectionData.ImageURL,
}
}
return ret
}
func fullCollectibleDataToDetails(c thirdparty.FullCollectibleData) Collectible {
ret := Collectible{
DataType: CollectibleDataTypeHeader,
ID: c.CollectibleData.ID,
CollectibleData: &CollectibleData{
Name: c.CollectibleData.Name,
Description: &c.CollectibleData.Description,
ImageURL: &c.CollectibleData.ImageURL,
AnimationURL: &c.CollectibleData.AnimationURL,
AnimationMediaType: &c.CollectibleData.AnimationMediaType,
BackgroundColor: &c.CollectibleData.BackgroundColor,
Traits: &c.CollectibleData.Traits,
},
}
if c.CollectionData != nil {
ret.CollectionData = &CollectionData{
Name: c.CollectionData.Name,
Slug: c.CollectionData.Slug,
ImageURL: c.CollectionData.ImageURL,
}
} }
return ret return ret
} }
func communityInfoToHeader(communityID string, community *thirdparty.CommunityInfo, communityCollectible *thirdparty.CollectibleCommunityInfo) CommunityHeader { func communityInfoToHeader(communityID string, community *thirdparty.CommunityInfo, communityCollectible *thirdparty.CollectibleCommunityInfo) CommunityData {
ret := CommunityHeader{ ret := CommunityData{
CommunityID: communityID, ID: communityID,
} }
if community != nil { if community != nil {
ret.CommunityName = community.CommunityName ret.Name = community.CommunityName
ret.CommunityColor = community.CommunityColor ret.Color = community.CommunityColor
} }
if communityCollectible != nil { if communityCollectible != nil {
@ -109,15 +110,15 @@ func communityInfoToHeader(communityID string, community *thirdparty.CommunityIn
return ret return ret
} }
func communityInfoToDetails(communityID string, community *thirdparty.CommunityInfo, communityCollectible *thirdparty.CollectibleCommunityInfo) CommunityDetails { func communityInfoToDetails(communityID string, community *thirdparty.CommunityInfo, communityCollectible *thirdparty.CollectibleCommunityInfo) CommunityData {
ret := CommunityDetails{ ret := CommunityData{
CommunityID: communityID, ID: communityID,
} }
if community != nil { if community != nil {
ret.CommunityName = community.CommunityName ret.Name = community.CommunityName
ret.CommunityColor = community.CommunityColor ret.Color = community.CommunityColor
ret.CommunityImage = community.CommunityImage ret.ImageURL = &community.CommunityImage
} }
if communityCollectible != nil { if communityCollectible != nil {