fetch.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package server
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strconv"
  6. "github.com/felamaslen/gmus-backend/pkg/database"
  7. "github.com/felamaslen/gmus-backend/pkg/logger"
  8. "github.com/felamaslen/gmus-backend/pkg/read"
  9. "github.com/felamaslen/gmus-backend/pkg/repository"
  10. "github.com/go-redis/redis/v7"
  11. "github.com/jmoiron/sqlx"
  12. )
  13. type ArtistsResponse struct {
  14. Artists []string `json:"artists"`
  15. }
  16. func routeFetchArtists(l *logger.Logger, rdb *redis.Client, w http.ResponseWriter, r *http.Request) error {
  17. db := database.GetConnection()
  18. artists, err := repository.SelectAllArtists(db)
  19. if err != nil {
  20. return err
  21. }
  22. response, err := json.Marshal(ArtistsResponse{
  23. Artists: *artists,
  24. })
  25. if err != nil {
  26. return err
  27. }
  28. w.Write(response)
  29. return nil
  30. }
  31. type AlbumsResponse struct {
  32. Artist string `json:"artist"`
  33. Albums []string `json:"albums"`
  34. }
  35. func routeFetchAlbums(l *logger.Logger, rdb *redis.Client, w http.ResponseWriter, r *http.Request) error {
  36. artist := r.URL.Query().Get("artist")
  37. db := database.GetConnection()
  38. albums, err := repository.SelectAlbumsByArtist(db, artist)
  39. if err != nil {
  40. return err
  41. }
  42. response, err := json.Marshal(AlbumsResponse{
  43. Artist: artist,
  44. Albums: *albums,
  45. })
  46. if err != nil {
  47. return err
  48. }
  49. w.Write(response)
  50. return nil
  51. }
  52. type SongsResponse struct {
  53. Artist string `json:"artist"`
  54. Songs *[]*read.SongExternal `json:"songs"`
  55. }
  56. func routeFetchSongs(l *logger.Logger, rdb *redis.Client, w http.ResponseWriter, r *http.Request) error {
  57. artist := r.URL.Query().Get("artist")
  58. db := database.GetConnection()
  59. songs, err := repository.SelectSongsByArtist(db, artist)
  60. if err != nil {
  61. return err
  62. }
  63. response, err := json.Marshal(SongsResponse{
  64. Artist: artist,
  65. Songs: songs,
  66. })
  67. if err != nil {
  68. return err
  69. }
  70. w.Write(response)
  71. return nil
  72. }
  73. func validateSongId(w http.ResponseWriter, r *http.Request) (id int, err error) {
  74. idRaw := r.URL.Query().Get("id")
  75. id, err = strconv.Atoi(idRaw)
  76. if err != nil {
  77. http.Error(w, "Must provide a valid id", http.StatusBadRequest)
  78. } else if id < 1 {
  79. http.Error(w, "id must be non-negative", http.StatusBadRequest)
  80. }
  81. return
  82. }
  83. func routeFetchSongInfo(l *logger.Logger, rdb *redis.Client, w http.ResponseWriter, r *http.Request) error {
  84. id, err := validateSongId(w, r)
  85. if err != nil {
  86. return nil
  87. }
  88. db := database.GetConnection()
  89. song, err := repository.SelectSong(db, id)
  90. if err != nil {
  91. if err.Error() == "No such ID" {
  92. http.Error(w, "Song not found", http.StatusNotFound)
  93. return nil
  94. }
  95. return err
  96. }
  97. response, err := json.Marshal(read.SongExternal{
  98. Id: id,
  99. TrackNumber: song.TrackNumber,
  100. Title: song.Title,
  101. Artist: song.Artist,
  102. Album: song.Album,
  103. Duration: song.Duration,
  104. })
  105. if err != nil {
  106. return err
  107. }
  108. w.Write(response)
  109. return nil
  110. }
  111. type NullResponse struct {
  112. Id int `json:"id"`
  113. }
  114. func respondWithSongOrNull(db *sqlx.DB, w http.ResponseWriter, song *read.Song) error {
  115. if song.Id == 0 {
  116. response, _ := json.Marshal(NullResponse{})
  117. w.Write(response)
  118. return nil
  119. }
  120. response, err := json.Marshal(read.SongExternal{
  121. Id: song.Id,
  122. TrackNumber: song.TrackNumber,
  123. Title: song.Title,
  124. Artist: song.Artist,
  125. Album: song.Album,
  126. Duration: song.Duration,
  127. })
  128. if err != nil {
  129. return err
  130. }
  131. w.Write(response)
  132. return nil
  133. }
  134. func routeFetchNextSong(l *logger.Logger, rdb *redis.Client, w http.ResponseWriter, r *http.Request) error {
  135. id, err := validateSongId(w, r)
  136. if err != nil {
  137. return nil
  138. }
  139. db := database.GetConnection()
  140. nextSong, err := repository.GetNextSong(db, int64(id))
  141. if err != nil {
  142. return err
  143. }
  144. if err := respondWithSongOrNull(db, w, nextSong); err != nil {
  145. return err
  146. }
  147. return nil
  148. }
  149. func routeFetchPrevSong(l *logger.Logger, rdb *redis.Client, w http.ResponseWriter, r *http.Request) error {
  150. id, err := validateSongId(w, r)
  151. if err != nil {
  152. return nil
  153. }
  154. db := database.GetConnection()
  155. prevSong, err := repository.GetPrevSong(db, int64(id))
  156. if err != nil {
  157. return err
  158. }
  159. if err := respondWithSongOrNull(db, w, prevSong); err != nil {
  160. return err
  161. }
  162. return nil
  163. }