|
|
package logs
import ( "errors" "strings" "time"
"git.aiterp.net/rpdata/api/internal/task" "git.aiterp.net/rpdata/api/models" "git.aiterp.net/rpdata/api/models/characters" "git.aiterp.net/rpdata/api/models/posts" "git.aiterp.net/rpdata/api/models/unknownnicks" "github.com/globalsign/mgo/bson" )
var updateTask = task.New(time.Second*60, RunFullUpdate)
// UpdateCharacters updates the characters for the given log.
func UpdateCharacters(log models.Log, addUnknowns bool) (models.Log, error) { posts, err := posts.List(&posts.Filter{LogID: &log.ShortID, Kind: []string{"action", "text", "chars"}, Limit: 0}) if err != nil { return models.Log{}, err }
added := make(map[string]bool) removed := make(map[string]bool) for _, post := range posts { if post.Kind == "text" || post.Kind == "action" { if strings.HasPrefix(post.Text, "(") || strings.Contains(post.Nick, "(") || strings.Contains(post.Nick, "[E]") { continue }
// Clean up the nick (remove possessive suffix, comma, formatting stuff)
if strings.HasSuffix(post.Nick, "'s") || strings.HasSuffix(post.Nick, "`s") { post.Nick = post.Nick[:len(post.Nick)-2] } else if strings.HasSuffix(post.Nick, "'") || strings.HasSuffix(post.Nick, "`") || strings.HasSuffix(post.Nick, ",") || strings.HasSuffix(post.Nick, "\x0f") { post.Nick = post.Nick[:len(post.Nick)-1] }
added[post.Nick] = true } if post.Kind == "chars" { tokens := strings.Fields(post.Text) for _, token := range tokens { if strings.HasPrefix(token, "-") { removed[token[1:]] = true } else { added[strings.Replace(token, "+", "", 1)] = true } } } }
nicks := make([]string, 0, len(added)) for nick := range added { if added[nick] && !removed[nick] { nicks = append(nicks, nick) } }
characters, err := characters.List(&characters.Filter{Nicks: nicks}) if err != nil { return models.Log{}, err }
characterIDs := make([]string, len(characters)) for i, char := range characters { if char.Name == "(Hidden)" { continue }
characterIDs[i] = char.ID }
err = collection.UpdateId(log.ID, bson.M{"$set": bson.M{"characterIds": characterIDs}}) if err != nil { return models.Log{}, err }
log.CharacterIDs = characterIDs
if addUnknowns { NickLoop: for nick := range added { if !added[nick] { continue }
for _, character := range characters { if character.HasNick(nick) { continue NickLoop } }
unknownnicks.Add(nick) } }
return log, nil }
// RunFullUpdate runs a full update on all logs.
func RunFullUpdate() error { iter := iter(bson.M{}, 0) err := iter.Err() if err != nil { return err }
err = unknownnicks.BeginUpdate() if err != nil { return err }
log := models.Log{} for iter.Next(&log) { _, err = UpdateCharacters(log, true) if err != nil { unknownnicks.CancelUpdate() return err } }
err = iter.Err() if err != nil { unknownnicks.CancelUpdate() return err }
err = unknownnicks.CommitUpdate() if err != nil { return errors.New("Failed to commit unknown nicks update: " + err.Error()) }
return nil }
// ScheduleFullUpdate runs a full character update within the next 60 seconds.
func ScheduleFullUpdate() { updateTask.Schedule() }
|