playlists.go 8.2 KB
Newer Older
1
//
Christian Pointner's avatar
Christian Pointner committed
2
3
//  tank, Import and Playlist Daemon for Aura project
//  Copyright (C) 2017-2020 Christian Pointner <equinox@helsinki.at>
4
//
Christian Pointner's avatar
Christian Pointner committed
5
6
7
8
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as
//  published by the Free Software Foundation, either version 3 of the
//  License, or (at your option) any later version.
9
//
Christian Pointner's avatar
Christian Pointner committed
10
//  This program is distributed in the hope that it will be useful,
11
12
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Christian Pointner's avatar
Christian Pointner committed
13
//  GNU Affero General Public License for more details.
14
//
Christian Pointner's avatar
Christian Pointner committed
15
16
//  You should have received a copy of the GNU Affero General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18
19
20
21
//

package v1

import (
22
	"encoding/json"
23
	"net/http"
24

25
	"github.com/gin-gonic/gin"
26
	"gitlab.servus.at/autoradio/tank/store"
27
28
)

29
30
31
32
33
34
35
36
// ListPlaylistsOfShow lists playlists.
// @Summary      List playlists
// @Description  Lists playlists of show.
// @Produce      json
// @Param        name    path      string  true   "Name of the show"
// @Param        limit   query     int  false  "Limit number of results"
// @Param        offset  query     int  false  "Start listing from offset"
// @Success      200     {object}  PlaylistsListing
37
// @Failure      400     {object}  ErrorResponse
38
39
40
// @Failure      403     {object}  ErrorResponse
// @Failure      500     {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/playlists [get]
41
42
func (api *API) ListPlaylistsOfShow(c *gin.Context) {
	showID := c.Param("show-id")
43
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
44
45
		return
	}
46
47
48
49
	offset, limit, ok := getPaginationParameter(c)
	if !ok {
		return
	}
50

51
	playlists, err := api.store.ListPlaylists(showID, offset, limit)
52
53
54
	if err != nil {
		sendError(c, err)
		return
55
	}
56
	c.JSON(http.StatusOK, PlaylistsListing{playlists})
57
58
}

59
60
61
62
63
64
65
66
67
68
69
70
// CreatePlaylistForShow creates a new playlist.
// @Summary      Create playlist
// @Description  Creates a new playlist for the show.
// @Accept       json
// @Produce      json
// @Param        name      path      string          true  "Name of the show"
// @Param        playlist  body      store.Playlist  true  "Playlist data"
// @Success      201       {object}  store.Playlist
// @Failure      400       {object}  ErrorResponse
// @Failure      403       {object}  ErrorResponse
// @Failure      500       {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/playlists [post]
71
72
func (api *API) CreatePlaylistForShow(c *gin.Context) {
	showID := c.Param("show-id")
73
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
74
75
		return
	}
76

77
78
79
80
81
82
83
84
85
	playlist := &store.Playlist{}
	err := json.NewDecoder(c.Request.Body).Decode(playlist)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "error decoding playlist: " + err.Error()})
		return
	}
	if playlist, err = api.store.CreatePlaylist(showID, *playlist); err != nil {
		sendError(c, err)
		return
86
	}
87
	c.JSON(http.StatusCreated, playlist)
88
89
}

90
91
92
93
94
95
96
97
98
// ReadPlaylistOfShow retrieves a playlist of a show.
// @Summary      Retrieve playlist
// @Description  Retrieves a playlist of a show.
// @Produce      json
// @Param        name  path      string  true  "Name of the show"
// @Param        id   path      int  true  "ID of the playlist"
// @Success      200  {object}  store.Playlist
// @Failure      400  {object}  ErrorResponse
// @Failure      403  {object}  ErrorResponse
99
// @Failure      404  {object}  ErrorResponse
100
101
// @Failure      500  {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/playlists/{id} [get]
102
103
func (api *API) ReadPlaylistOfShow(c *gin.Context) {
	showID := c.Param("show-id")
104
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
105
106
		return
	}
107

108
109
110
111
112
113
114
115
116
	id, err := idFromString(c.Param("playlist-id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid playlist-id: " + err.Error()})
		return
	}
	playlist, err := api.store.GetPlaylist(showID, id)
	if err != nil {
		sendError(c, err)
		return
117
	}
118
	c.JSON(http.StatusOK, playlist)
119
120
}

