55 "context"
66 "fmt"
77 "log/slog"
8+ "maps"
89 "net/http"
910 "slices"
1011
@@ -27,62 +28,123 @@ func (s *CharacterService) updateContactsESI(ctx context.Context, arg app.Charac
2728 return false , fmt .Errorf ("wrong section for update %s: %w" , arg .Section , app .ErrInvalid )
2829 }
2930 return s .updateSectionIfChanged (
30- ctx , arg , true ,
31+ ctx , arg , false ,
3132 func (ctx context.Context , characterID int64 ) (any , error ) {
3233 ctx = xgoesi .NewContextWithOperationID (ctx , "GetCharactersCharacterIdContacts" )
33- rows , err := xgoesi .FetchPages (
34+ contacts , err := xgoesi .FetchPages (
3435 func (page int32 ) ([]esi.CharactersCharacterIdContactsGetInner , * http.Response , error ) {
3536 return s .esiClient .ContactsAPI .GetCharactersCharacterIdContacts (ctx , characterID ).Page (page ).Execute ()
3637 },
3738 )
3839 if err != nil {
3940 return nil , err
4041 }
41- slices .SortFunc (rows , func (a , b esi.CharactersCharacterIdContactsGetInner ) int {
42+ slices .SortFunc (contacts , func (a , b esi.CharactersCharacterIdContactsGetInner ) int {
4243 return cmp .Compare (a .ContactId , b .ContactId )
4344 })
44-
45- slog .Debug ("Received contacts from ESI" , "count" , len (rows ), "characterID" , characterID )
46- return rows , nil
45+ slog .Debug ("Received contacts from ESI" , "count" , len (contacts ), "characterID" , characterID )
46+ return contacts , nil
4747 },
4848 func (ctx context.Context , characterID int64 , data any ) (bool , error ) {
49- rows := data .([]esi.CharactersCharacterIdContactsGetInner )
50- incomingIDs := set .Collect (xiter .MapSlice (rows , func (x esi.CharactersCharacterIdContactsGetInner ) int64 {
49+ contacts := data .([]esi.CharactersCharacterIdContactsGetInner )
50+
51+ incomingIDs := set .Collect (xiter .MapSlice (contacts , func (x esi.CharactersCharacterIdContactsGetInner ) int64 {
5152 return x .ContactId
5253 }))
53-
5454 _ , err := s .eus .AddMissingEntities (ctx , incomingIDs )
5555 if err != nil {
5656 return false , err
5757 }
58-
59- for _ , r := range rows {
58+ for _ , r := range contacts {
6059 err = s .st .UpdateOrCreateCharacterContact (ctx , storage.UpdateOrCreateCharacterContactParams {
6160 CharacterID : characterID ,
6261 ContactID : r .ContactId ,
6362 IsBlocked : optional .FromPtr (r .IsBlocked ),
6463 IsWatched : optional .FromPtr (r .IsWatched ),
6564 Standing : r .Standing ,
65+ LabelIDs : r .LabelIds ,
6666 })
6767 if err != nil {
6868 return false , err
6969 }
7070 }
71- slog .Info ("Updated loyalty points entries " , "characterID" , characterID , "count" , incomingIDs .Size ())
71+ slog .Info ("Updated contacts " , "characterID" , characterID , "count" , incomingIDs .Size ())
7272
7373 // Delete obsolete entries
7474 currentIDs , err := s .st .ListCharacterContactIDs (ctx , characterID )
7575 if err != nil {
7676 return false , err
7777 }
78- obsoleteIDs := set .Difference (incomingIDs , currentIDs )
78+ obsoleteIDs := set .Difference (currentIDs , incomingIDs )
7979 if obsoleteIDs .Size () > 0 {
8080 err := s .st .DeleteCharacterContacts (ctx , characterID , obsoleteIDs )
8181 if err != nil {
8282 return false , err
8383 }
84- slog .Info ("Deleted obsolete loyalty points entries " , "characterID" , characterID , "count" , obsoleteIDs .Size ())
84+ slog .Info ("Deleted obsolete contacts " , "characterID" , characterID , "count" , obsoleteIDs .Size ())
8585 }
8686 return true , nil
8787 })
8888}
89+
90+ func (s * CharacterService ) updateContactLabelsESI (ctx context.Context , arg app.CharacterSectionUpdateParams ) (bool , error ) {
91+ if arg .Section != app .SectionCharacterContactLabels {
92+ return false , fmt .Errorf ("wrong section for update %s: %w" , arg .Section , app .ErrInvalid )
93+ }
94+ return s .updateSectionIfChanged (
95+ ctx , arg , true ,
96+ func (ctx context.Context , characterID int64 ) (any , error ) {
97+ ctx = xgoesi .NewContextWithOperationID (ctx , "GetCharactersCharacterIdContactsLabels" )
98+ labels , _ , err := s .esiClient .ContactsAPI .GetCharactersCharacterIdContactsLabels (ctx , characterID ).Execute ()
99+ if err != nil {
100+ return nil , err
101+ }
102+ slog .Debug ("Received labels from ESI" , "count" , len (labels ), "characterID" , characterID )
103+ return labels , nil
104+ },
105+ func (ctx context.Context , characterID int64 , x any ) (bool , error ) {
106+ incoming := x .([]esi.AlliancesAllianceIdContactsLabelsGetInner )
107+ incoming2 := maps .Collect (xiter .MapSlice2 (incoming , func (x esi.AlliancesAllianceIdContactsLabelsGetInner ) (int64 , string ) {
108+ return x .LabelId , x .LabelName
109+ }))
110+
111+ current , err := s .st .ListCharacterContactLabels (ctx , characterID )
112+ if err != nil {
113+ return false , err
114+ }
115+ current2 := maps .Collect (xiter .MapSlice2 (current , func (x * app.CharacterContactLabel ) (int64 , string ) {
116+ return x .LabelID , x .Name
117+ }))
118+
119+ var changed int
120+ for id2 , name2 := range incoming2 {
121+ if name1 , ok := current2 [id2 ]; ok && name1 == name2 {
122+ continue
123+ }
124+ err := s .st .UpdateOrCreateCharacterContactLabel (ctx , storage.UpdateOrCreateCharacterContactLabelParams {
125+ CharacterID : characterID ,
126+ LabelID : id2 ,
127+ Name : name2 ,
128+ })
129+ if err != nil {
130+ return false , err
131+ }
132+ changed ++
133+ }
134+ slog .Info ("Updated contact labels" , "characterID" , characterID , "count" , changed )
135+
136+ // Delete obsolete labels
137+ currentIDs := set .Collect (maps .Keys (current2 ))
138+ incomingIDs := set .Collect (maps .Keys (incoming2 ))
139+ obsoleteIDs := set .Difference (currentIDs , incomingIDs )
140+ if obsoleteIDs .Size () > 0 {
141+ err := s .st .DeleteCharacterContactLabels (ctx , characterID , obsoleteIDs )
142+ if err != nil {
143+ return false , err
144+ }
145+ slog .Info ("Deleted obsolete contact labels" , "characterID" , characterID , "count" , obsoleteIDs .Size ())
146+ changed += obsoleteIDs .Size ()
147+ }
148+ return changed > 0 , nil
149+ })
150+ }
0 commit comments