From d7afbbe2a5069bb5417db991afa4d9bb639c99db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 18:45:01 +0800 Subject: [PATCH 001/240] ci: update golangci/golangci-lint-action action to v5 (#554) --- .github/workflows/lint.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 872eb6ce2..a3b04ec85 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -48,8 +48,6 @@ jobs: - run: go get -t ./... - name: Run linters - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v5 with: version: v1.57.2 - skip-pkg-cache: true - skip-build-cache: true From c04be55895e325215cd296264fd06130364558b4 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Thu, 16 May 2024 00:11:08 +0800 Subject: [PATCH 002/240] feat: add missing subject type for relation responses (#559) --- openapi/v0.yaml | 10 +++++ web/handler/character/get_related_persons.go | 1 + web/handler/character/get_related_subjects.go | 1 + web/handler/person/get_related_characters.go | 2 +- web/handler/person/get_related_subjects.go | 1 + web/res/subject.go | 40 ++++++++++--------- 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 10d03ec39..4825439e1 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -1782,6 +1782,7 @@ components: - name - type - subject_id + - subject_type - subject_name - subject_name_cn type: object @@ -1806,6 +1807,8 @@ components: subject_id: title: Subject ID type: integer + subject_type: + $ref: "#/components/schemas/SubjectType" subject_name: title: Subject Name type: string @@ -2396,6 +2399,7 @@ components: - name - type - subject_id + - subject_type - subject_name - subject_name_cn type: object @@ -2419,6 +2423,8 @@ components: subject_id: title: Subject ID type: integer + subject_type: + $ref: "#/components/schemas/SubjectType" subject_name: title: Subject Name type: string @@ -2670,13 +2676,17 @@ components: title: RelatedSubject required: - id + - type - staff + - name - name_cn type: object properties: id: title: ID type: integer + type: + $ref: "#/components/schemas/SubjectType" staff: title: Staff type: string diff --git a/web/handler/character/get_related_persons.go b/web/handler/character/get_related_persons.go index d974d485b..421a237f9 100644 --- a/web/handler/character/get_related_persons.go +++ b/web/handler/character/get_related_persons.go @@ -63,6 +63,7 @@ func (h Character) GetRelatedPersons(c echo.Context) error { Type: cast.Person.Type, Images: res.PersonImage(cast.Person.Image), SubjectID: cast.Subject.ID, + SubjectType: cast.Subject.TypeID, SubjectName: cast.Subject.Name, SubjectNameCn: cast.Subject.NameCN, Staff: res.CharacterStaffString(mSubjectRelations[cast.Subject.ID]), diff --git a/web/handler/character/get_related_subjects.go b/web/handler/character/get_related_subjects.go index 9ed59b9c4..38ca03a30 100644 --- a/web/handler/character/get_related_subjects.go +++ b/web/handler/character/get_related_subjects.go @@ -50,6 +50,7 @@ func (h Character) GetRelatedSubjects(c echo.Context) error { s := relation.Subject response[i] = res.CharacterRelatedSubject{ ID: s.ID, + Type: s.TypeID, Name: s.Name, NameCn: s.NameCN, Staff: res.CharacterStaffString(relation.TypeID), diff --git a/web/handler/person/get_related_characters.go b/web/handler/person/get_related_characters.go index 098a38b96..4207cd4d4 100644 --- a/web/handler/person/get_related_characters.go +++ b/web/handler/person/get_related_characters.go @@ -43,7 +43,6 @@ func (h Person) GetRelatedCharacters(c echo.Context) error { } return errgo.Wrap(err, "failed to get person") } - if r.Redirect != 0 { return res.ErrNotFound } @@ -84,6 +83,7 @@ func (h Person) GetRelatedCharacters(c echo.Context) error { Type: rel.Character.Type, Images: res.PersonImage(rel.Character.Image), SubjectID: rel.Subject.ID, + SubjectType: rel.Subject.TypeID, SubjectName: rel.Subject.Name, SubjectNameCn: rel.Subject.NameCN, Staff: res.CharacterStaffString(subjectTypeID), diff --git a/web/handler/person/get_related_subjects.go b/web/handler/person/get_related_subjects.go index 062002c80..89aada773 100644 --- a/web/handler/person/get_related_subjects.go +++ b/web/handler/person/get_related_subjects.go @@ -60,6 +60,7 @@ func (h Person) GetRelatedSubjects(c echo.Context) error { for i, relation := range relations { response[i] = res.PersonRelatedSubject{ SubjectID: relation.Subject.ID, + Type: relation.Subject.TypeID, Staff: vars.StaffMap[relation.Subject.TypeID][relation.TypeID].String(), Name: relation.Subject.Name, NameCn: relation.Subject.NameCN, diff --git a/web/res/subject.go b/web/res/subject.go index b9a26aae5..d981c87b7 100644 --- a/web/res/subject.go +++ b/web/res/subject.go @@ -131,11 +131,12 @@ type Rating struct { } type PersonRelatedSubject struct { - Staff string `json:"staff"` - Name string `json:"name"` - NameCn string `json:"name_cn"` - Image string `json:"image"` - SubjectID model.SubjectID `json:"id"` + Staff string `json:"staff"` + Name string `json:"name"` + NameCn string `json:"name_cn"` + Image string `json:"image"` + Type model.SubjectType `json:"type"` + SubjectID model.SubjectID `json:"id"` } type PersonRelatedCharacter struct { @@ -143,6 +144,7 @@ type PersonRelatedCharacter struct { Name string `json:"name"` SubjectName string `json:"subject_name"` SubjectNameCn string `json:"subject_name_cn"` + SubjectType model.SubjectType `json:"subject_type"` SubjectID model.SubjectID `json:"subject_id"` Staff string `json:"staff"` ID model.CharacterID `json:"id"` @@ -150,22 +152,24 @@ type PersonRelatedCharacter struct { } type CharacterRelatedPerson struct { - Images PersonImages `json:"images"` - Name string `json:"name"` - SubjectName string `json:"subject_name"` - SubjectNameCn string `json:"subject_name_cn"` - SubjectID model.SubjectID `json:"subject_id"` - Staff string `json:"staff"` - ID model.PersonID `json:"id"` - Type uint8 `json:"type" doc:"person type"` + Images PersonImages `json:"images"` + Name string `json:"name"` + SubjectName string `json:"subject_name"` + SubjectNameCn string `json:"subject_name_cn"` + SubjectType model.SubjectType `json:"subject_type"` + SubjectID model.SubjectID `json:"subject_id"` + Staff string `json:"staff"` + ID model.PersonID `json:"id"` + Type uint8 `json:"type" doc:"person type"` } type CharacterRelatedSubject struct { - Staff string `json:"staff"` - Name string `json:"name"` - NameCn string `json:"name_cn"` - Image string `json:"image"` - ID model.SubjectID `json:"id"` + Staff string `json:"staff"` + Name string `json:"name"` + NameCn string `json:"name_cn"` + Image string `json:"image"` + Type model.SubjectType `json:"type"` + ID model.SubjectID `json:"id"` } type SubjectRelatedSubject struct { From a2dd2262a7939912e041227515aa9a9e9c510fa7 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Wed, 22 May 2024 22:40:39 +0800 Subject: [PATCH 003/240] feat: add API for PersonCollect (#561) --- .github/workflows/test.yaml | 5 + cmd/gen/gorm/main.go | 21 +- dal/dao/chii_person_collects.gen.go | 21 ++ dal/query/chii_person_collects.gen.go | 348 ++++++++++++++++++ dal/query/gen.go | 6 + internal/collections/domain.go | 30 +- .../collections/domain/collection/model.go | 15 + internal/collections/infra/mysql_repo.go | 143 +++++++ internal/collections/infra/mysql_repo_test.go | 196 ++++++++++ internal/mocks/CollectionRepo.go | 277 ++++++++++++++ ...tion.yaml => user_subject_collection.yaml} | 0 ...er_subject_collection_modify_payload.yaml} | 0 openapi/v0.yaml | 346 ++++++++++++++++- web/handler/character/character.go | 32 +- web/handler/character/collect.go | 90 +++++ web/handler/character/get.go | 4 +- web/handler/character/get_related_persons.go | 2 +- web/handler/character/get_related_subjects.go | 2 +- web/handler/person/collect.go | 92 +++++ web/handler/person/get_related_characters.go | 6 +- web/handler/person/person.go | 22 +- web/handler/user/collection_test.go | 148 ++++++++ web/handler/user/get_character_collection.go | 81 ++++ web/handler/user/get_person_collection.go | 77 ++++ .../user/list_character_collections.go | 103 ++++++ web/handler/user/list_person_collections.go | 102 +++++ web/handler/user/user.go | 38 +- web/res/collection.go | 30 ++ web/routes.go | 15 +- 29 files changed, 2195 insertions(+), 57 deletions(-) create mode 100644 dal/dao/chii_person_collects.gen.go create mode 100644 dal/query/chii_person_collects.gen.go rename openapi/components/{subject_collection.yaml => user_subject_collection.yaml} (100%) rename openapi/components/{subject_collection_modify_payload.yaml => user_subject_collection_modify_payload.yaml} (100%) create mode 100644 web/handler/character/collect.go create mode 100644 web/handler/person/collect.go create mode 100644 web/handler/user/get_character_collection.go create mode 100644 web/handler/user/get_person_collection.go create mode 100644 web/handler/user/list_character_collections.go create mode 100644 web/handler/user/list_person_collections.go diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9cd675630..2001ad827 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -59,6 +59,11 @@ jobs: - run: bash $HOME/dev-env/wait_mysql_ready.sh + - name: Check Gorm gen + run: | + task gorm + git diff --exit-code + - name: Run tests run: task coverage env: diff --git a/cmd/gen/gorm/main.go b/cmd/gen/gorm/main.go index d53ae03a4..841d551ba 100644 --- a/cmd/gen/gorm/main.go +++ b/cmd/gen/gorm/main.go @@ -24,6 +24,7 @@ NOTICE: package main import ( + "path/filepath" "strings" "gorm.io/gen" @@ -58,9 +59,9 @@ const createdTime = "CreatedTime" // generate code. func main() { g := gen.NewGenerator(gen.Config{ - OutPath: "./dal/query/", - OutFile: "./gen.go", - ModelPkgPath: "./dao/", + OutPath: filepath.Clean("./dal/query/"), + OutFile: "gen.go", + ModelPkgPath: "dao", WithUnitTest: false, // if you want the nullable field generation property to be pointer type, set FieldNullable true @@ -78,6 +79,7 @@ func main() { "github.com/bangumi/server/dal/utiltype", "gorm.io/plugin/soft_delete", ) + g.WithJSONTagNameStrategy(func(_ string) string { return "" }) @@ -210,6 +212,19 @@ func main() { gen.FieldTrimPrefix("interest_"), )) + g.ApplyBasic(g.GenerateModelAs("chii_person_collects", "PersonCollect", + gen.FieldTrimPrefix("prsn_clt_"), + gen.FieldType("prsn_clt_id", "uint32"), + gen.FieldType("prsn_clt_cat", "string"), + gen.FieldType("prsn_clt_uid", userIDTypeString), + gen.FieldType("prsn_clt_mid", "uint32"), + gen.FieldType("prsn_clt_dateline", "uint32"), + gen.FieldRename("prsn_clt_cat", "Category"), + gen.FieldRename("prsn_clt_uid", "UserID"), + gen.FieldRename("prsn_clt_mid", "TargetID"), + gen.FieldRename("prsn_clt_dateline", createdTime), + )) + g.ApplyBasic(g.GenerateModelAs("chii_index", "Index", gen.FieldTrimPrefix("idx_"), gen.FieldType("idx_id", "uint32"), diff --git a/dal/dao/chii_person_collects.gen.go b/dal/dao/chii_person_collects.gen.go new file mode 100644 index 000000000..19c9b72e8 --- /dev/null +++ b/dal/dao/chii_person_collects.gen.go @@ -0,0 +1,21 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +const TableNamePersonCollect = "chii_person_collects" + +// PersonCollect 人物收藏 +type PersonCollect struct { + ID uint32 `gorm:"column:prsn_clt_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` + Category string `gorm:"column:prsn_clt_cat;type:enum('prsn','crt');not null" json:""` + TargetID uint32 `gorm:"column:prsn_clt_mid;type:mediumint(8) unsigned;not null" json:""` + UserID uint32 `gorm:"column:prsn_clt_uid;type:mediumint(8) unsigned;not null" json:""` + CreatedTime uint32 `gorm:"column:prsn_clt_dateline;type:int(10) unsigned;not null" json:""` +} + +// TableName PersonCollect's table name +func (*PersonCollect) TableName() string { + return TableNamePersonCollect +} diff --git a/dal/query/chii_person_collects.gen.go b/dal/query/chii_person_collects.gen.go new file mode 100644 index 000000000..bd7753700 --- /dev/null +++ b/dal/query/chii_person_collects.gen.go @@ -0,0 +1,348 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "github.com/bangumi/server/dal/dao" +) + +func newPersonCollect(db *gorm.DB, opts ...gen.DOOption) personCollect { + _personCollect := personCollect{} + + _personCollect.personCollectDo.UseDB(db, opts...) + _personCollect.personCollectDo.UseModel(&dao.PersonCollect{}) + + tableName := _personCollect.personCollectDo.TableName() + _personCollect.ALL = field.NewAsterisk(tableName) + _personCollect.ID = field.NewUint32(tableName, "prsn_clt_id") + _personCollect.Category = field.NewString(tableName, "prsn_clt_cat") + _personCollect.TargetID = field.NewUint32(tableName, "prsn_clt_mid") + _personCollect.UserID = field.NewUint32(tableName, "prsn_clt_uid") + _personCollect.CreatedTime = field.NewUint32(tableName, "prsn_clt_dateline") + + _personCollect.fillFieldMap() + + return _personCollect +} + +// personCollect 人物收藏 +type personCollect struct { + personCollectDo personCollectDo + + ALL field.Asterisk + ID field.Uint32 + Category field.String + TargetID field.Uint32 + UserID field.Uint32 + CreatedTime field.Uint32 + + fieldMap map[string]field.Expr +} + +func (p personCollect) Table(newTableName string) *personCollect { + p.personCollectDo.UseTable(newTableName) + return p.updateTableName(newTableName) +} + +func (p personCollect) As(alias string) *personCollect { + p.personCollectDo.DO = *(p.personCollectDo.As(alias).(*gen.DO)) + return p.updateTableName(alias) +} + +func (p *personCollect) updateTableName(table string) *personCollect { + p.ALL = field.NewAsterisk(table) + p.ID = field.NewUint32(table, "prsn_clt_id") + p.Category = field.NewString(table, "prsn_clt_cat") + p.TargetID = field.NewUint32(table, "prsn_clt_mid") + p.UserID = field.NewUint32(table, "prsn_clt_uid") + p.CreatedTime = field.NewUint32(table, "prsn_clt_dateline") + + p.fillFieldMap() + + return p +} + +func (p *personCollect) WithContext(ctx context.Context) *personCollectDo { + return p.personCollectDo.WithContext(ctx) +} + +func (p personCollect) TableName() string { return p.personCollectDo.TableName() } + +func (p personCollect) Alias() string { return p.personCollectDo.Alias() } + +func (p personCollect) Columns(cols ...field.Expr) gen.Columns { + return p.personCollectDo.Columns(cols...) +} + +func (p *personCollect) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := p.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (p *personCollect) fillFieldMap() { + p.fieldMap = make(map[string]field.Expr, 5) + p.fieldMap["prsn_clt_id"] = p.ID + p.fieldMap["prsn_clt_cat"] = p.Category + p.fieldMap["prsn_clt_mid"] = p.TargetID + p.fieldMap["prsn_clt_uid"] = p.UserID + p.fieldMap["prsn_clt_dateline"] = p.CreatedTime +} + +func (p personCollect) clone(db *gorm.DB) personCollect { + p.personCollectDo.ReplaceConnPool(db.Statement.ConnPool) + return p +} + +func (p personCollect) replaceDB(db *gorm.DB) personCollect { + p.personCollectDo.ReplaceDB(db) + return p +} + +type personCollectDo struct{ gen.DO } + +func (p personCollectDo) Debug() *personCollectDo { + return p.withDO(p.DO.Debug()) +} + +func (p personCollectDo) WithContext(ctx context.Context) *personCollectDo { + return p.withDO(p.DO.WithContext(ctx)) +} + +func (p personCollectDo) ReadDB() *personCollectDo { + return p.Clauses(dbresolver.Read) +} + +func (p personCollectDo) WriteDB() *personCollectDo { + return p.Clauses(dbresolver.Write) +} + +func (p personCollectDo) Session(config *gorm.Session) *personCollectDo { + return p.withDO(p.DO.Session(config)) +} + +func (p personCollectDo) Clauses(conds ...clause.Expression) *personCollectDo { + return p.withDO(p.DO.Clauses(conds...)) +} + +func (p personCollectDo) Returning(value interface{}, columns ...string) *personCollectDo { + return p.withDO(p.DO.Returning(value, columns...)) +} + +func (p personCollectDo) Not(conds ...gen.Condition) *personCollectDo { + return p.withDO(p.DO.Not(conds...)) +} + +func (p personCollectDo) Or(conds ...gen.Condition) *personCollectDo { + return p.withDO(p.DO.Or(conds...)) +} + +func (p personCollectDo) Select(conds ...field.Expr) *personCollectDo { + return p.withDO(p.DO.Select(conds...)) +} + +func (p personCollectDo) Where(conds ...gen.Condition) *personCollectDo { + return p.withDO(p.DO.Where(conds...)) +} + +func (p personCollectDo) Order(conds ...field.Expr) *personCollectDo { + return p.withDO(p.DO.Order(conds...)) +} + +func (p personCollectDo) Distinct(cols ...field.Expr) *personCollectDo { + return p.withDO(p.DO.Distinct(cols...)) +} + +func (p personCollectDo) Omit(cols ...field.Expr) *personCollectDo { + return p.withDO(p.DO.Omit(cols...)) +} + +func (p personCollectDo) Join(table schema.Tabler, on ...field.Expr) *personCollectDo { + return p.withDO(p.DO.Join(table, on...)) +} + +func (p personCollectDo) LeftJoin(table schema.Tabler, on ...field.Expr) *personCollectDo { + return p.withDO(p.DO.LeftJoin(table, on...)) +} + +func (p personCollectDo) RightJoin(table schema.Tabler, on ...field.Expr) *personCollectDo { + return p.withDO(p.DO.RightJoin(table, on...)) +} + +func (p personCollectDo) Group(cols ...field.Expr) *personCollectDo { + return p.withDO(p.DO.Group(cols...)) +} + +func (p personCollectDo) Having(conds ...gen.Condition) *personCollectDo { + return p.withDO(p.DO.Having(conds...)) +} + +func (p personCollectDo) Limit(limit int) *personCollectDo { + return p.withDO(p.DO.Limit(limit)) +} + +func (p personCollectDo) Offset(offset int) *personCollectDo { + return p.withDO(p.DO.Offset(offset)) +} + +func (p personCollectDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *personCollectDo { + return p.withDO(p.DO.Scopes(funcs...)) +} + +func (p personCollectDo) Unscoped() *personCollectDo { + return p.withDO(p.DO.Unscoped()) +} + +func (p personCollectDo) Create(values ...*dao.PersonCollect) error { + if len(values) == 0 { + return nil + } + return p.DO.Create(values) +} + +func (p personCollectDo) CreateInBatches(values []*dao.PersonCollect, batchSize int) error { + return p.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (p personCollectDo) Save(values ...*dao.PersonCollect) error { + if len(values) == 0 { + return nil + } + return p.DO.Save(values) +} + +func (p personCollectDo) First() (*dao.PersonCollect, error) { + if result, err := p.DO.First(); err != nil { + return nil, err + } else { + return result.(*dao.PersonCollect), nil + } +} + +func (p personCollectDo) Take() (*dao.PersonCollect, error) { + if result, err := p.DO.Take(); err != nil { + return nil, err + } else { + return result.(*dao.PersonCollect), nil + } +} + +func (p personCollectDo) Last() (*dao.PersonCollect, error) { + if result, err := p.DO.Last(); err != nil { + return nil, err + } else { + return result.(*dao.PersonCollect), nil + } +} + +func (p personCollectDo) Find() ([]*dao.PersonCollect, error) { + result, err := p.DO.Find() + return result.([]*dao.PersonCollect), err +} + +func (p personCollectDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*dao.PersonCollect, err error) { + buf := make([]*dao.PersonCollect, 0, batchSize) + err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (p personCollectDo) FindInBatches(result *[]*dao.PersonCollect, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return p.DO.FindInBatches(result, batchSize, fc) +} + +func (p personCollectDo) Attrs(attrs ...field.AssignExpr) *personCollectDo { + return p.withDO(p.DO.Attrs(attrs...)) +} + +func (p personCollectDo) Assign(attrs ...field.AssignExpr) *personCollectDo { + return p.withDO(p.DO.Assign(attrs...)) +} + +func (p personCollectDo) Joins(fields ...field.RelationField) *personCollectDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Joins(_f)) + } + return &p +} + +func (p personCollectDo) Preload(fields ...field.RelationField) *personCollectDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Preload(_f)) + } + return &p +} + +func (p personCollectDo) FirstOrInit() (*dao.PersonCollect, error) { + if result, err := p.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*dao.PersonCollect), nil + } +} + +func (p personCollectDo) FirstOrCreate() (*dao.PersonCollect, error) { + if result, err := p.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*dao.PersonCollect), nil + } +} + +func (p personCollectDo) FindByPage(offset int, limit int) (result []*dao.PersonCollect, count int64, err error) { + result, err = p.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = p.Offset(-1).Limit(-1).Count() + return +} + +func (p personCollectDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = p.Count() + if err != nil { + return + } + + err = p.Offset(offset).Limit(limit).Scan(result) + return +} + +func (p personCollectDo) Scan(result interface{}) (err error) { + return p.DO.Scan(result) +} + +func (p personCollectDo) Delete(models ...*dao.PersonCollect) (result gen.ResultInfo, err error) { + return p.DO.Delete(models) +} + +func (p *personCollectDo) withDO(do gen.Dao) *personCollectDo { + p.DO = *do.(*gen.DO) + return p +} diff --git a/dal/query/gen.go b/dal/query/gen.go index 7d1e11c49..133139c48 100644 --- a/dal/query/gen.go +++ b/dal/query/gen.go @@ -32,6 +32,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query { Notification: newNotification(db, opts...), NotificationField: newNotificationField(db, opts...), Person: newPerson(db, opts...), + PersonCollect: newPersonCollect(db, opts...), PersonField: newPersonField(db, opts...), PersonSubjects: newPersonSubjects(db, opts...), PrivateMessage: newPrivateMessage(db, opts...), @@ -64,6 +65,7 @@ type Query struct { Notification notification NotificationField notificationField Person person + PersonCollect personCollect PersonField personField PersonSubjects personSubjects PrivateMessage privateMessage @@ -97,6 +99,7 @@ func (q *Query) clone(db *gorm.DB) *Query { Notification: q.Notification.clone(db), NotificationField: q.NotificationField.clone(db), Person: q.Person.clone(db), + PersonCollect: q.PersonCollect.clone(db), PersonField: q.PersonField.clone(db), PersonSubjects: q.PersonSubjects.clone(db), PrivateMessage: q.PrivateMessage.clone(db), @@ -137,6 +140,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query { Notification: q.Notification.replaceDB(db), NotificationField: q.NotificationField.replaceDB(db), Person: q.Person.replaceDB(db), + PersonCollect: q.PersonCollect.replaceDB(db), PersonField: q.PersonField.replaceDB(db), PersonSubjects: q.PersonSubjects.replaceDB(db), PrivateMessage: q.PrivateMessage.replaceDB(db), @@ -167,6 +171,7 @@ type queryCtx struct { Notification *notificationDo NotificationField *notificationFieldDo Person *personDo + PersonCollect *personCollectDo PersonField *personFieldDo PersonSubjects *personSubjectsDo PrivateMessage *privateMessageDo @@ -197,6 +202,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx { Notification: q.Notification.WithContext(ctx), NotificationField: q.NotificationField.WithContext(ctx), Person: q.Person.WithContext(ctx), + PersonCollect: q.PersonCollect.WithContext(ctx), PersonField: q.PersonField.WithContext(ctx), PersonSubjects: q.PersonSubjects.WithContext(ctx), PrivateMessage: q.PrivateMessage.WithContext(ctx), diff --git a/internal/collections/domain.go b/internal/collections/domain.go index a3ccbb5cd..315172987 100644 --- a/internal/collections/domain.go +++ b/internal/collections/domain.go @@ -24,7 +24,7 @@ import ( "github.com/bangumi/server/internal/pkg/null" ) -type Repo interface { +type Repo interface { //nolint:interfacebloat // WithQuery is used to replace repo's query to txn WithQuery(query *query.Query) Repo CountSubjectCollections( @@ -70,6 +70,34 @@ type Repo interface { episodeIDs []model.EpisodeID, collection collection.EpisodeCollection, at time.Time, ) (collection.UserSubjectEpisodesCollection, error) + + GetPersonCollection( + ctx context.Context, userID model.UserID, + cat collection.PersonCollectCategory, targetID model.PersonID, + ) (collection.UserPersonCollection, error) + + AddPersonCollection( + ctx context.Context, userID model.UserID, + cat collection.PersonCollectCategory, targetID model.PersonID, + ) error + + RemovePersonCollection( + ctx context.Context, userID model.UserID, + cat collection.PersonCollectCategory, targetID model.PersonID, + ) error + + CountPersonCollections( + ctx context.Context, + userID model.UserID, + cat collection.PersonCollectCategory, + ) (int64, error) + + ListPersonCollection( + ctx context.Context, + userID model.UserID, + cat collection.PersonCollectCategory, + limit, offset int, + ) ([]collection.UserPersonCollection, error) } type Update struct { diff --git a/internal/collections/domain/collection/model.go b/internal/collections/domain/collection/model.go index f2f229ba4..ec1b0fb07 100644 --- a/internal/collections/domain/collection/model.go +++ b/internal/collections/domain/collection/model.go @@ -51,3 +51,18 @@ type UserEpisodeCollection struct { } type UserSubjectEpisodesCollection map[model.EpisodeID]UserEpisodeCollection + +type PersonCollectCategory string + +const ( + PersonCollectCategoryPerson PersonCollectCategory = "prsn" + PersonCollectCategoryCharacter PersonCollectCategory = "crt" +) + +type UserPersonCollection struct { + ID uint32 + Category string + TargetID model.PersonID + UserID model.UserID + CreatedAt time.Time +} diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index a42e46dec..2d0114a8c 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -461,6 +461,149 @@ func (r mysqlRepo) updateCollectionTime(obj *dao.SubjectCollection, return nil } +func (r mysqlRepo) GetPersonCollection( + ctx context.Context, userID model.UserID, + cat collection.PersonCollectCategory, targetID model.PersonID, +) (collection.UserPersonCollection, error) { + c, err := r.q.PersonCollect.WithContext(ctx). + Where(r.q.PersonCollect.UserID.Eq(userID), r.q.PersonCollect.Category.Eq(string(cat)), + r.q.PersonCollect.TargetID.Eq(targetID)).Take() + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return collection.UserPersonCollection{}, gerr.ErrNotFound + } + return collection.UserPersonCollection{}, errgo.Wrap(err, "dal") + } + + return collection.UserPersonCollection{ + ID: c.ID, + Category: c.Category, + TargetID: c.TargetID, + UserID: c.UserID, + CreatedAt: time.Unix(int64(c.CreatedTime), 0), + }, nil +} + +func (r mysqlRepo) AddPersonCollection( + ctx context.Context, userID model.UserID, + cat collection.PersonCollectCategory, targetID model.PersonID, +) error { + collect := &dao.PersonCollect{ + UserID: userID, + Category: string(cat), + TargetID: targetID, + CreatedTime: uint32(time.Now().Unix()), + } + err := r.q.Transaction(func(tx *query.Query) error { + switch cat { + case collection.PersonCollectCategoryCharacter: + if _, err := tx.Character.WithContext(ctx).Where( + tx.Character.ID.Eq(targetID)).UpdateSimple(tx.Character.Collects.Add(1)); err != nil { + r.log.Error("failed to update character collects", zap.Error(err)) + return err + } + case collection.PersonCollectCategoryPerson: + if _, err := tx.Person.WithContext(ctx).Where( + tx.Person.ID.Eq(targetID)).UpdateSimple(tx.Person.Collects.Add(1)); err != nil { + r.log.Error("failed to update person collects", zap.Error(err)) + return err + } + } + if err := tx.PersonCollect.WithContext(ctx).Create(collect); err != nil { + r.log.Error("failed to create person collection record", zap.Error(err)) + return err + } + return nil + }) + if err != nil { + return errgo.Wrap(err, "dal") + } + return nil +} + +func (r mysqlRepo) RemovePersonCollection( + ctx context.Context, userID model.UserID, + cat collection.PersonCollectCategory, targetID model.PersonID, +) error { + err := r.q.Transaction(func(tx *query.Query) error { + switch cat { + case collection.PersonCollectCategoryCharacter: + if _, err := tx.Character.WithContext(ctx).Where( + tx.Character.ID.Eq(targetID)).UpdateSimple(tx.Character.Collects.Sub(1)); err != nil { + r.log.Error("failed to update character collects", zap.Error(err)) + return err + } + case collection.PersonCollectCategoryPerson: + if _, err := tx.Person.WithContext(ctx).Where( + tx.Person.ID.Eq(targetID)).UpdateSimple(tx.Person.Collects.Sub(1)); err != nil { + r.log.Error("failed to update person collects", zap.Error(err)) + return err + } + } + _, err := tx.PersonCollect.WithContext(ctx).Where( + tx.PersonCollect.UserID.Eq(userID), + tx.PersonCollect.Category.Eq(string(cat)), + tx.PersonCollect.TargetID.Eq(targetID), + ).Delete() + if err != nil { + r.log.Error("failed to delete person collection record", zap.Error(err)) + return err + } + return nil + }) + if err != nil { + return errgo.Wrap(err, "dal") + } + + return nil +} + +func (r mysqlRepo) CountPersonCollections( + ctx context.Context, + userID model.UserID, + cat collection.PersonCollectCategory, +) (int64, error) { + q := r.q.PersonCollect.WithContext(ctx). + Where(r.q.PersonCollect.UserID.Eq(userID), r.q.PersonCollect.Category.Eq(string(cat))) + + c, err := q.Count() + if err != nil { + return 0, errgo.Wrap(err, "dal") + } + + return c, nil +} + +func (r mysqlRepo) ListPersonCollection( + ctx context.Context, + userID model.UserID, + cat collection.PersonCollectCategory, + limit, offset int, +) ([]collection.UserPersonCollection, error) { + q := r.q.PersonCollect.WithContext(ctx). + Order(r.q.PersonCollect.CreatedTime.Desc()). + Where(r.q.PersonCollect.UserID.Eq(userID), r.q.PersonCollect.Category.Eq(string(cat))).Limit(limit).Offset(offset) + + collections, err := q.Find() + if err != nil { + r.log.Error("unexpected error happened", zap.Error(err)) + return nil, errgo.Wrap(err, "dal") + } + + var results = make([]collection.UserPersonCollection, len(collections)) + for i, c := range collections { + results[i] = collection.UserPersonCollection{ + ID: c.ID, + Category: c.Category, + TargetID: c.TargetID, + UserID: c.UserID, + CreatedAt: time.Unix(int64(c.CreatedTime), 0), + } + } + + return results, nil +} + func (r mysqlRepo) UpdateEpisodeCollection( ctx context.Context, userID model.UserID, diff --git a/internal/collections/infra/mysql_repo_test.go b/internal/collections/infra/mysql_repo_test.go index c38945548..7507b6110 100644 --- a/internal/collections/infra/mysql_repo_test.go +++ b/internal/collections/infra/mysql_repo_test.go @@ -23,6 +23,7 @@ import ( "github.com/trim21/go-phpserialize" "go.uber.org/zap" "gorm.io/gen/field" + "gorm.io/gorm" "github.com/bangumi/server/dal/dao" "github.com/bangumi/server/dal/query" @@ -415,6 +416,7 @@ func TestMysqlRepo_UpdateSubjectCollectionType(t *testing.T) { require.Zero(t, r.DoneTime) require.Zero(t, r.OnHoldTime) } + func TestMysqlRepo_UpdateEpisodeCollection(t *testing.T) { test.RequireEnv(t, test.EnvMysql) t.Parallel() @@ -507,3 +509,197 @@ func TestMysqlRepo_UpdateEpisodeCollection_create_ep_status(t *testing.T) { require.Contains(t, m, uint32(2)) require.EqualValues(t, collection.EpisodeCollectionDone, m[2].Type) } + +func TestMysqlRepo_GetPersonCollect(t *testing.T) { + test.RequireEnv(t, test.EnvMysql) + t.Parallel() + + const uid model.UserID = 39000 + const cat = "prsn" + const mid model.PersonID = 12000 + + repo, q := getRepo(t) + test.RunAndCleanup(t, func() { + _, err := q.PersonCollect.WithContext(context.TODO()).Where(q.PersonCollect.UserID.Eq(uid)).Delete() + require.NoError(t, err) + }) + + err := q.PersonCollect.WithContext(context.Background()).Create(&dao.PersonCollect{ + UserID: uid, + Category: cat, + TargetID: mid, + CreatedTime: uint32(time.Now().Unix()), + }) + require.NoError(t, err) + + r, err := repo.GetPersonCollection(context.Background(), uid, cat, mid) + require.NoError(t, err) + require.Equal(t, uid, r.UserID) + require.Equal(t, mid, r.TargetID) + require.Equal(t, cat, r.Category) +} + +func TestMysqlRepo_AddPersonCollect(t *testing.T) { + test.RequireEnv(t, test.EnvMysql) + t.Parallel() + + const uid model.UserID = 40000 + const cat = "prsn" + const mid model.PersonID = 13000 + const collects uint32 = 10 + + repo, q := getRepo(t) + table := q.PersonCollect + test.RunAndCleanup(t, func() { + _, err := table.WithContext(context.TODO()).Where(table.UserID.Eq(uid)).Delete() + require.NoError(t, err) + _, err = q.Person.WithContext(context.TODO()).Where(q.Person.ID.Eq(mid)).Delete() + require.NoError(t, err) + }) + + err := q.Person.WithContext(context.Background()).Create(&dao.Person{ + ID: mid, + Collects: collects, + }) + require.NoError(t, err) + + err = repo.AddPersonCollection(context.Background(), uid, cat, mid) + require.NoError(t, err) + + r, err := table.WithContext(context.TODO()).Where(table.UserID.Eq(uid)).Take() + require.NoError(t, err) + require.NotZero(t, r.ID) + + p, err := q.Person.WithContext(context.Background()).Where(q.Person.ID.Eq(mid)).Take() + require.NoError(t, err) + require.Equal(t, collects+1, p.Collects) +} + +func TestMysqlRepo_RemovePersonCollect(t *testing.T) { + test.RequireEnv(t, test.EnvMysql) + t.Parallel() + + const uid model.UserID = 41000 + const cat = "prsn" + const mid model.PersonID = 14000 + const collects uint32 = 10 + + repo, q := getRepo(t) + test.RunAndCleanup(t, func() { + _, err := q.PersonCollect.WithContext(context.TODO()).Where(q.PersonCollect.UserID.Eq(uid)).Delete() + require.NoError(t, err) + _, err = q.Person.WithContext(context.TODO()).Where(q.Person.ID.Eq(mid)).Delete() + require.NoError(t, err) + }) + + err := q.Person.WithContext(context.Background()).Create(&dao.Person{ + ID: mid, + Collects: collects, + }) + require.NoError(t, err) + err = q.PersonCollect.WithContext(context.Background()).Create(&dao.PersonCollect{ + UserID: uid, + Category: cat, + TargetID: mid, + CreatedTime: uint32(time.Now().Unix()), + }) + require.NoError(t, err) + + r, err := q.PersonCollect.WithContext(context.TODO()).Where(q.PersonCollect.UserID.Eq(uid)).Take() + require.NoError(t, err) + require.NotZero(t, r.ID) + + err = repo.RemovePersonCollection(context.Background(), uid, cat, mid) + require.NoError(t, err) + + _, err = q.PersonCollect.WithContext(context.TODO()).Where(q.PersonCollect.UserID.Eq(uid)).Take() + require.ErrorIs(t, err, gorm.ErrRecordNotFound) + + p, err := q.Person.WithContext(context.Background()).Where(q.Person.ID.Eq(mid)).Take() + require.NoError(t, err) + require.Equal(t, collects-1, p.Collects) +} + +func TestMysqlRepo_CountPersonCollections(t *testing.T) { + t.Parallel() + test.RequireEnv(t, test.EnvMysql) + + const uid model.UserID = 42000 + const cat = "prsn" + + repo, q := getRepo(t) + test.RunAndCleanup(t, func() { + _, err := q.PersonCollect. + WithContext(context.Background()). + Where(q.PersonCollect.UserID.Eq(uid)). + Delete() + require.NoError(t, err) + }) + + for i := 0; i < 5; i++ { + err := q.PersonCollect. + WithContext(context.Background()). + Create(&dao.PersonCollect{ + UserID: uid, + TargetID: model.PersonID(i + 100), + Category: cat, + CreatedTime: uint32(time.Now().Unix()), + }) + require.NoError(t, err) + } + + count, err := repo.CountPersonCollections(context.Background(), uid, cat) + require.NoError(t, err) + require.EqualValues(t, 5, count) +} + +func TestMysqlRepo_ListPersonCollection(t *testing.T) { + t.Parallel() + test.RequireEnv(t, test.EnvMysql) + + const uid model.UserID = 43000 + const cat = "prsn" + + repo, q := getRepo(t) + + var err error + test.RunAndCleanup(t, func() { + _, err = q.PersonCollect. + WithContext(context.Background()). + Where(q.PersonCollect.UserID.Eq(uid)). + Delete() + require.NoError(t, err) + }) + + data, err := repo.ListPersonCollection(context.Background(), uid, collection.PersonCollectCategory(cat), 5, 0) + require.NoError(t, err) + require.Len(t, data, 0) + + for i := 0; i < 5; i++ { + err = q.PersonCollect. + WithContext(context.Background()). + Create(&dao.PersonCollect{ + UserID: uid, + TargetID: model.PersonID(i + 100), + Category: cat, + CreatedTime: uint32(time.Now().Unix()), + }) + require.NoError(t, err) + } + + for i := 0; i < 2; i++ { + err = q.PersonCollect. + WithContext(context.Background()). + Create(&dao.PersonCollect{ + UserID: uid, + TargetID: model.PersonID(i + 200), + Category: cat, + CreatedTime: uint32(time.Now().Unix()), + }) + require.NoError(t, err) + } + + data, err = repo.ListPersonCollection(context.Background(), uid, collection.PersonCollectCategory(cat), 5, 0) + require.NoError(t, err) + require.Len(t, data, 5) +} diff --git a/internal/mocks/CollectionRepo.go b/internal/mocks/CollectionRepo.go index 811b211b2..3fbafd138 100644 --- a/internal/mocks/CollectionRepo.go +++ b/internal/mocks/CollectionRepo.go @@ -30,6 +30,113 @@ func (_m *CollectionRepo) EXPECT() *CollectionRepo_Expecter { return &CollectionRepo_Expecter{mock: &_m.Mock} } +// AddPersonCollection provides a mock function with given fields: ctx, userID, cat, targetID +func (_m *CollectionRepo) AddPersonCollection(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, targetID uint32) error { + ret := _m.Called(ctx, userID, cat, targetID) + + if len(ret) == 0 { + panic("no return value specified for AddPersonCollection") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory, uint32) error); ok { + r0 = rf(ctx, userID, cat, targetID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CollectionRepo_AddPersonCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddPersonCollection' +type CollectionRepo_AddPersonCollection_Call struct { + *mock.Call +} + +// AddPersonCollection is a helper method to define mock.On call +// - ctx context.Context +// - userID uint32 +// - cat collection.PersonCollectCategory +// - targetID uint32 +func (_e *CollectionRepo_Expecter) AddPersonCollection(ctx interface{}, userID interface{}, cat interface{}, targetID interface{}) *CollectionRepo_AddPersonCollection_Call { + return &CollectionRepo_AddPersonCollection_Call{Call: _e.mock.On("AddPersonCollection", ctx, userID, cat, targetID)} +} + +func (_c *CollectionRepo_AddPersonCollection_Call) Run(run func(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, targetID uint32)) *CollectionRepo_AddPersonCollection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32), args[2].(collection.PersonCollectCategory), args[3].(uint32)) + }) + return _c +} + +func (_c *CollectionRepo_AddPersonCollection_Call) Return(_a0 error) *CollectionRepo_AddPersonCollection_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CollectionRepo_AddPersonCollection_Call) RunAndReturn(run func(context.Context, uint32, collection.PersonCollectCategory, uint32) error) *CollectionRepo_AddPersonCollection_Call { + _c.Call.Return(run) + return _c +} + +// CountPersonCollections provides a mock function with given fields: ctx, userID, cat +func (_m *CollectionRepo) CountPersonCollections(ctx context.Context, userID uint32, cat collection.PersonCollectCategory) (int64, error) { + ret := _m.Called(ctx, userID, cat) + + if len(ret) == 0 { + panic("no return value specified for CountPersonCollections") + } + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory) (int64, error)); ok { + return rf(ctx, userID, cat) + } + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory) int64); ok { + r0 = rf(ctx, userID, cat) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, uint32, collection.PersonCollectCategory) error); ok { + r1 = rf(ctx, userID, cat) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CollectionRepo_CountPersonCollections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CountPersonCollections' +type CollectionRepo_CountPersonCollections_Call struct { + *mock.Call +} + +// CountPersonCollections is a helper method to define mock.On call +// - ctx context.Context +// - userID uint32 +// - cat collection.PersonCollectCategory +func (_e *CollectionRepo_Expecter) CountPersonCollections(ctx interface{}, userID interface{}, cat interface{}) *CollectionRepo_CountPersonCollections_Call { + return &CollectionRepo_CountPersonCollections_Call{Call: _e.mock.On("CountPersonCollections", ctx, userID, cat)} +} + +func (_c *CollectionRepo_CountPersonCollections_Call) Run(run func(ctx context.Context, userID uint32, cat collection.PersonCollectCategory)) *CollectionRepo_CountPersonCollections_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32), args[2].(collection.PersonCollectCategory)) + }) + return _c +} + +func (_c *CollectionRepo_CountPersonCollections_Call) Return(_a0 int64, _a1 error) *CollectionRepo_CountPersonCollections_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CollectionRepo_CountPersonCollections_Call) RunAndReturn(run func(context.Context, uint32, collection.PersonCollectCategory) (int64, error)) *CollectionRepo_CountPersonCollections_Call { + _c.Call.Return(run) + return _c +} + // CountSubjectCollections provides a mock function with given fields: ctx, userID, subjectType, collectionType, showPrivate func (_m *CollectionRepo) CountSubjectCollections(ctx context.Context, userID uint32, subjectType uint8, collectionType collection.SubjectCollection, showPrivate bool) (int64, error) { ret := _m.Called(ctx, userID, subjectType, collectionType, showPrivate) @@ -90,6 +197,65 @@ func (_c *CollectionRepo_CountSubjectCollections_Call) RunAndReturn(run func(con return _c } +// GetPersonCollection provides a mock function with given fields: ctx, userID, cat, targetID +func (_m *CollectionRepo) GetPersonCollection(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, targetID uint32) (collection.UserPersonCollection, error) { + ret := _m.Called(ctx, userID, cat, targetID) + + if len(ret) == 0 { + panic("no return value specified for GetPersonCollection") + } + + var r0 collection.UserPersonCollection + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory, uint32) (collection.UserPersonCollection, error)); ok { + return rf(ctx, userID, cat, targetID) + } + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory, uint32) collection.UserPersonCollection); ok { + r0 = rf(ctx, userID, cat, targetID) + } else { + r0 = ret.Get(0).(collection.UserPersonCollection) + } + + if rf, ok := ret.Get(1).(func(context.Context, uint32, collection.PersonCollectCategory, uint32) error); ok { + r1 = rf(ctx, userID, cat, targetID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CollectionRepo_GetPersonCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPersonCollection' +type CollectionRepo_GetPersonCollection_Call struct { + *mock.Call +} + +// GetPersonCollection is a helper method to define mock.On call +// - ctx context.Context +// - userID uint32 +// - cat collection.PersonCollectCategory +// - targetID uint32 +func (_e *CollectionRepo_Expecter) GetPersonCollection(ctx interface{}, userID interface{}, cat interface{}, targetID interface{}) *CollectionRepo_GetPersonCollection_Call { + return &CollectionRepo_GetPersonCollection_Call{Call: _e.mock.On("GetPersonCollection", ctx, userID, cat, targetID)} +} + +func (_c *CollectionRepo_GetPersonCollection_Call) Run(run func(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, targetID uint32)) *CollectionRepo_GetPersonCollection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32), args[2].(collection.PersonCollectCategory), args[3].(uint32)) + }) + return _c +} + +func (_c *CollectionRepo_GetPersonCollection_Call) Return(_a0 collection.UserPersonCollection, _a1 error) *CollectionRepo_GetPersonCollection_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CollectionRepo_GetPersonCollection_Call) RunAndReturn(run func(context.Context, uint32, collection.PersonCollectCategory, uint32) (collection.UserPersonCollection, error)) *CollectionRepo_GetPersonCollection_Call { + _c.Call.Return(run) + return _c +} + // GetSubjectCollection provides a mock function with given fields: ctx, userID, subjectID func (_m *CollectionRepo) GetSubjectCollection(ctx context.Context, userID uint32, subjectID uint32) (collection.UserSubjectCollection, error) { ret := _m.Called(ctx, userID, subjectID) @@ -208,6 +374,68 @@ func (_c *CollectionRepo_GetSubjectEpisodesCollection_Call) RunAndReturn(run fun return _c } +// ListPersonCollection provides a mock function with given fields: ctx, userID, cat, limit, offset +func (_m *CollectionRepo) ListPersonCollection(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, limit int, offset int) ([]collection.UserPersonCollection, error) { + ret := _m.Called(ctx, userID, cat, limit, offset) + + if len(ret) == 0 { + panic("no return value specified for ListPersonCollection") + } + + var r0 []collection.UserPersonCollection + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory, int, int) ([]collection.UserPersonCollection, error)); ok { + return rf(ctx, userID, cat, limit, offset) + } + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory, int, int) []collection.UserPersonCollection); ok { + r0 = rf(ctx, userID, cat, limit, offset) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]collection.UserPersonCollection) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint32, collection.PersonCollectCategory, int, int) error); ok { + r1 = rf(ctx, userID, cat, limit, offset) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CollectionRepo_ListPersonCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListPersonCollection' +type CollectionRepo_ListPersonCollection_Call struct { + *mock.Call +} + +// ListPersonCollection is a helper method to define mock.On call +// - ctx context.Context +// - userID uint32 +// - cat collection.PersonCollectCategory +// - limit int +// - offset int +func (_e *CollectionRepo_Expecter) ListPersonCollection(ctx interface{}, userID interface{}, cat interface{}, limit interface{}, offset interface{}) *CollectionRepo_ListPersonCollection_Call { + return &CollectionRepo_ListPersonCollection_Call{Call: _e.mock.On("ListPersonCollection", ctx, userID, cat, limit, offset)} +} + +func (_c *CollectionRepo_ListPersonCollection_Call) Run(run func(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, limit int, offset int)) *CollectionRepo_ListPersonCollection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32), args[2].(collection.PersonCollectCategory), args[3].(int), args[4].(int)) + }) + return _c +} + +func (_c *CollectionRepo_ListPersonCollection_Call) Return(_a0 []collection.UserPersonCollection, _a1 error) *CollectionRepo_ListPersonCollection_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CollectionRepo_ListPersonCollection_Call) RunAndReturn(run func(context.Context, uint32, collection.PersonCollectCategory, int, int) ([]collection.UserPersonCollection, error)) *CollectionRepo_ListPersonCollection_Call { + _c.Call.Return(run) + return _c +} + // ListSubjectCollection provides a mock function with given fields: ctx, userID, subjectType, collectionType, showPrivate, limit, offset func (_m *CollectionRepo) ListSubjectCollection(ctx context.Context, userID uint32, subjectType uint8, collectionType collection.SubjectCollection, showPrivate bool, limit int, offset int) ([]collection.UserSubjectCollection, error) { ret := _m.Called(ctx, userID, subjectType, collectionType, showPrivate, limit, offset) @@ -272,6 +500,55 @@ func (_c *CollectionRepo_ListSubjectCollection_Call) RunAndReturn(run func(conte return _c } +// RemovePersonCollection provides a mock function with given fields: ctx, userID, cat, targetID +func (_m *CollectionRepo) RemovePersonCollection(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, targetID uint32) error { + ret := _m.Called(ctx, userID, cat, targetID) + + if len(ret) == 0 { + panic("no return value specified for RemovePersonCollection") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, uint32, collection.PersonCollectCategory, uint32) error); ok { + r0 = rf(ctx, userID, cat, targetID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CollectionRepo_RemovePersonCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemovePersonCollection' +type CollectionRepo_RemovePersonCollection_Call struct { + *mock.Call +} + +// RemovePersonCollection is a helper method to define mock.On call +// - ctx context.Context +// - userID uint32 +// - cat collection.PersonCollectCategory +// - targetID uint32 +func (_e *CollectionRepo_Expecter) RemovePersonCollection(ctx interface{}, userID interface{}, cat interface{}, targetID interface{}) *CollectionRepo_RemovePersonCollection_Call { + return &CollectionRepo_RemovePersonCollection_Call{Call: _e.mock.On("RemovePersonCollection", ctx, userID, cat, targetID)} +} + +func (_c *CollectionRepo_RemovePersonCollection_Call) Run(run func(ctx context.Context, userID uint32, cat collection.PersonCollectCategory, targetID uint32)) *CollectionRepo_RemovePersonCollection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32), args[2].(collection.PersonCollectCategory), args[3].(uint32)) + }) + return _c +} + +func (_c *CollectionRepo_RemovePersonCollection_Call) Return(_a0 error) *CollectionRepo_RemovePersonCollection_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CollectionRepo_RemovePersonCollection_Call) RunAndReturn(run func(context.Context, uint32, collection.PersonCollectCategory, uint32) error) *CollectionRepo_RemovePersonCollection_Call { + _c.Call.Return(run) + return _c +} + // UpdateEpisodeCollection provides a mock function with given fields: ctx, userID, subjectID, episodeIDs, _a4, at func (_m *CollectionRepo) UpdateEpisodeCollection(ctx context.Context, userID uint32, subjectID uint32, episodeIDs []uint32, _a4 collection.EpisodeCollection, at time.Time) (collection.UserSubjectEpisodesCollection, error) { ret := _m.Called(ctx, userID, subjectID, episodeIDs, _a4, at) diff --git a/openapi/components/subject_collection.yaml b/openapi/components/user_subject_collection.yaml similarity index 100% rename from openapi/components/subject_collection.yaml rename to openapi/components/user_subject_collection.yaml diff --git a/openapi/components/subject_collection_modify_payload.yaml b/openapi/components/user_subject_collection_modify_payload.yaml similarity index 100% rename from openapi/components/subject_collection_modify_payload.yaml rename to openapi/components/user_subject_collection_modify_payload.yaml diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 4825439e1..16fb81a38 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -571,6 +571,70 @@ paths: application/json: schema: "$ref": "#/components/schemas/ErrorDetail" + "/v0/characters/{character_id}/collect": + post: + tags: + - 角色 + summary: Collect character for current user + operationId: collectCharacterByCharacterIdAndUserId + description: 为当前用户收藏角色 + parameters: + - $ref: "#/components/parameters/path_character_id" + responses: + "204": + description: Successful Response + "400": + description: character ID not valid + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "401": + description: not authorized + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: 角色不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + security: + - HTTPBearer: [] + delete: + tags: + - 角色 + summary: Uncollect character for current user + operationId: uncollectCharacterByCharacterIdAndUserId + description: 为当前用户取消收藏角色 + parameters: + - $ref: "#/components/parameters/path_character_id" + responses: + "204": + description: Successful Response + "400": + description: character ID not valid + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "401": + description: not authorized + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: 角色不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + security: + - HTTPBearer: [] + "/v0/persons/{person_id}": get: tags: @@ -696,6 +760,69 @@ paths: application/json: schema: "$ref": "#/components/schemas/ErrorDetail" + "/v0/persons/{person_id}/collect": + post: + tags: + - 人物 + summary: Collect person for current user + operationId: collectPersonByPersonIdAndUserId + description: 为当前用户收藏人物 + parameters: + - $ref: "#/components/parameters/path_person_id" + responses: + "204": + description: Successful Response + "400": + description: person ID not valid + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "401": + description: not authorized + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: 人物不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + security: + - OptionalHTTPBearer: [] + delete: + tags: + - 人物 + summary: Uncollect person for current user + operationId: uncollectPersonByPersonIdAndUserId + description: 为当前用户取消收藏人物 + parameters: + - $ref: "#/components/parameters/path_person_id" + responses: + "204": + description: Successful Response + "400": + description: person ID not valid + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "401": + description: not authorized + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: 人物不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + security: + - OptionalHTTPBearer: [] "/v0/users/{username}": get: @@ -847,8 +974,8 @@ paths: get: tags: - 收藏 - summary: 获取用户单个收藏 - description: 获取对应用户的收藏,查看私有收藏需要access token。 + summary: 获取用户单个条目收藏 + description: 获取对应用户的收藏,查看私有收藏需要 access token operationId: getUserCollection parameters: - $ref: "#/components/parameters/path_username" @@ -878,7 +1005,7 @@ paths: post: tags: - 收藏 - summary: 新增或修改用户单个收藏 + summary: 新增或修改用户单个条目收藏 description: | 修改条目收藏状态, 如果不存在则创建,如果存在则修改 @@ -1143,6 +1270,106 @@ paths: security: - HTTPBearer: [] + "/v0/users/{username}/collections/-/characters": + get: + tags: + - 收藏 + summary: 获取用户角色收藏列表 + operationId: getUserCharacterCollections + parameters: + - $ref: "#/components/parameters/path_username" + responses: + "200": + description: Successful Response + content: + application/json: + schema: + "$ref": "#/components/schemas/Paged_UserCharacterCollection" + "404": + description: 用户不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "/v0/users/{username}/collections/-/characters/{character_id}": + get: + tags: + - 收藏 + summary: 获取用户单个角色收藏信息 + operationId: getUserCharacterCollection + parameters: + - $ref: "#/components/parameters/path_username" + - $ref: "#/components/parameters/path_character_id" + responses: + "200": + description: Successful Response + content: + application/json: + schema: + "$ref": "#/components/schemas/UserCharacterCollection" + "400": + description: character ID not valid + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: 用户或角色不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + + "/v0/users/{username}/collections/-/persons": + get: + tags: + - 收藏 + summary: 获取用户人物收藏列表 + operationId: getUserPersonCollections + parameters: + - $ref: "#/components/parameters/path_username" + responses: + "200": + description: Successful Response + content: + application/json: + schema: + "$ref": "#/components/schemas/Paged_UserPersonCollection" + "404": + description: 用户不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "/v0/users/{username}/collections/-/persons/{person_id}": + get: + tags: + - 收藏 + summary: 获取用户单个人物收藏信息 + operationId: getUserPersonCollection + parameters: + - $ref: "#/components/parameters/path_username" + - $ref: "#/components/parameters/path_person_id" + responses: + "200": + description: Successful Response + content: + application/json: + schema: + "$ref": "#/components/schemas/UserPersonCollection" + "400": + description: person ID not valid + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: 用户或人物不存在 + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "/v0/revisions/persons": get: tags: @@ -2342,6 +2569,50 @@ components: items: "$ref": "#/components/schemas/UserSubjectCollection" default: [] + Paged_UserCharacterCollection: + title: Paged[UserCharacterCollection] + type: object + properties: + total: + title: Total + type: integer + default: 0 + limit: + title: Limit + type: integer + default: 0 + offset: + title: Offset + type: integer + default: 0 + data: + title: Data + type: array + items: + "$ref": "#/components/schemas/UserCharacterCollection" + default: [] + Paged_UserPersonCollection: + title: Paged[UserPersonCollection] + type: object + properties: + total: + title: Total + type: integer + default: 0 + limit: + title: Limit + type: integer + default: 0 + offset: + title: Offset + type: integer + default: 0 + data: + title: Data + type: array + items: + "$ref": "#/components/schemas/UserPersonCollection" + default: [] Person: title: Person required: @@ -2621,6 +2892,71 @@ components: relation: title: Relation type: string + UserCharacterCollection: + title: UserCharacterCollection + required: + - id + - name + - type + - created_at + type: object + properties: + id: + title: ID + type: integer + name: + title: Name + type: string + type: + type: integer + allOf: + - "$ref": "#/components/schemas/CharacterType" + description: 角色,机体,舰船,组织... + images: + title: Images + type: object + allOf: + - "$ref": "#/components/schemas/PersonImages" + description: object with some size of images, this object maybe `null` + created_at: + title: Created At + type: string + format: date-time + UserPersonCollection: + title: UserPersonCollection + required: + - id + - name + - type + - career + - created_at + type: object + properties: + id: + title: ID + type: integer + name: + title: Name + type: string + type: + type: integer + allOf: + - "$ref": "#/components/schemas/PersonType" + description: "`1`, `2`, `3` 表示 `个人`, `公司`, `组合`" + career: + type: array + items: + "$ref": "#/components/schemas/PersonCareer" + images: + title: Images + type: object + allOf: + - "$ref": "#/components/schemas/PersonImages" + description: object with some size of images, this object maybe `null` + created_at: + title: Created At + type: string + format: date-time Revision: title: Revision required: @@ -2667,9 +3003,9 @@ components: SubjectType: $ref: "./components/subject_type.yaml" UserSubjectCollection: - $ref: "./components/subject_collection.yaml" + $ref: "./components/user_subject_collection.yaml" UserSubjectCollectionModifyPayload: - $ref: "./components/subject_collection_modify_payload.yaml" + $ref: "./components/user_subject_collection_modify_payload.yaml" UserEpisodeCollection: $ref: "./components/get-user-episodes-collection.yaml" v0_RelatedSubject: diff --git a/web/handler/character/character.go b/web/handler/character/character.go index 2d42cfa2f..8578489f9 100644 --- a/web/handler/character/character.go +++ b/web/handler/character/character.go @@ -20,6 +20,7 @@ import ( "github.com/bangumi/server/config" "github.com/bangumi/server/ctrl" "github.com/bangumi/server/internal/character" + "github.com/bangumi/server/internal/collections" "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/person" "github.com/bangumi/server/internal/pkg/compat" @@ -30,28 +31,31 @@ import ( ) type Character struct { - ctrl ctrl.Ctrl - person person.Service - c character.Repo - subject subject.Repo - log *zap.Logger - cfg config.AppConfig + ctrl ctrl.Ctrl + person person.Service + character character.Repo + subject subject.Repo + collect collections.Repo + log *zap.Logger + cfg config.AppConfig } func New( - p person.Service, + person person.Service, ctrl ctrl.Ctrl, - c character.Repo, + character character.Repo, subject subject.Repo, + collect collections.Repo, log *zap.Logger, ) (Character, error) { return Character{ - ctrl: ctrl, - c: c, - subject: subject, - person: p, - log: log.Named("handler.Character"), - cfg: config.AppConfig{}, + ctrl: ctrl, + character: character, + subject: subject, + person: person, + collect: collect, + log: log.Named("handler.Character"), + cfg: config.AppConfig{}, }, nil } diff --git a/web/handler/character/collect.go b/web/handler/character/collect.go new file mode 100644 index 000000000..f8d6c60b6 --- /dev/null +++ b/web/handler/character/collect.go @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package character + +import ( + "errors" + + "github.com/labstack/echo/v4" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/collections/domain/collection" + "github.com/bangumi/server/web/accessor" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h Character) CollectCharacter(c echo.Context) error { + cid, err := req.ParseID(c.Param("id")) + if err != nil { + return err + } + uid := accessor.GetFromCtx(c).ID + return h.collectCharacter(c, cid, uid) +} + +func (h Character) UncollectCharacter(c echo.Context) error { + cid, err := req.ParseID(c.Param("id")) + if err != nil { + return err + } + uid := accessor.GetFromCtx(c).ID + return h.uncollectCharacter(c, cid, uid) +} + +func (h Character) collectCharacter(c echo.Context, cid uint32, uid uint32) error { + ctx := c.Request().Context() + // check if the character exists + if _, err := h.character.Get(ctx, cid); err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.ErrNotFound + } + return res.InternalError(c, err, "get character error") + } + // check if the user has collected the character + if _, err := h.collect.GetPersonCollection(ctx, uid, collection.PersonCollectCategoryCharacter, cid); err == nil { + return nil // already collected + } else if !errors.Is(err, gerr.ErrNotFound) { + return res.InternalError(c, err, "get character collect error") + } + // add the collect + if err := h.collect.AddPersonCollection(ctx, uid, collection.PersonCollectCategoryCharacter, cid); err != nil { + return res.InternalError(c, err, "add character collect failed") + } + return nil +} + +func (h Character) uncollectCharacter(c echo.Context, cid uint32, uid uint32) error { + ctx := c.Request().Context() + // check if the character exists + if _, err := h.character.Get(ctx, cid); err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.ErrNotFound + } + return res.InternalError(c, err, "get character error") + } + // check if the user has collected the character + if _, err := h.collect.GetPersonCollection(ctx, uid, collection.PersonCollectCategoryCharacter, cid); err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound("character not collected") + } + return res.InternalError(c, err, "get character collect error") + } + // remove the collect + if err := h.collect.RemovePersonCollection(ctx, uid, collection.PersonCollectCategoryCharacter, cid); err != nil { + return res.InternalError(c, err, "remove character collect failed") + } + return nil +} diff --git a/web/handler/character/get.go b/web/handler/character/get.go index 5def90ca7..08547ddca 100644 --- a/web/handler/character/get.go +++ b/web/handler/character/get.go @@ -36,7 +36,7 @@ func (h Character) Get(c echo.Context) error { return err } - r, err := h.c.Get(c.Request().Context(), id) + r, err := h.character.Get(c.Request().Context(), id) if err != nil { if errors.Is(err, gerr.ErrNotFound) { return res.ErrNotFound @@ -62,7 +62,7 @@ func (h Character) GetImage(c echo.Context) error { return err } - p, err := h.c.Get(c.Request().Context(), id) + p, err := h.character.Get(c.Request().Context(), id) if err != nil { if errors.Is(err, gerr.ErrNotFound) { return res.ErrNotFound diff --git a/web/handler/character/get_related_persons.go b/web/handler/character/get_related_persons.go index 421a237f9..d82bc8c18 100644 --- a/web/handler/character/get_related_persons.go +++ b/web/handler/character/get_related_persons.go @@ -33,7 +33,7 @@ func (h Character) GetRelatedPersons(c echo.Context) error { return err } - _, err = h.c.Get(c.Request().Context(), id) + _, err = h.character.Get(c.Request().Context(), id) if err != nil { if errors.Is(err, gerr.ErrNotFound) { return res.ErrNotFound diff --git a/web/handler/character/get_related_subjects.go b/web/handler/character/get_related_subjects.go index 38ca03a30..ce228d015 100644 --- a/web/handler/character/get_related_subjects.go +++ b/web/handler/character/get_related_subjects.go @@ -65,7 +65,7 @@ func (h Character) getCharacterRelatedSubjects( ctx context.Context, characterID model.CharacterID, ) (model.Character, []model.SubjectCharacterRelation, error) { - character, err := h.c.Get(ctx, characterID) + character, err := h.character.Get(ctx, characterID) if err != nil { return model.Character{}, nil, errgo.Wrap(err, "get character") } diff --git a/web/handler/person/collect.go b/web/handler/person/collect.go new file mode 100644 index 000000000..d1ec9fa62 --- /dev/null +++ b/web/handler/person/collect.go @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package person + +import ( + "errors" + + "github.com/labstack/echo/v4" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/collections/domain/collection" + "github.com/bangumi/server/web/accessor" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h Person) CollectPerson(c echo.Context) error { + pid, err := req.ParseID(c.Param("id")) + if err != nil { + return err + } + + uid := accessor.GetFromCtx(c).ID + return h.collectPerson(c, pid, uid) +} + +func (h Person) UncollectPerson(c echo.Context) error { + pid, err := req.ParseID(c.Param("id")) + if err != nil { + return err + } + + uid := accessor.GetFromCtx(c).ID + return h.uncollectPerson(c, pid, uid) +} + +func (h Person) collectPerson(c echo.Context, pid uint32, uid uint32) error { + ctx := c.Request().Context() + // check if the person exists + if _, err := h.person.Get(ctx, pid); err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.ErrNotFound + } + return res.InternalError(c, err, "get person error") + } + // check if the user has collected the person + if _, err := h.collect.GetPersonCollection(ctx, uid, collection.PersonCollectCategoryPerson, pid); err == nil { + return nil // already collected + } else if !errors.Is(err, gerr.ErrNotFound) { + return res.InternalError(c, err, "get person collect error") + } + // add the collect + if err := h.collect.AddPersonCollection(ctx, uid, collection.PersonCollectCategoryPerson, pid); err != nil { + return res.InternalError(c, err, "add person collect failed") + } + return nil +} + +func (h Person) uncollectPerson(c echo.Context, pid uint32, uid uint32) error { + ctx := c.Request().Context() + // check if the person exists + if _, err := h.person.Get(ctx, pid); err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.ErrNotFound + } + return res.InternalError(c, err, "get person error") + } + // check if the user has collected the person + if _, err := h.collect.GetPersonCollection(ctx, uid, collection.PersonCollectCategoryPerson, pid); err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound("person not collected") + } + return res.InternalError(c, err, "get person collect error") + } + // remove the collect + if err := h.collect.RemovePersonCollection(ctx, uid, collection.PersonCollectCategoryPerson, pid); err != nil { + return res.InternalError(c, err, "remove person collect failed") + } + return nil +} diff --git a/web/handler/person/get_related_characters.go b/web/handler/person/get_related_characters.go index 4207cd4d4..60a530fb6 100644 --- a/web/handler/person/get_related_characters.go +++ b/web/handler/person/get_related_characters.go @@ -59,7 +59,7 @@ func (h Person) GetRelatedCharacters(c echo.Context) error { SubjectID: relation.Subject.ID, } } - subjectRelations, err := h.c.GetSubjectRelationByIDs(c.Request().Context(), compositeIDs) + subjectRelations, err := h.character.GetSubjectRelationByIDs(c.Request().Context(), compositeIDs) if err != nil { return errgo.Wrap(err, "CharacterRepo.GetRelations") } @@ -96,7 +96,7 @@ func (h Person) GetRelatedCharacters(c echo.Context) error { func (h Person) getPersonRelatedCharacters( ctx context.Context, personID model.PersonID, ) ([]model.PersonCharacterRelation, error) { - relations, err := h.c.GetPersonRelated(ctx, personID) + relations, err := h.character.GetPersonRelated(ctx, personID) if err != nil { return nil, errgo.Wrap(err, "CharacterRepo.GetPersonRelated") } @@ -112,7 +112,7 @@ func (h Person) getPersonRelatedCharacters( subjectIDs[i] = relation.SubjectID } - characters, err := h.c.GetByIDs(ctx, characterIDs) + characters, err := h.character.GetByIDs(ctx, characterIDs) if err != nil { return nil, errgo.Wrap(err, "CharacterRepo.GetByIDs") } diff --git a/web/handler/person/person.go b/web/handler/person/person.go index 3146859ae..a087c9cef 100644 --- a/web/handler/person/person.go +++ b/web/handler/person/person.go @@ -17,27 +17,31 @@ package person import ( "github.com/bangumi/server/ctrl" "github.com/bangumi/server/internal/character" + "github.com/bangumi/server/internal/collections" "github.com/bangumi/server/internal/person" "github.com/bangumi/server/internal/subject" ) type Person struct { - person person.Repo - c character.Repo - ctrl ctrl.Ctrl - subject subject.Repo + ctrl ctrl.Ctrl + person person.Repo + character character.Repo + subject subject.Repo + collect collections.Repo } func New( ctrl ctrl.Ctrl, person person.Repo, subject subject.Repo, - c character.Repo, + character character.Repo, + collect collections.Repo, ) (Person, error) { return Person{ - person: person, - ctrl: ctrl, - c: c, - subject: subject, + ctrl: ctrl, + person: person, + character: character, + subject: subject, + collect: collect, }, nil } diff --git a/web/handler/user/collection_test.go b/web/handler/user/collection_test.go index cc54dfeb1..e25c85dcf 100644 --- a/web/handler/user/collection_test.go +++ b/web/handler/user/collection_test.go @@ -130,3 +130,151 @@ func TestUser_ListSubjectCollection_other_user(t *testing.T) { Get(fmt.Sprintf("/v0/users/%s/collections/%d", username, subjectID)). ExpectCode(http.StatusNotFound) } + +func TestUser_GetPersonCollection(t *testing.T) { + t.Parallel() + const username = "ni" + const userID model.UserID = 7 + const personID model.PersonID = 9 + + m := mocks.NewUserRepo(t) + m.EXPECT().GetByName(mock.Anything, username).Return(user.User{ID: userID, UserName: username}, nil) + c := mocks.NewCollectionRepo(t) + c.EXPECT().GetPersonCollection(mock.Anything, userID, mock.Anything, mock.Anything). + Return(collection.UserPersonCollection{UserID: userID, Category: "prsn", TargetID: personID}, nil) + + p := mocks.NewPersonRepo(t) + p.EXPECT().Get(mock.Anything, personID).Return(model.Person{ + ID: personID, + Name: "v", + }, nil) + + app := test.GetWebApp(t, test.Mock{UserRepo: m, CollectionRepo: c, PersonRepo: p}) + + var r res.PersonCollection + resp := htest.New(t, app). + Get(fmt.Sprintf("/v0/users/%s/collections/-/persons/%d", username, personID)). + JSON(&r). + ExpectCode(http.StatusOK) + + require.Equal(t, personID, r.ID, resp.BodyString()) + require.Equal(t, "v", r.Name, resp.BodyString()) +} + +func TestUser_ListPersonCollection(t *testing.T) { + t.Parallel() + const username = "ni" + const userID model.UserID = 7 + const personID model.PersonID = 9 + + m := mocks.NewUserRepo(t) + m.EXPECT().GetByName(mock.Anything, username).Return(user.User{ID: userID, UserName: username}, nil) + + c := mocks.NewCollectionRepo(t) + c.EXPECT().ListPersonCollection(mock.Anything, userID, mock.Anything, 10, 0). + Return([]collection.UserPersonCollection{{UserID: userID, Category: "prsn", TargetID: personID}}, nil) + c.EXPECT().CountPersonCollections(mock.Anything, userID, mock.Anything). + Return(1, nil) + + p := mocks.NewPersonRepo(t) + p.EXPECT().GetByIDs(mock.Anything, mock.Anything).Return(map[model.PersonID]model.Person{ + personID: {ID: personID, Name: "v"}, + }, nil) + + app := test.GetWebApp(t, test.Mock{UserRepo: m, CollectionRepo: c, PersonRepo: p}) + + var r struct { + Data json.RawMessage `json:"data"` + Total int64 `json:"total"` + Limit int `json:"limit"` + Offset int `json:"offset"` + } + + resp := htest.New(t, app). + Query("limit", "10"). + Get(fmt.Sprintf("/v0/users/%s/collections/-/persons", username)). + JSON(&r). + ExpectCode(http.StatusOK) + + var data []res.PersonCollection + require.NoError(t, json.Unmarshal(r.Data, &data)) + + require.Len(t, data, 1) + + require.Equal(t, personID, data[0].ID, resp.BodyString()) + require.Equal(t, "v", data[0].Name, resp.BodyString()) +} + +func TestUser_GetCharacterCollection(t *testing.T) { + t.Parallel() + const username = "ni" + const userID model.UserID = 7 + const characterID model.CharacterID = 9 + + m := mocks.NewUserRepo(t) + m.EXPECT().GetByName(mock.Anything, username).Return(user.User{ID: userID, UserName: username}, nil) + c := mocks.NewCollectionRepo(t) + c.EXPECT().GetPersonCollection(mock.Anything, userID, mock.Anything, mock.Anything). + Return(collection.UserPersonCollection{UserID: userID, Category: "crt", TargetID: characterID}, nil) + + p := mocks.NewCharacterRepo(t) + p.EXPECT().Get(mock.Anything, characterID).Return(model.Character{ + ID: characterID, + Name: "v", + }, nil) + + app := test.GetWebApp(t, test.Mock{UserRepo: m, CollectionRepo: c, CharacterRepo: p}) + + var r res.PersonCollection + resp := htest.New(t, app). + Get(fmt.Sprintf("/v0/users/%s/collections/-/characters/%d", username, characterID)). + JSON(&r). + ExpectCode(http.StatusOK) + + require.Equal(t, characterID, r.ID, resp.BodyString()) + require.Equal(t, "v", r.Name, resp.BodyString()) +} + +func TestUser_ListCharacterCollection(t *testing.T) { + t.Parallel() + const username = "ni" + const userID model.UserID = 7 + const characterID model.CharacterID = 9 + + m := mocks.NewUserRepo(t) + m.EXPECT().GetByName(mock.Anything, username).Return(user.User{ID: userID, UserName: username}, nil) + + c := mocks.NewCollectionRepo(t) + c.EXPECT().ListPersonCollection(mock.Anything, userID, mock.Anything, 10, 0). + Return([]collection.UserPersonCollection{{UserID: userID, Category: "crt", TargetID: characterID}}, nil) + c.EXPECT().CountPersonCollections(mock.Anything, userID, mock.Anything). + Return(1, nil) + + p := mocks.NewCharacterRepo(t) + p.EXPECT().GetByIDs(mock.Anything, mock.Anything).Return(map[model.CharacterID]model.Character{ + characterID: {ID: characterID, Name: "v"}, + }, nil) + + app := test.GetWebApp(t, test.Mock{UserRepo: m, CollectionRepo: c, CharacterRepo: p}) + + var r struct { + Data json.RawMessage `json:"data"` + Total int64 `json:"total"` + Limit int `json:"limit"` + Offset int `json:"offset"` + } + + resp := htest.New(t, app). + Query("limit", "10"). + Get(fmt.Sprintf("/v0/users/%s/collections/-/characters", username)). + JSON(&r). + ExpectCode(http.StatusOK) + + var data []res.PersonCollection + require.NoError(t, json.Unmarshal(r.Data, &data)) + + require.Len(t, data, 1) + + require.Equal(t, characterID, data[0].ID, resp.BodyString()) + require.Equal(t, "v", data[0].Name, resp.BodyString()) +} diff --git a/web/handler/user/get_character_collection.go b/web/handler/user/get_character_collection.go new file mode 100644 index 000000000..42657e601 --- /dev/null +++ b/web/handler/user/get_character_collection.go @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package user + +import ( + "errors" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/collections/domain/collection" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h User) GetCharacterCollection(c echo.Context) error { + username := c.Param("username") + if username == "" { + return res.BadRequest("missing require parameters `username`") + } + + characterID, err := req.ParseID(c.Param("character_id")) + if err != nil { + return err + } + + return h.getCharacterCollection(c, username, characterID) +} + +func (h User) getCharacterCollection(c echo.Context, username string, characterID model.CharacterID) error { + const notFoundMessage = "character is not collected by user" + + character, err := h.character.Get(c.Request().Context(), characterID) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.ErrNotFound + } + + return errgo.Wrap(err, "failed to get character") + } + + u, err := h.user.GetByName(c.Request().Context(), username) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound("user doesn't exist or has been removed") + } + + return errgo.Wrap(err, "failed to get user by name") + } + + collect, err := h.collect.GetPersonCollection( + c.Request().Context(), + u.ID, + collection.PersonCollectCategoryCharacter, + characterID, + ) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound(notFoundMessage) + } + + return errgo.Wrap(err, "failed to get user's character collection") + } + + return c.JSON(http.StatusOK, res.ConvertModelCharacterCollection(collect, character)) +} diff --git a/web/handler/user/get_person_collection.go b/web/handler/user/get_person_collection.go new file mode 100644 index 000000000..1240cb8a4 --- /dev/null +++ b/web/handler/user/get_person_collection.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package user + +import ( + "errors" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/collections/domain/collection" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h User) GetPersonCollection(c echo.Context) error { + username := c.Param("username") + if username == "" { + return res.BadRequest("missing require parameters `username`") + } + + personID, err := req.ParseID(c.Param("person_id")) + if err != nil { + return err + } + + return h.getPersonCollection(c, username, personID) +} + +func (h User) getPersonCollection(c echo.Context, username string, personID model.PersonID) error { + const notFoundMessage = "person is not collected by user" + + person, err := h.person.Get(c.Request().Context(), personID) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.ErrNotFound + } + + return errgo.Wrap(err, "failed to get person") + } + + u, err := h.user.GetByName(c.Request().Context(), username) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound("user doesn't exist or has been removed") + } + + return errgo.Wrap(err, "failed to get user by name") + } + + collect, err := h.collect.GetPersonCollection( + c.Request().Context(), u.ID, collection.PersonCollectCategoryPerson, personID) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound(notFoundMessage) + } + + return errgo.Wrap(err, "failed to get person collect") + } + + return c.JSON(http.StatusOK, res.ConvertModelPersonCollection(collect, person)) +} diff --git a/web/handler/user/list_character_collections.go b/web/handler/user/list_character_collections.go new file mode 100644 index 000000000..38309bc53 --- /dev/null +++ b/web/handler/user/list_character_collections.go @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package user + +import ( + "errors" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/collections/domain/collection" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/generic/slice" + "github.com/bangumi/server/internal/user" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h User) ListCharacterCollection(c echo.Context) error { + page, err := req.GetPageQuery(c, req.DefaultPageLimit, req.DefaultMaxPageLimit) + if err != nil { + return err + } + + username := c.Param("username") + if username == "" { + return res.BadRequest("missing require parameters `username`") + } + + u, err := h.user.GetByName(c.Request().Context(), username) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound("user doesn't exist or has been removed") + } + + return errgo.Wrap(err, "user.GetByName") + } + + return h.listCharacterCollection(c, u, page) +} + +func (h User) listCharacterCollection(c echo.Context, u user.User, page req.PageQuery) error { + count, err := h.collect.CountPersonCollections(c.Request().Context(), u.ID, collection.PersonCollectCategoryCharacter) + if err != nil { + return errgo.Wrap(err, "failed to count user's character collections") + } + + if count == 0 { + return c.JSON(http.StatusOK, res.Paged{Data: []int{}, Total: count, Limit: page.Limit, Offset: page.Offset}) + } + + if err = page.Check(count); err != nil { + return err + } + + cols, err := h.collect.ListPersonCollection( + c.Request().Context(), + u.ID, collection.PersonCollectCategoryCharacter, + page.Limit, page.Offset) + if err != nil { + return errgo.Wrap(err, "failed to list user's person collections") + } + + characterIDs := slice.Map(cols, func(item collection.UserPersonCollection) model.PersonID { + return item.TargetID + }) + + characterMap, err := h.character.GetByIDs(c.Request().Context(), characterIDs) + if err != nil { + return errgo.Wrap(err, "failed to get persons") + } + + var data = make([]res.PersonCollection, 0, len(cols)) + + for _, col := range cols { + character, ok := characterMap[col.TargetID] + if !ok { + continue + } + data = append(data, res.ConvertModelCharacterCollection(col, character)) + } + + return c.JSON(http.StatusOK, res.Paged{ + Data: data, + Total: count, + Limit: page.Limit, + Offset: page.Offset, + }) +} diff --git a/web/handler/user/list_person_collections.go b/web/handler/user/list_person_collections.go new file mode 100644 index 000000000..b48f1da4d --- /dev/null +++ b/web/handler/user/list_person_collections.go @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package user + +import ( + "errors" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/collections/domain/collection" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/generic/slice" + "github.com/bangumi/server/internal/user" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h User) ListPersonCollection(c echo.Context) error { + page, err := req.GetPageQuery(c, req.DefaultPageLimit, req.DefaultMaxPageLimit) + if err != nil { + return err + } + + username := c.Param("username") + if username == "" { + return res.BadRequest("missing require parameters `username`") + } + + u, err := h.user.GetByName(c.Request().Context(), username) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return res.NotFound("user doesn't exist or has been removed") + } + + return errgo.Wrap(err, "user.GetByName") + } + + return h.listPersonCollection(c, u, page) +} + +func (h User) listPersonCollection(c echo.Context, u user.User, page req.PageQuery) error { + count, err := h.collect.CountPersonCollections(c.Request().Context(), u.ID, collection.PersonCollectCategoryPerson) + if err != nil { + return errgo.Wrap(err, "failed to count user's person collections") + } + + if count == 0 { + return c.JSON(http.StatusOK, res.Paged{Data: []int{}, Total: count, Limit: page.Limit, Offset: page.Offset}) + } + + if err = page.Check(count); err != nil { + return err + } + + cols, err := h.collect.ListPersonCollection( + c.Request().Context(), u.ID, collection.PersonCollectCategoryPerson, + page.Limit, page.Offset) + if err != nil { + return errgo.Wrap(err, "failed to list user's person collections") + } + + personIDs := slice.Map(cols, func(item collection.UserPersonCollection) model.PersonID { + return item.TargetID + }) + + personMap, err := h.person.GetByIDs(c.Request().Context(), personIDs) + if err != nil { + return errgo.Wrap(err, "failed to get persons") + } + + var data = make([]res.PersonCollection, 0, len(cols)) + + for _, col := range cols { + person, ok := personMap[col.TargetID] + if !ok { + continue + } + data = append(data, res.ConvertModelPersonCollection(col, person)) + } + + return c.JSON(http.StatusOK, res.Paged{ + Data: data, + Total: count, + Limit: page.Limit, + Offset: page.Offset, + }) +} diff --git a/web/handler/user/user.go b/web/handler/user/user.go index 59236045f..a85733224 100644 --- a/web/handler/user/user.go +++ b/web/handler/user/user.go @@ -19,6 +19,7 @@ import ( "github.com/bangumi/server/config" "github.com/bangumi/server/ctrl" + "github.com/bangumi/server/internal/character" "github.com/bangumi/server/internal/collections" "github.com/bangumi/server/internal/episode" "github.com/bangumi/server/internal/person" @@ -27,18 +28,20 @@ import ( ) type User struct { - ctrl ctrl.Ctrl - episode episode.Repo - person person.Service - collect collections.Repo - subject subject.CachedRepo - log *zap.Logger - user user.Repo - cfg config.AppConfig + ctrl ctrl.Ctrl + episode episode.Repo + character character.Repo + person person.Repo + collect collections.Repo + subject subject.CachedRepo + log *zap.Logger + user user.Repo + cfg config.AppConfig } func New( - p person.Service, + person person.Repo, + character character.Repo, user user.Repo, ctrl ctrl.Ctrl, subject subject.Repo, @@ -47,13 +50,14 @@ func New( log *zap.Logger, ) (User, error) { return User{ - ctrl: ctrl, - episode: episode, - collect: collect, - subject: subject, - user: user, - person: p, - log: log.Named("handler.User"), - cfg: config.AppConfig{}, + ctrl: ctrl, + episode: episode, + collect: collect, + subject: subject, + user: user, + person: person, + character: character, + log: log.Named("handler.User"), + cfg: config.AppConfig{}, }, nil } diff --git a/web/res/collection.go b/web/res/collection.go index 7cb639ec9..84534d55b 100644 --- a/web/res/collection.go +++ b/web/res/collection.go @@ -51,3 +51,33 @@ func ConvertModelSubjectCollection(c collection.UserSubjectCollection, subject S Subject: subject, } } + +type PersonCollection struct { + ID uint32 `json:"id"` + Type uint8 `json:"type"` + Name string `json:"name"` + Images PersonImages `json:"images"` + CreatedAt time.Time `json:"created_at"` +} + +func ConvertModelPersonCollection(c collection.UserPersonCollection, person model.Person) PersonCollection { + img := PersonImage(person.Image) + return PersonCollection{ + ID: person.ID, + Type: person.Type, + Name: person.Name, + Images: img, + CreatedAt: c.CreatedAt, + } +} + +func ConvertModelCharacterCollection(c collection.UserPersonCollection, character model.Character) PersonCollection { + img := PersonImage(character.Image) + return PersonCollection{ + ID: character.ID, + Type: character.Type, + Name: character.Name, + Images: img, + CreatedAt: c.CreatedAt, + } +} diff --git a/web/routes.go b/web/routes.go index dc071617c..f3a2b169c 100644 --- a/web/routes.go +++ b/web/routes.go @@ -66,18 +66,28 @@ func AddRouters( v0.GET("/persons/:id/image", personHandler.GetImage) v0.GET("/persons/:id/subjects", personHandler.GetRelatedSubjects) v0.GET("/persons/:id/characters", personHandler.GetRelatedCharacters) + v0.POST("/persons/:id/collect", personHandler.CollectPerson, mw.NeedLogin) + // TODO: wait for soft delete + // v0.DELETE("/persons/:id/collect", personHandler.UncollectPerson, mw.NeedLogin) + v0.GET("/characters/:id", characterHandler.Get) v0.GET("/characters/:id/image", characterHandler.GetImage) v0.GET("/characters/:id/subjects", characterHandler.GetRelatedSubjects) v0.GET("/characters/:id/persons", characterHandler.GetRelatedPersons) + v0.POST("/characters/:id/collect", characterHandler.CollectCharacter, mw.NeedLogin) + // TODO: wait for soft delete + // v0.DELETE("/characters/:id/collect", characterHandler.UncollectCharacter, mw.NeedLogin) + v0.GET("/episodes/:id", h.GetEpisode) v0.GET("/episodes", h.ListEpisode) // echo 中间件从前往后运行按顺序 v0.GET("/me", userHandler.GetCurrent) v0.GET("/users/:username", userHandler.Get) + v0.GET("/users/:username/avatar", userHandler.GetAvatar) v0.GET("/users/:username/collections", userHandler.ListSubjectCollection) v0.GET("/users/:username/collections/:subject_id", userHandler.GetSubjectCollection) + v0.GET("/users/-/collections/-/episodes/:episode_id", userHandler.GetEpisodeCollection, mw.NeedLogin) v0.PUT("/users/-/collections/-/episodes/:episode_id", userHandler.PutEpisodeCollection, req.JSON, mw.NeedLogin) v0.GET("/users/-/collections/:subject_id/episodes", userHandler.GetSubjectEpisodeCollection, mw.NeedLogin) @@ -86,7 +96,10 @@ func AddRouters( v0.PATCH("/users/-/collections/:subject_id/episodes", userHandler.PatchEpisodeCollectionBatch, req.JSON, mw.NeedLogin) - v0.GET("/users/:username/avatar", userHandler.GetAvatar) + v0.GET("/users/:username/collections/-/characters", userHandler.ListCharacterCollection) + v0.GET("/users/:username/collections/-/characters/:character_id", userHandler.GetCharacterCollection) + v0.GET("/users/:username/collections/-/persons", userHandler.ListPersonCollection) + v0.GET("/users/:username/collections/-/persons/:person_id", userHandler.GetPersonCollection) { i := indexHandler From abb3ee46627b30b2addd373d5452673d113011c8 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Sun, 26 May 2024 15:46:23 +0800 Subject: [PATCH 004/240] feat: add field series for subject v0 res (#565) --- openapi/components/subject_v0.yaml | 7 ++++++- web/handler/subject/get.go | 1 + web/res/subject.go | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/openapi/components/subject_v0.yaml b/openapi/components/subject_v0.yaml index 7bf9df61e..0c8c3ecc7 100644 --- a/openapi/components/subject_v0.yaml +++ b/openapi/components/subject_v0.yaml @@ -10,6 +10,7 @@ required: - platform - volumes - eps + - series - total_episodes - rating - images @@ -34,6 +35,10 @@ properties: summary: title: Summary type: string + series: + title: Series + type: boolean + description: 是否为书籍系列的主条目 nsfw: title: Nsfw type: boolean @@ -47,7 +52,7 @@ properties: platform: title: Platform type: string - description: TV, Web, 欧美剧, PS4... + description: TV, Web, 欧美剧, DLC... images: $ref: "./subject_image.yaml" infobox: diff --git a/web/handler/subject/get.go b/web/handler/subject/get.go index 6e57bfbc4..e7f0f623a 100644 --- a/web/handler/subject/get.go +++ b/web/handler/subject/get.go @@ -142,6 +142,7 @@ func convertModelSubject(s model.Subject, totalEpisode int64) res.SubjectV0 { Doing: s.Doing, }, TypeID: s.TypeID, + Series: s.Series, Locked: s.Locked(), NSFW: s.NSFW, Rating: res.Rating{ diff --git a/web/res/subject.go b/web/res/subject.go index d981c87b7..39f36e54c 100644 --- a/web/res/subject.go +++ b/web/res/subject.go @@ -48,10 +48,11 @@ type SubjectV0 struct { ID model.SubjectID `json:"id"` Eps uint32 `json:"eps"` Volumes uint32 `json:"volumes"` - Redirect model.SubjectID `json:"-"` + Series bool `json:"series"` Locked bool `json:"locked"` NSFW bool `json:"nsfw"` TypeID model.SubjectType `json:"type"` + Redirect model.SubjectID `json:"-"` } type SlimSubjectV0 struct { From cedf8505505b878f5f4e97ce32a2c30320881ad0 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Sun, 26 May 2024 21:22:04 +0800 Subject: [PATCH 005/240] fix(search): restrict search field to names only (#558) --- internal/search/client.go | 4 ++-- internal/search/handle.go | 3 +-- internal/search/index.go | 12 +----------- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/internal/search/client.go b/internal/search/client.go index d1fe8afcc..89b0697d9 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -254,8 +254,8 @@ func (c *client) firstRun() { return } - c.log.Info("set searchable attributes", zap.Strings("attributes", *searchAbleAttribute())) - _, err = subjectIndex.UpdateSearchableAttributes(searchAbleAttribute()) + c.log.Info("set searchable attributes", zap.Strings("attributes", *getAttributes("searchable"))) + _, err = subjectIndex.UpdateSearchableAttributes(getAttributes("searchable")) if err != nil { c.log.Fatal("failed to update search index searchable attributes", zap.Error(err)) return diff --git a/internal/search/handle.go b/internal/search/handle.go index 4404407a8..e264dfb23 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -43,8 +43,7 @@ type Client interface { OnSubjectDelete(ctx context.Context, id model.SubjectID) error } -// Handler -// TODO: 想个办法挪到 web 里面去. +// Handler TODO: 想个办法挪到 web 里面去. type Handler interface { Handle(c echo.Context) error } diff --git a/internal/search/index.go b/internal/search/index.go index a48641970..e3f0cec76 100644 --- a/internal/search/index.go +++ b/internal/search/index.go @@ -29,7 +29,7 @@ type subjectIndex struct { ID model.SubjectID `json:"id"` Summary string `json:"summary"` Tag []string `json:"tag,omitempty" filterable:"true"` - Name []string `json:"name"` + Name []string `json:"name" searchable:"true"` Date int `json:"date,omitempty" filterable:"true" sortable:"true"` Score float64 `json:"score" filterable:"true" sortable:"true"` PageRank float64 `json:"page_rank" sortable:"true"` @@ -40,16 +40,6 @@ type subjectIndex struct { NSFW bool `json:"nsfw" filterable:"true"` } -func searchAbleAttribute() *[]string { - return &[]string{ - "name", - "summary", - "tag", - "type", - "id", - } -} - func rankRule() *[]string { return &[]string{ // 相似度最优先 From 2cd9bfb9fbaa3582a67eedfab919665a260a4efe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 16:48:57 +0800 Subject: [PATCH 006/240] build(deps): update module google.golang.org/grpc to v1.64.0 (#578) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 7 +++---- go.sum | 14 ++++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 403d2617d..558c9e309 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.uber.org/fx v1.21.1 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.22.0 - google.golang.org/grpc v1.63.2 + google.golang.org/grpc v1.64.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.34.0 gopkg.in/yaml.v3 v3.0.1 @@ -94,9 +94,8 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect gorm.io/datatypes v1.2.0 // indirect gorm.io/hints v1.1.2 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect diff --git a/go.sum b/go.sum index 541d8f38a..88afcc3fe 100644 --- a/go.sum +++ b/go.sum @@ -642,12 +642,10 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -657,8 +655,8 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From d2e2ff760fa41309f6a5de652f17d51b2f23e57c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:56:09 +0800 Subject: [PATCH 007/240] build(deps): update module github.com/go-resty/resty/v2 to v2.13.1 (#575) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 24 +++++++++++------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 558c9e309..bcda644f5 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.20.0 github.com/go-redis/redismock/v9 v9.2.0 - github.com/go-resty/resty/v2 v2.12.0 + github.com/go-resty/resty/v2 v2.13.1 github.com/go-sql-driver/mysql v1.8.1 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jarcoal/httpmock v1.3.1 @@ -36,7 +36,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.13 go.uber.org/fx v1.21.1 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.22.0 + golang.org/x/crypto v0.23.0 google.golang.org/grpc v1.64.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.34.0 @@ -89,9 +89,9 @@ require ( go.uber.org/multierr v1.10.0 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect diff --git a/go.sum b/go.sum index 88afcc3fe..2c9a830cf 100644 --- a/go.sum +++ b/go.sum @@ -105,8 +105,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= -github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= -github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= +github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= +github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -487,9 +487,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= @@ -533,9 +532,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 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= @@ -584,16 +582,15 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= 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= @@ -603,8 +600,9 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= From 6a280e779ca08ab53bbc4f4a762234fe17244847 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:57:35 +0800 Subject: [PATCH 008/240] build(deps): update module go.uber.org/fx to v1.22.0 (#576) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bcda644f5..857c40333 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 go.etcd.io/etcd/client/v3 v3.5.13 - go.uber.org/fx v1.21.1 + go.uber.org/fx v1.22.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.23.0 google.golang.org/grpc v1.64.0 diff --git a/go.sum b/go.sum index 2c9a830cf..c174e87c7 100644 --- a/go.sum +++ b/go.sum @@ -463,8 +463,8 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= -go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= +go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= From d9647c640ca7a889c229d2cb399da7593b881ef6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 18:23:26 +0800 Subject: [PATCH 009/240] build(deps): update module go.etcd.io/etcd/client/v3 to v3.5.14 (#572) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 857c40333..c136d3b7c 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 - go.etcd.io/etcd/client/v3 v3.5.13 + go.etcd.io/etcd/client/v3 v3.5.14 go.uber.org/fx v1.22.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.23.0 @@ -83,8 +83,8 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - go.etcd.io/etcd/api/v3 v3.5.13 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect + go.etcd.io/etcd/api/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect diff --git a/go.sum b/go.sum index c174e87c7..8fca48c49 100644 --- a/go.sum +++ b/go.sum @@ -450,12 +450,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.13 h1:8WXU2/NBge6AUF1K1gOexB6e07NgsN1hXK0rSTtgSp4= -go.etcd.io/etcd/api/v3 v3.5.13/go.mod h1:gBqlqkcMMZMVTMm4NDZloEVJzxQOQIls8splbqBDa0c= -go.etcd.io/etcd/client/pkg/v3 v3.5.13 h1:RVZSAnWWWiI5IrYAXjQorajncORbS0zI48LQlE2kQWg= -go.etcd.io/etcd/client/pkg/v3 v3.5.13/go.mod h1:XxHT4u1qU12E2+po+UVPrEeL94Um6zL58ppuJWXSAB8= -go.etcd.io/etcd/client/v3 v3.5.13 h1:o0fHTNJLeO0MyVbc7I3fsCf6nrOqn5d+diSarKnB2js= -go.etcd.io/etcd/client/v3 v3.5.13/go.mod h1:cqiAeY8b5DEEcpxvgWKsbLIWNM/8Wy2xJSDMtioMcoI= +go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= +go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= +go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= +go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= +go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= From 2ba3be4c59197a84083e9d913a71ac5a9a740f63 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Sun, 2 Jun 2024 23:38:38 +0800 Subject: [PATCH 010/240] feat: add api for subjects browsing (#564) Co-authored-by: Trim21 --- Taskfile.yaml | 25 ++++ internal/cachekey/cachekey.go | 8 ++ internal/mocks/SubjectCachedRepo.go | 118 +++++++++++++++++ internal/mocks/SubjectRepo.go | 118 +++++++++++++++++ internal/pkg/gstr/parse.go | 24 ++++ internal/subject/cache_repo.go | 65 ++++++++++ internal/subject/domain.go | 49 +++++++ internal/subject/mysql_repository.go | 88 +++++++++++++ internal/subject/mysql_repository_test.go | 59 +++++++++ openapi/components/subject_cat_anime.yaml | 31 +++++ openapi/components/subject_cat_book.yaml | 27 ++++ openapi/components/subject_cat_game.yaml | 31 +++++ openapi/components/subject_cat_real.yaml | 43 +++++++ openapi/components/subject_v0_slim.yaml | 6 +- openapi/v0.yaml | 115 ++++++++++++++++- readme.md | 4 +- web/handler/subject/browse.go | 150 ++++++++++++++++++++++ web/handler/subject/subject.go | 1 + web/req/query_parse.go | 19 +++ 19 files changed, 975 insertions(+), 6 deletions(-) create mode 100644 openapi/components/subject_cat_anime.yaml create mode 100644 openapi/components/subject_cat_book.yaml create mode 100644 openapi/components/subject_cat_game.yaml create mode 100644 openapi/components/subject_cat_real.yaml create mode 100644 web/handler/subject/browse.go diff --git a/Taskfile.yaml b/Taskfile.yaml index 5f8d4ed0b..ff17b7a14 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -44,6 +44,31 @@ tasks: env: CGO_ENABLED: "0" + web: + desc: Run Web Server + aliases: + - serve + - server + cmds: + - go run main.go --config config.yaml web + + consumer: + desc: Run Kafka Consumer + aliases: + - canal + cmds: + - go run main.go canal --config config.yaml + + openapi-test: + desc: Test OpenAPI Schema + cmds: + - npm run test + + openapi: + desc: Build OpenAPI Schema + cmds: + - npm run build + bench: desc: Run benchmark cmds: diff --git a/internal/cachekey/cachekey.go b/internal/cachekey/cachekey.go index 99ce587f6..319cc3b23 100644 --- a/internal/cachekey/cachekey.go +++ b/internal/cachekey/cachekey.go @@ -35,6 +35,14 @@ func Subject(id model.SubjectID) string { return resPrefix + "subject:" + strconv.FormatUint(uint64(id), 10) } +func SubjectBrowse(s string, limit, offset int) string { + return resPrefix + "subject::browse:" + s + ":" + strconv.Itoa(limit) + ":" + strconv.Itoa(offset) +} + +func SubjectBrowseCount(s string) string { + return resPrefix + "subject::browse:" + s + "::count" +} + func Episode(id model.EpisodeID) string { return resPrefix + "episode:" + strconv.FormatUint(uint64(id), 10) } diff --git a/internal/mocks/SubjectCachedRepo.go b/internal/mocks/SubjectCachedRepo.go index 867524561..48c1ce036 100644 --- a/internal/mocks/SubjectCachedRepo.go +++ b/internal/mocks/SubjectCachedRepo.go @@ -26,6 +26,124 @@ func (_m *SubjectCachedRepo) EXPECT() *SubjectCachedRepo_Expecter { return &SubjectCachedRepo_Expecter{mock: &_m.Mock} } +// Browse provides a mock function with given fields: ctx, filter, limit, offset +func (_m *SubjectCachedRepo) Browse(ctx context.Context, filter subject.BrowseFilter, limit int, offset int) ([]model.Subject, error) { + ret := _m.Called(ctx, filter, limit, offset) + + if len(ret) == 0 { + panic("no return value specified for Browse") + } + + var r0 []model.Subject + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter, int, int) ([]model.Subject, error)); ok { + return rf(ctx, filter, limit, offset) + } + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter, int, int) []model.Subject); ok { + r0 = rf(ctx, filter, limit, offset) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]model.Subject) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, subject.BrowseFilter, int, int) error); ok { + r1 = rf(ctx, filter, limit, offset) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubjectCachedRepo_Browse_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Browse' +type SubjectCachedRepo_Browse_Call struct { + *mock.Call +} + +// Browse is a helper method to define mock.On call +// - ctx context.Context +// - filter subject.BrowseFilter +// - limit int +// - offset int +func (_e *SubjectCachedRepo_Expecter) Browse(ctx interface{}, filter interface{}, limit interface{}, offset interface{}) *SubjectCachedRepo_Browse_Call { + return &SubjectCachedRepo_Browse_Call{Call: _e.mock.On("Browse", ctx, filter, limit, offset)} +} + +func (_c *SubjectCachedRepo_Browse_Call) Run(run func(ctx context.Context, filter subject.BrowseFilter, limit int, offset int)) *SubjectCachedRepo_Browse_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(subject.BrowseFilter), args[2].(int), args[3].(int)) + }) + return _c +} + +func (_c *SubjectCachedRepo_Browse_Call) Return(_a0 []model.Subject, _a1 error) *SubjectCachedRepo_Browse_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SubjectCachedRepo_Browse_Call) RunAndReturn(run func(context.Context, subject.BrowseFilter, int, int) ([]model.Subject, error)) *SubjectCachedRepo_Browse_Call { + _c.Call.Return(run) + return _c +} + +// Count provides a mock function with given fields: ctx, filter +func (_m *SubjectCachedRepo) Count(ctx context.Context, filter subject.BrowseFilter) (int64, error) { + ret := _m.Called(ctx, filter) + + if len(ret) == 0 { + panic("no return value specified for Count") + } + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter) (int64, error)); ok { + return rf(ctx, filter) + } + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter) int64); ok { + r0 = rf(ctx, filter) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, subject.BrowseFilter) error); ok { + r1 = rf(ctx, filter) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubjectCachedRepo_Count_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Count' +type SubjectCachedRepo_Count_Call struct { + *mock.Call +} + +// Count is a helper method to define mock.On call +// - ctx context.Context +// - filter subject.BrowseFilter +func (_e *SubjectCachedRepo_Expecter) Count(ctx interface{}, filter interface{}) *SubjectCachedRepo_Count_Call { + return &SubjectCachedRepo_Count_Call{Call: _e.mock.On("Count", ctx, filter)} +} + +func (_c *SubjectCachedRepo_Count_Call) Run(run func(ctx context.Context, filter subject.BrowseFilter)) *SubjectCachedRepo_Count_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(subject.BrowseFilter)) + }) + return _c +} + +func (_c *SubjectCachedRepo_Count_Call) Return(_a0 int64, _a1 error) *SubjectCachedRepo_Count_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SubjectCachedRepo_Count_Call) RunAndReturn(run func(context.Context, subject.BrowseFilter) (int64, error)) *SubjectCachedRepo_Count_Call { + _c.Call.Return(run) + return _c +} + // Get provides a mock function with given fields: ctx, id, filter func (_m *SubjectCachedRepo) Get(ctx context.Context, id uint32, filter subject.Filter) (model.Subject, error) { ret := _m.Called(ctx, id, filter) diff --git a/internal/mocks/SubjectRepo.go b/internal/mocks/SubjectRepo.go index 84c36ee4b..8ec7b2338 100644 --- a/internal/mocks/SubjectRepo.go +++ b/internal/mocks/SubjectRepo.go @@ -26,6 +26,124 @@ func (_m *SubjectRepo) EXPECT() *SubjectRepo_Expecter { return &SubjectRepo_Expecter{mock: &_m.Mock} } +// Browse provides a mock function with given fields: ctx, filter, limit, offset +func (_m *SubjectRepo) Browse(ctx context.Context, filter subject.BrowseFilter, limit int, offset int) ([]model.Subject, error) { + ret := _m.Called(ctx, filter, limit, offset) + + if len(ret) == 0 { + panic("no return value specified for Browse") + } + + var r0 []model.Subject + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter, int, int) ([]model.Subject, error)); ok { + return rf(ctx, filter, limit, offset) + } + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter, int, int) []model.Subject); ok { + r0 = rf(ctx, filter, limit, offset) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]model.Subject) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, subject.BrowseFilter, int, int) error); ok { + r1 = rf(ctx, filter, limit, offset) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubjectRepo_Browse_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Browse' +type SubjectRepo_Browse_Call struct { + *mock.Call +} + +// Browse is a helper method to define mock.On call +// - ctx context.Context +// - filter subject.BrowseFilter +// - limit int +// - offset int +func (_e *SubjectRepo_Expecter) Browse(ctx interface{}, filter interface{}, limit interface{}, offset interface{}) *SubjectRepo_Browse_Call { + return &SubjectRepo_Browse_Call{Call: _e.mock.On("Browse", ctx, filter, limit, offset)} +} + +func (_c *SubjectRepo_Browse_Call) Run(run func(ctx context.Context, filter subject.BrowseFilter, limit int, offset int)) *SubjectRepo_Browse_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(subject.BrowseFilter), args[2].(int), args[3].(int)) + }) + return _c +} + +func (_c *SubjectRepo_Browse_Call) Return(_a0 []model.Subject, _a1 error) *SubjectRepo_Browse_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SubjectRepo_Browse_Call) RunAndReturn(run func(context.Context, subject.BrowseFilter, int, int) ([]model.Subject, error)) *SubjectRepo_Browse_Call { + _c.Call.Return(run) + return _c +} + +// Count provides a mock function with given fields: ctx, filter +func (_m *SubjectRepo) Count(ctx context.Context, filter subject.BrowseFilter) (int64, error) { + ret := _m.Called(ctx, filter) + + if len(ret) == 0 { + panic("no return value specified for Count") + } + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter) (int64, error)); ok { + return rf(ctx, filter) + } + if rf, ok := ret.Get(0).(func(context.Context, subject.BrowseFilter) int64); ok { + r0 = rf(ctx, filter) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, subject.BrowseFilter) error); ok { + r1 = rf(ctx, filter) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubjectRepo_Count_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Count' +type SubjectRepo_Count_Call struct { + *mock.Call +} + +// Count is a helper method to define mock.On call +// - ctx context.Context +// - filter subject.BrowseFilter +func (_e *SubjectRepo_Expecter) Count(ctx interface{}, filter interface{}) *SubjectRepo_Count_Call { + return &SubjectRepo_Count_Call{Call: _e.mock.On("Count", ctx, filter)} +} + +func (_c *SubjectRepo_Count_Call) Run(run func(ctx context.Context, filter subject.BrowseFilter)) *SubjectRepo_Count_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(subject.BrowseFilter)) + }) + return _c +} + +func (_c *SubjectRepo_Count_Call) Return(_a0 int64, _a1 error) *SubjectRepo_Count_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SubjectRepo_Count_Call) RunAndReturn(run func(context.Context, subject.BrowseFilter) (int64, error)) *SubjectRepo_Count_Call { + _c.Call.Return(run) + return _c +} + // Get provides a mock function with given fields: ctx, id, filter func (_m *SubjectRepo) Get(ctx context.Context, id uint32, filter subject.Filter) (model.Subject, error) { ret := _m.Called(ctx, id, filter) diff --git a/internal/pkg/gstr/parse.go b/internal/pkg/gstr/parse.go index 7b637447a..84287ed13 100644 --- a/internal/pkg/gstr/parse.go +++ b/internal/pkg/gstr/parse.go @@ -20,14 +20,38 @@ import ( "github.com/trim21/errgo" ) +func ParseInt8(s string) (int8, error) { + v, err := strconv.ParseInt(s, 10, 8) + + return int8(v), errgo.Wrap(err, "strconv") +} + func ParseUint8(s string) (uint8, error) { v, err := strconv.ParseUint(s, 10, 8) return uint8(v), errgo.Wrap(err, "strconv") } +func ParseUint16(s string) (uint16, error) { + v, err := strconv.ParseUint(s, 10, 16) + + return uint16(v), errgo.Wrap(err, "strconv") +} + +func ParseInt32(s string) (int32, error) { + v, err := strconv.ParseInt(s, 10, 32) + + return int32(v), errgo.Wrap(err, "strconv") +} + func ParseUint32(s string) (uint32, error) { v, err := strconv.ParseUint(s, 10, 32) return uint32(v), errgo.Wrap(err, "strconv") } + +func ParseBool(s string) (bool, error) { + v, err := strconv.ParseBool(s) + + return v, errgo.Wrap(err, "strconv") +} diff --git a/internal/subject/cache_repo.go b/internal/subject/cache_repo.go index 72ff9da52..c172a87b3 100644 --- a/internal/subject/cache_repo.go +++ b/internal/subject/cache_repo.go @@ -39,6 +39,11 @@ type cacheRepo struct { log *zap.Logger } +const ( + browseCacheTTLFirst = 24 * time.Hour + browseCacheTTLOther = time.Hour +) + func (r cacheRepo) Get(ctx context.Context, id model.SubjectID, filter Filter) (model.Subject, error) { var key = cachekey.Subject(id) @@ -71,6 +76,66 @@ func (r cacheRepo) GetByIDs( return r.repo.GetByIDs(ctx, ids, filter) } +func (r cacheRepo) Count(ctx context.Context, filter BrowseFilter) (int64, error) { + hash, err := filter.Hash() + if err != nil { + return 0, err + } + key := cachekey.SubjectBrowseCount(hash) + + var s int64 + ok, err := r.cache.Get(ctx, key, &s) + if err != nil { + return s, errgo.Wrap(err, "cache.Get") + } + if ok { + return s, nil + } + + s, err = r.repo.Count(ctx, filter) + if err != nil { + return s, err + } + if e := r.cache.Set(ctx, key, s, 10*time.Minute); e != nil { + r.log.Error("can't set response to cache", zap.Error(e)) + } + + return s, nil +} + +func (r cacheRepo) Browse( + ctx context.Context, filter BrowseFilter, limit, offset int, +) ([]model.Subject, error) { + hash, err := filter.Hash() + if err != nil { + return nil, err + } + key := cachekey.SubjectBrowse(hash, limit, offset) + + var subjects []model.Subject + ok, err := r.cache.Get(ctx, key, &subjects) + if err != nil { + return nil, errgo.Wrap(err, "cache.Get") + } + if ok { + return subjects, nil + } + + subjects, err = r.repo.Browse(ctx, filter, limit, offset) + if err != nil { + return nil, err + } + ttl := browseCacheTTLFirst + if offset > 0 { + ttl = browseCacheTTLOther + } + if e := r.cache.Set(ctx, key, subjects, ttl); e != nil { + r.log.Error("can't set response to cache", zap.Error(e)) + } + + return subjects, nil +} + func (r cacheRepo) GetPersonRelated( ctx context.Context, personID model.PersonID, ) ([]domain.SubjectPersonRelation, error) { diff --git a/internal/subject/domain.go b/internal/subject/domain.go index 2fe2c3e8e..ae176f560 100644 --- a/internal/subject/domain.go +++ b/internal/subject/domain.go @@ -16,6 +16,8 @@ package subject import ( "context" + "fmt" + "hash/fnv" "github.com/bangumi/server/domain" "github.com/bangumi/server/internal/model" @@ -27,6 +29,50 @@ type Filter struct { NSFW null.Bool } +type BrowseFilter struct { + NSFW null.Bool + Type uint8 + Category null.Uint16 + Series null.Bool + Platform null.String + Sort null.String + Year null.Int32 + Month null.Int8 +} + +func (f BrowseFilter) Hash() (string, error) { + h := fnv.New64a() + fields := []string{} + fields = append(fields, fmt.Sprintf("type:%v", f.Type)) + if f.NSFW.Set { + fields = append(fields, fmt.Sprintf("nsfw:%v", f.NSFW)) + } + if f.Category.Set { + fields = append(fields, fmt.Sprintf("category:%v", f.Category)) + } + if f.Series.Set { + fields = append(fields, fmt.Sprintf("series:%v", f.Series)) + } + if f.Platform.Set { + fields = append(fields, fmt.Sprintf("platform:%v", f.Platform)) + } + if f.Sort.Set { + fields = append(fields, fmt.Sprintf("sort:%v", f.Sort)) + } + if f.Year.Set { + fields = append(fields, fmt.Sprintf("year:%v", f.Year)) + } + if f.Month.Set { + fields = append(fields, fmt.Sprintf("month:%v", f.Month)) + } + for _, field := range fields { + if _, err := h.Write([]byte(field)); err != nil { + return "", err + } + } + return fmt.Sprintf("%x", h.Sum64()), nil +} + type Repo interface { read } @@ -40,6 +86,9 @@ type read interface { Get(ctx context.Context, id model.SubjectID, filter Filter) (model.Subject, error) GetByIDs(ctx context.Context, ids []model.SubjectID, filter Filter) (map[model.SubjectID]model.Subject, error) + Count(ctx context.Context, filter BrowseFilter) (int64, error) + Browse(ctx context.Context, filter BrowseFilter, limit, offset int) ([]model.Subject, error) + GetPersonRelated(ctx context.Context, personID model.PersonID) ([]domain.SubjectPersonRelation, error) GetCharacterRelated(ctx context.Context, characterID model.CharacterID) ([]domain.SubjectCharacterRelation, error) GetSubjectRelated(ctx context.Context, subjectID model.SubjectID) ([]domain.SubjectInternalRelation, error) diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index a76a9baa7..1765eb9c4 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -231,6 +231,94 @@ func (r mysqlRepo) GetByIDs( return result, nil } +func (r mysqlRepo) Count( + ctx context.Context, + filter BrowseFilter) (int64, error) { + q := r.q.Subject.WithContext(ctx).Joins(r.q.Subject.Fields).Join( + r.q.SubjectField, r.q.Subject.ID.EqCol(r.q.SubjectField.Sid), + ).Where(r.q.Subject.TypeID.Eq(filter.Type)) + if filter.NSFW.Set { + q = q.Where(r.q.Subject.Nsfw.Is(filter.NSFW.Value)) + } + if filter.Category.Set { + q = q.Where(r.q.Subject.Platform.Eq(filter.Category.Value)) + } + if filter.Series.Set { + q = q.Where(r.q.Subject.Series.Is(filter.Series.Value)) + } + if filter.Platform.Set { + q = q.Where(r.q.Subject.Infobox.Like(fmt.Sprintf("%%[%s]%%", filter.Platform.Value))) + } + if filter.Year.Set { + q = q.Where(r.q.SubjectField.Year.Eq(filter.Year.Value)) + } + if filter.Month.Set { + q = q.Where(r.q.SubjectField.Mon.Eq(filter.Month.Value)) + } + + if filter.Sort.Set { + switch filter.Sort.Value { + case "date": + q = q.Order(r.q.SubjectField.Date.Desc()) + case "rank": + q = q.Order(r.q.SubjectField.Rank) + } + } + + return q.Count() +} + +func (r mysqlRepo) Browse( + ctx context.Context, filter BrowseFilter, limit, offset int, +) ([]model.Subject, error) { + q := r.q.Subject.WithContext(ctx).Joins(r.q.Subject.Fields).Join( + r.q.SubjectField, r.q.Subject.ID.EqCol(r.q.SubjectField.Sid), + ).Where(r.q.Subject.TypeID.Eq(filter.Type)) + if filter.NSFW.Set { + q = q.Where(r.q.Subject.Nsfw.Is(filter.NSFW.Value)) + } + if filter.Category.Set { + q = q.Where(r.q.Subject.Platform.Eq(filter.Category.Value)) + } + if filter.Series.Set { + q = q.Where(r.q.Subject.Series.Is(filter.Series.Value)) + } + if filter.Platform.Set { + q = q.Where(r.q.Subject.Infobox.Like(fmt.Sprintf("%%[%s]%%", filter.Platform.Value))) + } + if filter.Year.Set { + q = q.Where(r.q.SubjectField.Year.Eq(filter.Year.Value)) + } + if filter.Month.Set { + q = q.Where(r.q.SubjectField.Mon.Eq(filter.Month.Value)) + } + + if filter.Sort.Set { + switch filter.Sort.Value { + case "date": + q = q.Order(r.q.SubjectField.Date.Desc()) + case "rank": + q = q.Order(r.q.SubjectField.Rank) + } + } + + subjects, err := q.Limit(limit).Offset(offset).Find() + if err != nil { + r.log.Error("unexpected error happened", zap.Error(err)) + return nil, errgo.Wrap(err, "dal") + } + + var result = make([]model.Subject, len(subjects)) + for i, subject := range subjects { + result[i], err = ConvertDao(subject) + if err != nil { + return nil, err + } + } + + return result, nil +} + func (r mysqlRepo) GetActors( ctx context.Context, subjectID model.SubjectID, diff --git a/internal/subject/mysql_repository_test.go b/internal/subject/mysql_repository_test.go index 3dfc5b4fd..adcfad4ce 100644 --- a/internal/subject/mysql_repository_test.go +++ b/internal/subject/mysql_repository_test.go @@ -62,6 +62,65 @@ func TestMysqlRepo_Get_filter(t *testing.T) { require.ErrorIs(t, err, gerr.ErrNotFound) } +func TestBrowse(t *testing.T) { + test.RequireEnv(t, test.EnvMysql) + t.Parallel() + + repo := getRepo(t) + + filter := subject.BrowseFilter{ + Type: 2, + } + s, err := repo.Browse(context.Background(), filter, 30, 0) + require.NoError(t, err) + require.Equal(t, 12, len(s)) + + filter = subject.BrowseFilter{ + Type: 1, + Category: null.New(uint16(1003)), + } + s, err = repo.Browse(context.Background(), filter, 30, 0) + require.NoError(t, err) + require.Equal(t, 2, len(s)) + + filter = subject.BrowseFilter{ + Type: 2, + Year: null.New(int32(2008)), + } + s, err = repo.Browse(context.Background(), filter, 30, 0) + require.NoError(t, err) + require.Equal(t, 2, len(s)) + + filter = subject.BrowseFilter{ + Type: 3, + Sort: null.New("rank"), + } + s, err = repo.Browse(context.Background(), filter, 30, 0) + require.NoError(t, err) + require.Equal(t, 9, len(s)) + require.Equal(t, model.SubjectID(2), s[0].ID) + require.Equal(t, model.SubjectID(20), s[1].ID) + require.Equal(t, model.SubjectID(17), s[2].ID) + require.Equal(t, model.SubjectID(16), s[3].ID) + require.Equal(t, model.SubjectID(15), s[4].ID) + require.Equal(t, model.SubjectID(406604), s[5].ID) + require.Equal(t, model.SubjectID(19), s[6].ID) + require.Equal(t, model.SubjectID(315957), s[7].ID) + require.Equal(t, model.SubjectID(18), s[8].ID) + + filter = subject.BrowseFilter{ + Type: 4, + Platform: null.New("PS3"), + Sort: null.New("date"), + } + s, err = repo.Browse(context.Background(), filter, 30, 0) + require.NoError(t, err) + require.Equal(t, 3, len(s)) + require.Equal(t, model.SubjectID(7), s[0].ID) + require.Equal(t, model.SubjectID(6), s[1].ID) + require.Equal(t, model.SubjectID(13), s[2].ID) +} + func TestMysqlRepo_GetByIDs(t *testing.T) { test.RequireEnv(t, test.EnvMysql) t.Parallel() diff --git a/openapi/components/subject_cat_anime.yaml b/openapi/components/subject_cat_anime.yaml new file mode 100644 index 000000000..42ca9c232 --- /dev/null +++ b/openapi/components/subject_cat_anime.yaml @@ -0,0 +1,31 @@ +title: SubjectAnimeCategory +example: 1 +enum: + - 0 + - 1 + - 2 + - 3 + - 5 +type: integer +description: |- + 动画类型 + - `0` 为 其他 + - `1` 为 TV + - `2` 为 OVA + - `3` 为 Movie + - `5` 为 WEB +x-ms-enum: + name: SubjectAnimeCategory + modelAsString: false + values: + - Other + - TV + - OVA + - Movie + - WEB +x-enum-varnames: + - Other + - TV + - OVA + - Movie + - WEB diff --git a/openapi/components/subject_cat_book.yaml b/openapi/components/subject_cat_book.yaml new file mode 100644 index 000000000..0c5cb8bd7 --- /dev/null +++ b/openapi/components/subject_cat_book.yaml @@ -0,0 +1,27 @@ +title: SubjectBookCategory +example: 1001 +enum: + - 0 + - 1001 + - 1002 + - 1003 +type: integer +description: |- + 书籍类型 + - `0` 为 其他 + - `1001` 为 漫画 + - `1002` 为 小说 + - `1003` 为 画集 +x-ms-enum: + name: SubjectBookCategory + modelAsString: false + values: + - Other + - Comic + - Novel + - Illustration +x-enum-varnames: + - Other + - Comic + - Novel + - Illustration diff --git a/openapi/components/subject_cat_game.yaml b/openapi/components/subject_cat_game.yaml new file mode 100644 index 000000000..ec1eeaafa --- /dev/null +++ b/openapi/components/subject_cat_game.yaml @@ -0,0 +1,31 @@ +title: SubjectGameCategory +example: 4001 +enum: + - 0 + - 4001 + - 4003 + - 4002 + - 4005 +type: integer +description: |- + 游戏类型 + - `0` 为 其他 + - `4001` 为 游戏 + - `4002` 为 软件 + - `4003` 为 扩展包 + - `4005` 为 桌游 +x-ms-enum: + name: SubjectGameCategory + modelAsString: false + values: + - Other + - Games + - Software + - DLC + - Tabletop +x-enum-varnames: + - Other + - Games + - Software + - DLC + - Tabletop diff --git a/openapi/components/subject_cat_real.yaml b/openapi/components/subject_cat_real.yaml new file mode 100644 index 000000000..317d4291b --- /dev/null +++ b/openapi/components/subject_cat_real.yaml @@ -0,0 +1,43 @@ +title: SubjectRealCategory +example: 6 +enum: + - 0 + - 1 + - 2 + - 3 + - 6001 + - 6002 + - 6003 + - 6004 +type: integer +description: |- + 电影类型 + - `0` 为 其他 + - `1` 为 日剧 + - `2` 为 欧美剧 + - `3` 为 华语剧 + - `6001` 为 电视剧 + - `6002` 为 电影 + - `6003` 为 演出 + - `6004` 为 综艺 +x-ms-enum: + name: SubjectRealCategory + modelAsString: false + values: + - Other + - JP + - EN + - CN + - TV + - Movie + - Live + - Show +x-enum-varnames: + - Other + - JP + - EN + - CN + - TV + - Movie + - Live + - Show diff --git a/openapi/components/subject_v0_slim.yaml b/openapi/components/subject_v0_slim.yaml index 8a47772c9..048929646 100644 --- a/openapi/components/subject_v0_slim.yaml +++ b/openapi/components/subject_v0_slim.yaml @@ -52,8 +52,12 @@ properties: type: integer score: description: 分数 - title: Total + title: Score type: number + rank: + description: 排名 + title: Rank + type: integer tags: description: 前 10 个 tag diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 16fb81a38..efd29febe 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -196,6 +196,81 @@ paths: description: 排名 "type": "integer" + "/v0/subjects": + get: + tags: + - 条目 + summary: 浏览条目 + description: 第一页会 cache 24h,之后会 cache 1h + operationId: getSubjects + parameters: + - name: type + in: query + description: 条目类型 + required: true + schema: + $ref: "#/components/schemas/SubjectType" + - name: cat + in: query + description: 条目分类,参照 `SubjectCategory` enum + required: false + schema: + $ref: "#/components/schemas/SubjectCategory" + - name: series + in: query + description: 是否系列,仅对书籍类型的条目有效 + required: false + schema: + type: boolean + - name: platform + in: query + description: 平台,仅对游戏类型的条目有效 + required: false + schema: + type: string + - name: order + in: query + description: 排序,枚举值 {date|rank} + required: false + schema: + title: Sort Order + type: string + - name: year + in: query + description: 年份 + required: false + schema: + type: integer + - name: month + in: query + description: 月份 + required: false + schema: + type: integer + - $ref: "#/components/parameters/default_query_limit" + - $ref: "#/components/parameters/default_query_offset" + responses: + "200": + description: Successful Response + content: + application/json: + schema: + "$ref": "#/components/schemas/Paged_Subject" + "400": + description: Validation Error + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + "404": + description: Not Found + content: + application/json: + schema: + "$ref": "#/components/schemas/ErrorDetail" + security: + - OptionalHTTPBearer: [] + "/v0/subjects/{subject_id}": get: tags: @@ -2310,9 +2385,7 @@ components: title: ID type: integer type: - title: Type - type: integer - description: "`0` 本篇,`1` SP,`2` OP,`3` ED" + $ref: "#/components/schemas/EpType" name: title: Name type: string @@ -2481,6 +2554,28 @@ components: Page: $ref: "./components/page.yaml" + Paged_Subject: + title: Paged[Subject] + type: object + properties: + total: + title: Total + type: integer + default: 0 + limit: + title: Limit + type: integer + default: 0 + offset: + title: Offset + type: integer + default: 0 + data: + title: Data + type: array + items: + "$ref": "#/components/schemas/Subject" + default: [] Paged_Episode: title: Paged[Episode] type: object @@ -3002,6 +3097,20 @@ components: $ref: "./components/subject_tags.yaml" SubjectType: $ref: "./components/subject_type.yaml" + SubjectBookCategory: + $ref: "./components/subject_cat_book.yaml" + SubjectAnimeCategory: + $ref: "./components/subject_cat_anime.yaml" + SubjectGameCategory: + $ref: "./components/subject_cat_game.yaml" + SubjectRealCategory: + $ref: "./components/subject_cat_real.yaml" + SubjectCategory: + anyOf: + - $ref: "#/components/schemas/SubjectBookCategory" + - $ref: "#/components/schemas/SubjectAnimeCategory" + - $ref: "#/components/schemas/SubjectGameCategory" + - $ref: "#/components/schemas/SubjectRealCategory" UserSubjectCollection: $ref: "./components/user_subject_collection.yaml" UserSubjectCollectionModifyPayload: diff --git a/readme.md b/readme.md index 91016cd9e..55104f6a9 100644 --- a/readme.md +++ b/readme.md @@ -78,13 +78,13 @@ ORM: [GORM](https://github.com/go-gorm/gorm) 和 [GORM Gen](https://github.com/g 启动 HTTP server ```shell -go run main.go --config config.yaml web +task web ``` 启动 kafka consumer ```shell -go run main.go canal --config config.yaml +task consumer ``` ### 后端环境 diff --git a/web/handler/subject/browse.go b/web/handler/subject/browse.go new file mode 100644 index 000000000..10618b137 --- /dev/null +++ b/web/handler/subject/browse.go @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package subject + +import ( + "net/http" + + "github.com/labstack/echo/v4" + "github.com/trim21/errgo" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/gstr" + "github.com/bangumi/server/internal/pkg/null" + "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/web/accessor" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +func (h Subject) Browse(c echo.Context) error { + page, err := req.GetPageQuery(c, req.DefaultPageLimit, req.DefaultMaxPageLimit) + if err != nil { + return err + } + + filter, err := parseBrowseQuery(c) + if err != nil { + return err + } + + count, err := h.subject.Count(c.Request().Context(), *filter) + if err != nil { + return errgo.Wrap(err, "failed to count subjects") + } + + if count == 0 { + return c.JSON(http.StatusOK, res.Paged{ + Data: []res.SubjectV0{}, Total: count, Limit: page.Limit, Offset: page.Offset}) + } + + if err = page.Check(count); err != nil { + return err + } + + subjects, err := h.subject.Browse(c.Request().Context(), *filter, page.Limit, page.Offset) + if err != nil { + return errgo.Wrap(err, "failed to browse subjects") + } + data := make([]res.SubjectV0, 0, len(subjects)) + for _, s := range subjects { + data = append(data, convertModelSubject(s, 0)) + } + + return c.JSON(http.StatusOK, res.Paged{Data: data, Total: count, Limit: page.Limit, Offset: page.Offset}) +} + +func parseBrowseQuery(c echo.Context) (*subject.BrowseFilter, error) { + filter := subject.BrowseFilter{} + u := accessor.GetFromCtx(c) + filter.NSFW = null.Bool{Value: !u.AllowNSFW(), Set: true} + if stype, err := req.ParseSubjectType(c.QueryParam("type")); err != nil { + return nil, res.BadRequest(err.Error()) + } else { + filter.Type = stype + } + if catStr := c.QueryParam("cat"); catStr != "" { + if cat, err := req.ParseSubjectCategory(filter.Type, catStr); err != nil { + return nil, res.BadRequest(err.Error()) + } else { + filter.Category = null.Uint16{Value: cat, Set: true} + } + } + if filter.Type == model.SubjectTypeBook { + if seriesStr := c.QueryParam("series"); seriesStr != "" { + if series, err := gstr.ParseBool(seriesStr); err != nil { + return nil, res.BadRequest(err.Error()) + } else { + filter.Series = null.Bool{Value: series, Set: true} + } + } + } + if filter.Type == model.SubjectTypeGame { + if platform := c.QueryParam("platform"); platform != "" { + // TODO: check if platform is valid + filter.Platform = null.String{Value: platform, Set: true} + } + } + if sort := c.QueryParam("sort"); sort != "" { + switch sort { + case "rank", "date": + filter.Sort = null.String{Value: sort, Set: true} + default: + return nil, res.BadRequest("unknown sort: " + sort) + } + } + if year, err := GetYearQuery(c); err != nil { + return nil, err + } else { + filter.Year = year + } + if month, err := GetMonthQuery(c); err != nil { + return nil, err + } else { + filter.Month = month + } + + return &filter, nil +} + +func GetYearQuery(c echo.Context) (null.Int32, error) { + yearStr := c.QueryParam("year") + if yearStr == "" { + return null.Int32{}, nil + } + if year, err := gstr.ParseInt32(yearStr); err != nil { + return null.Int32{}, res.BadRequest(err.Error()) + } else { + if year < 1900 || year > 3000 { + return null.Int32{}, res.BadRequest("invalid year: " + yearStr) + } + return null.Int32{Value: year, Set: true}, nil + } +} + +func GetMonthQuery(c echo.Context) (null.Int8, error) { + monthStr := c.QueryParam("month") + if monthStr == "" { + return null.Int8{}, nil + } + if month, err := gstr.ParseInt8(monthStr); err != nil { + return null.Int8{}, res.BadRequest(err.Error()) + } else { + if month < 1 || month > 12 { + return null.Int8{}, res.BadRequest("invalid month: " + monthStr) + } + return null.Int8{Value: month, Set: true}, nil + } +} diff --git a/web/handler/subject/subject.go b/web/handler/subject/subject.go index b1eec2e71..d7cbf6055 100644 --- a/web/handler/subject/subject.go +++ b/web/handler/subject/subject.go @@ -48,6 +48,7 @@ func New( } func (h *Subject) Routes(g *echo.Group) { + g.GET("/subjects", h.Browse) g.GET("/subjects/:id", h.Get) g.GET("/subjects/:id/image", h.GetImage) g.GET("/subjects/:id/persons", h.GetRelatedPersons) diff --git a/web/req/query_parse.go b/web/req/query_parse.go index e9a71c456..63a0fa085 100644 --- a/web/req/query_parse.go +++ b/web/req/query_parse.go @@ -22,6 +22,7 @@ import ( "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/pkg/gstr" "github.com/bangumi/server/internal/pm" + "github.com/bangumi/server/pkg/vars" "github.com/bangumi/server/web/res" ) @@ -47,6 +48,24 @@ func ParseSubjectType(s string) (model.SubjectType, error) { return 0, res.BadRequest(strconv.Quote(s) + " is not a valid subject type") } +func ParseSubjectCategory(stype model.SubjectType, s string) (uint16, error) { + if s == "" { + return 0, res.BadRequest("subject category is empty") + } + platforms, ok := vars.PlatformMap[stype] + if !ok { + return 0, res.BadRequest("bad subject type: " + strconv.Quote(s)) + } + v, err := gstr.ParseUint16(s) + if err != nil { + return 0, res.BadRequest("bad subject category: " + strconv.Quote(s)) + } + if _, ok := platforms[v]; !ok { + return 0, res.BadRequest("bad subject category: " + strconv.Quote(s)) + } + return v, nil +} + func ParseID(s string) (model.CharacterID, error) { if s == "" { return 0, errMissingID From a1c15ca6a34c00a3801b6c7f723f31d33327b3ce Mon Sep 17 00:00:00 2001 From: everpcpc Date: Mon, 3 Jun 2024 19:35:12 +0800 Subject: [PATCH 011/240] fix: adjust search fields (#582) --- internal/search/extractor.common.go | 11 +++++------ internal/search/index.go | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/internal/search/extractor.common.go b/internal/search/extractor.common.go index 7f63e83e0..6213919d1 100644 --- a/internal/search/extractor.common.go +++ b/internal/search/extractor.common.go @@ -23,20 +23,19 @@ func heat(s *model.Subject) uint32 { return s.OnHold + s.Doing + s.Dropped + s.Wish + s.Collect } -func extractNames(s *model.Subject, w wiki.Wiki) []string { - var names = make([]string, 0, 3) - names = append(names, s.Name) +func extractAliases(s *model.Subject, w wiki.Wiki) []string { + var aliases = make([]string, 0, 2) if s.NameCN != "" { - names = append(names, s.NameCN) + aliases = append(aliases, s.NameCN) } for _, field := range w.Fields { if field.Key == "别名" { - names = append(names, getValues(field)...) + aliases = append(aliases, getValues(field)...) } } - return names + return aliases } func getValues(f wiki.Field) []string { diff --git a/internal/search/index.go b/internal/search/index.go index e3f0cec76..3c7c4433c 100644 --- a/internal/search/index.go +++ b/internal/search/index.go @@ -27,9 +27,9 @@ import ( // 搜索字段因为带有排序,所以定义在 [search.searchAbleAttribute] 中. type subjectIndex struct { ID model.SubjectID `json:"id"` - Summary string `json:"summary"` Tag []string `json:"tag,omitempty" filterable:"true"` - Name []string `json:"name" searchable:"true"` + Name string `json:"name" searchable:"true"` + Aliases []string `json:"aliases,omitempty" searchable:"true"` Date int `json:"date,omitempty" filterable:"true" sortable:"true"` Score float64 `json:"score" filterable:"true" sortable:"true"` PageRank float64 `json:"page_rank" sortable:"true"` @@ -72,9 +72,9 @@ func extractSubject(s *model.Subject) subjectIndex { return subjectIndex{ ID: s.ID, - Name: extractNames(s, w), + Name: s.Name, + Aliases: extractAliases(s, w), Tag: tagNames, - Summary: s.Summary, NSFW: s.NSFW, Type: s.TypeID, Date: parseDateVal(s.Date), From 8cb0d6d5bd3bad644090dc65dc166ae63f043ce3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:26:46 +0800 Subject: [PATCH 012/240] build(deps): update module github.com/aws/aws-sdk-go to v1.53.14 (#574) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c136d3b7c..16b01445c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.22.2 require ( github.com/avast/retry-go/v4 v4.6.0 - github.com/aws/aws-sdk-go v1.51.32 + github.com/aws/aws-sdk-go v1.53.14 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 diff --git a/go.sum b/go.sum index 8fca48c49..f4458cb8c 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinR github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.51.32 h1:A6mPui7QP4mwmovyzgtdedbRbNur1Iu0/El7hBWNHms= -github.com/aws/aws-sdk-go v1.51.32/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.14 h1:SzhkC2Pzag0iRW8WBb80RzKdGXDydJR9LAMs2GyKJ2M= +github.com/aws/aws-sdk-go v1.53.14/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= From 6d80cbf659f63acc8a8080cea79a5b92defe11ac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:26:55 +0800 Subject: [PATCH 013/240] build(deps): update module github.com/prometheus/client_golang to v1.19.1 (#569) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 16b01445c..2d5ab3990 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/meilisearch/meilisearch-go v0.26.2 github.com/mitchellh/mapstructure v1.5.0 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/redis/go-redis/v9 v9.5.1 github.com/samber/lo v1.39.0 github.com/segmentio/kafka-go v0.4.47 diff --git a/go.sum b/go.sum index f4458cb8c..1ec54f6d4 100644 --- a/go.sum +++ b/go.sum @@ -340,8 +340,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= From 95847f1c56a6cd81442d0257d648c94178bfd37b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:27:04 +0800 Subject: [PATCH 014/240] build(deps): update npm (#567) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index be510e9b1..8ec9b068d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,20 @@ "name": "chii", "version": "0.33.19", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.6.1", + "@apidevtools/json-schema-ref-parser": "^11.6.3", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.2.5" + "prettier": "^3.3.0" } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.6.1", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.1.tgz", - "integrity": "sha512-DxjgKBCoyReu4p5HMvpmgSOfRhhBcuf5V5soDDRgOTZMwsA4KSFzol1abFZgiCTE11L2kKGca5Md9GwDdXVBwQ==", + "version": "11.6.3", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.3.tgz", + "integrity": "sha512-lzKdPBz+Eo7xo7GUB2buWl4sqvUhHnMXrde1aRnj2kgbol6S8ZaHviDhKIif5M/q9E0A5ZVp3P9ZBPZnENcUHQ==", "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -294,9 +294,9 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -444,9 +444,9 @@ }, "dependencies": { "@apidevtools/json-schema-ref-parser": { - "version": "11.6.1", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.1.tgz", - "integrity": "sha512-DxjgKBCoyReu4p5HMvpmgSOfRhhBcuf5V5soDDRgOTZMwsA4KSFzol1abFZgiCTE11L2kKGca5Md9GwDdXVBwQ==", + "version": "11.6.3", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.3.tgz", + "integrity": "sha512-lzKdPBz+Eo7xo7GUB2buWl4sqvUhHnMXrde1aRnj2kgbol6S8ZaHviDhKIif5M/q9E0A5ZVp3P9ZBPZnENcUHQ==", "requires": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -664,9 +664,9 @@ } }, "prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", "dev": true }, "reftools": { diff --git a/package.json b/package.json index 068e5c511..627ab4ec9 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "printWidth": 120 }, "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.6.1", + "@apidevtools/json-schema-ref-parser": "^11.6.3", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.2.5" + "prettier": "^3.3.0" }, "nodemonConfig": { "restartable": "rs", From 582bb075596bda3fada8cdf79991d87273e72b98 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:27:21 +0800 Subject: [PATCH 015/240] build(deps): update module github.com/meilisearch/meilisearch-go to v0.26.3 (#568) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2d5ab3990..2ea2d1d8f 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/jarcoal/httpmock v1.3.1 github.com/labstack/echo/v4 v4.12.0 github.com/mattn/go-colorable v0.1.13 - github.com/meilisearch/meilisearch-go v0.26.2 + github.com/meilisearch/meilisearch-go v0.26.3 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 github.com/redis/go-redis/v9 v9.5.1 diff --git a/go.sum b/go.sum index 1ec54f6d4..e901ff530 100644 --- a/go.sum +++ b/go.sum @@ -270,8 +270,8 @@ github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/meilisearch/meilisearch-go v0.26.2 h1:3gTlmiV1dHHumVUhYdJbvh3camiNiyqQ1hNveVsU2OE= -github.com/meilisearch/meilisearch-go v0.26.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= +github.com/meilisearch/meilisearch-go v0.26.3 h1:EYt+C1n7IvjKzgXM3xqce5iJzNBq33F7ayZOKx96TKY= +github.com/meilisearch/meilisearch-go v0.26.3/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= From bad4e663c5cb72b1f644e4b9c99b50a8ed48c98c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:27:41 +0800 Subject: [PATCH 016/240] build(deps): update module github.com/trim21/go-phpserialize to v0.0.22 (#571) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 2ea2d1d8f..063103217 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/trim21/errgo v0.0.2 - github.com/trim21/go-phpserialize v0.0.21 + github.com/trim21/go-phpserialize v0.0.22 github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 diff --git a/go.sum b/go.sum index e901ff530..2ab35e6dd 100644 --- a/go.sum +++ b/go.sum @@ -79,8 +79,8 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -419,8 +419,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trim21/errgo v0.0.2 h1:OlaTR0PaSzBGFgBMEhwwTtnpN2q03WNNr3YossUCHCY= github.com/trim21/errgo v0.0.2/go.mod h1:T9MN4yD51VA68yqmod0e6z4ZjTBd8buD0aCFjfQ+hUM= -github.com/trim21/go-phpserialize v0.0.21 h1:/RaseAU8bDOVJRzmogTD/WNLjcqKJlGueKTs5eF1FJE= -github.com/trim21/go-phpserialize v0.0.21/go.mod h1:vNqVtkwoZtQuK3VMD0KoytIGUEmofWvujEwxvPKjHyo= +github.com/trim21/go-phpserialize v0.0.22 h1:gcs36ir5s3iPFtGrp+3uU/R1lO05Et0nuhaBdUahq0Y= +github.com/trim21/go-phpserialize v0.0.22/go.mod h1:BxWksx+mEAaKC+ekgfTHas1z25dEE3n0bZbAp+tsJUM= github.com/trim21/go-redis-prometheus v0.0.0 h1:9svVIZkKaDGE1bSRbtTQdsKBzW+QEWfwc35QIF8JsfA= github.com/trim21/go-redis-prometheus v0.0.0/go.mod h1:UTXPI/fofnsXF9/X/WtvwhAdbSOBVjLg17xDjQj9VgU= github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= From 6468c635abd281c6f314df349b2ac3502cc04804 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Mon, 3 Jun 2024 20:31:23 +0800 Subject: [PATCH 017/240] fix: do not index merged subject (#583) --- internal/search/client.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/search/client.go b/internal/search/client.go index 89b0697d9..501465b61 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -159,6 +159,9 @@ func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error return errgo.Wrap(err, "subjectRepo.Get") } + if s.Redirect != 0 { + return nil + } extracted := extractSubject(&s) c.queue.Push(extracted) From b4f5f6d9ce830ee9c601d3e8789375db496e4749 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:31:37 +0800 Subject: [PATCH 018/240] build(deps): update module github.com/redis/go-redis/v9 to v9.5.2 (#570) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 063103217..b1f5177eb 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/meilisearch/meilisearch-go v0.26.3 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 - github.com/redis/go-redis/v9 v9.5.1 + github.com/redis/go-redis/v9 v9.5.2 github.com/samber/lo v1.39.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.0 diff --git a/go.sum b/go.sum index 2ab35e6dd..77d8a0ac1 100644 --- a/go.sum +++ b/go.sum @@ -367,8 +367,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= -github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= -github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E= +github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= From 75ce30cfa0c6b50d0b69e6442ce03224cc315392 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Tue, 4 Jun 2024 01:28:38 +0800 Subject: [PATCH 019/240] fix: empty rank for subject browsing (#584) --- internal/subject/mysql_repository.go | 4 ++-- internal/subject/mysql_repository_test.go | 19 +++++++++---------- openapi/v0.yaml | 2 +- web/handler/subject/browse.go | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index 1765eb9c4..5d1652026 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -261,7 +261,7 @@ func (r mysqlRepo) Count( case "date": q = q.Order(r.q.SubjectField.Date.Desc()) case "rank": - q = q.Order(r.q.SubjectField.Rank) + q = q.Where(r.q.SubjectField.Rank.Gt(0)).Order(r.q.SubjectField.Rank) } } @@ -298,7 +298,7 @@ func (r mysqlRepo) Browse( case "date": q = q.Order(r.q.SubjectField.Date.Desc()) case "rank": - q = q.Order(r.q.SubjectField.Rank) + q = q.Where(r.q.SubjectField.Rank.Gt(0)).Order(r.q.SubjectField.Rank) } } diff --git a/internal/subject/mysql_repository_test.go b/internal/subject/mysql_repository_test.go index adcfad4ce..c6a767a99 100644 --- a/internal/subject/mysql_repository_test.go +++ b/internal/subject/mysql_repository_test.go @@ -97,16 +97,15 @@ func TestBrowse(t *testing.T) { } s, err = repo.Browse(context.Background(), filter, 30, 0) require.NoError(t, err) - require.Equal(t, 9, len(s)) - require.Equal(t, model.SubjectID(2), s[0].ID) - require.Equal(t, model.SubjectID(20), s[1].ID) - require.Equal(t, model.SubjectID(17), s[2].ID) - require.Equal(t, model.SubjectID(16), s[3].ID) - require.Equal(t, model.SubjectID(15), s[4].ID) - require.Equal(t, model.SubjectID(406604), s[5].ID) - require.Equal(t, model.SubjectID(19), s[6].ID) - require.Equal(t, model.SubjectID(315957), s[7].ID) - require.Equal(t, model.SubjectID(18), s[8].ID) + require.Equal(t, 8, len(s)) + require.Equal(t, model.SubjectID(20), s[0].ID) + require.Equal(t, model.SubjectID(17), s[1].ID) + require.Equal(t, model.SubjectID(16), s[2].ID) + require.Equal(t, model.SubjectID(15), s[3].ID) + require.Equal(t, model.SubjectID(406604), s[4].ID) + require.Equal(t, model.SubjectID(19), s[5].ID) + require.Equal(t, model.SubjectID(315957), s[6].ID) + require.Equal(t, model.SubjectID(18), s[7].ID) filter = subject.BrowseFilter{ Type: 4, diff --git a/openapi/v0.yaml b/openapi/v0.yaml index efd29febe..e50e0959d 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -228,7 +228,7 @@ paths: required: false schema: type: string - - name: order + - name: sort in: query description: 排序,枚举值 {date|rank} required: false diff --git a/web/handler/subject/browse.go b/web/handler/subject/browse.go index 10618b137..ebfb7b5f3 100644 --- a/web/handler/subject/browse.go +++ b/web/handler/subject/browse.go @@ -69,7 +69,7 @@ func (h Subject) Browse(c echo.Context) error { func parseBrowseQuery(c echo.Context) (*subject.BrowseFilter, error) { filter := subject.BrowseFilter{} u := accessor.GetFromCtx(c) - filter.NSFW = null.Bool{Value: !u.AllowNSFW(), Set: true} + filter.NSFW = null.Bool{Value: false, Set: !u.AllowNSFW()} if stype, err := req.ParseSubjectType(c.QueryParam("type")); err != nil { return nil, res.BadRequest(err.Error()) } else { From b7a3b8d28b735d0370df4f6ae2d70ebea1b09150 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 01:47:45 +0800 Subject: [PATCH 020/240] fix: search nsfw filter --- internal/search/handle.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index e264dfb23..d4af8e959 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -205,7 +205,9 @@ func filterToMeiliFilter(req ReqFilter) [][]string { })) } if req.NSFW.Set { - filter = append(filter, []string{"nsfw = " + strconv.FormatBool(req.NSFW.Value)}) + if !req.NSFW.Value { + filter = append(filter, []string{"nsfw = false"}) + } } // AND From af87d8f304d11611ee64fb51b2c566b89167b6ea Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 22:49:27 +0800 Subject: [PATCH 021/240] fix(search): nsfw response --- internal/search/handle.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index d4af8e959..02d929745 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -110,15 +110,19 @@ func (c *client) Handle(ctx echo.Context) error { } ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) - subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, subject.Filter{NSFW: r.Filter.NSFW}) + subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, subject.Filter{}) if err != nil { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - data := slice.Map(ids, func(id model.SubjectID) ReponseSubject { - s := subjects[id] + var data = make([]ReponseSubject, 0, len(subjects)) + for _, id := range ids { + s, ok := subjects[id] + if !ok { + continue + } - return ReponseSubject{ + data = append(data, ReponseSubject{ Date: s.Date, Image: res.SubjectImage(s.Image).Large, Type: s.TypeID, @@ -131,8 +135,9 @@ func (c *client) Handle(ctx echo.Context) error { Score: s.Rating.Score, ID: s.ID, Rank: s.Rating.Rank, - } - }) + }) + + } return ctx.JSON(http.StatusOK, res.Paged{ Data: data, From 03393cd9d9d543306d9869db2ecd9ac5df0212a9 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 22:57:50 +0800 Subject: [PATCH 022/240] fix(search): nsfw response --- internal/search/handle.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 02d929745..035661d70 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -110,7 +110,13 @@ func (c *client) Handle(ctx echo.Context) error { } ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) - subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, subject.Filter{}) + var sf subject.Filter + + if r.Filter.NSFW.Set && !r.Filter.NSFW.Value { + sf.NSFW = null.Bool{Set: true, Value: false} + } + + subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, sf) if err != nil { return errgo.Wrap(err, "subjectRepo.GetByIDs") } From 273ad3696e4179dc7439e016153a9f001d30e9bc Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 23:11:40 +0800 Subject: [PATCH 023/240] perf: browser filter hash --- internal/subject/domain.go | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/internal/subject/domain.go b/internal/subject/domain.go index ae176f560..cc47e95eb 100644 --- a/internal/subject/domain.go +++ b/internal/subject/domain.go @@ -25,7 +25,6 @@ import ( ) type Filter struct { - // if nsfw subject are allowed NSFW null.Bool } @@ -42,34 +41,30 @@ type BrowseFilter struct { func (f BrowseFilter) Hash() (string, error) { h := fnv.New64a() - fields := []string{} - fields = append(fields, fmt.Sprintf("type:%v", f.Type)) + + fmt.Fprintf(h, "type:%v", f.Type) if f.NSFW.Set { - fields = append(fields, fmt.Sprintf("nsfw:%v", f.NSFW)) + fmt.Fprintf(h, "nsfw:%v", f.NSFW) } if f.Category.Set { - fields = append(fields, fmt.Sprintf("category:%v", f.Category)) + fmt.Fprintf(h, "category:%v", f.Category) } if f.Series.Set { - fields = append(fields, fmt.Sprintf("series:%v", f.Series)) + fmt.Fprintf(h, "series:%v", f.Series) } if f.Platform.Set { - fields = append(fields, fmt.Sprintf("platform:%v", f.Platform)) + fmt.Fprintf(h, "platform:%v", f.Platform) } if f.Sort.Set { - fields = append(fields, fmt.Sprintf("sort:%v", f.Sort)) + fmt.Fprintf(h, "sort:%v", f.Sort) } if f.Year.Set { - fields = append(fields, fmt.Sprintf("year:%v", f.Year)) + fmt.Fprintf(h, "year:%v", f.Year) } if f.Month.Set { - fields = append(fields, fmt.Sprintf("month:%v", f.Month)) - } - for _, field := range fields { - if _, err := h.Write([]byte(field)); err != nil { - return "", err - } + fmt.Fprintf(h, "month:%v", f.Month) } + return fmt.Sprintf("%x", h.Sum64()), nil } From 579b0dc9ec358fc8b232173a74369b4ca644d765 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 23:18:42 +0800 Subject: [PATCH 024/240] fix(search): nsfw response --- internal/search/handle.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 035661d70..6d811f688 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -63,7 +63,9 @@ type ReqFilter struct { //nolint:musttag AirDate []string `json:"air_date"` // and Score []string `json:"rating"` // and Rank []string `json:"rank"` // and - NSFW null.Bool `json:"nsfw"` + + // if NSFW subject is enabled + NSFW bool `json:"nsfw"` } type hit struct { @@ -96,7 +98,7 @@ func (c *client) Handle(ctx echo.Context) error { } if !auth.AllowNSFW() { - r.Filter.NSFW = null.New(false) + r.Filter.NSFW = false } result, err := c.doSearch(r.Keyword, filterToMeiliFilter(r.Filter), r.Sort, q.Limit, q.Offset) @@ -112,7 +114,7 @@ func (c *client) Handle(ctx echo.Context) error { var sf subject.Filter - if r.Filter.NSFW.Set && !r.Filter.NSFW.Value { + if !r.Filter.NSFW { sf.NSFW = null.Bool{Set: true, Value: false} } @@ -215,10 +217,9 @@ func filterToMeiliFilter(req ReqFilter) [][]string { return fmt.Sprintf("type = %d", s) })) } - if req.NSFW.Set { - if !req.NSFW.Value { - filter = append(filter, []string{"nsfw = false"}) - } + + if !req.NSFW { + filter = append(filter, []string{"nsfw = false"}) } // AND From 664ff322186604e52c95a061cf9566c0715f264b Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 23:23:53 +0800 Subject: [PATCH 025/240] fix(search): nsfw response --- internal/search/handle.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 6d811f688..0c321b830 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -65,7 +65,7 @@ type ReqFilter struct { //nolint:musttag Rank []string `json:"rank"` // and // if NSFW subject is enabled - NSFW bool `json:"nsfw"` + NSFW null.Bool `json:"nsfw"` } type hit struct { @@ -98,7 +98,7 @@ func (c *client) Handle(ctx echo.Context) error { } if !auth.AllowNSFW() { - r.Filter.NSFW = false + r.Filter.NSFW = null.New(false) } result, err := c.doSearch(r.Keyword, filterToMeiliFilter(r.Filter), r.Sort, q.Limit, q.Offset) @@ -112,10 +112,10 @@ func (c *client) Handle(ctx echo.Context) error { } ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) - var sf subject.Filter + var sf = subject.Filter{NSFW: null.NewBool(false)} - if !r.Filter.NSFW { - sf.NSFW = null.Bool{Set: true, Value: false} + if r.Filter.NSFW.Set && r.Filter.NSFW.Value { + sf.NSFW = null.Bool{Set: false} } subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, sf) @@ -218,7 +218,11 @@ func filterToMeiliFilter(req ReqFilter) [][]string { })) } - if !req.NSFW { + if req.NSFW.Set { + if !req.NSFW.Value { + filter = append(filter, []string{"nsfw = false"}) + } + } else { filter = append(filter, []string{"nsfw = false"}) } From 8305216059d52ead43725b82235a8505daf54562 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 23:29:34 +0800 Subject: [PATCH 026/240] fix(search): nsfw response --- internal/search/handle.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 0c321b830..f2a43dfda 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -85,6 +85,7 @@ type ReponseSubject struct { Rank uint32 `json:"rank"` } +//nolint:funlen func (c *client) Handle(ctx echo.Context) error { auth := accessor.GetFromCtx(ctx) q, err := req.GetPageQuery(ctx, defaultLimit, maxLimit) @@ -98,7 +99,7 @@ func (c *client) Handle(ctx echo.Context) error { } if !auth.AllowNSFW() { - r.Filter.NSFW = null.New(false) + r.Filter.NSFW.Set = false } result, err := c.doSearch(r.Keyword, filterToMeiliFilter(r.Filter), r.Sort, q.Limit, q.Offset) @@ -112,10 +113,10 @@ func (c *client) Handle(ctx echo.Context) error { } ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) - var sf = subject.Filter{NSFW: null.NewBool(false)} + var sf = subject.Filter{} - if r.Filter.NSFW.Set && r.Filter.NSFW.Value { - sf.NSFW = null.Bool{Set: false} + if !r.Filter.NSFW.Set || !r.Filter.NSFW.Value { + sf.NSFW = null.Bool{Set: true, Value: false} } subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, sf) @@ -144,7 +145,6 @@ func (c *client) Handle(ctx echo.Context) error { ID: s.ID, Rank: s.Rating.Rank, }) - } return ctx.JSON(http.StatusOK, res.Paged{ @@ -218,11 +218,7 @@ func filterToMeiliFilter(req ReqFilter) [][]string { })) } - if req.NSFW.Set { - if !req.NSFW.Value { - filter = append(filter, []string{"nsfw = false"}) - } - } else { + if !req.NSFW.Set || !req.NSFW.Value { filter = append(filter, []string{"nsfw = false"}) } From d198d706052d9ee955eedc4ae4cb8f052935c1f8 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 30 Jun 2024 23:32:36 +0800 Subject: [PATCH 027/240] fix: add nsfw field to search response --- internal/search/handle.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/search/handle.go b/internal/search/handle.go index f2a43dfda..8a444ef92 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -83,6 +83,7 @@ type ReponseSubject struct { Score float64 `json:"score"` ID model.SubjectID `json:"id"` Rank uint32 `json:"rank"` + NSFW bool `json:"nsfw"` } //nolint:funlen @@ -144,6 +145,7 @@ func (c *client) Handle(ctx echo.Context) error { Score: s.Rating.Score, ID: s.ID, Rank: s.Rating.Rank, + NSFW: s.NSFW, }) } From ab3d60a155a7309ec7664b2ca73d7f617baba165 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 1 Jul 2024 00:21:48 +0800 Subject: [PATCH 028/240] tests: fix --- internal/search/handle_internal_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/search/handle_internal_test.go b/internal/search/handle_internal_test.go index 17f2bb668..738f5009f 100644 --- a/internal/search/handle_internal_test.go +++ b/internal/search/handle_internal_test.go @@ -31,6 +31,7 @@ func Test_ReqFilterToMeiliFilter(t *testing.T) { }) require.Equal(t, [][]string{ + {`nsfw = false`}, {`tag = "a"`}, {`tag = "b"`}, }, actual) From 04497c0e08a4d602ba124707e14735ee387e484b Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 1 Jul 2024 00:31:15 +0800 Subject: [PATCH 029/240] fix(search): subject redirect --- internal/search/client.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/search/client.go b/internal/search/client.go index 501465b61..a56a11a7d 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -160,8 +160,9 @@ func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error } if s.Redirect != 0 { - return nil + return c.DeleteSubject(ctx, id) } + extracted := extractSubject(&s) c.queue.Push(extracted) From a19056755604a985f72319f6d8d19cb3dc594de7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 00:37:38 +0800 Subject: [PATCH 030/240] ci: update autofix-ci/action digest to dd55f44 (#588) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/lint-review.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-review.yaml b/.github/workflows/lint-review.yaml index 5d22de19f..596ac2f8a 100644 --- a/.github/workflows/lint-review.yaml +++ b/.github/workflows/lint-review.yaml @@ -29,4 +29,4 @@ jobs: - run: gofmt -w -s . - - uses: autofix-ci/action@ea32e3a12414e6d3183163c3424a7d7a8631ad84 + - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a From a15b799e1d2192b788add893b76a42ee4500f8da Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 00:41:33 +0800 Subject: [PATCH 031/240] build(deps): update npm (#594) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ec9b068d..287ccbe19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,20 @@ "name": "chii", "version": "0.33.19", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.6.3", + "@apidevtools/json-schema-ref-parser": "^11.6.4", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.3.0" + "prettier": "^3.3.2" } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.6.3", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.3.tgz", - "integrity": "sha512-lzKdPBz+Eo7xo7GUB2buWl4sqvUhHnMXrde1aRnj2kgbol6S8ZaHviDhKIif5M/q9E0A5ZVp3P9ZBPZnENcUHQ==", + "version": "11.6.4", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", + "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -294,9 +294,9 @@ } }, "node_modules/prettier": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", - "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -444,9 +444,9 @@ }, "dependencies": { "@apidevtools/json-schema-ref-parser": { - "version": "11.6.3", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.3.tgz", - "integrity": "sha512-lzKdPBz+Eo7xo7GUB2buWl4sqvUhHnMXrde1aRnj2kgbol6S8ZaHviDhKIif5M/q9E0A5ZVp3P9ZBPZnENcUHQ==", + "version": "11.6.4", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", + "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", "requires": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -664,9 +664,9 @@ } }, "prettier": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", - "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true }, "reftools": { diff --git a/package.json b/package.json index 627ab4ec9..c6bc19d12 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "printWidth": 120 }, "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.6.3", + "@apidevtools/json-schema-ref-parser": "^11.6.4", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.3.0" + "prettier": "^3.3.2" }, "nodemonConfig": { "restartable": "rs", From dcdf758b56d0763eb115d90f185878416f67fdb1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:24:39 +0800 Subject: [PATCH 032/240] build(deps): update module github.com/redis/go-redis/v9 to v9.5.3 (#589) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b1f5177eb..33a32d1a9 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/meilisearch/meilisearch-go v0.26.3 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 - github.com/redis/go-redis/v9 v9.5.2 + github.com/redis/go-redis/v9 v9.5.3 github.com/samber/lo v1.39.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.0 diff --git a/go.sum b/go.sum index 77d8a0ac1..c98201e97 100644 --- a/go.sum +++ b/go.sum @@ -367,8 +367,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= -github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E= -github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU= +github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= From 8d06c1b9ffc98f6fa5752b4094c8aa8d9934fc8c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:24:46 +0800 Subject: [PATCH 033/240] build(deps): update module github.com/spf13/cobra to v1.8.1 (#590) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 33a32d1a9..097325ebb 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/redis/go-redis/v9 v9.5.3 github.com/samber/lo v1.39.0 github.com/segmentio/kafka-go v0.4.47 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/trim21/errgo v0.0.2 diff --git a/go.sum b/go.sum index c98201e97..55bd12b2a 100644 --- a/go.sum +++ b/go.sum @@ -60,7 +60,7 @@ github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27 github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -393,8 +393,8 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= From 194738bc4d7c87e8bc8c9af49d57fb4d0eb5662a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:25:49 +0800 Subject: [PATCH 034/240] build(deps): update module go.uber.org/fx to v1.22.1 (#591) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 097325ebb..a93ba005f 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 go.etcd.io/etcd/client/v3 v3.5.14 - go.uber.org/fx v1.22.0 + go.uber.org/fx v1.22.1 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.23.0 google.golang.org/grpc v1.64.0 diff --git a/go.sum b/go.sum index 55bd12b2a..4b91c0ec1 100644 --- a/go.sum +++ b/go.sum @@ -463,8 +463,8 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= -go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= From a4c2ce1d5bf42023927347ffe226c391a14480e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:33:38 +0800 Subject: [PATCH 035/240] build(deps): update module gorm.io/driver/mysql to v1.5.7 (#592) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a93ba005f..e6af73848 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.34.0 gopkg.in/yaml.v3 v3.0.1 - gorm.io/driver/mysql v1.5.6 + gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 gorm.io/gorm v1.25.10 gorm.io/plugin/dbresolver v1.5.1 diff --git a/go.sum b/go.sum index 4b91c0ec1..1d9af5ca4 100644 --- a/go.sum +++ b/go.sum @@ -694,8 +694,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco= gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04= gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= -gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8= -gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= +gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= +gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A= gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= From f756350ba2dfc9cce44d00b2806e4aae3bb9b1b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:34:00 +0800 Subject: [PATCH 036/240] ci: update docker/build-push-action action to v6 (#598) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index 00aa61915..6f95fa57b 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -74,7 +74,7 @@ jobs: password: ${{ github.token }} - name: Build Final Docker Image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: ./ provenance: false From a91340519f528b31429ea73196409ba1e36485dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:35:16 +0800 Subject: [PATCH 037/240] build(deps): update module github.com/aws/aws-sdk-go to v1.54.11 (#595) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e6af73848..8a1aa7ec3 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.22.2 require ( github.com/avast/retry-go/v4 v4.6.0 - github.com/aws/aws-sdk-go v1.53.14 + github.com/aws/aws-sdk-go v1.54.11 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 diff --git a/go.sum b/go.sum index 1d9af5ca4..9c62eb4c0 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinR github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.53.14 h1:SzhkC2Pzag0iRW8WBb80RzKdGXDydJR9LAMs2GyKJ2M= -github.com/aws/aws-sdk-go v1.53.14/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.54.11 h1:Zxuv/R+IVS0B66yz4uezhxH9FN9/G2nbxejYqAMFjxk= +github.com/aws/aws-sdk-go v1.54.11/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= From d3a6716a60e2f4a4db4736549c11ed9913bcd09b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:35:25 +0800 Subject: [PATCH 038/240] build(deps): update module github.com/go-playground/validator/v10 to v10.22.0 (#596) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8a1aa7ec3..9f84c011d 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 - github.com/go-playground/validator/v10 v10.20.0 + github.com/go-playground/validator/v10 v10.22.0 github.com/go-redis/redismock/v9 v9.2.0 github.com/go-resty/resty/v2 v2.13.1 github.com/go-sql-driver/mysql v1.8.1 diff --git a/go.sum b/go.sum index 9c62eb4c0..926c2ae0a 100644 --- a/go.sum +++ b/go.sum @@ -101,8 +101,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= -github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= From 7cfac46ecf4e54347116ec4989687914996cdf9a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:39:47 +0800 Subject: [PATCH 039/240] build(deps): update module gorm.io/plugin/dbresolver to v1.5.2 (#593) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 9f84c011d..4902a2d91 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 gorm.io/gorm v1.25.10 - gorm.io/plugin/dbresolver v1.5.1 + gorm.io/plugin/dbresolver v1.5.2 gorm.io/plugin/soft_delete v1.2.1 ) diff --git a/go.sum b/go.sum index 926c2ae0a..fb2fec2af 100644 --- a/go.sum +++ b/go.sum @@ -108,7 +108,6 @@ github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9 github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= @@ -693,7 +692,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco= gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04= -gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= +gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= @@ -707,17 +706,15 @@ gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY= gorm.io/gen v0.3.26/go.mod h1:a5lq5y3w4g5LMxBcw0wnO6tYUCdNutWODq5LrIt75LE= gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o= gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg= -gorm.io/plugin/dbresolver v1.5.1 h1:s9Dj9f7r+1rE3nx/Ywzc85nXptUEaeOO0pt27xdopM8= -gorm.io/plugin/dbresolver v1.5.1/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0= +gorm.io/plugin/dbresolver v1.5.2 h1:Iut7lW4TXNoVs++I+ra3zxjSxTRj4ocIeFEVp4lLhII= +gorm.io/plugin/dbresolver v1.5.2/go.mod h1:jPh59GOQbO7v7v28ZKZPd45tr+u3vyT+8tHdfdfOWcU= gorm.io/plugin/soft_delete v1.2.1 h1:qx9D/c4Xu6w5KT8LviX8DgLcB9hkKl6JC9f44Tj7cGU= gorm.io/plugin/soft_delete v1.2.1/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From e5b0933af5673f9dc45f2489a9d927b647c035fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 05:16:21 +0800 Subject: [PATCH 040/240] build(deps): update module github.com/samber/lo to v1.44.0 (#597) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 4902a2d91..41682b049 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 github.com/redis/go-redis/v9 v9.5.3 - github.com/samber/lo v1.39.0 + github.com/samber/lo v1.44.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 @@ -87,13 +87,13 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect - golang.org/x/mod v0.14.0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.25.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect gorm.io/datatypes v1.2.0 // indirect diff --git a/go.sum b/go.sum index fb2fec2af..a74ca6c64 100644 --- a/go.sum +++ b/go.sum @@ -375,8 +375,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.44.0 h1:5il56KxRE+GHsm1IR+sZ/6J42NODigFiqCWpSc2dybA= +github.com/samber/lo v1.44.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0= @@ -489,8 +489,6 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -502,8 +500,8 @@ 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= @@ -544,8 +542,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ 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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= @@ -600,8 +598,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 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/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -624,8 +623,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY 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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 0ff8ee09dfdd9ae40d455ec1e9e5b89d3279e194 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 05:16:51 +0800 Subject: [PATCH 041/240] ci: update golangci/golangci-lint-action action to v6 (#579) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a3b04ec85..3be3f7eb5 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -48,6 +48,6 @@ jobs: - run: go get -t ./... - name: Run linters - uses: golangci/golangci-lint-action@v5 + uses: golangci/golangci-lint-action@v6 with: version: v1.57.2 From cd8a22e3df674c88169f374329c845f9a098267f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 05:17:05 +0800 Subject: [PATCH 042/240] build(deps): update module google.golang.org/protobuf to v1.34.2 (#573) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 41682b049..95229e1e7 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( golang.org/x/crypto v0.23.0 google.golang.org/grpc v1.64.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 - google.golang.org/protobuf v1.34.0 + google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 diff --git a/go.sum b/go.sum index a74ca6c64..e170b8ed5 100644 --- a/go.sum +++ b/go.sum @@ -661,8 +661,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From bd143c2bbfe300865c12b7a060ff5a6a3f2fd547 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 05:23:22 +0800 Subject: [PATCH 043/240] build(deps): update module golang.org/x/crypto to v0.24.0 (#577) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 95229e1e7..6a7cf4058 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.14 go.uber.org/fx v1.22.1 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.23.0 + golang.org/x/crypto v0.24.0 google.golang.org/grpc v1.64.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.34.2 @@ -90,7 +90,7 @@ require ( golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect + golang.org/x/sys v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect diff --git a/go.sum b/go.sum index e170b8ed5..828c1c4f3 100644 --- a/go.sum +++ b/go.sum @@ -486,8 +486,9 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -579,8 +580,9 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= From 82115a39470653f6d55d289fcfd177413848351b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 05:23:31 +0800 Subject: [PATCH 044/240] build(deps): update module google.golang.org/grpc/cmd/protoc-gen-go-grpc to v1.4.0 (#580) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6a7cf4058..ae1c12107 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/crypto v0.24.0 google.golang.org/grpc v1.64.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 diff --git a/go.sum b/go.sum index 828c1c4f3..462c86787 100644 --- a/go.sum +++ b/go.sum @@ -655,8 +655,8 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 h1:9SxA29VM43MF5Z9dQu694wmY5t8E/Gxr7s+RSxiIDmc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0/go.mod h1:yZOK5zhQMiALmuweVdIVoQPa6eIJyXn2B9g5dJDhqX4= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 6269bbf9620f703e9f0be428d69259f849abbf92 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 9 Jul 2024 00:20:15 +0800 Subject: [PATCH 045/240] fix: subject name escape (#599) --- internal/subject/mysql_repository.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index 5d1652026..2c924b769 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "html" "math" "github.com/trim21/errgo" @@ -75,8 +76,8 @@ func ConvertDao(s *dao.Subject) (model.Subject, error) { Redirect: s.Fields.Redirect, Date: date, ID: s.ID, - Name: s.Name, - NameCN: s.NameCN, + Name: html.UnescapeString(s.Name), + NameCN: html.UnescapeString(s.NameCN), TypeID: s.TypeID, Image: s.Image, PlatformID: s.Platform, From b8ea73948b71d08dbf0eeac1b9e99d3cf45e9209 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 06:24:16 +0800 Subject: [PATCH 046/240] build(deps): update module google.golang.org/grpc to v1.64.1 [security] (#601) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index ae1c12107..6d657ab01 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.uber.org/fx v1.22.1 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.24.0 - google.golang.org/grpc v1.64.0 + google.golang.org/grpc v1.64.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 @@ -88,7 +88,7 @@ require ( go.uber.org/dig v1.17.1 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect diff --git a/go.sum b/go.sum index 462c86787..9e44fc94b 100644 --- a/go.sum +++ b/go.sum @@ -530,8 +530,9 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 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= @@ -653,8 +654,8 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 h1:9SxA29VM43MF5Z9dQu694wmY5t8E/Gxr7s+RSxiIDmc= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0/go.mod h1:yZOK5zhQMiALmuweVdIVoQPa6eIJyXn2B9g5dJDhqX4= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From 8f260252f609413e34eb630658b1482bc75d2059 Mon Sep 17 00:00:00 2001 From: Ronnie Wang Date: Mon, 22 Jul 2024 01:30:22 +0800 Subject: [PATCH 047/240] feat: enrich new fields in archive program (#602) --- cmd/archive/main.go | 83 +++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/cmd/archive/main.go b/cmd/archive/main.go index ca504be95..7cba8e92e 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -180,6 +180,14 @@ type Score struct { Field10 uint32 `json:"10"` } +type Favorite struct { + Wish uint32 `json:"wish"` + Done uint32 `json:"done"` + Doing uint32 `json:"doing"` + OnHold uint32 `json:"on_hold"` + Dropped uint32 `json:"dropped"` +} + type Subject struct { ID model.SubjectID `json:"id"` Type model.SubjectType `json:"type"` @@ -190,10 +198,12 @@ type Subject struct { Summary string `json:"summary"` Nsfw bool `json:"nsfw"` - Tags []Tag `json:"tags"` - Score float64 `json:"score"` - ScoreDetails Score `json:"score_details"` - Rank uint32 `json:"rank"` + Tags []Tag `json:"tags"` + Score float64 `json:"score"` + ScoreDetails Score `json:"score_details"` + Rank uint32 `json:"rank"` + Date string `json:"date"` + Favorite Favorite `json:"favorite"` } type Tag struct { @@ -238,6 +248,11 @@ func exportSubjects(q *query.Query, w io.Writer) { 6*f.Rate6+7*f.Rate7+8*f.Rate8+9*f.Rate9+10*f.Rate10) / float64(total) } + encodedDate := "" + if !subject.Fields.Date.IsZero() { + encodedDate = subject.Fields.Date.Format("2006-01-02") + } + encode(w, Subject{ ID: subject.ID, Type: subject.TypeID, @@ -262,18 +277,28 @@ func exportSubjects(q *query.Query, w io.Writer) { Field9: subject.Fields.Rate9, Field10: subject.Fields.Rate10, }, + Date: encodedDate, + Favorite: Favorite{ + Wish: subject.Wish, + Done: subject.Done, + Doing: subject.Doing, + OnHold: subject.OnHold, + Dropped: subject.Dropped, + }, }) } } } type Person struct { - ID model.PersonID `json:"id"` - Name string `json:"name"` - Type uint8 `json:"type"` - Career []string `json:"career"` - Infobox string `json:"infobox"` - Summary string `json:"summary"` + ID model.PersonID `json:"id"` + Name string `json:"name"` + Type uint8 `json:"type"` + Career []string `json:"career"` + Infobox string `json:"infobox"` + Summary string `json:"summary"` + Comments uint32 `json:"comments"` + Collects uint32 `json:"collects"` } func exportPersons(q *query.Query, w io.Writer) { @@ -286,12 +311,14 @@ func exportPersons(q *query.Query, w io.Writer) { for _, p := range persons { encode(w, Person{ - ID: p.ID, - Name: p.Name, - Type: p.Type, - Career: careers(p), - Infobox: p.Infobox, - Summary: p.Summary, + ID: p.ID, + Name: p.Name, + Type: p.Type, + Career: careers(p), + Infobox: p.Infobox, + Summary: p.Summary, + Comments: p.Comment, + Collects: p.Collects, }) } } @@ -336,11 +363,13 @@ func careers(p *dao.Person) []string { } type Character struct { - ID model.CharacterID `json:"id"` - Role uint8 `json:"role"` - Name string `json:"name"` - Infobox string `json:"infobox"` - Summary string `json:"summary"` + ID model.CharacterID `json:"id"` + Role uint8 `json:"role"` + Name string `json:"name"` + Infobox string `json:"infobox"` + Summary string `json:"summary"` + Comments uint32 `json:"comments"` + Collects uint32 `json:"collects"` } func exportCharacters(q *query.Query, w io.Writer) { @@ -353,11 +382,13 @@ func exportCharacters(q *query.Query, w io.Writer) { for _, c := range characters { encode(w, Character{ - ID: c.ID, - Name: c.Name, - Role: c.Role, - Infobox: c.Infobox, - Summary: c.Summary, + ID: c.ID, + Name: c.Name, + Role: c.Role, + Infobox: c.Infobox, + Summary: c.Summary, + Comments: c.Comment, + Collects: c.Collects, }) } } From 5c576e267268c490a0b97686d0668ffc36bf1dd9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:37:44 +0800 Subject: [PATCH 048/240] build(deps): update npm (#605) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 287ccbe19..40ca6472a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,20 @@ "name": "chii", "version": "0.33.19", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.6.4", + "@apidevtools/json-schema-ref-parser": "^11.7.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.3.2" + "prettier": "^3.3.3" } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.6.4", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", - "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", + "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -294,9 +294,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -444,9 +444,9 @@ }, "dependencies": { "@apidevtools/json-schema-ref-parser": { - "version": "11.6.4", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", - "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", + "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", "requires": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -664,9 +664,9 @@ } }, "prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true }, "reftools": { diff --git a/package.json b/package.json index c6bc19d12..2848db844 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "printWidth": 120 }, "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.6.4", + "@apidevtools/json-schema-ref-parser": "^11.7.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.3.2" + "prettier": "^3.3.3" }, "nodemonConfig": { "restartable": "rs", From d9e06b4a51a029a3a73625bc9471a0c38ce5f178 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 14 Aug 2024 22:59:31 +0800 Subject: [PATCH 049/240] minor refactor --- internal/pkg/random/string.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/pkg/random/string.go b/internal/pkg/random/string.go index fb1524822..b767b12dd 100644 --- a/internal/pkg/random/string.go +++ b/internal/pkg/random/string.go @@ -28,8 +28,8 @@ var p = pool.New(func() *bufio.Reader { // we may never need to change these values. const base62Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -const base62CharsLength = 62 // len(base62Chars) -const base62MaxByte byte = 255 - (256 % base62CharsLength) //nolint:gomnd +const base62CharsLength = byte(len(base62Chars)) +const base62MaxByte = byte(255 - (256 % len(base62Chars))) // Base62String generate a cryptographically secure base62 string in given length. // Will panic if it can't read from 'crypto/rand'. From b18c75fbb037edd42942fadcb013e303fea3b191 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 14 Aug 2024 23:00:31 +0800 Subject: [PATCH 050/240] fix: upgrade chii_crt_subject_index.crt_order type --- cmd/archive/main.go | 2 +- dal/dao/chii_crt_subject_index.gen.go | 2 +- dal/query/chii_crt_subject_index.gen.go | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/archive/main.go b/cmd/archive/main.go index 7cba8e92e..316e9b407 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -490,7 +490,7 @@ type SubjectCharacter struct { CharacterID model.CharacterID `json:"character_id"` SubjectID model.SubjectID `json:"subject_id"` Type uint8 `json:"type"` - Order uint8 `json:"order"` + Order uint16 `json:"order"` } func exportSubjectCharacterRelations(q *query.Query, w io.Writer) { diff --git a/dal/dao/chii_crt_subject_index.gen.go b/dal/dao/chii_crt_subject_index.gen.go index 09671e218..960048ca9 100644 --- a/dal/dao/chii_crt_subject_index.gen.go +++ b/dal/dao/chii_crt_subject_index.gen.go @@ -13,7 +13,7 @@ type CharacterSubjects struct { SubjectTypeID uint8 `gorm:"column:subject_type_id;type:tinyint(4) unsigned;not null" json:""` CrtType uint8 `gorm:"column:crt_type;type:tinyint(4) unsigned;not null;comment:主角,配角" json:""` // 主角,配角 CtrAppearEps string `gorm:"column:ctr_appear_eps;type:mediumtext;not null;comment:可选,角色出场的的章节" json:""` // 可选,角色出场的的章节 - CrtOrder uint8 `gorm:"column:crt_order;type:tinyint(3) unsigned;not null" json:""` + CrtOrder uint16 `gorm:"column:crt_order;type:smallint(6) unsigned;not null" json:""` Character Character `gorm:"foreignKey:crt_id;references:crt_id" json:"character"` Subject Subject `gorm:"foreignKey:subject_id;references:subject_id" json:"subject"` } diff --git a/dal/query/chii_crt_subject_index.gen.go b/dal/query/chii_crt_subject_index.gen.go index 10be0b8b0..0f18a66a0 100644 --- a/dal/query/chii_crt_subject_index.gen.go +++ b/dal/query/chii_crt_subject_index.gen.go @@ -32,7 +32,7 @@ func newCharacterSubjects(db *gorm.DB, opts ...gen.DOOption) characterSubjects { _characterSubjects.SubjectTypeID = field.NewUint8(tableName, "subject_type_id") _characterSubjects.CrtType = field.NewUint8(tableName, "crt_type") _characterSubjects.CtrAppearEps = field.NewString(tableName, "ctr_appear_eps") - _characterSubjects.CrtOrder = field.NewUint8(tableName, "crt_order") + _characterSubjects.CrtOrder = field.NewUint16(tableName, "crt_order") _characterSubjects.Character = characterSubjectsHasOneCharacter{ db: db.Session(&gorm.Session{}), @@ -69,7 +69,7 @@ type characterSubjects struct { SubjectTypeID field.Uint8 CrtType field.Uint8 // 主角,配角 CtrAppearEps field.String // 可选,角色出场的的章节 - CrtOrder field.Uint8 + CrtOrder field.Uint16 Character characterSubjectsHasOneCharacter Subject characterSubjectsHasOneSubject @@ -94,7 +94,7 @@ func (c *characterSubjects) updateTableName(table string) *characterSubjects { c.SubjectTypeID = field.NewUint8(table, "subject_type_id") c.CrtType = field.NewUint8(table, "crt_type") c.CtrAppearEps = field.NewString(table, "ctr_appear_eps") - c.CrtOrder = field.NewUint8(table, "crt_order") + c.CrtOrder = field.NewUint16(table, "crt_order") c.fillFieldMap() From 9b62696e5f7c20a0b6182a3326d72d70f7c1c519 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 14 Aug 2024 23:02:09 +0800 Subject: [PATCH 051/240] ci: upgrade docker compose --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2001ad827..46dec39a0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-22.04 steps: - run: git clone https://github.com/bangumi/dev-env $HOME/dev-env - - run: cd ~/dev-env && docker-compose up -d + - run: cd ~/dev-env && docker compose up -d - uses: actions/checkout@v4 with: From d4ada11c7155ef0b6c50e6cd03258db9ac824765 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:12:37 +0800 Subject: [PATCH 052/240] build(deps): update module google.golang.org/grpc to v1.65.0 (#614) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 15 ++++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 6d657ab01..c635620e0 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.uber.org/fx v1.22.1 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.24.0 - google.golang.org/grpc v1.64.1 + google.golang.org/grpc v1.65.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 @@ -53,7 +53,7 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -94,8 +94,8 @@ require ( golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect gorm.io/datatypes v1.2.0 // indirect gorm.io/hints v1.1.2 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect diff --git a/go.sum b/go.sum index 9e44fc94b..41eed42e8 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,9 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -641,10 +642,10 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -654,8 +655,8 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 h1:9SxA29VM43MF5Z9dQu694wmY5t8E/Gxr7s+RSxiIDmc= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0/go.mod h1:yZOK5zhQMiALmuweVdIVoQPa6eIJyXn2B9g5dJDhqX4= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From e32bf0b9832d9e06e97fce2108489ef7a116bb33 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 14 Aug 2024 23:33:57 +0800 Subject: [PATCH 053/240] style: disable lint --- internal/pkg/random/string.go | 2 +- internal/pkg/random/string_internal_test.go | 28 --------------------- 2 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 internal/pkg/random/string_internal_test.go diff --git a/internal/pkg/random/string.go b/internal/pkg/random/string.go index b767b12dd..d5590d361 100644 --- a/internal/pkg/random/string.go +++ b/internal/pkg/random/string.go @@ -29,7 +29,7 @@ var p = pool.New(func() *bufio.Reader { // we may never need to change these values. const base62Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" const base62CharsLength = byte(len(base62Chars)) -const base62MaxByte = byte(255 - (256 % len(base62Chars))) +const base62MaxByte = byte(255 - (256 % len(base62Chars))) //nolint:gomnd // Base62String generate a cryptographically secure base62 string in given length. // Will panic if it can't read from 'crypto/rand'. diff --git a/internal/pkg/random/string_internal_test.go b/internal/pkg/random/string_internal_test.go deleted file mode 100644 index 166cfb5ee..000000000 --- a/internal/pkg/random/string_internal_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see - -package random - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestConst(t *testing.T) { - t.Parallel() - - require.EqualValues(t, len(base62Chars), base62CharsLength) - require.EqualValues(t, 255-(256%len(base62Chars)), base62MaxByte) -} From 61682811a6dde9cd33230e10d1f4c9b79fd97368 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:35:44 +0800 Subject: [PATCH 054/240] build(deps): update module github.com/redis/go-redis/v9 to v9.6.1 (#611) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c635620e0..3de6dd62a 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/meilisearch/meilisearch-go v0.26.3 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 - github.com/redis/go-redis/v9 v9.5.3 + github.com/redis/go-redis/v9 v9.6.1 github.com/samber/lo v1.44.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 diff --git a/go.sum b/go.sum index 41eed42e8..2944200b7 100644 --- a/go.sum +++ b/go.sum @@ -367,8 +367,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= -github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU= -github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= From 3d16bfb0bc2694b5dfaa70f3af1b4cdb65249923 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:36:02 +0800 Subject: [PATCH 055/240] build(deps): update module github.com/trim21/errgo to v0.0.3 (#606) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3de6dd62a..fabe91f0d 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 - github.com/trim21/errgo v0.0.2 + github.com/trim21/errgo v0.0.3 github.com/trim21/go-phpserialize v0.0.22 github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 diff --git a/go.sum b/go.sum index 2944200b7..4094e1bd4 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= @@ -417,8 +419,8 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/trim21/errgo v0.0.2 h1:OlaTR0PaSzBGFgBMEhwwTtnpN2q03WNNr3YossUCHCY= -github.com/trim21/errgo v0.0.2/go.mod h1:T9MN4yD51VA68yqmod0e6z4ZjTBd8buD0aCFjfQ+hUM= +github.com/trim21/errgo v0.0.3 h1:q0cUPTs+4c5NxByA4f0HUGRvlNyBlUtdxFiTKQdTE68= +github.com/trim21/errgo v0.0.3/go.mod h1:AH1KzogdvSkSPXbZq9QAuqSt1L1Eu5W8eYK32zPYv9s= github.com/trim21/go-phpserialize v0.0.22 h1:gcs36ir5s3iPFtGrp+3uU/R1lO05Et0nuhaBdUahq0Y= github.com/trim21/go-phpserialize v0.0.22/go.mod h1:BxWksx+mEAaKC+ekgfTHas1z25dEE3n0bZbAp+tsJUM= github.com/trim21/go-redis-prometheus v0.0.0 h1:9svVIZkKaDGE1bSRbtTQdsKBzW+QEWfwc35QIF8JsfA= From b30fe2e79828df0d124280fc8669d78d653fc225 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:36:19 +0800 Subject: [PATCH 056/240] build(deps): update module go.etcd.io/etcd/client/v3 to v3.5.15 (#607) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index fabe91f0d..bb04f6fc6 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 - go.etcd.io/etcd/client/v3 v3.5.14 + go.etcd.io/etcd/client/v3 v3.5.15 go.uber.org/fx v1.22.1 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.24.0 @@ -83,8 +83,8 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect + go.etcd.io/etcd/api/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect diff --git a/go.sum b/go.sum index 4094e1bd4..19f5e67c4 100644 --- a/go.sum +++ b/go.sum @@ -452,12 +452,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk= +go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM= +go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA= +go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU= +go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4= +go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= From 3ec2ea01fea8b7d515048bc97ffba8051cce09aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:36:34 +0800 Subject: [PATCH 057/240] chore(deps): update gcr.io/distroless/static docker digest to ce46866 (#603) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- etc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/Dockerfile b/etc/Dockerfile index c318a35b6..78ec71132 100644 --- a/etc/Dockerfile +++ b/etc/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/distroless/static@sha256:41972110a1c1a5c0b6adb283e8aa092c43c31f7c5d79b8656fbffff2c3e61f05 +FROM gcr.io/distroless/static@sha256:ce46866b3a5170db3b49364900fb3168dc0833dfb46c26da5c77f22abb01d8c3 ENTRYPOINT ["/app/chii.exe"] From 2eb52906fb25a36da64e3648d1639ae7df4ac693 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:36:51 +0800 Subject: [PATCH 058/240] ci: update autofix-ci/action digest to ff86a55 (#604) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/lint-review.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-review.yaml b/.github/workflows/lint-review.yaml index 596ac2f8a..066941984 100644 --- a/.github/workflows/lint-review.yaml +++ b/.github/workflows/lint-review.yaml @@ -29,4 +29,4 @@ jobs: - run: gofmt -w -s . - - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a + - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c From fe5325e2b2451722eb81305b21bffe5d65cf0666 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:37:07 +0800 Subject: [PATCH 059/240] build(deps): update module gorm.io/gorm to v1.25.11 (#608) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bb04f6fc6..5c4f24aae 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 - gorm.io/gorm v1.25.10 + gorm.io/gorm v1.25.11 gorm.io/plugin/dbresolver v1.5.2 gorm.io/plugin/soft_delete v1.2.1 ) diff --git a/go.sum b/go.sum index 19f5e67c4..cfc98a958 100644 --- a/go.sum +++ b/go.sum @@ -714,8 +714,8 @@ gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= -gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= +gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o= gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg= gorm.io/plugin/dbresolver v1.5.2 h1:Iut7lW4TXNoVs++I+ra3zxjSxTRj4ocIeFEVp4lLhII= From 845b135137df44698e40daf5d872d8f073d108df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:37:24 +0800 Subject: [PATCH 060/240] build(deps): update module golang.org/x/crypto to v0.26.0 (#613) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 5c4f24aae..d47be436f 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.15 go.uber.org/fx v1.22.1 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.24.0 + golang.org/x/crypto v0.26.0 google.golang.org/grpc v1.65.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 google.golang.org/protobuf v1.34.2 @@ -89,9 +89,9 @@ require ( go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect diff --git a/go.sum b/go.sum index cfc98a958..d2944cf80 100644 --- a/go.sum +++ b/go.sum @@ -490,8 +490,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -547,8 +547,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ 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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= @@ -585,8 +585,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= @@ -605,8 +605,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= From 1af01f9f1fab8e8120ff29b4ab39e9045bce8ef0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:37:40 +0800 Subject: [PATCH 061/240] build(deps): update module github.com/meilisearch/meilisearch-go to v0.27.2 (#610) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d47be436f..47beed390 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/jarcoal/httpmock v1.3.1 github.com/labstack/echo/v4 v4.12.0 github.com/mattn/go-colorable v0.1.13 - github.com/meilisearch/meilisearch-go v0.26.3 + github.com/meilisearch/meilisearch-go v0.27.2 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 github.com/redis/go-redis/v9 v9.6.1 diff --git a/go.sum b/go.sum index d2944cf80..11252fd47 100644 --- a/go.sum +++ b/go.sum @@ -272,8 +272,8 @@ github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/meilisearch/meilisearch-go v0.26.3 h1:EYt+C1n7IvjKzgXM3xqce5iJzNBq33F7ayZOKx96TKY= -github.com/meilisearch/meilisearch-go v0.26.3/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= +github.com/meilisearch/meilisearch-go v0.27.2 h1:3G21dJ5i208shnLPDsIEZ0L0Geg/5oeXABFV7nlK94k= +github.com/meilisearch/meilisearch-go v0.27.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= From c32251aa8d5f2298c2ea3fcadb70176b44ba78b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:37:47 +0800 Subject: [PATCH 062/240] build(deps): update module github.com/samber/lo to v1.47.0 (#612) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 47beed390..dfcbb4009 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.19.1 github.com/redis/go-redis/v9 v9.6.1 - github.com/samber/lo v1.44.0 + github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 11252fd47..8e3444369 100644 --- a/go.sum +++ b/go.sum @@ -378,8 +378,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samber/lo v1.44.0 h1:5il56KxRE+GHsm1IR+sZ/6J42NODigFiqCWpSc2dybA= -github.com/samber/lo v1.44.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0= From bd9c28e7cab17c23ac651103455d4d5ecc3710bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:37:59 +0800 Subject: [PATCH 063/240] build(deps): update module google.golang.org/grpc/cmd/protoc-gen-go-grpc to v1.5.1 (#615) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index dfcbb4009..7e940c9cd 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/crypto v0.26.0 google.golang.org/grpc v1.65.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 @@ -95,7 +95,7 @@ require ( golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect gorm.io/datatypes v1.2.0 // indirect gorm.io/hints v1.1.2 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect diff --git a/go.sum b/go.sum index 8e3444369..be207d415 100644 --- a/go.sum +++ b/go.sum @@ -646,8 +646,8 @@ google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -659,8 +659,8 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0 h1:9SxA29VM43MF5Z9dQu694wmY5t8E/Gxr7s+RSxiIDmc= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.4.0/go.mod h1:yZOK5zhQMiALmuweVdIVoQPa6eIJyXn2B9g5dJDhqX4= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From a8d42978851ba4043481e1d32b1789738e7ba3f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:38:06 +0800 Subject: [PATCH 064/240] build(deps): update module github.com/aws/aws-sdk-go to v1.55.5 (#609) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7e940c9cd..98659879d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.22.2 require ( github.com/avast/retry-go/v4 v4.6.0 - github.com/aws/aws-sdk-go v1.54.11 + github.com/aws/aws-sdk-go v1.55.5 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 diff --git a/go.sum b/go.sum index be207d415..740ba3cf5 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinR github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.54.11 h1:Zxuv/R+IVS0B66yz4uezhxH9FN9/G2nbxejYqAMFjxk= -github.com/aws/aws-sdk-go v1.54.11/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= From 8707b0909bb029c9f622a359d68ddbf0f0dc631c Mon Sep 17 00:00:00 2001 From: Contextualist Date: Thu, 15 Aug 2024 18:44:09 -0700 Subject: [PATCH 065/240] feat: include field PrsnAppearEps in subject persons response (#616) --- domain/relation.go | 1 + internal/model/relation.go | 1 + internal/person/mysql_repository.go | 1 + internal/person/service.go | 1 + openapi/v0.yaml | 5 +++++ web/handler/subject/related_persons.go | 1 + web/res/subject.go | 1 + 7 files changed, 11 insertions(+) diff --git a/domain/relation.go b/domain/relation.go index 6240c906f..ac9b6714c 100644 --- a/domain/relation.go +++ b/domain/relation.go @@ -29,6 +29,7 @@ type SubjectPersonRelation struct { PersonID model.PersonID SubjectID model.SubjectID + Eps string } type SubjectCharacterRelation struct { diff --git a/internal/model/relation.go b/internal/model/relation.go index 63589d551..b997cda9a 100644 --- a/internal/model/relation.go +++ b/internal/model/relation.go @@ -24,6 +24,7 @@ type SubjectPersonRelation struct { Person Person Subject Subject TypeID uint16 + Eps string } type SubjectCharacterRelation struct { diff --git a/internal/person/mysql_repository.go b/internal/person/mysql_repository.go index d14a8284e..67d62be4d 100644 --- a/internal/person/mysql_repository.go +++ b/internal/person/mysql_repository.go @@ -68,6 +68,7 @@ func (r mysqlRepo) GetSubjectRelated( rel[i] = domain.SubjectPersonRelation{ PersonID: relation.PersonID, TypeID: relation.PrsnPosition, + Eps: relation.PrsnAppearEps, } } diff --git a/internal/person/service.go b/internal/person/service.go index 7c7b5ead2..83d2948d9 100644 --- a/internal/person/service.go +++ b/internal/person/service.go @@ -65,6 +65,7 @@ func (s service) GetSubjectRelated( Person: persons[rel.PersonID], Subject: sub, TypeID: rel.TypeID, + Eps: rel.Eps, } } diff --git a/openapi/v0.yaml b/openapi/v0.yaml index e50e0959d..76cb82d6f 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -2961,6 +2961,7 @@ components: - type - career - relation + - eps type: object properties: id: @@ -2987,6 +2988,10 @@ components: relation: title: Relation type: string + eps: + title: Eps + type: string + description: 参与章节/曲目 UserCharacterCollection: title: UserCharacterCollection required: diff --git a/web/handler/subject/related_persons.go b/web/handler/subject/related_persons.go index af1d96196..cee74ad32 100644 --- a/web/handler/subject/related_persons.go +++ b/web/handler/subject/related_persons.go @@ -62,6 +62,7 @@ func (h Subject) GetRelatedPersons(c echo.Context) error { Career: rel.Person.Careers(), Type: rel.Person.Type, ID: rel.Person.ID, + Eps: rel.Eps, } } diff --git a/web/res/subject.go b/web/res/subject.go index 39f36e54c..ba3bde9d4 100644 --- a/web/res/subject.go +++ b/web/res/subject.go @@ -198,6 +198,7 @@ type SubjectRelatedPerson struct { Career []string `json:"career"` Type uint8 `json:"type"` ID model.PersonID `json:"id" doc:"person ID"` + Eps string `json:"eps" doc:"episodes participated"` } type Actor struct { From e6bd50603517699e4b9806e4e192e709e47d9de5 Mon Sep 17 00:00:00 2001 From: Contextualist Date: Sun, 25 Aug 2024 15:50:01 -0700 Subject: [PATCH 066/240] fix: update staff definition (#617) --- pkg/vars/staff.go.json | 49 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/pkg/vars/staff.go.json b/pkg/vars/staff.go.json index 198929657..abfba3be4 100644 --- a/pkg/vars/staff.go.json +++ b/pkg/vars/staff.go.json @@ -53,6 +53,18 @@ "EN": "Original Character Design", "JP": "キャラクター原案", "RDF": "" + }, + "2010": { + "CN": "脚本", + "EN": "", + "JP": "シナリオ", + "RDF": "" + }, + "2011": { + "CN": "文库", + "EN": "", + "JP": "文庫", + "RDF": "" } }, "2": { @@ -635,9 +647,34 @@ "RDF": "" }, "3011": { - "en": "O.P.", - "cn": "出版方", - "jp": "音楽出版社" + "CN": "出版方", + "EN": "O.P.", + "JP": "音楽出版社", + "RDF": "" + }, + "3012": { + "CN": "母带制作", + "EN": "Mastering", + "JP": "", + "RDF": "" + }, + "3013": { + "CN": "混音", + "EN": "Mixing", + "JP": "", + "RDF": "" + }, + "3014": { + "CN": "乐器", + "EN": "Instrument", + "JP": "", + "RDF": "" + }, + "3015": { + "CN": "声乐", + "EN": "Vocal", + "JP": "", + "RDF": "" } }, "4": { @@ -942,6 +979,12 @@ "EN": "Production", "JP": "製作 製作スタジオ", "RDF": "" + }, + "4019": { + "CN": "出品", + "EN": "", + "JP": "配給", + "RDF": "" } } } From 3e358e2c9ec1d06428b9265d4e1b209f458839aa Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 30 Aug 2024 18:20:55 +0800 Subject: [PATCH 067/240] fix: archive dump escape (#618) --- cmd/archive/main.go | 6 +-- cmd/gen/gorm/main.go | 3 ++ dal/dao/chii_subjects.gen.go | 56 +++++++++++++++------------- dal/query/chii_subjects.gen.go | 18 ++++----- internal/subject/mysql_repository.go | 12 +++--- 5 files changed, 51 insertions(+), 44 deletions(-) diff --git a/cmd/archive/main.go b/cmd/archive/main.go index 316e9b407..97bb9e4ca 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -256,9 +256,9 @@ func exportSubjects(q *query.Query, w io.Writer) { encode(w, Subject{ ID: subject.ID, Type: subject.TypeID, - Name: subject.Name, - NameCN: subject.NameCN, - Infobox: subject.Infobox, + Name: string(subject.Name), + NameCN: string(subject.NameCN), + Infobox: string(subject.Infobox), Platform: subject.Platform, Summary: subject.Summary, Nsfw: subject.Nsfw, diff --git a/cmd/gen/gorm/main.go b/cmd/gen/gorm/main.go index 841d551ba..d41412b05 100644 --- a/cmd/gen/gorm/main.go +++ b/cmd/gen/gorm/main.go @@ -318,6 +318,9 @@ func main() { gen.FieldRename("subject_collect", "Done"), gen.FieldRename("field_infobox", "infobox"), gen.FieldType("subject_id", subjectIDTypeString), + gen.FieldType("subject_name", "utiltype.HTMLEscapedString"), + gen.FieldType("field_infobox", "utiltype.HTMLEscapedString"), + gen.FieldType("subject_name_cn", "utiltype.HTMLEscapedString"), gen.FieldType("subject_ban", "uint8"), gen.FieldType("subject_type_id", subjectTypeIDTypeString), gen.FieldType("subject_airtime", "uint8"), diff --git a/dal/dao/chii_subjects.gen.go b/dal/dao/chii_subjects.gen.go index 47e26d911..d7bba616b 100644 --- a/dal/dao/chii_subjects.gen.go +++ b/dal/dao/chii_subjects.gen.go @@ -4,36 +4,40 @@ package dao +import ( + "github.com/bangumi/server/dal/utiltype" +) + const TableNameSubject = "chii_subjects" // Subject mapped from table type Subject struct { - ID uint32 `gorm:"column:subject_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` - TypeID uint8 `gorm:"column:subject_type_id;type:smallint(6) unsigned;not null" json:""` - Name string `gorm:"column:subject_name;type:varchar(80);not null" json:""` - NameCN string `gorm:"column:subject_name_cn;type:varchar(80);not null" json:""` - UID string `gorm:"column:subject_uid;type:varchar(20);not null;comment:isbn / imdb" json:""` // isbn / imdb - Creator uint32 `gorm:"column:subject_creator;type:mediumint(8) unsigned;not null" json:""` - Dateline uint32 `gorm:"column:subject_dateline;type:int(10) unsigned;not null" json:""` - Image string `gorm:"column:subject_image;type:varchar(255);not null" json:""` - Platform uint16 `gorm:"column:subject_platform;type:smallint(6) unsigned;not null" json:""` - Infobox string `gorm:"column:field_infobox;type:mediumtext;not null" json:""` - Summary string `gorm:"column:field_summary;type:mediumtext;not null;comment:summary" json:""` // summary - Field5 string `gorm:"column:field_5;type:mediumtext;not null;comment:author summary" json:""` // author summary - Volumes uint32 `gorm:"column:field_volumes;type:mediumint(8) unsigned;not null;comment:卷数" json:""` // 卷数 - Eps uint32 `gorm:"column:field_eps;type:mediumint(8) unsigned;not null" json:""` - Wish uint32 `gorm:"column:subject_wish;type:mediumint(8) unsigned;not null" json:""` - Done uint32 `gorm:"column:subject_collect;type:mediumint(8) unsigned;not null" json:""` - Doing uint32 `gorm:"column:subject_doing;type:mediumint(8) unsigned;not null" json:""` - OnHold uint32 `gorm:"column:subject_on_hold;type:mediumint(8) unsigned;not null;comment:搁置人数" json:""` // 搁置人数 - Dropped uint32 `gorm:"column:subject_dropped;type:mediumint(8) unsigned;not null;comment:抛弃人数" json:""` // 抛弃人数 - Series bool `gorm:"column:subject_series;type:tinyint(1) unsigned;not null" json:""` - SeriesEntry uint32 `gorm:"column:subject_series_entry;type:mediumint(8) unsigned;not null" json:""` - IdxCn string `gorm:"column:subject_idx_cn;type:varchar(1);not null" json:""` - Airtime uint8 `gorm:"column:subject_airtime;type:tinyint(1) unsigned;not null" json:""` - Nsfw bool `gorm:"column:subject_nsfw;type:tinyint(1);not null" json:""` - Ban uint8 `gorm:"column:subject_ban;type:tinyint(1) unsigned;not null" json:""` - Fields SubjectField `gorm:"foreignKey:subject_id;references:field_sid" json:"fields"` + ID uint32 `gorm:"column:subject_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` + TypeID uint8 `gorm:"column:subject_type_id;type:smallint(6) unsigned;not null" json:""` + Name utiltype.HTMLEscapedString `gorm:"column:subject_name;type:varchar(80);not null" json:""` + NameCN utiltype.HTMLEscapedString `gorm:"column:subject_name_cn;type:varchar(80);not null" json:""` + UID string `gorm:"column:subject_uid;type:varchar(20);not null;comment:isbn / imdb" json:""` // isbn / imdb + Creator uint32 `gorm:"column:subject_creator;type:mediumint(8) unsigned;not null" json:""` + Dateline uint32 `gorm:"column:subject_dateline;type:int(10) unsigned;not null" json:""` + Image string `gorm:"column:subject_image;type:varchar(255);not null" json:""` + Platform uint16 `gorm:"column:subject_platform;type:smallint(6) unsigned;not null" json:""` + Infobox utiltype.HTMLEscapedString `gorm:"column:field_infobox;type:mediumtext;not null" json:""` + Summary string `gorm:"column:field_summary;type:mediumtext;not null;comment:summary" json:""` // summary + Field5 string `gorm:"column:field_5;type:mediumtext;not null;comment:author summary" json:""` // author summary + Volumes uint32 `gorm:"column:field_volumes;type:mediumint(8) unsigned;not null;comment:卷数" json:""` // 卷数 + Eps uint32 `gorm:"column:field_eps;type:mediumint(8) unsigned;not null" json:""` + Wish uint32 `gorm:"column:subject_wish;type:mediumint(8) unsigned;not null" json:""` + Done uint32 `gorm:"column:subject_collect;type:mediumint(8) unsigned;not null" json:""` + Doing uint32 `gorm:"column:subject_doing;type:mediumint(8) unsigned;not null" json:""` + OnHold uint32 `gorm:"column:subject_on_hold;type:mediumint(8) unsigned;not null;comment:搁置人数" json:""` // 搁置人数 + Dropped uint32 `gorm:"column:subject_dropped;type:mediumint(8) unsigned;not null;comment:抛弃人数" json:""` // 抛弃人数 + Series bool `gorm:"column:subject_series;type:tinyint(1) unsigned;not null" json:""` + SeriesEntry uint32 `gorm:"column:subject_series_entry;type:mediumint(8) unsigned;not null" json:""` + IdxCn string `gorm:"column:subject_idx_cn;type:varchar(1);not null" json:""` + Airtime uint8 `gorm:"column:subject_airtime;type:tinyint(1) unsigned;not null" json:""` + Nsfw bool `gorm:"column:subject_nsfw;type:tinyint(1);not null" json:""` + Ban uint8 `gorm:"column:subject_ban;type:tinyint(1) unsigned;not null" json:""` + Fields SubjectField `gorm:"foreignKey:subject_id;references:field_sid" json:"fields"` } // TableName Subject's table name diff --git a/dal/query/chii_subjects.gen.go b/dal/query/chii_subjects.gen.go index c89c7275d..1845a13ad 100644 --- a/dal/query/chii_subjects.gen.go +++ b/dal/query/chii_subjects.gen.go @@ -29,14 +29,14 @@ func newSubject(db *gorm.DB, opts ...gen.DOOption) subject { _subject.ALL = field.NewAsterisk(tableName) _subject.ID = field.NewUint32(tableName, "subject_id") _subject.TypeID = field.NewUint8(tableName, "subject_type_id") - _subject.Name = field.NewString(tableName, "subject_name") - _subject.NameCN = field.NewString(tableName, "subject_name_cn") + _subject.Name = field.NewField(tableName, "subject_name") + _subject.NameCN = field.NewField(tableName, "subject_name_cn") _subject.UID = field.NewString(tableName, "subject_uid") _subject.Creator = field.NewUint32(tableName, "subject_creator") _subject.Dateline = field.NewUint32(tableName, "subject_dateline") _subject.Image = field.NewString(tableName, "subject_image") _subject.Platform = field.NewUint16(tableName, "subject_platform") - _subject.Infobox = field.NewString(tableName, "field_infobox") + _subject.Infobox = field.NewField(tableName, "field_infobox") _subject.Summary = field.NewString(tableName, "field_summary") _subject.Field5 = field.NewString(tableName, "field_5") _subject.Volumes = field.NewUint32(tableName, "field_volumes") @@ -69,14 +69,14 @@ type subject struct { ALL field.Asterisk ID field.Uint32 TypeID field.Uint8 - Name field.String - NameCN field.String + Name field.Field + NameCN field.Field UID field.String // isbn / imdb Creator field.Uint32 Dateline field.Uint32 Image field.String Platform field.Uint16 - Infobox field.String + Infobox field.Field Summary field.String // summary Field5 field.String // author summary Volumes field.Uint32 // 卷数 @@ -111,14 +111,14 @@ func (s *subject) updateTableName(table string) *subject { s.ALL = field.NewAsterisk(table) s.ID = field.NewUint32(table, "subject_id") s.TypeID = field.NewUint8(table, "subject_type_id") - s.Name = field.NewString(table, "subject_name") - s.NameCN = field.NewString(table, "subject_name_cn") + s.Name = field.NewField(table, "subject_name") + s.NameCN = field.NewField(table, "subject_name_cn") s.UID = field.NewString(table, "subject_uid") s.Creator = field.NewUint32(table, "subject_creator") s.Dateline = field.NewUint32(table, "subject_dateline") s.Image = field.NewString(table, "subject_image") s.Platform = field.NewUint16(table, "subject_platform") - s.Infobox = field.NewString(table, "field_infobox") + s.Infobox = field.NewField(table, "field_infobox") s.Summary = field.NewString(table, "field_summary") s.Field5 = field.NewString(table, "field_5") s.Volumes = field.NewUint32(table, "field_volumes") diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index 2c924b769..64e9ccaf9 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -18,7 +18,6 @@ import ( "context" "errors" "fmt" - "html" "math" "github.com/trim21/errgo" @@ -27,6 +26,7 @@ import ( "github.com/bangumi/server/dal/dao" "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/dal/utiltype" "github.com/bangumi/server/domain" "github.com/bangumi/server/domain/gerr" "github.com/bangumi/server/internal/model" @@ -76,12 +76,12 @@ func ConvertDao(s *dao.Subject) (model.Subject, error) { Redirect: s.Fields.Redirect, Date: date, ID: s.ID, - Name: html.UnescapeString(s.Name), - NameCN: html.UnescapeString(s.NameCN), + Name: string(s.Name), + NameCN: string(s.NameCN), TypeID: s.TypeID, Image: s.Image, PlatformID: s.Platform, - Infobox: s.Infobox, + Infobox: string(s.Infobox), Summary: s.Summary, Volumes: s.Volumes, Eps: s.Eps, @@ -248,7 +248,7 @@ func (r mysqlRepo) Count( q = q.Where(r.q.Subject.Series.Is(filter.Series.Value)) } if filter.Platform.Set { - q = q.Where(r.q.Subject.Infobox.Like(fmt.Sprintf("%%[%s]%%", filter.Platform.Value))) + q = q.Where(r.q.Subject.Infobox.Like(utiltype.HTMLEscapedString(fmt.Sprintf("%%[%s]%%", filter.Platform.Value)))) } if filter.Year.Set { q = q.Where(r.q.SubjectField.Year.Eq(filter.Year.Value)) @@ -285,7 +285,7 @@ func (r mysqlRepo) Browse( q = q.Where(r.q.Subject.Series.Is(filter.Series.Value)) } if filter.Platform.Set { - q = q.Where(r.q.Subject.Infobox.Like(fmt.Sprintf("%%[%s]%%", filter.Platform.Value))) + q = q.Where(r.q.Subject.Infobox.Like(utiltype.HTMLEscapedString(fmt.Sprintf("%%[%s]%%", filter.Platform.Value)))) } if filter.Year.Set { q = q.Where(r.q.SubjectField.Year.Eq(filter.Year.Value)) From 9a7bf633766da01a9b07e46176467503f7970806 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Sep 2024 01:24:34 +0800 Subject: [PATCH 068/240] build(deps): update module go.uber.org/fx to v1.22.2 (#620) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 98659879d..31e1dbb4b 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 go.etcd.io/etcd/client/v3 v3.5.15 - go.uber.org/fx v1.22.1 + go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.26.0 google.golang.org/grpc v1.65.0 @@ -85,7 +85,7 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect go.etcd.io/etcd/api/v3 v3.5.15 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect - go.uber.org/dig v1.17.1 // indirect + go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.26.0 // indirect diff --git a/go.sum b/go.sum index 740ba3cf5..3cce30ca8 100644 --- a/go.sum +++ b/go.sum @@ -463,10 +463,10 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= -go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= From 37536d2771c6258b3b36111be6e02d0c173d3e4e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Sep 2024 03:09:12 +0800 Subject: [PATCH 069/240] build(deps): update module github.com/go-resty/resty/v2 to v2.14.0 (#621) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 31e1dbb4b..8d6f044ed 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.22.0 github.com/go-redis/redismock/v9 v9.2.0 - github.com/go-resty/resty/v2 v2.13.1 + github.com/go-resty/resty/v2 v2.14.0 github.com/go-sql-driver/mysql v1.8.1 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jarcoal/httpmock v1.3.1 @@ -88,11 +88,11 @@ require ( go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect diff --git a/go.sum b/go.sum index 3cce30ca8..f49cae89d 100644 --- a/go.sum +++ b/go.sum @@ -108,8 +108,8 @@ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4 github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= -github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= -github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= +github.com/go-resty/resty/v2 v2.14.0 h1:/rhkzsAqGQkozwfKS5aFAbb6TyKd3zyFRWcdRXLPCAU= +github.com/go-resty/resty/v2 v2.14.0/go.mod h1:IW6mekUOsElt9C7oWr0XRt9BNSD6D5rr9mhk6NjmNHg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -487,9 +487,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -504,6 +506,8 @@ 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -531,11 +535,12 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= 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= @@ -547,6 +552,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ 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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -582,18 +590,23 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= 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= @@ -605,12 +618,13 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -629,6 +643,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY 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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 4d917a770b77c78a11162ee0e89633ae5a482384 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 5 Sep 2024 00:59:18 +0800 Subject: [PATCH 070/240] feat(archive): add series --- cmd/archive/main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/archive/main.go b/cmd/archive/main.go index 97bb9e4ca..3a7bcee3e 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -204,6 +204,8 @@ type Subject struct { Rank uint32 `json:"rank"` Date string `json:"date"` Favorite Favorite `json:"favorite"` + + Series bool `json:"series"` } type Tag struct { @@ -277,7 +279,8 @@ func exportSubjects(q *query.Query, w io.Writer) { Field9: subject.Fields.Rate9, Field10: subject.Fields.Rate10, }, - Date: encodedDate, + Date: encodedDate, + Series: subject.Series, Favorite: Favorite{ Wish: subject.Wish, Done: subject.Done, From 60f2e7f0ba2b59c7d7eca04447414b79185ec446 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 22:05:31 +0800 Subject: [PATCH 071/240] build(deps): update module github.com/prometheus/client_golang to v1.20.3 (#623) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 11 ++++++----- go.sum | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 8d6f044ed..0368a5058 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/meilisearch/meilisearch-go v0.27.2 github.com/mitchellh/mapstructure v1.5.0 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.20.3 github.com/redis/go-redis/v9 v9.6.1 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 @@ -69,16 +69,17 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d // indirect diff --git a/go.sum b/go.sum index f49cae89d..c6336fc39 100644 --- a/go.sum +++ b/go.sum @@ -233,8 +233,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -245,6 +245,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= @@ -290,6 +292,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= @@ -342,31 +346,31 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= +github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= From 5a8f047ddfb036f01e861bba0a7d69136dc29c68 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 05:18:52 +0800 Subject: [PATCH 072/240] build(deps): update module google.golang.org/grpc to v1.66.1 (#624) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 0368a5058..fedeeb0f7 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.26.0 - google.golang.org/grpc v1.65.0 + google.golang.org/grpc v1.66.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 @@ -95,7 +95,7 @@ require ( golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect gorm.io/datatypes v1.2.0 // indirect gorm.io/hints v1.1.2 // indirect diff --git a/go.sum b/go.sum index c6336fc39..59dbb5684 100644 --- a/go.sum +++ b/go.sum @@ -663,8 +663,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU= +google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -676,8 +676,8 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= +google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From ce9291d643677e328e4b83fac474f873a008c3cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 05:22:46 +0800 Subject: [PATCH 073/240] build(deps): update module golang.org/x/crypto to v0.27.0 (#626) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index fedeeb0f7..32b831726 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.15 go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 google.golang.org/grpc v1.66.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 @@ -91,8 +91,8 @@ require ( golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect diff --git a/go.sum b/go.sum index 59dbb5684..550d007f2 100644 --- a/go.sum +++ b/go.sum @@ -496,8 +496,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -599,8 +599,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -623,8 +623,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= From f91b72beb74ffedeb7a9def50550d5c66ab0da29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 05:26:33 +0800 Subject: [PATCH 074/240] chore(deps): update gcr.io/distroless/static docker digest to 95eb83a (#627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- etc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/Dockerfile b/etc/Dockerfile index 78ec71132..372fc4140 100644 --- a/etc/Dockerfile +++ b/etc/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/distroless/static@sha256:ce46866b3a5170db3b49364900fb3168dc0833dfb46c26da5c77f22abb01d8c3 +FROM gcr.io/distroless/static@sha256:95eb83a44a62c1c27e5f0b38d26085c486d71ece83dd64540b7209536bb13f6d ENTRYPOINT ["/app/chii.exe"] From 0f095e3e40da64714c03b322b09b916a1102a635 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 14 Sep 2024 20:28:02 +0800 Subject: [PATCH 075/240] feat: include episode duraiton in dump --- cmd/archive/main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/archive/main.go b/cmd/archive/main.go index 3a7bcee3e..782ff3a9b 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -404,6 +404,7 @@ type Episode struct { Description string `json:"description"` AirDate string `json:"airdate"` Disc uint8 `json:"disc"` + Duration string `json:"duration"` SubjectID model.SubjectID `json:"subject_id"` Sort float32 `json:"sort"` Type episode.Type `json:"type"` @@ -428,6 +429,7 @@ func exportEpisodes(q *query.Query, w io.Writer) { NameCn: e.NameCn, Sort: e.Sort, SubjectID: e.SubjectID, + Duration: e.Duration, Description: e.Desc, Type: e.Type, AirDate: e.Airdate, From bffc5f2ced434c193822c69c46328b7fb2739742 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 21 Sep 2024 08:16:41 +0800 Subject: [PATCH 076/240] ci: release branches --- .github/workflows/release-docker.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index 6f95fa57b..490897392 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -6,6 +6,8 @@ on: - "v*.*.*" branches: - master + branches-ignore: + - "renovate/**" permissions: packages: write From c1a20e7bb6bb258118019ff627710079304ad2fd Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 21 Sep 2024 08:18:15 +0800 Subject: [PATCH 077/240] Update release-docker.yaml --- .github/workflows/release-docker.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index 490897392..b7b5c8bf1 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -4,8 +4,6 @@ on: push: tags: - "v*.*.*" - branches: - - master branches-ignore: - "renovate/**" From 8fa5b60c0efa9a747cc4aa7addd4ec6426e22670 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 21 Sep 2024 08:47:01 +0800 Subject: [PATCH 078/240] refactor: remove etcd and use lb (#628) --- config/config.go | 6 +++--- go.mod | 8 -------- go.sum | 29 ----------------------------- internal/timeline/grpc.go | 23 ++++------------------- 4 files changed, 7 insertions(+), 59 deletions(-) diff --git a/config/config.go b/config/config.go index 32b7b510f..cd98eb246 100644 --- a/config/config.go +++ b/config/config.go @@ -68,9 +68,9 @@ type AppConfig struct { DisableWords string `yaml:"disable_words"` BannedDomain string `yaml:"banned_domain"` - // "http://localhost:2379" - EtcdAddr string `yaml:"etcd_addr" env:"ETCD_ADDR"` - EtcdNamespace string `yaml:"etcd_namespace" env:"ETCD_NAMESPACE" env-default:"/chii/services"` + // a timeline microservice listen domain + SrvTimelineDomain string `yaml:"srv_timeline_domain" env:"SRV_TIMELINE_DOMAIN"` + SrvTimelinePort uint16 `yaml:"srv_timeline_port" env:"SRV_TIMELINE_PORT"` S3EntryPoint string `yaml:"s3_entry_point" env:"S3_ENTRY_POINT"` S3AccessKey string `yaml:"s3_access_key" env:"S3_ACCESS_KEY"` diff --git a/go.mod b/go.mod index 32b831726..339b8655a 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,6 @@ require ( github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 - go.etcd.io/etcd/client/v3 v3.5.15 go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 @@ -54,15 +53,11 @@ require ( github.com/andybalholm/brotli v1.0.6 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -84,8 +79,6 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - go.etcd.io/etcd/api/v3 v3.5.15 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect @@ -95,7 +88,6 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect gorm.io/datatypes v1.2.0 // indirect gorm.io/hints v1.1.2 // indirect diff --git a/go.sum b/go.sum index 550d007f2..7d8a979ff 100644 --- a/go.sum +++ b/go.sum @@ -56,11 +56,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27wIbmOGUs7RIbVgPEjb31ehTVniDwPGXyMxm5U= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -115,13 +111,10 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9 github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= @@ -144,8 +137,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -228,7 +219,6 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -451,17 +441,9 @@ github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3k github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk= -go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM= -go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA= -go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU= -go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4= -go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -506,8 +488,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -530,9 +510,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -553,7 +531,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -580,7 +557,6 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -643,8 +619,6 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= @@ -653,7 +627,6 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -663,8 +636,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU= -google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= diff --git a/internal/timeline/grpc.go b/internal/timeline/grpc.go index b096c7ba5..b86f94e45 100644 --- a/internal/timeline/grpc.go +++ b/internal/timeline/grpc.go @@ -20,8 +20,6 @@ import ( "time" "github.com/trim21/errgo" - clientv3 "go.etcd.io/etcd/client/v3" - "go.etcd.io/etcd/client/v3/naming/resolver" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -130,26 +128,13 @@ func (m grpcClient) ChangeEpisodeStatus( } func newGrpcClient(cfg config.AppConfig) (pb.TimeLineServiceClient, error) { - if cfg.EtcdAddr == "" { - logger.Info("no etcd, using nope timeline service") + if cfg.SrvTimelineDomain == "" || cfg.SrvTimelinePort == 0 { + logger.Info("no srv_timeline_domain and srv_timeline_port, using nope timeline service") return noopClient{}, nil } - logger.Info("using etcd to discovery timeline services " + cfg.EtcdAddr) - - cli, err := clientv3.NewFromURL(cfg.EtcdAddr) - if err != nil { - return nil, errgo.Wrap(err, "etcd new client") - } - - etcdResolver, err := resolver.NewBuilder(cli) - if err != nil { - return nil, errgo.Wrap(err, "etcd grpc resolver") - } - - conn, err := grpc.Dial( - fmt.Sprintf("etcd:///%s/timeline", cfg.EtcdNamespace), - grpc.WithResolvers(etcdResolver), + conn, err := grpc.NewClient( + fmt.Sprintf("dns:///%s:%d", cfg.SrvTimelineDomain, cfg.SrvTimelinePort), grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { From 1ca319c16bb1f60211752c3c1325f775e7532b13 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 24 Sep 2024 04:16:40 +0800 Subject: [PATCH 079/240] refactor: remove redis broker --- canal/canal.go | 14 +---- canal/stream_redis.go | 143 ------------------------------------------ 2 files changed, 2 insertions(+), 155 deletions(-) delete mode 100644 canal/stream_redis.go diff --git a/canal/canal.go b/canal/canal.go index db51a2d5a..50ac7f1b8 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -35,7 +35,7 @@ import ( "github.com/bangumi/server/web/session" ) -const groupID = "my-group" +const groupID = "go-canal" var errNoTopic = fmt.Errorf("missing search events topic") @@ -50,16 +50,6 @@ func Main() error { return errNoTopic } - var opt fx.Option - switch cfg.Canal.Broker { - case "redis": - opt = fx.Provide(newRedisStream) - case "kafka": - opt = fx.Provide(newKafkaStream) - default: - return fmt.Errorf("broker not supported, only support redis/kafka as debezium broker") // nolint: goerr113 - } - var h *eventHandler di := fx.New( fx.NopLogger, @@ -77,7 +67,7 @@ func Main() error { newEventHandler, ), - opt, + fx.Provide(newKafkaStream), fx.Populate(&h), ) diff --git a/canal/stream_redis.go b/canal/stream_redis.go deleted file mode 100644 index d5dd39ac8..000000000 --- a/canal/stream_redis.go +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see - -package canal - -import ( - "context" - "reflect" - "sync/atomic" - "time" - - "github.com/redis/go-redis/v9" - "github.com/samber/lo" - "github.com/trim21/errgo" - "go.uber.org/zap" - - "github.com/bangumi/server/canal/stream" - "github.com/bangumi/server/config" - "github.com/bangumi/server/internal/pkg/logger" -) - -func newRedisStream(cfg config.AppConfig, redisClient *redis.Client) (Stream, error) { - var ch = make(chan Msg, 1) - - reader := stream.New( - redisClient, - groupID, - "canal", - lo.Map(cfg.Canal.Topics, func(item string, _ int) stream.Option { - return stream.WithStream(item) - })..., - ) - - r := &redisStream{ - log: logger.Named("canal.search.stream"), - ch: ch, - cfg: cfg, - redis: redisClient, - reader: reader, - } - - for _, s := range r.cfg.Canal.Topics { - var infos, err = r.redis.XInfoGroups(context.Background(), s).Result() - if err != nil { - if err.Error() != "ERR no such key" { - return nil, errgo.Trace(err) - } - } - - groups := lo.SliceToMap(infos, func(item redis.XInfoGroup) (string, bool) { - return item.Name, true - }) - - if !groups[groupID] { - err := r.redis.XGroupCreateMkStream(context.Background(), s, groupID, "$").Err() - if err != nil { - return nil, errgo.Trace(err) - } - } - } - - return r, nil -} - -type redisStream struct { - log *zap.Logger - redis *redis.Client - ch chan Msg - cfg config.AppConfig - closed atomic.Bool - reader *stream.Consumer -} - -func (r *redisStream) Read(ctx context.Context, onMessage func(msg Msg) error) error { - for { - if r.closed.Load() { - return nil - } - - rr, err := r.reader.Read(ctx) - if err != nil { - r.log.Error("failed to read new messages", zap.Error(err)) - time.Sleep(time.Second) - continue - } - - for _, msg := range rr { - r.log.Debug("new message", zap.String("id", msg.ID), zap.String("s", msg.Stream)) - - rawKey := msg.Values["key"] - rawValue := msg.Values["value"] - - if rawKey == nil || rawValue == nil { - _ = r.reader.Ack(context.Background(), msg) - continue - } - - value, ok := rawValue.(string) - if !ok { - r.log.Error("failed to handle event", zap.String("id", msg.ID), - zap.String("value-type", reflect.TypeOf(rawKey).String())) - _ = r.reader.Ack(context.Background(), msg) - continue - } - - key, ok := rawKey.(string) - if !ok { - r.log.Error("failed to handle event", zap.String("id", msg.ID), - zap.String("key-type", reflect.TypeOf(rawKey).String())) - _ = r.reader.Ack(context.Background(), msg) - continue - } - - if err := onMessage(Msg{ID: msg.ID, Stream: msg.Stream, Key: []byte(key), Value: []byte(value)}); err != nil { - return errgo.Trace(err) - } - - if err := r.reader.Ack(ctx, msg); err != nil { - return errgo.Trace(err) - } - } - } -} - -func (r *redisStream) Close() error { - r.closed.Store(true) - return nil -} - -func (r *redisStream) Ack(ctx context.Context, msg Msg) error { - return r.reader.Ack(ctx, stream.Message{Stream: msg.Stream, ID: msg.ID}) -} From 02fb312a5ed582a995eabe4d51d89fb52cd95bc0 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 24 Sep 2024 04:22:10 +0800 Subject: [PATCH 080/240] build: upgrade meilisearch deps --- go.mod | 4 +--- go.sum | 19 ++----------------- internal/search/client.go | 20 +++++++++++--------- 3 files changed, 14 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index 339b8655a..3f8276585 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/jarcoal/httpmock v1.3.1 github.com/labstack/echo/v4 v4.12.0 github.com/mattn/go-colorable v0.1.13 - github.com/meilisearch/meilisearch-go v0.27.2 + github.com/meilisearch/meilisearch-go v0.28.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.20.3 github.com/redis/go-redis/v9 v9.6.1 @@ -50,7 +50,6 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/BurntSushi/toml v1.2.1 // indirect - github.com/andybalholm/brotli v1.0.6 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -77,7 +76,6 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.10.0 // indirect diff --git a/go.sum b/go.sum index 7d8a979ff..bd3c42303 100644 --- a/go.sum +++ b/go.sum @@ -15,9 +15,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= -github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -220,8 +217,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= @@ -264,8 +259,8 @@ github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/meilisearch/meilisearch-go v0.27.2 h1:3G21dJ5i208shnLPDsIEZ0L0Geg/5oeXABFV7nlK94k= -github.com/meilisearch/meilisearch-go v0.27.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= +github.com/meilisearch/meilisearch-go v0.28.0 h1:f3XJ66ZM+R8bANAOLqsjvoq/HhQNpVJPYoNt6QgNzME= +github.com/meilisearch/meilisearch-go v0.28.0/go.mod h1:Szcc9CaDiKIfjdgdt49jlmDKpEzjD+x+b6Y6heMdlQ0= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -427,11 +422,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d h1:xS9QTPgKl9ewGsAOPc+xW7DeStJDqYPfisDmeSCcbco= -github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/volatiletech/null/v9 v9.0.0 h1:JCdlHEiSRVxOi7/MABiEfdsqmuj9oTV20Ao7VvZ0JkE= github.com/volatiletech/null/v9 v9.0.0/go.mod h1:zRFghPVahaiIMRXiUJrc6gsoG83Cm3ZoAfSTw7VHGQc= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -472,7 +464,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= @@ -512,8 +503,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -559,10 +548,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -590,7 +576,6 @@ golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= 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= -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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/internal/search/client.go b/internal/search/client.go index a56a11a7d..b619def91 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "net/http" "net/url" "os" "reflect" @@ -60,13 +61,13 @@ func New( return nil, errgo.Wrap(err, "url.Parse") } - meili := meilisearch.NewClient(meilisearch.ClientConfig{ - Host: cfg.Search.MeiliSearch.URL, - APIKey: cfg.Search.MeiliSearch.Key, - Timeout: cfg.Search.MeiliSearch.Timeout, - }) + meili := meilisearch.New( + cfg.Search.MeiliSearch.URL, + meilisearch.WithAPIKey(cfg.Search.MeiliSearch.Key), + meilisearch.WithCustomClient(&http.Client{Timeout: cfg.Search.MeiliSearch.Timeout}), + ) - if _, err := meili.GetVersion(); err != nil { + if _, err := meili.Version(); err != nil { return nil, errgo.Wrap(err, "meilisearch") } @@ -135,9 +136,9 @@ func (c *client) canalInit(cfg config.AppConfig) error { type client struct { subjectRepo subject.Repo - meili *meilisearch.Client + meili meilisearch.ServiceManager q *query.Query - subjectIndex *meilisearch.Index + subjectIndex meilisearch.IndexManager log *zap.Logger subject string queue *queue.Batched[subjectIndex] @@ -193,7 +194,8 @@ func (c *client) sendBatch(items []subjectIndex) { retry.Delay(time.Microsecond*100), retry.Attempts(5), //nolint:gomnd retry.RetryIf(func(err error) bool { - return errors.As(err, &meilisearch.Error{}) + var r = &meilisearch.Error{} + return errors.As(err, &r) }), ) From b1070869058a4240a1a3389f6f0a2e491b67edf3 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 25 Sep 2024 06:47:40 +0800 Subject: [PATCH 081/240] fix: remove schema from kafka message --- canal/event.go | 33 ++++++++++----------------------- canal/ifce.go | 8 ++++---- canal/on_subject.go | 4 ++-- canal/on_user.go | 2 +- canal/stream_kafka.go | 8 ++++---- 5 files changed, 21 insertions(+), 34 deletions(-) diff --git a/canal/event.go b/canal/event.go index 7af69f9a7..f880b784e 100644 --- a/canal/event.go +++ b/canal/event.go @@ -64,12 +64,12 @@ type eventHandler struct { func (e *eventHandler) start() error { ee := e.stream.Read(context.Background(), func(msg Msg) error { - e.log.Debug("new message", zap.String("stream", msg.Stream), zap.String("id", msg.ID)) + e.log.Debug("new message", zap.String("topic", msg.Topic), zap.String("id", msg.ID)) err := e.onMessage(msg.Key, msg.Value) if err != nil { e.log.Error("failed to handle stream msg", - zap.Error(err), zap.String("stream", msg.Stream), zap.String("id", msg.ID)) + zap.Error(err), zap.String("stream", msg.Topic), zap.String("id", msg.ID)) return errgo.Trace(err) } @@ -103,26 +103,21 @@ func (e *eventHandler) onMessage(key, value []byte) error { return nil } - var k messageKey - if err := json.Unmarshal(key, &k); err != nil { + var p Payload + if err := json.Unmarshal(value, &p); err != nil { return nil } - var v messageValue - if err := json.Unmarshal(value, &v); err != nil { - return nil - } - - e.log.Debug("new message", zap.String("table", v.Payload.Source.Table)) + e.log.Debug("new message", zap.String("table", p.Source.Table)) var err error - switch v.Payload.Source.Table { + switch p.Source.Table { case "chii_subject_fields": - err = e.OnSubjectField(k.Payload, v.Payload) + err = e.OnSubjectField(key, p) case "chii_subjects": - err = e.OnSubject(k.Payload, v.Payload) + err = e.OnSubject(key, p) case "chii_members": - err = e.OnUserChange(k.Payload, v.Payload) + err = e.OnUserChange(key, p) } return err @@ -138,15 +133,7 @@ const ( // https://debezium.io/documentation/reference/connectors/mysql.html // Table 9. Overview of change event basic content -type messageKey struct { - Payload json.RawMessage `json:"payload"` -} - -type messageValue struct { - Payload payload `json:"payload"` -} - -type payload struct { +type Payload struct { Before json.RawMessage `json:"before"` After json.RawMessage `json:"after"` Source source `json:"source"` diff --git a/canal/ifce.go b/canal/ifce.go index 1de12767c..892d546db 100644 --- a/canal/ifce.go +++ b/canal/ifce.go @@ -19,10 +19,10 @@ import ( ) type Msg struct { - ID string - Stream string - Key []byte - Value []byte + ID string + Topic string + Key []byte + Value []byte } type Stream interface { diff --git a/canal/on_subject.go b/canal/on_subject.go index 214f9ddfa..fbe70e8b4 100644 --- a/canal/on_subject.go +++ b/canal/on_subject.go @@ -23,7 +23,7 @@ import ( "github.com/bangumi/server/internal/model" ) -func (e *eventHandler) OnSubject(key json.RawMessage, payload payload) error { +func (e *eventHandler) OnSubject(key json.RawMessage, payload Payload) error { var k SubjectKey if err := json.Unmarshal(key, &k); err != nil { return nil @@ -32,7 +32,7 @@ func (e *eventHandler) OnSubject(key json.RawMessage, payload payload) error { return e.onSubjectChange(k.ID, payload.Op) } -func (e *eventHandler) OnSubjectField(key json.RawMessage, payload payload) error { +func (e *eventHandler) OnSubjectField(key json.RawMessage, payload Payload) error { var k SubjectFieldKey if err := json.Unmarshal(key, &k); err != nil { return nil diff --git a/canal/on_user.go b/canal/on_user.go index 34c08902e..da16f7b7a 100644 --- a/canal/on_user.go +++ b/canal/on_user.go @@ -30,7 +30,7 @@ import ( "github.com/bangumi/server/internal/pkg/logger/log" ) -func (e *eventHandler) OnUserChange(key json.RawMessage, payload payload) error { +func (e *eventHandler) OnUserChange(key json.RawMessage, payload Payload) error { var k UserKey if err := json.Unmarshal(key, &k); err != nil { e.log.Error("failed to unmarshal json", zap.Error(err)) diff --git a/canal/stream_kafka.go b/canal/stream_kafka.go index 5dbbd83b4..8166a9761 100644 --- a/canal/stream_kafka.go +++ b/canal/stream_kafka.go @@ -74,10 +74,10 @@ func (s *kafkaStream) Read(ctx context.Context, onMessage func(msg Msg) error) e s.log.Debug("new message", zap.String("topic", msg.Topic)) m := Msg{ - ID: strconv.FormatInt(msg.Offset, 10), - Stream: msg.Topic, - Key: msg.Key, - Value: msg.Value, + ID: strconv.FormatInt(msg.Offset, 10), + Topic: msg.Topic, + Key: msg.Key, + Value: msg.Value, } if err := onMessage(m); err != nil { From 3cb7c9a86fa691c410c840c4c6f6d1b8532dc318 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 25 Sep 2024 13:32:00 +0800 Subject: [PATCH 082/240] timeline: remove deprecated fields --- generated/proto/go/api/v1/timeline.pb.go | 218 +++++++---------------- proto | 2 +- 2 files changed, 64 insertions(+), 156 deletions(-) diff --git a/generated/proto/go/api/v1/timeline.pb.go b/generated/proto/go/api/v1/timeline.pb.go index 864c35ffd..4dfa208bc 100644 --- a/generated/proto/go/api/v1/timeline.pb.go +++ b/generated/proto/go/api/v1/timeline.pb.go @@ -262,16 +262,8 @@ type Subject struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - NameCn string `protobuf:"bytes,4,opt,name=name_cn,json=nameCn,proto3" json:"name_cn,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - Image string `protobuf:"bytes,5,opt,name=image,proto3" json:"image,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - Series bool `protobuf:"varint,6,opt,name=series,proto3" json:"series,omitempty"` + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"` VolsTotal uint32 `protobuf:"varint,7,opt,name=vols_total,json=volsTotal,proto3" json:"vols_total,omitempty"` EpsTotal uint32 `protobuf:"varint,8,opt,name=eps_total,json=epsTotal,proto3" json:"eps_total,omitempty"` } @@ -322,38 +314,6 @@ func (x *Subject) GetType() uint32 { return 0 } -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Subject) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Subject) GetNameCn() string { - if x != nil { - return x.NameCn - } - return "" -} - -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Subject) GetImage() string { - if x != nil { - return x.Image - } - return "" -} - -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Subject) GetSeries() bool { - if x != nil { - return x.Series - } - return false -} - func (x *Subject) GetVolsTotal() uint32 { if x != nil { return x.VolsTotal @@ -374,14 +334,6 @@ type Episode struct { unknownFields protoimpl.UnknownFields Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - NameCn string `protobuf:"bytes,4,opt,name=name_cn,json=nameCn,proto3" json:"name_cn,omitempty"` - // Deprecated: Marked as deprecated in api/v1/timeline.proto. - Sort float64 `protobuf:"fixed64,5,opt,name=sort,proto3" json:"sort,omitempty"` } func (x *Episode) Reset() { @@ -423,38 +375,6 @@ func (x *Episode) GetId() uint32 { return 0 } -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Episode) GetType() uint32 { - if x != nil { - return x.Type - } - return 0 -} - -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Episode) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Episode) GetNameCn() string { - if x != nil { - return x.NameCn - } - return "" -} - -// Deprecated: Marked as deprecated in api/v1/timeline.proto. -func (x *Episode) GetSort() float64 { - if x != nil { - return x.Sort - } - return 0 -} - // The request message containing the user's name. type SubjectCollectRequest struct { state protoimpl.MessageState @@ -695,83 +615,71 @@ var file_api_v1_timeline_proto_rawDesc = []byte{ 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0x28, 0x0a, 0x16, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0xd4, 0x01, - 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x6e, 0x61, 0x6d, 0x65, - 0x43, 0x6e, 0x12, 0x18, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x06, - 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x06, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x6c, 0x73, - 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x76, 0x6f, - 0x6c, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x70, 0x73, 0x5f, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x65, 0x70, 0x73, 0x54, - 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x7e, 0x0a, 0x07, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x16, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1b, 0x0a, 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6e, 0x12, 0x16, 0x0a, 0x04, - 0x73, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, - 0x73, 0x6f, 0x72, 0x74, 0x22, 0xce, 0x01, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, + 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0x6f, 0x0a, + 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x76, 0x6f, 0x6c, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x76, 0x6f, 0x6c, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x65, + 0x70, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, + 0x65, 0x70, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x07, 0x22, 0x1f, + 0x0a, 0x07, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x06, 0x22, + 0xce, 0x01, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1e, 0x0a, + 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x22, 0x80, 0x01, 0x0a, 0x15, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x70, 0x69, 0x73, 0x6f, + 0x64, 0x65, 0x52, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x22, 0x9c, 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x72, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x80, 0x01, 0x0a, 0x15, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, - 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x04, 0x6c, 0x61, 0x73, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x12, 0x29, 0x0a, - 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x9c, 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x70, 0x73, 0x5f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x70, 0x73, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x73, 0x5f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x76, 0x6f, 0x6c, - 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x32, 0xc5, 0x02, 0x0a, 0x0f, 0x54, 0x69, 0x6d, 0x65, - 0x4c, 0x69, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x48, - 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, - 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0e, - 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x1d, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x1f, 0x5a, 0x1d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, - 0x6e, 0x67, 0x75, 0x6d, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x70, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x70, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x73, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x32, 0xc5, 0x02, 0x0a, 0x0f, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, + 0x0a, 0x0e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x54, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x45, 0x70, 0x69, 0x73, 0x6f, + 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x2e, 0x45, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1f, 0x5a, 0x1d, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6e, 0x67, 0x75, 0x6d, 0x69, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/proto b/proto index 134977239..7475c4b23 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 134977239d0a241d32ae029076c31b55b070650f +Subproject commit 7475c4b237d2541de47d726ded88560405f17013 From f584afc3558e2e511bacb41cfa458accf3b70ac8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:43:26 +0800 Subject: [PATCH 083/240] ci: update peter-evans/create-pull-request action to v7 (#637) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-openapi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-openapi.yaml b/.github/workflows/release-openapi.yaml index 6c4ac250e..38c92ba0d 100644 --- a/.github/workflows/release-openapi.yaml +++ b/.github/workflows/release-openapi.yaml @@ -26,7 +26,7 @@ jobs: - run: cp ./dist/v0.yaml ./api/open-api/v0.yaml - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: path: api token: ${{ secrets.PAT }} From 240e4036da1b1348a99aacc3e87a997d0b33b486 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:43:35 +0800 Subject: [PATCH 084/240] ci: update dependency ubuntu to v24 (#636) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/release-docker.yaml | 2 +- .github/workflows/release-openapi.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/test.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 55fb7c2ad..204e4058a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -26,7 +26,7 @@ on: jobs: docker: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 3be3f7eb5..2e25d92f2 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -24,7 +24,7 @@ on: jobs: lint: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index b7b5c8bf1..92499f354 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -14,7 +14,7 @@ jobs: docker: name: "docker" - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 env: IMAGE: "ghcr.io/${{ github.repository_owner }}/chii" diff --git a/.github/workflows/release-openapi.yaml b/.github/workflows/release-openapi.yaml index 38c92ba0d..9604a4afc 100644 --- a/.github/workflows/release-openapi.yaml +++ b/.github/workflows/release-openapi.yaml @@ -8,7 +8,7 @@ on: jobs: openapi: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index af87e55df..a8d424a6e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: jobs: github: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 46dec39a0..a91f69108 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -24,7 +24,7 @@ on: jobs: test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - run: git clone https://github.com/bangumi/dev-env $HOME/dev-env - run: cd ~/dev-env && docker compose up -d From f6f50cb7a421a0d6551470ba6ccc63ee0b9d75fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:43:46 +0800 Subject: [PATCH 085/240] build(deps): update module github.com/go-resty/resty/v2 to v2.15.3 (#634) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 29 ++--------------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 3f8276585..2dec30080 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.22.0 github.com/go-redis/redismock/v9 v9.2.0 - github.com/go-resty/resty/v2 v2.14.0 + github.com/go-resty/resty/v2 v2.15.3 github.com/go-sql-driver/mysql v1.8.1 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jarcoal/httpmock v1.3.1 diff --git a/go.sum b/go.sum index bd3c42303..cef4ddc79 100644 --- a/go.sum +++ b/go.sum @@ -101,8 +101,8 @@ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4 github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= -github.com/go-resty/resty/v2 v2.14.0 h1:/rhkzsAqGQkozwfKS5aFAbb6TyKd3zyFRWcdRXLPCAU= -github.com/go-resty/resty/v2 v2.14.0/go.mod h1:IW6mekUOsElt9C7oWr0XRt9BNSD6D5rr9mhk6NjmNHg= +github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= +github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -464,11 +464,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -481,8 +477,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -506,10 +500,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -522,9 +513,6 @@ 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -556,23 +544,14 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= 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= @@ -581,9 +560,6 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -606,7 +582,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 51e6df6bf349be74f6e211bd37236b1d8dc69892 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:44:01 +0800 Subject: [PATCH 086/240] build(deps): update module gorm.io/plugin/dbresolver to v1.5.3 (#633) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 2dec30080..88ddf0a99 100644 --- a/go.mod +++ b/go.mod @@ -42,8 +42,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 - gorm.io/gorm v1.25.11 - gorm.io/plugin/dbresolver v1.5.2 + gorm.io/gorm v1.25.12 + gorm.io/plugin/dbresolver v1.5.3 gorm.io/plugin/soft_delete v1.2.1 ) diff --git a/go.sum b/go.sum index cef4ddc79..68fe1f95b 100644 --- a/go.sum +++ b/go.sum @@ -647,7 +647,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco= gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04= -gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= @@ -664,12 +663,12 @@ gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= -gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= +gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o= gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg= -gorm.io/plugin/dbresolver v1.5.2 h1:Iut7lW4TXNoVs++I+ra3zxjSxTRj4ocIeFEVp4lLhII= -gorm.io/plugin/dbresolver v1.5.2/go.mod h1:jPh59GOQbO7v7v28ZKZPd45tr+u3vyT+8tHdfdfOWcU= +gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU= +gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE= gorm.io/plugin/soft_delete v1.2.1 h1:qx9D/c4Xu6w5KT8LviX8DgLcB9hkKl6JC9f44Tj7cGU= gorm.io/plugin/soft_delete v1.2.1/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From f846f5f5ff60e9bf6dd56e6fe8acb822f185b1ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:44:46 +0800 Subject: [PATCH 087/240] chore(deps): update gcr.io/distroless/static docker digest to 69830f2 (#629) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- etc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/Dockerfile b/etc/Dockerfile index 372fc4140..08b4b7188 100644 --- a/etc/Dockerfile +++ b/etc/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/distroless/static@sha256:95eb83a44a62c1c27e5f0b38d26085c486d71ece83dd64540b7209536bb13f6d +FROM gcr.io/distroless/static@sha256:69830f29ed7545c762777507426a412f97dad3d8d32bae3e74ad3fb6160917ea ENTRYPOINT ["/app/chii.exe"] From bddd8675fc5d42c12bb54f5a48f31d88b21ffab0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:45:58 +0800 Subject: [PATCH 088/240] build(deps): update module google.golang.org/grpc to v1.67.0 (#635) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 88ddf0a99..e1cb28e15 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 - google.golang.org/grpc v1.66.1 + google.golang.org/grpc v1.67.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 @@ -80,13 +80,13 @@ require ( go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect gorm.io/datatypes v1.2.0 // indirect gorm.io/hints v1.1.2 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect diff --git a/go.sum b/go.sum index 68fe1f95b..b57533f0f 100644 --- a/go.sum +++ b/go.sum @@ -501,8 +501,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= 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= @@ -560,6 +560,7 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -596,8 +597,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -607,8 +608,8 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= -google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From cfb6a17f414e119e2b5186af5a30d23d8c14f23d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:46:08 +0800 Subject: [PATCH 089/240] build(deps): update module github.com/prometheus/client_golang to v1.20.4 (#631) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e1cb28e15..27a0ad8c5 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/meilisearch/meilisearch-go v0.28.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/prometheus/client_golang v1.20.3 + github.com/prometheus/client_golang v1.20.4 github.com/redis/go-redis/v9 v9.6.1 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 diff --git a/go.sum b/go.sum index b57533f0f..f69651d80 100644 --- a/go.sum +++ b/go.sum @@ -331,8 +331,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= -github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= -github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= From 51f5e9489bafd84635c9420730c49db18649a4cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:46:13 +0800 Subject: [PATCH 090/240] build(deps): update module github.com/go-playground/validator/v10 to v10.22.1 (#630) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 27a0ad8c5..09b2d1de6 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 - github.com/go-playground/validator/v10 v10.22.0 + github.com/go-playground/validator/v10 v10.22.1 github.com/go-redis/redismock/v9 v9.2.0 github.com/go-resty/resty/v2 v2.15.3 github.com/go-sql-driver/mysql v1.8.1 diff --git a/go.sum b/go.sum index f69651d80..ebf7cfa15 100644 --- a/go.sum +++ b/go.sum @@ -97,8 +97,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= From 7935a6de422ea6dd7df509407fc1daff580cc0ed Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 1 Oct 2024 13:54:25 +0800 Subject: [PATCH 091/240] feat: return user timezone (#638) --- internal/mocks/UserRepo.go | 57 +++++++++++++++++++++++++++++++ internal/user/domain.go | 3 ++ internal/user/model.go | 12 +++++++ internal/user/mysql_repository.go | 41 ++++++++++++++++++++++ openapi/v0.yaml | 8 ++++- web/handler/user/me.go | 31 ++++++++++++----- web/handler/user/user_test.go | 2 +- 7 files changed, 143 insertions(+), 11 deletions(-) diff --git a/internal/mocks/UserRepo.go b/internal/mocks/UserRepo.go index ee0c909d2..cea8aa675 100644 --- a/internal/mocks/UserRepo.go +++ b/internal/mocks/UserRepo.go @@ -385,6 +385,63 @@ func (_c *UserRepo_GetFriends_Call) RunAndReturn(run func(context.Context, uint3 return _c } +// GetFullUser provides a mock function with given fields: ctx, userID +func (_m *UserRepo) GetFullUser(ctx context.Context, userID uint32) (user.FullUser, error) { + ret := _m.Called(ctx, userID) + + if len(ret) == 0 { + panic("no return value specified for GetFullUser") + } + + var r0 user.FullUser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint32) (user.FullUser, error)); ok { + return rf(ctx, userID) + } + if rf, ok := ret.Get(0).(func(context.Context, uint32) user.FullUser); ok { + r0 = rf(ctx, userID) + } else { + r0 = ret.Get(0).(user.FullUser) + } + + if rf, ok := ret.Get(1).(func(context.Context, uint32) error); ok { + r1 = rf(ctx, userID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UserRepo_GetFullUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFullUser' +type UserRepo_GetFullUser_Call struct { + *mock.Call +} + +// GetFullUser is a helper method to define mock.On call +// - ctx context.Context +// - userID uint32 +func (_e *UserRepo_Expecter) GetFullUser(ctx interface{}, userID interface{}) *UserRepo_GetFullUser_Call { + return &UserRepo_GetFullUser_Call{Call: _e.mock.On("GetFullUser", ctx, userID)} +} + +func (_c *UserRepo_GetFullUser_Call) Run(run func(ctx context.Context, userID uint32)) *UserRepo_GetFullUser_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32)) + }) + return _c +} + +func (_c *UserRepo_GetFullUser_Call) Return(_a0 user.FullUser, _a1 error) *UserRepo_GetFullUser_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *UserRepo_GetFullUser_Call) RunAndReturn(run func(context.Context, uint32) (user.FullUser, error)) *UserRepo_GetFullUser_Call { + _c.Call.Return(run) + return _c +} + // NewUserRepo creates a new instance of UserRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewUserRepo(t interface { diff --git a/internal/user/domain.go b/internal/user/domain.go index d547004c0..c34c2fdd6 100644 --- a/internal/user/domain.go +++ b/internal/user/domain.go @@ -21,6 +21,9 @@ import ( ) type Repo interface { + // GetFullUser find a user by uid. + GetFullUser(ctx context.Context, userID model.UserID) (FullUser, error) + // GetByID find a user by uid. GetByID(ctx context.Context, userID model.UserID) (User, error) // GetByName find a user by username. diff --git a/internal/user/model.go b/internal/user/model.go index fc79bece2..d550b7df2 100644 --- a/internal/user/model.go +++ b/internal/user/model.go @@ -22,6 +22,18 @@ import ( "github.com/bangumi/server/internal/model" ) +// FullUser is for current user or admin only. +type FullUser struct { + RegistrationTime time.Time + NickName string + Avatar string + Sign string + UserName string + ID model.UserID + UserGroup GroupID + TimeOffset int8 +} + type GroupID = uint8 // User is visible for everyone. diff --git a/internal/user/mysql_repository.go b/internal/user/mysql_repository.go index d288f6504..3cd7b960d 100644 --- a/internal/user/mysql_repository.go +++ b/internal/user/mysql_repository.go @@ -17,6 +17,7 @@ package user import ( "context" "errors" + "strconv" "time" "github.com/trim21/errgo" @@ -40,6 +41,46 @@ type mysqlRepo struct { log *zap.Logger } +func (m mysqlRepo) GetFullUser(ctx context.Context, userID model.UserID) (FullUser, error) { + u, err := m.q.Member.WithContext(ctx).Where(m.q.Member.ID.Eq(userID)).Take() + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return FullUser{}, gerr.ErrUserNotFound + } + + m.log.Error("unexpected error happened", zap.Error(err)) + return FullUser{}, errgo.Wrap(err, "dal") + } + + return FullUser{ + UserName: u.Username, + NickName: u.Nickname, + UserGroup: u.Groupid, + Avatar: u.Avatar, + Sign: string(u.Sign), + ID: u.ID, + RegistrationTime: time.Unix(u.Regdate, 0), + TimeOffset: parseTimeOffset(u.Timeoffset), + }, nil +} + +// default time zone GMT+8. +const defaultTimeOffset = 8 + +func parseTimeOffset(s string) int8 { + switch s { + case "", "9999": + return defaultTimeOffset + } + + v, err := strconv.ParseInt(s, 10, 8) + if err != nil { + return defaultTimeOffset + } + + return int8(v) +} + func (m mysqlRepo) GetByID(ctx context.Context, userID model.UserID) (User, error) { u, err := m.q.Member.WithContext(ctx).Where(m.q.Member.ID.Eq(userID)).Take() if err != nil { diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 76cb82d6f..13848f4ce 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -982,7 +982,13 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/User" + allOf: + - "$ref": "#/components/schemas/User" + - type: object + properties: + time_offset: + description: "用户设置的时区偏移,以小时为单位。比如 GMT+8(shanghai/beijing)为 8" + type: integer "403": description: unauthorized content: diff --git a/web/handler/user/me.go b/web/handler/user/me.go index b0c48d45f..d2482c903 100644 --- a/web/handler/user/me.go +++ b/web/handler/user/me.go @@ -20,28 +20,41 @@ import ( "github.com/labstack/echo/v4" "github.com/trim21/errgo" + "github.com/bangumi/server/internal/model" "github.com/bangumi/server/web/accessor" "github.com/bangumi/server/web/res" ) +type CurrentUser struct { + Avatar res.Avatar `json:"avatar"` + Sign string `json:"sign"` + URL string `json:"url"` + Username string `json:"username"` + Nickname string `json:"nickname"` + ID model.UserID `json:"id"` + UserGroup uint8 `json:"user_group"` + TimeOffset int8 `json:"time_offset"` +} + func (h User) GetCurrent(c echo.Context) error { u := accessor.GetFromCtx(c) if !u.Login || u.ID == 0 { return res.Unauthorized("need Login") } - user, err := h.user.GetByID(c.Request().Context(), u.ID) + user, err := h.user.GetFullUser(c.Request().Context(), u.ID) if err != nil { return errgo.Wrap(err, "failed to get user") } - return c.JSON(http.StatusOK, res.User{ - ID: user.ID, - URL: "https://bgm.tv/user/" + user.UserName, - Username: user.UserName, - Nickname: user.NickName, - UserGroup: user.UserGroup, - Avatar: res.UserAvatar(user.Avatar), - Sign: user.Sign, + return c.JSON(http.StatusOK, CurrentUser{ + ID: user.ID, + URL: "https://bgm.tv/user/" + user.UserName, + Username: user.UserName, + Nickname: user.NickName, + UserGroup: user.UserGroup, + Avatar: res.UserAvatar(user.Avatar), + Sign: user.Sign, + TimeOffset: user.TimeOffset, }) } diff --git a/web/handler/user/user_test.go b/web/handler/user/user_test.go index 31a8d8a7f..87fdc7122 100644 --- a/web/handler/user/user_test.go +++ b/web/handler/user/user_test.go @@ -36,7 +36,7 @@ func TestUser_Get(t *testing.T) { const uid model.UserID = 7 u := mocks.NewUserRepo(t) - u.EXPECT().GetByID(mock.Anything, uid).Return(user.User{ID: uid}, nil) + u.EXPECT().GetFullUser(mock.Anything, uid).Return(user.FullUser{ID: uid}, nil) a := mocks.NewAuthRepo(t) a.EXPECT().GetByToken(mock.Anything, "token").Return(auth.UserInfo{ID: uid}, nil) From ce10030231aaa47e057d213f286ea2ddcb42c739 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 1 Oct 2024 13:54:44 +0800 Subject: [PATCH 092/240] bump: 0.34.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ca6472a..859cecfca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "chii", - "version": "0.33.19", + "version": "0.34.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "chii", - "version": "0.33.19", + "version": "0.34.0", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.7.0", "js-yaml": "^4.1.0", diff --git a/package.json b/package.json index 2848db844..710d89354 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chii", - "version": "0.33.19", + "version": "0.34.0", "description": "tools to bundle openapi spec, not used in our server", "private": true, "scripts": { From 5d9de80060415ad84230890dc4413ae4ca7fa01a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:57:30 +0800 Subject: [PATCH 093/240] build(deps): update module google.golang.org/grpc to v1.67.1 (#639) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 09b2d1de6..e2a17663e 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index ebf7cfa15..e4d505731 100644 --- a/go.sum +++ b/go.sum @@ -608,8 +608,8 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From 3782f98f6d4c535e332b6ffe613cb167964da789 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 1 Oct 2024 13:58:06 +0800 Subject: [PATCH 094/240] chore: re-generate code --- generated/proto/go/api/v1/timeline.pb.go | 24 ++++++------ generated/proto/go/api/v1/timeline_grpc.pb.go | 37 +++++++++++++------ 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/generated/proto/go/api/v1/timeline.pb.go b/generated/proto/go/api/v1/timeline.pb.go index 4dfa208bc..de176aca5 100644 --- a/generated/proto/go/api/v1/timeline.pb.go +++ b/generated/proto/go/api/v1/timeline.pb.go @@ -2,7 +2,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.34.2 // protoc (unknown) // source: api/v1/timeline.proto @@ -695,7 +695,7 @@ func file_api_v1_timeline_proto_rawDescGZIP() []byte { } var file_api_v1_timeline_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_api_v1_timeline_proto_goTypes = []interface{}{ +var file_api_v1_timeline_proto_goTypes = []any{ (*HelloRequest)(nil), // 0: api.v1.HelloRequest (*HelloResponse)(nil), // 1: api.v1.HelloResponse (*SubjectCollectResponse)(nil), // 2: api.v1.SubjectCollectResponse @@ -733,7 +733,7 @@ func file_api_v1_timeline_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_api_v1_timeline_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*HelloRequest); i { case 0: return &v.state @@ -745,7 +745,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*HelloResponse); i { case 0: return &v.state @@ -757,7 +757,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*SubjectCollectResponse); i { case 0: return &v.state @@ -769,7 +769,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*SubjectProgressResponse); i { case 0: return &v.state @@ -781,7 +781,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*EpisodeCollectResponse); i { case 0: return &v.state @@ -793,7 +793,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*Subject); i { case 0: return &v.state @@ -805,7 +805,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*Episode); i { case 0: return &v.state @@ -817,7 +817,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*SubjectCollectRequest); i { case 0: return &v.state @@ -829,7 +829,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*EpisodeCollectRequest); i { case 0: return &v.state @@ -841,7 +841,7 @@ func file_api_v1_timeline_proto_init() { return nil } } - file_api_v1_timeline_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_api_v1_timeline_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*SubjectProgressRequest); i { case 0: return &v.state diff --git a/generated/proto/go/api/v1/timeline_grpc.pb.go b/generated/proto/go/api/v1/timeline_grpc.pb.go index e41f6a4fa..1ad4df8cd 100644 --- a/generated/proto/go/api/v1/timeline_grpc.pb.go +++ b/generated/proto/go/api/v1/timeline_grpc.pb.go @@ -2,7 +2,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc (unknown) // source: api/v1/timeline.proto @@ -17,8 +17,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( TimeLineService_Hello_FullMethodName = "/api.v1.TimeLineService/Hello" @@ -47,8 +47,9 @@ func NewTimeLineServiceClient(cc grpc.ClientConnInterface) TimeLineServiceClient } func (c *timeLineServiceClient) Hello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(HelloResponse) - err := c.cc.Invoke(ctx, TimeLineService_Hello_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, TimeLineService_Hello_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -56,8 +57,9 @@ func (c *timeLineServiceClient) Hello(ctx context.Context, in *HelloRequest, opt } func (c *timeLineServiceClient) SubjectCollect(ctx context.Context, in *SubjectCollectRequest, opts ...grpc.CallOption) (*SubjectCollectResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(SubjectCollectResponse) - err := c.cc.Invoke(ctx, TimeLineService_SubjectCollect_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, TimeLineService_SubjectCollect_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -65,8 +67,9 @@ func (c *timeLineServiceClient) SubjectCollect(ctx context.Context, in *SubjectC } func (c *timeLineServiceClient) SubjectProgress(ctx context.Context, in *SubjectProgressRequest, opts ...grpc.CallOption) (*SubjectProgressResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(SubjectProgressResponse) - err := c.cc.Invoke(ctx, TimeLineService_SubjectProgress_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, TimeLineService_SubjectProgress_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -74,8 +77,9 @@ func (c *timeLineServiceClient) SubjectProgress(ctx context.Context, in *Subject } func (c *timeLineServiceClient) EpisodeCollect(ctx context.Context, in *EpisodeCollectRequest, opts ...grpc.CallOption) (*EpisodeCollectResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(EpisodeCollectResponse) - err := c.cc.Invoke(ctx, TimeLineService_EpisodeCollect_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, TimeLineService_EpisodeCollect_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -84,7 +88,7 @@ func (c *timeLineServiceClient) EpisodeCollect(ctx context.Context, in *EpisodeC // TimeLineServiceServer is the server API for TimeLineService service. // All implementations must embed UnimplementedTimeLineServiceServer -// for forward compatibility +// for forward compatibility. type TimeLineServiceServer interface { // Debug function Hello(context.Context, *HelloRequest) (*HelloResponse, error) @@ -94,9 +98,12 @@ type TimeLineServiceServer interface { mustEmbedUnimplementedTimeLineServiceServer() } -// UnimplementedTimeLineServiceServer must be embedded to have forward compatible implementations. -type UnimplementedTimeLineServiceServer struct { -} +// UnimplementedTimeLineServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedTimeLineServiceServer struct{} func (UnimplementedTimeLineServiceServer) Hello(context.Context, *HelloRequest) (*HelloResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Hello not implemented") @@ -111,6 +118,7 @@ func (UnimplementedTimeLineServiceServer) EpisodeCollect(context.Context, *Episo return nil, status.Errorf(codes.Unimplemented, "method EpisodeCollect not implemented") } func (UnimplementedTimeLineServiceServer) mustEmbedUnimplementedTimeLineServiceServer() {} +func (UnimplementedTimeLineServiceServer) testEmbeddedByValue() {} // UnsafeTimeLineServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to TimeLineServiceServer will @@ -120,6 +128,13 @@ type UnsafeTimeLineServiceServer interface { } func RegisterTimeLineServiceServer(s grpc.ServiceRegistrar, srv TimeLineServiceServer) { + // If the following call pancis, it indicates UnimplementedTimeLineServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&TimeLineService_ServiceDesc, srv) } From 98bf0e165b9eb8eee88dd947f6c3a7df3363985f Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 01:03:23 +0800 Subject: [PATCH 095/240] fix: subject collection tags (#640) --- .golangci.yaml | 1 - cmd/archive/main.go | 2 +- cmd/gen/gorm/main.go | 41 ++ dal/dao/chii_members.gen.go | 6 +- dal/dao/chii_subject_relations.gen.go | 2 +- dal/dao/chii_subject_revisions.gen.go | 31 +- dal/dao/chii_subjects.gen.go | 53 +-- dal/dao/chii_tag_neue_index.gen.go | 23 + dal/dao/chii_tag_neue_list.gen.go | 23 + dal/query/chii_members.gen.go | 24 +- dal/query/chii_subject_relations.gen.go | 6 +- dal/query/chii_subject_revisions.gen.go | 38 +- dal/query/chii_subjects.gen.go | 60 +-- dal/query/chii_tag_neue_index.gen.go | 351 +++++++++++++++ dal/query/chii_tag_neue_list.gen.go | 425 ++++++++++++++++++ dal/query/export_db.go | 23 + dal/query/gen.go | 12 + internal/collections/infra/mysql_repo.go | 264 +++++++---- internal/collections/infra/mysql_repo_test.go | 31 +- internal/model/tag.go | 21 + 20 files changed, 1232 insertions(+), 205 deletions(-) create mode 100644 dal/dao/chii_tag_neue_index.gen.go create mode 100644 dal/dao/chii_tag_neue_list.gen.go create mode 100644 dal/query/chii_tag_neue_index.gen.go create mode 100644 dal/query/chii_tag_neue_list.gen.go create mode 100644 dal/query/export_db.go create mode 100644 internal/model/tag.go diff --git a/.golangci.yaml b/.golangci.yaml index 12d004952..dcb38b1d1 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -250,7 +250,6 @@ linters: - gocritic - gocyclo - godot - - goerr113 - gofmt - gomnd - gomoddirectives diff --git a/cmd/archive/main.go b/cmd/archive/main.go index 782ff3a9b..b60cda329 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -443,7 +443,7 @@ type SubjectRelation struct { SubjectID model.SubjectID `json:"subject_id"` RelationType uint16 `json:"relation_type"` RelatedSubjectID model.SubjectID `json:"related_subject_id"` - Order uint8 `json:"order"` + Order uint16 `json:"order"` } func exportSubjectRelations(q *query.Query, w io.Writer) { diff --git a/cmd/gen/gorm/main.go b/cmd/gen/gorm/main.go index d41412b05..5477fbea3 100644 --- a/cmd/gen/gorm/main.go +++ b/cmd/gen/gorm/main.go @@ -55,6 +55,7 @@ func DeprecatedFiled(s string) gen.ModelOpt { } const createdTime = "CreatedTime" +const updateTime = "UpdatedTime" // generate code. func main() { @@ -159,10 +160,33 @@ func main() { modelField := g.GenerateModelAs("chii_memberfields", "MemberField", gen.FieldType("uid", userIDTypeString), gen.FieldType("privacy", "[]byte"), + gen.FieldIgnore("index_sort"), + gen.FieldIgnore("user_agent"), + gen.FieldIgnore("ignorepm"), + gen.FieldIgnore("groupterms"), + gen.FieldIgnore("authstr"), + gen.FieldIgnoreReg("^(homepage|reg_source|invite_num|email_verified|reset_password_dateline|reset_password_token)$"), + gen.FieldIgnoreReg("^(reset_password_force|email_verify_dateline|email_verify_token|email_verify_score)$"), ) modelMember := g.GenerateModelAs("chii_members", "Member", gen.FieldRename("uid", "ID"), + // gen.FieldIgnore("password_crypt"), + gen.FieldIgnore("secques"), + gen.FieldIgnore("gender"), + gen.FieldIgnore("adminid"), + gen.FieldIgnore("regip"), + gen.FieldIgnore("lastip"), + + // gen.FieldIgnore("email"), + gen.FieldIgnore("bday"), + gen.FieldIgnore("styleid"), + gen.FieldIgnore("newsletter"), + gen.FieldIgnore("ukagaka_settings"), + gen.FieldIgnore("username_lock"), + gen.FieldIgnore("invited"), + gen.FieldIgnore("img_chart"), + gen.FieldType("uid", userIDTypeString), gen.FieldType("sign", "utiltype.HTMLEscapedString"), gen.FieldType("regdate", "int64"), @@ -499,6 +523,23 @@ func main() { gen.FieldRename("msg_rdeleted", "DeletedByReceiver"), )) + modelTagIndex := g.GenerateModelAs("chii_tag_neue_index", "TagIndex", + gen.FieldTrimPrefix("tag_"), + gen.FieldRename("tag_dateline", createdTime), + gen.FieldRename("tag_lasttouch", updateTime), + ) + + g.ApplyBasic(modelTagIndex) + + g.ApplyBasic(g.GenerateModelAs("chii_tag_neue_list", "TagList", + gen.FieldTrimPrefix("tlt_"), + gen.FieldRename("tlt_dateline", createdTime), + + gen.FieldRelate(field.HasOne, "Tag", modelTagIndex, &field.RelateConfig{ + GORMTag: field.GormTag{"foreignKey": []string{"tag_id"}, "references": []string{"tlt_tid"}}, + }), + )) + // execute the action of code generation g.Execute() } diff --git a/dal/dao/chii_members.gen.go b/dal/dao/chii_members.gen.go index b5cdebd31..56748c034 100644 --- a/dal/dao/chii_members.gen.go +++ b/dal/dao/chii_members.gen.go @@ -15,21 +15,21 @@ type Member struct { ID uint32 `gorm:"column:uid;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` Username string `gorm:"column:username;type:char(15);not null" json:""` Nickname string `gorm:"column:nickname;type:varchar(30);not null" json:""` + PasswordCrypt []byte `gorm:"column:password_crypt;type:char(64);not null" json:""` Avatar string `gorm:"column:avatar;type:varchar(255);not null" json:""` Groupid uint8 `gorm:"column:groupid;type:smallint(6) unsigned;not null" json:""` Regdate int64 `gorm:"column:regdate;type:int(10) unsigned;not null" json:""` Lastvisit uint32 `gorm:"column:lastvisit;type:int(10) unsigned;not null" json:""` Lastactivity uint32 `gorm:"column:lastactivity;type:int(10) unsigned;not null" json:""` Lastpost uint32 `gorm:"column:lastpost;type:int(10) unsigned;not null" json:""` + Email string `gorm:"column:email;type:char(50);not null" json:""` Dateformat string `gorm:"column:dateformat;type:char(10);not null" json:""` Timeformat bool `gorm:"column:timeformat;type:tinyint(1);not null" json:""` Timeoffset string `gorm:"column:timeoffset;type:char(4);not null" json:""` Newpm bool `gorm:"column:newpm;type:tinyint(1);not null" json:""` NewNotify uint16 `gorm:"column:new_notify;type:smallint(6) unsigned;not null;comment:新提醒" json:""` // 新提醒 - Sign utiltype.HTMLEscapedString `gorm:"column:sign;type:varchar(255);not null" json:""` - PasswordCrypt []byte `gorm:"column:password_crypt;type:char(64);not null" json:""` - Email string `gorm:"column:email;type:char(50);not null" json:""` Acl string `gorm:"column:acl;type:mediumtext;not null" json:""` + Sign utiltype.HTMLEscapedString `gorm:"column:sign;type:varchar(255);not null" json:""` Fields MemberField `gorm:"foreignKey:uid;references:uid" json:"fields"` } diff --git a/dal/dao/chii_subject_relations.gen.go b/dal/dao/chii_subject_relations.gen.go index dd09b6c40..08628db94 100644 --- a/dal/dao/chii_subject_relations.gen.go +++ b/dal/dao/chii_subject_relations.gen.go @@ -14,7 +14,7 @@ type SubjectRelation struct { RelatedSubjectID uint32 `gorm:"column:rlt_related_subject_id;type:mediumint(8) unsigned;primaryKey;comment:关联目标 ID" json:""` // 关联目标 ID RelatedSubjectTypeID uint8 `gorm:"column:rlt_related_subject_type_id;type:tinyint(3) unsigned;not null;comment:关联目标类型" json:""` // 关联目标类型 ViceVersa bool `gorm:"column:rlt_vice_versa;type:tinyint(1) unsigned;primaryKey" json:""` - Order uint8 `gorm:"column:rlt_order;type:tinyint(3) unsigned;not null;comment:关联排序" json:""` // 关联排序 + Order uint16 `gorm:"column:rlt_order;type:smallint(6) unsigned;not null;comment:关联排序" json:""` // 关联排序 Subject Subject `gorm:"foreignKey:rlt_related_subject_id;references:subject_id" json:"subject"` } diff --git a/dal/dao/chii_subject_revisions.gen.go b/dal/dao/chii_subject_revisions.gen.go index 8c1ad4d55..57360bb8f 100644 --- a/dal/dao/chii_subject_revisions.gen.go +++ b/dal/dao/chii_subject_revisions.gen.go @@ -8,21 +8,22 @@ const TableNameSubjectRevision = "chii_subject_revisions" // SubjectRevision mapped from table type SubjectRevision struct { - ID uint32 `gorm:"column:rev_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` - Type uint8 `gorm:"column:rev_type;type:tinyint(3) unsigned;not null;default:1;comment:修订类型" json:""` // 修订类型 - SubjectID uint32 `gorm:"column:rev_subject_id;type:mediumint(8) unsigned;not null" json:""` - TypeID uint16 `gorm:"column:rev_type_id;type:smallint(6) unsigned;not null" json:""` - CreatorID uint32 `gorm:"column:rev_creator;type:mediumint(8) unsigned;not null" json:""` - Dateline uint32 `gorm:"column:rev_dateline;type:int(10) unsigned;not null" json:""` - Name string `gorm:"column:rev_name;type:varchar(80);not null" json:""` - NameCN string `gorm:"column:rev_name_cn;type:varchar(80);not null" json:""` - FieldInfobox string `gorm:"column:rev_field_infobox;type:mediumtext;not null" json:""` - FieldSummary string `gorm:"column:rev_field_summary;type:mediumtext;not null" json:""` - VoteField string `gorm:"column:rev_vote_field;type:mediumtext;not null" json:""` - FieldEps uint32 `gorm:"column:rev_field_eps;type:mediumint(8) unsigned;not null" json:""` - EditSummary string `gorm:"column:rev_edit_summary;type:varchar(200);not null" json:""` - Platform uint16 `gorm:"column:rev_platform;type:smallint(6) unsigned;not null" json:""` - Subject Subject `gorm:"foreignKey:rev_subject_id;references:subject_id" json:"subject"` + ID uint32 `gorm:"column:rev_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` + Type uint8 `gorm:"column:rev_type;type:tinyint(3) unsigned;not null;default:1;comment:修订类型" json:""` // 修订类型 + SubjectID uint32 `gorm:"column:rev_subject_id;type:mediumint(8) unsigned;not null" json:""` + TypeID uint16 `gorm:"column:rev_type_id;type:smallint(6) unsigned;not null" json:""` + CreatorID uint32 `gorm:"column:rev_creator;type:mediumint(8) unsigned;not null" json:""` + Dateline uint32 `gorm:"column:rev_dateline;type:int(10) unsigned;not null" json:""` + Name string `gorm:"column:rev_name;type:varchar(80);not null" json:""` + NameCN string `gorm:"column:rev_name_cn;type:varchar(80);not null" json:""` + FieldInfobox string `gorm:"column:rev_field_infobox;type:mediumtext;not null" json:""` + FieldMetaTags string `gorm:"column:rev_field_meta_tags;type:mediumtext;not null" json:""` + FieldSummary string `gorm:"column:rev_field_summary;type:mediumtext;not null" json:""` + VoteField string `gorm:"column:rev_vote_field;type:mediumtext;not null" json:""` + FieldEps uint32 `gorm:"column:rev_field_eps;type:mediumint(8) unsigned;not null" json:""` + EditSummary string `gorm:"column:rev_edit_summary;type:varchar(200);not null" json:""` + Platform uint16 `gorm:"column:rev_platform;type:smallint(6) unsigned;not null" json:""` + Subject Subject `gorm:"foreignKey:rev_subject_id;references:subject_id" json:"subject"` } // TableName SubjectRevision's table name diff --git a/dal/dao/chii_subjects.gen.go b/dal/dao/chii_subjects.gen.go index d7bba616b..f345bd642 100644 --- a/dal/dao/chii_subjects.gen.go +++ b/dal/dao/chii_subjects.gen.go @@ -12,32 +12,33 @@ const TableNameSubject = "chii_subjects" // Subject mapped from table type Subject struct { - ID uint32 `gorm:"column:subject_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` - TypeID uint8 `gorm:"column:subject_type_id;type:smallint(6) unsigned;not null" json:""` - Name utiltype.HTMLEscapedString `gorm:"column:subject_name;type:varchar(80);not null" json:""` - NameCN utiltype.HTMLEscapedString `gorm:"column:subject_name_cn;type:varchar(80);not null" json:""` - UID string `gorm:"column:subject_uid;type:varchar(20);not null;comment:isbn / imdb" json:""` // isbn / imdb - Creator uint32 `gorm:"column:subject_creator;type:mediumint(8) unsigned;not null" json:""` - Dateline uint32 `gorm:"column:subject_dateline;type:int(10) unsigned;not null" json:""` - Image string `gorm:"column:subject_image;type:varchar(255);not null" json:""` - Platform uint16 `gorm:"column:subject_platform;type:smallint(6) unsigned;not null" json:""` - Infobox utiltype.HTMLEscapedString `gorm:"column:field_infobox;type:mediumtext;not null" json:""` - Summary string `gorm:"column:field_summary;type:mediumtext;not null;comment:summary" json:""` // summary - Field5 string `gorm:"column:field_5;type:mediumtext;not null;comment:author summary" json:""` // author summary - Volumes uint32 `gorm:"column:field_volumes;type:mediumint(8) unsigned;not null;comment:卷数" json:""` // 卷数 - Eps uint32 `gorm:"column:field_eps;type:mediumint(8) unsigned;not null" json:""` - Wish uint32 `gorm:"column:subject_wish;type:mediumint(8) unsigned;not null" json:""` - Done uint32 `gorm:"column:subject_collect;type:mediumint(8) unsigned;not null" json:""` - Doing uint32 `gorm:"column:subject_doing;type:mediumint(8) unsigned;not null" json:""` - OnHold uint32 `gorm:"column:subject_on_hold;type:mediumint(8) unsigned;not null;comment:搁置人数" json:""` // 搁置人数 - Dropped uint32 `gorm:"column:subject_dropped;type:mediumint(8) unsigned;not null;comment:抛弃人数" json:""` // 抛弃人数 - Series bool `gorm:"column:subject_series;type:tinyint(1) unsigned;not null" json:""` - SeriesEntry uint32 `gorm:"column:subject_series_entry;type:mediumint(8) unsigned;not null" json:""` - IdxCn string `gorm:"column:subject_idx_cn;type:varchar(1);not null" json:""` - Airtime uint8 `gorm:"column:subject_airtime;type:tinyint(1) unsigned;not null" json:""` - Nsfw bool `gorm:"column:subject_nsfw;type:tinyint(1);not null" json:""` - Ban uint8 `gorm:"column:subject_ban;type:tinyint(1) unsigned;not null" json:""` - Fields SubjectField `gorm:"foreignKey:subject_id;references:field_sid" json:"fields"` + ID uint32 `gorm:"column:subject_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` + TypeID uint8 `gorm:"column:subject_type_id;type:smallint(6) unsigned;not null" json:""` + Name utiltype.HTMLEscapedString `gorm:"column:subject_name;type:varchar(512);not null" json:""` + NameCN utiltype.HTMLEscapedString `gorm:"column:subject_name_cn;type:varchar(512);not null" json:""` + UID string `gorm:"column:subject_uid;type:varchar(20);not null;comment:isbn / imdb" json:""` // isbn / imdb + Creator uint32 `gorm:"column:subject_creator;type:mediumint(8) unsigned;not null" json:""` + Dateline uint32 `gorm:"column:subject_dateline;type:int(10) unsigned;not null" json:""` + Image string `gorm:"column:subject_image;type:varchar(255);not null" json:""` + Platform uint16 `gorm:"column:subject_platform;type:smallint(6) unsigned;not null" json:""` + Infobox utiltype.HTMLEscapedString `gorm:"column:field_infobox;type:mediumtext;not null" json:""` + FieldMetaTags string `gorm:"column:field_meta_tags;type:mediumtext;not null" json:""` + Summary string `gorm:"column:field_summary;type:mediumtext;not null;comment:summary" json:""` // summary + Field5 string `gorm:"column:field_5;type:mediumtext;not null;comment:author summary" json:""` // author summary + Volumes uint32 `gorm:"column:field_volumes;type:mediumint(8) unsigned;not null;comment:卷数" json:""` // 卷数 + Eps uint32 `gorm:"column:field_eps;type:mediumint(8) unsigned;not null" json:""` + Wish uint32 `gorm:"column:subject_wish;type:mediumint(8) unsigned;not null" json:""` + Done uint32 `gorm:"column:subject_collect;type:mediumint(8) unsigned;not null" json:""` + Doing uint32 `gorm:"column:subject_doing;type:mediumint(8) unsigned;not null" json:""` + OnHold uint32 `gorm:"column:subject_on_hold;type:mediumint(8) unsigned;not null;comment:搁置人数" json:""` // 搁置人数 + Dropped uint32 `gorm:"column:subject_dropped;type:mediumint(8) unsigned;not null;comment:抛弃人数" json:""` // 抛弃人数 + Series bool `gorm:"column:subject_series;type:tinyint(1) unsigned;not null" json:""` + SeriesEntry uint32 `gorm:"column:subject_series_entry;type:mediumint(8) unsigned;not null" json:""` + IdxCn string `gorm:"column:subject_idx_cn;type:varchar(1);not null" json:""` + Airtime uint8 `gorm:"column:subject_airtime;type:tinyint(1) unsigned;not null" json:""` + Nsfw bool `gorm:"column:subject_nsfw;type:tinyint(1);not null" json:""` + Ban uint8 `gorm:"column:subject_ban;type:tinyint(1) unsigned;not null" json:""` + Fields SubjectField `gorm:"foreignKey:subject_id;references:field_sid" json:"fields"` } // TableName Subject's table name diff --git a/dal/dao/chii_tag_neue_index.gen.go b/dal/dao/chii_tag_neue_index.gen.go new file mode 100644 index 000000000..bd14964d5 --- /dev/null +++ b/dal/dao/chii_tag_neue_index.gen.go @@ -0,0 +1,23 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +const TableNameTagIndex = "chii_tag_neue_index" + +// TagIndex mapped from table +type TagIndex struct { + ID uint32 `gorm:"column:tag_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` + Name string `gorm:"column:tag_name;type:varchar(30);not null" json:""` + Cat int8 `gorm:"column:tag_cat;type:tinyint(3);not null;comment:0=条目 1=日志 2=天窗" json:""` // 0=条目 1=日志 2=天窗 + Type int8 `gorm:"column:tag_type;type:tinyint(3);not null" json:""` + Results uint32 `gorm:"column:tag_results;type:mediumint(8) unsigned;not null" json:""` + CreatedTime uint32 `gorm:"column:tag_dateline;type:int(10) unsigned;not null" json:""` + UpdatedTime uint32 `gorm:"column:tag_lasttouch;type:int(10) unsigned;not null" json:""` +} + +// TableName TagIndex's table name +func (*TagIndex) TableName() string { + return TableNameTagIndex +} diff --git a/dal/dao/chii_tag_neue_list.gen.go b/dal/dao/chii_tag_neue_list.gen.go new file mode 100644 index 000000000..7b6499b7b --- /dev/null +++ b/dal/dao/chii_tag_neue_list.gen.go @@ -0,0 +1,23 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +const TableNameTagList = "chii_tag_neue_list" + +// TagList mapped from table +type TagList struct { + Tid uint32 `gorm:"column:tlt_tid;type:mediumint(8) unsigned;not null" json:""` + UID uint32 `gorm:"column:tlt_uid;type:mediumint(8) unsigned;not null" json:""` + Cat uint8 `gorm:"column:tlt_cat;type:tinyint(3) unsigned;not null" json:""` + Type uint8 `gorm:"column:tlt_type;type:tinyint(3) unsigned;not null" json:""` + Mid uint32 `gorm:"column:tlt_mid;type:mediumint(8) unsigned;not null" json:""` + CreatedTime uint32 `gorm:"column:tlt_dateline;type:int(10) unsigned;not null" json:""` + Tag TagIndex `gorm:"foreignKey:tag_id;references:tlt_tid" json:"tag"` +} + +// TableName TagList's table name +func (*TagList) TableName() string { + return TableNameTagList +} diff --git a/dal/query/chii_members.gen.go b/dal/query/chii_members.gen.go index 23de42ee5..525531682 100644 --- a/dal/query/chii_members.gen.go +++ b/dal/query/chii_members.gen.go @@ -30,21 +30,21 @@ func newMember(db *gorm.DB, opts ...gen.DOOption) member { _member.ID = field.NewUint32(tableName, "uid") _member.Username = field.NewString(tableName, "username") _member.Nickname = field.NewString(tableName, "nickname") + _member.PasswordCrypt = field.NewBytes(tableName, "password_crypt") _member.Avatar = field.NewString(tableName, "avatar") _member.Groupid = field.NewUint8(tableName, "groupid") _member.Regdate = field.NewInt64(tableName, "regdate") _member.Lastvisit = field.NewUint32(tableName, "lastvisit") _member.Lastactivity = field.NewUint32(tableName, "lastactivity") _member.Lastpost = field.NewUint32(tableName, "lastpost") + _member.Email = field.NewString(tableName, "email") _member.Dateformat = field.NewString(tableName, "dateformat") _member.Timeformat = field.NewBool(tableName, "timeformat") _member.Timeoffset = field.NewString(tableName, "timeoffset") _member.Newpm = field.NewBool(tableName, "newpm") _member.NewNotify = field.NewUint16(tableName, "new_notify") - _member.Sign = field.NewField(tableName, "sign") - _member.PasswordCrypt = field.NewBytes(tableName, "password_crypt") - _member.Email = field.NewString(tableName, "email") _member.Acl = field.NewString(tableName, "acl") + _member.Sign = field.NewField(tableName, "sign") _member.Fields = memberHasOneFields{ db: db.Session(&gorm.Session{}), @@ -63,21 +63,21 @@ type member struct { ID field.Uint32 Username field.String Nickname field.String + PasswordCrypt field.Bytes Avatar field.String Groupid field.Uint8 Regdate field.Int64 Lastvisit field.Uint32 Lastactivity field.Uint32 Lastpost field.Uint32 + Email field.String Dateformat field.String Timeformat field.Bool Timeoffset field.String Newpm field.Bool NewNotify field.Uint16 // 新提醒 - Sign field.Field - PasswordCrypt field.Bytes - Email field.String Acl field.String + Sign field.Field Fields memberHasOneFields fieldMap map[string]field.Expr @@ -98,21 +98,21 @@ func (m *member) updateTableName(table string) *member { m.ID = field.NewUint32(table, "uid") m.Username = field.NewString(table, "username") m.Nickname = field.NewString(table, "nickname") + m.PasswordCrypt = field.NewBytes(table, "password_crypt") m.Avatar = field.NewString(table, "avatar") m.Groupid = field.NewUint8(table, "groupid") m.Regdate = field.NewInt64(table, "regdate") m.Lastvisit = field.NewUint32(table, "lastvisit") m.Lastactivity = field.NewUint32(table, "lastactivity") m.Lastpost = field.NewUint32(table, "lastpost") + m.Email = field.NewString(table, "email") m.Dateformat = field.NewString(table, "dateformat") m.Timeformat = field.NewBool(table, "timeformat") m.Timeoffset = field.NewString(table, "timeoffset") m.Newpm = field.NewBool(table, "newpm") m.NewNotify = field.NewUint16(table, "new_notify") - m.Sign = field.NewField(table, "sign") - m.PasswordCrypt = field.NewBytes(table, "password_crypt") - m.Email = field.NewString(table, "email") m.Acl = field.NewString(table, "acl") + m.Sign = field.NewField(table, "sign") m.fillFieldMap() @@ -141,21 +141,21 @@ func (m *member) fillFieldMap() { m.fieldMap["uid"] = m.ID m.fieldMap["username"] = m.Username m.fieldMap["nickname"] = m.Nickname + m.fieldMap["password_crypt"] = m.PasswordCrypt m.fieldMap["avatar"] = m.Avatar m.fieldMap["groupid"] = m.Groupid m.fieldMap["regdate"] = m.Regdate m.fieldMap["lastvisit"] = m.Lastvisit m.fieldMap["lastactivity"] = m.Lastactivity m.fieldMap["lastpost"] = m.Lastpost + m.fieldMap["email"] = m.Email m.fieldMap["dateformat"] = m.Dateformat m.fieldMap["timeformat"] = m.Timeformat m.fieldMap["timeoffset"] = m.Timeoffset m.fieldMap["newpm"] = m.Newpm m.fieldMap["new_notify"] = m.NewNotify - m.fieldMap["sign"] = m.Sign - m.fieldMap["password_crypt"] = m.PasswordCrypt - m.fieldMap["email"] = m.Email m.fieldMap["acl"] = m.Acl + m.fieldMap["sign"] = m.Sign } diff --git a/dal/query/chii_subject_relations.gen.go b/dal/query/chii_subject_relations.gen.go index 01f786f63..06591e68c 100644 --- a/dal/query/chii_subject_relations.gen.go +++ b/dal/query/chii_subject_relations.gen.go @@ -33,7 +33,7 @@ func newSubjectRelation(db *gorm.DB, opts ...gen.DOOption) subjectRelation { _subjectRelation.RelatedSubjectID = field.NewUint32(tableName, "rlt_related_subject_id") _subjectRelation.RelatedSubjectTypeID = field.NewUint8(tableName, "rlt_related_subject_type_id") _subjectRelation.ViceVersa = field.NewBool(tableName, "rlt_vice_versa") - _subjectRelation.Order = field.NewUint8(tableName, "rlt_order") + _subjectRelation.Order = field.NewUint16(tableName, "rlt_order") _subjectRelation.Subject = subjectRelationHasOneSubject{ db: db.Session(&gorm.Session{}), @@ -61,7 +61,7 @@ type subjectRelation struct { RelatedSubjectID field.Uint32 // 关联目标 ID RelatedSubjectTypeID field.Uint8 // 关联目标类型 ViceVersa field.Bool - Order field.Uint8 // 关联排序 + Order field.Uint16 // 关联排序 Subject subjectRelationHasOneSubject fieldMap map[string]field.Expr @@ -85,7 +85,7 @@ func (s *subjectRelation) updateTableName(table string) *subjectRelation { s.RelatedSubjectID = field.NewUint32(table, "rlt_related_subject_id") s.RelatedSubjectTypeID = field.NewUint8(table, "rlt_related_subject_type_id") s.ViceVersa = field.NewBool(table, "rlt_vice_versa") - s.Order = field.NewUint8(table, "rlt_order") + s.Order = field.NewUint16(table, "rlt_order") s.fillFieldMap() diff --git a/dal/query/chii_subject_revisions.gen.go b/dal/query/chii_subject_revisions.gen.go index 0d50fdc81..93c7f4927 100644 --- a/dal/query/chii_subject_revisions.gen.go +++ b/dal/query/chii_subject_revisions.gen.go @@ -36,6 +36,7 @@ func newSubjectRevision(db *gorm.DB, opts ...gen.DOOption) subjectRevision { _subjectRevision.Name = field.NewString(tableName, "rev_name") _subjectRevision.NameCN = field.NewString(tableName, "rev_name_cn") _subjectRevision.FieldInfobox = field.NewString(tableName, "rev_field_infobox") + _subjectRevision.FieldMetaTags = field.NewString(tableName, "rev_field_meta_tags") _subjectRevision.FieldSummary = field.NewString(tableName, "rev_field_summary") _subjectRevision.VoteField = field.NewString(tableName, "rev_vote_field") _subjectRevision.FieldEps = field.NewUint32(tableName, "rev_field_eps") @@ -60,22 +61,23 @@ func newSubjectRevision(db *gorm.DB, opts ...gen.DOOption) subjectRevision { type subjectRevision struct { subjectRevisionDo subjectRevisionDo - ALL field.Asterisk - ID field.Uint32 - Type field.Uint8 // 修订类型 - SubjectID field.Uint32 - TypeID field.Uint16 - CreatorID field.Uint32 - Dateline field.Uint32 - Name field.String - NameCN field.String - FieldInfobox field.String - FieldSummary field.String - VoteField field.String - FieldEps field.Uint32 - EditSummary field.String - Platform field.Uint16 - Subject subjectRevisionBelongsToSubject + ALL field.Asterisk + ID field.Uint32 + Type field.Uint8 // 修订类型 + SubjectID field.Uint32 + TypeID field.Uint16 + CreatorID field.Uint32 + Dateline field.Uint32 + Name field.String + NameCN field.String + FieldInfobox field.String + FieldMetaTags field.String + FieldSummary field.String + VoteField field.String + FieldEps field.Uint32 + EditSummary field.String + Platform field.Uint16 + Subject subjectRevisionBelongsToSubject fieldMap map[string]field.Expr } @@ -101,6 +103,7 @@ func (s *subjectRevision) updateTableName(table string) *subjectRevision { s.Name = field.NewString(table, "rev_name") s.NameCN = field.NewString(table, "rev_name_cn") s.FieldInfobox = field.NewString(table, "rev_field_infobox") + s.FieldMetaTags = field.NewString(table, "rev_field_meta_tags") s.FieldSummary = field.NewString(table, "rev_field_summary") s.VoteField = field.NewString(table, "rev_vote_field") s.FieldEps = field.NewUint32(table, "rev_field_eps") @@ -134,7 +137,7 @@ func (s *subjectRevision) GetFieldByName(fieldName string) (field.OrderExpr, boo } func (s *subjectRevision) fillFieldMap() { - s.fieldMap = make(map[string]field.Expr, 15) + s.fieldMap = make(map[string]field.Expr, 16) s.fieldMap["rev_id"] = s.ID s.fieldMap["rev_type"] = s.Type s.fieldMap["rev_subject_id"] = s.SubjectID @@ -144,6 +147,7 @@ func (s *subjectRevision) fillFieldMap() { s.fieldMap["rev_name"] = s.Name s.fieldMap["rev_name_cn"] = s.NameCN s.fieldMap["rev_field_infobox"] = s.FieldInfobox + s.fieldMap["rev_field_meta_tags"] = s.FieldMetaTags s.fieldMap["rev_field_summary"] = s.FieldSummary s.fieldMap["rev_vote_field"] = s.VoteField s.fieldMap["rev_field_eps"] = s.FieldEps diff --git a/dal/query/chii_subjects.gen.go b/dal/query/chii_subjects.gen.go index 1845a13ad..53b6a059f 100644 --- a/dal/query/chii_subjects.gen.go +++ b/dal/query/chii_subjects.gen.go @@ -37,6 +37,7 @@ func newSubject(db *gorm.DB, opts ...gen.DOOption) subject { _subject.Image = field.NewString(tableName, "subject_image") _subject.Platform = field.NewUint16(tableName, "subject_platform") _subject.Infobox = field.NewField(tableName, "field_infobox") + _subject.FieldMetaTags = field.NewString(tableName, "field_meta_tags") _subject.Summary = field.NewString(tableName, "field_summary") _subject.Field5 = field.NewString(tableName, "field_5") _subject.Volumes = field.NewUint32(tableName, "field_volumes") @@ -66,33 +67,34 @@ func newSubject(db *gorm.DB, opts ...gen.DOOption) subject { type subject struct { subjectDo subjectDo - ALL field.Asterisk - ID field.Uint32 - TypeID field.Uint8 - Name field.Field - NameCN field.Field - UID field.String // isbn / imdb - Creator field.Uint32 - Dateline field.Uint32 - Image field.String - Platform field.Uint16 - Infobox field.Field - Summary field.String // summary - Field5 field.String // author summary - Volumes field.Uint32 // 卷数 - Eps field.Uint32 - Wish field.Uint32 - Done field.Uint32 - Doing field.Uint32 - OnHold field.Uint32 // 搁置人数 - Dropped field.Uint32 // 抛弃人数 - Series field.Bool - SeriesEntry field.Uint32 - IdxCn field.String - Airtime field.Uint8 - Nsfw field.Bool - Ban field.Uint8 - Fields subjectHasOneFields + ALL field.Asterisk + ID field.Uint32 + TypeID field.Uint8 + Name field.Field + NameCN field.Field + UID field.String // isbn / imdb + Creator field.Uint32 + Dateline field.Uint32 + Image field.String + Platform field.Uint16 + Infobox field.Field + FieldMetaTags field.String + Summary field.String // summary + Field5 field.String // author summary + Volumes field.Uint32 // 卷数 + Eps field.Uint32 + Wish field.Uint32 + Done field.Uint32 + Doing field.Uint32 + OnHold field.Uint32 // 搁置人数 + Dropped field.Uint32 // 抛弃人数 + Series field.Bool + SeriesEntry field.Uint32 + IdxCn field.String + Airtime field.Uint8 + Nsfw field.Bool + Ban field.Uint8 + Fields subjectHasOneFields fieldMap map[string]field.Expr } @@ -119,6 +121,7 @@ func (s *subject) updateTableName(table string) *subject { s.Image = field.NewString(table, "subject_image") s.Platform = field.NewUint16(table, "subject_platform") s.Infobox = field.NewField(table, "field_infobox") + s.FieldMetaTags = field.NewString(table, "field_meta_tags") s.Summary = field.NewString(table, "field_summary") s.Field5 = field.NewString(table, "field_5") s.Volumes = field.NewUint32(table, "field_volumes") @@ -158,7 +161,7 @@ func (s *subject) GetFieldByName(fieldName string) (field.OrderExpr, bool) { } func (s *subject) fillFieldMap() { - s.fieldMap = make(map[string]field.Expr, 26) + s.fieldMap = make(map[string]field.Expr, 27) s.fieldMap["subject_id"] = s.ID s.fieldMap["subject_type_id"] = s.TypeID s.fieldMap["subject_name"] = s.Name @@ -169,6 +172,7 @@ func (s *subject) fillFieldMap() { s.fieldMap["subject_image"] = s.Image s.fieldMap["subject_platform"] = s.Platform s.fieldMap["field_infobox"] = s.Infobox + s.fieldMap["field_meta_tags"] = s.FieldMetaTags s.fieldMap["field_summary"] = s.Summary s.fieldMap["field_5"] = s.Field5 s.fieldMap["field_volumes"] = s.Volumes diff --git a/dal/query/chii_tag_neue_index.gen.go b/dal/query/chii_tag_neue_index.gen.go new file mode 100644 index 000000000..c7e42f1bb --- /dev/null +++ b/dal/query/chii_tag_neue_index.gen.go @@ -0,0 +1,351 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "github.com/bangumi/server/dal/dao" +) + +func newTagIndex(db *gorm.DB, opts ...gen.DOOption) tagIndex { + _tagIndex := tagIndex{} + + _tagIndex.tagIndexDo.UseDB(db, opts...) + _tagIndex.tagIndexDo.UseModel(&dao.TagIndex{}) + + tableName := _tagIndex.tagIndexDo.TableName() + _tagIndex.ALL = field.NewAsterisk(tableName) + _tagIndex.ID = field.NewUint32(tableName, "tag_id") + _tagIndex.Name = field.NewString(tableName, "tag_name") + _tagIndex.Cat = field.NewInt8(tableName, "tag_cat") + _tagIndex.Type = field.NewInt8(tableName, "tag_type") + _tagIndex.Results = field.NewUint32(tableName, "tag_results") + _tagIndex.CreatedTime = field.NewUint32(tableName, "tag_dateline") + _tagIndex.UpdatedTime = field.NewUint32(tableName, "tag_lasttouch") + + _tagIndex.fillFieldMap() + + return _tagIndex +} + +type tagIndex struct { + tagIndexDo tagIndexDo + + ALL field.Asterisk + ID field.Uint32 + Name field.String + Cat field.Int8 // 0=条目 1=日志 2=天窗 + Type field.Int8 + Results field.Uint32 + CreatedTime field.Uint32 + UpdatedTime field.Uint32 + + fieldMap map[string]field.Expr +} + +func (t tagIndex) Table(newTableName string) *tagIndex { + t.tagIndexDo.UseTable(newTableName) + return t.updateTableName(newTableName) +} + +func (t tagIndex) As(alias string) *tagIndex { + t.tagIndexDo.DO = *(t.tagIndexDo.As(alias).(*gen.DO)) + return t.updateTableName(alias) +} + +func (t *tagIndex) updateTableName(table string) *tagIndex { + t.ALL = field.NewAsterisk(table) + t.ID = field.NewUint32(table, "tag_id") + t.Name = field.NewString(table, "tag_name") + t.Cat = field.NewInt8(table, "tag_cat") + t.Type = field.NewInt8(table, "tag_type") + t.Results = field.NewUint32(table, "tag_results") + t.CreatedTime = field.NewUint32(table, "tag_dateline") + t.UpdatedTime = field.NewUint32(table, "tag_lasttouch") + + t.fillFieldMap() + + return t +} + +func (t *tagIndex) WithContext(ctx context.Context) *tagIndexDo { return t.tagIndexDo.WithContext(ctx) } + +func (t tagIndex) TableName() string { return t.tagIndexDo.TableName() } + +func (t tagIndex) Alias() string { return t.tagIndexDo.Alias() } + +func (t tagIndex) Columns(cols ...field.Expr) gen.Columns { return t.tagIndexDo.Columns(cols...) } + +func (t *tagIndex) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := t.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (t *tagIndex) fillFieldMap() { + t.fieldMap = make(map[string]field.Expr, 7) + t.fieldMap["tag_id"] = t.ID + t.fieldMap["tag_name"] = t.Name + t.fieldMap["tag_cat"] = t.Cat + t.fieldMap["tag_type"] = t.Type + t.fieldMap["tag_results"] = t.Results + t.fieldMap["tag_dateline"] = t.CreatedTime + t.fieldMap["tag_lasttouch"] = t.UpdatedTime +} + +func (t tagIndex) clone(db *gorm.DB) tagIndex { + t.tagIndexDo.ReplaceConnPool(db.Statement.ConnPool) + return t +} + +func (t tagIndex) replaceDB(db *gorm.DB) tagIndex { + t.tagIndexDo.ReplaceDB(db) + return t +} + +type tagIndexDo struct{ gen.DO } + +func (t tagIndexDo) Debug() *tagIndexDo { + return t.withDO(t.DO.Debug()) +} + +func (t tagIndexDo) WithContext(ctx context.Context) *tagIndexDo { + return t.withDO(t.DO.WithContext(ctx)) +} + +func (t tagIndexDo) ReadDB() *tagIndexDo { + return t.Clauses(dbresolver.Read) +} + +func (t tagIndexDo) WriteDB() *tagIndexDo { + return t.Clauses(dbresolver.Write) +} + +func (t tagIndexDo) Session(config *gorm.Session) *tagIndexDo { + return t.withDO(t.DO.Session(config)) +} + +func (t tagIndexDo) Clauses(conds ...clause.Expression) *tagIndexDo { + return t.withDO(t.DO.Clauses(conds...)) +} + +func (t tagIndexDo) Returning(value interface{}, columns ...string) *tagIndexDo { + return t.withDO(t.DO.Returning(value, columns...)) +} + +func (t tagIndexDo) Not(conds ...gen.Condition) *tagIndexDo { + return t.withDO(t.DO.Not(conds...)) +} + +func (t tagIndexDo) Or(conds ...gen.Condition) *tagIndexDo { + return t.withDO(t.DO.Or(conds...)) +} + +func (t tagIndexDo) Select(conds ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.Select(conds...)) +} + +func (t tagIndexDo) Where(conds ...gen.Condition) *tagIndexDo { + return t.withDO(t.DO.Where(conds...)) +} + +func (t tagIndexDo) Order(conds ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.Order(conds...)) +} + +func (t tagIndexDo) Distinct(cols ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.Distinct(cols...)) +} + +func (t tagIndexDo) Omit(cols ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.Omit(cols...)) +} + +func (t tagIndexDo) Join(table schema.Tabler, on ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.Join(table, on...)) +} + +func (t tagIndexDo) LeftJoin(table schema.Tabler, on ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.LeftJoin(table, on...)) +} + +func (t tagIndexDo) RightJoin(table schema.Tabler, on ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.RightJoin(table, on...)) +} + +func (t tagIndexDo) Group(cols ...field.Expr) *tagIndexDo { + return t.withDO(t.DO.Group(cols...)) +} + +func (t tagIndexDo) Having(conds ...gen.Condition) *tagIndexDo { + return t.withDO(t.DO.Having(conds...)) +} + +func (t tagIndexDo) Limit(limit int) *tagIndexDo { + return t.withDO(t.DO.Limit(limit)) +} + +func (t tagIndexDo) Offset(offset int) *tagIndexDo { + return t.withDO(t.DO.Offset(offset)) +} + +func (t tagIndexDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *tagIndexDo { + return t.withDO(t.DO.Scopes(funcs...)) +} + +func (t tagIndexDo) Unscoped() *tagIndexDo { + return t.withDO(t.DO.Unscoped()) +} + +func (t tagIndexDo) Create(values ...*dao.TagIndex) error { + if len(values) == 0 { + return nil + } + return t.DO.Create(values) +} + +func (t tagIndexDo) CreateInBatches(values []*dao.TagIndex, batchSize int) error { + return t.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (t tagIndexDo) Save(values ...*dao.TagIndex) error { + if len(values) == 0 { + return nil + } + return t.DO.Save(values) +} + +func (t tagIndexDo) First() (*dao.TagIndex, error) { + if result, err := t.DO.First(); err != nil { + return nil, err + } else { + return result.(*dao.TagIndex), nil + } +} + +func (t tagIndexDo) Take() (*dao.TagIndex, error) { + if result, err := t.DO.Take(); err != nil { + return nil, err + } else { + return result.(*dao.TagIndex), nil + } +} + +func (t tagIndexDo) Last() (*dao.TagIndex, error) { + if result, err := t.DO.Last(); err != nil { + return nil, err + } else { + return result.(*dao.TagIndex), nil + } +} + +func (t tagIndexDo) Find() ([]*dao.TagIndex, error) { + result, err := t.DO.Find() + return result.([]*dao.TagIndex), err +} + +func (t tagIndexDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*dao.TagIndex, err error) { + buf := make([]*dao.TagIndex, 0, batchSize) + err = t.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (t tagIndexDo) FindInBatches(result *[]*dao.TagIndex, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return t.DO.FindInBatches(result, batchSize, fc) +} + +func (t tagIndexDo) Attrs(attrs ...field.AssignExpr) *tagIndexDo { + return t.withDO(t.DO.Attrs(attrs...)) +} + +func (t tagIndexDo) Assign(attrs ...field.AssignExpr) *tagIndexDo { + return t.withDO(t.DO.Assign(attrs...)) +} + +func (t tagIndexDo) Joins(fields ...field.RelationField) *tagIndexDo { + for _, _f := range fields { + t = *t.withDO(t.DO.Joins(_f)) + } + return &t +} + +func (t tagIndexDo) Preload(fields ...field.RelationField) *tagIndexDo { + for _, _f := range fields { + t = *t.withDO(t.DO.Preload(_f)) + } + return &t +} + +func (t tagIndexDo) FirstOrInit() (*dao.TagIndex, error) { + if result, err := t.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*dao.TagIndex), nil + } +} + +func (t tagIndexDo) FirstOrCreate() (*dao.TagIndex, error) { + if result, err := t.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*dao.TagIndex), nil + } +} + +func (t tagIndexDo) FindByPage(offset int, limit int) (result []*dao.TagIndex, count int64, err error) { + result, err = t.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = t.Offset(-1).Limit(-1).Count() + return +} + +func (t tagIndexDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = t.Count() + if err != nil { + return + } + + err = t.Offset(offset).Limit(limit).Scan(result) + return +} + +func (t tagIndexDo) Scan(result interface{}) (err error) { + return t.DO.Scan(result) +} + +func (t tagIndexDo) Delete(models ...*dao.TagIndex) (result gen.ResultInfo, err error) { + return t.DO.Delete(models) +} + +func (t *tagIndexDo) withDO(do gen.Dao) *tagIndexDo { + t.DO = *do.(*gen.DO) + return t +} diff --git a/dal/query/chii_tag_neue_list.gen.go b/dal/query/chii_tag_neue_list.gen.go new file mode 100644 index 000000000..ee820e9ef --- /dev/null +++ b/dal/query/chii_tag_neue_list.gen.go @@ -0,0 +1,425 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "github.com/bangumi/server/dal/dao" +) + +func newTagList(db *gorm.DB, opts ...gen.DOOption) tagList { + _tagList := tagList{} + + _tagList.tagListDo.UseDB(db, opts...) + _tagList.tagListDo.UseModel(&dao.TagList{}) + + tableName := _tagList.tagListDo.TableName() + _tagList.ALL = field.NewAsterisk(tableName) + _tagList.Tid = field.NewUint32(tableName, "tlt_tid") + _tagList.UID = field.NewUint32(tableName, "tlt_uid") + _tagList.Cat = field.NewUint8(tableName, "tlt_cat") + _tagList.Type = field.NewUint8(tableName, "tlt_type") + _tagList.Mid = field.NewUint32(tableName, "tlt_mid") + _tagList.CreatedTime = field.NewUint32(tableName, "tlt_dateline") + _tagList.Tag = tagListHasOneTag{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Tag", "dao.TagIndex"), + } + + _tagList.fillFieldMap() + + return _tagList +} + +type tagList struct { + tagListDo tagListDo + + ALL field.Asterisk + Tid field.Uint32 + UID field.Uint32 + Cat field.Uint8 + Type field.Uint8 + Mid field.Uint32 + CreatedTime field.Uint32 + Tag tagListHasOneTag + + fieldMap map[string]field.Expr +} + +func (t tagList) Table(newTableName string) *tagList { + t.tagListDo.UseTable(newTableName) + return t.updateTableName(newTableName) +} + +func (t tagList) As(alias string) *tagList { + t.tagListDo.DO = *(t.tagListDo.As(alias).(*gen.DO)) + return t.updateTableName(alias) +} + +func (t *tagList) updateTableName(table string) *tagList { + t.ALL = field.NewAsterisk(table) + t.Tid = field.NewUint32(table, "tlt_tid") + t.UID = field.NewUint32(table, "tlt_uid") + t.Cat = field.NewUint8(table, "tlt_cat") + t.Type = field.NewUint8(table, "tlt_type") + t.Mid = field.NewUint32(table, "tlt_mid") + t.CreatedTime = field.NewUint32(table, "tlt_dateline") + + t.fillFieldMap() + + return t +} + +func (t *tagList) WithContext(ctx context.Context) *tagListDo { return t.tagListDo.WithContext(ctx) } + +func (t tagList) TableName() string { return t.tagListDo.TableName() } + +func (t tagList) Alias() string { return t.tagListDo.Alias() } + +func (t tagList) Columns(cols ...field.Expr) gen.Columns { return t.tagListDo.Columns(cols...) } + +func (t *tagList) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := t.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (t *tagList) fillFieldMap() { + t.fieldMap = make(map[string]field.Expr, 7) + t.fieldMap["tlt_tid"] = t.Tid + t.fieldMap["tlt_uid"] = t.UID + t.fieldMap["tlt_cat"] = t.Cat + t.fieldMap["tlt_type"] = t.Type + t.fieldMap["tlt_mid"] = t.Mid + t.fieldMap["tlt_dateline"] = t.CreatedTime + +} + +func (t tagList) clone(db *gorm.DB) tagList { + t.tagListDo.ReplaceConnPool(db.Statement.ConnPool) + return t +} + +func (t tagList) replaceDB(db *gorm.DB) tagList { + t.tagListDo.ReplaceDB(db) + return t +} + +type tagListHasOneTag struct { + db *gorm.DB + + field.RelationField +} + +func (a tagListHasOneTag) Where(conds ...field.Expr) *tagListHasOneTag { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a tagListHasOneTag) WithContext(ctx context.Context) *tagListHasOneTag { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a tagListHasOneTag) Session(session *gorm.Session) *tagListHasOneTag { + a.db = a.db.Session(session) + return &a +} + +func (a tagListHasOneTag) Model(m *dao.TagList) *tagListHasOneTagTx { + return &tagListHasOneTagTx{a.db.Model(m).Association(a.Name())} +} + +type tagListHasOneTagTx struct{ tx *gorm.Association } + +func (a tagListHasOneTagTx) Find() (result *dao.TagIndex, err error) { + return result, a.tx.Find(&result) +} + +func (a tagListHasOneTagTx) Append(values ...*dao.TagIndex) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a tagListHasOneTagTx) Replace(values ...*dao.TagIndex) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a tagListHasOneTagTx) Delete(values ...*dao.TagIndex) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a tagListHasOneTagTx) Clear() error { + return a.tx.Clear() +} + +func (a tagListHasOneTagTx) Count() int64 { + return a.tx.Count() +} + +type tagListDo struct{ gen.DO } + +func (t tagListDo) Debug() *tagListDo { + return t.withDO(t.DO.Debug()) +} + +func (t tagListDo) WithContext(ctx context.Context) *tagListDo { + return t.withDO(t.DO.WithContext(ctx)) +} + +func (t tagListDo) ReadDB() *tagListDo { + return t.Clauses(dbresolver.Read) +} + +func (t tagListDo) WriteDB() *tagListDo { + return t.Clauses(dbresolver.Write) +} + +func (t tagListDo) Session(config *gorm.Session) *tagListDo { + return t.withDO(t.DO.Session(config)) +} + +func (t tagListDo) Clauses(conds ...clause.Expression) *tagListDo { + return t.withDO(t.DO.Clauses(conds...)) +} + +func (t tagListDo) Returning(value interface{}, columns ...string) *tagListDo { + return t.withDO(t.DO.Returning(value, columns...)) +} + +func (t tagListDo) Not(conds ...gen.Condition) *tagListDo { + return t.withDO(t.DO.Not(conds...)) +} + +func (t tagListDo) Or(conds ...gen.Condition) *tagListDo { + return t.withDO(t.DO.Or(conds...)) +} + +func (t tagListDo) Select(conds ...field.Expr) *tagListDo { + return t.withDO(t.DO.Select(conds...)) +} + +func (t tagListDo) Where(conds ...gen.Condition) *tagListDo { + return t.withDO(t.DO.Where(conds...)) +} + +func (t tagListDo) Order(conds ...field.Expr) *tagListDo { + return t.withDO(t.DO.Order(conds...)) +} + +func (t tagListDo) Distinct(cols ...field.Expr) *tagListDo { + return t.withDO(t.DO.Distinct(cols...)) +} + +func (t tagListDo) Omit(cols ...field.Expr) *tagListDo { + return t.withDO(t.DO.Omit(cols...)) +} + +func (t tagListDo) Join(table schema.Tabler, on ...field.Expr) *tagListDo { + return t.withDO(t.DO.Join(table, on...)) +} + +func (t tagListDo) LeftJoin(table schema.Tabler, on ...field.Expr) *tagListDo { + return t.withDO(t.DO.LeftJoin(table, on...)) +} + +func (t tagListDo) RightJoin(table schema.Tabler, on ...field.Expr) *tagListDo { + return t.withDO(t.DO.RightJoin(table, on...)) +} + +func (t tagListDo) Group(cols ...field.Expr) *tagListDo { + return t.withDO(t.DO.Group(cols...)) +} + +func (t tagListDo) Having(conds ...gen.Condition) *tagListDo { + return t.withDO(t.DO.Having(conds...)) +} + +func (t tagListDo) Limit(limit int) *tagListDo { + return t.withDO(t.DO.Limit(limit)) +} + +func (t tagListDo) Offset(offset int) *tagListDo { + return t.withDO(t.DO.Offset(offset)) +} + +func (t tagListDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *tagListDo { + return t.withDO(t.DO.Scopes(funcs...)) +} + +func (t tagListDo) Unscoped() *tagListDo { + return t.withDO(t.DO.Unscoped()) +} + +func (t tagListDo) Create(values ...*dao.TagList) error { + if len(values) == 0 { + return nil + } + return t.DO.Create(values) +} + +func (t tagListDo) CreateInBatches(values []*dao.TagList, batchSize int) error { + return t.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (t tagListDo) Save(values ...*dao.TagList) error { + if len(values) == 0 { + return nil + } + return t.DO.Save(values) +} + +func (t tagListDo) First() (*dao.TagList, error) { + if result, err := t.DO.First(); err != nil { + return nil, err + } else { + return result.(*dao.TagList), nil + } +} + +func (t tagListDo) Take() (*dao.TagList, error) { + if result, err := t.DO.Take(); err != nil { + return nil, err + } else { + return result.(*dao.TagList), nil + } +} + +func (t tagListDo) Last() (*dao.TagList, error) { + if result, err := t.DO.Last(); err != nil { + return nil, err + } else { + return result.(*dao.TagList), nil + } +} + +func (t tagListDo) Find() ([]*dao.TagList, error) { + result, err := t.DO.Find() + return result.([]*dao.TagList), err +} + +func (t tagListDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*dao.TagList, err error) { + buf := make([]*dao.TagList, 0, batchSize) + err = t.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (t tagListDo) FindInBatches(result *[]*dao.TagList, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return t.DO.FindInBatches(result, batchSize, fc) +} + +func (t tagListDo) Attrs(attrs ...field.AssignExpr) *tagListDo { + return t.withDO(t.DO.Attrs(attrs...)) +} + +func (t tagListDo) Assign(attrs ...field.AssignExpr) *tagListDo { + return t.withDO(t.DO.Assign(attrs...)) +} + +func (t tagListDo) Joins(fields ...field.RelationField) *tagListDo { + for _, _f := range fields { + t = *t.withDO(t.DO.Joins(_f)) + } + return &t +} + +func (t tagListDo) Preload(fields ...field.RelationField) *tagListDo { + for _, _f := range fields { + t = *t.withDO(t.DO.Preload(_f)) + } + return &t +} + +func (t tagListDo) FirstOrInit() (*dao.TagList, error) { + if result, err := t.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*dao.TagList), nil + } +} + +func (t tagListDo) FirstOrCreate() (*dao.TagList, error) { + if result, err := t.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*dao.TagList), nil + } +} + +func (t tagListDo) FindByPage(offset int, limit int) (result []*dao.TagList, count int64, err error) { + result, err = t.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = t.Offset(-1).Limit(-1).Count() + return +} + +func (t tagListDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = t.Count() + if err != nil { + return + } + + err = t.Offset(offset).Limit(limit).Scan(result) + return +} + +func (t tagListDo) Scan(result interface{}) (err error) { + return t.DO.Scan(result) +} + +func (t tagListDo) Delete(models ...*dao.TagList) (result gen.ResultInfo, err error) { + return t.DO.Delete(models) +} + +func (t *tagListDo) withDO(do gen.Dao) *tagListDo { + t.DO = *do.(*gen.DO) + return t +} diff --git a/dal/query/export_db.go b/dal/query/export_db.go new file mode 100644 index 000000000..bac903af6 --- /dev/null +++ b/dal/query/export_db.go @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package query + +import ( + "gorm.io/gorm" +) + +func (q *Query) DB() *gorm.DB { + return q.db +} diff --git a/dal/query/gen.go b/dal/query/gen.go index 133139c48..d24e02f71 100644 --- a/dal/query/gen.go +++ b/dal/query/gen.go @@ -43,6 +43,8 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query { SubjectField: newSubjectField(db, opts...), SubjectRelation: newSubjectRelation(db, opts...), SubjectRevision: newSubjectRevision(db, opts...), + TagIndex: newTagIndex(db, opts...), + TagList: newTagList(db, opts...), UserGroup: newUserGroup(db, opts...), WebSession: newWebSession(db, opts...), } @@ -76,6 +78,8 @@ type Query struct { SubjectField subjectField SubjectRelation subjectRelation SubjectRevision subjectRevision + TagIndex tagIndex + TagList tagList UserGroup userGroup WebSession webSession } @@ -110,6 +114,8 @@ func (q *Query) clone(db *gorm.DB) *Query { SubjectField: q.SubjectField.clone(db), SubjectRelation: q.SubjectRelation.clone(db), SubjectRevision: q.SubjectRevision.clone(db), + TagIndex: q.TagIndex.clone(db), + TagList: q.TagList.clone(db), UserGroup: q.UserGroup.clone(db), WebSession: q.WebSession.clone(db), } @@ -151,6 +157,8 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query { SubjectField: q.SubjectField.replaceDB(db), SubjectRelation: q.SubjectRelation.replaceDB(db), SubjectRevision: q.SubjectRevision.replaceDB(db), + TagIndex: q.TagIndex.replaceDB(db), + TagList: q.TagList.replaceDB(db), UserGroup: q.UserGroup.replaceDB(db), WebSession: q.WebSession.replaceDB(db), } @@ -182,6 +190,8 @@ type queryCtx struct { SubjectField *subjectFieldDo SubjectRelation *subjectRelationDo SubjectRevision *subjectRevisionDo + TagIndex *tagIndexDo + TagList *tagListDo UserGroup *userGroupDo WebSession *webSessionDo } @@ -213,6 +223,8 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx { SubjectField: q.SubjectField.WithContext(ctx), SubjectRelation: q.SubjectRelation.WithContext(ctx), SubjectRevision: q.SubjectRevision.WithContext(ctx), + TagIndex: q.TagIndex.WithContext(ctx), + TagList: q.TagList.WithContext(ctx), UserGroup: q.UserGroup.WithContext(ctx), WebSession: q.WebSession.WithContext(ctx), } diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 2d0114a8c..e0dd06b48 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -15,10 +15,11 @@ package infra import ( + "cmp" "context" "errors" "fmt" - "sort" + "slices" "strings" "time" @@ -27,8 +28,8 @@ import ( "github.com/trim21/go-phpserialize" "go.uber.org/zap" "gorm.io/gen" - "gorm.io/gen/field" "gorm.io/gorm" + "gorm.io/gorm/clause" "github.com/bangumi/server/dal/dao" "github.com/bangumi/server/dal/query" @@ -162,10 +163,156 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return err } + err = r.updateUserTags(ctx, userID, subject, at, s) + if err != nil { + return errgo.Trace(err) + } + r.updateSubject(ctx, subject.ID) return nil } +//nolint:funlen +func (r mysqlRepo) updateUserTags( + ctx context.Context, + userID model.UserID, + subject model.Subject, + at time.Time, + s *collection.Subject, +) error { + return r.q.Transaction(func(q *query.Query) error { + tx := q.WithContext(ctx) + + if (len(s.Tags())) == 0 { + _, err := tx.TagList.Where(q.TagList.UID.Eq(userID), + q.TagList.Mid.Eq(subject.ID), + q.TagList.Cat.Eq(model.TagCatSubject)).Delete() + if err != nil { + return errgo.Trace(err) + } + return r.reCountSubjectTags(ctx, q, subject.ID) + } + + tags, err := tx.TagIndex.Select(). + Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject)).Find() + if err != nil { + return errgo.Trace(err) + } + + var existsTags = lo.SliceToMap(tags, func(item *dao.TagIndex) (string, bool) { + return item.Name, true + }) + + var missingTags []string + for _, tag := range s.Tags() { + if !existsTags[tag] { + missingTags = append(missingTags, tag) + } + } + + if len(missingTags) > 0 { + err = tx.TagIndex.Create(lo.Map(missingTags, func(item string, index int) *dao.TagIndex { + return &dao.TagIndex{ + Name: item, + Cat: model.TagCatSubject, + Type: int8(subject.TypeID), + Results: 1, + CreatedTime: uint32(at.Unix()), + UpdatedTime: uint32(at.Unix()), + } + })...) + + if err != nil { + return errgo.Trace(err) + } + } + + tags, err = tx.TagIndex.Select(). + Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject)).Find() + if err != nil { + return errgo.Trace(err) + } + + err = tx.TagList.Clauses(clause.OnConflict{DoNothing: true}). + Create(lo.Map(tags, func(item *dao.TagIndex, index int) *dao.TagList { + return &dao.TagList{ + Tid: item.ID, + UID: s.User(), + Cat: model.TagCatSubject, + Type: subject.TypeID, + Mid: subject.ID, + CreatedTime: uint32(at.Unix()), + } + })...) + if err != nil { + return errgo.Trace(err) + } + + return r.reCountSubjectTags(ctx, q, subject.ID) + }) +} + +func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id model.SubjectID) error { + tags, err := tx.WithContext(ctx).TagList.Select(). + Where(tx.TagList.Cat.Eq(model.TagCatSubject), tx.TagList.Mid.Eq(id)).Find() + if err != nil { + return err + } + + db := tx.DB().WithContext(ctx) + + err = db.Exec(` + update chii_tag_neue_index + set tag_results = ( + select count(1) + from chii_tag_neue_list + where tlt_tid = chii_tag_neue_index.tag_id + ) + where tag_id in ? + `, lo.Map(tags, func(item *dao.TagList, index int) uint32 { + return item.Tid + })).Error + + if err != nil { + return errgo.Trace(err) + } + + tagList, err := tx.WithContext(ctx).TagList.Preload(tx.TagList.Tag). + Where(tx.TagList.Cat.Eq(model.TagCatSubject), tx.TagList.Mid.Eq(id)).Find() + if err != nil { + return errgo.Trace(err) + } + + var count = make(map[string]int) + + for _, tag := range tagList { + count[tag.Tag.Name]++ + } + + var phpTags = make([]subject.Tag, 0, len(count)) + + for name, c := range count { + phpTags = append(phpTags, subject.Tag{ + Name: lo.ToPtr(name), + Count: c, + }) + } + + slices.SortFunc(phpTags, func(a, b subject.Tag) int { + return cmp.Compare(a.Count, b.Count) + }) + + newTag, err := phpserialize.Marshal(lo.Slice(phpTags, 0, 30)) //nolint:gomnd + if err != nil { + return errgo.Wrap(err, "php.Marshal") + } + + _, err = tx.WithContext(ctx).SubjectField.Where(r.q.SubjectField.Sid.Eq(id)). + UpdateSimple(r.q.SubjectField.Tags.Value(newTag)) + + return errgo.Wrap(err, "failed to update subject field") +} + // 根据新旧 collection.Subject 状态 // 更新 dao.SubjectCollection. func (r mysqlRepo) updateSubjectCollection( @@ -339,105 +486,32 @@ func (r mysqlRepo) GetSubjectEpisodesCollection( } func (r mysqlRepo) updateSubject(ctx context.Context, subjectID model.SubjectID) { - if err := r.updateSubjectTags(ctx, subjectID); err != nil { - r.log.Error("failed to update subject tags", zap.Error(err)) - } - if err := r.reCountSubjectCollection(ctx, subjectID); err != nil { r.log.Error("failed to update collection counts", zap.Error(err)) } } func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model.SubjectID) error { - var counts []struct { - Type uint8 `gorm:"type"` - Total uint32 `gorm:"total"` - } - - err := r.q.SubjectCollection.WithContext(ctx). - Select(r.q.SubjectCollection.Type.As("type"), r.q.SubjectCollection.Type.Count().As("total")). - Group(r.q.SubjectCollection.Type). - Where(r.q.SubjectCollection.SubjectID.Eq(subjectID)).Group(r.q.SubjectCollection.Type).Scan(&counts) - if err != nil { - return errgo.Wrap(err, "dal") - } - - var updater = make([]field.AssignExpr, 0, 5) - - for _, count := range counts { - switch collection.SubjectCollection(count.Type) { //nolint:exhaustive - case collection.SubjectCollectionDropped: - updater = append(updater, r.q.Subject.Dropped.Value(count.Total)) - - case collection.SubjectCollectionWish: - updater = append(updater, r.q.Subject.Wish.Value(count.Total)) - - case collection.SubjectCollectionDoing: - updater = append(updater, r.q.Subject.Doing.Value(count.Total)) - - case collection.SubjectCollectionOnHold: - updater = append(updater, r.q.Subject.OnHold.Value(count.Total)) - - case collection.SubjectCollectionDone: - updater = append(updater, r.q.Subject.Done.Value(count.Total)) - } - } - - _, err = r.q.Subject.WithContext(ctx).Where(r.q.Subject.ID.Eq(subjectID)).UpdateSimple(updater...) - if err != nil { - return errgo.Wrap(err, "dal") - } - - return nil -} - -func (r mysqlRepo) updateSubjectTags(ctx context.Context, subjectID model.SubjectID) error { - collections, err := r.q.SubjectCollection.WithContext(ctx). - Where( - r.q.SubjectCollection.SubjectID.Eq(subjectID), - r.q.SubjectCollection.Private.Neq(uint8(collection.CollectPrivacyBan)), - ).Find() - if err != nil { - return errgo.Wrap(err, "failed to get all collection") - } - - var tags = make(map[string]int) - for _, collection := range collections { - for _, s := range strings.Split(collection.Tag, " ") { - if s == "" { - continue - } - tags[s]++ - } - } - - var phpTags = make([]subject.Tag, 0, len(tags)) - - for name, count := range tags { - name := name - phpTags = append(phpTags, subject.Tag{ - Name: &name, - Count: count, - }) - } - - sort.Slice(phpTags, func(i, j int) bool { - if phpTags[i].Count != phpTags[j].Count { - return phpTags[i].Count > phpTags[j].Count - } - - return *phpTags[i].Name > *phpTags[j].Name - }) - - newTag, err := phpserialize.Marshal(lo.Slice(phpTags, 0, 30)) //nolint:gomnd - if err != nil { - return errgo.Wrap(err, "php.Marshal") - } - - _, err = r.q.SubjectField.WithContext(ctx).Where(r.q.SubjectField.Sid.Eq(subjectID)). - UpdateSimple(r.q.SubjectField.Tags.Value(newTag)) - - return errgo.Wrap(err, "failed to update subject field") + err := r.q.DB().WithContext(ctx).Exec(` + update chii_subjects + set subject_wish = (select count(1) + from chii_subject_interests + where interest_subject_id = 1 and interest_type = subject_id), + subject_collect = (select count(1) + from chii_subject_interests + where interest_subject_id = 2 and interest_type = subject_id), + subject_doing = (select count(1) + from chii_subject_interests + where interest_subject_id = 3 and interest_type = subject_id), + subject_on_hold = (select count(1) + from chii_subject_interests + where interest_subject_id = 4 and interest_type = subject_id), + subject_dropped = (select count(1) + from chii_subject_interests + where interest_subject_id = 5 and interest_type = subject_id) + where chii_subjects.subject_id = ? +`, subjectID).Error + return errgo.Trace(err) } func (r mysqlRepo) updateCollectionTime(obj *dao.SubjectCollection, diff --git a/internal/collections/infra/mysql_repo_test.go b/internal/collections/infra/mysql_repo_test.go index 7507b6110..923230929 100644 --- a/internal/collections/infra/mysql_repo_test.go +++ b/internal/collections/infra/mysql_repo_test.go @@ -19,11 +19,13 @@ import ( "testing" "time" + "github.com/samber/lo" "github.com/stretchr/testify/require" "github.com/trim21/go-phpserialize" "go.uber.org/zap" "gorm.io/gen/field" "gorm.io/gorm" + "gorm.io/gorm/clause" "github.com/bangumi/server/dal/dao" "github.com/bangumi/server/dal/query" @@ -32,11 +34,13 @@ import ( "github.com/bangumi/server/internal/collections/infra" "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/pkg/test" + subject2 "github.com/bangumi/server/internal/subject" ) func getRepo(t *testing.T) (collections.Repo, *query.Query) { t.Helper() q := test.GetQuery(t) + repo, err := infra.NewMysqlRepo(q, zap.NewNop()) require.NoError(t, err) @@ -209,12 +213,24 @@ func TestMysqlRepo_UpdateOrCreateSubjectCollection(t *testing.T) { repo, q := getRepo(t) table := q.SubjectCollection + err := q.Subject.WithContext(context.TODO()).Clauses(clause.OnConflict{DoNothing: true}). + Where(q.Subject.ID.Eq(sid)).Create(&dao.Subject{ID: sid}) + require.NoError(t, err) + + err = q.SubjectField.WithContext(context.TODO()).Clauses(clause.OnConflict{DoNothing: true}). + Where(q.Subject.ID.Eq(sid)).Create(&dao.SubjectField{Sid: sid, Tags: []byte("")}) + require.NoError(t, err) + + t.Cleanup(func() { + lo.Must(q.Subject.WithContext(context.TODO()).Where(q.Subject.ID.Eq(sid)).Delete()) + lo.Must(q.SubjectField.WithContext(context.TODO()).Where(q.SubjectField.Sid.Eq(sid)).Delete()) + }) + test.RunAndCleanup(t, func() { - _, err := table.WithContext(context.TODO()).Where(field.Or(table.SubjectID.Eq(sid), table.UserID.Eq(uid))).Delete() - require.NoError(t, err) + lo.Must(table.WithContext(context.TODO()).Where(field.Or(table.SubjectID.Eq(sid), table.UserID.Eq(uid))).Delete()) }) - err := table.WithContext(context.Background()).Create( + err = table.WithContext(context.Background()).Create( &dao.SubjectCollection{ UserID: uid, SubjectID: sid + 1, Rate: 8, Type: uint8(collection.SubjectCollectionDoing), }, @@ -247,6 +263,7 @@ func TestMysqlRepo_UpdateOrCreateSubjectCollection(t *testing.T) { s.UpdateType(collection.SubjectCollectionDropped) require.NoError(t, s.UpdateComment("c")) require.NoError(t, s.UpdateRate(1)) + require.NoError(t, s.UpdateTags([]string{"1", "2", "3"})) return s, nil }) require.NoError(t, err) @@ -287,6 +304,14 @@ func TestMysqlRepo_UpdateOrCreateSubjectCollection(t *testing.T) { require.NoError(t, err) require.EqualValues(t, 8, r.Rate) + + s, err := q.WithContext(context.Background()).Subject.Preload(q.Subject.Fields).Where(q.Subject.ID.Eq(sid)).First() + require.NoError(t, err) + + tags, err := subject2.ParseTags(s.Fields.Tags) + require.NoError(t, err) + + require.Len(t, tags, 3) } func TestMysqlRepo_UpdateSubjectCollection(t *testing.T) { diff --git a/internal/model/tag.go b/internal/model/tag.go new file mode 100644 index 000000000..becc2f209 --- /dev/null +++ b/internal/model/tag.go @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package model + +// TagCatSubject 条目tag. +const TagCatSubject = 0 + +// TagCatMeta 官方tag. +const TagCatMeta = 3 From 93b9258f09564c104e009b1f43d3b876d769a7d7 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 01:06:12 +0800 Subject: [PATCH 096/240] style: upgrade linter --- .github/workflows/lint.yaml | 2 +- .golangci.yaml | 6 +++--- cmd/archive/main.go | 2 +- internal/collections/infra/mysql_repo.go | 2 +- internal/metrics/metrics.go | 2 +- internal/pkg/random/string.go | 4 ++-- internal/search/client.go | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 2e25d92f2..78dce3e58 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -50,4 +50,4 @@ jobs: - name: Run linters uses: golangci/golangci-lint-action@v6 with: - version: v1.57.2 + version: v1.59.1 diff --git a/.golangci.yaml b/.golangci.yaml index dcb38b1d1..f1be719f4 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -131,7 +131,7 @@ linters-settings: - pkg: "github.com/golang/mock" desc: 'use "github.com/stretchr/testify/mock" and "github.com/vektra/mockery"' - gomnd: + mnd: # settings: # mnd: # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. @@ -251,7 +251,7 @@ linters: - gocyclo - godot - gofmt - - gomnd + - mnd - gomoddirectives - gomodguard - goprintffuncname @@ -318,7 +318,7 @@ issues: - source: 'var .* sync\.Once' linters: [gochecknoglobals] - - linters: [goerr113, errorlint] + - linters: [err113, errorlint] source: "if err == redis.Nil {" # https://github.com/kunwardeep/paralleltest/issues/8 diff --git a/cmd/archive/main.go b/cmd/archive/main.go index b60cda329..fd23fbc79 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -231,7 +231,7 @@ func exportSubjects(q *query.Query, w io.Writer) { return tags[i].Count >= tags[j].Count }) - tags = lo.Filter(lo.Slice(tags, 0, 11), func(item model.Tag, index int) bool { //nolint:gomnd + tags = lo.Filter(lo.Slice(tags, 0, 11), func(item model.Tag, index int) bool { //nolint:mnd return utf8.RuneCountInString(item.Name) < 10 || item.Count >= 10 }) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index e0dd06b48..e38329fa4 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -302,7 +302,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id m return cmp.Compare(a.Count, b.Count) }) - newTag, err := phpserialize.Marshal(lo.Slice(phpTags, 0, 30)) //nolint:gomnd + newTag, err := phpserialize.Marshal(lo.Slice(phpTags, 0, 30)) //nolint:mnd if err != nil { return errgo.Wrap(err, "php.Marshal") } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 410f90e5c..8e42118eb 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -12,7 +12,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see -//nolint:gomnd,gochecknoinits,gochecknoglobals +//nolint:mnd,gochecknoinits,gochecknoglobals package metrics import ( diff --git a/internal/pkg/random/string.go b/internal/pkg/random/string.go index d5590d361..600cb653b 100644 --- a/internal/pkg/random/string.go +++ b/internal/pkg/random/string.go @@ -29,7 +29,7 @@ var p = pool.New(func() *bufio.Reader { // we may never need to change these values. const base62Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" const base62CharsLength = byte(len(base62Chars)) -const base62MaxByte = byte(255 - (256 % len(base62Chars))) //nolint:gomnd +const base62MaxByte = byte(255 - (256 % len(base62Chars))) //nolint:mnd // Base62String generate a cryptographically secure base62 string in given length. // Will panic if it can't read from 'crypto/rand'. @@ -39,7 +39,7 @@ func Base62String(length int) string { b := make([]byte, length) // storage for random bytes. - r := make([]byte, length+(length/4)) //nolint:gomnd + r := make([]byte, length+(length/4)) //nolint:mnd i := 0 for { diff --git a/internal/search/client.go b/internal/search/client.go index b619def91..69e3f16ab 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -192,7 +192,7 @@ func (c *client) sendBatch(items []subjectIndex) { retry.DelayType(retry.BackOffDelay), retry.Delay(time.Microsecond*100), - retry.Attempts(5), //nolint:gomnd + retry.Attempts(5), //nolint:mnd retry.RetryIf(func(err error) bool { var r = &meilisearch.Error{} return errors.As(err, &r) From 57632d7ba3582533b28f4bd249b18f5e2cc475bd Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 01:17:08 +0800 Subject: [PATCH 097/240] fix: tag should be filtered by subject type --- internal/collections/infra/mysql_repo.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index e38329fa4..3bb2f246c 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -194,7 +194,8 @@ func (r mysqlRepo) updateUserTags( } tags, err := tx.TagIndex.Select(). - Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject)).Find() + Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), + q.TagIndex.Type.Eq(int8(subject.TypeID))).Find() if err != nil { return errgo.Trace(err) } @@ -228,7 +229,8 @@ func (r mysqlRepo) updateUserTags( } tags, err = tx.TagIndex.Select(). - Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject)).Find() + Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), + q.TagIndex.Type.Eq(int8(subject.TypeID))).Find() if err != nil { return errgo.Trace(err) } @@ -266,7 +268,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id m set tag_results = ( select count(1) from chii_tag_neue_list - where tlt_tid = chii_tag_neue_index.tag_id + where tlt_tid = chii_tag_neue_index.tag_id and tlt_type = tag_type ) where tag_id in ? `, lo.Map(tags, func(item *dao.TagList, index int) uint32 { From ad27c96ff504d2bea2f91bc3761978f4856bb8d4 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 02:46:33 +0800 Subject: [PATCH 098/240] fix: subject tag sorting --- internal/collections/infra/mysql_repo.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 3bb2f246c..7516a4fa4 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -163,9 +163,11 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return err } - err = r.updateUserTags(ctx, userID, subject, at, s) - if err != nil { - return errgo.Trace(err) + if s.Privacy() == collection.CollectPrivacyNone { + err = r.updateUserTags(ctx, userID, subject, at, s) + if err != nil { + return errgo.Trace(err) + } } r.updateSubject(ctx, subject.ID) @@ -301,7 +303,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id m } slices.SortFunc(phpTags, func(a, b subject.Tag) int { - return cmp.Compare(a.Count, b.Count) + return -cmp.Compare(a.Count, b.Count) }) newTag, err := phpserialize.Marshal(lo.Slice(phpTags, 0, 30)) //nolint:mnd From 53b03d02856ea4891265375ca968b95a94b875f5 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 10:58:34 +0800 Subject: [PATCH 099/240] fix: subject collection count --- internal/collections/infra/mysql_repo.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 7516a4fa4..8dbcaab3e 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -500,19 +500,19 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model update chii_subjects set subject_wish = (select count(1) from chii_subject_interests - where interest_subject_id = 1 and interest_type = subject_id), + where interest_type = 1 and interest_subject_id = subject_id), subject_collect = (select count(1) from chii_subject_interests - where interest_subject_id = 2 and interest_type = subject_id), + where interest_type = 2 and interest_subject_id = subject_id), subject_doing = (select count(1) from chii_subject_interests - where interest_subject_id = 3 and interest_type = subject_id), + where interest_type = 3 and interest_subject_id = subject_id), subject_on_hold = (select count(1) from chii_subject_interests - where interest_subject_id = 4 and interest_type = subject_id), + where interest_type = 4 and interest_subject_id = subject_id), subject_dropped = (select count(1) from chii_subject_interests - where interest_subject_id = 5 and interest_type = subject_id) + where interest_type = 5 and interest_subject_id = subject_id) where chii_subjects.subject_id = ? `, subjectID).Error return errgo.Trace(err) From 4bc2bf5e45401d3be989fa0aca39fc41d7d168d3 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 11:23:25 +0800 Subject: [PATCH 100/240] perf: dedupe tag id in app before send to mysql --- internal/collections/infra/mysql_repo.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 8dbcaab3e..71222e3ae 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -270,12 +270,12 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id m set tag_results = ( select count(1) from chii_tag_neue_list - where tlt_tid = chii_tag_neue_index.tag_id and tlt_type = tag_type + where tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type ) - where tag_id in ? - `, lo.Map(tags, func(item *dao.TagList, index int) uint32 { + where tag_id IN ? + `, lo.Uniq(lo.Map(tags, func(item *dao.TagList, index int) uint32 { return item.Tid - })).Error + }))).Error if err != nil { return errgo.Trace(err) From ce4182b3744104bdb0aa2d24591e516ff6c74f9e Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 11:28:34 +0800 Subject: [PATCH 101/240] perf: add cat filter --- internal/collections/infra/mysql_repo.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 71222e3ae..a5b3022ca 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -270,10 +270,10 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id m set tag_results = ( select count(1) from chii_tag_neue_list - where tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type + where tlt_cat = ? AND tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type ) - where tag_id IN ? - `, lo.Uniq(lo.Map(tags, func(item *dao.TagList, index int) uint32 { + where tag_cat = ? AND tag_id IN ? + `, model.TagCatSubject, model.TagCatSubject, lo.Uniq(lo.Map(tags, func(item *dao.TagList, index int) uint32 { return item.Tid }))).Error From c712d738d313dd8ca9a605005e5ebe995214a374 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 11:37:09 +0800 Subject: [PATCH 102/240] perf: improve tag count --- internal/collections/infra/mysql_repo.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index a5b3022ca..2d1b78911 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -257,25 +257,17 @@ func (r mysqlRepo) updateUserTags( } func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id model.SubjectID) error { - tags, err := tx.WithContext(ctx).TagList.Select(). - Where(tx.TagList.Cat.Eq(model.TagCatSubject), tx.TagList.Mid.Eq(id)).Find() - if err != nil { - return err - } - db := tx.DB().WithContext(ctx) - err = db.Exec(` + err := db.Exec(` update chii_tag_neue_index set tag_results = ( select count(1) from chii_tag_neue_list where tlt_cat = ? AND tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type ) - where tag_cat = ? AND tag_id IN ? - `, model.TagCatSubject, model.TagCatSubject, lo.Uniq(lo.Map(tags, func(item *dao.TagList, index int) uint32 { - return item.Tid - }))).Error + where tag_cat = ? AND tag_id IN (select distinct tag_id from chii_tag_neue_list as tl where tl.tlt_cat = ? and tl.tlt_mid = ?) + `, model.TagCatSubject, model.TagCatSubject, model.TagCatSubject, id).Error if err != nil { return errgo.Trace(err) From b6fd833f6b793d39ea66a16cdbf02ce96c80b0e2 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 11:40:47 +0800 Subject: [PATCH 103/240] perf: improve tag count --- internal/collections/infra/mysql_repo.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 2d1b78911..4fb042bc5 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -263,10 +263,12 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id m update chii_tag_neue_index set tag_results = ( select count(1) - from chii_tag_neue_list - where tlt_cat = ? AND tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type + from chii_tag_neue_list + where tlt_cat = ? AND tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type ) - where tag_cat = ? AND tag_id IN (select distinct tag_id from chii_tag_neue_list as tl where tl.tlt_cat = ? and tl.tlt_mid = ?) + where tag_cat = ? AND tag_id IN ( + select distinct tl.tlt_tid from chii_tag_neue_list as tl where tl.tlt_cat = ? and tl.tlt_mid = ? + ) `, model.TagCatSubject, model.TagCatSubject, model.TagCatSubject, id).Error if err != nil { From a94105b7d9c0dd9276e32b85c4bb8102ec9d0d3a Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 12:07:13 +0800 Subject: [PATCH 104/240] perf: improve tag count --- a.sql | 12 ++++ cmd/gen/gorm/main.go | 1 + dal/dao/chii_tag_neue_index.gen.go | 2 +- dal/query/chii_tag_neue_index.gen.go | 6 +- internal/collections/infra/mysql_repo.go | 71 +++++++++++++----------- 5 files changed, 57 insertions(+), 35 deletions(-) create mode 100644 a.sql diff --git a/a.sql b/a.sql new file mode 100644 index 000000000..b120cf010 --- /dev/null +++ b/a.sql @@ -0,0 +1,12 @@ +update chii_tag_neue_index +set tag_results = (select count(1) + from chii_tag_neue_list AS tl1 + where tl1.tlt_cat = ? + AND tl1.tlt_tid = chii_tag_neue_index.tag_id + AND tl1.tlt_type = chii_tag_neue_index.tag_type) +where tag_cat = ? + AND tag_id IN (select distinct tl2.tlt_tid + from chii_tag_neue_list as tl2 + inner join chii_tag_neue_index as ti on ti.tag_id = tl2.tlt_tid + where tl2.tlt_cat = ? + and tl2.tlt_mid = ?) diff --git a/cmd/gen/gorm/main.go b/cmd/gen/gorm/main.go index 5477fbea3..643aa85d4 100644 --- a/cmd/gen/gorm/main.go +++ b/cmd/gen/gorm/main.go @@ -527,6 +527,7 @@ func main() { gen.FieldTrimPrefix("tag_"), gen.FieldRename("tag_dateline", createdTime), gen.FieldRename("tag_lasttouch", updateTime), + gen.FieldType("tag_type", "uint8"), ) g.ApplyBasic(modelTagIndex) diff --git a/dal/dao/chii_tag_neue_index.gen.go b/dal/dao/chii_tag_neue_index.gen.go index bd14964d5..142365250 100644 --- a/dal/dao/chii_tag_neue_index.gen.go +++ b/dal/dao/chii_tag_neue_index.gen.go @@ -11,7 +11,7 @@ type TagIndex struct { ID uint32 `gorm:"column:tag_id;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` Name string `gorm:"column:tag_name;type:varchar(30);not null" json:""` Cat int8 `gorm:"column:tag_cat;type:tinyint(3);not null;comment:0=条目 1=日志 2=天窗" json:""` // 0=条目 1=日志 2=天窗 - Type int8 `gorm:"column:tag_type;type:tinyint(3);not null" json:""` + Type uint8 `gorm:"column:tag_type;type:tinyint(3);not null" json:""` Results uint32 `gorm:"column:tag_results;type:mediumint(8) unsigned;not null" json:""` CreatedTime uint32 `gorm:"column:tag_dateline;type:int(10) unsigned;not null" json:""` UpdatedTime uint32 `gorm:"column:tag_lasttouch;type:int(10) unsigned;not null" json:""` diff --git a/dal/query/chii_tag_neue_index.gen.go b/dal/query/chii_tag_neue_index.gen.go index c7e42f1bb..630c6d284 100644 --- a/dal/query/chii_tag_neue_index.gen.go +++ b/dal/query/chii_tag_neue_index.gen.go @@ -30,7 +30,7 @@ func newTagIndex(db *gorm.DB, opts ...gen.DOOption) tagIndex { _tagIndex.ID = field.NewUint32(tableName, "tag_id") _tagIndex.Name = field.NewString(tableName, "tag_name") _tagIndex.Cat = field.NewInt8(tableName, "tag_cat") - _tagIndex.Type = field.NewInt8(tableName, "tag_type") + _tagIndex.Type = field.NewUint8(tableName, "tag_type") _tagIndex.Results = field.NewUint32(tableName, "tag_results") _tagIndex.CreatedTime = field.NewUint32(tableName, "tag_dateline") _tagIndex.UpdatedTime = field.NewUint32(tableName, "tag_lasttouch") @@ -47,7 +47,7 @@ type tagIndex struct { ID field.Uint32 Name field.String Cat field.Int8 // 0=条目 1=日志 2=天窗 - Type field.Int8 + Type field.Uint8 Results field.Uint32 CreatedTime field.Uint32 UpdatedTime field.Uint32 @@ -70,7 +70,7 @@ func (t *tagIndex) updateTableName(table string) *tagIndex { t.ID = field.NewUint32(table, "tag_id") t.Name = field.NewString(table, "tag_name") t.Cat = field.NewInt8(table, "tag_cat") - t.Type = field.NewInt8(table, "tag_type") + t.Type = field.NewUint8(table, "tag_type") t.Results = field.NewUint32(table, "tag_results") t.CreatedTime = field.NewUint32(table, "tag_dateline") t.UpdatedTime = field.NewUint32(table, "tag_lasttouch") diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 4fb042bc5..e27fe4cfb 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -142,6 +142,8 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( original := *collectionSubject + relatedTags := slices.Clone(original.Tags()) + // Update subject collection s, err := update(ctx, collectionSubject) if err != nil { @@ -163,11 +165,18 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return err } - if s.Privacy() == collection.CollectPrivacyNone { - err = r.updateUserTags(ctx, userID, subject, at, s) - if err != nil { - return errgo.Trace(err) - } + relatedTags = append(relatedTags, s.Tags()...) + + err = r.updateUserTags(ctx, userID, subject, at, s) + if err != nil { + return errgo.Trace(err) + } + + err = r.q.Transaction(func(tx *query.Query) error { + return r.reCountSubjectTags(ctx, tx, subject, relatedTags) + }) + if err != nil { + return errgo.Trace(err) } r.updateSubject(ctx, subject.ID) @@ -175,13 +184,9 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( } //nolint:funlen -func (r mysqlRepo) updateUserTags( - ctx context.Context, - userID model.UserID, - subject model.Subject, - at time.Time, - s *collection.Subject, -) error { +func (r mysqlRepo) updateUserTags(ctx context.Context, + userID model.UserID, subject model.Subject, + at time.Time, s *collection.Subject) error { return r.q.Transaction(func(q *query.Query) error { tx := q.WithContext(ctx) @@ -189,15 +194,12 @@ func (r mysqlRepo) updateUserTags( _, err := tx.TagList.Where(q.TagList.UID.Eq(userID), q.TagList.Mid.Eq(subject.ID), q.TagList.Cat.Eq(model.TagCatSubject)).Delete() - if err != nil { - return errgo.Trace(err) - } - return r.reCountSubjectTags(ctx, q, subject.ID) + return errgo.Trace(err) } tags, err := tx.TagIndex.Select(). Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), - q.TagIndex.Type.Eq(int8(subject.TypeID))).Find() + q.TagIndex.Type.Eq(subject.TypeID)).Find() if err != nil { return errgo.Trace(err) } @@ -218,7 +220,7 @@ func (r mysqlRepo) updateUserTags( return &dao.TagIndex{ Name: item, Cat: model.TagCatSubject, - Type: int8(subject.TypeID), + Type: subject.TypeID, Results: 1, CreatedTime: uint32(at.Unix()), UpdatedTime: uint32(at.Unix()), @@ -232,7 +234,7 @@ func (r mysqlRepo) updateUserTags( tags, err = tx.TagIndex.Select(). Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), - q.TagIndex.Type.Eq(int8(subject.TypeID))).Find() + q.TagIndex.Type.Eq(subject.TypeID)).Find() if err != nil { return errgo.Trace(err) } @@ -252,31 +254,38 @@ func (r mysqlRepo) updateUserTags( return errgo.Trace(err) } - return r.reCountSubjectTags(ctx, q, subject.ID) + return nil }) } -func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, id model.SubjectID) error { +func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, s model.Subject, relatedTags []string) error { + tagIndexs, err := tx.WithContext(ctx).TagIndex.Select(). + Where(tx.TagIndex.Cat.Eq(model.TagCatSubject), tx.TagIndex.Name.In(relatedTags...), tx.TagIndex.Type.Eq(s.TypeID)).Find() + if err != nil { + return err + } + db := tx.DB().WithContext(ctx) - err := db.Exec(` - update chii_tag_neue_index + err = db.Exec(` + update chii_tag_neue_index as ti set tag_results = ( select count(1) - from chii_tag_neue_list - where tlt_cat = ? AND tlt_tid = chii_tag_neue_index.tag_id and tlt_type = chii_tag_neue_index.tag_type + from chii_tag_neue_list as tl + where tl.tlt_cat = ti.tag_cat AND tl.tlt_tid = ti.tag_id and tl.tlt_type = ti.tag_type ) - where tag_cat = ? AND tag_id IN ( - select distinct tl.tlt_tid from chii_tag_neue_list as tl where tl.tlt_cat = ? and tl.tlt_mid = ? - ) - `, model.TagCatSubject, model.TagCatSubject, model.TagCatSubject, id).Error - + where ti.tag_cat = ? AND ti.tag_type = ? AND ti.tag_id IN ? + `, model.TagCatSubject, s.TypeID, + lo.Uniq(lo.Map(tagIndexs, func(item *dao.TagIndex, index int) uint32 { + return item.ID + })), + ).Error if err != nil { return errgo.Trace(err) } tagList, err := tx.WithContext(ctx).TagList.Preload(tx.TagList.Tag). - Where(tx.TagList.Cat.Eq(model.TagCatSubject), tx.TagList.Mid.Eq(id)).Find() + Where(tx.TagList.Cat.Eq(model.TagCatSubject), tx.TagList.Mid.Eq(s.ID)).Find() if err != nil { return errgo.Trace(err) } From f3845e50465f956db7667c53fff8d7357ed1a266 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 12:08:25 +0800 Subject: [PATCH 105/240] perf: improve tag count --- internal/collections/infra/mysql_repo.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index e27fe4cfb..523b35553 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -165,7 +165,11 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return err } - relatedTags = append(relatedTags, s.Tags()...) + if slices.Equal(relatedTags, s.Tags()) { + relatedTags = nil + } else { + relatedTags = append(relatedTags, s.Tags()...) + } err = r.updateUserTags(ctx, userID, subject, at, s) if err != nil { @@ -259,6 +263,10 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, } func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, s model.Subject, relatedTags []string) error { + if len(relatedTags) == 0 { + return nil + } + tagIndexs, err := tx.WithContext(ctx).TagIndex.Select(). Where(tx.TagIndex.Cat.Eq(model.TagCatSubject), tx.TagIndex.Name.In(relatedTags...), tx.TagIndex.Type.Eq(s.TypeID)).Find() if err != nil { From bb71dbb3965ba602db4f412c77e30a6ed76d3474 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 12:09:19 +0800 Subject: [PATCH 106/240] perf: improve tag count --- internal/collections/infra/mysql_repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 523b35553..c6da059c5 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -322,7 +322,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, s mo return errgo.Wrap(err, "php.Marshal") } - _, err = tx.WithContext(ctx).SubjectField.Where(r.q.SubjectField.Sid.Eq(id)). + _, err = tx.WithContext(ctx).SubjectField.Where(r.q.SubjectField.Sid.Eq(s.ID)). UpdateSimple(r.q.SubjectField.Tags.Value(newTag)) return errgo.Wrap(err, "failed to update subject field") From 58c34705c9a6111e7695fb8335a57b0a5c3b7eab Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 12:16:58 +0800 Subject: [PATCH 107/240] perf: improve tag count --- internal/collections/infra/mysql_repo.go | 29 ++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index c6da059c5..f630b5c11 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -143,6 +143,7 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( original := *collectionSubject relatedTags := slices.Clone(original.Tags()) + slices.Sort(relatedTags) // Update subject collection s, err := update(ctx, collectionSubject) @@ -154,21 +155,23 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return errgo.Trace(err) } - T := r.q.SubjectCollection if created { - err = errgo.Trace(T.WithContext(ctx).Create(obj)) + err = errgo.Trace(r.q.SubjectCollection.WithContext(ctx).Clauses(clause.OnConflict{UpdateAll: true}).Create(obj)) } else { - err = errgo.Trace(T.WithContext(ctx).Save(obj)) + err = errgo.Trace(r.q.SubjectCollection.WithContext(ctx).Save(obj)) } if err != nil { return err } - if slices.Equal(relatedTags, s.Tags()) { + newTags := slices.Clone(s.Tags()) + slices.Sort(newTags) + + if slices.Equal(relatedTags, newTags) { relatedTags = nil } else { - relatedTags = append(relatedTags, s.Tags()...) + relatedTags = lo.Uniq(append(relatedTags, newTags...)) } err = r.updateUserTags(ctx, userID, subject, at, s) @@ -176,11 +179,13 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return errgo.Trace(err) } - err = r.q.Transaction(func(tx *query.Query) error { - return r.reCountSubjectTags(ctx, tx, subject, relatedTags) - }) - if err != nil { - return errgo.Trace(err) + if len(relatedTags) != 0 { + err = r.q.Transaction(func(tx *query.Query) error { + return r.reCountSubjectTags(ctx, tx, subject, relatedTags) + }) + if err != nil { + return errgo.Trace(err) + } } r.updateSubject(ctx, subject.ID) @@ -263,10 +268,6 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, } func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, s model.Subject, relatedTags []string) error { - if len(relatedTags) == 0 { - return nil - } - tagIndexs, err := tx.WithContext(ctx).TagIndex.Select(). Where(tx.TagIndex.Cat.Eq(model.TagCatSubject), tx.TagIndex.Name.In(relatedTags...), tx.TagIndex.Type.Eq(s.TypeID)).Find() if err != nil { From 2b0fb688b2216020b0b85f0b5250912b3b8e2fd9 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 3 Oct 2024 12:18:34 +0800 Subject: [PATCH 108/240] style: lint --- internal/collections/infra/mysql_repo.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index f630b5c11..5b2f1b89a 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -118,6 +118,7 @@ func (r mysqlRepo) UpdateOrCreateSubjectCollection( return r.updateOrCreateSubjectCollection(ctx, userID, subject, at, ip, update, s) } +//nolint:funlen func (r mysqlRepo) updateOrCreateSubjectCollection( ctx context.Context, userID model.UserID, @@ -267,9 +268,12 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, }) } -func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, s model.Subject, relatedTags []string) error { +//nolint:funlen +func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, + s model.Subject, relatedTags []string) error { tagIndexs, err := tx.WithContext(ctx).TagIndex.Select(). - Where(tx.TagIndex.Cat.Eq(model.TagCatSubject), tx.TagIndex.Name.In(relatedTags...), tx.TagIndex.Type.Eq(s.TypeID)).Find() + Where(tx.TagIndex.Cat.Eq(model.TagCatSubject), tx.TagIndex.Name.In(relatedTags...), + tx.TagIndex.Type.Eq(s.TypeID)).Find() if err != nil { return err } From 91c54b61b07641cdde60f90c4db8674d8d177652 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 17:14:19 +0800 Subject: [PATCH 109/240] fix: remove zero width tags (#641) --- .github/workflows/test.yaml | 5 ----- internal/collections/infra/mysql_repo.go | 9 +++++++++ internal/pkg/dam/dam.go | 2 ++ internal/subject/mysq_repository_compat.go | 5 +++-- web/req/collection.go | 6 ++++++ 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a91f69108..7b0cd4321 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -59,11 +59,6 @@ jobs: - run: bash $HOME/dev-env/wait_mysql_ready.sh - - name: Check Gorm gen - run: | - task gorm - git diff --exit-code - - name: Run tests run: task coverage env: diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 5b2f1b89a..51265b07e 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -38,6 +38,7 @@ import ( "github.com/bangumi/server/internal/collections" "github.com/bangumi/server/internal/collections/domain/collection" "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/dam" "github.com/bangumi/server/internal/pkg/gstr" "github.com/bangumi/server/internal/subject" ) @@ -306,6 +307,14 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, var count = make(map[string]int) for _, tag := range tagList { + if len(tag.Tag.Name) == 0 { + continue + } + + if dam.ZeroWithPattern.MatchString(tag.Tag.Name) { + continue + } + count[tag.Tag.Name]++ } diff --git a/internal/pkg/dam/dam.go b/internal/pkg/dam/dam.go index 81eb59dd0..6191fb021 100644 --- a/internal/pkg/dam/dam.go +++ b/internal/pkg/dam/dam.go @@ -96,3 +96,5 @@ func AllPrintableChar(text string) bool { return true } + +var ZeroWithPattern = regexp.MustCompile(`\p{Cf}|\p{Cc}|\p{Co}`) diff --git a/internal/subject/mysq_repository_compat.go b/internal/subject/mysq_repository_compat.go index 01a700445..4f5c203e8 100644 --- a/internal/subject/mysq_repository_compat.go +++ b/internal/subject/mysq_repository_compat.go @@ -23,8 +23,9 @@ import ( ) type Tag struct { - Name *string `php:"tag_name"` - Count int `php:"result,string"` + Name *string `php:"tag_name"` + Count int `php:"result,string"` + TotalCount int `php:"tag_results,string"` } func ParseTags(b []byte) ([]model.Tag, error) { diff --git a/web/req/collection.go b/web/req/collection.go index 4387fd3d6..8e4193698 100644 --- a/web/req/collection.go +++ b/web/req/collection.go @@ -51,6 +51,12 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { if !lo.EveryBy(v.Tags, dam.AllPrintableChar) { return res.BadRequest("invisible character are included in tags") } + + if lo.ContainsBy(v.Tags, func(item string) bool { + return len(item) == 0 + }) { + return res.BadRequest("zero length tags are included in tags") + } } if v.Comment.Set { From 5d647f28348489899dc1b447b185a168da4c10c5 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 17:40:55 +0800 Subject: [PATCH 110/240] build: upgrade deps --- dal/dao/chii_members.gen.go | 6 +-- dal/query/chii_members.gen.go | 24 ++++++------ go.mod | 35 ++++++++--------- go.sum | 71 +++++++++++++++++++---------------- 4 files changed, 71 insertions(+), 65 deletions(-) diff --git a/dal/dao/chii_members.gen.go b/dal/dao/chii_members.gen.go index 56748c034..b5cdebd31 100644 --- a/dal/dao/chii_members.gen.go +++ b/dal/dao/chii_members.gen.go @@ -15,21 +15,21 @@ type Member struct { ID uint32 `gorm:"column:uid;type:mediumint(8) unsigned;primaryKey;autoIncrement:true" json:""` Username string `gorm:"column:username;type:char(15);not null" json:""` Nickname string `gorm:"column:nickname;type:varchar(30);not null" json:""` - PasswordCrypt []byte `gorm:"column:password_crypt;type:char(64);not null" json:""` Avatar string `gorm:"column:avatar;type:varchar(255);not null" json:""` Groupid uint8 `gorm:"column:groupid;type:smallint(6) unsigned;not null" json:""` Regdate int64 `gorm:"column:regdate;type:int(10) unsigned;not null" json:""` Lastvisit uint32 `gorm:"column:lastvisit;type:int(10) unsigned;not null" json:""` Lastactivity uint32 `gorm:"column:lastactivity;type:int(10) unsigned;not null" json:""` Lastpost uint32 `gorm:"column:lastpost;type:int(10) unsigned;not null" json:""` - Email string `gorm:"column:email;type:char(50);not null" json:""` Dateformat string `gorm:"column:dateformat;type:char(10);not null" json:""` Timeformat bool `gorm:"column:timeformat;type:tinyint(1);not null" json:""` Timeoffset string `gorm:"column:timeoffset;type:char(4);not null" json:""` Newpm bool `gorm:"column:newpm;type:tinyint(1);not null" json:""` NewNotify uint16 `gorm:"column:new_notify;type:smallint(6) unsigned;not null;comment:新提醒" json:""` // 新提醒 - Acl string `gorm:"column:acl;type:mediumtext;not null" json:""` Sign utiltype.HTMLEscapedString `gorm:"column:sign;type:varchar(255);not null" json:""` + PasswordCrypt []byte `gorm:"column:password_crypt;type:char(64);not null" json:""` + Email string `gorm:"column:email;type:char(50);not null" json:""` + Acl string `gorm:"column:acl;type:mediumtext;not null" json:""` Fields MemberField `gorm:"foreignKey:uid;references:uid" json:"fields"` } diff --git a/dal/query/chii_members.gen.go b/dal/query/chii_members.gen.go index 525531682..23de42ee5 100644 --- a/dal/query/chii_members.gen.go +++ b/dal/query/chii_members.gen.go @@ -30,21 +30,21 @@ func newMember(db *gorm.DB, opts ...gen.DOOption) member { _member.ID = field.NewUint32(tableName, "uid") _member.Username = field.NewString(tableName, "username") _member.Nickname = field.NewString(tableName, "nickname") - _member.PasswordCrypt = field.NewBytes(tableName, "password_crypt") _member.Avatar = field.NewString(tableName, "avatar") _member.Groupid = field.NewUint8(tableName, "groupid") _member.Regdate = field.NewInt64(tableName, "regdate") _member.Lastvisit = field.NewUint32(tableName, "lastvisit") _member.Lastactivity = field.NewUint32(tableName, "lastactivity") _member.Lastpost = field.NewUint32(tableName, "lastpost") - _member.Email = field.NewString(tableName, "email") _member.Dateformat = field.NewString(tableName, "dateformat") _member.Timeformat = field.NewBool(tableName, "timeformat") _member.Timeoffset = field.NewString(tableName, "timeoffset") _member.Newpm = field.NewBool(tableName, "newpm") _member.NewNotify = field.NewUint16(tableName, "new_notify") - _member.Acl = field.NewString(tableName, "acl") _member.Sign = field.NewField(tableName, "sign") + _member.PasswordCrypt = field.NewBytes(tableName, "password_crypt") + _member.Email = field.NewString(tableName, "email") + _member.Acl = field.NewString(tableName, "acl") _member.Fields = memberHasOneFields{ db: db.Session(&gorm.Session{}), @@ -63,21 +63,21 @@ type member struct { ID field.Uint32 Username field.String Nickname field.String - PasswordCrypt field.Bytes Avatar field.String Groupid field.Uint8 Regdate field.Int64 Lastvisit field.Uint32 Lastactivity field.Uint32 Lastpost field.Uint32 - Email field.String Dateformat field.String Timeformat field.Bool Timeoffset field.String Newpm field.Bool NewNotify field.Uint16 // 新提醒 - Acl field.String Sign field.Field + PasswordCrypt field.Bytes + Email field.String + Acl field.String Fields memberHasOneFields fieldMap map[string]field.Expr @@ -98,21 +98,21 @@ func (m *member) updateTableName(table string) *member { m.ID = field.NewUint32(table, "uid") m.Username = field.NewString(table, "username") m.Nickname = field.NewString(table, "nickname") - m.PasswordCrypt = field.NewBytes(table, "password_crypt") m.Avatar = field.NewString(table, "avatar") m.Groupid = field.NewUint8(table, "groupid") m.Regdate = field.NewInt64(table, "regdate") m.Lastvisit = field.NewUint32(table, "lastvisit") m.Lastactivity = field.NewUint32(table, "lastactivity") m.Lastpost = field.NewUint32(table, "lastpost") - m.Email = field.NewString(table, "email") m.Dateformat = field.NewString(table, "dateformat") m.Timeformat = field.NewBool(table, "timeformat") m.Timeoffset = field.NewString(table, "timeoffset") m.Newpm = field.NewBool(table, "newpm") m.NewNotify = field.NewUint16(table, "new_notify") - m.Acl = field.NewString(table, "acl") m.Sign = field.NewField(table, "sign") + m.PasswordCrypt = field.NewBytes(table, "password_crypt") + m.Email = field.NewString(table, "email") + m.Acl = field.NewString(table, "acl") m.fillFieldMap() @@ -141,21 +141,21 @@ func (m *member) fillFieldMap() { m.fieldMap["uid"] = m.ID m.fieldMap["username"] = m.Username m.fieldMap["nickname"] = m.Nickname - m.fieldMap["password_crypt"] = m.PasswordCrypt m.fieldMap["avatar"] = m.Avatar m.fieldMap["groupid"] = m.Groupid m.fieldMap["regdate"] = m.Regdate m.fieldMap["lastvisit"] = m.Lastvisit m.fieldMap["lastactivity"] = m.Lastactivity m.fieldMap["lastpost"] = m.Lastpost - m.fieldMap["email"] = m.Email m.fieldMap["dateformat"] = m.Dateformat m.fieldMap["timeformat"] = m.Timeformat m.fieldMap["timeoffset"] = m.Timeoffset m.fieldMap["newpm"] = m.Newpm m.fieldMap["new_notify"] = m.NewNotify - m.fieldMap["acl"] = m.Acl m.fieldMap["sign"] = m.Sign + m.fieldMap["password_crypt"] = m.PasswordCrypt + m.fieldMap["email"] = m.Email + m.fieldMap["acl"] = m.Acl } diff --git a/go.mod b/go.mod index e2a17663e..d322a6b90 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/bangumi/server -go 1.22 +go 1.22.0 -toolchain go1.22.2 +toolchain go1.22.6 require ( github.com/avast/retry-go/v4 v4.6.0 @@ -35,7 +35,7 @@ require ( github.com/trim21/pkg v0.0.3 go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.27.0 + golang.org/x/crypto v0.28.0 google.golang.org/grpc v1.67.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 @@ -49,45 +49,46 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/BurntSushi/toml v1.2.1 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.10 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pierrec/lz4/v4 v4.1.18 // indirect + github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/dig v1.18.0 // indirect - go.uber.org/multierr v1.10.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.28.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - gorm.io/datatypes v1.2.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/time v0.7.0 // indirect + golang.org/x/tools v0.26.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + gorm.io/datatypes v1.2.2 // indirect gorm.io/hints v1.1.2 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect ) diff --git a/go.sum b/go.sum index e4d505731..9f5584fa4 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,9 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -82,8 +83,8 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -147,6 +148,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -185,10 +188,12 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA= -github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -218,8 +223,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -316,8 +321,8 @@ github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= -github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -346,8 +351,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -449,8 +454,8 @@ 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/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.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -465,8 +470,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -477,8 +482,8 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +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/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= @@ -501,8 +506,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= 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= @@ -545,8 +550,8 @@ 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= @@ -561,12 +566,12 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -583,8 +588,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -597,8 +602,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -646,8 +651,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco= -gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04= +gorm.io/datatypes v1.2.2 h1:sdn7ZmG4l7JWtMDUb3L98f2Ym7CO5F8mZLlrQJMfF9g= +gorm.io/datatypes v1.2.2/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= From 5f5a514fa952bfad8e681f7d5d876ce0c9f55259 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 17:53:56 +0800 Subject: [PATCH 111/240] fix: tag total count --- internal/collections/infra/mysql_repo.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 51265b07e..2eed15027 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -305,6 +305,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, } var count = make(map[string]int) + var countMap = make(map[string]uint32) for _, tag := range tagList { if len(tag.Tag.Name) == 0 { @@ -316,14 +317,16 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, } count[tag.Tag.Name]++ + countMap[tag.Tag.Name] = tag.Tag.Results } var phpTags = make([]subject.Tag, 0, len(count)) for name, c := range count { phpTags = append(phpTags, subject.Tag{ - Name: lo.ToPtr(name), - Count: c, + Name: lo.ToPtr(name), + Count: c, + TotalCount: int(countMap[name]), }) } From 69c70dea0afa43b48a5af1fd7b6b1fa16a624185 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 18:11:42 +0800 Subject: [PATCH 112/240] fix: check tags --- internal/collections/infra/mysql_repo.go | 6 +----- internal/pkg/dam/dam.go | 19 ++++++++++++++++++- web/req/collection.go | 15 ++++----------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 2eed15027..5b1f82c9e 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -308,11 +308,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, var countMap = make(map[string]uint32) for _, tag := range tagList { - if len(tag.Tag.Name) == 0 { - continue - } - - if dam.ZeroWithPattern.MatchString(tag.Tag.Name) { + if !dam.ValidateTag(tag.Tag.Name) { continue } diff --git a/internal/pkg/dam/dam.go b/internal/pkg/dam/dam.go index 6191fb021..ac525dabf 100644 --- a/internal/pkg/dam/dam.go +++ b/internal/pkg/dam/dam.go @@ -97,4 +97,21 @@ func AllPrintableChar(text string) bool { return true } -var ZeroWithPattern = regexp.MustCompile(`\p{Cf}|\p{Cc}|\p{Co}`) +var ZeroWidthPattern = regexp.MustCompile(`\p{Cf}|\p{Cc}|\p{Co}`) +var ExtraSpacePattern = regexp.MustCompile("[\u3000 ]") + +func ValidateTag(t string) bool { + if len(t) == 0 { + return false + } + + if !AllPrintableChar(t) { + return false + } + + if ExtraSpacePattern.MatchString(t) { + return false + } + + return true +} diff --git a/web/req/collection.go b/web/req/collection.go index 8e4193698..c2c6e3606 100644 --- a/web/req/collection.go +++ b/web/req/collection.go @@ -15,11 +15,10 @@ package req import ( + "fmt" "strings" "unicode/utf8" - "github.com/samber/lo" - "github.com/bangumi/server/internal/collections/domain/collection" "github.com/bangumi/server/internal/pkg/dam" "github.com/bangumi/server/internal/pkg/null" @@ -47,15 +46,9 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { } } - if len(v.Tags) > 0 { - if !lo.EveryBy(v.Tags, dam.AllPrintableChar) { - return res.BadRequest("invisible character are included in tags") - } - - if lo.ContainsBy(v.Tags, func(item string) bool { - return len(item) == 0 - }) { - return res.BadRequest("zero length tags are included in tags") + for _, tag := range v.Tags { + if !dam.ValidateTag(tag) { + return res.BadRequest(fmt.Sprintf("invalid tag: %q", tag)) } } From f6b52f7d39856dfdf28566a613036e98b37e8d57 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 19:44:09 +0800 Subject: [PATCH 113/240] chore: log user tags --- internal/collections/infra/mysql_repo.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 5b1f82c9e..1e1794a4c 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -198,6 +198,7 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( func (r mysqlRepo) updateUserTags(ctx context.Context, userID model.UserID, subject model.Subject, at time.Time, s *collection.Subject) error { + r.log.Info("user collections with tags", zap.Strings("tags", s.Tags())) return r.q.Transaction(func(q *query.Query) error { tx := q.WithContext(ctx) From a6cc30155460afddeeb848290e44730396ad7bb1 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 20:05:43 +0800 Subject: [PATCH 114/240] chore: log user tags --- internal/collections/infra/mysql_repo.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 1e1794a4c..979cdfb00 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "slices" + "strconv" "strings" "time" @@ -198,7 +199,11 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( func (r mysqlRepo) updateUserTags(ctx context.Context, userID model.UserID, subject model.Subject, at time.Time, s *collection.Subject) error { - r.log.Info("user collections with tags", zap.Strings("tags", s.Tags())) + r.log.Info("user collections with tags", zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { + ss := strconv.Quote(item) + return ss[1 : len(ss)-1] + }))) + return r.q.Transaction(func(q *query.Query) error { tx := q.WithContext(ctx) From 479d5420b635b59a88b872726129bae03952772e Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 20:44:58 +0800 Subject: [PATCH 115/240] chore: log more data --- internal/collections/infra/mysql_repo.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 979cdfb00..7d20fb9bb 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -199,10 +199,11 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( func (r mysqlRepo) updateUserTags(ctx context.Context, userID model.UserID, subject model.Subject, at time.Time, s *collection.Subject) error { - r.log.Info("user collections with tags", zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { - ss := strconv.Quote(item) - return ss[1 : len(ss)-1] - }))) + r.log.Info("user collections with tags", zap.Uint32("user_id", userID), zap.Uint32("subject_id", subject.ID), + zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { + ss := strconv.Quote(item) + return ss[1 : len(ss)-1] + }))) return r.q.Transaction(func(q *query.Query) error { tx := q.WithContext(ctx) From 63ddc8f51e94f3de9678701eb38c075f54a63886 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 5 Oct 2024 20:58:10 +0800 Subject: [PATCH 116/240] chore: log more data --- internal/collections/infra/mysql_repo.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 7d20fb9bb..d981a1561 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -199,11 +199,11 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( func (r mysqlRepo) updateUserTags(ctx context.Context, userID model.UserID, subject model.Subject, at time.Time, s *collection.Subject) error { - r.log.Info("user collections with tags", zap.Uint32("user_id", userID), zap.Uint32("subject_id", subject.ID), - zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { - ss := strconv.Quote(item) - return ss[1 : len(ss)-1] - }))) + log := r.log.With(zap.Uint32("user_id", userID), zap.Uint32("subject_id", subject.ID)) + log.Info("user collections with tags", zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { + ss := strconv.Quote(item) + return ss[1 : len(ss)-1] + }))) return r.q.Transaction(func(q *query.Query) error { tx := q.WithContext(ctx) @@ -234,6 +234,7 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, } if len(missingTags) > 0 { + log.Info("create missing tags", zap.Strings("missing_tags", missingTags)) err = tx.TagIndex.Create(lo.Map(missingTags, func(item string, index int) *dao.TagIndex { return &dao.TagIndex{ Name: item, From b6924bdc89efcb1f8c8983dd913987fbf5be7c6c Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 02:24:59 +0800 Subject: [PATCH 117/240] fix: run unicode NFKC on input --- go.mod | 2 +- internal/collections/domain/collection/subject.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d322a6b90..90c13749b 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 + golang.org/x/text v0.19.0 google.golang.org/grpc v1.67.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.34.2 @@ -84,7 +85,6 @@ require ( golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect diff --git a/internal/collections/domain/collection/subject.go b/internal/collections/domain/collection/subject.go index 8fc8227ae..292ab709a 100644 --- a/internal/collections/domain/collection/subject.go +++ b/internal/collections/domain/collection/subject.go @@ -19,6 +19,7 @@ import ( "github.com/samber/lo" "github.com/trim21/errgo" + "golang.org/x/text/unicode/norm" "github.com/bangumi/server/domain/gerr" "github.com/bangumi/server/internal/model" @@ -135,6 +136,10 @@ func (s *Subject) UpdateTags(tags []string) error { return gerr.ErrInvisibleChar } + for i, tag := range tags { + tags[i] = norm.NFKC.String(tag) + } + s.tags = lo.Uniq(tags) return nil From 4bb6af64b948633204ccab25493d628e6d77d31c Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 02:25:34 +0800 Subject: [PATCH 118/240] fix: run unicode NFKC on input --- internal/collections/domain/collection/subject.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/collections/domain/collection/subject.go b/internal/collections/domain/collection/subject.go index 292ab709a..3534aca95 100644 --- a/internal/collections/domain/collection/subject.go +++ b/internal/collections/domain/collection/subject.go @@ -119,7 +119,7 @@ func (s *Subject) UpdateComment(comment string) error { return gerr.ErrInvisibleChar } - s.comment = comment + s.comment = norm.NFKC.String(comment) return nil } From e98bbddde3faf5e01e95adfa28bbbb193515379e Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 02:40:38 +0800 Subject: [PATCH 119/240] metrics: add bucket --- internal/collections/infra/mysql_repo.go | 14 +++++++------- internal/metrics/metrics.go | 10 ++++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index d981a1561..6aa9ed514 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -290,13 +290,13 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, db := tx.DB().WithContext(ctx) err = db.Exec(` - update chii_tag_neue_index as ti - set tag_results = ( - select count(1) - from chii_tag_neue_list as tl - where tl.tlt_cat = ti.tag_cat AND tl.tlt_tid = ti.tag_id and tl.tlt_type = ti.tag_type - ) - where ti.tag_cat = ? AND ti.tag_type = ? AND ti.tag_id IN ? + update chii_tag_neue_index as ti + set tag_results = ( + select count(1) + from chii_tag_neue_list as tl + where tl.tlt_cat = ti.tag_cat AND tl.tlt_tid = ti.tag_id and tl.tlt_type = ti.tag_type + ) + where ti.tag_cat = ? AND ti.tag_type = ? AND ti.tag_id IN ? `, model.TagCatSubject, s.TypeID, lo.Uniq(lo.Map(tagIndexs, func(item *dao.TagIndex, index int) uint32 { return item.ID diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 8e42118eb..9756532f9 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -45,7 +45,10 @@ var RequestHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{ 0.200, 0.300, 0.500, - 1.000, + 1, + 2, + 5, + 10, }, }) @@ -68,6 +71,9 @@ var SQLHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{ 0.200, 0.300, 0.500, - 1.000, + 1, + 2, + 5, + 10, }, }) From 612f70b377879181f401150e35a06a5c513b70ac Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 03:14:47 +0800 Subject: [PATCH 120/240] perf: improve collection type count --- a.sql | 12 ----- internal/collections/infra/mysql_repo.go | 66 +++++++++++++++++------- 2 files changed, 46 insertions(+), 32 deletions(-) delete mode 100644 a.sql diff --git a/a.sql b/a.sql deleted file mode 100644 index b120cf010..000000000 --- a/a.sql +++ /dev/null @@ -1,12 +0,0 @@ -update chii_tag_neue_index -set tag_results = (select count(1) - from chii_tag_neue_list AS tl1 - where tl1.tlt_cat = ? - AND tl1.tlt_tid = chii_tag_neue_index.tag_id - AND tl1.tlt_type = chii_tag_neue_index.tag_type) -where tag_cat = ? - AND tag_id IN (select distinct tl2.tlt_tid - from chii_tag_neue_list as tl2 - inner join chii_tag_neue_index as ti on ti.tag_id = tl2.tlt_tid - where tl2.tlt_cat = ? - and tl2.tlt_mid = ?) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 6aa9ed514..b4db3538e 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -29,6 +29,7 @@ import ( "github.com/trim21/go-phpserialize" "go.uber.org/zap" "gorm.io/gen" + "gorm.io/gen/field" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -528,26 +529,51 @@ func (r mysqlRepo) updateSubject(ctx context.Context, subjectID model.SubjectID) } func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model.SubjectID) error { - err := r.q.DB().WithContext(ctx).Exec(` - update chii_subjects - set subject_wish = (select count(1) - from chii_subject_interests - where interest_type = 1 and interest_subject_id = subject_id), - subject_collect = (select count(1) - from chii_subject_interests - where interest_type = 2 and interest_subject_id = subject_id), - subject_doing = (select count(1) - from chii_subject_interests - where interest_type = 3 and interest_subject_id = subject_id), - subject_on_hold = (select count(1) - from chii_subject_interests - where interest_type = 4 and interest_subject_id = subject_id), - subject_dropped = (select count(1) - from chii_subject_interests - where interest_type = 5 and interest_subject_id = subject_id) - where chii_subjects.subject_id = ? -`, subjectID).Error - return errgo.Trace(err) + return r.q.Transaction(func(tx *query.Query) error { + var counts = make([]struct { + Type uint8 `gorm:"type"` + Total uint32 `gorm:"total"` + }, 5) + + for i, t := range []collection.SubjectCollection{ + collection.SubjectCollectionDropped, + collection.SubjectCollectionDoing, + collection.SubjectCollectionDone, + collection.SubjectCollectionDropped, + collection.SubjectCollectionWish, + } { + err := tx.DB().WithContext(ctx).Exec(` + select interest_type as type, count(1) as total from chii_subject_interests + where interest_subject_id = ? and interest_type = ? + `, subjectID, t).Scan(&counts[i]).Error + if err != nil { + return errgo.Wrap(err, "dal") + } + } + + var updater = make([]field.AssignExpr, 0, 5) + for _, count := range counts { + switch collection.SubjectCollection(count.Type) { //nolint:exhaustive + case collection.SubjectCollectionDropped: + updater = append(updater, r.q.Subject.Dropped.Value(count.Total)) + + case collection.SubjectCollectionWish: + updater = append(updater, r.q.Subject.Wish.Value(count.Total)) + + case collection.SubjectCollectionDoing: + updater = append(updater, r.q.Subject.Doing.Value(count.Total)) + + case collection.SubjectCollectionOnHold: + updater = append(updater, r.q.Subject.OnHold.Value(count.Total)) + + case collection.SubjectCollectionDone: + updater = append(updater, r.q.Subject.Done.Value(count.Total)) + } + } + + _, err := tx.Subject.WithContext(ctx).Where(r.q.Subject.ID.Eq(subjectID)).UpdateSimple(updater...) + return errgo.Wrap(err, "dal") + }) } func (r mysqlRepo) updateCollectionTime(obj *dao.SubjectCollection, From 67c6567222bd40dfc902e655a35e4be0e9f6c36a Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 03:19:01 +0800 Subject: [PATCH 121/240] fix: remove meanless perf --- internal/collections/infra/mysql_repo.go | 39 +++++++++++------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index b4db3538e..a8ac30911 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -529,26 +529,19 @@ func (r mysqlRepo) updateSubject(ctx context.Context, subjectID model.SubjectID) } func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model.SubjectID) error { + var counts []struct { + Type uint8 `gorm:"type"` + Total uint32 `gorm:"total"` + } + return r.q.Transaction(func(tx *query.Query) error { - var counts = make([]struct { - Type uint8 `gorm:"type"` - Total uint32 `gorm:"total"` - }, 5) - - for i, t := range []collection.SubjectCollection{ - collection.SubjectCollectionDropped, - collection.SubjectCollectionDoing, - collection.SubjectCollectionDone, - collection.SubjectCollectionDropped, - collection.SubjectCollectionWish, - } { - err := tx.DB().WithContext(ctx).Exec(` - select interest_type as type, count(1) as total from chii_subject_interests - where interest_subject_id = ? and interest_type = ? - `, subjectID, t).Scan(&counts[i]).Error - if err != nil { - return errgo.Wrap(err, "dal") - } + err := tx.DB().WithContext(ctx).Exec(` + select interest_type as type, count(interest_type) as total from chii_subject_interests + where interest_subject_id = ? + group by interest_type + `, subjectID).Scan(&counts).Error + if err != nil { + return errgo.Wrap(err, "dal") } var updater = make([]field.AssignExpr, 0, 5) @@ -571,8 +564,12 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model } } - _, err := tx.Subject.WithContext(ctx).Where(r.q.Subject.ID.Eq(subjectID)).UpdateSimple(updater...) - return errgo.Wrap(err, "dal") + _, err = tx.Subject.WithContext(ctx).Where(r.q.Subject.ID.Eq(subjectID)).UpdateSimple(updater...) + if err != nil { + return errgo.Wrap(err, "dal") + } + + return nil }) } From 73f71d11ef821c068a43da3173db794984f741d1 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 13:47:26 +0800 Subject: [PATCH 122/240] fix: sql syntax error --- internal/collections/infra/mysql_repo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index a8ac30911..29b095083 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -535,8 +535,8 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model } return r.q.Transaction(func(tx *query.Query) error { - err := tx.DB().WithContext(ctx).Exec(` - select interest_type as type, count(interest_type) as total from chii_subject_interests + err := tx.DB().WithContext(ctx).Exec(`select interest_type as type, count(interest_type) as total + from chii_subject_interests where interest_subject_id = ? group by interest_type `, subjectID).Scan(&counts).Error From eaa719a06db8f436b3615edb827a10213764bfa3 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 13:57:25 +0800 Subject: [PATCH 123/240] chore: log sql to debug level --- dal/new.go | 5 ++--- internal/collections/infra/mysql_repo.go | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dal/new.go b/dal/new.go index 35de32e5a..bef0f170b 100644 --- a/dal/new.go +++ b/dal/new.go @@ -16,10 +16,9 @@ package dal import ( "database/sql" - "log" - "os" "github.com/trim21/errgo" + "go.uber.org/zap" "gorm.io/driver/mysql" "gorm.io/gorm" gormLogger "gorm.io/gorm/logger" @@ -33,7 +32,7 @@ func NewDB(conn *sql.DB, c config.AppConfig) (*gorm.DB, error) { if c.Debug.Gorm { logger.Info("enable gorm debug mode, will log all sql") gLog = gormLogger.New( - log.New(os.Stdout, "\r\n", log.LstdFlags), + logger.StdAt(zap.DebugLevel), gormLogger.Config{ LogLevel: gormLogger.Info, IgnoreRecordNotFoundError: true, diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 29b095083..a8ac30911 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -535,8 +535,8 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model } return r.q.Transaction(func(tx *query.Query) error { - err := tx.DB().WithContext(ctx).Exec(`select interest_type as type, count(interest_type) as total - from chii_subject_interests + err := tx.DB().WithContext(ctx).Exec(` + select interest_type as type, count(interest_type) as total from chii_subject_interests where interest_subject_id = ? group by interest_type `, subjectID).Scan(&counts).Error From 9a3612abf179cd1805a0734a34f89271f1373b20 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 14:05:06 +0800 Subject: [PATCH 124/240] chore: log more data --- internal/collections/infra/mysql_repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index a8ac30911..25ac4a00c 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -524,7 +524,7 @@ func (r mysqlRepo) GetSubjectEpisodesCollection( func (r mysqlRepo) updateSubject(ctx context.Context, subjectID model.SubjectID) { if err := r.reCountSubjectCollection(ctx, subjectID); err != nil { - r.log.Error("failed to update collection counts", zap.Error(err)) + r.log.Error("failed to update collection counts", zap.Error(err), zap.Uint32("subject_id", subjectID)) } } From 6e5ef19d2fcd7c0040475312036ad94b6bd6ff00 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 14:15:07 +0800 Subject: [PATCH 125/240] fix sql --- internal/collections/infra/mysql_repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 25ac4a00c..c325be18f 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -535,7 +535,7 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model } return r.q.Transaction(func(tx *query.Query) error { - err := tx.DB().WithContext(ctx).Exec(` + err := tx.DB().WithContext(ctx).Raw(` select interest_type as type, count(interest_type) as total from chii_subject_interests where interest_subject_id = ? group by interest_type From d947dbb356abeda3c1c78f08b8451e949216837d Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 6 Oct 2024 14:37:14 +0800 Subject: [PATCH 126/240] minor refactor --- internal/collections/infra/mysql_repo.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index c325be18f..51f632247 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -546,7 +546,10 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model var updater = make([]field.AssignExpr, 0, 5) for _, count := range counts { - switch collection.SubjectCollection(count.Type) { //nolint:exhaustive + switch collection.SubjectCollection(count.Type) { + case collection.SubjectCollectionAll: + continue + case collection.SubjectCollectionDropped: updater = append(updater, r.q.Subject.Dropped.Value(count.Total)) From 7c65126da152502d9b15d3983099018b7a583c34 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 7 Oct 2024 20:15:40 +0800 Subject: [PATCH 127/240] fix: filter zero width unicode in tags --- internal/pkg/dam/dam.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/pkg/dam/dam.go b/internal/pkg/dam/dam.go index ac525dabf..2c2ebe24e 100644 --- a/internal/pkg/dam/dam.go +++ b/internal/pkg/dam/dam.go @@ -97,7 +97,7 @@ func AllPrintableChar(text string) bool { return true } -var ZeroWidthPattern = regexp.MustCompile(`\p{Cf}|\p{Cc}|\p{Co}`) +var ZeroWidthPattern = regexp.MustCompile(`[^\t\r\n\p{L}\p{M}\p{N}\p{P}\p{S}\p{Z}]`) var ExtraSpacePattern = regexp.MustCompile("[\u3000 ]") func ValidateTag(t string) bool { @@ -109,6 +109,10 @@ func ValidateTag(t string) bool { return false } + if ZeroWidthPattern.MatchString(t) { + return false + } + if ExtraSpacePattern.MatchString(t) { return false } From 4efaf8e49fa5cfeb92c97741bb293d63338dcdf1 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 7 Oct 2024 20:17:58 +0800 Subject: [PATCH 128/240] fix: filter zero width unicode in tags --- web/req/collection.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/req/collection.go b/web/req/collection.go index c2c6e3606..f715d753c 100644 --- a/web/req/collection.go +++ b/web/req/collection.go @@ -19,6 +19,9 @@ import ( "strings" "unicode/utf8" + "github.com/samber/lo" + "golang.org/x/text/unicode/norm" + "github.com/bangumi/server/internal/collections/domain/collection" "github.com/bangumi/server/internal/pkg/dam" "github.com/bangumi/server/internal/pkg/null" @@ -46,6 +49,10 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { } } + v.Tags = lo.Map(v.Tags, func(item string, index int) string { + return norm.NFKC.String(item) + }) + for _, tag := range v.Tags { if !dam.ValidateTag(tag) { return res.BadRequest(fmt.Sprintf("invalid tag: %q", tag)) @@ -53,11 +60,12 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { } if v.Comment.Set { + v.Comment.Value = norm.NFKC.String(v.Comment.Value) + v.Comment.Value = strings.TrimSpace(v.Comment.Value) if !dam.AllPrintableChar(v.Comment.Value) { return res.BadRequest("invisible character are included in comment") } - v.Comment.Value = strings.TrimSpace(v.Comment.Value) if utf8.RuneCountInString(v.Comment.Value) > 380 { return res.BadRequest("comment too long, only allow less equal than 380 characters") } From 607d1887c9df7eb8c423808845e23b30cd27d740 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 7 Oct 2024 20:22:33 +0800 Subject: [PATCH 129/240] tests: fix --- web/req/collection.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/req/collection.go b/web/req/collection.go index f715d753c..5d86ef65d 100644 --- a/web/req/collection.go +++ b/web/req/collection.go @@ -49,9 +49,11 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { } } - v.Tags = lo.Map(v.Tags, func(item string, index int) string { - return norm.NFKC.String(item) - }) + if v.Tags != nil { + v.Tags = lo.Map(v.Tags, func(item string, index int) string { + return norm.NFKC.String(item) + }) + } for _, tag := range v.Tags { if !dam.ValidateTag(tag) { From aa16d090121c93921bde6dce14d17a7e2c91bfc0 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 7 Oct 2024 20:27:00 +0800 Subject: [PATCH 130/240] fix: dam should match string case insenstive --- internal/pkg/dam/dam.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/internal/pkg/dam/dam.go b/internal/pkg/dam/dam.go index 2c2ebe24e..719577802 100644 --- a/internal/pkg/dam/dam.go +++ b/internal/pkg/dam/dam.go @@ -16,7 +16,6 @@ package dam import ( "regexp" - "strings" "unicode" "github.com/trim21/errgo" @@ -34,21 +33,21 @@ func New(c config.AppConfig) (Dam, error) { var cc Dam var err error if c.NsfwWord != "" { - cc.nsfwWord, err = regexp.Compile(c.NsfwWord) + cc.nsfwWord, err = regexp.Compile("(?i)" + c.NsfwWord) if err != nil { return Dam{}, errgo.Wrap(err, "nsfw_word") } } if c.DisableWords != "" { - cc.disableWord, err = regexp.Compile(c.DisableWords) + cc.disableWord, err = regexp.Compile("(?i)" + c.DisableWords) if err != nil { return Dam{}, errgo.Wrap(err, "disable_words") } } if c.BannedDomain != "" { - cc.bannedDomain, err = regexp.Compile(c.BannedDomain) + cc.bannedDomain, err = regexp.Compile("(?i)" + c.BannedDomain) if err != nil { return Dam{}, errgo.Wrap(err, "banned_domain") } @@ -65,8 +64,6 @@ func (d Dam) NeedReview(text string) bool { return false } - text = strings.ToLower(text) - return d.disableWord.MatchString(text) } From 6bcf1c2d1d353dd75c4d8cd43e12a40e2e2c7cd3 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 8 Oct 2024 22:18:37 +0800 Subject: [PATCH 131/240] fix: only allow len(tag) >= 2 --- web/req/collection.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/req/collection.go b/web/req/collection.go index 5d86ef65d..ae4cc4a30 100644 --- a/web/req/collection.go +++ b/web/req/collection.go @@ -56,6 +56,10 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { } for _, tag := range v.Tags { + if utf8.RuneCountInString(tag) < 2 { + return res.BadRequest("tag 最短为两个字") + } + if !dam.ValidateTag(tag) { return res.BadRequest(fmt.Sprintf("invalid tag: %q", tag)) } From bc39402e35aae3a2c9b9184e063199fa39781b5c Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 8 Oct 2024 22:27:16 +0800 Subject: [PATCH 132/240] tests: fix --- web/handler/user/patch_subject_collection_test.go | 6 +++--- web/handler/user/post_subject_collection_test.go | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/handler/user/patch_subject_collection_test.go b/web/handler/user/patch_subject_collection_test.go index 25c59234d..86c3ab3b2 100644 --- a/web/handler/user/patch_subject_collection_test.go +++ b/web/handler/user/patch_subject_collection_test.go @@ -80,14 +80,14 @@ func TestUser_PatchSubjectCollection(t *testing.T) { "type": 2, "private": true, "rate": 8, - "tags": []string{"q", "vv"}, + "tags": []string{"qq", "vv"}, }). Patch(fmt.Sprintf("/v0/users/-/collections/%d", sid)). ExpectCode(http.StatusNoContent) require.Equal(t, collection.CollectPrivacySelf, s.Privacy()) require.Equal(t, "1 test_content 2", s.Comment()) - require.EqualValues(t, []string{"q", "vv"}, s.Tags()) + require.EqualValues(t, []string{"qq", "vv"}, s.Tags()) require.EqualValues(t, 8, s.Rate()) } @@ -118,7 +118,7 @@ func TestUser_PatchToNonExistsSubjectCollection(t *testing.T) { "type": 1, "private": true, "rate": 8, - "tags": []string{"q", "vv"}, + "tags": []string{"qq", "vv"}, }). Patch(fmt.Sprintf("/v0/users/-/collections/%d", sid)). ExpectCode(http.StatusNotFound) diff --git a/web/handler/user/post_subject_collection_test.go b/web/handler/user/post_subject_collection_test.go index c4a9cb99f..32dc5ea6b 100644 --- a/web/handler/user/post_subject_collection_test.go +++ b/web/handler/user/post_subject_collection_test.go @@ -78,14 +78,14 @@ func TestUser_PostSubjectCollection(t *testing.T) { "type": 2, "private": true, "rate": 8, - "tags": []string{"q", "vv"}, + "tags": []string{"qq", "vv"}, }). Post(fmt.Sprintf("/v0/users/-/collections/%d", sid)). ExpectCode(http.StatusAccepted) require.Equal(t, collection.CollectPrivacySelf, s.Privacy()) require.Equal(t, "1 test_content 2", s.Comment()) - require.EqualValues(t, []string{"q", "vv"}, s.Tags()) + require.EqualValues(t, []string{"qq", "vv"}, s.Tags()) require.EqualValues(t, 8, s.Rate()) } @@ -151,12 +151,12 @@ func TestUser_PostSubjectCollectionPartialData(t *testing.T) { htest.New(t, app). Header(echo.HeaderAuthorization, "Bearer t"). BodyJSON(map[string]any{ - "tags": []string{"q", "vv"}, + "tags": []string{"qq", "vv"}, }). Post(fmt.Sprintf("/v0/users/-/collections/%d", sid)). ExpectCode(http.StatusAccepted) - require.EqualValues(t, []string{"q", "vv"}, s.Tags()) + require.EqualValues(t, []string{"qq", "vv"}, s.Tags()) } func TestUser_PostSubjectCollection_badID(t *testing.T) { From a092c1332501b2ba196ccb943c302420570bca63 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 9 Oct 2024 19:48:06 +0800 Subject: [PATCH 133/240] fix: avoid tag split in to multiple tags by case --- internal/collections/infra/mysql_repo.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 51f632247..af0b2b01f 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -224,12 +224,12 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, } var existsTags = lo.SliceToMap(tags, func(item *dao.TagIndex) (string, bool) { - return item.Name, true + return strings.ToLower(item.Name), true }) var missingTags []string for _, tag := range s.Tags() { - if !existsTags[tag] { + if !existsTags[strings.ToLower(tag)] { missingTags = append(missingTags, tag) } } @@ -282,12 +282,27 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, s model.Subject, relatedTags []string) error { tagIndexs, err := tx.WithContext(ctx).TagIndex.Select(). - Where(tx.TagIndex.Cat.Eq(model.TagCatSubject), tx.TagIndex.Name.In(relatedTags...), - tx.TagIndex.Type.Eq(s.TypeID)).Find() + Where( + tx.TagIndex.Cat.Eq(model.TagCatSubject), + tx.TagIndex.Name.In(relatedTags...), + tx.TagIndex.Type.Eq(s.TypeID), + ).Order(tx.TagIndex.ID.Asc()).Find() if err != nil { return err } + // tag in (...) 操作不区分大小写,使用第一次出现的 tag + // 比如 {name="Galgame"} {name="galgame"} 在过滤后会只保留 {name="Galgame"} + seen := make(map[string]bool) + tagIndexs = lo.Filter(tagIndexs, func(item *dao.TagIndex, index int) bool { + n := strings.ToLower(item.Name) + if seen[n] { + return false + } + seen[n] = true + return true + }) + db := tx.DB().WithContext(ctx) err = db.Exec(` From 3ef1e88817c5865119791b1a72006640e52a2b57 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 9 Oct 2024 19:51:23 +0800 Subject: [PATCH 134/240] ci: force golang version --- .github/workflows/build.yaml | 3 +++ .github/workflows/lint-review.yaml | 3 +++ .github/workflows/lint.yaml | 3 +++ .github/workflows/release-docker.yaml | 3 +++ .github/workflows/release-openapi.yaml | 3 +++ .github/workflows/release.yaml | 3 +++ .github/workflows/test-openapi.yaml | 3 +++ .github/workflows/test.yaml | 3 +++ go.mod | 4 +--- 9 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 204e4058a..c8c0b5006 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,6 +24,9 @@ on: - "**.go.json" - "etc/Dockerfile" +env: + GOTOOLCHAIN: "local" + jobs: docker: runs-on: ubuntu-24.04 diff --git a/.github/workflows/lint-review.yaml b/.github/workflows/lint-review.yaml index 066941984..eba0e7e82 100644 --- a/.github/workflows/lint-review.yaml +++ b/.github/workflows/lint-review.yaml @@ -8,6 +8,9 @@ on: permissions: contents: read +env: + GOTOOLCHAIN: "local" + jobs: lint: runs-on: ubuntu-latest diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 78dce3e58..3ad959c20 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -22,6 +22,9 @@ on: - ".golangci.yaml" - ".github/workflows/lint.yaml" +env: + GOTOOLCHAIN: "local" + jobs: lint: runs-on: ubuntu-24.04 diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index 92499f354..d884e8538 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -10,6 +10,9 @@ on: permissions: packages: write +env: + GOTOOLCHAIN: "local" + jobs: docker: name: "docker" diff --git a/.github/workflows/release-openapi.yaml b/.github/workflows/release-openapi.yaml index 9604a4afc..0b575dddc 100644 --- a/.github/workflows/release-openapi.yaml +++ b/.github/workflows/release-openapi.yaml @@ -6,6 +6,9 @@ on: - "v*.*.*" workflow_dispatch: +env: + GOTOOLCHAIN: "local" + jobs: openapi: runs-on: ubuntu-24.04 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a8d424a6e..dffbf0816 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -5,6 +5,9 @@ on: tags: - "v*.*.*" +env: + GOTOOLCHAIN: "local" + jobs: github: runs-on: ubuntu-24.04 diff --git a/.github/workflows/test-openapi.yaml b/.github/workflows/test-openapi.yaml index e14032bc4..7eb0242c7 100644 --- a/.github/workflows/test-openapi.yaml +++ b/.github/workflows/test-openapi.yaml @@ -18,6 +18,9 @@ on: - "package-lock.json" - ".github/workflows/test-openapi.yaml" +env: + GOTOOLCHAIN: "local" + jobs: test: runs-on: "${{ matrix.os }}" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 7b0cd4321..a469247d5 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -22,6 +22,9 @@ on: - "**.go" - "**.go.json" +env: + GOTOOLCHAIN: "local" + jobs: test: runs-on: ubuntu-24.04 diff --git a/go.mod b/go.mod index 90c13749b..d976e61f7 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/bangumi/server -go 1.22.0 - -toolchain go1.22.6 +go 1.22.6 require ( github.com/avast/retry-go/v4 v4.6.0 From 494b3e936b8c736abfdd7248edacab35bb0b6858 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 9 Oct 2024 20:08:00 +0800 Subject: [PATCH 135/240] fix: only keep sanitized tags in user interest --- internal/collections/infra/mysql_repo.go | 148 +++++++++++------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index af0b2b01f..924b73c74 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "slices" + "sort" "strconv" "strings" "time" @@ -159,30 +160,28 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return errgo.Trace(err) } - if created { - err = errgo.Trace(r.q.SubjectCollection.WithContext(ctx).Clauses(clause.OnConflict{UpdateAll: true}).Create(obj)) - } else { - err = errgo.Trace(r.q.SubjectCollection.WithContext(ctx).Save(obj)) - } - - if err != nil { - return err - } - newTags := slices.Clone(s.Tags()) slices.Sort(newTags) + err = r.q.Transaction(func(tx *query.Query) error { + sanitizedTags, err := r.updateUserTags(ctx, tx, userID, subject, at, s) + if err != nil { + return errgo.Trace(err) + } + + sort.Strings(sanitizedTags) + + obj.Tag = strings.Join(sanitizedTags, " ") + + return errgo.Trace(r.q.SubjectCollection.WithContext(ctx).Clauses(clause.OnConflict{UpdateAll: true}).Create(obj)) + }) + if slices.Equal(relatedTags, newTags) { relatedTags = nil } else { relatedTags = lo.Uniq(append(relatedTags, newTags...)) } - err = r.updateUserTags(ctx, userID, subject, at, s) - if err != nil { - return errgo.Trace(err) - } - if len(relatedTags) != 0 { err = r.q.Transaction(func(tx *query.Query) error { return r.reCountSubjectTags(ctx, tx, subject, relatedTags) @@ -198,84 +197,85 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( //nolint:funlen func (r mysqlRepo) updateUserTags(ctx context.Context, + q *query.Query, userID model.UserID, subject model.Subject, - at time.Time, s *collection.Subject) error { + at time.Time, s *collection.Subject) ([]string, error) { log := r.log.With(zap.Uint32("user_id", userID), zap.Uint32("subject_id", subject.ID)) log.Info("user collections with tags", zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { ss := strconv.Quote(item) return ss[1 : len(ss)-1] }))) - return r.q.Transaction(func(q *query.Query) error { - tx := q.WithContext(ctx) + tx := q.WithContext(ctx) - if (len(s.Tags())) == 0 { - _, err := tx.TagList.Where(q.TagList.UID.Eq(userID), - q.TagList.Mid.Eq(subject.ID), - q.TagList.Cat.Eq(model.TagCatSubject)).Delete() - return errgo.Trace(err) - } + if (len(s.Tags())) == 0 { + _, err := tx.TagList.Where(q.TagList.UID.Eq(userID), + q.TagList.Mid.Eq(subject.ID), + q.TagList.Cat.Eq(model.TagCatSubject)).Delete() + return nil, errgo.Trace(err) + } - tags, err := tx.TagIndex.Select(). - Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), - q.TagIndex.Type.Eq(subject.TypeID)).Find() - if err != nil { - return errgo.Trace(err) - } + tags, err := tx.TagIndex.Select(). + Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), + q.TagIndex.Type.Eq(subject.TypeID)).Find() + if err != nil { + return nil, errgo.Trace(err) + } - var existsTags = lo.SliceToMap(tags, func(item *dao.TagIndex) (string, bool) { - return strings.ToLower(item.Name), true - }) + var existsTags = lo.SliceToMap(tags, func(item *dao.TagIndex) (string, bool) { + return strings.ToLower(item.Name), true + }) - var missingTags []string - for _, tag := range s.Tags() { - if !existsTags[strings.ToLower(tag)] { - missingTags = append(missingTags, tag) - } + var missingTags []string + for _, tag := range s.Tags() { + if !existsTags[strings.ToLower(tag)] { + missingTags = append(missingTags, tag) } + } - if len(missingTags) > 0 { - log.Info("create missing tags", zap.Strings("missing_tags", missingTags)) - err = tx.TagIndex.Create(lo.Map(missingTags, func(item string, index int) *dao.TagIndex { - return &dao.TagIndex{ - Name: item, - Cat: model.TagCatSubject, - Type: subject.TypeID, - Results: 1, - CreatedTime: uint32(at.Unix()), - UpdatedTime: uint32(at.Unix()), - } - })...) - - if err != nil { - return errgo.Trace(err) + if len(missingTags) > 0 { + log.Info("create missing tags", zap.Strings("missing_tags", missingTags)) + err = tx.TagIndex.Create(lo.Map(missingTags, func(item string, index int) *dao.TagIndex { + return &dao.TagIndex{ + Name: item, + Cat: model.TagCatSubject, + Type: subject.TypeID, + Results: 1, + CreatedTime: uint32(at.Unix()), + UpdatedTime: uint32(at.Unix()), } - } + })...) - tags, err = tx.TagIndex.Select(). - Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), - q.TagIndex.Type.Eq(subject.TypeID)).Find() if err != nil { - return errgo.Trace(err) + return nil, errgo.Trace(err) } + } - err = tx.TagList.Clauses(clause.OnConflict{DoNothing: true}). - Create(lo.Map(tags, func(item *dao.TagIndex, index int) *dao.TagList { - return &dao.TagList{ - Tid: item.ID, - UID: s.User(), - Cat: model.TagCatSubject, - Type: subject.TypeID, - Mid: subject.ID, - CreatedTime: uint32(at.Unix()), - } - })...) - if err != nil { - return errgo.Trace(err) - } + tags, err = tx.TagIndex.Select(). + Where(q.TagIndex.Name.In(s.Tags()...), q.TagIndex.Cat.Eq(model.TagCatSubject), + q.TagIndex.Type.Eq(subject.TypeID)).Find() + if err != nil { + return nil, errgo.Trace(err) + } + + err = tx.TagList.Clauses(clause.OnConflict{DoNothing: true}). + Create(lo.Map(tags, func(item *dao.TagIndex, index int) *dao.TagList { + return &dao.TagList{ + Tid: item.ID, + UID: s.User(), + Cat: model.TagCatSubject, + Type: subject.TypeID, + Mid: subject.ID, + CreatedTime: uint32(at.Unix()), + } + })...) + if err != nil { + return nil, errgo.Trace(err) + } - return nil - }) + return lo.Map(tags, func(item *dao.TagIndex, index int) string { + return item.Name + }), nil } //nolint:funlen From 5c70f955fbe133056dc45d48432baeee5b1ab2cc Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 9 Oct 2024 20:12:52 +0800 Subject: [PATCH 136/240] fix lint --- internal/collections/infra/mysql_repo.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 924b73c74..9439102e5 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -164,9 +164,9 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( slices.Sort(newTags) err = r.q.Transaction(func(tx *query.Query) error { - sanitizedTags, err := r.updateUserTags(ctx, tx, userID, subject, at, s) - if err != nil { - return errgo.Trace(err) + sanitizedTags, txErr := r.updateUserTags(ctx, tx, userID, subject, at, s) + if txErr != nil { + return errgo.Trace(txErr) } sort.Strings(sanitizedTags) @@ -175,6 +175,9 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return errgo.Trace(r.q.SubjectCollection.WithContext(ctx).Clauses(clause.OnConflict{UpdateAll: true}).Create(obj)) }) + if err != nil { + return err + } if slices.Equal(relatedTags, newTags) { relatedTags = nil From b09774825b5c9971ba27f01d8fc75d543df79b95 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 10 Oct 2024 02:37:44 +0800 Subject: [PATCH 137/240] chore: remove some debug logging --- internal/collections/infra/mysql_repo.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 9439102e5..55c6562a4 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -21,7 +21,6 @@ import ( "fmt" "slices" "sort" - "strconv" "strings" "time" @@ -203,12 +202,6 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, q *query.Query, userID model.UserID, subject model.Subject, at time.Time, s *collection.Subject) ([]string, error) { - log := r.log.With(zap.Uint32("user_id", userID), zap.Uint32("subject_id", subject.ID)) - log.Info("user collections with tags", zap.Strings("tags", lo.Map(s.Tags(), func(item string, index int) string { - ss := strconv.Quote(item) - return ss[1 : len(ss)-1] - }))) - tx := q.WithContext(ctx) if (len(s.Tags())) == 0 { @@ -237,7 +230,7 @@ func (r mysqlRepo) updateUserTags(ctx context.Context, } if len(missingTags) > 0 { - log.Info("create missing tags", zap.Strings("missing_tags", missingTags)) + r.log.Info("create missing tags", zap.Strings("missing_tags", missingTags)) err = tx.TagIndex.Create(lo.Map(missingTags, func(item string, index int) *dao.TagIndex { return &dao.TagIndex{ Name: item, From 10ec95751e646a2f677616cd62dab305c493058f Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 10 Oct 2024 18:27:21 +0800 Subject: [PATCH 138/240] build: upgrade golang to 1.23.1 --- go.mod | 5 +++-- go.sum | 8 ++++---- internal/collections/infra/mysql_repo_compat.go | 6 ++++-- internal/subject/mysq_repository_compat.go | 8 +++++--- internal/user/model.go | 8 +++++--- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index d976e61f7..c12045895 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/bangumi/server -go 1.22.6 +go 1.23.1 require ( github.com/avast/retry-go/v4 v4.6.0 @@ -27,7 +27,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/trim21/errgo v0.0.3 - github.com/trim21/go-phpserialize v0.0.22 + github.com/trim21/go-phpserialize v0.1.0-alpha.3 github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 @@ -79,6 +79,7 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect + go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect diff --git a/go.sum b/go.sum index 9f5584fa4..018e8d75f 100644 --- a/go.sum +++ b/go.sum @@ -415,8 +415,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trim21/errgo v0.0.3 h1:q0cUPTs+4c5NxByA4f0HUGRvlNyBlUtdxFiTKQdTE68= github.com/trim21/errgo v0.0.3/go.mod h1:AH1KzogdvSkSPXbZq9QAuqSt1L1Eu5W8eYK32zPYv9s= -github.com/trim21/go-phpserialize v0.0.22 h1:gcs36ir5s3iPFtGrp+3uU/R1lO05Et0nuhaBdUahq0Y= -github.com/trim21/go-phpserialize v0.0.22/go.mod h1:BxWksx+mEAaKC+ekgfTHas1z25dEE3n0bZbAp+tsJUM= +github.com/trim21/go-phpserialize v0.1.0-alpha.3 h1:6Z09BQa5Sr3ODyWxOHVHeiGezkIxam2asocjJ2xkfQo= +github.com/trim21/go-phpserialize v0.1.0-alpha.3/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= github.com/trim21/go-redis-prometheus v0.0.0 h1:9svVIZkKaDGE1bSRbtTQdsKBzW+QEWfwc35QIF8JsfA= github.com/trim21/go-redis-prometheus v0.0.0/go.mod h1:UTXPI/fofnsXF9/X/WtvwhAdbSOBVjLg17xDjQj9VgU= github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= @@ -429,8 +429,6 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/volatiletech/null/v9 v9.0.0 h1:JCdlHEiSRVxOi7/MABiEfdsqmuj9oTV20Ao7VvZ0JkE= -github.com/volatiletech/null/v9 v9.0.0/go.mod h1:zRFghPVahaiIMRXiUJrc6gsoG83Cm3ZoAfSTw7VHGQc= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= @@ -461,6 +459,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 h1:lGdhQUN/cnWdSH3291CUuxSEqc+AsGTiDxPP3r2J0l4= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/internal/collections/infra/mysql_repo_compat.go b/internal/collections/infra/mysql_repo_compat.go index bd95aba89..c4c5435d1 100644 --- a/internal/collections/infra/mysql_repo_compat.go +++ b/internal/collections/infra/mysql_repo_compat.go @@ -33,8 +33,10 @@ type mysqlEpCollection map[model.EpisodeID]mysqlEpCollectionItem func deserializePhpEpStatus(phpSerialized []byte) (mysqlEpCollection, error) { var e map[model.EpisodeID]mysqlEpCollectionItem - if err := phpserialize.Unmarshal(phpSerialized, &e); err != nil { - return nil, errgo.Wrap(err, "php deserialize") + if len(phpSerialized) != 0 { + if err := phpserialize.Unmarshal(phpSerialized, &e); err != nil { + return nil, errgo.Wrap(err, "php deserialize") + } } return e, nil diff --git a/internal/subject/mysq_repository_compat.go b/internal/subject/mysq_repository_compat.go index 4f5c203e8..a1d761142 100644 --- a/internal/subject/mysq_repository_compat.go +++ b/internal/subject/mysq_repository_compat.go @@ -30,9 +30,11 @@ type Tag struct { func ParseTags(b []byte) ([]model.Tag, error) { var tags []Tag - err := phpserialize.Unmarshal(b, &tags) - if err != nil { - return nil, errgo.Wrap(err, "ParseTags: phpserialize.Unmarshal") + if len(b) != 0 { + err := phpserialize.Unmarshal(b, &tags) + if err != nil { + return nil, errgo.Wrap(err, "ParseTags: phpserialize.Unmarshal") + } } return slice.MapFilter(tags, func(item Tag) (model.Tag, bool) { diff --git a/internal/user/model.go b/internal/user/model.go index d550b7df2..2ee5e2bbb 100644 --- a/internal/user/model.go +++ b/internal/user/model.go @@ -77,9 +77,11 @@ type PrivacySettings struct { func (settings *PrivacySettings) Unmarshal(s []byte) { rawMap := make(map[PrivacySettingsField]ReceiveFilter, 4) - err := phpserialize.Unmarshal(s, &rawMap) - if err != nil { - return + if len(s) != 0 { + err := phpserialize.Unmarshal(s, &rawMap) + if err != nil { + return + } } settings.ReceivePrivateMessage = rawMap[PrivacyReceivePrivateMessage] From cc05cf2f35d5f1e475fe929945370c47415a5847 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 10 Oct 2024 18:56:57 +0800 Subject: [PATCH 139/240] fix: only allow at most 10 tags --- web/req/collection.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/req/collection.go b/web/req/collection.go index ae4cc4a30..f0e5d6aac 100644 --- a/web/req/collection.go +++ b/web/req/collection.go @@ -50,6 +50,10 @@ func (v *SubjectEpisodeCollectionPatch) Validate() error { } if v.Tags != nil { + if len(v.Tags) > 10 { + return res.BadRequest("最多允许 10 个标签") + } + v.Tags = lo.Map(v.Tags, func(item string, index int) string { return norm.NFKC.String(item) }) From 25fbccdff556cf92e9fa8c8762a0f12ef690b937 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 10 Oct 2024 19:43:40 +0800 Subject: [PATCH 140/240] style: upgrade linter --- .github/workflows/lint.yaml | 2 +- .golangci.yaml | 24 +++++++------------ internal/collections/infra/mysql_repo_test.go | 4 ++-- internal/index/mysql_repository_test.go | 10 ++++---- internal/pkg/generic/set/set_test.go | 1 - pkg/duration/duration_test.go | 1 - pkg/wiki/spec_test.go | 1 - web/handler/character/character_test.go | 1 - web/handler/person/person_test.go | 1 - web/handler/revision_test.go | 2 -- web/handler/subject/get_test.go | 2 -- web/handler/user/user_test.go | 1 - web/req/auth_test.go | 2 -- 13 files changed, 16 insertions(+), 36 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 3ad959c20..8cf84936b 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -53,4 +53,4 @@ jobs: - name: Run linters uses: golangci/golangci-lint-action@v6 with: - version: v1.59.1 + version: v1.61.0 diff --git a/.golangci.yaml b/.golangci.yaml index f1be719f4..380125165 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -18,9 +18,7 @@ run: # If false (default) - golangci-lint acquires file lock on start. allow-parallel-runners: true - skip-files: [] - - go: "1.22" + go: "1.23" # output configuration options output: @@ -106,8 +104,6 @@ linters-settings: - standard # Captures all standard packages if they do not match another section. - default # Contains all imports that could not be matched to another section type. - prefix(github.com/bangumi/server) # Groups all imports with the specified Prefix. - sectionSeparators: - - newLine depguard: rules: @@ -141,8 +137,8 @@ linters-settings: - operation - return - assign - ignored-functions: strconv\..*,time\..*,make,math\..*,strings\..* - ignored-numbers: 1,2,3,10,100,1000,10000 + ignored-functions: [strconv\..*, time\..*, make, math\..*, strings\..*] + ignored-numbers: ["1", "2", "3", "10", "100", "1000", "10000"] gosimple: # Select the Go version to target. The default is '1.13'. @@ -181,7 +177,7 @@ linters-settings: checks: ["all"] stylecheck: - # Select the Go version to target. The default is '1.13'. + # Select the Go version to target. The default is '1.13'. testpackage: # regexp pattern to skip files @@ -203,12 +199,9 @@ linters-settings: nlreturn: block-size: 3 - ifshort: - # Maximum length of vars declaration measured in number of lines, after which linter won't suggest using short syntax. - # Has higher priority than max-decl-chars. - max-decl-lines: 1 - # Maximum length of vars declaration measured in number of characters, after which linter won't suggest using short syntax. - max-decl-chars: 30 + gosec: + excludes: + - G115 tagliatelle: # Check the struck tag name case. @@ -236,8 +229,9 @@ linters: - errchkjson - errname - errorlint + # https://github.com/golangci/golangci-lint/issues/5065 - exhaustive - - exportloopref + - copyloopvar - forbidigo - forcetypeassert - funlen diff --git a/internal/collections/infra/mysql_repo_test.go b/internal/collections/infra/mysql_repo_test.go index 923230929..b464faee7 100644 --- a/internal/collections/infra/mysql_repo_test.go +++ b/internal/collections/infra/mysql_repo_test.go @@ -143,12 +143,12 @@ func TestMysqlRepo_ListSubjectCollection(t *testing.T) { require.NoError(t, err) } - for i := 0; i < 2; i++ { + for i := uint32(0); i < 2; i++ { err = q.SubjectCollection. WithContext(context.Background()). Create(&dao.SubjectCollection{ UserID: uid, - SubjectID: model.SubjectID(200 + i), + SubjectID: 200 + i, SubjectType: model.SubjectTypeGame, UpdatedTime: uint32(time.Now().Unix()), }) diff --git a/internal/index/mysql_repository_test.go b/internal/index/mysql_repository_test.go index 2aef0a569..d57e2b288 100644 --- a/internal/index/mysql_repository_test.go +++ b/internal/index/mysql_repository_test.go @@ -189,9 +189,8 @@ func TestMysqlRepo_DeleteIndex2(t *testing.T) { err := repo.New(ctx, index) require.NoError(t, err) - for i := 10; i < 20; i++ { - _, err = repo.AddOrUpdateIndexSubject(ctx, index.ID, model.SubjectID(i), - uint32(i), fmt.Sprintf("comment %d", i)) + for i := uint32(10); i < 20; i++ { + _, err = repo.AddOrUpdateIndexSubject(ctx, index.ID, i, i, fmt.Sprintf("comment %d", i)) require.NoError(t, err) } @@ -292,9 +291,8 @@ func TestMysqlRepo_DeleteIndexSubject(t *testing.T) { require.NotEqual(t, 0, index.ID) require.NoError(t, err) - for i := 10; i < 20; i++ { - _, err = repo.AddOrUpdateIndexSubject(ctx, index.ID, model.SubjectID(i), - uint32(i), fmt.Sprintf("comment %d", i)) + for i := uint32(10); i < 20; i++ { + _, err = repo.AddOrUpdateIndexSubject(ctx, index.ID, i, i, fmt.Sprintf("comment %d", i)) require.NoError(t, err) } diff --git a/internal/pkg/generic/set/set_test.go b/internal/pkg/generic/set/set_test.go index 5c8034303..cad2a3b41 100644 --- a/internal/pkg/generic/set/set_test.go +++ b/internal/pkg/generic/set/set_test.go @@ -43,7 +43,6 @@ func TestFromSlice(t *testing.T) { {"init without values", []string{}}, } for _, tc := range testcases { - tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() s := set.FromSlice[string](tc.input) diff --git a/pkg/duration/duration_test.go b/pkg/duration/duration_test.go index 3f87e5cd6..a05a2014e 100644 --- a/pkg/duration/duration_test.go +++ b/pkg/duration/duration_test.go @@ -64,7 +64,6 @@ func TestParse(t *testing.T) { } for _, tc := range testcases { - tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() actual, err := duration.Parse(tc.Input) diff --git a/pkg/wiki/spec_test.go b/pkg/wiki/spec_test.go index e3c9c0f0b..c030c4b5d 100644 --- a/pkg/wiki/spec_test.go +++ b/pkg/wiki/spec_test.go @@ -88,7 +88,6 @@ func TestAgainstInvalidSpec(t *testing.T) { for _, file := range files { // name := file.Name() - file := file t.Run(file.Name(), func(t *testing.T) { t.Parallel() raw, err := os.ReadFile(filepath.Join(caseRoot, file.Name())) diff --git a/web/handler/character/character_test.go b/web/handler/character/character_test.go index 305c2b06a..ddf5cff3d 100644 --- a/web/handler/character/character_test.go +++ b/web/handler/character/character_test.go @@ -92,7 +92,6 @@ func TestCharacter_GetImage(t *testing.T) { app := test.GetWebApp(t, test.Mock{CharacterRepo: m}) for _, imageType := range []string{"large", "grid", "medium", "small"} { - imageType := imageType t.Run(imageType, func(t *testing.T) { t.Parallel() diff --git a/web/handler/person/person_test.go b/web/handler/person/person_test.go index 64dd45f24..073e5b00f 100644 --- a/web/handler/person/person_test.go +++ b/web/handler/person/person_test.go @@ -61,7 +61,6 @@ func TestPerson_GetImage(t *testing.T) { app := test.GetWebApp(t, test.Mock{PersonRepo: m}) for _, imageType := range []string{"small", "grid", "large", "medium"} { - imageType := imageType t.Run(imageType, func(t *testing.T) { t.Parallel() diff --git a/web/handler/revision_test.go b/web/handler/revision_test.go index 13c54d233..88690293d 100644 --- a/web/handler/revision_test.go +++ b/web/handler/revision_test.go @@ -62,7 +62,6 @@ func TestHandler_ListPersonRevision_Bad_ID(t *testing.T) { badIDs := []string{"-1", "a", "0"} for _, id := range badIDs { - id := id t.Run(id, func(t *testing.T) { t.Parallel() @@ -122,7 +121,6 @@ func TestHandler_ListSubjectRevision_Bad_ID(t *testing.T) { badIDs := []string{"-1", "a", "0"} for _, id := range badIDs { - id := id t.Run(id, func(t *testing.T) { t.Parallel() diff --git a/web/handler/subject/get_test.go b/web/handler/subject/get_test.go index 8f9b1fc91..a5a520450 100644 --- a/web/handler/subject/get_test.go +++ b/web/handler/subject/get_test.go @@ -134,7 +134,6 @@ func TestSubject_Get_bad_id(t *testing.T) { app := test.GetWebApp(t, test.Mock{SubjectRepo: m}) for _, path := range []string{"/v0/subjects/0", "/v0/subjects/-1", "/v0/subjects/a"} { - path := path t.Run(path, func(t *testing.T) { t.Parallel() @@ -154,7 +153,6 @@ func TestSubject_GetImage_302(t *testing.T) { app := test.GetWebApp(t, test.Mock{SubjectRepo: m}) for _, imageType := range []string{"small", "grid", "large", "medium", "common"} { - imageType := imageType t.Run(imageType, func(t *testing.T) { t.Parallel() diff --git a/web/handler/user/user_test.go b/web/handler/user/user_test.go index 87fdc7122..9201023cf 100644 --- a/web/handler/user/user_test.go +++ b/web/handler/user/user_test.go @@ -101,7 +101,6 @@ func TestUser_GetAvatar_302(t *testing.T) { app := test.GetWebApp(t, test.Mock{UserRepo: m}) for _, imageType := range []string{"large", "medium", "small"} { - imageType := imageType t.Run(imageType, func(t *testing.T) { t.Parallel() diff --git a/web/req/auth_test.go b/web/req/auth_test.go index 2cb9fedda..d519d114f 100644 --- a/web/req/auth_test.go +++ b/web/req/auth_test.go @@ -32,7 +32,6 @@ func TestLoginPass(t *testing.T) { } validate := validator.New() for i, login := range testCase { - login := login t.Run(fmt.Sprintf("success %d", i), func(t *testing.T) { t.Parallel() require.NoError(t, validate.Struct(login)) @@ -50,7 +49,6 @@ func TestLoginErr(t *testing.T) { } validate := validator.New() for i, login := range testCase { - login := login t.Run(fmt.Sprintf("fail %d", i), func(t *testing.T) { t.Parallel() require.Error(t, validate.Struct(login)) From 0fc9d551d9f198c4776b8a3c10b4f6e3f24adb8f Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 10 Oct 2024 20:16:45 +0800 Subject: [PATCH 141/240] build: upgrade aws sdk to v2 (#643) --- canal/event.go | 6 ++--- canal/on_user.go | 55 +++++++++++++++++++++------------------ go.mod | 14 ++++++++-- go.sum | 33 ++++++++++++++++------- internal/pkg/driver/s3.go | 26 +++++++----------- 5 files changed, 79 insertions(+), 55 deletions(-) diff --git a/canal/event.go b/canal/event.go index f880b784e..fec87c3d2 100644 --- a/canal/event.go +++ b/canal/event.go @@ -19,7 +19,7 @@ import ( "encoding/json" "sync/atomic" - "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/redis/go-redis/v9" "github.com/trim21/errgo" "go.uber.org/zap" @@ -38,7 +38,7 @@ func newEventHandler( redis *redis.Client, stream Stream, search search.Client, - s3 *s3.S3, + s3 *s3.Client, ) *eventHandler { return &eventHandler{ redis: redis, @@ -58,7 +58,7 @@ type eventHandler struct { log *zap.Logger search search.Client stream Stream - s3 *s3.S3 // optional, check nil before use + s3 *s3.Client // optional, check nil before use redis *redis.Client } diff --git a/canal/on_user.go b/canal/on_user.go index da16f7b7a..27c5af9b1 100644 --- a/canal/on_user.go +++ b/canal/on_user.go @@ -20,8 +20,10 @@ import ( "encoding/json" "fmt" "strings" + "time" - "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/samber/lo" "github.com/trim21/errgo" "go.uber.org/zap" @@ -91,34 +93,37 @@ func (e *eventHandler) clearImageCache(avatar string) { e.log.Debug("clear image for prefix", zap.String("avatar", avatar), zap.String("prefix", p)) - err := e.s3.ListObjectsV2PagesWithContext(context.Background(), - &s3.ListObjectsV2Input{Bucket: &e.config.S3ImageResizeBucket, Prefix: &p}, - func(output *s3.ListObjectsV2Output, b bool) bool { - if len(output.Contents) == 0 { - return false - } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() - _, err := e.s3.DeleteObjects(&s3.DeleteObjectsInput{ - Bucket: &e.config.S3ImageResizeBucket, - Delete: &s3.Delete{ - Objects: lo.Map(output.Contents, func(item *s3.Object, index int) *s3.ObjectIdentifier { - return &s3.ObjectIdentifier{ - Key: item.Key, - } - }), - }, - }) + pages := s3.NewListObjectsV2Paginator( + e.s3, + &s3.ListObjectsV2Input{Bucket: &e.config.S3ImageResizeBucket, Prefix: &p}, + ) - if err != nil { - e.log.Error("failed to clear s3 cached image", zap.Error(err)) - } + for pages.HasMorePages() { + output, err := pages.NextPage(ctx) + if err != nil { + break + } - return true - }, - ) + if len(output.Contents) == 0 { + break + } - if err != nil { - e.log.Error("failed to clear s3 cached image", zap.Error(err)) + _, err = e.s3.DeleteObjects(ctx, &s3.DeleteObjectsInput{ + Bucket: &e.config.S3ImageResizeBucket, + Delete: &types.Delete{ + Objects: lo.Map(output.Contents, func(item types.Object, index int) types.ObjectIdentifier { + return types.ObjectIdentifier{ + Key: item.Key, + } + }), + }, + }) + if err != nil { + e.log.Error("failed to clear s3 cached image", zap.Error(err)) + } } } diff --git a/go.mod b/go.mod index c12045895..d30917dd9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,9 @@ go 1.23.1 require ( github.com/avast/retry-go/v4 v4.6.0 - github.com/aws/aws-sdk-go v1.55.5 + github.com/aws/aws-sdk-go-v2 v1.32.2 + github.com/aws/aws-sdk-go-v2/credentials v1.17.41 + github.com/aws/aws-sdk-go-v2/service/s3 v1.65.2 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 @@ -49,6 +51,15 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect + github.com/aws/smithy-go v1.22.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -60,7 +71,6 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.10 // indirect diff --git a/go.sum b/go.sum index 018e8d75f..b08d60829 100644 --- a/go.sum +++ b/go.sum @@ -26,9 +26,31 @@ github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinR github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= +github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.2 h1:yi8m+jepdp6foK14xXLGkYBenxnlcfJ45ka4Pg7fDSQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.2/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= +github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= +github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -203,10 +225,6 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -644,10 +662,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/pkg/driver/s3.go b/internal/pkg/driver/s3.go index 97499fe68..84a943349 100644 --- a/internal/pkg/driver/s3.go +++ b/internal/pkg/driver/s3.go @@ -15,30 +15,24 @@ package driver import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/s3" - "github.com/samber/lo" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/bangumi/server/config" ) -func NewS3(c config.AppConfig) (*s3.S3, error) { +func NewS3(c config.AppConfig) (*s3.Client, error) { if c.S3EntryPoint == "" { return nil, nil //nolint:nilnil } - cred := credentials.NewStaticCredentials(c.S3AccessKey, c.S3SecretKey, "") - s := lo.Must(session.NewSession(&aws.Config{ - Credentials: cred, - Endpoint: &c.S3EntryPoint, - Region: lo.ToPtr("us-east-1"), - DisableSSL: lo.ToPtr(true), - S3ForcePathStyle: lo.ToPtr(true), - })) - - svc := s3.New(s) + svc := s3.New(s3.Options{ + BaseEndpoint: aws.String(c.S3EntryPoint), + Region: "us-east-1", + UsePathStyle: true, + Credentials: credentials.NewStaticCredentialsProvider(c.S3AccessKey, c.S3SecretKey, ""), + }) return svc, nil } From 5547fca7eea625775adf3b7e936e227cc2d895af Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 11 Oct 2024 01:05:20 +0800 Subject: [PATCH 142/240] fix: api rate --- internal/collections/infra/mysql_repo.go | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 55c6562a4..bbe3d3411 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -155,6 +155,8 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( return errgo.Trace(err) } + originalCollection := *obj + if err = r.updateSubjectCollection(obj, &original, s, at, ip, created); err != nil { return errgo.Trace(err) } @@ -194,6 +196,11 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( } r.updateSubject(ctx, subject.ID) + + if obj.Rate != originalCollection.Rate { + r.reCountSubjectRate(ctx, subject.ID, originalCollection.Rate, obj.Rate) + } + return nil } @@ -587,6 +594,59 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model }) } +func (r mysqlRepo) reCountSubjectRate(ctx context.Context, subjectID model.SubjectID, before uint8, after uint8) error { + var counts []struct { + Rate uint8 `gorm:"rate"` + Total uint32 `gorm:"total"` + } + + return r.q.Transaction(func(tx *query.Query) error { + err := tx.DB().WithContext(ctx).Raw(` + select interest_rate as rate, count(interest_rate) as total from chii_subject_interests + where interest_subject_id = ? and interest_private = 0 and interest_rate != 0 and ((interest_rate = ?) or (interest_rate = ?)) + group by interest_rate + `, subjectID, before, after).Scan(&counts).Error + if err != nil { + return errgo.Wrap(err, "dal") + } + + var updater = make([]field.AssignExpr, 0, 2) + for _, count := range counts { + switch count.Rate { + case 0: + continue + case 1: + updater = append(updater, tx.SubjectField.Rate1.Value(count.Total)) + case 2: + updater = append(updater, tx.SubjectField.Rate2.Value(count.Total)) + case 3: + updater = append(updater, tx.SubjectField.Rate3.Value(count.Total)) + case 4: + updater = append(updater, tx.SubjectField.Rate4.Value(count.Total)) + case 5: + updater = append(updater, tx.SubjectField.Rate5.Value(count.Total)) + case 6: + updater = append(updater, tx.SubjectField.Rate6.Value(count.Total)) + case 7: + updater = append(updater, tx.SubjectField.Rate7.Value(count.Total)) + case 8: + updater = append(updater, tx.SubjectField.Rate8.Value(count.Total)) + case 9: + updater = append(updater, tx.SubjectField.Rate9.Value(count.Total)) + case 10: + updater = append(updater, tx.SubjectField.Rate10.Value(count.Total)) + } + } + + _, err = tx.SubjectField.WithContext(ctx).Where(r.q.SubjectField.Sid.Eq(subjectID)).UpdateSimple(updater...) + if err != nil { + return errgo.Wrap(err, "dal") + } + + return nil + }) +} + func (r mysqlRepo) updateCollectionTime(obj *dao.SubjectCollection, t collection.SubjectCollection, at time.Time) error { switch t { From 829414391bc51ef12cc98c592d79e5ccfaaafa65 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 11 Oct 2024 01:10:44 +0800 Subject: [PATCH 143/240] fix lint --- Taskfile.yaml | 2 +- internal/collections/infra/mysql_repo.go | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index ff17b7a14..4b0ddcc49 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -35,7 +35,7 @@ tasks: silent: true desc: Run 'golangci-lint' cmds: - - golangci-lint run --fix + - golangci-lint --path-prefix "{{ .USER_WORKING_DIR }}" run --fix test: desc: Run mocked tests, need nothing. diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index bbe3d3411..963a089bf 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -198,7 +198,9 @@ func (r mysqlRepo) updateOrCreateSubjectCollection( r.updateSubject(ctx, subject.ID) if obj.Rate != originalCollection.Rate { - r.reCountSubjectRate(ctx, subject.ID, originalCollection.Rate, obj.Rate) + if err := r.reCountSubjectRate(ctx, subject.ID, originalCollection.Rate, obj.Rate); err != nil { + r.log.Error("failed to update collection counts", zap.Error(err), zap.Uint32("subject_id", subject.ID)) + } } return nil @@ -594,6 +596,7 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model }) } +//nolint:mnd func (r mysqlRepo) reCountSubjectRate(ctx context.Context, subjectID model.SubjectID, before uint8, after uint8) error { var counts []struct { Rate uint8 `gorm:"rate"` @@ -603,7 +606,9 @@ func (r mysqlRepo) reCountSubjectRate(ctx context.Context, subjectID model.Subje return r.q.Transaction(func(tx *query.Query) error { err := tx.DB().WithContext(ctx).Raw(` select interest_rate as rate, count(interest_rate) as total from chii_subject_interests - where interest_subject_id = ? and interest_private = 0 and interest_rate != 0 and ((interest_rate = ?) or (interest_rate = ?)) + where interest_subject_id = ? and + interest_private = 0 and + interest_rate != 0 and ((interest_rate = ?) or (interest_rate = ?)) group by interest_rate `, subjectID, before, after).Scan(&counts).Error if err != nil { From dd0be27b621c1bd35b58324975033f6d50ffd364 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 11 Oct 2024 01:20:58 +0800 Subject: [PATCH 144/240] fix: api rate --- internal/collections/infra/mysql_repo.go | 57 ++++++++++++------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index 963a089bf..b1cd567ef 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -596,54 +596,55 @@ func (r mysqlRepo) reCountSubjectCollection(ctx context.Context, subjectID model }) } -//nolint:mnd +//nolint:mnd,gocyclo func (r mysqlRepo) reCountSubjectRate(ctx context.Context, subjectID model.SubjectID, before uint8, after uint8) error { - var counts []struct { - Rate uint8 `gorm:"rate"` - Total uint32 `gorm:"total"` - } - return r.q.Transaction(func(tx *query.Query) error { - err := tx.DB().WithContext(ctx).Raw(` - select interest_rate as rate, count(interest_rate) as total from chii_subject_interests - where interest_subject_id = ? and - interest_private = 0 and - interest_rate != 0 and ((interest_rate = ?) or (interest_rate = ?)) - group by interest_rate - `, subjectID, before, after).Scan(&counts).Error - if err != nil { - return errgo.Wrap(err, "dal") + var counts = make(map[uint8]uint32, 2) + + for _, rate := range []uint8{before, after} { + var count uint32 + if rate != 0 { + err := tx.DB().WithContext(ctx).Raw(` + select count(*) from chii_subject_interests + where interest_subject_id = ? and interest_private = 0 and interest_rate = ? + `, subjectID, rate).Scan(&count).Error + if err != nil { + return errgo.Wrap(err, "dal") + } + + counts[rate] = count + } } var updater = make([]field.AssignExpr, 0, 2) - for _, count := range counts { - switch count.Rate { + for rate, total := range counts { + switch rate { case 0: continue case 1: - updater = append(updater, tx.SubjectField.Rate1.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate1.Value(total)) case 2: - updater = append(updater, tx.SubjectField.Rate2.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate2.Value(total)) case 3: - updater = append(updater, tx.SubjectField.Rate3.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate3.Value(total)) case 4: - updater = append(updater, tx.SubjectField.Rate4.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate4.Value(total)) case 5: - updater = append(updater, tx.SubjectField.Rate5.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate5.Value(total)) case 6: - updater = append(updater, tx.SubjectField.Rate6.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate6.Value(total)) case 7: - updater = append(updater, tx.SubjectField.Rate7.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate7.Value(total)) case 8: - updater = append(updater, tx.SubjectField.Rate8.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate8.Value(total)) case 9: - updater = append(updater, tx.SubjectField.Rate9.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate9.Value(total)) case 10: - updater = append(updater, tx.SubjectField.Rate10.Value(count.Total)) + updater = append(updater, tx.SubjectField.Rate10.Value(total)) } } - _, err = tx.SubjectField.WithContext(ctx).Where(r.q.SubjectField.Sid.Eq(subjectID)).UpdateSimple(updater...) + _, err := tx.SubjectField.WithContext(ctx).Where(r.q.SubjectField.Sid.Eq(subjectID)).UpdateSimple(updater...) if err != nil { return errgo.Wrap(err, "dal") } From cf9d301e3de61bfc56f6abce09d4430d7d45655d Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 11 Oct 2024 01:35:43 +0800 Subject: [PATCH 145/240] chore: improve lint output --- Taskfile.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 4b0ddcc49..e1a2d3317 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -35,7 +35,7 @@ tasks: silent: true desc: Run 'golangci-lint' cmds: - - golangci-lint --path-prefix "{{ .USER_WORKING_DIR }}" run --fix + - golangci-lint --path-prefix "{{ .TASKFILE_DIR }}" run --fix test: desc: Run mocked tests, need nothing. From 2d534b5f26c1e3a709d98e0c1101e18f6ee20ccc Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 11 Oct 2024 03:16:09 +0800 Subject: [PATCH 146/240] fix: ignore episode record exists --- internal/collections/infra/mysql_repo.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index b1cd567ef..a408e44ce 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -880,7 +880,8 @@ func (r mysqlRepo) createEpisodeCollection( } table := r.q.EpCollection - err = table.WithContext(ctx).Where(table.UserID.Eq(userID), table.SubjectID.Eq(subjectID)).Create(&dao.EpCollection{ + err = table.WithContext(ctx).Clauses(clause.OnConflict{DoNothing: true}). + Where(table.UserID.Eq(userID), table.SubjectID.Eq(subjectID)).Create(&dao.EpCollection{ UserID: userID, SubjectID: subjectID, Status: bytes, From 6ad7015d57d964d6e9d50abd9fa6348e8be41acb Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 19:08:36 +0800 Subject: [PATCH 147/240] build: keep debug info --- Taskfile.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index e1a2d3317..c27514bbe 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -27,7 +27,7 @@ tasks: generates: - ./dist/chii.exe cmds: - - go build -ldflags '-w -s' -trimpath -o dist/chii.exe main.go + - go build -trimpath -o dist/chii.exe main.go env: CGO_ENABLED: "0" From 66b6fd44f73f3585aaa603b269db298482dc29bf Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 19:42:45 +0800 Subject: [PATCH 148/240] build: upgrade go to 1.23.2 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d30917dd9..72498f820 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/bangumi/server -go 1.23.1 +go 1.23.2 require ( github.com/avast/retry-go/v4 v4.6.0 From d4b056fd3271600d7098c100e21954bb298d9858 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 20:23:13 +0800 Subject: [PATCH 149/240] fix: add debug router --- web/new.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/new.go b/web/new.go index c532821fb..c229bf6ef 100644 --- a/web/new.go +++ b/web/new.go @@ -19,6 +19,7 @@ import ( "fmt" "net" "net/http" + "net/http/pprof" "strconv" "strings" "time" @@ -107,6 +108,11 @@ func New() *echo.Echo { app.Use(recovery.New()) app.GET("/metrics", echo.WrapHandler(promhttp.Handler())) + app.GET("/debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(pprof.Cmdline))) + app.GET("/debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(pprof.Profile))) + app.GET("/debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(pprof.Symbol))) + app.GET("/debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(pprof.Trace))) + app.GET("/debug/pprof/*", echo.WrapHandler(http.HandlerFunc(pprof.Index))) addProfile(app) From d74ce3b1ce00b2cc1898524795d7d5b402a2d958 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 20:26:20 +0800 Subject: [PATCH 150/240] build: upgrade go-phpserialize --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 72498f820..0f785e04f 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/trim21/errgo v0.0.3 - github.com/trim21/go-phpserialize v0.1.0-alpha.3 + github.com/trim21/go-phpserialize v0.1.0-alpha.4 github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 diff --git a/go.sum b/go.sum index b08d60829..0fc70cb59 100644 --- a/go.sum +++ b/go.sum @@ -433,8 +433,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trim21/errgo v0.0.3 h1:q0cUPTs+4c5NxByA4f0HUGRvlNyBlUtdxFiTKQdTE68= github.com/trim21/errgo v0.0.3/go.mod h1:AH1KzogdvSkSPXbZq9QAuqSt1L1Eu5W8eYK32zPYv9s= -github.com/trim21/go-phpserialize v0.1.0-alpha.3 h1:6Z09BQa5Sr3ODyWxOHVHeiGezkIxam2asocjJ2xkfQo= -github.com/trim21/go-phpserialize v0.1.0-alpha.3/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= +github.com/trim21/go-phpserialize v0.1.0-alpha.4 h1:ZFeFZ1F1NE1CTPCO4RpY8N4RVjGsCxhc4K3P655n8Ag= +github.com/trim21/go-phpserialize v0.1.0-alpha.4/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= github.com/trim21/go-redis-prometheus v0.0.0 h1:9svVIZkKaDGE1bSRbtTQdsKBzW+QEWfwc35QIF8JsfA= github.com/trim21/go-redis-prometheus v0.0.0/go.mod h1:UTXPI/fofnsXF9/X/WtvwhAdbSOBVjLg17xDjQj9VgU= github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= From c39782fe7344a17819c4f37956f7006c6b8ed4d3 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 20:33:01 +0800 Subject: [PATCH 151/240] build: upgrade go-phpserialize --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0f785e04f..fc6cda2e4 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/trim21/errgo v0.0.3 - github.com/trim21/go-phpserialize v0.1.0-alpha.4 + github.com/trim21/go-phpserialize v0.1.0-alpha.5 github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 diff --git a/go.sum b/go.sum index 0fc70cb59..1c37f8fd3 100644 --- a/go.sum +++ b/go.sum @@ -433,8 +433,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trim21/errgo v0.0.3 h1:q0cUPTs+4c5NxByA4f0HUGRvlNyBlUtdxFiTKQdTE68= github.com/trim21/errgo v0.0.3/go.mod h1:AH1KzogdvSkSPXbZq9QAuqSt1L1Eu5W8eYK32zPYv9s= -github.com/trim21/go-phpserialize v0.1.0-alpha.4 h1:ZFeFZ1F1NE1CTPCO4RpY8N4RVjGsCxhc4K3P655n8Ag= -github.com/trim21/go-phpserialize v0.1.0-alpha.4/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= +github.com/trim21/go-phpserialize v0.1.0-alpha.5 h1:bMsUpfwAgPggQzDKdafNBvkPWDCMfzlvH30MWzI/SYg= +github.com/trim21/go-phpserialize v0.1.0-alpha.5/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= github.com/trim21/go-redis-prometheus v0.0.0 h1:9svVIZkKaDGE1bSRbtTQdsKBzW+QEWfwc35QIF8JsfA= github.com/trim21/go-redis-prometheus v0.0.0/go.mod h1:UTXPI/fofnsXF9/X/WtvwhAdbSOBVjLg17xDjQj9VgU= github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= From 75865250ff55600c8f8b857067b9cf323d4fd8f4 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 23:30:55 +0800 Subject: [PATCH 152/240] ci: enable openapi again --- .github/workflows/release-openapi.yaml | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release-openapi.yaml b/.github/workflows/release-openapi.yaml index 0b575dddc..df1529d92 100644 --- a/.github/workflows/release-openapi.yaml +++ b/.github/workflows/release-openapi.yaml @@ -2,8 +2,8 @@ name: Release(openapi) on: push: - tags: - - "v*.*.*" + branches: + - master workflow_dispatch: env: @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 16 + node-version: 20 - run: npm ci - run: npm run build @@ -42,13 +42,14 @@ jobs: with: repository: "bangumi/dev-docs" path: dev-docs -# - run: cp ./dist/private.yaml ./dev-docs/api.yaml -# - name: Create Pull Request -# uses: peter-evans/create-pull-request@v4 -# with: -# path: dev-docs -# token: ${{ secrets.PAT }} -# title: Update Openapi Specification from bangumi/server -# push-to-fork: Trim21-bot/dev-docs -# branch: "update-upstream" -# author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" + + - run: cp ./dist/private.yaml ./dev-docs/api.yaml + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4 + with: + path: dev-docs + token: ${{ secrets.PAT }} + title: Update Openapi Specification from bangumi/server + push-to-fork: Trim21-bot/dev-docs + branch: "update-upstream" + author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" From 1cb1a6d3e3dba1797b1a750a96fa4b5e9a8cb7df Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 12 Oct 2024 23:32:30 +0800 Subject: [PATCH 153/240] ci: fix openapi --- .github/workflows/release-openapi.yaml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/workflows/release-openapi.yaml b/.github/workflows/release-openapi.yaml index df1529d92..aa78ef435 100644 --- a/.github/workflows/release-openapi.yaml +++ b/.github/workflows/release-openapi.yaml @@ -37,19 +37,3 @@ jobs: push-to-fork: Trim21-bot/api branch: "update-upstream" author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" - - - uses: actions/checkout@v4 - with: - repository: "bangumi/dev-docs" - path: dev-docs - - - run: cp ./dist/private.yaml ./dev-docs/api.yaml - - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 - with: - path: dev-docs - token: ${{ secrets.PAT }} - title: Update Openapi Specification from bangumi/server - push-to-fork: Trim21-bot/dev-docs - branch: "update-upstream" - author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" From 760f316b51505749cfe9c5efec9ef579f786a50e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:09:06 +0800 Subject: [PATCH 154/240] build(deps): update dependency @apidevtools/json-schema-ref-parser to ^11.7.2 (#644) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 859cecfca..146a2750f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "chii", "version": "0.34.0", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.7.0", + "@apidevtools/json-schema-ref-parser": "^11.7.2", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, @@ -19,9 +19,9 @@ } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", - "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", + "version": "11.7.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz", + "integrity": "sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==", "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -444,9 +444,9 @@ }, "dependencies": { "@apidevtools/json-schema-ref-parser": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", - "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", + "version": "11.7.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz", + "integrity": "sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==", "requires": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", diff --git a/package.json b/package.json index 710d89354..812c53117 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "printWidth": 120 }, "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.7.0", + "@apidevtools/json-schema-ref-parser": "^11.7.2", "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, From 9f7e7d5acaccc3afb1cfa517efbae16a1a2c27a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:09:47 +0800 Subject: [PATCH 155/240] build(deps): update module github.com/aws/aws-sdk-go-v2/service/s3 to v1.65.3 (#645) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fc6cda2e4..497c44898 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/avast/retry-go/v4 v4.6.0 github.com/aws/aws-sdk-go-v2 v1.32.2 github.com/aws/aws-sdk-go-v2/credentials v1.17.41 - github.com/aws/aws-sdk-go-v2/service/s3 v1.65.2 + github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 diff --git a/go.sum b/go.sum index 1c37f8fd3..6c483956d 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.2 h1:yi8m+jepdp6foK14xXLGkYBenxnlcfJ45ka4Pg7fDSQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.2/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 h1:xxHGZ+wUgZNACQmxtdvP5tgzfsxGS3vPpTP5Hy3iToE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= From d3adee81cd49380ac92d170013336f5577b1574b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:09:58 +0800 Subject: [PATCH 156/240] build(deps): update module go.uber.org/fx to v1.23.0 (#646) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 497c44898..56d0445ec 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 - go.uber.org/fx v1.22.2 + go.uber.org/fx v1.23.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 golang.org/x/text v0.19.0 diff --git a/go.sum b/go.sum index 6c483956d..15ca9ce95 100644 --- a/go.sum +++ b/go.sum @@ -464,8 +464,8 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= From 69c292369c56ea2aa63028cf2a2404b0d702cddc Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 05:48:10 +0800 Subject: [PATCH 157/240] fix: request context leak --- web/new.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/new.go b/web/new.go index c229bf6ef..7419ebe4e 100644 --- a/web/new.go +++ b/web/new.go @@ -96,7 +96,7 @@ func New() *echo.Echo { reqIP := c.RealIP() c.SetRequest(c.Request(). - WithContext(context.WithValue(context.Background(), logger.RequestKey, &logger.RequestTrace{ + WithContext(context.WithValue(c.Request().Context(), logger.RequestKey, &logger.RequestTrace{ IP: reqIP, ReqID: reqID, }))) From 9e21e2f38920b721c4e840b1a7d53335d42b2af2 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 06:23:57 +0800 Subject: [PATCH 158/240] fix: make sure canal have context --- canal/event.go | 13 ++++++++----- canal/on_subject.go | 14 +++++++------- canal/on_user.go | 12 ++++++------ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/canal/event.go b/canal/event.go index fec87c3d2..67efec00d 100644 --- a/canal/event.go +++ b/canal/event.go @@ -85,10 +85,10 @@ func (e *eventHandler) Close() error { return nil } -func (e *eventHandler) OnUserPasswordChange(id model.UserID) error { +func (e *eventHandler) OnUserPasswordChange(ctx context.Context, id model.UserID) error { e.log.Info("user change password", log.User(id)) - if err := e.session.RevokeUser(context.Background(), id); err != nil { + if err := e.session.RevokeUser(ctx, id); err != nil { e.log.Error("failed to revoke user", log.User(id), zap.Error(err)) return errgo.Wrap(err, "session.RevokeUser") } @@ -110,14 +110,17 @@ func (e *eventHandler) onMessage(key, value []byte) error { e.log.Debug("new message", zap.String("table", p.Source.Table)) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var err error switch p.Source.Table { case "chii_subject_fields": - err = e.OnSubjectField(key, p) + err = e.OnSubjectField(ctx, key, p) case "chii_subjects": - err = e.OnSubject(key, p) + err = e.OnSubject(ctx, key, p) case "chii_members": - err = e.OnUserChange(key, p) + err = e.OnUserChange(ctx, key, p) } return err diff --git a/canal/on_subject.go b/canal/on_subject.go index fbe70e8b4..c60a42872 100644 --- a/canal/on_subject.go +++ b/canal/on_subject.go @@ -23,32 +23,32 @@ import ( "github.com/bangumi/server/internal/model" ) -func (e *eventHandler) OnSubject(key json.RawMessage, payload Payload) error { +func (e *eventHandler) OnSubject(ctx context.Context, key json.RawMessage, payload Payload) error { var k SubjectKey if err := json.Unmarshal(key, &k); err != nil { return nil } - return e.onSubjectChange(k.ID, payload.Op) + return e.onSubjectChange(ctx, k.ID, payload.Op) } -func (e *eventHandler) OnSubjectField(key json.RawMessage, payload Payload) error { +func (e *eventHandler) OnSubjectField(ctx context.Context, key json.RawMessage, payload Payload) error { var k SubjectFieldKey if err := json.Unmarshal(key, &k); err != nil { return nil } - return e.onSubjectChange(k.ID, payload.Op) + return e.onSubjectChange(ctx, k.ID, payload.Op) } -func (e *eventHandler) onSubjectChange(subjectID model.SubjectID, op string) error { +func (e *eventHandler) onSubjectChange(ctx context.Context, subjectID model.SubjectID, op string) error { switch op { case opCreate, opUpdate, opSnapshot: - if err := e.search.OnSubjectUpdate(context.TODO(), subjectID); err != nil { + if err := e.search.OnSubjectUpdate(ctx, subjectID); err != nil { return errgo.Wrap(err, "search.OnSubjectUpdate") } case opDelete: - if err := e.search.OnSubjectDelete(context.TODO(), subjectID); err != nil { + if err := e.search.OnSubjectDelete(ctx, subjectID); err != nil { return errgo.Wrap(err, "search.OnSubjectDelete") } } diff --git a/canal/on_user.go b/canal/on_user.go index 27c5af9b1..990a4044d 100644 --- a/canal/on_user.go +++ b/canal/on_user.go @@ -32,7 +32,7 @@ import ( "github.com/bangumi/server/internal/pkg/logger/log" ) -func (e *eventHandler) OnUserChange(key json.RawMessage, payload Payload) error { +func (e *eventHandler) OnUserChange(ctx context.Context, key json.RawMessage, payload Payload) error { var k UserKey if err := json.Unmarshal(key, &k); err != nil { e.log.Error("failed to unmarshal json", zap.Error(err)) @@ -53,14 +53,14 @@ func (e *eventHandler) OnUserChange(key json.RawMessage, payload Payload) error } if before.Password != after.Password { - err := e.OnUserPasswordChange(k.ID) + err := e.OnUserPasswordChange(ctx, k.ID) if err != nil { e.log.Error("failed to clear cache", zap.Error(err)) } } if before.NewNotify != after.NewNotify { - e.redis.Publish(context.Background(), fmt.Sprintf("event-user-notify-%d", k.ID), redisUserChannel{ + e.redis.Publish(ctx, fmt.Sprintf("event-user-notify-%d", k.ID), redisUserChannel{ UserID: k.ID, NewNotify: after.NewNotify, }) @@ -72,14 +72,14 @@ func (e *eventHandler) OnUserChange(key json.RawMessage, payload Payload) error } e.log.Debug("clear user avatar cache", log.User(k.ID)) - go e.clearImageCache(after.Avatar) + go e.clearImageCache(context.Background(), after.Avatar) } } return nil } -func (e *eventHandler) clearImageCache(avatar string) { +func (e *eventHandler) clearImageCache(ctx context.Context, avatar string) { p, q, ok := strings.Cut(avatar, "?") if !ok { p = avatar @@ -93,7 +93,7 @@ func (e *eventHandler) clearImageCache(avatar string) { e.log.Debug("clear image for prefix", zap.String("avatar", avatar), zap.String("prefix", p)) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() pages := s3.NewListObjectsV2Paginator( From f022dfbe873573ed73797674d1f57e0ae9695174 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 06:58:43 +0800 Subject: [PATCH 159/240] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 55104f6a9..a511c732e 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,7 @@ ## Requirements -- [Go 1.22](https://go.dev/) +- [Go 1.23](https://go.dev/) - [go-task](https://taskfile.dev/installation/),使用 `task` 查看所有的构建目标。 - [golangci-lint](https://golangci-lint.run/),使用 `task lint` 运行 linter。 From af1c55a80bac9d49b11a8353f8c2493b3bdc5e6f Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 06:59:10 +0800 Subject: [PATCH 160/240] Update readme.md --- readme.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/readme.md b/readme.md index a511c732e..cc8ad863e 100644 --- a/readme.md +++ b/readme.md @@ -1,11 +1,8 @@ 新后端服务器。 -![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/Bangumi/server?style=flat-square) -[![Codecov](https://img.shields.io/codecov/c/github/Bangumi/server?style=flat-square)](https://app.codecov.io/gh/Bangumi/server) - ## Requirements -- [Go 1.23](https://go.dev/) +- ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/Bangumi/server?style=flat-square) - [go-task](https://taskfile.dev/installation/),使用 `task` 查看所有的构建目标。 - [golangci-lint](https://golangci-lint.run/),使用 `task lint` 运行 linter。 From f972eecf0ba553d0b72ff230b65fcfc1d94211c3 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 07:15:43 +0800 Subject: [PATCH 161/240] refactor: profile router --- web/dev.go | 11 ----------- web/new.go | 16 +++++++--------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/web/dev.go b/web/dev.go index 8d3097a8e..786f6aa68 100644 --- a/web/dev.go +++ b/web/dev.go @@ -15,9 +15,6 @@ package web import ( - "net/http" - "net/http/pprof" - "github.com/labstack/echo/v4" "github.com/bangumi/server/internal/pkg/random" @@ -33,11 +30,3 @@ func genFakeRequestID(next echo.HandlerFunc) echo.HandlerFunc { return next(c) } } - -func addProfile(app *echo.Echo) { - app.GET("/debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(pprof.Cmdline))) - app.GET("/debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(pprof.Profile))) - app.GET("/debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(pprof.Symbol))) - app.GET("/debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(pprof.Trace))) - app.Any("/debug/pprof/", echo.WrapHandler(http.HandlerFunc(pprof.Index))) -} diff --git a/web/new.go b/web/new.go index 7419ebe4e..aae9dfe10 100644 --- a/web/new.go +++ b/web/new.go @@ -79,6 +79,13 @@ func New() *echo.Echo { } }) + app.GET("/metrics", echo.WrapHandler(promhttp.Handler())) + app.GET("/debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(pprof.Cmdline))) + app.GET("/debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(pprof.Profile))) + app.GET("/debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(pprof.Symbol))) + app.GET("/debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(pprof.Trace))) + app.GET("/debug/pprof/*", echo.WrapHandler(http.HandlerFunc(pprof.Index))) + if env.Development { app.Use(genFakeRequestID) } @@ -107,15 +114,6 @@ func New() *echo.Echo { app.Use(recovery.New()) - app.GET("/metrics", echo.WrapHandler(promhttp.Handler())) - app.GET("/debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(pprof.Cmdline))) - app.GET("/debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(pprof.Profile))) - app.GET("/debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(pprof.Symbol))) - app.GET("/debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(pprof.Trace))) - app.GET("/debug/pprof/*", echo.WrapHandler(http.HandlerFunc(pprof.Index))) - - addProfile(app) - app.GET("/openapi", func(c echo.Context) error { return c.Redirect(http.StatusFound, "/openapi/") }) From 20fc7c9f3e7f557b79143738d708f0778fcdbe94 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 07:39:10 +0800 Subject: [PATCH 162/240] perf: use sonic for json --- go.mod | 7 +++++++ go.sum | 18 ++++++++++++++++++ web/json.go | 8 ++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 56d0445ec..60b02588d 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.32.2 github.com/aws/aws-sdk-go-v2/credentials v1.17.41 github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 + github.com/bytedance/sonic v1.12.3 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 @@ -61,7 +62,10 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect github.com/aws/smithy-go v1.22.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect @@ -74,6 +78,7 @@ require ( github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.10 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -85,11 +90,13 @@ require ( github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect diff --git a/go.sum b/go.sum index 15ca9ce95..90b09c1e2 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,11 @@ github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdb github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= +github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -73,6 +78,10 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -243,6 +252,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -424,6 +436,7 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -441,6 +454,8 @@ github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= github.com/trim21/htest v0.0.4/go.mod h1:W+zaYAGCBqx38eMrMGvXrALnbcXR6OBtZiRiHahgo+E= github.com/trim21/pkg v0.0.3 h1:uAqfoFmmYiIMOSretKj8/tvrQs3KG57020Ff0cx8UtE= github.com/trim21/pkg v0.0.3/go.mod h1:JrRIFidkCLeuU5j0vBP5ZN0NOp2JavagHZNr4D3AH6Q= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -479,6 +494,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 h1:lGdhQUN/cnWdSH3291CUuxSEqc+AsGTiDxPP3r2J0l4= go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -696,6 +713,7 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ= olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/web/json.go b/web/json.go index 7f3262e5e..484f8a8ed 100644 --- a/web/json.go +++ b/web/json.go @@ -15,8 +15,8 @@ package web import ( - "encoding/json" - + "github.com/bytedance/sonic/decoder" + "github.com/bytedance/sonic/encoder" "github.com/labstack/echo/v4" ) @@ -26,7 +26,7 @@ type jsonSerializer struct { } func (j jsonSerializer) Serialize(c echo.Context, i any, indent string) error { - enc := json.NewEncoder(c.Response()) + enc := encoder.NewStreamEncoder(c.Response()) if indent != "" { enc.SetIndent("", indent) } @@ -34,7 +34,7 @@ func (j jsonSerializer) Serialize(c echo.Context, i any, indent string) error { } func (j jsonSerializer) Deserialize(c echo.Context, i any) error { - dec := json.NewDecoder(c.Request().Body) + dec := decoder.NewStreamDecoder(c.Request().Body) dec.DisallowUnknownFields() return dec.Decode(i) } From d6efd915ef2cd2f23377b6e7d93cf3e838f0c5a0 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 14 Oct 2024 09:34:24 +0800 Subject: [PATCH 163/240] fix: check access token by case sensitive (#647) --- dal/fx.go | 6 ++++ go.mod | 2 ++ go.sum | 11 +++++-- internal/auth/mysql_repository.go | 44 ++++++++++++++++---------- internal/auth/mysql_repository_test.go | 15 ++++++++- internal/pkg/test/gorm.go | 2 +- 6 files changed, 58 insertions(+), 22 deletions(-) diff --git a/dal/fx.go b/dal/fx.go index 3810e1785..465467229 100644 --- a/dal/fx.go +++ b/dal/fx.go @@ -17,6 +17,9 @@ package dal import ( + "database/sql" + + "github.com/jmoiron/sqlx" "go.uber.org/fx" "github.com/bangumi/server/dal/query" @@ -27,5 +30,8 @@ var Module = fx.Module("dal", NewDB, query.Use, NewMysqlTransaction, + func(db *sql.DB) *sqlx.DB { + return sqlx.NewDb(db, "mysql") + }, ), ) diff --git a/go.mod b/go.mod index 60b02588d..912ef457b 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/go-sql-driver/mysql v1.8.1 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jarcoal/httpmock v1.3.1 + github.com/jmoiron/sqlx v1.4.0 github.com/labstack/echo/v4 v4.12.0 github.com/mattn/go-colorable v0.1.13 github.com/meilisearch/meilisearch-go v0.28.0 @@ -89,6 +90,7 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect diff --git a/go.sum b/go.sum index 90b09c1e2..47325d807 100644 --- a/go.sum +++ b/go.sum @@ -234,6 +234,8 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -273,6 +275,8 @@ github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0 github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= @@ -289,8 +293,9 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= @@ -397,8 +402,8 @@ github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0 github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= diff --git a/internal/auth/mysql_repository.go b/internal/auth/mysql_repository.go index f477fde9f..6ce8cae56 100644 --- a/internal/auth/mysql_repository.go +++ b/internal/auth/mysql_repository.go @@ -16,11 +16,13 @@ package auth import ( "context" + "database/sql" "encoding/json" "errors" "strconv" "time" + "github.com/jmoiron/sqlx" "github.com/trim21/errgo" "go.uber.org/zap" "gorm.io/gorm" @@ -32,14 +34,20 @@ import ( "github.com/bangumi/server/internal/pkg/gstr" "github.com/bangumi/server/internal/pkg/logger" "github.com/bangumi/server/internal/pkg/random" + "github.com/bangumi/server/internal/user" ) -func NewMysqlRepo(q *query.Query, log *zap.Logger) Repo { - return mysqlRepo{q: q, log: log.Named("auth.mysqlRepo")} +func NewMysqlRepo(q *query.Query, log *zap.Logger, db *sqlx.DB) Repo { + return mysqlRepo{ + q: q, + log: log.Named("auth.mysqlRepo"), + db: db, + } } type mysqlRepo struct { q *query.Query + db *sqlx.DB log *zap.Logger } @@ -62,16 +70,17 @@ func (m mysqlRepo) GetByEmail(ctx context.Context, email string) (UserInfo, []by } func (m mysqlRepo) GetByToken(ctx context.Context, token string) (UserInfo, error) { - access, err := m.q.AccessToken.WithContext(ctx). - Where(m.q.AccessToken.AccessToken.Eq(token), m.q.AccessToken.ExpiredAt.Gte(time.Now())). - First() + var access struct { + UserID string `db:"user_id"` + } + err := m.db.GetContext(ctx, &access, + `select user_id from chii_oauth_access_tokens + where access_token = BINARY ? and expires > ? limit 1`, token, time.Now()) if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { + if errors.Is(err, sql.ErrNoRows) { return UserInfo{}, gerr.ErrNotFound } - m.log.Error("unexpected error happened", zap.Error(err)) - return UserInfo{}, errgo.Wrap(err, "gorm") } @@ -81,24 +90,25 @@ func (m mysqlRepo) GetByToken(ctx context.Context, token string) (UserInfo, erro return UserInfo{}, errgo.Wrap(err, "parsing user id") } - u, err := m.q.Member.WithContext(ctx).Where(m.q.Member.ID.Eq(id)).Take() - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - m.log.Error("can't find user of access token", - zap.String("token", token), zap.String("uid", access.UserID)) + var u struct { + Regdate int64 + GroupID user.GroupID + } + err = m.db.QueryRowContext(ctx, `select regdate, groupid from chii_members where uid = ? limit 1`, id). + Scan(&u.Regdate, &u.GroupID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { return UserInfo{}, gerr.ErrNotFound } - m.log.Error("unexpected error happened", zap.Error(err)) - return UserInfo{}, errgo.Wrap(err, "gorm") } return UserInfo{ RegTime: time.Unix(u.Regdate, 0), - ID: u.ID, - GroupID: u.Groupid, + ID: id, + GroupID: u.GroupID, }, nil } diff --git a/internal/auth/mysql_repository_test.go b/internal/auth/mysql_repository_test.go index daa1f7a3a..0320de7ac 100644 --- a/internal/auth/mysql_repository_test.go +++ b/internal/auth/mysql_repository_test.go @@ -17,9 +17,12 @@ package auth_test import ( "context" "strconv" + "strings" "testing" "time" + "github.com/jmoiron/sqlx" + "github.com/samber/lo" "github.com/stretchr/testify/require" "go.uber.org/zap" @@ -34,7 +37,7 @@ import ( func getRepo(t *testing.T) (auth.Repo, *query.Query) { t.Helper() q := query.Use(test.GetGorm(t)) - repo := auth.NewMysqlRepo(q, zap.NewNop()) + repo := auth.NewMysqlRepo(q, zap.NewNop(), sqlx.NewDb(lo.Must(q.DB().DB()), "mysql")) return repo, q } @@ -61,6 +64,16 @@ func TestMysqlRepo_GetByToken(t *testing.T) { require.EqualValues(t, 382951, u.ID) } +func TestMysqlRepo_GetByToken_case_sensitive(t *testing.T) { + test.RequireEnv(t, "mysql") + t.Parallel() + + repo, _ := getRepo(t) + + _, err := repo.GetByToken(context.Background(), strings.ToUpper("a_development_access_token")) + require.ErrorIs(t, err, gerr.ErrNotFound) +} + func TestMysqlRepo_GetByToken_expired(t *testing.T) { test.RequireEnv(t, "mysql") t.Parallel() diff --git a/internal/pkg/test/gorm.go b/internal/pkg/test/gorm.go index 83985d504..7c90a4eb2 100644 --- a/internal/pkg/test/gorm.go +++ b/internal/pkg/test/gorm.go @@ -44,7 +44,7 @@ func GetQuery(tb testing.TB) *query.Query { func GetGorm(tb testing.TB) *gorm.DB { tb.Helper() - RequireEnv(tb, EnvRedis) + RequireEnv(tb, EnvMysql) cfg, err := config.NewAppConfig() require.NoError(tb, err) From 22d04e74cb2809aaa9f6eee911e799158d836baa Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 00:20:47 +0800 Subject: [PATCH 164/240] fix: do not allow update collection for locked subject --- web/handler/user/patch_subject_collection.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/handler/user/patch_subject_collection.go b/web/handler/user/patch_subject_collection.go index 56f196edb..e410eeef7 100644 --- a/web/handler/user/patch_subject_collection.go +++ b/web/handler/user/patch_subject_collection.go @@ -84,6 +84,10 @@ func (h User) updateOrCreateSubjectCollection( return errgo.Wrap(err, "query.GetSubject") } + if s.Locked() { + return res.NotFound("subject locked") + } + if s.TypeID != model.SubjectTypeBook { if r.VolStatus.Set || r.EpStatus.Set { return res.BadRequest("can't set 'vol_status' or 'ep_status' on non-book subject") From 97fa07130262fef34beb077f7a644fc91c1458d6 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 00:21:32 +0800 Subject: [PATCH 165/240] fix: do not allow update collection for locked subject --- web/handler/user/patch_subject_collection.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/handler/user/patch_subject_collection.go b/web/handler/user/patch_subject_collection.go index e410eeef7..557ae90bd 100644 --- a/web/handler/user/patch_subject_collection.go +++ b/web/handler/user/patch_subject_collection.go @@ -84,8 +84,8 @@ func (h User) updateOrCreateSubjectCollection( return errgo.Wrap(err, "query.GetSubject") } - if s.Locked() { - return res.NotFound("subject locked") + if s.Ban != 0 { + return res.NotFound("subject locked or merged") } if s.TypeID != model.SubjectTypeBook { From 7059cf9dd80e73bc58ebd988a13f32c697bd8ad2 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 04:30:06 +0800 Subject: [PATCH 166/240] feat: include meta tag in api (#648) --- canal/canal.go | 2 +- canal/stream/redis_stream.go | 183 ------------------- cmd/archive/main.go | 4 +- cmd/gen/gorm/main.go | 4 +- cmd/web/cmd.go | 8 +- dal/fx.go | 2 +- dal/metrics.go | 2 +- dal/new.go | 6 +- dal/new_test.go | 4 +- etc/mock.task.yaml | 14 ++ go.mod | 3 +- go.sum | 18 +- internal/cachekey/cachekey.go | 4 + internal/collections/infra/mysql_repo.go | 8 +- internal/mocks/RedisCache.go | 52 +++++- internal/mocks/TagRepo.go | 155 ++++++++++++++++ internal/model/subject.go | 5 +- internal/pkg/cache/noop.go | 4 + internal/pkg/cache/redis.go | 46 +++-- internal/pkg/cache/redis_test.go | 112 +----------- internal/pkg/cache/serialize.go | 9 - internal/pkg/driver/mysql.go | 3 +- internal/pkg/driver/redis.go | 21 +++ internal/pkg/test/fx.go | 58 ++++++ internal/pkg/test/gorm.go | 2 +- internal/pkg/test/redis.go | 17 +- internal/pkg/test/web.go | 15 ++ internal/subject/mysq_repository_compat.go | 4 +- internal/tag/cache_repo.go | 112 ++++++++++++ internal/tag/cache_repo_test.go | 57 ++++++ internal/{subject/repo2.go => tag/domain.go} | 34 +++- internal/tag/mysql_repo.go | 97 ++++++++++ internal/tag/mysql_repo_test.go | 59 ++++++ web/handler/subject/browse.go | 2 +- web/handler/subject/get.go | 18 +- web/handler/subject/get_test.go | 6 +- web/handler/subject/subject.go | 4 + web/res/subject.go | 6 +- 38 files changed, 790 insertions(+), 370 deletions(-) delete mode 100644 canal/stream/redis_stream.go create mode 100644 internal/mocks/TagRepo.go create mode 100644 internal/pkg/test/fx.go create mode 100644 internal/tag/cache_repo.go create mode 100644 internal/tag/cache_repo_test.go rename internal/{subject/repo2.go => tag/domain.go} (54%) create mode 100644 internal/tag/mysql_repo.go create mode 100644 internal/tag/mysql_repo_test.go diff --git a/canal/canal.go b/canal/canal.go index 50ac7f1b8..3b57ec5e6 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -59,7 +59,7 @@ func Main() error { // driver and connector fx.Provide( - driver.NewMysqlConnectionPool, + driver.NewMysqlSqlDB, driver.NewRedisClient, logger.Copy, cache.NewRedisCache, subject.NewMysqlRepo, search.New, session.NewMysqlRepo, session.New, driver.NewS3, diff --git a/canal/stream/redis_stream.go b/canal/stream/redis_stream.go deleted file mode 100644 index bc3198e06..000000000 --- a/canal/stream/redis_stream.go +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see - -package stream - -import ( - "context" - "errors" - "time" - - "github.com/redis/go-redis/v9" -) - -// A Message is a consumed message from a redis stream. -type Message struct { - Stream string - ID string - Values map[string]any -} - -type config struct { - group string - consumer string - streams []string // list of streams and ids, e.g. stream1 stream2 id1 id2 - count int64 - block time.Duration - noAck bool -} - -// An Option modifies the config. -type Option func(*config) - -// WithStream adds a stream to the consumer. -func WithStream(stream string) Option { - return func(cfg *config) { - cfg.streams = append(cfg.streams, stream) - } -} - -// WithCount sets the count for the config. -func WithCount(cnt int64) Option { - return func(cfg *config) { - cfg.count = cnt - } -} - -// WithBlock sets the block field of the config. -func WithBlock(duration time.Duration) Option { - return func(cfg *config) { - cfg.block = duration - } -} - -// WithNoAck sets the noAck field of the config. -func WithNoAck(noAck bool) Option { - return func(cfg *config) { - cfg.noAck = noAck - } -} - -// A Consumer consumes messages from a stream. -type Consumer struct { - client *redis.Client - cfg *config - lastIDs map[string]string -} - -// New creates a new consumer. -func New(client *redis.Client, group, consumer string, options ...Option) *Consumer { - cfg := &config{ - group: group, - consumer: consumer, - } - for _, opt := range options { - opt(cfg) - } - lastIDs := make(map[string]string) - for _, stream := range cfg.streams { - lastIDs[stream] = "0-0" - } - - return &Consumer{ - client: client, - cfg: cfg, - lastIDs: lastIDs, - } -} - -// Read reads messages from the stream. -func (c *Consumer) Read(ctx context.Context) ([]Message, error) { - for { - streams := make([]string, 0, len(c.cfg.streams)*2) - streams = append(streams, c.cfg.streams...) - for _, stream := range c.cfg.streams { - streams = append(streams, c.lastIDs[stream]) - } - - cmd := c.client.XReadGroup(ctx, &redis.XReadGroupArgs{ - Group: c.cfg.group, - Consumer: c.cfg.consumer, - Streams: streams, - Count: c.cfg.count, - Block: c.cfg.block, - NoAck: c.cfg.noAck, - }) - - vals, err := cmd.Result() - if err == redis.Nil { - if c.cfg.block >= 0 { - continue - } - - return nil, nil //nolint:revive - } else if err != nil { - return nil, err - } - - allLatest := true - for _, lastID := range c.lastIDs { - if lastID != ">" { - allLatest = false - } - } - - var msgs []Message - for _, stream := range vals { - if len(stream.Messages) == 0 { - c.lastIDs[stream.Stream] = ">" - } - for _, msg := range stream.Messages { - msgs = append(msgs, Message{ - Stream: stream.Stream, - ID: msg.ID, - Values: msg.Values, - }) - c.lastIDs[stream.Stream] = msg.ID - } - } - if len(msgs) > 0 || allLatest { - return msgs, nil - } - } -} - -// Ack acknowledges the messages. -func (c *Consumer) Ack(ctx context.Context, msgs ...Message) error { - if len(msgs) == 0 { - return nil - } - - if len(msgs) == 1 { - msg := msgs[0] - return errors.Join( - c.client.XAck(ctx, msg.Stream, c.cfg.group, msg.ID).Err(), - c.client.XDel(ctx, msg.Stream, msg.ID).Err(), - ) - } - - ids := map[string][]string{} - for _, msg := range msgs { - ids[msg.Stream] = append(ids[msg.Stream], msg.ID) - } - - _, err := c.client.Pipelined(ctx, func(p redis.Pipeliner) error { - for stream, msgIDs := range ids { - p.XAck(ctx, stream, c.cfg.group, msgIDs...) - p.XDel(ctx, stream, msgIDs...) - } - return nil - }) - return err -} diff --git a/cmd/archive/main.go b/cmd/archive/main.go index fd23fbc79..047b6a79d 100644 --- a/cmd/archive/main.go +++ b/cmd/archive/main.go @@ -80,7 +80,7 @@ func start(out string) { err := fx.New( fx.NopLogger, fx.Provide( - driver.NewMysqlConnectionPool, dal.NewDB, + driver.NewMysqlSqlDB, dal.NewGormDB, config.NewAppConfig, logger.Copy, @@ -210,7 +210,7 @@ type Subject struct { type Tag struct { Name string `json:"name"` - Count int `json:"count"` + Count uint `json:"count"` } func exportSubjects(q *query.Query, w io.Writer) { diff --git a/cmd/gen/gorm/main.go b/cmd/gen/gorm/main.go index 643aa85d4..baccbecba 100644 --- a/cmd/gen/gorm/main.go +++ b/cmd/gen/gorm/main.go @@ -92,12 +92,12 @@ func main() { panic("failed to read config: " + err.Error()) } - conn, err := driver.NewMysqlConnectionPool(c) + conn, err := driver.NewMysqlSqlDB(c) if err != nil { panic(err) } - db, err := dal.NewDB(conn, c) + db, err := dal.NewGormDB(conn, c) if err != nil { panic(err) } diff --git a/cmd/web/cmd.go b/cmd/web/cmd.go index 7127a0561..4e3ff73b2 100644 --- a/cmd/web/cmd.go +++ b/cmd/web/cmd.go @@ -41,6 +41,7 @@ import ( "github.com/bangumi/server/internal/revision" "github.com/bangumi/server/internal/search" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/internal/timeline" "github.com/bangumi/server/internal/user" "github.com/bangumi/server/web" @@ -65,7 +66,8 @@ func start() error { fx.Provide( config.AppConfigReader(config.AppTypeHTTP), driver.NewRedisClientWithMetrics, // redis - driver.NewMysqlConnectionPool, // mysql + driver.NewMysqlSqlDB, // mysql + driver.NewRueidisClient, func() *resty.Client { httpClient := resty.New().SetJSONEscapeHTML(false) httpClient.JSONUnmarshal = json.Unmarshal @@ -74,6 +76,8 @@ func start() error { }, ), + fx.Invoke(dal.SetupMetrics), + dal.Module, fx.Provide( @@ -87,6 +91,8 @@ func start() error { dam.New, subject.NewMysqlRepo, subject.NewCachedRepo, person.NewMysqlRepo, + tag.NewCachedRepo, tag.NewMysqlRepo, + auth.NewService, person.NewService, search.New, ), diff --git a/dal/fx.go b/dal/fx.go index 465467229..1f06120bb 100644 --- a/dal/fx.go +++ b/dal/fx.go @@ -27,7 +27,7 @@ import ( var Module = fx.Module("dal", fx.Provide( - NewDB, + NewGormDB, query.Use, NewMysqlTransaction, func(db *sql.DB) *sqlx.DB { diff --git a/dal/metrics.go b/dal/metrics.go index 041d6120f..4702c7a0b 100644 --- a/dal/metrics.go +++ b/dal/metrics.go @@ -22,7 +22,7 @@ import ( "gorm.io/gorm" ) -func setupMetrics(db *gorm.DB, conn *sql.DB) error { +func SetupMetrics(db *gorm.DB, conn *sql.DB) error { var DatabaseQuery = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "chii_db_execute_total", diff --git a/dal/new.go b/dal/new.go index bef0f170b..6166a1447 100644 --- a/dal/new.go +++ b/dal/new.go @@ -27,7 +27,7 @@ import ( "github.com/bangumi/server/internal/pkg/logger" ) -func NewDB(conn *sql.DB, c config.AppConfig) (*gorm.DB, error) { +func NewGormDB(conn *sql.DB, c config.AppConfig) (*gorm.DB, error) { var gLog gormLogger.Interface if c.Debug.Gorm { logger.Info("enable gorm debug mode, will log all sql") @@ -51,9 +51,5 @@ func NewDB(conn *sql.DB, c config.AppConfig) (*gorm.DB, error) { return nil, errgo.Wrap(err, "create dal") } - if err = setupMetrics(db, conn); err != nil { - return nil, errgo.Wrap(err, "setup metrics") - } - return db, nil } diff --git a/dal/new_test.go b/dal/new_test.go index 54f0645cc..7245ea6bc 100644 --- a/dal/new_test.go +++ b/dal/new_test.go @@ -31,9 +31,9 @@ func TestNewDB(t *testing.T) { cfg, err := config.NewAppConfig() require.NoError(t, err) - conn, err := driver.NewMysqlConnectionPool(cfg) + conn, err := driver.NewMysqlSqlDB(cfg) require.NoError(t, err) - db, err := dal.NewDB(conn, cfg) + db, err := dal.NewGormDB(conn, cfg) require.NoError(t, err) err = db.Exec("select 0;").Error diff --git a/etc/mock.task.yaml b/etc/mock.task.yaml index 57ef2ef06..47292fda1 100644 --- a/etc/mock.task.yaml +++ b/etc/mock.task.yaml @@ -6,6 +6,7 @@ vars: tasks: all: cmds: + - task: Tag - task: session-manager - task: session-repo - task: cache @@ -98,6 +99,19 @@ tasks: MOCK_STRUCT: "AuthService" INTERFACE: Service + "Tag": + sources: + - internal/tag/domain.go + - ./internal/pkg/tools/go.mod + generates: + - internal/mocks/TagRepo.go + cmds: + - task: base-mock + vars: + SRC_DIR: ./internal/tag + INTERFACE: "Repo" + MOCK_STRUCT: "TagRepo" + "CharacterRepo": sources: - ./internal/character/domain/.go diff --git a/go.mod b/go.mod index 912ef457b..b9a8606e7 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,6 @@ require ( github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.22.1 - github.com/go-redis/redismock/v9 v9.2.0 github.com/go-resty/resty/v2 v2.15.3 github.com/go-sql-driver/mysql v1.8.1 github.com/ilyakaznacheev/cleanenv v1.5.0 @@ -25,6 +24,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.20.4 github.com/redis/go-redis/v9 v9.6.1 + github.com/redis/rueidis v1.0.47 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 @@ -68,7 +68,6 @@ require ( github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect diff --git a/go.sum b/go.sum index 47325d807..d67908494 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,6 @@ github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLg github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -131,8 +129,6 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= -github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -328,18 +324,14 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= -github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -400,6 +392,8 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/redis/rueidis v1.0.47 h1:41UdeXOo4eJuW+cfpUJuLtVGyO0QJY3A2rEYgJWlfHs= +github.com/redis/rueidis v1.0.47/go.mod h1:by+34b0cFXndxtYmPAHpoTHO5NkosDlBvhexoTURIxM= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -513,6 +507,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -585,7 +581,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -676,7 +671,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/internal/cachekey/cachekey.go b/internal/cachekey/cachekey.go index 319cc3b23..2f424a728 100644 --- a/internal/cachekey/cachekey.go +++ b/internal/cachekey/cachekey.go @@ -54,3 +54,7 @@ func Index(id model.IndexID) string { func User(id model.UserID) string { return resPrefix + "user:" + strconv.FormatUint(uint64(id), 10) } + +func SubjectMetaTag(id model.SubjectID) string { + return resPrefix + "subject:meta-tags:" + strconv.FormatUint(uint64(id), 10) +} diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index a408e44ce..e069801b1 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -333,8 +333,8 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, return errgo.Trace(err) } - var count = make(map[string]int) - var countMap = make(map[string]uint32) + var count = make(map[string]uint) + var countMap = make(map[string]uint) for _, tag := range tagList { if !dam.ValidateTag(tag.Tag.Name) { @@ -342,7 +342,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, } count[tag.Tag.Name]++ - countMap[tag.Tag.Name] = tag.Tag.Results + countMap[tag.Tag.Name] = uint(tag.Tag.Results) } var phpTags = make([]subject.Tag, 0, len(count)) @@ -351,7 +351,7 @@ func (r mysqlRepo) reCountSubjectTags(ctx context.Context, tx *query.Query, phpTags = append(phpTags, subject.Tag{ Name: lo.ToPtr(name), Count: c, - TotalCount: int(countMap[name]), + TotalCount: countMap[name], }) } diff --git a/internal/mocks/RedisCache.go b/internal/mocks/RedisCache.go index fce7469dd..6728d19ed 100644 --- a/internal/mocks/RedisCache.go +++ b/internal/mocks/RedisCache.go @@ -4,9 +4,12 @@ package mocks import ( context "context" - time "time" + + cache "github.com/bangumi/server/internal/pkg/cache" mock "github.com/stretchr/testify/mock" + + time "time" ) // RedisCache is an autogenerated mock type for the RedisCache type @@ -141,6 +144,53 @@ func (_c *RedisCache_Get_Call) RunAndReturn(run func(context.Context, string, in return _c } +// MGet provides a mock function with given fields: ctx, key +func (_m *RedisCache) MGet(ctx context.Context, key []string) cache.MGetResult { + ret := _m.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for MGet") + } + + var r0 cache.MGetResult + if rf, ok := ret.Get(0).(func(context.Context, []string) cache.MGetResult); ok { + r0 = rf(ctx, key) + } else { + r0 = ret.Get(0).(cache.MGetResult) + } + + return r0 +} + +// RedisCache_MGet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MGet' +type RedisCache_MGet_Call struct { + *mock.Call +} + +// MGet is a helper method to define mock.On call +// - ctx context.Context +// - key []string +func (_e *RedisCache_Expecter) MGet(ctx interface{}, key interface{}) *RedisCache_MGet_Call { + return &RedisCache_MGet_Call{Call: _e.mock.On("MGet", ctx, key)} +} + +func (_c *RedisCache_MGet_Call) Run(run func(ctx context.Context, key []string)) *RedisCache_MGet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]string)) + }) + return _c +} + +func (_c *RedisCache_MGet_Call) Return(_a0 cache.MGetResult) *RedisCache_MGet_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *RedisCache_MGet_Call) RunAndReturn(run func(context.Context, []string) cache.MGetResult) *RedisCache_MGet_Call { + _c.Call.Return(run) + return _c +} + // Set provides a mock function with given fields: ctx, key, value, ttl func (_m *RedisCache) Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error { ret := _m.Called(ctx, key, value, ttl) diff --git a/internal/mocks/TagRepo.go b/internal/mocks/TagRepo.go new file mode 100644 index 000000000..2aec09a0e --- /dev/null +++ b/internal/mocks/TagRepo.go @@ -0,0 +1,155 @@ +// Code generated by mockery v2.43.0. DO NOT EDIT. + +package mocks + +import ( + context "context" + + tag "github.com/bangumi/server/internal/tag" + mock "github.com/stretchr/testify/mock" +) + +// TagRepo is an autogenerated mock type for the Repo type +type TagRepo struct { + mock.Mock +} + +type TagRepo_Expecter struct { + mock *mock.Mock +} + +func (_m *TagRepo) EXPECT() *TagRepo_Expecter { + return &TagRepo_Expecter{mock: &_m.Mock} +} + +// Get provides a mock function with given fields: ctx, id +func (_m *TagRepo) Get(ctx context.Context, id uint32) ([]tag.Tag, error) { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 []tag.Tag + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint32) ([]tag.Tag, error)); ok { + return rf(ctx, id) + } + if rf, ok := ret.Get(0).(func(context.Context, uint32) []tag.Tag); ok { + r0 = rf(ctx, id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]tag.Tag) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint32) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TagRepo_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' +type TagRepo_Get_Call struct { + *mock.Call +} + +// Get is a helper method to define mock.On call +// - ctx context.Context +// - id uint32 +func (_e *TagRepo_Expecter) Get(ctx interface{}, id interface{}) *TagRepo_Get_Call { + return &TagRepo_Get_Call{Call: _e.mock.On("Get", ctx, id)} +} + +func (_c *TagRepo_Get_Call) Run(run func(ctx context.Context, id uint32)) *TagRepo_Get_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32)) + }) + return _c +} + +func (_c *TagRepo_Get_Call) Return(_a0 []tag.Tag, _a1 error) *TagRepo_Get_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *TagRepo_Get_Call) RunAndReturn(run func(context.Context, uint32) ([]tag.Tag, error)) *TagRepo_Get_Call { + _c.Call.Return(run) + return _c +} + +// GetByIDs provides a mock function with given fields: ctx, ids +func (_m *TagRepo) GetByIDs(ctx context.Context, ids []uint32) (map[uint32][]tag.Tag, error) { + ret := _m.Called(ctx, ids) + + if len(ret) == 0 { + panic("no return value specified for GetByIDs") + } + + var r0 map[uint32][]tag.Tag + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []uint32) (map[uint32][]tag.Tag, error)); ok { + return rf(ctx, ids) + } + if rf, ok := ret.Get(0).(func(context.Context, []uint32) map[uint32][]tag.Tag); ok { + r0 = rf(ctx, ids) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[uint32][]tag.Tag) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []uint32) error); ok { + r1 = rf(ctx, ids) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TagRepo_GetByIDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetByIDs' +type TagRepo_GetByIDs_Call struct { + *mock.Call +} + +// GetByIDs is a helper method to define mock.On call +// - ctx context.Context +// - ids []uint32 +func (_e *TagRepo_Expecter) GetByIDs(ctx interface{}, ids interface{}) *TagRepo_GetByIDs_Call { + return &TagRepo_GetByIDs_Call{Call: _e.mock.On("GetByIDs", ctx, ids)} +} + +func (_c *TagRepo_GetByIDs_Call) Run(run func(ctx context.Context, ids []uint32)) *TagRepo_GetByIDs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]uint32)) + }) + return _c +} + +func (_c *TagRepo_GetByIDs_Call) Return(_a0 map[uint32][]tag.Tag, _a1 error) *TagRepo_GetByIDs_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *TagRepo_GetByIDs_Call) RunAndReturn(run func(context.Context, []uint32) (map[uint32][]tag.Tag, error)) *TagRepo_GetByIDs_Call { + _c.Call.Return(run) + return _c +} + +// NewTagRepo creates a new instance of TagRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewTagRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *TagRepo { + mock := &TagRepo{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/model/subject.go b/internal/model/subject.go index 577c9e55f..626de64ee 100644 --- a/internal/model/subject.go +++ b/internal/model/subject.go @@ -17,8 +17,9 @@ package model const subjectLocked = 2 type Tag struct { - Name string - Count int + Name string + Count uint + TotalCount uint } type Subject struct { diff --git a/internal/pkg/cache/noop.go b/internal/pkg/cache/noop.go index 491f46aab..8f9d2db59 100644 --- a/internal/pkg/cache/noop.go +++ b/internal/pkg/cache/noop.go @@ -36,3 +36,7 @@ func (n noop) Set(context.Context, string, any, time.Duration) error { func (n noop) Del(context.Context, ...string) error { return nil } + +func (n noop) MGet(ctx context.Context, key []string) MGetResult { + return MGetResult{} +} diff --git a/internal/pkg/cache/redis.go b/internal/pkg/cache/redis.go index 16746dd5f..f523a51df 100644 --- a/internal/pkg/cache/redis.go +++ b/internal/pkg/cache/redis.go @@ -18,7 +18,7 @@ import ( "context" "time" - "github.com/redis/go-redis/v9" + "github.com/redis/rueidis" "github.com/trim21/errgo" "go.uber.org/zap" @@ -34,31 +34,39 @@ type RedisCache interface { Get(ctx context.Context, key string, value any) (bool, error) Set(ctx context.Context, key string, value any, ttl time.Duration) error Del(ctx context.Context, keys ...string) error + MGet(ctx context.Context, key []string) MGetResult +} + +type MGetResult struct { + rueidis.RedisResult } // NewRedisCache create a redis backed cache. -func NewRedisCache(cli *redis.Client) RedisCache { - return redisCache{r: cli} +func NewRedisCache(ru rueidis.Client) RedisCache { + return redisCache{ru: ru} } type redisCache struct { - r *redis.Client + ru rueidis.Client } func (c redisCache) Get(ctx context.Context, key string, value any) (bool, error) { - raw, err := c.r.Get(ctx, key).Bytes() - if err != nil { - if err == redis.Nil { - return false, nil - } - + result := c.ru.Do(ctx, c.ru.B().Get().Key(key).Build()) + if err := result.NonRedisError(); err != nil { return false, errgo.Wrap(err, "redis get") } + raw, err := result.AsBytes() + // redis.Nil + if err != nil { + return false, nil + } + err = unmarshalBytes(raw, value) if err != nil { logger.Warn("can't unmarshal redis cached data as json", zap.String("key", key)) - c.r.Del(ctx, key) + + c.ru.Do(ctx, c.ru.B().Del().Key(key).Build()) return false, nil } @@ -66,13 +74,17 @@ func (c redisCache) Get(ctx context.Context, key string, value any) (bool, error return true, nil } +func (c redisCache) MGet(ctx context.Context, keys []string) MGetResult { + return MGetResult{c.ru.Do(ctx, c.ru.B().Mget().Key(keys...).Build())} +} + +func MGet[T any](c RedisCache, ctx context.Context, keys []string, value *[]T) error { + return rueidis.DecodeSliceOfJSON(c.MGet(ctx, keys).RedisResult, value) +} + func (c redisCache) Set(ctx context.Context, key string, value any, ttl time.Duration) error { - b, err := marshalBytes(value) + err := c.ru.Do(ctx, c.ru.B().Set().Key(key).Value(rueidis.JSON(value)).Ex(ttl).Build()).Error() if err != nil { - return err - } - - if err := c.r.Set(ctx, key, b, ttl).Err(); err != nil { return errgo.Wrap(err, "redis set") } @@ -80,6 +92,6 @@ func (c redisCache) Set(ctx context.Context, key string, value any, ttl time.Dur } func (c redisCache) Del(ctx context.Context, keys ...string) error { - err := c.r.Del(ctx, keys...).Err() + err := c.ru.Do(ctx, c.ru.B().Del().Key(keys...).Build()).Error() return errgo.Wrap(err, "redis.Del") } diff --git a/internal/pkg/cache/redis_test.go b/internal/pkg/cache/redis_test.go index 6d0f89a06..897432311 100644 --- a/internal/pkg/cache/redis_test.go +++ b/internal/pkg/cache/redis_test.go @@ -16,11 +16,10 @@ package cache_test import ( "context" - "encoding/json" + "fmt" "testing" "time" - redismock "github.com/go-redis/redismock/v9" "github.com/stretchr/testify/require" "github.com/bangumi/server/internal/pkg/cache" @@ -32,106 +31,15 @@ type RedisCacheTestItem struct { I int } -func mockedCache() (cache.RedisCache, redismock.ClientMock) { - db, mock := redismock.NewClientMock() - c := cache.NewRedisCache(db) - - return c, mock -} - -func TestRedisCache_Set(t *testing.T) { - t.Parallel() - var key = t.Name() + "redis_key" - c, mock := mockedCache() - mock.Regexp().ExpectSet(key, `.*`, time.Hour).SetVal("OK") - - value := RedisCacheTestItem{ - S: "sss", - I: 2, - } - - require.NoError(t, c.Set(context.TODO(), key, value, time.Hour)) - - if err := mock.ExpectationsWereMet(); err != nil { - t.Error(err) - } -} - -func TestRedisCache_Get_Nil(t *testing.T) { - t.Parallel() - - var key = t.Name() + "redis_key" - c, mock := mockedCache() - mock.Regexp().ExpectGet(key).RedisNil() - - var result RedisCacheTestItem - - ok, err := c.Get(context.TODO(), key, &result) - require.NoError(t, err) - require.False(t, ok) - - if err := mock.ExpectationsWereMet(); err != nil { - t.Error(err) - } -} - -func TestRedisCache_Get_Cached(t *testing.T) { - t.Parallel() - - var key = t.Name() + "redis_key" - value := RedisCacheTestItem{ - S: "sss", - I: 2, - } - - c, mock := mockedCache() - encoded, err := json.Marshal(value) - require.NoError(t, err) - - mock.Regexp().ExpectGet(key).SetVal(string(encoded)) - - var result RedisCacheTestItem - - ok, err := c.Get(context.TODO(), key, &result) - require.NoError(t, err) - require.True(t, ok) - - require.Equal(t, value, result) - - if err := mock.ExpectationsWereMet(); err != nil { - t.Error(err) - } -} - -func TestRedisCache_Get_Broken(t *testing.T) { - t.Parallel() - - var key = t.Name() + "redis_key" - c, mock := mockedCache() - - mock.Regexp().ExpectGet(key).SetVal("some random broken content") - mock.Regexp().ExpectDel(key).SetVal(1) - - var result RedisCacheTestItem - - ok, err := c.Get(context.TODO(), key, &result) - require.NoError(t, err) - require.False(t, ok) - - if err := mock.ExpectationsWereMet(); err != nil { - t.Error(err) - } -} - func TestRedisCache_Real(t *testing.T) { t.Parallel() var key = t.Name() + "redis_key" - db := test.GetRedis(t) - db.Del(context.TODO(), key) + r := test.GetRedis(t) + require.NoError(t, r.Do(context.TODO(), r.B().Del().Key(key).Build()).Error()) - c := cache.NewRedisCache(db) + c := cache.NewRedisCache(r) var data = RedisCacheTestItem{S: "ss", I: 5} require.NoError(t, c.Set(context.TODO(), key, data, time.Hour)) @@ -146,16 +54,16 @@ func TestRedisCache_Real(t *testing.T) { func TestRedisCache_Del(t *testing.T) { t.Parallel() - var key = t.Name() + "redis_test " + var key = fmt.Sprintln(t.Name(), "redis_test", time.Now()) - db := test.GetRedis(t) - require.NoError(t, db.Set(context.Background(), key, "", 0).Err()) + r := test.GetRedis(t) + require.NoError(t, r.Do(context.TODO(), r.B().Set().Key(key).Value("").Build()).Error()) - c := cache.NewRedisCache(db) + c := cache.NewRedisCache(r) require.NoError(t, c.Del(context.Background(), key)) - v, err := db.Exists(context.Background(), key).Result() + exist, err := r.Do(context.TODO(), r.B().Exists().Key(key).Build()).AsBool() require.NoError(t, err) - require.True(t, v == 0) + require.False(t, exist) } diff --git a/internal/pkg/cache/serialize.go b/internal/pkg/cache/serialize.go index 5110d84ae..6ca0cd2b9 100644 --- a/internal/pkg/cache/serialize.go +++ b/internal/pkg/cache/serialize.go @@ -20,15 +20,6 @@ import ( "github.com/trim21/errgo" ) -func marshalBytes(v any) ([]byte, error) { - b, err := json.Marshal(v) - if err != nil { - return nil, errgo.Wrap(err, "json.Marshal") - } - - return b, nil -} - func unmarshalBytes(b []byte, v any) error { err := json.Unmarshal(b, v) if err != nil { diff --git a/internal/pkg/driver/mysql.go b/internal/pkg/driver/mysql.go index 480ec3a54..03b65a5de 100644 --- a/internal/pkg/driver/mysql.go +++ b/internal/pkg/driver/mysql.go @@ -31,7 +31,8 @@ import ( var setLoggerOnce = sync.Once{} -func NewMysqlConnectionPool(c config.AppConfig) (*sql.DB, error) { +//nolint:stylecheck +func NewMysqlSqlDB(c config.AppConfig) (*sql.DB, error) { setLoggerOnce.Do(func() { _ = mysql.SetLogger(logger.StdAt(zap.ErrorLevel)) }) diff --git a/internal/pkg/driver/redis.go b/internal/pkg/driver/redis.go index 9eb4e3eaf..ea5d378fa 100644 --- a/internal/pkg/driver/redis.go +++ b/internal/pkg/driver/redis.go @@ -16,9 +16,12 @@ package driver import ( "context" + "fmt" + "net/url" "time" "github.com/redis/go-redis/v9" + "github.com/redis/rueidis" "github.com/trim21/errgo" "go.uber.org/zap" @@ -63,3 +66,21 @@ func NewRedisClientWithMetrics(c config.AppConfig) (*redis.Client, error) { return cli, nil } + +func NewRueidisClient(c config.AppConfig) (rueidis.Client, error) { + u, err := url.Parse(c.RedisURL) + if err != nil { + return nil, err + } + + password, _ := u.User.Password() + cli, err := rueidis.NewClient(rueidis.ClientOption{ + InitAddress: []string{fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, + Password: password, + }) + if err != nil { + return cli, err + } + + return cli, nil +} diff --git a/internal/pkg/test/fx.go b/internal/pkg/test/fx.go new file mode 100644 index 000000000..4a663d694 --- /dev/null +++ b/internal/pkg/test/fx.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package test + +import ( + "encoding/json" + "testing" + + "github.com/go-resty/resty/v2" + "github.com/stretchr/testify/require" + "go.uber.org/fx" + "go.uber.org/zap" + + "github.com/bangumi/server/config" + "github.com/bangumi/server/dal" + "github.com/bangumi/server/internal/pkg/cache" + "github.com/bangumi/server/internal/pkg/driver" +) + +func Fx(tb testing.TB, target ...fx.Option) { + tb.Helper() + err := fx.New( + append(target, fx.NopLogger, + + // driver and connector + fx.Provide( + config.AppConfigReader(config.AppTypeHTTP), + driver.NewRedisClient, // redis + driver.NewRueidisClient, // redis + driver.NewMysqlSqlDB, // mysql + func() *resty.Client { + httpClient := resty.New().SetJSONEscapeHTML(false) + httpClient.JSONUnmarshal = json.Unmarshal + httpClient.JSONMarshal = json.Marshal + return httpClient + }, + ), + + dal.Module, + + fx.Provide(cache.NewRedisCache, zap.NewNop), + )..., + ).Err() + + require.NoError(tb, err) +} diff --git a/internal/pkg/test/gorm.go b/internal/pkg/test/gorm.go index 7c90a4eb2..0424f24af 100644 --- a/internal/pkg/test/gorm.go +++ b/internal/pkg/test/gorm.go @@ -56,7 +56,7 @@ func GetGorm(tb testing.TB) *gorm.DB { func newGorm(tb testing.TB, c config.AppConfig) (*gorm.DB, error) { tb.Helper() - conn, err := driver.NewMysqlConnectionPool(c) + conn, err := driver.NewMysqlSqlDB(c) if err != nil { return nil, errgo.Wrap(err, "sql.Open") } diff --git a/internal/pkg/test/redis.go b/internal/pkg/test/redis.go index 1ae557634..ab61e0969 100644 --- a/internal/pkg/test/redis.go +++ b/internal/pkg/test/redis.go @@ -17,22 +17,15 @@ package test import ( "testing" - "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/require" - - "github.com/bangumi/server/config" - "github.com/bangumi/server/internal/pkg/driver" + "github.com/redis/rueidis" + "go.uber.org/fx" ) -func GetRedis(tb testing.TB) *redis.Client { +func GetRedis(tb testing.TB) (r rueidis.Client) { tb.Helper() - RequireEnv(tb, EnvRedis) - cfg, err := config.NewAppConfig() - require.NoError(tb, err) - db, err := driver.NewRedisClient(cfg) - require.NoError(tb, err) + Fx(tb, fx.Populate(&r)) - return db + return } diff --git a/internal/pkg/test/web.go b/internal/pkg/test/web.go index 1984e3b15..79cca3023 100644 --- a/internal/pkg/test/web.go +++ b/internal/pkg/test/web.go @@ -43,6 +43,7 @@ import ( "github.com/bangumi/server/internal/revision" "github.com/bangumi/server/internal/search" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/internal/timeline" "github.com/bangumi/server/internal/user" "github.com/bangumi/server/web" @@ -56,6 +57,7 @@ type Mock struct { PersonRepo person.Repo CharacterRepo character.Repo AuthRepo auth.Repo + TagRepo tag.Repo AuthService auth.Service EpisodeRepo episode.Repo UserRepo user.Repo @@ -108,6 +110,7 @@ func GetWebApp(tb testing.TB, m Mock) *echo.Echo { MockNoticationRepo(m.NotificationRepo), MockSessionManager(m.SessionManager), MockTimeLineSrv(m.TimeLineSrv), + MockTagRepo(m.TagRepo), // don't need a default mock for these repositories. fx.Provide(func() collections.Repo { return m.CollectionRepo }), @@ -237,6 +240,18 @@ func MockAuthRepo(m auth.Repo) fx.Option { return fx.Provide(func() auth.Repo { return m }) } +func MockTagRepo(m tag.Repo) fx.Option { + if m == nil { + mocker := &mocks.TagRepo{} + mocker.EXPECT().Get(mock.Anything, mock.Anything).Return([]tag.Tag{}, nil) + mocker.EXPECT().GetByIDs(mock.Anything, mock.Anything).Return(map[model.SubjectID][]tag.Tag{}, nil) + + m = mocker + } + + return fx.Provide(func() tag.Repo { return m }, func() tag.CachedRepo { return m }) +} + func MockAuthService(m auth.Service) fx.Option { if m == nil { return fx.Provide(auth.NewService) diff --git a/internal/subject/mysq_repository_compat.go b/internal/subject/mysq_repository_compat.go index a1d761142..b3c2ef2b4 100644 --- a/internal/subject/mysq_repository_compat.go +++ b/internal/subject/mysq_repository_compat.go @@ -24,8 +24,8 @@ import ( type Tag struct { Name *string `php:"tag_name"` - Count int `php:"result,string"` - TotalCount int `php:"tag_results,string"` + Count uint `php:"result,string"` + TotalCount uint `php:"tag_results,string"` } func ParseTags(b []byte) ([]model.Tag, error) { diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go new file mode 100644 index 000000000..71570723e --- /dev/null +++ b/internal/tag/cache_repo.go @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package tag + +import ( + "context" + "time" + + "github.com/samber/lo" + "github.com/trim21/errgo" + "go.uber.org/zap" + + "github.com/bangumi/server/internal/cachekey" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/cache" +) + +func NewCachedRepo(c cache.RedisCache, r Repo, log *zap.Logger) CachedRepo { + return cacheRepo{cache: c, repo: r, log: log.Named("subject.CachedRepo")} +} + +var _ CachedRepo = cacheRepo{} + +type cacheRepo struct { + cache cache.RedisCache + repo Repo + log *zap.Logger +} + +type cachedTags struct { + ID model.SubjectID + Tags []Tag +} + +func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { + var key = cachekey.SubjectMetaTag(id) + + var s cachedTags + ok, err := r.cache.Get(ctx, key, &s) + if err != nil { + return s.Tags, errgo.Wrap(err, "cache.Get") + } + + if ok { + return s.Tags, nil + } + + tags, err := r.repo.Get(ctx, id) + if err != nil { + return tags, err + } + + if e := r.cache.Set(ctx, key, cachedTags{ + ID: id, + Tags: tags, + }, time.Minute); e != nil { + r.log.Error("can't set response to cache", zap.Error(e)) + } + + return tags, nil +} + +func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { + var tags []cachedTags + err := cache.MGet(r.cache, ctx, lo.Map(ids, func(item model.SubjectID, index int) string { + return cachekey.SubjectMetaTag(item) + }), &tags) + if err != nil { + return nil, errgo.Wrap(err, "cache.MGet") + } + + result := make(map[model.SubjectID][]Tag, len(ids)) + for _, tag := range tags { + result[tag.ID] = tag.Tags + } + + var missing = make([]model.SubjectID, 0, len(ids)) + for _, id := range ids { + if _, ok := result[id]; !ok { + missing = append(missing, id) + } + } + + missingFromCache, err := r.repo.GetByIDs(ctx, missing) + if err != nil { + return nil, err + } + for id, tag := range missingFromCache { + result[id] = tag + err = r.cache.Set(ctx, cachekey.SubjectMetaTag(id), cachedTags{ + ID: id, + Tags: tag, + }, time.Hour) + if err != nil { + return nil, errgo.Wrap(err, "cache.Set") + } + } + + return result, nil +} diff --git a/internal/tag/cache_repo_test.go b/internal/tag/cache_repo_test.go new file mode 100644 index 000000000..cbb61927b --- /dev/null +++ b/internal/tag/cache_repo_test.go @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package tag_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/fx" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/test" + "github.com/bangumi/server/internal/tag" +) + +func getCacheRepo(t *testing.T) tag.CachedRepo { + t.Helper() + + var r tag.CachedRepo + + test.Fx(t, fx.Provide(tag.NewCachedRepo, tag.NewMysqlRepo), fx.Populate(&r)) + + return r +} + +func TestCacheGet(t *testing.T) { + test.RequireEnv(t, test.EnvMysql, test.EnvRedis) + t.Parallel() + + repo := getCacheRepo(t) + + _, err := repo.Get(context.Background(), 8) + require.NoError(t, err) +} + +func TestCacheGetTags(t *testing.T) { + test.RequireEnv(t, test.EnvMysql, test.EnvRedis) + t.Parallel() + + repo := getCacheRepo(t) + + _, err := repo.GetByIDs(context.Background(), []model.SubjectID{1, 2, 8}) + require.NoError(t, err) +} diff --git a/internal/subject/repo2.go b/internal/tag/domain.go similarity index 54% rename from internal/subject/repo2.go rename to internal/tag/domain.go index 32f36ee71..375a7e1ce 100644 --- a/internal/subject/repo2.go +++ b/internal/tag/domain.go @@ -12,4 +12,36 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see -package subject +package tag + +import ( + "context" + + "github.com/bangumi/server/internal/model" +) + +// CatSubject 条目tag. +const CatSubject = 0 + +// CatMeta 官方tag. +const CatMeta = 3 + +type Tag struct { + Name string + Count uint + // TotalCount count for all tags including all subject + TotalCount uint +} + +type CachedRepo interface { + read +} + +type Repo interface { + read +} + +type read interface { + Get(ctx context.Context, id model.SubjectID) ([]Tag, error) + GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) +} diff --git a/internal/tag/mysql_repo.go b/internal/tag/mysql_repo.go new file mode 100644 index 000000000..475bb5cb8 --- /dev/null +++ b/internal/tag/mysql_repo.go @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package tag + +import ( + "context" + + "github.com/jmoiron/sqlx" + "go.uber.org/zap" + + "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/internal/model" +) + +func NewMysqlRepo(q *query.Query, log *zap.Logger, db *sqlx.DB) (Repo, error) { + return mysqlRepo{q: q, log: log.Named("tag.mysqlRepo"), db: db}, nil +} + +type mysqlRepo struct { + q *query.Query + log *zap.Logger + db *sqlx.DB +} + +func (r mysqlRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { + var s []struct { + Tid uint `db:"tlt_tid"` + Name string `db:"tag_name"` + TotalCount uint `db:"tag_results"` + } + + err := r.db.SelectContext(ctx, &s, ` + select tlt_tid, tag_name, tag_results + from chii_tag_neue_list + inner join chii_tag_neue_index on tlt_tid = tag_id and tlt_type = tag_type + where tlt_uid = 0 and tag_cat = ? and tlt_mid = ? + `, CatSubject, id) + if err != nil { + return nil, err + } + + tags := make([]Tag, len(s)) + for i, t := range s { + tags[i] = Tag{ + Name: t.Name, + TotalCount: t.TotalCount, + } + } + + return tags, nil +} + +func (r mysqlRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { + var s []struct { + Tid uint `db:"tlt_tid"` + Name string `db:"tag_name"` + TotalCount uint `db:"tag_results"` + Mid model.SubjectID `db:"tlt_mid"` + } + + q, v, err := sqlx.In(` + select tlt_tid, tag_name, tag_results, tlt_mid + from chii_tag_neue_list + inner join chii_tag_neue_index on tlt_tid = tag_id and tlt_type = tag_type + where tlt_uid = 0 and tag_cat = ? and tlt_mid IN (?) + `, CatSubject, ids) + if err != nil { + return nil, err + } + + err = r.db.SelectContext(ctx, &s, q, v...) + if err != nil { + return nil, err + } + + tags := make(map[model.SubjectID][]Tag, len(s)) + for _, t := range s { + tags[t.Mid] = append(tags[t.Mid], Tag{ + Name: t.Name, + TotalCount: t.TotalCount, + }) + } + + return tags, nil +} diff --git a/internal/tag/mysql_repo_test.go b/internal/tag/mysql_repo_test.go new file mode 100644 index 000000000..31cc1585d --- /dev/null +++ b/internal/tag/mysql_repo_test.go @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package tag_test + +import ( + "context" + "testing" + + "github.com/jmoiron/sqlx" + "github.com/samber/lo" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/test" + "github.com/bangumi/server/internal/tag" +) + +func getRepo(t *testing.T) tag.Repo { + t.Helper() + q := query.Use(test.GetGorm(t)) + repo, err := tag.NewMysqlRepo(q, zap.NewNop(), sqlx.NewDb(lo.Must(q.DB().DB()), "mysql")) + require.NoError(t, err) + + return repo +} + +func TestGet(t *testing.T) { + test.RequireEnv(t, test.EnvMysql) + t.Parallel() + + repo := getRepo(t) + + _, err := repo.Get(context.Background(), 8) + require.NoError(t, err) +} + +func TestGetTags(t *testing.T) { + test.RequireEnv(t, test.EnvMysql) + t.Parallel() + + repo := getRepo(t) + + _, err := repo.GetByIDs(context.Background(), []model.SubjectID{1, 2, 8}) + require.NoError(t, err) +} diff --git a/web/handler/subject/browse.go b/web/handler/subject/browse.go index ebfb7b5f3..2968a425b 100644 --- a/web/handler/subject/browse.go +++ b/web/handler/subject/browse.go @@ -60,7 +60,7 @@ func (h Subject) Browse(c echo.Context) error { } data := make([]res.SubjectV0, 0, len(subjects)) for _, s := range subjects { - data = append(data, convertModelSubject(s, 0)) + data = append(data, convertModelSubject(s, 0, nil)) } return c.JSON(http.StatusOK, res.Paged{Data: data, Total: count, Limit: page.Limit, Offset: page.Offset}) diff --git a/web/handler/subject/get.go b/web/handler/subject/get.go index e7f0f623a..178842db5 100644 --- a/web/handler/subject/get.go +++ b/web/handler/subject/get.go @@ -20,6 +20,7 @@ import ( "net/http" "github.com/labstack/echo/v4" + "github.com/samber/lo" "github.com/trim21/errgo" "go.uber.org/zap" @@ -31,6 +32,7 @@ import ( "github.com/bangumi/server/internal/pkg/logger" "github.com/bangumi/server/internal/pkg/null" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/pkg/vars" "github.com/bangumi/server/pkg/wiki" "github.com/bangumi/server/web/accessor" @@ -66,7 +68,12 @@ func (h Subject) Get(c echo.Context) error { return errgo.Wrap(err, "episode.Count") } - return c.JSON(http.StatusOK, convertModelSubject(s, totalEpisode)) + metaTags, err := h.tag.Get(c.Request().Context(), s.ID) + if err != nil { + return err + } + + return c.JSON(http.StatusOK, convertModelSubject(s, totalEpisode, metaTags)) } func platformString(s model.Subject) *string { @@ -114,7 +121,7 @@ func (h Subject) GetImage(c echo.Context) error { return c.Redirect(http.StatusFound, l) } -func convertModelSubject(s model.Subject, totalEpisode int64) res.SubjectV0 { +func convertModelSubject(s model.Subject, totalEpisode int64, metaTags []tag.Tag) res.SubjectV0 { return res.SubjectV0{ TotalEpisodes: totalEpisode, ID: s.ID, @@ -128,6 +135,13 @@ func convertModelSubject(s model.Subject, totalEpisode int64) res.SubjectV0 { Volumes: s.Volumes, Redirect: s.Redirect, Eps: s.Eps, + MetaTags: lo.Map(metaTags, func(item tag.Tag, index int) res.SubjectTag { + return res.SubjectTag{ + Name: item.Name, + Count: item.Count, + TotalCont: item.TotalCount, + } + }), Tags: slice.Map(s.Tags, func(tag model.Tag) res.SubjectTag { return res.SubjectTag{ Name: tag.Name, diff --git a/web/handler/subject/get_test.go b/web/handler/subject/get_test.go index a5a520450..ee531eaea 100644 --- a/web/handler/subject/get_test.go +++ b/web/handler/subject/get_test.go @@ -31,6 +31,7 @@ import ( "github.com/bangumi/server/internal/pkg/null" "github.com/bangumi/server/internal/pkg/test" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/web/accessor" subjectHandler "github.com/bangumi/server/web/handler/subject" "github.com/bangumi/server/web/internal/ctxkey" @@ -56,7 +57,10 @@ func TestSubject_Get(t *testing.T) { ep := mocks.NewEpisodeRepo(t) ep.EXPECT().Count(mock.Anything, subjectID, mock.Anything).Return(3, nil) - s, err := subjectHandler.New(nil, m, nil, nil, ep) + tagRepo := mocks.NewTagRepo(t) + tagRepo.EXPECT().Get(mock.Anything, mock.Anything).Return([]tag.Tag{}, nil) + + s, err := subjectHandler.New(nil, m, nil, nil, ep, tagRepo) require.NoError(t, err) s.Routes(g) diff --git a/web/handler/subject/subject.go b/web/handler/subject/subject.go index d7cbf6055..aaa64c008 100644 --- a/web/handler/subject/subject.go +++ b/web/handler/subject/subject.go @@ -21,6 +21,7 @@ import ( "github.com/bangumi/server/internal/episode" "github.com/bangumi/server/internal/person" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" ) type Subject struct { @@ -28,6 +29,7 @@ type Subject struct { episode episode.Repo personRepo person.Repo subject subject.Repo + tag tag.CachedRepo c character.Repo } @@ -37,6 +39,7 @@ func New( personRepo person.Repo, c character.Repo, episode episode.Repo, + tag tag.CachedRepo, ) (Subject, error) { return Subject{ c: c, @@ -44,6 +47,7 @@ func New( personRepo: personRepo, subject: subject, person: p, + tag: tag, }, nil } diff --git a/web/res/subject.go b/web/res/subject.go index ba3bde9d4..8fb78cfb1 100644 --- a/web/res/subject.go +++ b/web/res/subject.go @@ -29,8 +29,9 @@ const defaultShortSummaryLength = 120 type v0wiki = []any type SubjectTag struct { - Name string `json:"name"` - Count int `json:"count"` + Name string `json:"name"` + Count uint `json:"count"` + TotalCont uint `json:"total_cont"` } type SubjectV0 struct { @@ -47,6 +48,7 @@ type SubjectV0 struct { Collection SubjectCollectionStat `json:"collection"` ID model.SubjectID `json:"id"` Eps uint32 `json:"eps"` + MetaTags []SubjectTag `json:"meta_tags"` Volumes uint32 `json:"volumes"` Series bool `json:"series"` Locked bool `json:"locked"` From d0d0fd4dcc05d381451251c5c22cc1894cc9d71d Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 04:46:59 +0800 Subject: [PATCH 167/240] fix: ignore context cancel error --- web/error.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/error.go b/web/error.go index 94daeff37..caaffcee8 100644 --- a/web/error.go +++ b/web/error.go @@ -15,6 +15,7 @@ package web import ( + "context" "errors" "net/http" @@ -74,6 +75,10 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { } } + if errors.Is(err, context.Canceled) { + return + } + log.Error("unexpected error", zap.Error(err), zap.String("path", c.Path()), From 0a5f9668039f43faad0301a93dfeea6d8e40eb1d Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 05:07:33 +0800 Subject: [PATCH 168/240] refactor: replace redis client --- canal/canal.go | 2 +- canal/event.go | 6 +- canal/on_user.go | 11 +- cmd/web/cmd.go | 5 +- go.mod | 3 - go.sum | 390 ----------------------------------- internal/metrics/redis.go | 28 --- internal/pkg/driver/redis.go | 46 +---- internal/pkg/test/fx.go | 1 - 9 files changed, 15 insertions(+), 477 deletions(-) delete mode 100644 internal/metrics/redis.go diff --git a/canal/canal.go b/canal/canal.go index 3b57ec5e6..bb33c7d27 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -60,7 +60,7 @@ func Main() error { // driver and connector fx.Provide( driver.NewMysqlSqlDB, - driver.NewRedisClient, logger.Copy, cache.NewRedisCache, + driver.NewRueidisClient, logger.Copy, cache.NewRedisCache, subject.NewMysqlRepo, search.New, session.NewMysqlRepo, session.New, driver.NewS3, diff --git a/canal/event.go b/canal/event.go index 67efec00d..e3cf10955 100644 --- a/canal/event.go +++ b/canal/event.go @@ -20,7 +20,7 @@ import ( "sync/atomic" "github.com/aws/aws-sdk-go-v2/service/s3" - "github.com/redis/go-redis/v9" + "github.com/redis/rueidis" "github.com/trim21/errgo" "go.uber.org/zap" @@ -35,7 +35,7 @@ func newEventHandler( log *zap.Logger, appConfig config.AppConfig, session session.Manager, - redis *redis.Client, + redis rueidis.Client, stream Stream, search search.Client, s3 *s3.Client, @@ -59,7 +59,7 @@ type eventHandler struct { search search.Client stream Stream s3 *s3.Client // optional, check nil before use - redis *redis.Client + redis rueidis.Client } func (e *eventHandler) start() error { diff --git a/canal/on_user.go b/canal/on_user.go index 990a4044d..5447ae2ef 100644 --- a/canal/on_user.go +++ b/canal/on_user.go @@ -24,6 +24,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/redis/rueidis" "github.com/samber/lo" "github.com/trim21/errgo" "go.uber.org/zap" @@ -60,10 +61,12 @@ func (e *eventHandler) OnUserChange(ctx context.Context, key json.RawMessage, pa } if before.NewNotify != after.NewNotify { - e.redis.Publish(ctx, fmt.Sprintf("event-user-notify-%d", k.ID), redisUserChannel{ - UserID: k.ID, - NewNotify: after.NewNotify, - }) + e.redis.Do(ctx, e.redis.B().Publish(). + Channel(fmt.Sprintf("event-user-notify-%d", k.ID)). + Message(rueidis.JSON(redisUserChannel{ + UserID: k.ID, + NewNotify: after.NewNotify, + })).Build()) } if before.Avatar != after.Avatar { diff --git a/cmd/web/cmd.go b/cmd/web/cmd.go index 4e3ff73b2..080542909 100644 --- a/cmd/web/cmd.go +++ b/cmd/web/cmd.go @@ -65,9 +65,8 @@ func start() error { // driver and connector fx.Provide( config.AppConfigReader(config.AppTypeHTTP), - driver.NewRedisClientWithMetrics, // redis - driver.NewMysqlSqlDB, // mysql - driver.NewRueidisClient, + driver.NewRueidisClient, // redis + driver.NewMysqlSqlDB, // mysql func() *resty.Client { httpClient := resty.New().SetJSONEscapeHTML(false) httpClient.JSONUnmarshal = json.Unmarshal diff --git a/go.mod b/go.mod index b9a8606e7..c2cc018f5 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,6 @@ require ( github.com/meilisearch/meilisearch-go v0.28.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.20.4 - github.com/redis/go-redis/v9 v9.6.1 github.com/redis/rueidis v1.0.47 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 @@ -32,7 +31,6 @@ require ( github.com/stretchr/testify v1.9.0 github.com/trim21/errgo v0.0.3 github.com/trim21/go-phpserialize v0.1.0-alpha.5 - github.com/trim21/go-redis-prometheus v0.0.0 github.com/trim21/htest v0.0.4 github.com/trim21/pkg v0.0.3 go.uber.org/fx v1.23.0 @@ -67,7 +65,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect diff --git a/go.sum b/go.sum index d67908494..7852e99c3 100644 --- a/go.sum +++ b/go.sum @@ -1,32 +1,10 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= @@ -51,76 +29,31 @@ github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 h1:xxHGZ+wUgZNACQmxtdvP5tgzfsxGS github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= -github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= -github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= -github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= -github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= -github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= -github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elliotchance/phpserialize v1.4.0 h1:cAp/9+KSnEbUC8oYCE32n2n84BeW8HOY3HMDI8hG2OY= github.com/elliotchance/phpserialize v1.4.0/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -131,15 +64,9 @@ github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27 github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= @@ -148,71 +75,14 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4= github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= @@ -229,38 +99,20 @@ github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= @@ -273,168 +125,63 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= github.com/meilisearch/meilisearch-go v0.28.0 h1:f3XJ66ZM+R8bANAOLqsjvoq/HhQNpVJPYoNt6QgNzME= github.com/meilisearch/meilisearch-go v0.28.0/go.mod h1:Szcc9CaDiKIfjdgdt49jlmDKpEzjD+x+b6Y6heMdlQ0= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= -github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= -github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/redis/rueidis v1.0.47 h1:41UdeXOo4eJuW+cfpUJuLtVGyO0QJY3A2rEYgJWlfHs= github.com/redis/rueidis v1.0.47/go.mod h1:by+34b0cFXndxtYmPAHpoTHO5NkosDlBvhexoTURIxM= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0= github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -442,21 +189,16 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trim21/errgo v0.0.3 h1:q0cUPTs+4c5NxByA4f0HUGRvlNyBlUtdxFiTKQdTE68= github.com/trim21/errgo v0.0.3/go.mod h1:AH1KzogdvSkSPXbZq9QAuqSt1L1Eu5W8eYK32zPYv9s= github.com/trim21/go-phpserialize v0.1.0-alpha.5 h1:bMsUpfwAgPggQzDKdafNBvkPWDCMfzlvH30MWzI/SYg= github.com/trim21/go-phpserialize v0.1.0-alpha.5/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= -github.com/trim21/go-redis-prometheus v0.0.0 h1:9svVIZkKaDGE1bSRbtTQdsKBzW+QEWfwc35QIF8JsfA= -github.com/trim21/go-redis-prometheus v0.0.0/go.mod h1:UTXPI/fofnsXF9/X/WtvwhAdbSOBVjLg17xDjQj9VgU= github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= github.com/trim21/htest v0.0.4/go.mod h1:W+zaYAGCBqx38eMrMGvXrALnbcXR6OBtZiRiHahgo+E= github.com/trim21/pkg v0.0.3 h1:uAqfoFmmYiIMOSretKj8/tvrQs3KG57020Ff0cx8UtE= github.com/trim21/pkg v0.0.3/go.mod h1:JrRIFidkCLeuU5j0vBP5ZN0NOp2JavagHZNr4D3AH6Q= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= @@ -467,76 +209,33 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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/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.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 h1:lGdhQUN/cnWdSH3291CUuxSEqc+AsGTiDxPP3r2J0l4= go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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/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= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -544,38 +243,12 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -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= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -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= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -593,7 +266,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= 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= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= @@ -603,82 +275,26 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -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/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -708,12 +324,6 @@ gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU= gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE= gorm.io/plugin/soft_delete v1.2.1 h1:qx9D/c4Xu6w5KT8LviX8DgLcB9hkKl6JC9f44Tj7cGU= gorm.io/plugin/soft_delete v1.2.1/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ= olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/metrics/redis.go b/internal/metrics/redis.go deleted file mode 100644 index 12fa990bb..000000000 --- a/internal/metrics/redis.go +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see - -package metrics - -import ( - "github.com/redis/go-redis/v9" - redisprom "github.com/trim21/go-redis-prometheus" -) - -func RedisHook(instance string) redis.Hook { - return redisprom.NewHook( - redisprom.WithNamespace("chii"), - redisprom.WithDurationBuckets([]float64{.001, .002, .003, .004, .005, .0075, .01, .05, .1, .3, .5, .75, 1, 2}), - redisprom.WithInstanceName(instance), - ) -} diff --git a/internal/pkg/driver/redis.go b/internal/pkg/driver/redis.go index ea5d378fa..8b943d7ba 100644 --- a/internal/pkg/driver/redis.go +++ b/internal/pkg/driver/redis.go @@ -15,58 +15,14 @@ package driver import ( - "context" "fmt" "net/url" - "time" - "github.com/redis/go-redis/v9" "github.com/redis/rueidis" - "github.com/trim21/errgo" - "go.uber.org/zap" "github.com/bangumi/server/config" - "github.com/bangumi/server/internal/metrics" - "github.com/bangumi/server/internal/pkg/logger" ) -const defaultRedisPoolSize = 4 - -// NewRedisClient create a redis client -// use [test.GetRedis] in tests. -func NewRedisClient(c config.AppConfig) (*redis.Client, error) { - redisOptions, err := redis.ParseURL(c.RedisURL) - if err != nil { - logger.Fatal("redis: failed to parse redis url", zap.String("url", c.RedisURL)) - } - - if redisOptions.PoolSize == 0 { - redisOptions.PoolSize = defaultRedisPoolSize - } - - cli := redis.NewClient(redisOptions) - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - if err := cli.Ping(ctx).Err(); err != nil { - return nil, errgo.Wrap(err, "redis: failed to ping") - } - - return cli, nil -} - -func NewRedisClientWithMetrics(c config.AppConfig) (*redis.Client, error) { - cli, err := NewRedisClient(c) - if err != nil { - return cli, err - } - - cli.AddHook(metrics.RedisHook(cli.Options().Addr)) - - return cli, nil -} - func NewRueidisClient(c config.AppConfig) (rueidis.Client, error) { u, err := url.Parse(c.RedisURL) if err != nil { @@ -77,6 +33,8 @@ func NewRueidisClient(c config.AppConfig) (rueidis.Client, error) { cli, err := rueidis.NewClient(rueidis.ClientOption{ InitAddress: []string{fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, Password: password, + // 1<<2 = 4 connection for each node + PipelineMultiplex: 2, }) if err != nil { return cli, err diff --git a/internal/pkg/test/fx.go b/internal/pkg/test/fx.go index 4a663d694..6db211382 100644 --- a/internal/pkg/test/fx.go +++ b/internal/pkg/test/fx.go @@ -37,7 +37,6 @@ func Fx(tb testing.TB, target ...fx.Option) { // driver and connector fx.Provide( config.AppConfigReader(config.AppTypeHTTP), - driver.NewRedisClient, // redis driver.NewRueidisClient, // redis driver.NewMysqlSqlDB, // mysql func() *resty.Client { From b0f0e18d02b6437cd9ebbd7f42699444b1815e91 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 05:38:54 +0800 Subject: [PATCH 169/240] refactor: fix redis mget --- internal/mocks/RedisCache.go | 32 ++++++++++----------- internal/pkg/cache/noop.go | 4 +-- internal/pkg/cache/redis.go | 54 ++++++++++++++++++++++++++++++------ internal/tag/cache_repo.go | 2 +- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/internal/mocks/RedisCache.go b/internal/mocks/RedisCache.go index 6728d19ed..6a08e0216 100644 --- a/internal/mocks/RedisCache.go +++ b/internal/mocks/RedisCache.go @@ -4,12 +4,9 @@ package mocks import ( context "context" - - cache "github.com/bangumi/server/internal/pkg/cache" + time "time" mock "github.com/stretchr/testify/mock" - - time "time" ) // RedisCache is an autogenerated mock type for the RedisCache type @@ -144,19 +141,19 @@ func (_c *RedisCache_Get_Call) RunAndReturn(run func(context.Context, string, in return _c } -// MGet provides a mock function with given fields: ctx, key -func (_m *RedisCache) MGet(ctx context.Context, key []string) cache.MGetResult { - ret := _m.Called(ctx, key) +// MGet provides a mock function with given fields: ctx, key, result +func (_m *RedisCache) MGet(ctx context.Context, key []string, result interface{}) error { + ret := _m.Called(ctx, key, result) if len(ret) == 0 { panic("no return value specified for MGet") } - var r0 cache.MGetResult - if rf, ok := ret.Get(0).(func(context.Context, []string) cache.MGetResult); ok { - r0 = rf(ctx, key) + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []string, interface{}) error); ok { + r0 = rf(ctx, key, result) } else { - r0 = ret.Get(0).(cache.MGetResult) + r0 = ret.Error(0) } return r0 @@ -170,23 +167,24 @@ type RedisCache_MGet_Call struct { // MGet is a helper method to define mock.On call // - ctx context.Context // - key []string -func (_e *RedisCache_Expecter) MGet(ctx interface{}, key interface{}) *RedisCache_MGet_Call { - return &RedisCache_MGet_Call{Call: _e.mock.On("MGet", ctx, key)} +// - result interface{} +func (_e *RedisCache_Expecter) MGet(ctx interface{}, key interface{}, result interface{}) *RedisCache_MGet_Call { + return &RedisCache_MGet_Call{Call: _e.mock.On("MGet", ctx, key, result)} } -func (_c *RedisCache_MGet_Call) Run(run func(ctx context.Context, key []string)) *RedisCache_MGet_Call { +func (_c *RedisCache_MGet_Call) Run(run func(ctx context.Context, key []string, result interface{})) *RedisCache_MGet_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]string)) + run(args[0].(context.Context), args[1].([]string), args[2].(interface{})) }) return _c } -func (_c *RedisCache_MGet_Call) Return(_a0 cache.MGetResult) *RedisCache_MGet_Call { +func (_c *RedisCache_MGet_Call) Return(_a0 error) *RedisCache_MGet_Call { _c.Call.Return(_a0) return _c } -func (_c *RedisCache_MGet_Call) RunAndReturn(run func(context.Context, []string) cache.MGetResult) *RedisCache_MGet_Call { +func (_c *RedisCache_MGet_Call) RunAndReturn(run func(context.Context, []string, interface{}) error) *RedisCache_MGet_Call { _c.Call.Return(run) return _c } diff --git a/internal/pkg/cache/noop.go b/internal/pkg/cache/noop.go index 8f9d2db59..0555f9eaf 100644 --- a/internal/pkg/cache/noop.go +++ b/internal/pkg/cache/noop.go @@ -37,6 +37,6 @@ func (n noop) Del(context.Context, ...string) error { return nil } -func (n noop) MGet(ctx context.Context, key []string) MGetResult { - return MGetResult{} +func (n noop) MGet(ctx context.Context, key []string, result any) error { + return nil } diff --git a/internal/pkg/cache/redis.go b/internal/pkg/cache/redis.go index f523a51df..3bfa9cc08 100644 --- a/internal/pkg/cache/redis.go +++ b/internal/pkg/cache/redis.go @@ -16,6 +16,7 @@ package cache import ( "context" + "reflect" "time" "github.com/redis/rueidis" @@ -34,11 +35,13 @@ type RedisCache interface { Get(ctx context.Context, key string, value any) (bool, error) Set(ctx context.Context, key string, value any, ttl time.Duration) error Del(ctx context.Context, keys ...string) error - MGet(ctx context.Context, key []string) MGetResult -} -type MGetResult struct { - rueidis.RedisResult + // MGet result should be `*[]T` + // for example + // + // var s []struct{} + // cache.MGet(ctx, keys, &s) + MGet(ctx context.Context, key []string, result any) error } // NewRedisCache create a redis backed cache. @@ -74,12 +77,45 @@ func (c redisCache) Get(ctx context.Context, key string, value any) (bool, error return true, nil } -func (c redisCache) MGet(ctx context.Context, keys []string) MGetResult { - return MGetResult{c.ru.Do(ctx, c.ru.B().Mget().Key(keys...).Build())} -} +// MGet result should be `*[]T` +// for example +// +// var s []struct{} +// cache.MGet(ctx, keys, &s) +func (c redisCache) MGet(ctx context.Context, keys []string, result any) error { + results, err := c.ru.Do(ctx, c.ru.B().Mget().Key(keys...).Build()).ToArray() + if err != nil { + if err == rueidis.Nil { + return nil + } + + return errgo.Wrap(err, "redis mget") + } + + // no more ideal way to do this + // reflect.ValueOf(*[]T) + rv := reflect.ValueOf(result) + if !(rv.Kind() == reflect.Ptr && rv.Elem().Kind() == reflect.Slice) { + panic("only allow *[]T as input") + } + + // reflect.ValueOf([]T) + vv := rv.Elem() + + vv.Set(reflect.MakeSlice(rv.Elem().Type(), 0, len(results))) + elementType := rv.Elem().Type().Elem() + for _, message := range results { + var v = reflect.New(elementType) + + e := message.DecodeJSON(v.Interface()) + if e != nil { + continue + } -func MGet[T any](c RedisCache, ctx context.Context, keys []string, value *[]T) error { - return rueidis.DecodeSliceOfJSON(c.MGet(ctx, keys).RedisResult, value) + reflect.Append(vv, v.Elem()) + } + + return nil } func (c redisCache) Set(ctx context.Context, key string, value any, ttl time.Duration) error { diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index 71570723e..b1ca5e190 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -74,7 +74,7 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { var tags []cachedTags - err := cache.MGet(r.cache, ctx, lo.Map(ids, func(item model.SubjectID, index int) string { + err := r.cache.MGet(ctx, lo.Map(ids, func(item model.SubjectID, index int) string { return cachekey.SubjectMetaTag(item) }), &tags) if err != nil { From 1ebab660439bdfbafb4988a08fd8f8f0f91f5b1b Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 05:42:20 +0800 Subject: [PATCH 170/240] fix: meta tags should be []string --- web/handler/subject/get.go | 8 ++------ web/res/subject.go | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/web/handler/subject/get.go b/web/handler/subject/get.go index 178842db5..17a3568a1 100644 --- a/web/handler/subject/get.go +++ b/web/handler/subject/get.go @@ -135,12 +135,8 @@ func convertModelSubject(s model.Subject, totalEpisode int64, metaTags []tag.Tag Volumes: s.Volumes, Redirect: s.Redirect, Eps: s.Eps, - MetaTags: lo.Map(metaTags, func(item tag.Tag, index int) res.SubjectTag { - return res.SubjectTag{ - Name: item.Name, - Count: item.Count, - TotalCont: item.TotalCount, - } + MetaTags: lo.Map(metaTags, func(item tag.Tag, index int) string { + return item.Name }), Tags: slice.Map(s.Tags, func(tag model.Tag) res.SubjectTag { return res.SubjectTag{ diff --git a/web/res/subject.go b/web/res/subject.go index 8fb78cfb1..66300e7b5 100644 --- a/web/res/subject.go +++ b/web/res/subject.go @@ -48,7 +48,7 @@ type SubjectV0 struct { Collection SubjectCollectionStat `json:"collection"` ID model.SubjectID `json:"id"` Eps uint32 `json:"eps"` - MetaTags []SubjectTag `json:"meta_tags"` + MetaTags []string `json:"meta_tags"` Volumes uint32 `json:"volumes"` Series bool `json:"series"` Locked bool `json:"locked"` From 46b11a73a041c86fdf1c6314b2d43c346de95a40 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 05:43:52 +0800 Subject: [PATCH 171/240] docs: update openapi for meta tags --- openapi/components/subject_v0.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openapi/components/subject_v0.yaml b/openapi/components/subject_v0.yaml index 0c8c3ecc7..d6ce9392d 100644 --- a/openapi/components/subject_v0.yaml +++ b/openapi/components/subject_v0.yaml @@ -8,6 +8,7 @@ required: - nsfw - locked - platform + - meta_tags - volumes - eps - series @@ -137,5 +138,10 @@ properties: dropped: title: Dropped type: integer + meta_tags: + description: 由维基人维护的 tag + type: array + items: + type: string tags: $ref: "./subject_tags.yaml" From be0fe62244d462e913eedac1510e700f91455e45 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 06:07:52 +0800 Subject: [PATCH 172/240] feat: support meta tags filter (#649) --- canal/canal.go | 3 +++ canal/event.go | 4 ++++ internal/model/subject.go | 1 + internal/pkg/cache/redis.go | 1 + internal/search/handle.go | 15 ++++++++++----- internal/search/index.go | 3 +++ internal/search/index_internal_test.go | 2 +- internal/subject/mysql_repository.go | 1 + openapi/v0.yaml | 8 ++++++++ 9 files changed, 32 insertions(+), 6 deletions(-) diff --git a/canal/canal.go b/canal/canal.go index bb33c7d27..985c7b4de 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -32,6 +32,7 @@ import ( "github.com/bangumi/server/internal/pkg/sys" "github.com/bangumi/server/internal/search" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/web/session" ) @@ -64,6 +65,8 @@ func Main() error { subject.NewMysqlRepo, search.New, session.NewMysqlRepo, session.New, driver.NewS3, + tag.NewMysqlRepo, + newEventHandler, ), diff --git a/canal/event.go b/canal/event.go index e3cf10955..e75d9ffe5 100644 --- a/canal/event.go +++ b/canal/event.go @@ -28,6 +28,7 @@ import ( "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/pkg/logger/log" "github.com/bangumi/server/internal/search" + "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/web/session" ) @@ -37,6 +38,7 @@ func newEventHandler( session session.Manager, redis rueidis.Client, stream Stream, + tag tag.Repo, search search.Client, s3 *s3.Client, ) *eventHandler { @@ -48,6 +50,7 @@ func newEventHandler( s3: s3, stream: stream, log: log.Named("eventHandler"), + tag: tag, } } @@ -60,6 +63,7 @@ type eventHandler struct { stream Stream s3 *s3.Client // optional, check nil before use redis rueidis.Client + tag tag.Repo } func (e *eventHandler) start() error { diff --git a/internal/model/subject.go b/internal/model/subject.go index 626de64ee..256dc8e02 100644 --- a/internal/model/subject.go +++ b/internal/model/subject.go @@ -26,6 +26,7 @@ type Subject struct { Image string Summary string Name string + MetaTags string Date string // first release date NameCN string Infobox string diff --git a/internal/pkg/cache/redis.go b/internal/pkg/cache/redis.go index 3bfa9cc08..c73384055 100644 --- a/internal/pkg/cache/redis.go +++ b/internal/pkg/cache/redis.go @@ -85,6 +85,7 @@ func (c redisCache) Get(ctx context.Context, key string, value any) (bool, error func (c redisCache) MGet(ctx context.Context, keys []string, result any) error { results, err := c.ru.Do(ctx, c.ru.B().Mget().Key(keys...).Build()).ToArray() if err != nil { + //nolint:errorlint if err == rueidis.Nil { return nil } diff --git a/internal/search/handle.go b/internal/search/handle.go index 8a444ef92..4df44682f 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -58,11 +58,12 @@ type Req struct { } type ReqFilter struct { //nolint:musttag - Type []model.SubjectType `json:"type"` // or - Tag []string `json:"tag"` // and - AirDate []string `json:"air_date"` // and - Score []string `json:"rating"` // and - Rank []string `json:"rank"` // and + Type []model.SubjectType `json:"type"` // or + Tag []string `json:"tag"` // and + AirDate []string `json:"air_date"` // and + Score []string `json:"rating"` // and + Rank []string `json:"rank"` // and + MetaTags []string `json:"meta_tags"` // and // if NSFW subject is enabled NSFW null.Bool `json:"nsfw"` @@ -224,6 +225,10 @@ func filterToMeiliFilter(req ReqFilter) [][]string { filter = append(filter, []string{"nsfw = false"}) } + for _, tag := range req.MetaTags { + filter = append(filter, []string{"meta_tag = " + strconv.Quote(tag)}) + } + // AND for _, tag := range req.Tag { diff --git a/internal/search/index.go b/internal/search/index.go index 3c7c4433c..d185c5a49 100644 --- a/internal/search/index.go +++ b/internal/search/index.go @@ -16,6 +16,7 @@ package search import ( "strconv" + "strings" "github.com/bangumi/server/internal/model" "github.com/bangumi/server/pkg/wiki" @@ -28,6 +29,7 @@ import ( type subjectIndex struct { ID model.SubjectID `json:"id"` Tag []string `json:"tag,omitempty" filterable:"true"` + MetaTags []string `json:"meta_tag" filterable:"true"` Name string `json:"name" searchable:"true"` Aliases []string `json:"aliases,omitempty" searchable:"true"` Date int `json:"date,omitempty" filterable:"true" sortable:"true"` @@ -74,6 +76,7 @@ func extractSubject(s *model.Subject) subjectIndex { ID: s.ID, Name: s.Name, Aliases: extractAliases(s, w), + MetaTags: strings.Split(s.MetaTags, " "), Tag: tagNames, NSFW: s.NSFW, Type: s.TypeID, diff --git a/internal/search/index_internal_test.go b/internal/search/index_internal_test.go index a9d218441..5049c767b 100644 --- a/internal/search/index_internal_test.go +++ b/internal/search/index_internal_test.go @@ -25,7 +25,7 @@ func TestIndexFilter(t *testing.T) { t.Parallel() actual := *(getAttributes("filterable")) - expected := []string{"date", "score", "rank", "type", "nsfw", "tag"} + expected := []string{"date", "meta_tag", "score", "rank", "type", "nsfw", "tag"} sort.Strings(expected) sort.Strings(actual) diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index 64e9ccaf9..395979ebc 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -78,6 +78,7 @@ func ConvertDao(s *dao.Subject) (model.Subject, error) { ID: s.ID, Name: string(s.Name), NameCN: string(s.NameCN), + MetaTags: s.FieldMetaTags, TypeID: s.TypeID, Image: s.Image, PlatformID: s.Platform, diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 13848f4ce..53cc49801 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -86,6 +86,14 @@ paths: items: $ref: "#/components/schemas/SubjectType" description: 条目类型,参照 `SubjectType` enum,多值之间为 `或` 的关系。 + meta_tags: + type: array + items: + type: string + example: + - 童年 + - 原创 + description: 公共标签。多个值之间为 `且` 关系。可以用 `-` 排除标签。比如 `-科幻` 可以排除科幻标签。 tag: type: array items: From d7b4b160f2033a2acbfa4960e2a43423fdd21069 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 06:39:12 +0800 Subject: [PATCH 173/240] chore: add more logging --- canal/on_subject.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/canal/on_subject.go b/canal/on_subject.go index c60a42872..0cc87d0a0 100644 --- a/canal/on_subject.go +++ b/canal/on_subject.go @@ -19,6 +19,7 @@ import ( "encoding/json" "github.com/trim21/errgo" + "go.uber.org/zap" "github.com/bangumi/server/internal/model" ) @@ -26,7 +27,7 @@ import ( func (e *eventHandler) OnSubject(ctx context.Context, key json.RawMessage, payload Payload) error { var k SubjectKey if err := json.Unmarshal(key, &k); err != nil { - return nil + return err } return e.onSubjectChange(ctx, k.ID, payload.Op) @@ -35,7 +36,7 @@ func (e *eventHandler) OnSubject(ctx context.Context, key json.RawMessage, paylo func (e *eventHandler) OnSubjectField(ctx context.Context, key json.RawMessage, payload Payload) error { var k SubjectFieldKey if err := json.Unmarshal(key, &k); err != nil { - return nil + return err } return e.onSubjectChange(ctx, k.ID, payload.Op) @@ -51,6 +52,8 @@ func (e *eventHandler) onSubjectChange(ctx context.Context, subjectID model.Subj if err := e.search.OnSubjectDelete(ctx, subjectID); err != nil { return errgo.Wrap(err, "search.OnSubjectDelete") } + default: + e.log.Warn("unexpected operator", zap.String("op", op)) } return nil From faa390cc88dc62a403c96a6c88e0a38d563fd3a6 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 06:47:50 +0800 Subject: [PATCH 174/240] fix: remove locked subject from search --- internal/search/client.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/search/client.go b/internal/search/client.go index 69e3f16ab..ffc0291ce 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -155,12 +155,12 @@ func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error s, err := c.subjectRepo.Get(ctx, id, subject.Filter{}) if err != nil { if errors.Is(err, gerr.ErrNotFound) { - return c.DeleteSubject(ctx, id) + return nil } return errgo.Wrap(err, "subjectRepo.Get") } - if s.Redirect != 0 { + if s.Redirect != 0 || s.Ban != 0 { return c.DeleteSubject(ctx, id) } @@ -178,6 +178,9 @@ func (c *client) OnSubjectDelete(_ context.Context, id model.SubjectID) error { return errgo.Wrap(err, "search") } +func (c *client) flush() { +} + // UpsertSubject add subject to search backend. func (c *client) sendBatch(items []subjectIndex) { c.log.Debug("send batch to meilisearch", zap.Int("len", len(items))) From 50ca3fe2f524d65a87966f2bbad01928e744f018 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 06:50:50 +0800 Subject: [PATCH 175/240] fix lint --- internal/search/client.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/search/client.go b/internal/search/client.go index ffc0291ce..0cc8f1dea 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -178,9 +178,6 @@ func (c *client) OnSubjectDelete(_ context.Context, id model.SubjectID) error { return errgo.Wrap(err, "search") } -func (c *client) flush() { -} - // UpsertSubject add subject to search backend. func (c *client) sendBatch(items []subjectIndex) { c.log.Debug("send batch to meilisearch", zap.Int("len", len(items))) From 09be440d89a2f69d969e770cb735fa7c25c74c42 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 07:03:35 +0800 Subject: [PATCH 176/240] chore: add more logging --- canal/event.go | 1 + internal/search/client.go | 12 +++--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/canal/event.go b/canal/event.go index e75d9ffe5..458b49819 100644 --- a/canal/event.go +++ b/canal/event.go @@ -109,6 +109,7 @@ func (e *eventHandler) onMessage(key, value []byte) error { var p Payload if err := json.Unmarshal(value, &p); err != nil { + e.log.Warn("failed to parse kafka value", zap.String("table", p.Source.Table), zap.Error(err)) return nil } diff --git a/internal/search/client.go b/internal/search/client.go index 0cc8f1dea..dc79300cc 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -161,7 +161,7 @@ func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error } if s.Redirect != 0 || s.Ban != 0 { - return c.DeleteSubject(ctx, id) + return c.OnSubjectDelete(ctx, id) } extracted := extractSubject(&s) @@ -172,8 +172,8 @@ func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error } // OnSubjectDelete is the hook called by canal. -func (c *client) OnSubjectDelete(_ context.Context, id model.SubjectID) error { - _, err := c.subjectIndex.DeleteDocument(strconv.FormatUint(uint64(id), 10)) +func (c *client) OnSubjectDelete(ctx context.Context, id model.SubjectID) error { + _, err := c.subjectIndex.DeleteDocumentWithContext(ctx, strconv.FormatUint(uint64(id), 10)) return errgo.Wrap(err, "search") } @@ -204,12 +204,6 @@ func (c *client) sendBatch(items []subjectIndex) { } } -func (c *client) DeleteSubject(_ context.Context, id model.SubjectID) error { - _, err := c.subjectIndex.Delete(strconv.FormatUint(uint64(id), 10)) - - return errgo.Wrap(err, "delete") -} - func (c *client) needFirstRun() (bool, error) { if os.Getenv("CHII_SEARCH_INIT") == "true" { return true, nil From dd54b7ad426076b1302d76720c24fcef3608f2ae Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 07:14:12 +0800 Subject: [PATCH 177/240] fix: flush new subject to search engine at once --- canal/on_subject.go | 6 ++++- go.mod | 2 +- go.sum | 4 +-- internal/mocks/SearchClient.go | 47 ++++++++++++++++++++++++++++++++++ internal/search/client.go | 20 +++++++++++++++ internal/search/handle.go | 4 ++- internal/search/noop.go | 2 ++ 7 files changed, 80 insertions(+), 5 deletions(-) diff --git a/canal/on_subject.go b/canal/on_subject.go index 0cc87d0a0..f96b7354b 100644 --- a/canal/on_subject.go +++ b/canal/on_subject.go @@ -44,7 +44,11 @@ func (e *eventHandler) OnSubjectField(ctx context.Context, key json.RawMessage, func (e *eventHandler) onSubjectChange(ctx context.Context, subjectID model.SubjectID, op string) error { switch op { - case opCreate, opUpdate, opSnapshot: + case opCreate: + if err := e.search.OnSubjectAdded(ctx, subjectID); err != nil { + return errgo.Wrap(err, "search.OnSubjectAdded") + } + case opUpdate, opSnapshot: if err := e.search.OnSubjectUpdate(ctx, subjectID); err != nil { return errgo.Wrap(err, "search.OnSubjectUpdate") } diff --git a/go.mod b/go.mod index c2cc018f5..064306e40 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/trim21/errgo v0.0.3 github.com/trim21/go-phpserialize v0.1.0-alpha.5 github.com/trim21/htest v0.0.4 - github.com/trim21/pkg v0.0.3 + github.com/trim21/pkg v0.0.4 go.uber.org/fx v1.23.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index 7852e99c3..7a7179cbf 100644 --- a/go.sum +++ b/go.sum @@ -195,8 +195,8 @@ github.com/trim21/go-phpserialize v0.1.0-alpha.5 h1:bMsUpfwAgPggQzDKdafNBvkPWDCM github.com/trim21/go-phpserialize v0.1.0-alpha.5/go.mod h1:/3zMYuOzpcKOevwP3ZN0WxdVRaB3CzJh5T2i41QPgRQ= github.com/trim21/htest v0.0.4 h1:dDIzKNdIClgtB158DlO+Xf0sfwNycmx3kfo/FJuY+eE= github.com/trim21/htest v0.0.4/go.mod h1:W+zaYAGCBqx38eMrMGvXrALnbcXR6OBtZiRiHahgo+E= -github.com/trim21/pkg v0.0.3 h1:uAqfoFmmYiIMOSretKj8/tvrQs3KG57020Ff0cx8UtE= -github.com/trim21/pkg v0.0.3/go.mod h1:JrRIFidkCLeuU5j0vBP5ZN0NOp2JavagHZNr4D3AH6Q= +github.com/trim21/pkg v0.0.4 h1:0nYODKdqNUzmUaPFvqSiR420u2uXQgIYyVyiNfH7olc= +github.com/trim21/pkg v0.0.4/go.mod h1:edl6xdqBOJrhMuIGvcY2lg5L9cqp/hVuwHRM/kdzbMg= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= diff --git a/internal/mocks/SearchClient.go b/internal/mocks/SearchClient.go index cdf74f078..2311ae084 100644 --- a/internal/mocks/SearchClient.go +++ b/internal/mocks/SearchClient.go @@ -100,6 +100,53 @@ func (_c *SearchClient_Handle_Call) RunAndReturn(run func(echo.Context) error) * return _c } +// OnSubjectAdded provides a mock function with given fields: ctx, id +func (_m *SearchClient) OnSubjectAdded(ctx context.Context, id uint32) error { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for OnSubjectAdded") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, uint32) error); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SearchClient_OnSubjectAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnSubjectAdded' +type SearchClient_OnSubjectAdded_Call struct { + *mock.Call +} + +// OnSubjectAdded is a helper method to define mock.On call +// - ctx context.Context +// - id uint32 +func (_e *SearchClient_Expecter) OnSubjectAdded(ctx interface{}, id interface{}) *SearchClient_OnSubjectAdded_Call { + return &SearchClient_OnSubjectAdded_Call{Call: _e.mock.On("OnSubjectAdded", ctx, id)} +} + +func (_c *SearchClient_OnSubjectAdded_Call) Run(run func(ctx context.Context, id uint32)) *SearchClient_OnSubjectAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint32)) + }) + return _c +} + +func (_c *SearchClient_OnSubjectAdded_Call) Return(_a0 error) *SearchClient_OnSubjectAdded_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *SearchClient_OnSubjectAdded_Call) RunAndReturn(run func(context.Context, uint32) error) *SearchClient_OnSubjectAdded_Call { + _c.Call.Return(run) + return _c +} + // OnSubjectDelete provides a mock function with given fields: ctx, id func (_m *SearchClient) OnSubjectDelete(ctx context.Context, id uint32) error { ret := _m.Called(ctx, id) diff --git a/internal/search/client.go b/internal/search/client.go index dc79300cc..62a3d30ea 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -150,6 +150,26 @@ func (c *client) Close() { } } +// OnSubjectAdded is the hook called by canal. +func (c *client) OnSubjectAdded(ctx context.Context, id model.SubjectID) error { + s, err := c.subjectRepo.Get(ctx, id, subject.Filter{}) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "subjectRepo.Get") + } + + if s.Redirect != 0 || s.Ban != 0 { + return c.OnSubjectDelete(ctx, id) + } + + extracted := extractSubject(&s) + + _, err = c.subjectIndex.UpdateDocumentsWithContext(ctx, extracted, "id") + return err +} + // OnSubjectUpdate is the hook called by canal. func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error { s, err := c.subjectRepo.Get(ctx, id, subject.Filter{}) diff --git a/internal/search/handle.go b/internal/search/handle.go index 4df44682f..b5842d2f5 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -38,8 +38,10 @@ import ( type Client interface { Handler - OnSubjectUpdate(ctx context.Context, id model.SubjectID) error Close() + + OnSubjectAdded(ctx context.Context, id model.SubjectID) error + OnSubjectUpdate(ctx context.Context, id model.SubjectID) error OnSubjectDelete(ctx context.Context, id model.SubjectID) error } diff --git a/internal/search/noop.go b/internal/search/noop.go index 0a929174b..bf68f32d8 100644 --- a/internal/search/noop.go +++ b/internal/search/noop.go @@ -28,6 +28,8 @@ var _ Client = NoopClient{} type NoopClient struct { } +func (n NoopClient) OnSubjectAdded(ctx context.Context, id model.SubjectID) error { return nil } + func (n NoopClient) Handle(c echo.Context) error { return c.String(http.StatusOK, "search is not enable") } From 8dc04ce7a47221ebb9ffea271514d1372a979854 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 07:16:44 +0800 Subject: [PATCH 178/240] ci: stop reuse cache with different go.mod --- .github/workflows/build.yaml | 1 - .github/workflows/lint.yaml | 1 - .github/workflows/release-docker.yaml | 1 - .github/workflows/test.yaml | 1 - 4 files changed, 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c8c0b5006..56f80f84a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -49,7 +49,6 @@ jobs: key: go-cache-122-${{ hashFiles('**/go.sum') }}-build restore-keys: | go-cache-122-${{ hashFiles('**/go.sum') }}- - go-cache-122- - name: Install Task uses: arduino/setup-task@v2 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 8cf84936b..cdd1cabac 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -46,7 +46,6 @@ jobs: key: go-cache-122-${{ hashFiles('**/go.sum') }}-lint restore-keys: | go-cache-122-${{ hashFiles('**/go.sum') }}- - go-cache-122- - run: go get -t ./... diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index d884e8538..55bdffcf1 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -39,7 +39,6 @@ jobs: key: go-cache-122-${{ hashFiles('**/go.sum') }}-build restore-keys: | go-cache-122-${{ hashFiles('**/go.sum') }}- - go-cache-122- - run: echo "SHA=${GITHUB_REF##*/}" >> $GITHUB_ENV if: "${{ startsWith(github.ref, 'refs/tags/') }}" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a469247d5..120a98cb9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -56,7 +56,6 @@ jobs: key: go-cache-122-${{ hashFiles('**/go.sum') }}-test restore-keys: | go-cache-122-${{ hashFiles('**/go.sum') }}- - go-cache-122- - run: go get -t ./... From bb9ae3d2cc9fb943ea0a311acaf60a00d9faf33e Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 07:21:36 +0800 Subject: [PATCH 179/240] fix: full search indexing missing latest subject --- internal/search/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/search/client.go b/internal/search/client.go index 62a3d30ea..d92627b94 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -299,7 +299,7 @@ func (c *client) firstRun() { c.log.Info(fmt.Sprintf("run full search index with max subject id %d", maxSubject.ID)) width := len(strconv.Itoa(int(maxSubject.ID))) - for i := model.SubjectID(1); i < maxSubject.ID; i++ { + for i := model.SubjectID(1); i <= maxSubject.ID; i++ { if i%10000 == 0 { c.log.Info(fmt.Sprintf("progress %*d/%d", width, i, maxSubject.ID)) } From 1f40e5700e979a334f0e00ec0b997df68af78f25 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 08:18:43 +0800 Subject: [PATCH 180/240] perf: tag search should hit index --- internal/tag/mysql_repo.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/internal/tag/mysql_repo.go b/internal/tag/mysql_repo.go index 475bb5cb8..535aa61de 100644 --- a/internal/tag/mysql_repo.go +++ b/internal/tag/mysql_repo.go @@ -16,8 +16,11 @@ package tag import ( "context" + "database/sql" + "errors" "github.com/jmoiron/sqlx" + "github.com/trim21/errgo" "go.uber.org/zap" "github.com/bangumi/server/dal/query" @@ -35,18 +38,31 @@ type mysqlRepo struct { } func (r mysqlRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { + // this is not necessary information for query data, but it will help mysql to hit cache + var subjectType model.SubjectType + err := r.db.QueryRowContext(ctx, ` + select chii_subjects.subject_type_id from chii_subjects where subject_id = ? + `, id).Scan(&subjectType) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return []Tag{}, nil + } + + return nil, errgo.Trace(err) + } + var s []struct { Tid uint `db:"tlt_tid"` Name string `db:"tag_name"` TotalCount uint `db:"tag_results"` } - err := r.db.SelectContext(ctx, &s, ` + err = r.db.SelectContext(ctx, &s, ` select tlt_tid, tag_name, tag_results from chii_tag_neue_list - inner join chii_tag_neue_index on tlt_tid = tag_id and tlt_type = tag_type + inner join chii_tag_neue_index on tlt_tid = tag_id and tlt_type = ? where tlt_uid = 0 and tag_cat = ? and tlt_mid = ? - `, CatSubject, id) + `, subjectType, CatSubject, id) if err != nil { return nil, err } From 71ba1300ccc99799ac2decf14f24572dd759260d Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 15 Oct 2024 08:23:02 +0800 Subject: [PATCH 181/240] perf: db query index miss --- internal/tag/mysql_repo.go | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/internal/tag/mysql_repo.go b/internal/tag/mysql_repo.go index 535aa61de..955388df6 100644 --- a/internal/tag/mysql_repo.go +++ b/internal/tag/mysql_repo.go @@ -16,11 +16,8 @@ package tag import ( "context" - "database/sql" - "errors" "github.com/jmoiron/sqlx" - "github.com/trim21/errgo" "go.uber.org/zap" "github.com/bangumi/server/dal/query" @@ -38,31 +35,18 @@ type mysqlRepo struct { } func (r mysqlRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { - // this is not necessary information for query data, but it will help mysql to hit cache - var subjectType model.SubjectType - err := r.db.QueryRowContext(ctx, ` - select chii_subjects.subject_type_id from chii_subjects where subject_id = ? - `, id).Scan(&subjectType) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return []Tag{}, nil - } - - return nil, errgo.Trace(err) - } - var s []struct { Tid uint `db:"tlt_tid"` Name string `db:"tag_name"` TotalCount uint `db:"tag_results"` } - err = r.db.SelectContext(ctx, &s, ` + err := r.db.SelectContext(ctx, &s, ` select tlt_tid, tag_name, tag_results from chii_tag_neue_list - inner join chii_tag_neue_index on tlt_tid = tag_id and tlt_type = ? + inner join chii_tag_neue_index on tlt_tid = tag_id where tlt_uid = 0 and tag_cat = ? and tlt_mid = ? - `, subjectType, CatSubject, id) + `, CatSubject, id) if err != nil { return nil, err } @@ -89,7 +73,7 @@ func (r mysqlRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod q, v, err := sqlx.In(` select tlt_tid, tag_name, tag_results, tlt_mid from chii_tag_neue_list - inner join chii_tag_neue_index on tlt_tid = tag_id and tlt_type = tag_type + inner join chii_tag_neue_index on tlt_tid = tag_id where tlt_uid = 0 and tag_cat = ? and tlt_mid IN (?) `, CatSubject, ids) if err != nil { From 456c163a1b6bc4448fe602b4dca92bb1b82364f1 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 18 Oct 2024 21:50:22 +0800 Subject: [PATCH 182/240] chore: remove too many logging --- internal/auth/mysql_repository.go | 3 --- internal/character/mysql_repository.go | 5 ----- internal/collections/infra/mysql_repo.go | 2 -- internal/person/mysql_repository.go | 5 ----- internal/revision/mysql_repo_episode.go | 2 +- internal/revision/mysql_repository.go | 6 ++---- internal/subject/mysql_repository.go | 8 -------- internal/user/mysql_repository.go | 1 - 8 files changed, 3 insertions(+), 29 deletions(-) diff --git a/internal/auth/mysql_repository.go b/internal/auth/mysql_repository.go index 6ce8cae56..14e17b090 100644 --- a/internal/auth/mysql_repository.go +++ b/internal/auth/mysql_repository.go @@ -58,7 +58,6 @@ func (m mysqlRepo) GetByEmail(ctx context.Context, email string) (UserInfo, []by return UserInfo{}, nil, gerr.ErrNotFound } - m.log.Error("unexpected error happened", zap.Error(err)) return UserInfo{}, nil, errgo.Wrap(err, "gorm") } @@ -169,7 +168,6 @@ func (m mysqlRepo) CreateAccessToken( Info: infoByte, }) if err != nil { - m.log.Error("unexpected error happened", zap.Error(err)) return "", errgo.Wrap(err, "dal") } @@ -186,7 +184,6 @@ func (m mysqlRepo) ListAccessToken(ctx context.Context, userID model.UserID) ([] Where(m.q.AccessToken.UserID.Eq(strconv.FormatUint(uint64(userID), 10)), m.q.AccessToken.ExpiredAt.Gte(time.Now())).Find() if err != nil { - m.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } diff --git a/internal/character/mysql_repository.go b/internal/character/mysql_repository.go index 47bc3640c..543615ac1 100644 --- a/internal/character/mysql_repository.go +++ b/internal/character/mysql_repository.go @@ -47,7 +47,6 @@ func (r mysqlRepo) Get(ctx context.Context, id model.CharacterID) (model.Charact return model.Character{}, gerr.ErrCharacterNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) return model.Character{}, errgo.Wrap(err, "dal") } @@ -60,7 +59,6 @@ func (r mysqlRepo) GetByIDs( records, err := r.q.Character.WithContext(ctx).Preload(r.q.Character.Fields). Where(r.q.Character.ID.In(slice.ToUint32(ids)...)).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -80,7 +78,6 @@ func (r mysqlRepo) GetPersonRelated( Order(r.q.Cast.SubjectID). Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -103,7 +100,6 @@ func (r mysqlRepo) GetSubjectRelated( Where(r.q.CharacterSubjects.SubjectID.Eq(subjectID)). Order(r.q.CharacterSubjects.CharacterID).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -137,7 +133,6 @@ func (r mysqlRepo) GetSubjectRelationByIDs( Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } diff --git a/internal/collections/infra/mysql_repo.go b/internal/collections/infra/mysql_repo.go index e069801b1..e0375d152 100644 --- a/internal/collections/infra/mysql_repo.go +++ b/internal/collections/infra/mysql_repo.go @@ -467,7 +467,6 @@ func (r mysqlRepo) ListSubjectCollection( collections, err := q.Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -799,7 +798,6 @@ func (r mysqlRepo) ListPersonCollection( collections, err := q.Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } diff --git a/internal/person/mysql_repository.go b/internal/person/mysql_repository.go index 67d62be4d..95eccc14d 100644 --- a/internal/person/mysql_repository.go +++ b/internal/person/mysql_repository.go @@ -45,8 +45,6 @@ func (r mysqlRepo) Get(ctx context.Context, id model.PersonID) (model.Person, er return model.Person{}, gerr.ErrNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) - return model.Person{}, errgo.Wrap(err, "dal") } @@ -59,7 +57,6 @@ func (r mysqlRepo) GetSubjectRelated( relations, err := r.q.PersonSubjects.WithContext(ctx). Where(r.q.PersonSubjects.SubjectID.Eq(subjectID)).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -84,7 +81,6 @@ func (r mysqlRepo) GetCharacterRelated( Order(r.q.Cast.PersonID). Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -104,7 +100,6 @@ func (r mysqlRepo) GetByIDs(ctx context.Context, ids []model.PersonID) (map[mode u, err := r.q.Person.WithContext(ctx).Joins(r.q.Person.Fields). Where(r.q.Person.ID.In(ids...)).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } diff --git a/internal/revision/mysql_repo_episode.go b/internal/revision/mysql_repo_episode.go index 291098469..a47827f67 100644 --- a/internal/revision/mysql_repo_episode.go +++ b/internal/revision/mysql_repo_episode.go @@ -76,7 +76,7 @@ func (r mysqlRepo) GetEpisodeRelated(ctx context.Context, id model.RevisionID) ( r.log.Error("can't find revision text", zap.Uint32("id", revision.TextID)) return model.EpisodeRevision{}, gerr.ErrNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) + return model.EpisodeRevision{}, errgo.Wrap(err, "dal") } diff --git a/internal/revision/mysql_repository.go b/internal/revision/mysql_repository.go index 37b975c3d..99b7b337d 100644 --- a/internal/revision/mysql_repository.go +++ b/internal/revision/mysql_repository.go @@ -84,7 +84,7 @@ func (r mysqlRepo) GetPersonRelated(ctx context.Context, id model.RevisionID) (m if errors.Is(err, gorm.ErrRecordNotFound) { return model.PersonRevision{}, gerr.ErrNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) + return model.PersonRevision{}, errgo.Wrap(err, "dal") } data, err := r.q.RevisionText.WithContext(ctx). @@ -95,7 +95,6 @@ func (r mysqlRepo) GetPersonRelated(ctx context.Context, id model.RevisionID) (m return model.PersonRevision{}, gerr.ErrNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) return model.PersonRevision{}, errgo.Wrap(err, "dal") } return convertPersonRevisionDao(revision, data), nil @@ -148,7 +147,7 @@ func (r mysqlRepo) GetCharacterRelated(ctx context.Context, id model.RevisionID) r.log.Error("can't find revision text", zap.Uint32("id", revision.TextID)) return model.CharacterRevision{}, gerr.ErrNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) + return model.CharacterRevision{}, errgo.Wrap(err, "dal") } return convertCharacterRevisionDao(revision, data), nil @@ -199,7 +198,6 @@ func (r mysqlRepo) GetSubjectRelated(ctx context.Context, id model.RevisionID) ( return model.SubjectRevision{}, gerr.ErrNotFound } - r.log.Error("unexpected error happened", zap.Error(err)) return model.SubjectRevision{}, errgo.Wrap(err, "dal") } return convertSubjectRevisionDao(revision, true), nil diff --git a/internal/subject/mysql_repository.go b/internal/subject/mysql_repository.go index 395979ebc..3e2a44179 100644 --- a/internal/subject/mysql_repository.go +++ b/internal/subject/mysql_repository.go @@ -54,7 +54,6 @@ func (r mysqlRepo) Get(ctx context.Context, id model.SubjectID, filter Filter) ( return model.Subject{}, fmt.Errorf("%w: %d", gerr.ErrNotFound, id) } - r.log.Error("unexpected error happened", zap.Error(err)) return model.Subject{}, errgo.Wrap(err, "dal") } @@ -138,8 +137,6 @@ func (r mysqlRepo) GetPersonRelated( Joins(r.q.PersonSubjects.Person). Where(r.q.PersonSubjects.PersonID.Eq(personID)).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) - return nil, errgo.Wrap(err, "dal") } @@ -163,7 +160,6 @@ func (r mysqlRepo) GetCharacterRelated( Joins(r.q.CharacterSubjects.Subject). Where(r.q.CharacterSubjects.CharacterID.Eq(characterID)).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -187,7 +183,6 @@ func (r mysqlRepo) GetSubjectRelated( Joins(r.q.SubjectRelation.Subject).Where(r.q.SubjectRelation.SubjectID.Eq(subjectID)). Order(r.q.SubjectRelation.Order).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -217,7 +212,6 @@ func (r mysqlRepo) GetByIDs( records, err := q.Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -306,7 +300,6 @@ func (r mysqlRepo) Browse( subjects, err := q.Limit(limit).Offset(offset).Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } @@ -331,7 +324,6 @@ func (r mysqlRepo) GetActors( Order(r.q.Cast.PersonID). Find() if err != nil { - r.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } diff --git a/internal/user/mysql_repository.go b/internal/user/mysql_repository.go index 3cd7b960d..6f241d185 100644 --- a/internal/user/mysql_repository.go +++ b/internal/user/mysql_repository.go @@ -112,7 +112,6 @@ func (m mysqlRepo) GetByName(ctx context.Context, username string) (User, error) func (m mysqlRepo) GetByIDs(ctx context.Context, ids []model.UserID) (map[model.UserID]User, error) { u, err := m.q.Member.WithContext(ctx).Where(m.q.Member.ID.In(ids...)).Find() if err != nil { - m.log.Error("unexpected error happened", zap.Error(err)) return nil, errgo.Wrap(err, "dal") } From 9c439ba8c723e108712a4c35c02381fcfffd1fee Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 18 Oct 2024 21:52:53 +0800 Subject: [PATCH 183/240] refactor: ignore context cancel error --- dal/log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dal/log.go b/dal/log.go index ed29dabb9..5f56bb7b1 100644 --- a/dal/log.go +++ b/dal/log.go @@ -82,7 +82,7 @@ func (l *metricsLog) Trace(_ context.Context, begin time.Time, fc func() (sql st l.h.Observe(elapsed.Seconds()) switch { - case err != nil && !errors.Is(err, gorm.ErrRecordNotFound): + case err != nil && !errors.Is(err, gorm.ErrRecordNotFound) && !errors.Is(err, context.Canceled): sql, rows := fc() l.log.Error("gorm error", zap.String("sql", sql), zap.Error(err), zap.Duration("duration", elapsed), zap.Int64("rows", rows)) From 2997789144d520da83dd27f7c70d1809ac5f9066 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sat, 19 Oct 2024 01:02:27 +0800 Subject: [PATCH 184/240] refactor: add request path to context --- internal/pkg/logger/ctx.go | 7 ++++++- web/new.go | 8 +++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/internal/pkg/logger/ctx.go b/internal/pkg/logger/ctx.go index 6fcc9694f..ca71d5442 100644 --- a/internal/pkg/logger/ctx.go +++ b/internal/pkg/logger/ctx.go @@ -23,17 +23,22 @@ import ( // https://github.com/uber-go/zap/issues/654 +// make RequestKey and unique. +type key string + //nolint:gochecknoglobals -var RequestKey = &struct{}{} +const RequestKey key = "logger.contextKey" type RequestTrace struct { IP string ReqID string + Path string } func (r *RequestTrace) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("ip", r.IP) enc.AddString("request-id", r.ReqID) + enc.AddString("path", r.Path) return nil } diff --git a/web/new.go b/web/new.go index aae9dfe10..b618d0731 100644 --- a/web/new.go +++ b/web/new.go @@ -99,13 +99,11 @@ func New() *echo.Echo { app.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - reqID := c.Request().Header.Get(cf.HeaderRequestID) - reqIP := c.RealIP() - c.SetRequest(c.Request(). WithContext(context.WithValue(c.Request().Context(), logger.RequestKey, &logger.RequestTrace{ - IP: reqIP, - ReqID: reqID, + IP: c.RealIP(), + ReqID: c.Request().Header.Get(cf.HeaderRequestID), + Path: c.Request().RequestURI, }))) return next(c) From c635c98e8a160b779a8189f35e4d27786ba3f7a0 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Sun, 20 Oct 2024 05:02:50 +0800 Subject: [PATCH 185/240] chore: remove some logger --- internal/user/mysql_repository.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/internal/user/mysql_repository.go b/internal/user/mysql_repository.go index 6f241d185..c77fb0d3e 100644 --- a/internal/user/mysql_repository.go +++ b/internal/user/mysql_repository.go @@ -47,8 +47,6 @@ func (m mysqlRepo) GetFullUser(ctx context.Context, userID model.UserID) (FullUs if errors.Is(err, gorm.ErrRecordNotFound) { return FullUser{}, gerr.ErrUserNotFound } - - m.log.Error("unexpected error happened", zap.Error(err)) return FullUser{}, errgo.Wrap(err, "dal") } @@ -87,8 +85,6 @@ func (m mysqlRepo) GetByID(ctx context.Context, userID model.UserID) (User, erro if errors.Is(err, gorm.ErrRecordNotFound) { return User{}, gerr.ErrUserNotFound } - - m.log.Error("unexpected error happened", zap.Error(err)) return User{}, errgo.Wrap(err, "dal") } @@ -101,8 +97,6 @@ func (m mysqlRepo) GetByName(ctx context.Context, username string) (User, error) if errors.Is(err, gorm.ErrRecordNotFound) { return User{}, gerr.ErrUserNotFound } - - m.log.Error("unexpected error happened", zap.Error(err)) return User{}, errgo.Wrap(err, "dal") } From 78693d330dec2d09da75e82e97d45fdcb5484012 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 21 Oct 2024 04:17:41 +0800 Subject: [PATCH 186/240] fix: make sure context are not canceled before request finish and set a default timeout --- go.mod | 2 +- internal/auth/mysql_repository.go | 2 -- main.go | 3 +++ web/error.go | 16 ++++++++++++++++ web/new.go | 21 +++++++++++++++------ web/res/error.go | 3 +++ 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 064306e40..67c507e1f 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/go-playground/validator/v10 v10.22.1 github.com/go-resty/resty/v2 v2.15.3 github.com/go-sql-driver/mysql v1.8.1 + github.com/google/uuid v1.6.0 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jarcoal/httpmock v1.3.1 github.com/jmoiron/sqlx v1.4.0 @@ -68,7 +69,6 @@ require ( github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect diff --git a/internal/auth/mysql_repository.go b/internal/auth/mysql_repository.go index 14e17b090..806743f75 100644 --- a/internal/auth/mysql_repository.go +++ b/internal/auth/mysql_repository.go @@ -118,8 +118,6 @@ func (m mysqlRepo) GetPermission(ctx context.Context, groupID uint8) (Permission m.log.Error("can't find permission for group", zap.Uint8("user_group_id", groupID)) return Permission{}, nil } - - m.log.Error("unexpected error", zap.Error(err)) return Permission{}, errgo.Wrap(err, "dal") } diff --git a/main.go b/main.go index 7c046eaab..b89fe5333 100644 --- a/main.go +++ b/main.go @@ -17,11 +17,14 @@ package main import ( "fmt" + "github.com/google/uuid" + "github.com/bangumi/server/cmd" "github.com/bangumi/server/internal/pkg/logger" ) func main() { + uuid.EnableRandPool() if err := cmd.Root.Execute(); err != nil { logger.Fatal("failed to start app:\n" + fmt.Sprintf("\n%+v", err)) } diff --git a/web/error.go b/web/error.go index caaffcee8..bb7666b32 100644 --- a/web/error.go +++ b/web/error.go @@ -37,6 +37,7 @@ func globalNotFoundHandler(c echo.Context) error { }) } +//nolint:funlen func getDefaultErrorHandler() echo.HTTPErrorHandler { var log = logger.Named("http.err"). WithOptions(zap.AddStacktrace(zapcore.PanicLevel), zap.WithCaller(false)) @@ -49,6 +50,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { _ = c.JSON(e.Code, res.Error{ Title: http.StatusText(e.Code), Description: e.Msg, + RequestID: c.Request().Header.Get(cf.HeaderRequestID), Details: util.Detail(c), }) return @@ -69,6 +71,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { _ = c.JSON(http.StatusInternalServerError, res.Error{ Title: http.StatusText(e.Code), Description: e.Error(), + RequestID: c.Request().Header.Get(cf.HeaderRequestID), Details: util.DetailWithErr(c, err), }) return @@ -76,6 +79,19 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { } if errors.Is(err, context.Canceled) { + log.Error("unexpected echo error", + zap.Int("code", http.StatusInternalServerError), + zap.Any("message", "request timeout"), + zap.String("path", c.Request().URL.Path), + zap.String("query", c.Request().URL.RawQuery), + zap.String("cf-ray", c.Request().Header.Get(cf.HeaderRequestID)), + ) + + _ = c.JSON(http.StatusInternalServerError, res.Error{ + Title: "request timeout", + Description: "request timeout", + RequestID: c.Request().Header.Get(cf.HeaderRequestID), + }) return } diff --git a/web/new.go b/web/new.go index b618d0731..97b902520 100644 --- a/web/new.go +++ b/web/new.go @@ -24,6 +24,7 @@ import ( "strings" "time" + "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -99,12 +100,20 @@ func New() *echo.Echo { app.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - c.SetRequest(c.Request(). - WithContext(context.WithValue(c.Request().Context(), logger.RequestKey, &logger.RequestTrace{ - IP: c.RealIP(), - ReqID: c.Request().Header.Get(cf.HeaderRequestID), - Path: c.Request().RequestURI, - }))) + ctx, cancel := context.WithTimeout(context.WithoutCancel(c.Request().Context()), time.Minute) + defer cancel() + + reqID := c.Request().Header.Get(cf.HeaderRequestID) + + if reqID == "" { + reqID = uuid.Must(uuid.NewV7()).String() + } + + c.SetRequest(c.Request().WithContext(context.WithValue(ctx, logger.RequestKey, &logger.RequestTrace{ + IP: c.RealIP(), + ReqID: reqID, + Path: c.Request().RequestURI, + }))) return next(c) } diff --git a/web/res/error.go b/web/res/error.go index 1b34a81a4..94c1e5260 100644 --- a/web/res/error.go +++ b/web/res/error.go @@ -22,6 +22,7 @@ import ( "github.com/labstack/echo/v4" + "github.com/bangumi/server/web/req/cf" "github.com/bangumi/server/web/util" ) @@ -31,6 +32,7 @@ var ErrNotFound = NewError(http.StatusNotFound, "resource can't be found in the type Error struct { Title string `json:"title"` Details any `json:"details,omitempty"` + RequestID string `json:"request_id,omitempty"` Description string `json:"description"` } @@ -77,6 +79,7 @@ func InternalError(c echo.Context, err error, message string) error { return c.JSON(http.StatusInternalServerError, Error{ Title: "Internal Server Error", Description: message, + RequestID: c.Request().Header.Get(cf.HeaderRequestID), Details: util.DetailWithErr(c, err), }) } From 919645a075a052bb5065e904367094cd1512f17e Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 21 Oct 2024 04:53:24 +0800 Subject: [PATCH 187/240] chore: fix logging message --- web/error.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/error.go b/web/error.go index bb7666b32..b144db555 100644 --- a/web/error.go +++ b/web/error.go @@ -79,7 +79,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { } if errors.Is(err, context.Canceled) { - log.Error("unexpected echo error", + log.Error("request timeout", zap.Int("code", http.StatusInternalServerError), zap.Any("message", "request timeout"), zap.String("path", c.Request().URL.Path), From 3693afed59ce3a4cc3eaa4cd3f414c6e55b7ef0a Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 21 Oct 2024 04:54:35 +0800 Subject: [PATCH 188/240] chore: fix logging message --- web/error.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/error.go b/web/error.go index b144db555..729b4f241 100644 --- a/web/error.go +++ b/web/error.go @@ -80,8 +80,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { if errors.Is(err, context.Canceled) { log.Error("request timeout", - zap.Int("code", http.StatusInternalServerError), - zap.Any("message", "request timeout"), + zap.String("message", err.Error()), zap.String("path", c.Request().URL.Path), zap.String("query", c.Request().URL.RawQuery), zap.String("cf-ray", c.Request().Header.Get(cf.HeaderRequestID)), From 16767f7e309f6ee7b073816f3b57259a83e6bca8 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 21 Oct 2024 04:55:30 +0800 Subject: [PATCH 189/240] chore: fix logging message --- web/error.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/error.go b/web/error.go index 729b4f241..888596d88 100644 --- a/web/error.go +++ b/web/error.go @@ -81,9 +81,10 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { if errors.Is(err, context.Canceled) { log.Error("request timeout", zap.String("message", err.Error()), - zap.String("path", c.Request().URL.Path), - zap.String("query", c.Request().URL.RawQuery), - zap.String("cf-ray", c.Request().Header.Get(cf.HeaderRequestID)), + zap.String("request_method", c.Request().Method), + zap.String("request_uri", c.Request().URL.Path), + zap.String("request_query", c.Request().URL.RawQuery), + zap.String("request_id", c.Request().Header.Get(cf.HeaderRequestID)), ) _ = c.JSON(http.StatusInternalServerError, res.Error{ From b63c8c25cfc0c3fbc5457ed95c18dd445c2924eb Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 21 Oct 2024 04:56:01 +0800 Subject: [PATCH 190/240] chore: fix logging message --- web/error.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/error.go b/web/error.go index 888596d88..3365e26e9 100644 --- a/web/error.go +++ b/web/error.go @@ -97,9 +97,10 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { log.Error("unexpected error", zap.Error(err), - zap.String("path", c.Path()), - zap.String("query", c.Request().URL.RawQuery), - zap.String("cf-ray", c.Request().Header.Get(cf.HeaderRequestID)), + zap.String("request_method", c.Request().Method), + zap.String("request_uri", c.Request().URL.Path), + zap.String("request_query", c.Request().URL.RawQuery), + zap.String("request_id", c.Request().Header.Get(cf.HeaderRequestID)), ) // unexpected error, return internal server error From 5ce009f43de385e1af1f5dcee07394f02917c904 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 21 Oct 2024 04:57:53 +0800 Subject: [PATCH 191/240] chore: fix logging message --- web/error.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/web/error.go b/web/error.go index 3365e26e9..fa57db47a 100644 --- a/web/error.go +++ b/web/error.go @@ -43,6 +43,8 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { WithOptions(zap.AddStacktrace(zapcore.PanicLevel), zap.WithCaller(false)) return func(err error, c echo.Context) { + reqID := c.Request().Header.Get(cf.HeaderRequestID) + { var e res.HTTPError if errors.As(err, &e) { @@ -50,7 +52,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { _ = c.JSON(e.Code, res.Error{ Title: http.StatusText(e.Code), Description: e.Msg, - RequestID: c.Request().Header.Get(cf.HeaderRequestID), + RequestID: reqID, Details: util.Detail(c), }) return @@ -63,15 +65,16 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { log.Error("unexpected echo error", zap.Int("code", e.Code), zap.Any("message", e.Message), - zap.String("path", c.Request().URL.Path), - zap.String("query", c.Request().URL.RawQuery), - zap.String("cf-ray", c.Request().Header.Get(cf.HeaderRequestID)), + zap.String("request_method", c.Request().Method), + zap.String("request_uri", c.Request().URL.Path), + zap.String("request_query", c.Request().URL.RawQuery), + zap.String("request_id", reqID), ) _ = c.JSON(http.StatusInternalServerError, res.Error{ Title: http.StatusText(e.Code), Description: e.Error(), - RequestID: c.Request().Header.Get(cf.HeaderRequestID), + RequestID: reqID, Details: util.DetailWithErr(c, err), }) return @@ -84,7 +87,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { zap.String("request_method", c.Request().Method), zap.String("request_uri", c.Request().URL.Path), zap.String("request_query", c.Request().URL.RawQuery), - zap.String("request_id", c.Request().Header.Get(cf.HeaderRequestID)), + zap.String("request_id", reqID), ) _ = c.JSON(http.StatusInternalServerError, res.Error{ @@ -100,7 +103,7 @@ func getDefaultErrorHandler() echo.HTTPErrorHandler { zap.String("request_method", c.Request().Method), zap.String("request_uri", c.Request().URL.Path), zap.String("request_query", c.Request().URL.RawQuery), - zap.String("request_id", c.Request().Header.Get(cf.HeaderRequestID)), + zap.String("request_id", reqID), ) // unexpected error, return internal server error From 5136dc4ab6deceee4ebaa72cee73f7fe8e26e41a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:31:25 +0800 Subject: [PATCH 192/240] chore(deps): update gcr.io/distroless/static docker digest to cc226ca (#650) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- etc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/Dockerfile b/etc/Dockerfile index 08b4b7188..7e6c62637 100644 --- a/etc/Dockerfile +++ b/etc/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/distroless/static@sha256:69830f29ed7545c762777507426a412f97dad3d8d32bae3e74ad3fb6160917ea +FROM gcr.io/distroless/static@sha256:cc226ca14d17d01d4b278d9489da930a0dd11150df10ae95829d13e6d00fbdbf ENTRYPOINT ["/app/chii.exe"] From 59c3612723b1d71bb59c6e3a9179dc57c7614f42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:34:01 +0800 Subject: [PATCH 193/240] build(deps): update module google.golang.org/protobuf to v1.35.1 (#655) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 67c507e1f..9cabcc7f4 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( golang.org/x/text v0.19.0 google.golang.org/grpc v1.67.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 - google.golang.org/protobuf v1.34.2 + google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 diff --git a/go.sum b/go.sum index 7a7179cbf..169a5cb67 100644 --- a/go.sum +++ b/go.sum @@ -290,8 +290,8 @@ google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From 1f52e6cd96f449fd0e0ce4e55a87c6025a491912 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:34:10 +0800 Subject: [PATCH 194/240] build(deps): update module github.com/meilisearch/meilisearch-go to v0.29.0 (#654) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9cabcc7f4..41856058c 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/jmoiron/sqlx v1.4.0 github.com/labstack/echo/v4 v4.12.0 github.com/mattn/go-colorable v0.1.13 - github.com/meilisearch/meilisearch-go v0.28.0 + github.com/meilisearch/meilisearch-go v0.29.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.20.4 github.com/redis/rueidis v1.0.47 @@ -52,6 +52,7 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect diff --git a/go.sum b/go.sum index 169a5cb67..4e6c96911 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4 github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= @@ -139,8 +141,8 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/meilisearch/meilisearch-go v0.28.0 h1:f3XJ66ZM+R8bANAOLqsjvoq/HhQNpVJPYoNt6QgNzME= -github.com/meilisearch/meilisearch-go v0.28.0/go.mod h1:Szcc9CaDiKIfjdgdt49jlmDKpEzjD+x+b6Y6heMdlQ0= +github.com/meilisearch/meilisearch-go v0.29.0 h1:HZ9NEKN59USINQ/DXJge/aaXq8IrsKbXGTdAoBaaDz4= +github.com/meilisearch/meilisearch-go v0.29.0/go.mod h1:2cRCAn4ddySUsFfNDLVPod/plRibQsJkXF/4gLhxbOk= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= From 33a6a939dc738e12711bca15ed399045e0348109 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:34:39 +0800 Subject: [PATCH 195/240] build(deps): update module github.com/redis/rueidis to v1.0.48 (#653) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 41856058c..51c955c54 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/meilisearch/meilisearch-go v0.29.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.20.4 - github.com/redis/rueidis v1.0.47 + github.com/redis/rueidis v1.0.48 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 diff --git a/go.sum b/go.sum index 4e6c96911..11d29c207 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJN github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/redis/rueidis v1.0.47 h1:41UdeXOo4eJuW+cfpUJuLtVGyO0QJY3A2rEYgJWlfHs= -github.com/redis/rueidis v1.0.47/go.mod h1:by+34b0cFXndxtYmPAHpoTHO5NkosDlBvhexoTURIxM= +github.com/redis/rueidis v1.0.48 h1:ggZHjEtc/echUmPkGTfssRisnc3p/mIUEwrpbNsZ1mQ= +github.com/redis/rueidis v1.0.48/go.mod h1:by+34b0cFXndxtYmPAHpoTHO5NkosDlBvhexoTURIxM= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= From 7ea877dbe9ee89b49d08c78209056f27fcc7c6d4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:35:22 +0800 Subject: [PATCH 196/240] build(deps): update aws-sdk-go-v2 monorepo (#651) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 51c955c54..2235cdf3e 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,9 @@ go 1.23.2 require ( github.com/avast/retry-go/v4 v4.6.0 - github.com/aws/aws-sdk-go-v2 v1.32.2 - github.com/aws/aws-sdk-go-v2/credentials v1.17.41 - github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 + github.com/aws/aws-sdk-go-v2 v1.32.3 + github.com/aws/aws-sdk-go-v2/credentials v1.17.42 + github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 github.com/bytedance/sonic v1.12.3 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 @@ -54,13 +54,13 @@ require ( github.com/BurntSushi/toml v1.4.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 // indirect github.com/aws/smithy-go v1.22.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect diff --git a/go.sum b/go.sum index 11d29c207..4f43ffe96 100644 --- a/go.sum +++ b/go.sum @@ -7,28 +7,28 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= -github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= -github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2 v1.32.3 h1:T0dRlFBKcdaUPGNtkBSwHZxrtis8CQU17UpNBZYd0wk= +github.com/aws/aws-sdk-go-v2 v1.32.3/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= -github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8= -github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.42/go.mod h1:FwZBfU530dJ26rv9saAbxa9Ej3eF/AK0OAY86k13n4M= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 h1:Jw50LwEkVjuVzE1NzkhNKkBf9cRN7MtE1F/b2cOKTUM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22/go.mod h1:Y/SmAyPcOTmpeVaWSzSKiILfXTVJwrGmYZhcRbhWuEY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 h1:981MHwBaRZM7+9QSR6XamDzF/o7ouUGxFzr+nVSIhrs= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22/go.mod h1:1RA1+aBEfn+CAB/Mh0MB6LsdCYCnjZm7tKXtnk499ZQ= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 h1:yV+hCAHZZYJQcwAaszoBNwLbPItHvApxT0kVIw6jRgs= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22/go.mod h1:kbR1TL8llqB1eGnVbybcA4/wgScxdylOdyAd51yxPdw= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 h1:xxHGZ+wUgZNACQmxtdvP5tgzfsxGS3vPpTP5Hy3iToE= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 h1:kT6BcZsmMtNkP/iYMcRG+mIEA/IbeiUimXtGmqF39y0= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3/go.mod h1:Z8uGua2k4PPaGOYn66pK02rhMrot3Xk3tpBuUFPomZU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 h1:qcxX0JYlgWH3hpPUnd6U0ikcl6LLA9sLkXE2w1fpMvY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3/go.mod h1:cLSNEmI45soc+Ef8K/L+8sEA3A3pYFEYf5B5UI+6bH4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 h1:ZC7Y/XgKUxwqcdhO5LE8P6oGP1eh6xlQReWNKfhvJno= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3/go.mod h1:WqfO7M9l9yUAw0HcHaikwRd/H6gzYdz7vjejCA5e2oY= +github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 h1:p9TNFL8bFUMd+38YIpTAXpoxyz0MxC7FlbFEH4P4E1U= +github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2/go.mod h1:fNjyo0Coen9QTwQLWeV6WO2Nytwiu+cCcWaTdKCAqqE= github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= From d4c6bf268ab02e3c69cfe59aee22d4bd120376c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:36:07 +0800 Subject: [PATCH 197/240] build(deps): update module github.com/prometheus/client_golang to v1.20.5 (#652) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2235cdf3e..7e762a975 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/meilisearch/meilisearch-go v0.29.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/prometheus/client_golang v1.20.4 + github.com/prometheus/client_golang v1.20.5 github.com/redis/rueidis v1.0.48 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 diff --git a/go.sum b/go.sum index 4f43ffe96..c3f6b5715 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,8 @@ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= From 6bcf80134ef6a22e720099dbbdb84f3c5bc32827 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 07:32:43 +0800 Subject: [PATCH 198/240] build(deps): bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 (#659) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 7e762a975..22e26191d 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/cloudwego/iasm v0.2.0 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect diff --git a/go.sum b/go.sum index c3f6b5715..93b33ca2b 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,9 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= From 8e31b4093d2518c009de6a1d81a06ae595754382 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 02:39:36 +0800 Subject: [PATCH 199/240] build(deps): update module github.com/bytedance/sonic to v1.12.4 (#661) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 22e26191d..92fbde363 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.32.3 github.com/aws/aws-sdk-go-v2/credentials v1.17.42 github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 - github.com/bytedance/sonic v1.12.3 + github.com/bytedance/sonic v1.12.4 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 diff --git a/go.sum b/go.sum index 93b33ca2b..93e7a9796 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.12.4 h1:9Csb3c9ZJhfUWeMtpCDCq6BUoH5ogfDFLUgQ/jG+R0k= +github.com/bytedance/sonic v1.12.4/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= From 6ad9900cce73de805d6e7f9f8fa2edd8cadbe84b Mon Sep 17 00:00:00 2001 From: Predidit <34627277+Predidit@users.noreply.github.com> Date: Mon, 18 Nov 2024 22:19:16 +0800 Subject: [PATCH 200/240] revert: disable img proxy for person grid image (#662) --- web/res/image.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/res/image.go b/web/res/image.go index 3b5fc5c0d..7f870bec2 100644 --- a/web/res/image.go +++ b/web/res/image.go @@ -93,7 +93,7 @@ func PersonImage(s string) PersonImages { Large: "https://lain.bgm.tv/pic/crt/l/" + s, Small: "https://lain.bgm.tv/r/100/pic/crt/l/" + s, - Grid: "https://lain.bgm.tv/r/200/pic/crt/l/" + s, + Grid: "https://lain.bgm.tv/pic/crt/g/" + s, Medium: "https://lain.bgm.tv/r/400/pic/crt/l/" + s, } } From e4bb7f943d2626640074082f5e6db7922ba8bd7c Mon Sep 17 00:00:00 2001 From: everpcpc Date: Mon, 25 Nov 2024 14:45:20 +0800 Subject: [PATCH 201/240] fix: filter nsfw on search (#663) --- internal/search/handle.go | 8 ++++---- internal/search/handle_internal_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index b5842d2f5..f3ef51f35 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -103,7 +103,7 @@ func (c *client) Handle(ctx echo.Context) error { } if !auth.AllowNSFW() { - r.Filter.NSFW.Set = false + r.Filter.NSFW = null.Bool{Set: true, Value: false} } result, err := c.doSearch(r.Keyword, filterToMeiliFilter(r.Filter), r.Sort, q.Limit, q.Offset) @@ -119,7 +119,7 @@ func (c *client) Handle(ctx echo.Context) error { var sf = subject.Filter{} - if !r.Filter.NSFW.Set || !r.Filter.NSFW.Value { + if r.Filter.NSFW.Set && !r.Filter.NSFW.Value { sf.NSFW = null.Bool{Set: true, Value: false} } @@ -223,8 +223,8 @@ func filterToMeiliFilter(req ReqFilter) [][]string { })) } - if !req.NSFW.Set || !req.NSFW.Value { - filter = append(filter, []string{"nsfw = false"}) + if req.NSFW.Set { + filter = append(filter, []string{fmt.Sprintf("nsfw = %t", req.NSFW.Value)}) } for _, tag := range req.MetaTags { diff --git a/internal/search/handle_internal_test.go b/internal/search/handle_internal_test.go index 738f5009f..fb54defb2 100644 --- a/internal/search/handle_internal_test.go +++ b/internal/search/handle_internal_test.go @@ -27,7 +27,7 @@ func Test_ReqFilterToMeiliFilter(t *testing.T) { actual := filterToMeiliFilter(ReqFilter{ Tag: []string{"a", "b"}, - NSFW: null.Bool{Set: false}, + NSFW: null.Bool{Set: true, Value: false}, }) require.Equal(t, [][]string{ From a5d5e62e37730b6ebaebc9d0d43534185b78ec99 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Mon, 25 Nov 2024 16:35:47 +0800 Subject: [PATCH 202/240] feat: add more fields for subject search (#664) --- internal/search/client.go | 4 ++ internal/search/handle.go | 114 ++++++++++++++++++++++++++-------- openapi/v0.yaml | 61 +----------------- web/handler/subject/browse.go | 12 +++- web/handler/subject/get.go | 80 +----------------------- web/res/character.go | 2 +- web/res/person.go | 2 +- web/res/subject.go | 84 +++++++++++++++++++++++-- 8 files changed, 186 insertions(+), 173 deletions(-) diff --git a/internal/search/client.go b/internal/search/client.go index d92627b94..b3b3b50a2 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -39,6 +39,7 @@ import ( "github.com/bangumi/server/domain/gerr" "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" ) // New provide a search app is AppConfig.MeiliSearchURL is empty string, return nope search client. @@ -47,6 +48,7 @@ import ( func New( cfg config.AppConfig, subjectRepo subject.Repo, + tagRepo tag.CachedRepo, log *zap.Logger, query *query.Query, ) (Client, error) { @@ -78,6 +80,7 @@ func New( subjectIndex: meili.Index("subjects"), log: log.Named("search"), subjectRepo: subjectRepo, + tagRepo: tagRepo, } if cfg.AppType != config.AppTypeCanal { @@ -136,6 +139,7 @@ func (c *client) canalInit(cfg config.AppConfig) error { type client struct { subjectRepo subject.Repo + tagRepo tag.CachedRepo meili meilisearch.ServiceManager q *query.Query subjectIndex meilisearch.IndexManager diff --git a/internal/search/handle.go b/internal/search/handle.go index f3ef51f35..2c407bc8b 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -25,12 +25,16 @@ import ( "github.com/labstack/echo/v4" "github.com/meilisearch/meilisearch-go" + "github.com/samber/lo" "github.com/trim21/errgo" "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/compat" "github.com/bangumi/server/internal/pkg/generic/slice" "github.com/bangumi/server/internal/pkg/null" "github.com/bangumi/server/internal/subject" + "github.com/bangumi/server/internal/tag" + "github.com/bangumi/server/pkg/wiki" "github.com/bangumi/server/web/accessor" "github.com/bangumi/server/web/req" "github.com/bangumi/server/web/res" @@ -76,17 +80,26 @@ type hit struct { } type ReponseSubject struct { - Date string `json:"date"` - Image string `json:"image"` - Type uint8 `json:"type"` - Summary string `json:"summary"` - Name string `json:"name"` - NameCN string `json:"name_cn"` - Tags []res.SubjectTag `json:"tags"` - Score float64 `json:"score"` - ID model.SubjectID `json:"id"` - Rank uint32 `json:"rank"` - NSFW bool `json:"nsfw"` + Date *string `json:"date"` + Platform *string `json:"platform"` + Images res.SubjectImages `json:"images"` + Image string `json:"image"` + Summary string `json:"summary"` + Name string `json:"name"` + NameCN string `json:"name_cn"` + Tags []res.SubjectTag `json:"tags"` + Infobox res.V0wiki `json:"infobox"` + Rating res.Rating `json:"rating"` + Collection res.SubjectCollectionStat `json:"collection"` + ID model.SubjectID `json:"id"` + Eps uint32 `json:"eps"` + MetaTags []string `json:"meta_tags"` + Volumes uint32 `json:"volumes"` + Series bool `json:"series"` + Locked bool `json:"locked"` + NSFW bool `json:"nsfw"` + TypeID model.SubjectType `json:"type"` + Redirect model.SubjectID `json:"-"` } //nolint:funlen @@ -128,28 +141,20 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } + tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) + if err != nil { + return errgo.Wrap(err, "tagRepo.GetByIDs") + } + var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { s, ok := subjects[id] if !ok { continue } - - data = append(data, ReponseSubject{ - Date: s.Date, - Image: res.SubjectImage(s.Image).Large, - Type: s.TypeID, - Summary: s.Summary, - Name: s.Name, - NameCN: s.NameCN, - Tags: slice.Map(s.Tags, func(item model.Tag) res.SubjectTag { - return res.SubjectTag{Name: item.Name, Count: item.Count} - }), - Score: s.Rating.Score, - ID: s.ID, - Rank: s.Rating.Rank, - NSFW: s.NSFW, - }) + metaTags := tags[id] + subject := toResponseSubject(s, metaTags) + data = append(data, subject) } return ctx.JSON(http.StatusOK, res.Paged{ @@ -323,3 +328,58 @@ func isDigitsOnly(s string) bool { } return true } + +func toResponseSubject(s model.Subject, metaTags []tag.Tag) ReponseSubject { + images := res.SubjectImage(s.Image) + return ReponseSubject{ + ID: s.ID, + Image: images.Large, + Images: images, + Summary: s.Summary, + Name: s.Name, + Platform: res.PlatformString(s), + NameCN: s.NameCN, + Date: null.NilString(s.Date), + Infobox: compat.V0Wiki(wiki.ParseOmitError(s.Infobox).NonZero()), + Volumes: s.Volumes, + Redirect: s.Redirect, + Eps: s.Eps, + MetaTags: lo.Map(metaTags, func(item tag.Tag, index int) string { + return item.Name + }), + Tags: slice.Map(s.Tags, func(tag model.Tag) res.SubjectTag { + return res.SubjectTag{ + Name: tag.Name, + Count: tag.Count, + } + }), + Collection: res.SubjectCollectionStat{ + OnHold: s.OnHold, + Wish: s.Wish, + Dropped: s.Dropped, + Collect: s.Collect, + Doing: s.Doing, + }, + TypeID: s.TypeID, + Series: s.Series, + Locked: s.Locked(), + NSFW: s.NSFW, + Rating: res.Rating{ + Rank: s.Rating.Rank, + Total: s.Rating.Total, + Count: res.Count{ + Field1: s.Rating.Count.Field1, + Field2: s.Rating.Count.Field2, + Field3: s.Rating.Count.Field3, + Field4: s.Rating.Count.Field4, + Field5: s.Rating.Count.Field5, + Field6: s.Rating.Count.Field6, + Field7: s.Rating.Count.Field7, + Field8: s.Rating.Count.Field8, + Field9: s.Rating.Count.Field9, + Field10: s.Rating.Count.Field10, + }, + Score: s.Rating.Score, + }, + } +} diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 53cc49801..c7ea620dd 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -143,66 +143,7 @@ paths: content: application/json: schema: - description: 用户信息 - type: object - properties: - total: - description: 搜索结果数量 - type: integer - example: 100 - limit: - description: 当前分页参数 - type: integer - example: 100 - offset: - description: 当前分页参数 - type: integer - example: 100 - data: - type: array - items: - type: object - required: - - score - - id - - rank - - tags - - name - - name_cn - - image - - date - - summary - properties: - id: - description: 条目ID - type: integer - example: 8 - type: - $ref: "#/components/schemas/SubjectType" - "date": - "type": "string" - description: 上映/开播/连载开始日期,可能为空字符串 - "image": - "type": "string" - format: url - description: 封面 - summary: - type: string - description: 条目描述 - "name": - "type": "string" - description: 条目原名 - "name_cn": - "type": "string" - description: 条目中文名 - "tags": - $ref: "#/components/schemas/SubjectTags" - "score": - description: 评分 - "type": "number" - "rank": - description: 排名 - "type": "integer" + "$ref": "#/components/schemas/Paged_Subject" "/v0/subjects": get: diff --git a/web/handler/subject/browse.go b/web/handler/subject/browse.go index 2968a425b..1e08f763d 100644 --- a/web/handler/subject/browse.go +++ b/web/handler/subject/browse.go @@ -58,9 +58,19 @@ func (h Subject) Browse(c echo.Context) error { if err != nil { return errgo.Wrap(err, "failed to browse subjects") } + ids := make([]model.SubjectID, 0, len(subjects)) + for _, s := range subjects { + ids = append(ids, s.ID) + } + tags, err := h.tag.GetByIDs(c.Request().Context(), ids) + if err != nil { + return errgo.Wrap(err, "failed to get tags") + } + data := make([]res.SubjectV0, 0, len(subjects)) for _, s := range subjects { - data = append(data, convertModelSubject(s, 0, nil)) + metaTags := tags[s.ID] + data = append(data, res.ToSubjectV0(s, 0, metaTags)) } return c.JSON(http.StatusOK, res.Paged{Data: data, Total: count, Limit: page.Limit, Offset: page.Offset}) diff --git a/web/handler/subject/get.go b/web/handler/subject/get.go index 17a3568a1..4aa9179b7 100644 --- a/web/handler/subject/get.go +++ b/web/handler/subject/get.go @@ -20,21 +20,14 @@ import ( "net/http" "github.com/labstack/echo/v4" - "github.com/samber/lo" "github.com/trim21/errgo" - "go.uber.org/zap" "github.com/bangumi/server/domain/gerr" "github.com/bangumi/server/internal/episode" "github.com/bangumi/server/internal/model" - "github.com/bangumi/server/internal/pkg/compat" - "github.com/bangumi/server/internal/pkg/generic/slice" - "github.com/bangumi/server/internal/pkg/logger" "github.com/bangumi/server/internal/pkg/null" "github.com/bangumi/server/internal/subject" - "github.com/bangumi/server/internal/tag" "github.com/bangumi/server/pkg/vars" - "github.com/bangumi/server/pkg/wiki" "github.com/bangumi/server/web/accessor" "github.com/bangumi/server/web/req" "github.com/bangumi/server/web/res" @@ -73,24 +66,7 @@ func (h Subject) Get(c echo.Context) error { return err } - return c.JSON(http.StatusOK, convertModelSubject(s, totalEpisode, metaTags)) -} - -func platformString(s model.Subject) *string { - platform, ok := vars.PlatformMap[s.TypeID][s.PlatformID] - if !ok && s.TypeID != 0 { - logger.Warn("unknown platform", - zap.Uint32("subject", s.ID), - zap.Uint8("type", s.TypeID), - zap.Uint16("platform", s.PlatformID), - ) - - return nil - } - - v := platform.String() - - return &v + return c.JSON(http.StatusOK, res.ToSubjectV0(s, totalEpisode, metaTags)) } func (h Subject) GetImage(c echo.Context) error { @@ -121,60 +97,6 @@ func (h Subject) GetImage(c echo.Context) error { return c.Redirect(http.StatusFound, l) } -func convertModelSubject(s model.Subject, totalEpisode int64, metaTags []tag.Tag) res.SubjectV0 { - return res.SubjectV0{ - TotalEpisodes: totalEpisode, - ID: s.ID, - Image: res.SubjectImage(s.Image), - Summary: s.Summary, - Name: s.Name, - Platform: platformString(s), - NameCN: s.NameCN, - Date: null.NilString(s.Date), - Infobox: compat.V0Wiki(wiki.ParseOmitError(s.Infobox).NonZero()), - Volumes: s.Volumes, - Redirect: s.Redirect, - Eps: s.Eps, - MetaTags: lo.Map(metaTags, func(item tag.Tag, index int) string { - return item.Name - }), - Tags: slice.Map(s.Tags, func(tag model.Tag) res.SubjectTag { - return res.SubjectTag{ - Name: tag.Name, - Count: tag.Count, - } - }), - Collection: res.SubjectCollectionStat{ - OnHold: s.OnHold, - Wish: s.Wish, - Dropped: s.Dropped, - Collect: s.Collect, - Doing: s.Doing, - }, - TypeID: s.TypeID, - Series: s.Series, - Locked: s.Locked(), - NSFW: s.NSFW, - Rating: res.Rating{ - Rank: s.Rating.Rank, - Total: s.Rating.Total, - Count: res.Count{ - Field1: s.Rating.Count.Field1, - Field2: s.Rating.Count.Field2, - Field3: s.Rating.Count.Field3, - Field4: s.Rating.Count.Field4, - Field5: s.Rating.Count.Field5, - Field6: s.Rating.Count.Field6, - Field7: s.Rating.Count.Field7, - Field8: s.Rating.Count.Field8, - Field9: s.Rating.Count.Field9, - Field10: s.Rating.Count.Field10, - }, - Score: s.Rating.Score, - }, - } -} - func readableRelation(destSubjectType model.SubjectType, relation uint16) string { var r, ok = vars.RelationMap[destSubjectType][relation] if !ok || relation == 1 { diff --git a/web/res/character.go b/web/res/character.go index 703b55d37..2f6ac467d 100644 --- a/web/res/character.go +++ b/web/res/character.go @@ -25,7 +25,7 @@ type CharacterV0 struct { Images PersonImages `json:"images"` Summary string `json:"summary"` Name string `json:"name"` - Infobox v0wiki `json:"infobox"` + Infobox V0wiki `json:"infobox"` Stat Stat `json:"stat"` ID model.CharacterID `json:"id"` Redirect model.CharacterID `json:"-"` diff --git a/web/res/person.go b/web/res/person.go index f08c8f101..8c5410e31 100644 --- a/web/res/person.go +++ b/web/res/person.go @@ -34,7 +34,7 @@ type PersonV0 struct { Summary string `json:"summary"` Name string `json:"name"` Img string `json:"img"` - Infobox v0wiki `json:"infobox"` + Infobox V0wiki `json:"infobox"` Career []string `json:"career"` Stat Stat `json:"stat"` Redirect model.PersonID `json:"-"` diff --git a/web/res/subject.go b/web/res/subject.go index 66300e7b5..c7bf3ab01 100644 --- a/web/res/subject.go +++ b/web/res/subject.go @@ -18,15 +18,22 @@ import ( "time" "github.com/samber/lo" + "go.uber.org/zap" "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/compat" "github.com/bangumi/server/internal/pkg/generic/slice" "github.com/bangumi/server/internal/pkg/gstr" + "github.com/bangumi/server/internal/pkg/logger" + "github.com/bangumi/server/internal/pkg/null" + "github.com/bangumi/server/internal/tag" + "github.com/bangumi/server/pkg/vars" + "github.com/bangumi/server/pkg/wiki" ) const defaultShortSummaryLength = 120 -type v0wiki = []any +type V0wiki = []any type SubjectTag struct { Name string `json:"name"` @@ -37,12 +44,12 @@ type SubjectTag struct { type SubjectV0 struct { Date *string `json:"date"` Platform *string `json:"platform"` - Image SubjectImages `json:"images"` + Images SubjectImages `json:"images"` Summary string `json:"summary"` Name string `json:"name"` NameCN string `json:"name_cn"` Tags []SubjectTag `json:"tags"` - Infobox v0wiki `json:"infobox"` + Infobox V0wiki `json:"infobox"` Rating Rating `json:"rating"` TotalEpisodes int64 `json:"total_episodes" doc:"episodes count in database"` Collection SubjectCollectionStat `json:"collection"` @@ -101,6 +108,75 @@ func ToSlimSubjectV0(s model.Subject) SlimSubjectV0 { } } +func PlatformString(s model.Subject) *string { + platform, ok := vars.PlatformMap[s.TypeID][s.PlatformID] + if !ok && s.TypeID != 0 { + logger.Warn("unknown platform", + zap.Uint32("subject", s.ID), + zap.Uint8("type", s.TypeID), + zap.Uint16("platform", s.PlatformID), + ) + + return nil + } + v := platform.String() + return &v +} + +func ToSubjectV0(s model.Subject, totalEpisode int64, metaTags []tag.Tag) SubjectV0 { + return SubjectV0{ + TotalEpisodes: totalEpisode, + ID: s.ID, + Images: SubjectImage(s.Image), + Summary: s.Summary, + Name: s.Name, + Platform: PlatformString(s), + NameCN: s.NameCN, + Date: null.NilString(s.Date), + Infobox: compat.V0Wiki(wiki.ParseOmitError(s.Infobox).NonZero()), + Volumes: s.Volumes, + Redirect: s.Redirect, + Eps: s.Eps, + MetaTags: lo.Map(metaTags, func(item tag.Tag, index int) string { + return item.Name + }), + Tags: slice.Map(s.Tags, func(tag model.Tag) SubjectTag { + return SubjectTag{ + Name: tag.Name, + Count: tag.Count, + } + }), + Collection: SubjectCollectionStat{ + OnHold: s.OnHold, + Wish: s.Wish, + Dropped: s.Dropped, + Collect: s.Collect, + Doing: s.Doing, + }, + TypeID: s.TypeID, + Series: s.Series, + Locked: s.Locked(), + NSFW: s.NSFW, + Rating: Rating{ + Rank: s.Rating.Rank, + Total: s.Rating.Total, + Count: Count{ + Field1: s.Rating.Count.Field1, + Field2: s.Rating.Count.Field2, + Field3: s.Rating.Count.Field3, + Field4: s.Rating.Count.Field4, + Field5: s.Rating.Count.Field5, + Field6: s.Rating.Count.Field6, + Field7: s.Rating.Count.Field7, + Field8: s.Rating.Count.Field8, + Field9: s.Rating.Count.Field9, + Field10: s.Rating.Count.Field10, + }, + Score: s.Rating.Score, + }, + } +} + type SubjectCollectionStat struct { OnHold uint32 `json:"on_hold"` Dropped uint32 `json:"dropped"` @@ -220,7 +296,7 @@ type IndexSubjectV0 struct { Name string `json:"name"` NameCN string `json:"name_cn"` Comment string `json:"comment"` - Infobox v0wiki `json:"infobox"` + Infobox V0wiki `json:"infobox"` ID model.SubjectID `json:"id"` TypeID model.SubjectType `json:"type"` } From 52ee030e7ffd482d43870367dfc15b001eed111c Mon Sep 17 00:00:00 2001 From: everpcpc Date: Mon, 25 Nov 2024 22:16:02 +0800 Subject: [PATCH 203/240] fix: return empty for empty tag request (#665) --- internal/tag/cache_repo.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index b1ca5e190..74c6ab70e 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -74,6 +74,11 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { var tags []cachedTags + result := make(map[model.SubjectID][]Tag, len(ids)) + if len(ids) == 0 { + return result, nil + } + err := r.cache.MGet(ctx, lo.Map(ids, func(item model.SubjectID, index int) string { return cachekey.SubjectMetaTag(item) }), &tags) @@ -81,7 +86,6 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod return nil, errgo.Wrap(err, "cache.MGet") } - result := make(map[model.SubjectID][]Tag, len(ids)) for _, tag := range tags { result[tag.ID] = tag.Tags } From 61c46bcad0c216ad779d0a9df2d8a4ec5a7d65e2 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Mon, 25 Nov 2024 22:31:44 +0800 Subject: [PATCH 204/240] fix: missing tag cached repo for canal (#666) --- canal/canal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/canal/canal.go b/canal/canal.go index 985c7b4de..1681c5d10 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -64,7 +64,7 @@ func Main() error { driver.NewRueidisClient, logger.Copy, cache.NewRedisCache, subject.NewMysqlRepo, search.New, session.NewMysqlRepo, session.New, driver.NewS3, - + tag.NewCachedRepo, tag.NewMysqlRepo, newEventHandler, From 942e226e795150f91d19824371f247ad2d02d041 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:10:29 +0800 Subject: [PATCH 205/240] metrics: add meta tags cached count (#667) --- internal/tag/cache_repo.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index 74c6ab70e..65ba0c288 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -18,6 +18,7 @@ import ( "context" "time" + "github.com/prometheus/client_golang/prometheus" "github.com/samber/lo" "github.com/trim21/errgo" "go.uber.org/zap" @@ -44,6 +45,28 @@ type cachedTags struct { Tags []Tag } +//nolint:gochecknoglobals +var CacheCount = prometheus.NewCounter(prometheus.CounterOpts{ + Subsystem: "chii", + Name: "cached_count_total", + Help: "", + ConstLabels: map[string]string{"repo": "meta_tags"}, +}) + +//nolint:gochecknoglobals +var NotCacheCount = prometheus.NewCounter(prometheus.CounterOpts{ + Subsystem: "chii", + Name: "not_cached_count_total", + Help: "", + ConstLabels: map[string]string{"repo": "meta_tags"}, +}) + +//nolint:gochecknoinits +func init() { + prometheus.MustRegister(CacheCount) + prometheus.MustRegister(NotCacheCount) +} + func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { var key = cachekey.SubjectMetaTag(id) @@ -54,8 +77,10 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { } if ok { + CacheCount.Add(1) return s.Tags, nil } + NotCacheCount.Add(1) tags, err := r.repo.Get(ctx, id) if err != nil { @@ -86,6 +111,7 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod return nil, errgo.Wrap(err, "cache.MGet") } + CacheCount.Add(float64(len(tags))) for _, tag := range tags { result[tag.ID] = tag.Tags } @@ -97,6 +123,7 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod } } + NotCacheCount.Add(float64(len(missing))) missingFromCache, err := r.repo.GetByIDs(ctx, missing) if err != nil { return nil, err From 38d2434e949eb5de53efaaf0db79f58dd23ce5df Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:14:01 +0800 Subject: [PATCH 206/240] build: add commit date to docker tags (#668) --- .github/workflows/release-docker.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml index 55bdffcf1..e9fbd9837 100644 --- a/.github/workflows/release-docker.yaml +++ b/.github/workflows/release-docker.yaml @@ -65,6 +65,7 @@ jobs: images: ${{ env.IMAGE }} tags: | type=semver,event=tag,pattern=v{{version}} + type=raw,value={{commit_date 'YYYY-MM-DD'}}-{{sha}} type=ref,event=branch type=ref,event=branch,suffix=-${{ env.SHA }} From 47fb70b3577583d1733d9942905a84404c246d29 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:32:26 +0800 Subject: [PATCH 207/240] perf: cache subject empty meta tags list (#669) --- internal/cachekey/cachekey.go | 2 +- internal/tag/cache_repo.go | 1 + internal/tag/mysql_repo.go | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/cachekey/cachekey.go b/internal/cachekey/cachekey.go index 2f424a728..524fe1ded 100644 --- a/internal/cachekey/cachekey.go +++ b/internal/cachekey/cachekey.go @@ -56,5 +56,5 @@ func User(id model.UserID) string { } func SubjectMetaTag(id model.SubjectID) string { - return resPrefix + "subject:meta-tags:" + strconv.FormatUint(uint64(id), 10) + return "chii:v0:subject:meta-tags:" + strconv.FormatUint(uint64(id), 10) } diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index 65ba0c288..bfda1de40 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -97,6 +97,7 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { return tags, nil } +// GetByIDs also need to change version in [cachekey.SubjectMetaTag] if schema is changed. func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { var tags []cachedTags result := make(map[model.SubjectID][]Tag, len(ids)) diff --git a/internal/tag/mysql_repo.go b/internal/tag/mysql_repo.go index 955388df6..a171efcf0 100644 --- a/internal/tag/mysql_repo.go +++ b/internal/tag/mysql_repo.go @@ -93,5 +93,13 @@ func (r mysqlRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod }) } + // set empty slice for subjects without tags + // this help we cache them. + for _, id := range ids { + if _, ok := tags[id]; !ok { + tags[id] = []Tag{} + } + } + return tags, nil } From be53cba54b1f9c4c8f1ceaa5969cf591d136a0f4 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:38:47 +0800 Subject: [PATCH 208/240] perf: only query tags for non-empty id list --- internal/tag/cache_repo.go | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index bfda1de40..900cde4df 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -46,28 +46,27 @@ type cachedTags struct { } //nolint:gochecknoglobals -var CacheCount = prometheus.NewCounter(prometheus.CounterOpts{ +var CachedCount = prometheus.NewCounter(prometheus.CounterOpts{ Subsystem: "chii", - Name: "cached_count_total", - Help: "", + Name: "query_cached_count_total", ConstLabels: map[string]string{"repo": "meta_tags"}, }) //nolint:gochecknoglobals -var NotCacheCount = prometheus.NewCounter(prometheus.CounterOpts{ +var TotalCount = prometheus.NewCounter(prometheus.CounterOpts{ Subsystem: "chii", - Name: "not_cached_count_total", - Help: "", + Name: "query_count_total", ConstLabels: map[string]string{"repo": "meta_tags"}, }) //nolint:gochecknoinits func init() { - prometheus.MustRegister(CacheCount) - prometheus.MustRegister(NotCacheCount) + prometheus.MustRegister(CachedCount) + prometheus.MustRegister(TotalCount) } func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { + TotalCount.Add(1) var key = cachekey.SubjectMetaTag(id) var s cachedTags @@ -77,10 +76,9 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { } if ok { - CacheCount.Add(1) + CachedCount.Add(1) return s.Tags, nil } - NotCacheCount.Add(1) tags, err := r.repo.Get(ctx, id) if err != nil { @@ -99,6 +97,8 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { // GetByIDs also need to change version in [cachekey.SubjectMetaTag] if schema is changed. func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { + TotalCount.Add(float64(len(ids))) + var tags []cachedTags result := make(map[model.SubjectID][]Tag, len(ids)) if len(ids) == 0 { @@ -112,7 +112,7 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod return nil, errgo.Wrap(err, "cache.MGet") } - CacheCount.Add(float64(len(tags))) + CachedCount.Add(float64(len(tags))) for _, tag := range tags { result[tag.ID] = tag.Tags } @@ -124,19 +124,20 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod } } - NotCacheCount.Add(float64(len(missing))) - missingFromCache, err := r.repo.GetByIDs(ctx, missing) - if err != nil { - return nil, err - } - for id, tag := range missingFromCache { - result[id] = tag - err = r.cache.Set(ctx, cachekey.SubjectMetaTag(id), cachedTags{ - ID: id, - Tags: tag, - }, time.Hour) + if len(missing) != 0 { + missingFromCache, err := r.repo.GetByIDs(ctx, missing) if err != nil { - return nil, errgo.Wrap(err, "cache.Set") + return nil, err + } + for id, tag := range missingFromCache { + result[id] = tag + err = r.cache.Set(ctx, cachekey.SubjectMetaTag(id), cachedTags{ + ID: id, + Tags: tag, + }, time.Hour) + if err != nil { + return nil, errgo.Wrap(err, "cache.Set") + } } } From 4176a449867722e4ede99c36621debff2299bfad Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:42:57 +0800 Subject: [PATCH 209/240] style: add help message to metrics --- internal/tag/cache_repo.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index 900cde4df..ccdcfe4cd 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -49,6 +49,7 @@ type cachedTags struct { var CachedCount = prometheus.NewCounter(prometheus.CounterOpts{ Subsystem: "chii", Name: "query_cached_count_total", + Help: "cached sql query count total", ConstLabels: map[string]string{"repo": "meta_tags"}, }) @@ -56,6 +57,7 @@ var CachedCount = prometheus.NewCounter(prometheus.CounterOpts{ var TotalCount = prometheus.NewCounter(prometheus.CounterOpts{ Subsystem: "chii", Name: "query_count_total", + Help: "sql query count total", ConstLabels: map[string]string{"repo": "meta_tags"}, }) From b5322530d51a42d59b8b636f83aae23df03a98fa Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:44:52 +0800 Subject: [PATCH 210/240] perf: always cache meta tags 1h --- internal/tag/cache_repo.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index ccdcfe4cd..e4a476b9f 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -67,6 +67,8 @@ func init() { prometheus.MustRegister(TotalCount) } +// also need to change version in [cachekey.SubjectMetaTag] if schema is changed. + func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { TotalCount.Add(1) var key = cachekey.SubjectMetaTag(id) @@ -90,14 +92,13 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { if e := r.cache.Set(ctx, key, cachedTags{ ID: id, Tags: tags, - }, time.Minute); e != nil { + }, time.Hour); e != nil { r.log.Error("can't set response to cache", zap.Error(e)) } return tags, nil } -// GetByIDs also need to change version in [cachekey.SubjectMetaTag] if schema is changed. func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { TotalCount.Add(float64(len(ids))) From 713a905e871f16db006ec579c61a70d2d009bed5 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:46:04 +0800 Subject: [PATCH 211/240] refactor: use early return --- internal/tag/cache_repo.go | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index e4a476b9f..0b85bcfad 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -100,14 +100,15 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { } func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[model.SubjectID][]Tag, error) { - TotalCount.Add(float64(len(ids))) - - var tags []cachedTags result := make(map[model.SubjectID][]Tag, len(ids)) if len(ids) == 0 { return result, nil } + TotalCount.Add(float64(len(ids))) + + var tags []cachedTags + err := r.cache.MGet(ctx, lo.Map(ids, func(item model.SubjectID, index int) string { return cachekey.SubjectMetaTag(item) }), &tags) @@ -127,20 +128,22 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod } } - if len(missing) != 0 { - missingFromCache, err := r.repo.GetByIDs(ctx, missing) + if len(missing) == 0 { + return result, nil + } + + missingFromCache, err := r.repo.GetByIDs(ctx, missing) + if err != nil { + return nil, err + } + for id, tag := range missingFromCache { + result[id] = tag + err = r.cache.Set(ctx, cachekey.SubjectMetaTag(id), cachedTags{ + ID: id, + Tags: tag, + }, time.Hour) if err != nil { - return nil, err - } - for id, tag := range missingFromCache { - result[id] = tag - err = r.cache.Set(ctx, cachekey.SubjectMetaTag(id), cachedTags{ - ID: id, - Tags: tag, - }, time.Hour) - if err != nil { - return nil, errgo.Wrap(err, "cache.Set") - } + return nil, errgo.Wrap(err, "cache.Set") } } From 43d03abbaab4e57826e118bda69e105e63d93221 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:52:06 +0800 Subject: [PATCH 212/240] chore: add some logger --- internal/pkg/cache/redis.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/pkg/cache/redis.go b/internal/pkg/cache/redis.go index c73384055..d09fe4baa 100644 --- a/internal/pkg/cache/redis.go +++ b/internal/pkg/cache/redis.go @@ -110,6 +110,7 @@ func (c redisCache) MGet(ctx context.Context, keys []string, result any) error { e := message.DecodeJSON(v.Interface()) if e != nil { + logger.Warn("unexpected failure when decoding json", zap.Error(e)) continue } From 792c56bda56a64e65a2d0ea380bdf79af9ac5687 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 25 Nov 2024 23:56:40 +0800 Subject: [PATCH 213/240] chore: ignore nil redis error --- internal/pkg/cache/redis.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/pkg/cache/redis.go b/internal/pkg/cache/redis.go index d09fe4baa..3ba23db54 100644 --- a/internal/pkg/cache/redis.go +++ b/internal/pkg/cache/redis.go @@ -108,6 +108,11 @@ func (c redisCache) MGet(ctx context.Context, keys []string, result any) error { for _, message := range results { var v = reflect.New(elementType) + //nolint:errorlint + if message.Error() == rueidis.Nil { + continue + } + e := message.DecodeJSON(v.Interface()) if e != nil { logger.Warn("unexpected failure when decoding json", zap.Error(e)) From b0d5e5a1afed6d0dec49011afd1b160fc04d6f39 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:15:19 +0800 Subject: [PATCH 214/240] perf: use metaTags in subject table --- internal/search/handle.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 2c407bc8b..744a02a16 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -141,10 +141,10 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) - if err != nil { - return errgo.Wrap(err, "tagRepo.GetByIDs") - } + // tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) + // if err != nil { + // return errgo.Wrap(err, "tagRepo.GetByIDs") + // } var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { @@ -152,7 +152,13 @@ func (c *client) Handle(ctx echo.Context) error { if !ok { continue } - metaTags := tags[id] + // metaTags := tags[id] + var metaTags []tag.Tag + + for _, t := range strings.Split(s.MetaTags, " ") { + metaTags = append(metaTags, tag.Tag{Name: t, Count: 1}) + } + subject := toResponseSubject(s, metaTags) data = append(data, subject) } From f93cd3d44886fa4875ac051ca33ae1215002ca38 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:28:02 +0800 Subject: [PATCH 215/240] perf: remove unnecessary sql filter --- internal/search/handle.go | 8 +------- internal/tag/cache_repo.go | 9 ++++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 744a02a16..f0d943227 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -130,13 +130,7 @@ func (c *client) Handle(ctx echo.Context) error { } ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) - var sf = subject.Filter{} - - if r.Filter.NSFW.Set && !r.Filter.NSFW.Value { - sf.NSFW = null.Bool{Set: true, Value: false} - } - - subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, sf) + subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, subject.Filter{}) if err != nil { return errgo.Wrap(err, "subjectRepo.GetByIDs") } diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index 0b85bcfad..32f3b4bae 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -28,6 +28,8 @@ import ( "github.com/bangumi/server/internal/pkg/cache" ) +const cacheTTL = time.Hour * 4 + func NewCachedRepo(c cache.RedisCache, r Repo, log *zap.Logger) CachedRepo { return cacheRepo{cache: c, repo: r, log: log.Named("subject.CachedRepo")} } @@ -89,10 +91,7 @@ func (r cacheRepo) Get(ctx context.Context, id model.SubjectID) ([]Tag, error) { return tags, err } - if e := r.cache.Set(ctx, key, cachedTags{ - ID: id, - Tags: tags, - }, time.Hour); e != nil { + if e := r.cache.Set(ctx, key, cachedTags{ID: id, Tags: tags}, cacheTTL); e != nil { r.log.Error("can't set response to cache", zap.Error(e)) } @@ -141,7 +140,7 @@ func (r cacheRepo) GetByIDs(ctx context.Context, ids []model.SubjectID) (map[mod err = r.cache.Set(ctx, cachekey.SubjectMetaTag(id), cachedTags{ ID: id, Tags: tag, - }, time.Hour) + }, cacheTTL) if err != nil { return nil, errgo.Wrap(err, "cache.Set") } From 867e0f06083a2b8b014c842accffb778676d1997 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:38:07 +0800 Subject: [PATCH 216/240] perf: only get meta tags for non-empty string --- internal/search/handle.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index f0d943227..ed580a223 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -135,10 +135,17 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - // tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) - // if err != nil { - // return errgo.Wrap(err, "tagRepo.GetByIDs") - // } + var idsToGetTags []model.SubjectID + for _, m := range subjects { + if m.MetaTags != "" { + idsToGetTags = append(idsToGetTags, m.ID) + } + } + + tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), idsToGetTags) + if err != nil { + return errgo.Wrap(err, "tagRepo.GetByIDs") + } var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { @@ -146,8 +153,10 @@ func (c *client) Handle(ctx echo.Context) error { if !ok { continue } - // metaTags := tags[id] - var metaTags []tag.Tag + metaTags := tags[id] + if metaTags == nil { + metaTags = []tag.Tag{} + } for _, t := range strings.Split(s.MetaTags, " ") { metaTags = append(metaTags, tag.Tag{Name: t, Count: 1}) From 42c1534918442506b6a165ba52afc6713b441f08 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:43:12 +0800 Subject: [PATCH 217/240] Revert "perf: only get meta tags for non-empty string" This reverts commit 867e0f06083a2b8b014c842accffb778676d1997. --- internal/search/handle.go | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index ed580a223..f0d943227 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -135,17 +135,10 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - var idsToGetTags []model.SubjectID - for _, m := range subjects { - if m.MetaTags != "" { - idsToGetTags = append(idsToGetTags, m.ID) - } - } - - tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), idsToGetTags) - if err != nil { - return errgo.Wrap(err, "tagRepo.GetByIDs") - } + // tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) + // if err != nil { + // return errgo.Wrap(err, "tagRepo.GetByIDs") + // } var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { @@ -153,10 +146,8 @@ func (c *client) Handle(ctx echo.Context) error { if !ok { continue } - metaTags := tags[id] - if metaTags == nil { - metaTags = []tag.Tag{} - } + // metaTags := tags[id] + var metaTags []tag.Tag for _, t := range strings.Split(s.MetaTags, " ") { metaTags = append(metaTags, tag.Tag{Name: t, Count: 1}) From 02803c97c253313b3080764d4c795a38a2887d11 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:49:27 +0800 Subject: [PATCH 218/240] fix: reduce default search page size --- internal/search/handle.go | 4 ++-- openapi/v0.yaml | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index f0d943227..76818d284 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -54,8 +54,8 @@ type Handler interface { Handle(c echo.Context) error } -const defaultLimit = 50 -const maxLimit = 200 +const defaultLimit = 10 +const maxLimit = 20 type Req struct { Keyword string `json:"keyword"` diff --git a/openapi/v0.yaml b/openapi/v0.yaml index c7ea620dd..98584a8d2 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -33,11 +33,6 @@ paths: 不同筛选条件之间为 `且` - - 由于目前 meilisearch 的一些问题,条目排名更新并不会触发搜索数据更新,所以条目排名可能是过期数据。 - - 希望未来版本的 meilisearch 能解决相关的问题。 - parameters: - name: limit in: query From 0986a409d82c418c37461b587210b021e8577c92 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:52:26 +0800 Subject: [PATCH 219/240] fix!: reduce search page limit to 20 --- internal/search/handle.go | 2 +- web/req/page.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 76818d284..44061308a 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -105,7 +105,7 @@ type ReponseSubject struct { //nolint:funlen func (c *client) Handle(ctx echo.Context) error { auth := accessor.GetFromCtx(ctx) - q, err := req.GetPageQuery(ctx, defaultLimit, maxLimit) + q, err := req.GetPageQuerySoftLimit(ctx, defaultLimit, maxLimit) if err != nil { return err } diff --git a/web/req/page.go b/web/req/page.go index c0e1de94b..18e719ac1 100644 --- a/web/req/page.go +++ b/web/req/page.go @@ -35,6 +35,42 @@ func (q PageQuery) Check(count int64) error { return nil } +// GetPageQuerySoftLimit apply soft limit on query without error. +func GetPageQuerySoftLimit(c echo.Context, defaultLimit int, maxLimit int) (PageQuery, error) { + q := PageQuery{Limit: defaultLimit} + var err error + + raw := c.QueryParam("limit") + if raw != "" { + q.Limit, err = strconv.Atoi(raw) + if err != nil { + return q, res.BadRequest("can't parse query args limit as int: " + strconv.Quote(raw)) + } + + if q.Limit <= 0 { + return q, res.BadRequest("limit should be greater than zero") + } + + if q.Limit > maxLimit { + q.Limit = maxLimit + } + } + + raw = c.QueryParam("offset") + if raw != "" { + q.Offset, err = strconv.Atoi(raw) + if err != nil { + return q, res.BadRequest("can't parse query args offset as int: " + strconv.Quote(raw)) + } + + if q.Offset < 0 { + return q, res.BadRequest("offset should be greater than or equal to 0") + } + } + + return q, nil +} + func GetPageQuery(c echo.Context, defaultLimit int, maxLimit int) (PageQuery, error) { q := PageQuery{Limit: defaultLimit} var err error From 679000afb3b1a011b517a16ca2a53599e45fe0af Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 00:38:07 +0800 Subject: [PATCH 220/240] perf: only get meta tags for non-empty string --- internal/search/handle.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 44061308a..42e88396b 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -135,10 +135,17 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - // tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) - // if err != nil { - // return errgo.Wrap(err, "tagRepo.GetByIDs") - // } + var idsToGetTags []model.SubjectID + for _, m := range subjects { + if m.MetaTags != "" { + idsToGetTags = append(idsToGetTags, m.ID) + } + } + + tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), idsToGetTags) + if err != nil { + return errgo.Wrap(err, "tagRepo.GetByIDs") + } var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { @@ -146,8 +153,10 @@ func (c *client) Handle(ctx echo.Context) error { if !ok { continue } - // metaTags := tags[id] - var metaTags []tag.Tag + metaTags := tags[id] + if metaTags == nil { + metaTags = []tag.Tag{} + } for _, t := range strings.Split(s.MetaTags, " ") { metaTags = append(metaTags, tag.Tag{Name: t, Count: 1}) From b136b6010de398f16bcc2961ad9ec5b82335333b Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 01:04:59 +0800 Subject: [PATCH 221/240] perf: cache meta tags 24h --- internal/tag/cache_repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tag/cache_repo.go b/internal/tag/cache_repo.go index 32f3b4bae..4cbc3ff0f 100644 --- a/internal/tag/cache_repo.go +++ b/internal/tag/cache_repo.go @@ -28,7 +28,7 @@ import ( "github.com/bangumi/server/internal/pkg/cache" ) -const cacheTTL = time.Hour * 4 +const cacheTTL = time.Hour * 24 func NewCachedRepo(c cache.RedisCache, r Repo, log *zap.Logger) CachedRepo { return cacheRepo{cache: c, repo: r, log: log.Named("subject.CachedRepo")} From b5a9fe0c386f733b6a8f49cb17aefb66187847c5 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 26 Nov 2024 01:24:32 +0800 Subject: [PATCH 222/240] Revert "perf: only get meta tags for non-empty string" This reverts commit 679000afb3b1a011b517a16ca2a53599e45fe0af. --- internal/search/handle.go | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/internal/search/handle.go b/internal/search/handle.go index 42e88396b..44061308a 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -135,17 +135,10 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - var idsToGetTags []model.SubjectID - for _, m := range subjects { - if m.MetaTags != "" { - idsToGetTags = append(idsToGetTags, m.ID) - } - } - - tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), idsToGetTags) - if err != nil { - return errgo.Wrap(err, "tagRepo.GetByIDs") - } + // tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) + // if err != nil { + // return errgo.Wrap(err, "tagRepo.GetByIDs") + // } var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { @@ -153,10 +146,8 @@ func (c *client) Handle(ctx echo.Context) error { if !ok { continue } - metaTags := tags[id] - if metaTags == nil { - metaTags = []tag.Tag{} - } + // metaTags := tags[id] + var metaTags []tag.Tag for _, t := range strings.Split(s.MetaTags, " ") { metaTags = append(metaTags, tag.Tag{Name: t, Count: 1}) From 7f56155804011d7566774953dcc5f30c4a87a939 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Tue, 26 Nov 2024 08:51:03 +0800 Subject: [PATCH 223/240] fix: ignore empty tag on search (#670) --- internal/search/client.go | 4 ---- internal/search/handle.go | 9 +++------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/internal/search/client.go b/internal/search/client.go index b3b3b50a2..d92627b94 100644 --- a/internal/search/client.go +++ b/internal/search/client.go @@ -39,7 +39,6 @@ import ( "github.com/bangumi/server/domain/gerr" "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/subject" - "github.com/bangumi/server/internal/tag" ) // New provide a search app is AppConfig.MeiliSearchURL is empty string, return nope search client. @@ -48,7 +47,6 @@ import ( func New( cfg config.AppConfig, subjectRepo subject.Repo, - tagRepo tag.CachedRepo, log *zap.Logger, query *query.Query, ) (Client, error) { @@ -80,7 +78,6 @@ func New( subjectIndex: meili.Index("subjects"), log: log.Named("search"), subjectRepo: subjectRepo, - tagRepo: tagRepo, } if cfg.AppType != config.AppTypeCanal { @@ -139,7 +136,6 @@ func (c *client) canalInit(cfg config.AppConfig) error { type client struct { subjectRepo subject.Repo - tagRepo tag.CachedRepo meili meilisearch.ServiceManager q *query.Query subjectIndex meilisearch.IndexManager diff --git a/internal/search/handle.go b/internal/search/handle.go index 44061308a..dc7978c23 100644 --- a/internal/search/handle.go +++ b/internal/search/handle.go @@ -135,21 +135,18 @@ func (c *client) Handle(ctx echo.Context) error { return errgo.Wrap(err, "subjectRepo.GetByIDs") } - // tags, err := c.tagRepo.GetByIDs(ctx.Request().Context(), ids) - // if err != nil { - // return errgo.Wrap(err, "tagRepo.GetByIDs") - // } - var data = make([]ReponseSubject, 0, len(subjects)) for _, id := range ids { s, ok := subjects[id] if !ok { continue } - // metaTags := tags[id] var metaTags []tag.Tag for _, t := range strings.Split(s.MetaTags, " ") { + if t == "" { + continue + } metaTags = append(metaTags, tag.Tag{Name: t, Count: 1}) } From 181fb87a7dbc20b638371f17d1be284fbdfc1eb4 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Tue, 26 Nov 2024 14:41:10 +0800 Subject: [PATCH 224/240] feat: support searching character & person (#671) --- canal/canal.go | 5 +- canal/event.go | 4 + canal/on_character.go | 45 +++ canal/on_person.go | 44 +++ canal/on_subject.go | 23 +- cmd/web/cmd.go | 3 +- internal/mocks/SearchClient.go | 132 +++---- internal/search/character/client.go | 110 ++++++ internal/search/character/doc.go | 51 +++ internal/search/character/event.go | 57 +++ internal/search/character/handle.go | 128 +++++++ internal/search/client.go | 340 ------------------ internal/search/extractor.common.go | 55 --- internal/search/noop.go | 14 +- internal/search/person/client.go | 110 ++++++ internal/search/person/doc.go | 49 +++ internal/search/person/event.go | 57 +++ internal/search/person/handle.go | 121 +++++++ internal/search/search.go | 150 ++++++++ internal/search/searcher/client.go | 231 ++++++++++++ internal/search/subject/client.go | 111 ++++++ internal/search/{index.go => subject/doc.go} | 32 +- .../doc_internal_test.go} | 2 +- internal/search/subject/event.go | 58 +++ internal/search/{ => subject}/handle.go | 21 +- .../{ => subject}/handle_internal_test.go | 2 +- .../{ => subject}/index_internal_test.go | 8 +- openapi/v0.yaml | 165 ++++++++- web/handler/character/character.go | 30 -- web/handler/character/get.go | 2 +- web/handler/search.go | 14 +- web/res/character.go | 32 +- web/routes.go | 4 +- 33 files changed, 1667 insertions(+), 543 deletions(-) create mode 100644 canal/on_character.go create mode 100644 canal/on_person.go create mode 100644 internal/search/character/client.go create mode 100644 internal/search/character/doc.go create mode 100644 internal/search/character/event.go create mode 100644 internal/search/character/handle.go delete mode 100644 internal/search/client.go delete mode 100644 internal/search/extractor.common.go create mode 100644 internal/search/person/client.go create mode 100644 internal/search/person/doc.go create mode 100644 internal/search/person/event.go create mode 100644 internal/search/person/handle.go create mode 100644 internal/search/search.go create mode 100644 internal/search/searcher/client.go create mode 100644 internal/search/subject/client.go rename internal/search/{index.go => subject/doc.go} (82%) rename internal/search/{extract_internal_test.go => subject/doc_internal_test.go} (98%) create mode 100644 internal/search/subject/event.go rename internal/search/{ => subject}/handle.go (94%) rename internal/search/{ => subject}/handle_internal_test.go (98%) rename internal/search/{ => subject}/index_internal_test.go (84%) diff --git a/canal/canal.go b/canal/canal.go index 1681c5d10..9ad7ea470 100644 --- a/canal/canal.go +++ b/canal/canal.go @@ -26,6 +26,8 @@ import ( "github.com/bangumi/server/config" "github.com/bangumi/server/dal" + "github.com/bangumi/server/internal/character" + "github.com/bangumi/server/internal/person" "github.com/bangumi/server/internal/pkg/cache" "github.com/bangumi/server/internal/pkg/driver" "github.com/bangumi/server/internal/pkg/logger" @@ -62,7 +64,8 @@ func Main() error { fx.Provide( driver.NewMysqlSqlDB, driver.NewRueidisClient, logger.Copy, cache.NewRedisCache, - subject.NewMysqlRepo, search.New, session.NewMysqlRepo, session.New, + subject.NewMysqlRepo, character.NewMysqlRepo, person.NewMysqlRepo, + search.New, session.NewMysqlRepo, session.New, driver.NewS3, tag.NewCachedRepo, tag.NewMysqlRepo, diff --git a/canal/event.go b/canal/event.go index 458b49819..4d7fc3d0f 100644 --- a/canal/event.go +++ b/canal/event.go @@ -124,6 +124,10 @@ func (e *eventHandler) onMessage(key, value []byte) error { err = e.OnSubjectField(ctx, key, p) case "chii_subjects": err = e.OnSubject(ctx, key, p) + case "chii_characters": + err = e.OnCharacter(ctx, key, p) + case "chii_persons": + err = e.OnPerson(ctx, key, p) case "chii_members": err = e.OnUserChange(ctx, key, p) } diff --git a/canal/on_character.go b/canal/on_character.go new file mode 100644 index 000000000..525d1b7d8 --- /dev/null +++ b/canal/on_character.go @@ -0,0 +1,45 @@ +package canal + +import ( + "context" + "encoding/json" + + "github.com/trim21/errgo" + "go.uber.org/zap" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search" +) + +type CharacterKey struct { + ID model.CharacterID `json:"crt_id"` +} + +func (e *eventHandler) OnCharacter(ctx context.Context, key json.RawMessage, payload Payload) error { + var k CharacterKey + if err := json.Unmarshal(key, &k); err != nil { + return err + } + return e.onCharacterChange(ctx, k.ID, payload.Op) +} + +func (e *eventHandler) onCharacterChange(ctx context.Context, characterID model.CharacterID, op string) error { + switch op { + case opCreate: + if err := e.search.EventAdded(ctx, characterID, search.SearchTargetCharacter); err != nil { + return errgo.Wrap(err, "search.OnCharacterAdded") + } + case opUpdate, opSnapshot: + if err := e.search.EventUpdate(ctx, characterID, search.SearchTargetCharacter); err != nil { + return errgo.Wrap(err, "search.OnCharacterUpdate") + } + case opDelete: + if err := e.search.EventDelete(ctx, characterID, search.SearchTargetCharacter); err != nil { + return errgo.Wrap(err, "search.OnCharacterDelete") + } + default: + e.log.Warn("unexpected operator", zap.String("op", op)) + } + + return nil +} diff --git a/canal/on_person.go b/canal/on_person.go new file mode 100644 index 000000000..f5f75b4fa --- /dev/null +++ b/canal/on_person.go @@ -0,0 +1,44 @@ +package canal + +import ( + "context" + "encoding/json" + + "github.com/trim21/errgo" + "go.uber.org/zap" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search" +) + +type PersonKey struct { + ID model.PersonID `json:"prsn_id"` +} + +func (e *eventHandler) OnPerson(ctx context.Context, key json.RawMessage, payload Payload) error { + var k PersonKey + if err := json.Unmarshal(key, &k); err != nil { + return err + } + return e.onPersonChange(ctx, k.ID, payload.Op) +} + +func (e *eventHandler) onPersonChange(ctx context.Context, personID model.PersonID, op string) error { + switch op { + case opCreate: + if err := e.search.EventAdded(ctx, personID, search.SearchTargetPerson); err != nil { + return errgo.Wrap(err, "search.OnPersonAdded") + } + case opUpdate, opSnapshot: + if err := e.search.EventUpdate(ctx, personID, search.SearchTargetPerson); err != nil { + return errgo.Wrap(err, "search.OnPersonUpdate") + } + case opDelete: + if err := e.search.EventDelete(ctx, personID, search.SearchTargetPerson); err != nil { + return errgo.Wrap(err, "search.OnPersonDelete") + } + default: + e.log.Warn("unexpected operator", zap.String("op", op)) + } + return nil +} diff --git a/canal/on_subject.go b/canal/on_subject.go index f96b7354b..5ecf0b406 100644 --- a/canal/on_subject.go +++ b/canal/on_subject.go @@ -22,8 +22,17 @@ import ( "go.uber.org/zap" "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search" ) +type SubjectKey struct { + ID model.SubjectID `json:"subject_id"` +} + +type SubjectFieldKey struct { + ID model.SubjectID `json:"field_sid"` +} + func (e *eventHandler) OnSubject(ctx context.Context, key json.RawMessage, payload Payload) error { var k SubjectKey if err := json.Unmarshal(key, &k); err != nil { @@ -45,15 +54,15 @@ func (e *eventHandler) OnSubjectField(ctx context.Context, key json.RawMessage, func (e *eventHandler) onSubjectChange(ctx context.Context, subjectID model.SubjectID, op string) error { switch op { case opCreate: - if err := e.search.OnSubjectAdded(ctx, subjectID); err != nil { + if err := e.search.EventAdded(ctx, subjectID, search.SearchTargetSubject); err != nil { return errgo.Wrap(err, "search.OnSubjectAdded") } case opUpdate, opSnapshot: - if err := e.search.OnSubjectUpdate(ctx, subjectID); err != nil { + if err := e.search.EventUpdate(ctx, subjectID, search.SearchTargetSubject); err != nil { return errgo.Wrap(err, "search.OnSubjectUpdate") } case opDelete: - if err := e.search.OnSubjectDelete(ctx, subjectID); err != nil { + if err := e.search.EventDelete(ctx, subjectID, search.SearchTargetSubject); err != nil { return errgo.Wrap(err, "search.OnSubjectDelete") } default: @@ -62,11 +71,3 @@ func (e *eventHandler) onSubjectChange(ctx context.Context, subjectID model.Subj return nil } - -type SubjectKey struct { - ID model.SubjectID `json:"subject_id"` -} - -type SubjectFieldKey struct { - ID model.SubjectID `json:"field_sid"` -} diff --git a/cmd/web/cmd.go b/cmd/web/cmd.go index 080542909..ea11b7a55 100644 --- a/cmd/web/cmd.go +++ b/cmd/web/cmd.go @@ -88,7 +88,8 @@ func start() error { index.NewMysqlRepo, auth.NewMysqlRepo, episode.NewMysqlRepo, revision.NewMysqlRepo, infra.NewMysqlRepo, timeline.NewMysqlRepo, pm.NewMysqlRepo, notification.NewMysqlRepo, - dam.New, subject.NewMysqlRepo, subject.NewCachedRepo, person.NewMysqlRepo, + dam.New, subject.NewMysqlRepo, subject.NewCachedRepo, + character.NewMysqlRepo, person.NewMysqlRepo, tag.NewCachedRepo, tag.NewMysqlRepo, diff --git a/internal/mocks/SearchClient.go b/internal/mocks/SearchClient.go index 2311ae084..41241d903 100644 --- a/internal/mocks/SearchClient.go +++ b/internal/mocks/SearchClient.go @@ -7,6 +7,8 @@ import ( echo "github.com/labstack/echo/v4" mock "github.com/stretchr/testify/mock" + + search "github.com/bangumi/server/internal/search" ) // SearchClient is an autogenerated mock type for the Client type @@ -54,17 +56,17 @@ func (_c *SearchClient_Close_Call) RunAndReturn(run func()) *SearchClient_Close_ return _c } -// Handle provides a mock function with given fields: c -func (_m *SearchClient) Handle(c echo.Context) error { - ret := _m.Called(c) +// EventAdded provides a mock function with given fields: ctx, id, target +func (_m *SearchClient) EventAdded(ctx context.Context, id uint32, target search.SearchTarget) error { + ret := _m.Called(ctx, id, target) if len(ret) == 0 { - panic("no return value specified for Handle") + panic("no return value specified for EventAdded") } var r0 error - if rf, ok := ret.Get(0).(func(echo.Context) error); ok { - r0 = rf(c) + if rf, ok := ret.Get(0).(func(context.Context, uint32, search.SearchTarget) error); ok { + r0 = rf(ctx, id, target) } else { r0 = ret.Error(0) } @@ -72,45 +74,47 @@ func (_m *SearchClient) Handle(c echo.Context) error { return r0 } -// SearchClient_Handle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Handle' -type SearchClient_Handle_Call struct { +// SearchClient_EventAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventAdded' +type SearchClient_EventAdded_Call struct { *mock.Call } -// Handle is a helper method to define mock.On call -// - c echo.Context -func (_e *SearchClient_Expecter) Handle(c interface{}) *SearchClient_Handle_Call { - return &SearchClient_Handle_Call{Call: _e.mock.On("Handle", c)} +// EventAdded is a helper method to define mock.On call +// - ctx context.Context +// - id uint32 +// - target search.SearchTarget +func (_e *SearchClient_Expecter) EventAdded(ctx interface{}, id interface{}, target interface{}) *SearchClient_EventAdded_Call { + return &SearchClient_EventAdded_Call{Call: _e.mock.On("EventAdded", ctx, id, target)} } -func (_c *SearchClient_Handle_Call) Run(run func(c echo.Context)) *SearchClient_Handle_Call { +func (_c *SearchClient_EventAdded_Call) Run(run func(ctx context.Context, id uint32, target search.SearchTarget)) *SearchClient_EventAdded_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(echo.Context)) + run(args[0].(context.Context), args[1].(uint32), args[2].(search.SearchTarget)) }) return _c } -func (_c *SearchClient_Handle_Call) Return(_a0 error) *SearchClient_Handle_Call { +func (_c *SearchClient_EventAdded_Call) Return(_a0 error) *SearchClient_EventAdded_Call { _c.Call.Return(_a0) return _c } -func (_c *SearchClient_Handle_Call) RunAndReturn(run func(echo.Context) error) *SearchClient_Handle_Call { +func (_c *SearchClient_EventAdded_Call) RunAndReturn(run func(context.Context, uint32, search.SearchTarget) error) *SearchClient_EventAdded_Call { _c.Call.Return(run) return _c } -// OnSubjectAdded provides a mock function with given fields: ctx, id -func (_m *SearchClient) OnSubjectAdded(ctx context.Context, id uint32) error { - ret := _m.Called(ctx, id) +// EventDelete provides a mock function with given fields: ctx, id, target +func (_m *SearchClient) EventDelete(ctx context.Context, id uint32, target search.SearchTarget) error { + ret := _m.Called(ctx, id, target) if len(ret) == 0 { - panic("no return value specified for OnSubjectAdded") + panic("no return value specified for EventDelete") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint32) error); ok { - r0 = rf(ctx, id) + if rf, ok := ret.Get(0).(func(context.Context, uint32, search.SearchTarget) error); ok { + r0 = rf(ctx, id, target) } else { r0 = ret.Error(0) } @@ -118,46 +122,47 @@ func (_m *SearchClient) OnSubjectAdded(ctx context.Context, id uint32) error { return r0 } -// SearchClient_OnSubjectAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnSubjectAdded' -type SearchClient_OnSubjectAdded_Call struct { +// SearchClient_EventDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventDelete' +type SearchClient_EventDelete_Call struct { *mock.Call } -// OnSubjectAdded is a helper method to define mock.On call +// EventDelete is a helper method to define mock.On call // - ctx context.Context // - id uint32 -func (_e *SearchClient_Expecter) OnSubjectAdded(ctx interface{}, id interface{}) *SearchClient_OnSubjectAdded_Call { - return &SearchClient_OnSubjectAdded_Call{Call: _e.mock.On("OnSubjectAdded", ctx, id)} +// - target search.SearchTarget +func (_e *SearchClient_Expecter) EventDelete(ctx interface{}, id interface{}, target interface{}) *SearchClient_EventDelete_Call { + return &SearchClient_EventDelete_Call{Call: _e.mock.On("EventDelete", ctx, id, target)} } -func (_c *SearchClient_OnSubjectAdded_Call) Run(run func(ctx context.Context, id uint32)) *SearchClient_OnSubjectAdded_Call { +func (_c *SearchClient_EventDelete_Call) Run(run func(ctx context.Context, id uint32, target search.SearchTarget)) *SearchClient_EventDelete_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint32)) + run(args[0].(context.Context), args[1].(uint32), args[2].(search.SearchTarget)) }) return _c } -func (_c *SearchClient_OnSubjectAdded_Call) Return(_a0 error) *SearchClient_OnSubjectAdded_Call { +func (_c *SearchClient_EventDelete_Call) Return(_a0 error) *SearchClient_EventDelete_Call { _c.Call.Return(_a0) return _c } -func (_c *SearchClient_OnSubjectAdded_Call) RunAndReturn(run func(context.Context, uint32) error) *SearchClient_OnSubjectAdded_Call { +func (_c *SearchClient_EventDelete_Call) RunAndReturn(run func(context.Context, uint32, search.SearchTarget) error) *SearchClient_EventDelete_Call { _c.Call.Return(run) return _c } -// OnSubjectDelete provides a mock function with given fields: ctx, id -func (_m *SearchClient) OnSubjectDelete(ctx context.Context, id uint32) error { - ret := _m.Called(ctx, id) +// EventUpdate provides a mock function with given fields: ctx, id, target +func (_m *SearchClient) EventUpdate(ctx context.Context, id uint32, target search.SearchTarget) error { + ret := _m.Called(ctx, id, target) if len(ret) == 0 { - panic("no return value specified for OnSubjectDelete") + panic("no return value specified for EventUpdate") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint32) error); ok { - r0 = rf(ctx, id) + if rf, ok := ret.Get(0).(func(context.Context, uint32, search.SearchTarget) error); ok { + r0 = rf(ctx, id, target) } else { r0 = ret.Error(0) } @@ -165,46 +170,47 @@ func (_m *SearchClient) OnSubjectDelete(ctx context.Context, id uint32) error { return r0 } -// SearchClient_OnSubjectDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnSubjectDelete' -type SearchClient_OnSubjectDelete_Call struct { +// SearchClient_EventUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventUpdate' +type SearchClient_EventUpdate_Call struct { *mock.Call } -// OnSubjectDelete is a helper method to define mock.On call +// EventUpdate is a helper method to define mock.On call // - ctx context.Context // - id uint32 -func (_e *SearchClient_Expecter) OnSubjectDelete(ctx interface{}, id interface{}) *SearchClient_OnSubjectDelete_Call { - return &SearchClient_OnSubjectDelete_Call{Call: _e.mock.On("OnSubjectDelete", ctx, id)} +// - target search.SearchTarget +func (_e *SearchClient_Expecter) EventUpdate(ctx interface{}, id interface{}, target interface{}) *SearchClient_EventUpdate_Call { + return &SearchClient_EventUpdate_Call{Call: _e.mock.On("EventUpdate", ctx, id, target)} } -func (_c *SearchClient_OnSubjectDelete_Call) Run(run func(ctx context.Context, id uint32)) *SearchClient_OnSubjectDelete_Call { +func (_c *SearchClient_EventUpdate_Call) Run(run func(ctx context.Context, id uint32, target search.SearchTarget)) *SearchClient_EventUpdate_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint32)) + run(args[0].(context.Context), args[1].(uint32), args[2].(search.SearchTarget)) }) return _c } -func (_c *SearchClient_OnSubjectDelete_Call) Return(_a0 error) *SearchClient_OnSubjectDelete_Call { +func (_c *SearchClient_EventUpdate_Call) Return(_a0 error) *SearchClient_EventUpdate_Call { _c.Call.Return(_a0) return _c } -func (_c *SearchClient_OnSubjectDelete_Call) RunAndReturn(run func(context.Context, uint32) error) *SearchClient_OnSubjectDelete_Call { +func (_c *SearchClient_EventUpdate_Call) RunAndReturn(run func(context.Context, uint32, search.SearchTarget) error) *SearchClient_EventUpdate_Call { _c.Call.Return(run) return _c } -// OnSubjectUpdate provides a mock function with given fields: ctx, id -func (_m *SearchClient) OnSubjectUpdate(ctx context.Context, id uint32) error { - ret := _m.Called(ctx, id) +// Handle provides a mock function with given fields: c, target +func (_m *SearchClient) Handle(c echo.Context, target search.SearchTarget) error { + ret := _m.Called(c, target) if len(ret) == 0 { - panic("no return value specified for OnSubjectUpdate") + panic("no return value specified for Handle") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint32) error); ok { - r0 = rf(ctx, id) + if rf, ok := ret.Get(0).(func(echo.Context, search.SearchTarget) error); ok { + r0 = rf(c, target) } else { r0 = ret.Error(0) } @@ -212,31 +218,31 @@ func (_m *SearchClient) OnSubjectUpdate(ctx context.Context, id uint32) error { return r0 } -// SearchClient_OnSubjectUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnSubjectUpdate' -type SearchClient_OnSubjectUpdate_Call struct { +// SearchClient_Handle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Handle' +type SearchClient_Handle_Call struct { *mock.Call } -// OnSubjectUpdate is a helper method to define mock.On call -// - ctx context.Context -// - id uint32 -func (_e *SearchClient_Expecter) OnSubjectUpdate(ctx interface{}, id interface{}) *SearchClient_OnSubjectUpdate_Call { - return &SearchClient_OnSubjectUpdate_Call{Call: _e.mock.On("OnSubjectUpdate", ctx, id)} +// Handle is a helper method to define mock.On call +// - c echo.Context +// - target search.SearchTarget +func (_e *SearchClient_Expecter) Handle(c interface{}, target interface{}) *SearchClient_Handle_Call { + return &SearchClient_Handle_Call{Call: _e.mock.On("Handle", c, target)} } -func (_c *SearchClient_OnSubjectUpdate_Call) Run(run func(ctx context.Context, id uint32)) *SearchClient_OnSubjectUpdate_Call { +func (_c *SearchClient_Handle_Call) Run(run func(c echo.Context, target search.SearchTarget)) *SearchClient_Handle_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint32)) + run(args[0].(echo.Context), args[1].(search.SearchTarget)) }) return _c } -func (_c *SearchClient_OnSubjectUpdate_Call) Return(_a0 error) *SearchClient_OnSubjectUpdate_Call { +func (_c *SearchClient_Handle_Call) Return(_a0 error) *SearchClient_Handle_Call { _c.Call.Return(_a0) return _c } -func (_c *SearchClient_OnSubjectUpdate_Call) RunAndReturn(run func(context.Context, uint32) error) *SearchClient_OnSubjectUpdate_Call { +func (_c *SearchClient_Handle_Call) RunAndReturn(run func(echo.Context, search.SearchTarget) error) *SearchClient_Handle_Call { _c.Call.Return(run) return _c } diff --git a/internal/search/character/client.go b/internal/search/character/client.go new file mode 100644 index 000000000..83e926243 --- /dev/null +++ b/internal/search/character/client.go @@ -0,0 +1,110 @@ +package character + +import ( + "context" + "fmt" + "reflect" + "strconv" + + "github.com/meilisearch/meilisearch-go" + "github.com/trim21/errgo" + "github.com/trim21/pkg/queue" + "go.uber.org/zap" + + "github.com/bangumi/server/config" + "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/internal/character" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search/searcher" +) + +const ( + idx = "characters" +) + +func New( + cfg config.AppConfig, + meili meilisearch.ServiceManager, + repo character.Repo, + log *zap.Logger, + query *query.Query, +) (searcher.Searcher, error) { + if repo == nil { + return nil, fmt.Errorf("nil characterRepo") + } + c := &client{ + meili: meili, + repo: repo, + index: meili.Index(idx), + log: log.Named("search").With(zap.String("index", idx)), + q: query, + } + + if cfg.AppType != config.AppTypeCanal { + return c, nil + } + + return c, c.canalInit(cfg) +} + +type client struct { + repo character.Repo + index meilisearch.IndexManager + + meili meilisearch.ServiceManager + log *zap.Logger + q *query.Query + + queue *queue.Batched[searcher.Document] +} + +func (c *client) Close() { + if c.queue != nil { + c.queue.Close() + } +} + +func (c *client) canalInit(cfg config.AppConfig) error { + if err := searcher.ValidateConfigs(cfg); err != nil { + return errgo.Wrap(err, "validate search config") + } + c.queue = searcher.NewBatchQueue(cfg, c.log, c.index) + searcher.RegisterQueueMetrics(idx, c.queue) + shouldCreateIndex, err := searcher.NeedFirstRun(c.meili, idx) + if err != nil { + return err + } + if shouldCreateIndex { + go c.firstRun() + } + return nil +} + +//nolint:funlen +func (c *client) firstRun() { + c.log.Info("search initialize") + rt := reflect.TypeOf(document{}) + searcher.InitIndex(c.log, c.meili, idx, rt, rankRule()) + + ctx := context.Background() + + maxItem, err := c.q.Character.WithContext(ctx).Limit(1).Order(c.q.Character.ID.Desc()).Take() + if err != nil { + c.log.Fatal("failed to get current max id", zap.Error(err)) + return + } + + c.log.Info(fmt.Sprintf("run full search index with max %s id %d", idx, maxItem.ID)) + + width := len(strconv.Itoa(int(maxItem.ID))) + for i := model.CharacterID(1); i <= maxItem.ID; i++ { + if i%10000 == 0 { + c.log.Info(fmt.Sprintf("progress %*d/%d", width, i, maxItem.ID)) + } + + err := c.OnUpdate(ctx, i) + if err != nil { + c.log.Error("error when updating", zap.Error(err)) + } + } +} diff --git a/internal/search/character/doc.go b/internal/search/character/doc.go new file mode 100644 index 000000000..1e1a23de8 --- /dev/null +++ b/internal/search/character/doc.go @@ -0,0 +1,51 @@ +package character + +import ( + "strconv" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search/searcher" + "github.com/bangumi/server/pkg/wiki" +) + +type document struct { + ID model.CharacterID `json:"id"` + Name string `json:"name" searchable:"true"` + Aliases []string `json:"aliases,omitempty" searchable:"true"` + Comment uint32 `json:"comment" sortable:"true"` + Collect uint32 `json:"collect" sortable:"true"` + NSFW bool `json:"nsfw" filterable:"true"` +} + +func (d *document) GetID() string { + return strconv.FormatUint(uint64(d.ID), 10) +} + +func rankRule() *[]string { + return &[]string{ + // 相似度最优先 + "exactness", + "words", + "typo", + "proximity", + "attribute", + "sort", + "id:asc", + "comment:desc", + "collect:desc", + "nsfw:asc", + } +} + +func extract(c *model.Character) searcher.Document { + w := wiki.ParseOmitError(c.Infobox) + + return &document{ + ID: c.ID, + Name: c.Name, + Aliases: searcher.ExtractAliases(w), + Comment: c.CommentCount, + Collect: c.CollectCount, + NSFW: c.NSFW, + } +} diff --git a/internal/search/character/event.go b/internal/search/character/event.go new file mode 100644 index 000000000..10c3dad66 --- /dev/null +++ b/internal/search/character/event.go @@ -0,0 +1,57 @@ +package character + +import ( + "context" + "errors" + "strconv" + + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/model" +) + +func (c *client) OnAdded(ctx context.Context, id model.CharacterID) error { + s, err := c.repo.Get(ctx, id) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "characterRepo.Get") + } + + if s.Redirect != 0 { + return c.OnDelete(ctx, id) + } + + extracted := extract(&s) + + _, err = c.index.UpdateDocumentsWithContext(ctx, extracted, "id") + return err +} + +func (c *client) OnUpdate(ctx context.Context, id model.CharacterID) error { + s, err := c.repo.Get(ctx, id) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "characterRepo.Get") + } + + if s.Redirect != 0 { + return c.OnDelete(ctx, id) + } + + extracted := extract(&s) + + c.queue.Push(extracted) + + return nil +} + +func (c *client) OnDelete(ctx context.Context, id model.CharacterID) error { + _, err := c.index.DeleteDocumentWithContext(ctx, strconv.FormatUint(uint64(id), 10)) + + return errgo.Wrap(err, "search") +} diff --git a/internal/search/character/handle.go b/internal/search/character/handle.go new file mode 100644 index 000000000..660b2704e --- /dev/null +++ b/internal/search/character/handle.go @@ -0,0 +1,128 @@ +package character + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/meilisearch/meilisearch-go" + "github.com/trim21/errgo" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/generic/slice" + "github.com/bangumi/server/internal/pkg/null" + "github.com/bangumi/server/web/accessor" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +const defaultLimit = 10 +const maxLimit = 20 + +type Req struct { + Keyword string `json:"keyword"` + Filter ReqFilter `json:"filter"` +} + +type ReqFilter struct { //nolint:musttag + NSFW null.Bool `json:"nsfw"` +} + +type hit struct { + ID model.CharacterID `json:"id"` +} + +//nolint:funlen +func (c *client) Handle(ctx echo.Context) error { + auth := accessor.GetFromCtx(ctx) + q, err := req.GetPageQuerySoftLimit(ctx, defaultLimit, maxLimit) + if err != nil { + return err + } + + var r Req + if err = json.NewDecoder(ctx.Request().Body).Decode(&r); err != nil { + return res.JSONError(ctx, err) + } + + if !auth.AllowNSFW() { + r.Filter.NSFW = null.Bool{Set: true, Value: false} + } + + result, err := c.doSearch(r.Keyword, filterToMeiliFilter(r.Filter), q.Limit, q.Offset) + if err != nil { + return errgo.Wrap(err, "search") + } + + var hits []hit + if err = json.Unmarshal(result.Hits, &hits); err != nil { + return errgo.Wrap(err, "json.Unmarshal") + } + ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) + + characters, err := c.repo.GetByIDs(ctx.Request().Context(), ids) + if err != nil { + return errgo.Wrap(err, "characterRepo.GetByIDs") + } + + var data = make([]res.CharacterV0, 0, len(characters)) + for _, id := range ids { + s, ok := characters[id] + if !ok { + continue + } + character := res.ConvertModelCharacter(s) + data = append(data, character) + } + + return ctx.JSON(http.StatusOK, res.Paged{ + Data: data, + Total: result.EstimatedTotalHits, + Limit: q.Limit, + Offset: q.Offset, + }) +} + +func (c *client) doSearch( + words string, + filter [][]string, + limit, offset int, +) (*meiliSearchResponse, error) { + if limit == 0 { + limit = 10 + } else if limit > 50 { + limit = 50 + } + + raw, err := c.index.SearchRaw(words, &meilisearch.SearchRequest{ + Offset: int64(offset), + Limit: int64(limit), + Filter: filter, + }) + if err != nil { + return nil, errgo.Wrap(err, "meilisearch search") + } + + var r meiliSearchResponse + if err := json.Unmarshal(*raw, &r); err != nil { + return nil, errgo.Wrap(err, "json.Unmarshal") + } + + return &r, nil +} + +type meiliSearchResponse struct { + Hits json.RawMessage `json:"hits"` + EstimatedTotalHits int64 `json:"estimatedTotalHits"` //nolint:tagliatelle +} + +func filterToMeiliFilter(req ReqFilter) [][]string { + var filter = make([][]string, 0, 1) + + if req.NSFW.Set { + filter = append(filter, []string{fmt.Sprintf("nsfw = %t", req.NSFW.Value)}) + } + + return filter +} diff --git a/internal/search/client.go b/internal/search/client.go deleted file mode 100644 index d92627b94..000000000 --- a/internal/search/client.go +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see - -package search - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/url" - "os" - "reflect" - "strconv" - "strings" - "time" - - "github.com/avast/retry-go/v4" - "github.com/meilisearch/meilisearch-go" - "github.com/prometheus/client_golang/prometheus" - "github.com/samber/lo" - "github.com/trim21/errgo" - "github.com/trim21/pkg/queue" - "go.uber.org/zap" - - "github.com/bangumi/server/config" - "github.com/bangumi/server/dal/query" - "github.com/bangumi/server/domain/gerr" - "github.com/bangumi/server/internal/model" - "github.com/bangumi/server/internal/subject" -) - -// New provide a search app is AppConfig.MeiliSearchURL is empty string, return nope search client. -// -// see `MeiliSearchURL` and `MeiliSearchKey` in [config.AppConfig]. -func New( - cfg config.AppConfig, - subjectRepo subject.Repo, - log *zap.Logger, - query *query.Query, -) (Client, error) { - if cfg.Search.MeiliSearch.URL == "" { - return NoopClient{}, nil - } - - if subjectRepo == nil { - panic("nil SubjectRepo") - } - if _, err := url.Parse(cfg.Search.MeiliSearch.URL); err != nil { - return nil, errgo.Wrap(err, "url.Parse") - } - - meili := meilisearch.New( - cfg.Search.MeiliSearch.URL, - meilisearch.WithAPIKey(cfg.Search.MeiliSearch.Key), - meilisearch.WithCustomClient(&http.Client{Timeout: cfg.Search.MeiliSearch.Timeout}), - ) - - if _, err := meili.Version(); err != nil { - return nil, errgo.Wrap(err, "meilisearch") - } - - c := &client{ - meili: meili, - q: query, - subject: "subjects", - subjectIndex: meili.Index("subjects"), - log: log.Named("search"), - subjectRepo: subjectRepo, - } - - if cfg.AppType != config.AppTypeCanal { - return c, nil - } - - return c, c.canalInit(cfg) -} - -func (c *client) canalInit(cfg config.AppConfig) error { - if cfg.Search.SearchBatchSize <= 0 { - // nolint: goerr113 - return fmt.Errorf("config.SearchBatchSize should >= 0, current %d", cfg.Search.SearchBatchSize) - } - - if cfg.Search.SearchBatchInterval <= 0 { - // nolint: goerr113 - return fmt.Errorf("config.SearchBatchInterval should >= 0, current %d", cfg.Search.SearchBatchInterval) - } - - c.queue = queue.NewBatchedDedupe[subjectIndex]( - c.sendBatch, - cfg.Search.SearchBatchSize, - cfg.Search.SearchBatchInterval, - func(items []subjectIndex) []subjectIndex { - // lo.UniqBy 会保留第一次出现的元素,reverse 之后会保留新的数据 - return lo.UniqBy(lo.Reverse(items), func(item subjectIndex) model.SubjectID { - return item.ID - }) - }, - ) - - prometheus.DefaultRegisterer.MustRegister( - prometheus.NewGaugeFunc( - prometheus.GaugeOpts{ - Namespace: "chii", - Name: "meilisearch_queue_batch", - Help: "meilisearch update queue batch size", - }, - func() float64 { - return float64(c.queue.Len()) - }, - )) - - shouldCreateIndex, err := c.needFirstRun() - if err != nil { - return err - } - - if shouldCreateIndex { - go c.firstRun() - } - - return nil -} - -type client struct { - subjectRepo subject.Repo - meili meilisearch.ServiceManager - q *query.Query - subjectIndex meilisearch.IndexManager - log *zap.Logger - subject string - queue *queue.Batched[subjectIndex] -} - -func (c *client) Close() { - if c.queue != nil { - c.queue.Close() - } -} - -// OnSubjectAdded is the hook called by canal. -func (c *client) OnSubjectAdded(ctx context.Context, id model.SubjectID) error { - s, err := c.subjectRepo.Get(ctx, id, subject.Filter{}) - if err != nil { - if errors.Is(err, gerr.ErrNotFound) { - return nil - } - return errgo.Wrap(err, "subjectRepo.Get") - } - - if s.Redirect != 0 || s.Ban != 0 { - return c.OnSubjectDelete(ctx, id) - } - - extracted := extractSubject(&s) - - _, err = c.subjectIndex.UpdateDocumentsWithContext(ctx, extracted, "id") - return err -} - -// OnSubjectUpdate is the hook called by canal. -func (c *client) OnSubjectUpdate(ctx context.Context, id model.SubjectID) error { - s, err := c.subjectRepo.Get(ctx, id, subject.Filter{}) - if err != nil { - if errors.Is(err, gerr.ErrNotFound) { - return nil - } - return errgo.Wrap(err, "subjectRepo.Get") - } - - if s.Redirect != 0 || s.Ban != 0 { - return c.OnSubjectDelete(ctx, id) - } - - extracted := extractSubject(&s) - - c.queue.Push(extracted) - - return nil -} - -// OnSubjectDelete is the hook called by canal. -func (c *client) OnSubjectDelete(ctx context.Context, id model.SubjectID) error { - _, err := c.subjectIndex.DeleteDocumentWithContext(ctx, strconv.FormatUint(uint64(id), 10)) - - return errgo.Wrap(err, "search") -} - -// UpsertSubject add subject to search backend. -func (c *client) sendBatch(items []subjectIndex) { - c.log.Debug("send batch to meilisearch", zap.Int("len", len(items))) - err := retry.Do( - func() error { - _, err := c.subjectIndex.UpdateDocuments(items, "id") - return err - }, - retry.OnRetry(func(n uint, err error) { - c.log.Warn("failed to send batch", zap.Uint("attempt", n), zap.Error(err)) - }), - - retry.DelayType(retry.BackOffDelay), - retry.Delay(time.Microsecond*100), - retry.Attempts(5), //nolint:mnd - retry.RetryIf(func(err error) bool { - var r = &meilisearch.Error{} - return errors.As(err, &r) - }), - ) - - if err != nil { - c.log.Error("failed to send batch", zap.Error(err)) - } -} - -func (c *client) needFirstRun() (bool, error) { - if os.Getenv("CHII_SEARCH_INIT") == "true" { - return true, nil - } - - index, err := c.meili.GetIndex("subjects") - if err != nil { - var e *meilisearch.Error - if errors.As(err, &e) { - return true, nil - } - return false, errgo.Wrap(err, "get subjects index") - } - - stat, err := index.GetStats() - if err != nil { - return false, errgo.Wrap(err, "get subjects index stats") - } - - return stat.NumberOfDocuments == 0, nil -} - -//nolint:funlen -func (c *client) firstRun() { - c.log.Info("search initialize") - _, err := c.meili.CreateIndex(&meilisearch.IndexConfig{ - Uid: "subjects", - PrimaryKey: "id", - }) - if err != nil { - c.log.Fatal("failed to create search subject index", zap.Error(err)) - return - } - - subjectIndex := c.meili.Index("subjects") - - c.log.Info("set sortable attributes", zap.Strings("attributes", *getAttributes("sortable"))) - _, err = subjectIndex.UpdateSortableAttributes(getAttributes("sortable")) - if err != nil { - c.log.Fatal("failed to update search index sortable attributes", zap.Error(err)) - return - } - - c.log.Info("set filterable attributes", zap.Strings("attributes", *getAttributes("filterable"))) - _, err = subjectIndex.UpdateFilterableAttributes(getAttributes("filterable")) - if err != nil { - c.log.Fatal("failed to update search index filterable attributes", zap.Error(err)) - return - } - - c.log.Info("set searchable attributes", zap.Strings("attributes", *getAttributes("searchable"))) - _, err = subjectIndex.UpdateSearchableAttributes(getAttributes("searchable")) - if err != nil { - c.log.Fatal("failed to update search index searchable attributes", zap.Error(err)) - return - } - - c.log.Info("set ranking rules", zap.Strings("rule", *rankRule())) - _, err = subjectIndex.UpdateRankingRules(rankRule()) - if err != nil { - c.log.Fatal("failed to update search index searchable attributes", zap.Error(err)) - return - } - - ctx := context.Background() - - maxSubject, err := c.q.Subject.WithContext(ctx).Limit(1).Order(c.q.Subject.ID.Desc()).Take() - if err != nil { - c.log.Fatal("failed to get current max subject id", zap.Error(err)) - return - } - - c.log.Info(fmt.Sprintf("run full search index with max subject id %d", maxSubject.ID)) - - width := len(strconv.Itoa(int(maxSubject.ID))) - for i := model.SubjectID(1); i <= maxSubject.ID; i++ { - if i%10000 == 0 { - c.log.Info(fmt.Sprintf("progress %*d/%d", width, i, maxSubject.ID)) - } - - err := c.OnSubjectUpdate(ctx, i) - if err != nil { - c.log.Error("error when updating subject", zap.Error(err)) - } - } -} - -func getAttributes(tag string) *[]string { - rt := reflect.TypeOf(subjectIndex{}) - var s []string - for i := 0; i < rt.NumField(); i++ { - t, ok := rt.Field(i).Tag.Lookup(tag) - if !ok { - continue - } - - if t != "true" { - continue - } - - s = append(s, getJSONFieldName(rt.Field(i))) - } - - return &s -} - -func getJSONFieldName(f reflect.StructField) string { - t := f.Tag.Get("json") - if t == "" { - return f.Name - } - - return strings.Split(t, ",")[0] -} diff --git a/internal/search/extractor.common.go b/internal/search/extractor.common.go deleted file mode 100644 index 6213919d1..000000000 --- a/internal/search/extractor.common.go +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see - -package search - -import ( - "github.com/bangumi/server/internal/model" - "github.com/bangumi/server/pkg/wiki" -) - -func heat(s *model.Subject) uint32 { - return s.OnHold + s.Doing + s.Dropped + s.Wish + s.Collect -} - -func extractAliases(s *model.Subject, w wiki.Wiki) []string { - var aliases = make([]string, 0, 2) - if s.NameCN != "" { - aliases = append(aliases, s.NameCN) - } - - for _, field := range w.Fields { - if field.Key == "别名" { - aliases = append(aliases, getValues(field)...) - } - } - - return aliases -} - -func getValues(f wiki.Field) []string { - if f.Null { - return nil - } - - if !f.Array { - return []string{f.Value} - } - - var s = make([]string, len(f.Values)) - for i, value := range f.Values { - s[i] = value.Value - } - return s -} diff --git a/internal/search/noop.go b/internal/search/noop.go index bf68f32d8..56ca35a8e 100644 --- a/internal/search/noop.go +++ b/internal/search/noop.go @@ -19,8 +19,6 @@ import ( "net/http" "github.com/labstack/echo/v4" - - "github.com/bangumi/server/internal/model" ) var _ Client = NoopClient{} @@ -28,17 +26,19 @@ var _ Client = NoopClient{} type NoopClient struct { } -func (n NoopClient) OnSubjectAdded(ctx context.Context, id model.SubjectID) error { return nil } - -func (n NoopClient) Handle(c echo.Context) error { +func (n NoopClient) Handle(c echo.Context, _ SearchTarget) error { return c.String(http.StatusOK, "search is not enable") } -func (n NoopClient) OnSubjectUpdate(_ context.Context, _ model.SubjectID) error { +func (n NoopClient) EventAdded(ctx context.Context, _ uint32, _ SearchTarget) error { + return nil +} + +func (n NoopClient) EventUpdate(_ context.Context, _ uint32, _ SearchTarget) error { return nil } -func (n NoopClient) OnSubjectDelete(_ context.Context, _ model.SubjectID) error { +func (n NoopClient) EventDelete(_ context.Context, _ uint32, _ SearchTarget) error { return nil } diff --git a/internal/search/person/client.go b/internal/search/person/client.go new file mode 100644 index 000000000..a7a454005 --- /dev/null +++ b/internal/search/person/client.go @@ -0,0 +1,110 @@ +package person + +import ( + "context" + "fmt" + "reflect" + "strconv" + + "github.com/meilisearch/meilisearch-go" + "github.com/trim21/errgo" + "github.com/trim21/pkg/queue" + "go.uber.org/zap" + + "github.com/bangumi/server/config" + "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/person" + "github.com/bangumi/server/internal/search/searcher" +) + +const ( + idx = "persons" +) + +func New( + cfg config.AppConfig, + meili meilisearch.ServiceManager, + repo person.Repo, + log *zap.Logger, + query *query.Query, +) (searcher.Searcher, error) { + if repo == nil { + return nil, fmt.Errorf("nil personRepo") + } + c := &client{ + meili: meili, + repo: repo, + index: meili.Index("persons"), + log: log.Named("search").With(zap.String("index", idx)), + q: query, + } + + if cfg.AppType != config.AppTypeCanal { + return c, nil + } + + return c, c.canalInit(cfg) +} + +type client struct { + repo person.Repo + index meilisearch.IndexManager + + meili meilisearch.ServiceManager + log *zap.Logger + q *query.Query + + queue *queue.Batched[searcher.Document] +} + +func (c *client) Close() { + if c.queue != nil { + c.queue.Close() + } +} + +func (c *client) canalInit(cfg config.AppConfig) error { + if err := searcher.ValidateConfigs(cfg); err != nil { + return errgo.Wrap(err, "validate search config") + } + c.queue = searcher.NewBatchQueue(cfg, c.log, c.index) + searcher.RegisterQueueMetrics(idx, c.queue) + shouldCreateIndex, err := searcher.NeedFirstRun(c.meili, idx) + if err != nil { + return err + } + if shouldCreateIndex { + go c.firstRun() + } + return nil +} + +//nolint:funlen +func (c *client) firstRun() { + c.log.Info("search initialize") + rt := reflect.TypeOf(document{}) + searcher.InitIndex(c.log, c.meili, idx, rt, rankRule()) + + ctx := context.Background() + + maxItem, err := c.q.Person.WithContext(ctx).Limit(1).Order(c.q.Person.ID.Desc()).Take() + if err != nil { + c.log.Fatal("failed to get current max id", zap.Error(err)) + return + } + + c.log.Info(fmt.Sprintf("run full search index with max %s id %d", idx, maxItem.ID)) + + width := len(strconv.Itoa(int(maxItem.ID))) + for i := model.PersonID(1); i <= maxItem.ID; i++ { + if i%10000 == 0 { + c.log.Info(fmt.Sprintf("progress %*d/%d", width, i, maxItem.ID)) + } + + err := c.OnUpdate(ctx, i) + if err != nil { + c.log.Error("error when updating", zap.Error(err)) + } + } +} diff --git a/internal/search/person/doc.go b/internal/search/person/doc.go new file mode 100644 index 000000000..c19e3a7ef --- /dev/null +++ b/internal/search/person/doc.go @@ -0,0 +1,49 @@ +package person + +import ( + "strconv" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search/searcher" + "github.com/bangumi/server/pkg/wiki" +) + +type document struct { + ID model.PersonID `json:"id"` + Name string `json:"name" searchable:"true"` + Aliases []string `json:"aliases,omitempty" searchable:"true"` + Comment uint32 `json:"comment" sortable:"true"` + Collect uint32 `json:"collect" sortable:"true"` + Career []string `json:"career,omitempty" filterable:"true"` +} + +func (d *document) GetID() string { + return strconv.FormatUint(uint64(d.ID), 10) +} + +func rankRule() *[]string { + return &[]string{ + // 相似度最优先 + "exactness", + "words", + "typo", + "proximity", + "attribute", + "sort", + "id:asc", + "comment:desc", + "collect:desc", + } +} + +func extract(c *model.Person) searcher.Document { + w := wiki.ParseOmitError(c.Infobox) + + return &document{ + ID: c.ID, + Name: c.Name, + Aliases: searcher.ExtractAliases(w), + Comment: c.CommentCount, + Collect: c.CollectCount, + } +} diff --git a/internal/search/person/event.go b/internal/search/person/event.go new file mode 100644 index 000000000..467c2fdf2 --- /dev/null +++ b/internal/search/person/event.go @@ -0,0 +1,57 @@ +package person + +import ( + "context" + "errors" + "strconv" + + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/model" +) + +func (c *client) OnAdded(ctx context.Context, id model.PersonID) error { + s, err := c.repo.Get(ctx, id) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "characterRepo.Get") + } + + if s.Redirect != 0 { + return c.OnDelete(ctx, id) + } + + extracted := extract(&s) + + _, err = c.index.UpdateDocumentsWithContext(ctx, extracted, "id") + return err +} + +func (c *client) OnUpdate(ctx context.Context, id model.PersonID) error { + s, err := c.repo.Get(ctx, id) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "characterRepo.Get") + } + + if s.Redirect != 0 { + return c.OnDelete(ctx, id) + } + + extracted := extract(&s) + + c.queue.Push(extracted) + + return nil +} + +func (c *client) OnDelete(ctx context.Context, id model.PersonID) error { + _, err := c.index.DeleteDocumentWithContext(ctx, strconv.FormatUint(uint64(id), 10)) + + return errgo.Wrap(err, "search") +} diff --git a/internal/search/person/handle.go b/internal/search/person/handle.go new file mode 100644 index 000000000..3f4bf1023 --- /dev/null +++ b/internal/search/person/handle.go @@ -0,0 +1,121 @@ +package person + +import ( + "encoding/json" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" + "github.com/meilisearch/meilisearch-go" + "github.com/trim21/errgo" + + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/generic/slice" + "github.com/bangumi/server/web/req" + "github.com/bangumi/server/web/res" +) + +const defaultLimit = 10 +const maxLimit = 20 + +type Req struct { + Keyword string `json:"keyword"` + Filter ReqFilter `json:"filter"` +} + +type ReqFilter struct { //nolint:musttag + Careers []string `json:"meta_tags"` // and +} + +type hit struct { + ID model.PersonID `json:"id"` +} + +//nolint:funlen +func (c *client) Handle(ctx echo.Context) error { + q, err := req.GetPageQuerySoftLimit(ctx, defaultLimit, maxLimit) + if err != nil { + return err + } + + var r Req + if err = json.NewDecoder(ctx.Request().Body).Decode(&r); err != nil { + return res.JSONError(ctx, err) + } + + result, err := c.doSearch(r.Keyword, filterToMeiliFilter(r.Filter), q.Limit, q.Offset) + if err != nil { + return errgo.Wrap(err, "search") + } + + var hits []hit + if err = json.Unmarshal(result.Hits, &hits); err != nil { + return errgo.Wrap(err, "json.Unmarshal") + } + ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) + + persons, err := c.repo.GetByIDs(ctx.Request().Context(), ids) + if err != nil { + return errgo.Wrap(err, "personRepo.GetByIDs") + } + + var data = make([]res.PersonV0, 0, len(persons)) + for _, id := range ids { + s, ok := persons[id] + if !ok { + continue + } + person := res.ConvertModelPerson(s) + data = append(data, person) + } + + return ctx.JSON(http.StatusOK, res.Paged{ + Data: data, + Total: result.EstimatedTotalHits, + Limit: q.Limit, + Offset: q.Offset, + }) +} + +func (c *client) doSearch( + words string, + filter [][]string, + limit, offset int, +) (*meiliSearchResponse, error) { + if limit == 0 { + limit = 10 + } else if limit > 50 { + limit = 50 + } + + raw, err := c.index.SearchRaw(words, &meilisearch.SearchRequest{ + Offset: int64(offset), + Limit: int64(limit), + Filter: filter, + }) + if err != nil { + return nil, errgo.Wrap(err, "meilisearch search") + } + + var r meiliSearchResponse + if err := json.Unmarshal(*raw, &r); err != nil { + return nil, errgo.Wrap(err, "json.Unmarshal") + } + + return &r, nil +} + +type meiliSearchResponse struct { + Hits json.RawMessage `json:"hits"` + EstimatedTotalHits int64 `json:"estimatedTotalHits"` //nolint:tagliatelle +} + +func filterToMeiliFilter(req ReqFilter) [][]string { + var filter = make([][]string, 0, len(req.Careers)) + + for _, career := range req.Careers { + filter = append(filter, []string{"career = " + strconv.Quote(career)}) + } + + return filter +} diff --git a/internal/search/search.go b/internal/search/search.go new file mode 100644 index 000000000..8c80027be --- /dev/null +++ b/internal/search/search.go @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +package search + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/labstack/echo/v4" + "github.com/meilisearch/meilisearch-go" + "github.com/trim21/errgo" + "go.uber.org/zap" + + "github.com/bangumi/server/config" + "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/internal/character" + "github.com/bangumi/server/internal/person" + characterSearcher "github.com/bangumi/server/internal/search/character" + personSearcher "github.com/bangumi/server/internal/search/person" + "github.com/bangumi/server/internal/search/searcher" + subjectSearcher "github.com/bangumi/server/internal/search/subject" + "github.com/bangumi/server/internal/subject" +) + +type SearchTarget string + +const ( + SearchTargetSubject SearchTarget = "subject" + SearchTargetCharacter SearchTarget = "character" + SearchTargetPerson SearchTarget = "person" +) + +type Client interface { + Handle(c echo.Context, target SearchTarget) error + Close() + + EventAdded(ctx context.Context, id uint32, target SearchTarget) error + EventUpdate(ctx context.Context, id uint32, target SearchTarget) error + EventDelete(ctx context.Context, id uint32, target SearchTarget) error +} + +type Handler interface { + Handle(c echo.Context, target SearchTarget) error +} + +type Search struct { + searchers map[SearchTarget]searcher.Searcher +} + +// New provide a search app is AppConfig.MeiliSearchURL is empty string, return nope search client. +// +// see `MeiliSearchURL` and `MeiliSearchKey` in [config.AppConfig]. +func New( + cfg config.AppConfig, + subjectRepo subject.Repo, + characterRepo character.Repo, + personRepo person.Repo, + log *zap.Logger, + query *query.Query, +) (Client, error) { + if cfg.Search.MeiliSearch.URL == "" { + return NoopClient{}, nil + } + if _, err := url.Parse(cfg.Search.MeiliSearch.URL); err != nil { + return nil, errgo.Wrap(err, "url.Parse") + } + meili := meilisearch.New( + cfg.Search.MeiliSearch.URL, + meilisearch.WithAPIKey(cfg.Search.MeiliSearch.Key), + meilisearch.WithCustomClient(&http.Client{Timeout: cfg.Search.MeiliSearch.Timeout}), + ) + if _, err := meili.Version(); err != nil { + return nil, errgo.Wrap(err, "meilisearch") + } + + subject, err := subjectSearcher.New(cfg, meili, subjectRepo, log, query) + if err != nil { + return nil, errgo.Wrap(err, "subject search") + } + character, err := characterSearcher.New(cfg, meili, characterRepo, log, query) + if err != nil { + return nil, errgo.Wrap(err, "character search") + } + person, err := personSearcher.New(cfg, meili, personRepo, log, query) + if err != nil { + return nil, errgo.Wrap(err, "person search") + } + + searchers := map[SearchTarget]searcher.Searcher{ + SearchTargetSubject: subject, + SearchTargetCharacter: character, + SearchTargetPerson: person, + } + s := &Search{ + searchers: searchers, + } + return s, nil +} + +func (s *Search) Handle(c echo.Context, target SearchTarget) error { + searcher := s.searchers[target] + if searcher == nil { + return fmt.Errorf("searcher not found for %s", target) + } + return searcher.Handle(c) +} + +func (s *Search) EventAdded(ctx context.Context, id uint32, target SearchTarget) error { + searcher := s.searchers[target] + if searcher == nil { + return fmt.Errorf("searcher not found for %s", target) + } + return searcher.OnAdded(ctx, id) +} + +func (s *Search) EventUpdate(ctx context.Context, id uint32, target SearchTarget) error { + searcher := s.searchers[target] + if searcher == nil { + return fmt.Errorf("searcher not found for %s", target) + } + return searcher.OnUpdate(ctx, id) +} + +func (s *Search) EventDelete(ctx context.Context, id uint32, target SearchTarget) error { + searcher := s.searchers[target] + if searcher == nil { + return fmt.Errorf("searcher not found for %s", target) + } + return searcher.OnDelete(ctx, id) +} + +func (s *Search) Close() { + for _, searcher := range s.searchers { + searcher.Close() + } +} diff --git a/internal/search/searcher/client.go b/internal/search/searcher/client.go new file mode 100644 index 000000000..d18498cb5 --- /dev/null +++ b/internal/search/searcher/client.go @@ -0,0 +1,231 @@ +package searcher + +import ( + "context" + "errors" + "fmt" + "os" + "reflect" + "strings" + "time" + + "github.com/avast/retry-go/v4" + "github.com/labstack/echo/v4" + "github.com/meilisearch/meilisearch-go" + "github.com/prometheus/client_golang/prometheus" + "github.com/samber/lo" + "github.com/trim21/errgo" + "github.com/trim21/pkg/queue" + "go.uber.org/zap" + + "github.com/bangumi/server/config" + "github.com/bangumi/server/pkg/wiki" +) + +type Searcher interface { + Handle(c echo.Context) error + + Close() + + OnAdded(ctx context.Context, id uint32) error + OnUpdate(ctx context.Context, id uint32) error + OnDelete(ctx context.Context, id uint32) error +} + +type Document interface { + GetID() string +} + +func NeedFirstRun(meili meilisearch.ServiceManager, idx string) (bool, error) { + if os.Getenv("CHII_SEARCH_INIT") == "true" { + return true, nil + } + + index, err := meili.GetIndex(idx) + if err != nil { + var e *meilisearch.Error + if errors.As(err, &e) { + return true, nil + } + return false, errgo.Wrap(err, fmt.Sprintf("get index %s", idx)) + } + + stat, err := index.GetStats() + if err != nil { + return false, errgo.Wrap(err, fmt.Sprintf("get index %s stats", idx)) + } + + return stat.NumberOfDocuments == 0, nil +} + +func ValidateConfigs(cfg config.AppConfig) error { + if cfg.Search.SearchBatchSize <= 0 { + // nolint: goerr113 + return fmt.Errorf("config.SearchBatchSize should >= 0, current %d", cfg.Search.SearchBatchSize) + } + + if cfg.Search.SearchBatchInterval <= 0 { + // nolint: goerr113 + return fmt.Errorf("config.SearchBatchInterval should >= 0, current %d", cfg.Search.SearchBatchInterval) + } + + return nil +} + +func ExtractAliases(w wiki.Wiki) []string { + aliases := []string{} + for _, field := range w.Fields { + if field.Key == "中文名" { + aliases = append(aliases, GetWikiValues(field)...) + } + if field.Key == "简体中文名" { + aliases = append(aliases, GetWikiValues(field)...) + } + } + for _, field := range w.Fields { + if field.Key == "别名" { + aliases = append(aliases, GetWikiValues(field)...) + } + } + return aliases +} + +func GetWikiValues(f wiki.Field) []string { + if f.Null { + return nil + } + + if !f.Array { + return []string{f.Value} + } + + var s = make([]string, len(f.Values)) + for i, value := range f.Values { + s[i] = value.Value + } + return s +} + +func NewSendBatch(log *zap.Logger, index meilisearch.IndexManager) func([]Document) { + return func(items []Document) { + log.Debug("send batch to meilisearch", zap.Int("len", len(items))) + err := retry.Do( + func() error { + _, err := index.UpdateDocuments(items, "id") + return err + }, + retry.OnRetry(func(n uint, err error) { + log.Warn("failed to send batch", zap.Uint("attempt", n), zap.Error(err)) + }), + retry.DelayType(retry.BackOffDelay), + retry.Delay(time.Microsecond*100), + retry.Attempts(5), //nolint:mnd + retry.RetryIf(func(err error) bool { + var r = &meilisearch.Error{} + return errors.As(err, &r) + }), + ) + if err != nil { + log.Error("failed to send batch", zap.Error(err)) + } + } +} + +func NewDedupeFunc() func([]Document) []Document { + return func(items []Document) []Document { + // lo.UniqBy 会保留第一次出现的元素,reverse 之后会保留新的数据 + return lo.UniqBy(lo.Reverse(items), func(item Document) string { + return item.GetID() + }) + } +} + +func NewBatchQueue(cfg config.AppConfig, log *zap.Logger, index meilisearch.IndexManager) *queue.Batched[Document] { + return queue.NewBatchedDedupe( + NewSendBatch(log, index), + cfg.Search.SearchBatchSize, + cfg.Search.SearchBatchInterval, + NewDedupeFunc(), + ) +} + +func RegisterQueueMetrics(idx string, queue *queue.Batched[Document]) { + prometheus.DefaultRegisterer.MustRegister( + prometheus.NewGaugeFunc( + prometheus.GaugeOpts{ + Namespace: "chii", + Name: "meilisearch_queue_batch", + Help: "meilisearch update queue batch size", + ConstLabels: prometheus.Labels{ + "index": idx, + }, + }, + func() float64 { + return float64(queue.Len()) + }, + )) +} + +func GetAttributes(rt reflect.Type, tag string) *[]string { + var s []string + for i := 0; i < rt.NumField(); i++ { + t, ok := rt.Field(i).Tag.Lookup(tag) + if !ok { + continue + } + if t != "true" { + continue + } + s = append(s, getJSONFieldName(rt.Field(i))) + } + return &s +} + +func getJSONFieldName(f reflect.StructField) string { + t := f.Tag.Get("json") + if t == "" { + return f.Name + } + return strings.Split(t, ",")[0] +} + +func InitIndex(log *zap.Logger, meili meilisearch.ServiceManager, idx string, rt reflect.Type, rankRule *[]string) { + _, err := meili.CreateIndex(&meilisearch.IndexConfig{ + Uid: idx, + PrimaryKey: "id", + }) + if err != nil { + log.Fatal("failed to create search index", zap.Error(err)) + return + } + + index := meili.Index(idx) + + log.Info("set sortable attributes", zap.Strings("attributes", *GetAttributes(rt, "sortable"))) + _, err = index.UpdateSortableAttributes(GetAttributes(rt, "sortable")) + if err != nil { + log.Fatal("failed to update search index sortable attributes", zap.Error(err)) + return + } + + log.Info("set filterable attributes", zap.Strings("attributes", *GetAttributes(rt, "filterable"))) + _, err = index.UpdateFilterableAttributes(GetAttributes(rt, "filterable")) + if err != nil { + log.Fatal("failed to update search index filterable attributes", zap.Error(err)) + return + } + + log.Info("set searchable attributes", zap.Strings("attributes", *GetAttributes(rt, "searchable"))) + _, err = index.UpdateSearchableAttributes(GetAttributes(rt, "searchable")) + if err != nil { + log.Fatal("failed to update search index searchable attributes", zap.Error(err)) + return + } + + log.Info("set ranking rules", zap.Strings("rule", *rankRule)) + _, err = index.UpdateRankingRules(rankRule) + if err != nil { + log.Fatal("failed to update search index searchable attributes", zap.Error(err)) + return + } +} diff --git a/internal/search/subject/client.go b/internal/search/subject/client.go new file mode 100644 index 000000000..b7c899740 --- /dev/null +++ b/internal/search/subject/client.go @@ -0,0 +1,111 @@ +package subject + +import ( + "context" + "fmt" + "reflect" + "strconv" + + "github.com/meilisearch/meilisearch-go" + "github.com/trim21/errgo" + "github.com/trim21/pkg/queue" + "go.uber.org/zap" + + "github.com/bangumi/server/config" + "github.com/bangumi/server/dal/query" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search/searcher" + "github.com/bangumi/server/internal/subject" +) + +const ( + idx = "subjects" +) + +func New( + cfg config.AppConfig, + meili meilisearch.ServiceManager, + repo subject.Repo, + log *zap.Logger, + query *query.Query, +) (searcher.Searcher, error) { + if repo == nil { + return nil, fmt.Errorf("nil subjectRepo") + } + c := &client{ + meili: meili, + repo: repo, + index: meili.Index(idx), + log: log.Named("search").With(zap.String("index", idx)), + q: query, + } + + if cfg.AppType != config.AppTypeCanal { + return c, nil + } + + return c, c.canalInit(cfg) +} + +type client struct { + repo subject.Repo + index meilisearch.IndexManager + + meili meilisearch.ServiceManager + log *zap.Logger + q *query.Query + + queue *queue.Batched[searcher.Document] +} + +func (c *client) Close() { + if c.queue != nil { + c.queue.Close() + } +} + +func (c *client) canalInit(cfg config.AppConfig) error { + if err := searcher.ValidateConfigs(cfg); err != nil { + return errgo.Wrap(err, "validate search config") + } + c.queue = searcher.NewBatchQueue(cfg, c.log, c.index) + searcher.RegisterQueueMetrics(idx, c.queue) + + shouldCreateIndex, err := searcher.NeedFirstRun(c.meili, idx) + if err != nil { + return err + } + if shouldCreateIndex { + go c.firstRun() + } + return nil +} + +//nolint:funlen +func (c *client) firstRun() { + c.log.Info("search initialize") + rt := reflect.TypeOf(document{}) + searcher.InitIndex(c.log, c.meili, idx, rt, rankRule()) + + ctx := context.Background() + + maxItem, err := c.q.Subject.WithContext(ctx).Limit(1).Order(c.q.Subject.ID.Desc()).Take() + if err != nil { + c.log.Fatal("failed to get current max id", zap.Error(err)) + return + } + + c.log.Info(fmt.Sprintf("run full search index with max %s id %d", idx, maxItem.ID)) + + width := len(strconv.Itoa(int(maxItem.ID))) + for i := model.SubjectID(1); i <= maxItem.ID; i++ { + if i%10000 == 0 { + c.log.Info(fmt.Sprintf("progress %*d/%d", width, i, maxItem.ID)) + } + + err := c.OnUpdate(ctx, i) + if err != nil { + c.log.Error("error when updating", zap.Error(err)) + } + } +} diff --git a/internal/search/index.go b/internal/search/subject/doc.go similarity index 82% rename from internal/search/index.go rename to internal/search/subject/doc.go index d185c5a49..ec7b083a4 100644 --- a/internal/search/index.go +++ b/internal/search/subject/doc.go @@ -12,13 +12,14 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see -package search +package subject import ( "strconv" "strings" "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/search/searcher" "github.com/bangumi/server/pkg/wiki" ) @@ -26,7 +27,7 @@ import ( // 使用 `filterable:"true"`, `sortable:"true"` // 两种 tag 来设置是否可以被索引和排序. // 搜索字段因为带有排序,所以定义在 [search.searchAbleAttribute] 中. -type subjectIndex struct { +type document struct { ID model.SubjectID `json:"id"` Tag []string `json:"tag,omitempty" filterable:"true"` MetaTags []string `json:"meta_tag" filterable:"true"` @@ -42,6 +43,10 @@ type subjectIndex struct { NSFW bool `json:"nsfw" filterable:"true"` } +func (d *document) GetID() string { + return strconv.FormatUint(uint64(d.ID), 10) +} + func rankRule() *[]string { return &[]string{ // 相似度最优先 @@ -60,7 +65,11 @@ func rankRule() *[]string { } } -func extractSubject(s *model.Subject) subjectIndex { +func heat(s *model.Subject) uint32 { + return s.OnHold + s.Doing + s.Dropped + s.Wish + s.Collect +} + +func extract(s *model.Subject) searcher.Document { tags := s.Tags w := wiki.ParseOmitError(s.Infobox) @@ -72,7 +81,7 @@ func extractSubject(s *model.Subject) subjectIndex { tagNames[i] = tag.Name } - return subjectIndex{ + return &document{ ID: s.ID, Name: s.Name, Aliases: extractAliases(s, w), @@ -89,6 +98,21 @@ func extractSubject(s *model.Subject) subjectIndex { } } +func extractAliases(s *model.Subject, w wiki.Wiki) []string { + var aliases = make([]string, 0, 2) + if s.NameCN != "" { + aliases = append(aliases, s.NameCN) + } + + for _, field := range w.Fields { + if field.Key == "别名" { + aliases = append(aliases, searcher.GetWikiValues(field)...) + } + } + + return aliases +} + func parseDateVal(date string) int { if len(date) < 10 { return 0 diff --git a/internal/search/extract_internal_test.go b/internal/search/subject/doc_internal_test.go similarity index 98% rename from internal/search/extract_internal_test.go rename to internal/search/subject/doc_internal_test.go index f84874568..6af854169 100644 --- a/internal/search/extract_internal_test.go +++ b/internal/search/subject/doc_internal_test.go @@ -12,7 +12,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see -package search +package subject import ( "testing" diff --git a/internal/search/subject/event.go b/internal/search/subject/event.go new file mode 100644 index 000000000..268338403 --- /dev/null +++ b/internal/search/subject/event.go @@ -0,0 +1,58 @@ +package subject + +import ( + "context" + "errors" + "strconv" + + "github.com/trim21/errgo" + + "github.com/bangumi/server/domain/gerr" + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/subject" +) + +func (c *client) OnAdded(ctx context.Context, id model.SubjectID) error { + s, err := c.repo.Get(ctx, id, subject.Filter{}) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "subjectRepo.Get") + } + + if s.Redirect != 0 || s.Ban != 0 { + return c.OnDelete(ctx, id) + } + + extracted := extract(&s) + + _, err = c.index.UpdateDocumentsWithContext(ctx, extracted, "id") + return err +} + +func (c *client) OnUpdate(ctx context.Context, id model.SubjectID) error { + s, err := c.repo.Get(ctx, id, subject.Filter{}) + if err != nil { + if errors.Is(err, gerr.ErrNotFound) { + return nil + } + return errgo.Wrap(err, "subjectRepo.Get") + } + + if s.Redirect != 0 || s.Ban != 0 { + return c.OnDelete(ctx, id) + } + + extracted := extract(&s) + + c.queue.Push(extracted) + + return nil +} + +func (c *client) OnDelete(ctx context.Context, id model.SubjectID) error { + _, err := c.index.DeleteDocumentWithContext(ctx, strconv.FormatUint(uint64(id), 10)) + + return errgo.Wrap(err, "search") +} diff --git a/internal/search/handle.go b/internal/search/subject/handle.go similarity index 94% rename from internal/search/handle.go rename to internal/search/subject/handle.go index dc7978c23..bc524a8e8 100644 --- a/internal/search/handle.go +++ b/internal/search/subject/handle.go @@ -13,10 +13,9 @@ // along with this program. If not, see // Package search 基于 meilisearch 提供搜索功能 -package search +package subject import ( - "context" "encoding/json" "fmt" "net/http" @@ -40,20 +39,6 @@ import ( "github.com/bangumi/server/web/res" ) -type Client interface { - Handler - Close() - - OnSubjectAdded(ctx context.Context, id model.SubjectID) error - OnSubjectUpdate(ctx context.Context, id model.SubjectID) error - OnSubjectDelete(ctx context.Context, id model.SubjectID) error -} - -// Handler TODO: 想个办法挪到 web 里面去. -type Handler interface { - Handle(c echo.Context) error -} - const defaultLimit = 10 const maxLimit = 20 @@ -130,7 +115,7 @@ func (c *client) Handle(ctx echo.Context) error { } ids := slice.Map(hits, func(h hit) model.SubjectID { return h.ID }) - subjects, err := c.subjectRepo.GetByIDs(ctx.Request().Context(), ids, subject.Filter{}) + subjects, err := c.repo.GetByIDs(ctx.Request().Context(), ids, subject.Filter{}) if err != nil { return errgo.Wrap(err, "subjectRepo.GetByIDs") } @@ -187,7 +172,7 @@ func (c *client) doSearch( return nil, res.BadRequest("sort not supported") } - raw, err := c.subjectIndex.SearchRaw(words, &meilisearch.SearchRequest{ + raw, err := c.index.SearchRaw(words, &meilisearch.SearchRequest{ Offset: int64(offset), Limit: int64(limit), Filter: filter, diff --git a/internal/search/handle_internal_test.go b/internal/search/subject/handle_internal_test.go similarity index 98% rename from internal/search/handle_internal_test.go rename to internal/search/subject/handle_internal_test.go index fb54defb2..5eb9e839f 100644 --- a/internal/search/handle_internal_test.go +++ b/internal/search/subject/handle_internal_test.go @@ -12,7 +12,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see -package search +package subject import ( "testing" diff --git a/internal/search/index_internal_test.go b/internal/search/subject/index_internal_test.go similarity index 84% rename from internal/search/index_internal_test.go rename to internal/search/subject/index_internal_test.go index 5049c767b..1da67e001 100644 --- a/internal/search/index_internal_test.go +++ b/internal/search/subject/index_internal_test.go @@ -12,19 +12,23 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see -package search +package subject import ( + "reflect" "sort" "testing" "github.com/stretchr/testify/require" + + "github.com/bangumi/server/internal/search/searcher" ) func TestIndexFilter(t *testing.T) { t.Parallel() - actual := *(getAttributes("filterable")) + rt := reflect.TypeOf(document{}) + actual := *(searcher.GetAttributes(rt, "filterable")) expected := []string{"date", "meta_tag", "score", "rank", "type", "nsfw", "tag"} sort.Strings(expected) diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 98584a8d2..69addf9f0 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -131,7 +131,6 @@ paths: `true` 只会返回 R18 条目。 `false` 只会返回非 R18 条目。 - responses: 200: description: 返回搜索结果 @@ -140,6 +139,120 @@ paths: schema: "$ref": "#/components/schemas/Paged_Subject" + "/v0/search/characters": + post: + tags: + - 角色 + summary: 角色搜索 + operationId: searchCharacters + description: | + ## 实验性 API, 本 schema 和实际的 API 行为都可能随时发生改动 + + 目前支持的筛选条件包括: + - `nsfw`: 使用 `include` 包含NSFW搜索结果。默认排除搜索NSFW条目。无权限情况下忽略此选项,不会返回NSFW条目。 + + parameters: + - name: limit + in: query + description: 分页参数 + required: false + schema: + type: integer + - name: offset + in: query + description: 分页参数 + required: false + schema: + type: integer + requestBody: + content: + "application/json": + schema: + type: object + required: + - keyword + properties: + keyword: + type: string + filter: + type: object + description: 不同条件之间是 `且` 的关系 + properties: + nsfw: + type: boolean + description: | + 无权限的用户会直接忽略此字段,不会返回 R18 角色。 + + 默认或者 `null` 会返回包含 R18 的所有搜索结果。 + + `true` 只会返回 R18 角色。 + + `false` 只会返回非 R18 角色。 + responses: + 200: + description: 返回搜索结果 + content: + application/json: + schema: + "$ref": "#/components/schemas/Paged_Character" + + "/v0/search/persons": + post: + tags: + - 人物 + summary: 人物搜索 + operationId: searchPersons + description: | + ## 实验性 API, 本 schema 和实际的 API 行为都可能随时发生改动 + + 目前支持的筛选条件包括: + - `career`: 职业,可以多次出现。`且` 关系。 + + 不同筛选条件之间为 `且` + + parameters: + - name: limit + in: query + description: 分页参数 + required: false + schema: + type: integer + - name: offset + in: query + description: 分页参数 + required: false + schema: + type: integer + requestBody: + content: + "application/json": + schema: + type: object + required: + - keyword + properties: + keyword: + type: string + filter: + type: object + description: 不同条件之间是 `且` 的关系 + properties: + career: + type: array + items: + type: string + example: + - artist + - director + description: 职业,可以多次出现。多值之间为 `且` 关系。 + responses: + 200: + description: 返回搜索结果 + content: + application/json: + schema: + "$ref": "#/components/schemas/Paged_Person" + "/v0/subjects": get: tags: @@ -479,7 +592,7 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/CharacterDetail" + "$ref": "#/components/schemas/Character" "404": description: Not Found content: @@ -1962,8 +2075,8 @@ components: - B - AB - O - CharacterDetail: - title: CharacterDetail + Character: + title: Character required: - id - name @@ -2526,6 +2639,50 @@ components: items: "$ref": "#/components/schemas/Subject" default: [] + Paged_Character: + title: Paged[Character] + type: object + properties: + total: + title: Total + type: integer + default: 0 + limit: + title: Limit + type: integer + default: 0 + offset: + title: Offset + type: integer + default: 0 + data: + title: Data + type: array + items: + "$ref": "#/components/schemas/Character" + default: [] + Paged_Person: + title: Paged[Person] + type: object + properties: + total: + title: Total + type: integer + default: 0 + limit: + title: Limit + type: integer + default: 0 + offset: + title: Offset + type: integer + default: 0 + data: + title: Data + type: array + items: + "$ref": "#/components/schemas/Person" + default: [] Paged_Episode: title: Paged[Episode] type: object diff --git a/web/handler/character/character.go b/web/handler/character/character.go index 8578489f9..eacf54fd4 100644 --- a/web/handler/character/character.go +++ b/web/handler/character/character.go @@ -21,13 +21,8 @@ import ( "github.com/bangumi/server/ctrl" "github.com/bangumi/server/internal/character" "github.com/bangumi/server/internal/collections" - "github.com/bangumi/server/internal/model" "github.com/bangumi/server/internal/person" - "github.com/bangumi/server/internal/pkg/compat" - "github.com/bangumi/server/internal/pkg/null" "github.com/bangumi/server/internal/subject" - "github.com/bangumi/server/pkg/wiki" - "github.com/bangumi/server/web/res" ) type Character struct { @@ -58,28 +53,3 @@ func New( cfg: config.AppConfig{}, }, nil } - -func convertModelCharacter(s model.Character) res.CharacterV0 { - img := res.PersonImage(s.Image) - - return res.CharacterV0{ - ID: s.ID, - Type: s.Type, - Name: s.Name, - NSFW: s.NSFW, - Images: img, - Summary: s.Summary, - Infobox: compat.V0Wiki(wiki.ParseOmitError(s.Infobox).NonZero()), - Gender: null.NilString(res.GenderMap[s.FieldGender]), - BloodType: null.NilUint8(s.FieldBloodType), - BirthYear: null.NilUint16(s.FieldBirthYear), - BirthMon: null.NilUint8(s.FieldBirthMon), - BirthDay: null.NilUint8(s.FieldBirthDay), - Stat: res.Stat{ - Comments: s.CommentCount, - Collects: s.CollectCount, - }, - Redirect: s.Redirect, - Locked: s.Locked, - } -} diff --git a/web/handler/character/get.go b/web/handler/character/get.go index 08547ddca..8e9fde474 100644 --- a/web/handler/character/get.go +++ b/web/handler/character/get.go @@ -53,7 +53,7 @@ func (h Character) Get(c echo.Context) error { return res.ErrNotFound } - return c.JSON(http.StatusOK, convertModelCharacter(r)) + return c.JSON(http.StatusOK, res.ConvertModelCharacter(r)) } func (h Character) GetImage(c echo.Context) error { diff --git a/web/handler/search.go b/web/handler/search.go index 38895045f..cf0aeec0c 100644 --- a/web/handler/search.go +++ b/web/handler/search.go @@ -16,8 +16,18 @@ package handler import ( "github.com/labstack/echo/v4" + + "github.com/bangumi/server/internal/search" ) -func (h Handler) Search(c echo.Context) error { - return h.search.Handle(c) //nolint:wrapcheck +func (h Handler) SearchSubjects(c echo.Context) error { + return h.search.Handle(c, search.SearchTargetSubject) //nolint:wrapcheck +} + +func (h Handler) SearchCharacters(c echo.Context) error { + return h.search.Handle(c, search.SearchTargetCharacter) //nolint:wrapcheck +} + +func (h Handler) SearchPersons(c echo.Context) error { + return h.search.Handle(c, search.SearchTargetPerson) //nolint:wrapcheck } diff --git a/web/res/character.go b/web/res/character.go index 2f6ac467d..4acdd7e04 100644 --- a/web/res/character.go +++ b/web/res/character.go @@ -14,7 +14,12 @@ package res -import "github.com/bangumi/server/internal/model" +import ( + "github.com/bangumi/server/internal/model" + "github.com/bangumi/server/internal/pkg/compat" + "github.com/bangumi/server/internal/pkg/null" + "github.com/bangumi/server/pkg/wiki" +) type CharacterV0 struct { BirthMon *uint8 `json:"birth_mon"` @@ -52,3 +57,28 @@ func CharacterStaffString(i uint8) string { return "" } + +func ConvertModelCharacter(s model.Character) CharacterV0 { + img := PersonImage(s.Image) + + return CharacterV0{ + ID: s.ID, + Type: s.Type, + Name: s.Name, + NSFW: s.NSFW, + Images: img, + Summary: s.Summary, + Infobox: compat.V0Wiki(wiki.ParseOmitError(s.Infobox).NonZero()), + Gender: null.NilString(GenderMap[s.FieldGender]), + BloodType: null.NilUint8(s.FieldBloodType), + BirthYear: null.NilUint16(s.FieldBirthYear), + BirthMon: null.NilUint8(s.FieldBirthMon), + BirthDay: null.NilUint8(s.FieldBirthDay), + Stat: Stat{ + Comments: s.CommentCount, + Collects: s.CollectCount, + }, + Redirect: s.Redirect, + Locked: s.Locked, + } +} diff --git a/web/routes.go b/web/routes.go index f3a2b169c..2c3808fde 100644 --- a/web/routes.go +++ b/web/routes.go @@ -58,7 +58,9 @@ func AddRouters( v0 := app.Group("/v0", common.MiddlewareAccessTokenAuth) - v0.POST("/search/subjects", h.Search) + v0.POST("/search/subjects", h.SearchSubjects) + v0.POST("/search/characters", h.SearchCharacters) + v0.POST("/search/persons", h.SearchPersons) subjectHandler.Routes(v0) From 552c090f7af71d992a5c2c02f8992a9f2bd6ac81 Mon Sep 17 00:00:00 2001 From: everpcpc Date: Tue, 26 Nov 2024 15:01:20 +0800 Subject: [PATCH 225/240] fix: update example config for kafka topics (#672) --- config.example.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.example.yaml b/config.example.yaml index e342a4aba..4e125cfed 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -23,6 +23,8 @@ canal: topics: # kafka topic of redis stream keys - debezium.bangumi.chii_subject_fields - debezium.bangumi.chii_subjects + - debezium.bangumi.chii_characters + - debezium.bangumi.chii_persons - debezium.bangumi.chii_members search: From b719b55ee31172054b2233de7d1827d211a2f7df Mon Sep 17 00:00:00 2001 From: everpcpc Date: Wed, 27 Nov 2024 08:29:46 +0800 Subject: [PATCH 226/240] fix: remove duplicate repo arg (#674) --- cmd/web/cmd.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/web/cmd.go b/cmd/web/cmd.go index ea11b7a55..739a44e01 100644 --- a/cmd/web/cmd.go +++ b/cmd/web/cmd.go @@ -82,8 +82,6 @@ func start() error { fx.Provide( logger.Copy, cache.NewRedisCache, - character.NewMysqlRepo, - user.NewMysqlRepo, index.NewMysqlRepo, auth.NewMysqlRepo, episode.NewMysqlRepo, revision.NewMysqlRepo, infra.NewMysqlRepo, timeline.NewMysqlRepo, pm.NewMysqlRepo, notification.NewMysqlRepo, From 38ce8e6d91023d543dda151f33f3681f4cd24478 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:19:32 +0800 Subject: [PATCH 227/240] chore(deps): update gcr.io/distroless/static docker digest to 5c7e2b4 (#675) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- etc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/Dockerfile b/etc/Dockerfile index 7e6c62637..76bc339a6 100644 --- a/etc/Dockerfile +++ b/etc/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/distroless/static@sha256:cc226ca14d17d01d4b278d9489da930a0dd11150df10ae95829d13e6d00fbdbf +FROM gcr.io/distroless/static@sha256:5c7e2b465ac6a2a4e5f4f7f722ce43b147dabe87cb21ac6c4007ae5178a1fa58 ENTRYPOINT ["/app/chii.exe"] From 386ae6808984149034b2d08dc95892855327e32c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:19:43 +0800 Subject: [PATCH 228/240] ci: update codecov/codecov-action action to v5 (#687) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 120a98cb9..20ada4382 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -72,7 +72,7 @@ jobs: MYSQL_DB: bangumi REDIS_URI: "redis://:redis-pass@127.0.0.1:6379/0" - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 with: files: coverage.out token: ${{ secrets.CODECOV_TOKEN }} # required From e553755722475071ea05b684c8c38afab8843db8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:19:59 +0800 Subject: [PATCH 229/240] build(deps): update module github.com/bytedance/sonic to v1.12.5 (#677) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 92fbde363..514ce6754 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.32.3 github.com/aws/aws-sdk-go-v2/credentials v1.17.42 github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 - github.com/bytedance/sonic v1.12.4 + github.com/bytedance/sonic v1.12.5 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 diff --git a/go.sum b/go.sum index 93e7a9796..a02876b86 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= -github.com/bytedance/sonic v1.12.4 h1:9Csb3c9ZJhfUWeMtpCDCq6BUoH5ogfDFLUgQ/jG+R0k= -github.com/bytedance/sonic v1.12.4/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/w= +github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= From 3b32f43d0b3edc931b22b781cf73259a087306fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:26:05 +0800 Subject: [PATCH 230/240] build(deps): update module golang.org/x/text to v0.20.0 (#685) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 514ce6754..573f56020 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.uber.org/fx v1.23.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 - golang.org/x/text v0.19.0 + golang.org/x/text v0.20.0 google.golang.org/grpc v1.67.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.35.1 @@ -98,7 +98,7 @@ require ( golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/sync v0.9.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect diff --git a/go.sum b/go.sum index a02876b86..cdf763267 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,8 @@ golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -276,8 +276,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 9299c86e94e51ebcc8b8da95008ffdacfaab53d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:26:24 +0800 Subject: [PATCH 231/240] build(deps): update aws-sdk-go-v2 monorepo (#676) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 24 ++++++++++++------------ go.sum | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index 573f56020..1a3e40c7c 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,9 @@ go 1.23.2 require ( github.com/avast/retry-go/v4 v4.6.0 - github.com/aws/aws-sdk-go-v2 v1.32.3 - github.com/aws/aws-sdk-go-v2/credentials v1.17.42 - github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 + github.com/aws/aws-sdk-go-v2 v1.32.5 + github.com/aws/aws-sdk-go-v2/credentials v1.17.46 + github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 github.com/bytedance/sonic v1.12.5 github.com/davecgh/go-spew v1.1.1 github.com/elliotchance/phpserialize v1.4.0 @@ -53,15 +53,15 @@ require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 // indirect - github.com/aws/smithy-go v1.22.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 // indirect + github.com/aws/smithy-go v1.22.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index cdf763267..d5963ab85 100644 --- a/go.sum +++ b/go.sum @@ -7,30 +7,30 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= -github.com/aws/aws-sdk-go-v2 v1.32.3 h1:T0dRlFBKcdaUPGNtkBSwHZxrtis8CQU17UpNBZYd0wk= -github.com/aws/aws-sdk-go-v2 v1.32.3/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= -github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.42/go.mod h1:FwZBfU530dJ26rv9saAbxa9Ej3eF/AK0OAY86k13n4M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 h1:Jw50LwEkVjuVzE1NzkhNKkBf9cRN7MtE1F/b2cOKTUM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22/go.mod h1:Y/SmAyPcOTmpeVaWSzSKiILfXTVJwrGmYZhcRbhWuEY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 h1:981MHwBaRZM7+9QSR6XamDzF/o7ouUGxFzr+nVSIhrs= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22/go.mod h1:1RA1+aBEfn+CAB/Mh0MB6LsdCYCnjZm7tKXtnk499ZQ= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 h1:yV+hCAHZZYJQcwAaszoBNwLbPItHvApxT0kVIw6jRgs= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22/go.mod h1:kbR1TL8llqB1eGnVbybcA4/wgScxdylOdyAd51yxPdw= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 h1:kT6BcZsmMtNkP/iYMcRG+mIEA/IbeiUimXtGmqF39y0= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3/go.mod h1:Z8uGua2k4PPaGOYn66pK02rhMrot3Xk3tpBuUFPomZU= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 h1:qcxX0JYlgWH3hpPUnd6U0ikcl6LLA9sLkXE2w1fpMvY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3/go.mod h1:cLSNEmI45soc+Ef8K/L+8sEA3A3pYFEYf5B5UI+6bH4= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 h1:ZC7Y/XgKUxwqcdhO5LE8P6oGP1eh6xlQReWNKfhvJno= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3/go.mod h1:WqfO7M9l9yUAw0HcHaikwRd/H6gzYdz7vjejCA5e2oY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 h1:p9TNFL8bFUMd+38YIpTAXpoxyz0MxC7FlbFEH4P4E1U= -github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2/go.mod h1:fNjyo0Coen9QTwQLWeV6WO2Nytwiu+cCcWaTdKCAqqE= -github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= -github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go-v2 v1.32.5 h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo= +github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= +github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg= +github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 h1:wtpJ4zcwrSbwhECWQoI/g6WM9zqCcSpHDJIWSbMLOu4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5/go.mod h1:qu/W9HXQbbQ4+1+JcZp0ZNPV31ym537ZJN+fiS7Ti8E= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w= +github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= From 663b3256522577e3279ee8b14f0f699846dc8faa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:28:09 +0800 Subject: [PATCH 232/240] build(deps): update module golang.org/x/crypto to v0.29.0 (#684) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 1a3e40c7c..c81468762 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/trim21/pkg v0.0.4 go.uber.org/fx v1.23.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.29.0 golang.org/x/text v0.20.0 google.golang.org/grpc v1.67.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 @@ -99,7 +99,7 @@ require ( golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.26.0 // indirect + golang.org/x/sys v0.27.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect diff --git a/go.sum b/go.sum index d5963ab85..fed24c2cf 100644 --- a/go.sum +++ b/go.sum @@ -230,8 +230,8 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -261,8 +261,8 @@ 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= From df715b7ee6524941bdf343e9732279b55236462d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:28:27 +0800 Subject: [PATCH 233/240] build(deps): update module google.golang.org/grpc to v1.68.0 (#686) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c81468762..ef72ca93c 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/crypto v0.29.0 golang.org/x/text v0.20.0 - google.golang.org/grpc v1.67.1 + google.golang.org/grpc v1.68.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index fed24c2cf..750a10ad2 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,8 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -289,8 +291,8 @@ golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= From d1967bf2a77887720d77dd54e05a2d964905d02a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:28:40 +0800 Subject: [PATCH 234/240] build(deps): update module github.com/stretchr/testify to v1.10.0 (#683) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ef72ca93c..cffdbf5c9 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/trim21/errgo v0.0.3 github.com/trim21/go-phpserialize v0.1.0-alpha.5 github.com/trim21/htest v0.0.4 diff --git a/go.sum b/go.sum index 750a10ad2..2e9d8f062 100644 --- a/go.sum +++ b/go.sum @@ -192,8 +192,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/trim21/errgo v0.0.3 h1:q0cUPTs+4c5NxByA4f0HUGRvlNyBlUtdxFiTKQdTE68= github.com/trim21/errgo v0.0.3/go.mod h1:AH1KzogdvSkSPXbZq9QAuqSt1L1Eu5W8eYK32zPYv9s= github.com/trim21/go-phpserialize v0.1.0-alpha.5 h1:bMsUpfwAgPggQzDKdafNBvkPWDCMfzlvH30MWzI/SYg= From fa0683df02d9d64480cae262c56a643652baa678 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:28:50 +0800 Subject: [PATCH 235/240] build(deps): update module github.com/go-resty/resty/v2 to v2.16.2 (#682) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cffdbf5c9..27193fda8 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.22.1 - github.com/go-resty/resty/v2 v2.15.3 + github.com/go-resty/resty/v2 v2.16.2 github.com/go-sql-driver/mysql v1.8.1 github.com/google/uuid v1.6.0 github.com/ilyakaznacheev/cleanenv v1.5.0 diff --git a/go.sum b/go.sum index 2e9d8f062..8389b919e 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= -github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= +github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= +github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= From 75e48ac8c92a74f3b23a97a809b6a6e3a467d872 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:31:10 +0800 Subject: [PATCH 236/240] build(deps): update dependency prettier to ^3.4.1 (#680) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 146a2750f..8b8d05ba4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.3.3" + "prettier": "^3.4.1" } }, "node_modules/@apidevtools/json-schema-ref-parser": { @@ -294,9 +294,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz", + "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -664,9 +664,9 @@ } }, "prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz", + "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==", "dev": true }, "reftools": { diff --git a/package.json b/package.json index 812c53117..c49a7c45d 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "devDependencies": { "colors": "^1.4.0", "oas-validator": "^5.0.8", - "prettier": "^3.3.3" + "prettier": "^3.4.1" }, "nodemonConfig": { "restartable": "rs", From b9de5a6c5443941a374b66308d946acb5bc55f16 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:31:15 +0800 Subject: [PATCH 237/240] build(deps): update module google.golang.org/protobuf to v1.35.2 (#679) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 27193fda8..f5b5f5d05 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( golang.org/x/text v0.20.0 google.golang.org/grpc v1.68.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 - google.golang.org/protobuf v1.35.1 + google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 gorm.io/gen v0.3.26 diff --git a/go.sum b/go.sum index 8389b919e..6be930b5f 100644 --- a/go.sum +++ b/go.sum @@ -295,8 +295,8 @@ google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From ba0e96f37448b48052fee51ddb0936706e12328b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:31:24 +0800 Subject: [PATCH 238/240] build(deps): update module github.com/redis/rueidis to v1.0.49 (#678) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f5b5f5d05..1a6c30876 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/meilisearch/meilisearch-go v0.29.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus/client_golang v1.20.5 - github.com/redis/rueidis v1.0.48 + github.com/redis/rueidis v1.0.49 github.com/samber/lo v1.47.0 github.com/segmentio/kafka-go v0.4.47 github.com/spf13/cobra v1.8.1 diff --git a/go.sum b/go.sum index 6be930b5f..9868c1a65 100644 --- a/go.sum +++ b/go.sum @@ -167,8 +167,8 @@ github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJN github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/redis/rueidis v1.0.48 h1:ggZHjEtc/echUmPkGTfssRisnc3p/mIUEwrpbNsZ1mQ= -github.com/redis/rueidis v1.0.48/go.mod h1:by+34b0cFXndxtYmPAHpoTHO5NkosDlBvhexoTURIxM= +github.com/redis/rueidis v1.0.49 h1:uhjMcQ663R8st3saoo85VV9Ce37zfvRXiveZcBrS3YQ= +github.com/redis/rueidis v1.0.49/go.mod h1:by+34b0cFXndxtYmPAHpoTHO5NkosDlBvhexoTURIxM= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= From 4051eedde0f4ecb2ce5e2a298575ffd8dc1f7031 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:31:34 +0800 Subject: [PATCH 239/240] build(deps): update module github.com/go-playground/validator/v10 to v10.23.0 (#681) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1a6c30876..7904b9973 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/elliotchance/phpserialize v1.4.0 github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 - github.com/go-playground/validator/v10 v10.22.1 + github.com/go-playground/validator/v10 v10.23.0 github.com/go-resty/resty/v2 v2.16.2 github.com/go-sql-driver/mysql v1.8.1 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 9868c1a65..e9657e3c9 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= -github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= From 40ab2997c01246e32a64c55dc29448cf0ea7ee0a Mon Sep 17 00:00:00 2001 From: xrz <62951481+xrz-cloud@users.noreply.github.com> Date: Sun, 8 Dec 2024 22:05:17 +0800 Subject: [PATCH 240/240] feat: support get current user's email and reg_time (#690) --- internal/user/model.go | 1 + internal/user/mysql_repository.go | 1 + openapi/v0.yaml | 11 +++++++++ web/handler/user/me.go | 37 ++++++++++++++++++------------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/internal/user/model.go b/internal/user/model.go index 2ee5e2bbb..cb700cf6b 100644 --- a/internal/user/model.go +++ b/internal/user/model.go @@ -32,6 +32,7 @@ type FullUser struct { ID model.UserID UserGroup GroupID TimeOffset int8 + Email string } type GroupID = uint8 diff --git a/internal/user/mysql_repository.go b/internal/user/mysql_repository.go index c77fb0d3e..a85365a79 100644 --- a/internal/user/mysql_repository.go +++ b/internal/user/mysql_repository.go @@ -59,6 +59,7 @@ func (m mysqlRepo) GetFullUser(ctx context.Context, userID model.UserID) (FullUs ID: u.ID, RegistrationTime: time.Unix(u.Regdate, 0), TimeOffset: parseTimeOffset(u.Timeoffset), + Email: u.Email, }, nil } diff --git a/openapi/v0.yaml b/openapi/v0.yaml index 69addf9f0..87e18ee9a 100644 --- a/openapi/v0.yaml +++ b/openapi/v0.yaml @@ -1041,8 +1041,19 @@ paths: schema: allOf: - "$ref": "#/components/schemas/User" + - required: + - email + - reg_time - type: object properties: + email: + description: "用户绑定的邮箱地址" + type: string + format: email + reg_time: + description: "用户注册时间。比如 2017-12-03T08:51:16+08:00" + type: string + format: date-time time_offset: description: "用户设置的时区偏移,以小时为单位。比如 GMT+8(shanghai/beijing)为 8" type: integer diff --git a/web/handler/user/me.go b/web/handler/user/me.go index d2482c903..ca4fecc8e 100644 --- a/web/handler/user/me.go +++ b/web/handler/user/me.go @@ -16,6 +16,7 @@ package user import ( "net/http" + "time" "github.com/labstack/echo/v4" "github.com/trim21/errgo" @@ -26,14 +27,16 @@ import ( ) type CurrentUser struct { - Avatar res.Avatar `json:"avatar"` - Sign string `json:"sign"` - URL string `json:"url"` - Username string `json:"username"` - Nickname string `json:"nickname"` - ID model.UserID `json:"id"` - UserGroup uint8 `json:"user_group"` - TimeOffset int8 `json:"time_offset"` + Avatar res.Avatar `json:"avatar"` + Sign string `json:"sign"` + URL string `json:"url"` + Username string `json:"username"` + Nickname string `json:"nickname"` + ID model.UserID `json:"id"` + UserGroup uint8 `json:"user_group"` + RegistrationTime time.Time `json:"reg_time"` + Email string `json:"email"` + TimeOffset int8 `json:"time_offset"` } func (h User) GetCurrent(c echo.Context) error { @@ -48,13 +51,15 @@ func (h User) GetCurrent(c echo.Context) error { } return c.JSON(http.StatusOK, CurrentUser{ - ID: user.ID, - URL: "https://bgm.tv/user/" + user.UserName, - Username: user.UserName, - Nickname: user.NickName, - UserGroup: user.UserGroup, - Avatar: res.UserAvatar(user.Avatar), - Sign: user.Sign, - TimeOffset: user.TimeOffset, + ID: user.ID, + URL: "https://bgm.tv/user/" + user.UserName, + Username: user.UserName, + Nickname: user.NickName, + UserGroup: user.UserGroup, + Avatar: res.UserAvatar(user.Avatar), + Sign: user.Sign, + RegistrationTime: user.RegistrationTime, + Email: user.Email, + TimeOffset: user.TimeOffset, }) }