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.

184 lines
4.8 KiB

  1. package queries
  2. import (
  3. "context"
  4. "errors"
  5. "strings"
  6. "time"
  7. "git.aiterp.net/rpdata/api/models/channels"
  8. "git.aiterp.net/rpdata/api/graph2/input"
  9. "git.aiterp.net/rpdata/api/internal/auth"
  10. "git.aiterp.net/rpdata/api/internal/loader"
  11. "git.aiterp.net/rpdata/api/models"
  12. "git.aiterp.net/rpdata/api/models/changekeys"
  13. "git.aiterp.net/rpdata/api/models/changes"
  14. "git.aiterp.net/rpdata/api/models/logs"
  15. "github.com/99designs/gqlgen/graphql"
  16. )
  17. // Queries
  18. func (r *resolver) Log(ctx context.Context, id string) (models.Log, error) {
  19. return logs.FindID(id)
  20. }
  21. func (r *resolver) Logs(ctx context.Context, filter *logs.Filter) ([]models.Log, error) {
  22. logs, err := logs.List(filter)
  23. if err != nil {
  24. return nil, err
  25. }
  26. reqCtx := graphql.GetRequestContext(ctx)
  27. maybeCharacters := strings.Contains(reqCtx.RawQuery, "characters")
  28. maybeChannels := strings.Contains(reqCtx.RawQuery, "channels")
  29. if len(logs) >= 100 && (maybeCharacters || maybeChannels) {
  30. loader := loader.FromContext(ctx)
  31. if loader == nil {
  32. return nil, errors.New("no loader")
  33. }
  34. for _, log := range logs {
  35. if maybeChannels {
  36. loader.PrimeChannels("name", log.ChannelName)
  37. }
  38. if maybeCharacters {
  39. loader.PrimeCharacters("id", log.CharacterIDs...)
  40. }
  41. }
  42. }
  43. return logs, nil
  44. }
  45. // Mutations
  46. func (r *mutationResolver) AddLog(ctx context.Context, input input.LogAddInput) (models.Log, error) {
  47. token := auth.TokenFromContext(ctx)
  48. if !token.Authenticated() || !token.Permitted("log.add") {
  49. return models.Log{}, errors.New("You are not permitted to add logs")
  50. }
  51. open := input.Open != nil && *input.Open == true
  52. title := ""
  53. if input.Title != nil {
  54. title = *input.Title
  55. }
  56. event := ""
  57. if input.Event != nil {
  58. event = *input.Event
  59. }
  60. description := ""
  61. if input.Description != nil {
  62. description = *input.Description
  63. }
  64. existingChannel, _ := channels.FindName(input.Channel)
  65. log, err := logs.Add(input.Date, input.Channel, title, event, description, open)
  66. if !token.Authenticated() || !token.Permitted("log.add") {
  67. return models.Log{}, errors.New("Failed to create log: " + err.Error())
  68. }
  69. go func() {
  70. if existingChannel.Name == "" {
  71. channel, err := channels.FindName(input.Channel)
  72. if err == nil {
  73. changes.Submit("Channel", "add", token.UserID, true, changekeys.Listed(channel), channel)
  74. }
  75. }
  76. changes.Submit("Log", "add", token.UserID, true, changekeys.Listed(log), log)
  77. }()
  78. return log, nil
  79. }
  80. func (r *mutationResolver) ImportLog(ctx context.Context, input input.LogImportInput) ([]models.Log, error) {
  81. token := auth.TokenFromContext(ctx)
  82. if !token.Authenticated() || !token.Permitted("log.add") {
  83. return nil, errors.New("You are not permitted to add logs")
  84. }
  85. date := time.Time{}
  86. if input.Date != nil {
  87. date = *input.Date
  88. }
  89. tz := time.UTC
  90. if input.Timezone != nil {
  91. parsedTZ, err := time.LoadLocation(*input.Timezone)
  92. if err != nil {
  93. return nil, errors.New("Unknown timezone: " + *input.Timezone)
  94. }
  95. tz = parsedTZ
  96. }
  97. results, err := logs.Import(input.Importer, date, tz, input.ChannelName, input.Data)
  98. if err != nil {
  99. return nil, err
  100. }
  101. newLogs := make([]models.Log, 0, len(results))
  102. for _, result := range results {
  103. go func() {
  104. changes.Submit("Log", "add", token.UserID, true, changekeys.Many(result.Log), result.Log)
  105. changes.Submit("Post", "add", token.UserID, true, changekeys.Many(result.Log, result.Posts), result.Posts)
  106. }()
  107. log, err := logs.UpdateCharacters(result.Log)
  108. if err != nil {
  109. log = result.Log
  110. }
  111. newLogs = append(newLogs, log)
  112. }
  113. return newLogs, nil
  114. }
  115. func (r *mutationResolver) EditLog(ctx context.Context, input input.LogEditInput) (models.Log, error) {
  116. token := auth.TokenFromContext(ctx)
  117. if !token.Authenticated() || !token.Permitted("log.edit") {
  118. return models.Log{}, errors.New("You are not permitted to edit logs")
  119. }
  120. log, err := logs.FindID(input.ID)
  121. if err != nil {
  122. return models.Log{}, errors.New("Log not found")
  123. }
  124. log, err = logs.Edit(log, input.Title, input.Event, input.Description, input.Open)
  125. if err != nil {
  126. return models.Log{}, errors.New("Failed to edit log: " + err.Error())
  127. }
  128. go changes.Submit("Log", "edit", token.UserID, true, changekeys.Listed(log), log)
  129. return log, nil
  130. }
  131. func (r *mutationResolver) RemoveLog(ctx context.Context, input input.LogRemoveInput) (models.Log, error) {
  132. token := auth.TokenFromContext(ctx)
  133. if !token.Authenticated() || !token.Permitted("log.remove") {
  134. return models.Log{}, errors.New("You are not permitted to remove logs")
  135. }
  136. log, err := logs.FindID(input.ID)
  137. if err != nil {
  138. return models.Log{}, errors.New("Log not found")
  139. }
  140. log, err = logs.Remove(log)
  141. if err != nil {
  142. return models.Log{}, errors.New("Failed to remove log: " + err.Error())
  143. }
  144. go changes.Submit("Log", "remove", token.UserID, true, changekeys.Listed(log), log)
  145. return log, nil
  146. }