parse.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package web
  2. import (
  3. "bytes"
  4. "io"
  5. "mime/multipart"
  6. "net/http"
  7. p "github.com/ajswis/go-pkparse-server/pokemon"
  8. "github.com/ajswis/go-pkparse-server/pokemon-parsing"
  9. "github.com/gin-gonic/gin"
  10. )
  11. /*
  12. curl -X POST http://localhost:8080/parse \
  13. -F "pkmn=@/path/to/test/file1" \
  14. -F "pkmn=@/path/to/test/file2" \
  15. -H "Content-Type: multipart/form-data"
  16. */
  17. // parse grabs multipart file uploads under the key `pkmn`, aggregates them, and
  18. // delegates work to the parser.
  19. // NOTE: This can probably be improved by 1) parallelizing upload reads, or 2)
  20. // not accepting file uploads, preferring to service binary data as encoded
  21. // strings
  22. func (s *Server) parse(c *gin.Context) {
  23. form, err := c.MultipartForm()
  24. if err != nil {
  25. render(c, http.StatusInternalServerError, gin.H{"error": err.Error()})
  26. return
  27. }
  28. var rawPokemon []p.RawPokemon
  29. var files []*multipart.FileHeader = form.File["pkmn"]
  30. for _, file := range files {
  31. var err error
  32. var src multipart.File
  33. src, err = file.Open()
  34. if err != nil {
  35. render(c, http.StatusInternalServerError, gin.H{"error": err.Error()})
  36. return
  37. }
  38. defer src.Close()
  39. buf := bytes.NewBuffer(nil)
  40. if _, err = io.Copy(buf, src); err != nil {
  41. render(c, http.StatusInternalServerError, gin.H{"error": err.Error()})
  42. return
  43. }
  44. rawPokemon = append(rawPokemon, buf.Bytes())
  45. }
  46. pkmn, err := pokemonparsing.ParseAll(rawPokemon)
  47. if err != nil {
  48. render(c, http.StatusUnprocessableEntity, gin.H{"error": err.Error()})
  49. return
  50. }
  51. render(c, http.StatusOK, pkmn)
  52. }