Mirror of github.com/gissleh/irc
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.

221 lines
4.9 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package irc
  2. import (
  3. "context"
  4. "encoding/json"
  5. "time"
  6. )
  7. // An Event is any thing that passes through the irc client's event loop. It's not thread safe, because it's processed
  8. // in sequence and should not be used off the goroutine that processed it.
  9. type Event struct {
  10. kind string
  11. verb string
  12. name string
  13. Time time.Time
  14. Nick string
  15. User string
  16. Host string
  17. Args []string
  18. Text string
  19. Tags map[string]string
  20. ctx context.Context
  21. cancel context.CancelFunc
  22. killed bool
  23. hidden bool
  24. targets []Target
  25. targetIds map[Target]string
  26. RenderTags map[string]string
  27. }
  28. // NewEvent makes a new event with Kind, Verb, Time set and Args and Tags initialized.
  29. func NewEvent(kind, verb string) Event {
  30. return Event{
  31. kind: kind,
  32. verb: verb,
  33. name: kind + "." + verb,
  34. Time: time.Now(),
  35. Args: make([]string, 0, 4),
  36. Tags: make(map[string]string),
  37. targetIds: make(map[Target]string),
  38. RenderTags: make(map[string]string),
  39. }
  40. }
  41. // Kind gets the event's kind
  42. func (event *Event) Kind() string {
  43. return event.kind
  44. }
  45. // Verb gets the event's verb
  46. func (event *Event) Verb() string {
  47. return event.verb
  48. }
  49. // Name gets the event name, which is Kind and Verb separated by a dot.
  50. func (event *Event) Name() string {
  51. return event.name
  52. }
  53. // IsEither returns true if the event has the kind and one of the verbs.
  54. func (event *Event) IsEither(kind string, verbs ...string) bool {
  55. if event.kind != kind {
  56. return false
  57. }
  58. for i := range verbs {
  59. if event.verb == verbs[i] {
  60. return true
  61. }
  62. }
  63. return false
  64. }
  65. // Context gets the event's context if it's part of the loop, or `context.Background` otherwise. client.Emit
  66. // will set this context on its copy and return it.
  67. func (event *Event) Context() context.Context {
  68. if event.ctx == nil {
  69. return context.Background()
  70. }
  71. return event.ctx
  72. }
  73. // Kill stops propagation of the event. The context will be killed once
  74. // the current event handler returns.
  75. //
  76. // A use case for this is to prevent the default input handler from firing
  77. // on an already prcoessed input event.
  78. func (event *Event) Kill() {
  79. event.killed = true
  80. }
  81. // Killed returns true if Kill has been called.
  82. func (event *Event) Killed() bool {
  83. return event.killed
  84. }
  85. // Hide will not stop propagation, but it will allow output handlers to know not to
  86. // render it.
  87. func (event *Event) Hide() {
  88. event.hidden = true
  89. }
  90. // Hidden returns true if Hide has been called.
  91. func (event *Event) Hidden() bool {
  92. return event.hidden
  93. }
  94. // Arg gets the argument by index. The rationale behind it is that some
  95. // servers may use it for the last argument in JOINs and such.
  96. func (event *Event) Arg(index int) string {
  97. if index < 0 || index > len(event.Args) {
  98. return ""
  99. }
  100. if index == len(event.Args) {
  101. return event.Text
  102. }
  103. return event.Args[index]
  104. }
  105. // Target finds the first target with one of the kinds specified. If none
  106. // are specified, the first target will be returned. If more than one
  107. // is provided, the first kinds are prioritized.
  108. func (event *Event) Target(kinds ...string) Target {
  109. if len(event.targets) == 0 {
  110. return nil
  111. }
  112. if len(kinds) == 0 || kinds[0] == "" {
  113. return event.targets[0]
  114. }
  115. for _, kind := range kinds {
  116. for _, target := range event.targets {
  117. if target.Kind() == kind {
  118. return target
  119. }
  120. }
  121. }
  122. return nil
  123. }
  124. // ChannelTarget gets the first channel target.
  125. func (event *Event) ChannelTarget() *Channel {
  126. target := event.Target("channel")
  127. if target == nil {
  128. return nil
  129. }
  130. return target.(*Channel)
  131. }
  132. // QueryTarget gets the first query target.
  133. func (event *Event) QueryTarget() *Query {
  134. target := event.Target("query")
  135. if target == nil {
  136. return nil
  137. }
  138. return target.(*Query)
  139. }
  140. // StatusTarget gets the first status target.
  141. func (event *Event) StatusTarget() *Status {
  142. target := event.Target("status")
  143. if target == nil {
  144. return nil
  145. }
  146. return target.(*Status)
  147. }
  148. // MarshalJSON makes a JSON object from the event.
  149. func (event *Event) MarshalJSON() ([]byte, error) {
  150. data := eventJSONData{
  151. Name: event.Name(),
  152. Kind: event.kind,
  153. Verb: event.verb,
  154. Time: event.Time,
  155. Nick: event.Nick,
  156. User: event.User,
  157. Host: event.Host,
  158. Args: event.Args,
  159. Text: event.Text,
  160. Tags: event.Tags,
  161. RenderTags: event.RenderTags,
  162. }
  163. data.Targets = make([]string, 0, len(event.targets))
  164. for _, target := range event.targets {
  165. data.Targets = append(data.Targets, event.targetIds[target])
  166. }
  167. return json.Marshal(data)
  168. }
  169. type eventJSONData struct {
  170. Name string `json:"name"`
  171. Kind string `json:"kind"`
  172. Verb string `json:"verb"`
  173. Time time.Time `json:"time"`
  174. Nick string `json:"nick"`
  175. User string `json:"user"`
  176. Host string `json:"host"`
  177. Args []string `json:"args"`
  178. Text string `json:"text"`
  179. Tags map[string]string `json:"tags"`
  180. Targets []string `json:"targets"`
  181. RenderTags map[string]string `json:"renderTags"`
  182. }