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.

92 lines
2.2 KiB

  1. package story
  2. import (
  3. "crypto/rand"
  4. "encoding/binary"
  5. "strconv"
  6. "time"
  7. "git.aiterp.net/rpdata/api/internal/store"
  8. "github.com/globalsign/mgo"
  9. "github.com/globalsign/mgo/bson"
  10. )
  11. var chapterCollection *mgo.Collection
  12. // A Chapter is a part of a story.
  13. type Chapter struct {
  14. ID string `bson:"_id"`
  15. StoryID string `bson:"storyId"`
  16. Title string `bson:"title"`
  17. Author string `bson:"author"`
  18. Source string `bson:"source"`
  19. CreatedDate time.Time `bson:"createdDate"`
  20. FictionalDate time.Time `bson:"fictionalDate,omitempty"`
  21. EditedDate time.Time `bson:"editedDate"`
  22. }
  23. // Edit edits a chapter, and updates EditedDate. While many Edit functions cheat if there's nothing to
  24. // change, this functill will due to EditedDate.
  25. func (chapter *Chapter) Edit(title, source *string, fictionalDate *time.Time) error {
  26. now := time.Now()
  27. changes := bson.M{"editedDate": now}
  28. changed := *chapter
  29. changed.EditedDate = now
  30. if title != nil && *title != chapter.Title {
  31. changes["title"] = *title
  32. changed.Title = *title
  33. }
  34. if source != nil && *source != chapter.Source {
  35. changes["source"] = *source
  36. changed.Source = *source
  37. }
  38. if fictionalDate != nil && *fictionalDate != chapter.FictionalDate {
  39. changes["fictionalDate"] = *fictionalDate
  40. changed.FictionalDate = *fictionalDate
  41. }
  42. err := chapterCollection.UpdateId(chapter.ID, bson.M{"$set": changes})
  43. if err != nil {
  44. return err
  45. }
  46. *chapter = changed
  47. return nil
  48. }
  49. // Remove removes a chapter.
  50. func (chapter *Chapter) Remove() error {
  51. return chapterCollection.RemoveId(chapter.ID)
  52. }
  53. // makeChapterID makes a random chapter ID that's 24 characters long
  54. func makeChapterID() string {
  55. result := "SC"
  56. offset := 0
  57. data := make([]byte, 32)
  58. rand.Read(data)
  59. for len(result) < 24 {
  60. result += strconv.FormatUint(binary.LittleEndian.Uint64(data[offset:]), 36)
  61. offset += 8
  62. if offset >= 32 {
  63. rand.Read(data)
  64. offset = 0
  65. }
  66. }
  67. return result[:24]
  68. }
  69. func init() {
  70. store.HandleInit(func(db *mgo.Database) {
  71. chapterCollection = db.C("story.chapters")
  72. chapterCollection.EnsureIndexKey("storyId")
  73. chapterCollection.EnsureIndexKey("author")
  74. chapterCollection.EnsureIndexKey("createdDate")
  75. })
  76. }