summaryrefslogtreecommitdiffstats
path: root/models/repo_list.go
diff options
context:
space:
mode:
authorLauris BH <lauris@nix.lv>2020-02-11 11:34:17 +0200
committerGitHub <noreply@github.com>2020-02-11 11:34:17 +0200
commitad2642a8aac9facb217a8471df1d3e00f1214e92 (patch)
treeea198b2b3130d22bb60886b6ba0a1df352f160ff /models/repo_list.go
parent37892be63580e40ced80e041ff2e7dabb2e80866 (diff)
downloadgitea-ad2642a8aac9facb217a8471df1d3e00f1214e92.tar.gz
gitea-ad2642a8aac9facb217a8471df1d3e00f1214e92.zip
Language statistics bar for repositories (#8037)
* Implementation for calculating language statistics Impement saving code language statistics to database Implement rendering langauge stats Add primary laguage to show in repository list Implement repository stats indexer queue Add indexer test Refactor to use queue module * Do not timeout for queues
Diffstat (limited to 'models/repo_list.go')
-rw-r--r--models/repo_list.go31
1 files changed, 25 insertions, 6 deletions
diff --git a/models/repo_list.go b/models/repo_list.go
index d3a113d26c..6385de4b32 100644
--- a/models/repo_list.go
+++ b/models/repo_list.go
@@ -46,11 +46,14 @@ func (repos RepositoryList) loadAttributes(e Engine) error {
return nil
}
- // Load owners.
set := make(map[int64]struct{})
+ repoIDs := make([]int64, len(repos))
for i := range repos {
set[repos[i].OwnerID] = struct{}{}
+ repoIDs[i] = repos[i].ID
}
+
+ // Load owners.
users := make(map[int64]*User, len(set))
if err := e.
Where("id > 0").
@@ -61,6 +64,25 @@ func (repos RepositoryList) loadAttributes(e Engine) error {
for i := range repos {
repos[i].Owner = users[repos[i].OwnerID]
}
+
+ // Load primary language.
+ stats := make(LanguageStatList, 0, len(repos))
+ if err := e.
+ Where("`is_primary` = ? AND `language` != ?", true, "other").
+ In("`repo_id`", repoIDs).
+ Find(&stats); err != nil {
+ return fmt.Errorf("find primary languages: %v", err)
+ }
+ stats.loadAttributes()
+ for i := range repos {
+ for _, st := range stats {
+ if st.RepoID == repos[i].ID {
+ repos[i].PrimaryLanguage = st
+ break
+ }
+ }
+ }
+
return nil
}
@@ -119,7 +141,6 @@ type SearchRepoOptions struct {
OrderBy SearchOrderBy
Private bool // Include private repositories in results
StarredByID int64
- IsProfile bool
AllPublic bool // Include also all public repositories of users and public organisations
AllLimited bool // Include also all public repositories of limited organisations
// None -> include collaborative AND non-collaborative
@@ -306,10 +327,8 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
return nil, 0, fmt.Errorf("Repo: %v", err)
}
- if !opts.IsProfile {
- if err = repos.loadAttributes(sess); err != nil {
- return nil, 0, fmt.Errorf("LoadAttributes: %v", err)
- }
+ if err = repos.loadAttributes(sess); err != nil {
+ return nil, 0, fmt.Errorf("LoadAttributes: %v", err)
}
return repos, count, nil
ackground-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
{{template "base/head" .}}
<div class="dashboard issues">
	{{template "user/dashboard/navbar" .}}
	<div class="ui container">
		<div class="ui grid">
			<div class="four wide column">
				<div class="ui secondary vertical filter menu">
					<a class="{{if eq .ViewType "your_repositories"}}ui basic blue button{{end}} item" href="{{.Link}}?type=your_repositories&repo={{.RepoID}}&sort={{$.SortType}}&state={{.State}}">
						{{.i18n.Tr "home.issues.in_your_repos"}}
						<strong class="ui right">{{.IssueStats.YourRepositoriesCount}}</strong>
					</a>
					{{if not .ContextUser.IsOrganization}}
						<a class="{{if eq .ViewType "assigned"}}ui basic blue button{{end}} item" href="{{.Link}}?type=assigned&repo={{.RepoID}}&sort={{$.SortType}}&state={{.State}}">
							{{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}}
							<strong class="ui right">{{.IssueStats.AssignCount}}</strong>
						</a>
						<a class="{{if eq .ViewType "created_by"}}ui basic blue button{{end}} item" href="{{.Link}}?type=created_by&repo={{.RepoID}}&sort={{$.SortType}}&state={{.State}}">
							{{.i18n.Tr "repo.issues.filter_type.created_by_you"}}
							<strong class="ui right">{{.IssueStats.CreateCount}}</strong>
						</a>
					{{end}}
					<div class="ui divider"></div>
					{{range .Repos}}
						<a class="{{if eq $.RepoID .ID}}ui basic blue button{{end}} repo name item" href="{{$.Link}}?type={{$.ViewType}}{{if not (eq $.RepoID .ID)}}&repo={{.ID}}{{end}}&sort={{$.SortType}}&state={{$.State}}">
							<span class="text truncate">{{.FullName}}</span>
							<div class="floating ui {{if $.IsShowClosed}}red{{else}}green{{end}} label">{{if $.IsShowClosed}}{{if $.PageIsPulls}}{{.NumClosedPulls}}{{else}}{{.NumClosedIssues}}{{end}}{{else}}{{if $.PageIsPulls}}{{.NumOpenPulls}}{{else}}{{.NumOpenIssues}}{{end}}{{end}}</div>
						</a>
					{{end}}
				</div>
			</div>
			<div class="twelve wide column content">
				<div class="ui tiny basic status buttons">
					<a class="ui {{if not .IsShowClosed}}green active{{end}} basic button" href="{{.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort={{$.SortType}}&state=open">
						<i class="octicon octicon-issue-opened"></i>
						{{.i18n.Tr "repo.issues.open_tab" .IssueStats.OpenCount}}
					</a>
					<a class="ui {{if .IsShowClosed}}red active{{end}} basic button" href="{{.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort={{$.SortType}}&state=closed">
						<i class="octicon octicon-issue-closed"></i>
						{{.i18n.Tr "repo.issues.close_tab" .IssueStats.ClosedCount}}
					</a>
				</div>
				<div class="ui right floated secondary filter menu">
					<!-- Sort -->
					<div class="ui dropdown type jump item">
						<span class="text">
							{{.i18n.Tr "repo.issues.filter_sort"}}
							<i class="dropdown icon"></i>
						</span>
						<div class="menu">
							<a class="{{if or (eq .SortType "latest") (not .SortType)}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort=latest&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a>
							<a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort=oldest&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a>
							<a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort=recentupdate&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a>
							<a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort=leastupdate&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a>
							<a class="{{if eq .SortType "mostcomment"}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort=mostcomment&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_sort.mostcomment"}}</a>
							<a class="{{if eq .SortType "leastcomment"}}active{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&repo={{.RepoID}}&sort=leastcomment&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_sort.leastcomment"}}</a>
						</div>
					</div>
				</div>

				<div class="issue list">
					{{range .Issues}}
						{{ $timeStr:= TimeSince .Created $.Lang }}
						<li class="item">
							<div class="ui label">{{if not $.RepoID}}{{.Repo.FullName}}{{end}}#{{.Index}}</div>
							<a class="title has-emoji" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Title}}</a>

							{{range .Labels}}
								<a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}">{{.Name}}</a>
							{{end}}

							{{if .NumComments}}
								<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>
							{{end}}

							<p class="desc">
								{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.HomeLink .Poster.Name | Safe}}
								{{if .Assignee}}
									<a class="ui right assignee poping up" href="{{.Assignee.HomeLink}}" data-content="{{.Assignee.Name}}" data-variation="inverted" data-position="left center">
										<img class="ui avatar image" src="{{.Assignee.RelAvatarLink}}">
									</a>
								{{end}}
							</p>
						</li>
					{{end}}

					{{with .Page}}
						{{if gt .TotalPages 1}}
							<div class="center page buttons">
								<div class="ui borderless pagination menu">
									<a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.Link}}?type={{$.ViewType}}&repo={{$.RepoID}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}&page={{.Previous}}"{{end}}>
										<i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
									</a>
									{{range .Pages}}
										{{if eq .Num -1}}
											<a class="disabled item">...</a>
										{{else}}
											<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.Link}}?type={{$.ViewType}}&repo={{$.RepoID}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}&page={{.Num}}"{{end}}>{{.Num}}</a>
										{{end}}
									{{end}}
									<a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.Link}}?type={{$.ViewType}}&repo={{$.RepoID}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}&page={{.Next}}"{{end}}>
										{{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
									</a>
								</div>
							</div>
						{{end}}
					{{end}}
				</div>
			</div>
		</div>
	</div>
</div>
{{template "base/footer" .}}