Merge branch 'main' into add-file-tree-to-file-view-page

This commit is contained in:
Kerwin Bryant authored and GitHub committed 2025-01-03 13:52:57 +08:00
commit b1b24282ae
266 files changed
+4462 -3471

No files matched your search

+4 -37
View File
@@ -37,8 +37,6 @@ import (
"code.gitea.io/gitea/routers/api/packages/vagrant"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/context"
"github.com/go-chi/chi/v5"
)
func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
@@ -140,39 +138,10 @@ func CommonRoutes() *web.Router {
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/arch", func() {
r.Methods("HEAD,GET", "/repository.key", arch.GetRepositoryKey)
reqPutRepository := web.NewPathProcessor("PUT", "/<repository:*>")
reqGetRepoArchFile := web.NewPathProcessor("HEAD,GET", "/<repository:*>/<architecture>/<filename>")
reqDeleteRepoNameVerArch := web.NewPathProcessor("DELETE", "/<repository:*>/<name>/<version>/<architecture>")
r.Any("*", func(ctx *context.Context) {
chiCtx := chi.RouteContext(ctx.Req.Context())
path := ctx.PathParam("*")
if reqPutRepository.ProcessRequestPath(chiCtx, path) {
reqPackageAccess(perm.AccessModeWrite)(ctx)
if ctx.Written() {
return
}
arch.UploadPackageFile(ctx)
return
}
if reqGetRepoArchFile.ProcessRequestPath(chiCtx, path) {
arch.GetPackageOrRepositoryFile(ctx)
return
}
if reqDeleteRepoNameVerArch.ProcessRequestPath(chiCtx, path) {
reqPackageAccess(perm.AccessModeWrite)(ctx)
if ctx.Written() {
return
}
arch.DeletePackageVersion(ctx)
return
}
ctx.Status(http.StatusNotFound)
r.PathGroup("*", func(g *web.RouterPathGroup) {
g.MatchPath("PUT", "/<repository:*>", reqPackageAccess(perm.AccessModeWrite), arch.UploadPackageFile)
g.MatchPath("HEAD,GET", "/<repository:*>/<architecture>/<filename>", arch.GetPackageOrRepositoryFile)
g.MatchPath("DELETE", "/<repository:*>/<name>/<version>/<architecture>", reqPackageAccess(perm.AccessModeWrite), arch.DeletePackageVersion)
})
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/cargo", func() {
@@ -461,8 +430,6 @@ func CommonRoutes() *web.Router {
r.Post("/api/charts", reqPackageAccess(perm.AccessModeWrite), helm.UploadPackage)
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/maven", func() {
// FIXME: this path design is not right.
// It should be `/.../{groupId}/{artifactId}/{version}`, but not `/.../{groupId}-{artifactId}/{version}`
r.Put("/*", reqPackageAccess(perm.AccessModeWrite), maven.UploadPackageFile)
r.Get("/*", maven.DownloadPackageFile)
r.Head("/*", maven.ProvidePackageFileHeader)
+56 -20
View File
@@ -13,7 +13,7 @@ import (
"errors"
"io"
"net/http"
"path/filepath"
"path"
"regexp"
"sort"
"strconv"
@@ -25,6 +25,7 @@ import (
"code.gitea.io/gitea/modules/log"
packages_module "code.gitea.io/gitea/modules/packages"
maven_module "code.gitea.io/gitea/modules/packages/maven"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/api/packages/helper"
"code.gitea.io/gitea/services/context"
packages_service "code.gitea.io/gitea/services/packages"
@@ -44,7 +45,7 @@ const (
var (
errInvalidParameters = errors.New("request parameters are invalid")
illegalCharacters = regexp.MustCompile(`[\\/:"<>|?\*]`)
illegalCharacters = regexp.MustCompile(`[\\/:"<>|?*]`)
)
func apiError(ctx *context.Context, status int, obj any) {
@@ -85,8 +86,10 @@ func handlePackageFile(ctx *context.Context, serveContent bool) {
func serveMavenMetadata(ctx *context.Context, params parameters) {
// /com/foo/project/maven-metadata.xml[.md5/.sha1/.sha256/.sha512]
packageName := params.GroupID + "-" + params.ArtifactID
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName)
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageName())
if errors.Is(err, util.ErrNotExist) {
pvs, err = packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageNameLegacy())
}
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
@@ -116,10 +119,10 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
latest := pds[len(pds)-1]
// http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
lastModifed := latest.Version.CreatedUnix.AsTime().UTC().Format(http.TimeFormat)
ctx.Resp.Header().Set("Last-Modified", lastModifed)
lastModified := latest.Version.CreatedUnix.AsTime().UTC().Format(http.TimeFormat)
ctx.Resp.Header().Set("Last-Modified", lastModified)
ext := strings.ToLower(filepath.Ext(params.Filename))
ext := strings.ToLower(path.Ext(params.Filename))
if isChecksumExtension(ext) {
var hash []byte
switch ext {
@@ -147,11 +150,12 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
}
func servePackageFile(ctx *context.Context, params parameters, serveContent bool) {
packageName := params.GroupID + "-" + params.ArtifactID
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName, params.Version)
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageName(), params.Version)
if errors.Is(err, util.ErrNotExist) {
pv, err = packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageNameLegacy(), params.Version)
}
if err != nil {
if err == packages_model.ErrPackageNotExist {
if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -161,14 +165,14 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
filename := params.Filename
ext := strings.ToLower(filepath.Ext(filename))
ext := strings.ToLower(path.Ext(filename))
if isChecksumExtension(ext) {
filename = filename[:len(filename)-len(ext)]
}
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, filename, packages_model.EmptyFileKey)
if err != nil {
if err == packages_model.ErrPackageFileNotExist {
if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -238,15 +242,17 @@ func UploadPackageFile(ctx *context.Context) {
return
}
log.Trace("Parameters: %+v", params)
// Ignore the package index /<name>/maven-metadata.xml
if params.IsMeta && params.Version == "" {
ctx.Status(http.StatusOK)
return
}
packageName := params.GroupID + "-" + params.ArtifactID
packageName := params.toInternalPackageName()
if ctx.FormBool("use_legacy_package_name") {
// for testing purpose only
packageName = params.toInternalPackageNameLegacy()
}
// for the same package, only one upload at a time
releaser, err := globallock.Lock(ctx, mavenPkgNameKey(packageName))
@@ -274,13 +280,26 @@ func UploadPackageFile(ctx *context.Context) {
Creator: ctx.Doer,
}
ext := filepath.Ext(params.Filename)
// old maven package uses "groupId-artifactId" as package name, so we need to update to the new format "groupId:artifactId"
legacyPackage, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageNameLegacy())
if err != nil && !errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusInternalServerError, err)
return
} else if legacyPackage != nil {
err = packages_model.UpdatePackageNameByID(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, legacyPackage.ID, packageName)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
}
ext := path.Ext(params.Filename)
// Do not upload checksum files but compare the hashes.
if isChecksumExtension(ext) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version)
if err != nil {
if err == packages_model.ErrPackageNotExist {
if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -289,7 +308,7 @@ func UploadPackageFile(ctx *context.Context) {
}
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, params.Filename[:len(params.Filename)-len(ext)], packages_model.EmptyFileKey)
if err != nil {
if err == packages_model.ErrPackageFileNotExist {
if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -343,7 +362,7 @@ func UploadPackageFile(ctx *context.Context) {
if pvci.Metadata != nil {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version)
if err != nil && err != packages_model.ErrPackageNotExist {
if err != nil && !errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusInternalServerError, err)
return
}
@@ -399,9 +418,26 @@ type parameters struct {
IsMeta bool
}
func (p *parameters) toInternalPackageName() string {
// there cuold be 2 choices: "/" or ":"
// Maven says: "groupId:artifactId:version" in their document: https://maven.apache.org/pom.html#Maven_Coordinates
// but it would be slightly ugly in URL: "/-/packages/maven/group-id%3Aartifact-id"
return p.GroupID + ":" + p.ArtifactID
}
func (p *parameters) toInternalPackageNameLegacy() string {
return p.GroupID + "-" + p.ArtifactID
}
func extractPathParameters(ctx *context.Context) (parameters, error) {
parts := strings.Split(ctx.PathParam("*"), "/")
// formats:
// * /com/group/id/artifactId/maven-metadata.xml[.md5|.sha1|.sha256|.sha512]
// * /com/group/id/artifactId/version-SNAPSHOT/maven-metadata.xml[.md5|.sha1|.sha256|.sha512]
// * /com/group/id/artifactId/version/any-file
// * /com/group/id/artifactId/version-SNAPSHOT/any-file
p := parameters{
Filename: parts[len(parts)-1],
}
+2 -2
View File
@@ -729,7 +729,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
} else {
if !isPlainRule {
if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
@@ -1057,7 +1057,7 @@ func EditBranchProtection(ctx *context.APIContext) {
} else {
if !isPlainRule {
if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
+1 -1
View File
@@ -45,7 +45,7 @@ func CompareDiff(ctx *context.APIContext) {
if ctx.Repo.GitRepo == nil {
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
+1 -1
View File
@@ -29,7 +29,7 @@ func DownloadArchive(ctx *context.APIContext) {
if ctx.Repo.GitRepo == nil {
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
+5 -11
View File
@@ -11,7 +11,6 @@ import (
"fmt"
"io"
"net/http"
"path"
"strings"
"time"
@@ -242,19 +241,14 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn
return nil, nil, nil
}
info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err)
ctx.Error(http.StatusInternalServerError, "GetTreePathLatestCommit", err)
return nil, nil, nil
}
when := &latestCommit.Committer.When
if len(info) == 1 {
// Not Modified
lastModified = &info[0].Commit.Committer.When
}
blob = entry.Blob()
return blob, entry, lastModified
return entry.Blob(), entry, when
}
// GetArchive get archive of a repository
@@ -288,7 +282,7 @@ func GetArchive(ctx *context.APIContext) {
if ctx.Repo.GitRepo == nil {
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
+1 -1
View File
@@ -726,7 +726,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if ctx.Repo.GitRepo == nil && !repo.IsEmpty {
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, repo)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err)
return err
+39
View File
@@ -0,0 +1,39 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package common
import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/context"
)
func PrepareCodeSearch(ctx *context.Context) (ret struct {
Keyword string
Language string
IsFuzzy bool
},
) {
ret.Language = ctx.FormTrim("l")
ret.Keyword = ctx.FormTrim("q")
fuzzyDefault := setting.Indexer.RepoIndexerEnabled
fuzzyAllow := true
if setting.Indexer.RepoType == "bleve" && setting.Indexer.TypeBleveMaxFuzzniess == 0 {
fuzzyDefault = false
fuzzyAllow = false
}
isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(fuzzyDefault)
if isFuzzy && !fuzzyAllow {
ctx.Flash.Info("Fuzzy search is disabled by default due to performance reasons")
isFuzzy = false
}
ctx.Data["IsBleveFuzzyDisabled"] = true
ctx.Data["Keyword"] = ret.Keyword
ctx.Data["Language"] = ret.Language
ctx.Data["IsFuzzy"] = isFuzzy
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
return ret
}
+1 -1
View File
@@ -368,7 +368,7 @@ func handlePullRequestMerging(ctx *gitea_context.PrivateContext, opts *private.H
if err := pull_model.DeleteScheduledAutoMerge(ctx, pr.ID); err != nil && !db.IsErrNotExist(err) {
return fmt.Errorf("DeleteScheduledAutoMerge[%d]: %v", opts.PullRequestID, err)
}
if _, err := pr.SetMerged(ctx); err != nil {
if _, err := pull_service.SetMerged(ctx, pr); err != nil {
return fmt.Errorf("SetMerged failed: %s/%s Error: %v", ownerName, repoName, err)
}
return nil
+1 -1
View File
@@ -27,7 +27,7 @@ func RepoAssignment(ctx *gitea_context.PrivateContext) {
return
}
gitRepo, err := gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, repo)
gitRepo, err := gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo)
if err != nil {
log.Error("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, private.Response{
+1 -1
View File
@@ -94,7 +94,7 @@ func Emails(ctx *context.Context) {
ctx.Data["Emails"] = emails
pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplEmails)
+1 -3
View File
@@ -77,9 +77,7 @@ func Packages(ctx *context.Context) {
ctx.Data["TotalUnreferencedBlobSize"] = totalUnreferencedBlobSize
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
pager.AddParamString("q", query)
pager.AddParamString("type", packageType)
pager.AddParamString("sort", sort)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplPackagesList)
+2 -5
View File
@@ -4,7 +4,6 @@
package admin
import (
"fmt"
"net/http"
"net/url"
"strings"
@@ -84,8 +83,7 @@ func UnadoptedRepos(ctx *context.Context) {
if !doSearch {
pager := context.NewPagination(0, opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("search", fmt.Sprint(doSearch))
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplUnadoptedRepos)
return
@@ -99,8 +97,7 @@ func UnadoptedRepos(ctx *context.Context) {
}
ctx.Data["Dirs"] = repoNames
pager := context.NewPagination(count, opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("search", fmt.Sprint(doSearch))
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplUnadoptedRepos)
}
+2 -5
View File
@@ -47,16 +47,12 @@ func Users(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.users")
ctx.Data["PageIsAdminUsers"] = true
extraParamStrings := map[string]string{}
statusFilterKeys := []string{"is_active", "is_admin", "is_restricted", "is_2fa_enabled", "is_prohibit_login"}
statusFilterMap := map[string]string{}
for _, filterKey := range statusFilterKeys {
paramKey := "status_filter[" + filterKey + "]"
paramVal := ctx.FormString(paramKey)
statusFilterMap[filterKey] = paramVal
if paramVal != "" {
extraParamStrings[paramKey] = paramVal
}
}
sortType := ctx.FormString("sort")
@@ -82,7 +78,6 @@ func Users(ctx *context.Context) {
IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]),
IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]),
IncludeReserved: true, // administrator needs to list all accounts include reserved, bot, remote ones
ExtraParamStrings: extraParamStrings,
}, tplUsers)
}
@@ -318,6 +313,8 @@ func editUserCommon(ctx *context.Context) {
ctx.Data["PageIsAdminUsers"] = true
ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
ctx.Data["DisableGitHooks"] = setting.DisableGitHooks
ctx.Data["DisableImportLocal"] = !setting.ImportLocalPaths
ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice()
ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx)
}
+2 -2
View File
@@ -689,7 +689,7 @@ func Activate(ctx *context.Context) {
}
// TODO: ctx.Doer/ctx.Data["SignedUser"] could be nil or not the same user as the one being activated
user := user_model.VerifyUserActiveCode(ctx, code)
user := user_model.VerifyUserTimeLimitCode(ctx, &user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeActivateAccount}, code)
if user == nil { // if code is wrong
renderActivationPromptMessage(ctx, ctx.Locale.Tr("auth.invalid_code"))
return
@@ -734,7 +734,7 @@ func ActivatePost(ctx *context.Context) {
}
// TODO: ctx.Doer/ctx.Data["SignedUser"] could be nil or not the same user as the one being activated
user := user_model.VerifyUserActiveCode(ctx, code)
user := user_model.VerifyUserTimeLimitCode(ctx, &user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeActivateAccount}, code)
if user == nil { // if code is wrong
renderActivationPromptMessage(ctx, ctx.Locale.Tr("auth.invalid_code"))
return
+1 -1
View File
@@ -113,7 +113,7 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto
}
// Fail early, don't frustrate the user
u := user_model.VerifyUserActiveCode(ctx, code)
u := user_model.VerifyUserTimeLimitCode(ctx, &user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeResetPassword}, code)
if u == nil {
ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", fmt.Sprintf("%s/user/forgot_password", setting.AppSubURL)), true)
return nil, nil
+82 -10
View File
@@ -9,6 +9,10 @@ import (
"strings"
"time"
"code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/services/context"
)
@@ -41,16 +45,85 @@ func FetchActionTest(ctx *context.Context) {
ctx.JSONRedirect("")
}
func Tmpl(ctx *context.Context) {
now := time.Now()
ctx.Data["TimeNow"] = now
ctx.Data["TimePast5s"] = now.Add(-5 * time.Second)
ctx.Data["TimeFuture5s"] = now.Add(5 * time.Second)
ctx.Data["TimePast2m"] = now.Add(-2 * time.Minute)
ctx.Data["TimeFuture2m"] = now.Add(2 * time.Minute)
ctx.Data["TimePast1y"] = now.Add(-1 * 366 * 86400 * time.Second)
ctx.Data["TimeFuture1y"] = now.Add(1 * 366 * 86400 * time.Second)
func prepareMockData(ctx *context.Context) {
if ctx.Req.URL.Path == "/devtest/gitea-ui" {
now := time.Now()
ctx.Data["TimeNow"] = now
ctx.Data["TimePast5s"] = now.Add(-5 * time.Second)
ctx.Data["TimeFuture5s"] = now.Add(5 * time.Second)
ctx.Data["TimePast2m"] = now.Add(-2 * time.Minute)
ctx.Data["TimeFuture2m"] = now.Add(2 * time.Minute)
ctx.Data["TimePast1y"] = now.Add(-1 * 366 * 86400 * time.Second)
ctx.Data["TimeFuture1y"] = now.Add(1 * 366 * 86400 * time.Second)
}
if ctx.Req.URL.Path == "/devtest/commit-sign-badge" {
var commits []*asymkey.SignCommit
mockUsers, _ := db.Find[user_model.User](ctx, user_model.SearchUserOptions{ListOptions: db.ListOptions{PageSize: 1}})
mockUser := mockUsers[0]
commits = append(commits, &asymkey.SignCommit{
Verification: &asymkey.CommitVerification{},
UserCommit: &user_model.UserCommit{
Commit: &git.Commit{ID: git.Sha1ObjectFormat.EmptyObjectID()},
},
})
commits = append(commits, &asymkey.SignCommit{
Verification: &asymkey.CommitVerification{
Verified: true,
Reason: "name / key-id",
SigningUser: mockUser,
SigningKey: &asymkey.GPGKey{KeyID: "12345678"},
TrustStatus: "trusted",
},
UserCommit: &user_model.UserCommit{
User: mockUser,
Commit: &git.Commit{ID: git.Sha1ObjectFormat.EmptyObjectID()},
},
})
commits = append(commits, &asymkey.SignCommit{
Verification: &asymkey.CommitVerification{
Verified: true,
Reason: "name / key-id",
SigningUser: mockUser,
SigningSSHKey: &asymkey.PublicKey{Fingerprint: "aa:bb:cc:dd:ee"},
TrustStatus: "untrusted",
},
UserCommit: &user_model.UserCommit{
User: mockUser,
Commit: &git.Commit{ID: git.Sha1ObjectFormat.EmptyObjectID()},
},
})
commits = append(commits, &asymkey.SignCommit{
Verification: &asymkey.CommitVerification{
Verified: true,
Reason: "name / key-id",
SigningUser: mockUser,
SigningSSHKey: &asymkey.PublicKey{Fingerprint: "aa:bb:cc:dd:ee"},
TrustStatus: "other(unmatch)",
},
UserCommit: &user_model.UserCommit{
User: mockUser,
Commit: &git.Commit{ID: git.Sha1ObjectFormat.EmptyObjectID()},
},
})
commits = append(commits, &asymkey.SignCommit{
Verification: &asymkey.CommitVerification{
Warning: true,
Reason: "gpg.error",
SigningEmail: "test@example.com",
},
UserCommit: &user_model.UserCommit{
User: mockUser,
Commit: &git.Commit{ID: git.Sha1ObjectFormat.EmptyObjectID()},
},
})
ctx.Data["MockCommits"] = commits
}
}
func Tmpl(ctx *context.Context) {
prepareMockData(ctx)
if ctx.Req.Method == "POST" {
_ = ctx.Req.ParseForm()
ctx.Flash.Info("form: "+ctx.Req.Method+" "+ctx.Req.RequestURI+"<br>"+
@@ -60,6 +133,5 @@ func Tmpl(ctx *context.Context) {
)
time.Sleep(2 * time.Second)
}
ctx.HTML(http.StatusOK, templates.TplName("devtest"+path.Clean("/"+ctx.PathParam("sub"))))
}
+7 -15
View File
@@ -11,6 +11,7 @@ import (
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/routers/common"
"code.gitea.io/gitea/services/context"
)
@@ -32,18 +33,10 @@ func Code(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreCode"] = true
language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")
isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["IsFuzzy"] = isFuzzy
ctx.Data["PageIsViewCode"] = true
if keyword == "" {
prepareSearch := common.PrepareCodeSearch(ctx)
if prepareSearch.Keyword == "" {
ctx.HTML(http.StatusOK, tplExploreCode)
return
}
@@ -80,9 +73,9 @@ func Code(ctx *context.Context) {
if (len(repoIDs) > 0) || isAdmin {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
RepoIDs: repoIDs,
Keyword: keyword,
IsKeywordFuzzy: isFuzzy,
Language: language,
Keyword: prepareSearch.Keyword,
IsKeywordFuzzy: prepareSearch.IsFuzzy,
Language: prepareSearch.Language,
Paginator: &db.ListOptions{
Page: page,
PageSize: setting.UI.RepoSearchPagingNum,
@@ -137,8 +130,7 @@ func Code(ctx *context.Context) {
ctx.Data["SearchResultLanguages"] = searchResultLanguages
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("l", language)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplExploreCode)
+1 -20
View File
@@ -4,7 +4,6 @@
package explore
import (
"fmt"
"net/http"
"code.gitea.io/gitea/models/db"
@@ -139,25 +138,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
pager := context.NewPagination(int(count), opts.PageSize, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("topic", fmt.Sprint(topicOnly))
pager.AddParamString("language", language)
pager.AddParamString(relevantReposOnlyParam, fmt.Sprint(opts.OnlyShowRelevant))
if archived.Has() {
pager.AddParamString("archived", fmt.Sprint(archived.Value()))
}
if fork.Has() {
pager.AddParamString("fork", fmt.Sprint(fork.Value()))
}
if mirror.Has() {
pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
}
if template.Has() {
pager.AddParamString("template", fmt.Sprint(template.Value()))
}
if private.Has() {
pager.AddParamString("private", fmt.Sprint(private.Value()))
}
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, opts.TplName)
+1 -4
View File
@@ -120,10 +120,7 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
for paramKey, paramVal := range opts.ExtraParamStrings {
pager.AddParamString(paramKey, paramVal)
}
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplName)
+48 -45
View File
@@ -4,7 +4,6 @@
package org
import (
"fmt"
"net/http"
"path"
"strings"
@@ -13,6 +12,7 @@ import (
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/renderhelper"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
@@ -22,9 +22,7 @@ import (
"code.gitea.io/gitea/services/context"
)
const (
tplOrgHome templates.TplName = "org/home"
)
const tplOrgHome templates.TplName = "org/home"
// Home show organization home page
func Home(ctx *context.Context) {
@@ -111,15 +109,19 @@ func home(ctx *context.Context, viewRepositories bool) {
ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull
ctx.Data["ShowMemberAndTeamTab"] = ctx.Org.IsMember || len(members) > 0
if !prepareOrgProfileReadme(ctx, viewRepositories) {
ctx.Data["PageIsViewRepositories"] = true
prepareResult, err := shared_user.PrepareOrgHeader(ctx)
if err != nil {
ctx.ServerError("PrepareOrgHeader", err)
return
}
var (
repos []*repo_model.Repository
count int64
)
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
// if no profile readme, it still means "view repositories"
isViewOverview := !viewRepositories && prepareOrgProfileReadme(ctx, prepareResult)
ctx.Data["PageIsViewRepositories"] = !isViewOverview
ctx.Data["PageIsViewOverview"] = isViewOverview
ctx.Data["ShowOrgProfileReadmeSelector"] = isViewOverview && prepareResult.ProfilePublicReadmeBlob != nil && prepareResult.ProfilePrivateReadmeBlob != nil
repos, count, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
PageSize: setting.UI.User.RepoPagingNum,
Page: page,
@@ -146,50 +148,51 @@ func home(ctx *context.Context, viewRepositories bool) {
ctx.Data["Total"] = count
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("language", language)
if archived.Has() {
pager.AddParamString("archived", fmt.Sprint(archived.Value()))
}
if fork.Has() {
pager.AddParamString("fork", fmt.Sprint(fork.Value()))
}
if mirror.Has() {
pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
}
if template.Has() {
pager.AddParamString("template", fmt.Sprint(template.Value()))
}
if private.Has() {
pager.AddParamString("private", fmt.Sprint(private.Value()))
}
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplOrgHome)
}
func prepareOrgProfileReadme(ctx *context.Context, viewRepositories bool) bool {
profileDbRepo, profileGitRepo, profileReadme, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose()
ctx.Data["HasProfileReadme"] = profileReadme != nil
func prepareOrgProfileReadme(ctx *context.Context, prepareResult *shared_user.PrepareOrgHeaderResult) bool {
viewAs := ctx.FormString("view_as", util.Iif(ctx.Org.IsMember, "member", "public"))
viewAsMember := viewAs == "member"
if profileGitRepo == nil || profileReadme == nil || viewRepositories {
var profileRepo *repo_model.Repository
var readmeBlob *git.Blob
if viewAsMember {
if prepareResult.ProfilePrivateReadmeBlob != nil {
profileRepo, readmeBlob = prepareResult.ProfilePrivateRepo, prepareResult.ProfilePrivateReadmeBlob
} else {
profileRepo, readmeBlob = prepareResult.ProfilePublicRepo, prepareResult.ProfilePublicReadmeBlob
viewAsMember = false
}
} else {
if prepareResult.ProfilePublicReadmeBlob != nil {
profileRepo, readmeBlob = prepareResult.ProfilePublicRepo, prepareResult.ProfilePublicReadmeBlob
} else {
profileRepo, readmeBlob = prepareResult.ProfilePrivateRepo, prepareResult.ProfilePrivateReadmeBlob
viewAsMember = true
}
}
if readmeBlob == nil {
return false
}
if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
log.Error("failed to GetBlobContent: %v", err)
} else {
rctx := renderhelper.NewRenderContextRepoFile(ctx, profileDbRepo, renderhelper.RepoFileOptions{
CurrentRefPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)),
})
if profileContent, err := markdown.RenderString(rctx, bytes); err != nil {
log.Error("failed to RenderString: %v", err)
} else {
ctx.Data["ProfileReadme"] = profileContent
}
readmeBytes, err := readmeBlob.GetBlobContent(setting.UI.MaxDisplayFileSize)
if err != nil {
log.Error("failed to GetBlobContent for profile %q (view as %q) readme: %v", profileRepo.FullName(), viewAs, err)
return false
}
ctx.Data["PageIsViewOverview"] = true
rctx := renderhelper.NewRenderContextRepoFile(ctx, profileRepo, renderhelper.RepoFileOptions{
CurrentRefPath: path.Join("branch", util.PathEscapeSegments(profileRepo.DefaultBranch)),
})
ctx.Data["ProfileReadmeContent"], err = markdown.RenderString(rctx, readmeBytes)
if err != nil {
log.Error("failed to GetBlobContent for profile %q (view as %q) readme: %v", profileRepo.FullName(), viewAs, err)
return false
}
ctx.Data["IsViewingOrgAsMember"] = viewAsMember
return true
}
+2 -2
View File
@@ -54,9 +54,9 @@ func Members(ctx *context.Context) {
return
}
err = shared_user.RenderOrgHeader(ctx)
_, err = shared_user.PrepareOrgHeader(ctx)
if err != nil {
ctx.ServerError("RenderOrgHeader", err)
ctx.ServerError("PrepareOrgHeader", err)
return
}
+4 -4
View File
@@ -120,7 +120,7 @@ func Projects(ctx *context.Context) {
}
pager := context.NewPagination(int(total), setting.UI.IssuePagingNum, page, numPages)
pager.AddParamString("state", fmt.Sprint(ctx.Data["State"]))
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
@@ -211,7 +211,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
ctx.JSONRedirect(fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), id))
ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.ContextUser, id))
}
// DeleteProject delete a project
@@ -261,7 +261,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["redirect"] = ctx.FormString("redirect")
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
ctx.Data["card_type"] = p.CardType
ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), p.ID)
ctx.Data["CancelLink"] = project_model.ProjectLinkForOrg(ctx.ContextUser, p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -275,7 +275,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["PageIsViewProjects"] = true
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), projectID)
ctx.Data["CancelLink"] = project_model.ProjectLinkForOrg(ctx.ContextUser, projectID)
shared_user.RenderUserHeader(ctx)
+2 -2
View File
@@ -58,9 +58,9 @@ func Teams(ctx *context.Context) {
}
ctx.Data["Teams"] = ctx.Org.Teams
err := shared_user.RenderOrgHeader(ctx)
_, err := shared_user.PrepareOrgHeader(ctx)
if err != nil {
ctx.ServerError("RenderOrgHeader", err)
ctx.ServerError("PrepareOrgHeader", err)
return
}
+1 -5
View File
@@ -6,7 +6,6 @@ package actions
import (
"bytes"
stdCtx "context"
"fmt"
"net/http"
"slices"
"strings"
@@ -262,10 +261,7 @@ func List(ctx *context.Context) {
ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("workflow", workflowID)
pager.AddParamString("actor", fmt.Sprint(actorID))
pager.AddParamString("status", fmt.Sprint(status))
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
+1 -1
View File
@@ -87,7 +87,7 @@ func Branches(ctx *context.Context) {
ctx.Data["CommitStatuses"] = commitStatuses
ctx.Data["DefaultBranchBranch"] = defaultBranch
pager := context.NewPagination(int(branchesCount), pageSize, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplBranch)
}
+3 -11
View File
@@ -101,7 +101,7 @@ func Commits(ctx *context.Context) {
ctx.Data["CommitCount"] = commitsCount
pager := context.NewPagination(int(commitsCount), pageSize, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplCommits)
}
@@ -139,7 +139,6 @@ func Graph(ctx *context.Context) {
if err != nil {
log.Warn("GetCommitGraphsCount error for generate graph exclude prs: %t branches: %s in %-v, Will Ignore branches and try again. Underlying Error: %v", hidePRRefs, branches, ctx.Repo.Repository, err)
realBranches = []string{}
branches = []string{}
graphCommitsCount, err = ctx.Repo.GetCommitGraphsCount(ctx, hidePRRefs, realBranches, files)
if err != nil {
ctx.ServerError("GetCommitGraphsCount", err)
@@ -175,14 +174,7 @@ func Graph(ctx *context.Context) {
ctx.Data["CommitCount"] = commitsCount
paginator := context.NewPagination(int(graphCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
paginator.AddParamString("mode", mode)
paginator.AddParamString("hide-pr-refs", fmt.Sprint(hidePRRefs))
for _, branch := range branches {
paginator.AddParamString("branch", branch)
}
for _, file := range files {
paginator.AddParamString("file", file)
}
paginator.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = paginator
if ctx.FormBool("div-only") {
ctx.HTML(http.StatusOK, tplGraphDiv)
@@ -262,7 +254,7 @@ func FileHistory(ctx *context.Context) {
ctx.Data["CommitCount"] = commitsCount
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplCommits)
}
+5 -11
View File
@@ -5,7 +5,6 @@
package repo
import (
"path"
"time"
git_model "code.gitea.io/gitea/models/git"
@@ -82,7 +81,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
}
func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.Time) {
func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
if err != nil {
if git.IsErrNotExist(err) {
@@ -98,19 +97,14 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.T
return nil, nil
}
info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
if err != nil {
ctx.ServerError("GetCommitsInfo", err)
ctx.ServerError("GetTreePathLatestCommit", err)
return nil, nil
}
lastModified := &latestCommit.Committer.When
if len(info) == 1 {
// Not Modified
lastModified = &info[0].Commit.Committer.When
}
blob = entry.Blob()
return blob, lastModified
return entry.Blob(), lastModified
}
// SingleDownload download a file by repos path
+1 -1
View File
@@ -602,7 +602,7 @@ func updateAttachments(ctx *context.Context, item any, files []string) error {
case *issues_model.Issue:
err = issues_model.UpdateIssueAttachments(ctx, content.ID, files)
case *issues_model.Comment:
err = content.UpdateAttachments(ctx, files)
err = issues_model.UpdateCommentAttachments(ctx, content, files)
default:
return fmt.Errorf("unknown Type: %T", content)
}
+5 -4
View File
@@ -162,10 +162,11 @@ func TestUpdateIssueLabel_Toggle(t *testing.T) {
UpdateIssueLabel(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
for _, issueID := range testCase.IssueIDs {
unittest.AssertExistsIf(t, testCase.ExpectedAdd, &issues_model.IssueLabel{
IssueID: issueID,
LabelID: testCase.LabelID,
})
if testCase.ExpectedAdd {
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: testCase.LabelID})
} else {
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: testCase.LabelID})
}
}
unittest.CheckConsistencyFor(t, &issues_model.Label{})
}
+10 -3
View File
@@ -396,8 +396,15 @@ func NewIssuePost(ctx *context.Context) {
log.Trace("Issue created: %d/%d", repo.ID, issue.ID)
if ctx.FormString("redirect_after_creation") == "project" && projectID > 0 {
ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects/" + strconv.FormatInt(projectID, 10))
} else {
ctx.JSONRedirect(issue.Link())
project, err := project_model.GetProjectByID(ctx, projectID)
if err == nil {
if project.Type == project_model.TypeOrganization {
ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.Repo.Owner, project.ID))
} else {
ctx.JSONRedirect(project_model.ProjectLinkForRepo(repo, project.ID))
}
return
}
}
ctx.JSONRedirect(issue.Link())
}
+1 -3
View File
@@ -4,7 +4,6 @@
package repo
import (
"fmt"
"net/http"
"net/url"
@@ -93,8 +92,7 @@ func Milestones(ctx *context.Context) {
ctx.Data["IsShowClosed"] = isShowClosed
pager := context.NewPagination(int(total), setting.UI.IssuePagingNum, page, 5)
pager.AddParamString("state", fmt.Sprint(ctx.Data["State"]))
pager.AddParamString("q", keyword)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplMilestone)
+1 -2
View File
@@ -70,8 +70,7 @@ func Packages(ctx *context.Context) {
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
pager.AddParamString("q", query)
pager.AddParamString("type", packageType)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplPackagesList)
+4 -4
View File
@@ -115,7 +115,7 @@ func Projects(ctx *context.Context) {
}
pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, numPages)
pager.AddParamString("state", fmt.Sprint(ctx.Data["State"]))
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
@@ -181,7 +181,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
ctx.JSONRedirect(fmt.Sprintf("%s/projects/%d", ctx.Repo.RepoLink, id))
ctx.JSONRedirect(project_model.ProjectLinkForRepo(ctx.Repo.Repository, id))
}
// DeleteProject delete a project
@@ -235,7 +235,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["content"] = p.Description
ctx.Data["card_type"] = p.CardType
ctx.Data["redirect"] = ctx.FormString("redirect")
ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), p.ID)
ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -249,7 +249,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), projectID)
ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, projectID)
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplProjectsNew)
+2 -2
View File
@@ -186,7 +186,7 @@ func Releases(ctx *context.Context) {
numReleases := ctx.Data["NumReleases"].(int64)
pager := context.NewPagination(int(numReleases), listOptions.PageSize, listOptions.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplReleasesList)
}
@@ -240,7 +240,7 @@ func TagsList(ctx *context.Context) {
ctx.Data["TagCount"] = count
pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.Data["PageIsViewCode"] = !ctx.Repo.Repository.UnitEnabled(ctx, unit.TypeReleases)
ctx.HTML(http.StatusOK, tplTagsList)
+22 -21
View File
@@ -148,27 +148,33 @@ func getRepoPrivate(ctx *context.Context) bool {
}
}
// Create render creating repository page
func Create(ctx *context.Context) {
func createCommon(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("new_repo")
// Give default value for template to render.
ctx.Data["Gitignores"] = repo_module.Gitignores
ctx.Data["LabelTemplateFiles"] = repo_module.LabelTemplateFiles
ctx.Data["Licenses"] = repo_module.Licenses
ctx.Data["Readmes"] = repo_module.Readmes
ctx.Data["readme"] = "Default"
ctx.Data["private"] = getRepoPrivate(ctx)
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
ctx.Data["default_branch"] = setting.Repository.DefaultBranch
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
ctx.Data["SupportedObjectFormats"] = git.DefaultFeatures().SupportedObjectFormats
ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
}
// Create render creating repository page
func Create(ctx *context.Context) {
createCommon(ctx)
ctxUser := checkContextUser(ctx, ctx.FormInt64("org"))
if ctx.Written() {
return
}
ctx.Data["ContextUser"] = ctxUser
ctx.Data["readme"] = "Default"
ctx.Data["private"] = getRepoPrivate(ctx)
ctx.Data["default_branch"] = setting.Repository.DefaultBranch
ctx.Data["repo_template_name"] = ctx.Tr("repo.template_select")
templateID := ctx.FormInt64("template_id")
if templateID > 0 {
templateRepo, err := repo_model.GetRepositoryByID(ctx, templateID)
@@ -178,11 +184,6 @@ func Create(ctx *context.Context) {
}
}
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
ctx.Data["SupportedObjectFormats"] = git.DefaultFeatures().SupportedObjectFormats
ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
ctx.HTML(http.StatusOK, tplCreate)
}
@@ -220,16 +221,8 @@ func handleCreateError(ctx *context.Context, owner *user_model.User, err error,
// CreatePost response for creating repository
func CreatePost(ctx *context.Context) {
createCommon(ctx)
form := web.GetForm(ctx).(*forms.CreateRepoForm)
ctx.Data["Title"] = ctx.Tr("new_repo")
ctx.Data["Gitignores"] = repo_module.Gitignores
ctx.Data["LabelTemplateFiles"] = repo_module.LabelTemplateFiles
ctx.Data["Licenses"] = repo_module.Licenses
ctx.Data["Readmes"] = repo_module.Readmes
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
ctxUser := checkContextUser(ctx, form.UID)
if ctx.Written() {
@@ -237,6 +230,14 @@ func CreatePost(ctx *context.Context) {
}
ctx.Data["ContextUser"] = ctxUser
if form.RepoTemplate > 0 {
templateRepo, err := repo_model.GetRepositoryByID(ctx, form.RepoTemplate)
if err == nil && access_model.CheckRepoUnitUser(ctx, templateRepo, ctxUser, unit.TypeCode) {
ctx.Data["repo_template"] = form.RepoTemplate
ctx.Data["repo_template_name"] = templateRepo.Name
}
}
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplCreate)
return
+9 -18
View File
@@ -12,6 +12,7 @@ import (
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/routers/common"
"code.gitea.io/gitea/services/context"
)
@@ -29,18 +30,9 @@ func indexSettingToGitGrepPathspecList() (list []string) {
// Search render repository search page
func Search(ctx *context.Context) {
language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")
isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["IsFuzzy"] = isFuzzy
ctx.Data["PageIsViewCode"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
if keyword == "" {
prepareSearch := common.PrepareCodeSearch(ctx)
if prepareSearch.Keyword == "" {
ctx.HTML(http.StatusOK, tplSearch)
return
}
@@ -57,9 +49,9 @@ func Search(ctx *context.Context) {
var err error
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
RepoIDs: []int64{ctx.Repo.Repository.ID},
Keyword: keyword,
IsKeywordFuzzy: isFuzzy,
Language: language,
Keyword: prepareSearch.Keyword,
IsKeywordFuzzy: prepareSearch.IsFuzzy,
Language: prepareSearch.Language,
Paginator: &db.ListOptions{
Page: page,
PageSize: setting.UI.RepoSearchPagingNum,
@@ -75,9 +67,9 @@ func Search(ctx *context.Context) {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx)
}
} else {
res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{
res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, prepareSearch.Keyword, git.GrepOptions{
ContextLineNumber: 1,
IsFuzzy: isFuzzy,
IsFuzzy: prepareSearch.IsFuzzy,
RefName: git.RefNameFromBranch(ctx.Repo.BranchName).String(), // BranchName should be default branch or the first existing branch
PathspecList: indexSettingToGitGrepPathspecList(),
})
@@ -108,8 +100,7 @@ func Search(ctx *context.Context) {
ctx.Data["SearchResultLanguages"] = searchResultLanguages
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("l", language)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplSearch)
+1 -2
View File
@@ -440,8 +440,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository)
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("action", "_revision")
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
return wikiRepo, entry
+55 -31
View File
@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/context"
)
@@ -102,37 +103,46 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
}
}
func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profileDbRepo *repo_model.Repository, profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
profileDbRepo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ".profile")
if err == nil {
perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer)
if err == nil && !profileDbRepo.IsEmpty && perm.CanRead(unit.TypeCode) {
if profileGitRepo, err = gitrepo.OpenRepository(ctx, profileDbRepo); err != nil {
log.Error("FindUserProfileReadme failed to OpenRepository: %v", err)
} else {
if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil {
log.Error("FindUserProfileReadme failed to GetBranchCommit: %v", err)
} else {
profileReadmeBlob, _ = commit.GetBlobByPath("README.md")
}
}
func FindOwnerProfileReadme(ctx *context.Context, doer *user_model.User, optProfileRepoName ...string) (profileDbRepo *repo_model.Repository, profileReadmeBlob *git.Blob) {
profileRepoName := util.OptionalArg(optProfileRepoName, RepoNameProfile)
profileDbRepo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, profileRepoName)
if err != nil {
if !repo_model.IsErrRepoNotExist(err) {
log.Error("FindOwnerProfileReadme failed to GetRepositoryByName: %v", err)
}
} else if !repo_model.IsErrRepoNotExist(err) {
log.Error("FindUserProfileReadme failed to GetRepositoryByName: %v", err)
return nil, nil
}
return profileDbRepo, profileGitRepo, profileReadmeBlob, func() {
if profileGitRepo != nil {
_ = profileGitRepo.Close()
}
perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer)
if err != nil {
log.Error("FindOwnerProfileReadme failed to GetRepositoryByName: %v", err)
return nil, nil
}
if profileDbRepo.IsEmpty || !perm.CanRead(unit.TypeCode) {
return nil, nil
}
profileGitRepo, err := gitrepo.RepositoryFromRequestContextOrOpen(ctx, profileDbRepo)
if err != nil {
log.Error("FindOwnerProfileReadme failed to OpenRepository: %v", err)
return nil, nil
}
commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch)
if err != nil {
log.Error("FindOwnerProfileReadme failed to GetBranchCommit: %v", err)
return nil, nil
}
profileReadmeBlob, _ = commit.GetBlobByPath("README.md") // no need to handle this error
return profileDbRepo, profileReadmeBlob
}
func RenderUserHeader(ctx *context.Context) {
prepareContextForCommonProfile(ctx)
_, _, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose()
ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
_, profileReadmeBlob := FindOwnerProfileReadme(ctx, ctx.Doer)
ctx.Data["HasUserProfileReadme"] = profileReadmeBlob != nil
}
func LoadHeaderCount(ctx *context.Context) error {
@@ -169,14 +179,28 @@ func LoadHeaderCount(ctx *context.Context) error {
return nil
}
func RenderOrgHeader(ctx *context.Context) error {
if err := LoadHeaderCount(ctx); err != nil {
return err
const (
RepoNameProfilePrivate = ".profile-private"
RepoNameProfile = ".profile"
)
type PrepareOrgHeaderResult struct {
ProfilePublicRepo *repo_model.Repository
ProfilePublicReadmeBlob *git.Blob
ProfilePrivateRepo *repo_model.Repository
ProfilePrivateReadmeBlob *git.Blob
HasOrgProfileReadme bool
}
func PrepareOrgHeader(ctx *context.Context) (result *PrepareOrgHeaderResult, err error) {
if err = LoadHeaderCount(ctx); err != nil {
return nil, err
}
_, _, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose()
ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
return nil
result = &PrepareOrgHeaderResult{}
result.ProfilePublicRepo, result.ProfilePublicReadmeBlob = FindOwnerProfileReadme(ctx, ctx.Doer)
result.ProfilePrivateRepo, result.ProfilePrivateReadmeBlob = FindOwnerProfileReadme(ctx, ctx.Doer, RepoNameProfilePrivate)
result.HasOrgProfileReadme = result.ProfilePublicReadmeBlob != nil || result.ProfilePrivateReadmeBlob != nil
ctx.Data["HasOrgProfileReadme"] = result.HasOrgProfileReadme // many pages need it to show the "overview" tab
return result, nil
}
+7 -16
View File
@@ -11,6 +11,7 @@ import (
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/routers/common"
shared_user "code.gitea.io/gitea/routers/web/shared/user"
"code.gitea.io/gitea/services/context"
)
@@ -34,20 +35,11 @@ func CodeSearch(ctx *context.Context) {
}
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["Title"] = ctx.Tr("explore.code")
language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")
isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["IsFuzzy"] = isFuzzy
ctx.Data["IsCodePage"] = true
if keyword == "" {
prepareSearch := common.PrepareCodeSearch(ctx)
if prepareSearch.Keyword == "" {
ctx.HTML(http.StatusOK, tplUserCode)
return
}
@@ -77,9 +69,9 @@ func CodeSearch(ctx *context.Context) {
if len(repoIDs) > 0 {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
RepoIDs: repoIDs,
Keyword: keyword,
IsKeywordFuzzy: isFuzzy,
Language: language,
Keyword: prepareSearch.Keyword,
IsKeywordFuzzy: prepareSearch.IsFuzzy,
Language: prepareSearch.Language,
Paginator: &db.ListOptions{
Page: page,
PageSize: setting.UI.RepoSearchPagingNum,
@@ -121,8 +113,7 @@ func CodeSearch(ctx *context.Context) {
ctx.Data["SearchResultLanguages"] = searchResultLanguages
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("l", language)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplUserCode)
+2 -5
View File
@@ -139,7 +139,7 @@ func Dashboard(ctx *context.Context) {
ctx.Data["Feeds"] = feeds
pager := context.NewPagination(int(count), setting.UI.FeedPagingNum, page, 5)
pager.AddParamString("date", date)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplDashboard)
@@ -330,10 +330,7 @@ func Milestones(ctx *context.Context) {
ctx.Data["IsShowClosed"] = isShowClosed
pager := context.NewPagination(pagerCount, setting.UI.IssuePagingNum, page, 5)
pager.AddParamString("q", keyword)
pager.AddParamString("repos", reposQuery)
pager.AddParamString("sort", sortType)
pager.AddParamString("state", fmt.Sprint(ctx.Data["State"]))
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplMilestones)
+3 -19
View File
@@ -173,7 +173,7 @@ func getNotifications(ctx *context.Context) {
ctx.Data["Status"] = status
ctx.Data["Notifications"] = notifications
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
}
@@ -357,8 +357,7 @@ func NotificationSubscriptions(ctx *context.Context) {
ctx.Redirect(fmt.Sprintf("/notifications/subscriptions?page=%d", pager.Paginater.Current()))
return
}
pager.AddParamString("sort", sortType)
pager.AddParamString("state", state)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplNotificationSubscriptions)
@@ -446,22 +445,7 @@ func NotificationWatching(ctx *context.Context) {
// redirect to last page if request page is more than total pages
pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
pager.SetDefaultParams(ctx)
if archived.Has() {
pager.AddParamString("archived", fmt.Sprint(archived.Value()))
}
if fork.Has() {
pager.AddParamString("fork", fmt.Sprint(fork.Value()))
}
if mirror.Has() {
pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
}
if template.Has() {
pager.AddParamString("template", fmt.Sprint(template.Value()))
}
if private.Has() {
pager.AddParamString("private", fmt.Sprint(private.Value()))
}
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.Data["Status"] = 2
+2 -11
View File
@@ -128,8 +128,7 @@ func ListPackages(ctx *context.Context) {
}
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
pager.AddParamString("q", query)
pager.AddParamString("type", packageType)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplPackagesList)
@@ -348,11 +347,6 @@ func ListPackageVersions(ctx *context.Context) {
ctx.Data["Query"] = query
ctx.Data["Sort"] = sort
pagerParams := map[string]string{
"q": query,
"sort": sort,
}
var (
total int64
pvs []*packages_model.PackageVersion
@@ -361,7 +355,6 @@ func ListPackageVersions(ctx *context.Context) {
case packages_model.TypeContainer:
tagged := ctx.FormTrim("tagged")
pagerParams["tagged"] = tagged
ctx.Data["Tagged"] = tagged
pvs, total, err = container_model.SearchImageTags(ctx, &container_model.ImageTagsSearchOptions{
@@ -407,9 +400,7 @@ func ListPackageVersions(ctx *context.Context) {
}
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
for k, v := range pagerParams {
pager.AddParamString(k, v)
}
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplPackageVersionList)
+3 -4
View File
@@ -74,8 +74,7 @@ func userProfile(ctx *context.Context) {
ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
}
profileDbRepo, _ /*profileGitRepo*/, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose()
profileDbRepo, profileReadmeBlob := shared_user.FindOwnerProfileReadme(ctx, ctx.Doer)
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
prepareUserProfileTabData(ctx, showPrivate, profileDbRepo, profileReadmeBlob)
@@ -96,7 +95,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
}
}
ctx.Data["TabName"] = tab
ctx.Data["HasProfileReadme"] = profileReadme != nil
ctx.Data["HasUserProfileReadme"] = profileReadme != nil
page := ctx.FormInt("page")
if page <= 0 {
@@ -254,7 +253,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
if profileContent, err := markdown.RenderString(rctx, bytes); err != nil {
log.Error("failed to RenderString: %v", err)
} else {
ctx.Data["ProfileReadme"] = profileContent
ctx.Data["ProfileReadmeContent"] = profileContent
}
}
case "organizations":
+2 -2
View File
@@ -222,7 +222,7 @@ func Organization(ctx *context.Context) {
ctx.Data["Orgs"] = orgs
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplSettingsOrganization)
}
@@ -329,7 +329,7 @@ func Repos(ctx *context.Context) {
}
ctx.Data["ContextUser"] = ctxUser
pager := context.NewPagination(count, opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplSettingsRepositories)
}