route_line.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SPDX-FileCopyrightText: Adam Evyčędo
  2. //
  3. // SPDX-License-Identifier: AGPL-3.0-or-later
  4. package server
  5. import (
  6. "strings"
  7. "apiote.xyz/p/szczanieckiej/api"
  8. "apiote.xyz/p/szczanieckiej/config"
  9. "apiote.xyz/p/szczanieckiej/traffic"
  10. "errors"
  11. "net/http"
  12. "apiote.xyz/p/gott/v2"
  13. "git.sr.ht/~sircmpwn/go-bare"
  14. )
  15. type LineHandlerVars struct {
  16. HandlerVars
  17. context traffic.Context
  18. line traffic.Line
  19. }
  20. func checkLinePath(v AbstractHandlerVars) error {
  21. if len(v.getPath()) < 3 {
  22. return ServerError{
  23. code: http.StatusNotFound,
  24. field: "line",
  25. value: "EMPTY",
  26. }
  27. }
  28. return nil
  29. }
  30. func getLine(v AbstractHandlerVars) (AbstractHandlerVars, error) {
  31. vv := v.(*LineHandlerVars)
  32. var (
  33. line traffic.Line
  34. err error
  35. )
  36. lineInQuery := v.getRequest().Form.Get("line")
  37. if lineInQuery != "" {
  38. line, err = traffic.GetLine(lineInQuery, v.getContext(), v.getTraffic())
  39. } else {
  40. lineName := strings.Join(v.getPath()[2:], "/")
  41. line, err = traffic.GetLineOld(lineName, v.getContext(), v.getTraffic())
  42. }
  43. vv.line = line
  44. return vv, err
  45. }
  46. func checkEmptyLine(v AbstractHandlerVars) error {
  47. vv := v.(*LineHandlerVars)
  48. if vv.line.Name == "" {
  49. return ServerError{
  50. code: http.StatusNotFound,
  51. field: "line",
  52. value: v.getPath()[2],
  53. }
  54. }
  55. return nil
  56. }
  57. func makeLineResponse(v AbstractHandlerVars) (AbstractHandlerVars, error) {
  58. vv := v.(*LineHandlerVars)
  59. response, err := api.MakeLineResponse(vv.line, v.getContext(), v.getTraffic(), v.getAccept())
  60. v.setResponse(response)
  61. if err != nil && errors.Is(err, api.AcceptError) {
  62. err = ServerError{
  63. code: http.StatusNotAcceptable,
  64. }
  65. }
  66. return vv, err
  67. }
  68. func marshalLineResponse(v AbstractHandlerVars) (AbstractHandlerVars, error) {
  69. r := v.getResponse().(api.LineResponse)
  70. bytes, err := bare.Marshal(&r)
  71. v.setResponseBytes(bytes)
  72. return v, err
  73. }
  74. func handleLine(w http.ResponseWriter, r *http.Request, feedName string, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
  75. handlerVars := &LineHandlerVars{
  76. HandlerVars: HandlerVars{
  77. w: w,
  78. r: r,
  79. t: t,
  80. c: cfg,
  81. a: accept,
  82. f: feedName,
  83. },
  84. }
  85. result := gott.R[AbstractHandlerVars]{
  86. S: handlerVars,
  87. }
  88. result = result.
  89. Bind(splitPath).
  90. SafeTee(prepareForm).
  91. Tee(checkLinePath).
  92. Bind(getVersionCode).
  93. Map(createContext).
  94. Bind(getLine).
  95. Tee(checkEmptyLine).
  96. Bind(makeLineResponse).
  97. Bind(marshalLineResponse).
  98. Tee(writeResponse)
  99. return result.E
  100. }