Passed
Push — main ( f69698...26bc38 )
by Yume
01:08
created

controllers.CreateNewCard   B

Complexity

Conditions 8

Size

Total Lines 64
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 42
nop 1
dl 0
loc 64
rs 7.0053
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
	"strconv"
9
	"strings"
10
11
	"github.com/gofiber/fiber/v2"
12
)
13
14
// GetTodayCard method
15
// @Description Get next today card
16
// @Summary get a card
17
// @Tags Card
18
// @Produce json
19
// @Success 200 {object} models.Card
20
// @Router /v1/cards/today [get]
21
func GetTodayCard(c *fiber.Ctx) error {
22
	res := *new(models.ResponseHTTP)
23
24
	auth := CheckAuth(c, models.PermUser) // Check auth
25
	if !auth.Success {
26
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
27
			Success: false,
28
			Message: auth.Message,
29
			Data:    nil,
30
			Count:   0,
31
		})
32
	}
33
34
	if res = queries.FetchNextTodayCard(c, &auth.User); !res.Success {
35
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
36
			Success: false,
37
			Message: res.Message,
38
			Data:    nil,
39
			Count:   0,
40
		})
41
	}
42
43
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
44
		Success: true,
45
		Message: "Get todays card",
46
		Data:    res.Data,
47
		Count:   1,
48
	})
49
}
50
51
// GetNextCard method
52
// @Description Get next card
53
// @Summary get a card
54
// @Tags Card
55
// @Produce json
56
// @Success 200 {object} models.Card
57
// @Router /v1/cards/next [get]
58
func GetNextCard(c *fiber.Ctx) error {
59
	//db := database.DBConn // DB Conn
60
61
	res := *new(models.ResponseHTTP)
62
	auth := CheckAuth(c, models.PermUser) // Check auth
63
	if !auth.Success {
64
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
65
			Success: false,
66
			Message: auth.Message,
67
			Data:    nil,
68
			Count:   0,
69
		})
70
	}
71
72
	if res = queries.FetchNextCard(c, &auth.User); !res.Success {
73
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
74
			Success: false,
75
			Message: res.Message,
76
			Data:    nil,
77
			Count:   0,
78
		})
79
	}
80
81
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
82
		Success: true,
83
		Message: "Get next card",
84
		Data:    res.Data,
85
		Count:   1,
86
	})
87
}
88
89
// GetNextCard method
90
// @Description Get next card by deckID
91
// @Summary get a card
92
// @Tags Card
93
// @Produce json
94
// @Success 200 {object} models.Card
95
// @Router /v1/cards/{deckID}/next [get]
96
func GetNextCardByDeck(c *fiber.Ctx) error {
97
	//db := database.DBConn // DB Conn
98
99
	deckID := c.Params("deckID")
100
101
	res := *new(models.ResponseHTTP)
102
	auth := CheckAuth(c, models.PermUser) // Check auth
103
	if !auth.Success {
104
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
105
			Success: false,
106
			Message: auth.Message,
107
			Data:    nil,
108
			Count:   0,
109
		})
110
	}
111
112
	if res = queries.FetchNextCardByDeck(c, &auth.User, deckID); !res.Success {
113
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
114
			Success: false,
115
			Message: res.Message,
116
			Data:    nil,
117
			Count:   0,
118
		})
119
	}
120
121
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
122
		Success: true,
123
		Message: "Get next card by deck",
124
		Data:    res.Data,
125
		Count:   1,
126
	})
127
}
128
129
// GetAllCards method
130
// @Description Get every cards. Shouldn't really be used
131
// @Summary get all cards
132
// @Tags Card
133
// @Produce json
134
// @Success 200 {array} models.Card
135
// @Router /v1/cards/ [get]
136
func GetAllCards(c *fiber.Ctx) error {
137
	db := database.DBConn // DB Conn
138
139
	auth := CheckAuth(c, models.PermAdmin) // Check auth
140
	if !auth.Success {
141
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
142
			Success: false,
143
			Message: auth.Message,
144
			Data:    nil,
145
			Count:   0,
146
		})
147
	}
148
149
	var cards []models.Card
150
151
	if res := db.Joins("Deck").Find(&cards); res.Error != nil {
152
153
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
154
			Success: false,
155
			Message: "Failed to get all cards",
156
			Data:    nil,
157
			Count:   0,
158
		})
159
	}
160
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
161
		Success: true,
162
		Message: "Get All cards",
163
		Data:    cards,
