module main
import veb
import git
fn pick_plural_form(count int, forms []string) string {
if forms.len == 1 {
return forms[0]
}
if forms.len == 2 {
return if count == 1 { forms[0] } else { forms[1] }
}
n := if count < 0 { -count } else { count }
last_two := n % 100
last := n % 10
if last_two >= 11 && last_two <= 14 {
return forms[2]
}
if last == 1 {
return forms[0]
}
if last >= 2 && last <= 4 {
return forms[1]
}
return forms[2]
}
fn format_thousands(n int) string {
s := n.str()
mut neg := false
mut digits := s
if s.starts_with('-') {
neg = true
digits = s[1..]
}
if digits.len <= 3 {
return s
}
mut out := ''
first := digits.len % 3
if first > 0 {
out = digits[..first]
}
for i := first; i < digits.len; i += 3 {
if out.len > 0 {
out += ' '
}
out += digits[i..i + 3]
}
return if neg { '-' + out } else { out }
}
fn format_count(count int, key string, lang Lang) veb.RawHtml {
s := veb.tr(lang.str(), key).trim_space()
forms := s.split('|')
form := pick_plural_form(count, forms)
return veb.RawHtml('${format_thousands(count)} ${form}')
}
fn (mut app App) format_commits_count(repo Repo, branch_name string, lang Lang) veb.RawHtml {
branch := app.find_repo_branch_by_name(repo.id, branch_name)
nr_commits := app.get_repo_commit_count(repo.id, branch.id)
return format_count(nr_commits, 'commits_count', lang)
}
fn (r &Repo) format_nr_branches(lang Lang) veb.RawHtml {
return format_count(r.nr_branches, 'branches_count', lang)
}
fn (r &Repo) format_nr_tags(lang Lang) veb.RawHtml {
return format_count(r.nr_tags, 'tags_count', lang)
}
fn (r &Repo) format_nr_open_prs(lang Lang) veb.RawHtml {
return format_count(r.nr_open_prs, 'prs_count', lang)
}
fn (r &Repo) format_nr_open_issues(lang Lang) veb.RawHtml {
return format_count(r.nr_open_issues, 'issues_count', lang)
}
fn (r &Repo) format_nr_contributors(lang Lang) veb.RawHtml {
return format_count(r.nr_contributors, 'contributors_count', lang)
}
fn (r &Repo) format_nr_topics(lang Lang) veb.RawHtml {
return format_count(r.nr_topics, 'topics_count', lang)
}
fn (r &Repo) format_nr_releases(lang Lang) veb.RawHtml {
return format_count(r.nr_releases, 'releases_count', lang)
}
fn (r &Repo) format_nr_stars(lang Lang) veb.RawHtml {
return format_count(r.nr_stars, 'stars_count', lang)
}
fn (mut app App) format_nr_watchers(repo_id int, lang Lang) veb.RawHtml {
return format_count(app.get_count_repo_watchers(repo_id), 'watchers_count', lang)
}
fn (r &Repo) format_size() veb.RawHtml {
bytes := r.disk_size_bytes()
if bytes <= 0 {
return veb.RawHtml('')
}
num, unit := format_repo_size_parts(bytes)
return veb.RawHtml('${num} ${unit}')
}
fn (r &Repo) disk_size_bytes() i64 {
if r.git_dir == '' {
return 0
}
result := git.Git.exec_in_dir(r.git_dir, ['count-objects', '-v'])
if result.exit_code != 0 {
return 0
}
mut total_kib := i64(0)
for line in result.output.split_into_lines() {
idx := line.index(':') or { continue }
key := line[..idx].trim_space()
if key != 'size' && key != 'size-pack' && key != 'size-garbage' {
continue
}
total_kib += line[idx + 1..].trim_space().i64()
}
return total_kib * 1024
}
fn format_repo_size_parts(bytes i64) (string, string) {
if bytes < 1024 {
return bytes.str(), 'B'
}
if bytes < i64(1024) * 1024 {
return (bytes / 1024).str(), 'KiB'
}
if bytes < i64(1024) * 1024 * 1024 {
return (bytes / (i64(1024) * 1024)).str(), 'MiB'
}
tenths := (bytes * 10) / (i64(1024) * 1024 * 1024)
return '${tenths / 10}.${tenths % 10}', 'GiB'
}