Browse Source

Move repo DOI checks to contexter

Check if a repository is registered when building the repository context
instead of just on the front page root dir listing.
This way, the DOI badge is rendered in the header on all pages of a
repository: Non-root directories, file views, issues, pull requests,
wiki pages, etc.
Achilleas Koutsou 5 năm trước cách đây
mục cha
commit
4ae9fb6fc8

+ 87 - 0
internal/context/context_gin.go

@@ -5,8 +5,11 @@ import (
 	"path"
 	"path"
 	"strings"
 	"strings"
 
 
+	"github.com/G-Node/git-module"
+	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/tool"
 	"github.com/G-Node/gogs/internal/tool"
+	"github.com/G-Node/libgin/libgin"
 	"github.com/unknwon/com"
 	"github.com/unknwon/com"
 	log "gopkg.in/clog.v1"
 	log "gopkg.in/clog.v1"
 )
 )
@@ -59,3 +62,87 @@ func readNotice(c *Context) {
 	c.Data["NoticeTitle"] = noticetext[0]
 	c.Data["NoticeTitle"] = noticetext[0]
 	c.Data["NoticeMessage"] = noticetext[1]
 	c.Data["NoticeMessage"] = noticetext[1]
 }
 }
+
+// getRepoDOI returns the DOI for the repository based on the following rules:
+// - if the repository belongs to the DOI user and has a tag that matches the
+// DOI prefix, returns the tag.
+// - if the repo is forked by the DOI user, check the DOI fork for the tag as above.
+// - if the repo is forked by the DOI user and the fork doesn't have a tag,
+// returns the (old-style) calculated DOI, based on the hash of the repository
+// path.
+// - An empty string is returned if it is not not forked by the DOI user.
+// If an error occurs at any point, returns an empty string (the error is logged).
+// Tag retrieval is allowed to fail and falls back on the hashed DOI method.
+func getRepoDOI(c *Context) string {
+	repo := c.Repo.Repository
+	var doiFork *db.Repository
+	if repo.Owner.Name == "doi" {
+		doiFork = repo
+	} else {
+		if forks, err := repo.GetForks(); err == nil {
+			for _, fork := range forks {
+				if fork.MustOwner().Name == "doi" {
+					doiFork = fork
+					break
+				}
+			}
+		} else {
+			log.Error(2, "failed to get forks for repository %q (%d): %v", repo.FullName(), repo.ID, err)
+			return ""
+		}
+	}
+
+	if doiFork == nil {
+		// not owned or forked by DOI, so not registered
+		return ""
+	}
+
+	// check the DOI fork for a tag that matches our DOI prefix
+	// if multiple exit, get the latest one
+	doiBase := setting.DOI.Base
+
+	doiForkGit, err := git.OpenRepository(doiFork.RepoPath())
+	if err != nil {
+		log.Error(2, "failed to open git repository at %q (%d): %v", doiFork.RepoPath(), doiFork.ID, err)
+		return ""
+	}
+	if tags, err := doiForkGit.GetTags(); err == nil {
+		var latestTime int64
+		latestTag := ""
+		for _, tagName := range tags {
+			if strings.Contains(tagName, doiBase) {
+				tag, err := doiForkGit.GetTag(tagName)
+				if err != nil {
+					// log the error and continue to the next tag
+					log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
+					continue
+				}
+				commit, err := tag.Commit()
+				if err != nil {
+					// log the error and continue to the next tag
+					log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
+					continue
+				}
+				commitTime := commit.Committer.When.Unix()
+				if commitTime > latestTime {
+					latestTag = tagName
+					latestTime = commitTime
+				}
+				return latestTag
+			}
+		}
+	} else {
+		// this shouldn't happen even if there are no tags
+		// log the error, but fall back to the old method anyway
+		log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path, err)
+	}
+
+	// Has DOI fork but isn't tagged: return old style has-based DOI
+	repoPath := repo.FullName()
+	// get base repo name if it's a DOI fork
+	if c.Repo.Repository.IsFork && c.Repo.Owner.Name == "doi" {
+		repoPath = c.Repo.Repository.BaseRepo.FullName()
+	}
+	uuid := libgin.RepoPathToUUID(repoPath)
+	return doiBase + uuid[:6]
+}

+ 8 - 4
internal/context/repo.go

@@ -6,17 +6,16 @@ package context
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"io/ioutil"
-	"strings"
-
 	"gopkg.in/editorconfig/editorconfig-core-go.v1"
 	"gopkg.in/editorconfig/editorconfig-core-go.v1"
 	"gopkg.in/macaron.v1"
 	"gopkg.in/macaron.v1"
+	"io/ioutil"
+	"strings"
 
 
 	"github.com/G-Node/git-module"
 	"github.com/G-Node/git-module"
-
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/db/errors"
 	"github.com/G-Node/gogs/internal/db/errors"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/setting"
+	"github.com/G-Node/libgin/libgin"
 )
 )
 
 
 type PullRequest struct {
 type PullRequest struct {
@@ -270,6 +269,11 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 		c.Data["CommitID"] = c.Repo.CommitID
 		c.Data["CommitID"] = c.Repo.CommitID
 
 
 		c.Data["IsGuest"] = !c.Repo.HasAccess()
 		c.Data["IsGuest"] = !c.Repo.HasAccess()
+
+		if doi := getRepoDOI(c); doi != "" && libgin.IsRegisteredDOI(doi) {
+			c.Data["DOI"] = doi
+		}
+
 	}
 	}
 }
 }
 
 

