Passed
Push — main ( 619ee7...6c7dd4 )
by Yume
01:38
created

controllers.CreateNewCard   C

Complexity

Conditions 9

Size

Total Lines 66
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 46
nop 1
dl 0
loc 66
rs 6.4339
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
package controllers
2
3
import (
4
	"memnixrest/app/database"
5
	"memnixrest/app/models"
6
	"memnixrest/pkg/queries"
7
	"net/http"
8
	"strings"
9
10
	"github.com/gofiber/fiber/v2"
11
)
12
13
// GetTodayCard method
14
// @Description Get next today card
15
// @Summary get a card
16
// @Tags Card
17
// @Produce json
18
// @Success 200 {object} models.Card
19
// @Router /v1/cards/today [get]
20
func GetTodayCard(c *fiber.Ctx) error {
21
	res := *new(models.ResponseHTTP)
22
23
	auth := CheckAuth(c, models.PermUser) // Check auth
24
	if !auth.Success {
25
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
26
			Success: false,
27
			Message: auth.Message,
28
			Data:    nil,
29
			Count:   0,
30
		})
31
	}
32
33
	if res = queries.FetchNextTodayCard(c, &auth.User); !res.Success {
34
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
35
			Success: false,
36
			Message: res.Message,
37
			Data:    nil,
38
			Count:   0,
39
		})
40
	}
41
42
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
43
		Success: true,
44
		Message: "Get todays card",
45
		Data:    res.Data,
46
		Count:   1,
47
	})
48
}
49
50
// GetNextCard method
51
// @Description Get next card
52
// @Summary get a card
53
// @Tags Card
54
// @Produce json
55
// @Success 200 {object} models.Card
56
// @Router /v1/cards/next [get]
57
func GetNextCard(c *fiber.Ctx) error {
58
	//db := database.DBConn // DB Conn
59
60
	res := *new(models.ResponseHTTP)
61
	auth := CheckAuth(c, models.PermUser) // Check auth
62
	if !auth.Success {
63
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
64
			Success: false,
65
			Message: auth.Message,
66
			Data:    nil,
67
			Count:   0,
68
		})
69
	}
70
71
	if res = queries.FetchNextCard(c, &auth.User); !res.Success {
72
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
73
			Success: false,
74
			Message: res.Message,
75
			Data:    nil,
76
			Count:   0,
77
		})
78
	}
79
80
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
81
		Success: true,
82
		Message: "Get next card",
83
		Data:    res.Data,
84
		Count:   1,
85
	})
86
}
87
88
// GetNextCard method
89
// @Description Get next card by deckID
90
// @Summary get a card
91
// @Tags Card
92
// @Produce json
93
// @Success 200 {object} models.Card
94
// @Router /v1/cards/{deckID}/next [get]
95
func GetNextCardByDeck(c *fiber.Ctx) error {
96
	//db := database.DBConn // DB Conn
97
98
	deckID := c.Params("deckID")
99
100
	res := *new(models.ResponseHTTP)
101
	auth := CheckAuth(c, models.PermUser) // Check auth
102
	if !auth.Success {
103
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
104
			Success: false,
105
			Message: auth.Message,
106
			Data:    nil,
107
			Count:   0,
108
		})
109
	}
110
111
	if res = queries.FetchNextCardByDeck(c, &auth.User, deckID); !res.Success {
112
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
113
			Success: false,
114
			Message: res.Message,
115
			Data:    nil,
116
			Count:   0,
117
		})
118
	}
119
120
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
121
		Success: true,
122
		Message: "Get next card by deck",
123
		Data:    res.Data,
124
		Count:   1,
125
	})
126
}
127
128
// GetAllCards method
129
// @Description Get every cards. Shouldn't really be used
130
// @Summary get all cards
131
// @Tags Card
132
// @Produce json
133
// @Success 200 {array} models.Card
134
// @Router /v1/cards/ [get]
135
func GetAllCards(c *fiber.Ctx) error {
136
	db := database.DBConn // DB Conn
137
138
	auth := CheckAuth(c, models.PermAdmin) // Check auth
139
	if !auth.Success {
140
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
141
			Success: false,
142
			Message: auth.Message,
143
			Data:    nil,
144
			Count:   0,
145
		})
146
	}
147
148
	var cards []models.Card
149
150
	if res := db.Joins("Deck").Find(&cards); res.Error != nil {
151
152
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
153
			Success: false,
154
			Message: "Failed to get all cards",
155
			Data:    nil,
156
			Count:   0,
157
		})
158
	}
159
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
160
		Success: true,
161
		Message: "Get All cards",
162
		Data:    cards,
163
		Count:   len(cards),
164
	})
165
166
}
167
168
// GetCardByID method to get a card by id
169
// @Description Get a card by tech id
170
// @Summary get a card
171
// @Tags Card
172
// @Produce json
173
// @Param id path int true "Card ID"
174
// @Success 200 {object} models.Card
175
// @Router /v1/cards/id/{id} [get]
176
func GetCardByID(c *fiber.Ctx) error {
177
	db := database.DBConn // DB Conn
178
179
	auth := CheckAuth(c, models.PermAdmin) // Check auth
180
	if !auth.Success {
181
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
182
			Success: false,
183
			Message: auth.Message,
184
			Data:    nil,
185
			Count:   0,
186
		})
187
	}
188
189
	// Params
190
	id := c.Params("id")
191
192
	card := new(models.Card)
193
194
	if err := db.Joins("Deck").First(&card, id).Error; err != nil {
195
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
196
			Success: false,
197
			Message: err.Error(),
198
			Data:    nil,
199
			Count:   0,
200
		})
201
	}
202
203
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
204
		Success: true,
