reprogl

Форк
0
/
comment.go 
175 строк · 4.2 Кб
1
package handlers
2

3
import (
4
	"errors"
5
	"net/http"
6
	"strconv"
7

8
	"github.com/go-chi/chi/v5"
9
	"xelbot.com/reprogl/api/backend"
10
	"xelbot.com/reprogl/api/telegram"
11
	"xelbot.com/reprogl/container"
12
	"xelbot.com/reprogl/models"
13
	"xelbot.com/reprogl/models/repositories"
14
	"xelbot.com/reprogl/session"
15
	"xelbot.com/reprogl/views"
16
)
17

18
type addCommentResponse struct {
19
	Valid  bool                `json:"valid"`
20
	Errors []backend.FormError `json:"errors,omitempty"`
21
}
22

23
func AddCommentDummy(w http.ResponseWriter, r *http.Request) {
24
	w.Header().Set("Content-Type", "text/plain")
25
	w.Write([]byte("Silence is gold"))
26
}
27

28
func AddComment(app *container.Application) http.HandlerFunc {
29
	return func(w http.ResponseWriter, r *http.Request) {
30
		topicId, err := strconv.Atoi(r.PostFormValue("topicId"))
31
		if err != nil {
32
			app.ClientError(w, http.StatusBadRequest)
33
			return
34
		}
35

36
		parentId, err := strconv.Atoi(r.PostFormValue("parentId"))
37
		if err != nil {
38
			app.ClientError(w, http.StatusBadRequest)
39
			return
40
		}
41

42
		repo := repositories.ArticleRepository{DB: app.DB}
43
		article, err := repo.GetByIdForComment(topicId)
44
		if err != nil {
45
			if errors.Is(err, models.RecordNotFound) {
46
				app.NotFound(w)
47
			} else {
48
				app.ServerError(w, err)
49
			}
50

51
			return
52
		}
53

54
		var commentator *backend.CommentatorDTO
55
		var user *backend.CommentUserDTO
56
		if identity, hasIdentity := session.GetIdentity(r.Context()); hasIdentity {
57
			user = &backend.CommentUserDTO{
58
				ID: identity.ID,
59
			}
60
		} else {
61
			commentator = &backend.CommentatorDTO{
62
				Name:    r.PostFormValue("name"),
63
				Email:   r.PostFormValue("mail"),
64
				Website: r.PostFormValue("website"),
65
			}
66
		}
67

68
		commentData := backend.CommentDTO{
69
			Commentator: commentator,
70
			User:        user,
71
			Text:        r.PostFormValue("comment_text"),
72
			TopicID:     topicId,
73
			ParentID:    parentId,
74
			UserAgent:   r.UserAgent(),
75
			IP:          container.RealRemoteAddress(r),
76
		}
77

78
		var responseData any
79
		statusCode := http.StatusCreated
80

81
		apiResponse, err := backend.SendComment(commentData)
82
		if err != nil {
83
			if errors.Is(err, backend.NotAllowedComment) {
84
				statusCode = http.StatusOK
85
				responseData = addCommentResponse{
86
					Valid: false,
87
					Errors: []backend.FormError{
88
						{
89
							Path:    "comment_text",
90
							Message: "Добавление комментариев тут отключено 😐",
91
						},
92
					},
93
				}
94
			} else {
95
				app.LogError(err)
96
				statusCode = http.StatusBadRequest
97
			}
98
		}
99

100
		if apiResponse != nil {
101
			result := addCommentResponse{
102
				Valid:  true,
103
				Errors: apiResponse.Violations,
104
			}
105

106
			if apiResponse.Violations != nil && len(apiResponse.Violations) > 0 {
107
				result.Valid = false
108
			} else {
109
				if apiResponse.Comment != nil {
110
					go afterCommentHook(app, apiResponse.Comment, article)
111
				}
112
			}
113

114
			responseData = result
115
		}
116

117
		jsonResponse(w, statusCode, responseData)
118
	}
119
}
120

121
func CommentsFragment(app *container.Application) http.HandlerFunc {
122
	return func(w http.ResponseWriter, r *http.Request) {
123
		var err error
124
		articleId, err := strconv.Atoi(chi.URLParam(r, "article_id"))
125
		if err != nil {
126
			app.ServerError(w, err)
127

128
			return
129
		}
130

131
		repo := repositories.CommentRepository{DB: app.DB}
132

133
		var comments models.CommentList
134
		identity, found := session.GetIdentity(r.Context())
135
		if found && identity.IsAdmin() {
136
			comments, err = repo.GetCollectionWithExtraDataByArticleId(articleId)
137
		} else {
138
			comments, err = repo.GetCollectionByArticleId(articleId)
139
		}
140
		if err != nil {
141
			app.ServerError(w, err)
142

143
			return
144
		}
145

146
		templateData := &views.FragmentCommentsData{
147
			Comments:        comments,
148
			EnabledComments: chi.URLParam(r, "disabled_flag") == models.EnabledComments,
149
		}
150

151
		cacheControl(w, container.DefaultEsiTTL)
152
		err = views.WriteTemplateWithContext(r.Context(), w, "comments.gohtml", templateData)
153
		if err != nil {
154
			app.ServerError(w, err)
155
		}
156
	}
157
}
158

159
func afterCommentHook(
160
	app *container.Application,
161
	comment *backend.CreatedCommentDTO,
162
	article *models.ArticleForComment,
163
) {
164
	var updatedComment *backend.CreatedCommentDTO
165

166
	backend.PingGeolocation()
167
	refreshedComment, err := backend.RefreshComment(comment.ID)
168
	if err != nil {
169
		updatedComment = comment
170
	} else {
171
		updatedComment = refreshedComment
172
	}
173

174
	telegram.SendNotification(app, updatedComment, article)
175
}
176

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.