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.

159 lines
3.6 KiB

  1. package channel
  2. import (
  3. "errors"
  4. "strings"
  5. "git.aiterp.net/rpdata/api/internal/store"
  6. "github.com/globalsign/mgo"
  7. "github.com/globalsign/mgo/bson"
  8. )
  9. var collection *mgo.Collection
  10. // ErrInvalidName is an error for an invalid channel name
  11. var ErrInvalidName = errors.New("Invalid channel name")
  12. // A Channel represents information abount an IRC RP channel, and whether it should be logged
  13. type Channel struct {
  14. Name string `bson:"_id"`
  15. Logged bool `bson:"logged"`
  16. Hub bool `bson:"hub"`
  17. EventName string `bson:"event,omitempty"`
  18. LocationName string `bson:"location,omitempty"`
  19. }
  20. // Filter for searching
  21. type Filter struct {
  22. Logged *bool `json:"logged"`
  23. EventName string `json:"eventName"`
  24. LocationName string `json:"locationName"`
  25. }
  26. // Edit edits the channel
  27. func (channel *Channel) Edit(logged, hub *bool, event, location *string) error {
  28. changes := bson.M{}
  29. changed := *channel
  30. if logged != nil && channel.Logged != *logged {
  31. changes["logged"] = *logged
  32. changed.Logged = *logged
  33. }
  34. if hub != nil && channel.Hub != *hub {
  35. changes["hub"] = *hub
  36. changed.Hub = *hub
  37. }
  38. if event != nil && channel.EventName != *event {
  39. changes["event"] = *event
  40. changed.EventName = *event
  41. }
  42. if location != nil && channel.LocationName != *location {
  43. changes["location"] = *location
  44. changed.LocationName = *location
  45. }
  46. if len(changes) == 0 {
  47. return nil
  48. }
  49. err := collection.UpdateId(channel.Name, bson.M{"$set": changes})
  50. if err != nil {
  51. return err
  52. }
  53. *channel = changed
  54. return nil
  55. }
  56. // Remove removes the channel information from the database.
  57. func (channel *Channel) Remove() error {
  58. return collection.RemoveId(channel.Name)
  59. }
  60. // Ensure ensures a channel's existence. It does not change `logged` if there is
  61. // an existing channel.
  62. func Ensure(name string, logged bool) (Channel, error) {
  63. channel, err := FindName(name)
  64. if err == mgo.ErrNotFound {
  65. return New(name, logged, false, "", "")
  66. } else if err != nil {
  67. return Channel{}, err
  68. }
  69. return channel, nil
  70. }
  71. // New creates a new channel
  72. func New(name string, logged, hub bool, event, location string) (Channel, error) {
  73. if len(name) < 3 && !strings.HasPrefix(name, "#") {
  74. return Channel{}, ErrInvalidName
  75. }
  76. channel := Channel{
  77. Name: name,
  78. Logged: logged,
  79. Hub: hub,
  80. EventName: event,
  81. LocationName: location,
  82. }
  83. err := collection.Insert(channel)
  84. if err != nil {
  85. return Channel{}, err
  86. }
  87. return channel, nil
  88. }
  89. // FindName finds a channel by its id (its name).
  90. func FindName(name string) (Channel, error) {
  91. channel := Channel{}
  92. err := collection.FindId(name).One(&channel)
  93. return channel, err
  94. }
  95. // List finds channels, if logged is true it will be limited to logged
  96. // channels
  97. func List(filter *Filter) ([]Channel, error) {
  98. query := bson.M{}
  99. if filter != nil {
  100. if filter.Logged != nil {
  101. query["logged"] = *filter.Logged
  102. }
  103. if filter.EventName != "" {
  104. query["eventName"] = filter.EventName
  105. }
  106. if filter.LocationName != "" {
  107. query["locationName"] = filter.LocationName
  108. }
  109. }
  110. channels := make([]Channel, 0, 128)
  111. err := collection.Find(query).All(&channels)
  112. return channels, err
  113. }
  114. // ListNames finds channels by the names provided
  115. func ListNames(names ...string) ([]Channel, error) {
  116. query := bson.M{"_id": bson.M{"$in": names}}
  117. channels := make([]Channel, 0, 32)
  118. err := collection.Find(query).All(&channels)
  119. return channels, err
  120. }
  121. func init() {
  122. store.HandleInit(func(db *mgo.Database) {
  123. collection = db.C("common.channels")
  124. collection.EnsureIndexKey("logged")
  125. collection.EnsureIndexKey("hub")
  126. collection.EnsureIndexKey("event")
  127. collection.EnsureIndexKey("location")
  128. })
  129. }