2014-04-13 09:57:42 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package user
import (
"fmt"
2014-05-07 20:09:30 +04:00
"github.com/Unknwon/com"
2014-04-13 09:57:42 +04:00
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
2014-05-08 00:51:14 +04:00
"github.com/gogits/gogs/modules/log"
2014-04-13 09:57:42 +04:00
"github.com/gogits/gogs/modules/middleware"
2014-09-14 21:35:22 +04:00
"github.com/gogits/gogs/modules/setting"
2014-04-13 09:57:42 +04:00
)
2014-06-23 07:11:12 +04:00
const (
2014-07-26 08:24:27 +04:00
DASHBOARD base . TplName = "user/dashboard/dashboard"
2014-07-27 07:53:16 +04:00
PULLS base . TplName = "user/dashboard/pulls"
2014-06-25 08:44:48 +04:00
ISSUES base . TplName = "user/issues"
2014-06-23 07:11:12 +04:00
STARS base . TplName = "user/stars"
2014-07-26 08:24:27 +04:00
PROFILE base . TplName = "user/profile"
2014-06-23 07:11:12 +04:00
)
2014-04-13 09:57:42 +04:00
func Dashboard ( ctx * middleware . Context ) {
2014-07-26 08:24:27 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "dashboard" )
ctx . Data [ "PageIsDashboard" ] = true
ctx . Data [ "PageIsNews" ] = true
2014-07-27 07:53:16 +04:00
var ctxUser * models . User
// Check context type.
orgName := ctx . Params ( ":org" )
if len ( orgName ) > 0 {
// Organization.
org , err := models . GetUserByName ( orgName )
if err != nil {
if err == models . ErrUserNotExist {
ctx . Handle ( 404 , "GetUserByName" , err )
} else {
ctx . Handle ( 500 , "GetUserByName" , err )
}
return
}
ctxUser = org
} else {
// Normal user.
ctxUser = ctx . User
collaborates , err := models . GetCollaborativeRepos ( ctxUser . Name )
if err != nil {
ctx . Handle ( 500 , "GetCollaborativeRepos" , err )
return
}
ctx . Data [ "CollaborateCount" ] = len ( collaborates )
ctx . Data [ "CollaborativeRepos" ] = collaborates
}
ctx . Data [ "ContextUser" ] = ctxUser
2014-07-26 10:28:04 +04:00
if err := ctx . User . GetOrganizations ( ) ; err != nil {
2014-07-27 07:53:16 +04:00
ctx . Handle ( 500 , "GetOrganizations" , err )
2014-07-26 10:28:04 +04:00
return
}
2014-07-27 07:53:16 +04:00
ctx . Data [ "Orgs" ] = ctx . User . Orgs
2014-06-25 08:44:48 +04:00
2014-07-27 07:53:16 +04:00
repos , err := models . GetRepositories ( ctxUser . Id , true )
2014-04-13 09:57:42 +04:00
if err != nil {
2014-07-26 08:24:27 +04:00
ctx . Handle ( 500 , "GetRepositories" , err )
2014-04-13 09:57:42 +04:00
return
}
2014-07-26 08:24:27 +04:00
ctx . Data [ "Repos" ] = repos
2014-04-13 09:57:42 +04:00
2014-07-27 07:53:16 +04:00
// Get mirror repositories.
mirrors := make ( [ ] * models . Repository , 0 , len ( repos ) / 2 )
for _ , repo := range repos {
if repo . IsMirror {
2014-08-11 07:11:18 +04:00
if err = repo . GetMirror ( ) ; err != nil {
ctx . Handle ( 500 , "GetMirror: " + repo . Name , err )
return
}
2014-07-27 07:53:16 +04:00
mirrors = append ( mirrors , repo )
}
2014-07-26 10:28:04 +04:00
}
2014-07-27 07:53:16 +04:00
ctx . Data [ "MirrorCount" ] = len ( mirrors )
ctx . Data [ "Mirrors" ] = mirrors
2014-05-12 23:14:22 +04:00
2014-07-27 07:53:16 +04:00
// Get feeds.
actions , err := models . GetFeeds ( ctxUser . Id , 0 , false )
2014-04-13 09:57:42 +04:00
if err != nil {
2014-07-26 08:24:27 +04:00
ctx . Handle ( 500 , "GetFeeds" , err )
2014-04-13 09:57:42 +04:00
return
}
2014-05-09 03:17:43 +04:00
2014-05-24 23:28:31 +04:00
// Check access of private repositories.
2014-05-09 03:17:43 +04:00
feeds := make ( [ ] * models . Action , 0 , len ( actions ) )
for _ , act := range actions {
if act . IsPrivate {
2014-09-16 12:20:32 +04:00
if has , _ := models . HasAccess ( ctx . User . Name , act . RepoUserName + "/" + act . RepoName ,
2014-06-25 08:44:48 +04:00
models . READABLE ) ; ! has {
2014-05-09 03:17:43 +04:00
continue
}
}
feeds = append ( feeds , act )
}
2014-04-13 09:57:42 +04:00
ctx . Data [ "Feeds" ] = feeds
2014-06-23 07:11:12 +04:00
ctx . HTML ( 200 , DASHBOARD )
2014-04-13 09:57:42 +04:00
}
2014-07-27 07:53:16 +04:00
func Pulls ( ctx * middleware . Context ) {
ctx . Data [ "Title" ] = ctx . Tr ( "pull_requests" )
ctx . Data [ "PageIsDashboard" ] = true
ctx . Data [ "PageIsPulls" ] = true
if err := ctx . User . GetOrganizations ( ) ; err != nil {
ctx . Handle ( 500 , "GetOrganizations" , err )
return
}
ctx . Data [ "ContextUser" ] = ctx . User
ctx . HTML ( 200 , PULLS )
}
2014-07-26 08:24:27 +04:00
func Profile ( ctx * middleware . Context ) {
2014-04-13 09:57:42 +04:00
ctx . Data [ "Title" ] = "Profile"
2014-05-24 23:28:31 +04:00
ctx . Data [ "PageIsUserProfile" ] = true
2014-04-13 09:57:42 +04:00
2014-08-07 01:21:24 +04:00
uname := ctx . Params ( ":username" )
// Special handle for FireFox requests favicon.ico.
if uname == "favicon.ico" {
2014-09-20 04:11:34 +04:00
ctx . Redirect ( setting . AppSubUrl + "/img/favicon.png" )
2014-08-07 01:21:24 +04:00
return
}
u , err := models . GetUserByName ( uname )
2014-04-13 09:57:42 +04:00
if err != nil {
2014-05-09 04:00:07 +04:00
if err == models . ErrUserNotExist {
2014-08-07 01:21:24 +04:00
ctx . Handle ( 404 , "GetUserByName" , err )
2014-05-09 04:00:07 +04:00
} else {
2014-08-07 01:21:24 +04:00
ctx . Handle ( 500 , "GetUserByName" , err )
2014-05-09 04:00:07 +04:00
}
2014-04-13 09:57:42 +04:00
return
}
2014-06-28 23:43:25 +04:00
if u . IsOrganization ( ) {
2014-09-20 04:11:34 +04:00
ctx . Redirect ( setting . AppSubUrl + "/org/" + u . Name )
2014-06-28 23:43:25 +04:00
return
}
2014-06-24 03:16:09 +04:00
// For security reason, hide e-mail address for anonymous visitors.
if ! ctx . IsSigned {
u . Email = ""
}
ctx . Data [ "Owner" ] = u
2014-04-13 09:57:42 +04:00
tab := ctx . Query ( "tab" )
ctx . Data [ "TabName" ] = tab
switch tab {
case "activity" :
2014-06-24 03:16:09 +04:00
ctx . Data [ "Feeds" ] , err = models . GetFeeds ( u . Id , 0 , true )
2014-04-13 09:57:42 +04:00
if err != nil {
2014-08-07 01:21:24 +04:00
ctx . Handle ( 500 , "GetFeeds" , err )
2014-04-13 09:57:42 +04:00
return
}
default :
2014-06-24 03:16:09 +04:00
ctx . Data [ "Repos" ] , err = models . GetRepositories ( u . Id , ctx . IsSigned && ctx . User . Id == u . Id )
2014-04-13 09:57:42 +04:00
if err != nil {
2014-08-07 01:21:24 +04:00
ctx . Handle ( 500 , "GetRepositories" , err )
2014-04-13 09:57:42 +04:00
return
}
}
2014-06-23 07:11:12 +04:00
ctx . HTML ( 200 , PROFILE )
2014-04-13 09:57:42 +04:00
}
func Email2User ( ctx * middleware . Context ) {
u , err := models . GetUserByEmail ( ctx . Query ( "email" ) )
if err != nil {
if err == models . ErrUserNotExist {
2014-05-24 23:28:31 +04:00
ctx . Handle ( 404 , "user.Email2User(GetUserByEmail)" , err )
2014-04-13 09:57:42 +04:00
} else {
ctx . Handle ( 500 , "user.Email2User(GetUserByEmail)" , err )
}
return
}
2014-09-20 04:11:34 +04:00
ctx . Redirect ( setting . AppSubUrl + "/user/" + u . Name )
2014-04-13 09:57:42 +04:00
}
const (
TPL_FEED = ` < i class = "icon fa fa-%s" > < / i >
< div class = "info" > < span class = "meta" > % s < / span > < br > % s < / div > `
)
2014-07-26 08:24:27 +04:00
// func Feeds(ctx *middleware.Context, form auth.FeedsForm) {
// actions, err := models.GetFeeds(form.UserId, form.Page*20, false)
// if err != nil {
// ctx.JSON(500, err)
// return
// }
// feeds := make([]string, 0, len(actions))
// for _, act := range actions {
// if act.IsPrivate {
// if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
// models.READABLE); !has {
// continue
// }
// }
// feeds = append(feeds, fmt.Sprintf(TPL_FEED, base.ActionIcon(act.OpType),
// base.TimeSince(act.Created), base.ActionDesc(act)))
// }
// ctx.JSON(200, &feeds)
// }
2014-04-13 09:57:42 +04:00
func Issues ( ctx * middleware . Context ) {
ctx . Data [ "Title" ] = "Your Issues"
2014-05-07 20:09:30 +04:00
viewType := ctx . Query ( "type" )
types := [ ] string { "assigned" , "created_by" }
if ! com . IsSliceContainsStr ( types , viewType ) {
viewType = "all"
}
2014-04-13 09:57:42 +04:00
2014-05-07 20:09:30 +04:00
isShowClosed := ctx . Query ( "state" ) == "closed"
2014-04-13 09:57:42 +04:00
2014-05-07 20:09:30 +04:00
var filterMode int
switch viewType {
case "assigned" :
filterMode = models . FM_ASSIGN
case "created_by" :
filterMode = models . FM_CREATE
2014-04-13 09:57:42 +04:00
}
2014-05-07 20:09:30 +04:00
2014-07-26 08:24:27 +04:00
repoId , _ := com . StrTo ( ctx . Query ( "repoid" ) ) . Int64 ( )
2014-05-07 20:09:30 +04:00
issueStats := models . GetUserIssueStats ( ctx . User . Id , filterMode )
2014-04-13 09:57:42 +04:00
// Get all repositories.
2014-05-24 23:28:31 +04:00
repos , err := models . GetRepositories ( ctx . User . Id , true )
2014-04-13 09:57:42 +04:00
if err != nil {
2014-05-08 00:51:14 +04:00
ctx . Handle ( 500 , "user.Issues(GetRepositories)" , err )
2014-04-13 09:57:42 +04:00
return
}
2014-05-24 23:28:31 +04:00
repoIds := make ( [ ] int64 , 0 , len ( repos ) )
2014-05-07 20:09:30 +04:00
showRepos := make ( [ ] * models . Repository , 0 , len ( repos ) )
for _ , repo := range repos {
if repo . NumIssues == 0 {
continue
2014-04-13 09:57:42 +04:00
}
2014-05-24 23:28:31 +04:00
repoIds = append ( repoIds , repo . Id )
2014-05-07 20:09:30 +04:00
repo . NumOpenIssues = repo . NumIssues - repo . NumClosedIssues
issueStats . AllCount += int64 ( repo . NumOpenIssues )
2014-04-13 09:57:42 +04:00
2014-05-07 20:09:30 +04:00
if isShowClosed {
if repo . NumClosedIssues > 0 {
2014-05-08 00:51:14 +04:00
if filterMode == models . FM_CREATE {
repo . NumClosedIssues = int ( models . GetIssueCountByPoster ( ctx . User . Id , repo . Id , isShowClosed ) )
}
2014-05-07 20:09:30 +04:00
showRepos = append ( showRepos , repo )
}
} else {
if repo . NumOpenIssues > 0 {
2014-05-08 00:51:14 +04:00
if filterMode == models . FM_CREATE {
repo . NumOpenIssues = int ( models . GetIssueCountByPoster ( ctx . User . Id , repo . Id , isShowClosed ) )
}
2014-05-07 20:09:30 +04:00
showRepos = append ( showRepos , repo )
}
2014-04-13 09:57:42 +04:00
}
2014-05-08 00:51:14 +04:00
}
2014-04-13 09:57:42 +04:00
2014-05-24 23:28:31 +04:00
if repoId > 0 {
repoIds = [ ] int64 { repoId }
2014-05-08 00:51:14 +04:00
}
2014-07-26 08:24:27 +04:00
page , _ := com . StrTo ( ctx . Query ( "page" ) ) . Int ( )
2014-05-08 00:51:14 +04:00
// Get all issues.
var ius [ ] * models . IssueUser
switch viewType {
case "assigned" :
fallthrough
case "created_by" :
2014-05-24 23:28:31 +04:00
ius , err = models . GetIssueUserPairsByMode ( ctx . User . Id , repoId , isShowClosed , page , filterMode )
2014-05-08 00:51:14 +04:00
default :
2014-05-24 23:28:31 +04:00
ius , err = models . GetIssueUserPairsByRepoIds ( repoIds , isShowClosed , page )
2014-05-08 00:51:14 +04:00
}
if err != nil {
ctx . Handle ( 500 , "user.Issues(GetAllIssueUserPairs)" , err )
return
}
issues := make ( [ ] * models . Issue , len ( ius ) )
for i := range ius {
issues [ i ] , err = models . GetIssueById ( ius [ i ] . IssueId )
if err != nil {
if err == models . ErrIssueNotExist {
2014-05-14 16:51:04 +04:00
log . Warn ( "user.Issues(GetIssueById #%d): issue not exist" , ius [ i ] . IssueId )
2014-05-08 00:51:14 +04:00
continue
} else {
2014-05-14 16:51:04 +04:00
ctx . Handle ( 500 , fmt . Sprintf ( "user.Issues(GetIssueById #%d)" , ius [ i ] . IssueId ) , err )
2014-05-08 00:51:14 +04:00
return
}
}
issues [ i ] . Repo , err = models . GetRepositoryById ( issues [ i ] . RepoId )
if err != nil {
2014-05-14 16:51:04 +04:00
if err == models . ErrRepoNotExist {
log . Warn ( "user.Issues(GetRepositoryById #%d): repository not exist" , issues [ i ] . RepoId )
continue
} else {
ctx . Handle ( 500 , fmt . Sprintf ( "user.Issues(GetRepositoryById #%d)" , issues [ i ] . RepoId ) , err )
return
}
2014-05-08 00:51:14 +04:00
}
2014-05-14 03:26:13 +04:00
if err = issues [ i ] . Repo . GetOwner ( ) ; err != nil {
2014-05-14 00:37:09 +04:00
ctx . Handle ( 500 , "user.Issues(GetOwner)" , err )
return
}
2014-05-14 16:51:04 +04:00
if err = issues [ i ] . GetPoster ( ) ; err != nil {
2014-05-08 00:51:14 +04:00
ctx . Handle ( 500 , "user.Issues(GetUserById)" , err )
return
}
}
2014-05-07 20:09:30 +04:00
2014-05-24 23:28:31 +04:00
ctx . Data [ "RepoId" ] = repoId
2014-04-13 09:57:42 +04:00
ctx . Data [ "Repos" ] = showRepos
2014-05-08 00:51:14 +04:00
ctx . Data [ "Issues" ] = issues
2014-05-07 20:09:30 +04:00
ctx . Data [ "ViewType" ] = viewType
ctx . Data [ "IssueStats" ] = issueStats
ctx . Data [ "IsShowClosed" ] = isShowClosed
if isShowClosed {
ctx . Data [ "State" ] = "closed"
ctx . Data [ "ShowCount" ] = issueStats . ClosedCount
} else {
ctx . Data [ "ShowCount" ] = issueStats . OpenCount
}
2014-06-23 07:11:12 +04:00
ctx . HTML ( 200 , ISSUES )
2014-04-13 09:57:42 +04:00
}