From d789d3646c086cec819f718c86a91f9a49c01dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Van=C4=9Bk?= Date: Fri, 24 Jun 2022 15:51:37 +0200 Subject: [PATCH 1/8] Fix typos related to ErrTaskDoesNotExist error (#20118) Fixes: f2a3abc683ad ("Move migrating repository from frontend to backend (#6200)") --- models/task.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/task.go b/models/task.go index cabb96c60831e..67f04d9562f42 100644 --- a/models/task.go +++ b/models/task.go @@ -156,14 +156,14 @@ type ErrTaskDoesNotExist struct { Type structs.TaskType } -// IsErrTaskDoesNotExist checks if an error is a ErrTaskIsNotExist. +// IsErrTaskDoesNotExist checks if an error is a ErrTaskDoesNotExist. func IsErrTaskDoesNotExist(err error) bool { _, ok := err.(ErrTaskDoesNotExist) return ok } func (err ErrTaskDoesNotExist) Error() string { - return fmt.Sprintf("task is not exist [id: %d, repo_id: %d, type: %d]", + return fmt.Sprintf("task does not exist [id: %d, repo_id: %d, type: %d]", err.ID, err.RepoID, err.Type) } From 02eb4b143b24f2091d82137aa3ee7d3469598499 Mon Sep 17 00:00:00 2001 From: John Olheiser Date: Fri, 24 Jun 2022 12:22:08 -0500 Subject: [PATCH 2/8] Disable status checks in template if none found (#20088) Signed-off-by: jolheiser --- templates/repo/settings/protected_branch.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/settings/protected_branch.tmpl b/templates/repo/settings/protected_branch.tmpl index 597567f057aa5..e7228f2ac9e15 100644 --- a/templates/repo/settings/protected_branch.tmpl +++ b/templates/repo/settings/protected_branch.tmpl @@ -127,7 +127,7 @@
- +

{{.i18n.Tr "repo.settings.protect_check_status_contexts_desc"}}

From 8a3cd5846325975bf2ff30d5ca9aa6c5690fce08 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Fri, 24 Jun 2022 15:04:30 -0400 Subject: [PATCH 3/8] Remove depricated queue indexer usage (#20124) --- integrations/mssql.ini.tmpl | 6 ++++-- integrations/mysql.ini.tmpl | 6 ++++-- integrations/mysql8.ini.tmpl | 6 ++++-- integrations/pgsql.ini.tmpl | 6 ++++-- integrations/sqlite.ini.tmpl | 6 ++++-- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/integrations/mssql.ini.tmpl b/integrations/mssql.ini.tmpl index da15e9ef69ee4..a6c34dc4b1a6a 100644 --- a/integrations/mssql.ini.tmpl +++ b/integrations/mssql.ini.tmpl @@ -10,11 +10,13 @@ PASSWD = {{TEST_MSSQL_PASSWORD}} SSL_MODE = disable [indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-mssql/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mssql/indexers/issues.queue REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-mssql/indexers/repos.bleve +[queue.issue_indexer] +ISSUE_INDEXER_PATH = integrations/gitea-integration-mssql/indexers/issues.bleve +ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mssql/indexers/issues.queue + [queue] TYPE = immediate diff --git a/integrations/mysql.ini.tmpl b/integrations/mysql.ini.tmpl index 4df49336424a6..2829af62fc2a4 100644 --- a/integrations/mysql.ini.tmpl +++ b/integrations/mysql.ini.tmpl @@ -10,11 +10,13 @@ PASSWD = {{TEST_MYSQL_PASSWORD}} SSL_MODE = disable [indexer] +REPO_INDEXER_ENABLED = true +REPO_INDEXER_PATH = integrations/gitea-integration-mysql/indexers/repos.bleve + +[queue.issue_indexer] ISSUE_INDEXER_TYPE = elasticsearch ISSUE_INDEXER_CONN_STR = http://elastic:changeme@elasticsearch:9200 ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mysql/indexers/issues.queue -REPO_INDEXER_ENABLED = true -REPO_INDEXER_PATH = integrations/gitea-integration-mysql/indexers/repos.bleve [queue] TYPE = immediate diff --git a/integrations/mysql8.ini.tmpl b/integrations/mysql8.ini.tmpl index 4b63dd51a1fdd..f1157b0887395 100644 --- a/integrations/mysql8.ini.tmpl +++ b/integrations/mysql8.ini.tmpl @@ -10,11 +10,13 @@ PASSWD = {{TEST_MYSQL8_PASSWORD}} SSL_MODE = disable [indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-mysql8/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mysql8/indexers/issues.queue REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-mysql8/indexers/repos.bleve +[queue.issue_indexer] +ISSUE_INDEXER_PATH = integrations/gitea-integration-mysql8/indexers/issues.bleve +ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mysql8/indexers/issues.queue + [queue] TYPE = immediate diff --git a/integrations/pgsql.ini.tmpl b/integrations/pgsql.ini.tmpl index 5b54a02c9fac8..418546787647c 100644 --- a/integrations/pgsql.ini.tmpl +++ b/integrations/pgsql.ini.tmpl @@ -11,11 +11,13 @@ SCHEMA = {{TEST_PGSQL_SCHEMA}} SSL_MODE = disable [indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-pgsql/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-pgsql/indexers/issues.queue REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-pgsql/indexers/repos.bleve +[queue.issue_indexer] +ISSUE_INDEXER_PATH = integrations/gitea-integration-pgsql/indexers/issues.bleve +ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-pgsql/indexers/issues.queue + [queue] TYPE = immediate diff --git a/integrations/sqlite.ini.tmpl b/integrations/sqlite.ini.tmpl index 2da7fd65d392b..cb1593af6dc1f 100644 --- a/integrations/sqlite.ini.tmpl +++ b/integrations/sqlite.ini.tmpl @@ -6,11 +6,13 @@ DB_TYPE = sqlite3 PATH = integrations/gitea-integration-sqlite/gitea.db [indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-sqlite/indexers/issues.queue REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/repos.bleve +[queue.issue_indexer] +ISSUE_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/issues.bleve +ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-sqlite/indexers/issues.queue + [queue] TYPE = immediate From 97bfabc745cdcce11ce50a62e29bb7a4e7e66e6c Mon Sep 17 00:00:00 2001 From: Kyle D Date: Fri, 24 Jun 2022 16:38:19 -0400 Subject: [PATCH 4/8] Use new config options (#20125) --- integrations/mssql.ini.tmpl | 4 ++-- integrations/mysql.ini.tmpl | 6 +++--- integrations/mysql8.ini.tmpl | 4 ++-- integrations/pgsql.ini.tmpl | 4 ++-- integrations/sqlite.ini.tmpl | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/integrations/mssql.ini.tmpl b/integrations/mssql.ini.tmpl index a6c34dc4b1a6a..d4d1517011e2a 100644 --- a/integrations/mssql.ini.tmpl +++ b/integrations/mssql.ini.tmpl @@ -14,8 +14,8 @@ REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-mssql/indexers/repos.bleve [queue.issue_indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-mssql/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mssql/indexers/issues.queue +PATH = integrations/gitea-integration-mssql/indexers/issues.bleve +DATADIR = integrations/gitea-integration-mssql/indexers/issues.queue [queue] TYPE = immediate diff --git a/integrations/mysql.ini.tmpl b/integrations/mysql.ini.tmpl index 2829af62fc2a4..8f610326e245b 100644 --- a/integrations/mysql.ini.tmpl +++ b/integrations/mysql.ini.tmpl @@ -14,9 +14,9 @@ REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-mysql/indexers/repos.bleve [queue.issue_indexer] -ISSUE_INDEXER_TYPE = elasticsearch -ISSUE_INDEXER_CONN_STR = http://elastic:changeme@elasticsearch:9200 -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mysql/indexers/issues.queue +TYPE = elasticsearch +CONN_STR = http://elastic:changeme@elasticsearch:9200 +DATADIR = integrations/gitea-integration-mysql/indexers/issues.queue [queue] TYPE = immediate diff --git a/integrations/mysql8.ini.tmpl b/integrations/mysql8.ini.tmpl index f1157b0887395..5133058237c20 100644 --- a/integrations/mysql8.ini.tmpl +++ b/integrations/mysql8.ini.tmpl @@ -14,8 +14,8 @@ REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-mysql8/indexers/repos.bleve [queue.issue_indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-mysql8/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-mysql8/indexers/issues.queue +PATH = integrations/gitea-integration-mysql8/indexers/issues.bleve +DATADIR = integrations/gitea-integration-mysql8/indexers/issues.queue [queue] TYPE = immediate diff --git a/integrations/pgsql.ini.tmpl b/integrations/pgsql.ini.tmpl index 418546787647c..15cd6a057b2c9 100644 --- a/integrations/pgsql.ini.tmpl +++ b/integrations/pgsql.ini.tmpl @@ -15,8 +15,8 @@ REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-pgsql/indexers/repos.bleve [queue.issue_indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-pgsql/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-pgsql/indexers/issues.queue +PATH = integrations/gitea-integration-pgsql/indexers/issues.bleve +DATADIR = integrations/gitea-integration-pgsql/indexers/issues.queue [queue] TYPE = immediate diff --git a/integrations/sqlite.ini.tmpl b/integrations/sqlite.ini.tmpl index cb1593af6dc1f..fa57e1aa96b88 100644 --- a/integrations/sqlite.ini.tmpl +++ b/integrations/sqlite.ini.tmpl @@ -10,8 +10,8 @@ REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/repos.bleve [queue.issue_indexer] -ISSUE_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/issues.bleve -ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-sqlite/indexers/issues.queue +PATH = integrations/gitea-integration-sqlite/indexers/issues.bleve +DATADIR = integrations/gitea-integration-sqlite/indexers/issues.queue [queue] TYPE = immediate From 95383b7a16205d749e9d696d69d0ae665e91501e Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Sat, 25 Jun 2022 19:06:01 +0200 Subject: [PATCH 5/8] Add sitemap support (#18407) --- custom/conf/app.example.ini | 3 + .../doc/advanced/config-cheat-sheet.en-us.md | 1 + modules/setting/setting.go | 2 + modules/sitemap/sitemap.go | 69 +++++++++++++++++ modules/sitemap/sitemap_test.go | 77 +++++++++++++++++++ routers/web/explore/repo.go | 26 ++++++- routers/web/explore/user.go | 25 +++++- routers/web/home.go | 53 +++++++++++++ routers/web/web.go | 3 + 9 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 modules/sitemap/sitemap.go create mode 100644 modules/sitemap/sitemap_test.go diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 80017a11764ee..5016f29cf9ffd 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1097,6 +1097,9 @@ PATH = ;; Number of items that are displayed in home feed ;FEED_PAGING_NUM = 20 ;; +;; Number of items that are displayed in a single subsitemap +;SITEMAP_PAGING_NUM = 20 +;; ;; Number of maximum commits displayed in commit graph. ;GRAPH_MAX_COMMIT_NUM = 100 ;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 15628a7def051..df659b6540119 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -174,6 +174,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `MEMBERS_PAGING_NUM`: **20**: Number of members that are shown in organization members. - `FEED_MAX_COMMIT_NUM`: **5**: Number of maximum commits shown in one activity feed. - `FEED_PAGING_NUM`: **20**: Number of items that are displayed in home feed. +- `SITEMAP_PAGING_NUM`: **20**: Number of items that are displayed in a single subsitemap. - `GRAPH_MAX_COMMIT_NUM`: **100**: Number of maximum commits shown in the commit graph. - `CODE_COMMENT_LINES`: **4**: Number of line of codes shown for a code comment. - `DEFAULT_THEME`: **auto**: \[auto, gitea, arc-green\]: Set the default theme for the Gitea install. diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 88f306b3fa7e3..7be0842b56a6d 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -207,6 +207,7 @@ var ( // UI settings UI = struct { ExplorePagingNum int + SitemapPagingNum int IssuePagingNum int RepoSearchPagingNum int MembersPagingNum int @@ -260,6 +261,7 @@ var ( } `ini:"ui.meta"` }{ ExplorePagingNum: 20, + SitemapPagingNum: 20, IssuePagingNum: 10, RepoSearchPagingNum: 10, MembersPagingNum: 20, diff --git a/modules/sitemap/sitemap.go b/modules/sitemap/sitemap.go new file mode 100644 index 0000000000000..14953765abbc2 --- /dev/null +++ b/modules/sitemap/sitemap.go @@ -0,0 +1,69 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package sitemap + +import ( + "bytes" + "encoding/xml" + "fmt" + "io" + "time" +) + +// sitemapFileLimit contains the maximum size of a sitemap file +const sitemapFileLimit = 50 * 1024 * 1024 + +// Url represents a single sitemap entry +type URL struct { + URL string `xml:"loc"` + LastMod *time.Time `xml:"lastmod,omitempty"` +} + +// SitemapUrl represents a sitemap +type Sitemap struct { + XMLName xml.Name + Namespace string `xml:"xmlns,attr"` + + URLs []URL `xml:"url"` +} + +// NewSitemap creates a sitemap +func NewSitemap() *Sitemap { + return &Sitemap{ + XMLName: xml.Name{Local: "urlset"}, + Namespace: "http://www.sitemaps.org/schemas/sitemap/0.9", + } +} + +// NewSitemap creates a sitemap index. +func NewSitemapIndex() *Sitemap { + return &Sitemap{ + XMLName: xml.Name{Local: "sitemapindex"}, + Namespace: "http://www.sitemaps.org/schemas/sitemap/0.9", + } +} + +// Add adds a URL to the sitemap +func (s *Sitemap) Add(u URL) { + s.URLs = append(s.URLs, u) +} + +// Write writes the sitemap to a response +func (s *Sitemap) WriteTo(w io.Writer) (int64, error) { + if len(s.URLs) > 50000 { + return 0, fmt.Errorf("The sitemap contains too many URLs: %d", len(s.URLs)) + } + buf := bytes.NewBufferString(xml.Header) + if err := xml.NewEncoder(buf).Encode(s); err != nil { + return 0, err + } + if err := buf.WriteByte('\n'); err != nil { + return 0, err + } + if buf.Len() > sitemapFileLimit { + return 0, fmt.Errorf("The sitemap is too big: %d", buf.Len()) + } + return buf.WriteTo(w) +} diff --git a/modules/sitemap/sitemap_test.go b/modules/sitemap/sitemap_test.go new file mode 100644 index 0000000000000..63007b84791f6 --- /dev/null +++ b/modules/sitemap/sitemap_test.go @@ -0,0 +1,77 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package sitemap + +import ( + "bytes" + "encoding/xml" + "fmt" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestOk(t *testing.T) { + testReal := func(s *Sitemap, name string, urls []URL, expected string) { + for _, url := range urls { + s.Add(url) + } + buf := &bytes.Buffer{} + _, err := s.WriteTo(buf) + assert.NoError(t, nil, err) + assert.Equal(t, xml.Header+"<"+name+" xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">"+expected+"\n", buf.String()) + } + test := func(urls []URL, expected string) { + testReal(NewSitemap(), "urlset", urls, expected) + testReal(NewSitemapIndex(), "sitemapindex", urls, expected) + } + + ts := time.Unix(1651322008, 0).UTC() + + test( + []URL{}, + "", + ) + test( + []URL{ + {URL: "https://gitea.io/test1", LastMod: &ts}, + }, + "https://gitea.io/test12022-04-30T12:33:28Z", + ) + test( + []URL{ + {URL: "https://gitea.io/test2", LastMod: nil}, + }, + "https://gitea.io/test2", + ) + test( + []URL{ + {URL: "https://gitea.io/test1", LastMod: &ts}, + {URL: "https://gitea.io/test2", LastMod: nil}, + }, + "https://gitea.io/test12022-04-30T12:33:28Z"+ + "https://gitea.io/test2", + ) +} + +func TestTooManyURLs(t *testing.T) { + s := NewSitemap() + for i := 0; i < 50001; i++ { + s.Add(URL{URL: fmt.Sprintf("https://gitea.io/test%d", i)}) + } + buf := &bytes.Buffer{} + _, err := s.WriteTo(buf) + assert.EqualError(t, err, "The sitemap contains too many URLs: 50001") +} + +func TestSitemapTooBig(t *testing.T) { + s := NewSitemap() + s.Add(URL{URL: strings.Repeat("b", sitemapFileLimit)}) + buf := &bytes.Buffer{} + _, err := s.WriteTo(buf) + assert.EqualError(t, err, "The sitemap is too big: 52428931") +} diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index f64642bc95d36..b5485f5832d4d 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -11,7 +11,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/sitemap" ) const ( @@ -30,11 +32,21 @@ type RepoSearchOptions struct { // RenderRepoSearch render repositories search page func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { - page := ctx.FormInt("page") + // Sitemap index for sitemap paths + page := int(ctx.ParamsInt64("idx")) + isSitemap := ctx.Params("idx") != "" + if page <= 1 { + page = ctx.FormInt("page") + } + if page <= 0 { page = 1 } + if isSitemap { + opts.PageSize = setting.UI.SitemapPagingNum + } + var ( repos []*repo_model.Repository count int64 @@ -100,6 +112,18 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { ctx.ServerError("SearchRepository", err) return } + if isSitemap { + m := sitemap.NewSitemap() + for _, item := range repos { + m.Add(sitemap.URL{URL: item.HTMLURL(), LastMod: item.UpdatedUnix.AsTimePtr()}) + } + ctx.Resp.Header().Set("Content-Type", "text/xml") + if _, err := m.WriteTo(ctx.Resp); err != nil { + log.Error("Failed writing sitemap: %v", err) + } + return + } + ctx.Data["Keyword"] = keyword ctx.Data["Total"] = count ctx.Data["Repos"] = repos diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index ea0d7d5f9d8c3..ea3d83e8d6c1c 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -12,7 +12,9 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/sitemap" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" ) @@ -33,11 +35,20 @@ func isKeywordValid(keyword string) bool { // RenderUserSearch render user search page func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, tplName base.TplName) { - opts.Page = ctx.FormInt("page") + // Sitemap index for sitemap paths + opts.Page = int(ctx.ParamsInt64("idx")) + isSitemap := ctx.Params("idx") != "" + if opts.Page <= 1 { + opts.Page = ctx.FormInt("page") + } if opts.Page <= 1 { opts.Page = 1 } + if isSitemap { + opts.PageSize = setting.UI.SitemapPagingNum + } + var ( users []*user_model.User count int64 @@ -73,6 +84,18 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, return } } + if isSitemap { + m := sitemap.NewSitemap() + for _, item := range users { + m.Add(sitemap.URL{URL: item.HTMLURL(), LastMod: item.UpdatedUnix.AsTimePtr()}) + } + ctx.Resp.Header().Set("Content-Type", "text/xml") + if _, err := m.WriteTo(ctx.Resp); err != nil { + log.Error("Failed writing sitemap: %v", err) + } + return + } + ctx.Data["Keyword"] = opts.Keyword ctx.Data["Total"] = count ctx.Data["Users"] = users diff --git a/routers/web/home.go b/routers/web/home.go index 9036814ddfa9d..0c74987ba7c47 100644 --- a/routers/web/home.go +++ b/routers/web/home.go @@ -7,11 +7,18 @@ package web import ( "net/http" + "strconv" + "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/sitemap" + "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/routers/web/auth" "code.gitea.io/gitea/routers/web/user" @@ -59,6 +66,52 @@ func Home(ctx *context.Context) { ctx.HTML(http.StatusOK, tplHome) } +// HomeSitemap renders the main sitemap +func HomeSitemap(ctx *context.Context) { + m := sitemap.NewSitemapIndex() + if !setting.Service.Explore.DisableUsersPage { + _, cnt, err := user_model.SearchUsers(&user_model.SearchUserOptions{ + Type: user_model.UserTypeIndividual, + ListOptions: db.ListOptions{PageSize: 1}, + IsActive: util.OptionalBoolTrue, + Visible: []structs.VisibleType{structs.VisibleTypePublic}, + }) + if err != nil { + ctx.ServerError("SearchUsers", err) + return + } + count := int(cnt) + idx := 1 + for i := 0; i < count; i += setting.UI.SitemapPagingNum { + m.Add(sitemap.URL{URL: setting.AppURL + "explore/users/sitemap-" + strconv.Itoa(idx) + ".xml"}) + idx++ + } + } + + _, cnt, err := repo_model.SearchRepository(&repo_model.SearchRepoOptions{ + ListOptions: db.ListOptions{ + PageSize: 1, + }, + Actor: ctx.Doer, + AllPublic: true, + }) + if err != nil { + ctx.ServerError("SearchRepository", err) + return + } + count := int(cnt) + idx := 1 + for i := 0; i < count; i += setting.UI.SitemapPagingNum { + m.Add(sitemap.URL{URL: setting.AppURL + "explore/repos/sitemap-" + strconv.Itoa(idx) + ".xml"}) + idx++ + } + + ctx.Resp.Header().Set("Content-Type", "text/xml") + if _, err := m.WriteTo(ctx.Resp); err != nil { + log.Error("Failed writing sitemap: %v", err) + } +} + // NotFound render 404 page func NotFound(ctx *context.Context) { ctx.Data["Title"] = "Page Not Found" diff --git a/routers/web/web.go b/routers/web/web.go index 4896bdb1e46f3..80469ef7cd599 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -294,6 +294,7 @@ func RegisterRoutes(m *web.Route) { // Routers. // for health check m.Get("/", Home) + m.Get("/sitemap.xml", ignExploreSignIn, HomeSitemap) m.Group("/.well-known", func() { m.Get("/openid-configuration", auth.OIDCWellKnown) m.Group("", func() { @@ -310,7 +311,9 @@ func RegisterRoutes(m *web.Route) { ctx.Redirect(setting.AppSubURL + "/explore/repos") }) m.Get("/repos", explore.Repos) + m.Get("/repos/sitemap-{idx}.xml", explore.Repos) m.Get("/users", explore.Users) + m.Get("/users/sitemap-{idx}.xml", explore.Users) m.Get("/organizations", explore.Organizations) m.Get("/code", explore.Code) m.Get("/topics/search", explore.TopicSearch) From 2111741a4871a7876f49e5bfde380edaa0f9accf Mon Sep 17 00:00:00 2001 From: zeripath Date: Sat, 25 Jun 2022 20:02:29 +0100 Subject: [PATCH 6/8] Add doctor command to write commit-graphs (#20007) This PR adds a doctor command to write the commit-graphs for the repositories: `gitea doctor --run check-commit-graphs --fix` Signed-off-by: Andrew Thornton --- modules/doctor/mergebase.go | 3 ++ modules/doctor/misc.go | 76 +++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/modules/doctor/mergebase.go b/modules/doctor/mergebase.go index 46369290a13d7..2da91cdcc35f6 100644 --- a/modules/doctor/mergebase.go +++ b/modules/doctor/mergebase.go @@ -30,6 +30,9 @@ func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*rep } func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) error { + if err := git.InitOnceWithSync(ctx); err != nil { + return err + } numRepos := 0 numPRs := 0 numPRsUpdated := 0 diff --git a/modules/doctor/misc.go b/modules/doctor/misc.go index 9bee78303e1a5..24175fcaf4bec 100644 --- a/modules/doctor/misc.go +++ b/modules/doctor/misc.go @@ -189,6 +189,75 @@ func checkDaemonExport(ctx context.Context, logger log.Logger, autofix bool) err return nil } +func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) error { + if err := git.InitOnceWithSync(ctx); err != nil { + return err + } + + numRepos := 0 + numNeedUpdate := 0 + numWritten := 0 + if err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { + numRepos++ + + commitGraphExists := func() (bool, error) { + // Check commit-graph exists + commitGraphFile := path.Join(repo.RepoPath(), `objects/info/commit-graph`) + isExist, err := util.IsExist(commitGraphFile) + if err != nil { + logger.Error("Unable to check if %s exists. Error: %v", commitGraphFile, err) + return false, err + } + + if !isExist { + commitGraphsDir := path.Join(repo.RepoPath(), `objects/info/commit-graphs`) + isExist, err = util.IsExist(commitGraphsDir) + if err != nil { + logger.Error("Unable to check if %s exists. Error: %v", commitGraphsDir, err) + return false, err + } + } + return isExist, nil + } + + isExist, err := commitGraphExists() + if err != nil { + return err + } + if !isExist { + numNeedUpdate++ + if autofix { + if err := git.WriteCommitGraph(ctx, repo.RepoPath()); err != nil { + logger.Error("Unable to write commit-graph in %s. Error: %v", repo.FullName(), err) + return err + } + isExist, err := commitGraphExists() + if err != nil { + return err + } + if isExist { + numWritten++ + logger.Info("Commit-graph written: %s", repo.FullName()) + } else { + logger.Warn("No commit-graph written: %s", repo.FullName()) + } + } + } + return nil + }); err != nil { + logger.Critical("Unable to checkCommitGraph: %v", err) + return err + } + + if autofix { + logger.Info("Wrote commit-graph files for %d of %d repositories.", numWritten, numRepos) + } else { + logger.Info("Checked %d repositories, %d without commit-graphs.", numRepos, numNeedUpdate) + } + + return nil +} + func init() { Register(&Check{ Title: "Check if SCRIPT_TYPE is available", @@ -225,4 +294,11 @@ func init() { Run: checkDaemonExport, Priority: 8, }) + Register(&Check{ + Title: "Check commit-graphs", + Name: "check-commit-graphs", + IsDefault: false, + Run: checkCommitGraph, + Priority: 9, + }) } From a8cdea013d16635c55ef8ef83a0b4219fe646b77 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 25 Jun 2022 21:49:56 +0200 Subject: [PATCH 7/8] Fix remove file on initial comment (#20127) Store the file uuid(which is returned by Gitea in the upload file response) onto the file object, so it can be used for the remove feature to specify this file. Fix #20115 --- web_src/js/features/common-global.js | 3 ++- web_src/js/features/repo-legacy.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index eb59bcbe38f7f..a508db39c5e6a 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -192,7 +192,8 @@ export function initGlobalDropzone() { thumbnailWidth: 480, thumbnailHeight: 480, init() { - this.on('success', (_file, data) => { + this.on('success', (file, data) => { + file.uuid = data.uuid; const input = $(``).val(data.uuid); $dropzone.find('.files').append(input); }); diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index 6cdde6a1e4c27..2bf80d551141b 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -300,6 +300,7 @@ async function onEditContent(event) { thumbnailHeight: 480, init() { this.on('success', (file, data) => { + file.uuid = data.uuid; fileUuidDict[file.uuid] = {submitted: false}; const input = $(``).val(data.uuid); $dropzone.find('.files').append(input); From 711cbcce8d6a193f5738c45861d11cb86b412ec7 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sun, 26 Jun 2022 00:50:12 +0200 Subject: [PATCH 8/8] Use neutral language in comments and docs (#20135) - Replace `his/her` to `their`, as it's more neutral language. --- docs/content/doc/developers/oauth2-provider.md | 4 ++-- docs/content/doc/developers/oauth2-provider.zh-tw.md | 2 +- models/migrations/v154.go | 2 +- models/org.go | 2 +- models/user/follow.go | 2 +- models/user/user.go | 4 ++-- routers/web/auth/password.go | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/content/doc/developers/oauth2-provider.md b/docs/content/doc/developers/oauth2-provider.md index efe78eed97659..ce6e9aad8cbe5 100644 --- a/docs/content/doc/developers/oauth2-provider.md +++ b/docs/content/doc/developers/oauth2-provider.md @@ -41,13 +41,13 @@ To use the Authorization Code Grant as a third party application it is required ## Scopes -Currently Gitea does not support scopes (see [#4300](https://github.com/go-gitea/gitea/issues/4300)) and all third party applications will be granted access to all resources of the user and his/her organizations. +Currently Gitea does not support scopes (see [#4300](https://github.com/go-gitea/gitea/issues/4300)) and all third party applications will be granted access to all resources of the user and their organizations. ## Example **Note:** This example does not use PKCE. -1. Redirect to user to the authorization endpoint in order to get his/her consent for accessing the resources: +1. Redirect to user to the authorization endpoint in order to get their consent for accessing the resources: ```curl https://[YOUR-GITEA-URL]/login/oauth/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI& response_type=code&state=STATE diff --git a/docs/content/doc/developers/oauth2-provider.zh-tw.md b/docs/content/doc/developers/oauth2-provider.zh-tw.md index a2013feac4cf3..179c6342cdd6a 100644 --- a/docs/content/doc/developers/oauth2-provider.zh-tw.md +++ b/docs/content/doc/developers/oauth2-provider.zh-tw.md @@ -46,7 +46,7 @@ Gitea 支援作為 OAuth2 提供者,能讓第三方程式能在使用者同意 **備註:** 此範例未使用 PKCE。 1. 重新導向使用者到 authorization endpoint 以獲得他同意授權存取資源: - + ```curl https://[YOUR-GITEA-URL]/login/oauth/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI& response_type=code&state=STATE diff --git a/models/migrations/v154.go b/models/migrations/v154.go index 11407c30ee140..bb17fb4725a04 100644 --- a/models/migrations/v154.go +++ b/models/migrations/v154.go @@ -30,7 +30,7 @@ func addTimeStamps(x *xorm.Engine) error { return err } - // Follow represents relations of user and his/her followers. + // Follow represents relations of user and their followers. type Follow struct { CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` } diff --git a/models/org.go b/models/org.go index 849c9b985b38a..efcb7183e7669 100644 --- a/models/org.go +++ b/models/org.go @@ -149,7 +149,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error { } } - // Delete member in his/her teams. + // Delete member in their teams. teams, err := organization.GetUserOrgTeams(ctx, org.ID, userID) if err != nil { return err diff --git a/models/user/follow.go b/models/user/follow.go index 6b02486c438c7..5f24f706d16b5 100644 --- a/models/user/follow.go +++ b/models/user/follow.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" ) -// Follow represents relations of user and his/her followers. +// Follow represents relations of user and their followers. type Follow struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"UNIQUE(follow)"` diff --git a/models/user/user.go b/models/user/user.go index f7d457b91b5a5..9460bd38fe428 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -86,7 +86,7 @@ type User struct { PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'argon2'"` // MustChangePassword is an attribute that determines if a user - // is to change his/her password after registration. + // is to change their password after registration. MustChangePassword bool `xorm:"NOT NULL DEFAULT false"` LoginType auth.Type @@ -537,7 +537,7 @@ func GetUserSalt() (string, error) { return hex.EncodeToString(rBytes), nil } -// NewGhostUser creates and returns a fake user for someone has deleted his/her account. +// NewGhostUser creates and returns a fake user for someone has deleted their account. func NewGhostUser() *User { return &User{ ID: -1, diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index 06ccd2e76f7d7..c41c8bd1e505c 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -274,7 +274,7 @@ func MustChangePassword(ctx *context.Context) { ctx.HTML(http.StatusOK, tplMustChangePassword) } -// MustChangePasswordPost response for updating a user's password after his/her +// MustChangePasswordPost response for updating a user's password after their // account was created by an admin func MustChangePasswordPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.MustChangePasswordForm)