164
		Count:   len(cards),
165
	})
166
167
}
168
169
// GetCardByID method to get a card by id
170
// @Description Get a card by tech id
171
// @Summary get a card
172
// @Tags Card
173
// @Produce json
174
// @Param id path int true "Card ID"
175
// @Success 200 {object} models.Card
176
// @Router /v1/cards/id/{id} [get]
177
func GetCardByID(c *fiber.Ctx) error {
178
	db := database.DBConn // DB Conn
179
180
	auth := CheckAuth(c, models.PermAdmin) // Check auth
181
	if !auth.Success {
182
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
183
			Success: false,
184
			Message: auth.Message,
185
			Data:    nil,
186
			Count:   0,
187
		})
188
	}
189
190
	// Params
191
	id := c.Params("id")
192
193
	card := new(models.Card)
194
195
	if err := db.Joins("Deck").First(&card, id).Error; err != nil {
196
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
197
			Success: false,
198
			Message: err.Error(),
199
			Data:    nil,
200
			Count:   0,
201
		})
202
	}
203
204
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
205
		Success: true,
206
		Message: "Success get card by ID.",
207
		Data:    *card,
208
		Count:   1,
209
	})
210
}
211
212
// GetCardsFromDeck method to get cards from deck
213
// @Description Get every cards from a deck
214
// @Summary get a list of card
215
// @Tags Card
216
// @Produce json
217
// @Param deckID path int true "Deck ID"
218
// @Success 200 {array} models.Card
219
// @Router /v1/cards/deck/{deckID} [get]
220
func GetCardsFromDeck(c *fiber.Ctx) error {
221
	db := database.DBConn // DB Conn
222
223
	// Params
224
	id := c.Params("deckID")
225
226
	auth := CheckAuth(c, models.PermAdmin) // Check auth
227
	if !auth.Success {
228
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
229
			Success: false,
230
			Message: auth.Message,
231
			Data:    nil,
232
			Count:   0,
233
		})
234
	}
235
236
	var cards []models.Card
237
238
	if err := db.Joins("Deck").Where("cards.deck_id = ?", id).Find(&cards).Error; err != nil {
239
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
240
			Success: false,
241
			Message: err.Error(),
242
			Data:    nil,
243
			Count:   0,
244
		})
245
	}
246
247
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
248
		Success: true,
249
		Message: "Success get cards from deck.",
250
		Data:    cards,
251
		Count:   len(cards),
252
	})
253
}
254
255
// POST
256
257
// CreateNewCard method
258
// @Description Create a new card
259
// @Summary create a card
260
// @Tags Card
261
// @Produce json
262
// @Accept json
263
// @Param card body models.Card true "Card to create"
264
// @Success 200
265
// @Router /v1/cards/new [post]
266
func CreateNewCard(c *fiber.Ctx) error {
267
	db := database.DBConn // DB Conn
268
269
	card := new(models.Card)
270
271
	auth := CheckAuth(c, models.PermUser) // Check auth
272
	if !auth.Success {
273
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
274
			Success: false,
275
			Message: auth.Message,
276
			Data:    nil,
277
			Count:   0,
278
		})
279
	}
280
281
	if err := c.BodyParser(&card); err != nil {
282
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
283
			Success: false,
284
			Message: err.Error(),
285
			Data:    nil,
286
			Count:   0,
287
		})
288
	}
289
290
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
291
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
292
			Success: false,
293
			Message: "You don't have the permission to add a card to this deck !",
294
			Data:    nil,
295
			Count:   0,
296
		})
297
	}
298
299
	if len(card.Question) < 1 || len(card.Answer) < 1 {
300
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
301
			Success: false,
302
			Message: "You must provide a question and an answer.",
303
			Data:    nil,
304
			Count:   0,
305
		})
306
	}
307
308
	db.Create(card)
309
310
	log := queries.CreateLog(models.LogCardCreated, auth.User.Username+" created "+card.Question)
311
	_ = queries.CreateUserLog(auth.User.ID, *log)
312
	_ = queries.CreateDeckLog(card.DeckID, *log)
313
	_ = queries.CreateCardLog(card.ID, *log)
314
315
	var users []models.User
316
317
	if users = queries.GetSubUsers(c, card.DeckID); len(users) > 0 {
318
319
		for _, s := range users {
320
			_ = queries.GenerateMemDate(c, &s, card)
321
322
		}
323
	}
324
325
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
326
		Success: true,
327
		Message: "Success register a card",
328
		Data:    *card,
