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.

143 lines
3.2 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. Event string `bson:"event,omitempty"`
  18. Location string `bson:"location,omitempty"`
  19. }
  20. // Edit edits the channel
  21. func (channel *Channel) Edit(logged, hub *bool, event, location *string) error {
  22. changes := bson.M{}
  23. changed := *channel
  24. if logged != nil && channel.Logged != *logged {
  25. changes["logged"] = *logged
  26. changed.Logged = *logged
  27. }
  28. if hub != nil && channel.Hub != *hub {
  29. changes["hub"] = *hub
  30. changed.Hub = *hub
  31. }
  32. if event != nil && channel.Event != *event {
  33. changes["event"] = *event
  34. changed.Event = *event
  35. }
  36. if location != nil && channel.Event != *location {
  37. changes["location"] = *location
  38. changed.Location = *location
  39. }
  40. if len(changes) == 0 {
  41. return nil
  42. }
  43. err := collection.UpdateId(channel.Name, bson.M{"$set": changes})
  44. if err != nil {
  45. return err
  46. }
  47. *channel = changed
  48. return nil
  49. }
  50. // Remove removes the channel information from the database.
  51. func (channel *Channel) Remove() error {
  52. return collection.RemoveId(channel.Name)
  53. }
  54. // Ensure ensures a channel's existence. It does not change `logged` if there is
  55. // an existing channel.
  56. func Ensure(name string, logged bool) (Channel, error) {
  57. channel, err := FindName(name)
  58. if err == mgo.ErrNotFound {
  59. return New(name, logged, false, "", "")
  60. } else if err != nil {
  61. return Channel{}, err
  62. }
  63. return channel, nil
  64. }
  65. // New creates a new channel
  66. func New(name string, logged, hub bool, event, location string) (Channel, error) {
  67. if len(name) < 3 && !strings.HasPrefix(name, "#") {
  68. return Channel{}, ErrInvalidName
  69. }
  70. channel := Channel{
  71. Name: name,
  72. Logged: logged,
  73. Hub: hub,
  74. Event: event,
  75. Location: location,
  76. }
  77. err := collection.Insert(channel)
  78. if err != nil {
  79. return Channel{}, err
  80. }
  81. return channel, nil
  82. }
  83. // FindName finds a channel by its id (its name).
  84. func FindName(name string) (Channel, error) {
  85. channel := Channel{}
  86. err := collection.FindId(name).One(&channel)
  87. return channel, err
  88. }
  89. // List finds channels, if logged is true it will be limited to logged
  90. // channels
  91. func List(logged bool) ([]Channel, error) {
  92. query := bson.M{}
  93. if logged {
  94. query["logged"] = true
  95. }
  96. channels := make([]Channel, 0, 32)
  97. err := collection.Find(query).All(&channels)
  98. return channels, err
  99. }
  100. // ListNames finds channels by the names provided
  101. func ListNames(names ...string) ([]Channel, error) {
  102. query := bson.M{"_id": bson.M{"$in": names}}
  103. channels := make([]Channel, 0, 32)
  104. err := collection.Find(query).All(&channels)
  105. return channels, err
  106. }
  107. func init() {
  108. store.HandleInit(func(db *mgo.Database) {
  109. collection = db.C("common.channels")
  110. collection.EnsureIndexKey("logged")
  111. collection.EnsureIndexKey("hub")
  112. collection.EnsureIndexKey("event")
  113. collection.EnsureIndexKey("location")
  114. })
  115. }