mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-03 16:59:05 +01:00
merge
This commit is contained in:
commit
a30e72323d
40 changed files with 1416 additions and 479 deletions
|
@ -5,7 +5,7 @@ Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language.
|
|||
|
||||
Since we choose to use pure Go implmentation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Max OS X, and Windows with **ZERO** dependency.
|
||||
|
||||
##### Current version: 0.0.8 Alpha
|
||||
##### Current version: 0.0.9 Alpha
|
||||
|
||||
## Purpose
|
||||
|
||||
|
|
3
bee.json
3
bee.json
|
@ -12,7 +12,8 @@
|
|||
"models": "",
|
||||
"others": [
|
||||
"modules",
|
||||
"$GOPATH/src/github.com/gogits/binding"
|
||||
"$GOPATH/src/github.com/gogits/binding",
|
||||
"$GOPATH/src/github.com/gogits/git"
|
||||
]
|
||||
},
|
||||
"cmd_args": [
|
||||
|
|
|
@ -7,6 +7,7 @@ LANG_IGNS=Google Go|C|Python|Ruby
|
|||
LICENSES=Apache v2 License|GPL v2|MIT License|BSD (3-Clause) License
|
||||
|
||||
[server]
|
||||
DOMAIN = gogits.org
|
||||
HTTP_ADDR =
|
||||
HTTP_PORT = 3000
|
||||
|
||||
|
|
2
gogs.go
2
gogs.go
|
@ -20,7 +20,7 @@ import (
|
|||
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
|
||||
const go11tag = true
|
||||
|
||||
const APP_VER = "0.0.8.0316.1"
|
||||
const APP_VER = "0.0.9.0317.1"
|
||||
|
||||
func init() {
|
||||
base.AppVer = APP_VER
|
||||
|
|
|
@ -44,6 +44,10 @@ func (a Action) GetRepoName() string {
|
|||
return a.RepoName
|
||||
}
|
||||
|
||||
func (a Action) GetContent() string {
|
||||
return a.Content
|
||||
}
|
||||
|
||||
// CommitRepoAction records action for commit repository.
|
||||
func CommitRepoAction(userId int64, userName string,
|
||||
repoId int64, repoName string, commits [][]string) error {
|
||||
|
|
|
@ -307,6 +307,9 @@ func DeleteRepository(userId, repoId int64, userName string) (err error) {
|
|||
}
|
||||
|
||||
session := orm.NewSession()
|
||||
if err = session.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = session.Delete(&Repository{Id: repoId}); err != nil {
|
||||
session.Rollback()
|
||||
return err
|
||||
|
|
|
@ -5,11 +5,26 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
git "github.com/gogits/git"
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
"github.com/gogits/git"
|
||||
)
|
||||
|
||||
type Commit struct {
|
||||
Author string
|
||||
Email string
|
||||
Date time.Time
|
||||
SHA string
|
||||
Message string
|
||||
}
|
||||
|
||||
var (
|
||||
ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded")
|
||||
)
|
||||
|
||||
type RepoFile struct {
|
||||
|
@ -18,6 +33,7 @@ type RepoFile struct {
|
|||
Message string
|
||||
Created time.Time
|
||||
Size int64
|
||||
Repo *git.Repository
|
||||
LastCommit string
|
||||
}
|
||||
|
||||
|
@ -43,10 +59,34 @@ func findTree(repo *git.Repository, tree *git.Tree, rpath string) *git.Tree {
|
|||
return g
|
||||
}
|
||||
|
||||
func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) {
|
||||
f := RepoPath(userName, reposName)
|
||||
func (file *RepoFile) LookupBlob() (*git.Blob, error) {
|
||||
if file.Repo == nil {
|
||||
return nil, ErrRepoFileNotLoaded
|
||||
}
|
||||
|
||||
repo, err := git.OpenRepository(f)
|
||||
return file.Repo.LookupBlob(file.Id)
|
||||
}
|
||||
|
||||
func GetBranches(userName, reposName string) ([]string, error) {
|
||||
repo, err := git.OpenRepository(RepoPath(userName, reposName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
refs, err := repo.AllReferences()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
brs := make([]string, len(refs))
|
||||
for i, ref := range refs {
|
||||
brs[i] = ref.Name
|
||||
}
|
||||
return brs, nil
|
||||
}
|
||||
|
||||
func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) {
|
||||
repo, err := git.OpenRepository(RepoPath(userName, reposName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -128,6 +168,7 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile,
|
|||
cm.Message(),
|
||||
cm.Committer.When,
|
||||
size,
|
||||
repo,
|
||||
cm.Id().String(),
|
||||
}
|
||||
|
||||
|
@ -142,3 +183,33 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile,
|
|||
|
||||
return append(repodirs, repofiles...), nil
|
||||
}
|
||||
|
||||
func GetLastestCommit(userName, repoName string) (*Commit, error) {
|
||||
stdout, _, err := com.ExecCmd("git", "--git-dir="+RepoPath(userName, repoName), "log", "-1")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commit := new(Commit)
|
||||
for _, line := range strings.Split(stdout, "\n") {
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case line[0] == 'c':
|
||||
commit.SHA = line[7:]
|
||||
case line[0] == 'A':
|
||||
infos := strings.SplitN(line, " ", 3)
|
||||
commit.Author = infos[1]
|
||||
commit.Email = infos[2][1 : len(infos[2])-1]
|
||||
case line[0] == 'D':
|
||||
commit.Date, err = time.Parse("Mon Jan 02 15:04:05 2006 -0700", line[8:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case line[:4] == " ":
|
||||
commit.Message = line[4:]
|
||||
}
|
||||
}
|
||||
return commit, nil
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
)
|
||||
|
||||
type CreateRepoForm struct {
|
||||
UserId int64 `form:"userId"`
|
||||
RepoName string `form:"repo" binding:"Required;AlphaDash"`
|
||||
Visibility string `form:"visibility"`
|
||||
Description string `form:"desc" binding:"MaxSize(100)"`
|
||||
|
@ -52,9 +51,3 @@ func (f *CreateRepoForm) Validate(errors *binding.Errors, req *http.Request, con
|
|||
|
||||
validate(errors, data, f)
|
||||
}
|
||||
|
||||
type DeleteRepoForm struct {
|
||||
UserId int64 `form:"userId" binding:"Required"`
|
||||
UserName string `form:"userName" binding:"Required"`
|
||||
RepoId int64 `form:"repoId" binding:"Required"`
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
var (
|
||||
AppVer string
|
||||
AppName string
|
||||
Domain string
|
||||
Cfg *goconfig.ConfigFile
|
||||
)
|
||||
|
||||
|
@ -58,4 +59,5 @@ func init() {
|
|||
Cfg.BlockMode = false
|
||||
|
||||
AppName = Cfg.MustValue("", "APP_NAME")
|
||||
Domain = Cfg.MustValue("server", "DOMAIN")
|
||||
}
|
||||
|
|
39
modules/base/markdown.go
Normal file
39
modules/base/markdown.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
// 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 base
|
||||
|
||||
import (
|
||||
"github.com/slene/blackfriday"
|
||||
)
|
||||
|
||||
func RenderMarkdown(rawBytes []byte) []byte {
|
||||
htmlFlags := 0
|
||||
htmlFlags |= blackfriday.HTML_USE_XHTML
|
||||
// htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
|
||||
// htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
|
||||
// htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
|
||||
htmlFlags |= blackfriday.HTML_SKIP_HTML
|
||||
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
||||
htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
|
||||
htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE
|
||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||
htmlFlags |= blackfriday.HTML_COMPLETE_PAGE
|
||||
renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
|
||||
|
||||
// set up the parser
|
||||
extensions := 0
|
||||
extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
|
||||
extensions |= blackfriday.EXTENSION_TABLES
|
||||
extensions |= blackfriday.EXTENSION_FENCED_CODE
|
||||
extensions |= blackfriday.EXTENSION_AUTOLINK
|
||||
extensions |= blackfriday.EXTENSION_STRIKETHROUGH
|
||||
extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK
|
||||
extensions |= blackfriday.EXTENSION_SPACE_HEADERS
|
||||
extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
|
||||
|
||||
body := blackfriday.Markdown(rawBytes, renderer, extensions)
|
||||
|
||||
return body
|
||||
}
|
|
@ -19,6 +19,10 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
|
|||
"AppVer": func() string {
|
||||
return AppVer
|
||||
},
|
||||
"AppDomain": func() string {
|
||||
return Domain
|
||||
},
|
||||
"AvatarLink": AvatarLink,
|
||||
"str2html": Str2html,
|
||||
"TimeSince": TimeSince,
|
||||
"FileSize": FileSize,
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
package base
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
|
@ -20,6 +22,11 @@ func EncodeMd5(str string) string {
|
|||
return hex.EncodeToString(m.Sum(nil))
|
||||
}
|
||||
|
||||
// AvatarLink returns avatar link by given e-mail.
|
||||
func AvatarLink(email string) string {
|
||||
return "http://1.gravatar.com/avatar/" + EncodeMd5(email)
|
||||
}
|
||||
|
||||
// Seconds-based time units
|
||||
const (
|
||||
Minute = 60
|
||||
|
@ -235,6 +242,7 @@ type Actioner interface {
|
|||
GetOpType() int
|
||||
GetActUserName() string
|
||||
GetRepoName() string
|
||||
GetContent() string
|
||||
}
|
||||
|
||||
// ActionIcon accepts a int that represents action operation type
|
||||
|
@ -243,23 +251,39 @@ func ActionIcon(opType int) string {
|
|||
switch opType {
|
||||
case 1: // Create repository.
|
||||
return "plus-circle"
|
||||
case 5: // Commit repository.
|
||||
return "arrow-circle-o-right"
|
||||
default:
|
||||
return "invalid type"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
CreateRepoTpl = `<a href="/user/%s">%s</a> created repository <a href="/%s/%s">%s</a>`
|
||||
TPL_CREATE_REPO = `<a href="/user/%s">%s</a> created repository <a href="/%s/%s">%s</a>`
|
||||
TPL_COMMIT_REPO = `<a href="/user/%s">%s</a> pushed to <a href="/%s/%s/tree/%s">%s</a> at <a href="/%s/%s">%s/%s</a>%s`
|
||||
TPL_COMMIT_REPO_LI = `<div><img id="gogs-user-avatar-commit" src="%s?s=16" alt="user-avatar" title="username"/> <a href="/%s/%s/commit/%s">%s</a> %s</div>`
|
||||
)
|
||||
|
||||
// ActionDesc accepts int that represents action operation type
|
||||
// and returns the description.
|
||||
func ActionDesc(act Actioner) string {
|
||||
func ActionDesc(act Actioner, avatarLink string) string {
|
||||
actUserName := act.GetActUserName()
|
||||
repoName := act.GetRepoName()
|
||||
content := act.GetContent()
|
||||
switch act.GetOpType() {
|
||||
case 1: // Create repository.
|
||||
return fmt.Sprintf(CreateRepoTpl, actUserName, actUserName, actUserName, repoName, repoName)
|
||||
return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, actUserName, repoName, repoName)
|
||||
case 5: // Commit repository.
|
||||
var commits [][]string
|
||||
if err := json.Unmarshal([]byte(content), &commits); err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
buf := bytes.NewBuffer([]byte("\n"))
|
||||
for _, commit := range commits {
|
||||
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, avatarLink, actUserName, repoName, commit[0], commit[0][:7], commit[1]) + "\n")
|
||||
}
|
||||
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, actUserName, repoName, "master", "master", actUserName, repoName, actUserName, repoName,
|
||||
buf.String())
|
||||
default:
|
||||
return "invalid type"
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package middleware
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/codegangsta/martini"
|
||||
|
||||
|
@ -23,8 +24,7 @@ func RepoAssignment(redirect bool) martini.Handler {
|
|||
)
|
||||
|
||||
// get repository owner
|
||||
ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == params["username"]
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
|
||||
ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(params["username"])
|
||||
|
||||
if !ctx.Repo.IsOwner {
|
||||
user, err = models.GetUserByName(params["username"])
|
||||
|
@ -70,5 +70,6 @@ func RepoAssignment(redirect bool) martini.Handler {
|
|||
ctx.Data["Owner"] = user
|
||||
ctx.Data["Title"] = user.Name + "/" + repo.Name
|
||||
ctx.Data["RepositoryLink"] = ctx.Data["Title"]
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ body {
|
|||
|
||||
html, body {
|
||||
height: 100%;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* override bs3 */
|
||||
|
@ -50,7 +51,6 @@ html, body {
|
|||
.gogs-masthead {
|
||||
background-color: #428bca;
|
||||
box-shadow: inset 0 -2px 5px rgba(0, 0, 0, .1);
|
||||
padding: 0 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,12 @@ html, body {
|
|||
height: 46px;
|
||||
}
|
||||
|
||||
#gogs-nav-logo{
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.gogs-nav-item:hover,
|
||||
.gogs-nav-item:focus {
|
||||
color: #fff;
|
||||
|
@ -128,6 +134,11 @@ html, body {
|
|||
padding: 5px 0;
|
||||
margin-left: 10px;
|
||||
height: 28px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#gogs-nav-signin{
|
||||
float: right;
|
||||
}
|
||||
|
||||
#gogs-nav-out .fa {
|
||||
|
@ -228,6 +239,12 @@ html, body {
|
|||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#gogs-user-avatar-commit {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#gogs-user-name {
|
||||
margin-top: 20px;
|
||||
font-size: 1.6em;
|
||||
|
@ -338,10 +355,6 @@ html, body {
|
|||
|
||||
/* #gogs-feed */
|
||||
|
||||
#gogs-feed-left {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#gogs-feed-right .repo-panel .panel-heading .btn {
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
@ -399,18 +412,11 @@ html, body {
|
|||
|
||||
.gogs-repo-nav h3 .fa {
|
||||
color: #BBB;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.gogs-repo-btns {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.gogs-repo-btns .btn-group {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.gogs-repo-btns .btn-group .btn {
|
||||
padding-left: 6px;
|
||||
.gogs-repo-nav .actions {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
#gogs-repo-watching .dropdown-menu {
|
||||
|
@ -475,7 +481,7 @@ html, body {
|
|||
|
||||
.activity-list .info {
|
||||
float: left;
|
||||
padding:0 0 0 10px;
|
||||
padding: 0 0 0 10px;
|
||||
line-height: 1.7em;
|
||||
}
|
||||
|
||||
|
@ -525,6 +531,10 @@ html, body {
|
|||
}
|
||||
|
||||
/* #gogs-source */
|
||||
#gogs-source {
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
#gogs-source .source-toolbar:after {
|
||||
clear: both;
|
||||
}
|
||||
|
@ -560,7 +570,9 @@ html, body {
|
|||
.file-list .icon {
|
||||
font-size: 17px;
|
||||
padding: 5px 0 4px 10px;
|
||||
width: 40px;
|
||||
width: 50px;
|
||||
color: #999;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.file-list .wrap {
|
||||
|
@ -581,13 +593,87 @@ html, body {
|
|||
|
||||
.file-list .date .wrap {
|
||||
max-width: 120px;
|
||||
padding: 0 20px 0 0;
|
||||
padding: 0 20px 0 0;
|
||||
}
|
||||
|
||||
.file-list .date {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.file-content .file-head {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.file-content .file-head .icon {
|
||||
color: #666;
|
||||
margin: 0 .5em 0 0;
|
||||
}
|
||||
|
||||
.file-content .file-body {
|
||||
padding: 30px 30px 50px;
|
||||
}
|
||||
|
||||
.branch-list th{
|
||||
background-color: #FFF;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
.branch-list td{
|
||||
line-height: 36px !important;
|
||||
}
|
||||
|
||||
.branch-box tr:hover td{
|
||||
background-color: rgba(19, 95, 215, 0.06) !important;
|
||||
}
|
||||
|
||||
.branch-box .name{
|
||||
padding-left: 20px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.branch-box .action{
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.branch-box td.date,.branch-box td.behind,.branch-box td.ahead{
|
||||
width: 120px;
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.branch-box .graph{
|
||||
display: block;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
.branch-box .behind{
|
||||
text-align: right;
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.branch-box .behind .graph{
|
||||
background-color: #888;
|
||||
}
|
||||
|
||||
.branch-box .ahead .graph{
|
||||
background-color: #0093c4;
|
||||
}
|
||||
|
||||
.branch-box .branch-main{
|
||||
background-color: #444;
|
||||
color: #FFF;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
.branch-box .branch-main a{
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.branch-box .branch-main .name .btn{
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
/* wrapper and footer */
|
||||
|
||||
#wrapper {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
|
@ -604,7 +690,7 @@ html, body {
|
|||
}
|
||||
|
||||
#footer .footer-wrap {
|
||||
padding: 20px 0;
|
||||
padding: 20px 15px;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
|
|
317
public/css/markdown.css
Normal file
317
public/css/markdown.css
Normal file
|
@ -0,0 +1,317 @@
|
|||
.markdown {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown a {
|
||||
color: #4183C4;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
line-height: 1.7;
|
||||
padding: 15px 0 0;
|
||||
margin: 0 0 15px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
.markdown h2 {
|
||||
border-bottom: 1px solid #EEE;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
border-bottom: 1px solid #EEE;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #000;
|
||||
font-size: 33px
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
color: #333;
|
||||
font-size: 28px
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 22px
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 18px
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.markdown table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
display: block;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
margin: 0 0 9px;
|
||||
}
|
||||
|
||||
.markdown table th {
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown table th,
|
||||
.markdown table td {
|
||||
border: 1px solid #DDD;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
.markdown table tr {
|
||||
background-color: #FFF;
|
||||
border-top: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.markdown table tr:nth-child(2n) {
|
||||
background-color: #F8F8F8
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
line-height: 1.6;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.markdown dl dt {
|
||||
font-style: italic;
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
.markdown dl dd {
|
||||
margin: 0 0 9px;
|
||||
padding: 0 9px;
|
||||
}
|
||||
|
||||
.markdown blockquote,
|
||||
.markdown blockquote p {
|
||||
font-size: 14px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.markdown > pre {
|
||||
line-height: 1.6;
|
||||
overflow: auto;
|
||||
background: #fff;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.markdown > pre.linenums {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown > pre > ol.linenums {
|
||||
-webkit-box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc;
|
||||
box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc;
|
||||
}
|
||||
|
||||
.markdown > pre > code,
|
||||
.markdown > pre > ol.linenums > li > code {
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.markdown > pre > ol.linenums > li > code {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.markdown > pre > ol.linenums > li:first-child {
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.markdown > pre > ol.linenums > li:last-child {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.markdown > pre > ol.linenums > li {
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
border: none;
|
||||
color: #ccc;
|
||||
height: 4px;
|
||||
padding: 0;
|
||||
margin: 15px 0;
|
||||
border-bottom: 2px solid #EEE;
|
||||
}
|
||||
|
||||
.markdown blockquote:last-child,
|
||||
.markdown ul:last-child,
|
||||
.markdown ol:last-child,
|
||||
.markdown > pre:last-child,
|
||||
.markdown > pre:last-child,
|
||||
.markdown p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown .btn {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Author: jmblog */
|
||||
/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */
|
||||
/* GitHub Theme */
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
/* string content */
|
||||
.str {
|
||||
color: #dd1144;
|
||||
}
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
color: #999988;
|
||||
}
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #445588;
|
||||
}
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #445588;
|
||||
}
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: navy;
|
||||
}
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: teal;
|
||||
}
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #dd1144;
|
||||
}
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: teal;
|
||||
}
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #990000;
|
||||
}
|
||||
}
|
||||
/* Use higher contrast and text-weight for printable form. */
|
||||
@media print, projection {
|
||||
.str {
|
||||
color: #006600;
|
||||
}
|
||||
|
||||
.kwd {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.com {
|
||||
color: #600;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.typ {
|
||||
color: #404;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lit {
|
||||
color: #004444;
|
||||
}
|
||||
|
||||
.pun, .opn, .clo {
|
||||
color: #444400;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.atn {
|
||||
color: #440044;
|
||||
}
|
||||
|
||||
.atv {
|
||||
color: #006600;
|
||||
}
|
||||
}
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* IE indents via margin-left */
|
||||
li.L0,
|
||||
li.L1,
|
||||
li.L2,
|
||||
li.L3,
|
||||
li.L4,
|
||||
li.L5,
|
||||
li.L6,
|
||||
li.L7,
|
||||
li.L8,
|
||||
li.L9 {
|
||||
/* */
|
||||
}
|
||||
|
||||
/* Alternate shading for lines */
|
||||
li.L1,
|
||||
li.L3,
|
||||
li.L5,
|
||||
li.L7,
|
||||
li.L9 {
|
||||
/* */
|
||||
}
|
|
@ -40,10 +40,37 @@ var Gogits = {
|
|||
//container: "body"
|
||||
});
|
||||
};
|
||||
Gogits.initPopovers = function () {
|
||||
var hideAllPopovers = function() {
|
||||
$('[data-toggle=popover]').each(function() {
|
||||
$(this).popover('hide');
|
||||
});
|
||||
};
|
||||
|
||||
$(document).on('click', function(e) {
|
||||
var $e = $(e.target);
|
||||
if($e.data('toggle') == 'popover'||$e.parents("[data-toggle=popover], .popover").length > 0){
|
||||
return;
|
||||
}
|
||||
hideAllPopovers();
|
||||
});
|
||||
|
||||
$("body").popover({
|
||||
selector: "[data-toggle=popover]"
|
||||
});
|
||||
};
|
||||
Gogits.initTabs = function () {
|
||||
var $tabs = $('[data-init=tabs]');
|
||||
$tabs.find("li:eq(0) a").tab("show");
|
||||
};
|
||||
|
||||
// render markdown
|
||||
Gogits.renderMarkdown = function () {
|
||||
var $pre = $('.markdown').find('pre > code').parent();
|
||||
$pre.addClass("prettyprint");
|
||||
prettyPrint();
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
// ajax utils
|
||||
|
@ -68,8 +95,10 @@ var Gogits = {
|
|||
|
||||
function initCore() {
|
||||
Gogits.initTooltips();
|
||||
Gogits.initPopovers();
|
||||
Gogits.initTabs();
|
||||
Gogits.initModals();
|
||||
Gogits.renderMarkdown();
|
||||
}
|
||||
|
||||
function initRegister() {
|
||||
|
@ -98,17 +127,30 @@ function initRegister() {
|
|||
});
|
||||
}
|
||||
|
||||
function initUserSetting(){
|
||||
function initUserSetting() {
|
||||
$('#gogs-ssh-keys .delete').confirmation({
|
||||
singleton: true,
|
||||
onConfirm: function(e, $this){
|
||||
Gogits.ajaxDelete("",{"id":$this.data("del")},function(json){
|
||||
if(json.ok){
|
||||
onConfirm: function (e, $this) {
|
||||
Gogits.ajaxDelete("", {"id": $this.data("del")}, function (json) {
|
||||
if (json.ok) {
|
||||
window.location.reload();
|
||||
}else{
|
||||
} else {
|
||||
alert(json.err);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
(function ($) {
|
||||
$(function () {
|
||||
initCore();
|
||||
var body = $("#gogs-body");
|
||||
if (body.data("page") == "user-signup") {
|
||||
initRegister();
|
||||
}
|
||||
if (body.data("page") == "user") {
|
||||
initUserSetting();
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
|
|
259
public/js/bootstrap.min.js
vendored
259
public/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
482
public/js/lib.js
Normal file
482
public/js/lib.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -20,49 +20,35 @@ func Create(ctx *middleware.Context, form auth.CreateRepoForm) {
|
|||
return
|
||||
}
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.Render.HTML(200, "repo/create", ctx.Data)
|
||||
if _, err := models.CreateRepository(ctx.User,
|
||||
form.RepoName, form.Description, form.Language, form.License,
|
||||
form.Visibility == "private", form.InitReadme == "on"); err == nil {
|
||||
ctx.Render.Redirect("/"+ctx.User.Name+"/"+form.RepoName, 302)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: access check
|
||||
|
||||
user, err := models.GetUserById(form.UserId)
|
||||
if err != nil {
|
||||
if err.Error() == models.ErrUserNotExist.Error() {
|
||||
ctx.RenderWithErr("User does not exist", "repo/create", &form)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
if _, err = models.CreateRepository(user,
|
||||
form.RepoName, form.Description, form.Language, form.License,
|
||||
form.Visibility == "private", form.InitReadme == "on"); err == nil {
|
||||
ctx.Render.Redirect("/"+user.Name+"/"+form.RepoName, 302)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err.Error() == models.ErrRepoAlreadyExist.Error() {
|
||||
} else if err == models.ErrRepoAlreadyExist {
|
||||
ctx.RenderWithErr("Repository name has already been used", "repo/create", &form)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Handle(200, "repo.Create", err)
|
||||
}
|
||||
|
||||
func Delete(ctx *middleware.Context, form auth.DeleteRepoForm) {
|
||||
ctx.Data["Title"] = "Delete repository"
|
||||
|
||||
if ctx.Req.Method == "GET" {
|
||||
ctx.Render.HTML(200, "repo/delete", ctx.Data)
|
||||
func SettingPost(ctx *middleware.Context) {
|
||||
if !ctx.Repo.IsOwner {
|
||||
ctx.Render.Error(404)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteRepository(form.UserId, form.RepoId, form.UserName); err != nil {
|
||||
ctx.Handle(200, "repo.Delete", err)
|
||||
return
|
||||
switch ctx.Query("action") {
|
||||
case "delete":
|
||||
if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") {
|
||||
ctx.Data["ErrorMsg"] = "Please make sure you entered repository name is correct."
|
||||
ctx.Render.HTML(200, "repo/setting", ctx.Data)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil {
|
||||
ctx.Handle(200, "repo.Delete", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Render.Redirect("/", 302)
|
||||
|
|
|
@ -9,10 +9,33 @@ import (
|
|||
|
||||
"github.com/codegangsta/martini"
|
||||
|
||||
"github.com/gogits/git"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
func Branches(ctx *middleware.Context, params martini.Params) {
|
||||
if !ctx.Repo.IsValid {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Username"] = params["username"]
|
||||
ctx.Data["Reponame"] = params["reponame"]
|
||||
|
||||
brs, err := models.GetBranches(params["username"], params["reponame"])
|
||||
if err != nil {
|
||||
ctx.Handle(200, "repo.Branches", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Branches"] = brs
|
||||
ctx.Data["IsRepoToolbarBranches"] = true
|
||||
|
||||
ctx.Render.HTML(200, "repo/branches", ctx.Data)
|
||||
}
|
||||
|
||||
func Single(ctx *middleware.Context, params martini.Params) {
|
||||
if !ctx.Repo.IsValid {
|
||||
return
|
||||
|
@ -22,17 +45,28 @@ func Single(ctx *middleware.Context, params martini.Params) {
|
|||
params["branchname"] = "master"
|
||||
}
|
||||
|
||||
// Get tree path
|
||||
treename := params["_1"]
|
||||
|
||||
// Directory and file list.
|
||||
files, err := models.GetReposFiles(params["username"], params["reponame"],
|
||||
params["branchname"], treename)
|
||||
if err != nil {
|
||||
ctx.Handle(200, "repo.Single", err)
|
||||
ctx.Render.Error(404)
|
||||
return
|
||||
}
|
||||
ctx.Data["Username"] = params["username"]
|
||||
ctx.Data["Reponame"] = params["reponame"]
|
||||
ctx.Data["Branchname"] = params["branchname"]
|
||||
|
||||
// Branches.
|
||||
brs, err := models.GetBranches(params["username"], params["reponame"])
|
||||
if err != nil {
|
||||
ctx.Render.Error(404)
|
||||
return
|
||||
}
|
||||
ctx.Data["Branches"] = brs
|
||||
|
||||
var treenames []string
|
||||
Paths := make([]string, 0)
|
||||
|
||||
|
@ -43,16 +77,52 @@ func Single(ctx *middleware.Context, params martini.Params) {
|
|||
}
|
||||
}
|
||||
|
||||
// Get latest commit according username and repo name
|
||||
commit, err := models.GetLastestCommit(params["username"], params["reponame"])
|
||||
if err != nil {
|
||||
ctx.Render.Error(404)
|
||||
return
|
||||
}
|
||||
ctx.Data["LatestCommit"] = commit
|
||||
|
||||
var readmeFile *models.RepoFile
|
||||
|
||||
for _, f := range files {
|
||||
if !f.IsFile() {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(f.Name) < 6 {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.ToLower(f.Name[:6]) == "readme" {
|
||||
readmeFile = f
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if readmeFile != nil {
|
||||
// if file large than 1M not show it
|
||||
if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob {
|
||||
ctx.Data["FileIsLarge"] = true
|
||||
} else if blob, err := readmeFile.LookupBlob(); err != nil {
|
||||
ctx.Data["FileIsLarge"] = true
|
||||
} else {
|
||||
ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents()))
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["Paths"] = Paths
|
||||
ctx.Data["Treenames"] = treenames
|
||||
ctx.Data["IsRepoToolbarSource"] = true
|
||||
ctx.Data["IsRepositoryOwner"] = strings.ToLower(params["username"]) == ctx.User.LowerName
|
||||
ctx.Data["Files"] = files
|
||||
ctx.Render.HTML(200, "repo/single", ctx.Data)
|
||||
}
|
||||
|
||||
func Setting(ctx *middleware.Context, params martini.Params) {
|
||||
if !ctx.Repo.IsValid {
|
||||
if !ctx.Repo.IsOwner {
|
||||
ctx.Render.Error(404)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -63,7 +133,6 @@ func Setting(ctx *middleware.Context, params martini.Params) {
|
|||
|
||||
ctx.Data["Title"] = title + " - settings"
|
||||
ctx.Data["IsRepoToolbarSetting"] = true
|
||||
ctx.Data["IsRepositoryOwner"] = strings.ToLower(params["username"]) == ctx.User.LowerName
|
||||
ctx.Render.HTML(200, "repo/setting", ctx.Data)
|
||||
}
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ func Feeds(ctx *middleware.Context, form auth.FeedsForm) {
|
|||
feeds := make([]string, len(actions))
|
||||
for i := range actions {
|
||||
feeds[i] = fmt.Sprintf(feedTpl, base.ActionIcon(actions[i].OpType),
|
||||
base.TimeSince(actions[i].Created), base.ActionDesc(actions[i]))
|
||||
base.TimeSince(actions[i].Created), base.ActionDesc(actions[i], ctx.User.AvatarLink()))
|
||||
}
|
||||
ctx.Render.JSON(200, &feeds)
|
||||
}
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
<script>
|
||||
$(function(){
|
||||
initCore();{{if .PageIsSignUp}}
|
||||
initRegister();{{end}}{{if .PageIsUserSetting}}
|
||||
initUserSetting();{{end}}
|
||||
});
|
||||
</script>
|
||||
<div class="wrapper-push"></div>
|
||||
<div class="wrapper-push"></div>
|
||||
</div>
|
||||
<footer id="footer">
|
||||
<div class="container footer-wrap">
|
||||
<p>
|
||||
© 2014 Gogs · ver {{AppVer}} · <i class="fa fa-github"></i><a target="_blank" href="https://github.com/gogits/gogs">GitHub</a>
|
||||
</p>
|
||||
<p class="desc"></p>
|
||||
</div>
|
||||
<div class="container footer-wrap">
|
||||
<p>© 2014 Gogs · ver {{AppVer}} ·
|
||||
<i class="fa fa-github"></i><a target="_blank" href="https://github.com/gogits/gogs">GitHub</a>
|
||||
</p>
|
||||
<p class="desc"></p>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
|
@ -3,7 +3,9 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="shortcut icon" href="/img/favicon.png" />
|
||||
<meta name="author" content="Gogs - Go Git Service" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||
<meta name="author" content="Gogs - Go Git Service" />
|
||||
<meta name="description" content="Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language" />
|
||||
<meta name="keywords" content="go, git">
|
||||
|
||||
|
@ -11,10 +13,12 @@
|
|||
<link href="/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/css/todc-bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link href="/css/markdown.css" rel="stylesheet" />
|
||||
<link href="/css/gogs.css" rel="stylesheet" />
|
||||
|
||||
<script src="/js/jquery-1.10.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/lib.js"></script>
|
||||
<script src="/js/app.js"></script>
|
||||
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
|
||||
</head>
|
||||
|
|
42
templates/repo/branches.tmpl
Normal file
42
templates/repo/branches.tmpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
{{template "repo/nav" .}}
|
||||
{{template "repo/toolbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-source">
|
||||
<div class="panel panel-default branch-box info-box">
|
||||
<div class="panel-heading info-head">
|
||||
<h4>Branches</h4>
|
||||
</div>
|
||||
<table class="panel-footer table branch-list table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="name"></th>
|
||||
<th class="behind">Behind</th>
|
||||
<th class="ahead">Ahead</th>
|
||||
<th class="date">Last Commit</th>
|
||||
<th class="action"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="branch-main">
|
||||
<td class="name" colspan="3">
|
||||
<a href="#"><strong>BranchName</strong></a>
|
||||
<button class="btn btn-primary btn-sm">base branch</button>
|
||||
</td>
|
||||
<td class="date">3 years ago</td>
|
||||
<td class="action"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name"><a href="#"><strong>BranchName</strong></a></td>
|
||||
<td class="behind">102 <span class="graph" style="width: 100%"></span></td>
|
||||
<td class="ahead"><span class="graph" style="width: 4%"></span>4</td>
|
||||
<td class="date">3 years ago</td>
|
||||
<td class="action"><a class="btn btn-info btn-sm" href="#">compare</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
|
@ -1,12 +0,0 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div class="container">
|
||||
<form action="/repo/delete" method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-4 col-md-3">
|
||||
<button type="submit" class="btn btn-danger">Delete repository</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
|
@ -1,42 +1,41 @@
|
|||
<div id="gogs-body-nav" class="gogs-repo-nav">
|
||||
<div class="container">
|
||||
<div class="gogs-repo-btns pull-right">
|
||||
<div class="btn-group" id="gogs-repo-clone">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-download"></i>Clone</button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div data-val="down-http">http link</div>
|
||||
<div data-val="down-git">git link</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3><i class="fa fa-book fa-lg"></i><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / {{.Repository.Name}}</h3>
|
||||
</div>
|
||||
<div class="btn-group" id="gogs-repo-watching">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-eye"></i>Watch {x}</button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-item" data-val="not-watching">
|
||||
<h4 role="presentation" class="dropdown-header">Not Watching</h4>
|
||||
<p class="description">You only receive notifications for conversations in which you participate or are @mentioned.</p>
|
||||
<p class="divider"></p>
|
||||
</div>
|
||||
<div class="dropdown-item" data-val="watching">
|
||||
<h4 role="presentation" class="dropdown-header">Watching</h4>
|
||||
<p class="description">You receive notifications for all conversations in this repository.</p>
|
||||
<div class="col-md-6 actions text-right">
|
||||
<div class="btn-group" id="gogs-repo-clone">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-download"></i>Clone</button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-container="body" data-toggle="popover" data-placement="bottom" data-content="<label>SSH:</label><div class='input-group'><input type='text' class='form-control' value='git@{{AppDomain}}:{{.Owner.Name}}/{{.Repository.Name}}.git'></div>" data-html="1">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="btn-group" id="gogs-repo-watching">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-eye"></i>Watch {x}</button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-item" data-val="not-watching">
|
||||
<h4 role="presentation" class="dropdown-header">Not Watching</h4>
|
||||
<p class="description">You only receive notifications for conversations in which you participate or are @mentioned.</p>
|
||||
<p class="divider"></p>
|
||||
</div>
|
||||
<div class="dropdown-item" data-val="watching">
|
||||
<h4 role="presentation" class="dropdown-header">Watching</h4>
|
||||
<p class="description">You receive notifications for all conversations in this repository.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-star"></i>Star {{.Repository.NumStars}}</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-code-fork"></i>Fork {{.Repository.NumForks}}</button>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-star"></i>Star {{.Repository.NumStars}}</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default"><i class="fa fa-code-fork"></i>Fork {{.Repository.NumForks}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3><i class="fa fa-book fa-lg"></i><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / {{.Repository.Name}}</h3>
|
||||
</div>
|
||||
</div>
|
|
@ -4,30 +4,60 @@
|
|||
{{template "repo/toolbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Repository Settings</h4>
|
||||
<ul class="list-group" data-init="tabs">
|
||||
<li class="list-group-item"><a href="#options" data-toggle="tab">Options</a></li>
|
||||
<!--<li class="list-group-item" data-toggle="tab"><a href="#">Collaborators</a></li>
|
||||
<li class="list-group-item" data-toggle="tab"><a href="#">Notifications</a></li>-->
|
||||
<li class="list-group-item"><a href="#delete" data-toggle="tab">Delete</a></li>
|
||||
<li class="list-group-item active"><a href="/{{.Owner.Name}}/{{.Repository.Name}}/settings">Options</a></li>
|
||||
<!--<li class="list-group-item"><a href="#">Collaborators</a></li>
|
||||
<li class="list-group-item"><a href="#">Notifications</a></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
<div id="gogs-repo-setting-container" class="col-md-9 tab-content">
|
||||
<div id="options" class="tab-pane">
|
||||
<h4>Repository Options</h4>
|
||||
<div id="gogs-repo-setting-container" class="col-md-9">
|
||||
{{if .ErrorMsg}}<p class="alert alert-danger">{{.ErrorMsg}}</p>{{end}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Repository Options
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="delete" class="tab-pane">
|
||||
<h4>Delete Repository</h4>
|
||||
<p class="alert alert-warning">Unexpected bad things will happen if you don't read this!</p>
|
||||
<p>This action <strong>CANNOT</strong> be undone. This will delete the repository, wiki, issues, and comments permanently. </p>
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
Danger Zone
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<button type="button" class="btn btn-default pull-right" href="#delete-repository-modal" data-toggle="modal">
|
||||
Delete this repository
|
||||
</button>
|
||||
<dd>
|
||||
<dt>Delete this repository.</dt>
|
||||
<dl>Once you delete a repository, there is no going back. Please be certain.</dl>
|
||||
</dd>
|
||||
|
||||
<form action="/repo/delete" method="post">
|
||||
<input type="hidden" name="userId" value="{{.Owner.Id}}"/>
|
||||
<input type="hidden" name="userName" value="{{.Owner.Name}}"/>
|
||||
<input type="hidden" name="repoId" value="{{.Repository.Id}}"/>
|
||||
<hr/>
|
||||
<button class="btn btn-danger btn-lg">I understand the consequences, delete this repository</button>
|
||||
</form>
|
||||
<div class="modal fade" id="delete-repository-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="/{{.Owner.Name}}/{{.Repository.Name}}/settings" method="post" class="modal-content">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="myModalLabel">Delete repository</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>Please enter your repository name "<strong class="text-danger">{{.Repository.Name}}</strong>"</label>
|
||||
<input name="repository" class="form-control" type="text" placeholder="Type your repository name" required="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
<button class="btn btn-danger btn-lg">I understand the consequences, delete this repository</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,56 +5,61 @@
|
|||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-source">
|
||||
<div class="source-toolbar">
|
||||
<button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button>
|
||||
<div class="dropdown branch-switch">
|
||||
<a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>master
|
||||
<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="current" href="/{{.RepositoryLink}}/tree/master">master</a></li>
|
||||
<li><a href="/{{.RepositoryLink}}/tree/develop">develop</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{$paths := .Paths}}
|
||||
{{ $username := .Username}}
|
||||
{{ $username := .Username}}
|
||||
{{ $reponame := .Reponame}}
|
||||
{{ $branchname := .Branchname}}
|
||||
{{ $treenames := .Treenames}}
|
||||
{{ $repoLink := .RepositoryLink}}
|
||||
{{ $n := len $treenames}}
|
||||
<button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button>
|
||||
<div class="dropdown branch-switch">
|
||||
<a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>{{$branchname}}
|
||||
<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
{{range .Branches}}
|
||||
<li><a {{if eq . $branchname}}class="current" {{end}}href="/{{$repoLink}}/tree/{{.}}">{{.}}</a></li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{$paths := .Paths}}
|
||||
{{ $l := Subtract $n 1}}
|
||||
<ol class="breadcrumb">
|
||||
<li class="root dir"><a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}">{{.Repository.Name}}</a></li>
|
||||
<li class="root dir">
|
||||
<a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}">{{.Repository.Name}}</a></li>
|
||||
{{range $i, $v := $treenames}}
|
||||
<li class="dir">
|
||||
{{if eq $i $l}}{{$v}}
|
||||
{{else}}
|
||||
<a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{index $paths $i}}">{{$v}}</a>
|
||||
{{end}}</li>
|
||||
{{if eq $i $l}}{{$v}}
|
||||
{{else}}
|
||||
<a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{index $paths $i}}">{{$v}}</a>
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
</div>
|
||||
<div class="panel panel-default info-box">
|
||||
<div class="panel-heading info-head">
|
||||
Merge branch 'release/1.1.1'
|
||||
<a href="/{{$username}}/{{$reponame}}/commit/{{.LatestCommit.SHA}}">{{.LatestCommit.Message}}</a>
|
||||
</div>
|
||||
<div class="panel-body info-content">
|
||||
slene authored 4 days ago
|
||||
<a href="/user/{{.LatestCommit.Author}}">{{.LatestCommit.Author}}</a> <span class="text-muted">{{TimeSince .LatestCommit.Date}}</span>
|
||||
</div>
|
||||
<table class="panel-footer table file-list">
|
||||
<thead class="hidden">
|
||||
<tr>
|
||||
<th class="icon"></th>
|
||||
<th class="name">Filename</th>
|
||||
<th class="text">Message</th>
|
||||
<th class="date">Date modified</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="icon"></th>
|
||||
<th class="name">Filename</th>
|
||||
<th class="text">Message</th>
|
||||
<th class="date">Date modified</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Files}}
|
||||
<tr {{if .IsDir}}class="is-dir"{{end}}>
|
||||
<td class="icon">
|
||||
<i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i>
|
||||
</td>
|
||||
<td class="name">
|
||||
{{range .Files}}
|
||||
<tr
|
||||
{{if .IsDir}}class="is-dir"{{end}}>
|
||||
<td class="icon">
|
||||
<i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i>
|
||||
</td>
|
||||
<td class="name">
|
||||
<span class="wrap">
|
||||
{{if .IsDir}}
|
||||
<a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{.Path}}">{{.Name}}</a>
|
||||
|
@ -62,29 +67,35 @@
|
|||
<a href="/{{$username}}/{{$reponame}}/blob/{{$branchname}}/{{.Name}}">{{.Name}}</a>
|
||||
{{end}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="text">
|
||||
</td>
|
||||
<td class="text">
|
||||
<span class="wrap">
|
||||
{{.Message}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="date">
|
||||
</td>
|
||||
<td class="date">
|
||||
<span class="wrap">
|
||||
{{TimeSince .Created}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel panel-default file-content">
|
||||
<div class="panel-heading">
|
||||
README.md
|
||||
</div>
|
||||
<div class="panel-body markdown">
|
||||
httplib
|
||||
<div class="panel-heading file-head">
|
||||
<i class="icon fa fa-book"></i> README.md
|
||||
</div>
|
||||
{{if .FileIsLarge}}
|
||||
<div class="panel-footer">
|
||||
Large file size 1000kb
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel-body file-body markdown">
|
||||
{{.ReadmeContent|str2html}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
<div class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="{{if .IsRepoToolbarSource}}active{{end}}"><a href="/{{.RepositoryLink}}">Source</a></li>
|
||||
<li><a href="/{{.RepositoryLink}}/commits">Commits</a></li>
|
||||
<li><a href="/{{.RepositoryLink}}/issues">Issues <!--<span class="badge">42</span>--></a></li>
|
||||
<li><a href="/{{.RepositoryLink}}/pulls">Pull Requests</a></li>
|
||||
<li class="{{if .IsRepoToolbarCommits}}active{{end}}"><a href="/{{.RepositoryLink}}/commits">Commits</a></li>
|
||||
<li class="{{if .IsRepoToolbarBranches}}active{{end}}"><a href="/{{.RepositoryLink}}/branches">Branches</a></li>
|
||||
<li class="{{if .IsRepoToolbarPulls}}active{{end}}"><a href="/{{.RepositoryLink}}/pulls">Pull Requests</a></li>
|
||||
<li class="{{if .IsRepoToolbarIssues}}active{{end}}"><a href="/{{.RepositoryLink}}/issues">Issues <!--<span class="badge">42</span>--></a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">More <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<h3>News Feed</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
{{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}}
|
||||
<div id="gogs-feed-left" class="col-md-8">
|
||||
<ul class="list-unstyled activity-list">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Account Setting</h4>
|
||||
<ul class="list-group">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Account Setting</h4>
|
||||
<ul class="list-group">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Account Setting</h4>
|
||||
<ul class="list-group">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-profile" class="col-md-3">
|
||||
<div class="profile-avatar text-center">
|
||||
<a href="{{.Owner.HomeLink}}" class="center-block" data-toggle="tooltip" data-placement="bottom" title="Change Avatar">
|
||||
|
@ -32,10 +32,11 @@
|
|||
{{if eq .TabName "activity"}}
|
||||
<div class="tab-pane active">
|
||||
<ul class="list-unstyled activity-list">
|
||||
{{$avatarLink := .Owner.AvatarLink}}
|
||||
{{range .Feeds}}
|
||||
<li>
|
||||
<i class="icon fa fa-{{ActionIcon .OpType}}"></i>
|
||||
<div class="info"><span class="meta">{{TimeSince .Created}}</span><br>{{ActionDesc . | str2html}}</div>
|
||||
<div class="info"><span class="meta">{{TimeSince .Created}}</span><br>{{ActionDesc . $avatarLink | str2html}}</div>
|
||||
<span class="clearfix"></span>
|
||||
</li>
|
||||
{{else}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Account Setting</h4>
|
||||
<ul class="list-group">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Account Setting</h4>
|
||||
<ul class="list-group">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div id="gogs-body" class="container">
|
||||
<div id="gogs-body" class="container" data-page="user">
|
||||
<div id="gogs-user-setting-nav" class="col-md-3">
|
||||
<h4>Account Setting</h4>
|
||||
<ul class="list-group">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div class="container" id="gogs-body">
|
||||
<div class="container" id="gogs-body" data-page="user-signin">
|
||||
<form action="/user/login" method="post" class="form-horizontal gogs-card" id="gogs-login-card">
|
||||
<h3>Log in</h3>
|
||||
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<div class="container" id="gogs-body">
|
||||
<div class="container" id="gogs-body" data-page="user-signup">
|
||||
<form action="/user/sign_up" method="post" class="form-horizontal gogs-card" id="gogs-login-card">
|
||||
<h3>Sign Up</h3>
|
||||
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div>
|
||||
|
|
6
web.go
6
web.go
|
@ -68,14 +68,16 @@ func runWeb(*cli.Context) {
|
|||
m.Get("/user/:username", middleware.SignInRequire(false), user.Profile)
|
||||
|
||||
m.Any("/repo/create", middleware.SignInRequire(true), binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create)
|
||||
m.Any("/repo/delete", middleware.SignInRequire(true), binding.Bind(auth.DeleteRepoForm{}), repo.Delete)
|
||||
|
||||
m.Get("/help", routers.Help)
|
||||
|
||||
m.Get("/:username/:reponame/settings", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Setting)
|
||||
m.Post("/:username/:reponame/settings", middleware.SignInRequire(true), middleware.RepoAssignment(true), repo.SettingPost)
|
||||
m.Get("/:username/:reponame/settings", middleware.SignInRequire(true), middleware.RepoAssignment(true), repo.Setting)
|
||||
|
||||
m.Get("/:username/:reponame/commits", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Commits)
|
||||
m.Get("/:username/:reponame/issues", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Issues)
|
||||
m.Get("/:username/:reponame/pulls", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Pulls)
|
||||
m.Get("/:username/:reponame/branches", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Branches)
|
||||
m.Get("/:username/:reponame/tree/:branchname/**",
|
||||
middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
||||
m.Get("/:username/:reponame/tree/:branchname",
|
||||
|
|
Loading…
Reference in a new issue