/
channel.api.service.go
237 lines (204 loc) · 7.37 KB
/
channel.api.service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
package services
import (
"errors"
"fmt"
"github.com/gibigo/cornix-tv-channel/internal/api/dal"
"github.com/gibigo/cornix-tv-channel/internal/api/types"
"github.com/gibigo/cornix-tv-channel/internal/utils"
"github.com/gibigo/cornix-tv-channel/internal/utils/logging"
"github.com/gofiber/fiber/v2"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
)
// @Summary Create a channel
// @Description Create a new channel
// @Security BasicAuth
// @Tags channels
// @Accept json
// @Produce json
// @Param channel body types.AddChannel true "Channel to create"
// @Success 200 {object} types.Channel
// @Failure 401 {string} string
// @Failure 409 {object} utils.HTTPError
// @Router /channels [post]
func CreateChannel(c *fiber.Ctx) error {
// define logger for this function
logger := logging.Log.WithFields(log.Fields{
"function": "CreateChannel",
"package": "services",
})
// parse the request body
var newChannel types.AddChannel
if err := utils.ParseBodyAndValidate(c, &newChannel); err != nil {
// err = *fiber.Error, only log error message
logger.Error(err.Message)
return err
}
// check if there is already a channel with that particular telegram id
result := dal.FindChannelByTelegramId(&dal.Channel{}, newChannel.TelegramID)
if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
if result.RowsAffected > 0 {
return utils.NewHTTPError(c, fiber.StatusConflict, fmt.Errorf("channel %d already exists", newChannel.TelegramID))
} else {
logger.Error(result.Error)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, result.Error)
}
}
// get the user id of the current user
var user types.GetUserWithID
if err := dal.FindUserByName(&user, c.Locals("username")).Error; err != nil {
logger.Error(err)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, err)
}
// create the new channel
channel := &dal.Channel{
Telegram: newChannel.TelegramID,
UserID: user.ID,
}
if err := dal.CreateChannel(channel).Error; err != nil {
logger.Error(err)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, err)
}
logger.Infof("user %s created telegram channel: %d", c.Locals("username"), channel.Telegram)
// fetch the newly created channel
var returnChannel types.Channel
if err := dal.FindChannelByTelegramId(&returnChannel, channel.Telegram).Error; err != nil {
logger.Errorf("error while fetching the new channel: %s", err)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, err)
}
return c.JSON(returnChannel)
}
// @Summary Get all channels
// @Description Get all channels of the current user
// @Security BasicAuth
// @Tags channels
// @Accept json
// @Produce json
// @Success 200 {array} types.Channel
// @Failure 401 {string} string
// @Failure 404 {object} utils.HTTPError
// @Router /channels [get]
func GetChannels(c *fiber.Ctx) error {
// define logger for this function
logger := logging.Log.WithFields(log.Fields{
"function": "GetChannels",
"package": "services",
})
// get all channels from the user
var channels []types.Channel
result := dal.FindAllChannelsFromUser(&channels, c.Locals("username"))
if err := result.Error; err != nil {
logger.Error(err)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, result.Error)
}
// return 404 if user has no channels configured
if result.RowsAffected == 0 {
return utils.NewHTTPError(c, fiber.StatusNotFound, fmt.Sprintf("no channels found for user %s", c.Locals("username")))
}
return c.JSON(channels)
}
// @Summary Get a spectific channel
// @Description Get a spectific channel
// @Security BasicAuth
// @Tags channels
// @Accept json
// @Produce json
// @Success 200 {object} types.Channel
// @Failure 401 {string} string
// @Failure 404 {object} utils.HTTPError
// @Param channel_id path int true "Channel ID"
// @Router /channels/{channel_id} [get]
func GetChannel(c *fiber.Ctx) error {
// define logger for this function
logger := logging.Log.WithFields(log.Fields{
"function": "GetChannel",
"package": "services",
})
var channel types.Channel
result := dal.FindChannelFromUser(&channel, c.Locals("username"), c.Params("channel"))
if result.Error != nil {
logger.Error(result.Error)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, result.Error)
}
// return 404 if the channel does not exist
if result.RowsAffected == 0 {
return utils.NewHTTPError(c, fiber.StatusNotFound, fmt.Sprintf("channel with id %s not found", c.Params("channel")))
}
return c.JSON(channel)
}
// @Summary Delete a channel
// @Description Delete a channel and all related strategies
// @Security BasicAuth
// @Tags channels
// @Accept json
// @Produce json
// @Success 204 {string} string
// @Failure 401 {string} string
// @Failure 404 {object} utils.HTTPError
// @Param channel_id path int true "Channel ID"
// @Router /channels/{channel_id} [delete]
func DeleteChannel(c *fiber.Ctx) error {
// define logger for this function
logger := logging.Log.WithFields(log.Fields{
"function": "DeleteChannel",
"package": "services",
})
var channel types.Channel
result := dal.FindChannelFromUser(&channel, c.Locals("username"), c.Params("channel"))
if result.Error != nil {
logger.Error(result.Error)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, result.Error)
}
// return 404 if the channel does not exist or does not belong to the user
if result.RowsAffected == 0 {
return utils.NewHTTPError(c, fiber.StatusNotFound, fmt.Sprintf("user %s has no channel with id %s", c.Locals("username"), c.Params("channel")))
}
// delete the channel
if err := dal.DeleteChannelFromUser(c.Locals("username"), c.Params("channel")).Error; err != nil {
logger.Error(err)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, err)
}
logger.Infof("deleted channel %s from user %s", c.Params("channel"), c.Locals("username"))
c.Status(fiber.StatusNoContent)
return nil
}
// @Summary Update a channel
// @Description Change the telegram id of a channel and keep all related strategies
// @Security BasicAuth
// @Tags channels
// @Accept json
// @Produce json
// @Success 200 {object} types.Channel
// @Failure 401 {string} string
// @Failure 404 {object} utils.HTTPError
// @Param channel_id path int true "Channel ID"
// @Param channel body types.UpdateChannel true "Channel to create"
// @Router /channels/{channel_id} [put]
func UpdateChannel(c *fiber.Ctx) error {
// define logger for this function
logger := logging.Log.WithFields(log.Fields{
"function": "UpdateChannel",
"package": "services",
})
// parse the body to a new struct
var channelUpdate types.UpdateChannel
if err := utils.ParseBodyAndValidate(c, &channelUpdate); err != nil {
// err = *fiber.Error, only log error message
logger.Error(err.Message)
return err
}
result := dal.ChangeChannelTelegram(c.Locals("username"), channelUpdate.Telegram, c.Params("channel"))
if result.Error != nil {
logger.Error(result.Error)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, result.Error)
}
if result.RowsAffected == 0 {
return utils.NewHTTPError(c, fiber.StatusNotFound, fmt.Sprintf("user %s has no channel with id %s", c.Locals("username"), c.Params("channel")))
}
var returnChannel types.Channel
if err := dal.FindChannelByTelegramId(&returnChannel, channelUpdate.Telegram).Error; err != nil {
logger.Errorf("error while fetching the updated channel: %s", err)
return utils.NewHTTPError(c, fiber.StatusInternalServerError, err)
}
return c.JSON(returnChannel)
}