329
		Count:   1,
330
	})
331
}
332
333
// CreateNewCardBulk method
334
// @Description Create cards
335
// @Summary create cards
336
// @Tags Card
337
// @Produce json
338
// @Accept json
339
// @Param card body models.Card true "Cards to create"
340
// @Success 200
341
// @Router /v1/cards/deck/{deckID}/bulk [post]
342
func CreateNewCardBulk(c *fiber.Ctx) error {
343
	db := database.DBConn // DB Conn
344
345
	deckID, _ := strconv.ParseUint(c.Params("deckID"), 10, 32)
346
347
	auth := CheckAuth(c, models.PermUser) // Check auth
348
	if !auth.Success {
349
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
350
			Success: false,
351
			Message: auth.Message,
352
			Data:    nil,
353
			Count:   0,
354
		})
355
	}
356
357
	type Data struct {
358
		Cards []models.Card `json:"cards"`
359
	}
360
361
	data := new(Data)
362
363
	if err := c.BodyParser(&data); err != nil {
364
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
365
			Success: false,
366
			Message: err.Error(),
367
			Data:    nil,
368
			Count:   0,
369
		})
370
	}
371
372
	if res := queries.CheckAccess(c, auth.User.ID, uint(deckID), models.AccessEditor); !res.Success {
373
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
374
			Success: false,
375
			Message: "You don't have the permission to add a card to this deck !",
376
			Data:    nil,
377
			Count:   0,
378
		})
379
	}
380
381
	for _, card := range data.Cards {
382
		deckID := card.DeckID
383
		if len(card.Question) < 1 || len(card.Answer) < 1 {
384
			_ = models.ResponseHTTP{
385
				Success: false,
386
				Message: "You must provide a question and an answer.",
387
				Data:    nil,
388
				Count:   0,
389
			}
390
		} else {
391
			ca := &card
392
			ca.DeckID = deckID
393
			db.Create(ca)
394
395
			log := queries.CreateLog(models.LogCardCreated, auth.User.Username+" created "+ca.Question)
396
			_ = queries.CreateUserLog(auth.User.ID, *log)
397
			_ = queries.CreateDeckLog(deckID, *log)
398
			_ = queries.CreateCardLog(ca.ID, *log)
399
400
			_ = models.ResponseHTTP{
401
				Success: true,
402
				Message: "Success creating card",
403
				Data:    nil,
404
				Count:   0,
405
			}
406
407
			var users []models.User
408
409
			if users = queries.GetSubUsers(c, deckID); len(users) > 0 {
410
411
				for _, s := range users {
412
					_ = queries.GenerateMemDate(c, &s, &card)
413
				}
414
			}
415
		}
416
417
	}
418
419
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
420
		Success: true,
421
		Message: "Success bulk creation",
422
		Data:    data.Cards,
423
		Count:   len(data.Cards),
424
	})
425
}
426
427
// PostResponse method
428
// @Description Post a response and check it
429
// @Summary post a response
430
// @Tags Card
431
// @Produce json
432
// @Success 200
433
// @Accept json
434
// @Router /v1/cards/response [post]
435
func PostResponse(c *fiber.Ctx) error {
436
	db := database.DBConn // DB Conn
437
438
	auth := CheckAuth(c, models.PermUser) // Check auth
439
	if !auth.Success {
440
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
441
			Success: false,
442
			Message: auth.Message,
443
			Data:    nil,
444
			Count:   0,
445
		})
446
	}
447
448
	response := new(models.CardResponse)
449
	card := new(models.Card)
450
451
	if err := c.BodyParser(&response); err != nil {
452
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
453
			Success: false,
454
			Message: err.Error(),
455
			Data:    nil,
456
			Count:   0,
457
		})
458
	}
459
460
	if err := db.Joins("Deck").First(&card, response.CardID).Error; err != nil {
461
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
462
			Success: false,
463
			Message: err.Error(),
464
			Data:    nil,
465
			Count:   0,
466
		})
467
	}
468
469
	res := queries.CheckAccess(c, auth.User.ID, card.Deck.ID, models.AccessStudent)
470
471
	if !res.Success {
472
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
473
			Success: false,
474
			Message: "You don't have the permission to answer this deck!",
475
			Data:    nil,
476
			Count:   0,
477
		})
478
	}
479
480
	validation := new(models.CardResponseValidation)
