2023-04-29 15:02:29 +03:00
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package templates
import (
"context"
"fmt"
"html/template"
"mime"
"path/filepath"
"strings"
"time"
activities_model "code.gitea.io/gitea/models/activities"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
giturl "code.gitea.io/gitea/modules/git/url"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/svg"
"github.com/editorconfig/editorconfig-core-go/v2"
)
func SortArrow ( normSort , revSort , urlSort string , isDefault bool ) template . HTML {
// if needed
if len ( normSort ) == 0 || len ( urlSort ) == 0 {
return ""
}
if len ( urlSort ) == 0 && isDefault {
// if sort is sorted as default add arrow tho this table header
if isDefault {
return svg . RenderHTML ( "octicon-triangle-down" , 16 )
}
} else {
// if sort arg is in url test if it correlates with column header sort arguments
// the direction of the arrow should indicate the "current sort order", up means ASC(normal), down means DESC(rev)
if urlSort == normSort {
// the table is sorted with this header normal
return svg . RenderHTML ( "octicon-triangle-up" , 16 )
} else if urlSort == revSort {
// the table is sorted with this header reverse
return svg . RenderHTML ( "octicon-triangle-down" , 16 )
}
}
// the table is NOT sorted with this header
return ""
}
// IsMultilineCommitMessage checks to see if a commit message contains multiple lines.
func IsMultilineCommitMessage ( msg string ) bool {
return strings . Count ( strings . TrimSpace ( msg ) , "\n" ) >= 1
}
// Actioner describes an action
type Actioner interface {
GetOpType ( ) activities_model . ActionType
GetActUserName ( ) string
GetRepoUserName ( ) string
GetRepoName ( ) string
GetRepoPath ( ) string
GetRepoLink ( ) string
GetBranch ( ) string
GetContent ( ) string
GetCreate ( ) time . Time
GetIssueInfos ( ) [ ] string
}
// ActionIcon accepts an action operation type and returns an icon class name.
func ActionIcon ( opType activities_model . ActionType ) string {
switch opType {
case activities_model . ActionCreateRepo , activities_model . ActionTransferRepo , activities_model . ActionRenameRepo :
return "repo"
case activities_model . ActionCommitRepo , activities_model . ActionPushTag , activities_model . ActionDeleteTag , activities_model . ActionDeleteBranch :
return "git-commit"
case activities_model . ActionCreateIssue :
return "issue-opened"
case activities_model . ActionCreatePullRequest :
return "git-pull-request"
case activities_model . ActionCommentIssue , activities_model . ActionCommentPull :
return "comment-discussion"
case activities_model . ActionMergePullRequest , activities_model . ActionAutoMergePullRequest :
return "git-merge"
case activities_model . ActionCloseIssue , activities_model . ActionClosePullRequest :
return "issue-closed"
case activities_model . ActionReopenIssue , activities_model . ActionReopenPullRequest :
return "issue-reopened"
case activities_model . ActionMirrorSyncPush , activities_model . ActionMirrorSyncCreate , activities_model . ActionMirrorSyncDelete :
return "mirror"
case activities_model . ActionApprovePullRequest :
return "check"
case activities_model . ActionRejectPullRequest :
return "diff"
case activities_model . ActionPublishRelease :
return "tag"
case activities_model . ActionPullReviewDismissed :
return "x"
default :
return "question"
}
}
// ActionContent2Commits converts action content to push commits
func ActionContent2Commits ( act Actioner ) * repository . PushCommits {
push := repository . NewPushCommits ( )
if act == nil || act . GetContent ( ) == "" {
return push
}
if err := json . Unmarshal ( [ ] byte ( act . GetContent ( ) ) , push ) ; err != nil {
log . Error ( "json.Unmarshal:\n%s\nERROR: %v" , act . GetContent ( ) , err )
}
if push . Len == 0 {
push . Len = len ( push . Commits )
}
return push
}
// MigrationIcon returns a SVG name matching the service an issue/comment was migrated from
func MigrationIcon ( hostname string ) string {
switch hostname {
case "github.com" :
return "octicon-mark-github"
default :
return "gitea-git"
}
}
type remoteAddress struct {
Address string
Username string
Password string
}
func mirrorRemoteAddress ( ctx context . Context , m * repo_model . Repository , remoteName string , ignoreOriginalURL bool ) remoteAddress {
a := remoteAddress { }
remoteURL := m . OriginalURL
if ignoreOriginalURL || remoteURL == "" {
var err error
remoteURL , err = git . GetRemoteAddress ( ctx , m . RepoPath ( ) , remoteName )
if err != nil {
log . Error ( "GetRemoteURL %v" , err )
return a
}
}
u , err := giturl . Parse ( remoteURL )
if err != nil {
log . Error ( "giturl.Parse %v" , err )
return a
}
if u . Scheme != "ssh" && u . Scheme != "file" {
if u . User != nil {
a . Username = u . User . Username ( )
a . Password , _ = u . User . Password ( )
}
u . User = nil
}
a . Address = u . String ( )
return a
}
func FilenameIsImage ( filename string ) bool {
mimeType := mime . TypeByExtension ( filepath . Ext ( filename ) )
return strings . HasPrefix ( mimeType , "image/" )
}
2023-07-04 21:36:08 +03:00
func TabSizeClass ( ec any , filename string ) string {
2023-04-29 15:02:29 +03:00
var (
value * editorconfig . Editorconfig
ok bool
)
if ec != nil {
if value , ok = ec . ( * editorconfig . Editorconfig ) ; ! ok || value == nil {
return "tab-size-8"
}
def , err := value . GetDefinitionForFilename ( filename )
if err != nil {
log . Error ( "tab size class: getting definition for filename: %v" , err )
return "tab-size-8"
}
if def . TabWidth > 0 {
return fmt . Sprintf ( "tab-size-%d" , def . TabWidth )
}
}
return "tab-size-8"
}