GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.6 KiB

  1. package logs
  2. import (
  3. "strings"
  4. "time"
  5. "git.aiterp.net/rpdata/api/internal/task"
  6. "git.aiterp.net/rpdata/api/models"
  7. "git.aiterp.net/rpdata/api/models/characters"
  8. "git.aiterp.net/rpdata/api/models/posts"
  9. "github.com/globalsign/mgo/bson"
  10. )
  11. var updateTask = task.New(time.Second*60, RunFullUpdate)
  12. // UpdateCharacters updates the characters for the given log.
  13. func UpdateCharacters(log models.Log) (models.Log, error) {
  14. posts, err := posts.List(&posts.Filter{LogID: &log.ShortID, Kind: []string{"action", "text", "chars"}, Limit: 0})
  15. if err != nil {
  16. return models.Log{}, err
  17. }
  18. added := make(map[string]bool)
  19. removed := make(map[string]bool)
  20. for _, post := range posts {
  21. if post.Kind == "text" || post.Kind == "action" {
  22. if strings.HasPrefix(post.Text, "(") || strings.Contains(post.Nick, "(") || strings.Contains(post.Nick, "[E]") {
  23. continue
  24. }
  25. // Clean up the nick (remove possessive suffix, comma, formatting stuff)
  26. if strings.HasSuffix(post.Nick, "'s") || strings.HasSuffix(post.Nick, "`s") {
  27. post.Nick = post.Nick[:len(post.Nick)-2]
  28. } else if strings.HasSuffix(post.Nick, "'") || strings.HasSuffix(post.Nick, "`") || strings.HasSuffix(post.Nick, ",") || strings.HasSuffix(post.Nick, "\x0f") {
  29. post.Nick = post.Nick[:len(post.Nick)-1]
  30. }
  31. added[post.Nick] = true
  32. }
  33. if post.Kind == "chars" {
  34. tokens := strings.Fields(post.Text)
  35. for _, token := range tokens {
  36. if strings.HasPrefix(token, "-") {
  37. removed[token[1:]] = true
  38. } else {
  39. added[strings.Replace(token, "+", "", 1)] = true
  40. }
  41. }
  42. }
  43. }
  44. nicks := make([]string, 0, len(added))
  45. for nick := range added {
  46. if added[nick] && !removed[nick] {
  47. nicks = append(nicks, nick)
  48. }
  49. }
  50. characters, err := characters.List(&characters.Filter{Nicks: nicks})
  51. if err != nil {
  52. return models.Log{}, err
  53. }
  54. characterIDs := make([]string, len(characters))
  55. for i, char := range characters {
  56. characterIDs[i] = char.ID
  57. }
  58. err = collection.UpdateId(log.ID, bson.M{"$set": bson.M{"characterIds": characterIDs}})
  59. if err != nil {
  60. return models.Log{}, err
  61. }
  62. log.CharacterIDs = characterIDs
  63. return log, nil
  64. }
  65. // RunFullUpdate runs a full update on all logs.
  66. func RunFullUpdate() error {
  67. iter := iter(bson.M{}, 0)
  68. err := iter.Err()
  69. if err != nil {
  70. return err
  71. }
  72. log := models.Log{}
  73. for iter.Next(&log) {
  74. _, err = UpdateCharacters(log)
  75. if err != nil {
  76. return err
  77. }
  78. }
  79. err = iter.Err()
  80. if err != nil {
  81. return err
  82. }
  83. return nil
  84. }
  85. // ScheduleFullUpdate runs a full character update within the next 60 seconds.
  86. func ScheduleFullUpdate() {
  87. updateTask.Schedule()
  88. }