mirror of
https://github.com/gogs/gogs.git
synced 2026-03-01 17:50:59 +01:00
Compare commits
155 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54930c001d | ||
|
|
41dbb4c148 | ||
|
|
85c9f7c5f3 | ||
|
|
c31606daf9 | ||
|
|
d78abd3561 | ||
|
|
8c71ab5094 | ||
|
|
79262173a6 | ||
|
|
7b03b1df0e | ||
|
|
39931f8e00 | ||
|
|
1aa76bd279 | ||
|
|
54c9844d66 | ||
|
|
6705559ce0 | ||
|
|
8e8dfaf227 | ||
|
|
ce7422473a | ||
|
|
fc18741cc7 | ||
|
|
fef09c2de6 | ||
|
|
1e1f9e7166 | ||
|
|
64c68220d2 | ||
|
|
91e5c24a31 | ||
|
|
810ff480b8 | ||
|
|
de65c30770 | ||
|
|
bbf5bcdf99 | ||
|
|
02b53aff0f | ||
|
|
b694cc88e4 | ||
|
|
67c44b7d27 | ||
|
|
263d409326 | ||
|
|
6a79b76531 | ||
|
|
da0fbbadc2 | ||
|
|
1031271224 | ||
|
|
8c70bcee99 | ||
|
|
07c8925805 | ||
|
|
29a7d1ce61 | ||
|
|
500b8a2a0f | ||
|
|
ba1270df2d | ||
|
|
ba0feadc34 | ||
|
|
405ee14711 | ||
|
|
1126522a99 | ||
|
|
1601b27ad3 | ||
|
|
f03b6be8f9 | ||
|
|
3ffa17c49a | ||
|
|
98c719c342 | ||
|
|
2a031c1365 | ||
|
|
198567eccb | ||
|
|
f7de6d2b86 | ||
|
|
86eac0842b | ||
|
|
a046a31d2b | ||
|
|
cd084dacf1 | ||
|
|
ac2055e33c | ||
|
|
96f4c9045a | ||
|
|
d95e7065d9 | ||
|
|
5e48c89c5e | ||
|
|
3cfa4a581c | ||
|
|
ce6931a046 | ||
|
|
eb1e6f8e3e | ||
|
|
263fc76b87 | ||
|
|
c1d047d16e | ||
|
|
38f71af363 | ||
|
|
ecdbeea3f5 | ||
|
|
b7b0ee7df9 | ||
|
|
bb05ef907b | ||
|
|
204952439a | ||
|
|
e2e362f2dc | ||
|
|
26a0888bee | ||
|
|
9ce0bd043c | ||
|
|
5e747bc877 | ||
|
|
11af8658cf | ||
|
|
e6e6aaeacb | ||
|
|
e3b78c47e2 | ||
|
|
49193bebd2 | ||
|
|
3598c1435e | ||
|
|
ab59165d2f | ||
|
|
092b59a297 | ||
|
|
7d48f811f1 | ||
|
|
e3a27aeb25 | ||
|
|
dccc50e9d4 | ||
|
|
ad2ab6d214 | ||
|
|
b8368f98ff | ||
|
|
3164354255 | ||
|
|
54724c33ec | ||
|
|
d1911658e1 | ||
|
|
c8b50975bc | ||
|
|
10673417dc | ||
|
|
ad52b2d791 | ||
|
|
09c3c4e70c | ||
|
|
977779cdcf | ||
|
|
71e4689d11 | ||
|
|
f69761563b | ||
|
|
57d48fb6a2 | ||
|
|
7c30ae7002 | ||
|
|
089d934547 | ||
|
|
b0f8b1147c | ||
|
|
25268577a5 | ||
|
|
612fdb98df | ||
|
|
bd55b78775 | ||
|
|
5bbeeb0f1b | ||
|
|
93ee0838eb | ||
|
|
a1109e6fbc | ||
|
|
ebb05475ed | ||
|
|
a11ed51bbb | ||
|
|
e0493259a6 | ||
|
|
b3f0d25ce5 | ||
|
|
d750d53422 | ||
|
|
8d5a4cc9eb | ||
|
|
1476a1a729 | ||
|
|
e3eea745f4 | ||
|
|
60c65415dd | ||
|
|
b92cac7038 | ||
|
|
904f799c1a | ||
|
|
de2a4f8f83 | ||
|
|
135d3733b3 | ||
|
|
3f707b3f32 | ||
|
|
063aacd436 | ||
|
|
196efecaaa | ||
|
|
01e69af2c8 | ||
|
|
25c8d01676 | ||
|
|
7df60af60e | ||
|
|
79ec08141a | ||
|
|
150eef93b2 | ||
|
|
1273b3d3a9 | ||
|
|
b72d7c201a | ||
|
|
4a01bb8fa4 | ||
|
|
d325b23dbb | ||
|
|
976f1486e0 | ||
|
|
cb0ea46d1e | ||
|
|
052ab30409 | ||
|
|
7ba9257a7f | ||
|
|
6a7bd097fe | ||
|
|
0055cbd365 | ||
|
|
4f74b4e657 | ||
|
|
31d763bc1f | ||
|
|
a596388ebf | ||
|
|
8a09256941 | ||
|
|
c03f5a2c7c | ||
|
|
f94d7c3f51 | ||
|
|
061a879cea | ||
|
|
ed84adb679 | ||
|
|
9f015b4c73 | ||
|
|
bc3abb397f | ||
|
|
9e10304ab2 | ||
|
|
ae3639868e | ||
|
|
d082e821a0 | ||
|
|
78bd144c1c | ||
|
|
ebb4f1b78c | ||
|
|
62f21ff3ed | ||
|
|
0d9c41be7d | ||
|
|
c1ceec45da | ||
|
|
b162e565b3 | ||
|
|
6516ecaa51 | ||
|
|
5163d368e3 | ||
|
|
ad041167f7 | ||
|
|
cff3ca23a5 | ||
|
|
41386fa91a | ||
|
|
ea309acdb2 | ||
|
|
0f037b430a | ||
|
|
632b1b694d |
@@ -1,5 +1,8 @@
|
||||
[run]
|
||||
init_cmds = [["./gogs", "web"]]
|
||||
init_cmds = [
|
||||
["grep", "-rn", "FIXME", "."],
|
||||
["./gogs", "web"]
|
||||
]
|
||||
watch_all = true
|
||||
watch_dirs = [
|
||||
"$WORKDIR/conf/locale",
|
||||
@@ -11,7 +14,7 @@ watch_dirs = [
|
||||
watch_exts = [".go", ".ini"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["go", "install"],
|
||||
["go", "build"],
|
||||
["go", "install", "-tags", "sqlite cert"],
|
||||
["go", "build", "-tags", "sqlite cert"],
|
||||
["./gogs", "web"]
|
||||
]
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"paths": ["."],
|
||||
"depth": 2,
|
||||
"exclude": [],
|
||||
"include": ["\\.go$", "\\.ini$"],
|
||||
"command": [
|
||||
"bash", "-c", "go build && ./gogs web"
|
||||
],
|
||||
"env": {
|
||||
"POWERED_BY": "github.com/shxsun/fswatch"
|
||||
}
|
||||
}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -39,3 +39,6 @@ __pycache__
|
||||
output*
|
||||
config.codekit
|
||||
.brackets.json
|
||||
docker/fig.yml
|
||||
docker/docker/Dockerfile
|
||||
docker/docker/init_gogs.sh
|
||||
|
||||
@@ -10,3 +10,12 @@ filesets:
|
||||
- README_ZH.md
|
||||
excludes:
|
||||
- \.git
|
||||
settings:
|
||||
build: |
|
||||
if test "$GOOS" = "windows" -a "$GOARCH" = "386"
|
||||
then
|
||||
go install -v
|
||||
else
|
||||
go get -v -tags "sqlite redis memcache cert" github.com/gogits/gogs
|
||||
go install -v -tags "sqlite redis memcache cert"
|
||||
fi
|
||||
|
||||
11
.gopmfile
11
.gopmfile
@@ -8,7 +8,7 @@ github.com/Unknwon/cae = commit:2e70a1351b
|
||||
github.com/Unknwon/com = commit:2cbcbc6916
|
||||
github.com/Unknwon/goconfig = commit:0f8d8dc1c0
|
||||
github.com/Unknwon/i18n = commit:47baeff8d0
|
||||
github.com/Unknwon/macaron = commit:f22f45d79a
|
||||
github.com/Unknwon/macaron = commit:4927b78ad9
|
||||
github.com/codegangsta/cli = commit:7381bc4e62
|
||||
github.com/go-sql-driver/mysql = commit:8111ee3ec3
|
||||
github.com/go-xorm/core = commit:750aae0fa5
|
||||
@@ -17,13 +17,14 @@ github.com/gogits/gfm = commit:40f747a9c0
|
||||
github.com/gogits/oauth2 = commit:99cbec870a
|
||||
github.com/lib/pq = commit:b021d0ef20
|
||||
github.com/macaron-contrib/cache = commit:204d8e5137
|
||||
github.com/macaron-contrib/captcha = commit:8f3f1ac0e3
|
||||
github.com/macaron-contrib/csrf = commit:cd84c01723
|
||||
github.com/macaron-contrib/i18n = commit:489cc194b5
|
||||
github.com/macaron-contrib/session = commit:80a88a1bba
|
||||
github.com/macaron-contrib/captcha = commit:d37d37eeea
|
||||
github.com/macaron-contrib/csrf = commit:8e980822b0
|
||||
github.com/macaron-contrib/i18n = commit:2246f45894
|
||||
github.com/macaron-contrib/session = commit:42ad41e323
|
||||
github.com/macaron-contrib/toolbox = commit:57127bcc89
|
||||
github.com/mattn/go-sqlite3 = commit:a80c27ba33
|
||||
github.com/nfnt/resize = commit:581d15cb53
|
||||
github.com/russross/blackfriday = commit:05b8cefd6a
|
||||
github.com/saintfish/chardet = commit:3af4cd4741
|
||||
|
||||
[res]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
buildpack: "https://github.com/kr/heroku-buildpack-go.git"
|
||||
targets:
|
||||
ubuntu-14.04:
|
||||
ubuntu-12.04:
|
||||
debian-7:
|
||||
build_dependencies:
|
||||
- mercurial
|
||||
- bzr
|
||||
|
||||
@@ -2,5 +2,4 @@ language: go
|
||||
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- tip
|
||||
- 1.3
|
||||
16
README.md
16
README.md
@@ -1,16 +1,16 @@
|
||||
Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://drone.io/github.com/gogits/gogs/latest)
|
||||
Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://travis-ci.org/gogits/gogs)
|
||||
=====================
|
||||
|
||||
Gogs(Go Git Service) is a painless self-hosted Git Service written in Go.
|
||||
|
||||

|
||||
|
||||
##### Current version: 0.5.0 Beta
|
||||
##### Current version: 0.5.5 Beta
|
||||
|
||||
### NOTICES
|
||||
|
||||
- Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in **June 21, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
- Demo site [try.gogits.org](http://try.gogits.org) is running under `dev` branch.
|
||||
- Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **June 21, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
- Demo site [try.gogs.io](https://try.gogs.io) is running under `dev` branch.
|
||||
|
||||
#### Other language version
|
||||
|
||||
@@ -24,7 +24,7 @@ The goal of this project is to make the easiest, fastest and most painless way t
|
||||
|
||||
- Please see [Documentation](http://gogs.io/docs/intro/) for project design, known issues, and change log.
|
||||
- See [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
|
||||
- Try it before anything? Do it [online](http://try.gogits.org/Unknown/gogs) or go down to **Installation -> Install from binary** section!
|
||||
- Try it before anything? Do it [online](https://try.gogs.io/Unknown/gogs) or go down to **Installation -> Install from binary** section!
|
||||
- Having troubles? Get help from [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md).
|
||||
|
||||
## Features
|
||||
@@ -44,7 +44,7 @@ The goal of this project is to make the easiest, fastest and most painless way t
|
||||
- Slack webhook integration
|
||||
- Supports MySQL, PostgreSQL and SQLite3
|
||||
- Social account login(GitHub, Google, QQ, Weibo)
|
||||
- Multi-language support(English, Chinese, Germany etc.)
|
||||
- Multi-language support(English, Simplified Chinese, Traditional Chinese, Germany, French, Dutch etc.)
|
||||
|
||||
## System Requirements
|
||||
|
||||
@@ -57,7 +57,7 @@ Make sure you install [Prerequirements](http://gogs.io/docs/installation/) first
|
||||
|
||||
There are 5 ways to install Gogs:
|
||||
|
||||
- [Install from binary](http://gogs.io/docs/installation/install_from_binary.md): **STRONGLY RECOMMENDED**
|
||||
- [Install from binary](http://gogs.io/docs/installation/install_from_binary.md)
|
||||
- [Install from source](http://gogs.io/docs/installation/install_from_source.md)
|
||||
- [Install from packages](http://gogs.io/docs/installation/install_from_packages.md)
|
||||
- [Ship with Docker](https://github.com/gogits/gogs/tree/master/docker)
|
||||
@@ -65,7 +65,7 @@ There are 5 ways to install Gogs:
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- Router and middleware mechanism of [martini](http://martini.codegangsta.io/).
|
||||
- Router and middleware mechanism of [Macaron](https://github.com/Unknwon/macaron).
|
||||
- Mail Service, modules design is inspired by [WeTalk](https://github.com/beego/wetalk).
|
||||
- System Monitor Status is inspired by [GoBlog](https://github.com/fuxiaohei/goblog).
|
||||
- Usage and modification from [beego](http://beego.me) modules.
|
||||
|
||||
14
README_ZH.md
14
README_ZH.md
@@ -1,11 +1,11 @@
|
||||
Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://drone.io/github.com/gogits/gogs/latest)
|
||||
Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://travis-ci.org/gogits/gogs)
|
||||
=====================
|
||||
|
||||
Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。
|
||||
|
||||

|
||||
|
||||
##### 当前版本:0.5.0 Beta
|
||||
##### 当前版本:0.5.5 Beta
|
||||
|
||||
## 开发目的
|
||||
|
||||
@@ -15,7 +15,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
|
||||
- 有关项目设计、已知问题和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
|
||||
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
|
||||
- 想要先睹为快?通过 [在线体验](http://try.gogits.org/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
|
||||
- 想要先睹为快?通过 [在线体验](https://try.gogs.io/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
|
||||
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.md) 页面获取帮助。
|
||||
|
||||
## 功能特性
|
||||
@@ -35,7 +35,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
- Slack Web 钩子集成
|
||||
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
|
||||
- 社交帐号登录(GitHub、Google、QQ、微博)
|
||||
- 多语言支持(英文、简体中文、德语等等)
|
||||
- 多语言支持(英文、简体中文、繁体中文、德语、法语、荷兰语等等)
|
||||
|
||||
## 系统要求
|
||||
|
||||
@@ -48,7 +48,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
|
||||
然后,您可以通过以下 5 种方式来安装 Gogs:
|
||||
|
||||
- [二进制安装](http://gogs.io/docs/installation/install_from_binary.md): **强烈推荐**
|
||||
- [二进制安装](http://gogs.io/docs/installation/install_from_binary.md)
|
||||
- [源码安装](http://gogs.io/docs/installation/install_from_source.md)
|
||||
- [包管理安装](http://gogs.io/docs/installation/install_from_packages.md)
|
||||
- [采用 Docker 部署](https://github.com/gogits/gogs/tree/master/docker)
|
||||
@@ -56,10 +56,10 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
|
||||
## 特别鸣谢
|
||||
|
||||
- [Macaron](https://github.com/Unknwon/macaron) 的路由与中间件机制。
|
||||
- [beego](http://beego.me) 模块的使用与修改。
|
||||
- 基于 [WeTalk](https://github.com/beego/wetalk) 修改的邮件服务和模块设计。
|
||||
- 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。
|
||||
- [beego](http://beego.me) 模块的使用与修改。
|
||||
- [martini](http://martini.codegangsta.io/) 的路由与中间件机制。
|
||||
- 感谢 [gobuild.io](http://gobuild.io) 提供二进制编译与下载服务。
|
||||
- 感谢 [lavachen](http://www.lavachen.cn/) 和 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。
|
||||
|
||||
|
||||
160
cmd/cert.go
Normal file
160
cmd/cert.go
Normal file
@@ -0,0 +1,160 @@
|
||||
// +build cert
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// 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 cmd
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
var CmdCert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
|
||||
Action: runCert,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
|
||||
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
|
||||
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
|
||||
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
|
||||
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
|
||||
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
|
||||
},
|
||||
}
|
||||
|
||||
func publicKey(priv interface{}) interface{} {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &k.PublicKey
|
||||
case *ecdsa.PrivateKey:
|
||||
return &k.PublicKey
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
|
||||
case *ecdsa.PrivateKey:
|
||||
b, err := x509.MarshalECPrivateKey(k)
|
||||
if err != nil {
|
||||
log.Fatal("unable to marshal ECDSA private key: %v", err)
|
||||
}
|
||||
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func runCert(ctx *cli.Context) {
|
||||
if len(ctx.String("host")) == 0 {
|
||||
log.Fatal("Missing required --host parameter")
|
||||
}
|
||||
|
||||
var priv interface{}
|
||||
var err error
|
||||
switch ctx.String("ecdsa-curve") {
|
||||
case "":
|
||||
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits"))
|
||||
case "P224":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||
case "P256":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
case "P384":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
case "P521":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
default:
|
||||
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve"))
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate private key: %s", err)
|
||||
}
|
||||
|
||||
var notBefore time.Time
|
||||
if len(ctx.String("start-date")) == 0 {
|
||||
notBefore = time.Now()
|
||||
} else {
|
||||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date"))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse creation date: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
notAfter := notBefore.Add(ctx.Duration("duration"))
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate serial number: %s", err)
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"Acme Co"},
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
hosts := strings.Split(ctx.String("host"), ",")
|
||||
for _, h := range hosts {
|
||||
if ip := net.ParseIP(h); ip != nil {
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, h)
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Bool("ca") {
|
||||
template.IsCA = true
|
||||
template.KeyUsage |= x509.KeyUsageCertSign
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create certificate: %s", err)
|
||||
}
|
||||
|
||||
certOut, err := os.Create("cert.pem")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open cert.pem for writing: %s", err)
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
log.Println("Written cert.pem")
|
||||
|
||||
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
log.Fatal("failed to open key.pem for writing: %v", err)
|
||||
}
|
||||
pem.Encode(keyOut, pemBlockForKey(priv))
|
||||
keyOut.Close()
|
||||
log.Println("Written key.pem")
|
||||
}
|
||||
34
cmd/cert_stub.go
Normal file
34
cmd/cert_stub.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// +build !cert
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// 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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
var CmdCert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
|
||||
Action: runCert,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
|
||||
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
|
||||
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
|
||||
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
|
||||
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
|
||||
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
|
||||
},
|
||||
}
|
||||
|
||||
func runCert(ctx *cli.Context) {
|
||||
fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
|
||||
}
|
||||
@@ -171,7 +171,13 @@ func runServ(k *cli.Context) {
|
||||
uuid := uuid.NewV4().String()
|
||||
os.Setenv("uuid", uuid)
|
||||
|
||||
gitcmd := exec.Command(verb, repoPath)
|
||||
var gitcmd *exec.Cmd
|
||||
verbs := strings.Split(verb, " ")
|
||||
if len(verbs) == 2 {
|
||||
gitcmd = exec.Command(verbs[0], verbs[1], repoPath)
|
||||
} else {
|
||||
gitcmd = exec.Command(verb, repoPath)
|
||||
}
|
||||
gitcmd.Dir = setting.RepoRootPath
|
||||
gitcmd.Stdout = os.Stdout
|
||||
gitcmd.Stdin = os.Stdin
|
||||
|
||||
78
cmd/web.go
78
cmd/web.go
@@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/macaron"
|
||||
"github.com/codegangsta/cli"
|
||||
@@ -26,6 +27,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/auth/apiv1"
|
||||
"github.com/gogits/gogs/modules/avatar"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/middleware/binding"
|
||||
@@ -50,6 +52,7 @@ and it takes care of all the other things for you`,
|
||||
|
||||
// checkVersion checks if binary matches the version of templates files.
|
||||
func checkVersion() {
|
||||
// Templates.
|
||||
data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION"))
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
|
||||
@@ -57,6 +60,20 @@ func checkVersion() {
|
||||
if string(data) != setting.AppVer {
|
||||
log.Fatal(4, "Binary and template file version does not match, did you forget to recompile?")
|
||||
}
|
||||
|
||||
// Check dependency version.
|
||||
macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ".")[:3], "."))
|
||||
if macaronVer.LessThan(git.MustParseVersion("0.2.0")) {
|
||||
log.Fatal(4, "Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)")
|
||||
}
|
||||
i18nVer := git.MustParseVersion(i18n.Version())
|
||||
if i18nVer.LessThan(git.MustParseVersion("0.0.2")) {
|
||||
log.Fatal(4, "Package i18n version is too old, did you forget to update?(github.com/macaron-contrib/i18n)")
|
||||
}
|
||||
sessionVer := git.MustParseVersion(session.Version())
|
||||
if sessionVer.LessThan(git.MustParseVersion("0.0.1")) {
|
||||
log.Fatal(4, "Package session version is too old, did you forget to update?(github.com/macaron-contrib/session)")
|
||||
}
|
||||
}
|
||||
|
||||
// newMacaron initializes Macaron instance.
|
||||
@@ -64,7 +81,8 @@ func newMacaron() *macaron.Macaron {
|
||||
m := macaron.New()
|
||||
m.Use(macaron.Logger())
|
||||
m.Use(macaron.Recovery())
|
||||
m.Use(macaron.Static("public",
|
||||
m.Use(macaron.Static(
|
||||
path.Join(setting.StaticRootPath, "public"),
|
||||
macaron.StaticOptions{
|
||||
SkipLogging: !setting.DisableRouterLog,
|
||||
},
|
||||
@@ -78,24 +96,30 @@ func newMacaron() *macaron.Macaron {
|
||||
IndentJSON: macaron.Env != macaron.PROD,
|
||||
}))
|
||||
m.Use(i18n.I18n(i18n.Options{
|
||||
Langs: setting.Langs,
|
||||
Names: setting.Names,
|
||||
Redirect: true,
|
||||
SubURL: setting.AppSubUrl,
|
||||
Directory: path.Join(setting.ConfRootPath, "locale"),
|
||||
CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
|
||||
Langs: setting.Langs,
|
||||
Names: setting.Names,
|
||||
Redirect: true,
|
||||
}))
|
||||
m.Use(cache.Cacher(cache.Options{
|
||||
Adapter: setting.CacheAdapter,
|
||||
Interval: setting.CacheInternal,
|
||||
Conn: setting.CacheConn,
|
||||
}))
|
||||
m.Use(captcha.Captchaer())
|
||||
m.Use(captcha.Captchaer(captcha.Options{
|
||||
SubURL: setting.AppSubUrl,
|
||||
}))
|
||||
m.Use(session.Sessioner(session.Options{
|
||||
Provider: setting.SessionProvider,
|
||||
Config: *setting.SessionConfig,
|
||||
}))
|
||||
m.Use(csrf.Generate(csrf.Options{
|
||||
Secret: setting.SecretKey,
|
||||
SetCookie: true,
|
||||
Header: "X-Csrf-Token",
|
||||
Secret: setting.SecretKey,
|
||||
SetCookie: true,
|
||||
Header: "X-Csrf-Token",
|
||||
CookiePath: setting.AppSubUrl,
|
||||
}))
|
||||
m.Use(toolbox.Toolboxer(m, toolbox.Options{
|
||||
HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
|
||||
@@ -124,7 +148,7 @@ func runWeb(*cli.Context) {
|
||||
|
||||
// Routers.
|
||||
m.Get("/", ignSignIn, routers.Home)
|
||||
m.Get("/explore", routers.Explore)
|
||||
m.Get("/explore", ignSignIn, routers.Explore)
|
||||
m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
|
||||
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
|
||||
m.Group("", func(r *macaron.Router) {
|
||||
@@ -185,7 +209,8 @@ func runWeb(*cli.Context) {
|
||||
r.Get("/logout", user.SignOut)
|
||||
})
|
||||
|
||||
m.Get("/user/:username", ignSignIn, user.Profile) // TODO: Legacy
|
||||
// FIXME: Legacy
|
||||
m.Get("/user/:username", ignSignIn, user.Profile)
|
||||
|
||||
// Gravatar service.
|
||||
avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg")
|
||||
@@ -224,6 +249,11 @@ func runWeb(*cli.Context) {
|
||||
r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost)
|
||||
r.Post("/:authid/delete", admin.DeleteAuthSource)
|
||||
})
|
||||
|
||||
m.Group("/notices", func(r *macaron.Router) {
|
||||
r.Get("", admin.Notices)
|
||||
r.Get("/:id:int/delete", admin.DeleteNotice)
|
||||
})
|
||||
}, adminReq)
|
||||
|
||||
m.Get("/:username", ignSignIn, user.Profile)
|
||||
@@ -298,6 +328,12 @@ func runWeb(*cli.Context) {
|
||||
r.Get("/hooks/:id", repo.WebHooksEdit)
|
||||
r.Post("/hooks/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||
r.Post("/hooks/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
||||
|
||||
m.Group("/hooks/git", func(r *macaron.Router) {
|
||||
r.Get("", repo.GitHooks)
|
||||
r.Get("/:name", repo.GitHooksEdit)
|
||||
r.Post("/:name", repo.GitHooksEditPost)
|
||||
}, middleware.GitHookService())
|
||||
})
|
||||
}, reqSignIn, middleware.RepoAssignment(true), reqTrueOwner)
|
||||
|
||||
@@ -338,6 +374,8 @@ func runWeb(*cli.Context) {
|
||||
r.Get("/issues/:index", repo.ViewIssue)
|
||||
r.Get("/pulls", repo.Pulls)
|
||||
r.Get("/branches", repo.Branches)
|
||||
r.Get("/archive/*", repo.Download)
|
||||
r.Get("/issues2/", repo.Issues2)
|
||||
}, ignSignIn, middleware.RepoAssignment(true))
|
||||
|
||||
m.Group("/:username/:reponame", func(r *macaron.Router) {
|
||||
@@ -350,23 +388,29 @@ func runWeb(*cli.Context) {
|
||||
r.Get("/commit/:branchname", repo.Diff)
|
||||
r.Get("/commit/:branchname/*", repo.Diff)
|
||||
r.Get("/releases", repo.Releases)
|
||||
r.Get("/archive/*.*", repo.Download)
|
||||
r.Get("/compare/:before([a-z0-9]+)...:after([a-z0-9]+)", repo.CompareDiff)
|
||||
}, ignSignIn, middleware.RepoAssignment(true, true))
|
||||
|
||||
m.Group("/:username", func(r *macaron.Router) {
|
||||
r.Get("/:reponame", middleware.RepoAssignment(true, true, true), repo.Home)
|
||||
m.Group("/:reponame", func(r *macaron.Router) {
|
||||
r.Any("/*", repo.Http)
|
||||
})
|
||||
}, ignSignInAndCsrf)
|
||||
r.Get("/:reponame", ignSignIn, middleware.RepoAssignment(true, true, true), repo.Home)
|
||||
r.Any("/:reponame/*", ignSignInAndCsrf, repo.Http)
|
||||
})
|
||||
|
||||
// robots.txt
|
||||
m.Get("/robots.txt", func(ctx *middleware.Context) {
|
||||
if setting.HasRobotsTxt {
|
||||
ctx.ServeFile(path.Join(setting.CustomPath, "robots.txt"))
|
||||
} else {
|
||||
ctx.Error(404)
|
||||
}
|
||||
})
|
||||
|
||||
// Not found handler.
|
||||
m.NotFound(routers.NotFound)
|
||||
|
||||
var err error
|
||||
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
|
||||
log.Info("Listen: %v://%s", setting.Protocol, listenAddr)
|
||||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
|
||||
switch setting.Protocol {
|
||||
case setting.HTTP:
|
||||
err = http.ListenAndServe(listenAddr, m)
|
||||
|
||||
11
conf/app.ini
11
conf/app.ini
@@ -21,7 +21,7 @@ OFFLINE_MODE = false
|
||||
DISABLE_ROUTER_LOG = false
|
||||
; Generate steps:
|
||||
; $ cd path/to/gogs/custom/https
|
||||
; $ go run $GOROOT/src/pkg/crypto/tls/generate_cert.go -ca=true -duration=8760h0m0s -host=myhost.example.com
|
||||
; $ ./gogs cert -ca=true -duration=8760h0m0s -host=myhost.example.com
|
||||
CERT_FILE = custom/https/cert.pem
|
||||
KEY_FILE = custom/https/key.pem
|
||||
; Upper level of template and static file path
|
||||
@@ -70,6 +70,8 @@ ENABLE_CACHE_AVATAR = false
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
; More detail: https://github.com/gogits/gogs/issues/165
|
||||
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
|
||||
; Repository Git hooks
|
||||
ENABLE_GIT_HOOKS = false
|
||||
|
||||
[webhook]
|
||||
; Cron task interval in minutes
|
||||
@@ -252,6 +254,9 @@ DRIVER =
|
||||
; Based on xorm, e.g.: root:root@localhost/gogs?charset=utf8
|
||||
CONN =
|
||||
|
||||
[git]
|
||||
MAX_GITDIFF_LINES = 10000
|
||||
|
||||
[i18n]
|
||||
LANGS = en-US,zh-CN,de-DE
|
||||
NAMES = English,简体中文,Deutsch
|
||||
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL
|
||||
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands
|
||||
|
||||
@@ -5,9 +5,9 @@ dashboard = Dashboard
|
||||
explore = Erkunden
|
||||
help = Hilfe
|
||||
sign_in = Anmelden
|
||||
social_sign_in = Social Sign In: 2nd Step <small>associate account</small>
|
||||
social_sign_in = Anmeldung über soziales Konto: zweiter Schritt <small>Konto verknüpfen</small>
|
||||
sign_out = Abmelden
|
||||
sign_up = Sign up
|
||||
sign_up = Registrieren
|
||||
register = Registrieren
|
||||
website = Webseite
|
||||
version = Version
|
||||
@@ -18,7 +18,7 @@ language = Sprache
|
||||
username = Benutzername
|
||||
email = E-Mail
|
||||
password = Passwort
|
||||
re_type = wiederholen
|
||||
re_type = Passwort bestätigen
|
||||
captcha = Captcha
|
||||
|
||||
repository = Repository
|
||||
@@ -38,15 +38,62 @@ issues = Issues
|
||||
|
||||
cancel = Abbrechen
|
||||
|
||||
[install]
|
||||
install = Installation
|
||||
title = Installation für erstmaligen Start
|
||||
requite_db_desc = Gogs erfordert MySQL, PostgreSQL oder SQLite 3, aber SQLite3 ist in der offiziellen binären Version akiviert.
|
||||
db_type = Datenbanktyp
|
||||
host = Host
|
||||
user = Benutzer
|
||||
password = Passwort
|
||||
db_name = Datenbankname
|
||||
db_helper = Bitte verwenden InnoDB-Engine mit utf8_general_ci Zeichensatz für MySQL.
|
||||
ssl_mode = SSL-Modus
|
||||
path = Pfad
|
||||
sqlite_helper = Der Dateipfad des SQLite3 Datenbank.
|
||||
general_title = Allgemeine Einstellungen von Gogs
|
||||
repo_path = Repository Root-Verzeichnispfad
|
||||
repo_path_helper = Alle Git-Repositorys werden in diesem Verzeichnis gespeichert.
|
||||
run_user = Ausführender Benutzer
|
||||
run_user_helper = Der Benutzer muss die Zugriffsberechtigung für das Repository Root-Verzeichnis haben und der ausführende Benutzer von Gogs sein.
|
||||
domain = Domain
|
||||
domain_helper = Dies hat Auswirkung auf die SSH clone URLs.
|
||||
app_url = Anwendungs-URL
|
||||
app_url_helper = Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails.
|
||||
email_title = E-Mail-Service-Einstellungen (optional)
|
||||
smtp_host = SMTP Host
|
||||
mailer_user = Sender E-mail
|
||||
mailer_password = Sender Passwort
|
||||
notify_title = Benachrichtigungseinstellungen (optional)
|
||||
register_confirm = Registrierungsbestätigung aktvieren
|
||||
mail_notify = E-Mail-Benachrichtgung aktivieren
|
||||
admin_title = Konto-Einstellungen für den Administrator
|
||||
admin_name = Benutzername
|
||||
admin_password = Passwort
|
||||
confirm_password = Passwort bestätigen
|
||||
admin_email = E-Mail
|
||||
install_gogs = Gogs installieren
|
||||
test_git_failed = Fehler beim Test des 'git' Kommandos: %v
|
||||
sqlite3_not_available = Deine Version unterstüzt nicht SQLite3, bitte downloade dir die offiziele binäre Version von http://gogs.io/docs/installation/install_from_binary.html, NICHT die gobuild Version.
|
||||
invalid_db_setting = Datenbank-Einstellungen sind nicht korrekt: %v
|
||||
invalid_repo_path = Repository Root-Verzeichnis ist ungültig: %v
|
||||
run_user_not_match = Der ausführende Benutzer ist nicht der aktuelle Benutzer: %s -> %s
|
||||
save_config_failed = Versuche die Konfiguration zu speichern ist fehlgeschlagen: %v
|
||||
invalid_admin_setting = Admin-Konto Einstellungen sind ungültig: %v
|
||||
install_success = Herzlich Willkommen! Wir sind froh, dass du dich für Gogs entschieden hast. Hab viel Vergnügen damit.
|
||||
|
||||
[home]
|
||||
uname_holder = Benutzername oder E-Mail
|
||||
password_holder = Passwort
|
||||
switch_dashboard_context = Switch Dashboard Context
|
||||
switch_dashboard_context = Dashboard Kontext wechseln
|
||||
my_repos = Meine Repositorys
|
||||
collaborative_repos = Gemeinschaftliche Repositorys
|
||||
my_orgs = Meine Organisationen
|
||||
my_mirrors = Meine Spiegel
|
||||
|
||||
[explore]
|
||||
repos = Repositorys
|
||||
|
||||
[auth]
|
||||
create_new_account = Neues Konto erstellen
|
||||
register_hepler_msg = Du hast schon ein Konto? Jetzt anmelden!
|
||||
@@ -57,9 +104,9 @@ remember_me = angemeldet bleiben
|
||||
forgot_password= Passwort vergessen
|
||||
forget_password = Passwort vergessen?
|
||||
sign_up_now = Du willst ein Konto? Jetzt registrieren!
|
||||
confirmation_mail_sent_prompt = Eine neu Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden um die Registrierung abzuschließen.
|
||||
sign_in_email = Melden dich mit deiner E-Mail-Adresse an
|
||||
active_your_account = Aktivieren dein Konto
|
||||
confirmation_mail_sent_prompt = Eine neue Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden, um die Registrierung abzuschließen.
|
||||
sign_in_email = Melde dich mit deiner E-Mail-Adresse an
|
||||
active_your_account = Aktiviere dein Konto
|
||||
resent_limit_prompt = Es tut uns leid, du sendest zu häufig Aktivierungs-E-Mails. Bitte warte 3 Minuten.
|
||||
has_unconfirmed_mail = Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Falls du noch keine Bestätigungs-E-Mail erhalten hast oder eine neue senden musst, klicke auf den unteren Button.
|
||||
resend_mail = Hier klicken, um deine Aktivierungs-E-Mail erneut zu versenden
|
||||
@@ -75,12 +122,13 @@ UserName = Benutzername
|
||||
RepoName = Repository-Name
|
||||
Email = E-Mail-Adresse
|
||||
Password = Passwort
|
||||
Retype = Passwort erneut eingeben
|
||||
Retype = Passwort bestätigen
|
||||
SSHTitle = SSH-Schlüsselname
|
||||
HttpsUrl = HTTPS-URL
|
||||
PayloadUrl = Payload-URL
|
||||
TeamName = Teamname
|
||||
AuthName = Authentifizierungsname
|
||||
AdminEmail = Admin E-mail
|
||||
|
||||
require_error = ` darf nicht leer sein.`
|
||||
alpha_dash_error = ` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
|
||||
@@ -110,7 +158,7 @@ enterred_invalid_password = Bitte stelle sicher, dass das eingegebene Passwort r
|
||||
user_not_exist = Angegebener Benutzer existiert nicht.
|
||||
last_org_owner = Der zu entfernende Benutzer ist der letzte Teambesitzer. Es muss einen anderen Besitzer geben.
|
||||
|
||||
invalid_ssh_key = Leider sind wir nicht in der Lage, Ihren SSH-Schlüssel zu überprüfen: %s
|
||||
invalid_ssh_key = Leider sind wir nicht in der Lage, deinen SSH-Schlüssel zu überprüfen: %s
|
||||
auth_failed = Authentifizierung fehlgeschlagen: %v
|
||||
|
||||
still_own_repo = Dein Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
|
||||
@@ -118,6 +166,15 @@ org_still_own_repo = Diese Organisation besitzt noch Repositorys. Diese müssen
|
||||
|
||||
still_own_user = Diese Authentifizierung wird noch von einigen Benutzern genutzt. Entferne diese zuvor und lösche erneut.
|
||||
|
||||
[user]
|
||||
change_avatar = Ändere dein Profilbild auf gravatar.com
|
||||
join_on = Registriert
|
||||
repositories = Repositorys
|
||||
activity = Öffentliche Aktivität
|
||||
followers = Folgen
|
||||
starred = Markiert
|
||||
following = Folgt
|
||||
|
||||
[settings]
|
||||
profile = Profil
|
||||
password = Passwort
|
||||
@@ -125,6 +182,7 @@ ssh_keys = SSH-Schlüssel
|
||||
social = Soziale Konten
|
||||
orgs = Organisationen
|
||||
delete = Konto löschen
|
||||
uid = Uid
|
||||
|
||||
public_profile = Öffentliches Profil
|
||||
profile_desc = Deine E-Mail-Adresse ist öffentlich und dient dazu, dir Benachrichtigungen bezüglich deines Kontos und deiner Repositorys zu schicken.
|
||||
@@ -178,7 +236,6 @@ create_repo = Repository erstellen
|
||||
default_branch = Standard-Branch
|
||||
mirror_interval = Spiegel-Intervall (in Stunden)
|
||||
goget_meta = Go-Get Meta
|
||||
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
|
||||
goget_meta_helper = Dieses Repository wird man mit <span class="label label-blue label-radius">go get</span> klonen können.
|
||||
|
||||
need_auth = Authorisierung benötigt
|
||||
@@ -187,7 +244,7 @@ migrate_type_helper = Dieses Repository wird ein <span class="label label-blue l
|
||||
migrate_repo = Repository migrieren
|
||||
|
||||
copy_link = Klonen
|
||||
clone_helper = Du brauchst Hilef beim klonen? Hier gibt es<a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Hilfe</a>!
|
||||
clone_helper = Du brauchst Hilfe beim Klonen? Hier gibt es <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Hilfe</a>!
|
||||
unwatch = Beobachtung beenden
|
||||
watch = Beobachtung
|
||||
unstar = Markierung aufheben
|
||||
@@ -197,7 +254,7 @@ fork = Abspaltung
|
||||
quick_guide = Kurzanleitung
|
||||
clone_this_repo = Dieses Repository klonen
|
||||
create_new_repo_command = Erstelle ein neues Repository mittels der Kommandozeile
|
||||
push_exist_repo = Push an existing repository from the command line
|
||||
push_exist_repo = Übertrage ein existierendes Repository von der Kommandozeile
|
||||
|
||||
settings = Einstellungen
|
||||
settings.options = Optionen
|
||||
@@ -210,11 +267,13 @@ settings.site = Offizielle Webseite
|
||||
settings.update_settings = Aktualisierungseinstellungen
|
||||
settings.transfer = Besitz übertragen
|
||||
settings.transfer_desc = Übertrage dieses Repository einem anderen Benutzer oder einer Organisation.
|
||||
settings.new_owner_has_same_repo = Neuer Eigentümer hat bereits ein Repository mit dem gleichen Namen.
|
||||
settings.delete = Repository löschen
|
||||
settings.delete_desc = Wenn dieses Repository gelöschet ist, gibt es keinen Weg zurück. Sei dir sicher!
|
||||
settings.delete_desc = Wenn dieses Repository gelöscht ist, gibt es keinen Weg zurück. Sei dir sicher!
|
||||
settings.update_settings_success = Repository-Optionen aktualisiert
|
||||
settings.transfer_owner = Neuer Besitzer
|
||||
settings.make_transfer = übertragen
|
||||
settings.transfer_succeed = Repository-Eigentum wurde erfolgreich übertragen.
|
||||
settings.confirm_delete = Löschen
|
||||
settings.add_collaborator = Mitarbeiter hinzufügen
|
||||
settings.add_collaborator_success = Mitarbeiter hinzugefügt
|
||||
@@ -235,7 +294,7 @@ settings.update_webhook = Webhook aktualisieren
|
||||
settings.update_hook_success = Webhook aktualisiert
|
||||
settings.delete_webhook = Webhook löschen
|
||||
settings.recent_deliveries = letzte Zustellungen
|
||||
settings.hook_type = Hook Type
|
||||
settings.hook_type = Hook Typ
|
||||
settings.add_slack_hook_desc = Add <a href="http://slack.com">Slack</a> integration to your repository.
|
||||
settings.slack_token = Token
|
||||
settings.slack_domain = Domain
|
||||
@@ -271,6 +330,7 @@ settings.delete = Organisation löschen
|
||||
settings.delete_account = Diese Organisation löschen
|
||||
settings.delete_prompt = Die Organisation wird dauerhaft gelöscht. Dies kann <strong>NICHT</strong> rückgängig gemacht werden!
|
||||
settings.confirm_delete_account = Löschen
|
||||
settings.hooks_desc = Füge Webhooks hinzu, die für <strong>alle</strong> Repositorys dieser Organisation ausgelöst werden.
|
||||
|
||||
members.public = Öffentlich
|
||||
members.public_helper = Privat machen
|
||||
@@ -321,8 +381,8 @@ next = vor
|
||||
dashboard.statistic = Statistik
|
||||
dashboard.operations = Operationen
|
||||
dashboard.system_status = System-Monitor-Status
|
||||
dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organizationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> Zugriffe, <b>%d</b> issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> follows, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge.
|
||||
dashboard.operation_name = Operation Name
|
||||
dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organisationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> Beobachtungen, <b>%d</b> Markierungen, <b>%d</b> Aktionen, <b>%d</b> Zugriffe, <b>%d</b> Issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> Folgende, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge.
|
||||
dashboard.operation_name = Name der Operation
|
||||
dashboard.operation_switch = Switch
|
||||
dashboard.operation_run = Ausführen
|
||||
dashboard.clean_unbind_oauth = ungebundene OAuths bereinigen
|
||||
@@ -385,12 +445,12 @@ repos.repo_manage_panel = Repositorys
|
||||
repos.owner = Besitzer
|
||||
repos.name = Name
|
||||
repos.private = Privat
|
||||
repos.watches = Watches
|
||||
repos.stars = Stars
|
||||
repos.watches = Beobachtungen
|
||||
repos.stars = Markierungen
|
||||
repos.issues = Issues
|
||||
|
||||
auths.auth_manage_panel = Authentifizierung
|
||||
auths.new = Neu Authentifizierungsquelle hinzufügen
|
||||
auths.new = Neue Authentifizierungsquelle hinzufügen
|
||||
auths.name = Name
|
||||
auths.type = Typ
|
||||
auths.enabled = aktiviert
|
||||
@@ -442,11 +502,11 @@ config.db_path_helper = (nur für "sqlite3")
|
||||
config.service_config = Service-Einstellungen
|
||||
config.register_email_confirm = E-Mail-Bestätigung bei Registrierung
|
||||
config.disable_register = Registrierung deaktivieren
|
||||
config.require_sign_in_view = Require Sign In View
|
||||
config.require_sign_in_view = Ansehen erfordert Registrierung
|
||||
config.mail_notify = E-Mail-Benachrichtigung
|
||||
config.enable_cache_avatar = Avatar-Cache aktivieren
|
||||
config.active_code_lives = Active Code Lives
|
||||
config.reset_password_code_lives = Reset Password Code Lives
|
||||
config.active_code_lives = Aktivierungscode Lebensdauer
|
||||
config.reset_password_code_lives = Passwortcode Lebensdauer
|
||||
config.webhook_config = Webhook-Einstellungen
|
||||
config.task_interval = Task-Intervall
|
||||
config.deliver_timeout = Zeitlimit für Zustellung
|
||||
@@ -465,7 +525,7 @@ config.session_config = Session-Einstellungen
|
||||
config.session_provider = Session-Provider
|
||||
config.provider_config = Provider-Einstellungen
|
||||
config.cookie_name = Cookie-Name
|
||||
config.enable_set_cookie = Enable Set Cookie
|
||||
config.enable_set_cookie = Cookies einschalten
|
||||
config.gc_interval_time = GC-Intervallzeit
|
||||
config.session_life_time = Session-Lebensdauer
|
||||
config.https_only = nur HTTPS
|
||||
@@ -483,17 +543,18 @@ monitor.name = Name
|
||||
monitor.schedule = Zeitplan
|
||||
monitor.next = nächste Ausführung
|
||||
monitor.previous = letzte Ausführung
|
||||
monitor.execute_times = Execute Times
|
||||
monitor.execute_times = Anzahl Ausführungen
|
||||
monitor.process = Laufende Prozesse
|
||||
monitor.desc = Beschreibung
|
||||
monitor.start = Startzeit
|
||||
monitor.execute_time = Ausführungszeit
|
||||
|
||||
[action]
|
||||
create_repo = Repository erstellen <a href="/%s">%s</a>
|
||||
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
|
||||
create_issue = opened issue <a href="/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = commented on issue <a href="/%s/issues/%s">%s#%s</a>
|
||||
create_repo = hat Repository <a href="%s/%s">%s</a> erstellt
|
||||
commit_repo = hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht
|
||||
create_issue = hat Issue <a href="%s/%s/issues/%s">%s#%s</a> eröffnet
|
||||
comment_issue = hat Issue <a href="%s/%s/issues/%s">%s#%s</a> kommentiert
|
||||
transfer_repo = hat Repository <code>%s</code> transferiert an <a href="/%s%s">%s</a>
|
||||
|
||||
[tool]
|
||||
ago = vor
|
||||
|
||||
@@ -166,6 +166,15 @@ org_still_own_repo = This organization still have ownership of repository, you h
|
||||
|
||||
still_own_user = This authentication still has used by some users, you should move them and then delete again.
|
||||
|
||||
[user]
|
||||
change_avatar = Change your avatar at gravatar.com
|
||||
join_on = Joined on
|
||||
repositories = Repositories
|
||||
activity = Public Activity
|
||||
followers = Followers
|
||||
starred = Starred
|
||||
following = Following
|
||||
|
||||
[settings]
|
||||
profile = Profile
|
||||
password = Password
|
||||
@@ -182,6 +191,10 @@ website = Website
|
||||
location = Location
|
||||
update_profile = Update Profile
|
||||
update_profile_success = Your profile has been successfully updated.
|
||||
change_username = Username Changed
|
||||
change_username_desc = Username has been changed, do you want to continue? This will affect all links relate to your account.
|
||||
continue = Continue
|
||||
cancel = Cancel
|
||||
|
||||
change_password = Change Password
|
||||
old_password = Current Password
|
||||
@@ -210,6 +223,8 @@ unbind_success = Social account has been unbound.
|
||||
delete_account = Delete Your Account
|
||||
delete_prompt = The operation will delete your account permanently, and <strong>CANNOT</strong> be undone!
|
||||
confirm_delete_account = Confirm Deletion
|
||||
delete_account_title = Account Deletion
|
||||
delete_account_desc = This account is going to be deleted permanently, do you want to continue?
|
||||
|
||||
[repo]
|
||||
owner = Owner
|
||||
@@ -235,6 +250,8 @@ migrate_type_helper = This repository will be a <span class="label label-blue la
|
||||
migrate_repo = Migrate Repository
|
||||
|
||||
copy_link = Copy
|
||||
click_to_copy = Copy to clipboard
|
||||
copied = Copied OK
|
||||
clone_helper = Need help cloning? Visit <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Help</a>!
|
||||
unwatch = Unwatch
|
||||
watch = Watch
|
||||
@@ -242,34 +259,64 @@ unstar = Unstar
|
||||
star = Star
|
||||
fork = Fork
|
||||
|
||||
no_desc = No Description
|
||||
quick_guide = Quick Guide
|
||||
clone_this_repo = Clone this repository
|
||||
create_new_repo_command = Create a new repository on the command line
|
||||
push_exist_repo = Push an existing repository from the command line
|
||||
|
||||
branch = Branch
|
||||
tree = Tree
|
||||
branch_and_tags = Branches & Tags
|
||||
branches = Branches
|
||||
tags = Tags
|
||||
issues = Issues
|
||||
commits = Commits
|
||||
releases = Releases
|
||||
|
||||
commits.commits = Commits
|
||||
commits.search = Search commits
|
||||
commits.find = Find
|
||||
commits.author = Author
|
||||
commits.message = Message
|
||||
commits.date = Date
|
||||
commits.older = Older
|
||||
commits.newer = Newer
|
||||
|
||||
settings = Settings
|
||||
settings.options = Options
|
||||
settings.collaboration = Collaboration
|
||||
settings.hooks = Webhooks
|
||||
settings.githooks = Git Hooks
|
||||
settings.deploy_keys = Deploy Keys
|
||||
settings.basic_settings = Basic Settings
|
||||
settings.danger_zone = Danger Zone
|
||||
settings.site = Official Site
|
||||
settings.update_settings = Update Settings
|
||||
settings.change_reponame = Repository Name Changed
|
||||
settings.change_reponame_desc = Repository name has been changed, do you want to continue? This will affect all links relate to this repository.
|
||||
settings.transfer = Transfer Ownership
|
||||
settings.transfer_desc = Transfer this repo to another user or to an organization where you have admin rights.
|
||||
settings.new_owner_has_same_repo = New owner already has a repository with same name.
|
||||
settings.delete = Delete This Repository
|
||||
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
|
||||
settings.transfer_notices = <p>- You will lose access if new owner is a individual user.</p><p>- You will remain access if new owner is an organization and you're one of the owners.</p>
|
||||
settings.update_settings_success = Repository options has been successfully updated.
|
||||
settings.transfer_owner = New Owner
|
||||
settings.make_transfer = Make Transfer
|
||||
settings.transfer_succeed = Repository ownership has been successfully transferred.
|
||||
settings.confirm_delete = Confirm Deletion
|
||||
settings.add_collaborator = Add New Collaborator
|
||||
settings.add_collaborator_success = New collaborator has been added.
|
||||
settings.remove_collaborator_success = Collaborator has been removed.
|
||||
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
|
||||
settings.add_webhook = Add Webhook
|
||||
settings.hooks_desc = Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
|
||||
settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations.
|
||||
settings.githook_edit_desc = If hook is not active, sample content will be presented. Leave content to be blank will disable this hook.
|
||||
settings.githook_name = Hook Name
|
||||
settings.githook_content = Hook Content
|
||||
settings.update_githook = Update Hook
|
||||
settings.remove_hook_success = Webhook has been removed.
|
||||
settings.add_webhook_desc = We’ll send a <code>POST</code> request to the URL below with details of any subscribed events. You can also specify which data format you'd like to receive (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). More information can be found in <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
|
||||
settings.payload_url = Payload URL
|
||||
@@ -315,11 +362,15 @@ settings.full_name = Full Name
|
||||
settings.website = Website
|
||||
settings.location = Location
|
||||
settings.update_settings = Update Settings
|
||||
settings.change_orgname = Organization Name Changed
|
||||
settings.change_orgname_desc = Organization name has been changed, do you want to continue? This will affect all links relate to this organization.
|
||||
settings.update_setting_success = Organization setting has been successfully updated.
|
||||
settings.delete = Delete Organization
|
||||
settings.delete_account = Delete This Organization
|
||||
settings.delete_prompt = The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
|
||||
settings.confirm_delete_account = Confirm Deletion
|
||||
settings.delete_org_title = Organization Deletion
|
||||
settings.delete_org_desc = This organization is going to be deleted permanently, do you want to continue?
|
||||
settings.hooks_desc = Add webhooks that will be triggered for <strong>all repositories</strong> under this organization.
|
||||
|
||||
members.public = Public
|
||||
@@ -349,6 +400,8 @@ teams.members = Team Members
|
||||
teams.update_settings = Update Settings
|
||||
teams.delete_team = Delete This Team
|
||||
teams.add_team_member = Add Team Member
|
||||
teams.delete_team_title = Team Deletion
|
||||
teams.delete_team_desc = This team is going to be deleted, do you want to continue? Members of this team may lose access to some repositories.
|
||||
teams.delete_team_success = Given team has been successfully deleted.
|
||||
teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
|
||||
teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
|
||||
@@ -356,6 +409,7 @@ teams.admin_permission_desc = This team grants <strong>Admin</strong> access: me
|
||||
teams.repositories = Team Repositories
|
||||
teams.add_team_repository = Add Team Repository
|
||||
teams.remove_repo = Remove
|
||||
teams.add_nonexistent_repo = The repository you're trying to add does not exist, please create it first.
|
||||
|
||||
[admin]
|
||||
dashboard = Dashboard
|
||||
@@ -364,6 +418,7 @@ organizations = Organizations
|
||||
repositories = Repositories
|
||||
authentication = Authentications
|
||||
config = Configuration
|
||||
notices = System Notices
|
||||
monitor = Monitoring
|
||||
prev = Prev.
|
||||
next = Next
|
||||
@@ -465,6 +520,8 @@ auths.activated = This authentication has activated
|
||||
auths.update_success = Authorization setting has been successfully updated.
|
||||
auths.update = Update Authorization Setting
|
||||
auths.delete = Delete This Authorization
|
||||
auths.delete_auth_title = Authorization Deletion
|
||||
auths.delete_auth_desc = This authorization is going to be deleted, do you want to continue?
|
||||
|
||||
config.server_config = Server Configuration
|
||||
config.app_name = Application Name
|
||||
@@ -539,11 +596,19 @@ monitor.desc = Description
|
||||
monitor.start = Start Time
|
||||
monitor.execute_time = Execution Time
|
||||
|
||||
notices.system_notice_list = System Notices
|
||||
notices.type = Type
|
||||
notices.type_1 = Repository
|
||||
notices.desc = Description
|
||||
notices.op = Op.
|
||||
notices.delete_success = System notice has been successfully deleted.
|
||||
|
||||
[action]
|
||||
create_repo = created repository <a href="/%s">%s</a>
|
||||
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
|
||||
create_issue = opened issue <a href="/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = commented on issue <a href="/%s/issues/%s">%s#%s</a>
|
||||
create_repo = created repository <a href="%s/%s">%s</a>
|
||||
commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
|
||||
create_issue = opened issue <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = commented on issue <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
transfer_repo = transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
|
||||
|
||||
[tool]
|
||||
ago = ago
|
||||
|
||||
516
conf/locale/locale_fr-CA.ini
Normal file
516
conf/locale/locale_fr-CA.ini
Normal file
@@ -0,0 +1,516 @@
|
||||
app_desc = Un service Git écrit en Go auto-hébergé
|
||||
|
||||
home = Accueil
|
||||
dashboard = Tableau de bord
|
||||
explore = Explorer
|
||||
help = Aide
|
||||
sign_in = Connexion
|
||||
social_sign_in = Authentification via Internet: 2ème étape <small>associé le compte</small>
|
||||
sign_out = Déconnexion
|
||||
sign_up = Créer un compte
|
||||
register = S'inscrire
|
||||
website = Site web
|
||||
version = Version
|
||||
page = Page
|
||||
template = Gabarit
|
||||
language = Langage
|
||||
|
||||
username = Usager
|
||||
email = Courriel
|
||||
password = Mot de passe
|
||||
re_type = Saisir à nouveau
|
||||
captcha = Captcha
|
||||
|
||||
repository = Dépôt
|
||||
organization = Organisation
|
||||
mirror = Mirroir
|
||||
new_repo = Nouveau dépôt
|
||||
new_migrate = Nouvelle migration
|
||||
new_org = Nouvel organisation
|
||||
manage_org = Gestion des organisations
|
||||
admin_panel = Gestion
|
||||
account_settings = Profil usager
|
||||
settings = Configuration
|
||||
|
||||
news_feed = Fil de nouvelles
|
||||
pull_requests = Demandes de fusion (pull requests)
|
||||
issues = Suivi de problèmes
|
||||
|
||||
cancel = Annuler
|
||||
|
||||
[home]
|
||||
uname_holder = Nom d'usager ou courriel
|
||||
password_holder = Mot de passe
|
||||
switch_dashboard_context = Changer de tableau de bord
|
||||
my_repos = Mes dépôts
|
||||
collaborative_repos = Dépôts partagés
|
||||
my_orgs = Mes organisations
|
||||
my_mirrors = Mes mirroirs
|
||||
|
||||
[auth]
|
||||
create_new_account = Créer un nouveau compte
|
||||
register_hepler_msg = Déjà inscrits? Connectez-vous maintenant!
|
||||
social_register_hepler_msg = Déjà inscrits? Branchez-vous!
|
||||
disable_register_prompt = Désolé, l'auto-inscription n'est pas activée. Contactez l'admnistrateur du site.
|
||||
disable_register_mail = Désolé, la confirmation d'inscription par courriel est désactivée. Contactez l'administrateur du site.
|
||||
remember_me = Se souvenir de moi
|
||||
forgot_password= Mot de passe oublié
|
||||
forget_password = Mot de passe oublié?
|
||||
sign_up_now = Besoin d'un compte? Inscrivez-vous maintenant.
|
||||
confirmation_mail_sent_prompt = Un courriel de confirmation à été envoyé à <b>%s</b>, consultez vos courriels d'ici %d heures pour terminer l'inscription.
|
||||
sign_in_email = Connexion avec votre courriel
|
||||
active_your_account = Activez votre compte
|
||||
resent_limit_prompt = Désolé vous demandez trop souvent un courriel de confirmation. S.v.p. patientez 3 minutes.
|
||||
has_unconfirmed_mail = Bonjour %s, votre adresse courriel n'est pas vérifiée(<b>%s</b>). Si vous n'avez pas reçu de courriel de confirmation ou si vous avez besoin d'en envoyer un maintenant, appuyez sur le bouton ci-dessous.
|
||||
resend_mail = Appuyez ici pour envoyer de nouveau un courriel de confirmation.
|
||||
email_not_associate = Ce courriel ne correspond à aucun compte.
|
||||
send_reset_mail = Appuyez ici pour (ré)envoyer un courriel pour réinitialiser le mot de passe.
|
||||
reset_password = Réinitialiser votre mot de passe
|
||||
invalid_code = Désolé, ce code de confirmation est périmé ou non-valide.
|
||||
reset_password_helper = Appuyez ici pour réinitialiser votre mot de passe
|
||||
password_too_short = La longueur du mot de passe doit être d'au moins 6 caractères.
|
||||
|
||||
[form]
|
||||
UserName = Nom d'usager
|
||||
RepoName = Nom du dépôt
|
||||
Email = Adresse de courriel
|
||||
Password = Mot de passe
|
||||
Retype = Mot de passe (confirmation)
|
||||
SSHTitle = Nom de la clé SSH
|
||||
HttpsUrl = URL HTTPS
|
||||
PayloadUrl = URL cible
|
||||
TeamName = Nom de l'équipe
|
||||
AuthName = Nom d'usager
|
||||
|
||||
require_error = ` ne peut être vide.`
|
||||
alpha_dash_error = ` doit être composé de caractères alpha-numériques et/ou d'un tiret(-_).`
|
||||
alpha_dash_dot_error = ` doit être composé de caractères alpha-numérique, un point(.) et/ou tiret(-_).`
|
||||
min_size_error = ` doit être composé d'au moins %s caractères.`
|
||||
max_size_error = ` doit être conposé d'au plus %s caractères.`
|
||||
email_error = ` n'est pas une adresse de courriel bien formée.`
|
||||
url_error = ` n'est pas un URL valide.`
|
||||
unknown_error = Erreur inconnue:
|
||||
captcha_incorrect = Le captcha ne concorde pas.
|
||||
password_not_match = Les deux mots de passe diffèrent.
|
||||
|
||||
username_been_taken = `Nom d'usager dèjà utilisé.`
|
||||
repo_name_been_taken = Nom de dépôt déjà utilisé.
|
||||
org_name_been_taken = Nom d'organisation déjà utilisé.
|
||||
team_name_been_taken = Nom d'équipe déjà utilisé.
|
||||
email_been_used = Adresse de courriel déjà utilisée.
|
||||
ssh_key_been_used = Nom de clé publique déjà utilisé.
|
||||
illegal_username = Votre nom d'usager contient des caractères interdits.
|
||||
illegal_repo_name = Le nom du dépôt contient des caractères interdits.
|
||||
illegal_org_name = Le nom de l'organisation contient des caractères interdits.
|
||||
illegal_team_name = Le nom de l'équipe contient des caractères interdits.
|
||||
username_password_incorrect = Nom d'usager ou mot de passe erroné.
|
||||
enterred_invalid_repo_name = Nom de dépôt inexistant.
|
||||
enterred_invalid_owner_name = Responsable de dépôt inexistant.
|
||||
enterred_invalid_password = Mot de passe erroné.
|
||||
user_not_exist = Nom d'usager inexistant.
|
||||
last_org_owner = Ceci est le dernier responsable du dépôt. Il doit y avoir obligatoirement au moins un usager responsable.
|
||||
|
||||
invalid_ssh_key = Désolé, impossible de vérifier votre clé SSH: %
|
||||
auth_failed = Erreur d'authentification : %v
|
||||
|
||||
still_own_repo = Votre compte est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager.
|
||||
org_still_own_repo = Cette organisation est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager ou organisation.
|
||||
|
||||
still_own_user = Cette authentification est utilisée par un usager.
|
||||
|
||||
[settings]
|
||||
profile = Profil
|
||||
password = Mot de passe
|
||||
ssh_keys = Clés SSH
|
||||
social = Comptes Internet
|
||||
orgs = Organisations
|
||||
delete = Supprimer votre compte
|
||||
|
||||
public_profile = Profil public
|
||||
profile_desc = Votre adresse de courriel est publique et sera utilisée pour les avis produits par le site.
|
||||
full_name = Nom complet
|
||||
website = Site web
|
||||
location = Endroit
|
||||
update_profile = Mettre à jour le profil
|
||||
update_profile_success = Mise à jour du profil réussie.
|
||||
|
||||
change_password = Changer le mot de passe
|
||||
old_password = Mot de passe actuel
|
||||
new_password = Nouveau mot de passe
|
||||
password_incorrect = Mot de passe actuel erroné.
|
||||
change_password_success = Modification du mot de passe effectuée. Vous pouvez dorénavant vous connecter avec le nouveau mot de passe.
|
||||
|
||||
manage_ssh_keys = Gestion des clés SSH
|
||||
add_key = Ajouter une clé
|
||||
ssh_desc = Voici la liste de clés SSH associées à votre profil. Retirez les clés que vous ne reconnaissez pas.
|
||||
ssh_helper = <strong>Beson d'aide?</strong> Consultez le guide au <a href="https://help.github.com/articles/generating-ssh-keys">generating SSH keys</a> ou vérifiez <a href="https://help.github.com/ssh-issues/">les problèmes SSH fréquents</a>.
|
||||
add_new_key = Ajouter une clé SSH
|
||||
key_name = Nom de la clé
|
||||
key_content = Contenu
|
||||
add_key_success = Clé SSH ajoutée!
|
||||
delete_key = Détruire
|
||||
add_on = Ajoutée le
|
||||
last_used = Dernière utilisation le
|
||||
no_activity = Pas d'activité récente
|
||||
|
||||
manage_social = Gestion des comptes Internets associés
|
||||
social_desc = Ceci est une liste de comptes Internet associés. Retirez les comptes que vous ne reconnaissez pas.
|
||||
unbind = Désassocier
|
||||
unbind_success = Compte Internet déassocié.
|
||||
|
||||
delete_account = Detruire votre compte
|
||||
delete_prompt = Cette opération détruira votre compte et <strong>ne pourra être annulée</strong>!
|
||||
confirm_delete_account = Confirmez la suppression
|
||||
|
||||
[repo]
|
||||
owner = Responsable
|
||||
repo_name = Nom du dépôt
|
||||
repo_name_helper = Les bons noms de dépôts sont courts, mémorables et <strong>uniques</strong>.
|
||||
visibility = Visibilité
|
||||
visiblity_helper = Ce dépôt est <span class="label label-red label-radius">privé</span>
|
||||
repo_desc = Description
|
||||
repo_lang = Langue
|
||||
repo_lang_helper = Choisir un fichier .gitignore
|
||||
license = License
|
||||
license_helper = Choisir un fichier de licence
|
||||
init_readme = Initialiser le dépôt avec un fichier README.md
|
||||
create_repo = Créer le dépôt
|
||||
default_branch = Branche par défaut
|
||||
mirror_interval = Intervale de synchronisation (heures)
|
||||
goget_meta = Métadonnées Go-Get
|
||||
goget_meta_helper = Ce dépôt sera <span class="label label-blue label-radius">Go-Getable</span>
|
||||
|
||||
need_auth = Authorisation requise
|
||||
migrate_type = Type de migration
|
||||
migrate_type_helper = Ce dépôt sera un <span class="label label-blue label-radius">mirroir</span>
|
||||
migrate_repo = Migrer le dépôt
|
||||
|
||||
copy_link = Copier
|
||||
clone_helper = Besoin d'aide pour cloner? Obtenez de l' <a target="_blank" href="http://git-scm.com/book/fr/Les-bases-de-Git-Démarrer-un-dépôt-Git">aide</a>!
|
||||
unwatch = Ne plus suivre
|
||||
watch = Suivre
|
||||
unstar = Retirer étoile
|
||||
star = Étoile
|
||||
fork = Fork
|
||||
|
||||
quick_guide = Guide rapide
|
||||
clone_this_repo = Cloner ce dépôt
|
||||
create_new_repo_command = Créer un nouveau dépôt à la ligne de commande
|
||||
push_exist_repo = Pousser un dépôt existant depuis la ligne de commande
|
||||
|
||||
settings = Réglages
|
||||
settings.options = Réglages de base
|
||||
settings.collaboration = Collaboration
|
||||
settings.hooks = Webhooks
|
||||
settings.deploy_keys = Clé de déploiement
|
||||
settings.basic_settings = réglages de base
|
||||
settings.danger_zone = Danger!
|
||||
settings.site = Site officiel
|
||||
settings.update_settings = Réglage des mises à jour
|
||||
settings.transfer = Transférer la responsabilité
|
||||
settings.transfer_desc = Transférer ce dépôt à un autre usager ou organisation si vous en avez la responsabilité.
|
||||
settings.delete = Détruire ce dépôt
|
||||
settings.delete_desc = La destruction est irrémédiable, impossible d'annuler. Soyez sûr de votre décision.
|
||||
settings.update_settings_success = Réglages modifiés
|
||||
settings.transfer_owner = Nouveau responsable
|
||||
settings.make_transfer = Faire le transfert
|
||||
settings.confirm_delete = Confirmer la destruction
|
||||
settings.add_collaborator = Ajouter un nouveau collaborateur
|
||||
settings.add_collaborator_success = Nouveau collaborateur ajouté.
|
||||
settings.remove_collaborator_success = Collaborateur supprimé.
|
||||
settings.add_webhook = Ajouter un Webhook
|
||||
settings.hooks_desc = Les Webhooks permettent à des services externes d'être avertis de certains changements sur Gogs. Lorque qu'un changement se produit, Gogs envoie une requête POST à chacun des URLs spécifiés. Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>.
|
||||
settings.remove_hook_success = Webhook supprimé.
|
||||
settings.add_webhook_desc = Gogs envoiera un POST à l'URL ci-dessous avec le détail de l'événement souscrit. Vous pouvez aussi spécifier dans quel format vous désirez recevoir les données (JSON,<code>x-www-form-urlencoded</code>, <em>etc</em>). Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>.
|
||||
settings.payload_url = URL cible
|
||||
settings.content_type = Content Type
|
||||
settings.secret = Secret
|
||||
settings.event_desc = Quels changements déclencheront le webhook?
|
||||
settings.event_push_only = Uniquement les <code>push</code>.
|
||||
settings.active = Activé
|
||||
settings.active_helper = Gogs fournira le détail de l'événement lorsque ce webhook sera déclenché.
|
||||
settings.add_hook_success = Nouveau webhook ajouté.
|
||||
settings.update_webhook = Mettre à jour le webhook
|
||||
settings.update_hook_success = Webhook mis à jour.
|
||||
settings.delete_webhook = Détruire le webhook
|
||||
settings.recent_deliveries = Livraisons récentes
|
||||
settings.hook_type = Type de déclencheur
|
||||
settings.add_slack_hook_desc = Ajouter la compatibilité <a href="http://slack.com">Slack</a> à ce dépôt.
|
||||
settings.slack_token = Jeton (token)
|
||||
settings.slack_domain = Domaine
|
||||
settings.slack_channel = Canal
|
||||
|
||||
[org]
|
||||
org_name_holder = Nom de l'organisation
|
||||
org_name_helper = Les bons noms d'organisations sont courts, mémorables et uniques
|
||||
org_email_helper = Le courriel de l'organisation recevra toutes les notifications et les confirmations.
|
||||
create_org = Créer une organisation
|
||||
repo_updated = Changement effectué
|
||||
people = Personne
|
||||
invite_someone = Inviter quelqu'un
|
||||
teams = Équipes
|
||||
lower_members = Membres
|
||||
lower_repositories = Dépôts
|
||||
create_new_team = Créer une nouvelle équipe
|
||||
org_desc = Description
|
||||
team_name = Nom de l'équipe
|
||||
team_desc = Description
|
||||
team_name_helper = Le nom qui sera utilisé pour mentionner cette équipe dans les conversations.
|
||||
team_desc_helper = Quel est la raison d'être de cette équipe?
|
||||
team_permission_desc = Quel niveau de permission attribuer à cette équipe?
|
||||
|
||||
settings = Réglages
|
||||
settings.options = Paramètres
|
||||
settings.full_name = Nom complet
|
||||
settings.website = Site web
|
||||
settings.location = Endroit
|
||||
settings.update_settings = Mettre à jour les paramètres
|
||||
settings.update_setting_success = Paramètres mis à jour.
|
||||
settings.delete = Détruire l'organisation
|
||||
settings.delete_account = Détruire cette organisation
|
||||
settings.delete_prompt = La destruction de l'organisation est irrémédiable, impossible d'annuler. Soyez sûr de votre décision.
|
||||
settings.confirm_delete_account = Confirmer la destruction
|
||||
|
||||
members.public = Publique
|
||||
members.public_helper = Rendre privé
|
||||
members.private = Privé
|
||||
members.private_helper = Rendre publique
|
||||
members.owner = Responsable
|
||||
members.member = Membre
|
||||
members.conceal = Caché
|
||||
members.remove = Retirer
|
||||
members.leave = Quitter
|
||||
members.invite_desc = Commencez à saisir un nom d'usager pour l'inviter à %s:
|
||||
members.invite_now = Inviter
|
||||
|
||||
teams.join = Rejoindre
|
||||
teams.leave = Quitter
|
||||
teams.read_access = Droits de lecture
|
||||
teams.read_access_helper = Cette équipe pourra voir et cloner ses dépôts.
|
||||
teams.write_access = Droits d'écriture
|
||||
teams.write_access_helper = Cette équipe pourra voir et cloner ses dépôts ainsi que pousser vers ceux-ci.
|
||||
teams.admin_access = Droits de gestion
|
||||
teams.admin_access_helper = En plus des droits d'écriture, cette équipe pourra gérer les collaborateurs.
|
||||
teams.no_desc = Cette équipe ne posséde pas de description
|
||||
teams.settings = Réglages
|
||||
teams.owners_permission_desc = Les responsables ont accès à <strong>tous</strong> les dépôts et en possédent les droits de gestion.
|
||||
teams.members = Membre de l'équipe
|
||||
teams.update_settings = Mettre à jour
|
||||
teams.delete_team = Détruire cette équipe
|
||||
teams.add_team_member = Ajouter un membre à l'équipe
|
||||
teams.delete_team_success = Équipe détruite
|
||||
teams.read_permission_desc = La participation à cette équipe confère les droits de lecture. Ses membres peuvent voir et cloner ses dépôts.
|
||||
teams.write_permission_desc = La participation à cette équipe confère les droits d'écriture en plus des droits de lecture. Ses membres peuvent pousser vers les dépôts de l'équipe.
|
||||
teams.admin_permission_desc = La participation à cette équire confère les droits de gestion. Ses membres peuvent voir, cloner, pousser et gérer les collaborateurs des dépôts.
|
||||
teams.repositories = Dépôts de l'équipe
|
||||
teams.add_team_repository = Ajouer un dépôt à l'équipe
|
||||
teams.remove_repo = Enlever
|
||||
|
||||
[admin]
|
||||
dashboard = Tableau de bord
|
||||
users = Usagers
|
||||
organizations = Organisations
|
||||
repositories = Dépôts
|
||||
authentication = Sources d'authentifications
|
||||
config = Configuration
|
||||
monitor = Monitoring
|
||||
prev = Préc.
|
||||
next = Suiv.
|
||||
|
||||
dashboard.statistic = Statistiques
|
||||
dashboard.operations = Opérations
|
||||
dashboard.system_status = État du monitoring système
|
||||
dashboard.statistic_info = La BD Gogs compte <b>%d</b> usagers, <b>%d</b> organisations, <b>%d</b> clé SSH, <b>%d</b> dépôts, <b>%d</b> suivis, <b>%d</b> étoiles, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes Internet, <b>%d</b> suivis, <b>%d</b> mirroirs, <b>%d</b> publications, <b>%d</b> sources d'authentification, <b>%d</b> webhooks, <b>%d</b> jalons, <b>%d</b> tags, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jours, <b>%d</b> fichiers joints.
|
||||
dashboard.operation_name = Nom de l'opération
|
||||
dashboard.operation_switch = Commande
|
||||
dashboard.operation_run = Lancer
|
||||
dashboard.clean_unbind_oauth = Nettoyer les OAuths orphelins
|
||||
dashboard.delete_inactivate_accounts = Détruire les comptes inactifs
|
||||
dashboard.server_uptime = Démarré depuis
|
||||
dashboard.current_goroutine = Nombre de Goroutines
|
||||
dashboard.current_memory_usage = Usage mémoire actuel
|
||||
dashboard.total_memory_allocated = Mémoire allouée totale
|
||||
dashboard.memory_obtained = Memoire obtenue
|
||||
dashboard.pointer_lookup_times = Accès pointeur
|
||||
dashboard.memory_allocate_times = Allocation mémoire
|
||||
dashboard.memory_free_times = Désallocation mémoire
|
||||
dashboard.current_heap_usage = Taille du heap actuelle
|
||||
dashboard.heap_memory_obtained = Mémoire heap obtenue
|
||||
dashboard.heap_memory_idle = Mémoire heap inactive
|
||||
dashboard.heap_memory_in_use = Mémoire heap utilisée
|
||||
dashboard.heap_memory_released = Mémoire heap relachée
|
||||
dashboard.heap_objects = Objets dans le heap
|
||||
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
|
||||
dashboard.stack_memory_obtained = Stack Memory Obtained
|
||||
dashboard.mspan_structures_usage = MSpan Structures Usage
|
||||
dashboard.mspan_structures_obtained = MSpan Structures Obtained
|
||||
dashboard.mcache_structures_usage = MCache Structures Usage
|
||||
dashboard.mcache_structures_obtained = MCache Structures Obtained
|
||||
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
|
||||
dashboard.gc_metadata_obtained = GC Metadada Obtained
|
||||
dashboard.other_system_allocation_obtained = Other System Allocation Obtained
|
||||
dashboard.next_gc_recycle = Next GC Recycle
|
||||
dashboard.last_gc_time = Since Last GC Time
|
||||
dashboard.total_gc_time = Total GC Pause
|
||||
dashboard.total_gc_pause = Total GC Pause
|
||||
dashboard.last_gc_pause = Last GC Pause
|
||||
dashboard.gc_times = GC Times
|
||||
|
||||
users.user_manage_panel = Gestion des usager
|
||||
users.new_account = Creér un nouveau compte
|
||||
users.name = Nom
|
||||
users.activated = Activé
|
||||
users.admin = Gestionnaire
|
||||
users.repos = Dépôts
|
||||
users.created = Créé
|
||||
users.edit = Editer
|
||||
users.auth_source = Source d'authentification
|
||||
users.local = Locale
|
||||
users.auth_login_name = Identifiant d'authentification
|
||||
users.update_profile_success = Compte crée.
|
||||
users.edit_account = Éditer compte
|
||||
users.is_activated = Ce compte est activé
|
||||
users.is_admin = Ce compte a les droits de gestionnaire
|
||||
users.update_profile = Mettre à jour le compte
|
||||
users.delete_account = Détruire ce compte
|
||||
users.still_own_repo = Ce compte est responsables d'un dépôt. I faut détruire le dépôt ou transférer la responsabilité avant de détruire ce compte.
|
||||
|
||||
orgs.org_manage_panel = Gestion des organisations
|
||||
orgs.name = Nom
|
||||
orgs.teams = Équipes
|
||||
orgs.members = Membres
|
||||
|
||||
repos.repo_manage_panel = Gestion des dépôts
|
||||
repos.owner = Responsable
|
||||
repos.name = Nom
|
||||
repos.private = Privé
|
||||
repos.watches = Suivis
|
||||
repos.stars = Étoiles
|
||||
repos.issues = Ticket
|
||||
|
||||
auths.auth_manage_panel = Gestion des sources d'authentification
|
||||
auths.new = Ajouter une nouvelle source d'authentification
|
||||
auths.name = Nom
|
||||
auths.type = Type
|
||||
auths.enabled = Activé
|
||||
auths.updated = Mis à jour
|
||||
auths.auth_type = Type d'authentification
|
||||
auths.auth_name = Nom de l'authentification
|
||||
auths.domain = Domaine
|
||||
auths.host = Serveur
|
||||
auths.port = Port
|
||||
auths.base_dn = DN de base
|
||||
auths.attributes = Attributs de recherche
|
||||
auths.filter = Filtre de recherche
|
||||
auths.ms_ad_sa = Microsoft Active Directory
|
||||
auths.smtp_auth = Authentification SMTP
|
||||
auths.smtphost = Serveur SMTP
|
||||
auths.smtpport = Port SMTP
|
||||
auths.enable_tls = Chiffrement TLS
|
||||
auths.enable_auto_register = Activer auto-abonnement
|
||||
auths.tips = Trucs
|
||||
auths.edit = Éditer réglages d'authentification
|
||||
auths.activated = Source d'authentification activée
|
||||
auths.update_success = Réglages mis à jour.
|
||||
auths.update = Mettre à jour réglages
|
||||
auths.delete = Détruire cette source
|
||||
|
||||
config.server_config = Configuration du serveur
|
||||
config.app_name = Nom de l'applicaiton
|
||||
config.app_ver = Version de l'application
|
||||
config.app_url = URL de l'application
|
||||
config.domain = Domaine
|
||||
config.offline_mode = Mode hors-ligne
|
||||
config.disable_router_log = Journal du routeur désactivé
|
||||
config.run_user = Éxécuté en tant que
|
||||
config.run_mode = Mode de fonctionnement
|
||||
config.repo_root_path = Dossier contenant les dépôts
|
||||
config.static_file_root_path = Dossier contenant les fichiers statiques
|
||||
config.log_file_root_path = Dossier contenant les journaux
|
||||
config.script_type = Type de script
|
||||
config.reverse_auth_user = Usager d'authentification inversée
|
||||
config.db_config = Configuration de la BD
|
||||
config.db_type = Type
|
||||
config.db_host = Serveur
|
||||
config.db_name = Nom
|
||||
config.db_user = Usager
|
||||
config.db_ssl_mode = Mode SSL
|
||||
config.db_ssl_mode_helper = (pour "postgres" seulement)
|
||||
config.db_path = Path
|
||||
config.db_path_helper = (pour "sqlite3" seulement)
|
||||
config.service_config = Configuration du service
|
||||
config.register_email_confirm = Confirmation d'abonnement par courriel
|
||||
config.disable_register = Auto-inscription désactivée
|
||||
config.require_sign_in_view = Connexion requise pour visualiser
|
||||
config.mail_notify = Notifications par courriel
|
||||
config.enable_cache_avatar = Cache avatar activée
|
||||
config.active_code_lives = Jeton d'activation
|
||||
config.reset_password_code_lives = Jeton de modification mot-de-passe
|
||||
config.webhook_config = Configuration Webhook
|
||||
config.task_interval = Intervalle
|
||||
config.deliver_timeout = Expiration des appels
|
||||
config.mailer_config = Configuration expédition de courriels
|
||||
config.mailer_enabled = Activé
|
||||
config.mailer_name = Nom
|
||||
config.mailer_host = Serveur
|
||||
config.mailer_user = Usager
|
||||
config.oauth_config = Configuration OAuth
|
||||
config.oauth_enabled = Activé
|
||||
config.cache_config = Configuration du cache
|
||||
config.cache_adapter = Mécanisme de cache
|
||||
config.cache_interval = Intervalle
|
||||
config.cache_conn = Chaîne de connexion
|
||||
config.session_config = Configuration des session
|
||||
config.session_provider = Mécanisme
|
||||
config.provider_config = Configuration du mécanisme
|
||||
config.cookie_name = Nom du fichier témoin
|
||||
config.enable_set_cookie = Fichier témoin actvité
|
||||
config.gc_interval_time = Intervalle GC
|
||||
config.session_life_time = Durée de la session
|
||||
config.https_only = HTTPS exigé
|
||||
config.cookie_life_time = Expiration du fichier témoin
|
||||
config.session_hash_function = Fonction de hashage ID de session
|
||||
config.session_hash_key = Clé de hashage ID de session
|
||||
config.picture_config = Configuration des avatars
|
||||
config.picture_service = Service image
|
||||
config.disable_gravatar = Désactivé Gravatar
|
||||
config.log_config = Configuration du journal
|
||||
config.log_mode = Mode de journal
|
||||
|
||||
monitor.cron = Cron Tasks
|
||||
monitor.name = Name
|
||||
monitor.schedule = Schedule
|
||||
monitor.next = Next Time
|
||||
monitor.previous = Previous Time
|
||||
monitor.execute_times = Execute Times
|
||||
monitor.process = Running Processes
|
||||
monitor.desc = Description
|
||||
monitor.start = Start Time
|
||||
monitor.execute_time = Execution Time
|
||||
|
||||
[action]
|
||||
create_repo = a créé le dépôt <a href="/%s">%s</a>
|
||||
commit_repo = a poussé sur <a href="/%s/src/%s">%s</a> à <a href="/%s">%s</a>
|
||||
create_issue = a ouvert le ticket <a href="/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = a commenté sur le ticket <a href="/%s/issues/%s">%s#%s</a>
|
||||
|
||||
[tool]
|
||||
ago = auparavant
|
||||
from_now = depuis
|
||||
now = maintenant
|
||||
1s = 1 seconde %s
|
||||
1m = 1 minute %s
|
||||
1h = 1 heure %s
|
||||
1d = 1 jour %s
|
||||
1w = 1 semaine %s
|
||||
1mon = 1 mos %s
|
||||
1y = 1 an %s
|
||||
seconds = %d secondes %s
|
||||
minutes = %d minutes %s
|
||||
hours = %d heures %s
|
||||
days = %d jours %s
|
||||
weeks = %d semaines %s
|
||||
months = %d mois %s
|
||||
years = %d années %s
|
||||
raw_seconds = secondes
|
||||
raw_minutes = minutes
|
||||
585
conf/locale/locale_nl-NL.ini
Normal file
585
conf/locale/locale_nl-NL.ini
Normal file
@@ -0,0 +1,585 @@
|
||||
app_desc = Een pijnloze self-hosted Git-dienst geschreven in Go
|
||||
home = Home
|
||||
dashboard = Dashboard
|
||||
explore = Verkennen
|
||||
help = Help
|
||||
sign_in = Inloggen
|
||||
social_sign_in = Social netwerk inlog: tweede stap <small>account koppelen</small>
|
||||
sign_out = Afmelden
|
||||
sign_up = Aanmelden
|
||||
register = Registreer
|
||||
website = Website
|
||||
version = Versie
|
||||
page = Pagina
|
||||
template = Template
|
||||
language = Taal
|
||||
username = Gebruikersnaam
|
||||
email = E-mail
|
||||
password = Wachttwoord
|
||||
re_type = Verificatie
|
||||
captcha = Captcha
|
||||
repository = Repositorie
|
||||
organization = Organisatie
|
||||
mirror = Mirror
|
||||
new_repo = Nieuwe repositorie
|
||||
new_migrate = Nieuwe migratie
|
||||
new_org = Nieuwe organisatie
|
||||
manage_org = Beheer organisaties
|
||||
admin_panel = Adminpaneel
|
||||
account_settings = Accountinstellingen
|
||||
settings = Instellingen
|
||||
news_feed = Nieuwsfeed
|
||||
pull_requests = Pull-aanvragen
|
||||
issues = Issues
|
||||
cancel = Annuleer
|
||||
|
||||
[home]
|
||||
uname_holder = Gebruikersnaam of e-mail
|
||||
password_holder = Wachtwoord
|
||||
switch_dashboard_context = Wissel voorpaginacontext
|
||||
my_repos = Mijn repositories
|
||||
collaborative_repos = Gedeelde repositories
|
||||
my_orgs = Mijn organisaties
|
||||
my_mirrors = Mijn mirrors
|
||||
|
||||
[auth]
|
||||
create_new_account = Maak nieuw account aan
|
||||
register_hepler_msg = Heeft u al een account? Meld u nu aan!
|
||||
social_register_hepler_msg = Heeft u al een account? Koppel nu!
|
||||
disable_register_prompt = Sorry, registratie is uitgeschakeld. Neem contact op met de beheerder van deze site.
|
||||
disable_register_mail = Sorry, bevestiging van registratie per e-mail is uitgeschakeld.
|
||||
remember_me = Onthoud mij
|
||||
forgot_password = Wachtwoord vergeten
|
||||
forget_password = Wachtwoord vergeten?
|
||||
sign_up_now = Een account nodig? Meld u nu aan.
|
||||
confirmation_mail_sent_prompt = Een bevestigingsemail is gestuurd naar <b>%s</b>, Bevestig u aanvraag binnen %d uren om uw registratie te voltooien.
|
||||
sign_in_email = Meld u aan met uw e-mailadres
|
||||
active_your_account = Activeer uw account
|
||||
resent_limit_prompt = Sorry, u heeft te snel na elkaar een aanvraag gedaan voor een activatie mail. Wacht drie minuten voor uw volgende aanvraag.
|
||||
has_unconfirmed_mail = Beste %s, u heeft een onbevestigde e-mailadres (<b>%s</b>). Als u nog geen bevestiging per e-mail heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
|
||||
resend_mail = Klik hier om uw activatie mail nog een keer te verzenden
|
||||
send_reset_mail = Klik hier om uw wachtwoord reset mail (nogmaals) te versturen
|
||||
reset_password = Reset uw wachtwoord
|
||||
invalid_code = Sorry, uw bevestigingscode is verlopen of niet meer geldig.
|
||||
reset_password_helper = Klik hier om uw wachtwoord opnieuw in te stellen.
|
||||
password_too_short = De lengte van uw wachtwoord moet minimaal zes karakters zijn.
|
||||
email_not_associate = Dit e-mailadres is niet gekoppeld aan een account.
|
||||
|
||||
[form]
|
||||
UserName = Gebruikersnaam
|
||||
RepoName = Repositorie naam
|
||||
Email = e-mailadres
|
||||
Password = Wachtwoord
|
||||
Retype = Verifieer wachtwoord
|
||||
SSHTitle = SSH sleutel naam
|
||||
HttpsUrl = HTTPS URL
|
||||
PayloadUrl = Payload URL
|
||||
TeamName = Team naam
|
||||
AuthName = Autorisatienaam
|
||||
require_error = kan niet leeg zijn.
|
||||
alpha_dash_error = moet een valide alfanumeriek of dash(-_) karakter zijn.
|
||||
alpha_dash_dot_error = moet een valide alfanumeriek, dash(-_) of (.) punt karakter zijn.
|
||||
min_size_error = moet minimaal %s karakters bevatten.
|
||||
max_size_error = mag maximaal %s karakters bevatten.
|
||||
email_error = is niet een valide e-mail adres.
|
||||
url_error = is niet een valide URL.
|
||||
unknown_error = Onbekende fout:
|
||||
captcha_incorrect = Captcha komt niet overeen.
|
||||
password_not_match = Wachtwoord en verificatie wachtwoord komen niet overeen.
|
||||
username_been_taken = Gebruikersnaam is al in gebruik.
|
||||
repo_name_been_taken = Repositorie naam is al in gebruik.
|
||||
org_name_been_taken = Organisatie naam is al in gebruik.
|
||||
team_name_been_taken = Team naam is al in gebruik.
|
||||
email_been_used = e-mailadres is al in gebruik.
|
||||
ssh_key_been_used = Openbare sleutel naam is al in gebruik.
|
||||
illegal_username = Gebruikersnaam bevat illegale karakters.
|
||||
illegal_repo_name = Repositorie naam bevat illegale karakters.
|
||||
illegal_org_name = Organisatie naam bevat illegale karakters.
|
||||
illegal_team_name = Team naam bevat illegale karakters.
|
||||
username_password_incorrect = Gebruikersnaam of wachtwoord is niet correct.
|
||||
enterred_invalid_repo_name = U heeft een onjuiste repositorie naam ingevoerd.
|
||||
enterred_invalid_owner_name = U heeft een onjuiste eigenaar ingevoerd.
|
||||
enterred_invalid_password = U heeft een onjuiste wachtwoord ingevoerd.
|
||||
user_not_exist = Gegeven gebruiker bestaat niet.
|
||||
last_org_owner = De gebruiker die u probeert te verwijderen is het enige lid (eigenaar) van dit team. U moet eerst nieuwe lid (eigenaar) aanstellen.
|
||||
invalid_ssh_key = Sorry, we zijn niet in staat om uw SSH-sleutel te verifiëren: %s
|
||||
auth_failed = Verificatie mislukt: %v
|
||||
still_own_repo = Uw account heeft nog een eigendom op een repositorie. U moet deze eerst verwijderen of overdragen.
|
||||
org_still_own_repo = De organisatie heeft nog eigendomen op repositories. U moet deze eerst verwijderen of overdragen.
|
||||
still_own_user = Deze authenticatie methode wordt nog gebruikt door sommige gebruikers. U moet hen eerst verplaatsen of verwijderen.
|
||||
AdminEmail = E-mail beheerder
|
||||
|
||||
[settings]
|
||||
profile = Profiel
|
||||
password = Wachtwoord
|
||||
ssh_keys = SSH-sleutels
|
||||
social = Sociale netwerk-accounts
|
||||
orgs = Organisaties
|
||||
delete = Verwijder account
|
||||
public_profile = Openbaar profiel
|
||||
profile_desc = Uw e-mailadres is openbaar zichtbaar en zal gebruikt worden gebruikt voor alle account gerlateerde berichtgevingen en web bewerking gemaakt via de website.
|
||||
full_name = Volledige naam
|
||||
website = Website
|
||||
location = Locatie
|
||||
update_profile = Profile bijwerken
|
||||
update_profile_success = Uw profiel is succesvol bijgewerkt.
|
||||
change_password = Verander wachtwoord
|
||||
old_password = Huidige wachtwoord
|
||||
new_password = Nieuw wachtwoord
|
||||
password_incorrect = Huidig wachtwoord is niet correct.
|
||||
change_password_success = Wachtwoord is succesvol gewijzigd. U kunt nu met uw nieuwe wachtwoord inloggen.
|
||||
manage_ssh_keys = Beheer SSH sleutels
|
||||
add_key = Sleutel toevoegen
|
||||
ssh_desc = Dit is een lijst van alle SSH sleutels die gekoppeld zijn aan uw account. Verwijder alle sleutels die u niet herkent.
|
||||
ssh_helper = <strong>Hulp nodig?</strong> Bekijk onze help pagina's over <a href="https://help.github.com/articles/generating-ssh-keys">SSH sleutels genereeren</a> of over <a href="https://help.github.com/ssh-issues/">meest voorkomende SSH problemen</a>.
|
||||
add_new_key = SSH sleutel toevoegen
|
||||
key_name = Sleutel naam
|
||||
key_content = Inhoud
|
||||
add_key_success = Nieuwe SSH sleutel is toegevoegd!
|
||||
delete_key = Verwijder
|
||||
add_on = Toegevoegd op
|
||||
last_used = Laatst gebruikt op
|
||||
no_activity = Geen recente activiteiten
|
||||
manage_social = Beheer gekoppelde sociale accounts
|
||||
social_desc = Dit is een lijst van de bijbehorende sociale accounts koppelingen, Verwijder eventueel koppelingen die u niet herkent.
|
||||
unbind = Loskoppelen
|
||||
unbind_success = Sociaal account is ontkoppeld.
|
||||
delete_account = Verwijder uw account
|
||||
delete_prompt = Deze handeling zal uw account definitief verwijderen, u kunt dit <strong> NIET </strong> terug draaien!
|
||||
confirm_delete_account = Bevestig verwijdering
|
||||
uid = uid
|
||||
change_username = Username veranderd
|
||||
change_username_desc = Gebruikersnaam is gewijzigd. Wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op uw account.
|
||||
continue = Doorgaan
|
||||
cancel = Annuleren
|
||||
delete_account_title = Account verwijderen
|
||||
delete_account_desc = Dit account zal permanent worden verwijderd. Wilt u doorgaan?
|
||||
|
||||
[repo]
|
||||
owner = Eigenaar
|
||||
repo_name = Repositorie naam
|
||||
repo_name_helper = Een goede repositorie naam is kort, memorabel en <strong>uniek</strong>.
|
||||
visibility = Zichtbaarheid
|
||||
visiblity_helper = Deze repositorie is <span class="label label-red label-radius">prive</span>
|
||||
repo_desc = Omschrijving
|
||||
repo_lang = Taal
|
||||
repo_lang_helper = Selecteer een .gitignore bestand
|
||||
license = Licentie
|
||||
license_helper = Selecteer een licentie bestand
|
||||
init_readme = Initialiseer deze repositorie met een README.md
|
||||
create_repo = Nieuwe Repositorie
|
||||
default_branch = Standaard branch
|
||||
mirror_interval = Mirror interval(uur)
|
||||
goget_meta = Go-Get Meta
|
||||
goget_meta_helper = Deze repositorie is nu beschikbaar voor <span class="label label-blue label-radius">Go-Get</span>
|
||||
need_auth = Autorisatie vereist
|
||||
migrate_type = Migratie type
|
||||
migrate_type_helper = Deze repositorie zal een <span class="label label-blue label-radius">mirror</span> worden
|
||||
migrate_repo = Migreer repositorie
|
||||
clone_helper = Hulp nodig bij het klonen? Kijk dan <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">hier</a> voor hulp!
|
||||
unwatch = Negeren
|
||||
watch = Volgen
|
||||
unstar = Ontster
|
||||
star = Ster
|
||||
fork = Fork
|
||||
settings = Instellingen
|
||||
settings.options = Opties
|
||||
settings.collaboration = Samenwerking
|
||||
settings.hooks = Webhooks
|
||||
settings.deploy_keys = Installeer sleutels
|
||||
settings.basic_settings = Basis instellingen
|
||||
settings.danger_zone = Gevaren zone
|
||||
settings.site = Officiële site
|
||||
settings.update_settings = Instellingen bewerken
|
||||
settings.transfer = Eigendom overdragen
|
||||
settings.transfer_desc = Draag deze repo over aan een andere gebruiker of een organisatie waar u beheerders rechten heeft.
|
||||
settings.delete = Verwijder deze repositorie
|
||||
settings.delete_desc = Als u eenmaal een repositorie verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties.
|
||||
settings.update_settings_success = Repositorie instellingen zijn succesvol bijgewerkt.
|
||||
settings.transfer_owner = Nieuwe eigenaar
|
||||
settings.make_transfer = Maak overdracht
|
||||
settings.confirm_delete = Bevestig verwijdering
|
||||
settings.add_collaborator = Nieuwe medewerker toevoegen
|
||||
settings.add_collaborator_success = medewerker is toegevoegd.
|
||||
settings.remove_collaborator_success = medewerker is verwijderd.
|
||||
settings.add_webhook = Webhook toevoegen
|
||||
settings.hooks_desc = Webhooks maken het mogelijk om externe diensten te waaarschuwen wanneer zich bepaalde gebeurtenissen voordoen op Gogs . Wanneer de opgegeven gebeurtenissen gebeuren , zullen we een POST-aanvraag aan alle URL's die u verstrekt sturen . Lees meer in onze <a target="_blank" href="http://gogs.io/docs/features/webhook.html"> Webhooks gids </a>.
|
||||
settings.remove_hook_success = Webhook is verwijderd.
|
||||
settings.add_webhook_desc = We sturen een <code>POST</code> verzoek aan de onderstaande URL met de details van het geplaatste evenementen. U kunt ook aangeven welke data u wilt ontvangen (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). U kunt meer informatie vinden in onze <a target="_blank" href="http://gogs.io/docs/features/webhook.html"> webhooks gids</a>.
|
||||
settings.payload_url = Payload URL
|
||||
settings.content_type = Content type
|
||||
settings.secret = Geheim
|
||||
settings.event_desc = Bij welke gebeurtenissen wilt u dat deze webhook getriggerd wordt?
|
||||
settings.event_push_only = Alleen bij de <code>push</code> event.
|
||||
settings.active = Actief
|
||||
settings.active_helper = We zullen details van de gebeurtenissen af leveren wanneer deze webhook wordt geactiveerd.
|
||||
settings.add_hook_success = Nieuwe webhook toegevoegd.
|
||||
settings.update_webhook = Bewerk webhook
|
||||
settings.update_hook_success = Webhook is bijgewerkt.
|
||||
settings.delete_webhook = Webhook verwijderen
|
||||
settings.recent_deliveries = Recente bezorgingen
|
||||
copy_link = Kopieer
|
||||
click_to_copy = Kopieer link naar plakbord
|
||||
copied = Gekopieerd
|
||||
no_desc = Geen omschrijving
|
||||
quick_guide = Snelstart gids
|
||||
clone_this_repo = Kloon deze repositorie
|
||||
create_new_repo_command = Maak een nieuwe repositorie aan vanaf de console
|
||||
push_exist_repo = Push een bestaande repositorie vanaf de console
|
||||
branch = Aftakking
|
||||
tree = Boom
|
||||
branch_and_tags = Aftakkingen & labels
|
||||
branches = Aftakkingen
|
||||
tags = Labels
|
||||
issues = Issues
|
||||
commits = Commits
|
||||
releases = Publicaties
|
||||
commits.commits = Commits
|
||||
commits.search = Zoeken
|
||||
commits.find = zoek
|
||||
commits.author = Auteur
|
||||
commits.message = Bericht
|
||||
commits.date = Datum
|
||||
commits.older = Ouder
|
||||
commits.newer = Nieuwer
|
||||
settings.change_reponame = Repositorienaam aangepast
|
||||
settings.change_reponame_desc = De repositorienaam is veranderd. Wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op deze repositorie.
|
||||
settings.new_owner_has_same_repo = De nieuwe eigenaar heeft al een repositorie met deze naam
|
||||
settings.transfer_notices = <p> - U kan uw toegang verliezen als de nieuwe eigenaar een individuele gebruiker is</p> <p> - . . U zal uw toegang behouden als de nieuwe eigenaar een organisatie is en u één van de eigenaren bent</p>
|
||||
settings.transfer_succeed = Eigendom repositorie succesvol overgedragen
|
||||
settings.hook_type = Type hook
|
||||
settings.add_slack_hook_desc = Voeg een <a href="http://slack.com">Slack</a> integratie toe aan uw repositorie.
|
||||
settings.slack_token = Slack token
|
||||
settings.slack_domain = Slack domein
|
||||
settings.slack_channel = Slack kanaal
|
||||
|
||||
[org]
|
||||
org_name_holder = Organisatienaam
|
||||
org_name_helper = Een goede organisatienaam is kort en memorabel.
|
||||
org_email_helper = Alle notificaties en bevestigingen worden op het e-mailadres van de organisatie ontvangen.
|
||||
create_org = Nieuwe organisatie aanmaken
|
||||
repo_updated = Geupdate
|
||||
people = Mensen
|
||||
invite_someone = Iemand uitnodigen
|
||||
teams = Teams
|
||||
lower_members = leden
|
||||
lower_repositories = repositories
|
||||
create_new_team = Nieuw team aanmaken
|
||||
org_desc = Omschrijving
|
||||
team_name = Teamnaam
|
||||
team_desc = Omschrijving
|
||||
team_name_helper = U gebruikt deze naam om dit team te vermelden in conversaties.
|
||||
team_desc_helper = Waar gaat dit team doen?
|
||||
team_permission_desc = Welke privileges zou dit team moeten hebben?
|
||||
settings = Instellingen
|
||||
settings.options = Opties
|
||||
settings.full_name = Volledige naam
|
||||
settings.website = Website
|
||||
settings.location = Locatie
|
||||
settings.update_settings = Instellingen bijwerken
|
||||
settings.update_setting_success = Organisatie instellingen zijn succesvol bijgewerkt.
|
||||
settings.delete = Verwijder organisatie
|
||||
settings.delete_account = Verwijder deze organisatie
|
||||
settings.delete_prompt = Deze actie zal de origanisatie permanent verwijderen. U kunt dit <strong>NIET</strong> terug draaien!
|
||||
settings.confirm_delete_account = Bevestig verwijdering
|
||||
members.public = Openbaar
|
||||
members.public_helper = maak prive
|
||||
members.private = Prive
|
||||
members.private_helper = maak openbaar
|
||||
members.owner = Eigenaar
|
||||
members.member = Lid
|
||||
members.conceal = Verbergen
|
||||
members.remove = Verwijderen
|
||||
members.leave = Verlaat
|
||||
members.invite_desc = Begin met het typen van een gebruikersnaam om een nieuw lid aan %s uit te nodigen:
|
||||
members.invite_now = Nu uitnodigen
|
||||
teams.join = Lid worden
|
||||
teams.leave = Vertlaat
|
||||
teams.read_access = Leestoegang
|
||||
teams.read_access_helper = Dit team is in staat om zijn repositories te bekijken en te klonen.
|
||||
teams.write_access = Schrijf toegang
|
||||
teams.write_access_helper = Dit team is in staat om zijn repositories te bekijken en push aanvragen te verwerken.
|
||||
teams.admin_access = Beheerder toegang
|
||||
teams.admin_access_helper = Dit team is in staat om push & pull aanvragen te verwerken en om nieuwe medewerkers toe te voegen.
|
||||
teams.no_desc = Dit team heeft geen omschrijving
|
||||
teams.settings = Instellingen
|
||||
teams.owners_permission_desc = Eigenaren hebben volledige toegang tot <strong>alle repositories</strong> en hebben <strong>beheerder rechten</strong> over de organisatie.
|
||||
teams.members = Team leden
|
||||
teams.update_settings = Instellingen bijwerken
|
||||
teams.delete_team = Verwijder deze team
|
||||
teams.add_team_member = Nieuwe team lid aanmaken
|
||||
teams.delete_team_success = Gekozen team is succesvol verwijderd.
|
||||
teams.read_permission_desc = Dit team heeft <strong>Lees</strong> rechten : leden kunnen repositories lezen en klonen.
|
||||
teams.write_permission_desc = Dit team heeft <strong>Schrijf</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken.
|
||||
teams.admin_permission_desc = Dit team heeft <strong>Beheerders</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken en medewerkers toevoegen.
|
||||
teams.repositories = Teamrepositories
|
||||
teams.add_team_repository = Nieuwe teamrepositorie aanmaken
|
||||
teams.remove_repo = Verwijder
|
||||
settings.change_orgname = Organisatie naam veranderd
|
||||
settings.change_orgname_desc = De naam van de organisatie is veranderd, wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op deze organisatie.
|
||||
settings.delete_org_title = Verwijderen organsiatie
|
||||
settings.delete_org_desc = Deze organisatie zal permanent worden verwijderd, wilt u doorgaan?
|
||||
settings.hooks_desc = Een webhook toevoegen die door <strong>alle repositories</strong> in deze organisatie getriggerd kan worden.
|
||||
teams.delete_team_title = Team verwijderen
|
||||
teams.delete_team_desc = Dit team zal worden verwijderd. De leden van dit team zullen toegang tot alle repositories van het team verliezen. Wilt u doorgaan?
|
||||
|
||||
[admin]
|
||||
dashboard = Dashboard
|
||||
users = Gebruikers
|
||||
organizations = Orgranisaties
|
||||
repositories = Repositories
|
||||
authentication = Autenticaties
|
||||
config = Configuratie
|
||||
monitor = Bijhouden
|
||||
prev = Vorige
|
||||
next = Volgende
|
||||
dashboard.statistic = Statistieken
|
||||
dashboard.operations = Bewerkingen
|
||||
dashboard.system_status = Status Systeemmonitor
|
||||
dashboard.statistic_info = Gogs database heeft <b>%d</b> gebruikers, <b>%d</b> organisaties, <b>%d</b> openbare sleutels, <b>%d</b> repositories, <b>%d</b> volgers, <b>%d</b> sterren, <b>%d</b> acties, <b>%d</b> participanten, <b>%d</b> issues, <b>%d</b> reacties, <b>%d</b> sociale accounten, <b>%d</b> volgers, <b>%d</b> mirrors, <b>%d</b> publicaties, <b>%d</b> login bronnen, <b>%d</b> webhooks, <b>%d</b> mijlpalen, <b>%d</b> labels, <b>%d</b> hook taken, <b>%d</b> teams, <b>%d</b> bijgewerkte taken, <b>%d</b> bijlagen.
|
||||
dashboard.operation_name = Bewerking naam
|
||||
dashboard.operation_switch = Omschakelen
|
||||
dashboard.operation_run = Uitvoeren
|
||||
dashboard.clean_unbind_oauth = Clean unbound OAuths
|
||||
dashboard.delete_inactivate_accounts = Verwijder alle inactieve accounts
|
||||
dashboard.server_uptime = Uptime server
|
||||
dashboard.current_goroutine = Huidige Goroutines
|
||||
dashboard.current_memory_usage = Huidige geheugen gebruik
|
||||
dashboard.total_memory_allocated = Totaal toegewezen geheugen
|
||||
dashboard.memory_obtained = Geheugen gebruikt
|
||||
dashboard.pointer_lookup_times = Pointer Lookup Times
|
||||
dashboard.memory_allocate_times = Memory Allocate Times
|
||||
dashboard.memory_free_times = Memory Free Times
|
||||
dashboard.current_heap_usage = Current Heap Usage
|
||||
dashboard.heap_memory_obtained = Heap Memory Obtained
|
||||
dashboard.heap_memory_idle = Heap Memory Idle
|
||||
dashboard.heap_memory_in_use = Heap Memory In Use
|
||||
dashboard.heap_memory_released = Heap Memory Released
|
||||
dashboard.heap_objects = Heap Objects
|
||||
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
|
||||
dashboard.stack_memory_obtained = Stack Memory Obtained
|
||||
dashboard.mspan_structures_usage = MSpan Structures Usage
|
||||
dashboard.mspan_structures_obtained = MSpan Structures Obtained
|
||||
dashboard.mcache_structures_usage = MCache Structures Usage
|
||||
dashboard.mcache_structures_obtained = MCache Structures Obtained
|
||||
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
|
||||
dashboard.gc_metadata_obtained = GC Metadada Obtained
|
||||
dashboard.other_system_allocation_obtained = Other System Allocation Obtained
|
||||
dashboard.next_gc_recycle = Volgende GC recycle
|
||||
dashboard.last_gc_time = Sinds vorige GC verwerkingstijd
|
||||
dashboard.total_gc_time = Totaal GC verwerkingstijd
|
||||
dashboard.total_gc_pause = Totaal GC verwerkingstijd
|
||||
dashboard.last_gc_pause = Laatste GC verwerkingstijd
|
||||
dashboard.gc_times = GC verwerkingen
|
||||
users.user_manage_panel = Gebruikers beheren
|
||||
users.new_account = Nieuw account aanmaken
|
||||
users.name = Naam
|
||||
users.activated = Geactiveerd
|
||||
users.admin = Admin
|
||||
users.repos = Repos
|
||||
users.created = Aangemaakt
|
||||
users.edit = Bewerken
|
||||
users.auth_source = Autorisatiebron
|
||||
users.local = Lokaal
|
||||
users.auth_login_name = Autorisatie inlognaam
|
||||
users.update_profile_success = Profiel is succesvol bijgewerkt.
|
||||
users.edit_account = Bewerk account
|
||||
users.is_activated = Dit account is geactiveerd
|
||||
users.is_admin = Dit account heeft beheerdersrechten
|
||||
users.update_profile = Account profiel bijwerken
|
||||
users.delete_account = Dit account verwijderen
|
||||
users.still_own_repo = Dit account is nog steeds eigendom van een repositorie. U moet deze repositorie eerst verwijderen of overdragen.
|
||||
orgs.org_manage_panel = Organisaties beheren
|
||||
orgs.name = Naam
|
||||
orgs.teams = Teams
|
||||
orgs.members = Leden
|
||||
repos.repo_manage_panel = Repositoriebeheerpaneel
|
||||
repos.owner = Eigenaar
|
||||
repos.name = Naam
|
||||
repos.private = Prive
|
||||
repos.watches = Volgers
|
||||
repos.stars = Sterren
|
||||
repos.issues = Issues
|
||||
auths.auth_manage_panel = Autorisatiebeheerpaneel
|
||||
auths.new = Nieuwe autorisatiebron
|
||||
auths.name = Naam
|
||||
auths.type = Type
|
||||
auths.enabled = Ingeschakeld
|
||||
auths.updated = Bijgewerkt
|
||||
auths.auth_type = Autorisatietype
|
||||
auths.auth_name = Autorisatienaam
|
||||
auths.domain = Domein
|
||||
auths.host = Host
|
||||
auths.port = Poort
|
||||
auths.base_dn = Base DN
|
||||
auths.attributes = Zoek attributen
|
||||
auths.filter = Zoek filter
|
||||
auths.ms_ad_sa = Ms Ad SA
|
||||
auths.smtp_auth = SMTP authenticatietype
|
||||
auths.smtphost = SMTP host
|
||||
auths.smtpport = SMTP poort
|
||||
auths.enable_tls = Activeer TLS-encryptie
|
||||
auths.enable_auto_register = Activeer automatische registratie
|
||||
auths.tips = Tips
|
||||
auths.edit = Bewerk autorisatie-instellingen
|
||||
auths.activated = Deze autorisatiemethode is geactiveerd
|
||||
auths.update_success = Autorisatie-instellingen zijn succesvol bijgewerkt.
|
||||
auths.update = Update autorisatie-instellingen
|
||||
auths.delete = Verwijder deze autorisatie
|
||||
config.server_config = Serverconfiguratie
|
||||
config.app_name = Applicatienaam
|
||||
config.app_ver = Applicatieversie
|
||||
config.app_url = Applicatie-URL
|
||||
config.domain = Domein
|
||||
config.offline_mode = Offline-modus
|
||||
config.disable_router_log = Router-log uitschakelen
|
||||
config.run_user = Uitvoerende gebruiker
|
||||
config.run_mode = Uitvoer modus
|
||||
config.repo_root_path = Repositorie basis pad
|
||||
config.static_file_root_path = Statische bestanden basis pad
|
||||
config.log_file_root_path = Log bestand basis pad
|
||||
config.script_type = Script type
|
||||
config.reverse_auth_user = Reverse Authentication User
|
||||
config.db_config = Databaseconfiguratie
|
||||
config.db_type = Type
|
||||
config.db_host = Host
|
||||
config.db_name = Naam
|
||||
config.db_user = Gebruiker
|
||||
config.db_ssl_mode = SSL modus
|
||||
config.db_ssl_mode_helper = (alleen voor "postgres")
|
||||
config.db_path = Path
|
||||
config.db_path_helper = (alleen voor "sqlite3")
|
||||
config.service_config = Serviceconfiguratie
|
||||
config.register_email_confirm = Register Email Confirmation
|
||||
config.disable_register = Registratie uitgeschakeld
|
||||
config.require_sign_in_view = Inloggen vereist om te kunnen inzien
|
||||
config.mail_notify = E-mailnotificaties
|
||||
config.enable_cache_avatar = Avatar Cache inschakelen
|
||||
config.active_code_lives = Active Code Lives
|
||||
config.reset_password_code_lives = Reset Password Code Lives
|
||||
config.webhook_config = Webhook configuratie
|
||||
config.task_interval = Taakinterval
|
||||
config.deliver_timeout = Bezorging verlooptijd
|
||||
config.mailer_config = Mailerconfiguatie
|
||||
config.mailer_enabled = Ingeschakeld
|
||||
config.mailer_name = Naam
|
||||
config.mailer_host = Host
|
||||
config.mailer_user = Gebruiker
|
||||
config.oauth_config = OAuth-configuratie
|
||||
config.oauth_enabled = Ingeschakeld
|
||||
config.cache_config = Cache-configuratie
|
||||
config.cache_adapter = Cache-adapter
|
||||
config.cache_interval = Cache-interval
|
||||
config.cache_conn = Cache-connectie
|
||||
config.session_config = Sessieconfiguratie
|
||||
config.session_provider = Sessieprovider
|
||||
config.provider_config = Provider config
|
||||
config.cookie_name = Cookie naam
|
||||
config.enable_set_cookie = Set Cookie inschakelen
|
||||
config.gc_interval_time = GC interval time
|
||||
config.session_life_time = Sessie duur
|
||||
config.https_only = Alleen HTTPS
|
||||
config.cookie_life_time = Cookie duur leeftijd
|
||||
config.session_hash_function = Sessie ID Hash functie
|
||||
config.session_hash_key = Sessie ID Hash sleutel
|
||||
config.picture_config = Foto configuratie
|
||||
config.picture_service = Foto service
|
||||
config.disable_gravatar = Gravatar uitschakelen
|
||||
config.log_config = Logconfiguratie
|
||||
config.log_mode = Log-modus
|
||||
monitor.cron = Cron-taken
|
||||
monitor.name = Naam
|
||||
monitor.schedule = Planning
|
||||
monitor.next = Volgende
|
||||
monitor.previous = Vorige
|
||||
monitor.execute_times = Aantal keren uitgevoerd
|
||||
monitor.process = Draaiende processen
|
||||
monitor.desc = Omschrijving
|
||||
monitor.start = Starttijd
|
||||
monitor.execute_time = Uitvoertijd
|
||||
auths.delete_auth_title = Verwijderings-autorisatie
|
||||
auths.delete_auth_desc = Deze autorisatiemethode wordt verwijderd. Weet u zeker dat u wilt doorgaan?
|
||||
|
||||
[action]
|
||||
create_repo = repositorie aangemaakt in <a href="%s/%s">%s</a>
|
||||
commit_repo = push update naar <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a
|
||||
create_issue = opende issue in <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = reactie op issue <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
transfer_repo = repositorie verplaatst naar <code>%s</code> naar <a href="/%s%s">%s</a>
|
||||
|
||||
[tool]
|
||||
ago = geleden
|
||||
from_now = vanaf nu
|
||||
now = nu
|
||||
1s = 1 seconde %s
|
||||
1m = 1 minuut %s
|
||||
1h = 1 uur %s
|
||||
1d = 1 dag %s
|
||||
1w = 1 week %s
|
||||
1mon = 1 maand %s
|
||||
1y = 1 jaar %s
|
||||
seconds = %d seconden %s
|
||||
minutes = %d minuten %s
|
||||
hours = %d uur %s
|
||||
days = %d dagen %s
|
||||
weeks = %d weken %s
|
||||
months = %d maanden %s
|
||||
years = %d jaren %s
|
||||
raw_seconds = seconden
|
||||
raw_minutes = minuten
|
||||
|
||||
[install]
|
||||
install = Installatie
|
||||
title = Installatiestappen voor de eerste keer opstarten
|
||||
requite_db_desc = Om Gogs te gebruiken is MySQL, PostgreSQL of SQLite3 vereist (SQLite3 is beschikbaar in de officiële versie).
|
||||
db_type = Database-type
|
||||
host = Host
|
||||
user = Gebruikersnaam
|
||||
password = Wachtwoord
|
||||
db_name = Database naam
|
||||
db_helper = Gebruik InnoDB engine met utf8_general_ci karakterset voor MySQL.
|
||||
ssl_mode = SSL-modus
|
||||
path = Pad
|
||||
sqlite_helper = Het pad naar de SQLite3 database.
|
||||
general_title = Algemene instellingen van Gogs
|
||||
repo_path = Repositories basis directorie
|
||||
repo_path_helper = Alle remote Git repositories worden in deze directorie opgeslagen
|
||||
run_user = Uitvoerende gebruikersnaam
|
||||
run_user_helper = Deze gebruiker moet toegang hebben tot de git repositorie directorie en moet Gogs kunnen starten
|
||||
domain = Domein
|
||||
domain_helper = Dit heeft invloed op de SSH kloon URLs
|
||||
app_url = Applicatie URL
|
||||
app_url_helper = Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt
|
||||
email_title = Email service instellingen (Optioneel)
|
||||
smtp_host = SMTP host
|
||||
mailer_user = Afzender e-mail / gebruikersnaam
|
||||
mailer_password = Wachtwoord
|
||||
notify_title = Notificatie-instelligen (optioneel)
|
||||
register_confirm = Activeer registratie emails
|
||||
mail_notify = Activeer e-mailnotificaties
|
||||
admin_title = Instellingen beheerdersaccount
|
||||
admin_name = Gebruikersnaam
|
||||
admin_password = Wachtwoord
|
||||
confirm_password = Verifieer wachtwoord
|
||||
admin_email = E-mailadres
|
||||
install_gogs = Installeer Gogs
|
||||
test_git_failed = Git test niet gelukt: 'git' commando %v
|
||||
sqlite3_not_available = SQLite3 wordt niet ondersteund in uw versie. Gelieve de officiële versie downloaden vanaf http://gogs.io/docs/installation/install_from_binary.html, niet de gobuild versie downloaden.
|
||||
invalid_db_setting = Uw database instellingen zijn niet correct: %v
|
||||
invalid_repo_path = Repositorie basis pad is niet correct: %v
|
||||
run_user_not_match = De uitvoerende gebruiker is niet de huidig gebruiker: %s -> %s
|
||||
save_config_failed = Kan de configuratie niet opslaan: %v
|
||||
invalid_admin_setting = Uw admin-instellingen zijn niet geldig: %v
|
||||
install_success = Welkom! Wij zijn veheugd dat u voor Gogs heeft gekozen, veel plezier en tot ziens
|
||||
|
||||
[explore]
|
||||
repos = Repositories
|
||||
|
||||
[user]
|
||||
change_avatar = Verander uw avatar op Gravatar.com
|
||||
join_on = Aangemeld op
|
||||
repositories = repositories
|
||||
activity = Openbare activiteit
|
||||
followers = Volgers
|
||||
starred = Sterren
|
||||
following = Volgt
|
||||
@@ -166,6 +166,15 @@ org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先
|
||||
|
||||
still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试!
|
||||
|
||||
[user]
|
||||
change_avatar = 到 gravatar.com 上修改您的头像
|
||||
join_on = 加入于
|
||||
repositories = 仓库列表
|
||||
activity = 公开活动
|
||||
followers = 关注者
|
||||
starred = 已点赞
|
||||
following = 关注中
|
||||
|
||||
[settings]
|
||||
profile = 个人信息
|
||||
password = 修改密码
|
||||
@@ -182,6 +191,10 @@ website = 个人网站
|
||||
location = 所在地区
|
||||
update_profile = 更新信息
|
||||
update_profile_success = 您的个人信息更新成功!
|
||||
change_username = 用户名将被修改
|
||||
change_username_desc = 用户名被修改,您确定要继续操作吗?这将会影响到所有与您帐户有关的链接。
|
||||
continue = 继续操作
|
||||
cancel = 取消操作
|
||||
|
||||
change_password = 修改密码
|
||||
old_password = 当前密码
|
||||
@@ -210,6 +223,8 @@ unbind_success = 社交帐号解除绑定成功!
|
||||
delete_account = 删除当前帐户
|
||||
delete_prompt = 删除操作会永久清除您的帐户信息,并且 <strong>不可恢复</strong>!
|
||||
confirm_delete_account = 确认删除帐户
|
||||
delete_account_title = 帐户删除操作
|
||||
delete_account_desc = 该帐户将被永久性删除,您确定要继续操作吗?
|
||||
|
||||
[repo]
|
||||
owner = 拥有者
|
||||
@@ -235,6 +250,8 @@ migrate_type_helper = 本仓库将是 <span class="label label-blue label-radius
|
||||
migrate_repo = 迁移仓库
|
||||
|
||||
copy_link = 复制链接
|
||||
click_to_copy = 复制到剪切板
|
||||
copied = 复制成功
|
||||
clone_helper = 不知道如何操作?访问 <a target="_blank" href="http://git-scm.com/book/zh/Git-基础-取得项目的-Git-仓库">此处</a> 查看帮助!
|
||||
unwatch = 取消关注
|
||||
watch = 关注
|
||||
@@ -242,36 +259,66 @@ unstar = 取消点赞
|
||||
star = 点赞
|
||||
fork = 派生
|
||||
|
||||
no_desc = 暂无描述
|
||||
quick_guide = 快速帮助
|
||||
clone_this_repo = 克隆当前仓库
|
||||
create_new_repo_command = 从命令行创建一个新的仓库
|
||||
push_exist_repo = 从命令行推送已经创建的仓库
|
||||
|
||||
branch = 分支
|
||||
tree = 目录树
|
||||
branch_and_tags = 分支与标签
|
||||
branches = 分支列表
|
||||
tags = 标签列表
|
||||
issues = 工单管理
|
||||
commits = 提交历史
|
||||
releases = 版本发布
|
||||
|
||||
commits.commits = 次代码提交
|
||||
commits.search = 搜索提交历史
|
||||
commits.find = 查找
|
||||
commits.author = 作者
|
||||
commits.message = 备注
|
||||
commits.date = 提交日期
|
||||
commits.older = 更旧的提交
|
||||
commits.newer = 更新的提交
|
||||
|
||||
settings = 仓库设置
|
||||
settings.options = 基本设置
|
||||
settings.collaboration = 管理协作者
|
||||
settings.hooks = 管理 Web 钩子
|
||||
settings.githooks = 管理 Git 钩子
|
||||
settings.deploy_keys = 管理部署密钥
|
||||
settings.basic_settings = 基本设置
|
||||
settings.danger_zone = 危险操作区
|
||||
settings.site = 官方网站
|
||||
settings.update_settings = 更新仓库设置
|
||||
settings.change_reponame = 仓库名称将被修改
|
||||
settings.change_reponame_desc = 仓库名称被修改,您确定要继续操作吗?这将会影响到所有与该仓库有关的链接。
|
||||
settings.transfer = 转移仓库所有权
|
||||
settings.transfer_desc = 您可以将仓库转移至您拥有管理员权限的帐户或组织。
|
||||
settings.new_owner_has_same_repo = 新的仓库拥有者已经存在同名仓库!
|
||||
settings.delete = 删除本仓库
|
||||
settings.delete_desc = 删除仓库操作不可逆转,请三思而后行。
|
||||
settings.transfer_notices = <p>- 如果您转移给个人用户,您将对仓库失去所有权限。</p><p>- 如果您转移给您作为拥有者的组织,则可继续保持操作权限。</p>
|
||||
settings.update_settings_success = 仓库设置更新成功!
|
||||
settings.transfer_owner = 新拥有者
|
||||
settings.make_transfer = 确认转移仓库
|
||||
settings.transfer_succeed = 仓库所有权转移成功!
|
||||
settings.confirm_delete = 确认删除仓库
|
||||
settings.add_collaborator = 增加新的协作者
|
||||
settings.add_collaborator_success = 成功添加新的协作者!
|
||||
settings.remove_collaborator_success = 被操作的协作者已经被收回权限!
|
||||
settings.user_is_org_member = 被操作的用户是组织成员,因此无法添加为协作者!
|
||||
settings.add_webhook = 添加 Web 钩子
|
||||
settings.hooks_desc = Web 钩子允许您设定在 Gogs 上发生指定事件时对指定 URL 发送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。
|
||||
settings.remove_hook_success = Web 钩子删除成功!
|
||||
settings.add_webhook_desc = 我们会通过 <code>POST</code> 请求将订阅事件信息发送至向指定 URL 地址。您可以设置不同的数据接收方式(JSON 或 <code>x-www-form-urlencoded</code>)。 请查阅 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。
|
||||
settings.githooks_desc = Git 钩子是由 Git 本身提供的功能,以下为 Gogs 所支持的钩子列表。
|
||||
settings.githook_edit_desc = 如果钩子未启动,则会显示样例文件中的内容。如果想要删除某个钩子,则提交空白文本即可。
|
||||
settings.githook_name = 钩子名称
|
||||
settings.githook_content = 钩子文本
|
||||
settings.update_githook = 更新钩子设置
|
||||
settings.payload_url = 推送地址
|
||||
settings.content_type = 数据格式
|
||||
settings.secret = 密钥文本
|
||||
@@ -315,11 +362,16 @@ settings.full_name = 组织全名
|
||||
settings.website = 官方网站
|
||||
settings.location = 所在地区
|
||||
settings.update_settings = 更新组织设置
|
||||
settings.change_orgname = 组织名称将被修改
|
||||
settings.change_orgname_desc = 组织名称被修改,您确定要继续操作吗?这将会影响到所有与该组织有关的链接。
|
||||
settings.update_setting_success = 组织设置更新成功!
|
||||
settings.delete = 删除组织
|
||||
settings.delete_account = 删除当前组织
|
||||
settings.delete_prompt = 删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>!
|
||||
settings.confirm_delete_account = 确认删除组织
|
||||
settings.delete_org_title = 组织删除操作
|
||||
settings.delete_org_desc = 该组织将被永久性删除,您确定要继续操作吗?
|
||||
settings.hooks_desc = 在此处添加的 Web 钩子将会应用到该组织下的 <strong>所有仓库</strong>。
|
||||
|
||||
members.public = 公开成员
|
||||
members.public_helper = 设为私有
|
||||
@@ -348,6 +400,8 @@ teams.members = 团队成员
|
||||
teams.update_settings = 更新团队设置
|
||||
teams.delete_team = 删除当前团队
|
||||
teams.add_team_member = 添加团队成员
|
||||
teams.delete_team_title = 团队删除操作
|
||||
teams.delete_team_desc = 删除操作会永久清除有关该团队的信息,您确定要继续操作吗?团队成员可能会失去对某些仓库的操作权限。
|
||||
teams.delete_team_success = 指定团队删除成功!
|
||||
teams.read_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 权限,团队成员可以进行查看和克隆等只读操作。
|
||||
teams.write_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 和 <strong>写入</strong> 的权限。
|
||||
@@ -355,6 +409,7 @@ teams.admin_permission_desc = 该团队拥有一定的 <strong>管理</strong>
|
||||
teams.repositories = 团队仓库
|
||||
teams.add_team_repository = 添加团队仓库
|
||||
teams.remove_repo = 移除仓库
|
||||
teams.add_nonexistent_repo = 您尝试添加到团队的仓库不存在,请先创建仓库!
|
||||
|
||||
[admin]
|
||||
dashboard = 控制面板
|
||||
@@ -363,6 +418,7 @@ organizations = 组织管理
|
||||
repositories = 仓库管理
|
||||
authentication = 授权认证管理
|
||||
config = 应用配置管理
|
||||
notices = 系统提示管理
|
||||
monitor = 应用监控面板
|
||||
prev = 上一页
|
||||
next = 下一页
|
||||
@@ -423,6 +479,7 @@ users.is_activated = 该用户已被激活
|
||||
users.is_admin = 该用户具有管理员权限
|
||||
users.update_profile = 更新用户信息
|
||||
users.delete_account = 删除该用户
|
||||
users.still_own_repo = 该帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作!
|
||||
|
||||
orgs.org_manage_panel = 组织管理面板
|
||||
orgs.name = 组织名称
|
||||
@@ -463,6 +520,8 @@ auths.activated = 该授权认证已经启用
|
||||
auths.update_success = 授权认证设置更新成功!
|
||||
auths.update = 更新授权认证信息
|
||||
auths.delete = 删除该授权认证
|
||||
auths.delete_auth_title = 授权认证删除操作
|
||||
auths.delete_auth_desc = 该授权认证将被删除,您确定要继续吗?
|
||||
|
||||
config.server_config = 服务器配置
|
||||
config.app_name = 应用名称
|
||||
@@ -537,11 +596,19 @@ monitor.desc = 进程描述
|
||||
monitor.start = 开始时间
|
||||
monitor.execute_time = 已执行时间
|
||||
|
||||
notices.system_notice_list = 系统提示管理
|
||||
notices.type = 提示类型
|
||||
notices.type_1 = 仓库
|
||||
notices.desc = 描述
|
||||
notices.op = 操作
|
||||
notices.delete_success = 系统提示删除成功!
|
||||
|
||||
[action]
|
||||
create_repo = 创建了仓库 <a href="/%s">%s</a>
|
||||
commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>
|
||||
create_issue = 创建了工单 <a href="/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = 评论了工单 <a href="/%s/issues/%s">%s#%s</a>
|
||||
create_repo = 创建了仓库 <a href="%s/%s">%s</a>
|
||||
commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a>
|
||||
create_issue = 创建了工单 <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = 评论了工单 <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
transfer_repo = 将仓库 <code>%s</code> 转移至 <a href="/%s%s">%s</a>
|
||||
|
||||
[tool]
|
||||
ago = 之前
|
||||
|
||||
642
conf/locale/locale_zh-HK.ini
Normal file
642
conf/locale/locale_zh-HK.ini
Normal file
@@ -0,0 +1,642 @@
|
||||
app_desc = 基於 Go 語言的自助 Git 服務
|
||||
|
||||
home = 首頁
|
||||
dashboard = 控制面版
|
||||
explore = 探索
|
||||
help = 幫助
|
||||
sign_in = 登錄
|
||||
social_sign_in = 社交帳號登錄:第 2 步 <small>關聯帳號</small>
|
||||
sign_out = 退出
|
||||
sign_up = 註冊
|
||||
register = 註冊
|
||||
website = 官方網站
|
||||
version = 當前版本
|
||||
page = 頁面
|
||||
template = 模版
|
||||
language = 語言選項
|
||||
|
||||
username = 用戶名
|
||||
email = 郵箱
|
||||
password = 密碼
|
||||
re_type = 確認密碼
|
||||
captcha = 驗證碼
|
||||
|
||||
repository = 倉庫
|
||||
organization = 組織
|
||||
mirror = 鏡像
|
||||
new_repo = 創建新的倉庫
|
||||
new_migrate = 遷移外部倉庫
|
||||
new_org = 創建新的組織
|
||||
manage_org = 管理我的組織
|
||||
admin_panel = 管理面版
|
||||
account_settings = 帳戶設置
|
||||
settings = 帳戶設置
|
||||
|
||||
news_feed = 最新活動
|
||||
pull_requests = 合併請求
|
||||
issues = 問題管理
|
||||
|
||||
cancel = 取消
|
||||
|
||||
[install]
|
||||
install = 安裝頁面
|
||||
title = 首次執行安裝程序
|
||||
requite_db_desc = Gogs 允許後端數據庫為 MySQL、PostgreSQL 或 SQLite3,但是 SQLite3 一般只有官方二進制發行版才支持。
|
||||
db_type = 數據庫類型
|
||||
host = 數據庫主機
|
||||
user = 數據庫用戶
|
||||
password = 數據庫用戶密碼
|
||||
db_name = 數據庫名稱
|
||||
db_helper = 如果您使用 MySQL,請使用 INNODB 引擎以及 utf8_general_ci 字符集。
|
||||
ssl_mode = SSL 模式
|
||||
path = 數據庫文件路徑
|
||||
sqlite_helper = SQLite3 數據庫的文件路徑。
|
||||
general_title = 應用基本設置
|
||||
repo_path = 倉庫根目錄
|
||||
repo_path_helper = 所有 Git 遠程倉庫都將被存放於該目錄。
|
||||
run_user = 執行系統用戶
|
||||
run_user_helper = 該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。
|
||||
domain = 域名
|
||||
domain_helper = 該設置影響 SSH 克隆地址。
|
||||
app_url = 應用 URL
|
||||
app_url_helper = 該設置影響 HTTP/HTTPS 克隆地址和一些郵箱中的鏈接。
|
||||
email_title = 郵件服務設置(可選)
|
||||
smtp_host = SMTP 主機
|
||||
mailer_user = 發送郵箱
|
||||
mailer_password = 發送郵箱密碼
|
||||
notify_title = 通知提醒設置(可選)
|
||||
register_confirm = 啟用註冊郵箱確認
|
||||
mail_notify = 啟用郵件通知提醒
|
||||
admin_title = 管理員帳號設置
|
||||
admin_name = 管理員用戶名
|
||||
admin_password = 管理員密碼
|
||||
confirm_password = 確認密碼
|
||||
admin_email = 管理員郵箱
|
||||
install_gogs = 立即安裝
|
||||
test_git_failed = 無法識別 'git' 命令:%v
|
||||
sqlite3_not_available = 您所使用的發行版本不支持 SQLite3,請從 http://gogs.io/docs/installation/install_from_binary.html 下載官方二進制發行版本,而不是 gobuild 版本。
|
||||
invalid_db_setting = 數據庫設置不正確:%v
|
||||
invalid_repo_path = 倉庫根目錄設置不正確:%v
|
||||
run_user_not_match = 執行系統用戶非當前用戶:%s -> %s
|
||||
save_config_failed = 應用配置保存失敗:%v
|
||||
invalid_admin_setting = 管理員帳戶設置不正確:%v
|
||||
install_success = 您好!我們很高興您選擇使用 Gogs,祝您使用愉快,代碼從此無 BUG!
|
||||
|
||||
[home]
|
||||
uname_holder = 用戶名或郵箱
|
||||
password_holder = 密碼
|
||||
switch_dashboard_context = 切換控制面版用戶
|
||||
my_repos = 我的倉庫
|
||||
collaborative_repos = 參與協作的倉庫
|
||||
my_orgs = 我的組織
|
||||
my_mirrors = 我的鏡像
|
||||
|
||||
[explore]
|
||||
repos = 探索倉庫
|
||||
|
||||
[auth]
|
||||
create_new_account = 創建帳戶
|
||||
register_hepler_msg = 已經註冊?立即登錄!
|
||||
social_register_hepler_msg = 已經註冊?立即綁定!
|
||||
disable_register_prompt = 對不起,註冊功能已被關閉。請聯系網站管理員。
|
||||
disable_register_mail = 對不起,註冊郵箱確認功能已被關閉。
|
||||
remember_me = 記住登錄
|
||||
forgot_password = 忘記密碼
|
||||
forget_password = 忘記密碼?
|
||||
sign_up_now = 還沒帳戶?馬上註冊。
|
||||
confirmation_mail_sent_prompt = 一封新的確認郵件已經被發送至 <b>%s</b>,請檢查您的收件箱並在 %d 小時內完成確認註冊操作。
|
||||
sign_in_email = 登錄到您的郵箱
|
||||
active_your_account = 激活您的帳戶
|
||||
resent_limit_prompt = 對不起,您請求發送激活郵件過於頻繁,請等待 3 分鐘後再試!
|
||||
has_unconfirmed_mail = %s 您好,系統檢測到您有一封發送至 <b>%s</b> 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。
|
||||
resend_mail = 單擊此處重新發送確認郵件
|
||||
email_not_associate = 您輸入的郵箱地址未被關聯到任何帳號!
|
||||
send_reset_mail = 單擊此處(重新)發送您的密碼重置郵件
|
||||
reset_password = 重置密碼
|
||||
invalid_code = 對不起,您的確認代碼已過期或已失效。
|
||||
reset_password_helper = 單擊此處重置密碼
|
||||
password_too_short = 密碼長度不能少於 6 位!
|
||||
|
||||
[form]
|
||||
UserName = 用戶名
|
||||
RepoName = 倉庫名稱
|
||||
Email = 郵箱地址
|
||||
Password = 密碼
|
||||
Retype = 確認密碼
|
||||
SSHTitle = SSH 密鑰名稱
|
||||
HttpsUrl = HTTPS URL 地址
|
||||
PayloadUrl = 推送地址
|
||||
TeamName = 團隊名稱
|
||||
AuthName = 認證名稱
|
||||
AdminEmail = 管理員郵箱
|
||||
|
||||
require_error = 不能為空。
|
||||
alpha_dash_error = 必須為英文字母、阿拉伯數字或橫線(-_)。
|
||||
alpha_dash_dot_error = 必須為英文字母、阿拉伯數字、橫線(-_)或點。
|
||||
min_size_error = 長度最小為 %s 個字符。
|
||||
max_size_error = 長度最大為 %s 個字符。
|
||||
email_error = 不是一個有效的郵箱地址。
|
||||
url_error = 不是一個有效的 URL。
|
||||
unknown_error = 未知錯誤:
|
||||
captcha_incorrect = 驗證碼未匹配。
|
||||
password_not_match = 密碼與確認密碼未匹配。
|
||||
|
||||
username_been_taken = 用戶名已經被佔用。
|
||||
repo_name_been_taken = 倉庫名稱已經被佔用。
|
||||
org_name_been_taken = 組織名稱已經被佔用。
|
||||
team_name_been_taken = 團隊名稱已經被佔用。
|
||||
email_been_used = 郵箱地址已經被使用。
|
||||
ssh_key_been_used = SSH 密鑰已經被使用。
|
||||
illegal_username = 您的用戶名包含不合法字符。
|
||||
illegal_repo_name = 倉庫名稱包含不合法字符。
|
||||
illegal_org_name = 組織名稱包含不合法字符。
|
||||
illegal_team_name = 團隊名稱包含不合法字符。
|
||||
username_password_incorrect = 用戶名或密碼不正確。
|
||||
enterred_invalid_repo_name = 請檢查您輸入的倉庫名稱是正確。
|
||||
enterred_invalid_owner_name = 請檢查您輸入的新所有者用戶名是否正確。
|
||||
enterred_invalid_password = 請檢查您輸入的密碼是否正確。
|
||||
user_not_exist = 被操作的用戶不存在!
|
||||
last_org_owner = 被移除用戶為最後一位管理員。請添加一位新的管理員再進行移除成員操作!
|
||||
|
||||
invalid_ssh_key = 很抱歉,我們無法驗證您輸入的 SSH 密鑰:%s
|
||||
auth_failed = 授權驗證失敗:%v
|
||||
|
||||
still_own_repo = 您的帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作!
|
||||
org_still_own_repo = 該組織仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除組織操作!
|
||||
|
||||
still_own_user = 該授權認證依舊被部分用戶使用,請先刪除該部分用戶後再試!
|
||||
|
||||
[user]
|
||||
change_avatar = 到 gravatar.com 上修改您的頭像
|
||||
join_on = 加入於
|
||||
repositories = 倉庫列表
|
||||
activity = 公開活動
|
||||
followers = 關註者
|
||||
starred = 已點讚
|
||||
following = 關註中
|
||||
|
||||
[settings]
|
||||
profile = 個人信息
|
||||
password = 修改密碼
|
||||
ssh_keys = 管理 SSH 密鑰
|
||||
social = 社交帳號綁定
|
||||
orgs = 管理組織
|
||||
delete = 刪除帳戶
|
||||
uid = 用戶 ID
|
||||
|
||||
public_profile = 公開信息
|
||||
profile_desc = 您的郵箱地址將會被公開,並被用於接收帳戶的所有提醒和通知。
|
||||
full_name = 自定義名稱
|
||||
website = 個人網站
|
||||
location = 所在地區
|
||||
update_profile = 更新信息
|
||||
update_profile_success = 您的個人信息更新成功!
|
||||
change_username = 用戶名將被修改
|
||||
change_username_desc = 用戶名被修改,您確定要繼續操作嗎?這將會影響到所有與您帳戶有關的鏈接。
|
||||
continue = 繼續操作
|
||||
cancel = 取消操作
|
||||
|
||||
change_password = 修改密碼
|
||||
old_password = 當前密碼
|
||||
new_password = 新的密碼
|
||||
password_incorrect = 當前密碼不正確!
|
||||
change_password_success = 密碼修改成功!您現在可以使用新的密碼登錄。
|
||||
|
||||
manage_ssh_keys = 管理 SSH 密鑰
|
||||
add_key = 增加密鑰
|
||||
ssh_desc = 以下是與您帳戶所關聯的 SSH 密鑰,如果您發現有陌生的密鑰,請立即刪除它!
|
||||
ssh_helper = <strong>需要幫助?</strong> 請查看有關 <a href="https://help.github.com/articles/generating-ssh-keys">如何生成 SSH 密鑰</a> 或 <a href="https://help.github.com/ssh-issues/">常見 SSH 問題</a> 尋找答案。
|
||||
add_new_key = 增加 SSH 密鑰
|
||||
key_name = 密鑰名稱
|
||||
key_content = 密鑰內容
|
||||
add_key_success = 新的 SSH 密鑰添加成功!
|
||||
delete_key = 刪除
|
||||
add_on = 增加於
|
||||
last_used = 上次使用在
|
||||
no_activity = 沒有最近活動
|
||||
|
||||
manage_social = 管理關聯社交帳戶
|
||||
social_desc = 以下是與您帳戶所關聯的社交帳號,如果您發現有陌生的關聯,請立即解除綁定!
|
||||
unbind = 解除綁定
|
||||
unbind_success = 社交帳號解除綁定成功!
|
||||
|
||||
delete_account = 刪除當前帳戶
|
||||
delete_prompt = 刪除操作會永久清除您的帳戶信息,並且 <strong>不可恢復</strong>!
|
||||
confirm_delete_account = 確認刪除帳戶
|
||||
delete_account_title = 帳戶刪除操作
|
||||
delete_account_desc = 該帳戶將被永久性刪除,您確定要繼續操作嗎?
|
||||
|
||||
[repo]
|
||||
owner = 擁有者
|
||||
repo_name = 倉庫名稱
|
||||
repo_name_helper = 偉大的倉庫名稱一般都較短、令人深刻並且 <strong>獨一無二</strong> 的。
|
||||
visibility = 可見度
|
||||
visiblity_helper = 本倉庫將是 <span class="label label-red label-radius">私有的</span>
|
||||
repo_desc = 倉庫描述
|
||||
repo_lang = 倉庫語言
|
||||
repo_lang_helper = 請選擇 .gitignore 文件
|
||||
license = 授權許可
|
||||
license_helper = 請選擇授權許可文件
|
||||
init_readme = 使用 README.md 文件初始化倉庫
|
||||
create_repo = 創建倉庫
|
||||
default_branch = 默認分支
|
||||
mirror_interval = 鏡像同步周期(小時)
|
||||
goget_meta = Go-Get 支持
|
||||
goget_meta_helper = 本倉庫將可以通過 <span class="label label-blue label-radius">Go Get</span> 獲取
|
||||
|
||||
need_auth = 需要授權驗證
|
||||
migrate_type = 遷移類型
|
||||
migrate_type_helper = 本倉庫將是 <span class="label label-blue label-radius">鏡像</span>
|
||||
migrate_repo = 遷移倉庫
|
||||
|
||||
copy_link = 復製鏈接
|
||||
click_to_copy = 復製到剪切簿
|
||||
copied = 復製成功
|
||||
clone_helper = 不知道如何操作?訪問 <a target="_blank" href="http://git-scm.com/book/zh/Git-基礎-取得項目的-Git-倉庫">此處</a> 查看幫助!
|
||||
unwatch = 取消關註
|
||||
watch = 關註
|
||||
unstar = 取消點讚
|
||||
star = 點讚
|
||||
fork = 派生
|
||||
|
||||
no_desc = 暫無描述
|
||||
quick_guide = 快速幫助
|
||||
clone_this_repo = 克隆當前倉庫
|
||||
create_new_repo_command = 從命令行創建一個新的倉庫
|
||||
push_exist_repo = 從命令行推送已經創建的倉庫
|
||||
|
||||
branch = 分支
|
||||
tree = 目錄樹
|
||||
branch_and_tags = 分支與標籤
|
||||
branches = 分支列表
|
||||
tags = 標籤列表
|
||||
issues = 問題管理
|
||||
commits = 提交歷史
|
||||
releases = 版本發佈
|
||||
|
||||
commits.commits = 次代碼提交
|
||||
commits.search = 搜索提交歷史
|
||||
commits.find = 查找
|
||||
commits.author = 作者
|
||||
commits.message = 備註
|
||||
commits.date = 提交日期
|
||||
commits.older = 更舊的提交
|
||||
commits.newer = 更新的提交
|
||||
|
||||
settings = 倉庫設置
|
||||
settings.options = 基本設置
|
||||
settings.collaboration = 管理協作者
|
||||
settings.hooks = 管理 Web 鉤子
|
||||
settings.githooks = 管理 Git 鉤子
|
||||
settings.deploy_keys = 管理部署密鑰
|
||||
settings.basic_settings = 基本設置
|
||||
settings.danger_zone = 危險操作區
|
||||
settings.site = 官方網站
|
||||
settings.update_settings = 更新倉庫設置
|
||||
settings.change_reponame = 倉庫名稱將被修改
|
||||
settings.change_reponame_desc = 倉庫名稱被修改,您確定要繼續操作嗎?這將會影響到所有與該倉庫有關的鏈接。
|
||||
settings.transfer = 轉移倉庫所有權
|
||||
settings.transfer_desc = 您可以將倉庫轉移至您擁有管理員權限的帳戶或組織。
|
||||
settings.new_owner_has_same_repo = 新的倉庫擁有者已經存在同名倉庫!
|
||||
settings.delete = 刪除本倉庫
|
||||
settings.delete_desc = 刪除倉庫操作不可逆轉,請三思而後行。
|
||||
settings.transfer_notices = <p>- 如果您轉移給個人用戶,您將對倉庫失去所有權限。</p><p>- 如果您轉移給您作為擁有者的組織,則可繼續保持操作權限。</p>
|
||||
settings.update_settings_success = 倉庫設置更新成功!
|
||||
settings.transfer_owner = 新擁有者
|
||||
settings.make_transfer = 確認轉移倉庫
|
||||
settings.transfer_succeed = 倉庫所有權轉移成功!
|
||||
settings.confirm_delete = 確認刪除倉庫
|
||||
settings.add_collaborator = 增加新的協作者
|
||||
settings.add_collaborator_success = 成功添加新的協作者!
|
||||
settings.remove_collaborator_success = 被操作的協作者已經被收回權限!
|
||||
settings.add_webhook = 添加 Web 鉤子
|
||||
settings.hooks_desc = Web 鉤子允許您設定在 Gogs 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文檔</a> 獲取更多信息。
|
||||
settings.remove_hook_success = Web 鉤子刪除成功!
|
||||
settings.add_webhook_desc = 我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式(JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文檔</a> 獲取更多信息。
|
||||
settings.githooks_desc = Git 鉤子是由 Git 本身提供的功能,以下為 Gogs 所支持的鉤子列表。
|
||||
settings.githook_edit_desc = 如果鉤子未啟動,則會顯示樣例文件中的內容。如果想要刪除某個鉤子,則提交空白文本即可。
|
||||
settings.githook_name = 鉤子名稱
|
||||
settings.githook_content = 鉤子文本
|
||||
settings.update_githook = 更新鉤子設置
|
||||
settings.payload_url = 推送地址
|
||||
settings.content_type = 數據格式
|
||||
settings.secret = 密鑰文本
|
||||
settings.event_desc = 請設置您希望觸發 Web 鉤子的事件:
|
||||
settings.event_push_only = 只推送 <code>push</code> 事件。
|
||||
settings.active = 是否激活
|
||||
settings.active_helper = 當指定事件發生時我們將會觸發此 Web 鉤子。
|
||||
settings.add_hook_success = Web 鉤子添加成功!
|
||||
settings.update_webhook = 更新 Web 鉤子
|
||||
settings.update_hook_success = Web 鉤子更新成功!
|
||||
settings.delete_webhook = 刪除 Web 鉤子
|
||||
settings.recent_deliveries = 最近推送記錄
|
||||
settings.hook_type = 鉤子類型
|
||||
settings.add_slack_hook_desc = 為您的倉庫增加 <a href="http://slack.com">Slack</a> 集成
|
||||
settings.slack_token = 令牌
|
||||
settings.slack_domain = 域名
|
||||
settings.slack_channel = 頻道
|
||||
|
||||
[org]
|
||||
org_name_holder = 組織名稱
|
||||
org_name_helper = 偉大的組織都有一個簡短而寓意深刻的名字。
|
||||
org_email_helper = 組織的郵箱用於接收所有通知和確認郵件。
|
||||
create_org = 創建組織
|
||||
repo_updated = 最後更新於
|
||||
people = 組織成員
|
||||
invite_someone = 邀請他人加入
|
||||
teams = 組織團隊
|
||||
lower_members = 名成員
|
||||
lower_repositories = 個倉庫
|
||||
create_new_team = 創建新的團隊
|
||||
org_desc = 組織描述
|
||||
team_name = 團隊名稱
|
||||
team_desc = 團隊描述
|
||||
team_name_helper = 您可以使用該名稱來通知改組全體成員。
|
||||
team_desc_helper = 一句話描述這個團隊是做什麼的。
|
||||
team_permission_desc = 請選擇該團隊所具有的權限等級:
|
||||
|
||||
settings = 組織設置
|
||||
settings.options = 基本設置
|
||||
settings.full_name = 組織全名
|
||||
settings.website = 官方網站
|
||||
settings.location = 所在地區
|
||||
settings.update_settings = 更新組織設置
|
||||
settings.change_orgname = 組織名稱將被修改
|
||||
settings.change_orgname_desc = 組織名稱被修改,您確定要繼續操作嗎?這將會影響到所有與該組織有關的鏈接。
|
||||
settings.update_setting_success = 組織設置更新成功!
|
||||
settings.delete = 刪除組織
|
||||
settings.delete_account = 刪除當前組織
|
||||
settings.delete_prompt = 刪除操作會永久清除該組織的信息,並且 <strong>不可恢復</strong>!
|
||||
settings.confirm_delete_account = 確認刪除組織
|
||||
settings.delete_org_title = 組織刪除操作
|
||||
settings.delete_org_desc = 該組織將被永久性刪除,您確定要繼續操作嗎?
|
||||
settings.hooks_desc = 在此處添加的 Web 鉤子將會應用到該組織下的 <strong>所有倉庫</strong>。
|
||||
|
||||
members.public = 公開成員
|
||||
members.public_helper = 設為私有
|
||||
members.private = 私有成員
|
||||
members.private_helper = 設為公開
|
||||
members.owner = 管理員
|
||||
members.member = 普通成員
|
||||
members.conceal = 隱藏身份
|
||||
members.remove = 移除成員
|
||||
members.leave = 離開組織
|
||||
members.invite_desc = 請輸入被邀請到組織 %s 的用戶名稱:
|
||||
members.invite_now = 立即邀請
|
||||
|
||||
teams.join = 加入團隊
|
||||
teams.leave = 離開團隊
|
||||
teams.read_access = 讀取權限
|
||||
teams.read_access_helper = 這個團隊將擁有查看和克隆所屬倉庫的權限。
|
||||
teams.write_access = 寫入權限
|
||||
teams.write_access_helper = 這個團隊將擁有查看、克隆和推送所屬倉庫的權限。
|
||||
teams.admin_access = 管理權限
|
||||
teams.admin_access_helper = 這個團隊將擁有查看、克隆、推送和添加其他組織成員到團隊的權限。
|
||||
teams.no_desc = 該團隊暫無描述
|
||||
teams.settings = 團隊設置
|
||||
teams.owners_permission_desc = 管理員團隊對 <strong>所有倉庫</strong> 具有操作權限,且對組織具有 <strong>管理員權限</strong>。
|
||||
teams.members = 團隊成員
|
||||
teams.update_settings = 更新團隊設置
|
||||
teams.delete_team = 刪除當前團隊
|
||||
teams.add_team_member = 添加團隊成員
|
||||
teams.delete_team_title = 團隊刪除操作
|
||||
teams.delete_team_desc = 刪除操作會永久清除有關該團隊的信息,您確定要繼續操作嗎?團隊成員可能會失去對某些倉庫的操作權限。
|
||||
teams.delete_team_success = 指定團隊刪除成功!
|
||||
teams.read_permission_desc = 該團隊擁有對所屬倉庫的 <strong>讀取</strong> 權限,團隊成員可以進行查看和克隆等只讀操作。
|
||||
teams.write_permission_desc = 該團隊擁有對所屬倉庫的 <strong>讀取</strong> 和 <strong>寫入</strong> 的權限。
|
||||
teams.admin_permission_desc = 該團隊擁有一定的 <strong>管理</strong> 權限,團隊成員可以讀取、克隆、推送以及添加其它倉庫協作者。
|
||||
teams.repositories = 團隊倉庫
|
||||
teams.add_team_repository = 添加團隊倉庫
|
||||
teams.remove_repo = 移除倉庫
|
||||
|
||||
[admin]
|
||||
dashboard = 控制面版
|
||||
users = 用戶管理
|
||||
organizations = 組織管理
|
||||
repositories = 倉庫管理
|
||||
authentication = 授權認證管理
|
||||
config = 應用配置管理
|
||||
notices = 系統提示管理
|
||||
monitor = 應用監控面版
|
||||
prev = 上一頁
|
||||
next = 下一頁
|
||||
|
||||
dashboard.statistic = 應用統計數據
|
||||
dashboard.operations = 管理員操作
|
||||
dashboard.system_status = 系統監視狀態
|
||||
dashboard.statistic_info = Gogs 數據庫統計:<b>%d</b> 位用戶,<b>%d</b> 個組織,<b>%d</b> 個公鑰,<b>%d</b> 個倉庫,<b>%d</b> 個倉庫關註,<b>%d</b> 個贊,<b>%d</b> 次行為,<b>%d</b> 條權限記錄,<b>%d</b> 個問題,<b>%d</b> 次評論,<b>%d</b> 個社交帳號,<b>%d</b> 個用戶關註,<b>%d</b> 個鏡像,<b>%d</b> 個版本發佈,<b>%d</b> 個登錄源,<b>%d</b> 個 Web 鉤子,<b>%d</b> 個里程碑,<b>%d</b> 個標籤,<b>%d</b> 個鉤子任務,<b>%d</b> 個團隊,<b>%d</b> 個更新任務,<b>%d</b> 個附件。
|
||||
dashboard.operation_name = 操作名稱
|
||||
dashboard.operation_switch = 開關
|
||||
dashboard.operation_run = 執行
|
||||
dashboard.clean_unbind_oauth = 清理未綁定社交帳號
|
||||
dashboard.delete_inactivate_accounts = 刪除所有未激活帳戶
|
||||
dashboard.server_uptime = 服務執行時間
|
||||
dashboard.current_goroutine = 當前 Goroutines 數量
|
||||
dashboard.current_memory_usage = 當前內存使用量
|
||||
dashboard.total_memory_allocated = 所有被分配的內存
|
||||
dashboard.memory_obtained = 內存佔用量
|
||||
dashboard.pointer_lookup_times = 指針查找次數
|
||||
dashboard.memory_allocate_times = 內存分配次數
|
||||
dashboard.memory_free_times = 內存釋放次數
|
||||
dashboard.current_heap_usage = 當前 Heap 內存使用量
|
||||
dashboard.heap_memory_obtained = Heap 內存佔用量
|
||||
dashboard.heap_memory_idle = Heap 內存空閒量
|
||||
dashboard.heap_memory_in_use = 正在使用的 Heap 內存
|
||||
dashboard.heap_memory_released = 被釋放的 Heap 內存
|
||||
dashboard.heap_objects = Heap 對象數量
|
||||
dashboard.bootstrap_stack_usage = 啟動 Stack 使用量
|
||||
dashboard.stack_memory_obtained = 被分配的 Stack 內存
|
||||
dashboard.mspan_structures_usage = MSpan 結構內存使用量
|
||||
dashboard.mspan_structures_obtained = 被分配的 MSpan 結構內存
|
||||
dashboard.mcache_structures_usage = MCache 結構內存使用量
|
||||
dashboard.mcache_structures_obtained = 被分配的 MCache 結構內存
|
||||
dashboard.profiling_bucket_hash_table_obtained = 被分配的剖析哈希表內存
|
||||
dashboard.gc_metadata_obtained = 被分配的垃圾收集元數據內存
|
||||
dashboard.other_system_allocation_obtained = 其它被分配的系統內存
|
||||
dashboard.next_gc_recycle = 下次垃圾收集內存回收量
|
||||
dashboard.last_gc_time = 距離上次垃圾收集時間
|
||||
dashboard.total_gc_time = 垃圾收集執行時間總量
|
||||
dashboard.total_gc_pause = 垃圾收集暫停時間總量
|
||||
dashboard.last_gc_pause = 上次垃圾收集暫停時間
|
||||
dashboard.gc_times = 垃圾收集執行次數
|
||||
|
||||
users.user_manage_panel = 用戶管理面版
|
||||
users.new_account = 創建新的帳戶
|
||||
users.name = 用戶名
|
||||
users.activated = 已激活
|
||||
users.admin = 管理員
|
||||
users.repos = 倉庫數
|
||||
users.created = 創建時間
|
||||
users.edit = 編輯
|
||||
users.auth_source = 認證源
|
||||
users.local = 本地
|
||||
users.auth_login_name = 認證登錄名
|
||||
users.update_profile_success = 該用戶信息更新成功!
|
||||
users.edit_account = 編輯用戶信息
|
||||
users.is_activated = 該用戶已被激活
|
||||
users.is_admin = 該用戶具有管理員權限
|
||||
users.update_profile = 更新用戶信息
|
||||
users.delete_account = 刪除該用戶
|
||||
users.still_own_repo = 該帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作!
|
||||
|
||||
orgs.org_manage_panel = 組織管理面版
|
||||
orgs.name = 組織名稱
|
||||
orgs.teams = 團隊數
|
||||
orgs.members = 成員數
|
||||
|
||||
repos.repo_manage_panel = 倉庫管理界面
|
||||
repos.owner = 所有者
|
||||
repos.name = 倉庫名稱
|
||||
repos.private = 私有庫
|
||||
repos.watches = 關註數
|
||||
repos.stars = 點讚數
|
||||
repos.issues = 問題數
|
||||
|
||||
auths.auth_manage_panel = 授權認證管理面版
|
||||
auths.new = 添加新的認證源
|
||||
auths.name = 認證名稱
|
||||
auths.type = 認證類型
|
||||
auths.enabled = 已啟用
|
||||
auths.updated = 最後更新時間
|
||||
auths.auth_type = 授權類型
|
||||
auths.auth_name = 授權名稱
|
||||
auths.domain = 域名
|
||||
auths.host = 主機地址
|
||||
auths.port = 主機端口
|
||||
auths.base_dn = Base DN
|
||||
auths.attributes = 搜尋屬性
|
||||
auths.filter = 搜尋過濾
|
||||
auths.ms_ad_sa = Ms Ad SA
|
||||
auths.smtp_auth = SMTP 授權類型
|
||||
auths.smtphost = SMTP 主機地址
|
||||
auths.smtpport = SMTP 主機端口
|
||||
auths.enable_tls = 啟用 TLS 加密
|
||||
auths.enable_auto_register = 允許授權用戶自動註冊
|
||||
auths.tips = 幫助提示
|
||||
auths.edit = 修改授權認證設置
|
||||
auths.activated = 該授權認證已經啟用
|
||||
auths.update_success = 授權認證設置更新成功!
|
||||
auths.update = 更新授權認證信息
|
||||
auths.delete = 刪除該授權認證
|
||||
auths.delete_auth_title = 授權認證刪除操作
|
||||
auths.delete_auth_desc = 該授權認證將被刪除,您確定要繼續嗎?
|
||||
|
||||
config.server_config = 服務器配置
|
||||
config.app_name = 應用名稱
|
||||
config.app_ver = 應用版本
|
||||
config.app_url = 應用 URL
|
||||
config.domain = 應用域名
|
||||
config.offline_mode = 離線模式
|
||||
config.disable_router_log = 關閉路由日志
|
||||
config.run_user = 執行用戶
|
||||
config.run_mode = 執行模式
|
||||
config.repo_root_path = 倉庫根目錄
|
||||
config.static_file_root_path = 靜態文件根目錄
|
||||
config.log_file_root_path = 日志文件根目錄
|
||||
config.script_type = 腳本類型
|
||||
config.reverse_auth_user = 反向代理認證
|
||||
config.db_config = 數據庫配置
|
||||
config.db_type = 數據庫類型
|
||||
config.db_host = 主機地址
|
||||
config.db_name = 數據庫名稱
|
||||
config.db_user = 連接用戶
|
||||
config.db_ssl_mode = SSL 模式
|
||||
config.db_ssl_mode_helper = (僅限 "postgres" 使用)
|
||||
config.db_path = 數據庫路徑
|
||||
config.db_path_helper = (僅限 "sqlite3" 使用)
|
||||
config.service_config = 服務配置
|
||||
config.register_email_confirm = 註冊郵件確認
|
||||
config.disable_register = 關閉註冊功能
|
||||
config.require_sign_in_view = 強制登錄瀏覽
|
||||
config.mail_notify = 郵件通知提醒
|
||||
config.enable_cache_avatar = 開啟緩存頭像
|
||||
config.active_code_lives = 激活用戶鏈接有效期
|
||||
config.reset_password_code_lives = 重置密碼鏈接有效期
|
||||
config.webhook_config = Web 鉤子配置
|
||||
config.task_interval = 任務周期
|
||||
config.deliver_timeout = 推送超時
|
||||
config.mailer_config = 郵件配置
|
||||
config.mailer_enabled = 啟用服務
|
||||
config.mailer_name = 發送者名稱
|
||||
config.mailer_host = 郵件主機地址
|
||||
config.mailer_user = 發送者帳號
|
||||
config.oauth_config = 社交帳號配置
|
||||
config.oauth_enabled = 啟用服務
|
||||
config.cache_config = Cache 配置
|
||||
config.cache_adapter = Cache 適配器
|
||||
config.cache_interval = Cache 周期
|
||||
config.cache_conn = Cache 連接字符串
|
||||
config.session_config = Session 配置
|
||||
config.session_provider = Session 提供者
|
||||
config.provider_config = 提供者配置
|
||||
config.cookie_name = Cookie 名稱
|
||||
config.enable_set_cookie = 啟用設置 Cookie
|
||||
config.gc_interval_time = 垃圾收集周期
|
||||
config.session_life_time = Session 生命周期
|
||||
config.https_only = 僅限 HTTPS
|
||||
config.cookie_life_time = Cookie 生命周期
|
||||
config.session_hash_function = Session ID 哈希函數
|
||||
config.session_hash_key = Session ID 哈希健值
|
||||
config.picture_config = 圖片配置
|
||||
config.picture_service = 圖片服務
|
||||
config.disable_gravatar = 禁用 Gravatar 頭像
|
||||
config.log_config = 日誌配置
|
||||
config.log_mode = 日誌模式
|
||||
|
||||
monitor.cron = Cron 任務
|
||||
monitor.name = 任務名稱
|
||||
monitor.schedule = 任務安排
|
||||
monitor.next = 下次執行時間
|
||||
monitor.previous = 上次執行時間
|
||||
monitor.execute_times = 執行次數
|
||||
monitor.process = 執行中進程
|
||||
monitor.desc = 進程描述
|
||||
monitor.start = 開始時間
|
||||
monitor.execute_time = 已執行時間
|
||||
|
||||
notices.system_notice_list = 系統提示管理
|
||||
notices.type = 提示類型
|
||||
notices.type_1 = 倉庫
|
||||
notices.desc = 描述
|
||||
notices.op = 操作
|
||||
notices.delete_success = 系統提示刪除成功!
|
||||
|
||||
[action]
|
||||
create_repo = 創建了倉庫 <a href="%s/%s">%s</a>
|
||||
commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代碼到 <a href="%s/%s">%s</a>
|
||||
create_issue = 創建了問題 <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
comment_issue = 評論了問題 <a href="%s/%s/issues/%s">%s#%s</a>
|
||||
transfer_repo = 將倉庫 <code>%s</code> 轉移至 <a href="/%s%s">%s</a>
|
||||
|
||||
[tool]
|
||||
ago = 之前
|
||||
from_now = 之後
|
||||
now = 現在
|
||||
1s = 1 秒%s
|
||||
1m = 1 分鐘%s
|
||||
1h = 1 小時%s
|
||||
1d = 1 天%s
|
||||
1w = 1 周%s
|
||||
1mon = 1 月%s
|
||||
1y = 1 年%s
|
||||
seconds = %d 秒%s
|
||||
minutes = %d 分鐘%s
|
||||
hours = %d 小時%s
|
||||
days = %d 天%s
|
||||
weeks = %d 周%s
|
||||
months = %d 月%s
|
||||
years = %d 年%s
|
||||
raw_seconds = 秒
|
||||
raw_minutes = 分鐘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3
gogs.go
3
gogs.go
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.5.0.0913 Beta"
|
||||
const APP_VER = "0.5.5.1010 Beta"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
@@ -35,6 +35,7 @@ func main() {
|
||||
cmd.CmdUpdate,
|
||||
cmd.CmdFix,
|
||||
cmd.CmdDump,
|
||||
cmd.CmdCert,
|
||||
}
|
||||
app.Flags = append(app.Flags, []cli.Flag{}...)
|
||||
app.Run(os.Args)
|
||||
|
||||
@@ -137,7 +137,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
|
||||
return err
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("/%s/%s/commit/%s", repoUserName, repoName, c.Sha1)
|
||||
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
|
||||
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
|
||||
|
||||
if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
|
||||
@@ -243,15 +243,29 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
|
||||
if !strings.HasPrefix(oldCommitId, "0000000") {
|
||||
compareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId)
|
||||
}
|
||||
|
||||
pusher_email, pusher_name := "", ""
|
||||
pusher, err := GetUserByName(userName)
|
||||
if err == nil {
|
||||
pusher_email = pusher.Email
|
||||
pusher_name = pusher.GetFullNameFallback()
|
||||
}
|
||||
|
||||
commits := make([]*PayloadCommit, len(commit.Commits))
|
||||
for i, cmt := range commit.Commits {
|
||||
author_username := ""
|
||||
author, err := GetUserByEmail(cmt.AuthorEmail)
|
||||
if err == nil {
|
||||
author_username = author.Name
|
||||
}
|
||||
commits[i] = &PayloadCommit{
|
||||
Id: cmt.Sha1,
|
||||
Message: cmt.Message,
|
||||
Url: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1),
|
||||
Author: &PayloadAuthor{
|
||||
Name: cmt.AuthorName,
|
||||
Email: cmt.AuthorEmail,
|
||||
Name: cmt.AuthorName,
|
||||
Email: cmt.AuthorEmail,
|
||||
UserName: author_username,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -266,14 +280,16 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
|
||||
Website: repo.Website,
|
||||
Watchers: repo.NumWatches,
|
||||
Owner: &PayloadAuthor{
|
||||
Name: repoUserName,
|
||||
Email: actEmail,
|
||||
Name: repo.Owner.GetFullNameFallback(),
|
||||
Email: repo.Owner.Email,
|
||||
UserName: repo.Owner.Name,
|
||||
},
|
||||
Private: repo.IsPrivate,
|
||||
},
|
||||
Pusher: &PayloadAuthor{
|
||||
Name: repo.Owner.LowerName,
|
||||
Email: repo.Owner.Email,
|
||||
Name: pusher_name,
|
||||
Email: pusher_email,
|
||||
UserName: userName,
|
||||
},
|
||||
Before: oldCommitId,
|
||||
After: newCommitId,
|
||||
@@ -334,13 +350,29 @@ func NewRepoAction(u *User, repo *Repository) (err error) {
|
||||
|
||||
// TransferRepoAction adds new action for transfering repository.
|
||||
func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
|
||||
if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
|
||||
OpType: TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name,
|
||||
IsPrivate: repo.IsPrivate}); err != nil {
|
||||
action := &Action{
|
||||
ActUserId: u.Id,
|
||||
ActUserName: u.Name,
|
||||
ActEmail: u.Email,
|
||||
OpType: TRANSFER_REPO,
|
||||
RepoId: repo.Id,
|
||||
RepoUserName: newUser.Name,
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
Content: path.Join(repo.Owner.LowerName, repo.LowerName),
|
||||
}
|
||||
if err = NotifyWatchers(action); err != nil {
|
||||
log.Error(4, "NotifyWatchers: %d/%s", u.Id, repo.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove watch for organization.
|
||||
if repo.Owner.IsOrganization() {
|
||||
if err = WatchRepo(repo.Owner.Id, repo.Id, false); err != nil {
|
||||
log.Error(4, "WatchRepo", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("action.TransferRepoAction: %s/%s", u.Name, repo.Name)
|
||||
return err
|
||||
}
|
||||
@@ -350,7 +382,7 @@ func GetFeeds(uid, offset int64, isProfile bool) ([]*Action, error) {
|
||||
actions := make([]*Action, 0, 20)
|
||||
sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", uid)
|
||||
if isProfile {
|
||||
sess.Where("is_private=?", false).And("act_user_id=?", uid)
|
||||
sess.And("is_private=?", false).And("act_user_id=?", uid)
|
||||
}
|
||||
err := sess.Find(&actions)
|
||||
return actions, err
|
||||
|
||||
64
models/admin.go
Normal file
64
models/admin.go
Normal file
@@ -0,0 +1,64 @@
|
||||
// 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 models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
)
|
||||
|
||||
type NoticeType int
|
||||
|
||||
const (
|
||||
NOTICE_REPOSITORY NoticeType = iota + 1
|
||||
)
|
||||
|
||||
// Notice represents a system notice for admin.
|
||||
type Notice struct {
|
||||
Id int64
|
||||
Type NoticeType
|
||||
Description string `xorm:"TEXT"`
|
||||
Created time.Time `xorm:"CREATED"`
|
||||
}
|
||||
|
||||
// TrStr returns a translation format string.
|
||||
func (n *Notice) TrStr() string {
|
||||
return "admin.notices.type_" + com.ToStr(n.Type)
|
||||
}
|
||||
|
||||
// CreateNotice creates new system notice.
|
||||
func CreateNotice(tp NoticeType, desc string) error {
|
||||
n := &Notice{
|
||||
Type: tp,
|
||||
Description: desc,
|
||||
}
|
||||
_, err := x.Insert(n)
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateRepositoryNotice creates new system notice with type NOTICE_REPOSITORY.
|
||||
func CreateRepositoryNotice(desc string) error {
|
||||
return CreateNotice(NOTICE_REPOSITORY, desc)
|
||||
}
|
||||
|
||||
// CountNotices returns number of notices.
|
||||
func CountNotices() int64 {
|
||||
count, _ := x.Count(new(Notice))
|
||||
return count
|
||||
}
|
||||
|
||||
// GetNotices returns given number of notices with offset.
|
||||
func GetNotices(num, offset int) ([]*Notice, error) {
|
||||
notices := make([]*Notice, 0, num)
|
||||
err := x.Limit(num, offset).Desc("id").Find(¬ices)
|
||||
return notices, err
|
||||
}
|
||||
|
||||
// DeleteNotice deletes a system notice by given ID.
|
||||
func DeleteNotice(id int64) error {
|
||||
_, err := x.Id(id).Delete(new(Notice))
|
||||
return err
|
||||
}
|
||||
@@ -70,7 +70,7 @@ func (diff *Diff) NumFiles() int {
|
||||
|
||||
const DIFF_HEAD = "diff --git "
|
||||
|
||||
func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
var (
|
||||
curFile *DiffFile
|
||||
@@ -79,6 +79,7 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
}
|
||||
|
||||
leftLine, rightLine int
|
||||
isTooLong bool
|
||||
)
|
||||
|
||||
diff := &Diff{Files: make([]*DiffFile, 0)}
|
||||
@@ -90,18 +91,19 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
i = i + 1
|
||||
|
||||
// Diff data too large.
|
||||
if i == 5000 {
|
||||
log.Warn("Diff data too large")
|
||||
return &Diff{}, nil
|
||||
}
|
||||
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
i = i + 1
|
||||
|
||||
// Diff data too large, we only show the first about maxlines lines
|
||||
if i == maxlines {
|
||||
isTooLong = true
|
||||
log.Warn("Diff data too large")
|
||||
//return &Diff{}, nil
|
||||
}
|
||||
|
||||
switch {
|
||||
case line[0] == ' ':
|
||||
diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine}
|
||||
@@ -110,6 +112,10 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
curSection.Lines = append(curSection.Lines, diffLine)
|
||||
continue
|
||||
case line[0] == '@':
|
||||
if isTooLong {
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
curSection = &DiffSection{}
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
ss := strings.Split(line, "@@")
|
||||
@@ -143,6 +149,10 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
|
||||
// Get new file.
|
||||
if strings.HasPrefix(line, DIFF_HEAD) {
|
||||
if isTooLong {
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
fs := strings.Split(line[len(DIFF_HEAD):], " ")
|
||||
a := fs[0]
|
||||
|
||||
@@ -174,7 +184,7 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string) (*Diff, error) {
|
||||
func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string, maxlines int) (*Diff, error) {
|
||||
repo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -228,9 +238,9 @@ func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string) (*Diff,
|
||||
}
|
||||
}()
|
||||
|
||||
return ParsePatch(pid, cmd, rd)
|
||||
return ParsePatch(pid, maxlines, cmd, rd)
|
||||
}
|
||||
|
||||
func GetDiffCommit(repoPath, commitId string) (*Diff, error) {
|
||||
return GetDiffRange(repoPath, "", commitId)
|
||||
func GetDiffCommit(repoPath, commitId string, maxlines int) (*Diff, error) {
|
||||
return GetDiffRange(repoPath, "", commitId, maxlines)
|
||||
}
|
||||
|
||||
@@ -161,12 +161,8 @@ func UserSignIn(uname, passwd string) (*User, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.LoginType == NOTYPE {
|
||||
if has {
|
||||
u.LoginType = PLAIN
|
||||
} else {
|
||||
return nil, ErrUserNotExist
|
||||
}
|
||||
if u.LoginType == NOTYPE && has {
|
||||
u.LoginType = PLAIN
|
||||
}
|
||||
|
||||
// For plain login, user must exist to reach this line.
|
||||
|
||||
@@ -32,12 +32,12 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
tables = append(tables, new(User), new(PublicKey),
|
||||
tables = append(tables, new(User), new(PublicKey), new(Follow), new(Oauth2),
|
||||
new(Repository), new(Watch), new(Star), new(Action), new(Access),
|
||||
new(Issue), new(Comment), new(Oauth2), new(Follow),
|
||||
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
|
||||
new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
|
||||
new(UpdateTask), new(Attachment))
|
||||
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
|
||||
new(Mirror), new(Release), new(LoginSource), new(Webhook),
|
||||
new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
|
||||
new(Notice))
|
||||
}
|
||||
|
||||
func LoadModelsConfig() {
|
||||
@@ -87,7 +87,7 @@ func getEngine() (*xorm.Engine, error) {
|
||||
func NewTestEngine(x *xorm.Engine) (err error) {
|
||||
x, err = getEngine()
|
||||
if err != nil {
|
||||
return fmt.Errorf("models.init(fail to conntect database): %v", err)
|
||||
return fmt.Errorf("models.init(fail to connect to database): %v", err)
|
||||
}
|
||||
|
||||
return x.Sync(tables...)
|
||||
@@ -96,7 +96,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
|
||||
func SetEngine() (err error) {
|
||||
x, err = getEngine()
|
||||
if err != nil {
|
||||
return fmt.Errorf("models.init(fail to conntect database): %v", err)
|
||||
return fmt.Errorf("models.init(fail to connect to database): %v", err)
|
||||
}
|
||||
|
||||
// WARNNING: for serv command, MUST remove the output to os.stdout,
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -100,6 +101,7 @@ var (
|
||||
"(MCE)": 1702,
|
||||
"(McE)": 1702,
|
||||
"(RSA)": 2048,
|
||||
"(DSA)": 1024,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -119,23 +121,30 @@ func CheckPublicKeyString(content string) (bool, error) {
|
||||
tmpFile.WriteString(content)
|
||||
tmpFile.Close()
|
||||
|
||||
// … see if ssh-keygen recognizes its contents
|
||||
// Check if ssh-keygen recognizes its contents.
|
||||
stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath)
|
||||
if err != nil {
|
||||
return false, errors.New("ssh-keygen -l -f: " + stderr)
|
||||
} else if len(stdout) < 2 {
|
||||
return false, errors.New("ssh-keygen returned not enough output to evaluate the key")
|
||||
}
|
||||
|
||||
// The ssh-keygen in Windows does not print key type, so no need go further.
|
||||
if setting.IsWindows {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
sshKeygenOutput := strings.Split(stdout, " ")
|
||||
if len(sshKeygenOutput) < 4 {
|
||||
return false, errors.New("Not enough fields returned by ssh-keygen -l -f")
|
||||
}
|
||||
|
||||
// Check if key type and key size match.
|
||||
keySize, err := com.StrTo(sshKeygenOutput[0]).Int()
|
||||
if err != nil {
|
||||
return false, errors.New("Cannot get key size of the given key")
|
||||
}
|
||||
keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])
|
||||
|
||||
if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 {
|
||||
return false, errors.New("Sorry, unrecognized public key type")
|
||||
} else if keySize < minimumKeySize {
|
||||
@@ -160,10 +169,14 @@ func saveAuthorizedKeyFile(key *PublicKey) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if finfo.Mode().Perm() > 0600 {
|
||||
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String())
|
||||
if err = f.Chmod(0600); err != nil {
|
||||
return err
|
||||
|
||||
// FIXME: following command does not support in Windows.
|
||||
if !setting.IsWindows {
|
||||
if finfo.Mode().Perm() > 0600 {
|
||||
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String())
|
||||
if err = f.Chmod(0600); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
124
models/repo.go
124
models/repo.go
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/Unknwon/cae/zip"
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
@@ -48,7 +49,7 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
DescriptionPattern = regexp.MustCompile(`https?://\S+`)
|
||||
DescPattern = regexp.MustCompile(`https?://\S+`)
|
||||
)
|
||||
|
||||
func LoadRepoConfig() {
|
||||
@@ -95,8 +96,13 @@ func NewRepoContext() {
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to get Git version: %v", err)
|
||||
}
|
||||
if ver.Major < 2 && ver.Minor < 8 {
|
||||
log.Fatal(4, "Gogs requires Git version greater or equal to 1.8.0")
|
||||
|
||||
reqVer, err := git.ParseVersion("1.7.1")
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to parse required Git version: %v", err)
|
||||
}
|
||||
if ver.LessThan(reqVer) {
|
||||
log.Fatal(4, "Gogs requires Git version greater or equal to 1.7.1")
|
||||
}
|
||||
|
||||
// Check if server has basic git setting and set if not.
|
||||
@@ -160,7 +166,9 @@ type Repository struct {
|
||||
}
|
||||
|
||||
func (repo *Repository) GetOwner() (err error) {
|
||||
repo.Owner, err = GetUserById(repo.OwnerId)
|
||||
if repo.Owner == nil {
|
||||
repo.Owner, err = GetUserById(repo.OwnerId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -169,6 +177,14 @@ func (repo *Repository) GetMirror() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *Repository) HasAccess(uname string) bool {
|
||||
if err := repo.GetOwner(); err != nil {
|
||||
return false
|
||||
}
|
||||
has, _ := HasAccess(uname, path.Join(repo.Owner.Name, repo.Name), READABLE)
|
||||
return has
|
||||
}
|
||||
|
||||
// DescriptionHtml does special handles to description and return HTML string.
|
||||
func (repo *Repository) DescriptionHtml() template.HTML {
|
||||
sanitize := func(s string) string {
|
||||
@@ -176,7 +192,7 @@ func (repo *Repository) DescriptionHtml() template.HTML {
|
||||
ss := html.EscapeString(s)
|
||||
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss)
|
||||
}
|
||||
return template.HTML(DescriptionPattern.ReplaceAllStringFunc(repo.Description, sanitize))
|
||||
return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize))
|
||||
}
|
||||
|
||||
// IsRepositoryExist returns true if the repository with given name under user has already existed.
|
||||
@@ -651,7 +667,7 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
|
||||
}
|
||||
|
||||
// Check if new owner has repository with same name.
|
||||
has, err := IsRepositoryExist(u, repo.Name)
|
||||
has, err := IsRepositoryExist(newUser, repo.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
@@ -664,17 +680,34 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Where("repo_name = ?", u.LowerName+"/"+repo.LowerName).
|
||||
And("user_name = ?", u.LowerName).Update(&Access{UserName: newUser.LowerName}); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
owner := repo.Owner
|
||||
oldRepoLink := path.Join(owner.LowerName, repo.LowerName)
|
||||
// Delete all access first if current owner is an organization.
|
||||
if owner.IsOrganization() {
|
||||
if _, err = sess.Where("repo_name=?", oldRepoLink).Delete(new(Access)); err != nil {
|
||||
sess.Rollback()
|
||||
return fmt.Errorf("fail to delete current accesses: %v", err)
|
||||
}
|
||||
} else {
|
||||
// Delete current owner access.
|
||||
if _, err = sess.Where("repo_name=?", oldRepoLink).And("user_name=?", owner.LowerName).
|
||||
Delete(new(Access)); err != nil {
|
||||
sess.Rollback()
|
||||
return fmt.Errorf("fail to delete access(owner): %v", err)
|
||||
}
|
||||
// In case new owner has access.
|
||||
if _, err = sess.Where("repo_name=?", oldRepoLink).And("user_name=?", newUser.LowerName).
|
||||
Delete(new(Access)); err != nil {
|
||||
sess.Rollback()
|
||||
return fmt.Errorf("fail to delete access(new user): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = sess.Where("repo_name = ?", u.LowerName+"/"+repo.LowerName).Update(&Access{
|
||||
RepoName: newUser.LowerName + "/" + repo.LowerName,
|
||||
}); err != nil {
|
||||
// Change accesses to new repository path.
|
||||
if _, err = sess.Where("repo_name=?", oldRepoLink).
|
||||
Update(&Access{RepoName: path.Join(newUser.LowerName, repo.LowerName)}); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
return fmt.Errorf("fail to update access(change reponame): %v", err)
|
||||
}
|
||||
|
||||
// Update repository.
|
||||
@@ -690,17 +723,17 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", u.Id); err != nil {
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", owner.Id); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
mode := WRITABLE
|
||||
if repo.IsMirror {
|
||||
mode = READABLE
|
||||
}
|
||||
// New owner is organization.
|
||||
if newUser.IsOrganization() {
|
||||
mode := WRITABLE
|
||||
if repo.IsMirror {
|
||||
mode = READABLE
|
||||
}
|
||||
access := &Access{
|
||||
RepoName: path.Join(newUser.LowerName, repo.LowerName),
|
||||
Mode: mode,
|
||||
@@ -732,10 +765,20 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
access := &Access{
|
||||
RepoName: path.Join(newUser.LowerName, repo.LowerName),
|
||||
UserName: newUser.LowerName,
|
||||
Mode: mode,
|
||||
}
|
||||
if _, err = sess.Insert(access); err != nil {
|
||||
sess.Rollback()
|
||||
return fmt.Errorf("fail to insert access: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Change repository directory name.
|
||||
if err = os.Rename(RepoPath(u.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
|
||||
if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
@@ -744,14 +787,8 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add watch of new owner to repository.
|
||||
if !newUser.IsOrganization() {
|
||||
if err = WatchRepo(newUser.Id, repo.Id, true); err != nil {
|
||||
log.Error(4, "WatchRepo", err)
|
||||
}
|
||||
}
|
||||
if err = WatchRepo(u.Id, repo.Id, false); err != nil {
|
||||
log.Error(4, "WatchRepo2", err)
|
||||
if err = WatchRepo(newUser.Id, repo.Id, true); err != nil {
|
||||
log.Error(4, "WatchRepo", err)
|
||||
}
|
||||
|
||||
if err = TransferRepoAction(u, newUser, repo); err != nil {
|
||||
@@ -907,9 +944,14 @@ func DeleteRepository(uid, repoId int64, userName string) error {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove repository files.
|
||||
if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
desc := fmt.Sprintf("Fail to delete repository files(%s/%s): %v", userName, repo.Name, err)
|
||||
log.Warn(desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(4, "Fail to add notice: %v", err)
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
@@ -1076,6 +1118,13 @@ func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
|
||||
return repos, err
|
||||
}
|
||||
|
||||
// __ __ __ .__
|
||||
// / \ / \_____ _/ |_ ____ | |__
|
||||
// \ \/\/ /\__ \\ __\/ ___\| | \
|
||||
// \ / / __ \| | \ \___| Y \
|
||||
// \__/\ / (____ /__| \___ >___| /
|
||||
// \/ \/ \/ \/
|
||||
|
||||
// Watch is connection request for receiving repository notifycation.
|
||||
type Watch struct {
|
||||
Id int64
|
||||
@@ -1146,6 +1195,13 @@ func NotifyWatchers(act *Action) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// _________ __
|
||||
// / _____// |______ _______
|
||||
// \_____ \\ __\__ \\_ __ \
|
||||
// / \| | / __ \| | \/
|
||||
// /_______ /|__| (____ /__|
|
||||
// \/ \/
|
||||
|
||||
type Star struct {
|
||||
Id int64
|
||||
Uid int64 `xorm:"UNIQUE(s)"`
|
||||
@@ -1160,16 +1216,20 @@ func StarRepo(uid, repoId int64, star bool) (err error) {
|
||||
}
|
||||
if _, err = x.Insert(&Star{Uid: uid, RepoId: repoId}); err != nil {
|
||||
return err
|
||||
} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoId); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoId)
|
||||
_, err = x.Exec("UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", uid)
|
||||
} else {
|
||||
if !IsStaring(uid, repoId) {
|
||||
return nil
|
||||
}
|
||||
if _, err = x.Delete(&Star{0, uid, repoId}); err != nil {
|
||||
return err
|
||||
} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoId); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoId)
|
||||
_, err = x.Exec("UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", uid)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ type UpdateTask struct {
|
||||
NewCommitId string
|
||||
}
|
||||
|
||||
const (
|
||||
MAX_COMMITS int = 5
|
||||
)
|
||||
|
||||
func AddUpdateTask(task *UpdateTask) error {
|
||||
_, err := x.Insert(task)
|
||||
return err
|
||||
@@ -132,7 +136,6 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
|
||||
|
||||
// if commits push
|
||||
commits := make([]*base.PushCommit, 0)
|
||||
var maxCommits = 2
|
||||
var actEmail string
|
||||
for e := l.Front(); e != nil; e = e.Next() {
|
||||
commit := e.Value.(*git.Commit)
|
||||
@@ -145,7 +148,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
|
||||
commit.Message(),
|
||||
commit.Author.Email,
|
||||
commit.Author.Name})
|
||||
if len(commits) >= maxCommits {
|
||||
if len(commits) >= MAX_COMMITS {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@@ -82,22 +83,22 @@ type User struct {
|
||||
// DashboardLink returns the user dashboard page link.
|
||||
func (u *User) DashboardLink() string {
|
||||
if u.IsOrganization() {
|
||||
return "/org/" + u.Name + "/dashboard/"
|
||||
return setting.AppSubUrl + "/org/" + u.Name + "/dashboard/"
|
||||
}
|
||||
return "/"
|
||||
return setting.AppSubUrl + "/"
|
||||
}
|
||||
|
||||
// HomeLink returns the user home page link.
|
||||
func (u *User) HomeLink() string {
|
||||
return "/user/" + u.Name
|
||||
return setting.AppSubUrl + "/" + u.Name
|
||||
}
|
||||
|
||||
// AvatarLink returns user gravatar link.
|
||||
func (u *User) AvatarLink() string {
|
||||
if setting.DisableGravatar {
|
||||
return "/img/avatar_default.jpg"
|
||||
return setting.AppSubUrl + "/img/avatar_default.jpg"
|
||||
} else if setting.Service.EnableCacheAvatar {
|
||||
return "/avatar/" + u.Avatar
|
||||
return setting.AppSubUrl + "/avatar/" + u.Avatar
|
||||
}
|
||||
return "//1.gravatar.com/avatar/" + u.Avatar
|
||||
}
|
||||
@@ -167,6 +168,14 @@ func (u *User) GetOrganizations() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFullNameFallback returns Full Name if set, otherwise username
|
||||
func (u *User) GetFullNameFallback() string {
|
||||
if u.FullName == "" {
|
||||
return u.Name
|
||||
}
|
||||
return u.FullName
|
||||
}
|
||||
|
||||
// IsUserExist checks if given user name exist,
|
||||
// the user name should be noncased unique.
|
||||
func IsUserExist(name string) (bool, error) {
|
||||
@@ -505,6 +514,49 @@ func GetUserIdsByNames(names []string) []int64 {
|
||||
return ids
|
||||
}
|
||||
|
||||
// UserCommit represtns a commit with validation of user.
|
||||
type UserCommit struct {
|
||||
UserName string
|
||||
*git.Commit
|
||||
}
|
||||
|
||||
// ValidateCommitWithEmail chceck if author's e-mail of commit is corresponsind to a user.
|
||||
func ValidateCommitWithEmail(c *git.Commit) (uname string) {
|
||||
u, err := GetUserByEmail(c.Author.Email)
|
||||
if err == nil {
|
||||
uname = u.Name
|
||||
}
|
||||
return uname
|
||||
}
|
||||
|
||||
// ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
|
||||
func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
|
||||
emails := map[string]string{}
|
||||
newCommits := list.New()
|
||||
e := oldCommits.Front()
|
||||
for e != nil {
|
||||
c := e.Value.(*git.Commit)
|
||||
|
||||
uname := ""
|
||||
if v, ok := emails[c.Author.Email]; !ok {
|
||||
u, err := GetUserByEmail(c.Author.Email)
|
||||
if err == nil {
|
||||
uname = u.Name
|
||||
}
|
||||
emails[c.Author.Email] = uname
|
||||
} else {
|
||||
uname = v
|
||||
}
|
||||
|
||||
newCommits.PushBack(UserCommit{
|
||||
UserName: uname,
|
||||
Commit: c,
|
||||
})
|
||||
e = e.Next()
|
||||
}
|
||||
return newCommits
|
||||
}
|
||||
|
||||
// GetUserByEmail returns the user object by given e-mail if exists.
|
||||
func GetUserByEmail(email string) (*User, error) {
|
||||
if len(email) == 0 {
|
||||
@@ -548,27 +600,27 @@ type Follow struct {
|
||||
|
||||
// FollowUser marks someone be another's follower.
|
||||
func FollowUser(userId int64, followId int64) (err error) {
|
||||
session := x.NewSession()
|
||||
defer session.Close()
|
||||
session.Begin()
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
sess.Begin()
|
||||
|
||||
if _, err = session.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil {
|
||||
session.Rollback()
|
||||
if _, err = sess.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
rawSql := "UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?"
|
||||
if _, err = session.Exec(rawSql, followId); err != nil {
|
||||
session.Rollback()
|
||||
if _, err = sess.Exec(rawSql, followId); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
rawSql = "UPDATE `user` SET num_followings = num_followings + 1 WHERE id = ?"
|
||||
if _, err = session.Exec(rawSql, userId); err != nil {
|
||||
session.Rollback()
|
||||
if _, err = sess.Exec(rawSql, userId); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
return session.Commit()
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// UnFollowUser unmarks someone be another's follower.
|
||||
|
||||
@@ -154,8 +154,9 @@ const (
|
||||
)
|
||||
|
||||
type PayloadAuthor struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
UserName string `json:"username"`
|
||||
}
|
||||
|
||||
type PayloadCommit struct {
|
||||
@@ -172,7 +173,7 @@ type PayloadRepo struct {
|
||||
Description string `json:"description"`
|
||||
Website string `json:"website"`
|
||||
Watchers int `json:"watchers"`
|
||||
Owner *PayloadAuthor `json:"author"`
|
||||
Owner *PayloadAuthor `json:"owner"`
|
||||
Private bool `json:"private"`
|
||||
}
|
||||
|
||||
@@ -234,8 +235,22 @@ func UpdateHookTask(t *HookTask) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
// Prevent duplicate deliveries.
|
||||
// This happens with massive hook tasks cannot finish delivering
|
||||
// before next shooting starts.
|
||||
isShooting = false
|
||||
)
|
||||
|
||||
// DeliverHooks checks and delivers undelivered hooks.
|
||||
// FIXME: maybe can use goroutine to shoot a number of them at same time?
|
||||
func DeliverHooks() {
|
||||
if isShooting {
|
||||
return
|
||||
}
|
||||
isShooting = true
|
||||
defer func() { isShooting = false }()
|
||||
|
||||
tasks := make([]*HookTask, 0, 10)
|
||||
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
|
||||
x.Where("is_delivered=?", false).Iterate(new(HookTask),
|
||||
@@ -254,7 +269,7 @@ func DeliverHooks() {
|
||||
|
||||
t.IsDelivered = true
|
||||
|
||||
// TODO: record response.
|
||||
// FIXME: record response.
|
||||
switch t.Type {
|
||||
case GOGS:
|
||||
{
|
||||
|
||||
@@ -102,7 +102,7 @@ func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs *binding.Errors,
|
||||
// \/ \/ \/
|
||||
|
||||
type CreateIssueForm struct {
|
||||
IssueName string `form:"title" binding:"Required;MaxSize(50)"`
|
||||
IssueName string `form:"title" binding:"Required;MaxSize(255)"`
|
||||
MilestoneId int64 `form:"milestoneid"`
|
||||
AssigneeId int64 `form:"assigneeid"`
|
||||
Labels string `form:"labels"`
|
||||
|
||||
@@ -13,7 +13,9 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/gogits/gfm"
|
||||
"github.com/russross/blackfriday"
|
||||
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
func isletter(c byte) bool {
|
||||
@@ -73,7 +75,7 @@ func IsReadmeFile(name string) bool {
|
||||
}
|
||||
|
||||
type CustomRender struct {
|
||||
gfm.Renderer
|
||||
blackfriday.Renderer
|
||||
urlPrefix string
|
||||
}
|
||||
|
||||
@@ -112,7 +114,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
|
||||
ms := MentionPattern.FindAll(line, -1)
|
||||
for _, m := range ms {
|
||||
line = bytes.Replace(line, m,
|
||||
[]byte(fmt.Sprintf(`<a href="/user/%s">%s</a>`, m[1:], m)), -1)
|
||||
[]byte(fmt.Sprintf(`<a href="%s/user/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,39 +155,40 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
|
||||
|
||||
func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
|
||||
htmlFlags := 0
|
||||
// htmlFlags |= gfm.HTML_USE_XHTML
|
||||
// htmlFlags |= gfm.HTML_USE_SMARTYPANTS
|
||||
// htmlFlags |= gfm.HTML_SMARTYPANTS_FRACTIONS
|
||||
// htmlFlags |= gfm.HTML_SMARTYPANTS_LATEX_DASHES
|
||||
// htmlFlags |= gfm.HTML_SKIP_HTML
|
||||
htmlFlags |= gfm.HTML_SKIP_STYLE
|
||||
htmlFlags |= gfm.HTML_SKIP_SCRIPT
|
||||
htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE
|
||||
htmlFlags |= gfm.HTML_OMIT_CONTENTS
|
||||
// htmlFlags |= gfm.HTML_COMPLETE_PAGE
|
||||
// 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 := &CustomRender{
|
||||
Renderer: gfm.HtmlRenderer(htmlFlags, "", ""),
|
||||
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
|
||||
urlPrefix: urlPrefix,
|
||||
}
|
||||
|
||||
// set up the parser
|
||||
extensions := 0
|
||||
extensions |= gfm.EXTENSION_NO_INTRA_EMPHASIS
|
||||
extensions |= gfm.EXTENSION_TABLES
|
||||
extensions |= gfm.EXTENSION_FENCED_CODE
|
||||
extensions |= gfm.EXTENSION_AUTOLINK
|
||||
extensions |= gfm.EXTENSION_STRIKETHROUGH
|
||||
extensions |= gfm.EXTENSION_HARD_LINE_BREAK
|
||||
extensions |= gfm.EXTENSION_SPACE_HEADERS
|
||||
extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
|
||||
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 = gfm.Markdown(body, renderer, extensions)
|
||||
body = blackfriday.Markdown(body, renderer, extensions)
|
||||
return body
|
||||
}
|
||||
|
||||
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
|
||||
body := RenderSpecialLink(rawBytes, urlPrefix)
|
||||
body = RenderRawMarkdown(body, urlPrefix)
|
||||
body = XSS(body)
|
||||
return body
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,16 @@ import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogits/gogs/modules/mahonia"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/saintfish/chardet"
|
||||
)
|
||||
|
||||
func Str2html(raw string) template.HTML {
|
||||
@@ -45,6 +48,29 @@ func ShortSha(sha1 string) string {
|
||||
return sha1
|
||||
}
|
||||
|
||||
func ToUtf8WithErr(content []byte) (error, string) {
|
||||
detector := chardet.NewTextDetector()
|
||||
result, err := detector.DetectBest(content)
|
||||
if err != nil {
|
||||
return err, ""
|
||||
}
|
||||
|
||||
if result.Charset == "utf8" {
|
||||
return nil, string(content)
|
||||
}
|
||||
|
||||
decoder := mahonia.NewDecoder(result.Charset)
|
||||
if decoder != nil {
|
||||
return nil, decoder.ConvertString(string(content))
|
||||
}
|
||||
return errors.New("unknow char decoder"), string(content)
|
||||
}
|
||||
|
||||
func ToUtf8(content string) string {
|
||||
_, res := ToUtf8WithErr([]byte(content))
|
||||
return res
|
||||
}
|
||||
|
||||
var mailDomains = map[string]string{
|
||||
"gmail.com": "gmail.com",
|
||||
}
|
||||
@@ -56,6 +82,9 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
|
||||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSubUrl": func() string {
|
||||
return setting.AppSubUrl
|
||||
},
|
||||
"AppVer": func() string {
|
||||
return setting.AppVer
|
||||
},
|
||||
@@ -103,6 +132,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"Oauth2Icon": Oauth2Icon,
|
||||
"Oauth2Name": Oauth2Name,
|
||||
"ToUtf8": ToUtf8,
|
||||
}
|
||||
|
||||
type Actioner interface {
|
||||
@@ -119,14 +149,12 @@ type Actioner interface {
|
||||
// and returns a icon class name.
|
||||
func ActionIcon(opType int) string {
|
||||
switch opType {
|
||||
case 1: // Create repository.
|
||||
case 1, 8: // Create, transfer repository.
|
||||
return "repo"
|
||||
case 5, 9: // Commit repository.
|
||||
return "git-commit"
|
||||
case 6: // Create issue.
|
||||
return "issue-opened"
|
||||
case 8: // Transfer repository.
|
||||
return "share"
|
||||
case 10: // Comment issue.
|
||||
return "comment"
|
||||
default:
|
||||
@@ -134,16 +162,16 @@ func ActionIcon(opType int) string {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Legacy
|
||||
// FIXME: Legacy
|
||||
const (
|
||||
TPL_CREATE_REPO = `<a href="/user/%s">%s</a> created repository <a href="/%s">%s</a>`
|
||||
TPL_COMMIT_REPO = `<a href="/user/%s">%s</a> pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>%s`
|
||||
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="/%s/commit/%s" rel="nofollow">%s</a> %s</div>`
|
||||
TPL_CREATE_ISSUE = `<a href="/user/%s">%s</a> opened issue <a href="/%s/issues/%s">%s#%s</a>
|
||||
TPL_CREATE_REPO = `<a href="%s/user/%s">%s</a> created repository <a href="%s">%s</a>`
|
||||
TPL_COMMIT_REPO = `<a href="%s/user/%s">%s</a> pushed to <a href="%s/src/%s">%s</a> at <a href="%s">%s</a>%s`
|
||||
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="%s/commit/%s" rel="nofollow">%s</a> %s</div>`
|
||||
TPL_CREATE_ISSUE = `<a href="%s/user/%s">%s</a> opened issue <a href="%s/issues/%s">%s#%s</a>
|
||||
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>`
|
||||
TPL_TRANSFER_REPO = `<a href="/user/%s">%s</a> transfered repository <code>%s</code> to <a href="/%s">%s</a>`
|
||||
TPL_PUSH_TAG = `<a href="/user/%s">%s</a> pushed tag <a href="/%s/src/%s" rel="nofollow">%s</a> at <a href="/%s">%s</a>`
|
||||
TPL_COMMENT_ISSUE = `<a href="/user/%s">%s</a> commented on issue <a href="/%s/issues/%s">%s#%s</a>
|
||||
TPL_TRANSFER_REPO = `<a href="%s/user/%s">%s</a> transfered repository <code>%s</code> to <a href="%s">%s</a>`
|
||||
TPL_PUSH_TAG = `<a href="%s/user/%s">%s</a> pushed tag <a href="%s/src/%s" rel="nofollow">%s</a> at <a href="%s">%s</a>`
|
||||
TPL_COMMENT_ISSUE = `<a href="%s/user/%s">%s</a> commented on issue <a href="%s/issues/%s">%s#%s</a>
|
||||
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>`
|
||||
)
|
||||
|
||||
@@ -167,7 +195,7 @@ func ActionContent2Commits(act Actioner) *PushCommits {
|
||||
return push
|
||||
}
|
||||
|
||||
// TODO: Legacy
|
||||
// FIXME: Legacy
|
||||
// ActionDesc accepts int that represents action operation type
|
||||
// and returns the description.
|
||||
func ActionDesc(act Actioner) string {
|
||||
@@ -180,7 +208,7 @@ func ActionDesc(act Actioner) string {
|
||||
content := act.GetContent()
|
||||
switch act.GetOpType() {
|
||||
case 1: // Create repository.
|
||||
return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, repoLink, repoName)
|
||||
return fmt.Sprintf(TPL_CREATE_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, repoName)
|
||||
case 5: // Commit repository.
|
||||
var push *PushCommits
|
||||
if err := json.Unmarshal([]byte(content), &push); err != nil {
|
||||
@@ -191,22 +219,22 @@ func ActionDesc(act Actioner) string {
|
||||
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n")
|
||||
}
|
||||
if push.Len > 3 {
|
||||
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s" rel="nofollow">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
|
||||
buf.WriteString(fmt.Sprintf(`<div><a href="{{AppRootSubUrl}}/%s/%s/commits/%s" rel="nofollow">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
|
||||
}
|
||||
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink,
|
||||
return fmt.Sprintf(TPL_COMMIT_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink,
|
||||
buf.String())
|
||||
case 6: // Create issue.
|
||||
infos := strings.SplitN(content, "|", 2)
|
||||
return fmt.Sprintf(TPL_CREATE_ISSUE, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
|
||||
return fmt.Sprintf(TPL_CREATE_ISSUE, setting.AppSubUrl, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
|
||||
AvatarLink(email), infos[1])
|
||||
case 8: // Transfer repository.
|
||||
newRepoLink := content + "/" + repoName
|
||||
return fmt.Sprintf(TPL_TRANSFER_REPO, actUserName, actUserName, repoLink, newRepoLink, newRepoLink)
|
||||
return fmt.Sprintf(TPL_TRANSFER_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, newRepoLink, newRepoLink)
|
||||
case 9: // Push tag.
|
||||
return fmt.Sprintf(TPL_PUSH_TAG, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink)
|
||||
return fmt.Sprintf(TPL_PUSH_TAG, setting.AppSubUrl, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink)
|
||||
case 10: // Comment issue.
|
||||
infos := strings.SplitN(content, "|", 2)
|
||||
return fmt.Sprintf(TPL_COMMENT_ISSUE, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
|
||||
return fmt.Sprintf(TPL_COMMENT_ISSUE, setting.AppSubUrl, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
|
||||
AvatarLink(email), infos[1])
|
||||
default:
|
||||
return "invalid type"
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"hash"
|
||||
"html/template"
|
||||
"math"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -146,9 +147,9 @@ func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string
|
||||
// AvatarLink returns avatar link by given e-mail.
|
||||
func AvatarLink(email string) string {
|
||||
if setting.DisableGravatar {
|
||||
return "/img/avatar_default.jpg"
|
||||
return setting.AppSubUrl + "/img/avatar_default.jpg"
|
||||
} else if setting.Service.EnableCacheAvatar {
|
||||
return "/avatar/" + EncodeMd5(email)
|
||||
return setting.AppSubUrl + "/avatar/" + EncodeMd5(email)
|
||||
}
|
||||
return "//1.gravatar.com/avatar/" + EncodeMd5(email)
|
||||
}
|
||||
@@ -446,3 +447,29 @@ func DateFormat(t time.Time, format string) string {
|
||||
format = replacer.Replace(format)
|
||||
return t.Format(format)
|
||||
}
|
||||
|
||||
type xssFilter struct {
|
||||
reg *regexp.Regexp
|
||||
repl []byte
|
||||
}
|
||||
|
||||
var (
|
||||
whiteSpace = []byte(" ")
|
||||
xssFilters = []xssFilter{
|
||||
{regexp.MustCompile(`\ [ONon]\w*=["]*`), whiteSpace},
|
||||
{regexp.MustCompile(`<[SCRIPTscript]{6}`), whiteSpace},
|
||||
{regexp.MustCompile(`=[` + "`" + `'"]*[JAVASCRIPTjavascript \t\0
]*:`), whiteSpace},
|
||||
}
|
||||
)
|
||||
|
||||
// XSS goes through all the XSS filters to make user input content as safe as possible.
|
||||
func XSS(in []byte) []byte {
|
||||
for _, filter := range xssFilters {
|
||||
in = filter.reg.ReplaceAll(in, filter.repl)
|
||||
}
|
||||
return in
|
||||
}
|
||||
|
||||
func XSSString(in string) string {
|
||||
return string(XSS([]byte(in)))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"container/list"
|
||||
"strings"
|
||||
)
|
||||
@@ -17,7 +18,8 @@ type Commit struct {
|
||||
Committer *Signature
|
||||
CommitMessage string
|
||||
|
||||
parents []sha1 // sha1 strings
|
||||
parents []sha1 // sha1 strings
|
||||
submodules map[string]*SubModule
|
||||
}
|
||||
|
||||
// Return the commit message. Same as retrieving CommitMessage directly.
|
||||
@@ -84,3 +86,49 @@ func (c *Commit) CommitsByRange(page int) (*list.List, error) {
|
||||
func (c *Commit) GetCommitOfRelPath(relPath string) (*Commit, error) {
|
||||
return c.repo.getCommitOfRelPath(c.Id, relPath)
|
||||
}
|
||||
|
||||
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
|
||||
moduels, err := c.GetSubModules()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return moduels[entryname], nil
|
||||
}
|
||||
|
||||
func (c *Commit) GetSubModules() (map[string]*SubModule, error) {
|
||||
if c.submodules != nil {
|
||||
return c.submodules, nil
|
||||
}
|
||||
|
||||
entry, err := c.GetTreeEntryByPath(".gitmodules")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rd, err := entry.Blob().Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(rd)
|
||||
c.submodules = make(map[string]*SubModule)
|
||||
var ismodule bool
|
||||
var path string
|
||||
for scanner.Scan() {
|
||||
if strings.HasPrefix(scanner.Text(), "[submodule") {
|
||||
ismodule = true
|
||||
continue
|
||||
}
|
||||
if ismodule {
|
||||
fields := strings.Split(scanner.Text(), "=")
|
||||
k := strings.TrimSpace(fields[0])
|
||||
if k == "path" {
|
||||
path = strings.TrimSpace(fields[1])
|
||||
} else if k == "url" {
|
||||
c.submodules[path] = &SubModule{path, strings.TrimSpace(fields[1])}
|
||||
ismodule = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c.submodules, nil
|
||||
}
|
||||
|
||||
111
modules/git/hooks.go
Normal file
111
modules/git/hooks.go
Normal file
@@ -0,0 +1,111 @@
|
||||
// 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 git
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// hookNames is a list of Git hooks' name that are supported.
|
||||
var hookNames = []string{
|
||||
"pre-applypatch",
|
||||
"applypatch-msg",
|
||||
"prepare-commit-msg",
|
||||
"commit-msg",
|
||||
"pre-commit",
|
||||
"pre-rebase",
|
||||
"post-commit",
|
||||
"post-receive",
|
||||
"post-update",
|
||||
}
|
||||
|
||||
var (
|
||||
ErrNotValidHook = errors.New("not a valid Git hook")
|
||||
)
|
||||
|
||||
// IsValidHookName returns true if given name is a valid Git hook.
|
||||
func IsValidHookName(name string) bool {
|
||||
for _, hn := range hookNames {
|
||||
if hn == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Hook represents a Git hook.
|
||||
type Hook struct {
|
||||
name string
|
||||
IsActive bool // Indicates whether repository has this hook.
|
||||
Content string // Content of hook if it's active.
|
||||
Sample string // Sample content from Git.
|
||||
path string // Hook file path.
|
||||
}
|
||||
|
||||
// GetHook returns a Git hook by given name and repository.
|
||||
func GetHook(repoPath, name string) (*Hook, error) {
|
||||
if !IsValidHookName(name) {
|
||||
return nil, ErrNotValidHook
|
||||
}
|
||||
h := &Hook{
|
||||
name: name,
|
||||
path: path.Join(repoPath, "hooks", name),
|
||||
}
|
||||
if isFile(h.path) {
|
||||
data, err := ioutil.ReadFile(h.path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.IsActive = true
|
||||
h.Content = string(data)
|
||||
} else if isFile(h.path + ".sample") {
|
||||
data, err := ioutil.ReadFile(h.path + ".sample")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.Sample = string(data)
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *Hook) Name() string {
|
||||
return h.name
|
||||
}
|
||||
|
||||
// Update updates hook settings.
|
||||
func (h *Hook) Update() error {
|
||||
if len(strings.TrimSpace(h.Content)) == 0 {
|
||||
return os.Remove(h.path)
|
||||
}
|
||||
return ioutil.WriteFile(h.path, []byte(h.Content), os.ModePerm)
|
||||
}
|
||||
|
||||
// ListHooks returns a list of Git hooks of given repository.
|
||||
func ListHooks(repoPath string) (_ []*Hook, err error) {
|
||||
if !isDir(path.Join(repoPath, "hooks")) {
|
||||
return nil, errors.New("hooks path does not exist")
|
||||
}
|
||||
|
||||
hooks := make([]*Hook, len(hookNames))
|
||||
for i, name := range hookNames {
|
||||
hooks[i], err = GetHook(repoPath, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return hooks, nil
|
||||
}
|
||||
|
||||
func (repo *Repository) GetHook(name string) (*Hook, error) {
|
||||
return GetHook(repo.Path, name)
|
||||
}
|
||||
|
||||
func (repo *Repository) Hooks() ([]*Hook, error) {
|
||||
return ListHooks(repo.Path)
|
||||
}
|
||||
@@ -40,11 +40,11 @@ func (repo *Repository) GetCommitIdOfTag(tagName string) (string, error) {
|
||||
}
|
||||
|
||||
func (repo *Repository) GetCommitOfTag(tagName string) (*Commit, error) {
|
||||
commitId, err := repo.GetCommitIdOfTag(tagName)
|
||||
tag, err := repo.GetTag(tagName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.GetCommit(commitId)
|
||||
return tag.Commit()
|
||||
}
|
||||
|
||||
// Parse commit information from the (uncompressed) raw
|
||||
@@ -137,6 +137,14 @@ func (repo *Repository) GetCommit(commitId string) (*Commit, error) {
|
||||
}
|
||||
|
||||
func (repo *Repository) commitsCount(id sha1) (int, error) {
|
||||
if gitVer.LessThan(MustParseVersion("1.8.0")) {
|
||||
stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", "--pretty=format:''", id.String())
|
||||
if err != nil {
|
||||
return 0, errors.New(string(stderr))
|
||||
}
|
||||
return len(bytes.Split(stdout, []byte("\n"))), nil
|
||||
}
|
||||
|
||||
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "rev-list", "--count", id.String())
|
||||
if err != nil {
|
||||
return 0, errors.New(stderr)
|
||||
|
||||
@@ -22,6 +22,9 @@ func (repo *Repository) IsTagExist(tagName string) bool {
|
||||
|
||||
// GetTags returns all tags of given repository.
|
||||
func (repo *Repository) GetTags() ([]string, error) {
|
||||
if gitVer.AtLeast(MustParseVersion("2.0.0")) {
|
||||
return repo.getTagsReversed()
|
||||
}
|
||||
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l")
|
||||
if err != nil {
|
||||
return nil, errors.New(stderr)
|
||||
@@ -30,6 +33,15 @@ func (repo *Repository) GetTags() ([]string, error) {
|
||||
return tags[:len(tags)-1], nil
|
||||
}
|
||||
|
||||
func (repo *Repository) getTagsReversed() ([]string, error) {
|
||||
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l", "--sort=-v:refname")
|
||||
if err != nil {
|
||||
return nil, errors.New(stderr)
|
||||
}
|
||||
tags := strings.Split(stdout, "\n")
|
||||
return tags[:len(tags)-1], nil
|
||||
}
|
||||
|
||||
func (repo *Repository) CreateTag(tagName, idStr string) error {
|
||||
_, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", tagName, idStr)
|
||||
if err != nil {
|
||||
@@ -52,6 +64,7 @@ func (repo *Repository) getTag(id sha1) (*Tag, error) {
|
||||
if err != nil {
|
||||
return nil, errors.New(stderr)
|
||||
}
|
||||
tp = strings.TrimSpace(tp)
|
||||
|
||||
// Tag is a commit.
|
||||
if ObjectType(tp) == COMMIT {
|
||||
|
||||
58
modules/git/submodule.go
Normal file
58
modules/git/submodule.go
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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 git
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SubModule struct {
|
||||
Name string
|
||||
Url string
|
||||
}
|
||||
|
||||
// SubModuleFile represents a file with submodule type.
|
||||
type SubModuleFile struct {
|
||||
*Commit
|
||||
|
||||
refUrl string
|
||||
refId string
|
||||
}
|
||||
|
||||
func NewSubModuleFile(c *Commit, refUrl, refId string) *SubModuleFile {
|
||||
return &SubModuleFile{
|
||||
Commit: c,
|
||||
refUrl: refUrl,
|
||||
refId: refId,
|
||||
}
|
||||
}
|
||||
|
||||
// RefUrl guesses and returns reference URL.
|
||||
func (sf *SubModuleFile) RefUrl() string {
|
||||
url := strings.TrimSuffix(sf.refUrl, ".git")
|
||||
|
||||
// git://xxx/user/repo
|
||||
if strings.HasPrefix(url, "git://") {
|
||||
return "http://" + strings.TrimPrefix(url, "git://")
|
||||
}
|
||||
|
||||
// http[s]://xxx/user/repo
|
||||
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
|
||||
return url
|
||||
}
|
||||
|
||||
// sysuser@xxx:user/repo
|
||||
i := strings.Index(url, "@")
|
||||
j := strings.LastIndex(url, ":")
|
||||
if i > -1 && j > -1 {
|
||||
return "http://" + url[i+1:j] + "/" + url[j+1:]
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
// RefId returns reference ID.
|
||||
func (sf *SubModuleFile) RefId() string {
|
||||
return sf.refId
|
||||
}
|
||||
@@ -51,6 +51,8 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
|
||||
case "160000":
|
||||
entry.mode = ModeCommit
|
||||
entry.Type = COMMIT
|
||||
|
||||
step = 8
|
||||
case "040000":
|
||||
entry.mode = ModeTree
|
||||
entry.Type = TREE
|
||||
@@ -107,9 +109,12 @@ func (t *Tree) ListEntries(relpath string) (Entries, error) {
|
||||
}
|
||||
t.entriesParsed = true
|
||||
|
||||
stdout, _, err := com.ExecCmdDirBytes(t.repo.Path,
|
||||
stdout, stderr, err := com.ExecCmdDirBytes(t.repo.Path,
|
||||
"git", "ls-tree", t.Id.String())
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "exit status 128") {
|
||||
return nil, errors.New(strings.TrimSpace(string(stderr)))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
t.entries, err = parseTreeData(t, stdout)
|
||||
|
||||
@@ -61,6 +61,10 @@ func (te *TreeEntry) Size() int64 {
|
||||
return te.size
|
||||
}
|
||||
|
||||
func (te *TreeEntry) IsSubModule() bool {
|
||||
return te.mode == ModeCommit
|
||||
}
|
||||
|
||||
func (te *TreeEntry) IsDir() bool {
|
||||
return te.mode == ModeTree
|
||||
}
|
||||
@@ -80,7 +84,7 @@ type Entries []*TreeEntry
|
||||
|
||||
var sorter = []func(t1, t2 *TreeEntry) bool{
|
||||
func(t1, t2 *TreeEntry) bool {
|
||||
return t1.IsDir() && !t2.IsDir()
|
||||
return (t1.IsDir() || t1.IsSubModule()) && !t2.IsDir() && !t2.IsSubModule()
|
||||
},
|
||||
func(t1, t2 *TreeEntry) bool {
|
||||
return t1.name < t2.name
|
||||
|
||||
@@ -7,6 +7,7 @@ package git
|
||||
import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
@@ -46,3 +47,23 @@ func RefEndName(refStr string) string {
|
||||
func filepathFromSHA1(rootdir, sha1 string) string {
|
||||
return filepath.Join(rootdir, "objects", sha1[:2], sha1[2:])
|
||||
}
|
||||
|
||||
// isDir returns true if given path is a directory,
|
||||
// or returns false when it's a file or does not exist.
|
||||
func isDir(dir string) bool {
|
||||
f, e := os.Stat(dir)
|
||||
if e != nil {
|
||||
return false
|
||||
}
|
||||
return f.IsDir()
|
||||
}
|
||||
|
||||
// isFile returns true if given path is a file,
|
||||
// or returns false when it's a directory or does not exist.
|
||||
func isFile(filePath string) bool {
|
||||
f, e := os.Stat(filePath)
|
||||
if e != nil {
|
||||
return false
|
||||
}
|
||||
return !f.IsDir()
|
||||
}
|
||||
|
||||
@@ -11,33 +11,89 @@ import (
|
||||
"github.com/Unknwon/com"
|
||||
)
|
||||
|
||||
var (
|
||||
// Cached Git version.
|
||||
gitVer *Version
|
||||
)
|
||||
|
||||
// Version represents version of Git.
|
||||
type Version struct {
|
||||
Major, Minor, Patch int
|
||||
}
|
||||
|
||||
// GetVersion returns current Git version installed.
|
||||
func GetVersion() (Version, error) {
|
||||
stdout, stderr, err := com.ExecCmd("git", "version")
|
||||
if err != nil {
|
||||
return Version{}, errors.New(stderr)
|
||||
}
|
||||
|
||||
infos := strings.Split(stdout, " ")
|
||||
func ParseVersion(verStr string) (*Version, error) {
|
||||
infos := strings.Split(verStr, ".")
|
||||
if len(infos) < 3 {
|
||||
return Version{}, errors.New("not enough output")
|
||||
return nil, errors.New("incorrect version input")
|
||||
}
|
||||
|
||||
v := Version{}
|
||||
for i, s := range strings.Split(strings.TrimSpace(infos[2]), ".") {
|
||||
v := &Version{}
|
||||
for i, s := range infos {
|
||||
switch i {
|
||||
case 0:
|
||||
v.Major, _ = com.StrTo(s).Int()
|
||||
case 1:
|
||||
v.Minor, _ = com.StrTo(s).Int()
|
||||
case 2:
|
||||
v.Patch, _ = com.StrTo(s).Int()
|
||||
v.Patch, _ = com.StrTo(strings.TrimSpace(s)).Int()
|
||||
}
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func MustParseVersion(verStr string) *Version {
|
||||
v, _ := ParseVersion(verStr)
|
||||
return v
|
||||
}
|
||||
|
||||
// Compare compares two versions,
|
||||
// it returns 1 if original is greater, -1 if original is smaller, 0 if equal.
|
||||
func (v *Version) Compare(that *Version) int {
|
||||
if v.Major > that.Major {
|
||||
return 1
|
||||
} else if v.Major < that.Major {
|
||||
return -1
|
||||
}
|
||||
|
||||
if v.Minor > that.Minor {
|
||||
return 1
|
||||
} else if v.Minor < that.Minor {
|
||||
return -1
|
||||
}
|
||||
|
||||
if v.Patch > that.Patch {
|
||||
return 1
|
||||
} else if v.Patch < that.Patch {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (v *Version) LessThan(that *Version) bool {
|
||||
return v.Compare(that) < 0
|
||||
}
|
||||
|
||||
func (v *Version) AtLeast(that *Version) bool {
|
||||
return v.Compare(that) >= 0
|
||||
}
|
||||
|
||||
// GetVersion returns current Git version installed.
|
||||
func GetVersion() (*Version, error) {
|
||||
if gitVer != nil {
|
||||
return gitVer, nil
|
||||
}
|
||||
|
||||
stdout, stderr, err := com.ExecCmd("git", "version")
|
||||
if err != nil {
|
||||
return nil, errors.New(stderr)
|
||||
}
|
||||
|
||||
infos := strings.Split(stdout, " ")
|
||||
if len(infos) < 3 {
|
||||
return nil, errors.New("not enough output")
|
||||
}
|
||||
|
||||
gitVer, err = ParseVersion(infos[2])
|
||||
return gitVer, err
|
||||
}
|
||||
|
||||
@@ -87,6 +87,12 @@ func Fatal(skip int, format string, v ...interface{}) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func Close() {
|
||||
for _, l := range loggers {
|
||||
l.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// .___ __ _____
|
||||
// | | _____/ |_ ____________/ ____\____ ____ ____
|
||||
// | |/ \ __\/ __ \_ __ \ __\\__ \ _/ ___\/ __ \
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
package mailer
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
|
||||
@@ -33,7 +35,7 @@ func (m Message) Content() string {
|
||||
}
|
||||
|
||||
// create mail content
|
||||
content := "From: " + m.From + "<" + m.User +
|
||||
content := "From: \"" + m.From + "\" <" + m.User +
|
||||
">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
|
||||
return content
|
||||
}
|
||||
@@ -64,6 +66,53 @@ func processMailQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
// sendMail allows mail with self-signed certificates.
|
||||
func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipients []string, msgContent []byte) error {
|
||||
client, err := smtp.Dial(hostAddressWithPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
host, _, _ := net.SplitHostPort(hostAddressWithPort)
|
||||
tlsConn := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: host,
|
||||
}
|
||||
if err = client.StartTLS(tlsConn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if auth != nil {
|
||||
if err = client.Auth(auth); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = client.Mail(from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, rec := range recipients {
|
||||
if err = client.Rcpt(rec); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
w, err := client.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = w.Write([]byte(msgContent)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.Quit()
|
||||
}
|
||||
|
||||
// Direct Send mail message
|
||||
func Send(msg *Message) (int, error) {
|
||||
log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
|
||||
@@ -85,7 +134,7 @@ func Send(msg *Message) (int, error) {
|
||||
num := 0
|
||||
for _, to := range msg.To {
|
||||
body := []byte("To: " + to + "\r\n" + content)
|
||||
err := smtp.SendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
|
||||
err := sendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
|
||||
if err != nil {
|
||||
return num, err
|
||||
}
|
||||
@@ -96,7 +145,7 @@ func Send(msg *Message) (int, error) {
|
||||
body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
|
||||
|
||||
// send to multiple emails in one message
|
||||
err := smtp.SendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
|
||||
err := sendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
|
||||
@@ -25,13 +25,13 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
// Cannot view any page before installation.
|
||||
if !setting.InstallLock {
|
||||
ctx.Redirect("/install")
|
||||
ctx.Redirect(setting.AppSubUrl + "/install")
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect to dashboard if user tries to visit any non-login page.
|
||||
if options.SignOutRequire && ctx.IsSigned && ctx.Req.RequestURI != "/" {
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||
if strings.HasSuffix(ctx.Req.RequestURI, "watch") {
|
||||
return
|
||||
}
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
return
|
||||
} else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -30,7 +29,6 @@ import (
|
||||
// Context represents context of a request.
|
||||
type Context struct {
|
||||
*macaron.Context
|
||||
i18n.Locale
|
||||
Cache cache.Cache
|
||||
csrf csrf.CSRF
|
||||
Flash *session.Flash
|
||||
@@ -140,23 +138,6 @@ func (ctx *Context) Handle(status int, title string, err error) {
|
||||
ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
|
||||
}
|
||||
|
||||
func (ctx *Context) ServeFile(file string, names ...string) {
|
||||
var name string
|
||||
if len(names) > 0 {
|
||||
name = names[0]
|
||||
} else {
|
||||
name = path.Base(file)
|
||||
}
|
||||
ctx.Resp.Header().Set("Content-Description", "File Transfer")
|
||||
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
|
||||
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name)
|
||||
ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary")
|
||||
ctx.Resp.Header().Set("Expires", "0")
|
||||
ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
|
||||
ctx.Resp.Header().Set("Pragma", "public")
|
||||
http.ServeFile(ctx.Resp, ctx.Req, file)
|
||||
}
|
||||
|
||||
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
|
||||
modtime := time.Now()
|
||||
for _, p := range params {
|
||||
@@ -180,14 +161,13 @@ func Contexter() macaron.Handler {
|
||||
return func(c *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) {
|
||||
ctx := &Context{
|
||||
Context: c,
|
||||
Locale: l,
|
||||
Cache: cache,
|
||||
csrf: x,
|
||||
Flash: f,
|
||||
Session: sess,
|
||||
}
|
||||
// Compute current URL for real-time change language.
|
||||
link := ctx.Req.RequestURI
|
||||
link := setting.AppSubUrl + ctx.Req.RequestURI
|
||||
i := strings.Index(link, "?")
|
||||
if i > -1 {
|
||||
link = link[:i]
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
@@ -37,7 +38,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Handle(404, "GetUserByName", err)
|
||||
} else if redirect {
|
||||
log.Error(4, "GetUserByName", err)
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
}
|
||||
@@ -67,7 +68,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
}
|
||||
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
|
||||
|
||||
ctx.Org.OrgLink = "/org/" + org.Name
|
||||
ctx.Org.OrgLink = setting.AppSubUrl + "/org/" + org.Name
|
||||
ctx.Data["OrgLink"] = ctx.Org.OrgLink
|
||||
|
||||
// Team.
|
||||
@@ -79,7 +80,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Handle(404, "GetTeam", err)
|
||||
} else if redirect {
|
||||
log.Error(4, "GetTeam", err)
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
} else {
|
||||
ctx.Handle(500, "GetTeam", err)
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Handle(404, "GetUserByName", err)
|
||||
} else if redirect {
|
||||
log.Error(4, "GetUserByName", err)
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
|
||||
if u == nil {
|
||||
if redirect {
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
}
|
||||
ctx.Handle(404, "RepoAssignment", errors.New("invliad user account for single repository"))
|
||||
@@ -92,7 +92,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Handle(404, "GetRepositoryByName", err)
|
||||
return
|
||||
} else if redirect {
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
}
|
||||
ctx.Handle(500, "GetRepositoryByName", err)
|
||||
@@ -160,7 +160,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
return
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
ctx.Repo.RepoLink = "/" + u.Name + "/" + repo.Name
|
||||
ctx.Repo.RepoLink = setting.AppSubUrl + "/" + u.Name + "/" + repo.Name
|
||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||
|
||||
tags, err := ctx.Repo.GitRepo.GetTags()
|
||||
@@ -168,6 +168,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Handle(500, "GetTags", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Tags"] = tags
|
||||
ctx.Repo.Repository.NumTags = len(tags)
|
||||
|
||||
ctx.Data["Title"] = u.Name + "/" + repo.Name
|
||||
@@ -199,7 +200,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
|
||||
ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(refName)
|
||||
if err != nil {
|
||||
ctx.Handle(404, "RepoAssignment invalid branch", nil)
|
||||
ctx.Handle(500, "RepoAssignment invalid branch", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
|
||||
@@ -207,13 +208,11 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
} else if gitRepo.IsTagExist(refName) {
|
||||
ctx.Repo.IsTag = true
|
||||
ctx.Repo.BranchName = refName
|
||||
|
||||
ctx.Repo.Tag, err = gitRepo.GetTag(refName)
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommitOfTag(refName)
|
||||
if err != nil {
|
||||
ctx.Handle(404, "RepoAssignment invalid tag", nil)
|
||||
ctx.Handle(500, "Fail to get tag commit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.Commit, _ = ctx.Repo.Tag.Commit()
|
||||
ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
|
||||
} else if len(refName) == 40 {
|
||||
ctx.Repo.IsCommit = true
|
||||
@@ -226,7 +225,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctx.Handle(404, "RepoAssignment invalid repo", errors.New("branch or tag not exist"))
|
||||
ctx.Handle(404, "RepoAssignment invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -247,6 +246,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
}
|
||||
|
||||
ctx.Data["IsBranch"] = ctx.Repo.IsBranch
|
||||
ctx.Data["IsTag"] = ctx.Repo.IsTag
|
||||
ctx.Data["IsCommit"] = ctx.Repo.IsCommit
|
||||
|
||||
ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
|
||||
@@ -274,7 +274,8 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||
brs, err := ctx.Repo.GitRepo.GetBranches()
|
||||
if err != nil {
|
||||
log.Error(4, "GetBranches: %v", err)
|
||||
ctx.Handle(500, "GetBranches", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Branches"] = brs
|
||||
ctx.Data["BrancheCount"] = len(brs)
|
||||
@@ -298,8 +299,8 @@ func RequireTrueOwner() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.Repo.IsTrueOwner && !ctx.Repo.IsAdmin {
|
||||
if !ctx.IsSigned {
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
return
|
||||
}
|
||||
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
||||
@@ -307,3 +308,13 @@ func RequireTrueOwner() macaron.Handler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GitHookService checks if repsitory Git hooks service has been enabled.
|
||||
func GitHookService() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !setting.Service.EnableGitHooks {
|
||||
ctx.Handle(404, "GitHookService", nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,12 @@ package setting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -30,9 +32,10 @@ const (
|
||||
|
||||
var (
|
||||
// App settings.
|
||||
AppVer string
|
||||
AppName string
|
||||
AppUrl string
|
||||
AppVer string
|
||||
AppName string
|
||||
AppUrl string
|
||||
AppSubUrl string
|
||||
|
||||
// Server settings.
|
||||
Protocol Scheme
|
||||
@@ -92,18 +95,24 @@ var (
|
||||
SessionProvider string
|
||||
SessionConfig *session.Config
|
||||
|
||||
// Git settings.
|
||||
MaxGitDiffLines int
|
||||
|
||||
// I18n settings.
|
||||
Langs, Names []string
|
||||
|
||||
// Global setting objects.
|
||||
Cfg *goconfig.ConfigFile
|
||||
ConfRootPath string
|
||||
CustomPath string // Custom directory path.
|
||||
ProdMode bool
|
||||
RunUser string
|
||||
|
||||
// I18n settings.
|
||||
Langs, Names []string
|
||||
IsWindows bool
|
||||
HasRobotsTxt bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
IsWindows = runtime.GOOS == "windows"
|
||||
log.NewLogger(0, "console", `{"level": 0}`)
|
||||
}
|
||||
|
||||
@@ -159,6 +168,13 @@ func NewConfigContext() {
|
||||
AppUrl += "/"
|
||||
}
|
||||
|
||||
// Check if has app suburl.
|
||||
url, err := url.Parse(AppUrl)
|
||||
if err != nil {
|
||||
log.Fatal(4, "Invalid ROOT_URL(%s): %s", AppUrl, err)
|
||||
}
|
||||
AppSubUrl = strings.TrimSuffix(url.Path, "/")
|
||||
|
||||
Protocol = HTTP
|
||||
if Cfg.MustValue("server", "PROTOCOL") == "https" {
|
||||
Protocol = HTTPS
|
||||
@@ -241,8 +257,12 @@ func NewConfigContext() {
|
||||
[]string{"server"})
|
||||
DisableGravatar = Cfg.MustBool("picture", "DISABLE_GRAVATAR")
|
||||
|
||||
MaxGitDiffLines = Cfg.MustInt("git", "MAX_GITDIFF_LINES", 10000)
|
||||
|
||||
Langs = Cfg.MustValueArray("i18n", "LANGS", ",")
|
||||
Names = Cfg.MustValueArray("i18n", "NAMES", ",")
|
||||
|
||||
HasRobotsTxt = com.IsFile(path.Join(CustomPath, "robots.txt"))
|
||||
}
|
||||
|
||||
var Service struct {
|
||||
@@ -255,6 +275,7 @@ var Service struct {
|
||||
LdapAuth bool
|
||||
ActiveCodeLives int
|
||||
ResetPwdCodeLives int
|
||||
EnableGitHooks bool
|
||||
}
|
||||
|
||||
func newService() {
|
||||
@@ -264,6 +285,7 @@ func newService() {
|
||||
Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW")
|
||||
Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR")
|
||||
Service.EnableReverseProxyAuth = Cfg.MustBool("service", "ENABLE_REVERSE_PROXY_AUTHENTICATION")
|
||||
Service.EnableGitHooks = Cfg.MustBool("service", "ENABLE_GIT_HOOKS")
|
||||
}
|
||||
|
||||
var logLevels = map[string]string{
|
||||
@@ -363,6 +385,7 @@ func newSessionService() {
|
||||
SessionConfig = new(session.Config)
|
||||
SessionConfig.ProviderConfig = strings.Trim(Cfg.MustValue("session", "PROVIDER_CONFIG"), "\" ")
|
||||
SessionConfig.CookieName = Cfg.MustValue("session", "COOKIE_NAME", "i_like_gogits")
|
||||
SessionConfig.CookiePath = AppSubUrl
|
||||
SessionConfig.Secure = Cfg.MustBool("session", "COOKIE_SECURE")
|
||||
SessionConfig.EnableSetCookie = Cfg.MustBool("session", "ENABLE_SET_COOKIE", true)
|
||||
SessionConfig.Gclifetime = Cfg.MustInt64("session", "GC_INTERVAL_TIME", 86400)
|
||||
|
||||
@@ -20,9 +20,6 @@ APP_USER=$(${CLI} config:get APP_USER)
|
||||
APP_GROUP=$(${CLI} config:get APP_GROUP)
|
||||
APP_CONFIG="/etc/${APP_NAME}/conf/app.ini"
|
||||
|
||||
# source debconf library
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
case "$1" in
|
||||
|
||||
configure)
|
||||
|
||||
@@ -7,9 +7,6 @@ body {
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
.fa {
|
||||
font-size: 14px;
|
||||
}
|
||||
.container {
|
||||
max-width: 1170px;
|
||||
padding: 0 1.5em;
|
||||
@@ -20,6 +17,11 @@ img.avatar-16 {
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
img.avatar-20 {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
img.avatar-24 {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
@@ -45,6 +47,9 @@ img.avatar-100 {
|
||||
height: 100px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.drop-down .panel-header {
|
||||
font-size: 14px;
|
||||
}
|
||||
#wrapper {
|
||||
padding: 0;
|
||||
margin: 0 0 -55px 0;
|
||||
@@ -83,6 +88,7 @@ img.avatar-100 {
|
||||
z-index: 100;
|
||||
font-size: 12px;
|
||||
width: 120%;
|
||||
min-width: 100px;
|
||||
}
|
||||
#footer-lang .drop-down li > a {
|
||||
padding: 3px 9px;
|
||||
@@ -294,6 +300,12 @@ img.avatar-100 {
|
||||
.markdown li:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown code {
|
||||
padding: 0.2em 0.5em;
|
||||
margin: 0;
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.markdown > pre {
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
@@ -304,6 +316,10 @@ img.avatar-100 {
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.markdown > pre code {
|
||||
padding: 0;
|
||||
background-color: inherit;
|
||||
}
|
||||
.markdown img {
|
||||
padding: 10px 0;
|
||||
max-width: 100%;
|
||||
@@ -686,18 +702,20 @@ ol.linenums {
|
||||
width: auto;
|
||||
}
|
||||
/*
|
||||
The dashboard page style
|
||||
The dashboard page style
|
||||
*/
|
||||
#dashboard-header {
|
||||
border-bottom: 1px solid #d6d6d6;
|
||||
height: 69px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
#dashboard-header > .menu-line > li {
|
||||
padding: 12px 0;
|
||||
padding: 12px 6px;
|
||||
}
|
||||
#dashboard-header > .menu-line > li.right > a {
|
||||
font-size: 1.2em;
|
||||
color: #444444;
|
||||
padding: .4em .8em;
|
||||
}
|
||||
#dashboard-header > .menu-line > li.right > a:hover {
|
||||
background-color: transparent;
|
||||
@@ -727,7 +745,7 @@ The dashboard page style
|
||||
border-top-left-radius: .3em;
|
||||
border-top-right-radius: .3em;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
height: 32px;
|
||||
}
|
||||
#dashboard-sidebar-menu > li {
|
||||
border: 1px solid #d6d6d6;
|
||||
@@ -736,8 +754,8 @@ The dashboard page style
|
||||
border-bottom: none;
|
||||
}
|
||||
#dashboard-sidebar-menu > li > a {
|
||||
padding-top: .4em;
|
||||
padding-bottom: .4em;
|
||||
padding-top: .3em;
|
||||
padding-bottom: .3em;
|
||||
}
|
||||
#dashboard-sidebar-menu > li.first {
|
||||
border-top-left-radius: .3em;
|
||||
@@ -805,6 +823,11 @@ The dashboard page style
|
||||
#dashboard-my-repo .repo-contrib-header {
|
||||
border-top: 1px solid #d6d6d6;
|
||||
}
|
||||
#dashboard-my-mirror .panel-header,
|
||||
#dashboard-my-org .panel-header,
|
||||
#dashboard-my-repo .panel-header {
|
||||
font-size: 14px;
|
||||
}
|
||||
#dashboard-my-repo .panel-header .octicon {
|
||||
margin-right: 6px;
|
||||
font-size: 12px;
|
||||
@@ -818,7 +841,7 @@ The dashboard page style
|
||||
}
|
||||
#dashboard-new-repo {
|
||||
width: 50px;
|
||||
height: 35px;
|
||||
height: 33px;
|
||||
padding-top: 6px;
|
||||
margin-right: 1px;
|
||||
border-top-left-radius: .3em;
|
||||
@@ -828,7 +851,7 @@ The dashboard page style
|
||||
font-size: 2em;
|
||||
}
|
||||
#dashboard-new-repo-menu {
|
||||
top: 35px;
|
||||
top: 33px;
|
||||
width: 180px;
|
||||
background-color: #FFF;
|
||||
left: -132px;
|
||||
@@ -878,6 +901,9 @@ The dashboard page style
|
||||
#dashboard-switch-menu > li.checked > a .octicon {
|
||||
opacity: 1;
|
||||
}
|
||||
#dashboard-news {
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
#dashboard-news .news {
|
||||
margin-right: 2.4em;
|
||||
padding-bottom: 1em;
|
||||
@@ -984,8 +1010,8 @@ The register and sign-in page style
|
||||
}
|
||||
#repo-header-meta a > .btn {
|
||||
line-height: 16px;
|
||||
font-size: 1.05em;
|
||||
margin-left: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
#repo-header-meta a > .btn i {
|
||||
margin-right: 6px;
|
||||
@@ -1030,9 +1056,13 @@ The register and sign-in page style
|
||||
#repo-content {
|
||||
padding: 18px 0;
|
||||
}
|
||||
.repo-wide-wrapper {
|
||||
padding: 18px 0;
|
||||
position: relative;
|
||||
}
|
||||
#repo-clone-url {
|
||||
border-right: none;
|
||||
width: 200px;
|
||||
width: 190px;
|
||||
border-left: none;
|
||||
}
|
||||
#repo-clone-help {
|
||||
@@ -1054,6 +1084,9 @@ The register and sign-in page style
|
||||
#repo-desc {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
#repo-desc .no-description {
|
||||
color: #999;
|
||||
}
|
||||
#repo-sidebar-nav .label {
|
||||
font-size: 12px;
|
||||
line-height: 1.4em;
|
||||
@@ -1062,6 +1095,37 @@ The register and sign-in page style
|
||||
#repo-sidebar-nav i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
#repo-sidebar-mini {
|
||||
margin-top: 6px;
|
||||
width: 60px;
|
||||
}
|
||||
#repo-sidebar-mini li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
#repo-sidebar-mini li > a {
|
||||
position: relative;
|
||||
padding-left: 12px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
#repo-sidebar-mini li > a > i.octicon {
|
||||
font-size: 21px;
|
||||
}
|
||||
#repo-sidebar-mini .num {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
top: 0;
|
||||
left: 36px;
|
||||
padding: 0 2px;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
text-align: center;
|
||||
line-height: 16px;
|
||||
border-radius: 4px;
|
||||
opacity: 0.7;
|
||||
-webkit-transform: scale(0.9);
|
||||
font-weight: bold;
|
||||
}
|
||||
#repo-file-nav {
|
||||
padding: .6em 0 1em 0;
|
||||
}
|
||||
@@ -1107,6 +1171,10 @@ The register and sign-in page style
|
||||
background-color: #EEE;
|
||||
font-weight: bold;
|
||||
}
|
||||
#repo-branch-tag .switching-list {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
#repo-branch-list li i,
|
||||
#repo-tag-list li i {
|
||||
margin-right: 12px;
|
||||
@@ -1116,9 +1184,6 @@ The register and sign-in page style
|
||||
#repo-tag-list li.checked i {
|
||||
opacity: 1;
|
||||
}
|
||||
#repo-tag-list {
|
||||
display: none;
|
||||
}
|
||||
#repo-bread .bread {
|
||||
padding-right: 0;
|
||||
font-size: 16px;
|
||||
@@ -1189,7 +1254,8 @@ The register and sign-in page style
|
||||
font-weight: normal;
|
||||
color: #888;
|
||||
}
|
||||
#repo-readme {
|
||||
#repo-readme,
|
||||
#repo-read-file {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
#repo-bare-start {
|
||||
@@ -1396,6 +1462,31 @@ The register and sign-in page style
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
}
|
||||
#commits-list {
|
||||
padding-top: 20px;
|
||||
}
|
||||
#commits-list h4 {
|
||||
line-height: 30px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.commit-list th {
|
||||
background-color: #FFF;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
.commit-list .date {
|
||||
width: 120px;
|
||||
}
|
||||
.commit-list .author {
|
||||
padding-left: 20px;
|
||||
min-width: 180px;
|
||||
}
|
||||
.commit-list .author img {
|
||||
margin-top: -4px;
|
||||
}
|
||||
.commit-list .sha a {
|
||||
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
#admin-wrapper,
|
||||
#setting-wrapper {
|
||||
padding-bottom: 100px;
|
||||
@@ -1559,39 +1650,18 @@ The register and sign-in page style
|
||||
#user-ssh-add-form .field {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.repo-issue-wrapper {
|
||||
padding: 18px 0;
|
||||
}
|
||||
.pr-main {
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 100px;
|
||||
}
|
||||
.pr-sidebar {
|
||||
border-left: 1px solid #DDD;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 12px;
|
||||
}
|
||||
#pr-sidebar-nav {
|
||||
margin-top: 6px;
|
||||
}
|
||||
#pr-sidebar-nav li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
#pr-sidebar-nav li > a {
|
||||
border: 1px solid transparent;
|
||||
border-left: none;
|
||||
}
|
||||
#pr-sidebar-nav li > a:hover {
|
||||
background-color: #FFF;
|
||||
border-color: #DDD;
|
||||
}
|
||||
#pr-sidebar-nav .label {
|
||||
font-size: 12px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 1px;
|
||||
}
|
||||
#pr-sidebar-nav li.current a {
|
||||
background-color: #FFF;
|
||||
border-color: #DDD;
|
||||
.pr-title {
|
||||
padding: 4px 0;
|
||||
}
|
||||
.pr-title .pr-num {
|
||||
font-weight: normal;
|
||||
@@ -1599,6 +1669,7 @@ The register and sign-in page style
|
||||
}
|
||||
.pr-meta {
|
||||
color: #888;
|
||||
padding: 4px 0 8px 0;
|
||||
}
|
||||
.pr-meta .pr-author {
|
||||
margin: 0 8px;
|
||||
@@ -1672,7 +1743,7 @@ The register and sign-in page style
|
||||
.issue-line,
|
||||
.issue-merge,
|
||||
.issue-add-comment {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.issue-comment .author-avatar img {
|
||||
margin-right: 12px;
|
||||
@@ -1776,6 +1847,7 @@ textarea#issue-add-content {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
.org-header-alert .alert {
|
||||
margin-top: 10px;
|
||||
@@ -1810,7 +1882,10 @@ textarea#issue-add-content {
|
||||
color: #d9453d;
|
||||
}
|
||||
#org-header > div > .menu-line > li.right > a .octicon {
|
||||
margin-right: 6px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
#org-header > div > .menu-line > li.right > a .label {
|
||||
margin-left: 4px;
|
||||
}
|
||||
#org-header > div > .menu-line > li.right .current {
|
||||
border-bottom: 2px solid #D26911;
|
||||
@@ -2009,3 +2084,56 @@ textarea#issue-add-content {
|
||||
.admin-dl-horizontal > dd {
|
||||
margin-left: 240px;
|
||||
}
|
||||
.profile-avatar {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
#profile-name {
|
||||
padding: 10px 0;
|
||||
}
|
||||
#profile-fullname {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
#profile-username {
|
||||
font-size: 1.6em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.profile-info {
|
||||
padding: 0 50px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.profile-info ul {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.profile-info ul .list-group-item {
|
||||
background-color: transparent;
|
||||
padding-top: 5px;
|
||||
color: #666;
|
||||
}
|
||||
.profile-info ul .profile-rel {
|
||||
width: 31%;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
.profile-info ul .profile-rel strong {
|
||||
display: block;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
.profile-info ul .profile-rel p {
|
||||
font-size: 12px;
|
||||
}
|
||||
#profile-header li a {
|
||||
font-size: 1.2em;
|
||||
color: #444444;
|
||||
padding: .4em .8em;
|
||||
}
|
||||
#profile-header li a:hover {
|
||||
background-color: transparent;
|
||||
color: #d9453d;
|
||||
}
|
||||
#profile-header li .current {
|
||||
border-bottom: 2px solid #D26911;
|
||||
}
|
||||
|
||||
368
public/ng/css/magnific-popup.css
Normal file
368
public/ng/css/magnific-popup.css
Normal file
@@ -0,0 +1,368 @@
|
||||
/* Magnific Popup CSS */
|
||||
.mfp-bg {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1042;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
background: #0b0b0b;
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80); }
|
||||
|
||||
.mfp-wrap {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1043;
|
||||
position: fixed;
|
||||
outline: none !important;
|
||||
-webkit-backface-visibility: hidden; }
|
||||
|
||||
.mfp-container {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0 8px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box; }
|
||||
|
||||
.mfp-container:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle; }
|
||||
|
||||
.mfp-align-top .mfp-container:before {
|
||||
display: none; }
|
||||
|
||||
.mfp-content {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
z-index: 1045; }
|
||||
|
||||
.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
|
||||
width: 100%;
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-ajax-cur {
|
||||
cursor: progress; }
|
||||
|
||||
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
|
||||
cursor: -moz-zoom-out;
|
||||
cursor: -webkit-zoom-out;
|
||||
cursor: zoom-out; }
|
||||
|
||||
.mfp-zoom {
|
||||
cursor: pointer;
|
||||
cursor: -webkit-zoom-in;
|
||||
cursor: -moz-zoom-in;
|
||||
cursor: zoom-in; }
|
||||
|
||||
.mfp-auto-cursor .mfp-content {
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none; }
|
||||
|
||||
.mfp-loading.mfp-figure {
|
||||
display: none; }
|
||||
|
||||
.mfp-hide {
|
||||
display: none !important; }
|
||||
|
||||
.mfp-preloader {
|
||||
color: #cccccc;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: auto;
|
||||
text-align: center;
|
||||
margin-top: -0.8em;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
z-index: 1044; }
|
||||
.mfp-preloader a {
|
||||
color: #cccccc; }
|
||||
.mfp-preloader a:hover {
|
||||
color: white; }
|
||||
|
||||
.mfp-s-ready .mfp-preloader {
|
||||
display: none; }
|
||||
|
||||
.mfp-s-error .mfp-content {
|
||||
display: none; }
|
||||
|
||||
button.mfp-close, button.mfp-arrow {
|
||||
overflow: visible;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
display: block;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
z-index: 1046;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none; }
|
||||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0; }
|
||||
|
||||
.mfp-close {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
padding: 0 0 18px 10px;
|
||||
color: white;
|
||||
font-style: normal;
|
||||
font-size: 28px;
|
||||
font-family: Arial, Baskerville, monospace; }
|
||||
.mfp-close:hover, .mfp-close:focus {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100); }
|
||||
.mfp-close:active {
|
||||
top: 1px; }
|
||||
|
||||
.mfp-close-btn-in .mfp-close {
|
||||
color: #333333; }
|
||||
|
||||
.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
|
||||
color: white;
|
||||
right: -6px;
|
||||
text-align: right;
|
||||
padding-right: 6px;
|
||||
width: 100%; }
|
||||
|
||||
.mfp-counter {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #cccccc;
|
||||
font-size: 12px;
|
||||
line-height: 18px; }
|
||||
|
||||
.mfp-arrow {
|
||||
position: absolute;
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
margin: 0;
|
||||
top: 50%;
|
||||
margin-top: -55px;
|
||||
padding: 0;
|
||||
width: 90px;
|
||||
height: 110px;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
|
||||
.mfp-arrow:active {
|
||||
margin-top: -54px; }
|
||||
.mfp-arrow:hover, .mfp-arrow:focus {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100); }
|
||||
.mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin-top: 35px;
|
||||
margin-left: 35px;
|
||||
border: medium inset transparent; }
|
||||
.mfp-arrow:after, .mfp-arrow .mfp-a {
|
||||
border-top-width: 13px;
|
||||
border-bottom-width: 13px;
|
||||
top: 8px; }
|
||||
.mfp-arrow:before, .mfp-arrow .mfp-b {
|
||||
border-top-width: 21px;
|
||||
border-bottom-width: 21px;
|
||||
opacity: 0.7; }
|
||||
|
||||
.mfp-arrow-left {
|
||||
left: 0; }
|
||||
.mfp-arrow-left:after, .mfp-arrow-left .mfp-a {
|
||||
border-right: 17px solid white;
|
||||
margin-left: 31px; }
|
||||
.mfp-arrow-left:before, .mfp-arrow-left .mfp-b {
|
||||
margin-left: 25px;
|
||||
border-right: 27px solid #3f3f3f; }
|
||||
|
||||
.mfp-arrow-right {
|
||||
right: 0; }
|
||||
.mfp-arrow-right:after, .mfp-arrow-right .mfp-a {
|
||||
border-left: 17px solid white;
|
||||
margin-left: 39px; }
|
||||
.mfp-arrow-right:before, .mfp-arrow-right .mfp-b {
|
||||
border-left: 27px solid #3f3f3f; }
|
||||
|
||||
.mfp-iframe-holder {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px; }
|
||||
.mfp-iframe-holder .mfp-content {
|
||||
line-height: 0;
|
||||
width: 100%;
|
||||
max-width: 900px; }
|
||||
.mfp-iframe-holder .mfp-close {
|
||||
top: -40px; }
|
||||
|
||||
.mfp-iframe-scaler {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
padding-top: 56.25%; }
|
||||
.mfp-iframe-scaler iframe {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
|
||||
background: black; }
|
||||
|
||||
/* Main image in popup */
|
||||
img.mfp-img {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
line-height: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 40px 0 40px;
|
||||
margin: 0 auto; }
|
||||
|
||||
/* The shadow behind the image */
|
||||
.mfp-figure {
|
||||
line-height: 0; }
|
||||
.mfp-figure:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 40px;
|
||||
bottom: 40px;
|
||||
display: block;
|
||||
right: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
z-index: -1;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
|
||||
background: #444444; }
|
||||
.mfp-figure small {
|
||||
color: #bdbdbd;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 14px; }
|
||||
.mfp-figure figure {
|
||||
margin: 0; }
|
||||
|
||||
.mfp-bottom-bar {
|
||||
margin-top: -36px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-title {
|
||||
text-align: left;
|
||||
line-height: 18px;
|
||||
color: #f3f3f3;
|
||||
word-wrap: break-word;
|
||||
padding-right: 36px; }
|
||||
|
||||
.mfp-image-holder .mfp-content {
|
||||
max-width: 100%; }
|
||||
|
||||
.mfp-gallery .mfp-image-holder .mfp-figure {
|
||||
cursor: pointer; }
|
||||
|
||||
@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
|
||||
/**
|
||||
* Remove all paddings around the image on small screen
|
||||
*/
|
||||
.mfp-img-mobile .mfp-image-holder {
|
||||
padding-left: 0;
|
||||
padding-right: 0; }
|
||||
.mfp-img-mobile img.mfp-img {
|
||||
padding: 0; }
|
||||
.mfp-img-mobile .mfp-figure:after {
|
||||
top: 0;
|
||||
bottom: 0; }
|
||||
.mfp-img-mobile .mfp-figure small {
|
||||
display: inline;
|
||||
margin-left: 5px; }
|
||||
.mfp-img-mobile .mfp-bottom-bar {
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
top: auto;
|
||||
padding: 3px 5px;
|
||||
position: fixed;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box; }
|
||||
.mfp-img-mobile .mfp-bottom-bar:empty {
|
||||
padding: 0; }
|
||||
.mfp-img-mobile .mfp-counter {
|
||||
right: 5px;
|
||||
top: 3px; }
|
||||
.mfp-img-mobile .mfp-close {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
padding: 0; } }
|
||||
|
||||
@media all and (max-width: 900px) {
|
||||
.mfp-arrow {
|
||||
-webkit-transform: scale(0.75);
|
||||
transform: scale(0.75); }
|
||||
.mfp-arrow-left {
|
||||
-webkit-transform-origin: 0;
|
||||
transform-origin: 0; }
|
||||
.mfp-arrow-right {
|
||||
-webkit-transform-origin: 100%;
|
||||
transform-origin: 100%; }
|
||||
.mfp-container {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px; } }
|
||||
|
||||
.mfp-ie7 .mfp-img {
|
||||
padding: 0; }
|
||||
.mfp-ie7 .mfp-bottom-bar {
|
||||
width: 600px;
|
||||
left: 50%;
|
||||
margin-left: -300px;
|
||||
margin-top: 5px;
|
||||
padding-bottom: 5px; }
|
||||
.mfp-ie7 .mfp-container {
|
||||
padding: 0; }
|
||||
.mfp-ie7 .mfp-content {
|
||||
padding-top: 44px; }
|
||||
.mfp-ie7 .mfp-close {
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding-top: 0; }
|
||||
25
public/ng/css/tipsy.css
Normal file
25
public/ng/css/tipsy.css
Normal file
@@ -0,0 +1,25 @@
|
||||
.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
|
||||
.tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
|
||||
|
||||
/* Rounded corners */
|
||||
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
|
||||
|
||||
/* Uncomment for shadow */
|
||||
/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
|
||||
|
||||
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
|
||||
|
||||
/* Rules to colour arrows */
|
||||
.tipsy-arrow-n { border-bottom-color: #000; }
|
||||
.tipsy-arrow-s { border-top-color: #000; }
|
||||
.tipsy-arrow-e { border-left-color: #000; }
|
||||
.tipsy-arrow-w { border-right-color: #000; }
|
||||
|
||||
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
||||
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
||||
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
|
||||
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
|
||||
@@ -277,9 +277,6 @@ hr {
|
||||
border-bottom: 1px solid #dddddd;
|
||||
margin-bottom: .75em;
|
||||
}
|
||||
p code {
|
||||
color: #b63b2c;
|
||||
}
|
||||
.radius {
|
||||
border-radius: .25em;
|
||||
}
|
||||
@@ -483,6 +480,10 @@ dt {
|
||||
.ipt-large {
|
||||
font-size: 14.4px;
|
||||
}
|
||||
.ipt-textarea {
|
||||
height: auto !important;
|
||||
width: auto;
|
||||
}
|
||||
.ipt-disabled,
|
||||
input[disabled] {
|
||||
background-color: #f2f2f2 !important;
|
||||
@@ -735,6 +736,10 @@ ul.menu-radius > li:last-child > a {
|
||||
.label-green {
|
||||
background-color: #65ad4e;
|
||||
}
|
||||
.label-green:hover {
|
||||
background-color: #71bf57;
|
||||
color: #FFF;
|
||||
}
|
||||
.label-orange {
|
||||
background-color: #df7514;
|
||||
}
|
||||
@@ -795,6 +800,17 @@ ul.menu-radius > li:last-child > a {
|
||||
border: 1px solid #b05c10;
|
||||
background-color: #fcecdd;
|
||||
}
|
||||
.white-popup-block {
|
||||
background: #FFF;
|
||||
padding: 20px 30px;
|
||||
text-align: left;
|
||||
max-width: 650px;
|
||||
margin: 40px auto;
|
||||
position: relative;
|
||||
}
|
||||
.white-popup-block p {
|
||||
font-size: 14px;
|
||||
}
|
||||
table th,
|
||||
table td {
|
||||
padding: .3em .6em;
|
||||
|
||||
20
public/ng/fonts/octicons.css
vendored
20
public/ng/fonts/octicons.css
vendored
@@ -14,22 +14,20 @@
|
||||
.mega-octicon is optimized for 32px but can be used larger.
|
||||
|
||||
*/
|
||||
.octicon {
|
||||
font: normal normal 16px octicons;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.mega-octicon {
|
||||
font: normal normal 32px octicons;
|
||||
line-height: 1;
|
||||
.octicon, .mega-octicon {
|
||||
font: normal normal normal 16px/1 octicons;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.mega-octicon { font-size: 32px; }
|
||||
|
||||
|
||||
.octicon-alert:before { content: '\f02d'} /* */
|
||||
.octicon-alignment-align:before { content: '\f08a'} /* */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
// @codekit-prepend "lib/jquery-1.11.1.min.js"
|
||||
// @codekit-prepend "lib/lib.js"
|
||||
// @codekit-prepend "lib/tabs.js"
|
||||
// @codekit-prepend "utils/tabs.js"
|
||||
// @codekit-prepend "utils/preview.js"
|
||||
// @codekit-prepend "lib/jquery.tipsy.js"
|
||||
|
||||
var Gogs = {};
|
||||
|
||||
@@ -202,7 +204,7 @@ var Gogs = {};
|
||||
// Search users by keyword.
|
||||
Gogs.searchUsers = function (val, $target) {
|
||||
$.ajax({
|
||||
url: '/api/v1/users/search?q=' + val,
|
||||
url: Gogs.AppSubUrl + '/api/v1/users/search?q=' + val,
|
||||
dataType: "json",
|
||||
success: function (json) {
|
||||
if (json.ok && json.data.length) {
|
||||
@@ -222,7 +224,7 @@ var Gogs = {};
|
||||
// Search repositories by keyword.
|
||||
Gogs.searchRepos = function (val, $target, $param) {
|
||||
$.ajax({
|
||||
url: '/api/v1/repos/search?q=' + val + '&' + $param,
|
||||
url: Gogs.AppSubUrl + '/api/v1/repos/search?q=' + val + '&' + $param,
|
||||
dataType: "json",
|
||||
success: function (json) {
|
||||
if (json.ok && json.data.length) {
|
||||
@@ -245,7 +247,7 @@ var Gogs = {};
|
||||
return;
|
||||
}
|
||||
$(selector).zclip({
|
||||
path: "/js/ZeroClipboard.swf",
|
||||
path: Gogs.AppSubUrl + "/js/ZeroClipboard.swf",
|
||||
copy: function () {
|
||||
var t = $(this).data("copy-val");
|
||||
var to = $($(this).data("copy-from"));
|
||||
@@ -262,17 +264,14 @@ var Gogs = {};
|
||||
return str;
|
||||
},
|
||||
afterCopy: function () {
|
||||
alert("Clone URL has copied!");
|
||||
// var $this = $(this);
|
||||
// $this.tooltip('hide')
|
||||
// .attr('data-original-title', 'Copied OK');
|
||||
// setTimeout(function () {
|
||||
// $this.tooltip("show");
|
||||
// }, 200);
|
||||
// setTimeout(function () {
|
||||
// $this.tooltip('hide')
|
||||
// .attr('data-original-title', 'Copy to Clipboard');
|
||||
// }, 3000);
|
||||
var $this = $(this);
|
||||
$this.tipsy("hide").attr('original-title', $this.data('after-title'));
|
||||
setTimeout(function () {
|
||||
$this.tipsy("show");
|
||||
}, 200);
|
||||
setTimeout(function () {
|
||||
$this.tipsy('hide').attr('original-title', $this.data('original-title'));
|
||||
}, 2000);
|
||||
}
|
||||
}).addClass("js-copy-bind");
|
||||
}
|
||||
@@ -281,17 +280,51 @@ var Gogs = {};
|
||||
function initCore() {
|
||||
Gogs.renderMarkdown();
|
||||
Gogs.renderCodeView();
|
||||
|
||||
// Switch list.
|
||||
$('.js-tab-nav').click(function (e) {
|
||||
if (!$(this).hasClass('js-tab-nav-show')) {
|
||||
$(this).parent().find('.js-tab-nav-show').each(function () {
|
||||
$(this).removeClass('js-tab-nav-show');
|
||||
$($(this).data('tab-target')).hide();
|
||||
});
|
||||
$(this).addClass('js-tab-nav-show');
|
||||
$($(this).data('tab-target')).show();
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// Popup.
|
||||
$(document).on('click', '.popup-modal-dismiss', function (e) {
|
||||
e.preventDefault();
|
||||
$.magnificPopup.close();
|
||||
});
|
||||
}
|
||||
|
||||
function initUserSetting() {
|
||||
// Confirmation of change username in user profile page.
|
||||
$('#user-profile-form').submit(function (e) {
|
||||
var $username = $('#username');
|
||||
if (($username.data('uname') != $username.val()) && !confirm('Username has been changed, do you want to continue?')) {
|
||||
var $username = $('#username');
|
||||
var $profile_form = $('#user-profile-form');
|
||||
$('#change-username-btn').magnificPopup({
|
||||
modal: true,
|
||||
callbacks: {
|
||||
open: function () {
|
||||
if (($username.data('uname') == $username.val())) {
|
||||
$.magnificPopup.close();
|
||||
$profile_form.submit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}).click(function () {
|
||||
if (($username.data('uname') != $username.val())) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
$('#change-username-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$profile_form.submit();
|
||||
});
|
||||
|
||||
// Show add SSH key panel.
|
||||
$('#ssh-add').click(function () {
|
||||
@@ -299,11 +332,15 @@ function initUserSetting() {
|
||||
});
|
||||
|
||||
// Confirmation of delete account.
|
||||
$('#delete-account-button').click(function (e) {
|
||||
if (!confirm('This account is going to be deleted, do you want to continue?')) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
$('#delete-account-btn').magnificPopup({
|
||||
modal: true
|
||||
}).click(function (e) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
});
|
||||
$('#delete-account-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$('#delete-account-form').submit();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -343,48 +380,79 @@ function initRepo() {
|
||||
$('#repo-clone-url').val($(this).data('link'));
|
||||
$('.clone-url').text($(this).data('link'))
|
||||
});
|
||||
|
||||
// Copy URL.
|
||||
$('#repo-clone-copy').hover(function () {
|
||||
var $clone_btn = $('#repo-clone-copy');
|
||||
$clone_btn.hover(function () {
|
||||
Gogs.bindCopy($(this));
|
||||
})
|
||||
$clone_btn.tipsy({
|
||||
fade: true
|
||||
});
|
||||
}
|
||||
|
||||
// when user changes hook type, hide/show proper divs
|
||||
function initHookTypeChange() {
|
||||
// web hook type change
|
||||
$('select#hook-type').on("change", function () {
|
||||
hookTypes = ['Gogs','Slack'];
|
||||
hookTypes = ['Gogs', 'Slack'];
|
||||
|
||||
var curHook = $(this).val();
|
||||
hookTypes.forEach(function(hookType) {
|
||||
if (curHook === hookType) {
|
||||
$('div#'+hookType.toLowerCase()).toggleShow();
|
||||
}
|
||||
else {
|
||||
$('div#'+hookType.toLowerCase()).toggleHide();
|
||||
}
|
||||
});
|
||||
var curHook = $(this).val();
|
||||
hookTypes.forEach(function (hookType) {
|
||||
if (curHook === hookType) {
|
||||
$('div#' + hookType.toLowerCase()).toggleShow();
|
||||
}
|
||||
else {
|
||||
$('div#' + hookType.toLowerCase()).toggleHide();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initRepoSetting() {
|
||||
// Options.
|
||||
// Confirmation of changing repository name.
|
||||
$('#repo-setting-form').submit(function (e) {
|
||||
var $reponame = $('#repo_name');
|
||||
if (($reponame.data('repo-name') != $reponame.val()) && !confirm('Repository name has been changed, do you want to continue?')) {
|
||||
var $reponame = $('#repo_name');
|
||||
var $setting_form = $('#repo-setting-form');
|
||||
$('#change-reponame-btn').magnificPopup({
|
||||
modal: true,
|
||||
callbacks: {
|
||||
open: function () {
|
||||
if (($reponame.data('repo-name') == $reponame.val())) {
|
||||
$.magnificPopup.close();
|
||||
$setting_form.submit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}).click(function () {
|
||||
if (($reponame.data('repo-name') != $reponame.val())) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
$('#change-reponame-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$setting_form.submit();
|
||||
});
|
||||
|
||||
initHookTypeChange();
|
||||
|
||||
$('#transfer-button').click(function () {
|
||||
$('#transfer-form').show();
|
||||
// Transfer repository.
|
||||
$('#transfer-repo-btn').magnificPopup({
|
||||
modal: true
|
||||
});
|
||||
$('#delete-button').click(function () {
|
||||
$('#delete-form').show();
|
||||
$('#transfer-repo-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$('#transfer-repo-form').submit();
|
||||
});
|
||||
|
||||
// Delete repository.
|
||||
$('#delete-repo-btn').magnificPopup({
|
||||
modal: true
|
||||
});
|
||||
$('#delete-repo-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$('#delete-repo-form').submit();
|
||||
});
|
||||
|
||||
// Collaboration.
|
||||
@@ -412,19 +480,39 @@ function initRepoSetting() {
|
||||
function initOrgSetting() {
|
||||
// Options.
|
||||
// Confirmation of changing organization name.
|
||||
$('#org-setting-form').submit(function (e) {
|
||||
var $orgname = $('#orgname');
|
||||
if (($orgname.data('orgname') != $orgname.val()) && !confirm('Organization name has been changed, do you want to continue?')) {
|
||||
var $orgname = $('#orgname');
|
||||
var $setting_form = $('#org-setting-form');
|
||||
$('#change-orgname-btn').magnificPopup({
|
||||
modal: true,
|
||||
callbacks: {
|
||||
open: function () {
|
||||
if (($orgname.data('orgname') == $orgname.val())) {
|
||||
$.magnificPopup.close();
|
||||
$setting_form.submit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}).click(function () {
|
||||
if (($orgname.data('orgname') != $orgname.val())) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
$('#change-orgname-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$setting_form.submit();
|
||||
});
|
||||
|
||||
// Confirmation of delete organization.
|
||||
$('#delete-org-button').click(function (e) {
|
||||
if (!confirm('This organization is going to be deleted, do you want to continue?')) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
$('#delete-org-btn').magnificPopup({
|
||||
modal: true
|
||||
}).click(function (e) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
});
|
||||
$('#delete-org-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
$('#delete-org-form').submit();
|
||||
});
|
||||
|
||||
initHookTypeChange();
|
||||
@@ -454,11 +542,14 @@ function initInvite() {
|
||||
|
||||
function initOrgTeamCreate() {
|
||||
// Delete team.
|
||||
$('#org-team-delete').click(function (e) {
|
||||
if (!confirm('This team is going to be deleted, do you want to continue?')) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
$('#org-team-delete').magnificPopup({
|
||||
modal: true
|
||||
}).click(function (e) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
});
|
||||
$('#delete-team-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
var $form = $('#team-create-form');
|
||||
$form.attr('action', $form.data('delete-url'));
|
||||
});
|
||||
@@ -522,15 +613,20 @@ function initAdmin() {
|
||||
$('.auth-name').toggleShow();
|
||||
}
|
||||
});
|
||||
|
||||
// Delete account.
|
||||
$('#user-delete').click(function (e) {
|
||||
if (!confirm('This account is going to be deleted, do you want to continue?')) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
$('#delete-account-btn').magnificPopup({
|
||||
modal: true
|
||||
}).click(function (e) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
});
|
||||
$('#delete-account-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
var $form = $('#user-profile-form');
|
||||
$form.attr('action', $form.data('delete-url'));
|
||||
});
|
||||
|
||||
// Create authorization.
|
||||
$('#auth-type').on("change", function () {
|
||||
var v = $(this).val();
|
||||
@@ -543,13 +639,17 @@ function initAdmin() {
|
||||
$('.ldap').toggleHide();
|
||||
}
|
||||
});
|
||||
|
||||
// Delete authorization.
|
||||
$('#auth-delete').click(function (e) {
|
||||
if (!confirm('This authorization is going to be deleted, do you want to continue?')) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
var $form = $('auth-setting-form');
|
||||
$('#delete-auth-btn').magnificPopup({
|
||||
modal: true
|
||||
}).click(function (e) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
});
|
||||
$('#delete-auth-submit').click(function () {
|
||||
$.magnificPopup.close();
|
||||
var $form = $('#auth-setting-form');
|
||||
$form.attr('action', $form.data('delete-url'));
|
||||
});
|
||||
}
|
||||
@@ -591,7 +691,15 @@ function initInstall() {
|
||||
}());
|
||||
}
|
||||
|
||||
function initProfile() {
|
||||
// Avatar.
|
||||
$('#profile-avatar').tipsy({
|
||||
fade: true
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
Gogs.AppSubUrl = $('head').data('suburl') || '';
|
||||
initCore();
|
||||
if ($('#user-profile-setting').length) {
|
||||
initUserSetting();
|
||||
@@ -626,8 +734,12 @@ $(document).ready(function () {
|
||||
if ($('#install-form').length) {
|
||||
initInstall();
|
||||
}
|
||||
if ($('#user-profile-page').length) {
|
||||
initProfile();
|
||||
}
|
||||
|
||||
Tabs('#dashboard-sidebar-menu');
|
||||
$('#dashboard-sidebar-menu').tabs();
|
||||
$('#pull-issue-preview').markdown_preview(".issue-add-comment");
|
||||
|
||||
homepage();
|
||||
|
||||
@@ -644,7 +756,7 @@ function homepage() {
|
||||
$('#promo-form').submit(function (e) {
|
||||
if ($('#username').val() === "") {
|
||||
e.preventDefault();
|
||||
window.location.href = '/user/login';
|
||||
window.location.href = Gogs.AppSubUrl + '/user/login';
|
||||
return true
|
||||
}
|
||||
});
|
||||
@@ -652,9 +764,9 @@ function homepage() {
|
||||
$('#register-button').click(function (e) {
|
||||
if ($('#username').val() === "") {
|
||||
e.preventDefault();
|
||||
window.location.href = '/user/sign_up';
|
||||
window.location.href = Gogs.AppSubUrl + '/user/sign_up';
|
||||
return true
|
||||
}
|
||||
$('#promo-form').attr('action', '/user/sign_up');
|
||||
$('#promo-form').attr('action', Gogs.AppSubUrl + '/user/sign_up');
|
||||
});
|
||||
}
|
||||
|
||||
4
public/ng/js/lib/jquery.magnific-popup.min.js
vendored
Normal file
4
public/ng/js/lib/jquery.magnific-popup.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
258
public/ng/js/lib/jquery.tipsy.js
Normal file
258
public/ng/js/lib/jquery.tipsy.js
Normal file
@@ -0,0 +1,258 @@
|
||||
// tipsy, facebook style tooltips for jquery
|
||||
// version 1.0.0a
|
||||
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
|
||||
// released under the MIT license
|
||||
|
||||
(function($) {
|
||||
|
||||
function maybeCall(thing, ctx) {
|
||||
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
|
||||
};
|
||||
|
||||
function isElementInDOM(ele) {
|
||||
while (ele = ele.parentNode) {
|
||||
if (ele == document) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
function Tipsy(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = options;
|
||||
this.enabled = true;
|
||||
this.fixTitle();
|
||||
};
|
||||
|
||||
Tipsy.prototype = {
|
||||
show: function() {
|
||||
var title = this.getTitle();
|
||||
if (title && this.enabled) {
|
||||
var $tip = this.tip();
|
||||
|
||||
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
|
||||
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
|
||||
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
|
||||
|
||||
var pos = $.extend({}, this.$element.offset(), {
|
||||
width: this.$element[0].offsetWidth,
|
||||
height: this.$element[0].offsetHeight
|
||||
});
|
||||
|
||||
var actualWidth = $tip[0].offsetWidth,
|
||||
actualHeight = $tip[0].offsetHeight,
|
||||
gravity = maybeCall(this.options.gravity, this.$element[0]);
|
||||
|
||||
var tp;
|
||||
switch (gravity.charAt(0)) {
|
||||
case 'n':
|
||||
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
||||
break;
|
||||
case 's':
|
||||
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
||||
break;
|
||||
case 'e':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
|
||||
break;
|
||||
case 'w':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
|
||||
break;
|
||||
}
|
||||
|
||||
if (gravity.length == 2) {
|
||||
if (gravity.charAt(1) == 'w') {
|
||||
tp.left = pos.left + pos.width / 2 - 15;
|
||||
} else {
|
||||
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
|
||||
}
|
||||
}
|
||||
|
||||
$tip.css(tp).addClass('tipsy-' + gravity);
|
||||
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
|
||||
if (this.options.className) {
|
||||
$tip.addClass(maybeCall(this.options.className, this.$element[0]));
|
||||
}
|
||||
|
||||
if (this.options.fade) {
|
||||
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
|
||||
} else {
|
||||
$tip.css({visibility: 'visible', opacity: this.options.opacity});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.options.fade) {
|
||||
this.tip().stop().fadeOut(function() { $(this).remove(); });
|
||||
} else {
|
||||
this.tip().remove();
|
||||
}
|
||||
},
|
||||
|
||||
fixTitle: function() {
|
||||
var $e = this.$element;
|
||||
if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
|
||||
$e.attr('original-title', $e.attr('title') || '').removeAttr('title');
|
||||
}
|
||||
},
|
||||
|
||||
getTitle: function() {
|
||||
var title, $e = this.$element, o = this.options;
|
||||
this.fixTitle();
|
||||
var title, o = this.options;
|
||||
if (typeof o.title == 'string') {
|
||||
title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
|
||||
} else if (typeof o.title == 'function') {
|
||||
title = o.title.call($e[0]);
|
||||
}
|
||||
title = ('' + title).replace(/(^\s*|\s*$)/, "");
|
||||
return title || o.fallback;
|
||||
},
|
||||
|
||||
tip: function() {
|
||||
if (!this.$tip) {
|
||||
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
|
||||
this.$tip.data('tipsy-pointee', this.$element[0]);
|
||||
}
|
||||
return this.$tip;
|
||||
},
|
||||
|
||||
validate: function() {
|
||||
if (!this.$element[0].parentNode) {
|
||||
this.hide();
|
||||
this.$element = null;
|
||||
this.options = null;
|
||||
}
|
||||
},
|
||||
|
||||
enable: function() { this.enabled = true; },
|
||||
disable: function() { this.enabled = false; },
|
||||
toggleEnabled: function() { this.enabled = !this.enabled; }
|
||||
};
|
||||
|
||||
$.fn.tipsy = function(options) {
|
||||
|
||||
if (options === true) {
|
||||
return this.data('tipsy');
|
||||
} else if (typeof options == 'string') {
|
||||
var tipsy = this.data('tipsy');
|
||||
if (tipsy) tipsy[options]();
|
||||
return this;
|
||||
}
|
||||
|
||||
options = $.extend({}, $.fn.tipsy.defaults, options);
|
||||
|
||||
function get(ele) {
|
||||
var tipsy = $.data(ele, 'tipsy');
|
||||
if (!tipsy) {
|
||||
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
|
||||
$.data(ele, 'tipsy', tipsy);
|
||||
}
|
||||
return tipsy;
|
||||
}
|
||||
|
||||
function enter() {
|
||||
var tipsy = get(this);
|
||||
tipsy.hoverState = 'in';
|
||||
if (options.delayIn == 0) {
|
||||
tipsy.show();
|
||||
} else {
|
||||
tipsy.fixTitle();
|
||||
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
|
||||
}
|
||||
};
|
||||
|
||||
function leave() {
|
||||
var tipsy = get(this);
|
||||
tipsy.hoverState = 'out';
|
||||
if (options.delayOut == 0) {
|
||||
tipsy.hide();
|
||||
} else {
|
||||
setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
|
||||
}
|
||||
};
|
||||
|
||||
if (!options.live) this.each(function() { get(this); });
|
||||
|
||||
if (options.trigger != 'manual') {
|
||||
var binder = options.live ? 'live' : 'bind',
|
||||
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
|
||||
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
|
||||
this[binder](eventIn, enter)[binder](eventOut, leave);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
$.fn.tipsy.defaults = {
|
||||
className: null,
|
||||
delayIn: 0,
|
||||
delayOut: 0,
|
||||
fade: false,
|
||||
fallback: '',
|
||||
gravity: 'n',
|
||||
html: false,
|
||||
live: false,
|
||||
offset: 0,
|
||||
opacity: 0.8,
|
||||
title: 'title',
|
||||
trigger: 'hover'
|
||||
};
|
||||
|
||||
$.fn.tipsy.revalidate = function() {
|
||||
$('.tipsy').each(function() {
|
||||
var pointee = $.data(this, 'tipsy-pointee');
|
||||
if (!pointee || !isElementInDOM(pointee)) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Overwrite this method to provide options on a per-element basis.
|
||||
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
|
||||
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
|
||||
// (remember - do not modify 'options' in place!)
|
||||
$.fn.tipsy.elementOptions = function(ele, options) {
|
||||
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
|
||||
};
|
||||
|
||||
$.fn.tipsy.autoNS = function() {
|
||||
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
|
||||
};
|
||||
|
||||
$.fn.tipsy.autoWE = function() {
|
||||
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
|
||||
};
|
||||
|
||||
/**
|
||||
* yields a closure of the supplied parameters, producing a function that takes
|
||||
* no arguments and is suitable for use as an autogravity function like so:
|
||||
*
|
||||
* @param margin (int) - distance from the viewable region edge that an
|
||||
* element should be before setting its tooltip's gravity to be away
|
||||
* from that edge.
|
||||
* @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
|
||||
* if there are no viewable region edges effecting the tooltip's
|
||||
* gravity. It will try to vary from this minimally, for example,
|
||||
* if 'sw' is preferred and an element is near the right viewable
|
||||
* region edge, but not the top edge, it will set the gravity for
|
||||
* that element's tooltip to be 'se', preserving the southern
|
||||
* component.
|
||||
*/
|
||||
$.fn.tipsy.autoBounds = function(margin, prefer) {
|
||||
return function() {
|
||||
var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
|
||||
boundTop = $(document).scrollTop() + margin,
|
||||
boundLeft = $(document).scrollLeft() + margin,
|
||||
$this = $(this);
|
||||
|
||||
if ($this.offset().top < boundTop) dir.ns = 'n';
|
||||
if ($this.offset().left < boundLeft) dir.ew = 'w';
|
||||
if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
|
||||
if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
|
||||
|
||||
return dir.ns + (dir.ew ? dir.ew : '');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
10
public/ng/js/min/gogs-min.js
vendored
10
public/ng/js/min/gogs-min.js
vendored
File diff suppressed because one or more lines are too long
53
public/ng/js/utils/preview.js
Normal file
53
public/ng/js/utils/preview.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* preview plugin
|
||||
* @param selector
|
||||
* @param target_selector
|
||||
*/
|
||||
function Preview(selector, target_selector) {
|
||||
|
||||
// get input element
|
||||
function get_input($e) {
|
||||
return $e.find(".js-preview-input").eq(0);
|
||||
}
|
||||
|
||||
// get result html container element
|
||||
function get_container($t) {
|
||||
if ($t.hasClass("js-preview-container")) {
|
||||
return $t
|
||||
}
|
||||
return $t.find(".js-preview-container").eq(0);
|
||||
}
|
||||
|
||||
var $e = $(selector);
|
||||
var $t = $(target_selector);
|
||||
|
||||
var $ipt = get_input($t);
|
||||
if (!$ipt.length) {
|
||||
console.log("[preview]: no preview input");
|
||||
return
|
||||
}
|
||||
var $cnt = get_container($t);
|
||||
if (!$cnt.length) {
|
||||
console.log("[preview]: no preview container");
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// call api via ajax
|
||||
$e.on("click", function () {
|
||||
$.post("/api/v1/markdown", {
|
||||
text: $ipt.val()
|
||||
}, function (html) {
|
||||
$cnt.html(html);
|
||||
})
|
||||
});
|
||||
|
||||
console.log("[preview]: init preview @", selector, "&", target_selector);
|
||||
}
|
||||
|
||||
|
||||
$.fn.extend({
|
||||
markdown_preview: function (target) {
|
||||
Preview(this, target);
|
||||
}
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
/**
|
||||
* Created by fuxiaohei on 14-6-26.
|
||||
/*
|
||||
js tabs and tabbed content plugin
|
||||
*/
|
||||
|
||||
function Tabs(selector) {
|
||||
|
||||
function hide($nav) {
|
||||
@@ -24,7 +23,8 @@ function Tabs(selector) {
|
||||
$($current.data("tab-target")).addClass("js-tab-show");
|
||||
}
|
||||
// bind nav click
|
||||
$e.on("click", ".js-tab-nav", function () {
|
||||
$e.on("click", ".js-tab-nav", function (e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
// is showing, not change.
|
||||
if ($this.hasClass("js-tab-nav-show")) {
|
||||
@@ -36,4 +36,10 @@ function Tabs(selector) {
|
||||
});
|
||||
console.log("init tabs @", selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.fn.extend({
|
||||
tabs: function () {
|
||||
Tabs(this);
|
||||
}
|
||||
});
|
||||
@@ -7,4 +7,5 @@
|
||||
@import "gogs/settings";
|
||||
@import "gogs/issue";
|
||||
@import "gogs/organization";
|
||||
@import "gogs/admin";
|
||||
@import "gogs/admin";
|
||||
@import "gogs/profile";
|
||||
@@ -17,9 +17,6 @@ body {
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
.fa {
|
||||
font-size: 14px;
|
||||
}
|
||||
.container {
|
||||
max-width: 1170px;
|
||||
padding: 0 1.5em;
|
||||
@@ -30,6 +27,11 @@ img.avatar-16 {
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
img.avatar-20 {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
img.avatar-24 {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
@@ -55,6 +57,11 @@ img.avatar-100{
|
||||
height: 100px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.drop-down{
|
||||
.panel-header{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
#wrapper {
|
||||
padding: 0;
|
||||
margin: 0 0 -55px 0;
|
||||
@@ -95,6 +102,7 @@ clear: both;
|
||||
z-index: 100;
|
||||
font-size: 12px;
|
||||
width: 120%;
|
||||
min-width: 100px;
|
||||
li > a {
|
||||
padding: 3px 9px;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
@import "../ui/var";
|
||||
|
||||
/*
|
||||
The dashboard page style
|
||||
The dashboard page style
|
||||
*/
|
||||
|
||||
@dashboardHeaderBorderColor: #D6D6D6;
|
||||
@dashboardHeaderLinkColor: #444;
|
||||
@dashboardHeaderLinkHoverColor: #D9453D;
|
||||
@@ -14,14 +12,16 @@ The dashboard page style
|
||||
#dashboard-header {
|
||||
border-bottom: 1px solid @dashboardHeaderBorderColor;
|
||||
height: 69px;
|
||||
background-color: #FFF;
|
||||
> .menu-line {
|
||||
> li {
|
||||
padding: 12px 0;
|
||||
padding: 12px 6px;
|
||||
}
|
||||
> li.right {
|
||||
> a {
|
||||
font-size: 1.2em;
|
||||
color: @dashboardHeaderLinkColor;
|
||||
padding: .4em .8em;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
color: @dashboardHeaderLinkHoverColor;
|
||||
@@ -36,18 +36,15 @@ The dashboard page style
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dashboard context switch selection
|
||||
#dashboard-selection-menu {
|
||||
a img {
|
||||
margin: -4px 10px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
#dashboard {
|
||||
padding: 24px 0;
|
||||
}
|
||||
|
||||
// dashboard sidebar contains contributed repositories panel,
|
||||
// and my repositories panel
|
||||
#dashboard-sidebar {
|
||||
@@ -60,7 +57,6 @@ The dashboard page style
|
||||
border-bottom-right-radius: .3em;
|
||||
}
|
||||
}
|
||||
|
||||
#dashboard-sidebar-menu {
|
||||
border-top-left-radius: .3em;
|
||||
border-top-right-radius: .3em;
|
||||
@@ -70,8 +66,8 @@ The dashboard page style
|
||||
margin-right: -1px;
|
||||
border-bottom: none;
|
||||
> a {
|
||||
padding-top: .4em;
|
||||
padding-bottom: .4em;
|
||||
padding-top: .3em;
|
||||
padding-bottom: .3em;
|
||||
}
|
||||
}
|
||||
> li.first {
|
||||
@@ -85,7 +81,7 @@ The dashboard page style
|
||||
float: right;
|
||||
}
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
height: 32px;
|
||||
> li.js-tab-nav-show {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
@@ -96,7 +92,6 @@ The dashboard page style
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#dashboard-my-mirror,
|
||||
#dashboard-my-org,
|
||||
#dashboard-my-repo {
|
||||
@@ -131,8 +126,10 @@ The dashboard page style
|
||||
.repo-contrib-header {
|
||||
border-top: 1px solid #d6d6d6;
|
||||
}
|
||||
.panel-header{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
#dashboard-my-repo {
|
||||
.panel-header {
|
||||
.octicon {
|
||||
@@ -144,16 +141,14 @@ The dashboard page style
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
#dashboard-my-org,
|
||||
#dashboard-my-mirror {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// the button of new repository in my repositories panel
|
||||
#dashboard-new-repo {
|
||||
width: 50px;
|
||||
height: 35px;
|
||||
height: 33px;
|
||||
padding-top: 6px;
|
||||
margin-right: 1px;
|
||||
.octicon {
|
||||
@@ -162,10 +157,9 @@ The dashboard page style
|
||||
border-top-left-radius: .3em;
|
||||
border-top-right-radius: .3em;
|
||||
}
|
||||
|
||||
// the drop-down menu of #dashboard-new-repo
|
||||
#dashboard-new-repo-menu {
|
||||
top: 35px;
|
||||
top: 33px;
|
||||
width: 180px;
|
||||
background-color: #FFF;
|
||||
left: -132px;
|
||||
@@ -174,28 +168,26 @@ The dashboard page style
|
||||
font-size: 1.1em;
|
||||
}
|
||||
}
|
||||
|
||||
#dashboard-selection-menu {
|
||||
width: auto;
|
||||
max-width: 300px;
|
||||
> .drop-down {
|
||||
top: 56px;
|
||||
width: auto;
|
||||
max-width: 300px;
|
||||
> .drop-down {
|
||||
top: 56px;
|
||||
}
|
||||
li {
|
||||
white-space: nowrap;
|
||||
&.checked {
|
||||
.octicon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
li {
|
||||
white-space: nowrap;
|
||||
&.checked {
|
||||
.octicon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
a {
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
a {
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the drop-down menu of #dashboard-selection-menu
|
||||
#dashboard-switch-menu {
|
||||
> li {
|
||||
@@ -228,8 +220,8 @@ The dashboard page style
|
||||
border-bottom-left-radius: .3em;
|
||||
border-bottom-right-radius: .3em;
|
||||
}
|
||||
|
||||
#dashboard-news {
|
||||
padding-bottom: 60px;
|
||||
.news {
|
||||
margin-right: 2.4em;
|
||||
.mega-octicon {
|
||||
|
||||
@@ -1,54 +1,26 @@
|
||||
@import "../ui/var";
|
||||
|
||||
.repo-issue-wrapper {
|
||||
padding: 18px 0;
|
||||
}
|
||||
|
||||
// pull request main content
|
||||
.pr-main {
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 100px;
|
||||
}
|
||||
|
||||
// right bar in pull request page
|
||||
.pr-sidebar {
|
||||
border-left: 1px solid #DDD;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
#pr-sidebar-nav {
|
||||
margin-top: 6px;
|
||||
li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
li > a {
|
||||
border: 1px solid transparent;
|
||||
border-left: none;
|
||||
&:hover {
|
||||
background-color: #FFF;
|
||||
border-color: #DDD;
|
||||
}
|
||||
}
|
||||
.label {
|
||||
font-size: 12px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 1px;
|
||||
}
|
||||
li.current {
|
||||
a {
|
||||
background-color: #FFF;
|
||||
border-color: #DDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pr-title {
|
||||
.pr-num {
|
||||
font-weight: normal;
|
||||
color: #888;
|
||||
}
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.pr-meta {
|
||||
color: #888;
|
||||
padding: 4px 0 8px 0;
|
||||
.pr-author {
|
||||
margin: 0 8px;
|
||||
color: #444;
|
||||
@@ -62,7 +34,6 @@
|
||||
padding: 4px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.pr-nav {
|
||||
border-bottom: 1px solid #DDD;
|
||||
margin-top: 16px;
|
||||
@@ -89,7 +60,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.diff-bar {
|
||||
.diff-add {
|
||||
color: @btnGreenColor;
|
||||
@@ -114,26 +84,22 @@
|
||||
border-bottom-left-radius: .2em;
|
||||
}
|
||||
}
|
||||
|
||||
#pr-commit,
|
||||
#pr-file-diff,
|
||||
#issue-add-comment-preview {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#pr-conversation-list {
|
||||
padding-right: 30px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.issue-comment,
|
||||
.issue-commit,
|
||||
.issue-line,
|
||||
.issue-merge,
|
||||
.issue-add-comment {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.issue-comment {
|
||||
.author-avatar {
|
||||
img {
|
||||
@@ -165,7 +131,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.issue-commit {
|
||||
line-height: 32px;
|
||||
i, .author-avatar img {
|
||||
@@ -181,7 +146,6 @@
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.issue-merge {
|
||||
.ico {
|
||||
width: 40px;
|
||||
@@ -202,7 +166,6 @@
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.issue-merge-ok {
|
||||
.ico {
|
||||
background-color: #65AD4E;
|
||||
@@ -217,12 +180,10 @@
|
||||
color: darken(#65AD4E, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.issue-line {
|
||||
height: 4px;
|
||||
background-color: #E6E6E6;
|
||||
}
|
||||
|
||||
.issue-add-comment {
|
||||
.panel {
|
||||
margin-left: 60px;
|
||||
@@ -254,9 +215,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textarea#issue-add-content {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
@@ -26,7 +26,13 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
> pre {
|
||||
code {
|
||||
padding: 0.2em 0.5em;
|
||||
margin: 0;
|
||||
background-color: rgba(0,0,0,0.04);
|
||||
border-radius: 3px;
|
||||
}
|
||||
>pre {
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
overflow: auto;
|
||||
@@ -35,6 +41,10 @@
|
||||
margin: 5px 0;
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
code {
|
||||
padding: 0;
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
img {
|
||||
padding: 10px 0;
|
||||
|
||||
@@ -1,229 +1,232 @@
|
||||
@import "../ui/var";
|
||||
.org-header-alert .alert {
|
||||
margin-top: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.org-header {
|
||||
padding: 16px 0;
|
||||
background-color: #FFF;
|
||||
border-bottom: 1px solid #DDD;
|
||||
img {
|
||||
padding-right: 10px;
|
||||
}
|
||||
padding: 16px 0;
|
||||
background-color: #FFF;
|
||||
border-bottom: 1px solid #DDD;
|
||||
img {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
#org-home-header {
|
||||
min-height: 100px;
|
||||
min-height: 100px;
|
||||
}
|
||||
#org-header {
|
||||
height: 48px;
|
||||
.org-name {
|
||||
padding-left: 10px;
|
||||
font-size: 1.4em;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
> div {
|
||||
> .menu-line {
|
||||
> li {
|
||||
&.right {
|
||||
> a {
|
||||
font-size: 1.2em;
|
||||
color: @dashboardHeaderLinkColor;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
color: @dashboardHeaderLinkHoverColor;
|
||||
}
|
||||
.octicon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
.current {
|
||||
border-bottom: 2px solid #D26911;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
height: 48px;
|
||||
.org-name {
|
||||
padding-left: 10px;
|
||||
font-size: 1.4em;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
> div {
|
||||
> .menu-line {
|
||||
> li {
|
||||
&.right {
|
||||
> a {
|
||||
font-size: 1.2em;
|
||||
color: @dashboardHeaderLinkColor;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
color: @dashboardHeaderLinkHoverColor;
|
||||
}
|
||||
.octicon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.label{
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
.current {
|
||||
border-bottom: 2px solid #D26911;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#org-home-header-info {
|
||||
padding-top: 10px;
|
||||
h2 {
|
||||
font-size: 30px;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
li {
|
||||
float: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
padding-top: 10px;
|
||||
h2 {
|
||||
font-size: 30px;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
li {
|
||||
float: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
#org-home-repo-list {
|
||||
padding: 10px 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
#org-repo-list {
|
||||
padding: 10px 0;
|
||||
.org-repo-item {
|
||||
border-top: 1px solid #eee;
|
||||
padding: 30px 20px;
|
||||
.org-repo-status {
|
||||
list-style: none;
|
||||
color: #888;
|
||||
li {
|
||||
float: left;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.org-repo-description {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
.org-repo-updated {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
margin: 5px 0 0;
|
||||
color: #808080;
|
||||
}
|
||||
}
|
||||
padding: 10px 0;
|
||||
.org-repo-item {
|
||||
border-top: 1px solid #eee;
|
||||
padding: 30px 20px;
|
||||
.org-repo-status {
|
||||
list-style: none;
|
||||
color: #888;
|
||||
li {
|
||||
float: left;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.org-repo-description {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
.org-repo-updated {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
margin: 5px 0 0;
|
||||
color: #808080;
|
||||
}
|
||||
}
|
||||
}
|
||||
.org-sidebar {
|
||||
margin: -80px 0 0 20px;
|
||||
.panel-footer {
|
||||
padding: .8em 1.2em;
|
||||
}
|
||||
.member-avatar-group {
|
||||
padding: 15px;
|
||||
img {
|
||||
width: 59px;
|
||||
height: 59px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
margin: -80px 0 0 20px;
|
||||
.panel-footer {
|
||||
padding: .8em 1.2em;
|
||||
}
|
||||
.member-avatar-group {
|
||||
padding: 15px;
|
||||
img {
|
||||
width: 59px;
|
||||
height: 59px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
#org-home-team-list {
|
||||
padding: 0 15px;
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-top: 10px;
|
||||
li {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
padding: 0 15px;
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-top: 10px;
|
||||
li {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.team-name {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.team-meta {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
color: #777;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
color: #777;
|
||||
}
|
||||
.org-toolbar {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
#org-member-list {
|
||||
.org-member-item {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 15px 20px;
|
||||
.member-name {
|
||||
padding-left: 15px;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
li {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.org-member-item {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 15px 20px;
|
||||
.member-name {
|
||||
padding-left: 15px;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
li {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.invite-box {
|
||||
padding: 50px 0;
|
||||
min-height: 130px;
|
||||
margin: 0 auto;
|
||||
width: 50%;
|
||||
input {
|
||||
width: 300px;
|
||||
}
|
||||
padding: 50px 0;
|
||||
min-height: 130px;
|
||||
margin: 0 auto;
|
||||
width: 50%;
|
||||
input {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
#org-member-list-block {
|
||||
padding-top: 2px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.org-team-list {
|
||||
.org-team-list-item {
|
||||
float: left;
|
||||
padding: 15px;
|
||||
width: 555px;
|
||||
.member-avatar-group {
|
||||
padding: 5px 15px;
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.org-team-list-item {
|
||||
float: left;
|
||||
padding: 15px;
|
||||
width: 555px;
|
||||
.member-avatar-group {
|
||||
padding: 5px 15px;
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#team-create-form {
|
||||
.note {
|
||||
margin-left: 153px;
|
||||
}
|
||||
.note {
|
||||
margin-left: 153px;
|
||||
}
|
||||
}
|
||||
#org-team-card {
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.team-stats {
|
||||
padding: 0 20px 10px 20px;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
.panel-footer {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.team-stats {
|
||||
padding: 0 20px 10px 20px;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
.panel-footer {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
}
|
||||
#team-repositories-list,
|
||||
#team-members-list {
|
||||
.panel-body .search {
|
||||
padding: 4px 0 10px 10px;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
li {
|
||||
&.collab {
|
||||
padding-top: 10px !important;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
.panel-body .search {
|
||||
padding: 4px 0 10px 10px;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
li {
|
||||
&.collab {
|
||||
padding-top: 10px !important;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
#team-repositories-list {
|
||||
li {
|
||||
a .octicon {
|
||||
color: #888;
|
||||
}
|
||||
.member {
|
||||
color: @linkColor;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
li {
|
||||
a .octicon {
|
||||
color: #888;
|
||||
}
|
||||
.member {
|
||||
color: @linkColor;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
public/ng/less/gogs/profile.less
Normal file
57
public/ng/less/gogs/profile.less
Normal file
@@ -0,0 +1,57 @@
|
||||
.profile-avatar {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
#profile-name {
|
||||
padding: 10px 0;
|
||||
}
|
||||
#profile-fullname {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
#profile-username {
|
||||
font-size: 1.6em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.profile-info {
|
||||
padding: 0 50px;
|
||||
font-size: 14px;
|
||||
ul {
|
||||
padding-bottom: 10px;
|
||||
.list-group-item {
|
||||
background-color: transparent;
|
||||
padding-top: 5px;
|
||||
color: #666;
|
||||
}
|
||||
.profile-rel {
|
||||
width: 31%;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
strong {
|
||||
display: block;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
p {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#profile-header {
|
||||
li {
|
||||
a {
|
||||
font-size: 1.2em;
|
||||
color: #444444;
|
||||
padding: .4em .8em;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
color: @dashboardHeaderLinkHoverColor;
|
||||
}
|
||||
}
|
||||
.current {
|
||||
border-bottom: 2px solid #D26911;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,460 +6,525 @@
|
||||
/* repository main */
|
||||
|
||||
#repo-wrapper {
|
||||
padding-bottom: 100px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
#repo-header {
|
||||
height: 69px;
|
||||
border-bottom: 1px solid@repoHeaderBorderColor;
|
||||
|
||||
background-color: @repoHeaderBgColor;
|
||||
|
||||
height: 69px;
|
||||
border-bottom: 1px solid@repoHeaderBorderColor;
|
||||
background-color: @repoHeaderBgColor;
|
||||
}
|
||||
#repo-header-name {
|
||||
line-height: 66px;
|
||||
color: @repoHeaderNameColor;
|
||||
font-size: 1.6em;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0;
|
||||
i {
|
||||
margin-right: 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.divider {
|
||||
margin: 0 4px;
|
||||
}
|
||||
line-height: 66px;
|
||||
color: @repoHeaderNameColor;
|
||||
font-size: 1.6em;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0;
|
||||
i {
|
||||
margin-right: 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.divider {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
#repo-header-meta {
|
||||
line-height: 66px;
|
||||
li {
|
||||
> a {
|
||||
padding: 0;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
a {
|
||||
&>.btn {
|
||||
line-height: 16px;
|
||||
font-size: 1.05em;
|
||||
margin-left: 16px;
|
||||
i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.num {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
line-height: 66px;
|
||||
li {
|
||||
> a {
|
||||
padding: 0;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
a {
|
||||
& > .btn {
|
||||
line-height: 16px;
|
||||
margin-left: 16px;
|
||||
font-size: 13px;
|
||||
i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.num {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#repo-header-download-btn {
|
||||
> .btn > i {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
&:hover {
|
||||
&:after, .btn {
|
||||
background-color: @btnHoverBlackColor;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
&:after {
|
||||
background-color: @btnBlackColor;
|
||||
padding: 9px 16px 8px 0;
|
||||
margin-left: -8px !important;
|
||||
color: #FFF;
|
||||
border-top: 1px solid@btnBlackColor;
|
||||
border-bottom: 1px solid@btnBlackColor;
|
||||
border-top-right-radius: .25em;
|
||||
border-bottom-right-radius: .25em;
|
||||
}
|
||||
> .btn > i {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
&:hover {
|
||||
&:after, .btn {
|
||||
background-color: @btnHoverBlackColor;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
&:after {
|
||||
background-color: @btnBlackColor;
|
||||
padding: 9px 16px 8px 0;
|
||||
margin-left: -8px !important;
|
||||
color: #FFF;
|
||||
border-top: 1px solid@btnBlackColor;
|
||||
border-bottom: 1px solid@btnBlackColor;
|
||||
border-top-right-radius: .25em;
|
||||
border-bottom-right-radius: .25em;
|
||||
}
|
||||
}
|
||||
#repo-header-download-drop {
|
||||
line-height: 24px;
|
||||
width: 440px;
|
||||
top: 50px;
|
||||
left: -370px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
z-index: 1;
|
||||
.btn > i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
font-size: 11px;
|
||||
}
|
||||
line-height: 24px;
|
||||
width: 440px;
|
||||
top: 50px;
|
||||
left: -370px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
z-index: 1;
|
||||
.btn > i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
#repo-content {
|
||||
padding: 18px 0;
|
||||
padding: 18px 0;
|
||||
}
|
||||
.repo-wide-wrapper {
|
||||
padding: 18px 0;
|
||||
position: relative;
|
||||
}
|
||||
#repo-clone-url {
|
||||
border-right: none;
|
||||
width: 200px;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
width: 190px;
|
||||
border-left: none;
|
||||
}
|
||||
#repo-clone-help {
|
||||
clear: both;
|
||||
line-height: 48px;
|
||||
clear: both;
|
||||
line-height: 48px;
|
||||
}
|
||||
#repo-clone-zip {
|
||||
line-height: 48px;
|
||||
a {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
overflow: visible;
|
||||
padding: .6em 1.2em;
|
||||
}
|
||||
.btn {
|
||||
margin: 0 6px;
|
||||
}
|
||||
line-height: 48px;
|
||||
a {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
overflow: visible;
|
||||
padding: .6em 1.2em;
|
||||
}
|
||||
.btn {
|
||||
margin: 0 6px;
|
||||
}
|
||||
}
|
||||
#repo-desc {
|
||||
font-size: 1.2em;
|
||||
font-size: 1.2em;
|
||||
.no-description{
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
#repo-sidebar-nav {
|
||||
.label {
|
||||
font-size: 12px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 2px;
|
||||
}
|
||||
i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.label {
|
||||
font-size: 12px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 2px;
|
||||
}
|
||||
i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
#repo-sidebar-mini {
|
||||
margin-top: 6px;
|
||||
width: 60px;
|
||||
li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
li > a {
|
||||
position: relative;
|
||||
padding-left: 12px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
> i.octicon {
|
||||
font-size: 21px;
|
||||
}
|
||||
}
|
||||
.num {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
top: 0;
|
||||
left: 36px;
|
||||
padding: 0 2px;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
text-align: center;
|
||||
line-height: 16px;
|
||||
border-radius: 4px;
|
||||
opacity: 0.7;
|
||||
-webkit-transform: scale(0.9);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
#repo-file-nav {
|
||||
padding: .6em 0 1em 0;
|
||||
> li > a {
|
||||
padding-left: 0;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
li.repo-jump > a {
|
||||
padding-right: 0;
|
||||
.btn {
|
||||
margin-left: -1px;
|
||||
}
|
||||
}
|
||||
padding: .6em 0 1em 0;
|
||||
> li > a {
|
||||
padding-left: 0;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
li.repo-jump > a {
|
||||
padding-right: 0;
|
||||
.btn {
|
||||
margin-left: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
#repo-branch-switch {
|
||||
> a {
|
||||
.btn {
|
||||
padding-right: 30px;
|
||||
}
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 30px;
|
||||
margin-left: 0;
|
||||
color: @baseFontColor;
|
||||
> a {
|
||||
.btn {
|
||||
padding-right: 30px;
|
||||
}
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 30px;
|
||||
margin-left: 0;
|
||||
color: @baseFontColor;
|
||||
|
||||
}
|
||||
}
|
||||
> .drop-down {
|
||||
top: 40px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .drop-down {
|
||||
top: 40px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
#repo-branch-filter-ipt {
|
||||
width: 100%;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#repo-branch-tag {
|
||||
.tab-nav {
|
||||
border-bottom: 1px solid #EAEAEA;
|
||||
a {
|
||||
padding: .3em .8em;
|
||||
}
|
||||
.js-tab-nav-show {
|
||||
background-color: #EEE;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.tab-nav {
|
||||
border-bottom: 1px solid #EAEAEA;
|
||||
a {
|
||||
padding: .3em .8em;
|
||||
}
|
||||
.js-tab-nav-show {
|
||||
background-color: #EEE;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.switching-list {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
#repo-branch-list,
|
||||
#repo-tag-list {
|
||||
li {
|
||||
i {
|
||||
margin-right: 12px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
li.checked {
|
||||
i {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#repo-tag-list {
|
||||
display: none;
|
||||
li {
|
||||
i {
|
||||
margin-right: 12px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
li.checked {
|
||||
i {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#repo-bread {
|
||||
.bread {
|
||||
padding-right: 0;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.bread {
|
||||
padding-right: 0;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
#repo-main {
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#repo-files-table {
|
||||
margin-bottom: 20px;
|
||||
th, td {
|
||||
text-align: left;
|
||||
line-height: 32px;
|
||||
}
|
||||
td.icon {
|
||||
width: 16px;
|
||||
padding-right: .1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
td.name {
|
||||
max-width: 120px;
|
||||
.text-truncate {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
td.age {
|
||||
max-width: 120px;
|
||||
text-align: right;
|
||||
}
|
||||
td.msg {
|
||||
max-width: 440px;
|
||||
.text-truncate {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
td.age,
|
||||
td.size,
|
||||
td.msg a {
|
||||
color: #888;
|
||||
}
|
||||
td.msg a:hover {
|
||||
color: #428BCA;
|
||||
text-decoration: underline;
|
||||
}
|
||||
tbody {
|
||||
background-color: #FFF;
|
||||
tr:hover {
|
||||
background-color: #ffffEE;
|
||||
}
|
||||
}
|
||||
thead {
|
||||
background-color: #F0F0F0;
|
||||
.author {
|
||||
a {
|
||||
margin: 0 .4em;
|
||||
}
|
||||
}
|
||||
.last-commit {
|
||||
strong {
|
||||
color: #444;
|
||||
}
|
||||
.text-truncate {
|
||||
margin-left: .4em;
|
||||
}
|
||||
}
|
||||
.last-commit .text-truncate,
|
||||
.age {
|
||||
font-weight: normal;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
margin-bottom: 20px;
|
||||
th, td {
|
||||
text-align: left;
|
||||
line-height: 32px;
|
||||
}
|
||||
td.icon {
|
||||
width: 16px;
|
||||
padding-right: .1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
td.name {
|
||||
max-width: 120px;
|
||||
.text-truncate {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
td.age {
|
||||
max-width: 120px;
|
||||
text-align: right;
|
||||
}
|
||||
td.msg {
|
||||
max-width: 440px;
|
||||
.text-truncate {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
td.age,
|
||||
td.size,
|
||||
td.msg a {
|
||||
color: #888;
|
||||
}
|
||||
td.msg a:hover {
|
||||
color: #428BCA;
|
||||
text-decoration: underline;
|
||||
}
|
||||
tbody {
|
||||
background-color: #FFF;
|
||||
tr:hover {
|
||||
background-color: #ffffEE;
|
||||
}
|
||||
}
|
||||
thead {
|
||||
background-color: #F0F0F0;
|
||||
.author {
|
||||
a {
|
||||
margin: 0 .4em;
|
||||
}
|
||||
}
|
||||
.last-commit {
|
||||
strong {
|
||||
color: #444;
|
||||
}
|
||||
.text-truncate {
|
||||
margin-left: .4em;
|
||||
}
|
||||
}
|
||||
.last-commit .text-truncate,
|
||||
.age {
|
||||
font-weight: normal;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
#repo-readme {
|
||||
margin-bottom: 80px;
|
||||
#repo-readme,
|
||||
#repo-read-file {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
#repo-bare-start {
|
||||
margin-bottom: 100px;
|
||||
.panel-content {
|
||||
background-color: #FFF;
|
||||
}
|
||||
pre {
|
||||
margin: 0 40px;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #ddd;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
margin-bottom: 100px;
|
||||
.panel-content {
|
||||
background-color: #FFF;
|
||||
}
|
||||
pre {
|
||||
margin: 0 40px;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #ddd;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
}
|
||||
.repo-bare {
|
||||
#repo-bare-start {
|
||||
h2 {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
#repo-header-meta {
|
||||
display: none;
|
||||
}
|
||||
#repo-clone-ssh {
|
||||
margin-left: 200px;
|
||||
}
|
||||
#repo-clone-copy {
|
||||
margin-right: 200px;
|
||||
}
|
||||
#repo-clone-help {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
}
|
||||
#repo-clone-url {
|
||||
width: 520px;
|
||||
}
|
||||
#repo-bare-start {
|
||||
h2 {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
#repo-header-meta {
|
||||
display: none;
|
||||
}
|
||||
#repo-clone-ssh {
|
||||
margin-left: 200px;
|
||||
}
|
||||
#repo-clone-copy {
|
||||
margin-right: 200px;
|
||||
}
|
||||
#repo-clone-help {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
}
|
||||
#repo-clone-url {
|
||||
width: 520px;
|
||||
}
|
||||
}
|
||||
/* repository create */
|
||||
|
||||
#team-create-form,
|
||||
#repo-migrate-form,
|
||||
#repo-create-form {
|
||||
width: 800px;
|
||||
margin: 60px auto auto auto;
|
||||
background: white;
|
||||
h2 {
|
||||
margin: .5em 1em;
|
||||
}
|
||||
.field {
|
||||
margin: 1.2em 0 2em 0;
|
||||
}
|
||||
.ipt {
|
||||
width: 540px;
|
||||
}
|
||||
textarea {
|
||||
height: 120px;
|
||||
}
|
||||
.avatar {
|
||||
vertical-align: middle;
|
||||
margin-right: .6em;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 6px #CCC;
|
||||
}
|
||||
width: 800px;
|
||||
margin: 60px auto auto auto;
|
||||
background: white;
|
||||
h2 {
|
||||
margin: .5em 1em;
|
||||
}
|
||||
.field {
|
||||
margin: 1.2em 0 2em 0;
|
||||
}
|
||||
.ipt {
|
||||
width: 540px;
|
||||
}
|
||||
textarea {
|
||||
height: 120px;
|
||||
}
|
||||
.avatar {
|
||||
vertical-align: middle;
|
||||
margin-right: .6em;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 6px #CCC;
|
||||
}
|
||||
}
|
||||
#repo-create-cancel {
|
||||
margin-left: 4em;
|
||||
margin-left: 4em;
|
||||
}
|
||||
#repo-create-owner-list {
|
||||
top: 30px;
|
||||
left: 0;
|
||||
width: auto;
|
||||
max-width: 300px;
|
||||
.octicon {
|
||||
margin-right: 12px;
|
||||
opacity: 0;
|
||||
}
|
||||
.avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
li {
|
||||
white-space: nowrap;
|
||||
&.checked {
|
||||
.octicon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
a {
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
top: 30px;
|
||||
left: 0;
|
||||
width: auto;
|
||||
max-width: 300px;
|
||||
.octicon {
|
||||
margin-right: 12px;
|
||||
opacity: 0;
|
||||
}
|
||||
.avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
li {
|
||||
white-space: nowrap;
|
||||
&.checked {
|
||||
.octicon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
a {
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
.file-name {
|
||||
margin-left: 1em;
|
||||
margin-left: 1em;
|
||||
}
|
||||
.file-size {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
margin-left: 1em;
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
margin-left: 1em;
|
||||
}
|
||||
.code-view {
|
||||
overflow: auto;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
background: white;
|
||||
.view-raw {
|
||||
min-height: 40px;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
.btn {
|
||||
font-size: 1.05em;
|
||||
line-height: 16px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.lines-num {
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
background: #f5f5f5;
|
||||
width: 1%;
|
||||
span {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 18px;
|
||||
padding: 0 8px 0 10px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.lines-code > pre {
|
||||
border: none;
|
||||
border-left: 1px solid #ddd;
|
||||
> ol.linenums > li {
|
||||
padding: 0 10px;
|
||||
&.active {
|
||||
background: #ffffdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
overflow: auto;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
background: white;
|
||||
.view-raw {
|
||||
min-height: 40px;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
.btn {
|
||||
font-size: 1.05em;
|
||||
line-height: 16px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.lines-num {
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
background: #f5f5f5;
|
||||
width: 1%;
|
||||
span {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 18px;
|
||||
padding: 0 8px 0 10px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.lines-code > pre {
|
||||
border: none;
|
||||
border-left: 1px solid #ddd;
|
||||
> ol.linenums > li {
|
||||
padding: 0 10px;
|
||||
&.active {
|
||||
background: #ffffdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.repo-setting-zone {
|
||||
padding: 30px;
|
||||
padding: 30px;
|
||||
}
|
||||
#team-repositories-list,
|
||||
#team-members-list,
|
||||
#repo-collab-list {
|
||||
list-style: none;
|
||||
padding: 10px 0 5px 0;
|
||||
li.collab {
|
||||
clear: both;
|
||||
height: 50px;
|
||||
padding: 0 15px 0 15px;
|
||||
}
|
||||
a.member {
|
||||
color: #444;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
&:hover {
|
||||
color: #4183C4;
|
||||
}
|
||||
}
|
||||
.avatar {
|
||||
margin-right: 1em;
|
||||
width: 40px;
|
||||
}
|
||||
.remove-collab {
|
||||
color: #DD4B39;
|
||||
}
|
||||
list-style: none;
|
||||
padding: 10px 0 5px 0;
|
||||
li.collab {
|
||||
clear: both;
|
||||
height: 50px;
|
||||
padding: 0 15px 0 15px;
|
||||
}
|
||||
a.member {
|
||||
color: #444;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
&:hover {
|
||||
color: #4183C4;
|
||||
}
|
||||
}
|
||||
.avatar {
|
||||
margin-right: 1em;
|
||||
width: 40px;
|
||||
}
|
||||
.remove-collab {
|
||||
color: #DD4B39;
|
||||
}
|
||||
}
|
||||
.repo-user-list-block {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
.setting-list {
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
}
|
||||
#commits-list {
|
||||
padding-top: 20px;
|
||||
h4{
|
||||
line-height: 30px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.commit-list {
|
||||
th {
|
||||
background-color: #FFF;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
.date {
|
||||
width: 120px;
|
||||
}
|
||||
.author {
|
||||
padding-left: 20px;
|
||||
min-width: 180px;
|
||||
img {
|
||||
margin-top: -4px;
|
||||
}
|
||||
}
|
||||
.sha a {
|
||||
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,15 @@
|
||||
border: 1px solid darken(@alertOrangeColor,10%);
|
||||
background-color: lighten(@alertOrangeColor,45%);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.white-popup-block {
|
||||
background: #FFF;
|
||||
padding: 20px 30px;
|
||||
text-align: left;
|
||||
max-width: 650px;
|
||||
margin: 40px auto;
|
||||
position: relative;
|
||||
p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,25 +116,24 @@
|
||||
}
|
||||
|
||||
// input form elements
|
||||
|
||||
.ipt {
|
||||
&:focus {
|
||||
border-color: @iptFocusBorderColor;
|
||||
}
|
||||
&:focus {
|
||||
border-color: @iptFocusBorderColor;
|
||||
}
|
||||
}
|
||||
|
||||
.ipt-radius {
|
||||
border-radius: .25em;
|
||||
border-radius: .25em;
|
||||
}
|
||||
|
||||
.ipt-small {
|
||||
font-size: .8*@baseFontSize;
|
||||
font-size: .8*@baseFontSize;
|
||||
}
|
||||
|
||||
.ipt-large {
|
||||
font-size: 1.2*@baseFontSize;
|
||||
font-size: 1.2*@baseFontSize;
|
||||
}
|
||||
.ipt-textarea {
|
||||
height: auto !important;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.ipt-disabled,
|
||||
input[disabled] {
|
||||
background-color: @iptDisabledColor !important;
|
||||
@@ -144,14 +143,12 @@ input[disabled] {
|
||||
color: #888;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.ipt-readonly,
|
||||
input[readonly] {
|
||||
&:focus {
|
||||
background-color: @iptDisabledColor !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ipt-error {
|
||||
border-color: @iptErrorBorderColor !important;
|
||||
background-color: @iptErrorFocusColor !important;
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
.label-gray {
|
||||
background-color: @labelGrayColor;
|
||||
}
|
||||
|
||||
.label-green {
|
||||
background-color: @labelGreenColor;
|
||||
background-color: @labelGreenColor;
|
||||
&:hover {
|
||||
background-color: @btnHoverGreenColor;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.label-orange {
|
||||
background-color: @labelOrangeColor;
|
||||
}
|
||||
|
||||
@@ -193,22 +193,19 @@ code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.list-no-style {
|
||||
list-style: none;
|
||||
}
|
||||
@@ -342,15 +339,6 @@ hr {
|
||||
border-bottom: 1px solid @hrColor;
|
||||
margin-bottom: .75em;
|
||||
}
|
||||
|
||||
// code element
|
||||
|
||||
p {
|
||||
code {
|
||||
color: @inlineCodeColor;
|
||||
}
|
||||
}
|
||||
|
||||
// radius element
|
||||
|
||||
.radius {
|
||||
|
||||
@@ -143,7 +143,7 @@ func Dashboard(ctx *middleware.Context) {
|
||||
} else {
|
||||
ctx.Flash.Success(success)
|
||||
}
|
||||
ctx.Redirect("/admin")
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -99,7 +100,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
|
||||
}
|
||||
|
||||
log.Trace("Authentication created by admin(%s): %s", ctx.User.Name, form.AuthName)
|
||||
ctx.Redirect("/admin/auths")
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths")
|
||||
}
|
||||
|
||||
func EditAuthSource(ctx *middleware.Context) {
|
||||
@@ -180,7 +181,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
|
||||
|
||||
log.Trace("Authentication changed by admin(%s): %s", ctx.User.Name, form.AuthName)
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.update_success"))
|
||||
ctx.Redirect("/admin/auths/" + ctx.Params(":authid"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"))
|
||||
}
|
||||
|
||||
func DeleteAuthSource(ctx *middleware.Context) {
|
||||
@@ -200,12 +201,12 @@ func DeleteAuthSource(ctx *middleware.Context) {
|
||||
switch err {
|
||||
case models.ErrAuthenticationUserUsed:
|
||||
ctx.Flash.Error("form.still_own_user")
|
||||
ctx.Redirect("/admin/auths/" + ctx.Params(":authid"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"))
|
||||
default:
|
||||
ctx.Handle(500, "DelLoginSource", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Authentication deleted by admin(%s): %s", ctx.User.Name, a.Name)
|
||||
ctx.Redirect("/admin/auths")
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths")
|
||||
}
|
||||
|
||||
46
routers/admin/notice.go
Normal file
46
routers/admin/notice.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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 admin
|
||||
|
||||
import (
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
NOTICES base.TplName = "admin/notice"
|
||||
)
|
||||
|
||||
func Notices(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.notices")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminNotices"] = true
|
||||
|
||||
pageNum := 50
|
||||
p := pagination(ctx, models.CountNotices(), pageNum)
|
||||
|
||||
notices, err := models.GetNotices(pageNum, (p-1)*pageNum)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetNotices", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Notices"] = notices
|
||||
ctx.HTML(200, NOTICES)
|
||||
}
|
||||
|
||||
func DeleteNotice(ctx *middleware.Context) {
|
||||
id := com.StrTo(ctx.Params(":id")).MustInt64()
|
||||
if err := models.DeleteNotice(id); err != nil {
|
||||
ctx.Handle(500, "DeleteNotice", err)
|
||||
return
|
||||
}
|
||||
log.Trace("System notice deleted by admin(%s): %d", ctx.User.Name, id)
|
||||
ctx.Flash.Success(ctx.Tr("admin.notices.delete_success"))
|
||||
ctx.Redirect("/admin/notices")
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func Organizations(ctx *middleware.Context) {
|
||||
var err error
|
||||
ctx.Data["Orgs"], err = models.GetOrganizations(pageNum, (p-1)*pageNum)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetUsers", err)
|
||||
ctx.Handle(500, "GetOrganizations", err)
|
||||
return
|
||||
}
|
||||
ctx.HTML(200, ORGS)
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,14 +24,14 @@ const (
|
||||
)
|
||||
|
||||
func pagination(ctx *middleware.Context, count int64, pageNum int) int {
|
||||
p := com.StrTo(ctx.Query("p")).MustInt()
|
||||
p := ctx.QueryInt("p")
|
||||
if p < 1 {
|
||||
p = 1
|
||||
}
|
||||
curCount := int64((p-1)*pageNum + pageNum)
|
||||
if curCount > count {
|
||||
if curCount >= count {
|
||||
p = int(count) / pageNum
|
||||
} else if count > curCount {
|
||||
} else {
|
||||
ctx.Data["NextPageNum"] = p + 1
|
||||
}
|
||||
if p > 1 {
|
||||
@@ -47,12 +48,12 @@ func Users(ctx *middleware.Context) {
|
||||
pageNum := 50
|
||||
p := pagination(ctx, models.CountUsers(), pageNum)
|
||||
|
||||
var err error
|
||||
ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum)
|
||||
users, err := models.GetUsers(pageNum, (p-1)*pageNum)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetUsers", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Users"] = users
|
||||
ctx.HTML(200, USERS)
|
||||
}
|
||||
|
||||
@@ -120,7 +121,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
|
||||
return
|
||||
}
|
||||
log.Trace("Account created by admin(%s): %s", ctx.User.Name, u.Name)
|
||||
ctx.Redirect("/admin/users")
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/users")
|
||||
}
|
||||
|
||||
func EditUser(ctx *middleware.Context) {
|
||||
@@ -197,7 +198,7 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
|
||||
|
||||
ctx.Data["User"] = u
|
||||
ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
|
||||
ctx.Redirect("/admin/users/" + ctx.Params(":userid"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
|
||||
}
|
||||
|
||||
func DeleteUser(ctx *middleware.Context) {
|
||||
@@ -217,12 +218,12 @@ func DeleteUser(ctx *middleware.Context) {
|
||||
switch err {
|
||||
case models.ErrUserOwnRepos:
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
|
||||
ctx.Redirect("/admin/users/" + ctx.Params(":userid"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
|
||||
default:
|
||||
ctx.Handle(500, "DeleteUser", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name)
|
||||
ctx.Redirect("/admin/users")
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/users")
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func Home(ctx *middleware.Context) {
|
||||
// Check auto-login.
|
||||
uname := ctx.GetCookie(setting.CookieUserName)
|
||||
if len(uname) != 0 {
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -253,5 +253,5 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
|
||||
|
||||
log.Info("First-time run install finished!")
|
||||
ctx.Flash.Success(ctx.Tr("install.install_success"))
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -86,7 +87,7 @@ func MembersAction(ctx *middleware.Context) {
|
||||
if ctx.Params(":action") != "leave" {
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/members")
|
||||
} else {
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -82,5 +83,5 @@ func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) {
|
||||
}
|
||||
log.Trace("Organization created: %s", org.Name)
|
||||
|
||||
ctx.Redirect("/org/" + form.OrgName + "/dashboard")
|
||||
ctx.Redirect(setting.AppSubUrl + "/org/" + form.OrgName + "/dashboard")
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -48,7 +49,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
|
||||
} else if err = models.ChangeUserName(org, form.OrgUserName); err != nil {
|
||||
if err == models.ErrUserNameIllegal {
|
||||
ctx.Flash.Error(ctx.Tr("form.illegal_username"))
|
||||
ctx.Redirect("/org/" + org.LowerName + "/settings")
|
||||
ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings")
|
||||
return
|
||||
} else {
|
||||
ctx.Handle(500, "ChangeUserName", err)
|
||||
@@ -72,7 +73,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
|
||||
}
|
||||
log.Trace("Organization setting updated: %s", org.Name)
|
||||
ctx.Flash.Success(ctx.Tr("org.settings.update_setting_success"))
|
||||
ctx.Redirect("/org/" + org.Name + "/settings")
|
||||
ctx.Redirect(setting.AppSubUrl + "/org/" + org.Name + "/settings")
|
||||
}
|
||||
|
||||
func SettingsDelete(ctx *middleware.Context) {
|
||||
@@ -86,13 +87,13 @@ func SettingsDelete(ctx *middleware.Context) {
|
||||
switch err {
|
||||
case models.ErrUserOwnRepos:
|
||||
ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
|
||||
ctx.Redirect("/org/" + org.LowerName + "/settings/delete")
|
||||
ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings/delete")
|
||||
default:
|
||||
ctx.Handle(500, "DeleteOrganization", err)
|
||||
}
|
||||
} else {
|
||||
log.Trace("Organization deleted: %s", ctx.User.Name)
|
||||
ctx.Redirect("/")
|
||||
log.Trace("Organization deleted: %s", org.Name)
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -124,6 +124,11 @@ func TeamsRepoAction(ctx *middleware.Context) {
|
||||
var repo *models.Repository
|
||||
repo, err = models.GetRepositoryByName(ctx.Org.Organization.Id, repoName)
|
||||
if err != nil {
|
||||
if err == models.ErrRepoNotExist {
|
||||
ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
|
||||
return
|
||||
}
|
||||
ctx.Handle(500, "GetRepositoryByName", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,12 +56,14 @@ func Commits(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
// Both `git log branchName` and `git log commitId` work.
|
||||
ctx.Data["Commits"], err = ctx.Repo.Commit.CommitsByRange(page)
|
||||
commits, err := ctx.Repo.Commit.CommitsByRange(page)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "CommitsByRange", err)
|
||||
return
|
||||
}
|
||||
commits = models.ValidateCommitsWithEmails(commits)
|
||||
|
||||
ctx.Data["Commits"] = commits
|
||||
ctx.Data["Username"] = userName
|
||||
ctx.Data["Reponame"] = repoName
|
||||
ctx.Data["CommitCount"] = commitsCount
|
||||
@@ -93,9 +96,10 @@ func SearchCommits(ctx *middleware.Context) {
|
||||
|
||||
commits, err := ctx.Repo.Commit.SearchCommits(keyword)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err)
|
||||
ctx.Handle(500, "SearchCommits", err)
|
||||
return
|
||||
}
|
||||
commits = models.ValidateCommitsWithEmails(commits)
|
||||
|
||||
ctx.Data["Keyword"] = keyword
|
||||
ctx.Data["Username"] = userName
|
||||
@@ -114,7 +118,8 @@ func Diff(ctx *middleware.Context) {
|
||||
|
||||
commit := ctx.Repo.Commit
|
||||
|
||||
diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName), commitId)
|
||||
diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName),
|
||||
commitId, setting.MaxGitDiffLines)
|
||||
if err != nil {
|
||||
ctx.Handle(404, "GetDiffCommit", err)
|
||||
return
|
||||
@@ -157,8 +162,8 @@ func Diff(ctx *middleware.Context) {
|
||||
ctx.Data["Diff"] = diff
|
||||
ctx.Data["Parents"] = parents
|
||||
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
|
||||
ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", commitId)
|
||||
ctx.Data["RawPath"] = "/" + path.Join(userName, repoName, "raw", commitId)
|
||||
ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", commitId)
|
||||
ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", commitId)
|
||||
ctx.HTML(200, DIFF)
|
||||
}
|
||||
|
||||
@@ -176,7 +181,8 @@ func CompareDiff(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitId, afterCommitId)
|
||||
diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitId,
|
||||
afterCommitId, setting.MaxGitDiffLines)
|
||||
if err != nil {
|
||||
ctx.Handle(404, "GetDiffRange", err)
|
||||
return
|
||||
|
||||
@@ -54,8 +54,8 @@ func Issues(ctx *middleware.Context) {
|
||||
isShowClosed := ctx.Query("state") == "closed"
|
||||
|
||||
if viewType != "all" && !ctx.IsSigned {
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
|
||||
}
|
||||
log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.Id)
|
||||
|
||||
send(200, fmt.Sprintf("/%s/%s/issues/%d", ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
|
||||
send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
|
||||
}
|
||||
|
||||
func checkLabels(labels, allLabels []*models.Label) {
|
||||
@@ -1119,3 +1119,9 @@ func IssueGetAttachment(ctx *middleware.Context) {
|
||||
// We must put the name in " manually.
|
||||
ctx.ServeFile(attachment.Path, "\""+attachment.Name+"\"")
|
||||
}
|
||||
|
||||
// testing route handler for new issue ui page
|
||||
// todo : move to Issue() function
|
||||
func Issues2(ctx *middleware.Context){
|
||||
ctx.HTML(200,"repo/issue2/list")
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -95,7 +96,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
|
||||
form.Gitignore, form.License, form.Private, false, form.InitReadme)
|
||||
if err == nil {
|
||||
log.Trace("Repository created: %s/%s", ctxUser.Name, form.RepoName)
|
||||
ctx.Redirect("/" + ctxUser.Name + "/" + form.RepoName)
|
||||
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
|
||||
return
|
||||
} else if err == models.ErrRepoAlreadyExist {
|
||||
ctx.Data["Err_RepoName"] = true
|
||||
@@ -179,7 +180,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
|
||||
form.Mirror, url)
|
||||
if err == nil {
|
||||
log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
|
||||
ctx.Redirect("/" + ctxUser.Name + "/" + form.RepoName)
|
||||
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
|
||||
return
|
||||
} else if err == models.ErrRepoAlreadyExist {
|
||||
ctx.Data["Err_RepoName"] = true
|
||||
@@ -243,18 +244,25 @@ func Action(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
func Download(ctx *middleware.Context) {
|
||||
ext := "." + ctx.Params(":ext")
|
||||
var (
|
||||
uri = ctx.Params("*")
|
||||
refName string
|
||||
ext string
|
||||
archivePath string
|
||||
)
|
||||
|
||||
var archivePath string
|
||||
switch ext {
|
||||
case ".zip":
|
||||
switch {
|
||||
case strings.HasSuffix(uri, ".zip"):
|
||||
ext = ".zip"
|
||||
archivePath = path.Join(ctx.Repo.GitRepo.Path, "archives/zip")
|
||||
case ".tar.gz":
|
||||
case strings.HasSuffix(uri, ".tar.gz"):
|
||||
ext = ".tar.gz"
|
||||
archivePath = path.Join(ctx.Repo.GitRepo.Path, "archives/targz")
|
||||
default:
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
refName = strings.TrimSuffix(uri, ext)
|
||||
|
||||
if !com.IsDir(archivePath) {
|
||||
if err := os.MkdirAll(archivePath, os.ModePerm); err != nil {
|
||||
@@ -263,13 +271,42 @@ func Download(ctx *middleware.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get corresponding commit.
|
||||
var (
|
||||
commit *git.Commit
|
||||
err error
|
||||
)
|
||||
gitRepo := ctx.Repo.GitRepo
|
||||
if gitRepo.IsBranchExist(refName) {
|
||||
commit, err = gitRepo.GetCommitOfBranch(refName)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "Download", err)
|
||||
return
|
||||
}
|
||||
} else if gitRepo.IsTagExist(refName) {
|
||||
commit, err = gitRepo.GetCommitOfTag(refName)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "Download", err)
|
||||
return
|
||||
}
|
||||
} else if len(refName) == 40 {
|
||||
commit, err = gitRepo.GetCommit(refName)
|
||||
if err != nil {
|
||||
ctx.Handle(404, "Download", nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
|
||||
archivePath = path.Join(archivePath, ctx.Repo.CommitId+ext)
|
||||
if !com.IsFile(archivePath) {
|
||||
if err := ctx.Repo.Commit.CreateArchive(archivePath, git.ZIP); err != nil {
|
||||
if err := commit.CreateArchive(archivePath, git.ZIP); err != nil {
|
||||
ctx.Handle(500, "Download -> CreateArchive "+archivePath, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.ServeFile(archivePath, ctx.Repo.Repository.Name+"-"+base.ShortSha(ctx.Repo.CommitId)+ext)
|
||||
ctx.ServeFile(archivePath, ctx.Repo.Repository.Name+"-"+base.ShortSha(commit.Id.String())+ext)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/mailer"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
@@ -26,6 +27,8 @@ const (
|
||||
SETTINGS_OPTIONS base.TplName = "repo/settings/options"
|
||||
COLLABORATION base.TplName = "repo/settings/collaboration"
|
||||
HOOKS base.TplName = "repo/settings/hooks"
|
||||
GITHOOKS base.TplName = "repo/settings/githooks"
|
||||
GITHOOK_EDIT base.TplName = "repo/settings/githook_edit"
|
||||
HOOK_NEW base.TplName = "repo/settings/hook_new"
|
||||
ORG_HOOK_NEW base.TplName = "org/settings/hook_new"
|
||||
)
|
||||
@@ -97,7 +100,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
|
||||
ctx.Redirect(fmt.Sprintf("%s/%s/%s/settings", setting.AppSubUrl, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
|
||||
case "transfer":
|
||||
if ctx.Repo.Repository.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
@@ -112,7 +115,10 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
} else if !isExist {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), SETTINGS_OPTIONS, nil)
|
||||
return
|
||||
} else if err = models.TransferOwnership(ctx.Repo.Owner, newOwner, ctx.Repo.Repository); err != nil {
|
||||
} else if !ctx.User.ValidtePassword(ctx.Query("password")) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_OPTIONS, nil)
|
||||
return
|
||||
} else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil {
|
||||
if err == models.ErrRepoAlreadyExist {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), SETTINGS_OPTIONS, nil)
|
||||
} else {
|
||||
@@ -121,7 +127,8 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
return
|
||||
}
|
||||
log.Trace("Repository transfered: %s/%s -> %s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newOwner)
|
||||
ctx.Redirect("/")
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
case "delete":
|
||||
if ctx.Repo.Repository.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
@@ -150,9 +157,9 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
}
|
||||
log.Trace("Repository deleted: %s/%s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
if ctx.Repo.Owner.IsOrganization() {
|
||||
ctx.Redirect("/org/" + ctx.Repo.Owner.Name + "/dashboard")
|
||||
ctx.Redirect(setting.AppSubUrl + "/org/" + ctx.Repo.Owner.Name + "/dashboard")
|
||||
} else {
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +173,7 @@ func SettingsCollaboration(ctx *middleware.Context) {
|
||||
if ctx.Req.Method == "POST" {
|
||||
name := strings.ToLower(ctx.Query("collaborator"))
|
||||
if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
|
||||
ctx.Redirect(ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
|
||||
return
|
||||
}
|
||||
has, err := models.HasAccess(name, repoLink, models.WRITABLE)
|
||||
@@ -174,7 +181,7 @@ func SettingsCollaboration(ctx *middleware.Context) {
|
||||
ctx.Handle(500, "HasAccess", err)
|
||||
return
|
||||
} else if has {
|
||||
ctx.Redirect(ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -182,16 +189,23 @@ func SettingsCollaboration(ctx *middleware.Context) {
|
||||
if err != nil {
|
||||
if err == models.ErrUserNotExist {
|
||||
ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
|
||||
ctx.Redirect(ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check if user is organization member.
|
||||
if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) {
|
||||
ctx.Flash.Info(ctx.Tr("repo.settings.user_is_org_member"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink,
|
||||
Mode: models.WRITABLE}); err != nil {
|
||||
ctx.Handle(500, "AddAccess2", err)
|
||||
ctx.Handle(500, "AddAccess", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -203,7 +217,7 @@ func SettingsCollaboration(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
|
||||
ctx.Redirect(ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -240,16 +254,20 @@ func SettingsCollaboration(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
us := make([]*models.User, len(names))
|
||||
for i, name := range names {
|
||||
us[i], err = models.GetUserByName(name)
|
||||
collaborators := make([]*models.User, 0, len(names))
|
||||
for _, name := range names {
|
||||
u, err := models.GetUserByName(name)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
return
|
||||
}
|
||||
// Does not show organization members.
|
||||
if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) {
|
||||
continue
|
||||
}
|
||||
collaborators = append(collaborators, u)
|
||||
}
|
||||
|
||||
ctx.Data["Collaborators"] = us
|
||||
ctx.Data["Collaborators"] = collaborators
|
||||
ctx.HTML(200, COLLABORATION)
|
||||
}
|
||||
|
||||
@@ -587,3 +605,54 @@ func getOrgRepoCtx(ctx *middleware.Context) (*OrgRepoCtx, error) {
|
||||
return &OrgRepoCtx{}, errors.New("Unable to set OrgRepo context")
|
||||
}
|
||||
}
|
||||
|
||||
func GitHooks(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings")
|
||||
ctx.Data["PageIsSettingsGitHooks"] = true
|
||||
|
||||
hooks, err := ctx.Repo.GitRepo.Hooks()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "Hooks", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Hooks"] = hooks
|
||||
|
||||
ctx.HTML(200, GITHOOKS)
|
||||
}
|
||||
|
||||
func GitHooksEdit(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings")
|
||||
ctx.Data["PageIsSettingsGitHooks"] = true
|
||||
|
||||
name := ctx.Params(":name")
|
||||
hook, err := ctx.Repo.GitRepo.GetHook(name)
|
||||
if err != nil {
|
||||
if err == git.ErrNotValidHook {
|
||||
ctx.Handle(404, "GetHook", err)
|
||||
} else {
|
||||
ctx.Handle(500, "GetHook", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Data["Hook"] = hook
|
||||
ctx.HTML(200, GITHOOK_EDIT)
|
||||
}
|
||||
|
||||
func GitHooksEditPost(ctx *middleware.Context) {
|
||||
name := ctx.Params(":name")
|
||||
hook, err := ctx.Repo.GitRepo.GetHook(name)
|
||||
if err != nil {
|
||||
if err == git.ErrNotValidHook {
|
||||
ctx.Handle(404, "GetHook", err)
|
||||
} else {
|
||||
ctx.Handle(500, "GetHook", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
hook.Content = ctx.Query("content")
|
||||
if err = hook.Update(); err != nil {
|
||||
ctx.Handle(500, "hook.Update", err)
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks/git")
|
||||
}
|
||||
|
||||
@@ -11,12 +11,10 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/saintfish/chardet"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/mahonia"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
@@ -24,21 +22,6 @@ const (
|
||||
HOME base.TplName = "repo/home"
|
||||
)
|
||||
|
||||
func toUtf8(content []byte) (error, string) {
|
||||
detector := chardet.NewTextDetector()
|
||||
result, err := detector.DetectBest(content)
|
||||
if err != nil {
|
||||
return err, ""
|
||||
}
|
||||
|
||||
if result.Charset == "utf8" {
|
||||
return nil, string(content)
|
||||
}
|
||||
|
||||
decoder := mahonia.NewDecoder(result.Charset)
|
||||
return nil, decoder.ConvertString(string(content))
|
||||
}
|
||||
|
||||
func Home(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Repo.Repository.Name
|
||||
|
||||
@@ -117,7 +100,7 @@ func Home(ctx *middleware.Context) {
|
||||
if readmeExist {
|
||||
ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, ""))
|
||||
} else {
|
||||
if err, content := toUtf8(buf); err != nil {
|
||||
if err, content := base.ToUtf8WithErr(buf); err != nil {
|
||||
if err != nil {
|
||||
log.Error(4, "Convert content encoding: %s", err)
|
||||
}
|
||||
@@ -135,6 +118,7 @@ func Home(ctx *middleware.Context) {
|
||||
ctx.Handle(404, "SubTree", err)
|
||||
return
|
||||
}
|
||||
|
||||
entries, err := tree.ListEntries(treename)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "ListEntries", err)
|
||||
@@ -145,13 +129,27 @@ func Home(ctx *middleware.Context) {
|
||||
files := make([][]interface{}, 0, len(entries))
|
||||
|
||||
for _, te := range entries {
|
||||
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
|
||||
if err != nil {
|
||||
ctx.Handle(404, "GetCommitOfRelPath", err)
|
||||
return
|
||||
}
|
||||
if te.Type != git.COMMIT {
|
||||
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetCommitOfRelPath", err)
|
||||
return
|
||||
}
|
||||
files = append(files, []interface{}{te, c})
|
||||
} else {
|
||||
sm, err := ctx.Repo.Commit.GetSubModule(path.Join(treename, te.Name()))
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetSubModule", err)
|
||||
return
|
||||
}
|
||||
|
||||
files = append(files, []interface{}{te, c})
|
||||
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetCommitOfRelPath", err)
|
||||
return
|
||||
}
|
||||
files = append(files, []interface{}{te, git.NewSubModuleFile(c, sm.Url, te.Id.String())})
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["Files"] = files
|
||||
@@ -199,6 +197,18 @@ func Home(ctx *middleware.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastCommit := ctx.Repo.Commit
|
||||
if len(treePath) > 0 {
|
||||
c, err := ctx.Repo.Commit.GetCommitOfRelPath(treePath)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetCommitOfRelPath", err)
|
||||
return
|
||||
}
|
||||
lastCommit = c
|
||||
}
|
||||
ctx.Data["LastCommit"] = lastCommit
|
||||
ctx.Data["LastCommitUser"] = models.ValidateCommitWithEmail(lastCommit)
|
||||
}
|
||||
|
||||
ctx.Data["Username"] = userName
|
||||
@@ -219,7 +229,6 @@ func Home(ctx *middleware.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["LastCommit"] = ctx.Repo.Commit
|
||||
ctx.Data["Paths"] = Paths
|
||||
ctx.Data["TreeName"] = treename
|
||||
ctx.Data["Treenames"] = treenames
|
||||
|
||||
@@ -52,8 +52,8 @@ func SignIn(ctx *middleware.Context) {
|
||||
defer func() {
|
||||
if !isSucceed {
|
||||
log.Trace("auto-login cookie cleared: %s", uname)
|
||||
ctx.SetCookie(setting.CookieUserName, "", -1)
|
||||
ctx.SetCookie(setting.CookieRememberName, "", -1)
|
||||
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl)
|
||||
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl)
|
||||
return
|
||||
}
|
||||
}()
|
||||
@@ -77,12 +77,12 @@ func SignIn(ctx *middleware.Context) {
|
||||
ctx.Session.Set("uid", u.Id)
|
||||
ctx.Session.Set("uname", u.Name)
|
||||
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
|
||||
ctx.SetCookie("redirect_to", "", -1)
|
||||
ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
|
||||
ctx.Redirect(redirectTo)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
|
||||
func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
|
||||
@@ -113,9 +113,9 @@ func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
|
||||
|
||||
if form.Remember {
|
||||
days := 86400 * setting.LogInRememberDays
|
||||
ctx.SetCookie(setting.CookieUserName, u.Name, days)
|
||||
ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubUrl)
|
||||
ctx.SetSuperSecureCookie(base.EncodeMd5(u.Rands+u.Passwd),
|
||||
setting.CookieRememberName, u.Name, days)
|
||||
setting.CookieRememberName, u.Name, days, setting.AppSubUrl)
|
||||
}
|
||||
|
||||
// Bind with social account.
|
||||
@@ -135,12 +135,12 @@ func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
|
||||
ctx.Session.Set("uid", u.Id)
|
||||
ctx.Session.Set("uname", u.Name)
|
||||
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
|
||||
ctx.SetCookie("redirect_to", "", -1)
|
||||
ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
|
||||
ctx.Redirect(redirectTo)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
|
||||
func SignOut(ctx *middleware.Context) {
|
||||
@@ -149,9 +149,9 @@ func SignOut(ctx *middleware.Context) {
|
||||
ctx.Session.Delete("socialId")
|
||||
ctx.Session.Delete("socialName")
|
||||
ctx.Session.Delete("socialEmail")
|
||||
ctx.SetCookie(setting.CookieUserName, "", -1)
|
||||
ctx.SetCookie(setting.CookieRememberName, "", -1)
|
||||
ctx.Redirect("/")
|
||||
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl)
|
||||
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl)
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
|
||||
func oauthSignUp(ctx *middleware.Context, sid int64) {
|
||||
@@ -280,7 +280,7 @@ func SignUpPost(ctx *middleware.Context, cpt *captcha.Captcha, form auth.Registe
|
||||
ctx.Data["IsSendRegisterMail"] = true
|
||||
ctx.Data["Email"] = u.Email
|
||||
ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
|
||||
ctx.HTML(200, "user/activate")
|
||||
ctx.HTML(200, ACTIVATE)
|
||||
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
|
||||
log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
|
||||
@@ -288,7 +288,7 @@ func SignUpPost(ctx *middleware.Context, cpt *captcha.Captcha, form auth.Registe
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
}
|
||||
|
||||
func Activate(ctx *middleware.Context) {
|
||||
@@ -335,7 +335,7 @@ func Activate(ctx *middleware.Context) {
|
||||
|
||||
ctx.Session.Set("uid", user.Id)
|
||||
ctx.Session.Set("uname", user.Name)
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ func ResetPasswdPost(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
log.Trace("User password reset: %s", u.Name)
|
||||
ctx.Redirect("/user/login")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -94,7 +95,7 @@ func Dashboard(ctx *middleware.Context) {
|
||||
feeds := make([]*models.Action, 0, len(actions))
|
||||
for _, act := range actions {
|
||||
if act.IsPrivate {
|
||||
if has, _ := models.HasAccess(ctxUser.Name, act.RepoUserName+"/"+act.RepoName,
|
||||
if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
|
||||
models.READABLE); !has {
|
||||
continue
|
||||
}
|
||||
@@ -126,7 +127,7 @@ func Profile(ctx *middleware.Context) {
|
||||
uname := ctx.Params(":username")
|
||||
// Special handle for FireFox requests favicon.ico.
|
||||
if uname == "favicon.ico" {
|
||||
ctx.Redirect("/img/favicon.png")
|
||||
ctx.Redirect(setting.AppSubUrl + "/img/favicon.png")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ func Profile(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
if u.IsOrganization() {
|
||||
ctx.Redirect("/org/" + u.Name)
|
||||
ctx.Redirect(setting.AppSubUrl + "/org/" + u.Name)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -181,7 +182,7 @@ func Email2User(ctx *middleware.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Redirect("/user/" + u.Name)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/" + u.Name)
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,7 +56,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||
} else if err = models.ChangeUserName(ctx.User, form.UserName); err != nil {
|
||||
if err == models.ErrUserNameIllegal {
|
||||
ctx.Flash.Error(ctx.Tr("form.illegal_username"))
|
||||
ctx.Redirect("/user/settings")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
||||
return
|
||||
} else {
|
||||
ctx.Handle(500, "ChangeUserName", err)
|
||||
@@ -78,7 +79,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||
}
|
||||
log.Trace("User setting updated: %s", ctx.User.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
|
||||
ctx.Redirect("/user/settings")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
||||
}
|
||||
|
||||
func SettingsPassword(ctx *middleware.Context) {
|
||||
@@ -119,7 +120,7 @@ func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm)
|
||||
ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
|
||||
}
|
||||
|
||||
ctx.Redirect("/user/settings/password")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/password")
|
||||
}
|
||||
|
||||
func SettingsSSHKeys(ctx *middleware.Context) {
|
||||
@@ -160,7 +161,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
ctx.Handle(500, "DeletePublicKey", err)
|
||||
} else {
|
||||
log.Trace("SSH key deleted: %s", ctx.User.Name)
|
||||
ctx.Redirect("/user/settings/ssh")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -177,7 +178,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
|
||||
if ok, err := models.CheckPublicKeyString(cleanContent); !ok {
|
||||
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
|
||||
ctx.Redirect("/user/settings/ssh")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -196,7 +197,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
} else {
|
||||
log.Trace("SSH key added: %s", ctx.User.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_key_success"))
|
||||
ctx.Redirect("/user/settings/ssh")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -217,7 +218,7 @@ func SettingsSocial(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
|
||||
ctx.Redirect("/user/settings/social")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -248,13 +249,13 @@ func SettingsDelete(ctx *middleware.Context) {
|
||||
switch err {
|
||||
case models.ErrUserOwnRepos:
|
||||
ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
|
||||
ctx.Redirect("/user/settings/delete")
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
|
||||
default:
|
||||
ctx.Handle(500, "DeleteUser", err)
|
||||
}
|
||||
} else {
|
||||
log.Trace("Account deleted: %s", ctx.User.Name)
|
||||
ctx.Redirect("/")
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
func extractPath(next string) string {
|
||||
n, err := url.Parse(next)
|
||||
if err != nil {
|
||||
return "/"
|
||||
return setting.AppSubUrl + "/"
|
||||
}
|
||||
return n.Path
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func SocialSignIn(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
case models.ErrOauth2NotAssociated:
|
||||
next = "/user/sign_up"
|
||||
next = setting.AppSubUrl + "/user/sign_up"
|
||||
default:
|
||||
ctx.Handle(500, "social.SocialSignIn(GetOauth2)", err)
|
||||
return
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
### Install Gogs With Docker
|
||||
|
||||
Deploying gogs using [Docker](http://www.docker.io/) is as easy as pie. Simple
|
||||
open the `/dockerfiles/build.sh` file and replace the initial configuration
|
||||
settings:
|
||||
|
||||
```
|
||||
DB_TYPE="YOUR_DB_TYPE" # type of database, supports either 'mysql' or 'postgres'
|
||||
MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, supports either 'redis' or 'memcache'
|
||||
DB_PASSWORD="YOUR_DB_PASSWORD" # The database password
|
||||
DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value to use when running the database image
|
||||
MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value to use when running the memory database image
|
||||
HOST_PORT="YOUR_HOST_PORT" # The port to expose the app on (redirected to 3000 inside the gogs container)
|
||||
```
|
||||
|
||||
And run:
|
||||
```
|
||||
cd dockerfiles
|
||||
./build.sh
|
||||
```
|
||||
|
||||
The build will take some time, just be patient. After it finishes, it will
|
||||
display a message that looks like this (the content may be different, depending
|
||||
on your configuration options):
|
||||
|
||||
```
|
||||
Now we have the MySQL image(running) and gogs image, use the follow command to start gogs service:
|
||||
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs
|
||||
```
|
||||
|
||||
To run the container, just copy the above command:
|
||||
|
||||
```
|
||||
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs
|
||||
```
|
||||
|
||||
Now gogs should be running! Open your browser and navigate to:
|
||||
|
||||
```
|
||||
http://YOUR_HOST_IP:YOUR_HOST_PORT
|
||||
```
|
||||
|
||||
During the installation procedure, use the following information:
|
||||
|
||||
- The database type should be whichever `DB_TYPE` you selected above
|
||||
|
||||
- The database host should be either `db:5432` or `db:3306` for PostgreSQL and
|
||||
MySQL respectively
|
||||
|
||||
- The `RUN_USER` should be whichever user you're running the container with.
|
||||
Ideally that's `git`, but your individual configuration may vary
|
||||
|
||||
- Everything else is configured like a normal gogs installation
|
||||
|
||||
Let's 'gogs'!
|
||||
Ouya~
|
||||
@@ -1,77 +0,0 @@
|
||||
# Configs of the docker images, you might have specify your own configs here.
|
||||
|
||||
DB_TYPE="YOUR_DB_TYPE" # type of database, support 'mysql' and 'postgres'
|
||||
MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, support 'redis' and 'memcache'
|
||||
DB_PASSWORD="YOUR_DB_PASSWORD" # The database password.
|
||||
DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value when run the database image.
|
||||
MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value when run the mem database image.
|
||||
HOST_PORT="YOUR_HOST_PORT" # The port on host, which will be redirected to the port 3000 inside gogs container.
|
||||
|
||||
# apt source, you can select 'nchc'(mirror in Taiwan) or 'aliyun'(best for mainlance China users) according to your network, if you could connect to the official unbunt mirror in a fast speed, just leave it to "".
|
||||
APT_SOURCE=""
|
||||
|
||||
# fail immediately if anything goes wrong
|
||||
set -e
|
||||
|
||||
DOCKER_BIN=$(which docker.io || which docker)
|
||||
if [ -z "$DOCKER_BIN" ] ; then
|
||||
echo "Please install docker. You can install docker by running \"wget -qO- https://get.docker.io/ | sh\"."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the database root password in database image Dockerfile.
|
||||
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/$DB_TYPE/Dockerfile
|
||||
# Replace the database root password in gogits image deploy.sh file.
|
||||
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/gogits/deploy.sh
|
||||
# Replace the apt source in gogits image Dockerfile.
|
||||
sed -i "s/#$APT_SOURCE#//" images/gogits/Dockerfile
|
||||
# Uncomment the installation of database lib in gogs Dockerfile
|
||||
sed -i "s/#$DB_TYPE#//" images/gogits/Dockerfile
|
||||
# Replace the database type in gogits image deploy.sh file.
|
||||
sed -i "s/THE_DB_TYPE/$DB_TYPE/g" images/gogits/deploy.sh
|
||||
|
||||
if [ $MEM_TYPE != "" ]
|
||||
then
|
||||
# Replace the mem configs in deploy.sh
|
||||
sed -i "s/THE_MEM_TYPE/$MEM_TYPE/g" images/gogits/deploy.sh
|
||||
# Uncomment the installation of go mem lib
|
||||
sed -i "s/#$MEM_TYPE#//" images/gogits/Dockerfile
|
||||
|
||||
# Add the tags when get gogs
|
||||
sed -i "s#RUN go get -u -d github.com/gogits/gogs#RUN go get -u -d -tags $MEM_TYPE github.com/gogits/gogs#g" images/gogits/Dockerfile
|
||||
# Append the tag in gogs build
|
||||
GOGS_BUILD_LINE=`awk '$0 ~ str{print NR}' str="go build" images/gogits/Dockerfile`
|
||||
# Append the build tags
|
||||
sed -i "${GOGS_BUILD_LINE}s/$/ -tags $MEM_TYPE/" images/gogits/Dockerfile
|
||||
|
||||
cd images/$MEM_TYPE
|
||||
$DOCKER_BIN build -t gogits/$MEM_TYPE .
|
||||
$DOCKER_BIN run -d --name $MEM_RUN_NAME gogits/$MEM_TYPE
|
||||
MEM_LINK=" --link $MEM_RUN_NAME:mem "
|
||||
cd ../../
|
||||
fi
|
||||
|
||||
# Build the database image
|
||||
cd images/$DB_TYPE
|
||||
$DOCKER_BIN build -t gogits/$DB_TYPE .
|
||||
#
|
||||
|
||||
|
||||
## Build the gogits image
|
||||
cd ../gogits
|
||||
|
||||
$DOCKER_BIN build -t gogits/gogs .
|
||||
|
||||
#sed -i "s#RUN go get -u -tags $MEM_TYPE github.com/gogits/gogs#RUN go get -u github.com/gogits/gogs#g" Dockerfile
|
||||
|
||||
# Remove the appended tags in go build line(if there is any)
|
||||
sed -i "s/ -tags $MEM_TYPE//" Dockerfile
|
||||
|
||||
#
|
||||
## Run MySQL image with name
|
||||
$DOCKER_BIN run -d --name $DB_RUN_NAME gogits/$DB_TYPE
|
||||
#
|
||||
## Run gogits image and link it to the database image
|
||||
echo "Now we have the $DB_TYPE image(running) and gogs image, use the follow command to start gogs service:"
|
||||
echo -e "\033[33m $DOCKER_BIN run -i -t --link $DB_RUN_NAME:db $MEM_LINK -p $HOST_PORT:3000 gogits/gogs \033[0m"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user