205
		Message: "Success get card by ID.",
206
		Data:    *card,
207
		Count:   1,
208
	})
209
}
210
211
// GetCardsFromDeck method to get cards from deck
212
// @Description Get every cards from a deck
213
// @Summary get a list of card
214
// @Tags Card
215
// @Produce json
216
// @Param deckID path int true "Deck ID"
217
// @Success 200 {array} models.Card
218
// @Router /v1/cards/deck/{deckID} [get]
219
func GetCardsFromDeck(c *fiber.Ctx) error {
220
	db := database.DBConn // DB Conn
221
222
	// Params
223
	id := c.Params("deckID")
224
225
	auth := CheckAuth(c, models.PermAdmin) // Check auth
226
	if !auth.Success {
227
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
228
			Success: false,
229
			Message: auth.Message,
230
			Data:    nil,
231
			Count:   0,
232
		})
233
	}
234
235
	var cards []models.Card
236
237
	if err := db.Joins("Deck").Where("cards.deck_id = ?", id).Find(&cards).Error; err != nil {
238
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
239
			Success: false,
240
			Message: err.Error(),
241
			Data:    nil,
242
			Count:   0,
243
		})
244
	}
245
246
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
247
		Success: true,
248
		Message: "Success get cards from deck.",
249
		Data:    cards,
250
		Count:   len(cards),
251
	})
252
}
253
254
// POST
255
256
// CreateNewCard method
257
// @Description Create a new card
258
// @Summary create a card
259
// @Tags Card
260
// @Produce json
261
// @Accept json
262
// @Param card body models.Card true "Card to create"
263
// @Success 200
264
// @Router /v1/cards/new [post]
265
func CreateNewCard(c *fiber.Ctx) error {
266
	db := database.DBConn // DB Conn
267
	card := new(models.Card)
268
269
	auth := CheckAuth(c, models.PermUser) // Check auth
270
	if !auth.Success {
271
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
272
			Success: false,
273
			Message: auth.Message,
274
			Data:    nil,
275
			Count:   0,
276
		})
277
	}
278
279
	if err := c.BodyParser(&card); err != nil {
280
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
281
			Success: false,
282
			Message: err.Error(),
283
			Data:    nil,
284
			Count:   0,
285
		})
286
	}
287
288
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
289
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
290
			Success: false,
291
			Message: "You don't have the permission to add a card to this deck !",
292
			Data:    nil,
293
			Count:   0,
294
		})
295
	}
296
297
	if len(card.Question) < 1 || len(card.Answer) < 1 {
298
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
299
			Success: false,
300
			Message: "You must provide a question and an answer.",
301
			Data:    nil,
302
			Count:   0,
303
		})
304
	}
305
306
	db.Create(card)
307
308
	log := queries.CreateLog(models.LogCardCreated, auth.User.Username+" created "+card.Question)
309
	_ = queries.CreateUserLog(auth.User.ID, *log)
310
	_ = queries.CreateDeckLog(card.DeckID, *log)
311
	_ = queries.CreateCardLog(card.ID, *log)
312
313
	var users []models.User
314
315
	if users = queries.GetSubUsers(c, card.DeckID); len(users) > 0 {
316
		ch := make(chan models.ResponseHTTP)
317
318
		for _, s := range users {
319
			go func(c *fiber.Ctx, user models.User, card *models.Card) {
320
				res := queries.GenerateMemDate(c, &user, card)
321
				ch <- res
322
			}(c, s, card)
323
		}
324
	}
325
326
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
327
		Success: true,
328
		Message: "Success register a card",
329
		Data:    *card,
330
		Count:   1,
331
	})
332
}
333
334
// PostResponse method
335
// @Description Post a response and check it
336
// @Summary post a response
337
// @Tags Card
338
// @Produce json
339
// @Success 200
340
// @Accept json
341
// @Router /v1/cards/response [post]
342
func PostResponse(c *fiber.Ctx) error {
343
	db := database.DBConn // DB Conn
344
345
	auth := CheckAuth(c, models.PermUser) // Check auth
346
	if !auth.Success {
347
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
348
			Success: false,
349
			Message: auth.Message,
350
			Data:    nil,
351
			Count:   0,
352
		})
353
	}
354
355
	response := new(models.CardResponse)
356
	card := new(models.Card)
357
358
	if err := c.BodyParser(&response); err != nil {
359
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
360
			Success: false,
361
			Message: err.Error(),
362
			Data:    nil,
363
			Count:   0,
364
		})
365
	}
366
367
	if err := db.Joins("Deck").First(&card, response.CardID).Error; err != nil {
368
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
369
			Success: false,
370
			Message: err.Error(),
371
			Data:    nil,
372
			Count:   0,
373
		})
374
	}
375
376
	res := queries.CheckAccess(c, auth.User.ID, card.Deck.ID, models.AccessStudent)
377
378
	if !res.Success {
379
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
380
			Success: false,
381
			Message: "You don't have the permission to answer this deck!",
382
			Data:    nil,
383
			Count:   0,
384
		})
385
	}
386
387
	validation := new(models.CardResponseValidation)
388
389
	if strings.EqualFold(strings.TrimSpace(response.Response), strings.TrimSpace(card.Answer)) {
390
		validation.Validate = true
391
		validation.Message = "Correct answer"
392
	} else {
393
		validation.Validate = false
394
		validation.Message = "Incorrect answer"
395
	}
396
397
	_ = queries.PostMem(c, auth.User, *card, *validation)
398
399
	validation.Answer = card.Answer
400
401
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
402
		Success: true,
403
		Message: "Success post response",
404
		Data:    *validation,
405
		Count:   1,
406
	})
407
}
408