481
482
	if strings.EqualFold(
483
		strings.Replace(response.Response, " ", "", -1), strings.Replace(card.Answer, " ", "", -1)) {
484
		validation.Validate = true
485
		validation.Message = "Correct answer"
486
	} else {
487
		validation.Validate = false
488
		validation.Message = "Incorrect answer"
489
	}
490
491
	_ = queries.PostMem(c, auth.User, *card, *validation)
492
493
	validation.Answer = card.Answer
494
495
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
496
		Success: true,
497
		Message: "Success post response",
498
		Data:    *validation,
499
		Count:   1,
500
	})
501
}
502
503
// PUT
504
505
// UpdateCardByID method
506
// @Description Edit a card
507
// @Summary edit a card
508
// @Tags Card
509
// @Produce json
510
// @Success 200
511
// @Accept json
512
// @Param card body models.Card true "card to edit"
513
// @Router /v1/cards/{cardID}/edit [put]
514
func UpdateCardByID(c *fiber.Ctx) error {
515
	db := database.DBConn // DB Conn
516
517
	// Params
518
	id := c.Params("id")
519
520
	auth := CheckAuth(c, models.PermUser) // Check auth
521
	if !auth.Success {
522
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
523
			Success: false,
524
			Message: auth.Message,
525
			Data:    nil,
526
			Count:   0,
527
		})
528
	}
529
530
	card := new(models.Card)
531
532
	if err := db.First(&card, id).Error; err != nil {
533
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
534
			Success: false,
535
			Message: err.Error(),
536
			Data:    nil,
537
			Count:   0,
538
		})
539
	}
540
541
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
542
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
543
			Success: false,
544
			Message: "You don't have the permission to edit this card!",
545
			Data:    nil,
546
			Count:   0,
547
		})
548
	}
549
550
	if err := UpdateCard(c, card); err != nil {
551
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
552
			Success: false,
553
			Message: "Couldn't update the card",
554
			Data:    nil,
555
			Count:   0,
556
		})
557
	}
558
559
	log := queries.CreateLog(models.LogCardEdited, auth.User.Username+" edited "+card.Question)
560
	_ = queries.CreateUserLog(auth.User.ID, *log)
561
	_ = queries.CreateCardLog(card.ID, *log)
562
563
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
564
		Success: true,
565
		Message: "Success update card by ID",
566
		Data:    *card,
567
		Count:   1,
568
	})
569
}
570
571
// UpdateDeck
572
func UpdateCard(c *fiber.Ctx, card *models.Card) error {
573
	db := database.DBConn
574
575
	if err := c.BodyParser(&card); err != nil {
576
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
577
			Success: false,
578
			Message: err.Error(),
579
			Data:    nil,
580
			Count:   0,
581
		})
582
	}
583
584
	if len(card.Question) < 1 || len(card.Answer) < 1 {
585
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
586
			Success: false,
587
			Message: "You must provide a question and an answer",
588
			Data:    nil,
589
			Count:   0,
590
		})
591
	}
592
593
	db.Save(card)
594
595
	return nil
596
}
597
598
// DeleteCardById method
599
// @Description Delete a card
600
// @Summary delete a card
601
// @Tags Card
602
// @Produce json
603
// @Success 200
604
// @Router /v1/cards/{cardID} [delete]
605
func DeleteCardById(c *fiber.Ctx) error {
606
	db := database.DBConn // DB Conn
607
	id := c.Params("id")
608
609
	auth := CheckAuth(c, models.PermUser) // Check auth
610
	if !auth.Success {
611
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
612
			Success: false,
613
			Message: auth.Message,
614
			Data:    nil,
615
			Count:   0,
616
		})
617
	}
618
619
	card := new(models.Card)
620
621
	if err := db.First(&card, id).Error; err != nil {
622
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
623
			Success: false,
624
			Message: err.Error(),
625
			Data:    nil,
626
			Count:   0,
627
		})
628
	}
629
630
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessOwner); !res.Success {
631
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
632
			Success: false,
633
			Message: "You don't have the permission to delete this card!",
634
			Data:    nil,
635
			Count:   0,
636
		})
637
	}
638
639
	db.Delete(card)
640
641
	log := queries.CreateLog(models.LogCardDeleted, auth.User.Username+" deleted "+card.Question)
642
	_ = queries.CreateUserLog(auth.User.ID, *log)
643
	_ = queries.CreateCardLog(card.ID, *log)
644
645
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
646
		Success: true,
647
		Message: "Success delete card by ID",
648
		Data:    *card,
649
		Count:   1,
650
	})
651
652
}
653