121
122
123
124
125
126
127
128
129
130
131
// UpdatePlaylistOfShow updates a playlist of a show.
// @Summary      Update playlist
// @Description  Updates a playlist of a show.
// @Accept       json
// @Produce      json
// @Param        name      path      string          true  "Name of the show"
// @Param        id        path      int             true  "ID of the playlist"
// @Param        playlist  body      store.Playlist  true  "Playlist data"
// @Success      200       {object}  store.Playlist
// @Failure      400       {object}  ErrorResponse
// @Failure      403       {object}  ErrorResponse
132
// @Failure      404       {object}  ErrorResponse
133
134
// @Failure      500       {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/playlists/{id} [put]
135
136
func (api *API) UpdatePlaylistOfShow(c *gin.Context) {
	showID := c.Param("show-id")
137
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
138
139
		return
	}
140

141
142
143
144
145
146
147
148
149
150
151
152
153
	id, err := idFromString(c.Param("playlist-id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid playlist-id: " + err.Error()})
		return
	}
	playlist := &store.Playlist{}
	if err = json.NewDecoder(c.Request.Body).Decode(playlist); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "error decoding playlist: " + err.Error()})
		return
	}
	if playlist, err = api.store.UpdatePlaylist(showID, id, *playlist); err != nil {
		sendError(c, err)
		return
154
	}
155
	c.JSON(http.StatusOK, playlist)
156
157
}

158
159
160
161
162
163
164
165
// DeletePlaylistOfShow deletes a playlist of a show.
// @Summary      Delete playlist
// @Description  Deletes a playlist of a show.
// @Param        name  path      string  true  "Name of the show"
// @Param        id    path      int     true  "ID of the playlist"
// @Success      204   {object}  nil
// @Failure      400   {object}  ErrorResponse
// @Failure      403   {object}  ErrorResponse
166
// @Failure      404   {object}  ErrorResponse
167
168
// @Failure      500   {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/playlists/{id} [delete]
169
170
func (api *API) DeletePlaylistOfShow(c *gin.Context) {
	showID := c.Param("show-id")
171
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
172
173
		return
	}
174

175
176
177
178
179
180
181
182
	id, err := idFromString(c.Param("playlist-id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid playlist-id: " + err.Error()})
		return
	}
	if err = api.store.DeletePlaylist(showID, id); err != nil {
		sendError(c, err)
		return
183
	}
184
	c.JSON(http.StatusNoContent, nil)
185
}
186
187
188

// global

189
190
191
192
193
194
195
// ListPlaylists lists all playlists.
// @Summary      List playlists
// @Description  Lists all playlists.
// @Produce      json
// @Param        limit   query     int     false  "Limit number of results"
// @Param        offset  query     int     false  "Start listing from offset"
// @Success      200     {object}  PlaylistsListing
196
// @Failure      400     {object}  ErrorResponse
197
198
199
// @Failure      403     {object}  ErrorResponse
// @Failure      500     {object}  ErrorResponse
// @Router       /api/v1/playlists [get]
200
func (api *API) ListPlaylists(c *gin.Context) {
201
202
203
204
205
206
207
208
209
210
211
212
213
214
	if authorized, _ := authorizeRequestAllShows(c); !authorized {
		return
	}
	offset, limit, ok := getPaginationParameter(c)
	if !ok {
		return
	}

	playlists, err := api.store.ListPlaylistsAllShows(offset, limit)
	if err != nil {
		sendError(c, err)
		return
	}
	c.JSON(http.StatusOK, PlaylistsListing{playlists})
215
216
}

217
218
219
220
221
222
223
224
// ReadPlaylist retrieves a playlist.
// @Summary      Retrieve playlist
// @Description  Retrieves a playlist.
// @Produce      json
// @Param        id    path      int     true  "ID of the playlist"
// @Success      200   {object}  store.Playlist
// @Failure      400   {object}  ErrorResponse
// @Failure      403   {object}  ErrorResponse
225
// @Failure      404   {object}  ErrorResponse
226
227
// @Failure      500   {object}  ErrorResponse
// @Router       /api/v1/playlists/{id} [get]
228
func (api *API) ReadPlaylist(c *gin.Context) {
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
	if authorized, _ := authorizeRequestAllShows(c); !authorized {
		return
	}

	id, err := idFromString(c.Param("playlist-id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid playlist-id: " + err.Error()})
		return
	}
	playlist, err := api.store.GetPlaylistAllShows(id)
	if err != nil {
		sendError(c, err)
		return
	}
	c.JSON(http.StatusOK, playlist)
244
}