|
|
@ -783,3 +783,102 @@ func (s *LogService) makeCharacterMap(characters []*models.Character) map[string |
|
|
|
|
|
|
|
return characterMap |
|
|
|
} |
|
|
|
|
|
|
|
func (s *LogService) NextLogs(ctx context.Context, log *models.Log) ([]*models.LogSuggestion, error) { |
|
|
|
minDate := log.Date.Add(time.Millisecond) |
|
|
|
logs, err := s.logs.List(ctx, models.LogFilter{ |
|
|
|
MinDate: &minDate, |
|
|
|
}) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
sort.Slice(logs, func(i, j int) bool { |
|
|
|
return logs[i].Date.Before(logs[j].Date) |
|
|
|
}) |
|
|
|
|
|
|
|
return s.findSuggestions(ctx, log, logs) |
|
|
|
} |
|
|
|
|
|
|
|
func (s *LogService) PrevLogs(ctx context.Context, log *models.Log) ([]*models.LogSuggestion, error) { |
|
|
|
logs, err := s.logs.List(ctx, models.LogFilter{ |
|
|
|
MaxDate: &log.Date, |
|
|
|
}) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
return s.findSuggestions(ctx, log, logs) |
|
|
|
} |
|
|
|
|
|
|
|
func (s *LogService) findSuggestions(ctx context.Context, log *models.Log, logs []*models.Log) ([]*models.LogSuggestion, error) { |
|
|
|
characters, err := s.characterService.List(ctx, models.CharacterFilter{ |
|
|
|
IDs: log.CharacterIDs, |
|
|
|
}) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
charIntersect := func(l1, l2 *models.Log) []*models.Character { |
|
|
|
results := make([]*models.Character, 0, len(l1.CharacterIDs)) |
|
|
|
for _, c1 := range characters { |
|
|
|
for _, c2ID := range l2.CharacterIDs { |
|
|
|
if c1.ID == c2ID { |
|
|
|
results = append(results, c1) |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return results |
|
|
|
} |
|
|
|
groupKey := func(characters []*models.Character) string { |
|
|
|
if len(characters) == 0 { |
|
|
|
return "" |
|
|
|
} else if len(characters) == 1 { |
|
|
|
return characters[0].ID |
|
|
|
} |
|
|
|
|
|
|
|
builder := strings.Builder{} |
|
|
|
builder.WriteString(characters[0].ID) |
|
|
|
|
|
|
|
for _, character := range characters { |
|
|
|
builder.WriteRune(',') |
|
|
|
builder.WriteString(character.ID) |
|
|
|
} |
|
|
|
|
|
|
|
return builder.String() |
|
|
|
} |
|
|
|
|
|
|
|
suggestions := make([]*models.LogSuggestion, 0, 16) |
|
|
|
foundGroups := make(map[string]bool) |
|
|
|
foundChannel := false |
|
|
|
|
|
|
|
for _, log2 := range logs { |
|
|
|
hasEvent := log.EventName != "" && log2.EventName == log.EventName |
|
|
|
hasChannel := log.ChannelName == log2.ChannelName |
|
|
|
characters := charIntersect(log, log2) |
|
|
|
groupKey := groupKey(characters) |
|
|
|
|
|
|
|
suggestion := &models.LogSuggestion{ |
|
|
|
Log: log2, |
|
|
|
Characters: characters, |
|
|
|
HasChannel: hasChannel, |
|
|
|
HasEvent: hasEvent, |
|
|
|
} |
|
|
|
|
|
|
|
if hasChannel && foundChannel { |
|
|
|
foundChannel = true |
|
|
|
foundGroups[groupKey] = true |
|
|
|
suggestions = append(suggestions, suggestion) |
|
|
|
} else if hasEvent { |
|
|
|
foundGroups[groupKey] = true |
|
|
|
suggestions = append(suggestions, suggestion) |
|
|
|
} else if len(suggestions) < 8 && !hasEvent && len(characters) > 1 && !foundGroups[groupKey] { |
|
|
|
foundGroups[groupKey] = true |
|
|
|
suggestions = append(suggestions, suggestion) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return suggestions, nil |
|
|
|
} |