From 666ab706a66f7c39c8bb758c0abc2c08c15d4967 Mon Sep 17 00:00:00 2001
From: Dinesht04
Date: Thu, 13 Nov 2025 02:22:58 +0530
Subject: [PATCH 01/25] feat(ui): add min values for inputs and context-based
keyboards for inputs
---
ui/src/components/SchemaForm/components/Input.tsx | 15 +++++++++++++++
ui/src/components/SchemaForm/index.tsx | 3 +++
ui/src/components/SchemaForm/types.ts | 10 ++++++++++
ui/src/pages/Admin/Privileges/index.tsx | 2 ++
ui/src/pages/Admin/Write/index.tsx | 10 ++++++++++
5 files changed, 40 insertions(+)
diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx
index 1a3fe319b..c0fd084ca 100644
--- a/ui/src/components/SchemaForm/components/Input.tsx
+++ b/ui/src/components/SchemaForm/components/Input.tsx
@@ -29,6 +29,17 @@ interface Props {
onChange?: (fd: Type.FormDataType) => void;
formData: Type.FormDataType;
readOnly: boolean;
+ minValue?: number;
+ inputMode?:
+ | 'text'
+ | 'search'
+ | 'none'
+ | 'tel'
+ | 'url'
+ | 'email'
+ | 'numeric'
+ | 'decimal'
+ | undefined;
}
const Index: FC = ({
type = 'text',
@@ -37,6 +48,8 @@ const Index: FC = ({
onChange,
formData,
readOnly = false,
+ minValue = 0,
+ inputMode = 'text',
}) => {
const fieldObject = formData[fieldName];
const handleChange = (evt: React.ChangeEvent) => {
@@ -60,6 +73,8 @@ const Index: FC = ({
placeholder={placeholder}
type={type}
value={fieldObject?.value || ''}
+ min={minValue}
+ inputMode={inputMode}
onChange={handleChange}
disabled={readOnly}
isInvalid={fieldObject?.isInvalid}
diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx
index 421e0b1e1..23b193b48 100644
--- a/ui/src/components/SchemaForm/index.tsx
+++ b/ui/src/components/SchemaForm/index.tsx
@@ -368,6 +368,9 @@ const SchemaForm: ForwardRefRenderFunction = (
{widget === 'input' ? (
{
}
return true;
},
+ inputType: 'number',
+ inputMode: 'numeric',
},
};
});
diff --git a/ui/src/pages/Admin/Write/index.tsx b/ui/src/pages/Admin/Write/index.tsx
index 86d44d6d9..fee2d28cc 100644
--- a/ui/src/pages/Admin/Write/index.tsx
+++ b/ui/src/pages/Admin/Write/index.tsx
@@ -261,6 +261,8 @@ const Index: FC = () => {
{t('min_tags.label')}
{
@@ -302,6 +304,8 @@ const Index: FC = () => {
{t('min_content.label')}
{
@@ -344,6 +348,8 @@ const Index: FC = () => {
{t('image_size.label')}
{
@@ -366,6 +372,8 @@ const Index: FC = () => {
{t('attachment_size.label')}
{
@@ -388,6 +396,8 @@ const Index: FC = () => {
{t('image_megapixels.label')}
{
From 157dbfd08a1474534fe3548ef02243bf421ba020 Mon Sep 17 00:00:00 2001
From: Dinesht04
Date: Fri, 14 Nov 2025 02:28:46 +0530
Subject: [PATCH 02/25] feat(ui): add types, logic and defaults for min, max
value of input component of form
---
ui/src/components/SchemaForm/components/Input.tsx | 9 ++++++---
ui/src/components/SchemaForm/index.tsx | 9 +++++++++
ui/src/components/SchemaForm/types.ts | 2 ++
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx
index c0fd084ca..3a2c0397d 100644
--- a/ui/src/components/SchemaForm/components/Input.tsx
+++ b/ui/src/components/SchemaForm/components/Input.tsx
@@ -29,7 +29,8 @@ interface Props {
onChange?: (fd: Type.FormDataType) => void;
formData: Type.FormDataType;
readOnly: boolean;
- minValue?: number;
+ min?: number;
+ max?: number;
inputMode?:
| 'text'
| 'search'
@@ -48,7 +49,8 @@ const Index: FC = ({
onChange,
formData,
readOnly = false,
- minValue = 0,
+ min = 0,
+ max = 65355,
inputMode = 'text',
}) => {
const fieldObject = formData[fieldName];
@@ -73,7 +75,8 @@ const Index: FC = ({
placeholder={placeholder}
type={type}
value={fieldObject?.value || ''}
- min={minValue}
+ min={min}
+ max={max}
inputMode={inputMode}
onChange={handleChange}
disabled={readOnly}
diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx
index 23b193b48..5bde2fdc8 100644
--- a/ui/src/components/SchemaForm/index.tsx
+++ b/ui/src/components/SchemaForm/index.tsx
@@ -260,6 +260,8 @@ const SchemaForm: ForwardRefRenderFunction = (
enum: enumValues = [],
enumNames = [],
max_length = 0,
+ max = 65355,
+ min = 0,
} = properties[key];
const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } =
uiSchema?.[key] || {};
@@ -374,6 +376,8 @@ const SchemaForm: ForwardRefRenderFunction = (
placeholder={
uiOpt && 'placeholder' in uiOpt ? uiOpt.placeholder : ''
}
+ min={min}
+ max={max}
fieldName={key}
onChange={onChange}
formData={formData}
@@ -408,9 +412,14 @@ const SchemaForm: ForwardRefRenderFunction = (
type={
uiOpt && 'inputType' in uiOpt ? uiOpt.inputType : 'text'
}
+ inputMode={
+ uiOpt && 'inputMode' in uiOpt ? uiOpt.inputMode : 'text'
+ }
placeholder={
uiOpt && 'placeholder' in uiOpt ? uiOpt.placeholder : ''
}
+ min={min}
+ max={max}
fieldName={key}
onChange={onChange}
formData={formData}
diff --git a/ui/src/components/SchemaForm/types.ts b/ui/src/components/SchemaForm/types.ts
index eaedf902a..55cf8e99d 100644
--- a/ui/src/components/SchemaForm/types.ts
+++ b/ui/src/components/SchemaForm/types.ts
@@ -49,6 +49,8 @@ export interface JSONSchema {
description?: string;
enum?: Array;
enumNames?: string[];
+ min?: number;
+ max?: number;
default?: string | boolean | number | any[];
max_length?: number;
};
From 54e602c5e6ad9a8c49187eadc4d480fbd7892a97 Mon Sep 17 00:00:00 2001
From: Dinesht04
Date: Wed, 19 Nov 2025 15:28:58 +0530
Subject: [PATCH 03/25] fix(ui): refactor number input props (min,max)
---
ui/src/components/SchemaForm/components/Input.tsx | 9 ++++++---
ui/src/components/SchemaForm/index.tsx | 2 +-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx
index 3a2c0397d..d84d7d55a 100644
--- a/ui/src/components/SchemaForm/components/Input.tsx
+++ b/ui/src/components/SchemaForm/components/Input.tsx
@@ -50,10 +50,14 @@ const Index: FC = ({
formData,
readOnly = false,
min = 0,
- max = 65355,
+ max,
inputMode = 'text',
}) => {
const fieldObject = formData[fieldName];
+ const numberInputProps =
+ type === 'number'
+ ? { min, ...(max != null && max > 0 ? { max } : {}) }
+ : {};
const handleChange = (evt: React.ChangeEvent) => {
const { name, value } = evt.currentTarget;
const state = {
@@ -75,8 +79,7 @@ const Index: FC = ({
placeholder={placeholder}
type={type}
value={fieldObject?.value || ''}
- min={min}
- max={max}
+ {...numberInputProps}
inputMode={inputMode}
onChange={handleChange}
disabled={readOnly}
diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx
index 5bde2fdc8..171b5f675 100644
--- a/ui/src/components/SchemaForm/index.tsx
+++ b/ui/src/components/SchemaForm/index.tsx
@@ -260,7 +260,7 @@ const SchemaForm: ForwardRefRenderFunction = (
enum: enumValues = [],
enumNames = [],
max_length = 0,
- max = 65355,
+ max,
min = 0,
} = properties[key];
const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } =
From 9a7eb0f450d31042c8badf080354754a8704e429 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Thu, 20 Nov 2025 17:42:35 +0800
Subject: [PATCH 04/25] fix(service): set default language to "en_US" if
invalid language is provided
---
internal/service/siteinfo/siteinfo_service.go | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go
index a0f4891c4..92b3e0c71 100644
--- a/internal/service/siteinfo/siteinfo_service.go
+++ b/internal/service/siteinfo/siteinfo_service.go
@@ -40,7 +40,6 @@ import (
tagcommon "github.com/apache/answer/internal/service/tag_common"
"github.com/apache/answer/plugin"
"github.com/jinzhu/copier"
- "github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
)
@@ -159,10 +158,9 @@ func (s *SiteInfoService) SaveSiteGeneral(ctx context.Context, req schema.SiteGe
}
func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.SiteInterfaceReq) (err error) {
- // check language
+ // If the language is invalid, set it to the default language "en_US"
if !translator.CheckLanguageIsValid(req.Language) {
- err = errors.BadRequest(reason.LangNotFound)
- return
+ req.Language = "en_US"
}
content, _ := json.Marshal(req)
From 09b6b34b0540b1aa6f344b20df8507f56e6fb406 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Thu, 20 Nov 2025 17:50:57 +0800
Subject: [PATCH 05/25] fix(comment): decode CommentID using DeShortID for
consistency
---
internal/controller/comment_controller.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go
index 5b807d935..65fbedf04 100644
--- a/internal/controller/comment_controller.go
+++ b/internal/controller/comment_controller.go
@@ -246,6 +246,7 @@ func (cc *CommentController) GetCommentWithPage(ctx *gin.Context) {
return
}
req.ObjectID = uid.DeShortID(req.ObjectID)
+ req.CommentID = uid.DeShortID(req.CommentID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.CommentEdit,
From a15dd41550c282a4de44259c69a57dd52eeb0e9c Mon Sep 17 00:00:00 2001
From: ferhat elmas
Date: Sat, 22 Nov 2025 12:43:55 +0100
Subject: [PATCH 06/25] refactor(internal): compile regex once while clearing
text
Regex and Replacer can be reused.
No need to recreate for each invocation.
Signed-off-by: ferhat elmas
---
pkg/htmltext/htmltext.go | 48 ++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 26 deletions(-)
diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go
index 49049109d..0b84cda49 100644
--- a/pkg/htmltext/htmltext.go
+++ b/pkg/htmltext/htmltext.go
@@ -34,38 +34,34 @@ import (
"github.com/mozillazg/go-pinyin"
)
+var (
+ reCode = regexp.MustCompile(`(?ism)<(pre)>.*<\/pre>`)
+ reCodeReplace = "{code...}"
+ reLink = regexp.MustCompile(`(?ism)(.*)?<\/a>`)
+ reLinkReplace = " [$1] "
+ reSpace = regexp.MustCompile(` +`)
+ reSpaceReplace = " "
+
+ spaceReplacer = strings.NewReplacer(
+ "\n", " ",
+ "\r", " ",
+ "\t", " ",
+ )
+)
+
// ClearText clear HTML, get the clear text
-func ClearText(html string) (text string) {
- if len(html) == 0 {
- text = html
- return
+func ClearText(html string) string {
+ if html == "" {
+ return html
}
- var (
- re *regexp.Regexp
- codeReg = `(?ism)<(pre)>.*<\/pre>`
- codeRepl = "{code...}"
- linkReg = `(?ism)(.*)?<\/a>`
- linkRepl = " [$1] "
- spaceReg = ` +`
- spaceRepl = " "
- )
- re = regexp.MustCompile(codeReg)
- html = re.ReplaceAllString(html, codeRepl)
+ html = reCode.ReplaceAllString(html, reCodeReplace)
+ html = reLink.ReplaceAllString(html, reLinkReplace)
- re = regexp.MustCompile(linkReg)
- html = re.ReplaceAllString(html, linkRepl)
-
- text = strings.NewReplacer(
- "\n", " ",
- "\r", " ",
- "\t", " ",
- ).Replace(strip.StripTags(html))
+ text := spaceReplacer.Replace(strip.StripTags(html))
// replace multiple spaces to one space
- re = regexp.MustCompile(spaceReg)
- text = strings.TrimSpace(re.ReplaceAllString(text, spaceRepl))
- return
+ return strings.TrimSpace(reSpace.ReplaceAllString(text, reSpaceReplace))
}
func UrlTitle(title string) (text string) {
From ce053ccfa6620cc4c8263ba3b54dfcd988a1e6e9 Mon Sep 17 00:00:00 2001
From: ferhat elmas
Date: Tue, 25 Nov 2025 00:34:24 +0100
Subject: [PATCH 07/25] fix: multi byte run boundary for cut long title
Signed-off-by: ferhat elmas
---
pkg/htmltext/htmltext.go | 12 +++++++++---
pkg/htmltext/htmltext_test.go | 22 ++++++++++++++++++++++
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go
index 0b84cda49..707c20a80 100644
--- a/pkg/htmltext/htmltext.go
+++ b/pkg/htmltext/htmltext.go
@@ -96,10 +96,16 @@ func convertChinese(content string) string {
}
func cutLongTitle(title string) string {
- if len(title) > 150 {
- return title[0:150]
+ maxBytes := 150
+ if len(title) <= maxBytes {
+ return title
}
- return title
+
+ truncated := title[:maxBytes]
+ for len(truncated) > 0 && !utf8.ValidString(truncated) {
+ truncated = truncated[:len(truncated)-1]
+ }
+ return truncated
}
// FetchExcerpt return the excerpt from the HTML string
diff --git a/pkg/htmltext/htmltext_test.go b/pkg/htmltext/htmltext_test.go
index d549d8874..63866eb28 100644
--- a/pkg/htmltext/htmltext_test.go
+++ b/pkg/htmltext/htmltext_test.go
@@ -21,6 +21,7 @@ package htmltext
import (
"fmt"
+ "strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -178,6 +179,27 @@ func TestFetchRangedExcerpt(t *testing.T) {
assert.Equal(t, expected, actual)
}
+func TestCutLongTitle(t *testing.T) {
+ // Short title, no cutting needed
+ short := "hello"
+ assert.Equal(t, short, cutLongTitle(short))
+
+ // Exactly max bytes, no cutting needed
+ exact150 := strings.Repeat("a", 150)
+ assert.Equal(t, 150, len(cutLongTitle(exact150)))
+
+ // Just over max bytes, should be cut
+ exact151 := strings.Repeat("a", 151)
+ assert.Equal(t, 150, len(cutLongTitle(exact151)))
+
+ // Multi-byte rune at boundary gets removed properly
+ asciiPart := strings.Repeat("a", 149) // 149 bytes
+ multiByteChar := "中" // 3 bytes - will span bytes 149-151
+ title := asciiPart + multiByteChar // 152 bytes total
+
+ assert.Equal(t, asciiPart, cutLongTitle(title))
+}
+
func TestFetchMatchedExcerpt(t *testing.T) {
var (
expected,
From 0777291e80c804cb836b5059d7e0fad5f2b7fe79 Mon Sep 17 00:00:00 2001
From: ferhat elmas
Date: Wed, 26 Nov 2025 01:00:42 +0100
Subject: [PATCH 08/25] fix(ui): null pointer access if get branding fails
Signed-off-by: ferhat elmas
---
internal/router/ui.go | 6 ++--
internal/router/ui_test.go | 59 ++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 3 deletions(-)
create mode 100644 internal/router/ui_test.go
diff --git a/internal/router/ui.go b/internal/router/ui.go
index 0b5ee3f96..14f71f5fc 100644
--- a/internal/router/ui.go
+++ b/internal/router/ui.go
@@ -22,7 +22,6 @@ package router
import (
"embed"
"fmt"
- "github.com/apache/answer/plugin"
"io/fs"
"net/http"
"os"
@@ -31,6 +30,7 @@ import (
"github.com/apache/answer/internal/controller"
"github.com/apache/answer/internal/service/siteinfo_common"
"github.com/apache/answer/pkg/htmltext"
+ "github.com/apache/answer/plugin"
"github.com/apache/answer/ui"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/log"
@@ -111,10 +111,10 @@ func (a *UIRouter) Register(r *gin.Engine, baseURLPath string) {
if err != nil {
log.Error(err)
}
- if branding.Favicon != "" {
+ if branding != nil && branding.Favicon != "" {
c.String(http.StatusOK, htmltext.GetPicByUrl(branding.Favicon))
return
- } else if branding.SquareIcon != "" {
+ } else if branding != nil && branding.SquareIcon != "" {
c.String(http.StatusOK, htmltext.GetPicByUrl(branding.SquareIcon))
return
} else {
diff --git a/internal/router/ui_test.go b/internal/router/ui_test.go
new file mode 100644
index 000000000..645529338
--- /dev/null
+++ b/internal/router/ui_test.go
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package router
+
+import (
+ "errors"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/apache/answer/internal/service/mock"
+ "github.com/gin-gonic/gin"
+ "github.com/stretchr/testify/assert"
+ "go.uber.org/mock/gomock"
+)
+
+func TestUIRouter_FaviconWithNilBranding(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockSiteInfoService := mock.NewMockSiteInfoCommonService(ctrl)
+
+ // Simulate a database error
+ mockSiteInfoService.EXPECT().
+ GetSiteBranding(gomock.Any()).
+ Return(nil, errors.New("database connection failed"))
+
+ router := &UIRouter{
+ siteInfoService: mockSiteInfoService,
+ }
+
+ gin.SetMode(gin.TestMode)
+ r := gin.New()
+ router.Register(r, "")
+
+ req := httptest.NewRequest(http.MethodGet, "/favicon.ico", nil)
+ w := httptest.NewRecorder()
+
+ r.ServeHTTP(w, req)
+
+ assert.Equal(t, http.StatusOK, w.Code)
+}
From bc629db13266dfcd9560da38b39d71a615a1664f Mon Sep 17 00:00:00 2001
From: ferhat elmas
Date: Thu, 27 Nov 2025 22:05:14 +0100
Subject: [PATCH 09/25] chore(deps): bump mockgen to 0.6.0 for go1.25 support
Signed-off-by: ferhat elmas
---
Makefile | 4 ++--
README.md | 2 +-
cmd/wire_gen.go | 8 ++++----
docs/docs.go | 32 +++++++++++++++++++++++---------
docs/swagger.json | 32 +++++++++++++++++++++++---------
docs/swagger.yaml | 28 +++++++++++++++++++---------
go.mod | 14 +++++++-------
go.sum | 36 ++++++++++++++++++------------------
8 files changed, 97 insertions(+), 59 deletions(-)
diff --git a/Makefile b/Makefile
index 6e9679a89..8ab23cce3 100644
--- a/Makefile
+++ b/Makefile
@@ -23,10 +23,10 @@ universal: generate
generate:
@$(GO) get github.com/swaggo/swag/cmd/swag@v1.16.3
@$(GO) get github.com/google/wire/cmd/wire@v0.5.0
- @$(GO) get go.uber.org/mock/mockgen@v0.5.0
+ @$(GO) get go.uber.org/mock/mockgen@v0.6.0
@$(GO) install github.com/swaggo/swag/cmd/swag@v1.16.3
@$(GO) install github.com/google/wire/cmd/wire@v0.5.0
- @$(GO) install go.uber.org/mock/mockgen@v0.5.0
+ @$(GO) install go.uber.org/mock/mockgen@v0.6.0
@$(GO) generate ./...
@$(GO) mod tidy
diff --git a/README.md b/README.md
index 8d201500e..362365496 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ You can also check out the [plugins here](https://answer.apache.org/plugins).
- Golang >= 1.23
- Node.js >= 20
- pnpm >= 9
-- [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 1.6.0
+- [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 0.6.0
- [wire](https://github.com/google/wire/) >= 0.5.0
### Build
diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go
index bda555bca..aae1c6af6 100644
--- a/cmd/wire_gen.go
+++ b/cmd/wire_gen.go
@@ -192,22 +192,22 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService)
notificationQueueService := notice_queue.NewNotificationQueueService()
externalNotificationQueueService := notice_queue.NewNewQuestionNotificationQueueService()
+ reviewRepo := review.NewReviewRepo(dataData)
+ reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo)
+ commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService)
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService)
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService)
limitRepo := limit.NewRateLimitRepo(dataData)
rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo)
+ commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware)
reportRepo := report.NewReportRepo(dataData, uniqueIDRepo)
tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, activityQueueService)
answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, notificationQueueService)
answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService)
externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService, userExternalLoginRepo, siteInfoCommonService)
- reviewRepo := review.NewReviewRepo(dataData)
- reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo)
questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService, eventQueueService, reviewRepo)
answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService, reviewService, eventQueueService)
- commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService)
- commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware)
reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService)
reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventQueueService)
reportController := controller.NewReportController(reportService, rankService, captchaService)
diff --git a/docs/docs.go b/docs/docs.go
index 263e6775e..c87313917 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -9780,8 +9780,6 @@ const docTemplate = `{
"schema.QuestionAdd": {
"type": "object",
"required": [
- "content",
- "tags",
"title"
],
"properties": {
@@ -9796,7 +9794,7 @@ const docTemplate = `{
"description": "content",
"type": "string",
"maxLength": 65535,
- "minLength": 6
+ "minLength": 0
},
"tags": {
"description": "tags",
@@ -9817,8 +9815,6 @@ const docTemplate = `{
"type": "object",
"required": [
"answer_content",
- "content",
- "tags",
"title"
],
"properties": {
@@ -9838,7 +9834,7 @@ const docTemplate = `{
"description": "content",
"type": "string",
"maxLength": 65535,
- "minLength": 6
+ "minLength": 0
},
"mention_username_list": {
"type": "array",
@@ -10119,9 +10115,7 @@ const docTemplate = `{
"schema.QuestionUpdate": {
"type": "object",
"required": [
- "content",
"id",
- "tags",
"title"
],
"properties": {
@@ -10136,7 +10130,7 @@ const docTemplate = `{
"description": "content",
"type": "string",
"maxLength": 65535,
- "minLength": 6
+ "minLength": 0
},
"edit_summary": {
"description": "edit summary",
@@ -11047,6 +11041,16 @@ const docTemplate = `{
"max_image_size": {
"type": "integer"
},
+ "min_content": {
+ "type": "integer",
+ "maximum": 65535,
+ "minimum": 0
+ },
+ "min_tags": {
+ "type": "integer",
+ "maximum": 5,
+ "minimum": 0
+ },
"recommend_tags": {
"type": "array",
"items": {
@@ -11091,6 +11095,16 @@ const docTemplate = `{
"max_image_size": {
"type": "integer"
},
+ "min_content": {
+ "type": "integer",
+ "maximum": 65535,
+ "minimum": 0
+ },
+ "min_tags": {
+ "type": "integer",
+ "maximum": 5,
+ "minimum": 0
+ },
"recommend_tags": {
"type": "array",
"items": {
diff --git a/docs/swagger.json b/docs/swagger.json
index 8cc85e263..9f89cb157 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -9753,8 +9753,6 @@
"schema.QuestionAdd": {
"type": "object",
"required": [
- "content",
- "tags",
"title"
],
"properties": {
@@ -9769,7 +9767,7 @@
"description": "content",
"type": "string",
"maxLength": 65535,
- "minLength": 6
+ "minLength": 0
},
"tags": {
"description": "tags",
@@ -9790,8 +9788,6 @@
"type": "object",
"required": [
"answer_content",
- "content",
- "tags",
"title"
],
"properties": {
@@ -9811,7 +9807,7 @@
"description": "content",
"type": "string",
"maxLength": 65535,
- "minLength": 6
+ "minLength": 0
},
"mention_username_list": {
"type": "array",
@@ -10092,9 +10088,7 @@
"schema.QuestionUpdate": {
"type": "object",
"required": [
- "content",
"id",
- "tags",
"title"
],
"properties": {
@@ -10109,7 +10103,7 @@
"description": "content",
"type": "string",
"maxLength": 65535,
- "minLength": 6
+ "minLength": 0
},
"edit_summary": {
"description": "edit summary",
@@ -11020,6 +11014,16 @@
"max_image_size": {
"type": "integer"
},
+ "min_content": {
+ "type": "integer",
+ "maximum": 65535,
+ "minimum": 0
+ },
+ "min_tags": {
+ "type": "integer",
+ "maximum": 5,
+ "minimum": 0
+ },
"recommend_tags": {
"type": "array",
"items": {
@@ -11064,6 +11068,16 @@
"max_image_size": {
"type": "integer"
},
+ "min_content": {
+ "type": "integer",
+ "maximum": 65535,
+ "minimum": 0
+ },
+ "min_tags": {
+ "type": "integer",
+ "maximum": 5,
+ "minimum": 0
+ },
"recommend_tags": {
"type": "array",
"items": {
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 9cdf248e1..d2dd076cf 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -1589,7 +1589,7 @@ definitions:
content:
description: content
maxLength: 65535
- minLength: 6
+ minLength: 0
type: string
tags:
description: tags
@@ -1602,8 +1602,6 @@ definitions:
minLength: 6
type: string
required:
- - content
- - tags
- title
type: object
schema.QuestionAddByAnswer:
@@ -1620,7 +1618,7 @@ definitions:
content:
description: content
maxLength: 65535
- minLength: 6
+ minLength: 0
type: string
mention_username_list:
items:
@@ -1638,8 +1636,6 @@ definitions:
type: string
required:
- answer_content
- - content
- - tags
- title
type: object
schema.QuestionInfoResp:
@@ -1826,7 +1822,7 @@ definitions:
content:
description: content
maxLength: 65535
- minLength: 6
+ minLength: 0
type: string
edit_summary:
description: edit summary
@@ -1849,9 +1845,7 @@ definitions:
minLength: 6
type: string
required:
- - content
- id
- - tags
- title
type: object
schema.QuestionUpdateInviteUser:
@@ -2453,6 +2447,14 @@ definitions:
type: integer
max_image_size:
type: integer
+ min_content:
+ maximum: 65535
+ minimum: 0
+ type: integer
+ min_tags:
+ maximum: 5
+ minimum: 0
+ type: integer
recommend_tags:
items:
$ref: '#/definitions/schema.SiteWriteTag'
@@ -2482,6 +2484,14 @@ definitions:
type: integer
max_image_size:
type: integer
+ min_content:
+ maximum: 65535
+ minimum: 0
+ type: integer
+ min_tags:
+ maximum: 5
+ minimum: 0
+ type: integer
recommend_tags:
items:
$ref: '#/definitions/schema.SiteWriteTag'
diff --git a/go.mod b/go.mod
index 417688120..969d9ebbc 100644
--- a/go.mod
+++ b/go.mod
@@ -56,12 +56,12 @@ require (
github.com/swaggo/swag v1.16.3
github.com/tidwall/gjson v1.17.3
github.com/yuin/goldmark v1.7.4
- go.uber.org/mock v0.5.0
- golang.org/x/crypto v0.36.0
+ go.uber.org/mock v0.6.0
+ golang.org/x/crypto v0.41.0
golang.org/x/image v0.20.0
- golang.org/x/net v0.38.0
- golang.org/x/term v0.30.0
- golang.org/x/text v0.23.0
+ golang.org/x/net v0.43.0
+ golang.org/x/term v0.34.0
+ golang.org/x/text v0.28.0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.33.0
@@ -161,8 +161,8 @@ require (
go.uber.org/zap v1.27.0 // indirect
golang.org/x/arch v0.10.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
- golang.org/x/sys v0.31.0 // indirect
- golang.org/x/tools v0.25.0 // indirect
+ golang.org/x/sys v0.35.0 // indirect
+ golang.org/x/tools v0.36.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
diff --git a/go.sum b/go.sum
index b45d881fe..35db004db 100644
--- a/go.sum
+++ b/go.sum
@@ -654,8 +654,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
-go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
+go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
+go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
@@ -685,8 +685,8 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
-golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
+golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
+golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
@@ -703,8 +703,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
-golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
+golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -731,8 +731,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
-golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
+golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -743,8 +743,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
-golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
+golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -779,14 +779,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
+golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
-golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
+golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
+golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -795,8 +795,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
+golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -820,8 +820,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
-golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
+golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
+golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
From fc2a1d8afeb86602215d831c2767c2a1a56f30a2 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Fri, 28 Nov 2025 10:49:10 +0800
Subject: [PATCH 10/25] fix(answer): update QuestionID handling in answer
update process
---
internal/controller/answer_controller.go | 1 -
internal/schema/answer_schema.go | 1 -
internal/service/content/answer_service.go | 19 +++++++++----------
3 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go
index 7c5aca1db..0e43121c5 100644
--- a/internal/controller/answer_controller.go
+++ b/internal/controller/answer_controller.go
@@ -318,7 +318,6 @@ func (ac *AnswerController) UpdateAnswer(ctx *gin.Context) {
handler.HandleResponse(ctx, err, nil)
return
}
- req.QuestionID = uid.DeShortID(req.QuestionID)
linkUrlLimitUser := canList[2]
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin || !linkUrlLimitUser {
diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go
index 015e26ac5..9ac4bcad7 100644
--- a/internal/schema/answer_schema.go
+++ b/internal/schema/answer_schema.go
@@ -78,7 +78,6 @@ type GetAnswerInfoResp struct {
type AnswerUpdateReq struct {
ID string `json:"id"`
- QuestionID string `json:"question_id"`
Title string `json:"title"`
Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"`
EditSummary string `validate:"omitempty" json:"edit_summary"`
diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go
index b9d45b522..982bbf88a 100644
--- a/internal/service/content/answer_service.go
+++ b/internal/service/content/answer_service.go
@@ -346,24 +346,23 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
return "", errors.BadRequest(reason.AnswerCannotUpdate)
}
- questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
+ answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID)
if err != nil {
return "", err
}
if !exist {
- return "", errors.BadRequest(reason.QuestionNotFound)
+ return "", errors.BadRequest(reason.AnswerNotFound)
+ }
+ if answerInfo.Status == entity.AnswerStatusDeleted {
+ return "", errors.BadRequest(reason.AnswerCannotUpdate)
}
- answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID)
+ questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, answerInfo.QuestionID)
if err != nil {
return "", err
}
if !exist {
- return "", errors.BadRequest(reason.AnswerNotFound)
- }
-
- if answerInfo.Status == entity.AnswerStatusDeleted {
- return "", errors.BadRequest(reason.AnswerCannotUpdate)
+ return "", errors.BadRequest(reason.QuestionNotFound)
}
//If the content is the same, ignore it
@@ -374,7 +373,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
insertData := &entity.Answer{}
insertData.ID = req.ID
insertData.UserID = answerInfo.UserID
- insertData.QuestionID = req.QuestionID
+ insertData.QuestionID = questionInfo.ID
insertData.OriginalText = req.Content
insertData.ParsedText = req.HTML
insertData.UpdatedAt = time.Now()
@@ -403,7 +402,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "updated_at", "last_edit_user_id"}); err != nil {
return "", err
}
- err = as.questionCommon.UpdatePostTime(ctx, req.QuestionID)
+ err = as.questionCommon.UpdatePostTime(ctx, questionInfo.ID)
if err != nil {
return insertData.ID, err
}
From f723d120d924dcf7e65b969ce18f8111cac40343 Mon Sep 17 00:00:00 2001
From: ferhat elmas
Date: Fri, 28 Nov 2025 23:11:57 +0100
Subject: [PATCH 11/25] feat: add golangci-lint into lint target
* replace empty interface with any
* run fmt via golangci-lint
related to #1432
Signed-off-by: ferhat elmas
---
.gitignore | 2 +-
.golangci.yaml | 30 +++++++++++++++++++
Makefile | 17 +++++++++--
docs/docs.go | 7 ++---
docs/swagger.json | 7 ++---
docs/swagger.yaml | 6 ++--
internal/base/handler/handler.go | 6 ++--
internal/base/handler/response.go | 4 +--
internal/base/pager/pager.go | 2 +-
internal/base/pager/pagination.go | 6 ++--
internal/base/server/http_funcmap.go | 6 ++--
internal/base/translator/provider.go | 8 ++---
internal/base/validator/validator.go | 4 +--
internal/install/install_from_env.go | 2 +-
internal/migrations/init.go | 10 +++----
internal/migrations/init_data.go | 2 +-
internal/migrations/v25.go | 2 +-
internal/migrations/v6.go | 2 +-
internal/repo/meta/meta_repo.go | 2 +-
.../plugin_config/plugin_user_config_repo.go | 2 +-
internal/repo/revision/revision_repo.go | 2 +-
internal/repo/role/user_role_rel_repo.go | 2 +-
internal/repo/search_common/search_repo.go | 26 ++++++++--------
internal/repo/user/user_repo.go | 2 +-
internal/schema/question_schema.go | 28 ++++++++---------
internal/schema/revision_schema.go | 2 +-
internal/schema/siteinfo_schema.go | 14 ++++-----
internal/schema/user_schema.go | 2 +-
internal/service/question_common/question.go | 2 +-
internal/service/siteinfo/siteinfo_service.go | 2 +-
.../siteinfo_common/siteinfo_service.go | 4 +--
pkg/converter/str.go | 2 +-
32 files changed, 125 insertions(+), 90 deletions(-)
create mode 100644 .golangci.yaml
diff --git a/.gitignore b/.gitignore
index 1fc116a74..257ef31d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,7 @@ vendor/
/answer-data/
/answer
/new_answer
-
+build/tools/
dist/
# Lint setup generated file
diff --git a/.golangci.yaml b/.golangci.yaml
new file mode 100644
index 000000000..af00efc3b
--- /dev/null
+++ b/.golangci.yaml
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+version: "2"
+linters:
+ default: none
+
+formatters:
+ enable:
+ - gofmt
+ settings:
+ gofmt:
+ simplify: true
+ rewrite-rules:
+ - pattern: 'interface{}'
+ replacement: 'any'
diff --git a/Makefile b/Makefile
index 8ab23cce3..fd3f044fa 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,15 @@ Revision=$(shell git rev-parse --short HEAD 2>/dev/null || echo "")
GO_FLAGS=-ldflags="-X github.com/apache/answer/cmd.Version=$(VERSION) -X 'github.com/apache/answer/cmd.Revision=$(Revision)' -X 'github.com/apache/answer/cmd.Time=`date +%s`' -extldflags -static"
GO=$(GO_ENV) "$(shell which go)"
+GOLANGCI_VERSION ?= v2.6.2
+TOOLS_BIN := $(shell mkdir -p build/tools && realpath build/tools)
+
+GOLANGCI = $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION)
+$(GOLANGCI):
+ rm -f $(TOOLS_BIN)/golangci-lint*
+ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_VERSION)/install.sh | sh -s -- -b $(TOOLS_BIN) $(GOLANGCI_VERSION)
+ mv $(TOOLS_BIN)/golangci-lint $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION)
+
build: generate
@$(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC)
@@ -50,8 +59,12 @@ install-ui-packages:
ui:
@cd ui && pnpm pre-install && pnpm build && cd -
-lint: generate
+lint: generate $(GOLANGCI)
+ @bash ./script/check-asf-header.sh
+ $(GOLANGCI) run
+
+lint-fix: generate $(GOLANGCI)
@bash ./script/check-asf-header.sh
- @gofmt -w -l .
+ $(GOLANGCI) run --fix
all: clean build
diff --git a/docs/docs.go b/docs/docs.go
index c87313917..5e9d5b39d 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -8080,9 +8080,6 @@ const docTemplate = `{
"id": {
"type": "string"
},
- "question_id": {
- "type": "string"
- },
"title": {
"type": "string"
}
@@ -10920,7 +10917,7 @@ const docTemplate = `{
},
"theme_config": {
"type": "object",
- "additionalProperties": true
+ "additionalProperties": {}
}
}
},
@@ -10935,7 +10932,7 @@ const docTemplate = `{
},
"theme_config": {
"type": "object",
- "additionalProperties": true
+ "additionalProperties": {}
},
"theme_options": {
"type": "array",
diff --git a/docs/swagger.json b/docs/swagger.json
index 9f89cb157..e0f6378e4 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -8053,9 +8053,6 @@
"id": {
"type": "string"
},
- "question_id": {
- "type": "string"
- },
"title": {
"type": "string"
}
@@ -10893,7 +10890,7 @@
},
"theme_config": {
"type": "object",
- "additionalProperties": true
+ "additionalProperties": {}
}
}
},
@@ -10908,7 +10905,7 @@
},
"theme_config": {
"type": "object",
- "additionalProperties": true
+ "additionalProperties": {}
},
"theme_options": {
"type": "array",
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index d2dd076cf..e0244083b 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -399,8 +399,6 @@ definitions:
type: string
id:
type: string
- question_id:
- type: string
title:
type: string
required:
@@ -2364,7 +2362,7 @@ definitions:
maxLength: 255
type: string
theme_config:
- additionalProperties: true
+ additionalProperties: {}
type: object
required:
- theme
@@ -2376,7 +2374,7 @@ definitions:
theme:
type: string
theme_config:
- additionalProperties: true
+ additionalProperties: {}
type: object
theme_options:
items:
diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go
index 7670feea7..5a4961a3e 100644
--- a/internal/base/handler/handler.go
+++ b/internal/base/handler/handler.go
@@ -31,7 +31,7 @@ import (
)
// HandleResponse Handle response body
-func HandleResponse(ctx *gin.Context, err error, data interface{}) {
+func HandleResponse(ctx *gin.Context, err error, data any) {
lang := GetLang(ctx)
// no error
if err == nil {
@@ -61,7 +61,7 @@ func HandleResponse(ctx *gin.Context, err error, data interface{}) {
}
// BindAndCheck bind request and check
-func BindAndCheck(ctx *gin.Context, data interface{}) bool {
+func BindAndCheck(ctx *gin.Context, data any) bool {
lang := GetLang(ctx)
ctx.Set(constant.AcceptLanguageFlag, lang)
if err := ctx.ShouldBind(data); err != nil {
@@ -79,7 +79,7 @@ func BindAndCheck(ctx *gin.Context, data interface{}) bool {
}
// BindAndCheckReturnErr bind request and check
-func BindAndCheckReturnErr(ctx *gin.Context, data interface{}) (errFields []*validator.FormErrorField) {
+func BindAndCheckReturnErr(ctx *gin.Context, data any) (errFields []*validator.FormErrorField) {
lang := GetLang(ctx)
if err := ctx.ShouldBind(data); err != nil {
log.Errorf("http_handle BindAndCheck fail, %s", err.Error())
diff --git a/internal/base/handler/response.go b/internal/base/handler/response.go
index 827e0b362..51be8a8a1 100644
--- a/internal/base/handler/response.go
+++ b/internal/base/handler/response.go
@@ -34,7 +34,7 @@ type RespBody struct {
// response message
Message string `json:"msg"`
// response data
- Data interface{} `json:"data"`
+ Data any `json:"data"`
}
// TrMsg translate the reason cause as a message
@@ -63,7 +63,7 @@ func NewRespBodyFromError(e *errors.Error) *RespBody {
}
// NewRespBodyData new response body with data
-func NewRespBodyData(code int, reason string, data interface{}) *RespBody {
+func NewRespBodyData(code int, reason string, data any) *RespBody {
return &RespBody{
Code: code,
Reason: reason,
diff --git a/internal/base/pager/pager.go b/internal/base/pager/pager.go
index d7a4caa14..b14d99bfa 100644
--- a/internal/base/pager/pager.go
+++ b/internal/base/pager/pager.go
@@ -27,7 +27,7 @@ import (
)
// Help xorm page helper
-func Help(page, pageSize int, rowsSlicePtr interface{}, rowElement interface{}, session *xorm.Session) (total int64, err error) {
+func Help(page, pageSize int, rowsSlicePtr any, rowElement any, session *xorm.Session) (total int64, err error) {
page, pageSize = ValPageAndPageSize(page, pageSize)
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
diff --git a/internal/base/pager/pagination.go b/internal/base/pager/pagination.go
index 36849fed5..1b09e1f21 100644
--- a/internal/base/pager/pagination.go
+++ b/internal/base/pager/pagination.go
@@ -25,8 +25,8 @@ import (
// PageModel page model
type PageModel struct {
- Count int64 `json:"count"`
- List interface{} `json:"list"`
+ Count int64 `json:"count"`
+ List any `json:"list"`
}
// PageCond page condition
@@ -36,7 +36,7 @@ type PageCond struct {
}
// NewPageModel new page model
-func NewPageModel(totalRecords int64, records interface{}) *PageModel {
+func NewPageModel(totalRecords int64, records any) *PageModel {
sliceValue := reflect.Indirect(reflect.ValueOf(records))
if sliceValue.Kind() != reflect.Slice {
panic("not a slice")
diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go
index 9d8e98f96..8f6cac5fc 100644
--- a/internal/base/server/http_funcmap.go
+++ b/internal/base/server/http_funcmap.go
@@ -64,7 +64,7 @@ var funcMap = template.FuncMap{
"formatLinkNofollow": func(data string) template.HTML {
return template.HTML(FormatLinkNofollow(data))
},
- "translator": func(la i18n.Language, data string, params ...interface{}) string {
+ "translator": func(la i18n.Language, data string, params ...any) string {
trans := translator.GlobalTrans.Tr(la, data)
if len(params) > 0 && len(params)%2 == 0 {
@@ -128,8 +128,8 @@ var funcMap = template.FuncMap{
trans = translator.GlobalTrans.Tr(la, "ui.dates.long_date_with_year")
return day.Format(timestamp, trans, tz)
},
- "wrapComments": func(comments []*schema.GetCommentResp, la i18n.Language, tz string) map[string]interface{} {
- return map[string]interface{}{
+ "wrapComments": func(comments []*schema.GetCommentResp, la i18n.Language, tz string) map[string]any {
+ return map[string]any{
"comments": comments,
"language": la,
"timezone": tz,
diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go
index 9838d185d..47212e84f 100644
--- a/internal/base/translator/provider.go
+++ b/internal/base/translator/provider.go
@@ -76,14 +76,14 @@ func NewTranslator(c *I18n) (tr i18n.Translator, err error) {
// parse the backend translation
originalTr := struct {
- Backend map[string]map[string]interface{} `yaml:"backend"`
- UI map[string]interface{} `yaml:"ui"`
- Plugin map[string]interface{} `yaml:"plugin"`
+ Backend map[string]map[string]any `yaml:"backend"`
+ UI map[string]any `yaml:"ui"`
+ Plugin map[string]any `yaml:"plugin"`
}{}
if err = yaml.Unmarshal(buf, &originalTr); err != nil {
return nil, err
}
- translation := make(map[string]interface{}, 0)
+ translation := make(map[string]any, 0)
for k, v := range originalTr.Backend {
translation[k] = v
}
diff --git a/internal/base/validator/validator.go b/internal/base/validator/validator.go
index 70c7be2e9..22761c521 100644
--- a/internal/base/validator/validator.go
+++ b/internal/base/validator/validator.go
@@ -187,7 +187,7 @@ func GetValidatorByLang(lang i18n.Language) *MyValidator {
}
// Check /
-func (m *MyValidator) Check(value interface{}) (errFields []*FormErrorField, err error) {
+func (m *MyValidator) Check(value any) (errFields []*FormErrorField, err error) {
defer func() {
if len(errFields) == 0 {
return
@@ -261,7 +261,7 @@ type Checker interface {
Check() (errField []*FormErrorField, err error)
}
-func getObjectTagByFieldName(obj interface{}, fieldName string) (tag string) {
+func getObjectTagByFieldName(obj any, fieldName string) (tag string) {
defer func() {
if err := recover(); err != nil {
log.Error(err)
diff --git a/internal/install/install_from_env.go b/internal/install/install_from_env.go
index a6b668bab..c05d2aaba 100644
--- a/internal/install/install_from_env.go
+++ b/internal/install/install_from_env.go
@@ -133,7 +133,7 @@ func initBaseInfo(env *Env) (err error) {
return requestAPI(req, "POST", "/installation/base-info", InitBaseInfo)
}
-func requestAPI(req interface{}, method, url string, handlerFunc gin.HandlerFunc) error {
+func requestAPI(req any, method, url string, handlerFunc gin.HandlerFunc) error {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
body, _ := json.Marshal(req)
diff --git a/internal/migrations/init.go b/internal/migrations/init.go
index 392ecb2c6..184c986b9 100644
--- a/internal/migrations/init.go
+++ b/internal/migrations/init.go
@@ -208,7 +208,7 @@ func (m *Mentor) initSiteInfoGeneralData() {
}
func (m *Mentor) initSiteInfoLoginConfig() {
- loginConfig := map[string]interface{}{
+ loginConfig := map[string]any{
"allow_new_registrations": true,
"allow_email_registrations": true,
"allow_password_login": true,
@@ -223,7 +223,7 @@ func (m *Mentor) initSiteInfoLoginConfig() {
}
func (m *Mentor) initSiteInfoLegalConfig() {
- legalConfig := map[string]interface{}{
+ legalConfig := map[string]any{
"external_content_display": m.userData.ExternalContentDisplay,
}
legalConfigDataBytes, _ := json.Marshal(legalConfig)
@@ -244,7 +244,7 @@ func (m *Mentor) initSiteInfoThemeConfig() {
}
func (m *Mentor) initSiteInfoSEOConfig() {
- seoData := map[string]interface{}{
+ seoData := map[string]any{
"permalink": constant.PermalinkQuestionID,
"robots": defaultSEORobotTxt + m.userData.SiteURL + "/sitemap.xml",
}
@@ -276,7 +276,7 @@ func (m *Mentor) initSiteInfoUsersConfig() {
}
func (m *Mentor) initSiteInfoPrivilegeRank() {
- privilegeRankData := map[string]interface{}{
+ privilegeRankData := map[string]any{
"level": schema.PrivilegeLevel2,
}
privilegeRankDataBytes, _ := json.Marshal(privilegeRankData)
@@ -288,7 +288,7 @@ func (m *Mentor) initSiteInfoPrivilegeRank() {
}
func (m *Mentor) initSiteInfoWrite() {
- writeData := map[string]interface{}{
+ writeData := map[string]any{
"min_content": 6,
"restrict_answer": true,
"min_tags": 1,
diff --git a/internal/migrations/init_data.go b/internal/migrations/init_data.go
index 96151625d..356a915a7 100644
--- a/internal/migrations/init_data.go
+++ b/internal/migrations/init_data.go
@@ -43,7 +43,7 @@ Sitemap: `
)
var (
- tables = []interface{}{
+ tables = []any{
&entity.Activity{},
&entity.Answer{},
&entity.Collection{},
diff --git a/internal/migrations/v25.go b/internal/migrations/v25.go
index 560a852ac..228c2ef26 100644
--- a/internal/migrations/v25.go
+++ b/internal/migrations/v25.go
@@ -39,7 +39,7 @@ func addFileRecord(ctx context.Context, x *xorm.Engine) error {
if err != nil {
return fmt.Errorf("get legal config failed: %w", err)
}
- legalConfig := make(map[string]interface{})
+ legalConfig := make(map[string]any)
if exist {
if err := json.Unmarshal([]byte(legalInfo.Content), &legalConfig); err != nil {
return fmt.Errorf("unmarshal legal config failed: %w", err)
diff --git a/internal/migrations/v6.go b/internal/migrations/v6.go
index 9171ad47a..88fb58497 100644
--- a/internal/migrations/v6.go
+++ b/internal/migrations/v6.go
@@ -45,7 +45,7 @@ func addNewAnswerNotification(ctx context.Context, x *xorm.Engine) error {
}
}
- m := make(map[string]interface{})
+ m := make(map[string]any)
_ = json.Unmarshal([]byte(cond.Value), &m)
m["new_answer_title"] = "[{{.SiteName}}] {{.DisplayName}} answered your question"
m["new_answer_body"] = "{{.QuestionTitle}} \n\n{{.DisplayName}}: \n{{.AnswerSummary}} \nView it on {{.SiteName}} \n\nYou are receiving this because you authored the thread. Unsubscribe "
diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go
index 767bd04c7..9680fb419 100644
--- a/internal/repo/meta/meta_repo.go
+++ b/internal/repo/meta/meta_repo.go
@@ -72,7 +72,7 @@ func (mr *metaRepo) UpdateMeta(ctx context.Context, meta *entity.Meta) (err erro
// AddOrUpdateMetaByObjectIdAndKey if exist record with same objectID and key, update it. Or create a new one
func (mr *metaRepo) AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, objectId, key string, f func(*entity.Meta, bool) (*entity.Meta, error)) error {
- _, err := mr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) {
+ _, err := mr.data.DB.Transaction(func(session *xorm.Session) (any, error) {
session = session.Context(ctx)
// 1. acquire meta entity with target object id and key
diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go
index 19d6af5f9..83da8e758 100644
--- a/internal/repo/plugin_config/plugin_user_config_repo.go
+++ b/internal/repo/plugin_config/plugin_user_config_repo.go
@@ -44,7 +44,7 @@ func NewPluginUserConfigRepo(data *data.Data) plugin_common.PluginUserConfigRepo
func (ur *pluginUserConfigRepo) SaveUserPluginConfig(ctx context.Context, userID string,
pluginSlugName, configValue string) (err error) {
- _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) {
+ _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) {
session = session.Context(ctx)
old := &entity.PluginUserConfig{
UserID: userID,
diff --git a/internal/repo/revision/revision_repo.go b/internal/repo/revision/revision_repo.go
index 09ba1aacd..8b9e08400 100644
--- a/internal/repo/revision/revision_repo.go
+++ b/internal/repo/revision/revision_repo.go
@@ -64,7 +64,7 @@ func (rr *revisionRepo) AddRevision(ctx context.Context, revision *entity.Revisi
if !rr.allowRecord(revision.ObjectType) {
return nil
}
- _, err = rr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) {
+ _, err = rr.data.DB.Transaction(func(session *xorm.Session) (any, error) {
session = session.Context(ctx)
_, err = session.Insert(revision)
if err != nil {
diff --git a/internal/repo/role/user_role_rel_repo.go b/internal/repo/role/user_role_rel_repo.go
index 7bd14ecea..1925339c0 100644
--- a/internal/repo/role/user_role_rel_repo.go
+++ b/internal/repo/role/user_role_rel_repo.go
@@ -45,7 +45,7 @@ func NewUserRoleRelRepo(data *data.Data) role.UserRoleRelRepo {
// SaveUserRoleRel save user role rel
func (ur *userRoleRelRepo) SaveUserRoleRel(ctx context.Context, userID string, roleID int) (err error) {
- _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) {
+ _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) {
session = session.Context(ctx)
item := &entity.UserRoleRel{UserID: userID}
exist, err := session.Get(item)
diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go
index 314c51878..806517234 100644
--- a/internal/repo/search_common/search_repo.go
+++ b/internal/repo/search_common/search_repo.go
@@ -107,8 +107,8 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs
ub *builder.Builder
qfs = qFields
afs = aFields
- argsQ = []interface{}{}
- argsA = []interface{}{}
+ argsQ = []any{}
+ argsA = []any{}
)
if order == "relevance" {
@@ -212,8 +212,8 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs
return
}
- queryArgs := []interface{}{}
- countArgs := []interface{}{}
+ queryArgs := []any{}
+ countArgs := []any{}
queryArgs = append(queryArgs, querySQL)
queryArgs = append(queryArgs, argsQ...)
@@ -246,7 +246,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID
words = filterWords(words)
var (
qfs = qFields
- args = []interface{}{}
+ args = []any{}
)
if order == "relevance" {
if len(words) > 0 {
@@ -313,8 +313,8 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID
args = append(args, answers)
}
- queryArgs := []interface{}{}
- countArgs := []interface{}{}
+ queryArgs := []any{}
+ countArgs := []any{}
countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
if err != nil {
@@ -358,7 +358,7 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs
var (
afs = aFields
- args = []interface{}{}
+ args = []any{}
)
if order == "relevance" {
if len(words) > 0 {
@@ -409,8 +409,8 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs
args = append(args, questionID)
}
- queryArgs := []interface{}{}
- countArgs := []interface{}{}
+ queryArgs := []any{}
+ countArgs := []any{}
countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
if err != nil {
@@ -575,9 +575,9 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte,
return resultList, nil
}
-func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) {
+func addRelevanceField(searchFields, words, fields []string) (res []string, args []any) {
relevanceRes := []string{}
- args = []interface{}{}
+ args = []any{}
for _, searchField := range searchFields {
var (
@@ -585,7 +585,7 @@ func addRelevanceField(searchFields, words, fields []string) (res []string, args
replacement = "REPLACE(%s, ?, '')"
replaceField = searchField
replaced string
- argsField = []interface{}{}
+ argsField = []any{}
)
res = fields
diff --git a/internal/repo/user/user_repo.go b/internal/repo/user/user_repo.go
index a85cd79a1..1533cc5e8 100644
--- a/internal/repo/user/user_repo.go
+++ b/internal/repo/user/user_repo.go
@@ -51,7 +51,7 @@ func NewUserRepo(data *data.Data) usercommon.UserRepo {
// AddUser add user
func (ur *userRepo) AddUser(ctx context.Context, user *entity.User) (err error) {
- _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) {
+ _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) {
session = session.Context(ctx)
userInfo := &entity.User{}
exist, err := session.Where("username = ?", user.Username).Get(userInfo)
diff --git a/internal/schema/question_schema.go b/internal/schema/question_schema.go
index 84b97b830..133208286 100644
--- a/internal/schema/question_schema.go
+++ b/internal/schema/question_schema.go
@@ -330,24 +330,24 @@ type UserAnswerInfo struct {
CreateTime int `json:"create_time"`
UpdateTime int `json:"update_time"`
QuestionInfo struct {
- Title string `json:"title"`
- UrlTitle string `json:"url_title"`
- Tags []interface{} `json:"tags"`
+ Title string `json:"title"`
+ UrlTitle string `json:"url_title"`
+ Tags []any `json:"tags"`
} `json:"question_info"`
}
type UserQuestionInfo struct {
- ID string `json:"question_id"`
- Title string `json:"title"`
- UrlTitle string `json:"url_title"`
- VoteCount int `json:"vote_count"`
- Tags []interface{} `json:"tags"`
- ViewCount int `json:"view_count"`
- AnswerCount int `json:"answer_count"`
- CollectionCount int `json:"collection_count"`
- CreatedAt int64 `json:"created_at"`
- AcceptedAnswerID string `json:"accepted_answer_id"`
- Status string `json:"status"`
+ ID string `json:"question_id"`
+ Title string `json:"title"`
+ UrlTitle string `json:"url_title"`
+ VoteCount int `json:"vote_count"`
+ Tags []any `json:"tags"`
+ ViewCount int `json:"view_count"`
+ AnswerCount int `json:"answer_count"`
+ CollectionCount int `json:"collection_count"`
+ CreatedAt int64 `json:"created_at"`
+ AcceptedAnswerID string `json:"accepted_answer_id"`
+ Status string `json:"status"`
}
const (
diff --git a/internal/schema/revision_schema.go b/internal/schema/revision_schema.go
index 946d11653..b3ac0aadd 100644
--- a/internal/schema/revision_schema.go
+++ b/internal/schema/revision_schema.go
@@ -97,7 +97,7 @@ type GetRevisionResp struct {
Title string `json:"title"`
UrlTitle string `json:"url_title"`
Content string `json:"-"`
- ContentParsed interface{} `json:"content"`
+ ContentParsed any `json:"content"`
Status int `json:"status"`
CreatedAt time.Time `json:"-"`
CreatedAtParsed int64 `json:"create_at"`
diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go
index 76f66cb07..0e43bb420 100644
--- a/internal/schema/siteinfo_schema.go
+++ b/internal/schema/siteinfo_schema.go
@@ -178,9 +178,9 @@ type SiteCustomCssHTMLReq struct {
// SiteThemeReq site theme config
type SiteThemeReq struct {
- Theme string `validate:"required,gt=0,lte=255" json:"theme"`
- ThemeConfig map[string]interface{} `validate:"omitempty" json:"theme_config"`
- ColorScheme string `validate:"omitempty,gt=0,lte=100" json:"color_scheme"`
+ Theme string `validate:"required,gt=0,lte=255" json:"theme"`
+ ThemeConfig map[string]any `validate:"omitempty" json:"theme_config"`
+ ColorScheme string `validate:"omitempty,gt=0,lte=100" json:"color_scheme"`
}
type SiteSeoReq struct {
@@ -213,10 +213,10 @@ type SiteUsersResp SiteUsersReq
// SiteThemeResp site theme response
type SiteThemeResp struct {
- ThemeOptions []*ThemeOption `json:"theme_options"`
- Theme string `json:"theme"`
- ThemeConfig map[string]interface{} `json:"theme_config"`
- ColorScheme string `json:"color_scheme"`
+ ThemeOptions []*ThemeOption `json:"theme_options"`
+ Theme string `json:"theme"`
+ ThemeConfig map[string]any `json:"theme_config"`
+ ColorScheme string `json:"color_scheme"`
}
func (s *SiteThemeResp) TrTheme(ctx context.Context) {
diff --git a/internal/schema/user_schema.go b/internal/schema/user_schema.go
index 7ba8817a8..d209c8f58 100644
--- a/internal/schema/user_schema.go
+++ b/internal/schema/user_schema.go
@@ -200,7 +200,7 @@ func (r *GetOtherUserInfoByUsernameResp) ConvertFromUserEntityWithLang(ctx conte
r.SuspendedUntil = userInfo.SuspendedUntil.Unix()
trans := translator.GlobalTrans.Tr(lang, "ui.dates.long_date_with_time")
suspendedUntilFormatted := day.Format(userInfo.SuspendedUntil.Unix(), trans, "UTC")
- r.StatusMsg = translator.TrWithData(lang, reason.UserStatusSuspendedUntil, map[string]interface{}{
+ r.StatusMsg = translator.TrWithData(lang, reason.UserStatusSuspendedUntil, map[string]any{
"SuspendedUntil": suspendedUntilFormatted,
})
}
diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go
index feb5626ed..333806445 100644
--- a/internal/service/question_common/question.go
+++ b/internal/service/question_common/question.go
@@ -622,7 +622,7 @@ func (qs *QuestionCommon) SitemapCron(ctx context.Context) {
}
}
-func (qs *QuestionCommon) SetCache(ctx context.Context, cachekey string, info interface{}) error {
+func (qs *QuestionCommon) SetCache(ctx context.Context, cachekey string, info any) error {
infoStr, err := json.Marshal(info)
if err != nil {
return errors.InternalServer(reason.UnknownError).WithError(err).WithStack()
diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go
index 92b3e0c71..cf43d68d5 100644
--- a/internal/service/siteinfo/siteinfo_service.go
+++ b/internal/service/siteinfo/siteinfo_service.go
@@ -183,7 +183,7 @@ func (s *SiteInfoService) SaveSiteBranding(ctx context.Context, req *schema.Site
}
// SaveSiteWrite save site configuration about write
-func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp interface{}, err error) {
+func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp any, err error) {
recommendTags, reservedTags := make([]string, 0), make([]string, 0)
recommendTagMapping, reservedTagMapping := make(map[string]bool), make(map[string]bool)
for _, tag := range req.ReservedTags {
diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go
index ef4869cc4..fda117229 100644
--- a/internal/service/siteinfo_common/siteinfo_service.go
+++ b/internal/service/siteinfo_common/siteinfo_service.go
@@ -56,7 +56,7 @@ type SiteInfoCommonService interface {
GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error)
GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error)
GetSiteSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error)
- GetSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error)
+ GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error)
IsBrandingFileUsed(ctx context.Context, filePath string) bool
}
@@ -224,7 +224,7 @@ func (s *siteInfoCommonService) EnableShortID(ctx context.Context) (enabled bool
return siteSeo.IsShortLink()
}
-func (s *siteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error) {
+func (s *siteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) {
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, siteType)
if err != nil {
return err
diff --git a/pkg/converter/str.go b/pkg/converter/str.go
index 40c147fdc..5164609ca 100644
--- a/pkg/converter/str.go
+++ b/pkg/converter/str.go
@@ -47,7 +47,7 @@ func IntToString(data int64) string {
// InterfaceToString converts data to string
// It will be used in template render
-func InterfaceToString(data interface{}) string {
+func InterfaceToString(data any) string {
switch t := data.(type) {
case int:
i := data.(int)
From 9540ef60050fb6e2598d8d72ab23514f6e6d4f93 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Mon, 1 Dec 2025 11:30:42 +0800
Subject: [PATCH 12/25] refactor(goimports): add goimports to golangci-lint
configuration #1432
---
.golangci.yaml | 1 +
internal/base/handler/handler.go | 3 ++-
internal/base/middleware/accept_language.go | 3 ++-
internal/base/middleware/rate_limit.go | 1 +
internal/cli/config.go | 1 +
internal/cli/i18n.go | 7 ++++---
internal/controller/template_render/comment.go | 1 +
internal/controller/user_plugin_controller.go | 3 ++-
internal/entity/badge_entity.go | 3 ++-
internal/entity/config_entity.go | 1 +
internal/migrations/v1.go | 1 +
internal/migrations/v13.go | 1 +
internal/migrations/v14.go | 1 +
internal/migrations/v15.go | 1 +
internal/migrations/v16.go | 1 +
internal/migrations/v17.go | 1 +
internal/migrations/v18.go | 1 +
internal/migrations/v19.go | 1 +
internal/migrations/v2.go | 1 +
internal/migrations/v21.go | 1 +
internal/migrations/v22.go | 1 +
internal/migrations/v24.go | 1 +
internal/repo/activity/answer_repo.go | 3 ++-
internal/repo/activity/user_active_repo.go | 1 +
internal/repo/activity_common/vote.go | 1 +
internal/repo/auth/auth.go | 1 +
internal/repo/badge/badge_event_rule.go | 3 ++-
internal/repo/badge/badge_repo.go | 1 +
internal/repo/badge_award/badge_award_repo.go | 1 +
internal/repo/badge_group/badge_group_repo.go | 1 +
internal/repo/collection/collection_repo.go | 1 +
internal/repo/export/email_repo.go | 3 ++-
internal/repo/limit/limit.go | 3 ++-
internal/repo/meta/meta_repo.go | 2 +-
internal/repo/plugin_config/plugin_user_config_repo.go | 1 +
internal/repo/search_sync/search_sync.go | 1 +
.../user_notification_config_repo.go | 1 +
internal/schema/email_template.go | 1 +
internal/schema/notification_schema.go | 3 ++-
internal/schema/user_notification_schema.go | 1 +
internal/service/activity/activity.go | 2 +-
internal/service/activity/answer_activity_service.go | 1 +
internal/service/badge/badge_award_service.go | 1 +
internal/service/badge/badge_event_handler.go | 1 +
internal/service/badge/badge_group_service.go | 1 +
internal/service/badge/badge_service.go | 3 ++-
internal/service/content/question_hottest_service.go | 5 +++--
internal/service/content/vote_service.go | 3 ++-
internal/service/export/email_service.go | 3 ++-
internal/service/meta/meta_service.go | 3 ++-
internal/service/notification/notification_service.go | 1 +
internal/service/permission/answer_permission.go | 1 +
internal/service/permission/question_permission.go | 1 +
internal/service/provider.go | 2 +-
internal/service/report/report_service.go | 1 +
internal/service/search_parser/search_parser.go | 3 ++-
.../user_notification_config_service.go | 1 +
pkg/converter/str.go | 3 ++-
pkg/day/day_test.go | 3 ++-
pkg/gravatar/gravatar_test.go | 3 ++-
60 files changed, 82 insertions(+), 25 deletions(-)
diff --git a/.golangci.yaml b/.golangci.yaml
index af00efc3b..263f63f70 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -22,6 +22,7 @@ linters:
formatters:
enable:
- gofmt
+ - goimports
settings:
gofmt:
simplify: true
diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go
index 5a4961a3e..b545b5e01 100644
--- a/internal/base/handler/handler.go
+++ b/internal/base/handler/handler.go
@@ -21,13 +21,14 @@ package handler
import (
"errors"
+ "net/http"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/reason"
"github.com/apache/answer/internal/base/validator"
"github.com/gin-gonic/gin"
myErrors "github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
- "net/http"
)
// HandleResponse Handle response body
diff --git a/internal/base/middleware/accept_language.go b/internal/base/middleware/accept_language.go
index 7a8ee391a..ca8a1f903 100644
--- a/internal/base/middleware/accept_language.go
+++ b/internal/base/middleware/accept_language.go
@@ -20,13 +20,14 @@
package middleware
import (
+ "strings"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/translator"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/i18n"
"golang.org/x/text/language"
- "strings"
)
// ExtractAndSetAcceptLanguage extract accept language from header and set to context
diff --git a/internal/base/middleware/rate_limit.go b/internal/base/middleware/rate_limit.go
index 29b961757..d376a6d50 100644
--- a/internal/base/middleware/rate_limit.go
+++ b/internal/base/middleware/rate_limit.go
@@ -22,6 +22,7 @@ package middleware
import (
"encoding/json"
"fmt"
+
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/reason"
"github.com/apache/answer/internal/repo/limit"
diff --git a/internal/cli/config.go b/internal/cli/config.go
index 93cb8eab2..ecb62a13c 100644
--- a/internal/cli/config.go
+++ b/internal/cli/config.go
@@ -23,6 +23,7 @@ import (
"context"
"encoding/json"
"fmt"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/entity"
diff --git a/internal/cli/i18n.go b/internal/cli/i18n.go
index faef0f28a..819ebd753 100644
--- a/internal/cli/i18n.go
+++ b/internal/cli/i18n.go
@@ -21,13 +21,14 @@ package cli
import (
"fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
"github.com/apache/answer/i18n"
"github.com/apache/answer/pkg/dir"
"github.com/apache/answer/pkg/writer"
"gopkg.in/yaml.v3"
- "os"
- "path/filepath"
- "strings"
)
type YamlPluginContent struct {
diff --git a/internal/controller/template_render/comment.go b/internal/controller/template_render/comment.go
index 67efd2129..2862ad8dd 100644
--- a/internal/controller/template_render/comment.go
+++ b/internal/controller/template_render/comment.go
@@ -21,6 +21,7 @@ package templaterender
import (
"context"
+
"github.com/apache/answer/internal/base/pager"
"github.com/apache/answer/internal/schema"
)
diff --git a/internal/controller/user_plugin_controller.go b/internal/controller/user_plugin_controller.go
index 310215253..1c4c041c5 100644
--- a/internal/controller/user_plugin_controller.go
+++ b/internal/controller/user_plugin_controller.go
@@ -21,10 +21,11 @@ package controller
import (
"encoding/json"
+ "net/http"
+
"github.com/apache/answer/internal/base/middleware"
"github.com/apache/answer/internal/base/reason"
"github.com/segmentfault/pacman/errors"
- "net/http"
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/schema"
diff --git a/internal/entity/badge_entity.go b/internal/entity/badge_entity.go
index a370e2750..367bb7456 100644
--- a/internal/entity/badge_entity.go
+++ b/internal/entity/badge_entity.go
@@ -20,8 +20,9 @@
package entity
import (
- "github.com/tidwall/gjson"
"time"
+
+ "github.com/tidwall/gjson"
)
type BadgeLevel int
diff --git a/internal/entity/config_entity.go b/internal/entity/config_entity.go
index 95a02be48..d39af7b2d 100644
--- a/internal/entity/config_entity.go
+++ b/internal/entity/config_entity.go
@@ -21,6 +21,7 @@ package entity
import (
"encoding/json"
+
"github.com/segmentfault/pacman/log"
"github.com/apache/answer/pkg/converter"
diff --git a/internal/migrations/v1.go b/internal/migrations/v1.go
index c5e731a0e..688732fa7 100644
--- a/internal/migrations/v1.go
+++ b/internal/migrations/v1.go
@@ -21,6 +21,7 @@ package migrations
import (
"context"
+
"xorm.io/xorm"
)
diff --git a/internal/migrations/v13.go b/internal/migrations/v13.go
index 30bfbb542..57d248482 100644
--- a/internal/migrations/v13.go
+++ b/internal/migrations/v13.go
@@ -24,6 +24,7 @@ import (
"encoding/json"
"fmt"
"time"
+
"xorm.io/builder"
"github.com/apache/answer/internal/base/constant"
diff --git a/internal/migrations/v14.go b/internal/migrations/v14.go
index ee3a3d0d6..5e125c98e 100644
--- a/internal/migrations/v14.go
+++ b/internal/migrations/v14.go
@@ -22,6 +22,7 @@ package migrations
import (
"context"
"time"
+
"xorm.io/xorm/schemas"
"xorm.io/xorm"
diff --git a/internal/migrations/v15.go b/internal/migrations/v15.go
index 5195c105a..5858d0097 100644
--- a/internal/migrations/v15.go
+++ b/internal/migrations/v15.go
@@ -21,6 +21,7 @@ package migrations
import (
"context"
+
"github.com/apache/answer/internal/entity"
"xorm.io/xorm"
)
diff --git a/internal/migrations/v16.go b/internal/migrations/v16.go
index 11643600c..11ae36843 100644
--- a/internal/migrations/v16.go
+++ b/internal/migrations/v16.go
@@ -21,6 +21,7 @@ package migrations
import (
"context"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/entity"
"github.com/segmentfault/pacman/log"
diff --git a/internal/migrations/v17.go b/internal/migrations/v17.go
index 655e547a2..3fa2c7b31 100644
--- a/internal/migrations/v17.go
+++ b/internal/migrations/v17.go
@@ -22,6 +22,7 @@ package migrations
import (
"context"
"fmt"
+
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/service/permission"
"github.com/segmentfault/pacman/log"
diff --git a/internal/migrations/v18.go b/internal/migrations/v18.go
index 89db524f5..7178c704e 100644
--- a/internal/migrations/v18.go
+++ b/internal/migrations/v18.go
@@ -23,6 +23,7 @@ import (
"context"
"encoding/json"
"fmt"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/schema"
diff --git a/internal/migrations/v19.go b/internal/migrations/v19.go
index b45d374bb..b50c89f14 100644
--- a/internal/migrations/v19.go
+++ b/internal/migrations/v19.go
@@ -21,6 +21,7 @@ package migrations
import (
"context"
+
"github.com/apache/answer/internal/entity"
"xorm.io/xorm"
)
diff --git a/internal/migrations/v2.go b/internal/migrations/v2.go
index 4e17597dc..601ff98b2 100644
--- a/internal/migrations/v2.go
+++ b/internal/migrations/v2.go
@@ -21,6 +21,7 @@ package migrations
import (
"context"
+
"xorm.io/xorm"
)
diff --git a/internal/migrations/v21.go b/internal/migrations/v21.go
index 880852f8e..de38bffbd 100644
--- a/internal/migrations/v21.go
+++ b/internal/migrations/v21.go
@@ -21,6 +21,7 @@ package migrations
import (
"context"
+
"xorm.io/xorm"
)
diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go
index 14292a1e7..e7177deae 100644
--- a/internal/migrations/v22.go
+++ b/internal/migrations/v22.go
@@ -22,6 +22,7 @@ package migrations
import (
"context"
"fmt"
+
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/repo/unique"
diff --git a/internal/migrations/v24.go b/internal/migrations/v24.go
index 19358af45..a488679f6 100644
--- a/internal/migrations/v24.go
+++ b/internal/migrations/v24.go
@@ -23,6 +23,7 @@ import (
"context"
"encoding/json"
"fmt"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/schema"
diff --git a/internal/repo/activity/answer_repo.go b/internal/repo/activity/answer_repo.go
index db6e3bde4..4aca874a7 100644
--- a/internal/repo/activity/answer_repo.go
+++ b/internal/repo/activity/answer_repo.go
@@ -22,8 +22,9 @@ package activity
import (
"context"
"fmt"
- "github.com/segmentfault/pacman/log"
"time"
+
+ "github.com/segmentfault/pacman/log"
"xorm.io/builder"
"github.com/apache/answer/internal/base/constant"
diff --git a/internal/repo/activity/user_active_repo.go b/internal/repo/activity/user_active_repo.go
index 2452bcf83..68dfec7d7 100644
--- a/internal/repo/activity/user_active_repo.go
+++ b/internal/repo/activity/user_active_repo.go
@@ -22,6 +22,7 @@ package activity
import (
"context"
"fmt"
+
"xorm.io/builder"
"github.com/apache/answer/internal/base/data"
diff --git a/internal/repo/activity_common/vote.go b/internal/repo/activity_common/vote.go
index cb7d23d00..506578424 100644
--- a/internal/repo/activity_common/vote.go
+++ b/internal/repo/activity_common/vote.go
@@ -21,6 +21,7 @@ package activity_common
import (
"context"
+
"github.com/apache/answer/pkg/uid"
"github.com/apache/answer/internal/base/data"
diff --git a/internal/repo/auth/auth.go b/internal/repo/auth/auth.go
index a1e358f9a..597352b23 100644
--- a/internal/repo/auth/auth.go
+++ b/internal/repo/auth/auth.go
@@ -22,6 +22,7 @@ package auth
import (
"context"
"encoding/json"
+
"github.com/apache/answer/internal/service/auth"
"github.com/apache/answer/internal/base/constant"
diff --git a/internal/repo/badge/badge_event_rule.go b/internal/repo/badge/badge_event_rule.go
index 8c4656db3..786d988ac 100644
--- a/internal/repo/badge/badge_event_rule.go
+++ b/internal/repo/badge/badge_event_rule.go
@@ -21,6 +21,8 @@ package badge
import (
"context"
+ "strconv"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/reason"
@@ -29,7 +31,6 @@ import (
"github.com/apache/answer/internal/service/badge"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
- "strconv"
)
// eventRuleRepo event rule repo
diff --git a/internal/repo/badge/badge_repo.go b/internal/repo/badge/badge_repo.go
index 257caef81..baff45d8a 100644
--- a/internal/repo/badge/badge_repo.go
+++ b/internal/repo/badge/badge_repo.go
@@ -21,6 +21,7 @@ package badge
import (
"context"
+
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/pager"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/repo/badge_award/badge_award_repo.go b/internal/repo/badge_award/badge_award_repo.go
index eda5d80c2..11429e570 100644
--- a/internal/repo/badge_award/badge_award_repo.go
+++ b/internal/repo/badge_award/badge_award_repo.go
@@ -22,6 +22,7 @@ package badge_award
import (
"context"
"fmt"
+
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/pager"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/repo/badge_group/badge_group_repo.go b/internal/repo/badge_group/badge_group_repo.go
index 839ba4691..8f1111a48 100644
--- a/internal/repo/badge_group/badge_group_repo.go
+++ b/internal/repo/badge_group/badge_group_repo.go
@@ -21,6 +21,7 @@ package badge_group
import (
"context"
+
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/service/badge"
diff --git a/internal/repo/collection/collection_repo.go b/internal/repo/collection/collection_repo.go
index a3faacdb5..f30692c97 100644
--- a/internal/repo/collection/collection_repo.go
+++ b/internal/repo/collection/collection_repo.go
@@ -21,6 +21,7 @@ package collection
import (
"context"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/handler"
diff --git a/internal/repo/export/email_repo.go b/internal/repo/export/email_repo.go
index 1f8e1ce83..a3e619712 100644
--- a/internal/repo/export/email_repo.go
+++ b/internal/repo/export/email_repo.go
@@ -21,9 +21,10 @@ package export
import (
"context"
+ "time"
+
"github.com/apache/answer/internal/base/constant"
"github.com/tidwall/gjson"
- "time"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/repo/limit/limit.go b/internal/repo/limit/limit.go
index 4868accd5..524ad12bc 100644
--- a/internal/repo/limit/limit.go
+++ b/internal/repo/limit/limit.go
@@ -22,11 +22,12 @@ package limit
import (
"context"
"fmt"
+ "time"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/reason"
"github.com/segmentfault/pacman/errors"
- "time"
)
// LimitRepo auth repository
diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go
index 9680fb419..fecd7bd5d 100644
--- a/internal/repo/meta/meta_repo.go
+++ b/internal/repo/meta/meta_repo.go
@@ -25,7 +25,7 @@ import (
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/reason"
"github.com/apache/answer/internal/entity"
- "github.com/apache/answer/internal/service/meta_common"
+ metacommon "github.com/apache/answer/internal/service/meta_common"
"github.com/segmentfault/pacman/errors"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go
index 83da8e758..d14442a56 100644
--- a/internal/repo/plugin_config/plugin_user_config_repo.go
+++ b/internal/repo/plugin_config/plugin_user_config_repo.go
@@ -21,6 +21,7 @@ package plugin_config
import (
"context"
+
"github.com/apache/answer/internal/base/pager"
"xorm.io/xorm"
diff --git a/internal/repo/search_sync/search_sync.go b/internal/repo/search_sync/search_sync.go
index 5c0adc0f9..889ffe5be 100644
--- a/internal/repo/search_sync/search_sync.go
+++ b/internal/repo/search_sync/search_sync.go
@@ -21,6 +21,7 @@ package search_sync
import (
"context"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/entity"
diff --git a/internal/repo/user_notification_config/user_notification_config_repo.go b/internal/repo/user_notification_config/user_notification_config_repo.go
index 8ea2b065b..0e761514b 100644
--- a/internal/repo/user_notification_config/user_notification_config_repo.go
+++ b/internal/repo/user_notification_config/user_notification_config_repo.go
@@ -21,6 +21,7 @@ package user_notification_config
import (
"context"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/schema/email_template.go b/internal/schema/email_template.go
index 1fcdfbce3..d7e4b929a 100644
--- a/internal/schema/email_template.go
+++ b/internal/schema/email_template.go
@@ -21,6 +21,7 @@ package schema
import (
"encoding/json"
+
"github.com/apache/answer/internal/base/constant"
)
diff --git a/internal/schema/notification_schema.go b/internal/schema/notification_schema.go
index a68328ace..e5d60615e 100644
--- a/internal/schema/notification_schema.go
+++ b/internal/schema/notification_schema.go
@@ -21,8 +21,9 @@ package schema
import (
"encoding/json"
- "github.com/apache/answer/internal/entity"
"sort"
+
+ "github.com/apache/answer/internal/entity"
)
const (
diff --git a/internal/schema/user_notification_schema.go b/internal/schema/user_notification_schema.go
index eca97e81c..60cc4a27b 100644
--- a/internal/schema/user_notification_schema.go
+++ b/internal/schema/user_notification_schema.go
@@ -21,6 +21,7 @@ package schema
import (
"encoding/json"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/entity"
)
diff --git a/internal/service/activity/activity.go b/internal/service/activity/activity.go
index 2d384f34c..061d84493 100644
--- a/internal/service/activity/activity.go
+++ b/internal/service/activity/activity.go
@@ -26,7 +26,7 @@ import (
"strings"
"github.com/apache/answer/internal/service/activity_common"
- "github.com/apache/answer/internal/service/meta_common"
+ metacommon "github.com/apache/answer/internal/service/meta_common"
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/handler"
diff --git a/internal/service/activity/answer_activity_service.go b/internal/service/activity/answer_activity_service.go
index 169e7eb39..48b5f3ef9 100644
--- a/internal/service/activity/answer_activity_service.go
+++ b/internal/service/activity/answer_activity_service.go
@@ -21,6 +21,7 @@ package activity
import (
"context"
+
"github.com/apache/answer/internal/schema"
"github.com/apache/answer/internal/service/activity_type"
"github.com/apache/answer/internal/service/config"
diff --git a/internal/service/badge/badge_award_service.go b/internal/service/badge/badge_award_service.go
index 397a7471a..982c1d1a4 100644
--- a/internal/service/badge/badge_award_service.go
+++ b/internal/service/badge/badge_award_service.go
@@ -21,6 +21,7 @@ package badge
import (
"context"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/service/badge/badge_event_handler.go b/internal/service/badge/badge_event_handler.go
index 219822947..cc161f6ad 100644
--- a/internal/service/badge/badge_event_handler.go
+++ b/internal/service/badge/badge_event_handler.go
@@ -21,6 +21,7 @@ package badge
import (
"context"
+
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/schema"
diff --git a/internal/service/badge/badge_group_service.go b/internal/service/badge/badge_group_service.go
index e0dab6e89..7c220a0be 100644
--- a/internal/service/badge/badge_group_service.go
+++ b/internal/service/badge/badge_group_service.go
@@ -21,6 +21,7 @@ package badge
import (
"context"
+
"github.com/apache/answer/internal/entity"
)
diff --git a/internal/service/badge/badge_service.go b/internal/service/badge/badge_service.go
index 7bc9ffe21..03b8a8774 100644
--- a/internal/service/badge/badge_service.go
+++ b/internal/service/badge/badge_service.go
@@ -21,6 +21,8 @@ package badge
import (
"context"
+ "strings"
+
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/reason"
"github.com/apache/answer/internal/base/translator"
@@ -32,7 +34,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
- "strings"
)
type BadgeRepo interface {
diff --git a/internal/service/content/question_hottest_service.go b/internal/service/content/question_hottest_service.go
index a33b155fb..085b36709 100644
--- a/internal/service/content/question_hottest_service.go
+++ b/internal/service/content/question_hottest_service.go
@@ -21,11 +21,12 @@ package content
import (
"context"
+ "math"
+ "time"
+
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/schema"
"github.com/segmentfault/pacman/log"
- "math"
- "time"
)
func (q *QuestionService) RefreshHottestCron(ctx context.Context) {
diff --git a/internal/service/content/vote_service.go b/internal/service/content/vote_service.go
index ff3ee5974..92f0c9962 100644
--- a/internal/service/content/vote_service.go
+++ b/internal/service/content/vote_service.go
@@ -22,9 +22,10 @@ package content
import (
"context"
"fmt"
- "github.com/apache/answer/internal/service/event_queue"
"strings"
+ "github.com/apache/answer/internal/service/event_queue"
+
"github.com/apache/answer/internal/service/activity_common"
"github.com/apache/answer/internal/base/constant"
diff --git a/internal/service/export/email_service.go b/internal/service/export/email_service.go
index b00ee093b..ddf31b348 100644
--- a/internal/service/export/email_service.go
+++ b/internal/service/export/email_service.go
@@ -23,12 +23,13 @@ import (
"crypto/tls"
"encoding/json"
"fmt"
- "github.com/apache/answer/pkg/display"
"mime"
"os"
"strings"
"time"
+ "github.com/apache/answer/pkg/display"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go
index 9e4f07410..4b3104197 100644
--- a/internal/service/meta/meta_service.go
+++ b/internal/service/meta/meta_service.go
@@ -23,10 +23,11 @@ import (
"context"
"encoding/json"
"errors"
- "github.com/apache/answer/internal/service/event_queue"
"strconv"
"strings"
+ "github.com/apache/answer/internal/service/event_queue"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/reason"
diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go
index 598212aa1..09d871351 100644
--- a/internal/service/notification/notification_service.go
+++ b/internal/service/notification/notification_service.go
@@ -23,6 +23,7 @@ import (
"context"
"encoding/json"
"fmt"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/handler"
diff --git a/internal/service/permission/answer_permission.go b/internal/service/permission/answer_permission.go
index 4eb563a5a..340fca8db 100644
--- a/internal/service/permission/answer_permission.go
+++ b/internal/service/permission/answer_permission.go
@@ -21,6 +21,7 @@ package permission
import (
"context"
+
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/base/handler"
diff --git a/internal/service/permission/question_permission.go b/internal/service/permission/question_permission.go
index b6750beae..eca0a58f2 100644
--- a/internal/service/permission/question_permission.go
+++ b/internal/service/permission/question_permission.go
@@ -21,6 +21,7 @@ package permission
import (
"context"
+
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/base/handler"
diff --git a/internal/service/provider.go b/internal/service/provider.go
index 4b1b64276..65535f41b 100644
--- a/internal/service/provider.go
+++ b/internal/service/provider.go
@@ -40,7 +40,7 @@ import (
"github.com/apache/answer/internal/service/follow"
"github.com/apache/answer/internal/service/importer"
"github.com/apache/answer/internal/service/meta"
- "github.com/apache/answer/internal/service/meta_common"
+ metacommon "github.com/apache/answer/internal/service/meta_common"
"github.com/apache/answer/internal/service/notice_queue"
"github.com/apache/answer/internal/service/notification"
notficationcommon "github.com/apache/answer/internal/service/notification_common"
diff --git a/internal/service/report/report_service.go b/internal/service/report/report_service.go
index 7dcc1d689..d32ccdabf 100644
--- a/internal/service/report/report_service.go
+++ b/internal/service/report/report_service.go
@@ -21,6 +21,7 @@ package report
import (
"encoding/json"
+
"github.com/apache/answer/internal/service/event_queue"
"github.com/apache/answer/internal/base/constant"
diff --git a/internal/service/search_parser/search_parser.go b/internal/service/search_parser/search_parser.go
index e87efaf6f..3e6182e15 100644
--- a/internal/service/search_parser/search_parser.go
+++ b/internal/service/search_parser/search_parser.go
@@ -22,10 +22,11 @@ package search_parser
import (
"context"
"fmt"
- "github.com/apache/answer/internal/base/constant"
"regexp"
"strings"
+ "github.com/apache/answer/internal/base/constant"
+
"github.com/apache/answer/internal/schema"
"github.com/apache/answer/internal/service/tag_common"
usercommon "github.com/apache/answer/internal/service/user_common"
diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go
index 7c54df0aa..01da3ee2f 100644
--- a/internal/service/user_notification_config/user_notification_config_service.go
+++ b/internal/service/user_notification_config/user_notification_config_service.go
@@ -21,6 +21,7 @@ package user_notification_config
import (
"context"
+
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/schema"
diff --git a/pkg/converter/str.go b/pkg/converter/str.go
index 5164609ca..8553975be 100644
--- a/pkg/converter/str.go
+++ b/pkg/converter/str.go
@@ -21,8 +21,9 @@ package converter
import (
"fmt"
- "github.com/segmentfault/pacman/log"
"strconv"
+
+ "github.com/segmentfault/pacman/log"
)
func StringToInt64(str string) int64 {
diff --git a/pkg/day/day_test.go b/pkg/day/day_test.go
index 73e49aca3..4f945d88f 100644
--- a/pkg/day/day_test.go
+++ b/pkg/day/day_test.go
@@ -20,9 +20,10 @@
package day
import (
- "github.com/stretchr/testify/assert"
"testing"
"time"
+
+ "github.com/stretchr/testify/assert"
)
func TestFormat(t *testing.T) {
diff --git a/pkg/gravatar/gravatar_test.go b/pkg/gravatar/gravatar_test.go
index bf504e68f..b88a69649 100644
--- a/pkg/gravatar/gravatar_test.go
+++ b/pkg/gravatar/gravatar_test.go
@@ -20,9 +20,10 @@
package gravatar
import (
- "github.com/apache/answer/internal/base/constant"
"testing"
+ "github.com/apache/answer/internal/base/constant"
+
"github.com/stretchr/testify/assert"
)
From 5e705a124b3ae2d927f8084e545c3809ae70f4a8 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Mon, 1 Dec 2025 12:23:50 +0800
Subject: [PATCH 13/25] refactor(lint): improve error handling and code
consistency across multiple files
---
.golangci.yaml | 13 ++++-
cmd/wire.go | 3 +-
internal/base/conf/conf.go | 4 +-
internal/base/constant/ctx_flag.go | 7 +++
internal/base/data/data.go | 2 +-
internal/base/handler/lang.go | 2 +-
internal/base/handler/short_id.go | 2 +-
internal/base/server/http_funcmap.go | 9 ++--
internal/base/validator/validator.go | 2 +-
internal/cli/build.go | 52 -------------------
internal/cli/config.go | 6 ++-
internal/cli/dump.go | 4 +-
internal/cli/install_check.go | 8 ++-
internal/cli/reset_password.go | 4 +-
internal/controller/template_controller.go | 43 ++++++---------
.../controller/template_render/controller.go | 1 -
internal/controller/user_controller.go | 7 +--
internal/install/install_from_env.go | 3 +-
internal/migrations/migrations.go | 4 +-
internal/migrations/v22.go | 3 ++
internal/migrations/v24.go | 3 --
internal/repo/answer/answer_repo.go | 1 +
.../plugin_config/plugin_user_config_repo.go | 2 +-
internal/repo/repo_test/repo_main_test.go | 2 +-
internal/repo/tag/tag_rel_repo.go | 1 +
internal/service/action/captcha_service.go | 7 ++-
internal/service/action/captcha_strategy.go | 27 +++++-----
internal/service/badge/badge_event_handler.go | 1 -
internal/service/badge/badge_service.go | 26 +++-------
internal/service/content/question_service.go | 22 ++++----
internal/service/content/revision_service.go | 5 +-
internal/service/content/search_service.go | 3 ++
internal/service/content/vote_service.go | 3 --
.../service/dashboard/dashboard_service.go | 8 +--
.../file_record/file_record_service.go | 1 -
internal/service/importer/importer_service.go | 5 +-
internal/service/meta/meta_service.go | 12 +++--
.../invite_answer_notification.go | 2 +-
.../notification/new_answer_notification.go | 2 +-
.../notification/new_comment_notification.go | 2 +-
.../notification/new_question_notification.go | 2 +-
.../notification/notification_service.go | 4 +-
.../notification_common/notification.go | 3 ++
.../service/report_handle/report_handle.go | 6 +++
internal/service/review/review_service.go | 1 -
internal/service/siteinfo/siteinfo_service.go | 4 +-
internal/service/uploader/upload.go | 28 +++++++---
internal/service/user_admin/user_backyard.go | 11 ++--
.../user_notification_config_service.go | 8 +--
pkg/checker/file_type.go | 4 +-
pkg/checker/password.go | 3 +-
pkg/converter/markdown.go | 7 ++-
pkg/htmltext/htmltext.go | 4 +-
plugin/kv_storage.go | 6 +--
plugin/plugin_test/plugin_main_test.go | 2 +-
ui/static.go | 1 -
56 files changed, 194 insertions(+), 214 deletions(-)
diff --git a/.golangci.yaml b/.golangci.yaml
index 263f63f70..611b49bc2 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -17,7 +17,18 @@
version: "2"
linters:
- default: none
+ exclusions:
+ paths:
+ - answer-data
+ - ui
+ - i18n
+ enable:
+ - asasalint # checks for pass []any as any in variadic func(...any)
+ - asciicheck # checks that your code does not contain non-ASCII identifiers
+ - bidichk # checks for dangerous unicode character sequences
+ - bodyclose # checks whether HTTP response body is closed successfully
+ - canonicalheader # checks whether net/http.Header uses canonical header
+ - copyloopvar # detects places where loop variables are copied (Go 1.22+)
formatters:
enable:
diff --git a/cmd/wire.go b/cmd/wire.go
index b25026e5b..3979ecbf5 100644
--- a/cmd/wire.go
+++ b/cmd/wire.go
@@ -1,5 +1,4 @@
//go:build wireinject
-// +build wireinject
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -32,7 +31,7 @@ import (
"github.com/apache/answer/internal/base/server"
"github.com/apache/answer/internal/base/translator"
"github.com/apache/answer/internal/controller"
- "github.com/apache/answer/internal/controller/template_render"
+ templaterender "github.com/apache/answer/internal/controller/template_render"
"github.com/apache/answer/internal/controller_admin"
"github.com/apache/answer/internal/repo"
"github.com/apache/answer/internal/router"
diff --git a/internal/base/conf/conf.go b/internal/base/conf/conf.go
index db83862b0..04e3a19ba 100644
--- a/internal/base/conf/conf.go
+++ b/internal/base/conf/conf.go
@@ -117,7 +117,9 @@ func ReadConfig(configFilePath string) (c *AllConfig, err error) {
func RewriteConfig(configFilePath string, allConfig *AllConfig) error {
buf := bytes.Buffer{}
enc := yaml.NewEncoder(&buf)
- defer enc.Close()
+ defer func() {
+ _ = enc.Close()
+ }()
enc.SetIndent(2)
if err := enc.Encode(allConfig); err != nil {
return err
diff --git a/internal/base/constant/ctx_flag.go b/internal/base/constant/ctx_flag.go
index 2a757fa87..450491bb3 100644
--- a/internal/base/constant/ctx_flag.go
+++ b/internal/base/constant/ctx_flag.go
@@ -23,3 +23,10 @@ const (
AcceptLanguageFlag = "Accept-Language"
ShortIDFlag = "Short-ID-Enabled"
)
+
+type ContextKey string
+
+const (
+ AcceptLanguageContextKey ContextKey = ContextKey(AcceptLanguageFlag)
+ ShortIDContextKey ContextKey = ContextKey(ShortIDFlag)
+)
diff --git a/internal/base/data/data.go b/internal/base/data/data.go
index 1d24d7184..7696d8f56 100644
--- a/internal/base/data/data.go
+++ b/internal/base/data/data.go
@@ -47,7 +47,7 @@ type Data struct {
func NewData(db *xorm.Engine, cache cache.Cache) (*Data, func(), error) {
cleanup := func() {
log.Info("closing the data resources")
- db.Close()
+ _ = db.Close()
}
return &Data{DB: db, Cache: cache}, cleanup, nil
}
diff --git a/internal/base/handler/lang.go b/internal/base/handler/lang.go
index a676e5bc2..4ff1ac7f1 100644
--- a/internal/base/handler/lang.go
+++ b/internal/base/handler/lang.go
@@ -38,7 +38,7 @@ func GetLang(ctx *gin.Context) i18n.Language {
// GetLangByCtx get language from header
func GetLangByCtx(ctx context.Context) i18n.Language {
- acceptLanguage, ok := ctx.Value(constant.AcceptLanguageFlag).(i18n.Language)
+ acceptLanguage, ok := ctx.Value(constant.AcceptLanguageContextKey).(i18n.Language)
if ok {
return acceptLanguage
}
diff --git a/internal/base/handler/short_id.go b/internal/base/handler/short_id.go
index c763bf944..8f9a2a7e5 100644
--- a/internal/base/handler/short_id.go
+++ b/internal/base/handler/short_id.go
@@ -27,7 +27,7 @@ import (
// GetEnableShortID get language from header
func GetEnableShortID(ctx context.Context) bool {
- flag, ok := ctx.Value(constant.ShortIDFlag).(bool)
+ flag, ok := ctx.Value(constant.ShortIDContextKey).(bool)
if ok {
return flag
}
diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go
index 8f6cac5fc..db4604572 100644
--- a/internal/base/server/http_funcmap.go
+++ b/internal/base/server/http_funcmap.go
@@ -21,7 +21,6 @@ package server
import (
"html/template"
- "math"
"regexp"
"strconv"
"strings"
@@ -107,15 +106,15 @@ var funcMap = template.FuncMap{
}
if between >= 60 && between < 3600 {
- min := math.Floor(float64(between / 60))
+ min := between / 60
trans = translator.GlobalTrans.Tr(la, "ui.dates.x_minutes_ago")
- return strings.ReplaceAll(trans, "{{count}}", strconv.FormatFloat(min, 'f', 0, 64))
+ return strings.ReplaceAll(trans, "{{count}}", strconv.FormatInt(min, 10))
}
if between >= 3600 && between < 3600*24 {
- h := math.Floor(float64(between / 3600))
+ h := between / 3600
trans = translator.GlobalTrans.Tr(la, "ui.dates.x_hours_ago")
- return strings.ReplaceAll(trans, "{{count}}", strconv.FormatFloat(h, 'f', 0, 64))
+ return strings.ReplaceAll(trans, "{{count}}", strconv.FormatInt(h, 10))
}
if between >= 3600*24 &&
diff --git a/internal/base/validator/validator.go b/internal/base/validator/validator.go
index 22761c521..9c7f6ec41 100644
--- a/internal/base/validator/validator.go
+++ b/internal/base/validator/validator.go
@@ -142,7 +142,7 @@ func Sanitizer(fl validator.FieldLevel) (res bool) {
switch field.Kind() {
case reflect.String:
filter := bluemonday.UGCPolicy()
- content := strings.Replace(filter.Sanitize(field.String()), "&", "&", -1)
+ content := strings.ReplaceAll(filter.Sanitize(field.String()), "&", "&")
field.SetString(content)
return true
case reflect.Chan, reflect.Map, reflect.Slice, reflect.Array:
diff --git a/internal/cli/build.go b/internal/cli/build.go
index a5a4d938e..efc876e31 100644
--- a/internal/cli/build.go
+++ b/internal/cli/build.go
@@ -34,7 +34,6 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/apache/answer/pkg/dir"
"github.com/apache/answer/pkg/writer"
- "github.com/apache/answer/ui"
"github.com/segmentfault/pacman/log"
"gopkg.in/yaml.v3"
)
@@ -300,50 +299,6 @@ func copyUIFiles(b *buildingMaterial) (err error) {
return nil
}
-// overwriteIndexTs overwrites index.ts file in ui/src/plugins/ dir
-func overwriteIndexTs(b *buildingMaterial) (err error) {
- localUIPluginDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui/src/plugins/")
-
- folders, err := getFolders(localUIPluginDir)
- if err != nil {
- return fmt.Errorf("failed to get folders: %w", err)
- }
-
- content := generateIndexTsContent(folders)
- err = os.WriteFile(filepath.Join(localUIPluginDir, "index.ts"), []byte(content), 0644)
- if err != nil {
- return fmt.Errorf("failed to write index.ts: %w", err)
- }
- return nil
-}
-
-func getFolders(dir string) ([]string, error) {
- var folders []string
- files, err := os.ReadDir(dir)
- if err != nil {
- return nil, err
- }
- for _, file := range files {
- if file.IsDir() && file.Name() != "builtin" {
- folders = append(folders, file.Name())
- }
- }
- return folders, nil
-}
-
-func generateIndexTsContent(folders []string) string {
- builder := &strings.Builder{}
- builder.WriteString("export default null;\n")
- // Line 2:1: Delete `⏎` prettier/prettier
- if len(folders) > 0 {
- builder.WriteString("\n")
- }
- for _, folder := range folders {
- builder.WriteString(fmt.Sprintf("export { default as %s } from '%s';\n", folder, folder))
- }
- return builder.String()
-}
-
// buildUI run pnpm install and pnpm build commands to build ui
func buildUI(b *buildingMaterial) (err error) {
localUIBuildDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui")
@@ -362,13 +317,6 @@ func buildUI(b *buildingMaterial) (err error) {
return nil
}
-func replaceNecessaryFile(b *buildingMaterial) (err error) {
- fmt.Printf("try to replace ui build directory\n")
- uiBuildDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui")
- err = copyDirEntries(ui.Build, ".", uiBuildDir)
- return err
-}
-
// mergeI18nFiles merge i18n files
func mergeI18nFiles(b *buildingMaterial) (err error) {
fmt.Printf("try to merge i18n files\n")
diff --git a/internal/cli/config.go b/internal/cli/config.go
index ecb62a13c..e2445c590 100644
--- a/internal/cli/config.go
+++ b/internal/cli/config.go
@@ -42,7 +42,9 @@ func SetDefaultConfig(dbConf *data.Database, cacheConf *data.CacheConf, field *C
if err != nil {
return err
}
- defer db.Close()
+ defer func() {
+ _ = db.Close()
+ }()
cache, cacheCleanup, err := data.NewCache(cacheConf)
if err != nil {
@@ -50,7 +52,7 @@ func SetDefaultConfig(dbConf *data.Database, cacheConf *data.CacheConf, field *C
}
defer func() {
if cache != nil {
- cache.Flush(context.Background())
+ _ = cache.Flush(context.Background())
cacheCleanup()
}
}()
diff --git a/internal/cli/dump.go b/internal/cli/dump.go
index e5d528212..e63ef1a93 100644
--- a/internal/cli/dump.go
+++ b/internal/cli/dump.go
@@ -34,7 +34,9 @@ func DumpAllData(dataConf *data.Database, dumpDataPath string) error {
if err != nil {
return err
}
- defer db.Close()
+ defer func() {
+ _ = db.Close()
+ }()
if err = db.Ping(); err != nil {
return err
}
diff --git a/internal/cli/install_check.go b/internal/cli/install_check.go
index 9326e069f..c3fadcaba 100644
--- a/internal/cli/install_check.go
+++ b/internal/cli/install_check.go
@@ -43,7 +43,9 @@ func CheckDBConnection(dataConf *data.Database) bool {
fmt.Printf("connection database failed: %s\n", err)
return false
}
- defer db.Close()
+ defer func() {
+ _ = db.Close()
+ }()
if err = db.Ping(); err != nil {
fmt.Printf("connection ping database failed: %s\n", err)
return false
@@ -59,7 +61,9 @@ func CheckDBTableExist(dataConf *data.Database) bool {
fmt.Printf("connection database failed: %s\n", err)
return false
}
- defer db.Close()
+ defer func() {
+ _ = db.Close()
+ }()
if err = db.Ping(); err != nil {
fmt.Printf("connection ping database failed: %s\n", err)
return false
diff --git a/internal/cli/reset_password.go b/internal/cli/reset_password.go
index 2a7d1af4c..dbb3422af 100644
--- a/internal/cli/reset_password.go
+++ b/internal/cli/reset_password.go
@@ -77,7 +77,9 @@ func ResetPassword(ctx context.Context, dataDirPath string, opts *ResetPasswordO
if err != nil {
return fmt.Errorf("connect database failed: %w", err)
}
- defer db.Close()
+ defer func() {
+ _ = db.Close()
+ }()
cache, cacheCleanup, err := data.NewCache(config.Data.Cache)
if err != nil {
diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go
index 83cd58c32..801e129c2 100644
--- a/internal/controller/template_controller.go
+++ b/internal/controller/template_controller.go
@@ -162,11 +162,9 @@ func (tc *TemplateController) Index(ctx *gin.Context) {
siteInfo := tc.SiteInfo(ctx)
siteInfo.Canonical = siteInfo.General.SiteUrl
- UrlUseTitle := false
- if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
- siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID {
- UrlUseTitle = true
- }
+ UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
+ siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
+
siteInfo.Title = ""
tc.html(ctx, http.StatusOK, "question.html", siteInfo, gin.H{
"data": data,
@@ -205,11 +203,9 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) {
siteInfo.Canonical = fmt.Sprintf("%s/questions?page=%d", siteInfo.General.SiteUrl, page)
}
- UrlUseTitle := false
- if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
- siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID {
- UrlUseTitle = true
- }
+ UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
+ siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
+
siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name)
tc.html(ctx, http.StatusOK, "question.html", siteInfo, gin.H{
"data": data,
@@ -371,11 +367,8 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
return
}
- UrlUseTitle := false
- if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
- siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID {
- UrlUseTitle = true
- }
+ UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
+ siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
//related question
userID := middleware.GetLoginUserIDFromContext(ctx)
@@ -434,7 +427,7 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
for _, tag := range detail.Tags {
tags = append(tags, tag.DisplayName)
}
- siteInfo.Keywords = strings.Replace(strings.Trim(fmt.Sprint(tags), "[]"), " ", ",", -1)
+ siteInfo.Keywords = strings.ReplaceAll(strings.Trim(fmt.Sprint(tags), "[]"), " ", ",")
siteInfo.Title = fmt.Sprintf("%s - %s", detail.Title, siteInfo.General.Name)
tc.html(ctx, http.StatusOK, "question-detail.html", siteInfo, gin.H{
"id": id,
@@ -504,11 +497,9 @@ func (tc *TemplateController) TagInfo(ctx *gin.Context) {
}
siteInfo.Keywords = tagInfo.DisplayName
- UrlUseTitle := false
- if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
- siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID {
- UrlUseTitle = true
- }
+ UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
+ siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
+
siteInfo.Title = fmt.Sprintf("'%s' %s - %s", tagInfo.DisplayName, translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name)
tc.html(ctx, http.StatusOK, "tag-detail.html", siteInfo, gin.H{
"tag": tagInfo,
@@ -570,11 +561,9 @@ func (tc *TemplateController) Page404(ctx *gin.Context) {
}
func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteInfo *schema.TemplateSiteInfoResp, data gin.H) {
- var (
- prefix = ""
- cssPath = ""
- scriptPath = make([]string, len(tc.scriptPath))
- )
+ prefix := ""
+ cssPath := ""
+ scriptPath := make([]string, len(tc.scriptPath))
_ = plugin.CallCDN(func(fn plugin.CDN) error {
prefix = fn.GetStaticPrefix()
@@ -612,7 +601,7 @@ func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteI
data["description"] = siteInfo.Description
data["language"] = handler.GetLang(ctx)
data["timezone"] = siteInfo.Interface.TimeZone
- language := strings.Replace(siteInfo.Interface.Language, "_", "-", -1)
+ language := strings.ReplaceAll(siteInfo.Interface.Language, "_", "-")
data["lang"] = language
data["HeadCode"] = siteInfo.CustomCssHtml.CustomHead
data["HeaderCode"] = siteInfo.CustomCssHtml.CustomHeader
diff --git a/internal/controller/template_render/controller.go b/internal/controller/template_render/controller.go
index 5f802fa76..3412010db 100644
--- a/internal/controller/template_render/controller.go
+++ b/internal/controller/template_render/controller.go
@@ -101,7 +101,6 @@ func Paginator(page, pageSize int, nums int64) *schema.Paginator {
case page >= 3 && totalpages > 5:
start := page - 3 + 1
pages = make([]int, 5)
- prevpage = page - 3
for i := range pages {
pages[i] = start + i
}
diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go
index 49b9b23c6..e4a3b3d3b 100644
--- a/internal/controller/user_controller.go
+++ b/internal/controller/user_controller.go
@@ -151,7 +151,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
resp, err := uc.userService.EmailLogin(ctx, req)
if err != nil {
- _, _ = uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, ctx.ClientIP())
+ uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, ctx.ClientIP())
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "e_mail",
ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong),
@@ -404,10 +404,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
}
- _, err := uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEditUserinfo, req.UserID)
- if err != nil {
- log.Error(err)
- }
+ uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEditUserinfo, req.UserID)
}
oldPassVerification, err := uc.userService.UserModifyPassWordVerification(ctx, req)
diff --git a/internal/install/install_from_env.go b/internal/install/install_from_env.go
index c05d2aaba..02bc76381 100644
--- a/internal/install/install_from_env.go
+++ b/internal/install/install_from_env.go
@@ -22,6 +22,7 @@ package install
import (
"bytes"
"encoding/json"
+ "errors"
"fmt"
"net/http"
"net/http/httptest"
@@ -143,7 +144,7 @@ func requestAPI(req any, method, url string, handlerFunc gin.HandlerFunc) error
}
handlerFunc(c)
if w.Code != http.StatusOK {
- return fmt.Errorf(gjson.Get(w.Body.String(), "msg").String())
+ return errors.New(gjson.Get(w.Body.String(), "msg").String())
}
return nil
}
diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go
index 9caa28ed1..2fbfbb7fd 100644
--- a/internal/migrations/migrations.go
+++ b/internal/migrations/migrations.go
@@ -147,7 +147,9 @@ func Migrate(debug bool, dbConf *data.Database, cacheConf *data.CacheConf, upgra
fmt.Println("new database failed: ", err.Error())
return err
}
- defer engine.Close()
+ defer func() {
+ _ = engine.Close()
+ }()
currentDBVersion, err := GetCurrentDBVersion(engine)
if err != nil {
diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go
index e7177deae..5367f5d46 100644
--- a/internal/migrations/v22.go
+++ b/internal/migrations/v22.go
@@ -61,6 +61,9 @@ func addBadges(ctx context.Context, x *xorm.Engine) (err error) {
if exist {
badge.ID = beans.ID
_, err = x.Context(ctx).ID(beans.ID).Update(badge)
+ if err != nil {
+ return fmt.Errorf("update badge failed: %w", err)
+ }
continue
}
badge.ID, err = uniqueIDRepo.GenUniqueIDStr(ctx, new(entity.Badge).TableName())
diff --git a/internal/migrations/v24.go b/internal/migrations/v24.go
index a488679f6..86d624254 100644
--- a/internal/migrations/v24.go
+++ b/internal/migrations/v24.go
@@ -66,8 +66,5 @@ func addQuestionLinkedCount(ctx context.Context, x *xorm.Engine) error {
}
}
- type Question struct {
- LinkedCount int `xorm:"not null default 0 INT(11) linked_count"`
- }
return x.Context(ctx).Sync(new(entity.Question))
}
diff --git a/internal/repo/answer/answer_repo.go b/internal/repo/answer/answer_repo.go
index c5447befc..0f1ae8146 100644
--- a/internal/repo/answer/answer_repo.go
+++ b/internal/repo/answer/answer_repo.go
@@ -503,6 +503,7 @@ func (ar *answerRepo) updateSearch(ctx context.Context, answerID string) (err er
err = st.Find(&tagListList)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return
}
for _, tag := range tagListList {
tags = append(tags, tag.TagID)
diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go
index d14442a56..df5ae29b8 100644
--- a/internal/repo/plugin_config/plugin_user_config_repo.go
+++ b/internal/repo/plugin_config/plugin_user_config_repo.go
@@ -71,7 +71,7 @@ func (ur *pluginUserConfigRepo) SaveUserPluginConfig(ctx context.Context, userID
return nil, nil
})
if err != nil {
- err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
return nil
}
diff --git a/internal/repo/repo_test/repo_main_test.go b/internal/repo/repo_test/repo_main_test.go
index a59ae6269..919ca94e8 100644
--- a/internal/repo/repo_test/repo_main_test.go
+++ b/internal/repo/repo_test/repo_main_test.go
@@ -77,7 +77,7 @@ func TestMain(t *testing.M) {
dbSetting = dbSettingMapping[string(schemas.SQLITE)]
}
if dbSetting.Driver == string(schemas.SQLITE) {
- os.RemoveAll(dbSetting.Connection)
+ _ = os.RemoveAll(dbSetting.Connection)
}
defer func() {
diff --git a/internal/repo/tag/tag_rel_repo.go b/internal/repo/tag/tag_rel_repo.go
index 3634c97a7..a52b1bf54 100644
--- a/internal/repo/tag/tag_rel_repo.go
+++ b/internal/repo/tag/tag_rel_repo.go
@@ -198,6 +198,7 @@ func (tr *tagRelRepo) GetTagRelDefaultStatusByObjectID(ctx context.Context, obje
exist, err := tr.data.DB.Context(ctx).ID(objectID).Cols("show", "status").Get(&question)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return
}
if exist && (question.Show == entity.QuestionHide || question.Status == entity.QuestionStatusDeleted) {
return entity.TagRelStatusHide, nil
diff --git a/internal/service/action/captcha_service.go b/internal/service/action/captcha_service.go
index 04f8b16ac..aefb70519 100644
--- a/internal/service/action/captcha_service.go
+++ b/internal/service/action/captcha_service.go
@@ -106,11 +106,11 @@ func (cs *CaptchaService) ActionRecordVerifyCaptcha(
return pass
}
-func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) (int, error) {
+func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) {
info, err := cs.captchaRepo.GetActionType(ctx, unit, actionType)
if err != nil {
log.Error(err)
- return 0, err
+ return
}
amount := 1
if info != nil {
@@ -118,9 +118,8 @@ func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string
}
err = cs.captchaRepo.SetActionType(ctx, unit, actionType, "", amount)
if err != nil {
- return 0, err
+ log.Error(err)
}
- return amount, nil
}
func (cs *CaptchaService) ActionRecordDel(ctx context.Context, actionType string, unit string) {
diff --git a/internal/service/action/captcha_strategy.go b/internal/service/action/captcha_strategy.go
index 3befda821..b423b583b 100644
--- a/internal/service/action/captcha_strategy.go
+++ b/internal/service/action/captcha_strategy.go
@@ -89,7 +89,9 @@ func (cs *CaptchaService) CaptchaActionPassword(ctx context.Context, unit string
return false
}
if now-actionInfo.LastTime != 0 && now-actionInfo.LastTime > setTime {
- cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionPassword, "", 0)
+ if err := cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionPassword, "", 0); err != nil {
+ log.Error(err)
+ }
}
return true
}
@@ -105,7 +107,9 @@ func (cs *CaptchaService) CaptchaActionEditUserinfo(ctx context.Context, unit st
return false
}
if now-actionInfo.LastTime != 0 && now-actionInfo.LastTime > setTime {
- cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionEditUserinfo, "", 0)
+ if err := cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionEditUserinfo, "", 0); err != nil {
+ log.Error(err)
+ }
}
return true
}
@@ -154,10 +158,7 @@ func (cs *CaptchaService) CaptchaActionEdit(ctx context.Context, unit string, ac
return true
}
setNum := 10
- if actionInfo.Num >= setNum {
- return false
- }
- return true
+ return actionInfo.Num < setNum
}
func (cs *CaptchaService) CaptchaActionInvitationAnswer(ctx context.Context, unit string, actionInfo *entity.ActionRecordInfo) bool {
@@ -165,10 +166,7 @@ func (cs *CaptchaService) CaptchaActionInvitationAnswer(ctx context.Context, uni
return true
}
setNum := 30
- if actionInfo.Num >= setNum {
- return false
- }
- return true
+ return actionInfo.Num < setNum
}
func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string, actionInfo *entity.ActionRecordInfo) bool {
@@ -182,7 +180,9 @@ func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string,
return false
}
if now-actionInfo.LastTime > setTime {
- cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionSearch, "", 0)
+ if err := cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionSearch, "", 0); err != nil {
+ log.Error(err)
+ }
}
return true
}
@@ -218,8 +218,5 @@ func (cs *CaptchaService) CaptchaActionVote(ctx context.Context, unit string, ac
return true
}
setNum := 40
- if actionInfo.Num >= setNum {
- return false
- }
- return true
+ return actionInfo.Num < setNum
}
diff --git a/internal/service/badge/badge_event_handler.go b/internal/service/badge/badge_event_handler.go
index cc161f6ad..24cabf29b 100644
--- a/internal/service/badge/badge_event_handler.go
+++ b/internal/service/badge/badge_event_handler.go
@@ -32,7 +32,6 @@ import (
type BadgeEventService struct {
data *data.Data
eventQueueService event_queue.EventQueueService
- badgeAwardRepo BadgeAwardRepo
badgeRepo BadgeRepo
eventRuleRepo EventRuleRepo
badgeAwardService *BadgeAwardService
diff --git a/internal/service/badge/badge_service.go b/internal/service/badge/badge_service.go
index 03b8a8774..ebb90450a 100644
--- a/internal/service/badge/badge_service.go
+++ b/internal/service/badge/badge_service.go
@@ -206,10 +206,8 @@ func (b *BadgeService) ListPaged(ctx context.Context, req *schema.GetBadgeListPa
resp = make([]*schema.GetBadgeListPagedResp, len(badges))
general, siteErr := b.siteInfoCommonService.GetSiteGeneral(ctx)
- var baseURL = ""
- if siteErr != nil {
- baseURL = ""
- } else {
+ baseURL := ""
+ if siteErr == nil {
baseURL = general.SiteUrl
}
@@ -246,31 +244,23 @@ func (b *BadgeService) searchByName(ctx context.Context, name string) (result []
// GetBadgeInfo get badge info
func (b *BadgeService) GetBadgeInfo(ctx *gin.Context, id string, userID string) (info *schema.GetBadgeInfoResp, err error) {
- var (
- badge *entity.Badge
- earnedTotal int64 = 0
- exists = false
- )
-
- badge, exists, err = b.badgeRepo.GetByID(ctx, id)
+ badge, exists, err := b.badgeRepo.GetByID(ctx, id)
if err != nil {
- return
+ return nil, err
}
if !exists || badge.Status == entity.BadgeStatusInactive {
- err = errors.BadRequest(reason.BadgeObjectNotFound)
- return
+ return nil, errors.BadRequest(reason.BadgeObjectNotFound)
}
+ var earnedTotal int64
if len(userID) > 0 {
earnedTotal = b.badgeAwardRepo.CountByUserIdAndBadgeId(ctx, userID, badge.ID)
}
+ baseURL := ""
general, siteErr := b.siteInfoCommonService.GetSiteGeneral(ctx)
- var baseURL = ""
- if siteErr != nil {
- baseURL = ""
- } else {
+ if siteErr == nil {
baseURL = general.SiteUrl
}
diff --git a/internal/service/content/question_service.go b/internal/service/content/question_service.go
index 1d1d1af39..da15fae5d 100644
--- a/internal/service/content/question_service.go
+++ b/internal/service/content/question_service.go
@@ -277,7 +277,7 @@ func (qs *QuestionService) CheckAddQuestion(ctx context.Context, req *schema.Que
if tagerr != nil {
return errorlist, tagerr
}
- if !req.QuestionPermission.CanUseReservedTag {
+ if !req.CanUseReservedTag {
taglist, err := qs.AddQuestionCheckTags(ctx, Tags)
errMsg := fmt.Sprintf(`"%s" can only be used by moderators.`,
strings.Join(taglist, ","))
@@ -350,7 +350,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
if tagerr != nil {
return questionInfo, tagerr
}
- if !req.QuestionPermission.CanUseReservedTag {
+ if !req.CanUseReservedTag {
taglist, err := qs.AddQuestionCheckTags(ctx, tags)
errMsg := fmt.Sprintf(`"%s" can only be used by moderators.`,
strings.Join(taglist, ","))
@@ -1397,13 +1397,17 @@ func (qs *QuestionService) GetQuestionsByTitle(ctx context.Context, title string
for _, question := range res {
questionIDs = append(questionIDs, question.ID)
}
- questions, err = qs.questionRepo.FindByID(ctx, questionIDs)
+ var questionErr error
+ questions, questionErr = qs.questionRepo.FindByID(ctx, questionIDs)
+ if questionErr != nil {
+ return resp, questionErr
+ }
} else {
- questions, err = qs.questionRepo.GetQuestionsByTitle(ctx, title, 10)
- }
-
- if err != nil {
- return resp, err
+ var questionErr error
+ questions, questionErr = qs.questionRepo.GetQuestionsByTitle(ctx, title, 10)
+ if questionErr != nil {
+ return resp, questionErr
+ }
}
for _, question := range questions {
item := &schema.QuestionBaseInfo{}
@@ -1723,7 +1727,7 @@ func (qs *QuestionService) SitemapCron(ctx context.Context) {
log.Error(err)
return
}
- ctx = context.WithValue(ctx, constant.ShortIDFlag, siteSeo.IsShortLink())
+ ctx = context.WithValue(ctx, constant.ShortIDContextKey, siteSeo.IsShortLink())
qs.questioncommon.SitemapCron(ctx)
}
diff --git a/internal/service/content/revision_service.go b/internal/service/content/revision_service.go
index 1aed4cf82..a5cefeb41 100644
--- a/internal/service/content/revision_service.go
+++ b/internal/service/content/revision_service.go
@@ -41,7 +41,6 @@ import (
"github.com/apache/answer/internal/service/review"
"github.com/apache/answer/internal/service/revision"
"github.com/apache/answer/internal/service/tag_common"
- tagcommon "github.com/apache/answer/internal/service/tag_common"
usercommon "github.com/apache/answer/internal/service/user_common"
"github.com/apache/answer/pkg/converter"
"github.com/apache/answer/pkg/htmltext"
@@ -62,7 +61,7 @@ type RevisionService struct {
questionRepo questioncommon.QuestionRepo
answerRepo answercommon.AnswerRepo
tagRepo tag_common.TagRepo
- tagCommon *tagcommon.TagCommonService
+ tagCommon *tag_common.TagCommonService
notificationQueueService notice_queue.NotificationQueueService
activityQueueService activity_queue.ActivityQueueService
reportRepo report_common.ReportRepo
@@ -79,7 +78,7 @@ func NewRevisionService(
questionRepo questioncommon.QuestionRepo,
answerRepo answercommon.AnswerRepo,
tagRepo tag_common.TagRepo,
- tagCommon *tagcommon.TagCommonService,
+ tagCommon *tag_common.TagCommonService,
notificationQueueService notice_queue.NotificationQueueService,
activityQueueService activity_queue.ActivityQueueService,
reportRepo report_common.ReportRepo,
diff --git a/internal/service/content/search_service.go b/internal/service/content/search_service.go
index 98add0938..ccafcd82c 100644
--- a/internal/service/content/search_service.go
+++ b/internal/service/content/search_service.go
@@ -93,6 +93,9 @@ func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Searc
} else if cond.SearchAnswer() {
res, resp.Total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
}
+ if err != nil {
+ return resp, err
+ }
resp.SearchResults, err = ss.searchRepo.ParseSearchPluginResult(ctx, res, cond.Words)
return resp, err
diff --git a/internal/service/content/vote_service.go b/internal/service/content/vote_service.go
index 92f0c9962..aa6150497 100644
--- a/internal/service/content/vote_service.go
+++ b/internal/service/content/vote_service.go
@@ -26,8 +26,6 @@ import (
"github.com/apache/answer/internal/service/event_queue"
- "github.com/apache/answer/internal/service/activity_common"
-
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/pager"
@@ -64,7 +62,6 @@ type VoteService struct {
answerRepo answercommon.AnswerRepo
commentCommonRepo comment_common.CommentCommonRepo
objectService *object_info.ObjService
- activityRepo activity_common.ActivityRepo
eventQueueService event_queue.EventQueueService
}
diff --git a/internal/service/dashboard/dashboard_service.go b/internal/service/dashboard/dashboard_service.go
index d9198e6db..91f0e338a 100644
--- a/internal/service/dashboard/dashboard_service.go
+++ b/internal/service/dashboard/dashboard_service.go
@@ -274,7 +274,9 @@ func (ds *dashboardService) remoteVersion(ctx context.Context) string {
log.Errorf("request remote version failed: %s", err)
return ""
}
- defer resp.Body.Close()
+ defer func() {
+ _ = resp.Body.Close()
+ }()
respByte, err := io.ReadAll(resp.Body)
if err != nil {
@@ -358,7 +360,7 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) {
if err != nil {
log.Warnf("get db size failed: %s", err)
} else {
- if res != nil && len(res) > 0 && res[0]["db_size"] != nil {
+ if len(res) > 0 && res[0]["db_size"] != nil {
dbSizeStr, _ := res[0]["db_size"].(string)
dbSize = dir.FormatFileSize(converter.StringToInt64(dbSizeStr))
}
@@ -370,7 +372,7 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) {
if err != nil {
log.Warnf("get db size failed: %s", err)
} else {
- if res != nil && len(res) > 0 && res[0]["db_size"] != nil {
+ if len(res) > 0 && res[0]["db_size"] != nil {
dbSizeStr, _ := res[0]["db_size"].(int32)
dbSize = dir.FormatFileSize(int64(dbSizeStr))
}
diff --git a/internal/service/file_record/file_record_service.go b/internal/service/file_record/file_record_service.go
index 29097ba8c..aa526f014 100644
--- a/internal/service/file_record/file_record_service.go
+++ b/internal/service/file_record/file_record_service.go
@@ -174,7 +174,6 @@ func (fs *FileRecordService) PurgeDeletedFiles(ctx context.Context) {
if err != nil {
log.Errorf("create deleted directory error: %v", err)
}
- return
}
func (fs *FileRecordService) DeleteAndMoveFileRecord(ctx context.Context, fileRecord *entity.FileRecord) error {
diff --git a/internal/service/importer/importer_service.go b/internal/service/importer/importer_service.go
index 45aabf39b..c7673ffb5 100644
--- a/internal/service/importer/importer_service.go
+++ b/internal/service/importer/importer_service.go
@@ -62,8 +62,7 @@ type ImporterFunc struct {
}
func (ipfunc *ImporterFunc) AddQuestion(ctx context.Context, questionInfo plugin.QuestionImporterInfo) (err error) {
- ipfunc.importerService.ImportQuestion(ctx, questionInfo)
- return nil
+ return ipfunc.importerService.ImportQuestion(ctx, questionInfo)
}
func (ip *ImporterService) NewImporterFunc() plugin.ImporterFunc {
@@ -84,7 +83,7 @@ func (ip *ImporterService) ImportQuestion(ctx context.Context, questionInfo plug
return err
}
if !exist {
- return fmt.Errorf("User not found")
+ return fmt.Errorf("user not found")
}
// To limit rate, remove the following code from comment: Part 2/2
diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go
index 4b3104197..c1ca7c619 100644
--- a/internal/service/meta/meta_service.go
+++ b/internal/service/meta/meta_service.go
@@ -97,7 +97,8 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda
return nil, err
}
var event *schema.EventMsg
- if objectType == constant.AnswerObjectType {
+ switch objectType {
+ case constant.AnswerObjectType:
answerInfo, exist, err := ms.answerRepo.GetAnswer(ctx, req.ObjectID)
if err != nil {
return nil, err
@@ -107,7 +108,7 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda
}
event = schema.NewEvent(constant.EventAnswerReact, req.UserID).TID(answerInfo.ID).
AID(answerInfo.ID, answerInfo.UserID)
- } else if objectType == constant.QuestionObjectType {
+ case constant.QuestionObjectType:
questionInfo, exist, err := ms.questionRepo.GetQuestion(ctx, req.ObjectID)
if err != nil {
return nil, err
@@ -117,7 +118,7 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda
}
event = schema.NewEvent(constant.EventQuestionReact, req.UserID).TID(questionInfo.ID).
QID(questionInfo.ID, questionInfo.UserID)
- } else {
+ default:
return nil, myErrors.BadRequest(reason.ObjectNotFound)
}
@@ -159,9 +160,10 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda
// updateReaction update reaction
func (ms *MetaService) updateReaction(req *schema.UpdateReactionReq, reactions *schema.ReactionsSummaryMeta) {
- if req.Reaction == "activate" {
+ switch req.Reaction {
+ case "activate":
reactions.AddReactionSummary(req.Emoji, req.UserID)
- } else if req.Reaction == "deactivate" {
+ case "deactivate":
reactions.RemoveReactionSummary(req.Emoji, req.UserID)
}
}
diff --git a/internal/service/notification/invite_answer_notification.go b/internal/service/notification/invite_answer_notification.go
index 4e7c051cd..f68feb067 100644
--- a/internal/service/notification/invite_answer_notification.go
+++ b/internal/service/notification/invite_answer_notification.go
@@ -70,7 +70,7 @@ func (ns *ExternalNotificationService) sendInviteAnswerNotificationEmail(ctx con
// If receiver has set language, use it to send email.
if len(lang) > 0 {
- ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(lang))
+ ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(lang))
}
title, body, err := ns.emailService.NewInviteAnswerTemplate(ctx, rawData)
if err != nil {
diff --git a/internal/service/notification/new_answer_notification.go b/internal/service/notification/new_answer_notification.go
index 91b7e2ae3..c54fd961c 100644
--- a/internal/service/notification/new_answer_notification.go
+++ b/internal/service/notification/new_answer_notification.go
@@ -70,7 +70,7 @@ func (ns *ExternalNotificationService) sendNewAnswerNotificationEmail(ctx contex
// If receiver has set language, use it to send email.
if len(lang) > 0 {
- ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(lang))
+ ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(lang))
}
title, body, err := ns.emailService.NewAnswerTemplate(ctx, rawData)
if err != nil {
diff --git a/internal/service/notification/new_comment_notification.go b/internal/service/notification/new_comment_notification.go
index 3ec99d13c..e622ed4f7 100644
--- a/internal/service/notification/new_comment_notification.go
+++ b/internal/service/notification/new_comment_notification.go
@@ -69,7 +69,7 @@ func (ns *ExternalNotificationService) sendNewCommentNotificationEmail(ctx conte
}
// If receiver has set language, use it to send email.
if len(lang) > 0 {
- ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(lang))
+ ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(lang))
}
title, body, err := ns.emailService.NewCommentTemplate(ctx, rawData)
if err != nil {
diff --git a/internal/service/notification/new_question_notification.go b/internal/service/notification/new_question_notification.go
index 8a12d0b8c..debfb8c27 100644
--- a/internal/service/notification/new_question_notification.go
+++ b/internal/service/notification/new_question_notification.go
@@ -176,7 +176,7 @@ func (ns *ExternalNotificationService) sendNewQuestionNotificationEmail(ctx cont
}
// If receiver has set language, use it to send email.
if len(userInfo.Language) > 0 {
- ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(userInfo.Language))
+ ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(userInfo.Language))
}
title, body, err := ns.emailService.NewQuestionTemplate(ctx, rawData)
if err != nil {
diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go
index 09d871351..0369d4557 100644
--- a/internal/service/notification/notification_service.go
+++ b/internal/service/notification/notification_service.go
@@ -82,8 +82,8 @@ func (ns *NotificationService) GetRedDot(ctx context.Context, req *schema.GetRed
achievementKey := fmt.Sprintf(constant.RedDotCacheKey, constant.NotificationTypeAchievement, req.UserID)
redBot := &schema.RedDot{}
- redBot.Inbox, _, err = ns.data.Cache.GetInt64(ctx, inboxKey)
- redBot.Achievement, _, err = ns.data.Cache.GetInt64(ctx, achievementKey)
+ redBot.Inbox, _, _ = ns.data.Cache.GetInt64(ctx, inboxKey)
+ redBot.Achievement, _, _ = ns.data.Cache.GetInt64(ctx, achievementKey)
// get review amount
if req.CanReviewAnswer || req.CanReviewQuestion || req.CanReviewTag {
diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go
index 2bceb6298..55d638424 100644
--- a/internal/service/notification_common/notification.go
+++ b/internal/service/notification_common/notification.go
@@ -206,6 +206,9 @@ func (ns *NotificationCommon) AddNotification(ctx context.Context, msg *schema.N
}
if req.ObjectInfo.ObjectType == constant.BadgeAwardObjectType {
err = ns.AddBadgeAwardAlertCache(ctx, info.UserID, info.ID, req.ObjectInfo.ObjectMap["badge_id"])
+ if err != nil {
+ log.Error("AddBadgeAwardAlertCache Error", err.Error())
+ }
}
go ns.SendNotificationToAllFollower(ctx, msg, questionID)
diff --git a/internal/service/report_handle/report_handle.go b/internal/service/report_handle/report_handle.go
index 27cffb111..a04681663 100644
--- a/internal/service/report_handle/report_handle.go
+++ b/internal/service/report_handle/report_handle.go
@@ -112,6 +112,9 @@ func (rh *ReportHandle) updateReportedAnswerReport(ctx context.Context, report *
NoNeedReview: true,
})
}
+ if err != nil {
+ return err
+ }
return nil
}
@@ -128,5 +131,8 @@ func (rh *ReportHandle) updateReportedCommentReport(ctx context.Context, report
UserID: req.UserID,
})
}
+ if err != nil {
+ return err
+ }
return nil
}
diff --git a/internal/service/review/review_service.go b/internal/service/review/review_service.go
index 40089fb2d..a23b9ee43 100644
--- a/internal/service/review/review_service.go
+++ b/internal/service/review/review_service.go
@@ -469,7 +469,6 @@ func (cs *ReviewService) notificationCommentOnTheQuestion(ctx context.Context, c
cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID,
objInfo.ObjectCreatorUserID, comment.ID, comment.UserID, htmltext.FetchExcerpt(comment.ParsedText, "...", 240))
}
- return
}
func (cs *ReviewService) notificationCommentReply(ctx context.Context, replyUserID, commentID, commentUserID,
diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go
index cf43d68d5..f355d09f4 100644
--- a/internal/service/siteinfo/siteinfo_service.go
+++ b/internal/service/siteinfo/siteinfo_service.go
@@ -345,7 +345,7 @@ func (s *SiteInfoService) GetPrivilegesConfig(ctx context.Context) (resp *schema
return nil, err
}
privilegeOptions := schema.DefaultPrivilegeOptions
- if privilege.CustomPrivileges != nil && len(privilege.CustomPrivileges) > 0 {
+ if len(privilege.CustomPrivileges) > 0 {
privilegeOptions = append(privilegeOptions, &schema.PrivilegeOption{
Level: schema.PrivilegeLevelCustom,
LevelDesc: reason.PrivilegeLevelCustomDesc,
@@ -358,7 +358,7 @@ func (s *SiteInfoService) GetPrivilegesConfig(ctx context.Context) (resp *schema
Options: s.translatePrivilegeOptions(ctx, privilegeOptions),
SelectedLevel: schema.PrivilegeLevel3,
}
- if privilege != nil && privilege.Level > 0 {
+ if privilege.Level > 0 {
resp.SelectedLevel = privilege.Level
}
return resp, nil
diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go
index 2ae5369df..30029193b 100644
--- a/internal/service/uploader/upload.go
+++ b/internal/service/uploader/upload.go
@@ -119,7 +119,9 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
- file.Close()
+ defer func() {
+ _ = file.Close()
+ }()
fileExt := strings.ToLower(path.Ext(fileHeader.Filename))
if _, ok := plugin.DefaultFileTypeCheckMapping[plugin.UserAvatar][fileExt]; !ok {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
@@ -148,12 +150,12 @@ func (us *uploaderService) AvatarThumbFile(ctx *gin.Context, fileName string, si
thumbFileName := fmt.Sprintf("%d_%d@%s", size, size, fileName)
thumbFilePath := fmt.Sprintf("%s/%s/%s", us.serviceConfig.UploadPath, constant.AvatarThumbSubPath, thumbFileName)
- avatarFile, err := os.ReadFile(thumbFilePath)
+ _, err = os.ReadFile(thumbFilePath)
if err == nil {
return thumbFilePath, nil
}
filePath := fmt.Sprintf("%s/%s/%s", us.serviceConfig.UploadPath, constant.AvatarSubPath, fileName)
- avatarFile, err = os.ReadFile(filePath)
+ avatarFile, err := os.ReadFile(filePath)
if err != nil {
return "", errors.NotFound(reason.UnknownError).WithError(err)
}
@@ -179,7 +181,9 @@ func (us *uploaderService) AvatarThumbFile(ctx *gin.Context, fileName string, si
if err != nil {
return "", errors.InternalServer(reason.UnknownError).WithError(err).WithStack()
}
- defer out.Close()
+ defer func() {
+ _ = out.Close()
+ }()
thumbReader := bytes.NewReader(buf.Bytes())
if _, err = io.Copy(out, thumbReader); err != nil {
@@ -208,7 +212,9 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) (
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
- defer file.Close()
+ defer func() {
+ _ = file.Close()
+ }()
if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteWrite.AuthorizedImageExtensions) {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
@@ -244,7 +250,9 @@ func (us *uploaderService) UploadPostAttachment(ctx *gin.Context, userID string)
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
- defer file.Close()
+ defer func() {
+ _ = file.Close()
+ }()
if checker.IsUnAuthorizedExtension(fileHeader.Filename, resp.AuthorizedAttachmentExtensions) {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
@@ -280,7 +288,9 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) (
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
- file.Close()
+ defer func() {
+ _ = file.Close()
+ }()
fileExt := strings.ToLower(path.Ext(fileHeader.Filename))
if _, ok := plugin.DefaultFileTypeCheckMapping[plugin.AdminBranding][fileExt]; !ok {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
@@ -316,7 +326,9 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil
if err != nil {
return "", errors.InternalServer(reason.UnknownError).WithError(err).WithStack()
}
- defer src.Close()
+ defer func() {
+ _ = src.Close()
+ }()
if !checker.DecodeAndCheckImageFile(filePath, siteWrite.GetMaxImageMegapixel()) {
return "", errors.BadRequest(reason.UploadFileUnsupportedFileFormat)
diff --git a/internal/service/user_admin/user_backyard.go b/internal/service/user_admin/user_backyard.go
index 0f6ec81ed..6fce161ce 100644
--- a/internal/service/user_admin/user_backyard.go
+++ b/internal/service/user_admin/user_backyard.go
@@ -400,7 +400,7 @@ func (us *UserAdminService) EditUserProfile(ctx context.Context, req *schema.Edi
if req.UserID == req.LoginUserID {
return nil, errors.BadRequest(reason.AdminCannotEditTheirProfile)
}
- userInfo, exist, err := us.userRepo.GetUserInfo(ctx, req.UserID)
+ _, exist, err := us.userRepo.GetUserInfo(ctx, req.UserID)
if err != nil {
return nil, err
}
@@ -415,7 +415,7 @@ func (us *UserAdminService) EditUserProfile(ctx context.Context, req *schema.Edi
}), errors.BadRequest(reason.UsernameInvalid)
}
- userInfo, exist, err = us.userCommonService.GetByUsername(ctx, req.Username)
+ userInfo, exist, err := us.userCommonService.GetByUsername(ctx, req.Username)
if err != nil {
return nil, err
}
@@ -620,11 +620,12 @@ func (us *UserAdminService) SendUserActivation(ctx context.Context, req *schema.
}
func (us *UserAdminService) DeletePermanently(ctx context.Context, req *schema.DeletePermanentlyReq) (err error) {
- if req.Type == constant.DeletePermanentlyUsers {
+ switch req.Type {
+ case constant.DeletePermanentlyUsers:
return us.userRepo.DeletePermanentlyUsers(ctx)
- } else if req.Type == constant.DeletePermanentlyQuestions {
+ case constant.DeletePermanentlyQuestions:
return us.questionCommonRepo.DeletePermanentlyQuestions(ctx)
- } else if req.Type == constant.DeletePermanentlyAnswers {
+ case constant.DeletePermanentlyAnswers:
return us.answerCommonRepo.DeletePermanentlyAnswers(ctx)
}
diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go
index 01da3ee2f..c40df55cf 100644
--- a/internal/service/user_notification_config/user_notification_config_service.go
+++ b/internal/service/user_notification_config/user_notification_config_service.go
@@ -68,21 +68,21 @@ func (us *UserNotificationConfigService) GetUserNotificationConfig(ctx context.C
func (us *UserNotificationConfigService) UpdateUserNotificationConfig(
ctx context.Context, req *schema.UpdateUserNotificationConfigReq) (err error) {
- req.NotificationConfig.Format()
+ req.Format()
err = us.userNotificationConfigRepo.Save(ctx,
- us.convertToEntity(ctx, req.UserID, constant.InboxSource, req.NotificationConfig.Inbox))
+ us.convertToEntity(ctx, req.UserID, constant.InboxSource, req.Inbox))
if err != nil {
return err
}
err = us.userNotificationConfigRepo.Save(ctx,
- us.convertToEntity(ctx, req.UserID, constant.AllNewQuestionSource, req.NotificationConfig.AllNewQuestion))
+ us.convertToEntity(ctx, req.UserID, constant.AllNewQuestionSource, req.AllNewQuestion))
if err != nil {
return err
}
err = us.userNotificationConfigRepo.Save(ctx,
us.convertToEntity(ctx, req.UserID, constant.AllNewQuestionForFollowingTagsSource,
- req.NotificationConfig.AllNewQuestionForFollowingTags))
+ req.AllNewQuestionForFollowingTags))
if err != nil {
return err
}
diff --git a/pkg/checker/file_type.go b/pkg/checker/file_type.go
index 51f687d6c..ac1fbcaf9 100644
--- a/pkg/checker/file_type.go
+++ b/pkg/checker/file_type.go
@@ -75,7 +75,9 @@ func decodeAndCheckImageFile(localFilePath string, maxImageMegapixel int, checke
log.Errorf("open file error: %v", err)
return false
}
- defer file.Close()
+ defer func() {
+ _ = file.Close()
+ }()
if err = checker(file, maxImageMegapixel); err != nil {
log.Errorf("check image format error: %v", err)
diff --git a/pkg/checker/password.go b/pkg/checker/password.go
index ac274f352..ac99fd433 100644
--- a/pkg/checker/password.go
+++ b/pkg/checker/password.go
@@ -20,6 +20,7 @@
package checker
import (
+ "errors"
"fmt"
"regexp"
"strings"
@@ -40,7 +41,7 @@ const (
// CheckPassword checks the password strength
func CheckPassword(password string) error {
if strings.Contains(password, " ") {
- return fmt.Errorf(PasswordCannotContainSpaces)
+ return errors.New(PasswordCannotContainSpaces)
}
// TODO Currently there is no requirement for password strength
diff --git a/pkg/converter/markdown.go b/pkg/converter/markdown.go
index 1789a32cd..d16915a84 100644
--- a/pkg/converter/markdown.go
+++ b/pkg/converter/markdown.go
@@ -32,7 +32,6 @@ import (
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
goldmarkHTML "github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/util"
)
@@ -141,7 +140,7 @@ func (r *DangerousHTMLRenderer) renderLink(w util.BufWriter, source []byte, node
if entering && r.renderLinkIsUrl(string(n.Destination)) {
_, _ = w.WriteString("')
} else {
@@ -175,7 +174,7 @@ func (r *DangerousHTMLRenderer) renderAutoLink(w util.BufWriter, source []byte,
_, _ = w.Write(util.EscapeHTML(util.URLEscape(url, false)))
if n.Attributes() != nil {
_ = w.WriteByte('"')
- html.RenderAttributes(w, n, html.LinkAttributeFilter)
+ goldmarkHTML.RenderAttributes(w, n, goldmarkHTML.LinkAttributeFilter)
_ = w.WriteByte('>')
} else {
_, _ = w.WriteString(`">`)
diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go
index 707c20a80..56db4d2b2 100644
--- a/pkg/htmltext/htmltext.go
+++ b/pkg/htmltext/htmltext.go
@@ -194,7 +194,9 @@ func GetPicByUrl(Url string) string {
if err != nil {
return ""
}
- defer res.Body.Close()
+ defer func() {
+ _ = res.Body.Close()
+ }()
pix, err := io.ReadAll(res.Body)
if err != nil {
return ""
diff --git a/plugin/kv_storage.go b/plugin/kv_storage.go
index d1ed3eaa6..204e5ee68 100644
--- a/plugin/kv_storage.go
+++ b/plugin/kv_storage.go
@@ -88,7 +88,7 @@ func (kv *KVOperator) getSession(ctx context.Context) (*xorm.Session, func()) {
session = kv.data.DB.NewSession().Context(ctx)
cleanup = func() {
if session != nil {
- session.Close()
+ _ = session.Close()
}
}
}
@@ -281,7 +281,7 @@ func (kv *KVOperator) Tx(ctx context.Context, fn func(ctx context.Context, kv *K
if kv.session == nil {
session := kv.data.DB.NewSession().Context(ctx)
if err := session.Begin(); err != nil {
- session.Close()
+ _ = session.Close()
return fmt.Errorf("%w: begin transaction failed: %v", ErrKVTransactionFailed, err)
}
@@ -291,7 +291,7 @@ func (kv *KVOperator) Tx(ctx context.Context, fn func(ctx context.Context, kv *K
log.Errorf("rollback failed: %v", rollbackErr)
}
}
- session.Close()
+ _ = session.Close()
}()
txKv = &KVOperator{
diff --git a/plugin/plugin_test/plugin_main_test.go b/plugin/plugin_test/plugin_main_test.go
index add11460b..fd9015c86 100644
--- a/plugin/plugin_test/plugin_main_test.go
+++ b/plugin/plugin_test/plugin_main_test.go
@@ -78,7 +78,7 @@ func TestMain(t *testing.M) {
dbSetting = dbSettingMapping[string(schemas.SQLITE)]
}
if dbSetting.Driver == string(schemas.SQLITE) {
- os.RemoveAll(dbSetting.Connection)
+ _ = os.RemoveAll(dbSetting.Connection)
}
defer func() {
diff --git a/ui/static.go b/ui/static.go
index dc79a1785..65caae461 100644
--- a/ui/static.go
+++ b/ui/static.go
@@ -21,7 +21,6 @@ package ui
import (
"embed"
- _ "embed"
)
//go:embed build
From 670aa323254ca8f2a5d3927353afb83b7724e424 Mon Sep 17 00:00:00 2001
From: ferhat elmas
Date: Mon, 1 Dec 2025 21:22:18 +0100
Subject: [PATCH 14/25] refactor(lint): add new linters and fix their issues
* gocritic
* misspell
* modernize (aside, bumping go would be nice)
* testifylint
* unconvert
* unparam
* whitespace
related to #1432
Signed-off-by: ferhat elmas
---
.golangci.yaml | 7 +++
i18n/cs_CZ.yaml | 2 +-
i18n/cy_GB.yaml | 2 +-
i18n/da_DK.yaml | 2 +-
i18n/de_DE.yaml | 2 +-
i18n/en_US.yaml | 2 +-
i18n/es_ES.yaml | 2 +-
i18n/fa_IR.yaml | 2 +-
i18n/fr_FR.yaml | 2 +-
i18n/hi_IN.yaml | 2 +-
i18n/id_ID.yaml | 2 +-
i18n/it_IT.yaml | 2 +-
i18n/ja_JP.yaml | 2 +-
i18n/ko_KR.yaml | 2 +-
i18n/ml_IN.yaml | 2 +-
i18n/pl_PL.yaml | 2 +-
i18n/pt_PT.yaml | 2 +-
i18n/ro_RO.yaml | 2 +-
i18n/ru_RU.yaml | 2 +-
i18n/sk_SK.yaml | 2 +-
i18n/sv_SE.yaml | 10 ++--
i18n/te_IN.yaml | 2 +-
i18n/tr_TR.yaml | 2 +-
i18n/uk_UA.yaml | 2 +-
i18n/vi_VN.yaml | 2 +-
i18n/zh_CN.yaml | 2 +-
i18n/zh_TW.yaml | 2 +-
internal/base/middleware/avatar.go | 1 -
internal/base/reason/reason.go | 2 +-
internal/base/server/http.go | 1 -
internal/base/server/http_funcmap.go | 4 +-
internal/controller/question_controller.go | 3 +-
internal/controller/template_controller.go | 8 +--
.../controller/template_render/comment.go | 1 -
.../controller/template_render/controller.go | 10 ++--
internal/controller/user_controller.go | 1 -
internal/entity/collection_entity.go | 4 +-
internal/install/install_req.go | 9 +--
internal/migrations/v12.go | 1 -
internal/migrations/v13.go | 4 +-
internal/repo/activity/follow_repo.go | 2 +-
internal/repo/activity_common/follow.go | 6 +-
internal/repo/answer/answer_repo.go | 2 +-
internal/repo/collection/collection_repo.go | 4 +-
internal/repo/question/question_repo.go | 8 +--
internal/repo/rank/user_rank_repo.go | 2 +-
internal/repo/repo_test/auth_test.go | 31 +++++-----
internal/repo/repo_test/captcha_test.go | 11 ++--
internal/repo/repo_test/comment_repo_test.go | 27 ++++-----
internal/repo/repo_test/email_repo_test.go | 5 +-
internal/repo/repo_test/meta_repo_test.go | 31 +++++-----
.../repo/repo_test/notification_repo_test.go | 33 ++++++-----
internal/repo/repo_test/reason_repo_test.go | 5 +-
internal/repo/repo_test/recommend_test.go | 27 ++++-----
internal/repo/repo_test/repo_main_test.go | 2 +-
internal/repo/repo_test/revision_repo_test.go | 17 +++---
internal/repo/repo_test/siteinfo_repo_test.go | 9 +--
internal/repo/repo_test/tag_rel_repo_test.go | 25 ++++----
internal/repo/repo_test/tag_repo_test.go | 33 ++++++-----
.../repo/repo_test/user_backyard_repo_test.go | 15 ++---
internal/repo/repo_test/user_repo_test.go | 35 +++++------
internal/repo/search_common/search_repo.go | 4 +-
internal/schema/backyard_user_schema.go | 2 +-
internal/schema/meta_schema.go | 16 ++---
internal/schema/notification_schema.go | 6 +-
internal/schema/revision_schema.go | 2 +-
internal/schema/siteinfo_schema.go | 2 +-
internal/schema/tag_schema.go | 2 +-
internal/service/action/captcha_strategy.go | 21 ++++---
internal/service/auth/auth.go | 2 +-
internal/service/comment/comment_service.go | 15 +++--
internal/service/content/answer_service.go | 13 ++---
.../content/question_hottest_service.go | 1 -
internal/service/content/question_service.go | 58 ++++++++-----------
internal/service/content/revision_service.go | 1 -
internal/service/content/search_service.go | 14 +++--
internal/service/content/user_service.go | 7 +--
.../service/dashboard/dashboard_service.go | 18 +++---
.../invite_answer_notification.go | 3 +-
.../notification/new_answer_notification.go | 3 +-
.../notification/new_comment_notification.go | 3 +-
.../notification/new_question_notification.go | 3 +-
.../notification/notification_service.go | 13 ++---
.../notification_common/notification.go | 2 +-
.../plugin_common/plugin_common_service.go | 1 -
internal/service/question_common/question.go | 11 ++--
.../siteinfo_common/siteinfo_service_test.go | 5 +-
internal/service/tag/tag_service.go | 4 +-
internal/service/tag_common/tag_common.go | 8 +--
internal/service/uploader/upload.go | 2 -
internal/service/user_admin/user_backyard.go | 23 ++++----
internal/service/user_common/user.go | 4 +-
.../user_notification_config_service.go | 2 +-
pkg/checker/file_type.go | 8 +--
pkg/checker/path_ignore.go | 15 +----
pkg/checker/question_link.go | 11 ++--
pkg/converter/markdown.go | 18 +++---
pkg/day/day.go | 7 ++-
pkg/dir/dir.go | 16 ++---
pkg/htmltext/htmltext.go | 14 ++---
pkg/htmltext/htmltext_test.go | 4 +-
plugin/plugin_test/plugin_main_test.go | 13 ++---
102 files changed, 392 insertions(+), 431 deletions(-)
diff --git a/.golangci.yaml b/.golangci.yaml
index 611b49bc2..09fca51c5 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -29,6 +29,13 @@ linters:
- bodyclose # checks whether HTTP response body is closed successfully
- canonicalheader # checks whether net/http.Header uses canonical header
- copyloopvar # detects places where loop variables are copied (Go 1.22+)
+ - gocritic # provides diagnostics that check for bugs, performance and style issues
+ - misspell # finds commonly misspelled English words in comments and strings
+ - modernize # detects code that can be modernized to use newer Go features
+ - testifylint # checks usage of github.com/stretchr/testify
+ - unconvert # removes unnecessary type conversions
+ - unparam # reports unused function parameters
+ - whitespace # detects leading and trailing whitespace
formatters:
enable:
diff --git a/i18n/cs_CZ.yaml b/i18n/cs_CZ.yaml
index d9f972a63..ab53cb635 100644
--- a/i18n/cs_CZ.yaml
+++ b/i18n/cs_CZ.yaml
@@ -234,7 +234,7 @@ backend:
other: Nemáte oprávnění pro aktualizaci.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/cy_GB.yaml b/i18n/cy_GB.yaml
index 267070a08..5a5b9a654 100644
--- a/i18n/cy_GB.yaml
+++ b/i18n/cy_GB.yaml
@@ -234,7 +234,7 @@ backend:
other: Dim caniatâd i ddiweddaru.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/da_DK.yaml b/i18n/da_DK.yaml
index d3f410e45..37adc7db0 100644
--- a/i18n/da_DK.yaml
+++ b/i18n/da_DK.yaml
@@ -234,7 +234,7 @@ backend:
other: Ingen tilladelse til at opdatere.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/de_DE.yaml b/i18n/de_DE.yaml
index d7683f03b..542dca9b8 100644
--- a/i18n/de_DE.yaml
+++ b/i18n/de_DE.yaml
@@ -234,7 +234,7 @@ backend:
other: Keine Berechtigung zum Aktualisieren.
content_cannot_empty:
other: Der Inhalt darf nicht leer sein.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml
index 40017b75a..6ff6ef3c6 100644
--- a/i18n/en_US.yaml
+++ b/i18n/en_US.yaml
@@ -235,7 +235,7 @@ backend:
other: No permission to update.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/es_ES.yaml b/i18n/es_ES.yaml
index 99071e2fe..f53a2810c 100644
--- a/i18n/es_ES.yaml
+++ b/i18n/es_ES.yaml
@@ -234,7 +234,7 @@ backend:
other: Sin permiso para actualizar.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/fa_IR.yaml b/i18n/fa_IR.yaml
index 600d5cc11..d013d0172 100644
--- a/i18n/fa_IR.yaml
+++ b/i18n/fa_IR.yaml
@@ -234,7 +234,7 @@ backend:
other: اجازه بروزرسانی ندارید.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/fr_FR.yaml b/i18n/fr_FR.yaml
index ecb87bef1..879906fa5 100644
--- a/i18n/fr_FR.yaml
+++ b/i18n/fr_FR.yaml
@@ -234,7 +234,7 @@ backend:
other: Pas de permission pour mettre à jour.
content_cannot_empty:
other: Le contenu ne peut pas être vide.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/hi_IN.yaml b/i18n/hi_IN.yaml
index 09be62019..eb0cb50bd 100644
--- a/i18n/hi_IN.yaml
+++ b/i18n/hi_IN.yaml
@@ -234,7 +234,7 @@ backend:
other: No permission to update.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/id_ID.yaml b/i18n/id_ID.yaml
index f8a4a8a88..43c0d70d1 100644
--- a/i18n/id_ID.yaml
+++ b/i18n/id_ID.yaml
@@ -234,7 +234,7 @@ backend:
other: Tidak diizinkan untuk memperbarui.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/it_IT.yaml b/i18n/it_IT.yaml
index 29cd1f521..50f60aa6a 100644
--- a/i18n/it_IT.yaml
+++ b/i18n/it_IT.yaml
@@ -234,7 +234,7 @@ backend:
other: Nessun permesso per l'aggiornamento.
content_cannot_empty:
other: Il contenuto non può essere vuoto.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/ja_JP.yaml b/i18n/ja_JP.yaml
index 8e2fb52c3..4bfe45c97 100644
--- a/i18n/ja_JP.yaml
+++ b/i18n/ja_JP.yaml
@@ -234,7 +234,7 @@ backend:
other: 更新する権限がありません。
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/ko_KR.yaml b/i18n/ko_KR.yaml
index be1807457..0ddefa61f 100644
--- a/i18n/ko_KR.yaml
+++ b/i18n/ko_KR.yaml
@@ -234,7 +234,7 @@ backend:
other: 업데이트 권한이 없습니다.
content_cannot_empty:
other: 내용은 비워둘 수 없습니다.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/ml_IN.yaml b/i18n/ml_IN.yaml
index 421350311..e2cac0e0b 100644
--- a/i18n/ml_IN.yaml
+++ b/i18n/ml_IN.yaml
@@ -234,7 +234,7 @@ backend:
other: No permission to update.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml
index ae26c6d1a..e5972d9b3 100644
--- a/i18n/pl_PL.yaml
+++ b/i18n/pl_PL.yaml
@@ -234,7 +234,7 @@ backend:
other: Brak uprawnień do edycji.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/pt_PT.yaml b/i18n/pt_PT.yaml
index 997bb0552..5989071e8 100644
--- a/i18n/pt_PT.yaml
+++ b/i18n/pt_PT.yaml
@@ -234,7 +234,7 @@ backend:
other: Sem permissão para atualizar.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/ro_RO.yaml b/i18n/ro_RO.yaml
index cd0afb8a3..43af2180b 100644
--- a/i18n/ro_RO.yaml
+++ b/i18n/ro_RO.yaml
@@ -234,7 +234,7 @@ backend:
other: Nu aveți permisiunea de a actualiza.
content_cannot_empty:
other: Conținutul nu poate fi gol.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/ru_RU.yaml b/i18n/ru_RU.yaml
index c554ac8d7..458fd2e66 100644
--- a/i18n/ru_RU.yaml
+++ b/i18n/ru_RU.yaml
@@ -234,7 +234,7 @@ backend:
other: Нет разрешения на обновление.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/sk_SK.yaml b/i18n/sk_SK.yaml
index 72bd4726e..cd629fc94 100644
--- a/i18n/sk_SK.yaml
+++ b/i18n/sk_SK.yaml
@@ -234,7 +234,7 @@ backend:
other: Žiadne povolenie na aktualizáciu.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/sv_SE.yaml b/i18n/sv_SE.yaml
index 243703ce0..abf58112d 100644
--- a/i18n/sv_SE.yaml
+++ b/i18n/sv_SE.yaml
@@ -162,7 +162,7 @@ backend:
cannot_modify_self_status:
other: Du får inte ändra din status.
email_or_password_wrong:
- other: Fel e-post eller lösenord.
+ other: Fel e-post eller lösenord.
answer:
not_found:
other: Svar hittades inte.
@@ -189,12 +189,12 @@ backend:
need_to_be_verified:
other: E-postadressen ska vara verifierad.
verify_url_expired:
- other: Länken för att verifiera e-postadressen har gått ut. Vänligen skicka igen.
+ other: Länken för att verifiera e-postadressen har gått ut. Vänligen skicka igen.
illegal_email_domain_error:
- other: E-post från den domänen tillåts inte. Vänligen använt en annan.
+ other: E-post från den domänen tillåts inte. Vänligen använt en annan.
lang:
not_found:
- other: Språkfilen hittas inte.
+ other: Språkfilen hittas inte.
object:
captcha_verification_failed:
other: Fel Captcha.
@@ -234,7 +234,7 @@ backend:
other: No permission to update.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/te_IN.yaml b/i18n/te_IN.yaml
index dbf4acb14..9e80aa8d8 100644
--- a/i18n/te_IN.yaml
+++ b/i18n/te_IN.yaml
@@ -234,7 +234,7 @@ backend:
other: No permission to update.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml
index fdecee532..92d97ebe2 100644
--- a/i18n/tr_TR.yaml
+++ b/i18n/tr_TR.yaml
@@ -234,7 +234,7 @@ backend:
other: Güncelleme izni yok.
content_cannot_empty:
other: İçerik boş olamaz.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/uk_UA.yaml b/i18n/uk_UA.yaml
index ea0e4591c..67496262a 100644
--- a/i18n/uk_UA.yaml
+++ b/i18n/uk_UA.yaml
@@ -234,7 +234,7 @@ backend:
other: Немає дозволу на оновлення.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/vi_VN.yaml b/i18n/vi_VN.yaml
index 6f5e5cbbb..af01b1da4 100644
--- a/i18n/vi_VN.yaml
+++ b/i18n/vi_VN.yaml
@@ -234,7 +234,7 @@ backend:
other: Không có quyền cập nhật.
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml
index 0f7a25154..35321ac1f 100644
--- a/i18n/zh_CN.yaml
+++ b/i18n/zh_CN.yaml
@@ -234,7 +234,7 @@ backend:
other: 没有更新权限。
content_cannot_empty:
other: 内容不能为空。
- content_less_than_minumum:
+ content_less_than_minimum:
other: 输入的内容不足。
rank:
fail_to_meet_the_condition:
diff --git a/i18n/zh_TW.yaml b/i18n/zh_TW.yaml
index cc362ea1e..4b239c1e1 100644
--- a/i18n/zh_TW.yaml
+++ b/i18n/zh_TW.yaml
@@ -234,7 +234,7 @@ backend:
other: 無更新權限。
content_cannot_empty:
other: Content cannot be empty.
- content_less_than_minumum:
+ content_less_than_minimum:
other: Not enough content entered.
rank:
fail_to_meet_the_condition:
diff --git a/internal/base/middleware/avatar.go b/internal/base/middleware/avatar.go
index 98430638b..42b28da99 100644
--- a/internal/base/middleware/avatar.go
+++ b/internal/base/middleware/avatar.go
@@ -80,7 +80,6 @@ func (am *AvatarMiddleware) AvatarThumb() gin.HandlerFunc {
}
ctx.Abort()
return
-
} else {
urlInfo, err := url.Parse(uri)
if err != nil {
diff --git a/internal/base/reason/reason.go b/internal/base/reason/reason.go
index 42e29f4c5..97aaa75a9 100644
--- a/internal/base/reason/reason.go
+++ b/internal/base/reason/reason.go
@@ -47,7 +47,7 @@ const (
QuestionAlreadyDeleted = "error.question.already_deleted"
QuestionUnderReview = "error.question.under_review"
QuestionContentCannotEmpty = "error.question.content_cannot_empty"
- QuestionContentLessThanMinimum = "error.question.content_less_than_minumum"
+ QuestionContentLessThanMinimum = "error.question.content_less_than_minimum"
AnswerNotFound = "error.answer.not_found"
AnswerCannotDeleted = "error.answer.cannot_deleted"
AnswerCannotUpdate = "error.answer.cannot_update"
diff --git a/internal/base/server/http.go b/internal/base/server/http.go
index 088bbc9e4..4fbb04cb2 100644
--- a/internal/base/server/http.go
+++ b/internal/base/server/http.go
@@ -44,7 +44,6 @@ func NewHTTPServer(debug bool,
pluginAPIRouter *router.PluginAPIRouter,
uiConf *UI,
) *gin.Engine {
-
if debug {
gin.SetMode(gin.DebugMode)
} else {
diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go
index db4604572..a5d530b50 100644
--- a/internal/base/server/http_funcmap.go
+++ b/internal/base/server/http_funcmap.go
@@ -134,9 +134,7 @@ var funcMap = template.FuncMap{
"timezone": tz,
}
},
- "urlTitle": func(title string) string {
- return htmltext.UrlTitle(title)
- },
+ "urlTitle": htmltext.UrlTitle,
}
func FormatLinkNofollow(html string) string {
diff --git a/internal/controller/question_controller.go b/internal/controller/question_controller.go
index 4b1869fa7..581cf548b 100644
--- a/internal/controller/question_controller.go
+++ b/internal/controller/question_controller.go
@@ -287,7 +287,6 @@ func (qc *QuestionController) GetQuestionInviteUserInfo(ctx *gin.Context) {
questionID := uid.DeShortID(ctx.Query("id"))
resp, err := qc.questionService.InviteUserInfo(ctx, questionID)
handler.HandleResponse(ctx, err, resp)
-
}
// SimilarQuestion godoc
@@ -578,7 +577,7 @@ func (qc *QuestionController) AddQuestionByAnswer(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.BadRequest(reason.RequestFormatError), errFields)
return
}
- //add the question id to the answer
+ // add the question id to the answer
questionInfo, ok := resp.(*schema.QuestionInfoResp)
if ok {
answerReq := &schema.AnswerAddReq{}
diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go
index 801e129c2..f6a442c21 100644
--- a/internal/controller/template_controller.go
+++ b/internal/controller/template_controller.go
@@ -263,14 +263,13 @@ func (tc *TemplateController) QuestionInfoRedirect(ctx *gin.Context, siteInfo *s
if needChangeShortID {
return true, url
}
- //not have title
+ // not have title
if titleIsAnswerID || len(title) == 0 {
return false, ""
}
return true, url
} else {
-
detail, err := tc.templateRenderController.QuestionDetail(ctx, questionID)
if err != nil {
tc.Page404(ctx)
@@ -284,7 +283,7 @@ func (tc *TemplateController) QuestionInfoRedirect(ctx *gin.Context, siteInfo *s
if len(ctx.Request.URL.Query()) > 0 {
url = fmt.Sprintf("%s?%s", url, ctx.Request.URL.RawQuery)
}
- //have title
+ // have title
if len(title) > 0 && !titleIsAnswerID && correctTitle {
if needChangeShortID {
return true, url
@@ -370,7 +369,7 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
- //related question
+ // related question
userID := middleware.GetLoginUserIDFromContext(ctx)
relatedQuestion, _, _ := tc.questionService.SimilarQuestion(ctx, id, userID)
@@ -553,7 +552,6 @@ func (tc *TemplateController) UserInfo(ctx *gin.Context) {
"topQuestions": questionList,
"topAnswers": answerList,
})
-
}
func (tc *TemplateController) Page404(ctx *gin.Context) {
diff --git a/internal/controller/template_render/comment.go b/internal/controller/template_render/comment.go
index 2862ad8dd..c1265bd05 100644
--- a/internal/controller/template_render/comment.go
+++ b/internal/controller/template_render/comment.go
@@ -33,7 +33,6 @@ func (t *TemplateRenderController) CommentList(
comments map[string][]*schema.GetCommentResp,
err error,
) {
-
comments = make(map[string][]*schema.GetCommentResp, len(objectIDs))
for _, objectID := range objectIDs {
diff --git a/internal/controller/template_render/controller.go b/internal/controller/template_render/controller.go
index 3412010db..297b3f9a6 100644
--- a/internal/controller/template_render/controller.go
+++ b/internal/controller/template_render/controller.go
@@ -78,10 +78,10 @@ func Paginator(page, pageSize int, nums int64) *schema.Paginator {
pageSize = 10
}
- var prevpage int //Previous page address
- var nextpage int //Address on the last page
- //Generate the total number of pages based on the total number of nums and the number of prepage pages
- totalpages := int(math.Ceil(float64(nums) / float64(pageSize))) //Total number of Pages
+ var prevpage int // Previous page address
+ var nextpage int // Address on the last page
+ // Generate the total number of pages based on the total number of nums and the number of prepage pages
+ totalpages := int(math.Ceil(float64(nums) / float64(pageSize))) // Total number of Pages
if page > totalpages {
page = totalpages
}
@@ -90,7 +90,7 @@ func Paginator(page, pageSize int, nums int64) *schema.Paginator {
}
var pages []int
switch {
- case page >= totalpages-5 && totalpages > 5: //The last 5 pages
+ case page >= totalpages-5 && totalpages > 5: // The last 5 pages
start := totalpages - 5 + 1
prevpage = page - 1
nextpage = int(math.Min(float64(totalpages), float64(page+1)))
diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go
index e4a3b3d3b..cc89caf1a 100644
--- a/internal/controller/user_controller.go
+++ b/internal/controller/user_controller.go
@@ -509,7 +509,6 @@ func (uc *UserController) ActionRecord(ctx *gin.Context) {
resp, err := uc.actionService.ActionRecord(ctx, req)
handler.HandleResponse(ctx, err, resp)
}
-
}
// GetUserNotificationConfig get user's notification config
diff --git a/internal/entity/collection_entity.go b/internal/entity/collection_entity.go
index 5fbd5b0eb..24ae232f4 100644
--- a/internal/entity/collection_entity.go
+++ b/internal/entity/collection_entity.go
@@ -33,8 +33,8 @@ type Collection struct {
type CollectionSearch struct {
Collection
- Page int `json:"page" form:"page"` //Query number of pages
- PageSize int `json:"page_size" form:"page_size"` //Search page size
+ Page int `json:"page" form:"page"` // Query number of pages
+ PageSize int `json:"page_size" form:"page_size"` // Search page size
}
// TableName collection table name
diff --git a/internal/install/install_req.go b/internal/install/install_req.go
index e5b8839e9..39657a546 100644
--- a/internal/install/install_req.go
+++ b/internal/install/install_req.go
@@ -65,13 +65,14 @@ func (r *CheckDatabaseReq) GetConnection() string {
}
if r.DbType == string(schemas.POSTGRES) {
host, port := parsePgSQLHostPort(r.DbHost)
- if !r.Ssl {
+ switch {
+ case !r.Ssl:
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
host, port, r.DbUsername, r.DbPassword, r.DbName)
- } else if r.SslMode == "require" {
+ case r.SslMode == "require":
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host, port, r.DbUsername, r.DbPassword, r.DbName, r.SslMode)
- } else if r.SslMode == "verify-ca" || r.SslMode == "verify-full" {
+ case r.SslMode == "verify-ca" || r.SslMode == "verify-full":
connection := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host, port, r.DbUsername, r.DbPassword, r.DbName, r.SslMode)
if len(r.SslRootCert) > 0 && dir.CheckFileExist(r.SslRootCert) {
@@ -150,7 +151,7 @@ func (r *InitBaseInfoReq) FormatSiteUrl() {
}
r.SiteURL = fmt.Sprintf("%s://%s", parsedUrl.Scheme, parsedUrl.Host)
if len(parsedUrl.Path) > 0 {
- r.SiteURL = r.SiteURL + parsedUrl.Path
+ r.SiteURL += parsedUrl.Path
r.SiteURL = strings.TrimSuffix(r.SiteURL, "/")
}
}
diff --git a/internal/migrations/v12.go b/internal/migrations/v12.go
index 2dd3ce71e..23e8acdcd 100644
--- a/internal/migrations/v12.go
+++ b/internal/migrations/v12.go
@@ -75,7 +75,6 @@ func updateQuestionPostTime(ctx context.Context, x *xorm.Engine) error {
return fmt.Errorf("update question failed: %w", err)
}
}
-
}
return nil
diff --git a/internal/migrations/v13.go b/internal/migrations/v13.go
index 57d248482..16ba177e8 100644
--- a/internal/migrations/v13.go
+++ b/internal/migrations/v13.go
@@ -136,7 +136,7 @@ func addPrivilegeForInviteSomeoneToAnswer(ctx context.Context, x *xorm.Engine) e
}
func updateQuestionCount(ctx context.Context, x *xorm.Engine) error {
- //question answer count
+ // question answer count
answers := make([]AnswerV13, 0)
err := x.Context(ctx).Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable})
if err != nil {
@@ -216,7 +216,7 @@ func updateTagCount(ctx context.Context, x *xorm.Engine) error {
}
}
- //select tag count
+ // select tag count
newTagRelList := make([]entity.TagRel, 0)
err = x.Context(ctx).Find(&newTagRelList, &entity.TagRel{Status: entity.TagRelStatusAvailable})
if err != nil {
diff --git a/internal/repo/activity/follow_repo.go b/internal/repo/activity/follow_repo.go
index 7af2189a6..4c6fc431b 100644
--- a/internal/repo/activity/follow_repo.go
+++ b/internal/repo/activity/follow_repo.go
@@ -168,7 +168,7 @@ func (ar *FollowRepo) FollowCancel(ctx context.Context, objectID, userID string)
return err
}
-func (ar *FollowRepo) updateFollows(ctx context.Context, session *xorm.Session, objectID string, follows int) error {
+func (ar *FollowRepo) updateFollows(_ context.Context, session *xorm.Session, objectID string, follows int) error {
objectType, err := obj.GetObjectTypeStrByObjectID(objectID)
if err != nil {
return err
diff --git a/internal/repo/activity_common/follow.go b/internal/repo/activity_common/follow.go
index 99e5a6e67..a185c3d8a 100644
--- a/internal/repo/activity_common/follow.go
+++ b/internal/repo/activity_common/follow.go
@@ -66,19 +66,19 @@ func (ar *FollowRepo) GetFollowAmount(ctx context.Context, objectID string) (fol
model := &entity.Question{}
_, err = ar.data.DB.Context(ctx).Where("id = ?", objectID).Cols("`follow_count`").Get(model)
if err == nil {
- follows = int(model.FollowCount)
+ follows = model.FollowCount
}
case "user":
model := &entity.User{}
_, err = ar.data.DB.Context(ctx).Where("id = ?", objectID).Cols("`follow_count`").Get(model)
if err == nil {
- follows = int(model.FollowCount)
+ follows = model.FollowCount
}
case "tag":
model := &entity.Tag{}
_, err = ar.data.DB.Context(ctx).Where("id = ?", objectID).Cols("`follow_count`").Get(model)
if err == nil {
- follows = int(model.FollowCount)
+ follows = model.FollowCount
}
default:
err = errors.InternalServer(reason.DisallowFollow).WithMsg("this object can't be followed")
diff --git a/internal/repo/answer/answer_repo.go b/internal/repo/answer/answer_repo.go
index 0f1ae8146..52963c44c 100644
--- a/internal/repo/answer/answer_repo.go
+++ b/internal/repo/answer/answer_repo.go
@@ -335,7 +335,7 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
var err error
rows := make([]*entity.Answer, 0)
if search.Page > 0 {
- search.Page = search.Page - 1
+ search.Page--
} else {
search.Page = 0
}
diff --git a/internal/repo/collection/collection_repo.go b/internal/repo/collection/collection_repo.go
index f30692c97..482cb075d 100644
--- a/internal/repo/collection/collection_repo.go
+++ b/internal/repo/collection/collection_repo.go
@@ -167,7 +167,7 @@ func (cr *collectionRepo) GetCollectionPage(ctx context.Context, page, pageSize
// SearchObjectCollected check object is collected or not
func (cr *collectionRepo) SearchObjectCollected(ctx context.Context, userID string, objectIds []string) (map[string]bool, error) {
- for i := 0; i < len(objectIds); i++ {
+ for i := range objectIds {
objectIds[i] = uid.DeShortID(objectIds[i])
}
@@ -193,7 +193,7 @@ func (cr *collectionRepo) SearchList(ctx context.Context, search *entity.Collect
var err error
rows := make([]*entity.Collection, 0)
if search.Page > 0 {
- search.Page = search.Page - 1
+ search.Page--
} else {
search.Page = 0
}
diff --git a/internal/repo/question/question_repo.go b/internal/repo/question/question_repo.go
index 3935e6102..3449efb8b 100644
--- a/internal/repo/question/question_repo.go
+++ b/internal/repo/question/question_repo.go
@@ -89,9 +89,9 @@ func (qr *questionRepo) RemoveQuestion(ctx context.Context, id string) (err erro
}
// UpdateQuestion update question
-func (qr *questionRepo) UpdateQuestion(ctx context.Context, question *entity.Question, Cols []string) (err error) {
+func (qr *questionRepo) UpdateQuestion(ctx context.Context, question *entity.Question, cols []string) (err error) {
question.ID = uid.DeShortID(question.ID)
- _, err = qr.data.DB.Context(ctx).Where("id =?", question.ID).Cols(Cols...).Update(question)
+ _, err = qr.data.DB.Context(ctx).Where("id =?", question.ID).Cols(cols...).Update(question)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
@@ -344,7 +344,7 @@ func (qr *questionRepo) GetUserQuestionCount(ctx context.Context, userID string,
func (qr *questionRepo) SitemapQuestions(ctx context.Context, page, pageSize int) (
questionIDList []*schema.SiteMapQuestionInfo, err error) {
- page = page - 1
+ page--
questionIDList = make([]*schema.SiteMapQuestionInfo, 0)
// try to get sitemap data from cache
@@ -524,7 +524,7 @@ func (qr *questionRepo) AdminQuestionPage(ctx context.Context, search *schema.Ad
rows := make([]*entity.Question, 0)
if search.Page > 0 {
- search.Page = search.Page - 1
+ search.Page--
} else {
search.Page = 0
}
diff --git a/internal/repo/rank/user_rank_repo.go b/internal/repo/rank/user_rank_repo.go
index cb9ca1b3d..5e86f5929 100644
--- a/internal/repo/rank/user_rank_repo.go
+++ b/internal/repo/rank/user_rank_repo.go
@@ -141,7 +141,7 @@ func (ur *UserRankRepo) TriggerUserRank(ctx context.Context,
return false, nil
}
-func (ur *UserRankRepo) checkUserMinRank(ctx context.Context, session *xorm.Session, userID string, deltaRank int) (
+func (ur *UserRankRepo) checkUserMinRank(_ context.Context, session *xorm.Session, userID string, deltaRank int) (
isReachStandard bool, err error,
) {
bean := &entity.User{ID: userID}
diff --git a/internal/repo/repo_test/auth_test.go b/internal/repo/repo_test/auth_test.go
index 387332399..0c9919020 100644
--- a/internal/repo/repo_test/auth_test.go
+++ b/internal/repo/repo_test/auth_test.go
@@ -26,6 +26,7 @@ import (
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/repo/auth"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -38,10 +39,10 @@ func Test_authRepo_SetUserCacheInfo(t *testing.T) {
authRepo := auth.NewAuthRepo(testDataSource)
err := authRepo.SetUserCacheInfo(context.TODO(), accessToken, visitToken, &entity.UserCacheInfo{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
cacheInfo, err := authRepo.GetUserCacheInfo(context.TODO(), accessToken)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, userID, cacheInfo.UserID)
}
@@ -49,13 +50,13 @@ func Test_authRepo_RemoveUserCacheInfo(t *testing.T) {
authRepo := auth.NewAuthRepo(testDataSource)
err := authRepo.SetUserCacheInfo(context.TODO(), accessToken, visitToken, &entity.UserCacheInfo{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = authRepo.RemoveUserCacheInfo(context.TODO(), accessToken)
- assert.NoError(t, err)
+ require.NoError(t, err)
userInfo, err := authRepo.GetUserCacheInfo(context.TODO(), accessToken)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, userInfo)
}
@@ -63,23 +64,23 @@ func Test_authRepo_SetUserStatus(t *testing.T) {
authRepo := auth.NewAuthRepo(testDataSource)
err := authRepo.SetUserStatus(context.TODO(), userID, &entity.UserCacheInfo{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
cacheInfo, err := authRepo.GetUserStatus(context.TODO(), userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, userID, cacheInfo.UserID)
}
func Test_authRepo_RemoveUserStatus(t *testing.T) {
authRepo := auth.NewAuthRepo(testDataSource)
err := authRepo.SetUserStatus(context.TODO(), userID, &entity.UserCacheInfo{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = authRepo.RemoveUserStatus(context.TODO(), userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
userInfo, err := authRepo.GetUserStatus(context.TODO(), userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, userInfo)
}
@@ -87,10 +88,10 @@ func Test_authRepo_SetAdminUserCacheInfo(t *testing.T) {
authRepo := auth.NewAuthRepo(testDataSource)
err := authRepo.SetAdminUserCacheInfo(context.TODO(), accessToken, &entity.UserCacheInfo{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
cacheInfo, err := authRepo.GetAdminUserCacheInfo(context.TODO(), accessToken)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, userID, cacheInfo.UserID)
}
@@ -98,12 +99,12 @@ func Test_authRepo_RemoveAdminUserCacheInfo(t *testing.T) {
authRepo := auth.NewAuthRepo(testDataSource)
err := authRepo.SetAdminUserCacheInfo(context.TODO(), accessToken, &entity.UserCacheInfo{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = authRepo.RemoveAdminUserCacheInfo(context.TODO(), accessToken)
- assert.NoError(t, err)
+ require.NoError(t, err)
userInfo, err := authRepo.GetAdminUserCacheInfo(context.TODO(), accessToken)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, userInfo)
}
diff --git a/internal/repo/repo_test/captcha_test.go b/internal/repo/repo_test/captcha_test.go
index 48e9dd806..e6954a232 100644
--- a/internal/repo/repo_test/captcha_test.go
+++ b/internal/repo/repo_test/captcha_test.go
@@ -25,6 +25,7 @@ import (
"github.com/apache/answer/internal/repo/captcha"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -36,23 +37,23 @@ var (
func Test_captchaRepo_DelActionType(t *testing.T) {
captchaRepo := captcha.NewCaptchaRepo(testDataSource)
err := captchaRepo.SetActionType(context.TODO(), ip, actionType, "", amount)
- assert.NoError(t, err)
+ require.NoError(t, err)
actionInfo, err := captchaRepo.GetActionType(context.TODO(), ip, actionType)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, amount, actionInfo.Num)
err = captchaRepo.DelActionType(context.TODO(), ip, actionType)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_captchaRepo_SetCaptcha(t *testing.T) {
captchaRepo := captcha.NewCaptchaRepo(testDataSource)
key, capt := "key", "1234"
err := captchaRepo.SetCaptcha(context.TODO(), key, capt)
- assert.NoError(t, err)
+ require.NoError(t, err)
gotCaptcha, err := captchaRepo.GetCaptcha(context.TODO(), key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, capt, gotCaptcha)
}
diff --git a/internal/repo/repo_test/comment_repo_test.go b/internal/repo/repo_test/comment_repo_test.go
index 3de154817..41ba04464 100644
--- a/internal/repo/repo_test/comment_repo_test.go
+++ b/internal/repo/repo_test/comment_repo_test.go
@@ -29,6 +29,7 @@ import (
"github.com/apache/answer/internal/repo/unique"
commentService "github.com/apache/answer/internal/service/comment"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func buildCommentEntity() *entity.Comment {
@@ -48,10 +49,10 @@ func Test_commentRepo_AddComment(t *testing.T) {
commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo)
testCommentEntity := buildCommentEntity()
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_commentRepo_GetCommentPage(t *testing.T) {
@@ -59,7 +60,7 @@ func Test_commentRepo_GetCommentPage(t *testing.T) {
commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo)
testCommentEntity := buildCommentEntity()
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
- assert.NoError(t, err)
+ require.NoError(t, err)
resp, total, err := commentRepo.GetCommentPage(context.TODO(), &commentService.CommentQuery{
PageCond: pager.PageCond{
@@ -67,12 +68,12 @@ func Test_commentRepo_GetCommentPage(t *testing.T) {
PageSize: 10,
},
})
- assert.NoError(t, err)
- assert.Equal(t, total, int64(1))
+ require.NoError(t, err)
+ assert.Equal(t, int64(1), total)
assert.Equal(t, resp[0].ID, testCommentEntity.ID)
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_commentRepo_UpdateComment(t *testing.T) {
@@ -81,19 +82,19 @@ func Test_commentRepo_UpdateComment(t *testing.T) {
commonCommentRepo := comment.NewCommentCommonRepo(testDataSource, uniqueIDRepo)
testCommentEntity := buildCommentEntity()
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
- assert.NoError(t, err)
+ require.NoError(t, err)
testCommentEntity.ParsedText = "test"
err = commentRepo.UpdateCommentContent(context.TODO(), testCommentEntity.ID, "test", "test")
- assert.NoError(t, err)
+ require.NoError(t, err)
newComment, exist, err := commonCommentRepo.GetComment(context.TODO(), testCommentEntity.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, testCommentEntity.ParsedText, newComment.ParsedText)
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_commentRepo_CannotGetDeletedComment(t *testing.T) {
@@ -102,12 +103,12 @@ func Test_commentRepo_CannotGetDeletedComment(t *testing.T) {
testCommentEntity := buildCommentEntity()
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, exist, err := commentRepo.GetComment(context.TODO(), testCommentEntity.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exist)
}
diff --git a/internal/repo/repo_test/email_repo_test.go b/internal/repo/repo_test/email_repo_test.go
index 82fc6c571..03ca9efe3 100644
--- a/internal/repo/repo_test/email_repo_test.go
+++ b/internal/repo/repo_test/email_repo_test.go
@@ -26,15 +26,16 @@ import (
"github.com/apache/answer/internal/repo/export"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_emailRepo_VerifyCode(t *testing.T) {
emailRepo := export.NewEmailRepo(testDataSource)
code, content := "1111", "{\"source_type\":\"\",\"e_mail\":\"\",\"user_id\":\"1\",\"skip_validation_latest_code\":false}"
err := emailRepo.SetCode(context.TODO(), "1", code, content, time.Minute)
- assert.NoError(t, err)
+ require.NoError(t, err)
verifyContent, err := emailRepo.VerifyCode(context.TODO(), code)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, content, verifyContent)
}
diff --git a/internal/repo/repo_test/meta_repo_test.go b/internal/repo/repo_test/meta_repo_test.go
index e910dab3f..68965f22b 100644
--- a/internal/repo/repo_test/meta_repo_test.go
+++ b/internal/repo/repo_test/meta_repo_test.go
@@ -26,6 +26,7 @@ import (
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/repo/meta"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func buildMetaEntity() *entity.Meta {
@@ -41,15 +42,15 @@ func Test_metaRepo_GetMetaByObjectIdAndKey(t *testing.T) {
metaEnt := buildMetaEntity()
err := metaRepo.AddMeta(context.TODO(), metaEnt)
- assert.NoError(t, err)
+ require.NoError(t, err)
gotMeta, exist, err := metaRepo.GetMetaByObjectIdAndKey(context.TODO(), metaEnt.ObjectID, metaEnt.Key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, metaEnt.ID, gotMeta.ID)
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_metaRepo_GetMetaList(t *testing.T) {
@@ -57,15 +58,15 @@ func Test_metaRepo_GetMetaList(t *testing.T) {
metaEnt := buildMetaEntity()
err := metaRepo.AddMeta(context.TODO(), metaEnt)
- assert.NoError(t, err)
+ require.NoError(t, err)
gotMetaList, err := metaRepo.GetMetaList(context.TODO(), metaEnt)
- assert.NoError(t, err)
- assert.Equal(t, len(gotMetaList), 1)
+ require.NoError(t, err)
+ assert.Len(t, gotMetaList, 1)
assert.Equal(t, gotMetaList[0].ID, metaEnt.ID)
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_metaRepo_GetMetaPage(t *testing.T) {
@@ -73,15 +74,15 @@ func Test_metaRepo_GetMetaPage(t *testing.T) {
metaEnt := buildMetaEntity()
err := metaRepo.AddMeta(context.TODO(), metaEnt)
- assert.NoError(t, err)
+ require.NoError(t, err)
gotMetaList, err := metaRepo.GetMetaList(context.TODO(), metaEnt)
- assert.NoError(t, err)
- assert.Equal(t, len(gotMetaList), 1)
+ require.NoError(t, err)
+ assert.Len(t, gotMetaList, 1)
assert.Equal(t, gotMetaList[0].ID, metaEnt.ID)
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_metaRepo_UpdateMeta(t *testing.T) {
@@ -89,17 +90,17 @@ func Test_metaRepo_UpdateMeta(t *testing.T) {
metaEnt := buildMetaEntity()
err := metaRepo.AddMeta(context.TODO(), metaEnt)
- assert.NoError(t, err)
+ require.NoError(t, err)
metaEnt.Value = "testing"
err = metaRepo.UpdateMeta(context.TODO(), metaEnt)
- assert.NoError(t, err)
+ require.NoError(t, err)
gotMeta, exist, err := metaRepo.GetMetaByObjectIdAndKey(context.TODO(), metaEnt.ObjectID, metaEnt.Key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, gotMeta.Value, metaEnt.Value)
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
diff --git a/internal/repo/repo_test/notification_repo_test.go b/internal/repo/repo_test/notification_repo_test.go
index a05913ba1..4f843e777 100644
--- a/internal/repo/repo_test/notification_repo_test.go
+++ b/internal/repo/repo_test/notification_repo_test.go
@@ -27,6 +27,7 @@ import (
"github.com/apache/answer/internal/repo/notification"
"github.com/apache/answer/internal/schema"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func buildNotificationEntity() *entity.Notification {
@@ -44,13 +45,13 @@ func Test_notificationRepo_ClearIDUnRead(t *testing.T) {
notificationRepo := notification.NewNotificationRepo(testDataSource)
ent := buildNotificationEntity()
err := notificationRepo.AddNotification(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = notificationRepo.ClearIDUnRead(context.TODO(), ent.UserID, ent.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, schema.NotificationRead, got.IsRead)
}
@@ -59,13 +60,13 @@ func Test_notificationRepo_ClearUnRead(t *testing.T) {
notificationRepo := notification.NewNotificationRepo(testDataSource)
ent := buildNotificationEntity()
err := notificationRepo.AddNotification(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = notificationRepo.ClearUnRead(context.TODO(), ent.UserID, ent.Type)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, schema.NotificationRead, got.IsRead)
}
@@ -74,10 +75,10 @@ func Test_notificationRepo_GetById(t *testing.T) {
notificationRepo := notification.NewNotificationRepo(testDataSource)
ent := buildNotificationEntity()
err := notificationRepo.AddNotification(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, got.ID, ent.ID)
}
@@ -86,10 +87,10 @@ func Test_notificationRepo_GetByUserIdObjectIdTypeId(t *testing.T) {
notificationRepo := notification.NewNotificationRepo(testDataSource)
ent := buildNotificationEntity()
err := notificationRepo.AddNotification(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exists, err := notificationRepo.GetByUserIdObjectIdTypeId(context.TODO(), ent.UserID, ent.ObjectID, ent.Type)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, got.ObjectID, ent.ObjectID)
}
@@ -98,11 +99,11 @@ func Test_notificationRepo_GetNotificationPage(t *testing.T) {
notificationRepo := notification.NewNotificationRepo(testDataSource)
ent := buildNotificationEntity()
err := notificationRepo.AddNotification(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
notificationPage, total, err := notificationRepo.GetNotificationPage(context.TODO(), &schema.NotificationSearch{UserID: ent.UserID})
- assert.NoError(t, err)
- assert.True(t, total > 0)
+ require.NoError(t, err)
+ assert.Positive(t, total)
assert.Equal(t, notificationPage[0].UserID, ent.UserID)
}
@@ -110,14 +111,14 @@ func Test_notificationRepo_UpdateNotificationContent(t *testing.T) {
notificationRepo := notification.NewNotificationRepo(testDataSource)
ent := buildNotificationEntity()
err := notificationRepo.AddNotification(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
ent.Content = "test"
err = notificationRepo.UpdateNotificationContent(context.TODO(), ent)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, got.Content, ent.Content)
}
diff --git a/internal/repo/repo_test/reason_repo_test.go b/internal/repo/repo_test/reason_repo_test.go
index 636f8d278..acb8c861a 100644
--- a/internal/repo/repo_test/reason_repo_test.go
+++ b/internal/repo/repo_test/reason_repo_test.go
@@ -28,12 +28,13 @@ import (
"github.com/apache/answer/internal/repo/reason"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_reasonRepo_ListReasons(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource)
reasonRepo := reason.NewReasonRepo(serviceconfig.NewConfigService(configRepo))
reasonItems, err := reasonRepo.ListReasons(context.TODO(), "question", "close")
- assert.NoError(t, err)
- assert.Equal(t, 4, len(reasonItems))
+ require.NoError(t, err)
+ assert.Len(t, reasonItems, 4)
}
diff --git a/internal/repo/repo_test/recommend_test.go b/internal/repo/repo_test/recommend_test.go
index a21693886..7675aa204 100644
--- a/internal/repo/repo_test/recommend_test.go
+++ b/internal/repo/repo_test/recommend_test.go
@@ -34,6 +34,7 @@ import (
"github.com/apache/answer/internal/repo/user"
config2 "github.com/apache/answer/internal/service/config"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_questionRepo_GetRecommend(t *testing.T) {
@@ -61,8 +62,8 @@ func Test_questionRepo_GetRecommend(t *testing.T) {
IsAdmin: false,
}
err := userRepo.AddUser(context.TODO(), user)
- assert.NoError(t, err)
- assert.NotEqual(t, "", user.ID)
+ require.NoError(t, err)
+ assert.NotEmpty(t, user.ID)
questions := make([]*entity.Question, 0)
// tag, unjoin, unfollow
@@ -140,8 +141,8 @@ func Test_questionRepo_GetRecommend(t *testing.T) {
for _, question := range questions {
err = questionRepo.AddQuestion(context.TODO(), question)
- assert.NoError(t, err)
- assert.NotEqual(t, "", question.ID)
+ require.NoError(t, err)
+ assert.NotEmpty(t, question.ID)
}
tags := []*entity.Tag{
@@ -161,7 +162,7 @@ func Test_questionRepo_GetRecommend(t *testing.T) {
},
}
err = tagCommenRepo.AddTagList(context.TODO(), tags)
- assert.NoError(t, err)
+ require.NoError(t, err)
tagRels := make([]*entity.TagRel, 0)
for i, question := range questions {
@@ -173,7 +174,7 @@ func Test_questionRepo_GetRecommend(t *testing.T) {
tagRels = append(tagRels, tagRel)
}
err = tagRelRepo.AddTagRelList(context.TODO(), tagRels)
- assert.NoError(t, err)
+ require.NoError(t, err)
followQuestionIDs := make([]string, 0)
for i := range questions {
@@ -181,15 +182,15 @@ func Test_questionRepo_GetRecommend(t *testing.T) {
continue
}
err = followRepo.Follow(context.TODO(), questions[i].ID, user.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
followQuestionIDs = append(followQuestionIDs, questions[i].ID)
}
// get recommend
questionList, total, err := questionRepo.GetRecommendQuestionPageByTags(context.TODO(), user.ID, []string{tags[0].ID}, followQuestionIDs, 1, 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(5), total)
- assert.Equal(t, 5, len(questionList))
+ assert.Len(t, questionList, 5)
// recovery
t.Cleanup(func() {
@@ -197,19 +198,19 @@ func Test_questionRepo_GetRecommend(t *testing.T) {
for i, tagRel := range tagRels {
if i%2 == 1 {
err = followRepo.FollowCancel(context.TODO(), questions[i].ID, user.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
tagRelIDs = append(tagRelIDs, tagRel.ID)
}
err = tagRelRepo.RemoveTagRelListByIDs(context.TODO(), tagRelIDs)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, tag := range tags {
err = tagRepo.RemoveTag(context.TODO(), tag.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
for _, q := range questions {
err = questionRepo.RemoveQuestion(context.TODO(), q.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
})
}
diff --git a/internal/repo/repo_test/repo_main_test.go b/internal/repo/repo_test/repo_main_test.go
index 919ca94e8..e2f40f276 100644
--- a/internal/repo/repo_test/repo_main_test.go
+++ b/internal/repo/repo_test/repo_main_test.go
@@ -153,7 +153,7 @@ func initDatabaseImage(dbSetting TestDBSetting) (connection string, cleanup func
return "", nil, fmt.Errorf("could not connect to docker: %s", err)
}
- //resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV)
+ // resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV)
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: dbSetting.ImageName,
Tag: dbSetting.ImageVersion,
diff --git a/internal/repo/repo_test/revision_repo_test.go b/internal/repo/repo_test/revision_repo_test.go
index 01d262d2b..6fd067b30 100644
--- a/internal/repo/repo_test/revision_repo_test.go
+++ b/internal/repo/repo_test/revision_repo_test.go
@@ -29,6 +29,7 @@ import (
"github.com/apache/answer/internal/repo/revision"
"github.com/apache/answer/internal/repo/unique"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var q = &entity.Question{
@@ -69,29 +70,29 @@ func Test_revisionRepo_AddRevision(t *testing.T) {
// create question
err := questionRepo.AddQuestion(context.TODO(), q)
- assert.NoError(t, err)
- assert.NotEqual(t, "", q.ID)
+ require.NoError(t, err)
+ assert.NotEmpty(t, q.ID)
content, err := json.Marshal(q)
- assert.NoError(t, err)
+ require.NoError(t, err)
// auto update false
rev := getRev(q.ID, q.Title, string(content))
err = revisionRepo.AddRevision(context.TODO(), rev, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
qr, _, _ := questionRepo.GetQuestion(context.TODO(), q.ID)
assert.NotEqual(t, rev.ID, qr.RevisionID)
// auto update false
rev = getRev(q.ID, q.Title, string(content))
err = revisionRepo.AddRevision(context.TODO(), rev, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
qr, _, _ = questionRepo.GetQuestion(context.TODO(), q.ID)
assert.Equal(t, rev.ID, qr.RevisionID)
// recovery
t.Cleanup(func() {
err = questionRepo.RemoveQuestion(context.TODO(), q.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
})
}
@@ -103,7 +104,7 @@ func Test_revisionRepo_GetLastRevisionByObjectID(t *testing.T) {
Test_revisionRepo_AddRevision(t)
rev, exists, err := revisionRepo.GetLastRevisionByObjectID(context.TODO(), q.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.NotNil(t, rev)
}
@@ -115,6 +116,6 @@ func Test_revisionRepo_GetRevisionList(t *testing.T) {
)
Test_revisionRepo_AddRevision(t)
revs, err := revisionRepo.GetRevisionList(context.TODO(), &entity.Revision{ObjectID: q.ID})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.GreaterOrEqual(t, len(revs), 1)
}
diff --git a/internal/repo/repo_test/siteinfo_repo_test.go b/internal/repo/repo_test/siteinfo_repo_test.go
index cb5d8fc0d..9fa59d177 100644
--- a/internal/repo/repo_test/siteinfo_repo_test.go
+++ b/internal/repo/repo_test/siteinfo_repo_test.go
@@ -26,6 +26,7 @@ import (
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/repo/site_info"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_siteInfoRepo_SaveByType(t *testing.T) {
@@ -34,19 +35,19 @@ func Test_siteInfoRepo_SaveByType(t *testing.T) {
data := &entity.SiteInfo{Content: "site_info", Type: "test"}
err := siteInfoRepo.SaveByType(context.TODO(), data.Type, data)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err := siteInfoRepo.GetByType(context.TODO(), data.Type)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, data.Content, got.Content)
data.Content = "new site_info"
err = siteInfoRepo.SaveByType(context.TODO(), data.Type, data)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err = siteInfoRepo.GetByType(context.TODO(), data.Type)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, data.Content, got.Content)
}
diff --git a/internal/repo/repo_test/tag_rel_repo_test.go b/internal/repo/repo_test/tag_rel_repo_test.go
index e3af67a14..47c09a6a3 100644
--- a/internal/repo/repo_test/tag_rel_repo_test.go
+++ b/internal/repo/repo_test/tag_rel_repo_test.go
@@ -30,6 +30,7 @@ import (
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/repo/tag"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -61,15 +62,15 @@ func Test_tagListRepo_BatchGetObjectTagRelList(t *testing.T) {
tagRelRepo := tag.NewTagRelRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
relList, err :=
tagRelRepo.BatchGetObjectTagRelList(context.TODO(), []string{testTagRelList[0].ObjectID, testTagRelList[1].ObjectID})
- assert.NoError(t, err)
- assert.Equal(t, 2, len(relList))
+ require.NoError(t, err)
+ assert.Len(t, relList, 2)
}
func Test_tagListRepo_CountTagRelByTagID(t *testing.T) {
tagRelOnce.Do(addTagRelList)
tagRelRepo := tag.NewTagRelRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
count, err := tagRelRepo.CountTagRelByTagID(context.TODO(), "10030000000000101")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), count)
}
@@ -79,8 +80,8 @@ func Test_tagListRepo_GetObjectTagRelList(t *testing.T) {
relList, err :=
tagRelRepo.GetObjectTagRelList(context.TODO(), testTagRelList[0].ObjectID)
- assert.NoError(t, err)
- assert.Equal(t, 1, len(relList))
+ require.NoError(t, err)
+ assert.Len(t, relList, 1)
}
func Test_tagListRepo_GetObjectTagRelWithoutStatus(t *testing.T) {
@@ -89,25 +90,25 @@ func Test_tagListRepo_GetObjectTagRelWithoutStatus(t *testing.T) {
relList, err :=
tagRelRepo.BatchGetObjectTagRelList(context.TODO(), []string{testTagRelList[0].ObjectID, testTagRelList[1].ObjectID})
- assert.NoError(t, err)
- assert.Equal(t, 2, len(relList))
+ require.NoError(t, err)
+ assert.Len(t, relList, 2)
ids := []int64{relList[0].ID, relList[1].ID}
err = tagRelRepo.RemoveTagRelListByIDs(context.TODO(), ids)
- assert.NoError(t, err)
+ require.NoError(t, err)
count, err := tagRelRepo.CountTagRelByTagID(context.TODO(), "10030000000000101")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(0), count)
_, exist, err := tagRelRepo.GetObjectTagRelWithoutStatus(context.TODO(), relList[0].ObjectID, relList[0].TagID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
err = tagRelRepo.EnableTagRelByIDs(context.TODO(), ids, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
count, err = tagRelRepo.CountTagRelByTagID(context.TODO(), "10030000000000101")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), count)
}
diff --git a/internal/repo/repo_test/tag_repo_test.go b/internal/repo/repo_test/tag_repo_test.go
index b2475a227..aa1ec1a25 100644
--- a/internal/repo/repo_test/tag_repo_test.go
+++ b/internal/repo/repo_test/tag_repo_test.go
@@ -32,6 +32,7 @@ import (
"github.com/apache/answer/internal/repo/unique"
"github.com/apache/answer/pkg/converter"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -75,7 +76,7 @@ func Test_tagRepo_GetTagByID(t *testing.T) {
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[0].ID, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, testTagList[0].SlugName, gotTag.SlugName)
}
@@ -85,7 +86,7 @@ func Test_tagRepo_GetTagBySlugName(t *testing.T) {
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTag, exist, err := tagCommonRepo.GetTagBySlugName(context.TODO(), testTagList[0].SlugName)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, testTagList[0].SlugName, gotTag.SlugName)
}
@@ -95,7 +96,7 @@ func Test_tagRepo_GetTagList(t *testing.T) {
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTags, err := tagRepo.GetTagList(context.TODO(), &entity.Tag{ID: testTagList[0].ID})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
}
@@ -104,7 +105,7 @@ func Test_tagRepo_GetTagListByIDs(t *testing.T) {
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTags, err := tagCommonRepo.GetTagListByIDs(context.TODO(), []string{testTagList[0].ID})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
}
@@ -113,7 +114,7 @@ func Test_tagRepo_GetTagListByName(t *testing.T) {
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTags, err := tagCommonRepo.GetTagListByName(context.TODO(), testTagList[0].SlugName, false, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
}
@@ -122,7 +123,7 @@ func Test_tagRepo_GetTagListByNames(t *testing.T) {
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTags, err := tagCommonRepo.GetTagListByNames(context.TODO(), []string{testTagList[0].SlugName})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
}
@@ -131,7 +132,7 @@ func Test_tagRepo_GetTagPage(t *testing.T) {
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTags, _, err := tagCommonRepo.GetTagPage(context.TODO(), 1, 1, &entity.Tag{SlugName: testTagList[0].SlugName}, "")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
}
@@ -140,12 +141,12 @@ func Test_tagRepo_RemoveTag(t *testing.T) {
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo)
err := tagRepo.RemoveTag(context.TODO(), testTagList[1].ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
_, exist, err := tagCommonRepo.GetTagBySlugName(context.TODO(), testTagList[1].SlugName)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exist)
}
@@ -155,12 +156,12 @@ func Test_tagRepo_UpdateTag(t *testing.T) {
testTagList[0].DisplayName = "golang"
err := tagRepo.UpdateTag(context.TODO(), testTagList[0])
- assert.NoError(t, err)
+ require.NoError(t, err)
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[0].ID, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, testTagList[0].DisplayName, gotTag.DisplayName)
}
@@ -170,10 +171,10 @@ func Test_tagRepo_UpdateTagQuestionCount(t *testing.T) {
testTagList[0].DisplayName = "golang"
err := tagCommonRepo.UpdateTagQuestionCount(context.TODO(), testTagList[0].ID, 100)
- assert.NoError(t, err)
+ require.NoError(t, err)
gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[0].ID, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, 100, gotTag.QuestionCount)
}
@@ -184,16 +185,16 @@ func Test_tagRepo_UpdateTagSynonym(t *testing.T) {
testTagList[0].DisplayName = "golang"
err := tagRepo.UpdateTag(context.TODO(), testTagList[0])
- assert.NoError(t, err)
+ require.NoError(t, err)
err = tagRepo.UpdateTagSynonym(context.TODO(), []string{testTagList[2].SlugName},
converter.StringToInt64(testTagList[0].ID), testTagList[0].SlugName)
- assert.NoError(t, err)
+ require.NoError(t, err)
tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[2].ID, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, testTagList[0].ID, fmt.Sprintf("%d", gotTag.MainTagID))
}
diff --git a/internal/repo/repo_test/user_backyard_repo_test.go b/internal/repo/repo_test/user_backyard_repo_test.go
index 073a600cf..eb4db102b 100644
--- a/internal/repo/repo_test/user_backyard_repo_test.go
+++ b/internal/repo/repo_test/user_backyard_repo_test.go
@@ -28,12 +28,13 @@ import (
"github.com/apache/answer/internal/repo/auth"
"github.com/apache/answer/internal/repo/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_userAdminRepo_GetUserInfo(t *testing.T) {
userAdminRepo := user.NewUserAdminRepo(testDataSource, auth.NewAuthRepo(testDataSource))
got, exist, err := userAdminRepo.GetUserInfo(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, "1", got.ID)
}
@@ -41,7 +42,7 @@ func Test_userAdminRepo_GetUserInfo(t *testing.T) {
func Test_userAdminRepo_GetUserPage(t *testing.T) {
userAdminRepo := user.NewUserAdminRepo(testDataSource, auth.NewAuthRepo(testDataSource))
got, total, err := userAdminRepo.GetUserPage(context.TODO(), 1, 1, &entity.User{Username: "admin"}, "", false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Equal(t, "1", got[0].ID)
}
@@ -49,25 +50,25 @@ func Test_userAdminRepo_GetUserPage(t *testing.T) {
func Test_userAdminRepo_UpdateUserStatus(t *testing.T) {
userAdminRepo := user.NewUserAdminRepo(testDataSource, auth.NewAuthRepo(testDataSource))
got, exist, err := userAdminRepo.GetUserInfo(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, entity.UserStatusAvailable, got.Status)
err = userAdminRepo.UpdateUserStatus(context.TODO(), "1", entity.UserStatusSuspended, entity.EmailStatusAvailable,
"admin@admin.com", time.Now().Add(time.Minute*5))
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err = userAdminRepo.GetUserInfo(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, entity.UserStatusSuspended, got.Status)
err = userAdminRepo.UpdateUserStatus(context.TODO(), "1", entity.UserStatusAvailable, entity.EmailStatusAvailable,
"admin@admin.com", time.Time{})
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err = userAdminRepo.GetUserInfo(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, entity.UserStatusAvailable, got.Status)
}
diff --git a/internal/repo/repo_test/user_repo_test.go b/internal/repo/repo_test/user_repo_test.go
index 7b18833dd..95a85ab99 100644
--- a/internal/repo/repo_test/user_repo_test.go
+++ b/internal/repo/repo_test/user_repo_test.go
@@ -26,6 +26,7 @@ import (
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/repo/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_userRepo_AddUser(t *testing.T) {
@@ -40,21 +41,21 @@ func Test_userRepo_AddUser(t *testing.T) {
IsAdmin: false,
}
err := userRepo.AddUser(context.TODO(), userInfo)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_userRepo_BatchGetByID(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
got, err := userRepo.BatchGetByID(context.TODO(), []string{"1"})
- assert.NoError(t, err)
- assert.Equal(t, 1, len(got))
+ require.NoError(t, err)
+ assert.Len(t, got, 1)
assert.Equal(t, "admin", got[0].Username)
}
func Test_userRepo_GetByEmail(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
got, exist, err := userRepo.GetByEmail(context.TODO(), "admin@admin.com")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, "admin", got.Username)
}
@@ -62,7 +63,7 @@ func Test_userRepo_GetByEmail(t *testing.T) {
func Test_userRepo_GetByUserID(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, "admin", got.Username)
}
@@ -70,7 +71,7 @@ func Test_userRepo_GetByUserID(t *testing.T) {
func Test_userRepo_GetByUsername(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
got, exist, err := userRepo.GetByUsername(context.TODO(), "admin")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, "admin", got.Username)
}
@@ -78,10 +79,10 @@ func Test_userRepo_GetByUsername(t *testing.T) {
func Test_userRepo_IncreaseAnswerCount(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.IncreaseAnswerCount(context.TODO(), "1", 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, 1, got.AnswerCount)
}
@@ -89,10 +90,10 @@ func Test_userRepo_IncreaseAnswerCount(t *testing.T) {
func Test_userRepo_IncreaseQuestionCount(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.IncreaseQuestionCount(context.TODO(), "1", 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, 1, got.AnswerCount)
}
@@ -100,22 +101,22 @@ func Test_userRepo_IncreaseQuestionCount(t *testing.T) {
func Test_userRepo_UpdateEmail(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.UpdateEmail(context.TODO(), "1", "admin@admin.com")
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_userRepo_UpdateEmailStatus(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.UpdateEmailStatus(context.TODO(), "1", entity.EmailStatusToBeVerified)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_userRepo_UpdateInfo(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.UpdateInfo(context.TODO(), &entity.User{ID: "1", Bio: "test"})
- assert.NoError(t, err)
+ require.NoError(t, err)
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, "test", got.Bio)
}
@@ -123,17 +124,17 @@ func Test_userRepo_UpdateInfo(t *testing.T) {
func Test_userRepo_UpdateLastLoginDate(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.UpdateLastLoginDate(context.TODO(), "1")
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_userRepo_UpdateNoticeStatus(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.UpdateNoticeStatus(context.TODO(), "1", 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_userRepo_UpdatePass(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource)
err := userRepo.UpdatePass(context.TODO(), "1", "admin")
- assert.NoError(t, err)
+ require.NoError(t, err)
}
diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go
index 806517234..a56b8edb6 100644
--- a/internal/repo/search_common/search_repo.go
+++ b/internal/repo/search_common/search_repo.go
@@ -190,7 +190,7 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs
argsA = append(argsA, votes)
}
- //b = b.Union("all", ub)
+ // b = b.Union("all", ub)
ubSQL, _, err := ub.ToSQL()
if err != nil {
return
@@ -447,7 +447,7 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs
return
}
-func (sr *searchRepo) parseOrder(ctx context.Context, order string) (res string) {
+func (sr *searchRepo) parseOrder(_ context.Context, order string) (res string) {
switch order {
case "newest":
res = "created_at desc"
diff --git a/internal/schema/backyard_user_schema.go b/internal/schema/backyard_user_schema.go
index 6ec848721..d36ff8083 100644
--- a/internal/schema/backyard_user_schema.go
+++ b/internal/schema/backyard_user_schema.go
@@ -222,7 +222,7 @@ func (req *AddUsersReq) ParseUsers(ctx context.Context) (errFields []*validator.
}
// check users amount
- if len(req.Users) <= 0 || len(req.Users) > constant.DefaultBulkUser {
+ if len(req.Users) == 0 || len(req.Users) > constant.DefaultBulkUser {
errFields = append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "users",
ErrorMsg: translator.TrWithData(handler.GetLangByCtx(ctx), reason.AddBulkUsersAmountError,
diff --git a/internal/schema/meta_schema.go b/internal/schema/meta_schema.go
index 286e2e7d6..e5a072529 100644
--- a/internal/schema/meta_schema.go
+++ b/internal/schema/meta_schema.go
@@ -19,6 +19,8 @@
package schema
+import "slices"
+
type UpdateReactionReq struct {
ObjectID string `validate:"required" json:"object_id"`
Emoji string `validate:"required,oneof=heart smile frown" json:"emoji"`
@@ -48,13 +50,7 @@ func (r *ReactionsSummaryMeta) AddReactionSummary(emoji, userID string) {
if reaction.Emoji != emoji {
continue
}
- exist := false
- for _, id := range reaction.UserIDs {
- if id == userID {
- exist = true
- break
- }
- }
+ exist := slices.Contains(reaction.UserIDs, userID)
if !exist {
reaction.UserIDs = append(reaction.UserIDs, userID)
}
@@ -94,10 +90,8 @@ func (r *ReactionsSummaryMeta) CheckUserInReactionSummary(emoji, userID string)
if reaction.Emoji != emoji {
continue
}
- for _, id := range reaction.UserIDs {
- if id == userID {
- return true
- }
+ if slices.Contains(reaction.UserIDs, userID) {
+ return true
}
}
return false
diff --git a/internal/schema/notification_schema.go b/internal/schema/notification_schema.go
index e5d60615e..b9e029389 100644
--- a/internal/schema/notification_schema.go
+++ b/internal/schema/notification_schema.go
@@ -53,7 +53,7 @@ var NotificationInboxType = map[string]int{
type NotificationContent struct {
ID string `json:"id"`
- TriggerUserID string `json:"-"` //show userid
+ TriggerUserID string `json:"-"` // show userid
ReceiverUserID string `json:"-"` // receiver userid
UserInfo *UserBasicInfo `json:"user_info,omitempty"`
ObjectInfo ObjectInfo `json:"object_info"`
@@ -169,8 +169,8 @@ func (r *RedDotBadgeAwardCache) RemoveBadgeAward(notificationID string) {
}
type NotificationSearch struct {
- Page int `json:"page" form:"page"` //Query number of pages
- PageSize int `json:"page_size" form:"page_size"` //Search page size
+ Page int `json:"page" form:"page"` // Query number of pages
+ PageSize int `json:"page_size" form:"page_size"` // Search page size
Type int `json:"-" form:"-"`
TypeStr string `json:"type" form:"type"` // inbox achievement
InboxTypeStr string `json:"inbox_type" form:"inbox_type"` // inbox achievement
diff --git a/internal/schema/revision_schema.go b/internal/schema/revision_schema.go
index b3ac0aadd..6f3246e51 100644
--- a/internal/schema/revision_schema.go
+++ b/internal/schema/revision_schema.go
@@ -53,7 +53,7 @@ const RevisionAuditReject = "reject"
type RevisionAuditReq struct {
// object id
ID string `validate:"required" comment:"id" form:"id"`
- Operation string `validate:"required" comment:"operation" form:"operation"` //approve or reject
+ Operation string `validate:"required" comment:"operation" form:"operation"` // approve or reject
UserID string `json:"-"`
CanReviewQuestion bool `json:"-"`
CanReviewAnswer bool `json:"-"`
diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go
index 0e43bb420..7ab657512 100644
--- a/internal/schema/siteinfo_schema.go
+++ b/internal/schema/siteinfo_schema.go
@@ -52,7 +52,7 @@ func (r *SiteGeneralReq) FormatSiteUrl() {
}
r.SiteUrl = fmt.Sprintf("%s://%s", parsedUrl.Scheme, parsedUrl.Host)
if len(parsedUrl.Path) > 0 {
- r.SiteUrl = r.SiteUrl + parsedUrl.Path
+ r.SiteUrl += parsedUrl.Path
r.SiteUrl = strings.TrimSuffix(r.SiteUrl, "/")
}
}
diff --git a/internal/schema/tag_schema.go b/internal/schema/tag_schema.go
index a51b2d2d5..8eb3212c4 100644
--- a/internal/schema/tag_schema.go
+++ b/internal/schema/tag_schema.go
@@ -109,7 +109,7 @@ type GetTagPageResp struct {
DisplayName string `json:"display_name"`
// excerpt
Excerpt string `json:"excerpt"`
- //description
+ // description
Description string `json:"description"`
// original text
OriginalText string `json:"original_text"`
diff --git a/internal/service/action/captcha_strategy.go b/internal/service/action/captcha_strategy.go
index b423b583b..edda73252 100644
--- a/internal/service/action/captcha_strategy.go
+++ b/internal/service/action/captcha_strategy.go
@@ -67,9 +67,8 @@ func (cs *CaptchaService) ValidationStrategy(ctx context.Context, unit, actionTy
return cs.CaptchaActionDelete(ctx, unit, info)
case entity.CaptchaActionVote:
return cs.CaptchaActionVote(ctx, unit, info)
-
}
- //actionType not found
+ // actionType not found
return false
}
@@ -83,7 +82,7 @@ func (cs *CaptchaService) CaptchaActionPassword(ctx context.Context, unit string
return true
}
setNum := 3
- setTime := int64(60 * 30) //seconds
+ setTime := int64(60 * 30) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime && actionInfo.Num >= setNum {
return false
@@ -101,7 +100,7 @@ func (cs *CaptchaService) CaptchaActionEditUserinfo(ctx context.Context, unit st
return true
}
setNum := 3
- setTime := int64(60 * 30) //seconds
+ setTime := int64(60 * 30) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime && actionInfo.Num >= setNum {
return false
@@ -119,7 +118,7 @@ func (cs *CaptchaService) CaptchaActionQuestion(ctx context.Context, unit string
return true
}
setNum := 10
- setTime := int64(5) //seconds
+ setTime := int64(5) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum {
return false
@@ -132,7 +131,7 @@ func (cs *CaptchaService) CaptchaActionAnswer(ctx context.Context, unit string,
return true
}
setNum := 10
- setTime := int64(5) //seconds
+ setTime := int64(5) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum {
return false
@@ -145,7 +144,7 @@ func (cs *CaptchaService) CaptchaActionComment(ctx context.Context, unit string,
return true
}
setNum := 30
- setTime := int64(1) //seconds
+ setTime := int64(1) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum {
return false
@@ -175,8 +174,8 @@ func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string,
}
now := time.Now().Unix()
setNum := 20
- setTime := int64(60) //seconds
- if now-int64(actionInfo.LastTime) <= setTime && actionInfo.Num >= setNum {
+ setTime := int64(60) // seconds
+ if now-actionInfo.LastTime <= setTime && actionInfo.Num >= setNum {
return false
}
if now-actionInfo.LastTime > setTime {
@@ -192,7 +191,7 @@ func (cs *CaptchaService) CaptchaActionReport(ctx context.Context, unit string,
return true
}
setNum := 30
- setTime := int64(1) //seconds
+ setTime := int64(1) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum {
return false
@@ -205,7 +204,7 @@ func (cs *CaptchaService) CaptchaActionDelete(ctx context.Context, unit string,
return true
}
setNum := 5
- setTime := int64(5) //seconds
+ setTime := int64(5) // seconds
now := time.Now().Unix()
if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum {
return false
diff --git a/internal/service/auth/auth.go b/internal/service/auth/auth.go
index 9ee5f3ee0..b94f7912a 100644
--- a/internal/service/auth/auth.go
+++ b/internal/service/auth/auth.go
@@ -138,7 +138,7 @@ func (as *AuthService) RemoveTokensExceptCurrentUser(ctx context.Context, userID
as.authRepo.RemoveUserTokens(ctx, userID, accessToken)
}
-//Admin
+// Admin
func (as *AuthService) GetAdminUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error) {
return as.authRepo.GetAdminUserCacheInfo(ctx, accessToken)
diff --git a/internal/service/comment/comment_service.go b/internal/service/comment/comment_service.go
index 3a5b3e6c9..dc599e6df 100644
--- a/internal/service/comment/comment_service.go
+++ b/internal/service/comment/comment_service.go
@@ -178,9 +178,8 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment
time.Now(), req.CanEdit, req.CanDelete)
if comment.Status == entity.CommentStatusAvailable {
- commentResp, err := cs.addCommentNotification(ctx, req, resp, comment, objInfo)
- if err != nil {
- return commentResp, err
+ if err := cs.addCommentNotification(ctx, req, resp, comment, objInfo); err != nil {
+ return nil, err
}
}
@@ -220,7 +219,7 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment
func (cs *CommentService) addCommentNotification(
ctx context.Context, req *schema.AddCommentReq, resp *schema.GetCommentResp,
- comment *entity.Comment, objInfo *schema.SimpleObjectInfo) (*schema.GetCommentResp, error) {
+ comment *entity.Comment, objInfo *schema.SimpleObjectInfo) error {
// The priority of the notification
// 1. reply to user
// 2. comment mention to user
@@ -231,7 +230,7 @@ func (cs *CommentService) addCommentNotification(
if len(resp.ReplyUserID) > 0 && resp.ReplyUserID != req.UserID {
replyUser, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.ReplyUserID)
if err != nil {
- return nil, err
+ return err
}
if exist {
resp.ReplyUsername = replyUser.Username
@@ -241,7 +240,7 @@ func (cs *CommentService) addCommentNotification(
cs.notificationCommentReply(ctx, replyUser.ID, comment.ID, req.UserID,
objInfo.QuestionID, objInfo.Title, htmltext.FetchExcerpt(comment.ParsedText, "...", 240))
alreadyNotifiedUserID[replyUser.ID] = true
- return nil, nil
+ return nil
}
if len(req.MentionUsernameList) > 0 {
@@ -250,7 +249,7 @@ func (cs *CommentService) addCommentNotification(
for _, userID := range alreadyNotifiedUserIDs {
alreadyNotifiedUserID[userID] = true
}
- return nil, nil
+ return nil
}
if objInfo.ObjectType == constant.QuestionObjectType && !alreadyNotifiedUserID[objInfo.ObjectCreatorUserID] {
@@ -260,7 +259,7 @@ func (cs *CommentService) addCommentNotification(
cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID,
objInfo.ObjectCreatorUserID, comment.ID, req.UserID, htmltext.FetchExcerpt(comment.ParsedText, "...", 240))
}
- return nil, nil
+ return nil
}
// RemoveComment delete comment
diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go
index 982bbf88a..f904b82f0 100644
--- a/internal/service/content/answer_service.go
+++ b/internal/service/content/answer_service.go
@@ -146,7 +146,6 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns
if !exist {
return errors.BadRequest(reason.AnswerCannotDeleted)
}
-
}
err = as.answerRepo.RemoveAnswer(ctx, req.ID)
@@ -180,10 +179,10 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns
// #2372 In order to simplify the process and complexity, as well as to consider if it is in-house,
// facing the problem of recovery.
- //err = as.answerActivityService.DeleteAnswer(ctx, answerInfo.ID, answerInfo.CreatedAt, answerInfo.VoteCount)
- //if err != nil {
- // log.Errorf("delete answer activity change failed: %s", err.Error())
- //}
+ // err = as.answerActivityService.DeleteAnswer(ctx, answerInfo.ID, answerInfo.CreatedAt, answerInfo.VoteCount)
+ // if err != nil {
+ // log.Errorf("delete answer activity change failed: %s", err.Error())
+ // }
as.activityQueueService.Send(ctx, &schema.ActivityMsg{
UserID: req.UserID,
TriggerUserID: converter.StringToInt64(req.UserID),
@@ -264,7 +263,7 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
insertData.RevisionID = "0"
insertData.LastEditUserID = "0"
insertData.Status = entity.AnswerStatusPending
- //insertData.UpdatedAt = now
+ // insertData.UpdatedAt = now
if err = as.answerRepo.AddAnswer(ctx, insertData); err != nil {
return "", err
}
@@ -365,7 +364,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
return "", errors.BadRequest(reason.QuestionNotFound)
}
- //If the content is the same, ignore it
+ // If the content is the same, ignore it
if answerInfo.OriginalText == req.Content {
return "", nil
}
diff --git a/internal/service/content/question_hottest_service.go b/internal/service/content/question_hottest_service.go
index 085b36709..b73e7a30d 100644
--- a/internal/service/content/question_hottest_service.go
+++ b/internal/service/content/question_hottest_service.go
@@ -30,7 +30,6 @@ import (
)
func (q *QuestionService) RefreshHottestCron(ctx context.Context) {
-
var (
page = 1
pageSize = 100
diff --git a/internal/service/content/question_service.go b/internal/service/content/question_service.go
index da15fae5d..b8372a72e 100644
--- a/internal/service/content/question_service.go
+++ b/internal/service/content/question_service.go
@@ -216,9 +216,9 @@ func (qs *QuestionService) ReopenQuestion(ctx context.Context, req *schema.Reope
return nil
}
-func (qs *QuestionService) AddQuestionCheckTags(ctx context.Context, Tags []*entity.Tag) ([]string, error) {
+func (qs *QuestionService) AddQuestionCheckTags(ctx context.Context, tags []*entity.Tag) ([]string, error) {
list := make([]string, 0)
- for _, tag := range Tags {
+ for _, tag := range tags {
if tag.Reserved {
list = append(list, tag.DisplayName)
}
@@ -374,14 +374,14 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
question.AcceptedAnswerID = "0"
question.LastAnswerID = "0"
question.LastEditUserID = "0"
- //question.PostUpdateTime = nil
+ // question.PostUpdateTime = nil
question.Status = entity.QuestionStatusPending
question.RevisionID = "0"
question.CreatedAt = now
question.PostUpdateTime = now
question.Pin = entity.QuestionUnPin
question.Show = entity.QuestionShow
- //question.UpdatedAt = nil
+ // question.UpdatedAt = nil
err = qs.questionRepo.AddQuestion(ctx, question)
if err != nil {
return
@@ -416,10 +416,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
Title: question.Title,
}
- questionWithTagsRevision, err := qs.changeQuestionToRevision(ctx, question, tags)
- if err != nil {
- return nil, err
- }
+ questionWithTagsRevision := qs.changeQuestionToRevision(ctx, question, tags)
infoJSON, _ := json.Marshal(questionWithTagsRevision)
revisionDTO.Content = string(infoJSON)
revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true)
@@ -554,7 +551,7 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov
if err != nil {
return err
}
- //if the status is deleted, return directly
+ // if the status is deleted, return directly
if questionInfo.Status == entity.QuestionStatusDeleted {
return nil
}
@@ -613,7 +610,7 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov
}
}
- //tag count
+ // tag count
tagIDs := make([]string, 0)
Tags, tagerr := qs.tagCommon.GetObjectEntityTag(ctx, req.ID)
if tagerr != nil {
@@ -684,7 +681,7 @@ func (qs *QuestionService) UpdateQuestionCheckTags(ctx context.Context, req *sch
isChange := qs.tagCommon.CheckTagsIsChange(ctx, tagNameList, oldtagNameList)
- //If the content is the same, ignore it
+ // If the content is the same, ignore it
if dbinfo.Title == req.Title && dbinfo.OriginalText == req.Content && !isChange {
return
}
@@ -798,7 +795,7 @@ func (qs *QuestionService) UpdateQuestionInviteUser(ctx context.Context, req *sc
return errors.BadRequest(reason.QuestionNotFound)
}
- //verify invite user
+ // verify invite user
inviteUserInfoList, err := qs.userCommon.BatchGetUserBasicInfoByUserNames(ctx, req.InviteUser)
if err != nil {
log.Error("BatchGetUserBasicInfoByUserNames error", err.Error())
@@ -826,7 +823,7 @@ func (qs *QuestionService) UpdateQuestionInviteUser(ctx context.Context, req *sc
if saveerr != nil {
return saveerr
}
- //send notification
+ // send notification
oldInviteUserIDsStr := originQuestion.InviteUserID
oldInviteUserIDs := make([]string, 0)
needSendNotificationUserIDs := make([]string, 0)
@@ -964,7 +961,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
isChange := qs.tagCommon.CheckTagsIsChange(ctx, tagNameList, oldtagNameList)
- //If the content is the same, ignore it
+ // If the content is the same, ignore it
if dbinfo.Title == req.Title && dbinfo.OriginalText == req.Content && !isChange {
return
}
@@ -1015,7 +1012,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
return errorlist, err
}
- //Administrators and themselves do not need to be audited
+ // Administrators and themselves do not need to be audited
revisionDTO := &schema.AddRevisionDTO{
UserID: question.UserID,
@@ -1031,11 +1028,11 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
// It's not you or the administrator that needs to be reviewed
if !canUpdate {
revisionDTO.Status = entity.RevisionUnreviewedStatus
- revisionDTO.UserID = req.UserID //use revision userid
+ revisionDTO.UserID = req.UserID // use revision userid
} else {
- //Direct modification
+ // Direct modification
revisionDTO.Status = entity.RevisionReviewPassStatus
- //update question to db
+ // update question to db
question.ParsedText, err = qs.questioncommon.UpdateQuestionLink(ctx, question.ID, "", question.ParsedText, question.OriginalText)
if err != nil {
return questionInfo, err
@@ -1054,10 +1051,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
}
}
- questionWithTagsRevision, err := qs.changeQuestionToRevision(ctx, question, Tags)
- if err != nil {
- return nil, err
- }
+ questionWithTagsRevision := qs.changeQuestionToRevision(ctx, question, Tags)
infoJSON, _ := json.Marshal(questionWithTagsRevision)
revisionDTO.Content = string(infoJSON)
revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true)
@@ -1165,7 +1159,6 @@ func (qs *QuestionService) CheckChangeReservedTag(ctx context.Context, oldobject
// PersonalQuestionPage get question list by user
func (qs *QuestionService) PersonalQuestionPage(ctx context.Context, req *schema.PersonalQuestionPageReq) (
pageModel *pager.PageModel, err error) {
-
userinfo, exist, err := qs.userCommon.GetUserBasicInfoByUserName(ctx, req.Username)
if err != nil {
return nil, err
@@ -1250,7 +1243,6 @@ func (qs *QuestionService) PersonalAnswerPage(ctx context.Context, req *schema.P
info.QuestionID = item.QuestionID
if item.QuestionInfo.Status == entity.QuestionStatusDeleted {
info.QuestionInfo.Title = "Deleted question"
-
}
userAnswerlist = append(userAnswerlist, info)
}
@@ -1489,7 +1481,8 @@ func (qs *QuestionService) GetQuestionPage(ctx context.Context, req *schema.Ques
if err != nil {
return nil, 0, err
}
- tagIDs = append(synTagIds, tagInfo.ID)
+ tagIDs = append(tagIDs, synTagIds...)
+ tagIDs = append(tagIDs, tagInfo.ID)
} else {
return questions, 0, nil
}
@@ -1585,10 +1578,10 @@ func (qs *QuestionService) AdminSetQuestionStatus(ctx context.Context, req *sche
if setStatus == entity.QuestionStatusDeleted {
// #2372 In order to simplify the process and complexity, as well as to consider if it is in-house,
// facing the problem of recovery.
- //err = qs.answerActivityService.DeleteQuestion(ctx, questionInfo.ID, questionInfo.CreatedAt, questionInfo.VoteCount)
- //if err != nil {
- // log.Errorf("admin delete question then rank rollback error %s", err.Error())
- //}
+ // err = qs.answerActivityService.DeleteQuestion(ctx, questionInfo.ID, questionInfo.CreatedAt, questionInfo.VoteCount)
+ // if err != nil {
+ // log.Errorf("admin delete question then rank rollback error %s", err.Error())
+ // }
qs.activityQueueService.Send(ctx, &schema.ActivityMsg{
UserID: questionInfo.UserID,
TriggerUserID: converter.StringToInt64(req.UserID),
@@ -1642,7 +1635,6 @@ func (qs *QuestionService) AdminSetQuestionStatus(ctx context.Context, req *sche
func (qs *QuestionService) AdminQuestionPage(
ctx context.Context, req *schema.AdminQuestionPageReq) (
resp *pager.PageModel, err error) {
-
list := make([]*schema.AdminQuestionInfo, 0)
questionList, count, err := qs.questionRepo.AdminQuestionPage(ctx, req)
if err != nil {
@@ -1708,8 +1700,8 @@ func (qs *QuestionService) AdminAnswerPage(ctx context.Context, req *schema.Admi
return pager.NewPageModel(count, answerResp), nil
}
-func (qs *QuestionService) changeQuestionToRevision(ctx context.Context, questionInfo *entity.Question, tags []*entity.Tag) (
- questionRevision *entity.QuestionWithTagsRevision, err error) {
+func (qs *QuestionService) changeQuestionToRevision(_ context.Context, questionInfo *entity.Question, tags []*entity.Tag) (
+ questionRevision *entity.QuestionWithTagsRevision) {
questionRevision = &entity.QuestionWithTagsRevision{}
questionRevision.Question = *questionInfo
@@ -1718,7 +1710,7 @@ func (qs *QuestionService) changeQuestionToRevision(ctx context.Context, questio
_ = copier.Copy(item, tag)
questionRevision.Tags = append(questionRevision.Tags, item)
}
- return questionRevision, nil
+ return questionRevision
}
func (qs *QuestionService) SitemapCron(ctx context.Context) {
diff --git a/internal/service/content/revision_service.go b/internal/service/content/revision_service.go
index a5cefeb41..4ac08e769 100644
--- a/internal/service/content/revision_service.go
+++ b/internal/service/content/revision_service.go
@@ -235,7 +235,6 @@ func (rs *RevisionService) revisionAuditQuestion(ctx context.Context, revisionit
func (rs *RevisionService) revisionAuditAnswer(ctx context.Context, revisionitem *schema.GetRevisionResp) (err error) {
answerinfo, ok := revisionitem.ContentParsed.(*schema.AnswerInfo)
if ok {
-
var PostUpdateTime time.Time
dbquestion, exist, dberr := rs.questionRepo.GetQuestion(ctx, answerinfo.QuestionID)
if dberr != nil || !exist {
diff --git a/internal/service/content/search_service.go b/internal/service/content/search_service.go
index ccafcd82c..866f1c6e2 100644
--- a/internal/service/content/search_service.go
+++ b/internal/service/content/search_service.go
@@ -68,13 +68,14 @@ func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (res
resp = &schema.SearchResp{}
// search plugin is not found, call system search
if finder == nil {
- if cond.SearchAll() {
+ switch {
+ case cond.SearchAll():
resp.SearchResults, resp.Total, err =
ss.searchRepo.SearchContents(ctx, cond.Words, cond.Tags, cond.UserID, cond.VoteAmount, dto.Page, dto.Size, dto.Order)
- } else if cond.SearchQuestion() {
+ case cond.SearchQuestion():
resp.SearchResults, resp.Total, err =
ss.searchRepo.SearchQuestions(ctx, cond.Words, cond.Tags, cond.NotAccepted, cond.Views, cond.AnswerAmount, dto.Page, dto.Size, dto.Order)
- } else if cond.SearchAnswer() {
+ case cond.SearchAnswer():
resp.SearchResults, resp.Total, err =
ss.searchRepo.SearchAnswers(ctx, cond.Words, cond.Tags, cond.Accepted, cond.QuestionID, dto.Page, dto.Size, dto.Order)
}
@@ -86,11 +87,12 @@ func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (res
func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Search, cond *schema.SearchCondition, dto *schema.SearchDTO) (resp *schema.SearchResp, err error) {
var res []plugin.SearchResult
resp = &schema.SearchResp{}
- if cond.SearchAll() {
+ switch {
+ case cond.SearchAll():
res, resp.Total, err = finder.SearchContents(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
- } else if cond.SearchQuestion() {
+ case cond.SearchQuestion():
res, resp.Total, err = finder.SearchQuestions(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
- } else if cond.SearchAnswer() {
+ case cond.SearchAnswer():
res, resp.Total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
}
if err != nil {
diff --git a/internal/service/content/user_service.go b/internal/service/content/user_service.go
index 81f7ac824..e9cc35788 100644
--- a/internal/service/content/user_service.go
+++ b/internal/service/content/user_service.go
@@ -314,7 +314,6 @@ func (us *UserService) UserModifyPassword(ctx context.Context, req *schema.UserM
// UpdateInfo update user info
func (us *UserService) UpdateInfo(ctx context.Context, req *schema.UpdateInfoRequest) (
errFields []*validator.FormErrorField, err error) {
-
if len(req.Username) > 0 {
if checker.IsInvalidUsername(req.Username) {
return append(errFields, &validator.FormErrorField{
@@ -598,7 +597,7 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri
// verifyPassword
// Compare whether the password is correct
-func (us *UserService) verifyPassword(ctx context.Context, loginPass, userPass string) bool {
+func (us *UserService) verifyPassword(_ context.Context, loginPass, userPass string) bool {
if len(loginPass) == 0 && len(userPass) == 0 {
return true
}
@@ -608,8 +607,8 @@ func (us *UserService) verifyPassword(ctx context.Context, loginPass, userPass s
// encryptPassword
// The password does irreversible encryption.
-func (us *UserService) encryptPassword(ctx context.Context, Pass string) (string, error) {
- hashPwd, err := bcrypt.GenerateFromPassword([]byte(Pass), bcrypt.DefaultCost)
+func (us *UserService) encryptPassword(_ context.Context, pass string) (string, error) {
+ hashPwd, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
// This encrypted string can be saved to the database and can be used as password matching verification
return string(hashPwd), err
}
diff --git a/internal/service/dashboard/dashboard_service.go b/internal/service/dashboard/dashboard_service.go
index 91f0e338a..8b08ba02f 100644
--- a/internal/service/dashboard/dashboard_service.go
+++ b/internal/service/dashboard/dashboard_service.go
@@ -264,7 +264,7 @@ func (ds *dashboardService) voteCount(ctx context.Context) int64 {
return voteCount
}
-func (ds *dashboardService) remoteVersion(ctx context.Context) string {
+func (ds *dashboardService) remoteVersion(_ context.Context) string {
req, _ := http.NewRequest("GET", "https://answer.apache.org/data/latest.json?from_version="+constant.Version, nil)
req.Header.Set("User-Agent", "Answer/"+constant.Version)
httpClient := &http.Client{}
@@ -359,11 +359,9 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) {
res, err := ds.data.DB.QueryInterface(sql)
if err != nil {
log.Warnf("get db size failed: %s", err)
- } else {
- if len(res) > 0 && res[0]["db_size"] != nil {
- dbSizeStr, _ := res[0]["db_size"].(string)
- dbSize = dir.FormatFileSize(converter.StringToInt64(dbSizeStr))
- }
+ } else if len(res) > 0 && res[0]["db_size"] != nil {
+ dbSizeStr, _ := res[0]["db_size"].(string)
+ dbSize = dir.FormatFileSize(converter.StringToInt64(dbSizeStr))
}
case schemas.POSTGRES:
sql := fmt.Sprintf("SELECT pg_database_size('%s') AS db_size",
@@ -371,11 +369,9 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) {
res, err := ds.data.DB.QueryInterface(sql)
if err != nil {
log.Warnf("get db size failed: %s", err)
- } else {
- if len(res) > 0 && res[0]["db_size"] != nil {
- dbSizeStr, _ := res[0]["db_size"].(int32)
- dbSize = dir.FormatFileSize(int64(dbSizeStr))
- }
+ } else if len(res) > 0 && res[0]["db_size"] != nil {
+ dbSizeStr, _ := res[0]["db_size"].(int32)
+ dbSize = dir.FormatFileSize(int64(dbSizeStr))
}
case schemas.SQLITE:
dirSize, err := dir.DirSize(ds.data.DB.DataSourceName())
diff --git a/internal/service/notification/invite_answer_notification.go b/internal/service/notification/invite_answer_notification.go
index f68feb067..6b0407f9f 100644
--- a/internal/service/notification/invite_answer_notification.go
+++ b/internal/service/notification/invite_answer_notification.go
@@ -45,8 +45,7 @@ func (ns *ExternalNotificationService) handleInviteAnswerNotification(ctx contex
if !channel.Enable {
continue
}
- switch channel.Key {
- case constant.EmailChannel:
+ if channel.Key == constant.EmailChannel {
ns.sendInviteAnswerNotificationEmail(ctx, msg.ReceiverUserID, msg.ReceiverEmail, msg.ReceiverLang, msg.NewInviteAnswerTemplateRawData)
}
}
diff --git a/internal/service/notification/new_answer_notification.go b/internal/service/notification/new_answer_notification.go
index c54fd961c..4ae9ca9ea 100644
--- a/internal/service/notification/new_answer_notification.go
+++ b/internal/service/notification/new_answer_notification.go
@@ -45,8 +45,7 @@ func (ns *ExternalNotificationService) handleNewAnswerNotification(ctx context.C
if !channel.Enable {
continue
}
- switch channel.Key {
- case constant.EmailChannel:
+ if channel.Key == constant.EmailChannel {
ns.sendNewAnswerNotificationEmail(ctx, msg.ReceiverUserID, msg.ReceiverEmail, msg.ReceiverLang, msg.NewAnswerTemplateRawData)
}
}
diff --git a/internal/service/notification/new_comment_notification.go b/internal/service/notification/new_comment_notification.go
index e622ed4f7..9734e54e5 100644
--- a/internal/service/notification/new_comment_notification.go
+++ b/internal/service/notification/new_comment_notification.go
@@ -45,8 +45,7 @@ func (ns *ExternalNotificationService) handleNewCommentNotification(ctx context.
if !channel.Enable {
continue
}
- switch channel.Key {
- case constant.EmailChannel:
+ if channel.Key == constant.EmailChannel {
ns.sendNewCommentNotificationEmail(ctx, msg.ReceiverUserID, msg.ReceiverEmail, msg.ReceiverLang, msg.NewCommentTemplateRawData)
}
}
diff --git a/internal/service/notification/new_question_notification.go b/internal/service/notification/new_question_notification.go
index debfb8c27..2f83042b2 100644
--- a/internal/service/notification/new_question_notification.go
+++ b/internal/service/notification/new_question_notification.go
@@ -55,8 +55,7 @@ func (ns *ExternalNotificationService) handleNewQuestionNotification(ctx context
if !channel.Enable {
continue
}
- switch channel.Key {
- case constant.EmailChannel:
+ if channel.Key == constant.EmailChannel {
ns.sendNewQuestionNotificationEmail(ctx, subscriber.UserID, &schema.NewQuestionTemplateRawData{
QuestionTitle: msg.NewQuestionTemplateRawData.QuestionTitle,
QuestionID: msg.NewQuestionTemplateRawData.QuestionID,
diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go
index 0369d4557..6a69cbaef 100644
--- a/internal/service/notification/notification_service.go
+++ b/internal/service/notification/notification_service.go
@@ -226,15 +226,12 @@ func (ns *NotificationService) GetNotificationPage(ctx context.Context, searchCo
if err != nil {
return nil, err
}
- resp, err = ns.formatNotificationPage(ctx, notifications)
- if err != nil {
- return nil, err
- }
+ resp = ns.formatNotificationPage(ctx, notifications)
return pager.NewPageModel(total, resp), nil
}
func (ns *NotificationService) formatNotificationPage(ctx context.Context, notifications []*entity.Notification) (
- resp []*schema.NotificationContent, err error) {
+ resp []*schema.NotificationContent) {
lang := handler.GetLangByCtx(ctx)
enableShortID := handler.GetEnableShortID(ctx)
userIDs := make([]string, 0)
@@ -287,13 +284,13 @@ func (ns *NotificationService) formatNotificationPage(ctx context.Context, notif
}
if len(userIDs) == 0 {
- return resp, nil
+ return resp
}
users, err := ns.userRepo.BatchGetByID(ctx, userIDs)
if err != nil {
log.Error(err)
- return resp, nil
+ return resp
}
userIDMapping := make(map[string]*entity.User, len(users))
for _, user := range users {
@@ -314,5 +311,5 @@ func (ns *NotificationService) formatNotificationPage(ctx context.Context, notif
}
}
}
- return resp, nil
+ return resp
}
diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go
index 55d638424..0bbd1865f 100644
--- a/internal/service/notification_common/notification.go
+++ b/internal/service/notification_common/notification.go
@@ -155,7 +155,7 @@ func (ns *NotificationCommon) AddNotification(ctx context.Context, msg *schema.N
}
req.Rank = rank
if exist {
- //modify notification
+ // modify notification
updateContent := &schema.NotificationContent{}
err := json.Unmarshal([]byte(notificationInfo.Content), updateContent)
if err != nil {
diff --git a/internal/service/plugin_common/plugin_common_service.go b/internal/service/plugin_common/plugin_common_service.go
index d3aa839b2..7d39a5aa0 100644
--- a/internal/service/plugin_common/plugin_common_service.go
+++ b/internal/service/plugin_common/plugin_common_service.go
@@ -69,7 +69,6 @@ func NewPluginCommonService(
data *data.Data,
importerService *importer.ImporterService,
) *PluginCommonService {
-
p := &PluginCommonService{
configService: configService,
pluginConfigRepo: pluginConfigRepo,
diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go
index 333806445..846dea894 100644
--- a/internal/service/question_common/question.go
+++ b/internal/service/question_common/question.go
@@ -179,17 +179,17 @@ func (qs *QuestionCommon) UpdateCollectionCount(ctx context.Context, questionID
return qs.questionRepo.UpdateCollectionCount(ctx, questionID)
}
-func (qs *QuestionCommon) UpdateAccepted(ctx context.Context, questionID, AnswerID string) error {
+func (qs *QuestionCommon) UpdateAccepted(ctx context.Context, questionID, answerID string) error {
question := &entity.Question{}
question.ID = questionID
- question.AcceptedAnswerID = AnswerID
+ question.AcceptedAnswerID = answerID
return qs.questionRepo.UpdateAccepted(ctx, question)
}
-func (qs *QuestionCommon) UpdateLastAnswer(ctx context.Context, questionID, AnswerID string) error {
+func (qs *QuestionCommon) UpdateLastAnswer(ctx context.Context, questionID, answerID string) error {
question := &entity.Question{}
question.ID = questionID
- question.LastAnswerID = AnswerID
+ question.LastAnswerID = answerID
return qs.questionRepo.UpdateLastAnswer(ctx, question)
}
@@ -232,7 +232,7 @@ func (qs *QuestionCommon) InviteUserInfo(ctx context.Context, questionID string)
if !has {
return InviteUserInfo, errors.NotFound(reason.QuestionNotFound)
}
- //InviteUser
+ // InviteUser
if dbinfo.InviteUserID != "" {
InviteUserIDs := make([]string, 0)
err := json.Unmarshal([]byte(dbinfo.InviteUserID), &InviteUserIDs)
@@ -681,7 +681,6 @@ func (qs *QuestionCommon) ShowFormat(ctx context.Context, data *entity.Question)
info.LastAnsweredUserID = answerInfo.UserID
}
}
-
}
info.Tags = make([]*schema.TagResp, 0)
return &info
diff --git a/internal/service/siteinfo_common/siteinfo_service_test.go b/internal/service/siteinfo_common/siteinfo_service_test.go
index 3a567dcb9..a87d427f2 100644
--- a/internal/service/siteinfo_common/siteinfo_service_test.go
+++ b/internal/service/siteinfo_common/siteinfo_service_test.go
@@ -27,6 +27,7 @@ import (
"github.com/apache/answer/internal/entity"
"github.com/apache/answer/internal/service/mock"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
)
@@ -46,6 +47,6 @@ func TestSiteInfoCommonService_GetSiteGeneral(t *testing.T) {
mockInit(ctl)
siteInfoCommonService := NewSiteInfoCommonService(mockSiteInfoRepo)
resp, err := siteInfoCommonService.GetSiteGeneral(context.TODO())
- assert.NoError(t, err)
- assert.Equal(t, resp.Name, "name")
+ require.NoError(t, err)
+ assert.Equal(t, "name", resp.Name)
}
diff --git a/internal/service/tag/tag_service.go b/internal/service/tag/tag_service.go
index 577199ec8..e61bfa06e 100644
--- a/internal/service/tag/tag_service.go
+++ b/internal/service/tag/tag_service.go
@@ -74,7 +74,7 @@ func NewTagService(
// RemoveTag delete tag
func (ts *TagService) RemoveTag(ctx context.Context, req *schema.RemoveTagReq) (err error) {
- //If the tag has associated problems, it cannot be deleted
+ // If the tag has associated problems, it cannot be deleted
tagCount, err := ts.tagCommonService.CountTagRelByTagID(ctx, req.TagID)
if err != nil {
return err
@@ -83,7 +83,7 @@ func (ts *TagService) RemoveTag(ctx context.Context, req *schema.RemoveTagReq) (
return errors.BadRequest(reason.TagIsUsedCannotDelete)
}
- //If the tag has associated problems, it cannot be deleted
+ // If the tag has associated problems, it cannot be deleted
tagSynonymCount, err := ts.tagRepo.GetTagSynonymCount(ctx, req.TagID)
if err != nil {
return err
diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go
index fed5dfbfb..87c10bcc9 100644
--- a/internal/service/tag_common/tag_common.go
+++ b/internal/service/tag_common/tag_common.go
@@ -591,7 +591,6 @@ func (ts *TagCommonService) CheckTag(ctx context.Context, tags []string, userID
err = errors.BadRequest(reason.TagNotFound).WithMsg(fmt.Sprintf("tag [%s] does not exist",
strings.Join(addTagMsgList, ",")))
return err
-
}
return nil
@@ -660,9 +659,8 @@ func (ts *TagCommonService) CheckChangeReservedTag(ctx context.Context, oldobjec
// ObjectChangeTag change object tag list
func (ts *TagCommonService) ObjectChangeTag(ctx context.Context, objectTagData *schema.TagChange, minimumTags int) (errorlist []*validator.FormErrorField, err error) {
- //checks if the tags sent in the put req are less than the minimum, if so, tag changes are not applied
+ // checks if the tags sent in the put req are less than the minimum, if so, tag changes are not applied
if len(objectTagData.Tags) < minimumTags {
-
errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags",
@@ -884,11 +882,11 @@ func (ts *TagCommonService) UpdateTag(ctx context.Context, req *schema.UpdateTag
return errors.BadRequest(reason.TagNotFound)
}
- //Adding equivalent slug formatting for tag update
+ // Adding equivalent slug formatting for tag update
slugName := strings.ReplaceAll(req.SlugName, " ", "-")
slugName = strings.ToLower(slugName)
- //If the content is the same, ignore it
+ // If the content is the same, ignore it
if tagInfo.OriginalText == req.OriginalText &&
tagInfo.DisplayName == req.DisplayName &&
tagInfo.SlugName == slugName {
diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go
index 30029193b..8dea746ce 100644
--- a/internal/service/uploader/upload.go
+++ b/internal/service/uploader/upload.go
@@ -135,7 +135,6 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur
}
us.fileRecordService.AddFileRecord(ctx, userID, avatarFilePath, url, string(plugin.UserAvatar))
return url, nil
-
}
func (us *uploaderService) AvatarThumbFile(ctx *gin.Context, fileName string, size int) (url string, err error) {
@@ -304,7 +303,6 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) (
}
us.fileRecordService.AddFileRecord(ctx, userID, avatarFilePath, url, string(plugin.AdminBranding))
return url, nil
-
}
func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.FileHeader, fileSubPath string) (
diff --git a/internal/service/user_admin/user_backyard.go b/internal/service/user_admin/user_backyard.go
index 6fce161ce..fcced1c8b 100644
--- a/internal/service/user_admin/user_backyard.go
+++ b/internal/service/user_admin/user_backyard.go
@@ -470,14 +470,15 @@ func (us *UserAdminService) GetUserPage(ctx context.Context, req *schema.GetUser
user := &entity.User{}
_ = copier.Copy(user, req)
- if req.IsInactive() {
+ switch {
+ case req.IsInactive():
user.MailStatus = entity.EmailStatusToBeVerified
user.Status = entity.UserStatusAvailable
- } else if req.IsSuspended() {
+ case req.IsSuspended():
user.Status = entity.UserStatusSuspended
- } else if req.IsDeleted() {
+ case req.IsDeleted():
user.Status = entity.UserStatusDeleted
- } else {
+ default:
user.MailStatus = entity.EmailStatusAvailable
user.Status = entity.UserStatusAvailable
}
@@ -486,8 +487,8 @@ func (us *UserAdminService) GetUserPage(ctx context.Context, req *schema.GetUser
if email, e := mail.ParseAddress(req.Query); e == nil {
user.EMail = email.Address
req.Query = ""
- } else if strings.HasPrefix(req.Query, "user:") {
- id := strings.TrimSpace(strings.TrimPrefix(req.Query, "user:"))
+ } else if after, ok := strings.CutPrefix(req.Query, "user:"); ok {
+ id := strings.TrimSpace(after)
idSearch := true
for _, r := range id {
if !unicode.IsDigit(r) {
@@ -521,18 +522,19 @@ func (us *UserAdminService) GetUserPage(ctx context.Context, req *schema.GetUser
DisplayName: u.DisplayName,
Avatar: avatarMapping[u.ID].GetURL(),
}
- if u.Status == entity.UserStatusDeleted {
+ switch {
+ case u.Status == entity.UserStatusDeleted:
t.Status = constant.UserDeleted
t.DeletedAt = u.DeletedAt.Unix()
- } else if u.Status == entity.UserStatusSuspended {
+ case u.Status == entity.UserStatusSuspended:
t.Status = constant.UserSuspended
t.SuspendedAt = u.SuspendedAt.Unix()
if !u.SuspendedUntil.IsZero() {
t.SuspendedUntil = u.SuspendedUntil.Unix()
}
- } else if u.MailStatus == entity.EmailStatusToBeVerified {
+ case u.MailStatus == entity.EmailStatusToBeVerified:
t.Status = constant.UserInactive
- } else {
+ default:
t.Status = constant.UserNormal
}
resp = append(resp, t)
@@ -646,7 +648,6 @@ func (us *UserAdminService) CheckAndUnsuspendExpiredUsers(ctx context.Context) e
if user.Status == entity.UserStatusSuspended &&
!user.SuspendedUntil.IsZero() &&
user.SuspendedUntil.Before(now) {
-
log.Infof("Unsuspending user %s (ID: %s) - suspension expired at %v",
user.Username, user.ID, user.SuspendedUntil)
diff --git a/internal/service/user_common/user.go b/internal/service/user_common/user.go
index 124972a16..2e777f14c 100644
--- a/internal/service/user_common/user.go
+++ b/internal/service/user_common/user.go
@@ -85,9 +85,9 @@ func NewUserCommon(
}
}
-func (us *UserCommon) GetUserBasicInfoByID(ctx context.Context, ID string) (
+func (us *UserCommon) GetUserBasicInfoByID(ctx context.Context, id string) (
userBasicInfo *schema.UserBasicInfo, exist bool, err error) {
- userInfo, exist, err := us.userRepo.GetByUserID(ctx, ID)
+ userInfo, exist, err := us.userRepo.GetByUserID(ctx, id)
if err != nil {
return nil, exist, err
}
diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go
index c40df55cf..8ab72fa94 100644
--- a/internal/service/user_notification_config/user_notification_config_service.go
+++ b/internal/service/user_notification_config/user_notification_config_service.go
@@ -96,7 +96,7 @@ func (us *UserNotificationConfigService) SetDefaultUserNotificationConfig(ctx co
string(constant.InboxSource), `[{"key":"email","enable":true}]`)
}
-func (us *UserNotificationConfigService) convertToEntity(ctx context.Context, userID string,
+func (us *UserNotificationConfigService) convertToEntity(_ context.Context, userID string,
source constant.NotificationSource, channel schema.NotificationChannelConfig) (c *entity.UserNotificationConfig) {
var channels schema.NotificationChannels
channels = append(channels, &channel)
diff --git a/pkg/checker/file_type.go b/pkg/checker/file_type.go
index ac1fbcaf9..8eaabcbfc 100644
--- a/pkg/checker/file_type.go
+++ b/pkg/checker/file_type.go
@@ -28,6 +28,7 @@ import (
"io"
"os"
"path/filepath"
+ "slices"
"strings"
"github.com/segmentfault/pacman/log"
@@ -38,12 +39,7 @@ import (
// WANING Only checks the file extension is not reliable, but `http.DetectContentType` and `mimetype` are not reliable for all file types.
func IsUnAuthorizedExtension(fileName string, allowedExtensions []string) bool {
ext := strings.ToLower(strings.Trim(filepath.Ext(fileName), "."))
- for _, extension := range allowedExtensions {
- if extension == ext {
- return false
- }
- }
- return true
+ return !slices.Contains(allowedExtensions, ext)
}
// DecodeAndCheckImageFile currently answers support image type is
diff --git a/pkg/checker/path_ignore.go b/pkg/checker/path_ignore.go
index 8be757be5..24b092f7c 100644
--- a/pkg/checker/path_ignore.go
+++ b/pkg/checker/path_ignore.go
@@ -20,6 +20,7 @@
package checker
import (
+ "slices"
"sync"
"github.com/apache/answer/configs"
@@ -46,21 +47,11 @@ func initPathIgnore() {
// IsUsersIgnorePath checks whether the username is in ignore path
func IsUsersIgnorePath(username string) bool {
ignorePathInit.Do(initPathIgnore)
- for _, u := range pathIgnore.Users {
- if u == username {
- return true
- }
- }
- return false
+ return slices.Contains(pathIgnore.Users, username)
}
// IsQuestionsIgnorePath checks whether the questionID is in ignore path
func IsQuestionsIgnorePath(questionID string) bool {
ignorePathInit.Do(initPathIgnore)
- for _, u := range pathIgnore.Questions {
- if u == questionID {
- return true
- }
- }
- return false
+ return slices.Contains(pathIgnore.Questions, questionID)
}
diff --git a/pkg/checker/question_link.go b/pkg/checker/question_link.go
index 41b246c36..efd19b3c3 100644
--- a/pkg/checker/question_link.go
+++ b/pkg/checker/question_link.go
@@ -44,15 +44,16 @@ func GetQuestionLink(content string) []QuestionLink {
left, right := 0, 0
for right < len(content) {
// find "/questions/" or "#"
- if right+11 < len(content) && content[right:right+11] == "/questions/" {
+ switch {
+ case right+11 < len(content) && content[right:right+11] == "/questions/":
left = right
right += 11
processURL(content, &left, &right, uniqueIDs, &questionLinks)
- } else if content[right] == '#' {
+ case content[right] == '#':
left = right + 1
right = left
processID(content, &left, &right, uniqueIDs, &questionLinks)
- } else {
+ default:
right++
}
}
@@ -101,9 +102,7 @@ func addUniqueID(questionID, answerID string, linkType int, uniqueIDs map[string
objectType, err := obj.GetObjectTypeStrByObjectID(uid.DeShortID(answerID))
if err != nil {
answerID = ""
- }
-
- if objectType == constant.AnswerObjectType {
+ } else if objectType == constant.AnswerObjectType {
if _, ok := uniqueIDs[answerID]; !ok {
uniqueIDs[answerID] = struct{}{}
isAdd = true
diff --git a/pkg/converter/markdown.go b/pkg/converter/markdown.go
index d16915a84..adae3faf6 100644
--- a/pkg/converter/markdown.go
+++ b/pkg/converter/markdown.go
@@ -107,7 +107,7 @@ func (r *DangerousHTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, n
}
n := node.(*ast.RawHTML)
l := n.Segments.Len()
- for i := 0; i < l; i++ {
+ for i := range l {
segment := n.Segments.At(i)
if string(source[segment.Start:segment.Stop]) == "" || string(source[segment.Start:segment.Stop]) == " " {
_, _ = w.Write(segment.Value(source))
@@ -122,15 +122,13 @@ func (r *DangerousHTMLRenderer) renderHTMLBlock(w util.BufWriter, source []byte,
n := node.(*ast.HTMLBlock)
if entering {
l := n.Lines().Len()
- for i := 0; i < l; i++ {
+ for i := range l {
line := n.Lines().At(i)
r.Writer.SecureWrite(w, line.Value(source))
}
- } else {
- if n.HasClosure() {
- closure := n.ClosureLine
- r.Writer.SecureWrite(w, closure.Value(source))
- }
+ } else if n.HasClosure() {
+ closure := n.ClosureLine
+ r.Writer.SecureWrite(w, closure.Value(source))
}
return ast.WalkContinue, nil
}
@@ -184,8 +182,8 @@ func (r *DangerousHTMLRenderer) renderAutoLink(w util.BufWriter, source []byte,
return ast.WalkContinue, nil
}
-func (r *DangerousHTMLRenderer) renderLinkIsUrl(verifyUrl string) bool {
- isURL := govalidator.IsURL(verifyUrl)
- isPath, _ := regexp.MatchString(`^/`, verifyUrl)
+func (r *DangerousHTMLRenderer) renderLinkIsUrl(verifyURL string) bool {
+ isURL := govalidator.IsURL(verifyURL)
+ isPath, _ := regexp.MatchString(`^/`, verifyURL)
return isURL || isPath
}
diff --git a/pkg/day/day.go b/pkg/day/day.go
index 90afac0ad..2fd86a6c9 100644
--- a/pkg/day/day.go
+++ b/pkg/day/day.go
@@ -20,6 +20,7 @@
package day
import (
+ "strings"
"time"
)
@@ -50,16 +51,16 @@ func Format(unix int64, format, tz string) (formatted string) {
for i := l; i >= 0; i-- {
format = strings.ReplaceAll(format, placeholders[i].old, placeholders[i].new)
}*/
- toFormat := ""
+ var toFormat strings.Builder
from := []rune(format)
for len(from) > 0 {
to, suffix := nextStdChunk(from)
- toFormat += string(to)
+ toFormat.WriteString(string(to))
from = suffix
}
_, _ = time.LoadLocation(tz)
- formatted = time.Unix(unix, 0).Format(toFormat)
+ formatted = time.Unix(unix, 0).Format(toFormat.String())
return
}
diff --git a/pkg/dir/dir.go b/pkg/dir/dir.go
index 928883c2e..09591f6ca 100644
--- a/pkg/dir/dir.go
+++ b/pkg/dir/dir.go
@@ -51,19 +51,19 @@ func DirSize(path string) (int64, error) {
}
func FormatFileSize(fileSize int64) (size string) {
- if fileSize < 1024 {
- //return strconv.FormatInt(fileSize, 10) + "B"
+ switch {
+ case fileSize < 1024:
+ // return strconv.FormatInt(fileSize, 10) + "B"
return fmt.Sprintf("%.2f B", float64(fileSize)/float64(1))
- } else if fileSize < (1024 * 1024) {
+ case fileSize < (1024 * 1024):
return fmt.Sprintf("%.2f KB", float64(fileSize)/float64(1024))
- } else if fileSize < (1024 * 1024 * 1024) {
+ case fileSize < (1024 * 1024 * 1024):
return fmt.Sprintf("%.2f MB", float64(fileSize)/float64(1024*1024))
- } else if fileSize < (1024 * 1024 * 1024 * 1024) {
+ case fileSize < (1024 * 1024 * 1024 * 1024):
return fmt.Sprintf("%.2f GB", float64(fileSize)/float64(1024*1024*1024))
- } else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) {
+ case fileSize < (1024 * 1024 * 1024 * 1024 * 1024):
return fmt.Sprintf("%.2f TB", float64(fileSize)/float64(1024*1024*1024*1024))
- } else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024)
+ default: // if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024)
return fmt.Sprintf("%.2f EB", float64(fileSize)/float64(1024*1024*1024*1024*1024))
}
-
}
diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go
index 56db4d2b2..e2e017c8d 100644
--- a/pkg/htmltext/htmltext.go
+++ b/pkg/htmltext/htmltext.go
@@ -77,14 +77,14 @@ func UrlTitle(title string) (text string) {
}
func clearEmoji(s string) string {
- ret := ""
+ var ret strings.Builder
rs := []rune(s)
- for i := 0; i < len(rs); i++ {
+ for i := range rs {
if len(string(rs[i])) != 4 {
- ret += string(rs[i])
+ ret.WriteString(string(rs[i]))
}
}
- return ret
+ return ret.String()
}
func convertChinese(content string) string {
@@ -164,7 +164,7 @@ func FetchRangedExcerpt(html, trimMarker string, offset int, limit int) (text st
text = trimMarker + text
}
if end < len(runeText) {
- text = text + trimMarker
+ text += trimMarker
}
return
@@ -189,8 +189,8 @@ func FetchMatchedExcerpt(html string, words []string, trimMarker string, trimLen
return FetchRangedExcerpt(html, trimMarker, runeOffset, runeLimit)
}
-func GetPicByUrl(Url string) string {
- res, err := http.Get(Url)
+func GetPicByUrl(url string) string {
+ res, err := http.Get(url)
if err != nil {
return ""
}
diff --git a/pkg/htmltext/htmltext_test.go b/pkg/htmltext/htmltext_test.go
index 63866eb28..39de9e960 100644
--- a/pkg/htmltext/htmltext_test.go
+++ b/pkg/htmltext/htmltext_test.go
@@ -186,11 +186,11 @@ func TestCutLongTitle(t *testing.T) {
// Exactly max bytes, no cutting needed
exact150 := strings.Repeat("a", 150)
- assert.Equal(t, 150, len(cutLongTitle(exact150)))
+ assert.Len(t, cutLongTitle(exact150), 150)
// Just over max bytes, should be cut
exact151 := strings.Repeat("a", 151)
- assert.Equal(t, 150, len(cutLongTitle(exact151)))
+ assert.Len(t, cutLongTitle(exact151), 150)
// Multi-byte rune at boundary gets removed properly
asciiPart := strings.Repeat("a", 149) // 149 bytes
diff --git a/plugin/plugin_test/plugin_main_test.go b/plugin/plugin_test/plugin_main_test.go
index fd9015c86..7ba6f8ae3 100644
--- a/plugin/plugin_test/plugin_main_test.go
+++ b/plugin/plugin_test/plugin_main_test.go
@@ -81,19 +81,16 @@ func TestMain(t *testing.M) {
_ = os.RemoveAll(dbSetting.Connection)
}
- defer func() {
- if tearDown != nil {
- tearDown()
- }
- }()
if err := initTestDataSource(dbSetting); err != nil {
panic(err)
}
log.Info("init test database successfully")
- if ret := t.Run(); ret != 0 {
- os.Exit(ret)
+ ret := t.Run()
+ if tearDown != nil {
+ tearDown()
}
+ os.Exit(ret)
}
type TestDBSetting struct {
@@ -155,7 +152,7 @@ func initDatabaseImage(dbSetting TestDBSetting) (connection string, cleanup func
return "", nil, fmt.Errorf("could not connect to docker: %s", err)
}
- //resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV)
+ // resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV)
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: dbSetting.ImageName,
Tag: dbSetting.ImageVersion,
From 6660cdf6e25df42a6e86deca5d25e9817d67a5d2 Mon Sep 17 00:00:00 2001
From: Krypt0n123 <352600525@qq.com>
Date: Tue, 2 Dec 2025 22:59:33 +0800
Subject: [PATCH 15/25] fix: add missing revision data for default content
(fixes #1436)
---
internal/migrations/init.go | 95 ++++++++++++++++++++++++++++++++++++-
1 file changed, 94 insertions(+), 1 deletion(-)
diff --git a/internal/migrations/init.go b/internal/migrations/init.go
index 184c986b9..8a72794fe 100644
--- a/internal/migrations/init.go
+++ b/internal/migrations/init.go
@@ -28,6 +28,7 @@ import (
"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
+ "github.com/apache/answer/internal/repo/revision"
"github.com/apache/answer/internal/repo/unique"
"github.com/apache/answer/internal/schema"
"github.com/segmentfault/pacman/log"
@@ -311,6 +312,7 @@ func (m *Mentor) initSiteInfoWrite() {
func (m *Mentor) initDefaultContent() {
uniqueIDRepo := unique.NewUniqueIDRepo(&data.Data{DB: m.engine})
+ revisionRepo := revision.NewRevisionRepo(&data.Data{DB: m.engine}, uniqueIDRepo)
now := time.Now()
tagId, err := uniqueIDRepo.GenUniqueIDStr(m.ctx, entity.Tag{}.TableName())
@@ -343,7 +345,7 @@ func (m *Mentor) initDefaultContent() {
return
}
- tag := entity.Tag{
+ tag := &entity.Tag{
ID: tagId,
SlugName: "support",
DisplayName: "support",
@@ -419,16 +421,74 @@ func (m *Mentor) initDefaultContent() {
if m.err != nil {
return
}
+ tagContent, err := json.Marshal(tag)
+ if err != nil {
+ m.err = err
+ return
+ }
+ m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{
+ UserID: tag.UserID,
+ ObjectID: tag.ID,
+ Title: tag.SlugName,
+ Content: string(tagContent),
+ Status: entity.RevisionReviewPassStatus,
+ }, true)
+ if m.err != nil {
+ return
+ }
+ tagForRevision := &entity.TagSimpleInfoForRevision{
+ ID: tag.ID,
+ MainTagID: tag.MainTagID,
+ MainTagSlugName: tag.MainTagSlugName,
+ SlugName: tag.SlugName,
+ DisplayName: tag.DisplayName,
+ Recommend: tag.Recommend,
+ Reserved: tag.Reserved,
+ RevisionID: tag.RevisionID,
+ }
_, m.err = m.engine.Context(m.ctx).Insert(q1)
if m.err != nil {
return
}
+ q1Revision := &entity.QuestionWithTagsRevision{
+ Question: *q1,
+ Tags: []*entity.TagSimpleInfoForRevision{tagForRevision},
+ }
+ q1Content, err := json.Marshal(q1Revision)
+ if err != nil {
+ m.err = err
+ return
+ }
+ m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{
+ UserID: q1.UserID,
+ ObjectID: q1.ID,
+ Title: q1.Title,
+ Content: string(q1Content),
+ Status: entity.RevisionReviewPassStatus,
+ }, true)
+ if m.err != nil {
+ return
+ }
_, m.err = m.engine.Context(m.ctx).Insert(a1)
if m.err != nil {
return
}
+ a1Content, err := json.Marshal(a1)
+ if err != nil {
+ m.err = err
+ return
+ }
+ m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{
+ UserID: a1.UserID,
+ ObjectID: a1.ID,
+ Content: string(a1Content),
+ Status: entity.RevisionReviewPassStatus,
+ }, true)
+ if m.err != nil {
+ return
+ }
_, m.err = m.engine.Context(m.ctx).Insert(entity.TagRel{
ObjectID: q1.ID,
@@ -443,11 +503,44 @@ func (m *Mentor) initDefaultContent() {
if m.err != nil {
return
}
+ q2Revision := &entity.QuestionWithTagsRevision{
+ Question: *q2,
+ Tags: []*entity.TagSimpleInfoForRevision{tagForRevision},
+ }
+ q2Content, err := json.Marshal(q2Revision)
+ if err != nil {
+ m.err = err
+ return
+ }
+ m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{
+ UserID: q2.UserID,
+ ObjectID: q2.ID,
+ Title: q2.Title,
+ Content: string(q2Content),
+ Status: entity.RevisionReviewPassStatus,
+ }, true)
+ if m.err != nil {
+ return
+ }
_, m.err = m.engine.Context(m.ctx).Insert(a2)
if m.err != nil {
return
}
+ a2Content, err := json.Marshal(a2)
+ if err != nil {
+ m.err = err
+ return
+ }
+ m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{
+ UserID: a2.UserID,
+ ObjectID: a2.ID,
+ Content: string(a2Content),
+ Status: entity.RevisionReviewPassStatus,
+ }, true)
+ if m.err != nil {
+ return
+ }
_, m.err = m.engine.Context(m.ctx).Insert(entity.TagRel{
ObjectID: q2.ID,
From 740ac61bb228ec48bf3d15231e4ec6ccc30a8bfc Mon Sep 17 00:00:00 2001
From: liruohrh <2372221537@qq.com>
Date: Tue, 2 Dec 2025 01:21:49 +0800
Subject: [PATCH 16/25] fix: get right lang
---
internal/base/handler/handler.go | 8 +++----
internal/base/handler/lang.go | 10 ---------
internal/base/middleware/accept_language.go | 5 ++---
internal/controller/answer_controller.go | 6 ++---
internal/controller/comment_controller.go | 6 ++---
internal/controller/lang_controller.go | 2 +-
internal/controller/question_controller.go | 14 ++++++------
internal/controller/report_controller.go | 2 +-
internal/controller/search_controller.go | 2 +-
internal/controller/template_controller.go | 10 ++++-----
internal/controller/user_controller.go | 22 +++++++++----------
internal/controller/vote_controller.go | 8 +++----
.../user_backyard_controller.go | 2 +-
internal/service/importer/importer_service.go | 2 +-
plugin/plugin.go | 2 +-
15 files changed, 44 insertions(+), 57 deletions(-)
diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go
index b545b5e01..0c2fe8f4f 100644
--- a/internal/base/handler/handler.go
+++ b/internal/base/handler/handler.go
@@ -23,7 +23,6 @@ import (
"errors"
"net/http"
- "github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/reason"
"github.com/apache/answer/internal/base/validator"
"github.com/gin-gonic/gin"
@@ -33,7 +32,7 @@ import (
// HandleResponse Handle response body
func HandleResponse(ctx *gin.Context, err error, data any) {
- lang := GetLang(ctx)
+ lang := GetLangByCtx(ctx)
// no error
if err == nil {
ctx.JSON(http.StatusOK, NewRespBodyData(http.StatusOK, reason.Success, data).TrMsg(lang))
@@ -63,8 +62,7 @@ func HandleResponse(ctx *gin.Context, err error, data any) {
// BindAndCheck bind request and check
func BindAndCheck(ctx *gin.Context, data any) bool {
- lang := GetLang(ctx)
- ctx.Set(constant.AcceptLanguageFlag, lang)
+ lang := GetLangByCtx(ctx)
if err := ctx.ShouldBind(data); err != nil {
log.Errorf("http_handle BindAndCheck fail, %s", err.Error())
HandleResponse(ctx, myErrors.New(http.StatusBadRequest, reason.RequestFormatError), nil)
@@ -81,7 +79,7 @@ func BindAndCheck(ctx *gin.Context, data any) bool {
// BindAndCheckReturnErr bind request and check
func BindAndCheckReturnErr(ctx *gin.Context, data any) (errFields []*validator.FormErrorField) {
- lang := GetLang(ctx)
+ lang := GetLangByCtx(ctx)
if err := ctx.ShouldBind(data); err != nil {
log.Errorf("http_handle BindAndCheck fail, %s", err.Error())
HandleResponse(ctx, myErrors.New(http.StatusBadRequest, reason.RequestFormatError), nil)
diff --git a/internal/base/handler/lang.go b/internal/base/handler/lang.go
index 4ff1ac7f1..8886f0631 100644
--- a/internal/base/handler/lang.go
+++ b/internal/base/handler/lang.go
@@ -23,19 +23,9 @@ import (
"context"
"github.com/apache/answer/internal/base/constant"
- "github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/i18n"
)
-// GetLang get language from header
-func GetLang(ctx *gin.Context) i18n.Language {
- acceptLanguage := ctx.GetHeader(constant.AcceptLanguageFlag)
- if len(acceptLanguage) == 0 {
- return i18n.DefaultLanguage
- }
- return i18n.Language(acceptLanguage)
-}
-
// GetLangByCtx get language from header
func GetLangByCtx(ctx context.Context) i18n.Language {
acceptLanguage, ok := ctx.Value(constant.AcceptLanguageContextKey).(i18n.Language)
diff --git a/internal/base/middleware/accept_language.go b/internal/base/middleware/accept_language.go
index ca8a1f903..5d1b12b2d 100644
--- a/internal/base/middleware/accept_language.go
+++ b/internal/base/middleware/accept_language.go
@@ -23,7 +23,6 @@ import (
"strings"
"github.com/apache/answer/internal/base/constant"
- "github.com/apache/answer/internal/base/handler"
"github.com/apache/answer/internal/base/translator"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/i18n"
@@ -33,8 +32,8 @@ import (
// ExtractAndSetAcceptLanguage extract accept language from header and set to context
func ExtractAndSetAcceptLanguage(ctx *gin.Context) {
// The language of our front-end configuration, like en_US
- lang := handler.GetLang(ctx)
- tag, _, err := language.ParseAcceptLanguage(string(lang))
+ acceptLanguage := ctx.GetHeader(constant.AcceptLanguageFlag)
+ tag, _, err := language.ParseAcceptLanguage(acceptLanguage)
if err != nil || len(tag) == 0 {
ctx.Set(constant.AcceptLanguageFlag, i18n.LanguageEnglish)
return
diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go
index 0e43121c5..e76b02ccc 100644
--- a/internal/controller/answer_controller.go
+++ b/internal/controller/answer_controller.go
@@ -89,7 +89,7 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -225,7 +225,7 @@ func (ac *AnswerController) AddAnswer(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -325,7 +325,7 @@ func (ac *AnswerController) UpdateAnswer(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go
index 65fbedf04..7289a0e18 100644
--- a/internal/controller/comment_controller.go
+++ b/internal/controller/comment_controller.go
@@ -106,7 +106,7 @@ func (cc *CommentController) AddComment(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -154,7 +154,7 @@ func (cc *CommentController) RemoveComment(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -215,7 +215,7 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller/lang_controller.go b/internal/controller/lang_controller.go
index c7c607bdc..1e70fa88c 100644
--- a/internal/controller/lang_controller.go
+++ b/internal/controller/lang_controller.go
@@ -48,7 +48,7 @@ func NewLangController(tr i18n.Translator, siteInfoService siteinfo_common.SiteI
// @Success 200 {object} handler.RespBody{}
// @Router /answer/api/v1/language/config [get]
func (u *LangController) GetLangMapping(ctx *gin.Context) {
- data, _ := u.translator.Dump(handler.GetLang(ctx))
+ data, _ := u.translator.Dump(handler.GetLangByCtx(ctx))
var resp map[string]any
_ = json.Unmarshal(data, &resp)
handler.HandleResponse(ctx, nil, resp)
diff --git a/internal/controller/question_controller.go b/internal/controller/question_controller.go
index 581cf548b..d5164fc86 100644
--- a/internal/controller/question_controller.go
+++ b/internal/controller/question_controller.go
@@ -94,7 +94,7 @@ func (qc *QuestionController) RemoveQuestion(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -419,7 +419,7 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -445,7 +445,7 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) {
return
}
if !req.CanAddTag && hasNewTag {
- lang := handler.GetLang(ctx)
+ lang := handler.GetLangByCtx(ctx)
msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[6]})
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
@@ -524,7 +524,7 @@ func (qc *QuestionController) AddQuestionByAnswer(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -646,7 +646,7 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -681,7 +681,7 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) {
return
}
if !req.CanAddTag && hasNewTag {
- lang := handler.GetLang(ctx)
+ lang := handler.GetLangByCtx(ctx)
msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[4]})
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
@@ -765,7 +765,7 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller/report_controller.go b/internal/controller/report_controller.go
index 28048dd3d..13b4c0953 100644
--- a/internal/controller/report_controller.go
+++ b/internal/controller/report_controller.go
@@ -79,7 +79,7 @@ func (rc *ReportController) AddReport(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller/search_controller.go b/internal/controller/search_controller.go
index 64acbe252..a5d3e8d13 100644
--- a/internal/controller/search_controller.go
+++ b/internal/controller/search_controller.go
@@ -78,7 +78,7 @@ func (sc *SearchController) Search(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go
index f6a442c21..257b02fa4 100644
--- a/internal/controller/template_controller.go
+++ b/internal/controller/template_controller.go
@@ -206,7 +206,7 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) {
UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
- siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name)
+ siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLangByCtx(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name)
tc.html(ctx, http.StatusOK, "question.html", siteInfo, gin.H{
"data": data,
"useTitle": UrlUseTitle,
@@ -461,7 +461,7 @@ func (tc *TemplateController) TagList(ctx *gin.Context) {
if req.Page > 1 {
siteInfo.Canonical = fmt.Sprintf("%s/tags?page=%d", siteInfo.General.SiteUrl, req.Page)
}
- siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLang(ctx), constant.TagsListTitleTrKey), siteInfo.General.Name)
+ siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLangByCtx(ctx), constant.TagsListTitleTrKey), siteInfo.General.Name)
tc.html(ctx, http.StatusOK, "tags.html", siteInfo, gin.H{
"page": page,
"data": data,
@@ -492,14 +492,14 @@ func (tc *TemplateController) TagInfo(ctx *gin.Context) {
}
siteInfo.Description = htmltext.FetchExcerpt(tagInfo.ParsedText, "...", 240)
if len(tagInfo.ParsedText) == 0 {
- siteInfo.Description = translator.Tr(handler.GetLang(ctx), constant.TagHasNoDescription)
+ siteInfo.Description = translator.Tr(handler.GetLangByCtx(ctx), constant.TagHasNoDescription)
}
siteInfo.Keywords = tagInfo.DisplayName
UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID
- siteInfo.Title = fmt.Sprintf("'%s' %s - %s", tagInfo.DisplayName, translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name)
+ siteInfo.Title = fmt.Sprintf("'%s' %s - %s", tagInfo.DisplayName, translator.Tr(handler.GetLangByCtx(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name)
tc.html(ctx, http.StatusOK, "tag-detail.html", siteInfo, gin.H{
"tag": tagInfo,
"questionList": questionList,
@@ -597,7 +597,7 @@ func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteI
data["title"] = siteInfo.General.Name
}
data["description"] = siteInfo.Description
- data["language"] = handler.GetLang(ctx)
+ data["language"] = handler.GetLangByCtx(ctx)
data["timezone"] = siteInfo.Interface.TimeZone
language := strings.ReplaceAll(siteInfo.Interface.Language, "_", "-")
data["lang"] = language
diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go
index cc89caf1a..77c806e07 100644
--- a/internal/controller/user_controller.go
+++ b/internal/controller/user_controller.go
@@ -142,7 +142,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -154,7 +154,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, ctx.ClientIP())
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "e_mail",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.EmailOrPasswordWrong),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.EmailOrPasswordWrong), errFields)
return
@@ -191,7 +191,7 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -286,7 +286,7 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -297,7 +297,7 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) {
if len(errFields) > 0 {
for _, field := range errFields {
field.ErrorMsg = translator.
- Tr(handler.GetLang(ctx), field.ErrorMsg)
+ Tr(handler.GetLangByCtx(ctx), field.ErrorMsg)
}
handler.HandleResponse(ctx, err, errFields)
} else {
@@ -364,7 +364,7 @@ func (uc *UserController) UserVerifyEmailSend(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -399,7 +399,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -415,7 +415,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
if !oldPassVerification {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "old_pass",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.OldPasswordVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.OldPasswordVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.OldPasswordVerificationFailed), errFields)
return
@@ -424,7 +424,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
if req.OldPass == req.Pass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "pass",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.NewPasswordSameAsPreviousSetting),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.NewPasswordSameAsPreviousSetting),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.NewPasswordSameAsPreviousSetting), errFields)
return
@@ -456,7 +456,7 @@ func (uc *UserController) UserUpdateInfo(ctx *gin.Context) {
req.IsAdmin = middleware.GetUserIsAdminModerator(ctx)
errFields, err := uc.userService.UpdateInfo(ctx, req)
for _, field := range errFields {
- field.ErrorMsg = translator.Tr(handler.GetLang(ctx), field.ErrorMsg)
+ field.ErrorMsg = translator.Tr(handler.GetLangByCtx(ctx), field.ErrorMsg)
}
handler.HandleResponse(ctx, err, errFields)
}
@@ -587,7 +587,7 @@ func (uc *UserController) UserChangeEmailSendCode(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller/vote_controller.go b/internal/controller/vote_controller.go
index 2e0ee6121..302796677 100644
--- a/internal/controller/vote_controller.go
+++ b/internal/controller/vote_controller.go
@@ -79,7 +79,7 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) {
return
}
if !can {
- lang := handler.GetLang(ctx)
+ lang := handler.GetLangByCtx(ctx)
msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: needRank})
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
@@ -91,7 +91,7 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
@@ -134,7 +134,7 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) {
return
}
if !can {
- lang := handler.GetLang(ctx)
+ lang := handler.GetLangByCtx(ctx)
msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: needRank})
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
@@ -145,7 +145,7 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) {
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
- ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
+ ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
diff --git a/internal/controller_admin/user_backyard_controller.go b/internal/controller_admin/user_backyard_controller.go
index 00dfa2c3d..1356c55a1 100644
--- a/internal/controller_admin/user_backyard_controller.go
+++ b/internal/controller_admin/user_backyard_controller.go
@@ -177,7 +177,7 @@ func (uc *UserAdminController) EditUserProfile(ctx *gin.Context) {
errFields, err := uc.userService.EditUserProfile(ctx, req)
for _, field := range errFields {
- field.ErrorMsg = translator.Tr(handler.GetLang(ctx), field.ErrorMsg)
+ field.ErrorMsg = translator.Tr(handler.GetLangByCtx(ctx), field.ErrorMsg)
}
handler.HandleResponse(ctx, err, errFields)
}
diff --git a/internal/service/importer/importer_service.go b/internal/service/importer/importer_service.go
index c7673ffb5..9d12bf07b 100644
--- a/internal/service/importer/importer_service.go
+++ b/internal/service/importer/importer_service.go
@@ -135,7 +135,7 @@ func (ip *ImporterService) ImportQuestion(ctx context.Context, questionInfo plug
return err
}
if !req.CanAddTag && hasNewTag {
- lang := handler.GetLang(ctx.(*gin.Context))
+ lang := handler.GetLangByCtx(ctx.(*gin.Context))
msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[6]})
log.Errorf("error: %v", msg)
return errors.BadRequest(msg)
diff --git a/plugin/plugin.go b/plugin/plugin.go
index 266848353..8778b1625 100644
--- a/plugin/plugin.go
+++ b/plugin/plugin.go
@@ -216,7 +216,7 @@ func (m *statusManager) UnmarshalJSON(data []byte) error {
// Translate translates the key to the current language of the context
func Translate(ctx *GinContext, key string) string {
- return translator.Tr(handler.GetLang(ctx), key)
+ return translator.Tr(handler.GetLangByCtx(ctx), key)
}
// TranslateWithData translates the key to the language with data
From 8e395d421e5ded9277414c69cee1452429acc524 Mon Sep 17 00:00:00 2001
From: kinjelom
Date: Sat, 22 Nov 2025 12:36:06 +0100
Subject: [PATCH 17/25] Polish translation
---
i18n/pl_PL.yaml | 544 ++++++++++++++++++++++++++----------------------
1 file changed, 300 insertions(+), 244 deletions(-)
diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml
index e5972d9b3..c5c97d118 100644
--- a/i18n/pl_PL.yaml
+++ b/i18n/pl_PL.yaml
@@ -486,43 +486,42 @@ backend:
title:
other: "[{{.SiteName}}] Potwierdź swój nowy adres e-mail"
body:
- other: "Confirm your new email address for {{.SiteName}} by clicking on the following link: \n{{.ChangeEmailUrl}} \n\nIf you did not request this change, please ignore this email. \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen."
+ other: "Potwierdź swój nowy adres e-mail dla {{.SiteName}}, klikając poniższy link: \n{{.ChangeEmailUrl}} \n\nJeśli nie prosiłeś(-aś) o zmianę adresu e-mail, zignoruj tę wiadomość. \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana."
new_answer:
title:
other: "[{{.SiteName}}] {{.DisplayName}} odpowiedział(-a) na pytanie"
body:
- other: "{{.QuestionTitle}} \n\n{{.DisplayName}}: \n{{.AnswerSummary}} \nView it on {{.SiteName}} \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen. \n\nUnsubscribe "
+ other: "{{.QuestionTitle}} \n\n{{.DisplayName}} napisał(-a): \n{{.AnswerSummary}} \nZobacz na {{.SiteName}} \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana. \n\nZrezygnuj z subskrypcji "
invited_you_to_answer:
title:
- other: "[{{.SiteName}}] {{.DisplayName}} zaprosił(a) Cię do odpowiedzi"
+ other: "[{{.SiteName}}] {{.DisplayName}} zaprosił(-a) Cię do odpowiedzi"
body:
- other: "{{.QuestionTitle}} \n\n{{.DisplayName}}: \nI think you may know the answer. \nView it on {{.SiteName}} \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen. \n\nUnsubscribe "
+ other: "{{.QuestionTitle}} \n\n{{.DisplayName}} napisał(-a): \nMyślę, że możesz znać odpowiedź. \nZobacz na {{.SiteName}} \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana. \n\nZrezygnuj z subskrypcji "
new_comment:
title:
- other: "[{{.SiteName}}] {{.DisplayName}} skomentował/-a Twój wpis"
+ other: "[{{.SiteName}}] {{.DisplayName}} skomentował(-a) Twój wpis"
body:
- other: "{{.QuestionTitle}} \n\n{{.DisplayName}}: \n{{.CommentSummary}} \nView it on {{.SiteName}} \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen. \n\nUnsubscribe "
+ other: "{{.QuestionTitle}} \n\n{{.DisplayName}} napisał(-a): \n{{.CommentSummary}} \nZobacz na {{.SiteName}} \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana. \n\nZrezygnuj z subskrypcji "
new_question:
title:
other: "[{{.SiteName}}] Nowe pytanie: {{.QuestionTitle}}"
body:
- other: "{{.QuestionTitle}} \n{{.Tags}} \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen. \n\nUnsubscribe "
+ other: "{{.QuestionTitle}} \n{{.Tags}} \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana. \n\nZrezygnuj z subskrypcji "
pass_reset:
title:
- other: "[{{.SiteName }}] Reset hasła"
+ other: "[{{.SiteName}}] Reset hasła"
body:
- other: "Somebody asked to reset your password on {{.SiteName}}. \n\nIf it was not you, you can safely ignore this email. \n\nClick the following link to choose a new password: \n{{.PassResetUrl}} \n \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen."
+ other: "Otrzymaliśmy prośbę o zresetowanie Twojego hasła w serwisie {{.SiteName}}. \n\nJeśli to nie Ty wysłałeś(-aś) tę prośbę, możesz bezpiecznie zignorować tę wiadomość. \n\nKliknij poniższy link, aby ustawić nowe hasło: \n{{.PassResetUrl}} \n \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana."
register:
title:
other: "[{{.SiteName}}] Potwierdź swoje nowe konto"
body:
- other: "Welcome to {{.SiteName}}! \n\nClick the following link to confirm and activate your new account: \n{{.RegisterUrl}} \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen."
+ other: "Witamy w {{.SiteName}}! \n\nKliknij poniższy link, aby potwierdzić i aktywować swoje nowe konto: \n{{.RegisterUrl}} \n\nJeśli powyższy link nie jest klikalny, spróbuj skopiować go i wkleić do paska adresu przeglądarki.\n \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana."
test:
title:
other: "[{{.SiteName}}] Wiadomość testowa"
body:
- other: "This is a test email.\n \n\n-- \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen."
- action_activity_type:
+ other: "To jest testowa wiadomość e-mail.\n \n\n-- \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana."
upvote:
other: oceń pozytywnie
upvoted:
@@ -573,244 +572,300 @@ backend:
name:
other: Pierwszy pozytywny głos
desc:
- other: First up voted a post.
+ other: Po raz pierwszy oddano pozytywny głos na post.
first_link:
name:
other: Pierwszy odnośnik
desc:
- other: First added a link to another post.
+ other: Po raz pierwszy dodano link do innego wpisu.
+
first_reaction:
name:
- other: Pierwsza Reakcja
+ other: Pierwsza reakcja
desc:
- other: First reacted to the post.
+ other: Po raz pierwszy zareagowano na wpis.
+
first_share:
name:
- other: Pierwsze udostępnianie
+ other: Pierwsze udostępnienie
desc:
- other: First shared a post.
+ other: Po raz pierwszy udostępniono wpis.
+
scholar:
name:
other: Scholar
desc:
- other: Zadane pytania i zaakceptowane odpowiedź.
+ other: Zadano pytanie i zaakceptowano odpowiedź.
+
commentator:
name:
- other: Commentator
+ other: Komentator
desc:
- other: Pozostaw 5 komentarzy.
+ other: Pozostawiono 5 komentarzy.
+
new_user_of_the_month:
name:
other: Nowy użytkownik miesiąca
desc:
- other: Outstanding contributions in their first month.
+ other: Wyjątkowy wkład w pierwszym miesiącu aktywności.
+
read_guidelines:
name:
- other: Read Guidelines
+ other: Przeczytano zasady
desc:
- other: Read the [community guidelines].
+ other: Przeczytano [zasady społeczności].
+
reader:
name:
- other: Reader
+ other: Czytelnik
desc:
- other: Read every answers in a topic with more than 10 answers.
+ other: Przeczytano wszystkie odpowiedzi w wątku mającym ponad 10 odpowiedzi.
+
welcome:
name:
- other: Welcome
+ other: Witamy
desc:
- other: Received a up vote.
+ other: Otrzymano pozytywny głos.
+
nice_share:
name:
- other: Nice Share
+ other: Udane udostępnienie
desc:
- other: Shared a post with 25 unique visitors.
+ other: Udostępniono wpis, który odwiedziło 25 unikalnych użytkowników.
+
good_share:
name:
- other: Good Share
+ other: Dobre udostępnienie
desc:
- other: Shared a post with 300 unique visitors.
+ other: Udostępniono wpis, który odwiedziło 300 unikalnych użytkowników.
+
great_share:
name:
- other: Great Share
+ other: Świetne udostępnienie
desc:
- other: Shared a post with 1000 unique visitors.
+ other: Udostępniono wpis, który odwiedziło 1000 unikalnych użytkowników.
+
out_of_love:
name:
- other: Out of Love
+ other: Z miłości
desc:
- other: Used 50 up votes in a day.
+ other: Wykorzystano 50 pozytywnych głosów w ciągu dnia.
+
higher_love:
name:
- other: Higher Love
+ other: Więcej miłości
desc:
- other: Used 50 up votes in a day 5 times.
+ other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 5 razy.
+
crazy_in_love:
name:
- other: Crazy in Love
+ other: Szaleństwo miłości
desc:
- other: Used 50 up votes in a day 20 times.
+ other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 20 razy.
+
promoter:
name:
- other: Promoter
+ other: Promotor
desc:
- other: Invited a user.
+ other: Zaproszono użytkownika.
+
campaigner:
name:
- other: Campaigner
+ other: Kampanier
desc:
- other: Invited 3 basic users.
+ other: Zaproszono 3 podstawowych użytkowników.
+
champion:
name:
- other: Champion
+ other: Mistrz
desc:
- other: Invited 5 members.
+ other: Zaproszono 5 użytkowników.
+
thank_you:
name:
- other: Thank You
+ other: Dziękuję
desc:
- other: Has 20 up voted posts and gave 10 up votes.
+ other: Otrzymano 20 pozytywnych głosów i oddano 10.
+
gives_back:
name:
- other: Gives Back
+ other: Oddający dalej
desc:
- other: Has 100 up voted posts and gave 100 up votes.
+ other: Otrzymano 100 pozytywnych głosów i oddano 100.
+
empathetic:
name:
- other: Empathetic
+ other: Empatyczny
desc:
- other: Has 500 up voted posts and gave 1000 up votes.
+ other: Otrzymano 500 pozytywnych głosów i oddano 1000.
+
enthusiast:
name:
- other: Enthusiast
+ other: Entuzjasta
desc:
- other: Visited 10 consecutive days.
+ other: Odwiedzono serwis 10 dni z rzędu.
+
aficionado:
name:
- other: Aficionado
+ other: Koneser
desc:
- other: Visited 100 consecutive days.
+ other: Odwiedzono serwis 100 dni z rzędu.
+
devotee:
name:
- other: Devotee
+ other: Wytrwały
desc:
- other: Visited 365 consecutive days.
+ other: Odwiedzono serwis 365 dni z rzędu.
+
anniversary:
name:
- other: Anniversary
+ other: Rocznica
desc:
- other: Active member for a year, posted at least once.
+ other: Aktywny użytkownik od roku, co najmniej jeden wpis.
+
appreciated:
name:
- other: Appreciated
+ other: Doceniony
desc:
- other: Received 1 up vote on 20 posts.
+ other: Otrzymano 1 pozytywny głos na 20 wpisach.
+
respected:
name:
- other: Respected
+ other: Szanujący
desc:
- other: Received 2 up votes on 100 posts.
+ other: Otrzymano 2 pozytywne głosy na 100 wpisach.
+
admired:
name:
- other: Admired
+ other: Podziwiany
desc:
- other: Received 5 up votes on 300 posts.
+ other: Otrzymano 5 pozytywnych głosów na 300 wpisach.
+
solved:
name:
- other: Solved
+ other: Rozwiązane
desc:
- other: Have an answer be accepted.
+ other: Udzielono odpowiedzi, która została zaakceptowana.
+
guidance_counsellor:
name:
- other: Guidance Counsellor
+ other: Doradca
desc:
- other: Have 10 answers be accepted.
+ other: 10 udzielonych odpowiedzi zostało zaakceptowanych.
+
know_it_all:
name:
- other: Know-it-All
+ other: Wszystkowiedzący
desc:
- other: Have 50 answers be accepted.
+ other: 50 udzielonych odpowiedzi zostało zaakceptowanych.
+
solution_institution:
name:
- other: Solution Institution
+ other: Instytucja rozwiązań
desc:
- other: Have 150 answers be accepted.
+ other: 150 udzielonych odpowiedzi zostało zaakceptowanych.
+
nice_answer:
name:
- other: Nice Answer
+ other: Dobra odpowiedź
desc:
- other: Answer score of 10 or more.
+ other: Odpowiedź z wynikiem co najmniej 10.
+
good_answer:
name:
- other: Good Answer
+ other: Bardzo dobra odpowiedź
desc:
- other: Answer score of 25 or more.
+ other: Odpowiedź z wynikiem co najmniej 25.
+
great_answer:
name:
- other: Great Answer
+ other: Świetna odpowiedź
desc:
- other: Answer score of 50 or more.
+ other: Odpowiedź z wynikiem co najmniej 50.
+
nice_question:
name:
- other: Nice Question
+ other: Dobre pytanie
desc:
- other: Question score of 10 or more.
+ other: Pytanie z wynikiem co najmniej 10.
+
good_question:
name:
- other: Good Question
+ other: Bardzo dobre pytanie
desc:
- other: Question score of 25 or more.
+ other: Pytanie z wynikiem co najmniej 25.
+
great_question:
name:
- other: Great Question
+ other: Świetne pytanie
desc:
- other: Question score of 50 or more.
+ other: Pytanie z wynikiem co najmniej 50.
+
popular_question:
name:
- other: Popular Question
+ other: Popularne pytanie
desc:
- other: Question with 500 views.
+ other: Pytanie z 500 wyświetleniami.
+
notable_question:
name:
- other: Notable Question
+ other: Zauważalne pytanie
desc:
- other: Question with 1,000 views.
+ other: Pytanie z 1000 wyświetleniami.
+
famous_question:
name:
- other: Famous Question
+ other: Słynne pytanie
desc:
- other: Question with 5,000 views.
+ other: Pytanie z 5000 wyświetleniami.
+
popular_link:
name:
- other: Popular Link
+ other: Popularny link
desc:
- other: Posted an external link with 50 clicks.
+ other: Opublikowano zewnętrzny link z 50 kliknięciami.
+
hot_link:
name:
- other: Hot Link
+ other: Gorący link
desc:
- other: Posted an external link with 300 clicks.
+ other: Opublikowano zewnętrzny link z 300 kliknięciami.
+
famous_link:
name:
- other: Famous Link
+ other: Słynny link
desc:
- other: Posted an external link with 100 clicks.
+ other: Opublikowano zewnętrzny link z 1000 kliknięciami.
default_badge_groups:
getting_started:
name:
- other: Getting Started
+ other: Pierwsze kroki
community:
name:
- other: Community
+ other: Społeczność
posting:
name:
- other: Posting
+ other: Publikowanie
# The following fields are used for interface presentation(Front-end)
ui:
how_to_format:
title: Jak formatować
desc: >-
- mention a post: #post_id
to make links
<https://url.com> [Title](https://url.com)put returns between paragraphs
_italic_ or **bold **
indent code by 4 spaces
quote by placing > at start of line
backtick escapes `like _this_`
create code fences with backticks `
``` code here ```
- pagination:
+
+ wspomnij wpis: #post_id
+ tworzenie linków
+ <https://url.com> [Tytuł](https://url.com)
+
+ oddziel akapity pustą linią
+ _kursywa_ lub **pogrubienie **
+ zagnieźdź kod, dodając 4 spacje na początku wiersza
+ cytuj, dodając > na początku wiersza
+ użyj odwrotnego apostrofu (backtick) do zagnieżdżonego kodu `tak _to_ działa`
+ twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `
+ ``` kod tutaj ```
+
+
+ pagination:
prev: Poprzedni
next: Następny
page_title:
@@ -970,9 +1025,9 @@ ui:
heading: Nagłówek
cell: Komórka
file:
- text: Attach files
- not_supported: "Don’t support that file type. Try again with {{file_type}}."
- max_size: "Attach files size cannot exceed {{size}} MB."
+ text: Dołącz pliki
+ not_supported: "Ten typ pliku nie jest obsługiwany. Spróbuj ponownie z {{file_type}}."
+ max_size: "Rozmiar dołączanych plików nie może przekraczać {{size}} MB."
close_modal:
title: Zamykam ten post jako...
btn_cancel: Anuluj
@@ -1037,20 +1092,22 @@ ui:
delete:
title: Usuń ten tag
tip_with_posts: >-
- We do not allow deleting tag with posts .
Please remove this tag from the posts first.
+ Nie można usunąć tagu, który jest używany w postach .
+ Najpierw usuń ten tag z powiązanych postów.
tip_with_synonyms: >-
- We do not allow deleting tag with synonyms .
Please remove the synonyms from this tag first.
+ Nie można usunąć tagu, który ma synonimy .
+ Najpierw usuń synonimy przypisane do tego tagu.
tip: Czy na pewno chcesz usunąć?
close: Zamknij
merge:
- title: Merge tag
- source_tag_title: Source tag
- source_tag_description: The source tag and its associated data will be remapped to the target tag.
- target_tag_title: Target tag
- target_tag_description: A synonym between these two tags will be created after merging.
- no_results: No tags matched
- btn_submit: Submit
- btn_close: Close
+ title: Scal tag
+ source_tag_title: Źródłowy tag
+ source_tag_description: Źródłowy tag i wszystkie powiązane dane zostaną przemapowane na tag docelowy.
+ target_tag_title: Docelowy tag
+ target_tag_description: Po scaleniu zostanie utworzony synonim między tymi dwoma tagami.
+ no_results: Brak pasujących tagów
+ btn_submit: Zatwierdź
+ btn_close: Zamknij
edit_tag:
title: Edytuj tag
default_reason: Edytuj tag
@@ -1058,20 +1115,20 @@ ui:
btn_save_edits: Zapisz edycje
btn_cancel: Anuluj
dates:
- long_date: MMM D
- long_date_with_year: "MMM D, YYYY"
- long_date_with_time: "MMM D, YYYY [o] HH:mm"
+ long_date: D MMM
+ long_date_with_year: "YYYY MMM D"
+ long_date_with_time: "YYYY MMM D [o] HH:mm"
now: teraz
- x_seconds_ago: "{{count}} s temu"
- x_minutes_ago: "{{count}} min temu"
- x_hours_ago: "{{count}} h temu"
+ x_seconds_ago: "{{count}} sek. temu"
+ x_minutes_ago: "{{count}} min. temu"
+ x_hours_ago: "{{count}} godz. temu"
hour: godzina
day: dzień
hours: godziny
days: dni
month: month
months: months
- year: year
+ year: rok
reaction:
heart: serce
smile: uśmiech
@@ -1127,7 +1184,7 @@ ui:
more: Więcej
wiki: Wiki
ask:
- title: Create Question
+ title: Utwórz pytanie
edit_title: Edytuj pytanie
default_reason: Edytuj pytanie
default_first_reason: Create question
@@ -1138,7 +1195,7 @@ ui:
label: Rewizja
title:
label: Tytuł
- placeholder: What's your topic? Be specific.
+ placeholder: Jaki jest temat? Bądź konkretny.
msg:
empty: Tytuł nie może być pusty.
range: Tytuł do 150 znaków
@@ -1147,8 +1204,8 @@ ui:
msg:
empty: Treść nie może być pusta.
hint:
- optional_body: Describe what the question is about.
- minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required."
+ optional_body: Opisz, czego dotyczy pytanie.
+ minimum_characters: "Opisz, czego dotyczy pytanie — wymagane jest co najmniej {{min_content_length}} znaków."
tags:
label: Tagi
msg:
@@ -1169,9 +1226,9 @@ ui:
add_btn: Dodaj tag
create_btn: Utwórz nowy tag
search_tag: Wyszukaj tag
- hint: Describe what your content is about, at least one tag is required.
- hint_zero_tags: Describe what your content is about.
- hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required."
+ hint: Opisz, czego dotyczy Twoja treść — wymagany jest co najmniej jeden tag.
+ hint_zero_tags: Opisz, czego dotyczy Twoja treść.
+ hint_more_than_one_tag: "Opisz, czego dotyczy Twoja treść — wymagane są co najmniej {{min_tags_number}} tagi."
no_result: Nie znaleziono pasujących tagów
tag_required_text: Wymagany tag (co najmniej jeden)
header:
@@ -1179,7 +1236,7 @@ ui:
question: Pytania
tag: Tagi
user: Użytkownicy
- badges: Badges
+ badges: Odznaki
profile: Profil
setting: Ustawienia
logout: Wyloguj
@@ -1296,13 +1353,13 @@ ui:
display_name:
label: Nazwa wyświetlana
msg: Wyświetlana nazwa nie może być pusta.
- msg_range: Display name must be 2-30 characters in length.
+ msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków długości.
username:
label: Nazwa użytkownika
caption: Ludzie mogą oznaczać Cię jako "@nazwa_użytkownika".
msg: Nazwa użytkownika nie może być pusta.
- msg_range: Username must be 2-30 characters in length.
- character: 'Must use the character set "a-z", "0-9", "- . _"'
+ msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków długości.
+ character: 'Muszą być znaki ze zbioru "a-z", "0-9", "- . _"'
avatar:
label: Zdjęcie profilowe
gravatar: Gravatar
@@ -1391,11 +1448,11 @@ ui:
search: Wyszukaj osoby
question_detail:
action: Akcja
- created: Created
+ created: Utworzono
Asked: Zadane
asked: zadał(a)
update: Zmodyfikowane
- Edited: Edited
+ Edited: Wyedytowane
edit: edytowany
commented: skomentowano
Views: Wyświetlone
@@ -1442,7 +1499,7 @@ ui:
list:
confirm_btn: Lista
title: Pokaż ten post
- content: Are you sure you want to list?
+ content: Czy na pewno chcesz wyświetlić tę listę?
unlist:
confirm_btn: Usuń z listy
title: Usuń ten post z listy
@@ -1507,16 +1564,16 @@ ui:
normal: Normalny
closed: Zamknięty
deleted: Usunięty
- deleted_permanently: Deleted permanently
+ deleted_permanently: Usunięto trwale
pending: Oczekujący
more: Więcej
- view: View
- card: Card
- compact: Compact
- display_below: Display below
- always_display: Always display
- or: or
- back_sites: Back to sites
+ view: Podgląd
+ card: Karta
+ compact: Kompakt
+ display_below: Wyświetl poniżej
+ always_display: Wyświetlaj zawsze
+ or: lub
+ back_sites: Powrót do stron
search:
title: Wyniki wyszukiwania
keywords: Słowa kluczowe
@@ -1524,7 +1581,7 @@ ui:
follow: Obserwuj
following: Obserwuje
counts: "Liczba wyników: {{count}}"
- counts_loading: "... Results"
+ counts_loading: "... Wyniki"
more: Więcej
sort_btns:
relevance: Relewantność
@@ -1547,13 +1604,13 @@ ui:
via: Udostępnij post za pośrednictwem...
copied: Skopiowano
facebook: Udostępnij na Facebooku
- twitter: Share to X
+ twitter: Udostępnij na X
cannot_vote_for_self: Nie możesz głosować na własne posty.
modal_confirm:
title: Błąd...
delete_permanently:
- title: Delete permanently
- content: Are you sure you want to delete permanently?
+ title: Usuń trwale
+ content: Czy na pewno chcesz usunąć to trwale?
account_result:
success: Twoje nowe konto zostało potwierdzone; zostaniesz przekierowany na stronę główną.
link: Kontynuuj do strony głównej
@@ -1582,7 +1639,7 @@ ui:
newest: Najnowsze
active: Aktywne
hot: Gorące
- frequent: Frequent
+ frequent: Częste
recommend: Polecane
score: Ocena
unanswered: Bez odpowiedzi
@@ -1628,7 +1685,7 @@ ui:
x_votes: otrzymane głosy
x_answers: odpowiedzi
x_questions: pytania
- recent_badges: Recent Badges
+ recent_badges: Ostatnie odznaki
install:
title: Instalacja
next: Dalej
@@ -1667,14 +1724,14 @@ ui:
ssl_mode:
label: SSL Mode
ssl_root_cert:
- placeholder: sslrootcert file path
- msg: Path to sslrootcert file cannot be empty
+ placeholder: Ścieżka do pliku sslrootcert
+ msg: Ścieżka do pliku sslrootcert nie może być pusta
ssl_cert:
- placeholder: sslcert file path
- msg: Path to sslcert file cannot be empty
+ placeholder: Ścieżka do pliku sslcert
+ msg: Ścieżka do pliku sslcert nie może być pusta
ssl_key:
- placeholder: sslkey file path
- msg: Path to sslkey file cannot be empty
+ placeholder: Ścieżka do pliku sslkey
+ msg: Ścieżka do pliku sslkey nie może być pusta
config_yaml:
title: Utwórz plik config.yaml
label: Plik config.yaml utworzony.
@@ -1717,9 +1774,9 @@ ui:
msg_min_length: Hasło musi mieć co najmniej 8 znaków.
msg_max_length: Hasło musi mieć maksymalnie 32 znaki.
admin_confirm_password:
- label: "Confirm Password"
- text: "Please re-enter your password to confirm."
- msg: "Confirm password does not match."
+ label: "Potwierdź hasło"
+ text: "Wprowadź ponownie swoje hasło, aby potwierdzić."
+ msg: "Potwierdzenie hasła nie jest zgodne."
admin_email:
label: Email
text: Będziesz potrzebować tego adresu e-mail do logowania.
@@ -1777,7 +1834,7 @@ ui:
privileges: Uprawnienia
plugins: Wtyczki
installed_plugins: Zainstalowane wtyczki
- apperance: Appearance
+ apperance: Wygląd
website_welcome: Witamy w serwisie {{site_name}}
user_center:
login: Zaloguj się
@@ -1786,15 +1843,15 @@ ui:
badges:
modal:
title: Gratulacje
- content: You've earned a new badge.
- close: Close
- confirm: View badges
- title: Badges
- awarded: Awarded
- earned_×: Earned ×{{ number }}
- ×_awarded: "{{ number }} awarded"
- can_earn_multiple: You can earn this multiple times.
- earned: Earned
+ content: Zdobyłeś nową odznakę.
+ close: Zamknij
+ confirm: Zobacz odznaki
+ title: Odznaki
+ awarded: Przyznano
+ earned_×: Zdobyto ×{{ number }}
+ ×_awarded: „{{ number }} przyznano”
+ can_earn_multiple: Możesz zdobyć tę odznakę wielokrotnie.
+ earned: Zdobyto
admin:
admin_header:
title: Administrator
@@ -1803,15 +1860,15 @@ ui:
welcome: Witaj Administratorze!
site_statistics: Statystyki witryny
questions: "Pytania:"
- resolved: "Resolved:"
- unanswered: "Unanswered:"
+ resolved: "Rozwiązane:"
+ unanswered: "Bez odpowiedzi:"
answers: "Odpowiedzi:"
comments: "Komentarze:"
votes: "Głosy:"
users: "Użytkownicy:"
- flags: "Flagi:"
- reviews: "Reviews:"
- site_health: Site health
+ flags: "Zgłoszenia:"
+ reviews: "Przeglądy:"
+ site_health: "Stan serwisu"
version: "Wersja:"
https: "HTTPS:"
upload_folder: "Prześlij folder:"
@@ -1876,14 +1933,14 @@ ui:
form:
fields:
display_name:
- label: Display name
- msg_range: Display name must be 2-30 characters in length.
+ label: Wyświetlana nazwa
+ msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków.
username:
- label: Nazwa
- msg_range: Username must be 2-30 characters in length.
+ label: Nazwa użytkownika
+ msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków.
email:
label: Email
- msg_invalid: Błędny adresy email.
+ msg_invalid: Błędny adres e-mail.
edit_success: Edycja zakończona pomyślnie
btn_cancel: Anuluj
btn_submit: Prześlij
@@ -1898,7 +1955,7 @@ ui:
msg: "Podaj adresy e-mail użytkowników, jeden w każdej linii."
display_name:
label: Nazwa wyświetlana
- msg: Display name must be 2-30 characters in length.
+ msg: Wyświetlana nazwa musi mieć od 2 do 30 znaków.
email:
label: E-mail
msg: Email nie jest prawidłowy.
@@ -1912,10 +1969,10 @@ ui:
name: Imię
email: E-mail
reputation: Reputacja
- created_at: Created time
- delete_at: Deleted time
- suspend_at: Suspended time
- suspend_until: Suspend until
+ created_at: Czas utworzenia
+ delete_at: Czas usunięcia
+ suspend_at: Czas zawieszenia
+ suspend_until: Zawieszone do
status: Status
role: Rola
action: Akcja
@@ -1950,8 +2007,8 @@ ui:
suspend_user:
title: Zawieś tego użytkownika
content: Zawieszony użytkownik nie może się logować.
- label: How long will the user be suspended for?
- forever: Forever
+ label: Na jak długo użytkownik zostanie zawieszony?
+ forever: Na zawsze
questions:
page_title: Pytania
unlisted: Unlisted
@@ -2013,11 +2070,11 @@ ui:
msg: Strefa czasowa nie może być pusta.
text: Wybierz miasto w tej samej strefie czasowej, co Ty.
avatar:
- label: Default avatar
- text: For users without a custom avatar of their own.
+ label: Domyślny awatar
+ text: Dla użytkowników, którzy nie ustawili własnego awatara.
gravatar_base_url:
- label: Gravatar base URL
- text: URL of the Gravatar provider's API base. Ignored when empty.
+ label: Bazowy URL Gravatara
+ text: Adres bazowy API dostawcy Gravatara. Ignorowane, jeśli puste.
smtp:
page_title: SMTP
from_email:
@@ -2096,37 +2153,37 @@ ui:
restrict_answer:
title: Answer write
label: Każdy użytkownik może napisać tylko jedną odpowiedź na każde pytanie
- text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused."
+ text: "Wyłącz, aby pozwolić użytkownikom pisać wiele odpowiedzi na to samo pytanie, co może powodować, że odpowiedzi będą mniej skupione."
min_tags:
- label: "Minimum tags per question"
- text: "Minimum number of tags required in a question."
+ label: "Minimalna liczba tagów na pytanie"
+ text: "Minimalna liczba tagów wymagana w pytaniu."
recommend_tags:
label: Rekomendowane tagi
- text: "Recommend tags will show in the dropdown list by default."
+ text: "Rekomendowane tagi będą domyślnie wyświetlane na liście wyboru."
msg:
- contain_reserved: "recommended tags cannot contain reserved tags"
+ contain_reserved: "Rekomendowane tagi nie mogą zawierać tagów zarezerwowanych."
required_tag:
- title: Set required tags
- label: Set “Recommend tags” as required tags
+ title: Ustaw wymagane tagi
+ label: Ustaw „Rekomendowane tagi” jako wymagane
text: "Każde nowe pytanie musi mieć przynajmniej jeden rekomendowany tag."
reserved_tags:
label: Zarezerwowane tagi
- text: "Reserved tags can only be used by moderator."
+ text: "Zarezerwowane tagi mogą być używane tylko przez moderatorów."
image_size:
- label: Max image size (MB)
- text: "The maximum image upload size."
+ label: Maksymalny rozmiar obrazu (MB)
+ text: "Maksymalny dopuszczalny rozmiar przesyłanego obrazu."
attachment_size:
- label: Max attachment size (MB)
- text: "The maximum attachment files upload size."
+ label: Maksymalny rozmiar załącznika (MB)
+ text: "Maksymalny dopuszczalny rozmiar przesyłanych plików."
image_megapixels:
- label: Max image megapixels
- text: "Maximum number of megapixels allowed for an image."
+ label: Maksymalna liczba megapikseli
+ text: "Maksymalna liczba megapikseli dopuszczona dla obrazu."
image_extensions:
- label: Authorized image extensions
- text: "A list of file extensions allowed for image display, separate with commas."
+ label: Dozwolone rozszerzenia obrazów
+ text: "Lista rozszerzeń plików dozwolonych dla obrazów; oddziel po przecinkach."
attachment_extensions:
- label: Authorized attachment extensions
- text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues."
+ label: Dozwolone rozszerzenia załączników
+ text: "Lista rozszerzeń plików dozwolonych do przesyłania; oddziel po przecinkach. UWAGA: Zezwolenie na przesyłanie plików może powodować ryzyko bezpieczeństwa."
seo:
page_title: SEO
permalink:
@@ -2190,7 +2247,7 @@ ui:
text: "OSTRZEŻENIE: Jeśli wyłączone, już się nie zalogujesz, jeśli wcześniej nie skonfigurowałeś innej metody logowania."
installed_plugins:
title: Zainstalowane wtyczki
- plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository1>.
+ plugin_link: Wtyczki rozszerzają i rozbudowują funkcjonalność. Wtyczki znajdziesz w <1>Repozytorium Wtyczek1>.
filter:
all: Wszystkie
active: Aktywne
@@ -2232,25 +2289,25 @@ ui:
title: Uprawnienia
level:
label: Wymagany poziom reputacji
- text: Wybierz reputację wymaganą dla uprawnień
+ text: Wybierz reputację wymaganą dla tego uprawnienia
msg:
- should_be_number: the input should be number
- number_larger_1: number should be equal or larger than 1
+ should_be_number: Wartość musi być liczbą
+ number_larger_1: Liczba musi być równa 1 lub większa
badges:
- action: Action
- active: Active
- activate: Activate
- all: All
- awards: Awards
- deactivate: Deactivate
+ action: Akcja
+ active: Aktywne
+ activate: Aktywuj
+ all: Wszystkie
+ awards: Przyznane
+ deactivate: Dezaktywuj
filter:
- placeholder: Filter by name, badge:id
+ placeholder: Filtruj po nazwie, badge:id
group: Grupa
- inactive: Inactive
- name: Name
+ inactive: Nieaktywne
+ name: Nazwa
show_logs: Wyświetl dzienniki
status: Status
- title: Badges
+ title: Odznaki
form:
optional: (opcjonalne)
empty: nie może być puste
@@ -2273,11 +2330,11 @@ ui:
approve_flag_tip: Czy akceptujesz tę flagę?
approve_post_tip: Czy zatwierdzasz ten post?
approve_user_tip: Czy zatwierdzasz tego użytkownika?
- suggest_edits: Suggested edits
+ suggest_edits: Sugerowane edycje
flag_post: Oznacz wpis
flag_user: Oznacz użytkownika
- queued_post: Queued post
- queued_user: Queued user
+ queued_post: Oczekujący post
+ queued_user: Oczekujący użytkownik
filter_label: Typ
reputation: reputacja
flag_post_type: Oznaczono ten wpis jako {{ type }}.
@@ -2330,7 +2387,7 @@ ui:
discard_confirm: Czy na pewno chcesz odrzucić swoją wersję roboczą?
messages:
post_deleted: Ten post został usunięty.
- post_cancel_deleted: This post has been undeleted.
+ post_cancel_deleted: Usunięcie tego posta zostało anulowane.
post_pin: Ten post został przypięty.
post_unpin: Ten post został odpięty.
post_hide_list: Ten post został ukryty na liście.
@@ -2339,21 +2396,20 @@ ui:
post_list: Ten wpis został umieszczony na liście.
post_unlist: Ten wpis został usunięty z listy.
post_pending: Twój wpis oczekuje na recenzje. Będzie widoczny po jej akceptacji.
- post_closed: This post has been closed.
- answer_deleted: This answer has been deleted.
- answer_cancel_deleted: This answer has been undeleted.
- change_user_role: This user's role has been changed.
- user_inactive: This user is already inactive.
- user_normal: This user is already normal.
- user_suspended: This user has been suspended.
- user_deleted: This user has been deleted.
- badge_activated: This badge has been activated.
- badge_inactivated: This badge has been inactivated.
- users_deleted: These users have been deleted.
- posts_deleted: These questions have been deleted.
- answers_deleted: These answers have been deleted.
- copy: Copy to clipboard
- copied: Copied
- external_content_warning: External images/media are not displayed.
-
+ post_closed: Ten post został zamknięty.
+ answer_deleted: Ta odpowiedź została usunięta.
+ answer_cancel_deleted: Ta odpowiedź została przywrócona.
+ change_user_role: Rola tego użytkownika została zmieniona.
+ user_inactive: Ten użytkownik jest już nieaktywny.
+ user_normal: Ten użytkownik jest już aktywny.
+ user_suspended: Ten użytkownik został zawieszony.
+ user_deleted: Ten użytkownik został usunięty.
+ badge_activated: Ta odznaka została aktywowana.
+ badge_inactivated: Ta odznaka została dezaktywowana.
+ users_deleted: Ci użytkownicy zostali usunięci.
+ posts_deleted: Te pytania zostały usunięte.
+ answers_deleted: Te odpowiedzi zostały usunięte.
+ copy: Skopiuj do schowka
+ copied: Skopiowano
+ external_content_warning: Zewnętrzne obrazy/media nie są wyświetlane.
From 48b1de831473ed9e79fc4f453696428a43e69474 Mon Sep 17 00:00:00 2001
From: joaoback <156559121+joaoback@users.noreply.github.com>
Date: Fri, 12 Sep 2025 22:21:32 -0300
Subject: [PATCH 18/25] Update pt_BR.yaml
Translations of items that had not yet been translated. Adjustments to translations already made.
---
i18n/pt_BR.yaml | 248 ++++++++++++++++++++++++------------------------
1 file changed, 124 insertions(+), 124 deletions(-)
diff --git a/i18n/pt_BR.yaml b/i18n/pt_BR.yaml
index 42d56aaf7..45e00873c 100644
--- a/i18n/pt_BR.yaml
+++ b/i18n/pt_BR.yaml
@@ -288,7 +288,7 @@ ui:
change_email: Modificar e-mail
install: Instalação do Resposta
upgrade: Atualização do Resposta
- maintenance: Manutençã do Website
+ maintenance: Manutenção do Website
users: Usuários
notifications:
title: Notificações
@@ -327,7 +327,7 @@ ui:
empty: Código não pode ser vazio.
language:
label: Idioma (opcional)
- placeholder: Tetecção automática
+ placeholder: Detecção automática
btn_cancel: Cancelar
btn_confirm: Adicionar
formula:
@@ -351,7 +351,7 @@ ui:
image:
text: Imagem
add_image: Adicionar imagem
- tab_image: Enviar image,
+ tab_image: Enviar imagem
form_image:
fields:
file:
@@ -380,7 +380,7 @@ ui:
outdent:
text: Não identado
italic:
- text: Emphase
+ text: Ênfase
link:
text: Superlink (Hyperlink)
add_link: Adicionar superlink (hyperlink)
@@ -537,7 +537,7 @@ ui:
title: Adicionar Pergunta
edit_title: Editar Pergunta
default_reason: Editar pergunta
- similar_questions: Similar perguntas
+ similar_questions: Perguntas similares
form:
fields:
revision:
@@ -564,10 +564,10 @@ ui:
label: Resumo da edição
placeholder: >-
Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada)
- btn_post_question: Publicação a sua pergunta
+ btn_post_question: Publicar a sua pergunta
btn_save_edits: Salvar edições
answer_question: Responda a sua própria pergunta
- post_question&answer: Publicação a sua pergunta e resposta
+ post_question&answer: Publicar a sua pergunta e resposta
tag_selector:
add_btn: Adicionar marcador
create_btn: Criar novo marcador
@@ -589,7 +589,7 @@ ui:
placeholder: Procurar
footer:
build_on: >-
- Built on <1> Answer 1>- the open-source software that powers Q&A communities. Made with love © {{cc}}.
+ Desenvolvido com base no <1> Answer 1> — o software de código aberto que alimenta comunidades de perguntas e respostas. Feito com amor © {{cc}}.
upload_img:
name: Mudar
loading: carregando...
@@ -604,13 +604,13 @@ ui:
info: "Se não chegar, verifique sua pasta de spam."
another: >-
Enviamos outro e-mail de ativação para você em {{mail}} . Pode levar alguns minutos para chegar; certifique-se de verificar sua pasta de spam.
- btn_name: Resend activation email
+ btn_name: Reenviar e-mail de ativação
change_btn_name: Mudar email
msg:
empty: Não pode ser vazio.
login:
page_title: Bem vindo ao {{site_name}}
- login_to_continue: Entre para continue
+ login_to_continue: Entre para continuar
info_sign: Não possui uma conta? <1>Cadastrar-se1>
info_login: Já possui uma conta? <1>Entre1>
agreements: Ao se registrar, você concorda com as <1>políticas de privacidades1> e os <3>termos de serviços3>.
@@ -776,9 +776,9 @@ ui:
delete:
title: Excluir esta postagem
question: >-
- Nós não recomendamos excluindo perguntas com respostas porque isso priva os futuros leitores desse conhecimento.
Repeated deletion of answered questions can result in a sua account being blocked from asking. Você tem certeza que deseja deletar?
+ Nós não recomendamos excluir perguntas com respostas porque isso priva os futuros leitores desse conhecimento.
A exclusão repetida de perguntas respondidas pode resultar no bloqueio de perguntas de sua conta. Você tem certeza que deseja excluir?
answer_accepted: >-
-
Nós não recomendamos deleting accepted answer porque isso priva os futuros leitores desse conhecimento.
Repeated deletion of accepted answers can result in a sua account being blocked from answering. Você tem certeza que deseja deletar?
+ Não recomendamos excluir resposta aceita porque isso priva os futuros leitores desse conhecimento.
A exclusão repetida de respostas aceitas pode resultar no bloqueio de respostas de uma conta sua. Você tem certeza que deseja excluir?
other: Você tem certeza que deseja deletar?
tip_question_deleted: Esta postagem foi deletada
tip_answer_deleted: Esta resposta foi deletada
@@ -834,7 +834,7 @@ ui:
link: Continuar para a página inicial.
invalid: >-
Desculpe, este link de confirmação não é mais válido. Talvez a sua já está ativa.
- confirm_new_email: Your email has been updated.
+ confirm_new_email: Seu e-mail foi atualizado.
confirm_new_email_invalid: >-
Desculpe, este link de confirmação não é mais válido. Talvez o seu e-mail já tenha sido alterado.
unsubscribe:
@@ -846,7 +846,7 @@ ui:
following_tags: Seguindo Marcadores
edit: Editar
save: Salvar
- follow_tag_tip: Seguir tags to curate a sua lista de perguntas.
+ follow_tag_tip: Siga as tags para selecionar sua lista de perguntas.
hot_questions: Perguntas quentes
all_questions: Todas Perguntas
x_questions: "{{ count }} perguntas"
@@ -878,7 +878,7 @@ ui:
score: Pontuação
edit_profile: Editar Perfil
visited_x_days: "Visitado {{ count }} dias"
- viewed: Viewed
+ viewed: Visualizado
joined: Ingressou
last_login: Visto
about_me: Sobre mim
@@ -900,13 +900,13 @@ ui:
x_questions: perguntas
install:
title: Instalação
- next: Proximo
+ next: Próximo
done: Completo
config_yaml_error: Não é possível criar o arquivo config.yaml.
lang:
label: Por favor Escolha um Idioma
db_type:
- label: Database Engine
+ label: Mecanismo de banco de dados
db_username:
label: Nome de usuário
placeholder: root
@@ -916,68 +916,68 @@ ui:
placeholder: root
msg: Senha não pode ser vazio.
db_host:
- label: Database Host
+ label: Host do banco de dados
placeholder: "db:3306"
- msg: Database Host não pode ser vazio.
+ msg: Host de banco de dados não pode ficar vazio.
db_name:
- label: Database Nome
+ label: Nome do banco de dados
placeholder: answer
- msg: Database Nome não pode ser vazio.
+ msg: O nome do banco de dados não pode ficar vazio.
db_file:
- label: Database File
+ label: Arquivo de banco de dados
placeholder: /data/answer.db
- msg: Database File não pode ser vazio.
+ msg: O arquivo de banco de dados não pode ficar vazio.
config_yaml:
- title: Create config.yaml
- label: The config.yaml file created.
+ title: Criar config.yaml
+ label: O arquivo config.yaml foi criado.
desc: >-
- You can create the <1>config.yaml1> file manually in the <1>/var/wwww/xxx/1> directory and paste the following text into it.
- info: After you've done that, click "Next" button.
- site_information: Site Information
+ Você pode criar o arquivo <1>config.yaml1> manualmente no diretório <1>/var/www/xxx/1> e colar o seguinte texto nele.
+ info: Depois de fazer isso, clique no botão "Avançar".
+ site_information: Informações do site
admin_account: Administrador Conta
site_name:
label: Site Nome
msg: Site Nome não pode ser vazio.
site_url:
label: Site URL
- text: The address of a sua site.
+ text: O endereço do seu site.
msg:
empty: Site URL não pode ser vazio.
- incorrect: Site URL incorrect format.
+ incorrect: Formato incorreto da URL do site.
contact_email:
- label: E-mail par contato
- text: Email address of key contact responsible for this site.
+ label: E-mail para contato
+ text: Endereço de e-mail do contato principal responsável por este site.
msg:
- empty: E-mail par contato não pode ser vazio.
- incorrect: E-mail par contato incorrect format.
+ empty: E-mail para contato não pode ser vazio.
+ incorrect: E-mail para contato em formato incorreto.
admin_name:
label: Nome
msg: Nome não pode ser vazio.
admin_password:
label: Senha
text: >-
- You will need this password to log in. Por favor store it in a secure location.
- msg: Senha não pode ser vazio.
+ Você precisará dessa senha para efetuar login. Por favor, guarde-a em um local seguro.
+ msg: Senha não pode ser vazia.
admin_email:
label: Email
- text: You will need this email to log in.
+ text: Você precisará deste e-mail para fazer login.
msg:
empty: Email não pode ser vazio.
- incorrect: Email incorrect format.
- ready_title: Your Resposta is Ready!
+ incorrect: Formato de e-mail incorreto.
+ ready_title: Sua resposta está pronta!
ready_desc: >-
- If you ever feel like changing more settings, visit <1>admin section1>; find it in the site menu.
- good_luck: "Have fun, and good luck!"
- warn_title: Warning
+ Se você quiser alterar mais configurações, visite a <1>seção de administração1>; encontre-a no menu do site.
+ good_luck: "Divirta-se e boa sorte!"
+ warn_title: Aviso
warn_desc: >-
- The file <1>config.yaml1> already exists. If you need to reset any of the configuration items in this file, please delete it first.
- install_now: You may try <1>installing now1>.
- installed: Already installed
+ O arquivo <1>config.yaml1> já existe. Se precisar redefinir algum item de configuração neste arquivo, exclua-o primeiro.
+ install_now: Você pode tentar <1>instalar agora1>.
+ installed: Já instalado
installed_desc: >-
- You appear to have already installed. To reinstall please clear a sua old database tables first.
- db_failed: Database connection failed
+ Parece que você já instalou. Para reinstalar, limpe primeiro as tabelas antigas do seu banco de dados.
+ db_failed: Falha na conexão do banco de dados
db_failed_desc: >-
- This either means that the database information in a sua <1>config.yaml1> file is incorrect or that contact with the database server could not be established. This could mean a sua host's database server is down.
+ Isso significa que as informações do banco de dados em um arquivo <1>config.yaml1> do SUA estão incorretas ou que o contato com o servidor do banco de dados não pôde ser estabelecido. Isso pode significar que o servidor de banco de dados de um host SUA está inativo.
counts:
views: visualizações
Votos: votos
@@ -987,7 +987,7 @@ ui:
desc: "Infelizmente, esta postagem não existe mais."
back_home: Voltar para a página inicial
page_50X:
- desc: O servidor encontrou um erro e não pôde concluir uma solicitação sua.
+ desc: O servidor encontrou um erro e não pôde concluir sua solicitação.
back_home: Voltar para a página inicial
page_maintenance:
desc: "Estamos em manutenção, voltaremos em breve."
@@ -1037,7 +1037,7 @@ ui:
answer_links: Links das Respostas
documents: Documentos
feedback: Opinião
- support: Supporte
+ support: Suporte
review: Revisar
config: Configurações
update_to: Atualizar ao
@@ -1233,7 +1233,7 @@ ui:
smtp_port:
label: SMTP Port
msg: SMTP port must be number 1 ~ 65535.
- text: The port to a sua mail server.
+ text: A porta para seu servidor de e-mail.
smtp_username:
label: SMTP Nome de usuário
msg: SMTP username não pode ser vazio.
@@ -1241,9 +1241,9 @@ ui:
label: SMTP Senha
msg: SMTP password não pode ser vazio.
test_email_recipient:
- label: Test Email Recipients
- text: Provide email address that will receive test sends.
- msg: Test email recipients is invalid
+ label: Destinatários de e-mail de teste
+ text: Forneça o endereço de e-mail que receberá os envios de testes.
+ msg: Os destinatários do e-mail de teste são inválidos
smtp_authentication:
label: Enable authentication
title: SMTP Authentication
@@ -1255,127 +1255,127 @@ ui:
logo:
label: Logo (opcional)
msg: Logo não pode ser vazio.
- text: The logo image at the top left of a sua site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown.
+ text: A imagem do logotipo no canto superior esquerdo do seu site. Use uma imagem retangular larga com altura de 56 e proporção maior que 3:1. Se deixada em branco, o texto do título do site será exibido.
mobile_logo:
label: Mobile Logo (opcional)
- text: The logo used on mobile version of a sua site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used.
+ text: O logotipo usado na versão mobile do seu site. Use uma imagem retangular larga com altura de 56. Se deixado em branco, a imagem da configuração "logotipo" será usada.
square_icon:
label: Square Icon (opcional)
msg: Square icon não pode ser vazio.
- text: Imagem used as the base for metadata icons. Should ideally be larger than 512x512.
+ text: Imagem usada como base para ícones de metadados. Idealmente, deve ser maior que 512x512.
favicon:
label: Favicon (opcional)
- text: A favicon for a sua site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used.
+ text: Um favicon para o seu site. Para funcionar corretamente em uma CDN, ele deve ser um png. Será redimensionado para 32x32. Se deixado em branco, o "ícone quadrado" será usado.
legal:
page_title: Legal
terms_of_service:
- label: Terms of Service
- text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here."
+ label: Termos de Serviço
+ text: "Você pode adicionar conteúdo dos termos de serviço aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui."
privacy_policy:
- label: Privacy Policy
- text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here."
+ label: Política de Privacidade
+ text: "Você pode adicionar o conteúdo da política de privacidade aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui."
write:
- page_title: Write
+ page_title: Escrever
recommend_tags:
- label: Recommend Marcadores
- text: "Por favor input tag slug above, one tag per line."
+ label: Recomendar Marcadores
+ text: "Por favor, insira o slug da tag acima, uma tag por linha."
required_tag:
- title: Required Tag
- label: Set recommend tag as requirido
- text: "Every new question must have ao menos one recommend tag."
+ title: Tag necessária
+ label: Definir tag recomendada como necessária
+ text: "Cada nova pergunta deve ter pelo menos uma tag de recomendação."
reserved_tags:
- label: Reserved Marcadores
- text: "Reserved tags can only be added to a post by moderator."
+ label: Marcadores Reservados
+ text: "Tags reservadas só podem ser adicionadas a uma postagem pelo moderador."
seo:
page_title: SEO
permalink:
label: Permalink
- text: Custom URL structures can improve the usability, and forward-compatibility of a sua links.
+ text: Estruturas de URL personalizadas podem melhorar a usabilidade e a compatibilidade futura de seus links.
robots:
label: robots.txt
- text: This will permanently override any related site settings.
+ text: Isso substituirá permanentemente todas as configurações relacionadas do site.
Temas:
page_title: Temas
Temas:
label: Temas
- text: Select an existing Tema.
+ text: Selecione um tema existente.
navbar_style:
- label: Navbar Style
- text: Select an existing Tema.
+ label: Estilo da barra de navegação
+ text: Selecione um tema existente.
primary_color:
- label: Primary Color
- text: Modify the colors used by a sua Temas
+ label: Cor primária
+ text: Modifique as cores usadas por seus Temas
css_and_html:
- page_title: CSS and HTML
+ page_title: CSS e HTML
custom_css:
label: Custom CSS
- text: This will insert as
+ text: Isto será inserido como
head:
label: Head
- text: This will insert before
+ text: Isto será inserido antes de
header:
label: Header
- text: This will insert after
+ text: Isto será inserido após
footer:
label: Footer
- text: This will insert before .
+ text: Isso será inserido antes de .
login:
page_title: Login
membership:
- title: Membership
- label: Allow new registrations
- text: Turn off to prevent anyone from creating a new account.
+ title: Associação
+ label: Permitir novos registros
+ text: Desative para impedir que alguém crie uma nova conta.
private:
- title: Private
+ title: Privado
label: Login requirido
- text: Only logged in users can access this community.
+ text: Somente usuários logados podem acessar esta comunidade.
form:
empty: não pode ser vazio
- invalid: is invalid
+ invalid: é inválido
btn_submit: Salvar
- not_found_props: "Required property {{ key }} not found."
+ not_found_props: "Propriedade necessária {{ key }} não encontrada."
page_review:
review: Revisar
- proposed: proposed
- question_edit: Pergunta edit
- answer_edit: Resposta edit
- tag_edit: Tag edit
- edit_summary: Editar summary
- edit_question: Editar question
- edit_answer: Editar answer
+ proposed: proposta
+ question_edit: Editar Pergunta
+ answer_edit: Editar Resposta
+ tag_edit: Editar Tag
+ edit_summary: Editar resumo
+ edit_question: Editar pergunta
+ edit_answer: Editar resposta
edit_tag: Editar tag
- empty: No review tasks left.
+ empty: Não há mais tarefas de revisão.
timeline:
- undeleted: undeleted
- deleted: deleted
- downvote: downvote
- upvote: upvote
- accept: accept
- cancelled: cancelled
- commented: commented
+ undeleted: não excluído
+ deleted: apagado
+ downvote: voto negativo
+ upvote: voto positivo
+ accept: aceitar
+ cancelled: cancelado
+ commented: comentado
rollback: rollback
- edited: edited
- answered: answered
- asked: asked
- closed: closed
- reopened: reopened
- created: created
- title: "Histórico for"
- tag_title: "Timeline for"
- show_Votos: "Show Votos"
+ edited: editado
+ answered: respondido
+ asked: perguntado
+ closed: fechado
+ reopened: reaberto
+ created: criado
+ title: "Histórico para"
+ tag_title: "Linha do tempo para"
+ show_Votos: "Mostrar votos"
n_or_a: N/A
- title_for_question: "Timeline for"
- title_for_answer: "Timeline for answer to {{ title }} by {{ author }}"
- title_for_tag: "Timeline for tag"
+ title_for_question: "Linha do tempo para"
+ title_for_answer: "Linha do tempo para resposta a {{ title }} por {{ author }}"
+ title_for_tag: "Linha do tempo para tag"
datetime: Datetime
- type: Type
- by: By
- comment: Comment
- no_data: "We couldn't find anything."
+ type: Tipo
+ by: Por
+ comment: Comentário
+ no_data: "Não conseguimos encontrar nada."
users:
title: Usuários
- users_with_the_most_reputation: Usuários with the highest reputation scores
- users_with_the_most_vote: Usuários who voted the most
- staffs: Our community staff
- reputation: reputation
+ users_with_the_most_reputation: Usuários com as maiores pontuações de reputação
+ users_with_the_most_vote: Usuários que mais votaram
+ staffs: Nossa equipe comunitária
+ reputation: reputação
Votos: Votos
From 57ba299543e91b9f00362bfb3b0452bf2ccf0f35 Mon Sep 17 00:00:00 2001
From: Burak Tekin
Date: Thu, 11 Dec 2025 04:42:21 +0300
Subject: [PATCH 19/25] chore: turkish translation improved (#1454)
turkish translations improved
Co-authored-by: dashuai
---
i18n/tr_TR.yaml | 56 ++++++++++++++++++++++++-------------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml
index 92d97ebe2..86a6321c2 100644
--- a/i18n/tr_TR.yaml
+++ b/i18n/tr_TR.yaml
@@ -234,8 +234,8 @@ backend:
other: Güncelleme izni yok.
content_cannot_empty:
other: İçerik boş olamaz.
- content_less_than_minimum:
- other: Not enough content entered.
+ content_less_than_minumum:
+ other: Yeterli içerik girilmedi.
rank:
fail_to_meet_the_condition:
other: İtibar seviyesi koşulu karşılamıyor.
@@ -266,7 +266,7 @@ backend:
cannot_set_synonym_as_itself:
other: Bir etiketin eş anlamlısını kendisi olarak ayarlayamazsınız.
minimum_count:
- other: Not enough tags were entered.
+ other: Yeterli sayıda etiket girilmedi.
smtp:
config_from_name_cannot_be_email:
other: Gönderen adı bir e-posta adresi olamaz.
@@ -311,13 +311,13 @@ backend:
add_bulk_users_amount_error:
other: "Bir kerede eklediğiniz kullanıcı sayısı 1-{{.MaxAmount}} aralığında olmalıdır."
status_suspended_forever:
- other: "This user was suspended forever. This user doesn't meet a community guideline."
+ other: "Bu kullanıcı süresiz olarak askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor."
status_suspended_until:
- other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline."
+ other: "Bu kullanıcı {{.SuspendedUntil}} tarihine kadar askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor."
status_deleted:
- other: "This user was deleted."
+ other: "Bu kullanıcı silindi."
status_inactive:
- other: "This user is inactive."
+ other: "Bu kullanıcı aktif değil."
config:
read_config_failed:
other: Yapılandırma okunamadı.
@@ -821,7 +821,7 @@ ui:
tag_wiki: etiket wikisi
create_tag: Etiket Oluştur
edit_tag: Etiketi Düzenle
- ask_a_question: Create Question
+ ask_a_question: Soru Oluştur
edit_question: Soruyu Düzenle
edit_answer: Cevabı Düzenle
search: Ara
@@ -1069,9 +1069,9 @@ ui:
day: gün
hours: saatler
days: günler
- month: month
- months: months
- year: year
+ month: ay
+ months: aylar
+ year: yıl
reaction:
heart: kalp
smile: gülümseme
@@ -1127,10 +1127,10 @@ ui:
more: Daha Fazla
wiki: Wiki
ask:
- title: Create Question
+ title: Soru Oluştur
edit_title: Soruyu Düzenle
default_reason: Soruyu düzenle
- default_first_reason: Create question
+ default_first_reason: Soru oluştur
similar_questions: Benzer sorular
form:
fields:
@@ -1138,7 +1138,7 @@ ui:
label: Revizyon
title:
label: Başlık
- placeholder: What's your topic? Be specific.
+ placeholder: Konunuz nedir? Ayrıntılı belirtin.
msg:
empty: Başlık boş olamaz.
range: Başlık en fazla 150 karakter olabilir
@@ -1147,8 +1147,8 @@ ui:
msg:
empty: İçerik boş olamaz.
hint:
- optional_body: Describe what the question is about.
- minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required."
+ optional_body: Sorunun ne hakkında olduğunu açıklayın.
+ minimum_characters: "Sorunun ne hakkında olduğunu açıklayın, en az {{min_content_length}} karakter gereklidir."
tags:
label: Etiketler
msg:
@@ -1169,9 +1169,9 @@ ui:
add_btn: Etiket ekle
create_btn: Yeni etiket oluştur
search_tag: Etiket ara
- hint: Describe what your content is about, at least one tag is required.
- hint_zero_tags: Describe what your content is about.
- hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required."
+ hint: İçeriğinizin ne hakkında olduğunu açıklayın, en az bir etiket gereklidir.
+ hint_zero_tags: İçeriğinizin ne hakkında olduğunu açıklayın.
+ hint_more_than_one_tag: "İçeriğinizin ne hakkında olduğunu açıklayın, en az {{min_tags_number}} etiket gereklidir."
no_result: Eşleşen etiket bulunamadı
tag_required_text: Gerekli etiket (en az bir tane)
header:
@@ -1377,12 +1377,12 @@ ui:
review: Revizyonunuz incelendikten sonra görünecek.
sent_success: Başarıyla gönderildi
related_question:
- title: Related
+ title: İlgili
answers: cevap
linked_question:
- title: Linked
- description: Posts linked to
- no_linked_question: No contents linked from this content.
+ title: Bağlantılı
+ description: Bağlantılı gönderiler
+ no_linked_question: Bu içerikten bağlantı verilen içerik yok.
invite_to_answer:
title: İnsanları Davet Et
desc: Cevap verebileceğini düşündüğünüz kişileri davet edin.
@@ -1391,11 +1391,11 @@ ui:
search: Kişi ara
question_detail:
action: Eylem
- created: Created
+ created: Oluşturuldu
Asked: Soruldu
asked: sordu
update: Değiştirildi
- Edited: Edited
+ Edited: Düzenlendi
edit: düzenledi
commented: yorum yaptı
Views: Görüntülendi
@@ -1403,7 +1403,7 @@ ui:
Following: Takip Ediliyor
follow_tip: Bildirim almak için bu soruyu takip edin
answered: cevapladı
- closed_in: Şurada kapatıldı
+ closed_in: Burada kapatıldı
show_exist: Var olan soruyu göster.
useful: Faydalı
question_useful: Faydalı ve açık
@@ -2098,8 +2098,8 @@ ui:
label: Her kullanıcı aynı soru için sadece bir cevap yazabilir
text: "Kullanıcıların aynı soruya birden fazla cevap yazmasına izin vermek için kapatın, bu cevapların odaktan uzaklaşmasına neden olabilir."
min_tags:
- label: "Minimum tags per question"
- text: "Minimum number of tags required in a question."
+ label: "Soru başına minimum etiket"
+ text: "Bir soruda bulunması gereken minimum etiket sayısı."
recommend_tags:
label: Önerilen etiketler
text: "Önerilen etiketler varsayılan olarak açılır listede gösterilecektir."
From d468e2ba8dee2577ff0af8e7cbcfb2b111f6abdb Mon Sep 17 00:00:00 2001
From: liruohrh <2372221537@qq.com>
Date: Sun, 7 Dec 2025 00:51:15 +0800
Subject: [PATCH 20/25] feat: add env for glob load template files by gin debug
render
---
internal/base/server/http.go | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/internal/base/server/http.go b/internal/base/server/http.go
index 4fbb04cb2..512f3da21 100644
--- a/internal/base/server/http.go
+++ b/internal/base/server/http.go
@@ -22,6 +22,7 @@ package server
import (
"html/template"
"io/fs"
+ "os"
brotli "github.com/anargu/gin-brotli"
"github.com/apache/answer/internal/base/middleware"
@@ -53,9 +54,14 @@ func NewHTTPServer(debug bool,
r.Use(brotli.Brotli(brotli.DefaultCompression), middleware.ExtractAndSetAcceptLanguage, shortIDMiddleware.SetShortIDFlag())
r.GET("/healthz", func(ctx *gin.Context) { ctx.String(200, "OK") })
- html, _ := fs.Sub(ui.Template, "template")
- htmlTemplate := template.Must(template.New("").Funcs(funcMap).ParseFS(html, "*"))
- r.SetHTMLTemplate(htmlTemplate)
+ templatePath := os.Getenv("ANSWER_TEMPLATE_PATH")
+ if templatePath != "" {
+ r.LoadHTMLGlob(templatePath)
+ } else {
+ html, _ := fs.Sub(ui.Template, "template")
+ htmlTemplate := template.Must(template.New("").Funcs(funcMap).ParseFS(html, "*"))
+ r.SetHTMLTemplate(htmlTemplate)
+ }
r.Use(middleware.HeadersByRequestURI())
viewRouter.Register(r, uiConf.BaseURL)
From fbb877ab11760b69ee17cb0d00822fead64e60c9 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Thu, 11 Dec 2025 14:23:17 +0800
Subject: [PATCH 21/25] fix(translator): enhance error reporting for invalid
translator YAML files
---
internal/base/translator/provider.go | 165 +++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go
index 47212e84f..1a465b1e8 100644
--- a/internal/base/translator/provider.go
+++ b/internal/base/translator/provider.go
@@ -23,6 +23,8 @@ import (
"fmt"
"os"
"path/filepath"
+ "sort"
+ "strings"
"github.com/google/wire"
myTran "github.com/segmentfault/pacman/contrib/i18n"
@@ -100,6 +102,7 @@ func NewTranslator(c *I18n) (tr i18n.Translator, err error) {
// add translator use backend translation
if err = myTran.AddTranslator(content, file.Name()); err != nil {
log.Debugf("add translator failed: %s %s", file.Name(), err)
+ reportTranslatorFormatError(file.Name(), buf)
continue
}
}
@@ -160,3 +163,165 @@ func TrWithData(lang i18n.Language, key string, templateData any) string {
}
return translation
}
+
+// reportTranslatorFormatError re-parses the YAML file to locate the invalid entry
+// when go-i18n fails to add the translator.
+func reportTranslatorFormatError(fileName string, content []byte) {
+ var raw any
+ if err := yaml.Unmarshal(content, &raw); err != nil {
+ log.Errorf("parse translator file %s failed when diagnosing format error: %s", fileName, err)
+ return
+ }
+ if err := inspectTranslatorNode(raw, nil, true); err != nil {
+ log.Errorf("translator file %s invalid: %s", fileName, err)
+ }
+}
+
+func inspectTranslatorNode(node any, path []string, isRoot bool) error {
+ switch data := node.(type) {
+ case nil:
+ if isRoot {
+ return fmt.Errorf("root value is empty")
+ }
+ return fmt.Errorf("%s contains an empty value", formatTranslationPath(path))
+ case string:
+ if isRoot {
+ return fmt.Errorf("root value must be an object but found string")
+ }
+ return nil
+ case bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
+ if isRoot {
+ return fmt.Errorf("root value must be an object but found %T", data)
+ }
+ return fmt.Errorf("%s expects a string translation but found %T", formatTranslationPath(path), data)
+ case map[string]any:
+ if isMessageMap(data) {
+ return nil
+ }
+ keys := make([]string, 0, len(data))
+ for key := range data {
+ keys = append(keys, key)
+ }
+ sort.Strings(keys)
+ for _, key := range keys {
+ if err := inspectTranslatorNode(data[key], append(path, key), false); err != nil {
+ return err
+ }
+ }
+ return nil
+ case map[string]string:
+ mapped := make(map[string]any, len(data))
+ for k, v := range data {
+ mapped[k] = v
+ }
+ return inspectTranslatorNode(mapped, path, isRoot)
+ case map[any]any:
+ if isMessageMap(data) {
+ return nil
+ }
+ type kv struct {
+ key string
+ val any
+ }
+ items := make([]kv, 0, len(data))
+ for key, val := range data {
+ strKey, ok := key.(string)
+ if !ok {
+ return fmt.Errorf("%s uses a non-string key %#v", formatTranslationPath(path), key)
+ }
+ items = append(items, kv{key: strKey, val: val})
+ }
+ sort.Slice(items, func(i, j int) bool {
+ return items[i].key < items[j].key
+ })
+ for _, item := range items {
+ if err := inspectTranslatorNode(item.val, append(path, item.key), false); err != nil {
+ return err
+ }
+ }
+ return nil
+ case []any:
+ for idx, child := range data {
+ nextPath := append(path, fmt.Sprintf("[%d]", idx))
+ if err := inspectTranslatorNode(child, nextPath, false); err != nil {
+ return err
+ }
+ }
+ return nil
+ case []map[string]any:
+ for idx, child := range data {
+ nextPath := append(path, fmt.Sprintf("[%d]", idx))
+ if err := inspectTranslatorNode(child, nextPath, false); err != nil {
+ return err
+ }
+ }
+ return nil
+ default:
+ if isRoot {
+ return fmt.Errorf("root value must be an object but found %T", data)
+ }
+ return fmt.Errorf("%s contains unsupported value type %T", formatTranslationPath(path), data)
+ }
+}
+
+var translatorReservedKeys = []string{
+ "id", "description", "hash", "leftdelim", "rightdelim",
+ "zero", "one", "two", "few", "many", "other",
+}
+
+func isMessageMap(data any) bool {
+ switch v := data.(type) {
+ case map[string]any:
+ for _, key := range translatorReservedKeys {
+ val, ok := v[key]
+ if !ok {
+ continue
+ }
+ if _, ok := val.(string); ok {
+ return true
+ }
+ }
+ case map[string]string:
+ for _, key := range translatorReservedKeys {
+ val, ok := v[key]
+ if !ok {
+ continue
+ }
+ if val != "" {
+ return true
+ }
+ }
+ case map[any]any:
+ for _, key := range translatorReservedKeys {
+ val, ok := v[key]
+ if !ok {
+ continue
+ }
+ if _, ok := val.(string); ok {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func formatTranslationPath(path []string) string {
+ if len(path) == 0 {
+ return "root"
+ }
+ var b strings.Builder
+ for _, part := range path {
+ if part == "" {
+ continue
+ }
+ if part[0] == '[' {
+ b.WriteString(part)
+ continue
+ }
+ if b.Len() > 0 {
+ b.WriteByte('.')
+ }
+ b.WriteString(part)
+ }
+ return b.String()
+}
From f88ff2e2ca543cb45a62e9347f3e9161b0818f9d Mon Sep 17 00:00:00 2001
From: shuai
Date: Fri, 12 Dec 2025 17:37:21 +0800
Subject: [PATCH 22/25] fix: footer width should be aligned with main content
---
ui/src/pages/SideNavLayout/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/pages/SideNavLayout/index.tsx b/ui/src/pages/SideNavLayout/index.tsx
index 907b9b281..b9bc38b9c 100644
--- a/ui/src/pages/SideNavLayout/index.tsx
+++ b/ui/src/pages/SideNavLayout/index.tsx
@@ -38,7 +38,7 @@ const Index: FC = () => {
-
+
From e35b9551597aa5979b624b342e7e923cee814988 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Mon, 15 Dec 2025 12:34:42 +0800
Subject: [PATCH 23/25] fix(lang): enhance language retrieval from gin context
---
internal/base/handler/lang.go | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/internal/base/handler/lang.go b/internal/base/handler/lang.go
index 8886f0631..202449e9d 100644
--- a/internal/base/handler/lang.go
+++ b/internal/base/handler/lang.go
@@ -23,11 +23,22 @@ import (
"context"
"github.com/apache/answer/internal/base/constant"
+ "github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/i18n"
)
// GetLangByCtx get language from header
func GetLangByCtx(ctx context.Context) i18n.Language {
+ if ginCtx, ok := ctx.(*gin.Context); ok {
+ acceptLanguage, ok := ginCtx.Get(constant.AcceptLanguageFlag)
+ if ok {
+ if acceptLanguage, ok := acceptLanguage.(i18n.Language); ok {
+ return acceptLanguage
+ }
+ return i18n.DefaultLanguage
+ }
+ }
+
acceptLanguage, ok := ctx.Value(constant.AcceptLanguageContextKey).(i18n.Language)
if ok {
return acceptLanguage
From f43f22b91410030d87c4f06148ecee655b570e06 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Mon, 15 Dec 2025 15:08:51 +0800
Subject: [PATCH 24/25] fix(lang): correct translations in Polish and Turkish
language files
---
i18n/pl_PL.yaml | 3 +--
i18n/tr_TR.yaml | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml
index a8d7b064a..7cf88431b 100644
--- a/i18n/pl_PL.yaml
+++ b/i18n/pl_PL.yaml
@@ -864,8 +864,7 @@ ui:
twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `
``` kod tutaj ```
-
-
+
prev: Poprzedni
next: Następny
page_title:
diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml
index 970ae8cb2..802a81f69 100644
--- a/i18n/tr_TR.yaml
+++ b/i18n/tr_TR.yaml
@@ -235,7 +235,7 @@ backend:
content_cannot_empty:
other: İçerik boş olamaz.
content_less_than_minimum:
- other: Yeterli içerik girilmedi.
+ other: Not enough content entered.
rank:
fail_to_meet_the_condition:
other: İtibar seviyesi koşulu karşılamıyor.
From 59408774fba059d039846a88cf2aebd2b943c042 Mon Sep 17 00:00:00 2001
From: LinkinStars
Date: Mon, 15 Dec 2025 15:08:51 +0800
Subject: [PATCH 25/25] fix(lang): correct translations in Polish and Turkish
language files
---
i18n/pl_PL.yaml | 3 +--
i18n/tr_TR.yaml | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml
index a8d7b064a..7cf88431b 100644
--- a/i18n/pl_PL.yaml
+++ b/i18n/pl_PL.yaml
@@ -864,8 +864,7 @@ ui:
twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `
``` kod tutaj ```
-
-
+
prev: Poprzedni
next: Następny
page_title:
diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml
index 970ae8cb2..802a81f69 100644
--- a/i18n/tr_TR.yaml
+++ b/i18n/tr_TR.yaml
@@ -235,7 +235,7 @@ backend:
content_cannot_empty:
other: İçerik boş olamaz.
content_less_than_minimum:
- other: Yeterli içerik girilmedi.
+ other: Not enough content entered.
rank:
fail_to_meet_the_condition:
other: İtibar seviyesi koşulu karşılamıyor.