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.

321 lines
6.7 KiB

  1. package resolver
  2. import (
  3. "context"
  4. "errors"
  5. "time"
  6. "git.aiterp.net/rpdata/api/loader"
  7. "git.aiterp.net/rpdata/api/model/change"
  8. "git.aiterp.net/rpdata/api/internal/session"
  9. "git.aiterp.net/rpdata/api/model/character"
  10. "git.aiterp.net/rpdata/api/model/log"
  11. )
  12. // LogResolver for the Log graphql type
  13. type LogResolver struct{ L log.Log }
  14. // LogArgs is an arg
  15. type LogArgs struct {
  16. ID *string
  17. }
  18. // LogPostArgs is an arg
  19. type LogPostArgs struct {
  20. Kinds *[]string
  21. }
  22. // Log finds log
  23. func (r *QueryResolver) Log(ctx context.Context, args *LogArgs) (*LogResolver, error) {
  24. var l log.Log
  25. var err error
  26. switch {
  27. case args.ID != nil:
  28. l, err = log.FindID(*args.ID)
  29. default:
  30. err = ErrCannotResolve
  31. }
  32. if err != nil {
  33. return nil, err
  34. }
  35. return &LogResolver{L: l}, nil
  36. }
  37. // LogQueryInput is an input
  38. type LogQueryInput struct {
  39. Search *string
  40. Characters *[]string
  41. Channels *[]string
  42. Events *[]string
  43. Open *bool
  44. Limit *int32
  45. }
  46. // Logs lists logs
  47. func (r *QueryResolver) Logs(ctx context.Context, args *struct{ Input *LogQueryInput }) ([]*LogResolver, error) {
  48. var logs []log.Log
  49. var err error
  50. input := args.Input
  51. if input != nil {
  52. // Parse input
  53. limit := 100
  54. search := ""
  55. if input.Search != nil {
  56. search = *input.Search
  57. limit = 0
  58. }
  59. channels := []string(nil)
  60. if input.Channels != nil {
  61. channels = *input.Channels
  62. limit = 0
  63. }
  64. characters := []string(nil)
  65. if input.Characters != nil {
  66. characters = *input.Characters
  67. limit = 0
  68. }
  69. events := []string(nil)
  70. if input.Events != nil {
  71. events = *input.Events
  72. limit = 0
  73. }
  74. if input.Limit != nil {
  75. limit = int(*input.Limit)
  76. }
  77. open := input.Open != nil && *input.Open == true
  78. logs, err = log.ListSearch(search, channels, characters, events, open, limit)
  79. if err != nil {
  80. return nil, err
  81. }
  82. } else {
  83. logs, err = log.List(100)
  84. if err != nil {
  85. return nil, err
  86. }
  87. }
  88. resolvers := make([]*LogResolver, len(logs))
  89. for i := range logs {
  90. resolvers[i] = &LogResolver{L: logs[i]}
  91. }
  92. return resolvers, nil
  93. }
  94. // LogAddInput is an input
  95. type LogAddInput struct {
  96. Date string
  97. Channel string
  98. Title *string
  99. Open *bool
  100. Event *string
  101. Description *string
  102. }
  103. // AddLog resolves the addLog mutation
  104. func (r *MutationResolver) AddLog(ctx context.Context, args *struct{ Input LogAddInput }) (*LogResolver, error) {
  105. user := session.FromContext(ctx).User()
  106. if user == nil || !user.Permitted("log.add") {
  107. return nil, ErrUnauthorized
  108. }
  109. date, err := time.Parse(time.RFC3339Nano, args.Input.Date)
  110. if err != nil {
  111. return nil, err
  112. }
  113. title := ""
  114. if args.Input.Title != nil {
  115. title = *args.Input.Title
  116. }
  117. event := ""
  118. if args.Input.Event != nil {
  119. event = *args.Input.Event
  120. }
  121. description := ""
  122. if args.Input.Description != nil {
  123. description = *args.Input.Description
  124. }
  125. open := args.Input.Open != nil && *args.Input.Open == true
  126. log, err := log.New(date, args.Input.Channel, title, event, description, open)
  127. if err != nil {
  128. return nil, err
  129. }
  130. change.Submit("Log", "add", user.ID, log.ID, map[string]interface{}{
  131. "channel": log.Channel,
  132. "title": log.Title,
  133. "event": log.Event,
  134. "description": log.Description,
  135. "open": log.Open,
  136. })
  137. return &LogResolver{L: log}, nil
  138. }
  139. // LogEditInput is an input
  140. type LogEditInput struct {
  141. ID string
  142. Title *string
  143. Event *string
  144. Description *string
  145. Open *bool
  146. }
  147. // EditLog resolves the addLog mutation
  148. func (r *MutationResolver) EditLog(ctx context.Context, args *struct{ Input LogEditInput }) (*LogResolver, error) {
  149. user := session.FromContext(ctx).User()
  150. if user == nil || !user.Permitted("log.edit") {
  151. return nil, ErrUnauthorized
  152. }
  153. l, err := log.FindID(args.Input.ID)
  154. if err != nil {
  155. return nil, err
  156. }
  157. err = l.Edit(args.Input.Title, args.Input.Event, args.Input.Description, args.Input.Open)
  158. if err != nil {
  159. return nil, err
  160. }
  161. change.Submit("Log", "edit", user.ID, l.ID, map[string]interface{}{
  162. "channel": l.Channel,
  163. "title": args.Input.Title,
  164. "event": args.Input.Event,
  165. "description": args.Input.Description,
  166. "open": args.Input.Open,
  167. })
  168. return &LogResolver{L: l}, nil
  169. }
  170. // RemoveLog resolves the removeLog mutation
  171. func (r *MutationResolver) RemoveLog(ctx context.Context, args *struct{ ID string }) (*LogResolver, error) {
  172. user := session.FromContext(ctx).User()
  173. if user == nil || !user.Permitted("log.remove") {
  174. return nil, ErrUnauthorized
  175. }
  176. l, err := log.FindID(args.ID)
  177. if err != nil {
  178. return nil, err
  179. }
  180. err = log.Remove(args.ID)
  181. if err != nil {
  182. return nil, err
  183. }
  184. change.Submit("Log", "add", user.ID, l.ID, map[string]interface{}{
  185. "channel": l.Channel,
  186. "title": l.Title,
  187. "event": l.Event,
  188. "description": l.Description,
  189. "open": l.Open,
  190. })
  191. return &LogResolver{L: l}, nil
  192. }
  193. // ID resolves Log.id
  194. func (r *LogResolver) ID() string {
  195. return r.L.ID
  196. }
  197. // ShortID resolves Log.shortId
  198. func (r *LogResolver) ShortID() string {
  199. return r.L.ShortID
  200. }
  201. // Date resolves Log.date
  202. func (r *LogResolver) Date() string {
  203. return r.L.Date.Format(time.RFC3339Nano)
  204. }
  205. // ChannelName resolves Log.channelName
  206. func (r *LogResolver) ChannelName() string {
  207. return r.L.Channel
  208. }
  209. // Channel resolves Log.channe
  210. func (r *LogResolver) Channel(ctx context.Context) (*ChannelResolver, error) {
  211. loader := loader.FromContext(ctx)
  212. if loader == nil {
  213. return nil, errors.New("no loader")
  214. }
  215. channel, err := loader.Channel("name", r.L.Channel)
  216. if err != nil {
  217. return nil, err
  218. }
  219. return &ChannelResolver{C: channel}, nil
  220. }
  221. // Title resolves Log.title
  222. func (r *LogResolver) Title() string {
  223. return r.L.Title
  224. }
  225. // Event resolves Log.event
  226. func (r *LogResolver) Event() string {
  227. return r.L.Event
  228. }
  229. // Description resolves Log.description
  230. func (r *LogResolver) Description() string {
  231. return r.L.Description
  232. }
  233. // Open resolves Log.open
  234. func (r *LogResolver) Open() bool {
  235. return r.L.Open
  236. }
  237. // Characters resolves Log.characters
  238. func (r *LogResolver) Characters(ctx context.Context) ([]*CharacterResolver, error) {
  239. chars, err := character.ListIDs(r.L.CharacterIDs...)
  240. if err != nil {
  241. return nil, err
  242. }
  243. resolvers := make([]*CharacterResolver, 0, len(chars))
  244. for i := range chars {
  245. if chars[i].ID == "" {
  246. continue
  247. }
  248. resolvers = append(resolvers, &CharacterResolver{C: chars[i]})
  249. }
  250. return resolvers, nil
  251. }
  252. // Posts resolves Log.posts
  253. func (r *LogResolver) Posts(ctx context.Context, args *LogPostArgs) ([]*PostResolver, error) {
  254. var kinds []string
  255. if args.Kinds != nil {
  256. kinds = *args.Kinds
  257. }
  258. posts, err := r.L.Posts(kinds...)
  259. if err != nil {
  260. return nil, err
  261. }
  262. resolvers := make([]*PostResolver, len(posts))
  263. for i := range posts {
  264. resolvers[i] = &PostResolver{posts[i]}
  265. }
  266. return resolvers, nil
  267. }