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.

101 lines
2.6 KiB

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "runtime/debug"
  8. "strings"
  9. "git.aiterp.net/rpdata/api/graph2"
  10. "git.aiterp.net/rpdata/api/internal/auth"
  11. "git.aiterp.net/rpdata/api/internal/loader"
  12. "git.aiterp.net/rpdata/api/internal/store"
  13. "git.aiterp.net/rpdata/api/models"
  14. "git.aiterp.net/rpdata/api/models/changes"
  15. "git.aiterp.net/rpdata/api/models/logs"
  16. "github.com/99designs/gqlgen/handler"
  17. )
  18. func main() {
  19. err := store.Init()
  20. if err != nil {
  21. log.Fatalln("Failed to init store:", err)
  22. }
  23. http.Handle("/", handler.Playground("RPData API", "/graphql"))
  24. http.Handle("/graphql", queryHandler())
  25. go func() {
  26. err := logs.RunFullUpdate()
  27. if err != nil {
  28. log.Println(err)
  29. }
  30. log.Println("Characters updated")
  31. }()
  32. go logListedChanges()
  33. log.Fatal(http.ListenAndServe(":8081", nil))
  34. }
  35. func logListedChanges() {
  36. sub := changes.Subscribe(context.Background(), nil, true)
  37. for change := range sub {
  38. log.Printf("Change: Author=%#+v Model=%#+v Op=%#+v", change.Author, change.Model, change.Op)
  39. for _, object := range change.Objects() {
  40. switch object := object.(type) {
  41. case models.Log:
  42. log.Printf("\tLog: %s (%s)", object.ID, object.ShortID)
  43. case models.Character:
  44. log.Printf("\tCharacter: %s", object.ID)
  45. case models.Channel:
  46. log.Printf("\tChannel: %s", object.Name)
  47. case models.Post:
  48. log.Printf("\tPost: %s", object.ID)
  49. case models.Story:
  50. log.Printf("\tStory: %s", object.ID)
  51. case models.Tag:
  52. log.Printf("\tTag: (%s,%s)", object.Kind, object.Name)
  53. case models.Chapter:
  54. log.Printf("\tChapter: %s", object.ID)
  55. case models.Comment:
  56. log.Printf("\tComment: %s", object.ID)
  57. }
  58. }
  59. }
  60. log.Println("Change subscription closed.")
  61. }
  62. func queryHandler() http.HandlerFunc {
  63. handler := handler.GraphQL(
  64. graph2.New(),
  65. handler.RecoverFunc(func(ctx context.Context, err interface{}) error {
  66. log.Println(err)
  67. log.Println(string(debug.Stack()))
  68. return fmt.Errorf("The server failed to serve your request due to an internal error, it has been logged")
  69. }),
  70. handler.ComplexityLimit(300),
  71. )
  72. return func(w http.ResponseWriter, r *http.Request) {
  73. l := loader.New()
  74. r = r.WithContext(l.ToContext(r.Context()))
  75. // >_>
  76. if strings.HasPrefix(r.Header.Get("Authorization"), "Bearer of the curse") {
  77. w.Header().Set("X-Emerald-Herald", "Seek souls. Larger, more powerful souls.")
  78. w.Header().Add("X-Emerald-Herald", "Seek the king, that is the only way.")
  79. w.Header().Add("X-Emerald-Herald", "Lest this land swallow you whole... As it has so many others.")
  80. }
  81. r = auth.RequestWithToken(r)
  82. handler.ServeHTTP(w, r)
  83. }
  84. }