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.

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