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.

130 lines
3.7 KiB

  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. "git.aiterp.net/rpdata/api/internal/session"
  7. "git.aiterp.net/rpdata/api/internal/store"
  8. "git.aiterp.net/rpdata/api/loader"
  9. "git.aiterp.net/rpdata/api/model/file"
  10. logModel "git.aiterp.net/rpdata/api/model/log"
  11. "git.aiterp.net/rpdata/api/resolver"
  12. "git.aiterp.net/rpdata/api/schema"
  13. graphql "github.com/graph-gophers/graphql-go"
  14. "github.com/graph-gophers/graphql-go/relay"
  15. )
  16. func main() {
  17. err := store.Init()
  18. if err != nil {
  19. log.Fatalln("Failed to init store:", err)
  20. }
  21. n, err := logModel.UpdateAllCharacters()
  22. if err != nil {
  23. log.Println("Charcter updated stopped:", err)
  24. }
  25. log.Println("Updated characters on", n, "logs")
  26. schema, err := graphql.ParseSchema(schema.String(), &resolver.RootResolver{}, graphql.MaxParallelism(4))
  27. if err != nil {
  28. log.Fatalln("Failed to parse schema:", err)
  29. }
  30. http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  31. if r.Method != "GET" {
  32. http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
  33. return
  34. }
  35. w.Write(page)
  36. }))
  37. relayHandler := &relay.Handler{Schema: schema}
  38. http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
  39. r = session.Load(w, r)
  40. l := loader.New()
  41. r = r.WithContext(l.ToContext(r.Context()))
  42. relayHandler.ServeHTTP(w, r)
  43. })
  44. http.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
  45. r = session.Load(w, r)
  46. sess := session.FromContext(r.Context())
  47. user := sess.User()
  48. if user == nil || !user.Permitted("file.upload") {
  49. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  50. return
  51. }
  52. if err := r.ParseMultipartForm(16384); err != nil {
  53. http.Error(w, "Internal (1): "+err.Error(), http.StatusInternalServerError)
  54. return
  55. }
  56. formFile, header, err := r.FormFile("file")
  57. if err != nil || header == nil || formFile == nil {
  58. http.Error(w, "No file provided", http.StatusBadRequest)
  59. return
  60. }
  61. file, err := file.Upload(r.Context(), header.Filename, header.Header.Get("Content-Type"), user.ID, header.Size, formFile)
  62. if err != nil {
  63. http.Error(w, "Internal (2): "+err.Error(), http.StatusInternalServerError)
  64. return
  65. }
  66. json, err := json.Marshal(file)
  67. if err != nil {
  68. http.Error(w, "Internal (3): "+err.Error(), http.StatusInternalServerError)
  69. return
  70. }
  71. w.Header().Set("Content-Type", "application/json")
  72. w.WriteHeader(http.StatusOK)
  73. w.Write(json)
  74. })
  75. log.Fatal(http.ListenAndServe(":17000", nil))
  76. }
  77. var page = []byte(`
  78. <!DOCTYPE html>
  79. <html>
  80. <head>
  81. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.10.2/graphiql.css" />
  82. <script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/1.1.0/fetch.min.js"></script>
  83. <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react.min.js"></script>
  84. <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react-dom.min.js"></script>
  85. <script src="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.10.2/graphiql.js"></script>
  86. </head>
  87. <body style="width: 100%; height: 100%; margin: 0; overflow: hidden;">
  88. <div id="graphiql" style="height: 100vh;">Loading...</div>
  89. <script>
  90. function graphQLFetcher(graphQLParams) {
  91. return fetch("/graphql", {
  92. method: "post",
  93. body: JSON.stringify(graphQLParams),
  94. credentials: "include",
  95. }).then(function (response) {
  96. return response.text();
  97. }).then(function (responseBody) {
  98. try {
  99. return JSON.parse(responseBody);
  100. } catch (error) {
  101. return responseBody;
  102. }
  103. });
  104. }
  105. ReactDOM.render(
  106. React.createElement(GraphiQL, {fetcher: graphQLFetcher}),
  107. document.getElementById("graphiql")
  108. );
  109. </script>
  110. </body>
  111. </html>
  112. `)