+ 3 - 90
internal/route/repo/repo_gin.go

@@ -14,7 +14,6 @@ import (
 
 
 	"github.com/G-Node/git-module"
 	"github.com/G-Node/git-module"
 	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/context"
-	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/tool"
 	"github.com/G-Node/gogs/internal/tool"
 	"github.com/G-Node/libgin/libgin"
 	"github.com/G-Node/libgin/libgin"
@@ -94,17 +93,15 @@ func readDataciteFile(entry *git.TreeEntry, c *context.Context) {
 		return
 		return
 	}
 	}
 	c.Data["DOIInfo"] = &doiInfo
 	c.Data["DOIInfo"] = &doiInfo
-
-	if doi := getRepoDOI(c); doi != "" && libgin.IsRegisteredDOI(doi) {
-		c.Data["DOI"] = doi
-	}
-
 	c.Data["IsDOIReady"] = isDOIReady(c)
 	c.Data["IsDOIReady"] = isDOIReady(c)
 }
 }
 
 
 // True if repository is not Private, is not registered, or is registered and
 // True if repository is not Private, is not registered, or is registered and
 // has changes.
 // has changes.
 func isDOIReady(c *context.Context) bool {
 func isDOIReady(c *context.Context) bool {
+	if hasDC, ok := c.Data["HasDatacite"]; !ok || !hasDC.(bool) {
+		return false
+	}
 	dbrepo := c.Repo.Repository
 	dbrepo := c.Repo.Repository
 	gitrepo := c.Repo.GitRepo
 	gitrepo := c.Repo.GitRepo
 
 
@@ -139,90 +136,6 @@ func isDOIReady(c *context.Context) bool {
 	return !dbrepo.IsPrivate && !headIsRegistered
 	return !dbrepo.IsPrivate && !headIsRegistered
 }
 }
 
 
-// getRepoDOI returns the DOI for the repository based on the following rules:
-// - if the repository belongs to the DOI user and has a tag that matches the
-// DOI prefix, returns the tag.
-// - if the repo is forked by the DOI user, check the DOI fork for the tag as above.
-// - if the repo is forked by the DOI user and the fork doesn't have a tag,
-// returns the (old-style) calculated DOI, based on the hash of the repository
-// path.
-// - An empty string is returned if it is not not forked by the DOI user.
-// If an error occurs at any point, returns an empty string (the error is logged).
-// Tag retrieval is allowed to fail and falls back on the hashed DOI method.
-func getRepoDOI(c *context.Context) string {
-	repo := c.Repo.Repository
-	var doiFork *db.Repository
-	if repo.Owner.Name == "doi" {
-		doiFork = repo
-	} else {
-		if forks, err := repo.GetForks(); err == nil {
-			for _, fork := range forks {
-				if fork.MustOwner().Name == "doi" {
-					doiFork = fork
-					break
-				}
-			}
-		} else {
-			log.Error(2, "failed to get forks for repository %q (%d): %v", repo.FullName(), repo.ID, err)
-			return ""
-		}
-	}
-
-	if doiFork == nil {
-		// not owned or forked by DOI, so not registered
-		return ""
-	}
-
-	// check the DOI fork for a tag that matches our DOI prefix
-	// if multiple exit, get the latest one
-	doiBase := setting.DOI.Base
-
-	doiForkGit, err := git.OpenRepository(doiFork.RepoPath())
-	if err != nil {
-		log.Error(2, "failed to open git repository at %q (%d): %v", doiFork.RepoPath(), doiFork.ID, err)
-		return ""
-	}
-	if tags, err := doiForkGit.GetTags(); err == nil {
-		var latestTime int64
-		latestTag := ""
-		for _, tagName := range tags {
-			if strings.Contains(tagName, doiBase) {
-				tag, err := doiForkGit.GetTag(tagName)
-				if err != nil {
-					// log the error and continue to the next tag
-					log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
-					continue
-				}
-				commit, err := tag.Commit()
-				if err != nil {
-					// log the error and continue to the next tag
-					log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
-					continue
-				}
-				commitTime := commit.Committer.When.Unix()
-				if commitTime > latestTime {
-					latestTag = tagName
-					latestTime = commitTime
-				}
-				return latestTag
-			}
-		}
-	} else {
-		// this shouldn't happen even if there are no tags
-		// log the error, but fall back to the old method anyway
-		log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path, err)
-	}
-
-	// Has DOI fork but isn't tagged: return old style has-based DOI
-	repoPath := repo.FullName()
-	// get base repo name if it's a DOI fork
-	if c.Repo.Repository.IsFork && c.Repo.Owner.Name == "doi" {
-		repoPath = c.Repo.Repository.BaseRepo.FullName()
-	}
-	uuid := libgin.RepoPathToUUID(repoPath)
-	return doiBase + uuid[:6]
-}
-
 // resolveAnnexedContent takes a buffer with the contents of a git-annex
 // resolveAnnexedContent takes a buffer with the contents of a git-annex
 // pointer file and an io.Reader for the underlying file and returns the
 // pointer file and an io.Reader for the underlying file and returns the
 // corresponding buffer and a bufio.Reader for the underlying content file.
 // corresponding buffer and a bufio.Reader for the underlying content file.