Conflicts:
	routers/repo/download.go
tokarchuk/v1.17
Don Bowman 10 years ago
commit 1cb46ede1a
  1. 4
      .bra.toml
  2. 1
      .gitignore
  3. 36
      .gopmfile
  4. 22
      .pkgr.yml
  5. 9
      .travis.yml
  6. 31
      README.md
  7. 21
      README_ZH.md
  8. 1
      cmd/cert.go
  9. 142
      cmd/serve.go
  10. 82
      cmd/web.go
  11. 37
      conf/app.ini
  12. 13
      conf/gitignore/PHP CakePHP
  13. 2
      conf/gitignore/PHP FuelPHP
  14. 4
      conf/gitignore/PHP Laravel
  15. 37
      conf/gitignore/PHP Symfony
  16. 6
      conf/gitignore/PHP Yii
  17. 20
      conf/gitignore/PHP ZendFramework
  18. 7
      conf/locale/TRANSLATORS
  19. 798
      conf/locale/locale_bg-BG.ini
  20. 103
      conf/locale/locale_de-DE.ini
  21. 126
      conf/locale/locale_en-US.ini
  22. 87
      conf/locale/locale_es-ES.ini
  23. 137
      conf/locale/locale_fr-FR.ini
  24. 798
      conf/locale/locale_it-IT.ini
  25. 85
      conf/locale/locale_ja-JP.ini
  26. 83
      conf/locale/locale_lv-LV.ini
  27. 97
      conf/locale/locale_nl-NL.ini
  28. 105
      conf/locale/locale_pl-PL.ini
  29. 85
      conf/locale/locale_pt-BR.ini
  30. 125
      conf/locale/locale_ru-RU.ini
  31. 128
      conf/locale/locale_zh-CN.ini
  32. 83
      conf/locale/locale_zh-HK.ini
  33. 1980
      config.codekit
  34. 21
      docker/README.md
  35. 16
      docker/assemble_blocks.sh
  36. 15
      docker/blocks/docker_gogs/Dockerfile
  37. 20
      docker/blocks/docker_gogs_dev/Dockerfile
  38. 0
      docker/blocks/option_cache_memcache/docker-compose
  39. 0
      docker/blocks/option_cache_redis/docker-compose
  40. 0
      docker/blocks/option_db_mysql/docker-compose
  41. 0
      docker/blocks/option_db_postgresql/docker-compose
  42. 0
      docker/blocks/option_session_mysql/docker-compose
  43. 0
      docker/blocks/w_cache/docker-compose
  44. 0
      docker/blocks/w_cache_session/docker-compose
  45. 0
      docker/blocks/w_db/docker-compose
  46. 0
      docker/blocks/w_db_cache/docker-compose
  47. 0
      docker/blocks/w_db_cache_session/docker-compose
  48. 0
      docker/blocks/w_db_session/docker-compose
  49. 0
      docker/blocks/w_none/docker-compose
  50. 0
      docker/blocks/w_session/docker-compose
  51. 2
      gogs.go
  52. 26
      models/access.go
  53. 36
      models/action.go
  54. 176
      models/error.go
  55. 47
      models/git_diff.go
  56. 406
      models/issue.go
  57. 71
      models/login.go
  58. 74
      models/migrations/migrations.go
  59. 14
      models/models.go
  60. 38
      models/org.go
  61. 337
      models/publickey.go
  62. 265
      models/repo.go
  63. 82
      models/user.go
  64. 172
      models/webhook.go
  65. 1
      modules/auth/admin.go
  66. 29
      modules/auth/auth.go
  67. 1
      modules/auth/auth_form.go
  68. 2
      modules/auth/org.go
  69. 35
      modules/auth/pam/pam.go
  70. 15
      modules/auth/pam/pam_stub.go
  71. 11
      modules/auth/repo_form.go
  72. 57
      modules/auth/user_form.go
  73. 12
      modules/base/template.go
  74. 960
      modules/bindata/bindata.go
  75. 2
      modules/cron/manager.go
  76. 2
      modules/git/repo_tag.go
  77. 8
      modules/git/utils.go
  78. 6
      modules/log/log.go
  79. 17
      modules/mailer/mailer.go
  80. 8
      modules/middleware/auth.go
  81. 13
      modules/middleware/context.go
  82. 8
      modules/middleware/org.go
  83. 20
      modules/middleware/repo.go
  84. 49
      modules/setting/setting.go
  85. 2
      packager/debian/postinst
  86. 9
      public/css/bootstrap-colorpicker.min.css
  87. 790
      public/css/datepicker3.css
  88. 2
      public/css/gogs.min.css
  89. 545
      public/css/jquery.datetimepicker.css
  90. 278
      public/css/jquery.minicolors.css
  91. 559
      public/css/markdown.css
  92. 4
      public/css/semantic.min.css
  93. 79
      public/js/app.js
  94. 1
      public/js/bootstrap-colorpicker.min.js
  95. 1671
      public/js/bootstrap-datepicker.js
  96. 133
      public/js/gogs.js
  97. 6
      public/js/jquery-1.10.1.min.js
  98. 1
      public/js/jquery-1.10.1.min.map
  99. 4
      public/js/jquery-1.11.2.min.js
  100. 5
      public/js/jquery-1.11.3.min.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -14,7 +14,7 @@ watch_exts = [".go"]
build_delay = 1500
cmds = [
#["go-bindata", "-o=modules/bindata/bindata.go", "-ignore=\\.DS_Store|README", "-pkg=bindata", "conf/..."],
["go", "install", "-tags", "sqlite cert"],# redis memcache
["go", "build", "-tags", "sqlite cert"],
["go", "install", "-tags", "sqlite"],# redis memcache cert pam
["go", "build", "-tags", "sqlite"],
["./gogs", "web"]
]

1
.gitignore vendored

@ -29,7 +29,6 @@ profile/
__pycache__
*.pem
output*
config.codekit
.brackets.json
docker/fig.yml
docker/docker/Dockerfile

@ -4,32 +4,36 @@ path = github.com/gogits/gogs
[deps]
github.com/bradfitz/gomemcache = commit:72a68649ba
github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:188d690b1a
github.com/Unknwon/com = commit:47d7d2b81a
github.com/Unknwon/i18n = commit:7457d88830
github.com/Unknwon/macaron = commit:93de4f3fad
github.com/Unknwon/macaron = commit:635c89ac74
github.com/Unknwon/paginater = commit:cab2d086fa
github.com/codegangsta/cli = commit:2bcd11f863
github.com/go-sql-driver/mysql = commit:a197e5d405
github.com/go-xorm/core = commit:be6e7ac47d
github.com/go-xorm/xorm = commit:1f0dd9bef2
github.com/go-xorm/core =
github.com/go-xorm/xorm =
github.com/gogits/chardet = commit:2404f77725
github.com/gogits/go-gogs-client = commit:92e76d616a
github.com/lib/pq = commit:30ed2200d7
github.com/macaron-contrib/binding = commit:548a793679
github.com/macaron-contrib/cache = commit:928d5c35cd
github.com/macaron-contrib/captcha = commit:fbb8b1ebb5
github.com/lib/pq = commit:0dad96c0b9
github.com/macaron-contrib/binding = commit:de6ed78668
github.com/macaron-contrib/cache = commit:cd824f6f2d
github.com/macaron-contrib/captcha = commit:9a0a0b1468
github.com/macaron-contrib/csrf = commit:98ddf5a710
github.com/macaron-contrib/i18n = commit:da2b19e90b
github.com/macaron-contrib/oauth2 = commit:8f394c3629
github.com/macaron-contrib/session = commit:31e841d95c
github.com/macaron-contrib/session = commit:e48134e803
github.com/macaron-contrib/toolbox = commit:acbfe36e16
github.com/mattn/go-sqlite3 = commit:e28cd440fa
github.com/microcosm-cc/bluemonday = commit:fcd0f5074e
github.com/nfnt/resize = commit:53e9ca890b
github.com/russross/blackfriday = commit:6928e11ecd
github.com/shurcooL/go = commit:bc30a0bd33
golang.org/x/net = commit:7dbad50ab5
golang.org/x/text = commit:5f741289c4
gopkg.in/ini.v1 = commit:177219109c
github.com/mcuadros/go-version
github.com/microcosm-cc/bluemonday = commit:2b7763a06c
github.com/mssola/user_agent = commit:f659b98638
github.com/msteinert/pam = commit:9a42d39dbf
github.com/nfnt/resize = commit:dc93e1b98c
github.com/russross/blackfriday = commit:8cec3a854e
github.com/shurcooL/go = commit:680f57227f
golang.org/x/net = commit:937a34c9de13
golang.org/x/text = commit:5b2527008a4c
gopkg.in/ini.v1 = commit:caf3f03ad9
gopkg.in/redis.v2 = commit:e617904962
[res]

@ -1,10 +1,24 @@
targets:
debian-7: &debian
build_dependencies:
- libpam0g-dev
dependencies:
- libpam0g
- git
debian-8:
<<: *debian
ubuntu-14.04:
<<: *debian
ubuntu-12.04:
debian-7:
centos-6:
dependencies:
- git
<<: *debian
centos-6: &el
build_dependencies:
- pam-devel
dependencies:
- pam
- git
centos-7:
<<: *el
before:
- mv packager/Procfile .
- mv packager/.godir .

@ -6,11 +6,14 @@ go:
- 1.4
- tip
sudo: false
before_install:
- sudo apt-get update -qq
- sudo apt-get install -y libpam-dev
- go get github.com/msteinert/pam
script: go build -v
script: go build -v -tags "pam"
notifications:
email:
- u@gogs.io
slack: gophercn:o5pSanyTeNhnfYc3QnG0X7Wx
slack: gophercn:o5pSanyTeNhnfYc3QnG0X7Wx

@ -7,7 +7,7 @@ Gogs (Go Git Service) is a painless self-hosted Git service.
![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### Current version: 0.6.1 Beta
##### Current version: 0.6.4 Beta
### NOTICES
@ -52,13 +52,27 @@ The goal of this project is to make the easiest, fastest, and most painless way
- Drone CI integration
- Supports MySQL, PostgreSQL and SQLite3
- Social account login (GitHub, Google, QQ, Weibo)
- Multi-language support ([11 languages](https://crowdin.com/project/gogs))
- Multi-language support ([14 languages](https://crowdin.com/project/gogs))
## System Requirements
- A cheap Raspberry Pi is powerful enough for basic functionality.
- At least 2 CPU cores and 1GB RAM would be the baseline for teamwork.
## Browser Support
According to [Semantic UI](https://github.com/Semantic-Org/Semantic-UI/tree/1.x):
- Last 2 Versions FF, Chrome, IE 10+
- Safari 6
- IE 9+ (Browser prefix only)
- Android 4
- Blackberry 10
Browser prefixes are present for Internet Explorer 9, but the browser is not officially supported.
The official support minimal size is 1024*768, UI may still looks right in smaller size but no promises and fixes.
## Installation
Make sure you install the [prerequisites](http://gogs.io/docs/installation/) first.
@ -71,6 +85,18 @@ There are 5 ways to install Gogs:
- [Ship with Docker](https://github.com/gogits/gogs/tree/master/docker)
- [Install with Vagrant](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
### Tutorials
- [How To Set Up Gogs on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-gogs-on-ubuntu-14-04)
- [Run your own GitHub-like service with the help of Docker](http://blog.hypriot.com/post/run-your-own-github-like-service-with-docker/)
- [阿里云上 Ubuntu 14.04 64 位安装 Gogs](http://my.oschina.net/luyao/blog/375654) (Chinese)
- [Installing Gogs on FreeBSD](https://www.codejam.info/2015/03/installing-gogs-on-freebsd.html)
- [Gogs on Raspberry Pi](http://blog.meinside.pe.kr/Gogs-on-Raspberry-Pi/)
### Screencasts
- [Instalando Gogs no Ubuntu](https://www.youtube.com/watch?v=DFNifgEHOzk) (Português)
## Acknowledgments
- Router and middleware mechanism of [Macaron](https://github.com/Unknwon/macaron).
@ -83,6 +109,7 @@ There are 5 ways to install Gogs:
## Contributors
- The [core team](http://gogs.io/team) of this project.
- Ex-team members [@lunny](https://github.com/lunny) and [@fuxiaohei](https://github.com/fuxiaohei).
- See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
- See [TRANSLATORS](conf/locale/TRANSLATORS) for full list of translators.

@ -3,10 +3,6 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
Gogs (Go Git Service) 是一款可轻易搭建的自助 Git 服务。
![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### 当前版本:0.6.1 Beta
## 开发目的
Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。使用 Go 语言开发使得 Gogs 能够通过独立的二进制分发,并且支持 Go 语言支持的 **所有平台**,包括 Linux、Mac OS X 以及 Windows。
@ -39,13 +35,27 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- Drone CI 持续部署集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录(GitHub、Google、QQ、微博)
- 多语言支持([11 种语言]([more](https://crowdin.com/project/gogs)))
- 多语言支持([14 种语言]([more](https://crowdin.com/project/gogs)))
## 系统要求
- 最低的系统硬件要求为一个廉价的树莓派
- 如果用于团队项目,建议使用 2 核 CPU 及 1GB 内存
## 浏览器支持
根据 [Semantic UI](https://github.com/Semantic-Org/Semantic-UI/tree/1.x) 的要求:
- 最新两版的 FF、Chrome 和 IE 10+
- Safari 6
- IE 9+ (仅限浏览器前缀)
- Android 4
- Blackberry 10
尽管已经使用了 Internet Explorer 9 的浏览器前缀,但该版本的浏览器被没有被正式支持。
官方支持的最小 UI 尺寸为 1024*768,UI 不一定会在更小尺寸的设备上被破坏,但我们无法保证且不会修复。
## 安装部署
在安装 Gogs 之前,您需要先安装 [基本环境](http://gogs.io/docs/installation/)。
@ -70,6 +80,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
## 贡献成员
- 本项目的 [开发团队](http://gogs.io/team)。
- 前团队成员 [@lunny](https://github.com/lunny) 和 [@fuxiaohei](https://github.com/fuxiaohei)。
- 您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
- 您可以通过查看 [TRANSLATORS](conf/locale/TRANSLATORS) 文件获取完整的翻译人员列表。

@ -114,6 +114,7 @@ func runCert(ctx *cli.Context) {
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
CommonName: "Gogs",
},
NotBefore: notBefore,
NotAfter: notAfter,

@ -16,6 +16,7 @@ import (
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/httplib"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/uuid"
@ -70,42 +71,25 @@ var (
}
)
func fail(userMessage, logMessage string, args ...interface{}) {
fmt.Fprintln(os.Stderr, "Gogs:", userMessage)
log.GitLogger.Fatal(3, logMessage, args...)
}
func runServ(c *cli.Context) {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
setup("serv.log")
fail := func(userMessage, logMessage string, args ...interface{}) {
fmt.Fprintln(os.Stderr, "Gogs: ", userMessage)
log.GitLogger.Fatal(2, logMessage, args...)
}
if len(c.Args()) < 1 {
fail("Not enough arguments", "Not enough arugments")
}
keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 {
fail("key-id format error", "Invalid key id: %s", c.Args()[0])
}
keyId, err := com.StrTo(keys[1]).Int64()
if err != nil {
fail("key-id format error", "Invalid key id: %s", err)
}
user, err := models.GetUserByKeyId(keyId)
if err != nil {
fail("internal error", "Fail to get user by key ID(%d): %v", keyId, err)
fail("Not enough arguments", "Not enough arguments")
}
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" {
println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
if user.IsAdmin {
println("If this is unexpected, please log in with password and setup Gogs under another user.")
}
if len(cmd) == 0 {
println("Hi there, You've successfully authenticated, but Gogs does not provide shell access.")
println("If this is unexpected, please log in with password and setup Gogs under another user.")
return
}
@ -113,29 +97,25 @@ func runServ(c *cli.Context) {
repoPath := strings.Trim(args, "'")
rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
fail("Invalid repository path", "Invalide repository path: %v", args)
fail("Invalid repository path", "Invalid repository path: %v", args)
}
repoUserName := rr[0]
repoName := strings.TrimSuffix(rr[1], ".git")
repoUser, err := models.GetUserByName(repoUserName)
if err != nil {
if err == models.ErrUserNotExist {
if models.IsErrUserNotExist(err) {
fail("Repository owner does not exist", "Unregistered owner: %s", repoUserName)
}
fail("Internal error", "Fail to get repository owner(%s): %v", repoUserName, err)
fail("Internal error", "Failed to get repository owner(%s): %v", repoUserName, err)
}
repo, err := models.GetRepositoryByName(repoUser.Id, repoName)
if err != nil {
if models.IsErrRepoNotExist(err) {
if user.Id == repoUser.Id || repoUser.IsOwnedBy(user.Id) {
fail("Repository does not exist", "Repository does not exist: %s/%s", repoUser.Name, repoName)
} else {
fail(_ACCESS_DENIED_MESSAGE, "Repository does not exist: %s/%s", repoUser.Name, repoName)
}
fail(_ACCESS_DENIED_MESSAGE, "Repository does not exist: %s/%s", repoUser.Name, repoName)
}
fail("Internal error", "Fail to get repository: %v", err)
fail("Internal error", "Failed to get repository: %v", err)
}
requestedMode, has := COMMANDS[verb]
@ -143,17 +123,62 @@ func runServ(c *cli.Context) {
fail("Unknown git command", "Unknown git command %s", verb)
}
mode, err := models.AccessLevel(user, repo)
if err != nil {
fail("Internal error", "Fail to check access: %v", err)
} else if mode < requestedMode {
clientMessage := _ACCESS_DENIED_MESSAGE
if mode >= models.ACCESS_MODE_READ {
clientMessage = "You do not have sufficient authorization for this action"
// Allow anonymous clone for public repositories.
var (
keyID int64
user *models.User
)
if requestedMode == models.ACCESS_MODE_WRITE || repo.IsPrivate {
keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 {
fail("Key ID format error", "Invalid key ID: %s", c.Args()[0])
}
key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
if err != nil {
fail("Key ID format error", "Invalid key ID[%s]: %v", c.Args()[0], err)
}
keyID = key.ID
// Check deploy key or user key.
if key.Type == models.KEY_TYPE_DEPLOY {
if key.Mode < requestedMode {
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
}
// Check if this deploy key belongs to current repository.
if !models.HasDeployKey(key.ID, repo.Id) {
fail("Key access denied", "Key access denied: %d-%d", key.ID, repo.Id)
}
// Update deploy key activity.
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.Id)
if err != nil {
fail("Internal error", "GetDeployKey: %v", err)
}
deployKey.Updated = time.Now()
if err = models.UpdateDeployKey(deployKey); err != nil {
fail("Internal error", "UpdateDeployKey: %v", err)
}
} else {
user, err = models.GetUserByKeyId(key.ID)
if err != nil {
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
}
mode, err := models.AccessLevel(user, repo)
if err != nil {
fail("Internal error", "Fail to check access: %v", err)
} else if mode < requestedMode {
clientMessage := _ACCESS_DENIED_MESSAGE
if mode >= models.ACCESS_MODE_READ {
clientMessage = "You do not have sufficient authorization for this action"
}
fail(clientMessage,
"User %s does not have level %v access to repository %s",
user.Name, requestedMode, repoPath)
}
}
fail(clientMessage,
"User %s does not have level %v access to repository %s",
user.Name, requestedMode, repoPath)
}
uuid := uuid.NewV4().String()
@ -171,7 +196,7 @@ func runServ(c *cli.Context) {
gitcmd.Stdin = os.Stdin
gitcmd.Stderr = os.Stderr
if err = gitcmd.Run(); err != nil {
fail("Internal error", "Fail to execute git command: %v", err)
fail("Internal error", "Failed to execute git command: %v", err)
}
if requestedMode == models.ACCESS_MODE_WRITE {
@ -184,7 +209,7 @@ func runServ(c *cli.Context) {
err = models.Update(task.RefName, task.OldCommitId, task.NewCommitId,
user.Name, repoUserName, repoName, user.Id)
if err != nil {
log.GitLogger.Error(2, "Fail to update: %v", err)
log.GitLogger.Error(2, "Failed to update: %v", err)
}
}
@ -193,13 +218,22 @@ func runServ(c *cli.Context) {
}
}
// Update key activity.
key, err := models.GetPublicKeyById(keyId)
if err != nil {
fail("Internal error", "GetPublicKeyById: %v", err)
// Send deliver hook request.
resp, err := httplib.Head(setting.AppUrl + setting.AppSubUrl + repoUserName + "/" + repoName + "/hooks/trigger").Response()
if err == nil {
resp.Body.Close()
}
key.Updated = time.Now()
if err = models.UpdatePublicKey(key); err != nil {
fail("Internal error", "UpdatePublicKey: %v", err)
// Update user key activity.
if keyID > 0 {
key, err := models.GetPublicKeyByID(keyID)
if err != nil {
fail("Internal error", "GetPublicKeyById: %v", err)
}
key.Updated = time.Now()
if err = models.UpdatePublicKey(key); err != nil {
fail("Internal error", "UpdatePublicKey: %v", err)
}
}
}

@ -17,6 +17,7 @@ import (
"github.com/Unknwon/macaron"
"github.com/codegangsta/cli"
"github.com/go-xorm/xorm"
"github.com/macaron-contrib/binding"
"github.com/macaron-contrib/cache"
"github.com/macaron-contrib/captcha"
@ -25,6 +26,7 @@ import (
"github.com/macaron-contrib/oauth2"
"github.com/macaron-contrib/session"
"github.com/macaron-contrib/toolbox"
"github.com/mcuadros/go-version"
"gopkg.in/ini.v1"
api "github.com/gogits/go-gogs-client"
@ -35,7 +37,6 @@ import (
"github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
@ -69,7 +70,7 @@ type VerChecker struct {
// checkVersion checks if binary matches the version of templates files.
func checkVersion() {
// Templates.
data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION"))
data, err := ioutil.ReadFile(setting.StaticRootPath + "/templates/.VERSION")
if err != nil {
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
}
@ -79,18 +80,18 @@ func checkVersion() {
// Check dependency version.
checkers := []VerChecker{
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.4.3.0806"},
{"github.com/Unknwon/macaron", macaron.Version, "0.5.4"},
{"github.com/macaron-contrib/binding", binding.Version, "0.0.6"},
{"github.com/macaron-contrib/binding", binding.Version, "0.1.0"},
{"github.com/macaron-contrib/cache", cache.Version, "0.0.7"},
{"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"},
{"github.com/macaron-contrib/session", session.Version, "0.1.6"},
{"gopkg.in/ini.v1", ini.Version, "1.2.0"},
{"gopkg.in/ini.v1", ini.Version, "1.3.4"},
}
for _, c := range checkers {
ver := strings.Join(strings.Split(c.Version(), ".")[:3], ".")
if git.MustParseVersion(ver).LessThan(git.MustParseVersion(c.Expected)) {
log.Fatal(4, "Package '%s' version is too old(%s -> %s), did you forget to update?", c.ImportPath, ver, c.Expected)
if !version.Compare(c.Version(), c.Expected, ">=") {
log.Fatal(4, "Package '%s' version is too old(%s -> %s), did you forget to update?", c.ImportPath, c.Version(), c.Expected)
}
}
}
@ -98,7 +99,9 @@ func checkVersion() {
// newMacaron initializes Macaron instance.
func newMacaron() *macaron.Macaron {
m := macaron.New()
m.Use(macaron.Logger())
if !setting.DisableRouterLog {
m.Use(macaron.Logger())
}
m.Use(macaron.Recovery())
if setting.EnableGzip {
m.Use(macaron.Gziper())
@ -109,14 +112,14 @@ func newMacaron() *macaron.Macaron {
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public"),
macaron.StaticOptions{
SkipLogging: !setting.DisableRouterLog,
SkipLogging: setting.DisableRouterLog,
},
))
m.Use(macaron.Static(
setting.AvatarUploadPath,
macaron.StaticOptions{
Prefix: "avatars",
SkipLogging: !setting.DisableRouterLog,
SkipLogging: setting.DisableRouterLog,
},
))
m.Use(macaron.Renderer(macaron.RenderOptions{
@ -242,7 +245,7 @@ func runWeb(ctx *cli.Context) {
ctx.HandleAPI(404, "Page not found")
})
})
})
}, ignSignIn)
// User.
m.Group("/user", func() {
@ -328,7 +331,7 @@ func runWeb(ctx *cli.Context) {
m.Get("/template/*", dev.TemplatePreview)
}
reqAdmin := middleware.RequireAdmin()
reqRepoAdmin := middleware.RequireRepoAdmin()
// Organization.
m.Group("/org", func() {
@ -380,8 +383,8 @@ func runWeb(ctx *cli.Context) {
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
m.Get("/migrate", repo.Migrate)
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
m.Get("/fork", repo.Fork)
m.Post("/fork", bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
m.Combo("/fork/:repoid").Get(repo.Fork).
Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
}, reqSignIn)
m.Group("/:username/:reponame", func() {
@ -402,8 +405,15 @@ func runWeb(ctx *cli.Context) {
m.Get("/:name", repo.GitHooksEdit)
m.Post("/:name", repo.GitHooksEditPost)
}, middleware.GitHookService())
m.Group("/keys", func() {
m.Combo("").Get(repo.SettingsDeployKeys).
Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.SettingsDeployKeysPost)
m.Post("/delete", repo.DeleteDeployKey)
})
})
}, reqSignIn, middleware.RepoAssignment(true), reqAdmin)
}, reqSignIn, middleware.RepoAssignment(true), reqRepoAdmin)
m.Group("/:username/:reponame", func() {
m.Get("/action/:action", repo.Action)
@ -416,15 +426,20 @@ func runWeb(ctx *cli.Context) {
m.Post("/:index/milestone", repo.UpdateIssueMilestone)
m.Post("/:index/assignee", repo.UpdateAssignee)
m.Get("/:index/attachment/:id", repo.IssueGetAttachment)
m.Post("/labels/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
m.Post("/labels/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
m.Post("/labels/delete", repo.DeleteLabel)
m.Get("/milestones/new", repo.NewMilestone)
m.Post("/milestones/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
m.Get("/milestones/:index/edit", repo.UpdateMilestone)
m.Post("/milestones/:index/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.UpdateMilestonePost)
m.Get("/milestones/:index/:action", repo.UpdateMilestone)
})
m.Group("/labels", func() {
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
m.Post("/delete", repo.DeleteLabel)
}, reqRepoAdmin)
m.Group("/milestones", func() {
m.Get("/new", repo.NewMilestone)
m.Post("/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
m.Get("/:id/edit", repo.EditMilestone)
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
m.Get("/:id/:action", repo.ChangeMilestonStatus)
m.Post("/delete", repo.DeleteMilestone)
}, reqRepoAdmin)
m.Post("/comment/:action", repo.Comment)
@ -433,21 +448,19 @@ func runWeb(ctx *cli.Context) {
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
m.Get("/edit/:tagname", repo.EditRelease)
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, middleware.RepoRef())
}, reqRepoAdmin, middleware.RepoRef())
}, reqSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func() {
m.Get("/releases", middleware.RepoRef(), repo.Releases)
m.Get("/issues", repo.Issues)
m.Get("/issues", repo.RetrieveLabels, repo.Issues)
m.Get("/issues/:index", repo.ViewIssue)
m.Get("/issues/milestones", repo.Milestones)
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
m.Get("/milestones", repo.Milestones)
m.Get("/pulls", repo.Pulls)
m.Get("/branches", repo.Branches)
m.Get("/archive/*", repo.Download)
m.Get("/issues2/", repo.Issues2)
m.Get("/pulls2/", repo.PullRequest2)
m.Get("/labels2/", repo.Labels2)
m.Get("/milestone2/", repo.Milestones2)
m.Group("", func() {
m.Get("/src/*", repo.Home)
@ -460,8 +473,15 @@ func runWeb(ctx *cli.Context) {
}, ignSignIn, middleware.RepoAssignment(true))
m.Group("/:username", func() {
m.Get("/:reponame", ignSignIn, middleware.RepoAssignment(true, true), middleware.RepoRef(), repo.Home)
m.Any("/:reponame/*", ignSignInAndCsrf, repo.Http)
m.Group("/:reponame", func() {
m.Get("", repo.Home)
m.Get(".git", repo.Home)
}, ignSignIn, middleware.RepoAssignment(true, true), middleware.RepoRef())
m.Group("/:reponame", func() {
m.Any("/*", ignSignInAndCsrf, repo.Http)
m.Head("/hooks/trigger", repo.TriggerHook)
})
})
// robots.txt

@ -12,6 +12,10 @@ RUN_MODE = dev
ROOT =
SCRIPT_TYPE = bash
[ui]
; Number of issues that are showed in one page
ISSUE_PAGING_NUM = 10
[server]
PROTOCOL = http
DOMAIN = localhost
@ -87,8 +91,8 @@ ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
DISABLE_MINIMUM_KEY_SIZE_CHECK = false
[webhook]
; Cron task interval in minutes
TASK_INTERVAL = 1
; Hook task queue length
QUEUE_LENGTH = 1000
; Deliver timeout in seconds
DELIVER_TIMEOUT = 5
; Allow insecure certification
@ -104,14 +108,18 @@ SUBJECT = %(APP_NAME)s
; Gmail: smtp.gmail.com:587
; QQ: smtp.qq.com:25
; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
HOST =
HOST =
; Disable HELO operation when hostname are different.
DISABLE_HELO =
; Custom hostname for HELO operation, default is from system.
HELO_HOSTNAME =
; Do not verify the certificate of the server. Only use this for self-signed certificates
SKIP_VERIFY =
; Use client certificate
USE_CERTIFICATE = false
CERT_FILE = custom/mailer/cert.pem
KEY_FILE = custom/mailer/key.pem
; Mail from address, RFC 5322. This can be just an email address, or the "Name" <email@example.com> format
; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
FROM =
; Mailer user name and password
USER =
@ -288,8 +296,25 @@ INTERVAL = 24
ARGS =
[i18n]
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语,Español,Português,Polski
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语,Español,Português,Polski,български,Italiano
; Used for datetimepicker
[i18n.datelang]
en-US = en
zh-CN = zh
zh-HK = zh-TW
de-DE = de
fr-FR = fr
nl-NL = nl
lv-LV = lv
ru-RU = ru
ja-JP = ja
es-ES = es
pt-BR = pt-BR
pl-PL = pl
bg-BG = bg
it-IT = it
[other]
SHOW_FOOTER_BRANDING = false

@ -0,0 +1,13 @@
# CakePHP 3
/vendor/*
/config/app.php
/tmp/*
/logs/*
# CakePHP 2
/app/tmp/*
/app/Config/core.php
/app/Config/database.php
/vendors/*

@ -0,0 +1,2 @@
fuel/app/logs/*/*/*
fuel/app/cache/*/*

@ -0,0 +1,4 @@
/bootstrap/compiled.php
.env.*.php
.env.php
.env

@ -0,0 +1,37 @@
# Cache and logs (Symfony2)
/app/cache/*
/app/logs/*
!app/cache/.gitkeep
!app/logs/.gitkeep
# Cache and logs (Symfony3)
/var/cache/*
/var/logs/*
!var/cache/.gitkeep
!var/logs/.gitkeep
# Parameters
/app/config/parameters.yml
/app/config/parameters.ini
# Managed by Composer
/app/bootstrap.php.cache
/var/bootstrap.php.cache
/bin/*
!bin/console
!bin/symfony_requirements
/vendor/
# Assets and user uploads
/web/bundles/
/web/uploads/
# PHPUnit
/app/phpunit.xml
/phpunit.xml
# Build data
/build/
# Composer PHAR
/composer.phar

@ -0,0 +1,6 @@
assets/*
!assets/.gitignore
protected/runtime/*
!protected/runtime/.gitignore
protected/data/*.db
themes/classic/views/

@ -0,0 +1,20 @@
# Composer files
composer.phar
vendor/
# Local configs
config/autoload/*.local.php
# Binary gettext files
*.mo
# Data
data/logs/
data/cache/
data/sessions/
data/tmp/
temp/
# Legacy ZF1
demos/
extras/documentation

@ -2,10 +2,15 @@
# Order of name is meaningless.
Akihiro YAGASAKI <yaggytter@momiage.com>
Alexander Steinhöfer <kontakt@lx-s.de>
Christoph Kisfeld <christoph.kisfeld@gmail.com>
Daniel Speichert <daniel@speichert.pl>
Huimin Wang <wanghm2009@hotmail.co.jp>
ilko <email>
Thomas Fanninger <gogs.thomas@fanninger.at>
Łukasz Jan Niemier <lukasz@niemier.pl>
Lafriks <lafriks@gmail.com>
Luc Stepniewski <luc@stepniewski.fr>
Miguel de la Cruz <miguel@mcrx.me>
Natan Albuquerque <natanalbuquerque5@gmail.com>
Natan Albuquerque <natanalbuquerque5@gmail.com>
Marc Schiller <marc@schiller.im>

@ -0,0 +1,798 @@
app_desc=Удобна услуга за самостоятелни Git услуги, написана на Go
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=Captcha
repository=Хранилище
organization=Организация
mirror=Mirror
new_repo=Ново хранилище
new_migrate=Нова миграция
new_fork=Създаване на нов форк на хранилището
new_org=Нова организация
manage_org=Управление на организации
admin_panel=Админ панел
account_settings=Настройки на профила
settings=Настройки
news_feed=Емисия новини
pull_requests=Pull Requests
issues=Проблеми
cancel=Отказ
[search]
search=Търсене...
repository=Хранилище
user=Потребител
issue=Проблем
code=Код
[install]
install=Инсталация
title=Стъпки за инсталиране при първоначално стартиране
requite_db_desc=Gogs изисква MySQL, PostgreSQL или SQLite3.
db_title=Настройки на базата данни
db_type=Тип на база данни
host=Хост
user=Потребител
password=Парола
db_name=Име на база данни
db_helper=Моля, използвайте INNODB engine с utf8_general_ci charset за MySQL.
ssl_mode=Режим SSL
path=Път
sqlite_helper=Пък към файла на SQLite3 база данни.
err_empty_sqlite_path=Пътят за SQLite3 база за данни не може да е празен.
general_title=Общи настройки на Gogs
app_name=Име на програмата
app_name_helper=Постави името на твоята организация тук - голямо е крещящо!
repo_path=Основен път към хранилището
repo_path_helper=Всички отдалечени хранилища ще бъдат съхранени в тази папка.
run_user=Run User
run_user_helper=The user must have access to Repository Root Path and run Gogs.
domain=Домейн
domain_helper=Това влияе на URL-адреса за клониране по SSH.
http_port=HTTP порт
http_port_helper=Порт, на който програмата ще слуша.
app_url=URL на програмата
app_url_helper=Този параметър влияе на URL на HTTP/HTTPS и понякога на адреса на електронната поща.
optional_title=Опционални настройки
email_title=Настройка на мейл услугата
smtp_host=SMTP хост
smtp_from=От
smtp_from_helper=Писмо от адрес, RFC 5322. Тя може да бъде мейл адрес или на < email@example.com > формат.
mailer_user=Адрес на изпращача
mailer_password=Парола на изпращача
register_confirm=Включи потвърждението на регистрациите
mail_notify=Включи оповестяването по пощата
server_service_title=Настройки на сървъра и други услуги
offline_mode=Включи офлайн режима
offline_mode_popup=Забранете CDN дори в режим production, всички ресурсни файлове ще бъдат връчени локално.
disable_registration=Изключи саморегистрацията
disable_registration_popup=Изключи потребителската саморегистрация, само администратор може да създава профили.
require_sign_in_view=Изисквай вписване за преглед на страниците
require_sign_in_view_popup=Само вписани потребители могат да виждат страниците, посетителите виждат само страниците за регистрация и вход.
admin_setting_desc=Няма Нужда да създавате администраторски акаунт в момента - потребителя с ID 1 получава администраторски достъп автоматично.
admin_title=Настройки на акаунта на администратора
admin_name=Потребителско име
admin_password=Парола
confirm_password=Потвърждение на паролата
admin_email=Електронна поща
install_gogs=Инсталирай Gogs
test_git_failed=Неуспех при тестването на "git" команда: %v
sqlite3_not_available=Вашата версия не поддържа SQLite3, моля, изтеглете официалната двоичен версия от %s, а не 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. Приятно ползване!
[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.
[modal]
yes=Да
no=Не
modify=Промени
[form]
UserName=Потребителско име
RepoName=Име на хранилище
Email=Адрес на електронната поща
Password=Парола
Retype=Въведете отново паролата си
SSHTitle=Име на SSH ключ
HttpsUrl=HTTPS URL
PayloadUrl=Payload URL
TeamName=Име на екипа
AuthName=Име за ауторизация
AdminEmail=Имейл на администратора
require_error="не може да бъде празен."
alpha_dash_error=`трябва да e валидна буква, число или тире(-_).`
alpha_dash_dot_error=`трябва да e валидна буква, число, тире(-_) или точка.`
size_error=`трябва да е с размер %s.`
min_size_error="трябва да съдържа поне %s знака."
max_size_error="трябва да съдържа най-много %s знака."
email_error=„не е валиден имейл адрес.“
url_error="не е валиден URL адрес."
unknown_error=Непозната грешка:
captcha_incorrect=Captcha не съвпада.
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=Име на публичен ключ или съдържание са били използвани.
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
unable_verify_ssh_key=Gogs не може да провери вашия SSH ключ, но предполагаме, че е валиден, моля, проверете го.
auth_failed=Неуспешно удостоверяване: %v
still_own_repo=Вашата регистрация все още е собственик на поне едно хранилище, вие трябва да изтриете или да ги прехвърлите първо.
still_has_org=Вашата сметка все още има членство в най-малко една организация, вие трябва да напусне или да изтриете вашите членства първо.
org_still_own_repo=Тази организация все още има собственост на хранилище, вие трябва да я изтриете или да я прехвърлите първо.
still_own_user=Тази аутентикация се ползва все още, моля премахнете я от аутентиканцията и опитайте отново.
target_branch_not_exist=Target branch does not exist.
[user]
change_avatar=Сменете вашия аватар на gravatar.com
change_custom_avatar=Промяна на вашия аватар в настройките
join_on=Присъедини се на
repositories=Хранилища
activity=Обществена дейност
followers=Последователи
starred=Избрано
following=Следване
form.name_reserved=Потребителското име "%s" е запазено.
form.name_pattern_not_allowed=Потребителското име «%s» не е допустимо.
[settings]
profile=Профил
password=Парола
ssh_keys=SSH ключове
social=Социални профили
applications=Приложения
orgs=Организации
delete=Изтриване на акаунт
uid=UID
public_profile=Публичен профил
profile_desc=Вашият имейл адрес е публичен и ще бъде използван за всеки свързани с профила ви уведомления и всички уеб базирани операции, направени чрез сайта.
full_name=Пълно име
website=Уебсайт
location=Местоположение
update_profile=Актуализиране на профила ви
update_profile_success=Вашият профил е актуализиран успешно.
change_username=Потребителското име е променено
change_username_desc=Сменихте вашето потребителско име. Това ще засегне връзките сочещи към акаунта ви. Искате ли да продължите?
continue=Продължи
cancel=Отказ
enable_custom_avatar=Разреши потребителски аватар
enable_custom_avatar_helper=Включете тази опция, за да изключите сареждането от Gravatar
choose_new_avatar=Изберете нов аватар
update_avatar=Обнови настройките на аватара
uploaded_avatar_not_a_image=Каченият файл не е изображение.
no_custom_avatar_available=Собствен аватар е забранен, включването е невъзможно.
update_avatar_success=Настройките за аватара са обновени успешно.
change_password=Промени парола
old_password=Текуща парола
new_password=Нова парола
password_incorrect=Въведената парола не е вярна.
change_password_success=Вашата парола бе успешно променена. Сега можете да влезете, използвайки тази нова парола.
emails=Имейл адреси
manage_emails=Управление на имейл адреси
email_desc=Вашият основен имейл адрес ще се използва за известия и други операции.
primary=Основен
primary_email=Задаване като основна
delete_email=Изтриване
add_new_email=Добавяне на нов имейл адрес
add_email=Добавяне на имейл
add_email_confirmation_sent=Нов имейл за потвърждение е бил изпратен до <b>%s</b>, моля, проверете пощенската си кутия в рамките на следващите %d часа, за да завършите процеса на регистрация.
add_email_success=Успешно беше добавен нов имейл адрес.
manage_ssh_keys=Управление на SSH ключове
add_key=Добавяне на ключ
ssh_desc=Това е списък на SSH ключове, свързани с вашия акаунт. Тъй като тези ключове позволяват на всеки, който ги използва да получи достъп до хранилищата ви, много е важно да се уверите, че ги разпознавате.
ssh_helper=<strong>Не знам как?</strong> Проверете на GitHub упътването как да <a href="%s"> създадете свои собствени SSH ключове</a> или решаване на <a href="%s"> Общи проблеми</a>, които може да възникнат при използване на SSH.
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=Социалния профил е освободен.
manage_access_token=Управление на tokens за персонален достъп
generate_new_token=Генерира нов маркер
tokens_desc=Маркерите, които са генерирани и могат да бъдат ползвани за достъп до API-то на Gogs.
new_token_desc=Всеки маркер ще има пълен достъп до вашия акаунт.
token_name=Име на маркера
generate_token=Генериране на маркер
generate_token_succees=Успешно е генериран вашия маркер за достъп! Уверете се, че сте го копирали, тъй като няма да можете да го видите отново!
delete_token=Изтриване
delete_token_success=Този маркер за личен достъп е премахнат успешно! Не забравяйте да актуализирате вашите приложения.
delete_account=Изтриване на вашия акаунт
delete_prompt=Тази операция ще изтрие вашия акаунт завинаги и <strong>няма да може</strong> да се отмени!
confirm_delete_account=Потвърждаване на изтриването
delete_account_title=Изтриване на акаунта
delete_account_desc=Този акаунт ще бъде окончателно изтрит. Искате ли да продължите?
[repo]
owner=Собственик
repo_name=Име на хранилище
repo_name_helper=Добро име на хранилище е име, състоящо от кратки, запомнящи се и уникални ключови думи.
visibility=Видимост
visiblity_helper=Това хранилище е <span class="label label-red label-radius"> частно</span>
fork_repo=Fork на хранилището
fork_from=Fork от
fork_visiblity_helper=Не можете да промените видимостта на форкнато хранилище.
repo_desc=Описание
repo_lang=Език
repo_lang_helper=Изберете .gitignore файл
license=Лиценз
license_helper=Изберете лицензионен файл
init_readme=Инициализиране на това хранилище с README.md
create_repo=Създаване на хранилище
default_branch=Клон по подразбиране
mirror_interval=Интервал на мирроване(часове)
form.name_reserved=Името на хранилището "%s" е запазено.
form.name_pattern_not_allowed=Името на хранилище „%s“ не е позволено.
need_auth=Нужда от удостоверяване
migrate_type=Тип мигриране
migrate_type_helper=НА хранилището ще бъде създаден <span class="label label-blue label-radius">мирор</span>
migrate_repo=Мигриране на хранилището
migrate.clone_address=Клонирай адрес
migrate.invalid_local_path=Невалиден път - не съществува или не е директория.
forked_from=Форкнато от
fork_from_self=Не можете да форкнате хранилище което си е Ваше!
copy_link=Копирай
click_to_copy=Копиране в клипборда
copied=Успешно копирано
clone_helper=Нуждаеш се от помощ при клониране? Посети <a target="_blank" href="%s">Помощ</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=Issues
labels=Етикети
milestones=Етапи
commits=Комити
releases=Релийзи
file_raw=Суров
file_history=История
file_view_raw=Прегледай в суров вид
file_permalink=Твърса връзка
commits.commits=Комити
commits.search=Търсене на комити
commits.find=Намери
commits.author=Автор
commits.message=Съобщение
commits.date=Дата
commits.older=По-стари
commits.newer=По-нови
issues.new=Нов въпрос
issues.new_label=Нов етикет
issues.new_label_placeholder=Име на етикет...
issues.open_tab=%d отворени
issues.close_tab=%d затворени
issues.filter_label=Етикет
issues.filter_label_no_select=Не е избран етикет
issues.filter_milestone=Етап
issues.filter_assignee=Назначена на
issues.filter_type=Тип
issues.filter_type.all_issues=Всички въпроси
issues.filter_type.assigned_to_you=Назначени на теб
issues.filter_type.created_by_you=Създадени от теб
issues.filter_type.mentioning_you=Които те споменават
issues.opened_by=отворен %[1]s от <a href="/%[2]s">%[2]s</a>
issues.previous=Предишна
issues.next=Следваща
issues.label_title=Име на етикет
issues.label_color=Цвят на етикет
issues.label_count=%d етикети
issues.label_open_issues=%d отворени въпроси
issues.label_edit=Редакция
issues.label_delete=Изтриване
issues.label_modify=Модифициране на етикет
issues.label_deletion=Изтриване на етикет
issues.label_deletion_desc=Изтриване на етикет ще премахне информацията за него във всички свързани въпроси. Желаете ли да продължите?
issues.label_deletion_success=Етикетът е изтрит успешно!
settings=Настройки
settings.options=Опции
settings.collaboration=Сътрудничество
settings.hooks=Webhooks
settings.githooks=Git Hooks
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=Добави Webhook
settings.hooks_desc=Webhooks са много като основните HTTP POST тригери. Когато нещо се случи в Gogs, ние ще пратим уведомлението до хоста, който е посочвате. Научете повече в това <a target="_blank" href="%s"> Webhooks ръководство</a>.
settings.githooks_desc=Git Hooks се изпълняват от Git, вие може да промените файловете на поддъръжаните хуукове в списъка отдолу, за да може да изпълнявате персонализирани операции.
settings.githook_edit_desc=Ако хуукът е неактивен, примерно съдържание ще бъдат представено. Ако оставите съдържанието празна стойност този хуук ще бъде изключен.
settings.githook_name=Име на хуук
settings.githook_content=Съдържание на хуука
settings.update_githook=Обнови хуука
settings.remove_hook_success=Webhook е бил изтрит.
settings.add_webhook_desc=Gogs ще изпрати <code>POST</code> заявка към ядрес който укажете, заедно с информация за събитието, което е настъпило. Можете също да укажете какъв формат на данни желаете да получите при задействане на куката (JSON, x-www-form-urlencoded, XML, и т.н.). Повече информация можете да намерите в нашето <a target="_blank" href="%s">Ръководство за уеб-куки</a>.
settings.payload_url=Payload URL
settings.content_type=Тип на съдържанието
settings.secret=Тайна
settings.event_desc=При какви събития да се задейства този webhook?
settings.event_push_only=Само <code>пуш</code> събитието.
settings.active=Активен
settings.active_helper=Подробности относно събитието извикало хуука ще бъде също представена.
settings.add_hook_success=Нова webhook е добавен.
settings.update_webhook=Актуализация на Webhook
settings.update_hook_success=Webhook е бил актуализиран.
settings.delete_webhook=Изтриване на Webhook
settings.recent_deliveries=Последните доставки
settings.hook_type=Вид на хуука
settings.add_slack_hook_desc=Добавяне на интеграция с <a href="%s">Slack</a> в вашето хранилище.
settings.slack_token=Маркер
settings.slack_domain=Домейн
settings.slack_channel=Канал
diff.browse_source=Преглед на кода
diff.parent=родител
diff.commit=commit
diff.data_not_available=Няма Diff данни.
diff.show_diff_stats=Покажи Diff статистика
diff.stats_desc=<strong>%d променени файлове</strong> с <strong>%d допълнения</strong> и <strong>изравания %d</strong>
diff.bin=BIN
diff.view_file=Преглед на файла
release.releases=Релийзи
release.new_release=Нов релийз
release.draft=Чернова
release.prerelease=Предварително издание
release.stable=Стабилна
release.edit=редактиране
release.ahead=<strong>%d</strong> комит(а) %s след последния издание
release.source_code=Програмен код
release.tag_name=Име на етикет
release.target=Цел
release.tag_helper=Изберете съществуващ етикет или създайте нов етикет при публикуване.
release.release_title=Заглавие на изданието
release.content_with_md=Съдържание с <a href="%s"> Markdown</a>
release.write=Писане
release.preview=Преглед
release.content_placeholder=Напишете някакво съдържание
release.loading=Зареждане...
release.prerelease_desc=Това е предварително издание
release.prerelease_helper=Ние ще се отбележим, че тази версия не е готова за производство.
release.publish=Публично издание
release.save_draft=Запази чернова
release.edit_release=Редактиране на изданието
release.tag_name_already_exist=Релийз с таг с такова име вече съществува.
[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=Какво ниво на достъп трябва да има този отбор?
form.name_reserved=Името за организация "%s" е запазено.
form.name_pattern_not_allowed=Името на хранилището „%s“ не е позволено.
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=Добави webhooks, който ще бъде използван за <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=Екипът може да пушва и пулва в своите хранилища и да добавя collaborators.
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>: членовете могат да четат от и пушват към хранилищата на екипа.
teams.admin_permission_desc=Този екип получава <strong>администраторски</strong> достъп: членовете могат да четат, да пушват и добавя сътрудници към хранилищата на екипа.
teams.repositories=Хранилища на екипа
teams.add_team_repository=Добави хранилище на екипа
teams.remove_repo=Премахни
teams.add_nonexistent_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> watches, <b>%d</b> stars, <b>%d</b> действия, <b>%d</b> accesses, <b>%d</b> issues, <b>%d</b> коментари, <b>%d</b> социални accounts, <b>%d</b> последователи , <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> login soureces, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> label, <b>%d</b> hook tasks <b>%d</b> teams, <b>%d</b> update tasks, <b>%d</b> attachments.
dashboard.operation_name=Име на операцията
dashboard.operation_switch=Превключване
dashboard.operation_run=Стартиране
dashboard.clean_unbind_oauth=Изчисти несвързаните OAuthes
dashboard.clean_unbind_oauth_success=Всички неизползвани OAuthes са изтрити успешно.
dashboard.delete_inactivate_accounts=Изтриване на всички неактивни профили
dashboard.delete_inactivate_accounts_success=Всички неактивни профили са изтрити успешно.
dashboard.delete_repo_archives=Изтрий всички архиви на хранилищата
dashboard.delete_repo_archives_success=Всички архиви на хранилищата са били изтрити успешно.
dashboard.git_gc_repos=Почисти ненужните данни в хранилищата
dashboard.git_gc_repos_success=Всички хранилища са изпълнили garbage collection успешно.
dashboard.resync_all_sshkeys=Презапис на ".ssh/authorized_keys" файл (внимание: не-Gogs ключове ще бъдат загубени)
dashboard.resync_all_sshkeys_success=Всички публични ключове са били презаписани успешно.
dashboard.resync_all_update_hooks=Пренапише всички хуукове за обновяване на хранилищата (необходимо, когато се ползва собствен път за конфигурацията)
dashboard.resync_all_update_hooks_success=Всички куки закачени на актуализация на хранилище са пренаписани успешно.
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=Заделена осн. памет
dashboard.heap_memory_idle=Празна осн. памет
dashboard.heap_memory_in_use=Използвана осн. памет
dashboard.heap_memory_released=Освободена осн. памет
dashboard.heap_objects=Обекти в осн. памет
dashboard.bootstrap_stack_usage=Изпалзван стек за bootstrap
dashboard.stack_memory_obtained=Заделена памет в стека
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=Получени Profiling Bucket Hash Table
dashboard.gc_metadata_obtained=Получени GC метаданни
dashboard.other_system_allocation_obtained=Получена друга системна памет
dashboard.next_gc_recycle=Слeдващо рециклиране на GC
dashboard.last_gc_time=Време от последен GC
dashboard.total_gc_time=Общо време за GC
dashboard.total_gc_pause=Общо пауза за GC
dashboard.last_gc_pause=Последна пауза за GC
dashboard.gc_times=Брой GC
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.allow_git_hook=Този профил има разрешение да създава Git hooks
users.update_profile=Обнови профила
users.delete_account=Изтриване на акаунта
users.still_own_repo=Този профил е собственик на поне едно хранилище. Трябва да ги изтриете или предадете на друг преди това.
users.still_has_org=Този потребител е поне в една организация. Първо трябва да излезете от или изтриете тези организации.
orgs.org_manage_panel=Управление на организациите
orgs.name=Име
orgs.teams=Екипи
orgs.members=Членове
repos.repo_manage_panel=Управление на хранилищата
repos.owner=Собственик
repos.name=Име
repos.private=Личен
repos.watches=Watches
repos.stars=Stars
repos.issues=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=Основен DN
auths.attribute_username=Атрибут на потребителско име
auths.attribute_name=Атрибут име
auths.attribute_surname=Атрибут фамилия
auths.attribute_mail=E-Mail атрибут
auths.filter=Филтър за търсене
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Вид на SMTP удостоверяване
auths.smtphost=SMTP хост
auths.smtpport=SMTP порт
auths.enable_tls=Разрешаване на TLS шифроване
auths.pam_service_name=Име на PAM услуга
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=Run User
config.run_mode=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.show_registration_button=Покажи бутон за регистрация
config.require_sign_in_view=Изисква влизане за преглед
config.mail_notify=Уведомяване по поща
config.enable_cache_avatar=Разрешено кеширане на аватари
config.active_code_lives=Кодове за активиране
config.reset_password_code_lives=Кодове за ресет на парола
config.webhook_config=Webhook настройки
config.task_interval=Интервал на повторение
config.deliver_timeout=Време за отказ на доставка
config.skip_tls_verify=Пропусни TLS проверката
config.mailer_config=Мейлър конфигурация
config.mailer_enabled=Включено
config.mailer_disable_helo=Изключи HELO
config.mailer_name=Име
config.mailer_host=Хост
config.mailer_user=Потребител
config.oauth_config=OAuth конфигурация
config.oauth_enabled=Активиран
config.cache_config=Конфигурация на кеша
config.cache_adapter=Кеш адаптер
config.cache_interval=Кеш интервал
config.cache_conn=Кеш на връзката
config.session_config=Конфигурация на сесията
config.session_provider=Доставчик на сесия
config.provider_config=Конфигурация на доставчик
config.cookie_name=Име на бисквитка
config.enable_set_cookie=Разреши установяване на бисквитки
config.gc_interval_time=GC през интервал
config.session_life_time=Време на живот на сесията
config.https_only=HTTPS само
config.cookie_life_time=Време на живот на бисквитка
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=Op.
notices.delete_success=Системното съобщение е изтрито успешно.
[action]
create_repo=създадено е хранилище <a href="%s"> %s</a>
commit_repo=пушнато към <a href="%s/src/%s">%[2]s</a> в <a href="%[1]s">%[3]s</a>
create_issue=`отворен въпрос <a href="%s/issues/%s">%s#%[2]s"</a>`
comment_issue=`коментира въпрос <a href="%s/issues/%s">%s#%[2]s"</a>`
transfer_repo=прехвърлено хранилище: от <code>%s</code> към <a href="%s"> %s</a>
push_tag=пушнат етикет <a href="%s/src/%s">%[2]s</a> към <a href="%[1]s">[3]s</a>
compare_2_commits=Виж сравнението между тези 2 комита
[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=минути

@ -39,10 +39,18 @@ issues=Issues
cancel=Abbrechen
[search]
search=Suchen...
repository=Repository
user=Benutzer
issue=Problem
code=Code
[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_title=Datenbankeinstellungen
db_type=Datenbanktyp
host=Host
user=Benutzer
@ -52,7 +60,11 @@ db_helper=Bitte verwenden InnoDB-Engine mit utf8_general_ci Zeichensatz für MyS
ssl_mode=SSL-Modus
path=Pfad
sqlite_helper=Der Dateipfad des SQLite3 Datenbank.
err_empty_sqlite_path=Pfad zur SQLite3-Datenbank darf nicht leer sein.
general_title=Allgemeine Einstellungen von Gogs
app_name=Anwendungsname
app_name_helper=Hier den Organisationsnamen einfügen.
repo_path=Repository Root-Verzeichnispfad
repo_path_helper=Alle Git-Repositorys werden in diesem Verzeichnis gespeichert.
run_user=Ausführender Benutzer
@ -63,13 +75,24 @@ http_port=HTTP Port
http_port_helper=Auf dieser Port Nummer ist die Apllikation erreichbar.
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)
optional_title=Optionale Einstellungen
email_title=E-Mail-Service Einstellungen
smtp_host=SMTP Host
smtp_from=Von
smtp_from_helper=Absender-Adresse nach RFC 5322. Entweder nur eine E-Mail Adresse oder im folgenden Format: "Name" <email@example.com>.
mailer_user=Sender E-mail
mailer_password=Sender Passwort
notify_title=Benachrichtigungseinstellungen (optional)
register_confirm=Registrierungsbestätigung aktvieren
mail_notify=E-Mail-Benachrichtgung aktivieren
server_service_title=Server- und sonstige Diensteinstellungen
offline_mode=Offline-Modus aktivieren
offline_mode_popup=Deaktiviere das CDN auch im Produktionsmodus, alle Dateien werden von diesem Server ausgeliefert.
disable_registration=Benutzerregistrierung deaktivieren
disable_registration_popup=Deaktiviere die Benutzerregistrierung, nur Administratoren können Benutzerkonten anlegen.
require_sign_in_view=Erfordere Anmeldung, um Inhalte anzusehen
require_sign_in_view_popup=Lediglich angemeldete Benutzer können Inhalte betrachten, Gäste sehen nur die Anmelden/Registrieren Seite.
admin_setting_desc=Sie müssen jetzt noch keinen Administrator-Account anlegen. Der erste Benutzer ("ID=1") erhält automatisch Administrationsrechte.
admin_title=Konto-Einstellungen für den Administrator
admin_name=Benutzername
admin_password=Passwort
@ -83,7 +106,7 @@ 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.
install_success=Herzlich Willkommen! Wir sind froh, dass du dich für Gogs entschieden hast. Wir wünschen viel Vergnügen damit.
[home]
uname_holder=Benutzername oder E-Mail
@ -120,6 +143,11 @@ invalid_code=Es tut uns leid, der Bestätigungscode ist abgelaufen oder ungülti
reset_password_helper=Hier klicken, um das Passwort zurückzusetzen
password_too_short=Das Passwort muss mindenstens 6 Zeichen lang sein
[modal]
yes=Ja
no=Nein
modify=Ändern
[form]
UserName=Benutzername
RepoName=Repository-Name
@ -136,6 +164,7 @@ AdminEmail=Admin E-mail
require_error=` darf nicht leer sein.`
alpha_dash_error=` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
alpha_dash_dot_error=` kann ausschließlich alphanumerische Zeichen und ".-_" enthalten.`
size_error=` muss die Größe %s haben.`
min_size_error=` muss mindestens %s Zeichen enthalten.`
max_size_error=` darf höchstens %s Zeichen enthalten.`
email_error=` ist keine gültige E-Mail-Adresse.`
@ -150,26 +179,23 @@ org_name_been_taken=Organisationsname ist bereits vergeben.
team_name_been_taken=Teamname ist bereits vergeben.
email_been_used=E-Mail-Adresse wird bereits verwendet.
ssh_key_been_used=SSH-Schlüsselname wird bereits verwendet.
illegal_username=Benutzername enthält ungültige Zeichen.
illegal_repo_name=Repository-Name enthält ungültige Zeichen.
illegal_org_name=Organisationsname enthält ungültige Zeichen.
illegal_team_name=Teamname enthält ungültige Zeichen.
username_password_incorrect=Benutzername oder Passwort ist nicht korrekt.
enterred_invalid_repo_name=Bitte stelle sicher, dass der eingegeben Repository-Name richtig ist.
enterred_invalid_owner_name=Bitte stelle sicher, dass der eingegeben Besitzername richtig ist.
enterred_invalid_repo_name=Bitte stelle sicher, dass der eingegebene Repository-Name richtig ist.
enterred_invalid_owner_name=Bitte stelle sicher, dass der eingegebene Besitzername richtig ist.
enterred_invalid_password=Bitte stelle sicher, dass das eingegebene Passwort richtig ist.
user_not_exist=Angegebener Benutzer existiert nicht.
last_org_owner=Der zu entfernende Benutzer ist der letzte Teambesitzer. Es muss einen anderen Besitzer geben.
last_org_owner=Der zu entfernende Benutzer ist der letzte Besitzer einer Organisation. Diese müssen zuerst gelöscht oder übertragen werden.
invalid_ssh_key=Leider sind wir nicht in der Lage, deinen SSH-Schlüssel zu überprüfen: %s
unable_verify_ssh_key=Gogs kann deinen SSH-Schlüssel nicht verifizieren, nimmt aber an, dass er gültig ist. Bitte stelle dies selbst sicher.
auth_failed=Authentifizierung fehlgeschlagen: %v
still_own_repo=Dein Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
still_own_repo=Dein Konto besitzt noch Repositories. Diese müssen zuerst gelöscht oder übertragen werden.
still_has_org=Du bist noch Mitglied einer Organisation, bitte lösche zunächst diese Mitgliedschaft.
org_still_own_repo=Diese Organisation besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
still_own_user=Diese Authentifizierung wird noch von einigen Benutzern genutzt. Entferne diese zuvor und lösche erneut.
still_own_user=Diese Authentifizierung wird noch von einigen Benutzern genutzt, diese müssen zuerst gelöscht oder deren Authentifizierung geändert werden.
target_branch_not_exist=Ziel-Branch existiert nicht
@ -183,6 +209,9 @@ followers=Folgen
starred=Markiert
following=Folgt
form.name_reserved=Der Benutzername '%s' ist reserviert.
form.name_pattern_not_allowed=Benutzernamens-Muster "%s" ist nicht zulässig.
[settings]
profile=Profil
password=Passwort
@ -227,6 +256,7 @@ primary_email=Als primäre Adresse verwenden
delete_email=Löschen
add_new_email=Neue E-Mail-Adresse hinzufügen
add_email=E-Mail-Adresse hinzufügen
add_email_confirmation_sent=Eine neue Bestätigungsmail wurde an <b>%s</b> gesendet, bitte überprüfen Sie Ihren Posteingang innerhalb von %d Stunden um die Bestätigung abzuschließen.
add_email_success=Deine neue E-Mail-Adresse wurde erfolgreich hinzugefügt.
manage_ssh_keys=SSH-Schlüssel verwalten
@ -282,6 +312,9 @@ create_repo=Repository erstellen
default_branch=Standard-Branch
mirror_interval=Spiegel-Intervall (in Stunden)
form.name_reserved=Repository-Name '%s' ist bereits vergeben.
form.name_pattern_not_allowed=Repository-Namesmuster '%s' ist nicht zulässig.
need_auth=Authorisierung benötigt
migrate_type=Migrationstyp
migrate_type_helper=Dieses Repository wird ein <span class="label label-blue label-radius">Spiegel</span>
@ -289,6 +322,8 @@ migrate_repo=Repository migrieren
migrate.clone_address=Adresse kopieren
migrate.invalid_local_path=Lokaler Pfad ist ungültig, er existiert nicht oder ist kein Ordner.
forked_from=Geforkt von
fork_from_self=SIe können kein Repository forken, das ihnen gehört!
copy_link=Kopieren
click_to_copy=In Zwischenablage kopieren
copied=Kopiert OK
@ -311,11 +346,14 @@ branch_and_tags=Branches & Tags
branches=Branches
tags=Markierungen
issues=Issues
labels=Label
milestones=Meilensteine
commits=Commits
releases=Veröffentlichungen
file_raw=Roh
file_history=Verlauf
file_view_raw=Ansicht Roh
file_permalink=Permalink
commits.commits=Commits
commits.search=Durchsuche Commits
@ -326,6 +364,34 @@ commits.date=Datum
commits.older=Älter
commits.newer=Neuer
issues.new=Neues Problem
issues.new_label=Neues Label
issues.new_label_placeholder=Label-Name...
issues.open_tab=%d offen
issues.close_tab=%d geschlossen
issues.filter_label=Label
issues.filter_label_no_select=Kein Label gewählt
issues.filter_milestone=Meilenstein
issues.filter_assignee=Beauftragter
issues.filter_type=Typ
issues.filter_type.all_issues=Alle Probleme
issues.filter_type.assigned_to_you=Dir zugewiesen
issues.filter_type.created_by_you=Erstellt von dir
issues.filter_type.mentioning_you=Erwähnen dich
issues.opened_by=eröffnet %[1]s von <a href="/%[2]s">%[2]s</a>
issues.previous=Vorherige Seite
issues.next=Nächste Seite
issues.label_title=Label Name
issues.label_color=Label Farbe
issues.label_count=%d Labels
issues.label_open_issues=%d offene Probleme
issues.label_edit=Bearbeiten
issues.label_delete=Löschen
issues.label_modify=Label Änderung
issues.label_deletion=Label Löschung
issues.label_deletion_desc=Das Löschen eines Labels entfernt es von allen verknüpften Issues. Möchtest du fortfahren?
issues.label_deletion_success=Label wurde erfolgreich gelöscht!
settings=Einstellungen
settings.options=Optionen
settings.collaboration=Zusammenarbeit
@ -339,7 +405,7 @@ settings.update_settings=Aktualisierungseinstellungen
settings.change_reponame=Name des Repositories geändert
settings.change_reponame_desc=Repository-Name wurde geändert, möchtest du fortfahren? Dies beeinträchtigt sämtliche Links, die dieses Repository betreffen.
settings.transfer=Besitz übertragen
settings.transfer_desc=Übertrage dieses Repository einem anderen Benutzer oder einer Organisation.
settings.transfer_desc=Übertrage dieses Repository einem anderen Benutzer oder einer Organisation in der du Admin-Rechte hast.
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öscht ist, gibt es keinen Weg zurück. Sei dir sicher!
@ -354,14 +420,14 @@ settings.add_collaborator_success=Mitarbeiter hinzugefügt
settings.remove_collaborator_success=Mitarbeiter entfernt
settings.user_is_org_member=Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
settings.add_webhook=Webhook hinzufügen
settings.hooks_desc=Webhooks erlauben es externe Dienste zu informieren, wenn etwas bestimmtes in deinem Repository passiert. GoGS sendet dann eine POST-Request an alle angegebenen URLs. Erfahre mehr in unserem <a target="_blank" href="%s">Webhooks Guide</a>.
settings.hooks_desc=Webhooks erlauben es dir, externe Dienste zu informieren, wenn etwas bestimmtes in deinem Repository passiert. Gogs sendet dann einen POST-Request an alle angegebenen URLs. Erfahre mehr in unserem <a target="_blank" href="%s">Webhooks Guide</a>.
settings.githooks_desc=Git-Hooks werden von Git selbst bereitgestellt. Du kannst die Dateien der unterstützten Hooks in der Liste unten bearbeiten, um eigene Operationen einzubinden.
settings.githook_edit_desc=Wenn ein Hook nicht aktiv ist, wird der Standardinhalt benutzt. Lasse den Inhalt leer, um den Hook zu deaktivieren.
settings.githook_name=Hook-Name
settings.githook_content=Hook-Inhalt
settings.update_githook=Aktualisiere Hook
settings.remove_hook_success=Webhook entfernt
settings.add_webhook_desc=GoGS sendet einen <code>POST</code>-Request an die unten stehende URL mit Details aller abonnierten Ereignisse. Du kannst auch angeben, welches Datenformat du erhalten willst (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mehr Informationen findest du im <a target="_blank" href="%s">Webhooks Guide</a>.
settings.add_webhook_desc=Gogs sendet einen <code>POST</code>-Request an die unten stehende URL mit Details aller abonnierten Ereignisse. Du kannst auch angeben, welches Datenformat du erhalten willst (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mehr Informationen findest du im <a target="_blank" href="%s">Webhooks Guide</a>.
settings.payload_url=Payload-URL
settings.content_type=Inhaltstyp
settings.secret=Secret
@ -432,6 +498,9 @@ team_name_helper=Verwende diesen Namen, um dich auf dieses Team zu beziehen.
team_desc_helper=Was hat es mit diesem Team auf sich?
team_permission_desc=Welche Berechtigungsstufe soll das Team haben?
form.name_reserved=Organisationsname '%s' ist bereits vergeben.
form.name_pattern_not_allowed=Organisations-Namensmuster '%s' ist nicht zulässig.
settings=Einstellungen
settings.options=Optionen
settings.full_name=Vollständiger Name
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=Alle Repository-Archive löschen
dashboard.delete_repo_archives_success=Alle Repositoriy-Archive wurden gelöscht.
dashboard.git_gc_repos=Führe Garbage Collection auf Repositories aus
dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt.
dashboard.resync_all_sshkeys=Überschreibe '.ssh/authorized_key' Datei (Warnung: Keys, die nicht zu Gogs gehören werden verloren gehen)
dashboard.resync_all_sshkeys=Überschreibe '.ssh/authorized_keys' Datei (Warnung: Keys, die nicht zu Gogs gehören werden verloren gehen)
dashboard.resync_all_sshkeys_success=Alle öffentlichen Keys sind erfolgreich neu geschrieben worden.
dashboard.resync_all_update_hooks=Überschreibe alle Hooks der Repositories (benötigt, wenn sich der Pfad in der Konfiguration ändert)
dashboard.resync_all_update_hooks_success=Die Hooks aller Repositories sind erfolgreich neu geschrieben worden.
@ -567,7 +636,7 @@ users.is_admin=Dieses Konto hat Administratorrechte
users.allow_git_hook=Dieses Konto ist berechtigt, Git-Hooks zu erstellen
users.update_profile=Kontoprofil aktualisieren
users.delete_account=Dieses Konto löschen
users.still_own_repo=Dieses Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
users.still_own_repo=Dieses Konto besitzt noch Repositories. Diese müssen zuerst gelöscht oder übertragen werden.
users.still_has_org=Dieses Konto ist noch Mitglied einer Organisation, bitte entferne diese Mitgliedschaft zuerst.
orgs.org_manage_panel=Organisationenverwaltung
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP-Authentifizierungstyp
auths.smtphost=SMTP-Host
auths.smtpport=SMTP-Port
auths.enable_tls=TLS-Verschlüsselung aktivieren
auths.pam_service_name=PAM Dienstname
auths.enable_auto_register=Automatische Registrierung aktivieren
auths.tips=Tipps
auths.edit=Authentifizierungseinstellungen bearbeiten
@ -653,6 +723,7 @@ config.deliver_timeout=Zeitlimit für Zustellung
config.skip_tls_verify=TLS verifikation überspringen
config.mailer_config=Mailer-Einstellungen
config.mailer_enabled=Aktiviert
config.mailer_disable_helo=HELO Deaktivieren
config.mailer_name=Name
config.mailer_host=Host
config.mailer_user=Benutzer

@ -50,6 +50,7 @@ code = Code
install = Installation
title = Install Steps For First-time Run
requite_db_desc = Gogs requires MySQL, PostgreSQL or SQLite3.
db_title = Database Settings
db_type = Database Type
host = Host
user = User
@ -59,7 +60,11 @@ db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL.
ssl_mode = SSL Mode
path = Path
sqlite_helper = The file path of SQLite3 database.
general_title = General Settings of Gogs
err_empty_sqlite_path = SQLite3 database path cannot be empty.
general_title = Application General Settings
app_name = Application Name
app_name_helper = Put your organization name here huge and loud!
repo_path = Repository Root Path
repo_path_helper = All Git remote repositories will be saved to this directory.
run_user = Run User
@ -70,13 +75,24 @@ http_port = HTTP Port
http_port_helper = Port number which application will listen on.
app_url = Application URL
app_url_helper = This affects HTTP/HTTPS clone URL and somewhere in e-mail.
email_title = E-mail Service Settings (Optional)
optional_title = Optional Settings
email_title = E-mail Service Settings
smtp_host = SMTP Host
smtp_from = From
smtp_from_helper = Mail from address, RFC 5322. It can be just an email address, or the "Name" <email@example.com> format.
mailer_user = Sender E-mail
mailer_password = Sender Password
notify_title = Notification Settings (Optional)
register_confirm = Enable Register Confirmation
mail_notify = Enable Mail Notification
server_service_title = Server and Other Services Settings
offline_mode = Enable Offline Mode
offline_mode_popup = Disable CDN even in production mode, all resource files will be served locally.
disable_registration = Disable Self-registration
disable_registration_popup = Disable user self-registration, only admin can create accounts.
require_sign_in_view = Enable Require Sign In to View Pages
require_sign_in_view_popup = Only signed in users can view pages, visitors will only be able to see sign in/up pages.
admin_setting_desc = You do not have to create an admin account right now, user whoever ID=1 will gain admin access automatically.
admin_title = Admin Account Settings
admin_name = Username
admin_password = Password
@ -127,6 +143,11 @@ invalid_code = Sorry, your confirmation code has expired or not valid.
reset_password_helper = Click here to reset your password
password_too_short = Password length cannot be less then 6.
[modal]
yes = Yes
no = No
modify = Modify
[form]
UserName = Username
RepoName = Repository name
@ -143,6 +164,7 @@ AdminEmail = Admin E-mail
require_error = ` cannot be empty.`
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.`
alpha_dash_dot_error = ` must be valid alpha or numeric or dash(-_) or dot characters.`
size_error = ` must be size %s.`
min_size_error = ` must contain at least %s characters.`
max_size_error = ` must contain at most %s characters.`
email_error = ` is not a valid e-mail address.`
@ -156,10 +178,6 @@ repo_name_been_taken = Repository name has been already taken.
org_name_been_taken = Organization name has been already taken.
team_name_been_taken = Team name has been already taken.
email_been_used = E-mail address has been already used.
ssh_key_been_used = Public key name or content has been used.
illegal_username = Your username contains illegal characters.
illegal_repo_name = Repository name contains illegal characters.
illegal_org_name = Organization name contains illegal characters.
illegal_team_name = Team name contains illegal characters.
username_password_incorrect = Username or password is not correct.
enterred_invalid_repo_name = Please make sure that the repository name you entered is correct.
@ -190,6 +208,9 @@ followers = Followers
starred = Starred
following = Following
form.name_reserved = Username '%s' is reserved.
form.name_pattern_not_allowed = Username pattern '%s' is not allowed.
[settings]
profile = Profile
password = Password
@ -242,13 +263,16 @@ add_key = Add Key
ssh_desc = This is a list of SSH keys associated with your account. As these keys allow anyone using them to gain access to your repositories, it is highly important that you make sure you recognize them.
ssh_helper = <strong>Don't know how?</strong> Check out GitHub's guide to <a href="%s">create your own SSH keys</a> or solve <a href="%s">common problems</a> you might encounter using SSH.
add_new_key = Add SSH Key
ssh_key_been_used = Public key content has been used.
ssh_key_name_used = Public key with same name has already existed.
key_name = Key Name
key_content = Content
add_key_success = New SSH Key has been added!
add_key_success = New SSH key '%s' has been added successfully!
delete_key = Delete
add_on = Added on
last_used = Last used on
no_activity = No recent activity
key_state_desc = This key is used in last 7 days
manage_social = Manage Associated Social Accounts
social_desc = This is a list of associated social accounts. Remove any binding that you do not recognize.
@ -276,7 +300,7 @@ owner = Owner
repo_name = Repository Name
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
visibility = Visibility
visiblity_helper = This repository is <span class="label label-red label-radius">Private</span>
visiblity_helper = This repository is <span class="ui red text">Private</span>
fork_repo = Fork Repository
fork_from = Fork From
fork_visiblity_helper = You cannot alter the visibility of a forked repository.
@ -290,6 +314,9 @@ create_repo = Create Repository
default_branch = Default Branch
mirror_interval = Mirror Interval (hour)
form.name_reserved = Repository name '%s' is reserved.
form.name_pattern_not_allowed = Repository name pattern '%s' is not allowed.
need_auth = Need Authorization
migrate_type = Migration Type
migrate_type_helper = This repository will be a <span class="label label-blue label-radius">mirror</span>
@ -297,6 +324,8 @@ migrate_repo = Migrate Repository
migrate.clone_address = Clone Address
migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
forked_from = forked from
fork_from_self = You cannot fork repository you already owned!
copy_link = Copy
click_to_copy = Copy to clipboard
copied = Copied OK
@ -319,11 +348,14 @@ branch_and_tags = Branches & Tags
branches = Branches
tags = Tags
issues = Issues
labels = Labels
milestones = Milestones
commits = Commits
releases = Releases
file_raw = Raw
file_history = History
file_view_raw = View Raw
file_permalink = Permalink
commits.commits = Commits
commits.search = Search commits
@ -334,12 +366,64 @@ commits.date = Date
commits.older = Older
commits.newer = Newer
issues.new = New Issue
issues.new_label = New Label
issues.new_label_placeholder = Label name...
issues.open_tab = %d Open
issues.close_tab = %d Closed
issues.filter_label = Label
issues.filter_label_no_select = No selected label
issues.filter_milestone = Milestone
issues.filter_milestone_no_select = No selected milestone
issues.filter_assignee = Assignee
issues.filter_type = Type
issues.filter_type.all_issues = All issues
issues.filter_type.assigned_to_you = Assigned to you
issues.filter_type.created_by_you = Created by you
issues.filter_type.mentioning_you = Mentioning you
issues.opened_by = opened %[1]s by <a href="/%[2]s">%[2]s</a>
issues.previous = Previous
issues.next = Next
issues.label_title = Label name
issues.label_color = Label color
issues.label_count = %d labels
issues.label_open_issues = %d open issues
issues.label_edit = Edit
issues.label_delete = Delete
issues.label_modify = Label Modification
issues.label_deletion = Label Deletion
issues.label_deletion_desc = Delete this label will remove its information in all related issues. Do you want to continue?
issues.label_deletion_success = Label has been deleted successfully!
milestones.new = New Milestone
milestones.open_tab = %d Open
milestones.close_tab = %d Closed
milestones.closed = Closed %s
milestones.no_due_date = No due date
milestones.open = Open
milestones.close = Close
milestones.new_subheader = Create milestones to organize your issues.
milestones.create = Create Milestone
milestones.title = Title
milestones.desc = Description
milestones.due_date = Due Date (optional)
milestones.clear = Clear
milestones.invalid_due_date_format = Due date format is invalid, must be 'year-mm-dd'.
milestones.create_success = Milestone '%s' has been created successfully!
milestones.edit = Edit Milestone
milestones.edit_subheader = Use better description for milestones so people won't be confused.
milestones.cancel = Cancel
milestones.modify = Modify Milestone
milestones.edit_success = Changes of milestone '%s' has been saved successfully!
milestones.deletion = Milestone Deletion
milestones.deletion_desc = Delete this milestone will remove its information in all related issues. Do you want to continue?
milestones.deletion_success = Milestone has been deleted successfully!
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
@ -387,6 +471,17 @@ settings.add_slack_hook_desc = Add <a href="%s">Slack</a> integration to your re
settings.slack_token = Token
settings.slack_domain = Domain
settings.slack_channel = Channel
settings.deploy_keys = Deploy Keys
settings.add_deploy_key = Add Deploy Key
settings.no_deploy_keys = You haven't added any deploy key.
settings.title = Title
settings.deploy_key_content = Content
settings.key_been_used = Deploy key content has been used.
settings.key_name_used = Deploy key with same name has already existed.
settings.add_key_success = New deploy key '%s' has been added successfully!
settings.deploy_key_deletion = Delete Deploy Key
settings.deploy_key_deletion_desc = Delete this deploy key will remove all related accesses for this repository. Do you want to continue?
settings.deploy_key_deletion_success = Deploy key has been deleted successfully!
diff.browse_source = Browse Source
diff.parent = parent
@ -440,6 +535,9 @@ team_name_helper = You'll use this name to mention this team in conversations.
team_desc_helper = What is this team all about?
team_permission_desc = What permission level should this team have?
form.name_reserved = Organization name '%s' is reserved.
form.name_pattern_not_allowed = Organization name pattern '%s' is not allowed.
settings = Settings
settings.options = Options
settings.full_name = Full Name
@ -449,7 +547,7 @@ settings.update_settings = Update Settings
settings.change_orgname = Organization Name Changed
settings.change_orgname_desc = Organization name has been changed. This will affect how links relate to the organization. Do you want to continue?
settings.update_setting_success = Organization settings were successfully updated.
settings.delete = Delete Organization
settings.delete = Delete Organization
settings.delete_account = Delete This Organization
settings.delete_prompt = The organization will be permanently removed, and this <strong>CANNOT</strong> be undone!
settings.confirm_delete_account = Confirm Deletion
@ -522,7 +620,7 @@ dashboard.delete_repo_archives = Delete all repositories archives
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully.
dashboard.git_gc_repos = Do garbage collection on repositories
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully.
dashboard.resync_all_sshkeys = Rewrite '.ssh/authorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys = Rewrite '.ssh/authorized_keys' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success = All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks = Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success = All repositories' update hook have been rewritten successfully.
@ -613,6 +711,7 @@ auths.smtp_auth = SMTP Authorization Type
auths.smtphost = SMTP Host
auths.smtpport = SMTP Port
auths.enable_tls = Enable TLS Encryption
auths.pam_service_name = PAM Service Name
auths.enable_auto_register = Enable Auto Registration
auths.tips = Tips
auths.edit = Edit Authorization Setting
@ -656,11 +755,12 @@ config.enable_cache_avatar = Enable Cache Avatar
config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook Configuration
config.task_interval = Task Interval
config.queue_length = Queue Length
config.deliver_timeout = Deliver Timeout
config.skip_tls_verify = Skip TLS Verify
config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled
config.mailer_disable_helo = Disable HELO
config.mailer_name = Name
config.mailer_host = Host
config.mailer_user = User

@ -39,10 +39,18 @@ issues=Publicaciones
cancel=Cancelar
[search]
search=Buscar...
repository=Repositorio
user=Usuario
issue=Incidencia
code=Código
[install]
install=Instalación
title=Pasos de la instalación por primera vez
requite_db_desc=Gogs necesita MySQL, PostgreSQL o SQLite3.
db_title=Configuración de base de datos
db_type=Tipo de base de datos
host=Anfitrión
user=Usuario
@ -52,7 +60,11 @@ db_helper=Por favor utilice el motor INNODB con la configuración de caracteres
ssl_mode=Modo SSL
path=Ruta
sqlite_helper=Ruta del archivo de la base de datos de SQLite3.
general_title=Configuraciones Generales de Gogs
err_empty_sqlite_path=La ruta de la base de datos SQLite3 no puede estar vacía.
general_title=Configuración General de Gogs
app_name=Nombre de la Aplicación
app_name_helper=Pon aquí el nombre de tu organización, ¡alto y claro!
repo_path=Ruta del repositorio de Raiz (Root)
repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio.
run_user=Abrir el usuario
@ -63,13 +75,24 @@ http_port=Puerto HTTP
http_port_helper=Puerto en el que escuchará la aplicación.
app_url=URL de la aplicación
app_url_helper=Esto afecta a las URLs para clonar por HTTP/HTTPS y a algunos correos electrónicos.
email_title=Configuración del Servicio de Correo (Opcional)
optional_title=Configuración Opcional
email_title=Configuración del Servicio de Correo
smtp_host=SMTP Host
smtp_from=Desde
smtp_from_helper=Remitente del email, RFC 5322. Puede ser solamente una dirección de correo electrónico, o estar en el formato "Nombre" <email@example.com>.
mailer_user=Remitente del Correo Electrónico
mailer_password=Contraseña del Remitente
notify_title=Configuración de Notificaciones (Opcional)
register_confirm=Habilitar la Confirmación en el Registro
mail_notify=Habilitar las Notificaciones de Correo
server_service_title=Configuración de Servidor y Otros Servicios
offline_mode=Activar el modo Sin Conexión
offline_mode_popup=Desactivar el CDN incluso en el modo de producción, todos los recursos se servirán localmente.
disable_registration=Desactivar Auto-Registro
disable_registration_popup=Desactivar auto-registro del usuario, solo el administrador podrá crear cuentas nuevas.
require_sign_in_view=Activar el Inicio de Sesión obligatorio para Ver Páginas
require_sign_in_view_popup=Solo los usuarios logados pueden ver páginas, los visitantes anónimos solo podrán ver las páginas de login/registro.
admin_setting_desc=No es necesario crear una cuenta de administrador ahora mismo, el usuario que tenga ID=1 obtendrá privilegios de administrador automáticamente.
admin_title=Configuración de la Cuenta de Administrador
admin_name=Nombre de usuario
admin_password=Contraseña
@ -113,13 +136,18 @@ active_your_account=Activa tu cuenta
resent_limit_prompt=Lo sentimos, estás solicitando el reenvío del mail de activación con demasiada frecuencia. Por favor, espera 3 minutos.
has_unconfirmed_mail=Hola %s, tu correo electrónico (<b>%s</b>) no está confirmado. Si no has recibido un correo de confirmación o necesitas que lo enviemos de nuevo, por favor, haz click en el siguiente botón.
resend_mail=Haz click aquí para reenviar tu correo electrónico de activación
email_not_associate=Esta dirección de correo electrónico no esta asociada a cuenta alguna.
email_not_associate=Esta dirección de correo electrónico no esta asociada a ninguna cuenta.
send_reset_mail=Haga clic aquí para (re)enviar el correo para el restablecimiento de la contraseña
reset_password=Restablecer su contraseña
invalid_code=Lo sentimos, su código de confirmación ha expirado o no es valido.
reset_password_helper=Haga Clic aquí para restablecer su contraseña
password_too_short=La longitud de la contraseña no puede ser menor a 6.
[modal]
yes=
no=No
modify=Editar
[form]
UserName=Nombre de usuario
RepoName=Nombre del repositorio
@ -136,6 +164,7 @@ AdminEmail=Correo electrónico del administrador
require_error=` no puede estar vacío.`
alpha_dash_error=` los caracteres deben ser Alfanumericos o dash(-_).`
alpha_dash_dot_error=` debe ser un caracter alfanumérivo válido, un guión alto o bajo (-_) o un signo de puntuación.`
size_error=` debe ser de tamaño %s.`
min_size_error=` debe contener al menos %s caracteres.`
max_size_error=` debe contener como máximo %s caracteres.`
email_error=` no es una dirección de correo válida.`
@ -150,9 +179,6 @@ org_name_been_taken=Ya existe una organización con este nombre.
team_name_been_taken=Ya existe un equipo con este nombre.
email_been_used=Esta dirección de correo electrónico ya está en uso.
ssh_key_been_used=Este nombre de clave pública ya está en uso.
illegal_username=Tu nombre de usuario contiene caracteres inválidos.
illegal_repo_name=El nombre del repositorio contiene caracteres inválidos.
illegal_org_name=El nombre de la organización contiene caracteres inválidos.
illegal_team_name=El nombre del equipo contiene caracteres inválidos.
username_password_incorrect=Nombre de usuario o contraseña incorrectos.
enterred_invalid_repo_name=Por favor, asegúrate de que has introducido correctamente el nombre del repositorio.
@ -183,6 +209,9 @@ followers=Seguidores
starred=Destacados
following=Siguiendo
form.name_reserved=El usuario '%s' está reservado.
form.name_pattern_not_allowed=El patrón de nombre de usuario '%s' no está permitido.
[settings]
profile=Perfil
password=Contraseña
@ -227,6 +256,7 @@ primary_email=Marcar como principal
delete_email=Eliminar
add_new_email=Añadir nueva dirección de correo electrónico
add_email=Añadir correo electrónico
add_email_confirmation_sent=Un nuevo correo de confirmación ha sido enviado a <b>%s</b>, por favor, comprueba tu bandeja de entrada en las próximas %d horas para completar el proceso de confirmación.
add_email_success=Tu nuevo correo electrónico se ha añadido correctamente.
manage_ssh_keys=Gestionar Claves SSH
@ -282,6 +312,9 @@ create_repo=Crear Repositorio
default_branch=Rama por defecto
mirror_interval=Intervalo de mirror(en horas)
form.name_reserved=El nombre del repositorio '%s' está reservado.
form.name_pattern_not_allowed=El patrón del nombre del repositorio '%s' no está permitido.
need_auth=Requiere Autorización
migrate_type=Tipo de Migración
migrate_type_helper=Este repositorio será un <span class="label label-blue label-radius">Mirror</span>
@ -289,6 +322,8 @@ migrate_repo=Migrar Repositorio
migrate.clone_address=Clonar Dirección
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio.
forked_from=forked de
fork_from_self=eres el propietario del repositorio, no puedes hacer fork!
copy_link=Copiar
click_to_copy=Copiar al portapapeles
copied=Copiado correctamente
@ -311,11 +346,14 @@ branch_and_tags=Ramas y Etiquetas
branches=Ramas
tags=Etiquetas
issues=Incidencias
labels=Etiquetas
milestones=Milestones
commits=Commits
releases=Releases
file_raw=Raw
file_history=Histórico
file_view_raw=Ver Raw
file_permalink=Permalink
commits.commits=Commits
commits.search=Buscar Commits
@ -326,6 +364,34 @@ commits.date=Fecha
commits.older=Anterior
commits.newer=Posterior
issues.new=Nueva Incidencia
issues.new_label=Nueva Etiqueta
issues.new_label_placeholder=Nombre etiqueta...
issues.open_tab=%d abiertas
issues.close_tab=%d cerradas
issues.filter_label=Etiqueta
issues.filter_label_no_select=Ninguna etiqueta seleccionada
issues.filter_milestone=Milestone
issues.filter_assignee=Asignada por
issues.filter_type=Tipo
issues.filter_type.all_issues=Todas las incidencias
issues.filter_type.assigned_to_you=Asignada a ti
issues.filter_type.created_by_you=Creada por ti
issues.filter_type.mentioning_you=Citado en
issues.opened_by=abierta %[1]s por <a href="/%[2]s">%[2]s</a>
issues.previous=Página Anterior
issues.next=Página Siguiente
issues.label_title=Nombre etiqueta
issues.label_color=Color etiqueta
issues.label_count=%d etiquetas
issues.label_open_issues=%d incidencias abiertas
issues.label_edit=Editar
issues.label_delete=Borrar
issues.label_modify=Modificación de Etiqueta
issues.label_deletion=Borrado de Etiqueta
issues.label_deletion_desc=Al borrar la etiqueta su información será eliminada de todas las incidencias relacionadas. Desea continuar?
issues.label_deletion_success=Etiqueta borrada con éxito!
settings=Configuración
settings.options=Opciones
settings.collaboration=Colaboración
@ -432,6 +498,9 @@ team_name_helper=Utiliza este nombre para mencionar a este equipo en las convers
team_desc_helper=¿En qué consiste este equipo?
team_permission_desc=¿Qué nivel de permisos debería tener este equipo?
form.name_reserved=El nombre de la organización '%s' está reservado.
form.name_pattern_not_allowed=El patrón de nombre de la organización '%s' no está permitido.
settings=Configuración
settings.options=Opciones
settings.full_name=Nombre Completo
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=Eliminar todos los archivos de repositorios
dashboard.delete_repo_archives_success=Todos los archivos de repositorios se han eliminado correctamente.
dashboard.git_gc_repos=Ejecutar la recolección de basura en los repositorios
dashboard.git_gc_repos_success=Todos los repositorios han ejecutado correctamente el recolector de basuras.
dashboard.resync_all_sshkeys=Reescribir el fichero '.ssh/authorized_key'(atención: se perderán las claves que no pertenezcan a Gogs)
dashboard.resync_all_sshkeys=Reescribir el fichero '.ssh/authorized_keys'(atención: se perderán las claves que no pertenezcan a Gogs)
dashboard.resync_all_sshkeys_success=Todas las claves públicas se han reescrito correctamente.
dashboard.resync_all_update_hooks=Reescribir todos los hooks de actualización de los repositorios (necesario cuando se modifica la ruta de configuración personalizada)
dashboard.resync_all_update_hooks_success=Todos los hooks de actualización de los repositorios se han reescrito correctamente.
@ -605,6 +674,7 @@ auths.smtp_auth=Tipo de Autorización SMTP
auths.smtphost=SMTP Host
auths.smtpport=Puerto SMTP
auths.enable_tls=Habilitar Cifrado TLS
auths.pam_service_name=Nombre del Servicio PAM
auths.enable_auto_register=Hablilitar Auto-Registro
auths.tips=Consejos
auths.edit=Editar la Configuración de Autorización
@ -653,6 +723,7 @@ config.deliver_timeout=Timeout de Entrega
config.skip_tls_verify=Omitir la Verificación TLS
config.mailer_config=Configuración del Mailer
config.mailer_enabled=Activado
config.mailer_disable_helo=Desactivar HELO
config.mailer_name=Nombre
config.mailer_host=Host
config.mailer_user=Usuario

@ -39,10 +39,18 @@ issues=Problèmes
cancel=Annuler
[search]
search=Rechercher...
repository=Référentiel
user=Utilisateur
issue=Problème
code=Code
[install]
install=Installation
title=Instructions de Première Installation
requite_db_desc=Gogs nécessite MySQL, PostgreSQL ou SQLite3.
db_title=Paramètres de la base de données
db_type=Type de Base de Données
host=Hôte
user=Utilisateur
@ -52,7 +60,11 @@ db_helper=Veuillez utiliser le moteur INNODB avec le jeu de caractères utf8_gen
ssl_mode=Mode SSL
path=Chemin
sqlite_helper=Emplacement du fichier de la base de données SQLite3.
err_empty_sqlite_path=Le chemin de la base de donnée SQLite3 ne peut être vide.
general_title=Paramètres Généraux de Gogs
app_name=Nom de l'Application
app_name_helper=Inscrivez fièrement le nom de votre organisation ici !
repo_path=Emplacement Racine du Référentiel
repo_path_helper=Tous les Référentiels Git distants seront sauvegardés ici.
run_user=Entrer un Utilisateur
@ -63,13 +75,24 @@ http_port=Port HTTP
http_port_helper=Numéro de port que l'application écoutera.
app_url=URL de l'Application
app_url_helper=Cela affecte les doublons d'URL HTTP/HTTPS et le contenu d'e-mail.
email_title=Paramètres du Service de Messagerie (Facultatif)
optional_title=Paramètres facultatifs
email_title=Paramètres du Service de Messagerie
smtp_host=Hôte SMTP
smtp_from=Provenant de
smtp_from_helper=Adresse de l'expéditeur, RFC 5322. Soit une adresse courriel simple, soit au format "Nom" <email@example.com>.
mailer_user=E-mail de l'Expéditeur
mailer_password=Mot de Passe de l'Expéditeur
notify_title=Paramètre des Notifications (Facultatif)
register_confirm=Activer la Confirmation d'Enregistrement
mail_notify=Activer la Notification des Mails reçus
server_service_title=Paramètres du serveur et des autres services
offline_mode=Activer le Mode hors connexion
offline_mode_popup=Désactiver le CDN, même en production. Toutes les ressources seront distribuées en local.
disable_registration=Désactiver le formulaire d'inscription
disable_registration_popup=Désactiver le formulaire d'inscription, seuls les administrateurs peuvent créer des comptes.
require_sign_in_view=Demander une connexion pour afficher des pages
require_sign_in_view_popup=Seules les personnes connectées peuvent voir les pages. Les visiteurs anonymes ne pourront voir que les pages de connexion/enregistrement.
admin_setting_desc=Vous n'avez pas besoin de créer un compte admin. L'utilisateur ayant l'ID = 1 aura l'accès admin automatiquement.
admin_title=Paramètres du Compte Administrateur
admin_name=Nom d'Utilisateur
admin_password=Mot de Passe
@ -112,14 +135,19 @@ sign_in_email=Connexion avec l'E-mail
active_your_account=Activer votre Compte
resent_limit_prompt=Désolé, vos tentatives d'activation sont trop fréquentes. Veuillez réessayer dans 3 minutes.
has_unconfirmed_mail=Bonjour %s, votre adresse courriel (<b>%s</b>) n'a pas été confirmée. Si vous n'avez reçu aucun courriel de confirmation ou souhaitez renouveler l'envoi, appuyez sur le bouton ci-dessous.
resend_mail=Appuyez ici pour renvoyer un mail de confirmation
resend_mail=Cliquez ici pour renvoyer un mail de confirmation
email_not_associate=Cette adresse e-mail n'est associée à aucun compte.
send_reset_mail=Appuyez ici pour (r)envoyer le mail de réinitialisation du mot de passe
send_reset_mail=Cliquez ici pour (r)envoyer le mail de réinitialisation du mot de passe
reset_password=Réinitialiser le Mot de Passe
invalid_code=Désolé, code de confirmation invalide ou expiré.
reset_password_helper=Appuyez ici pour réinitialiser votre mot de passe
reset_password_helper=Cliquez ici pour réinitialiser votre mot de passe
password_too_short=Le mot de passe doit contenir 6 caractères minimum.
[modal]
yes=Oui
no=Non
modify=Modifier
[form]
UserName=Nom d'Utilisateur
RepoName=Nom du Référentiel
@ -131,11 +159,12 @@ HttpsUrl=URL HTTPS
PayloadUrl=URL des Données Utiles
TeamName=Nom d'équipe
AuthName=Nom d'autorisation
AdminEmail=E-mail d'admin
AdminEmail=E-mail de l'administrateur
require_error=` Ne peut être vide `
alpha_dash_error=` doivent être des caractères alpha, numeriques ou console (-_) valides `
alpha_dash_dot_error=` doivent être des caractères alpha, numeriques, console (-_) valides ou des points `
size_error=` doit être à la taille de %s.`
min_size_error=` %s caractères minimum `
max_size_error=` %s caractères maximum `
email_error=` adresse e-mail invalide `
@ -150,9 +179,6 @@ org_name_been_taken=Nom d'organisation déjà pris.
team_name_been_taken=Nom d'équipe déjà pris.
email_been_used=Adresse e-mail déjà utilisée.
ssh_key_been_used=Le nom de la clé publique a déjà servi.
illegal_username=Le nom d'utilisateur contient des caractères interdits.
illegal_repo_name=Le nom du Référentiel 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'utilisateur ou mot de passe incorrect.
enterred_invalid_repo_name=Veuillez vérifier que le nom saisi du Référentiel soit correct.
@ -165,17 +191,17 @@ invalid_ssh_key=Désolé, impossible de valider votre clé SSH : %s
unable_verify_ssh_key=Gogs n'a pu vérifier la validité de votre clé SSH, même si nous partons du principe qu'elle le soit. Cela-dit, veuillez vous en assurer.
auth_failed=Échec d'authentification : %s
still_own_repo=Votre compte comporte toujours des propriétés de Référentiel. Vous devez d'abord les supprimer ou les transférer.
still_has_org=Votre compte a toujours membres de l'organisation, vous avez à gauche ou supprimez tout d'abord.
still_own_repo=Votre compte comporte toujours des propriétés du dépôt. Vous devez d'abord les supprimer ou les transférer.
still_has_org=Votre compte contient toujours au moins une adhésion à une organisation, vous devez quitter ou supprimer votre adhésion.
org_still_own_repo=Cette organisation comporte toujours des propriétés de Référentiel. Vous devez d'abord les supprimer ou les transférer.
still_own_user=Cette authentification a déjà servi à d'autres utilisateurs. Veuillez les déplacer puis supprimez à nouveau.
target_branch_not_exist=Branche cible n'existe pas
target_branch_not_exist=La branche cible n'existe pas.
[user]
change_avatar=Changez d'avatar via gravatar.com
change_custom_avatar=Changer de vignette dans les réglages
change_custom_avatar=Changer votre avatar dans les paramètres
join_on=Adhéré le
repositories=Référentiels
activity=Activités publiques
@ -183,6 +209,9 @@ followers=Abonnés
starred=Votés
following=Abonnements
form.name_reserved=Le nom '%s' est réservé.
form.name_pattern_not_allowed=Motif '%s' interdit pour les noms d'utilisateur.
[settings]
profile=Profil
password=Mot de Passe
@ -205,13 +234,13 @@ change_username_desc=Nom d'utilisateur modifié. Cela affecte tous les liens rel
continue=Continuer
cancel=Annuler
enable_custom_avatar=Permettre vignette personnalisée
enable_custom_avatar=Activer l'Avatar personnalisé
enable_custom_avatar_helper=Cette option désactive l'affichage via Gravatar
choose_new_avatar=Choisir nouvelle vignette
update_avatar=Réglage de mise à jour de vignette
choose_new_avatar=Sélectionner un nouvel avatar
update_avatar=Mettre l'Avatar à Jour
uploaded_avatar_not_a_image=Le fichier téléchargé n'est pas une image.
no_custom_avatar_available=Aucun avatar personnalisé disponible, activation impossible.
update_avatar_success=La mise à jour de votre vignette a réussi.
update_avatar_success=Votre avatar a été mis à jour avec succès.
change_password=Modifier le Mot de Passe
old_password=Mot de Passe actuel
@ -227,6 +256,7 @@ primary_email=Définir comme principale
delete_email=Supprimer
add_new_email=Ajouter une nouvelle adresse courriel
add_email=Ajouter un courriel
add_email_confirmation_sent=Un nouvel e-mail de confirmation a été envoyé à <b>%s</b>, merci de vérifier votre boite de réception dans les %d heures pour compléter le processus de confirmation.
add_email_success=Votre courriel a été ajouté avec succès.
manage_ssh_keys=Gérer les clés SSH
@ -255,7 +285,7 @@ token_name=Nom du jeton
generate_token=Générer le jeton
generate_token_succees=Nouveau jeton d'accès a été généré avec succès ! Assurez-vous de copier votre nouveau jeton d'accès personnel maintenant. Vous ne serez pas en mesure de le revoir !
delete_token=Supprimer
delete_token_success=Jeton d'accès personnelle a été supprimée avec succès ! N'oubliez pas de mettre à jour vos applications aussi bien.
delete_token_success=Ce Jeton d'accès personnel a été supprimé avec succès ! N'oubliez pas de mettre vos applications à jour également.
delete_account=Supprimer le Compte
delete_prompt=Votre compte sera supprimé définitivement et cette opération est <strong>IRRÉVERSIBLE</strong> !
@ -266,12 +296,12 @@ delete_account_desc=Ce compte sera supprimé définitivement. Voulez-vous contin
[repo]
owner=Propriétaire
repo_name=Nom du Référentiel
repo_name_helper=Idéalement, le nom d'un Référentiel devrait être court, mémorable et <strong>unique</strong>.
repo_name_helper=Idéalement, le nom d'un dépot devrait être court, mémorable et <strong>unique</strong>.
visibility=Visibilité
visiblity_helper=Ce Référentiel est <span class="label label-red label-radius">Privé</span>
fork_repo=Référentiel d'Embranchement
fork_from=Embranchement de
fork_visiblity_helper=Un Référentiel d'embranchement ne peut pas changer sa visiblité
fork_visiblity_helper=Un dépôt scindé ne peut pas changer sa visiblité
repo_desc=Description
repo_lang=Langue
repo_lang_helper=Sélectionner un fichier .gitignore
@ -282,15 +312,20 @@ create_repo=Créer un Référentiel
default_branch=Branche par défaut
mirror_interval=Intervalle du miroir (heure)
form.name_reserved=Le nom de dépôt '%s' est réservé.
form.name_pattern_not_allowed=Motif '%s' interdit pour les noms de dépôt.
need_auth=Nécessite une Autorisation
migrate_type=Type de Migration
migrate_type_helper=Ce Référentiel sera un <span class="label label-blue label-radius">Miroir</span>
migrate_type_helper=Ce dépôt sera un <span class="label label-blue label-radius">Miroir</span>
migrate_repo=Migrer le Référentiel
migrate.clone_address=Adresse du clone
migrate.invalid_local_path=Chemin local non valide, non existant ou n'étant pas un dossier.
forked_from=dérivé depuis
fork_from_self=Vous nous ne pouvez pas dériver un dépôt que vous possédez déja !
copy_link=Copier
click_to_copy=Copier dans le presse-papier
click_to_copy=Copier dans le presse-papiers
copied=Copié
clone_helper=Besoin d'aide pour le clonage ? Visitez <a target="_blank" href="%s"> l'aider</a> !
unwatch=Ne plus suivre
@ -311,11 +346,14 @@ branch_and_tags=Branches & Tags
branches=Branches
tags=Tags
issues=Problèmes
labels=Etiquettes
milestones=Étapes
commits=Commissions
releases=Publications
file_raw=Raw
file_history=Historique
file_view_raw=Voir le Raw
file_permalink=Lien permanent
commits.commits=Commissions
commits.search=Rechercher des commissions
@ -326,6 +364,34 @@ commits.date=Date
commits.older=Précédemment
commits.newer=Récemment
issues.new=Nouveau Problème
issues.new_label=Nouvelle étiquette
issues.new_label_placeholder=Nom de l'étiquette...
issues.open_tab=%d Ouvert
issues.close_tab=%d Fermé
issues.filter_label=Étiquette
issues.filter_label_no_select=Aucun étiquette sélectionnée
issues.filter_milestone=Étape
issues.filter_assignee=Assigné
issues.filter_type=Type
issues.filter_type.all_issues=Tous les problèmes
issues.filter_type.assigned_to_you=Qui vous sont assignés
issues.filter_type.created_by_you=Créé(es) par vous
issues.filter_type.mentioning_you=Vous mentionnant
issues.opened_by=ouvert %[1]s par <a href="/%[2]s">%[2]s</a>
issues.previous=Page Précédente
issues.next=Page Suivante
issues.label_title=Nom du Label
issues.label_color=Couleur du Label
issues.label_count=%d labels
issues.label_open_issues=%d problèmes ouverts
issues.label_edit=Éditer
issues.label_delete=Supprimer
issues.label_modify=Modification du Label
issues.label_deletion=Suppression du Label
issues.label_deletion_desc=Cette opération supprimera également toutes les informations relatives aux problèmes. Voulez-vous continuer ?
issues.label_deletion_success=Label supprimé avec succès !
settings=Paramètres
settings.options=Options
settings.collaboration=Collaboration
@ -337,10 +403,10 @@ settings.danger_zone=Zone de danger
settings.site=Site officiel
settings.update_settings=Valider
settings.change_reponame=Référentiel renommé
settings.change_reponame_desc=Le Référentiel a été renommé. Cela affecte tous les liens relatifs à ce Référentiel. Continuer ?
settings.change_reponame_desc=Le dépôt a été renommé. Cela affecte tous les liens relatifs à ce dépôt. Continuer ?
settings.transfer=Transférer les propriétés
settings.transfer_desc=Transfère ce Référentiel à un autre utilisateur ou organisation dont vous possédez des droits d'administrateur.
settings.new_owner_has_same_repo=Le nouveau propriétaire a déjà un Référentiel nommé ainsi.
settings.transfer_desc=Transfèrer ce dépôt à un autre utilisateur ou une organisation dont vous possédez des droits d'administrateur.
settings.new_owner_has_same_repo=Le nouveau propriétaire a déjà un dépôt nommé ainsi.
settings.delete=Supprimer ce Référentiel
settings.delete_desc=Attention, action irréversible. Soyez sûre de vous.
settings.transfer_notices=<p>- Vous perdrez l'accès si le nouveau propriétaire est un utilisateur individuel.</p><p>- Vous garderez l'accès si le nouveau propriétaire est une organisation et que vous en faites partie.</p>
@ -432,6 +498,9 @@ team_name_helper=Ce nom sera utilisé pour mentionner l'équipe dans les convers
team_desc_helper=Présentation de l'équipe
team_permission_desc=Quel niveau d'accès cette équipe devrait-elle posséder ?
form.name_reserved=Le nom d'organisation '%s' est réservé.
form.name_pattern_not_allowed=Motif '%s' interdit pour les noms d'organisation.
settings=Paramètres
settings.options=Options
settings.full_name=Non Complet
@ -477,7 +546,7 @@ teams.update_settings=Valider
teams.delete_team=Supprimer cette Équipe
teams.add_team_member=Ajouter un Membre
teams.delete_team_title=Suppression de l'équipe
teams.delete_team_desc=Cette équipe sera supprimée. Les membres pourraient perdre leurs accès à certains Référentiels.
teams.delete_team_desc=Cette équipe sera supprimée. Les membres pourraient perdre leurs accès à certains dépôts.
teams.delete_team_success=Équipe supprimée avec succès.
teams.read_permission_desc=Cette équipe permet l'accès en <strong>lecture</strong> : les membres peuvent voir et dupliquer ses Référentiels.
teams.write_permission_desc=Cette équipe permet l'accès en <strong>écriture</strong> : les membres peuvent participer à ses Référentiels.
@ -513,11 +582,11 @@ dashboard.delete_inactivate_accounts_success=Inactivent tous les comptes ont ét
dashboard.delete_repo_archives=Supprimer toutes les archives de référentiels
dashboard.delete_repo_archives_success=Toutes les archives de référentiels ont été supprimés avec succès.
dashboard.git_gc_repos=Collecter les déchets des référentiels
dashboard.git_gc_repos_success=Tous les référentiels ont effectué la collecte avec succès.
dashboard.resync_all_sshkeys=Ré-écrire le fichier '.ssh/authorized_key' (attention : les clés hors-Gogs vont être perdues)
dashboard.git_gc_repos_success=Tous les dépôts ont effectué la collecte avec succès.
dashboard.resync_all_sshkeys=Ré-écrire le fichier '.ssh/authorized_keys' (attention : les clés hors-Gogs vont être perdues)
dashboard.resync_all_sshkeys_success=Toutes les clés publiques ont été ré-écrites avec succès.
dashboard.resync_all_update_hooks=Ré-écrire tous les hooks de mises à jour des dépôts (requis quand le chemin de la configuration personnalisé est modifié)
dashboard.resync_all_update_hooks_success=Tous les hooks de mises à jour des dépôts ont été ré-écris avec succès.
dashboard.resync_all_update_hooks_success=Les mises à jour de hook des référentiels ont toutes été réécrites avec succès.
dashboard.server_uptime=Durée de Marche Serveur
dashboard.current_goroutine=Goroutines actuelles
@ -554,7 +623,7 @@ users.new_account=Créer un nouveau compte
users.name=Nom
users.activated=Activés
users.admin=Administrateur
users.repos=Repos
users.repos=Dépôts
users.created=Créés
users.edit=Éditer
users.auth_source=Source d'Autorisation
@ -567,7 +636,7 @@ users.is_admin=Ce compte possède un niveau d'accès administrateur
users.allow_git_hook=Ce compte dispose des autorisations pour créer des crochets de Git
users.update_profile=Mettre le profil à jour
users.delete_account=Supprimer ce Compte
users.still_own_repo=Ce compte comporte toujours des propriétés de Référentiel. Vous devez d'abord les supprimer ou les transférer.
users.still_own_repo=Ce compte possède toujours des dépôts. Vous devez d'abord les supprimer ou les transférer.
users.still_has_org=Ce compte a toujours membres de l'organisation, vous avez à gauche ou supprimez tout d'abord.
orgs.org_manage_panel=Gestion des Organisations
@ -605,6 +674,7 @@ auths.smtp_auth=Type d'Autorisation SMTP
auths.smtphost=Hôte SMTP
auths.smtpport=Port SMTP
auths.enable_tls=Activer le Chiffrement TLS
auths.pam_service_name=Nom du Service PAM
auths.enable_auto_register=Connexion Automatique
auths.tips=Conseils
auths.edit=Modifier les Paramètres d'Autorisation
@ -648,11 +718,12 @@ config.enable_cache_avatar=Activer le Cache d'Avatar
config.active_code_lives=Limites de Code Actif
config.reset_password_code_lives=Réinitialiser le Mot De Passe des Limites de Code
config.webhook_config=Configuration Webhook
config.task_interval=Intervalles de Tâches
config.task_interval=Intervalles des Tâches
config.deliver_timeout=Expiration d'Envoi
config.skip_tls_verify=Ne pas vérifier TLS
config.mailer_config=Configuration du Maileur
config.mailer_enabled=Activé
config.mailer_disable_helo=Désactiver HELO
config.mailer_name=Nom
config.mailer_host=Hôte
config.mailer_user=Utilisateur
@ -692,7 +763,7 @@ notices.system_notice_list=Notes Systèmes
notices.type=Type
notices.type_1=Référentiel
notices.desc=Description
notices.op=Auteur
notices.op=Opération
notices.delete_success=Note système supprimée avec succès.
[action]

@ -0,0 +1,798 @@
app_desc=Un servizio Git auto-ospitato pronto all'uso
home=Home
dashboard=Pannello di controllo
explore=Esplora
help=Aiuto
sign_in=Accedi
social_sign_in=Login Sociale: Passo 2 <small>associare l'account</small>
sign_out=Esci
sign_up=Registrati
register=Registrati
website=Sito Web
version=Versione
page=Pagina
template=Template
language=Lingua
username=Nome utente
email=E-mail
password=Password
re_type=Conferma
captcha=Captcha
repository=Repository
organization=Organizzazione
mirror=Mirror
new_repo=Nuovo Repository
new_migrate=Nuova Migrazione
new_fork=Nuovo Fork Repository
new_org=Nuova organizzazione
manage_org=Gestisci le organizzazioni
admin_panel=Pannello di amministrazione
account_settings=Impostazioni dell'account
settings=Impostazioni
news_feed=Notizie
pull_requests=Pull Requests
issues=Problemi
cancel=Annulla
[search]
search=Ricerca...
repository=Repository
user=Utente
issue=Problema
code=Codice
[install]
install=Installazione
title=Passi d'installazione per il primo avvio
requite_db_desc=Gogs richiede MySql, PostgresSQL o SQLite.
db_title=Impostazioni Database
db_type=Tipo di database
host=Host
user=Utente
password=Password
db_name=Nome del database
db_helper=Utilizza il motore INNODB con codifica utf8_general_ci per MySQL.
ssl_mode=Modalità SSL
path=Percorso
sqlite_helper=Percorso per database SQLite3.
err_empty_sqlite_path=Il percorso del database SQLite3 non può essere vuoto.
general_title=Impostazioni di Base dell'Applicazione
app_name=Nome Applicazione
app_name_helper=Scrivi qui il nome della tua organizzazione forte e chiaro!
repo_path=Percorso Root del Repository
repo_path_helper=Tutti i repository Git remoti saranno salvati in questa directory.
run_user=Esegui con l'utente
run_user_helper=L'utente deve avere accesso al percorso root del repository e avviare Gogs.
domain=Dominio
domain_helper=Questo modifica lo SSH clone URLs.
http_port=Porta HTTP
http_port_helper=Porta di ascolto dell'applicazione.
app_url=URL Applicazione
app_url_helper=Questo influisce sugli URL per il clonaggio via HTTP/HTTPS e da qualche parte nella posta elettronica.
optional_title=Impostazioni Facoltative
email_title=Impostazioni E-mail
smtp_host=Host SMTP
smtp_from=Da
smtp_from_helper=Mail da indirizzo, RFC 5322. Può essere solo un indirizzo email o il formato "Nome" <email@esempio.com>.
mailer_user=E-mail del Mittente
mailer_password=Password del Mittente
register_confirm=Abilita Conferma di Registrazione
mail_notify=Abilita Notifiche via Email
server_service_title=Impostazioni del Server e Altri Servizi
offline_mode=Abilita Modalità Offline
offline_mode_popup=Disabilita il CDN anche in modalità produttiva, tutte le risorse saranno servite localmente.
disable_registration=Disabilita Registrazione Manuale
disable_registration_popup=Disabilita la registrazione manuale degli utenti, solo gli amministratori possono creare account.
require_sign_in_view=Abilita Richiesta di Accesso per Vedere le Pagine
require_sign_in_view_popup=Solo gli utenti loggati possono vedere le pagine, i visitatori potranno vedere solo le pagine di accesso e registrazione.
admin_setting_desc=Non devi per forza creare un account admin proprio adesso, ma comunque l'utente ID=1 otterrà l'accesso da amministratore automaticamente.
admin_title=Impostazioni Account Amministratore
admin_name=Nome utente
admin_password=Password
confirm_password=Conferma Password
admin_email=E-mail
install_gogs=Installare Gogs
test_git_failed=Fallito il test del comando git: %v
sqlite3_not_available=Questa versione non supporta SQLite3, si prega di scaricare la versione binaria ufficiale da %s, NON la versione gobuild.
invalid_db_setting=La configurazione del database non è corretta: %v
invalid_repo_path=Percorso root del repository invalido: %v
run_user_not_match=Run user non è l'utente corrente: %s -> %s
save_config_failed=Fallito il salvataggio della configurazione: %v
invalid_admin_setting=Impostazioni account Admin non valide: %v
install_success=Benvenuto! Siamo felici che tu abbia scelto Gogs, buon divertimento.
[home]
uname_holder=Nome Utente o E-mail
password_holder=Password
switch_dashboard_context=Cambia Dashboard Context
my_repos=I miei Repository
collaborative_repos=Repository Condivisi
my_orgs=Le mie Organizzazioni
my_mirrors=I miei Mirror
[explore]
repos=Repository
[auth]
create_new_account=Crea un nuovo Account
register_hepler_msg=Hai già un account? Accedi ora!
social_register_hepler_msg=Hai già un account? Associalo ora!
disable_register_prompt=Siamo spiacenti, registrazione è stata disabilitata. Si prega di contattare l'amministratore del sito.
disable_register_mail=Siamo spiacenti, la conferma di registrazione via Mail è stata disattivata.
remember_me=Ricordami
forgot_password=Password dimenticata
forget_password=Password dimenticata?
sign_up_now=Bisogno di un account? Iscriviti ora.
confirmation_mail_sent_prompt=Una nuova email di conferma è stata inviata a <b>%s</b>, verifica la tua casella di posta entro le prossime %d ore per completare la registrazione.
sign_in_email=Accedi al tuo indirizzo e-mail
active_your_account=Attiva il tuo Account
resent_limit_prompt=Siamo spiacenti, si stanno inviando e-mail di attivazione troppo spesso. Si prega di attendere 3 minuti.
has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (<b>%s</b>). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
email_not_associate=Questo indirizzo e-mail non è associato ad alcun account.
send_reset_mail=Clicca qui per (ri)inviare la tua e-mail di reimpostazione password
reset_password=Reimposta la tua Password
invalid_code=Siamo spiacenti, il codice di conferma è scaduto o non valido.
reset_password_helper=Clicca qui per reimpostare la password
password_too_short=La lunghezza della password non può essere meno 6 caratteri.
[modal]
yes=
no=No
modify=Modifica
[form]
UserName=Nome utente
RepoName=Nome Repository
Email=Indirizzo E-mail
Password=Password
Retype=Reinserisci password
SSHTitle=Nome chiave SSH
HttpsUrl=URL HTTPS
PayloadUrl=URL Payload
TeamName=Nome Team
AuthName=Nome autorizzazione
AdminEmail=Email dell'Admin
require_error=` non può essere vuoto.`
alpha_dash_error=` ammessi solo caratteri alfanumerici o trattini(-_).`
alpha_dash_dot_error=` ammessi solo caratteri alfanumerici o trattini(-_) o punti.`
size_error='deve essere %s.'
min_size_error=` deve contenere almeno %s caratteri.`
max_size_error=` deve contenere massimo %s caratteri.`
email_error=` non è un indirizzo e-mail valido.`
url_error=` non è un URL valido.`
unknown_error=Errore sconosciuto:
captcha_incorrect=Il Captcha non corrisponde.
password_not_match=Le due password non corrispondono.
username_been_taken=Il nome utente è già utilizzato.
repo_name_been_taken=Il nome del Repository è già utilizzato.
org_name_been_taken=Il nome dell'Organizzazione è già utlizzato.
team_name_been_taken=Il nome del Team è già utilizzato.
email_been_used=L'indirizzo E-mail è già utilizzato.
ssh_key_been_used=Il nome della chiave pubblica è già utilizzato.
illegal_team_name=Il nome del Team contiene caratteri non validi.
username_password_incorrect=Nome utente o password incorretti.
enterred_invalid_repo_name=Si prega di assicurarsi che il nome del repository inserito sia corretto.
enterred_invalid_owner_name=Si prega di assicurarsi che il nome del proprietario inserito sia corretto.
enterred_invalid_password=Verificare che la password inserita sia corretta.
user_not_exist=L'utente inserito non esiste.
last_org_owner=L'utente che si vuole rimuovere è l'ultimo membro admin del team. Ci deve essere un altro proprietario.
invalid_ssh_key=Siamo spiacenti, non siamo in grado di verificare la chiave SSH: %s
unable_verify_ssh_key=Gogs non può verificare la chiave SSH, ma assumiamo che sia valida, si prega di verificare voi stessi.
auth_failed=Autenticazione non riuscita: %v
still_own_repo=Il tuo account possiede ancora almeno un repository, dovete prima cancellarli o trasferirne la proprietà.
still_has_org=Il tuo account è ancora associato ad almeno un'organizzazione, disassociarsi prima.
org_still_own_repo=Questa organizzazione ha ancora la proprietà del repository, dovete cancellarla o trasferirli prima.
still_own_user=Questa autenticazione è ancora in uso da almeno un utente, per favore rimuovili dall'autenticazione e riprova.
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
[user]
change_avatar=Cambia il tuo avatar su gravatar.com
change_custom_avatar=Cambia il tuo avatar nelle impostazioni
join_on=Si è unito il
repositories=Repository
activity=Attività pubblica
followers=Seguaci
starred=Votate
following=Seguiti
form.name_reserved=L'username '%s' è riservato.
form.name_pattern_not_allowed=La struttura del nome utente '%s' non è consentita.
[settings]
profile=Profilo
password=Password
ssh_keys=Chiavi SSH
social=Account Sociali
applications=Applicazioni
orgs=Organizzazioni
delete=Elimina account
uid=Uid
public_profile=Profilo pubblico
profile_desc=Il tuo indirizzo e-mail è pubblico e sarà usato per ogni notifica inerente al tuo account, e per qualsiasi operazione web effettuata attraverso il sito.
full_name=Nome Completo
website=Sito web
location=Posizione
update_profile=Aggiorna Profilo
update_profile_success=Il tuo profilo è stato aggiornato con successo.
change_username=Username Cambiato
change_username_desc=Hai cambiato il tuo username. Questo influenzerà il modo in cui i link si relazionano al tuo account. Vuoi proseguire?
continue=Continua
cancel=Annulla
enable_custom_avatar=Abilita avatar personalizzato
enable_custom_avatar_helper=Seleziona per disabilitare il fetch da Gravatar
choose_new_avatar=Scegli un nuovo avatar
update_avatar=Aggiorna le impostazioni avatar
uploaded_avatar_not_a_image=Il file caricato non è un'immagine.
no_custom_avatar_available=Nessun avatar personalizzato disponibile, impossibile abilitarlo.
update_avatar_success=Le tue impostazioni avatar sono state aggiornate con successo.
change_password=Cambia Password
old_password=Password attuale
new_password=Nuova Password
password_incorrect=La Password attuale non è corretta.
change_password_success=La tua password è stata cambiata con successo. Ora puoi accedere usando la nuova password.
emails=Indirizzi e-mail
manage_emails=Gestisci indirizzi email
email_desc=Il tuo indirizzo e-mail primario sarà usato per le notifiche e altre operazioni.
primary=Primario
primary_email=Imposta come primario
delete_email=Elimina
add_new_email=Aggiungi un nuovo indirizzo E-mail
add_email=Aggiungi E-mail
add_email_confirmation_sent=Una nuova email di conferma è stata inviata a <b>%s</b>, per favore controlla la tua posta in arrivo nelle prossime %d ore per completare il processo di registrazione.
add_email_success=Il tuo nuovo indirizzo e-mail è stato aggiunto con successo.
manage_ssh_keys=Gestisci chiavi SSH
add_key=Aggiungi Chiave
ssh_desc=Questa è una lista di chiavi SSH associate al tuo account. Poiché queste chiavi consentono a chiunque di ottenere accesso alle tue repository, è molto importante che tu le riconosca.
ssh_helper=<strong>Non sai come?</strong> Controlla la guida di GitHub sul <a href="%s">creare le tue chiavi SSH</a> o sul risolvere <a href="%s">problemi frequenti</a> che potresti incontrare usando SSH.
add_new_key=Aggiungi Chiave SSH
key_name=Nome della Chiave
key_content=Contenuto
add_key_success=La nuova chiave SSH è stata aggiunta!
delete_key=Elimina
add_on=Aggiunto il
last_used=Ultimo accesso il
no_activity=Nessuna attività recente
manage_social=Gestisci gli Account Sociali Associati
social_desc=Questa è un elenco degli account sociali associati. Rimuovere qualsiasi account che non si riconosce.
unbind=Disassocia
unbind_success=Account sociale disassociato.
manage_access_token=Gestisci i Token di Accesso Personale
generate_new_token=Genera Nuovo Token
tokens_desc=I Token che hai generato e che possono essere utilizzati per accedere alle API Gogs.
new_token_desc=Da questo momento, ogni token avrà pieno accesso al tuo account.
token_name=Nome Token
generate_token=Genera Token
generate_token_succees=Nuovo token di accesso generato con successo! Assicurarsi di copiare il nuovo token di accesso personale ora: non sarà possibile visualizzarlo nuovamente!
delete_token=Elimina
delete_token_success=Token di accesso personale eliminato con successo! Non dimenticare di aggiornare anche le applicazioni.
delete_account=Elimina Account
delete_prompt=L'operazione eliminerà permanentemente l'account e <strong>NON POTRÀ</strong> essere annullata!
confirm_delete_account=Conferma Eliminazione
delete_account_title=Eliminazione account
delete_account_desc=Questo account sta per essere eliminato in modo definitivo, vuoi continuare?
[repo]
owner=Proprietario
repo_name=Nome Repository
repo_name_helper=I migliori nomi dei repository sono brevi, facili da memorizzare e <strong>univoci</strong>.
visibility=Visibilità
visiblity_helper=Questo repository è <span class="label label-red label-radius">Privato</span>
fork_repo=Forka Repository
fork_from=Forka da
fork_visiblity_helper=Non puoi cambiare la visibilità di un repository forkato.
repo_desc=Descrizione
repo_lang=Lingua
repo_lang_helper=Selezionare un file .gitignore
license=Licenza
license_helper=Selezionare un file di licenza
init_readme=Inizializzare questo repository con un file README.md
create_repo=Crea Repository
default_branch=Ramo (Branch) predefinito
mirror_interval=Intervallo Mirror (in ore)
form.name_reserved=Il nome repository %s è riservato.
form.name_pattern_not_allowed=La struttura del nome del repository %s non è consentita.
need_auth=Richiesta di autorizzazione
migrate_type=Tipo di migrazione
migrate_type_helper=Questo repository sarà un <span class="label label-blue label-radius">Mirror</span>
migrate_repo=Migra Repository
migrate.clone_address=Duplica Indirizzo
migrate.invalid_local_path=Percorso locale non valido, non esiste o non è una cartella.
forked_from=forkato da
fork_from_self=Non puoi forkare il tuo stesso repository!
copy_link=Copia
click_to_copy=Copia negli appunti
copied=OK copiato
clone_helper=Hai bisogno di aiuto per la clonazione? Visita <a target="_blank" href="%s">Aiuto</a>!
unwatch=Non seguire più
watch=Segui
unstar=Togli il voto
star=Vota
fork=Forka
no_desc=Nessuna descrizione
quick_guide=Guida rapida
clone_this_repo=Clona questo repository
create_new_repo_command=Crea nuovo repository da riga di comando
push_exist_repo=Push un repo esistente dalla riga di comando
branch=Ramo (Branch)
tree=Albero (Tree)
branch_and_tags=Rami (Branch) & Tag
branches=Rami (Branch)
tags=Tag
issues=Problemi
labels=Etichette
milestones=Traguardi
commits=Commit
releases=Rilasci
file_raw=Originale
file_history=Cronologia
file_view_raw=Vedi originale
file_permalink=Permalink
commits.commits=Commits
commits.search=Ricerca una versione
commits.find=Cerca
commits.author=Autore
commits.message=Messaggio
commits.date=Data
commits.older=Più vecchio
commits.newer=Più recente
issues.new=Nuovo Problema
issues.new_label=Nuova etichetta
issues.new_label_placeholder=Nome dell'etichetta...
issues.open_tab=%d Aperti
issues.close_tab=%d Chiusi
issues.filter_label=Etichetta
issues.filter_label_no_select=Nessuna etichetta selezionata
issues.filter_milestone=Traguardo
issues.filter_assignee=Assegnatario
issues.filter_type=Tipo
issues.filter_type.all_issues=Tutti i problemi
issues.filter_type.assigned_to_you=Assegnati a te
issues.filter_type.created_by_you=Creati da te
issues.filter_type.mentioning_you=Che ti riguardano
issues.opened_by=aperto %[1]s da <a href="/%[2]s">%[2]s</a>
issues.previous=Pagina precedente
issues.next=Pagina successiva
issues.label_title=Nome etichetta
issues.label_color=Colore etichetta
issues.label_count=%d etichette
issues.label_open_issues=%d problemi aperti
issues.label_edit=Modifica
issues.label_delete=Elimina
issues.label_modify=Modifica Etichetta
issues.label_deletion=Elimina Etichetta
issues.label_deletion_desc=Eliminare l'etichetta rimuovera le sue informazioni in tutti i problemi correlati. Vuoi continuare?
issues.label_deletion_success=Etichetta eliminata con successo!
settings=Impostazioni
settings.options=Opzioni
settings.collaboration=Collaborazione
settings.hooks=Webhooks
settings.githooks=Git Hooks
settings.deploy_keys=Dispiega Chiavi
settings.basic_settings=Impostazioni di Base
settings.danger_zone=Zona Pericolosa
settings.site=Sito Ufficiale
settings.update_settings=Aggiorna Impostazioni
settings.change_reponame=Nome Repository Cambiato
settings.change_reponame_desc=Il nome repository è stato cambiato. Questo influenzerà il modo in cui i link si relazionano alla repository. Vuoi continuare?
settings.transfer=Trasferisci proprietà
settings.transfer_desc=Trasferisci questa repository a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore.
settings.new_owner_has_same_repo=Il nuovo proprietario ha già un repository con lo stesso nome. Per favore scegli un altro nome.
settings.delete=Elimina questo repository
settings.delete_desc=Una volta che hai cancellato il repository, non puoi tornare indietro. Si prega di fare attenzione.
settings.transfer_notices=<p>- Perderai accesso se il nuovo proprietario è un utente individuale.</p><p>- Conserverai l'accesso se il nuovo proprietario è un'organizzazione di cui sei uno dei proprietari.</p>
settings.update_settings_success=Le opzioni repository sono state aggiornate con successo.
settings.transfer_owner=Nuovo Proprietario
settings.make_transfer=Trasferisci
settings.transfer_succeed=Proprietà del repository trasferita con successo.
settings.confirm_delete=Conferma eliminazione
settings.add_collaborator=Aggiungi nuovo collaboratore
settings.add_collaborator_success=Il nuovo collaboratore è stato aggiunto.
settings.remove_collaborator_success=Il collaboratore è stato rimosso.
settings.user_is_org_member=L'utente è un membro dell'organizzazione che non può essere aggiunto come collaboratore.
settings.add_webhook=Aggiungi Webhook
settings.hooks_desc=I Webhooks sono molto simili a un basilare evento trigger HTTP POST. Ogni volta che qualcosa si verifica in Gogs, tratteremo la notifica all'host di destinazione specificato. Ulteriori informazioni in questa <a target="_blank" href="%s">Guida ai Webhooks</a>.
settings.githooks_desc=Gli Hooks di Git sono una funzionalità di Git stesso, puoi modificare i file degli hooks supportati nell'elenco qui sotto per compiere azioni personalizzate.
settings.githook_edit_desc=Se l'hook è inattivo, sarà presentato un contenuto esempio. Lasciando il contenuto vuoto disattiverai questo hook.
settings.githook_name=Nome hook
settings.githook_content=Contenuto hook
settings.update_githook=Aggiorna Hook
settings.remove_hook_success=Il webhook è stato rimosso.
settings.add_webhook_desc=Gogs manderà una richiesta <code>POST</code> all'URL specificata, insieme alle informazioni sull'evento avvenuto. Puoi anche specificare quale tipo di formato dati vorresti ottenere all'innesco dell'hook (JSON, x-www-form-urlencoded, XML, ecc). Puoi trovare più informazioni nella nostra <a target="_blank" href="%s">Guida ai Webhook</a>.
settings.payload_url=Payload URL
settings.content_type=Content Type
settings.secret=Secret
settings.event_desc=Quali eventi dovrebbero innescare questo webhook?
settings.event_push_only=Solo l'evento <code>push</code>.
settings.active=Attivo
settings.active_helper=Anche i dettagli riguardanti l'evento che ha innescato l'hook saranno inviati.
settings.add_hook_success=Il nuovo webhook è stato aggiunto.
settings.update_webhook=Aggiorna Webhook
settings.update_hook_success=Il webhook è stato aggiornato.
settings.delete_webhook=Eliminare Webhook
settings.recent_deliveries=Recenti Deliveries
settings.hook_type=Tipo di Hook
settings.add_slack_hook_desc=Aggiungi <a href="%s"> Slack</a> integrazione al tuo repository.
settings.slack_token=Token
settings.slack_domain=Dominio
settings.slack_channel=Canale
diff.browse_source=Sfoglia il codice sorgente
diff.parent=parent
diff.commit=commit
diff.data_not_available=Diff Data non disponibile.
diff.show_diff_stats=Mostra Diff Stats
diff.stats_desc=<strong>%d ha cambiato i file</strong> con <strong>%d aggiunte</strong> e <strong>%d eliminazioni</strong>
diff.bin=BIN
diff.view_file=Vedi File
release.releases=Rilasci
release.new_release=Nuovo Rilascio
release.draft=Bozza
release.prerelease=Pre-Rilascio
release.stable=Stabile
release.edit=modifica
release.ahead=<strong>%d</strong> commits da %s da questo rilascio
release.source_code=Codice Sorgente
release.tag_name=Nome tag
release.target=Obbiettivo
release.tag_helper=Scegli un tag esistente o crea un nuovo tag una volta pubblicato.
release.release_title=Nome release
release.content_with_md=Contenuto in <a href="%s">Markdown</a>
release.write=Scrivi
release.preview=Anteprima
release.content_placeholder=Scrivi qualcosa
release.loading=Caricamento...
release.prerelease_desc=Questo è un pre-rilascio
release.prerelease_helper=Precisiamo che questo rilascio non è pronta per la produzione.
release.publish=Pubblica Rilascio
release.save_draft=Salva Bozza
release.edit_release=Modifica Rilascio
release.tag_name_already_exist=Un rilascio con questo tag esiste già.
[org]
org_name_holder=Nome dell'Organizzazione
org_name_helper=Le migliori organizzazioni hanno nomi brevi e memorabili.
org_email_helper=L'Email dell'organizzazione riceve tutte le notifiche e le conferme.
create_org=Crea Organizzazione
repo_updated=Aggiornato
people=Utenti
invite_someone=Invita Qualcuno
teams=Team
lower_members=membri
lower_repositories=repository
create_new_team=Crea Nuovo Team
org_desc=Descrizione
team_name=Nome Team
team_desc=Descrizione
team_name_helper=Verrà usato questo nome per riferirsi a questo team nella conversazioni.
team_desc_helper=In cosa consiste questo team?
team_permission_desc=Quale livello di autorizzazione dovrebbe avere questa squadra?
form.name_reserved=Il nome organizzazione '%s' è riservato.
form.name_pattern_not_allowed=La struttura del nome dell'organizzazione '%s' non è consentita.
settings=Impostazioni
settings.options=Opzioni
settings.full_name=Nome Completo
settings.website=Sito Web
settings.location=Residenza
settings.update_settings=Aggiorna Impostazioni
settings.change_orgname=Il nome dell'organizzazione è cambiato
settings.change_orgname_desc=Il nome dell'organizzazione name è cambiato. Questo influenzerà come collegamenti si riferiscono all'organizzazione. Si desidera continuare?
settings.update_setting_success=Impostazioni dell'organizzazione aggiornate con successo.
settings.delete=Elimina organizzazione
settings.delete_account=Elimina questa organizzazione
settings.delete_prompt=L'organizzazione verrà rimossa definitivamente, e questa operazione <strong>NON PUÒ</strong> essere annullata!
settings.confirm_delete_account=Conferma Eliminazione
settings.delete_org_title=Eliminazione Organizzazione
settings.delete_org_desc=Questa organizzazione sta per essere eliminato in modo permanente, vuoi continuare?
settings.hooks_desc=Aggiungi i webhooks che verranno attivati per <strong>tutti i repository</strong> sotto questa organizzazione.
members.public=Pubblico
members.public_helper=rendi privato
members.private=Privato
members.private_helper=rendi pubblico
members.owner=Proprietario
members.member=Membro
members.conceal=Nascondere
members.remove=Rimuovere
members.leave=Abbandona
members.invite_desc=Digita un nome utente per invitare un nuovo membro a %s:
members.invite_now=Invita ora
teams.join=Iscriviti
teams.leave=Abbandona
teams.read_access=Accesso di Lettura
teams.read_access_helper=Questo team sarà in grado di visualizzare e clonare i suoi repository.
teams.write_access=Accesso di Scrittura
teams.write_access_helper=Questo team sarà in grado di leggere i suoi repository, come pure pusharli.
teams.admin_access=Accesso Amministratore
teams.admin_access_helper=Questo team sarà in grado di pushare/pullare i propri repo, così come aggiungere altri collaboratori.
teams.no_desc=Questo team non ha alcuna descrizione
teams.settings=Impostazioni
teams.owners_permission_desc=I Proprietari hanno pieno accesso a <strong>tutti i repository</strong> e hanno <strong>diritti di amministatore</strong> nell'organizzazione.
teams.members=Membri del Team
teams.update_settings=Aggiorna Impostazioni
teams.delete_team=Elimina questo Team
teams.add_team_member=Aggiungere un Membro al Team
teams.delete_team_title=Eliminazione Team
teams.delete_team_desc=Quando questo team verrà eliminato, i membri di questa squadra potrebbero perdere l'accesso ad alcuni repository. Si desidera continuare?
teams.delete_team_success=Team eliminato con successo.
teams.read_permission_desc=Questo Team concede accesso di <strong>Lettura</strong>: i membri possono visualizzare e clonare i repository del Team.
teams.write_permission_desc=Questo Team concede accesso di <strong>Scrittura</strong>: i membri possono leggere e pushare i repository del Team.
teams.admin_permission_desc=Questo Team concede accesso di <strong>Amministratore</strong>: i membri possono leggere i, pushare a, e aggiungere collaboratori ai repository del Team.
teams.repositories=Repository di Squadra
teams.add_team_repository=Aggiungere Repository di Squadra
teams.remove_repo=Rimuovi
teams.add_nonexistent_repo=Il repository che stai tentando di aggiungere non esiste, crealo prima.
[admin]
dashboard=Pannello di Controllo
users=Utenti
organizations=Organizzazioni
repositories=Repository
authentication=Autenticazioni
config=Configurazione
notices=Avvisi di sistema
monitor=Monitoraggio
prev=Prec.
next=Succ.
dashboard.statistic=Statistiche
dashboard.operations=Operazioni
dashboard.system_status=Stato del Monitor di Sistema
dashboard.statistic_info=Il database di Gogs ha <b>%d</b> utenti, <b>%d</b> organizzazioni, <b>%d</b> chiavi pubbliche, <b>%d</b> repository, <b>%d</b> utenti che seguono, <b>%d</b> voti, <b>%d</b> azioni, <b>%d</b> accessi, <b>%d</b> problemi, <b>%d</b> commenti, <b>%d</b> account sociali, <b>%d</b> utenti seguiti, <b>%d</b> mirror, <b>%d</b> rilasci, <b>%d</b> fonti di accesso, <b>%d</b> webhook, <b>%d</b> traguardi, <b>%d</b> etichette, <b>%d</b> incarichi hook, <b>%d</b> team, <b>%d</b> attività di aggiornamento, <b>%d</b> allegati.
dashboard.operation_name=Nome Operazione
dashboard.operation_switch=Cambia
dashboard.operation_run=Esegui
dashboard.clean_unbind_oauth=Pulire OAuthes non associati
dashboard.clean_unbind_oauth_success=Tutti gli OAuthes non associati eliminati con successo.
dashboard.delete_inactivate_accounts=Elimina tutti gli account inattivi
dashboard.delete_inactivate_accounts_success=Tutti gli account inattivi eliminati con successo.
dashboard.delete_repo_archives=Elimina tutti gli archivi dei repository
dashboard.delete_repo_archives_success=Tutti gli archivi del repository sono stati eliminati con successo.
dashboard.git_gc_repos=Fare la procedura di garbage collection sui repository
dashboard.git_gc_repos_success=Tutti i repository hanno fatto la procedura di garbage collection con successo.
dashboard.resync_all_sshkeys=Riscrivi il file '.ssh/authorized_keys' (attenzione: le chiavi non appartenenti a Gogs saranno perse)
dashboard.resync_all_sshkeys_success=Tutte le chiavi pubbliche riscritte con successo.
dashboard.resync_all_update_hooks=Riscrivere tutti gli update hook dei repository (necessario quando il percorso di configurazione personalizzata viene modificato)
dashboard.resync_all_update_hooks_success=Tutti gli update hook dei repository riscritti con successo.
dashboard.server_uptime=Tempo in Attività del Server
dashboard.current_goroutine=Goroutine Correnti
dashboard.current_memory_usage=Utilizzo di Memoria Corrente
dashboard.total_memory_allocated=Memoria Allocata Totale
dashboard.memory_obtained=Memoria Ottenuta
dashboard.pointer_lookup_times=Ricerche del Puntatore
dashboard.memory_allocate_times=Allocazioni Memoria
dashboard.memory_free_times=Svuotamenti di Memoria
dashboard.current_heap_usage=Utilizzo Heap Corrente
dashboard.heap_memory_obtained=Memoria Heap Ottenuta
dashboard.heap_memory_idle=Memoria Heap Inattiva
dashboard.heap_memory_in_use=Memoria Heap In Uso
dashboard.heap_memory_released=Memoria Heap Rilasciata
dashboard.heap_objects=Oggetti dell'Heap
dashboard.bootstrap_stack_usage=Utilizzo Pila di Bootstrap
dashboard.stack_memory_obtained=Memoria Stack Ottenuta
dashboard.mspan_structures_usage=Utilizzo Strutture MSpan
dashboard.mspan_structures_obtained=Strutture MSpan Ottenute
dashboard.mcache_structures_usage=Utilizzo di Strutture MCache
dashboard.mcache_structures_obtained=Strutture MCache Ottenute
dashboard.profiling_bucket_hash_table_obtained=Tabella di Hash del Bucket Ottenuta
dashboard.gc_metadata_obtained=Metadata della GC ottenuta
dashboard.other_system_allocation_obtained=Altre Allocazioni di Sistema Ottenute
dashboard.next_gc_recycle=Prossimo Riciclaggio GC
dashboard.last_gc_time=Dall'Ultimo GC
dashboard.total_gc_time=Pausa Totale della GC
dashboard.total_gc_pause=Pausa Totale della GC
dashboard.last_gc_pause=Ultima pausa della GC
dashboard.gc_times=Esecuzioni GC
users.user_manage_panel=Pannello Gestione Utenti
users.new_account=Crea Nuovo Account
users.name=Nome
users.activated=Attivato
users.admin=Amministratore
users.repos=Repo
users.created=Creato
users.edit=Modifica
users.auth_source=Origine Autorizzazione
users.local=Locale
users.auth_login_name=Nome di Accesso dell'Autorizzazione
users.update_profile_success=Profilo dell'account aggiornato con successo.
users.edit_account=Modifica Account
users.is_activated=Questo account è attivato
users.is_admin=Questo account ha permessi di amministratore
users.allow_git_hook=Questo account ha il permesso di creare hooks di Git
users.update_profile=Aggiornare Profilo Account
users.delete_account=Elimina Questo Account
users.still_own_repo=Questo account possiede ancora almeno un repository, devi prima cancellarli o trasferirli.
users.still_has_org=Questo account appartiene ancora ad almeno un'organizzazione, è necessario prima abbandonarle o eliminale.
orgs.org_manage_panel=Pannello Gestione Organizzazioni
orgs.name=Nome
orgs.teams=Team
orgs.members=Membri
repos.repo_manage_panel=Pannello Organizzazione Repository
repos.owner=Proprietario
repos.name=Nome
repos.private=Privati
repos.watches=Segue
repos.stars=Voti
repos.issues=Problemi
auths.auth_manage_panel=Pannello Gestione Autorizzazioni
auths.new=Aggiungi Nuova Origine Autorizzazione
auths.name=Nome
auths.type=Tipo
auths.enabled=Attivo
auths.updated=Aggiornato
auths.auth_type=Tipo di Autorizzazione
auths.auth_name=Nome Autorizzazione
auths.domain=Dominio
auths.host=Host
auths.port=Porta
auths.base_dn=Base DN
auths.attribute_username=Attributo Nome Utente
auths.attribute_name=Attributo Nome
auths.attribute_surname=Attributo Cognome
auths.attribute_mail=Attributo Email
auths.filter=Filtro di Ricerca
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Tipo di Autorizzazione SMTP
auths.smtphost=Host SMTP
auths.smtpport=Porta SMTP
auths.enable_tls=Abilitare Crittografia TLS
auths.pam_service_name=Nome del Servizio PAM
auths.enable_auto_register=Abilitare Registrazione Automatica
auths.tips=Consigli
auths.edit=Modificare Impostazioni Autorizzazioni
auths.activated=Questa Autenticazione è stata attivata
auths.update_success=Impostazione dell'Autorizzazione aggiornate con successo.
auths.update=Aggiorna Impostazioni Autorizzazioni
auths.delete=Elimina Questa Autorizzazione
auths.delete_auth_title=Eliminazione Autorizzazione
auths.delete_auth_desc=Questa autorizzazione sarà cancellata, vuoi continuare?
config.server_config=Configurazione Server
config.app_name=Nome Applicazione
config.app_ver=Versione Applicazione
config.app_url=URL Applicazione
config.domain=Dominio
config.offline_mode=Modalità Offline
config.disable_router_log=Disattivare Log del Router
config.run_user=Utente Esecutore
config.run_mode=Modalità Esecuzione
config.repo_root_path=Percorso Root del Repository
config.static_file_root_path=Percorso Root del File Statico
config.log_file_root_path=Percorso Root del File di Log
config.script_type=Tipo di Script
config.reverse_auth_user=Autenticazione Utente Inversa
config.db_config=Configurazione Database
config.db_type=Tipo
config.db_host=Host
config.db_name=Nome
config.db_user=Utente
config.db_ssl_mode=Modalità SSL
config.db_ssl_mode_helper=(solo per "postgres")
config.db_path=Percorso
config.db_path_helper=(solo per "sqlite3")
config.service_config=Configurazione Servizio
config.register_email_confirm=Richiedono Conferma dell'Email
config.disable_register=Disabilita Registrazione
config.show_registration_button=Mostra Pulsane Registrazione
config.require_sign_in_view=Richiesto Accesso per Vedere
config.mail_notify=Email di Notifica
config.enable_cache_avatar=Abilitare Cache dell'Avatar
config.active_code_lives=Attiva Vita del Codice
config.reset_password_code_lives=Reimpostare Password della Vita del Codice
config.webhook_config=Configurazione Webhook
config.task_interval=Intervallo Attività
config.deliver_timeout=Tempo Limite di Consegna
config.skip_tls_verify=Salta verifiche TLS
config.mailer_config=Configurazione Mailer
config.mailer_enabled=Attivo
config.mailer_disable_helo=Disattiva HELO
config.mailer_name=Nome
config.mailer_host=Host
config.mailer_user=Utente
config.oauth_config=Configurazione OAuth
config.oauth_enabled=Attivo
config.cache_config=Configurazione Cache
config.cache_adapter=Adattatore Cache
config.cache_interval=Intervallo Cache
config.cache_conn=Connessione Cache
config.session_config=Configurazione Sessione
config.session_provider=Fornitore Sessione
config.provider_config=Impostazioni Provider
config.cookie_name=Nome del Cookie
config.enable_set_cookie=Abilita Uso dei Cookie
config.gc_interval_time=Intervallo di tempo della GC
config.session_life_time=Durata Sessione
config.https_only=Solo HTTPS
config.cookie_life_time=Durata Cookie
config.picture_config=Configurazione Foto
config.picture_service=Servizio foto
config.disable_gravatar=Disabilita Gravatar
config.log_config=Configurazione Log
config.log_mode=Modalità Log
monitor.cron=Incarici di cron
monitor.name=Nome
monitor.schedule=Agenda
monitor.next=La Prossima Volta
monitor.previous=La Scorsa Volta
monitor.execute_times=Numero di Esecuzioni
monitor.process=Processi in Esecuzione
monitor.desc=Descrizione
monitor.start=Orario Avvio
monitor.execute_time=Tempo di Esecuzione
notices.system_notice_list=Avvisi di Sistema
notices.type=Tipo
notices.type_1=Repository
notices.desc=Descrizione
notices.op=Op.
notices.delete_success=Avviso di sistema cancellato con successo.
[action]
create_repo=ha creato il repository <a href="%s">%s</a>
commit_repo=ha pushato nel <a href="%s/src/%s">%[2]s</a> in <a href="%[1]s">%[3]s</a>
create_issue=`ha aperto il problema <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
push_tag=ha pushato il tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
compare_2_commits=Vedi confronto per questi 2 commit
[tool]
ago=fa
from_now=da adesso
now=ora
1s=1 secondo %s
1m=1 minuto %s
1h=1 ora %s
1d=1 giorno %s
1w=1 settimana %s
1mon=1 mese %s
1y=1 anno %s
seconds=%d secondi %s
minutes=%d minuti %s
hours=%d ore %s
days=%d giorni %s
weeks=%d settimane %s
months=%d mesi %s
years=%d anni %s
raw_seconds=secondi
raw_minutes=minuti

@ -1,4 +1,4 @@
app_desc=Go言語で実装したセルフホストGitサー
app_desc=Go言語で実装したセルフホストGitサービス
home=ホーム
dashboard=ダッシュボード
@ -39,10 +39,18 @@ issues=課題
cancel=キャンセル
[search]
search=検索...
repository=リポジトリ
user=ユーザ
issue=課題
code=コード
[install]
install=インストール
title=初回実行のインストール手順
requite_db_desc=Gogs には、MySQL や PostgreSQL 、SQLite3 が必要です。
db_title=データベース設定
db_type=データベースの種類
host=ホスト
user=ユーザ
@ -52,7 +60,11 @@ db_helper=Mysql INNODB エンジン utf8_general_ci の文字セットを使用
ssl_mode=SSL モード
path=パス
sqlite_helper=SQLite3 データベースのファイル パス
err_empty_sqlite_path=SQLite3 データベースのパスは、空にすることはできません。
general_title=Gogs の全般設定
app_name=アプリケーション名
app_name_helper=素晴らしい組織名を入れてください!
repo_path=リポジトリのルートパス
repo_path_helper=すべての Git リモート リポジトリはこのディレクトリに保存されます。
run_user=実行ユーザ
@ -63,13 +75,24 @@ http_port=HTTP ポート
http_port_helper=アプリケーションが待ち受けするポート番号。
app_url=アプリケーションの URL
app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。
email_title=E-mailサービス設定(Optional)
optional_title=オプション設定
email_title=E-mailサービス設定
smtp_host=SMTP ホスト
smtp_from=差出人
smtp_from_helper=送信者メールアドレス、RFC 5322。フォーマットはメールアドレスのみ、または"Name" <email@example.com>。
mailer_user=送信者の電子メール
mailer_password=送信者のパスワード
notify_title=通知 Settings(Optional)
register_confirm=登録の確認を有効にする
mail_notify=メール通知を有効にする
server_service_title=サーバーとその他のサービスの設定
offline_mode=オフラインモード有効化
offline_mode_popup=プロダクション モードでCDN を無効にし、すべてのリソースファイルをローカルで提供します 。
disable_registration=自己登録を無効にする
disable_registration_popup=自己登録を無効にし、管理者のみがアカウント作成できる
require_sign_in_view=サインインしたユーザのみページ閲覧を許可
require_sign_in_view_popup=サインインしたユーザのみがページを閲覧できます。ビジターはサインインもしくはサインアップページのみ見られます。
admin_setting_desc=今管理者アカウントを作成する必要はありません。ID = 1のユーザ は自動的に管理者の権限を獲得します。
admin_title=管理者アカウントの設定
admin_name=ユーザ名
admin_password=パスワード
@ -120,6 +143,11 @@ invalid_code=申し訳ありませんが、確認用コードが期限切れま
reset_password_helper=パスワードをリセットするにはここをクリック
password_too_short=6文字未満のパスワードは設定できません。
[modal]
yes=はい
no=いいえ
modify=変更
[form]
UserName=ユーザ名
RepoName=リポジトリ名
@ -136,6 +164,7 @@ AdminEmail=管理者の電子メール
require_error=空にできません
alpha_dash_error=アルファベット、数字、ハイフン"-"、アンダースコア"_"のいずれかの必要があります
alpha_dash_dot_error=' アルファベット、数値、ダッシュ(-)、アンダースコア(_) 、ドット(.)のいずれかを入力する必要があります。 '
size_error=`サイズは %s である必要があります`
min_size_error=' 少なくとも %s 文字の必要があります '
max_size_error=' %s 文字以下の必要があります '
email_error=' は有効な電子メール アドレスではない '
@ -150,9 +179,6 @@ org_name_been_taken=組織名は既に使用されています。
team_name_been_taken=チーム名は既に使用されています。
email_been_used=電子メール アドレスは既に使用されています。
ssh_key_been_used=パブリック キー名が使用されています。
illegal_username=あなたのユーザ名に無効な文字が含まれます。
illegal_repo_name=リポジトリ名には無効な文字が含まれています。
illegal_org_name=組織名に無効な文字が含まれています。
illegal_team_name=チーム名に無効な文字が含まれています。
username_password_incorrect=ユーザー名またはパスワードが正しくありません。
enterred_invalid_repo_name=入力したリポジトリの名前が正しいかどうかを確認してください。
@ -183,6 +209,9 @@ followers=フォロワー
starred=スター
following=フォロー
form.name_reserved=ユーザー名 '%s' は予約されています。
form.name_pattern_not_allowed=ユーザ名のパターン '%s' は許可されていません。
[settings]
profile=プロフィール
password=パスワード
@ -227,6 +256,7 @@ primary_email=プライマリに設定
delete_email=削除
add_new_email=新しいe-mailアドレスを追加
add_email=電子メールを追加します。
add_email_confirmation_sent=<b>%s</b> に新しい確認メールを送信しました、次の %d 時間以内に受信トレイを確認し、確認プロセスを完了してください。
add_email_success=新しいe-mail アドレスが追加されました。
manage_ssh_keys=SSH キーを管理
@ -282,6 +312,9 @@ create_repo=リポジトリを作成
default_branch=デフォルトのブランチ
mirror_interval=ミラー 間隔(時)
form.name_reserved=リポジトリ名 '%s' は予約されています。
form.name_pattern_not_allowed=リポジトリ名のパターン '%s' は許可されていません。
need_auth=認証が必要
migrate_type=マイグレーションの種類
migrate_type_helper=このリポジトリは <span class="label label-blue label-radius"> ミラー</span> になります
@ -289,6 +322,8 @@ migrate_repo=リポジトリを移行
migrate.clone_address=クローンアドレス
migrate.invalid_local_path=ローカルパスが無効です。存在しないかディレクトリではありません。
forked_from=フォーク元
fork_from_self=すでにあなたの所有しているリポジトリはフォークできません
copy_link=コピー
click_to_copy=クリップボードにコピー
copied=コピー成功
@ -311,11 +346,14 @@ branch_and_tags=ブランチ& タグ
branches=ブランチ
tags=タグ
issues=課題
labels=ラベル
milestones=マイルストーン
commits=コミット
releases=リリース
file_raw=生データ
file_history=履歴
file_view_raw=生データを見る
file_permalink=パーマリンク
commits.commits=コミット
commits.search=コミットの検索
@ -326,6 +364,34 @@ commits.date=日付
commits.older=古い
commits.newer=新しい
issues.new=新しい問題
issues.new_label=新しいラベル
issues.new_label_placeholder=ラベル名...
issues.open_tab=%d オープン
issues.close_tab=%d クローズ
issues.filter_label=ラベル
issues.filter_label_no_select=選択したラベルがありません。
issues.filter_milestone=マイルストーン
issues.filter_assignee=アサインされた人
issues.filter_type=タイプ
issues.filter_type.all_issues=すべての問題
issues.filter_type.assigned_to_you=あなたに割り当てられました。
issues.filter_type.created_by_you=あなたが作成しました。
issues.filter_type.mentioning_you=あなたに伝える
issues.opened_by=<a href="/%[2]s"> %[2]s</a>によって開かれた %[1]s
issues.previous=前ページ
issues.next=次ページ
issues.label_title=ラベル名
issues.label_color=ラベルの色
issues.label_count=%d ラベル
issues.label_open_issues=%d 未解決の問題
issues.label_edit=編集
issues.label_delete=削除
issues.label_modify=ラベルの変更
issues.label_deletion=ラベルの削除
issues.label_deletion_desc=ラベルを削除すると、関連するすべての問題の情報が削除されます。続行しますか。
issues.label_deletion_success=ラベルは正常に削除されました。
settings=設定
settings.options=オプション
settings.collaboration=コラボレーション
@ -432,6 +498,9 @@ team_name_helper=会話の時、この名前を使用しチーム名を表明し
team_desc_helper=このチームに関する全ての情報は?
team_permission_desc=このチームに必要な権限レベルは?
form.name_reserved=組織名 '%s' は予約されています。
form.name_pattern_not_allowed=組織名のパターン '%s' は許可されていません。
settings=設定
settings.options=オプション
settings.full_name=フルネーム
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=リポジトリのすべてのアーカイブを
dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。
dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。
dashboard.git_gc_repos_success=すべてのリポジトリは正常にガベージ コレクションを行いました。
dashboard.resync_all_sshkeys='.ssh/authorized_key' ファイルを再生成します。(警告:Gogsキー以外は失われます)
dashboard.resync_all_sshkeys='.ssh/ authorized_keys' ファイルを再生成します。(警告:Gogsキー以外は失われます)
dashboard.resync_all_sshkeys_success=すべての公開鍵が正常に書き換えられました。
dashboard.resync_all_update_hooks=リポジトリの update フックをすべて再更新する(カスタムの設定パスが変更されたときに必要)
dashboard.resync_all_update_hooks_success=リポジトリの update フックがすべて正常に再更新されました。
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP 認証の種類
auths.smtphost=SMTP ホスト
auths.smtpport=SMTP ポート
auths.enable_tls=TLS 暗号化を有効にする
auths.pam_service_name=PAMサービス名
auths.enable_auto_register=自動登録を有効にする
auths.tips=ヒント
auths.edit=認証設定を編集
@ -653,6 +723,7 @@ config.deliver_timeout=送信タイムアウト
config.skip_tls_verify=TLSの確認を省略
config.mailer_config=メーラーの構成
config.mailer_enabled=有効にした
config.mailer_disable_helo=HELOコマンド無効
config.mailer_name=名前
config.mailer_host=ホスト
config.mailer_user=ユーザ

@ -39,10 +39,18 @@ issues=Problēmas
cancel=Atcelt
[search]
search=Search...
repository=Repository
user=User
issue=Issue
code=Code
[install]
install=Instalācija
title=Instalācijas soļi pirmo reizi palaižot
requite_db_desc=Gogs ir nepieciešama MySQL, PostgreSQL vai SQLite3 datu bāze.
db_title=Database Settings
db_type=Datu bāzes veids
host=Resursdators
user=Lietotājs
@ -52,7 +60,11 @@ db_helper=Nepieciešams izmantot MySQL INNODB dzini ar rakstzīmju kopu utf8_gen
ssl_mode=SSL režīms
path=Ceļš
sqlite_helper=SQLite 3 datu bāzes faila atrašanās vieta.
err_empty_sqlite_path=SQLite3 database path cannot be empty.
general_title=Gogs vispārīgie iestatījumi
app_name=Application Name
app_name_helper=Put your organization name here huge and loud!
repo_path=Repozitoriju glabāšanas vieta
repo_path_helper=Visi Git attālinātie repozitoriji tiks glabāti šajā direktorijā.
run_user=Izpildes lietotājs
@ -63,13 +75,24 @@ http_port=HTTP ports
http_port_helper=Porta numurs pēc kura lietojumprogrammai būs iespējams pieslēgties.
app_url=Lietotnes URL
app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites.
email_title=E-pasta pakalpojuma iestatījumi (neobligāti)
optional_title=Optional Settings
email_title=E-pasta pakalpojuma iestatījumi
smtp_host=SMTP resursdators
smtp_from=From
smtp_from_helper=Mail from address, RFC 5322. It can be just an email address, or the "Name" <email@example.com> format.
mailer_user=Sūtītāja e-pasta adrese
mailer_password=Sūtītāja parole
notify_title=Paziņojumu iestatījumi (neobligāti)
register_confirm=Iespējot reģistrēšanās apstiprināšanu
mail_notify=Iespējot e-pasta paziņojumus
server_service_title=Server and Other Services Settings
offline_mode=Enable Offline Mode
offline_mode_popup=Disable CDN even in production mode, all resource files will be served locally.
disable_registration=Disable Self-registration
disable_registration_popup=Disable user self-registration, only admin can create accounts.
require_sign_in_view=Enable Require Sign In to View Pages
require_sign_in_view_popup=Only signed in users can view pages, visitors will only be able to see sign in/up pages.
admin_setting_desc=You do not have to create an admin account right now, user whoever ID=1 will gain admin access automatically.
admin_title=Admin konta iestatījumi
admin_name=Lietotājvārds
admin_password=Parole
@ -120,6 +143,11 @@ invalid_code=Atvainojiet, Jūsu apstiprināšanas kodam ir beidzies derīguma te
reset_password_helper=Nospiediet šeit, lai atjaunotu paroli
password_too_short=Paroles garums nedrīkst būt mazāks par 6.
[modal]
yes=Yes
no=No
modify=Modify
[form]
UserName=Lietotājvārds
RepoName=Repozitorija nosaukums
@ -136,6 +164,7 @@ AdminEmail=Admin e-pasta adrese
require_error=` nedrīkst būt tukšs.`
alpha_dash_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus vai domuzīmes (-_).`
alpha_dash_dot_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus, domuzīmes (-_) vai punktu.`
size_error=` must be size %s.`
min_size_error=` jabūt vismaz %s simbolu garumā.`
max_size_error=` jabūt ne mazāk kā %s simbolu garumā.`
email_error=` nav derīga e-pasta adrese.`
@ -150,9 +179,6 @@ org_name_been_taken=Organizācijas nosaukums ir jau aizņemts.
team_name_been_taken=Komandas nosaukums ir jau aizņemts.
email_been_used=E-pasta adrese jau tiek izmantota.
ssh_key_been_used=Publiskās atslēgas nosaukums jau tiek izmantos.
illegal_username=Jūsu lietotājvārds satur neatļautas rakstzīmes.
illegal_repo_name=Krātuves nosaukums satur neatļautas rakstzīmes.
illegal_org_name=Organizācijas nosaukums satur neatļautas rakstzīmes.
illegal_team_name=Grupas nosaukums satur neatļautas rakstzīmes.
username_password_incorrect=Lietotājvārds vai parole nav pareiza.
enterred_invalid_repo_name=Lūdzu, pārliecinieties, vai ievadītā repozitorija nosaukums ir pareizs.
@ -183,6 +209,9 @@ followers=Sekotāji
starred=Atzīmēti ar zvaigznīti
following=Seko
form.name_reserved=Username '%s' is reserved.
form.name_pattern_not_allowed=Username pattern '%s' is not allowed.
[settings]
profile=Profils
password=Parole
@ -227,6 +256,7 @@ primary_email=Iestatīt kā primāro
delete_email=Dzēst
add_new_email=Pievienot jaunu e-pasta adresi
add_email=Pievienot e-pastu
add_email_confirmation_sent=A new confirmation e-mail has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete the confirmation process.
add_email_success=Jūsu jaunā e-pasta adrese tika veiksmīgi pievienota.
manage_ssh_keys=Pārvaldīt SSH atslēgas
@ -282,6 +312,9 @@ create_repo=Izveidot repozitoriju
default_branch=Noklusējuma atzars
mirror_interval=Spoguļošanas intervāls (stundās)
form.name_reserved=Repository name '%s' is reserved.
form.name_pattern_not_allowed=Repository name pattern '%s' is not allowed.
need_auth=Nepieciešama autorizācija
migrate_type=Migrācijas veids
migrate_type_helper=Šis repozitorijs būs <span class="label label-blue label-radius">Spoguļots</span>
@ -289,6 +322,8 @@ migrate_repo=Migrēt repozitoriju
migrate.clone_address=Clone Address
migrate.invalid_local_path=Invalid local path, it does not exist or not a directory.
forked_from=forked from
fork_from_self=You cannot fork repository you already owned!
copy_link=Kopēt
click_to_copy=Kopēt uz starpliktuvi
copied=Kopēšana notikusi veiksmīgi
@ -311,11 +346,14 @@ branch_and_tags=Atzari un tagi
branches=Atzari
tags=Tagi
issues=Problēmas
labels=Labels
milestones=Milestones
commits=Revīzijas
releases=Laidieni
file_raw=Neapstrādāts
file_history=Vēsture
file_view_raw=Rādīt neapstrādātu
file_permalink=Permalink
commits.commits=Revīzijas
commits.search=Meklēt revīzijas
@ -326,6 +364,34 @@ commits.date=Datums
commits.older=Vecāki
commits.newer=Jaunāki
issues.new=New Issue
issues.new_label=New Label
issues.new_label_placeholder=Label name...
issues.open_tab=%d Open
issues.close_tab=%d Closed
issues.filter_label=Label
issues.filter_label_no_select=No selected label
issues.filter_milestone=Milestone
issues.filter_assignee=Assignee
issues.filter_type=Type
issues.filter_type.all_issues=All issues
issues.filter_type.assigned_to_you=Assigned to you
issues.filter_type.created_by_you=Created by you
issues.filter_type.mentioning_you=Mentioning you
issues.opened_by=opened %[1]s by <a href="/%[2]s">%[2]s</a>
issues.previous=Previous Page
issues.next=Next Page
issues.label_title=Label name
issues.label_color=Label color
issues.label_count=%d labels
issues.label_open_issues=%d open issues
issues.label_edit=Edit
issues.label_delete=Delete
issues.label_modify=Label Modification
issues.label_deletion=Label Deletion
issues.label_deletion_desc=Delete label will remove its information in all related issues. Do you want to continue?
issues.label_deletion_success=Label has been deleted successfully!
settings=Iestatījumi
settings.options=Opcijas
settings.collaboration=Sadarbība
@ -432,6 +498,9 @@ team_name_helper=Šo nosaukumu varēs izmantot, lai pieminētu komandu sarunās.
team_desc_helper=Komandas apraksts
team_permission_desc=Kādām tiesībām šai komandai būtu jābūt?
form.name_reserved=Organization name '%s' is reserved.
form.name_pattern_not_allowed=Organization name pattern '%s' is not allowed.
settings=Iestatījumi
settings.options=Opcijas
settings.full_name=Pilns vārds, uzvārds
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=Dzēst visu repozitoriju arhīvus
dashboard.delete_repo_archives_success=Visu repozitoriju arhīvi tika veiksmīgi izdzēsti.
dashboard.git_gc_repos=Veikt repozitoriju datu sakārtošānu (git gc)
dashboard.git_gc_repos_success=Datu sakārtošana visiem repozitorijiem veiksmīgi pabeigta.
dashboard.resync_all_sshkeys=Pārrakstīt '.ssh/authorized_key' failu (brīdinājums: ne-Git atslēgas tiks pazaudētas)
dashboard.resync_all_sshkeys=Pārrakstīt '.ssh/authorized_keys' failu (brīdinājums: ne-Git atslēgas tiks pazaudētas)
dashboard.resync_all_sshkeys_success=Visas publiskās atslēgas tika veiksmīgi pārrakstītas.
dashboard.resync_all_update_hooks=Pārrakstīt visu repozitoriju izmaiņu āķus (nepieciešams, ja tiek mainīta konfigurācijas faila atrašanās vieta)
dashboard.resync_all_update_hooks_success=Visu repozitoriju izmaiņu āķi tika veiksmīgi pārrakstīti.
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP autorizācijas veids
auths.smtphost=SMTP resursdators
auths.smtpport=SMTP ports
auths.enable_tls=Iespējot TLS šifrēšanu
auths.pam_service_name=PAM Service Name
auths.enable_auto_register=Iespējot automātisko reģistrāciju
auths.tips=Padomi
auths.edit=Labot autorizācijas iestatījumus
@ -653,6 +723,7 @@ config.deliver_timeout=Piegādes noildze
config.skip_tls_verify=Izlaist TLS pārbaudi
config.mailer_config=Sūtītāja konfigurācija
config.mailer_enabled=Iespējots
config.mailer_disable_helo=Disable HELO
config.mailer_name=Nosaukums
config.mailer_host=Resursdators
config.mailer_user=Lietotājs

@ -1,4 +1,4 @@
app_desc=Een pijnloze self-hosted Git-dienst geschreven in Go
app_desc=Een eenvoudige zelfgehoste Git service geschreven in Go
home=Huis
dashboard=Dashboard
@ -39,10 +39,18 @@ issues=Kwesties
cancel=Annuleer
[search]
search=Zoeken...
repository=Opslagplaats
user=Gebruiker
issue=Probleem
code=Code
[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_title=Database instellingen
db_type=Database-type
host=Host
user=Gebruikersnaam
@ -52,7 +60,11 @@ 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
err_empty_sqlite_path=SQLite3 database pad mag niet leeg zijn.
general_title=Toepassing algemene instellingen
app_name=Applicatienaam
app_name_helper=Plaats hier je organisatienaam in grote letters!
repo_path=Repositories basis directorie
repo_path_helper=Alle remote Git repositories worden in deze directorie opgeslagen
run_user=Uitvoerende gebruikersnaam
@ -63,13 +75,24 @@ http_port=HTTP-poort
http_port_helper=Poortnummer waar het programma naar luistert.
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=E-mail service instellingen (Optioneel)
optional_title=Optionele instellingen
email_title=E-mail service instellingen
smtp_host=SMTP host
smtp_from=Afzender
smtp_from_helper=Email afzender, RFC 5322. Dit kan gewoon een email adres zijn of het "Naam"<email@example.com> formaat.
mailer_user=Afzender e-mail / gebruikersnaam
mailer_password=Wachtwoord
notify_title=Notificatie-instelligen (optioneel)
register_confirm=Activeer registratie emails
mail_notify=Activeer e-mailnotificaties
server_service_title=Server en andere Services-instellingen
offline_mode=Off line modus inschakelen
offline_mode_popup=Schakel CDN uit in productiemodus, alle bestanden worden lokaal aangeboden.
disable_registration=Schakel zelfregistratie uit
disable_registration_popup=Schakel zelfregistratie uit, alleen admins kunnen accounts maken.
require_sign_in_view=Schakel vereiste aanmelding om pagina's te zien in
require_sign_in_view_popup=Alleen ingelogde gebruikers kunnen pagina's bekijken, bezoekers kunnen alleen de login/registratie pagina's zien.
admin_setting_desc=U hoeft niet meteen een administratie account te maken, de gebruiker met ID=1 krijgt automatisch administratierechten.
admin_title=Instellingen beheerdersaccount
admin_name=Gebruikersnaam
admin_password=Wachtwoord
@ -120,6 +143,11 @@ 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.
[modal]
yes=Ja
no=Nee
modify=Aanpassen
[form]
UserName=Gebruikersnaam
RepoName=Repositorie naam
@ -136,6 +164,7 @@ AdminEmail=E-mail beheerder
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.
size_error=moet groter zijn dan %s
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.
@ -150,9 +179,6 @@ 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.
@ -183,6 +209,9 @@ followers=Volgers
starred=Sterren
following=Volgt
form.name_reserved=De gebruikersnaam '%s' is gereserveerd.
form.name_pattern_not_allowed=Het gebruikersnaam patroon '%s' is niet toegestaan.
[settings]
profile=Profiel
password=Wachtwoord
@ -227,6 +256,7 @@ primary_email=Instellen als primair
delete_email=Verwijder
add_new_email=Nieuw e-mailadres toevoegen
add_email=E-mailadres toevoegen
add_email_confirmation_sent=Een nieuwe bevestiging e-mail werd verstuurd naar <b>%s</b>, gelieve uw inbox in de komende %d uren te controleren om het bevestigingsproces te voltooien.
add_email_success=Het e-mailadres was toegevoegd.
manage_ssh_keys=Beheer SSH sleutels
@ -282,13 +312,18 @@ create_repo=Nieuwe Repositorie
default_branch=Standaard branch
mirror_interval=Mirror interval(uur)
form.name_reserved=Repositorienaam '%s' is gereserveerd.
form.name_pattern_not_allowed=Repositorie naampatroon '%s' is niet toegestaan.
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
migrate.clone_address=Clone Address
migrate.invalid_local_path=Invalid local path, it does not exist or not a directory.
migrate.clone_address=Clone adres
migrate.invalid_local_path=Ongeldig lokaal pad, het pad bestaat niet of het is geen map.
forked_from=geforked van
fork_from_self=U kunt geen repository forken die u al beheert!
copy_link=Kopieer
click_to_copy=Kopieer link naar plakbord
copied=Gekopieerd
@ -311,11 +346,14 @@ branch_and_tags=Aftakkingen & labels
branches=Aftakkingen
tags=Labels
issues=Kwesties
labels=Labels
milestones=Mijlpalen
commits=Commits
releases=Publicaties
file_raw=Ruwe
file_history=Geschiedenis
file_view_raw=Weergave ruwe
file_permalink=Permalink
commits.commits=Commits
commits.search=Zoeken
@ -326,6 +364,34 @@ commits.date=Datum
commits.older=Ouder
commits.newer=Nieuwer
issues.new=New Issue
issues.new_label=Nieuw Label
issues.new_label_placeholder=Tekst label...
issues.open_tab=%d Open
issues.close_tab=%d gesloten
issues.filter_label=Label
issues.filter_label_no_select=Geen label geselecteerd
issues.filter_milestone=Mijlpaal
issues.filter_assignee=Aangewezene
issues.filter_type=Type
issues.filter_type.all_issues=Alle kwesties
issues.filter_type.assigned_to_you=Aan jou toegewezen
issues.filter_type.created_by_you=Created by you
issues.filter_type.mentioning_you=Mentioning you
issues.opened_by=opened %[1]s by <a href="/%[2]s">%[2]s</a>
issues.previous=Previous Page
issues.next=Next Page
issues.label_title=Label name
issues.label_color=Label color
issues.label_count=%d labels
issues.label_open_issues=%d open issues
issues.label_edit=Edit
issues.label_delete=Delete
issues.label_modify=Label Modification
issues.label_deletion=Label Deletion
issues.label_deletion_desc=Delete label will remove its information in all related issues. Do you want to continue?
issues.label_deletion_success=Label has been deleted successfully!
settings=Instellingen
settings.options=Opties
settings.collaboration=Samenwerking
@ -432,6 +498,9 @@ 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?
form.name_reserved=Organisatienaam '%s' is gereserveerd.
form.name_pattern_not_allowed=Organisatie naampatroon '%s' is niet toegestaan.
settings=Instellingen
settings.options=Opties
settings.full_name=Volledige naam
@ -595,16 +664,17 @@ auths.domain=Domein
auths.host=Host
auths.port=Poort
auths.base_dn=Base DN
auths.attribute_username=Username attribute
auths.attribute_name=First name attribute
auths.attribute_surname=Surname attribute
auths.attribute_mail=E-mail attribute
auths.attribute_username=Gebruikersnaam attribuut
auths.attribute_name=Voornaam attribuut
auths.attribute_surname=Achternaam attribuut
auths.attribute_mail=E-mail attribuut
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.pam_service_name=PAM servicenaam
auths.enable_auto_register=Activeer automatische registratie
auths.tips=Tips
auths.edit=Bewerk autorisatie-instellingen
@ -653,6 +723,7 @@ config.deliver_timeout=Bezorging verlooptijd
config.skip_tls_verify=TLS certificaat controle overslaan
config.mailer_config=Mailerconfiguatie
config.mailer_enabled=Ingeschakeld
config.mailer_disable_helo=Schakel HELO uit
config.mailer_name=Naam
config.mailer_host=Host
config.mailer_user=Gebruiker

@ -39,10 +39,18 @@ issues=Problemy
cancel=Anuluj
[search]
search=Wyszukiwanie...
repository=Repozytorium
user=Użytkownik
issue=Zgłoszenie
code=Kod
[install]
install=Instalacja
title=Kroki instalacyjne dla pierwszego uruchomienia
requite_db_desc=Gogs wymaga MySQL, PostgreSQL lub SQLite3.
db_title=Ustawienia bazy danych
db_type=Typ bazy danych
host=Host
user=Użytkownik
@ -52,7 +60,11 @@ db_helper=Proszę użyć silnika INNODB z kodowaniem utf8_general_ci dla MySQL.
ssl_mode=Tryb SSL
path=Ścieżka
sqlite_helper=Ścieżka do bazy SQLite3.
err_empty_sqlite_path=Ścieżka do bazy danych SQLite3 nie może być pusta.
general_title=Ustawienia ogólne Gogs
app_name=Nazwa aplikacji
app_name_helper=Umieść tutaj wielką i głośną nazwę swojej organizacji!
repo_path=Katalog repozytoriów
repo_path_helper=W tym katalogu zostaną zapisane wszystkie repozytoria Git.
run_user=Nazwa użytkownika uruchomieniowego
@ -63,13 +75,24 @@ http_port=Port HTTP
http_port_helper=Numer portu na którym aplikacja jest dostępna.
app_url=Adres URL aplikacji
app_url_helper=To wpłynie na adresy klonowania HTTP/HTTPS i w wiadomościach e-mail.
email_title=Ustawienia serwera e-mail (opcjonalne)
optional_title=Ustawienia opcjonalne
email_title=Ustawienia serwera e-mail
smtp_host=Serwer SMTP
smtp_from=Od
smtp_from_helper=Adres w polu "Od", zgodnie z RFC 5322. Może być to po prostu adres email, bądź adres w formacie "Nazwa" <email@example.com>.
mailer_user=Nadawca wiadomości E-mail
mailer_password=Hasło nadawcy
notify_title=Ustawienia powiadomień (opcjonalne)
register_confirm=Włącz potwierdzenia rejestracji
mail_notify=Włącz powiadomienia e-mail
server_service_title=Ustawienia serwera i innych usług
offline_mode=Włącz tryb offline
offline_mode_popup=Wyłącz CDN, nawet w trybie produkcyjnym, wszystkie pliki zasobów będą podawane lokalnie.
disable_registration=Wyłącz samodzielną rejestrację
disable_registration_popup=Wyłącz samodzielną rejestrację użytkownika, tylko administrator będzie mógł tworzyć konta.
require_sign_in_view=Włącz wymóg zalogowania do przeglądania stron
require_sign_in_view_popup=Tylko zalogowani użytkownicy będą mogli przeglądać strony, goście zobaczą tylko stronę logowania.
admin_setting_desc=Nie musisz tworzyć konta administratora teraz, użytkownik z ID = 1 zyska dostęp administratora automatycznie.
admin_title=Ustawienia konta administratora
admin_name=Nazwa Użytkownika
admin_password=Hasło
@ -120,6 +143,11 @@ invalid_code=Niestety, twój kod potwierdzający wygasł lub jest nieprawidłowy
reset_password_helper=Kliknij tutaj, aby zresetować hasło
password_too_short=Długość hasła nie może być mniejsza niż 6 znaków.
[modal]
yes=Yes
no=No
modify=Modify
[form]
UserName=Nazwa Użytkownika
RepoName=Nazwa repozytorium
@ -136,6 +164,7 @@ AdminEmail=E-mail administratora
require_error=` nie może być puste.`
alpha_dash_error=` musi się składać z prawidłowych znaków alfanumerycznych, myślników oraz podkreśleń.`
alpha_dash_dot_error=` musi się składać z prawidłowych znaków alfanumerycznych, myślników, podkreśleń oraz kropek.`
size_error=` must be size %s.`
min_size_error=` musi zawierać co najwyżej %s znaków.`
max_size_error=` musi zawierać co najwyżej %s znaków.`
email_error=` nie jest poprawnym adresem e-mail.`
@ -150,9 +179,6 @@ org_name_been_taken=Nazwa organizacji jest już zajęta.
team_name_been_taken=Nazwa zespołu jest już zajęta.
email_been_used=Adres e-mail jest już zarejestrowany.
ssh_key_been_used=Nazwa klucza publicznego jest już używana.
illegal_username=Twoja nazwa użytkownika zawiera niedozwolone znaki.
illegal_repo_name=Nazwa repozytorium zawiera niedozwolone znaki.
illegal_org_name=Nazwa organizacji zawiera niedozwolone znaki.
illegal_team_name=Nazwa zespołu zawiera niedozwolone znaki.
username_password_incorrect=Nazwa użytkownika lub hasło nie jest prawidłowe.
enterred_invalid_repo_name=Upewnij się, że wprowadzona nazwa repozytorium jest poprawna.
@ -183,6 +209,9 @@ followers=Obserwujący
starred=Polubionych
following=Obserwowani
form.name_reserved=Nazwa użytkownika "%s" jest zarezerwowana.
form.name_pattern_not_allowed=Wzorzec nazwy użytkownika "%s" jest niedozwolony.
[settings]
profile=Profil
password=Hasło
@ -227,6 +256,7 @@ primary_email=Ustaw jako podstawowy
delete_email=Usuń
add_new_email=Dodaj nowy e-mail
add_email=Dodaj e-mail
add_email_confirmation_sent=Nowa wiadomość e-mail z potwierdzeniem została wysłana do <b>%s</b>, proszę sprawdzić swoją skrzynkę odbiorczą w ciągu %d godzin, aby dokończyć proces potwierdzania.
add_email_success=Twój nowy e-mail został dodany pomyślnie.
manage_ssh_keys=Zarządzaj kluczami SSH
@ -282,6 +312,9 @@ create_repo=Utwórz repozytorium
default_branch=Domyślna gałąź
mirror_interval=Odświeżanie mirrorów (godziny)
form.name_reserved=Nazwa repozytorium "%s" jest zarezerwowana.
form.name_pattern_not_allowed=Wzorzec nazwy repozytorium "%s" jest niedozwolony.
need_auth=Wymaga autoryzacji
migrate_type=Typ migracji
migrate_type_helper=Repozytorium będzie <span class="label label-blue label-radius">mirrorem</span>
@ -289,6 +322,8 @@ migrate_repo=Przenieś repozytorium
migrate.clone_address=Sklonuj adres
migrate.invalid_local_path=Ścieżka jest niepoprawna. Nie istnieje lub nie jest katalogiem.
forked_from=forked from
fork_from_self=You cannot fork repository you already owned!
copy_link=Kopiuj
click_to_copy=Kopiuj do schowka
copied=Skopiowano
@ -311,11 +346,14 @@ branch_and_tags=Gałęzie i tagi
branches=Gałęzie
tags=Tagi
issues=Problemy
labels=Labels
milestones=Milestones
commits=Commity
releases=Wydania
file_raw=Czysty
file_history=Historia
file_view_raw=Zobacz czysty
file_permalink=Permalink
commits.commits=Commity
commits.search=Przeszukaj commity
@ -326,6 +364,34 @@ commits.date=Data
commits.older=Starsze
commits.newer=Nowsze
issues.new=New Issue
issues.new_label=New Label
issues.new_label_placeholder=Label name...
issues.open_tab=%d Open
issues.close_tab=%d Closed
issues.filter_label=Label
issues.filter_label_no_select=No selected label
issues.filter_milestone=Milestone
issues.filter_assignee=Assignee
issues.filter_type=Type
issues.filter_type.all_issues=All issues
issues.filter_type.assigned_to_you=Assigned to you
issues.filter_type.created_by_you=Created by you
issues.filter_type.mentioning_you=Mentioning you
issues.opened_by=opened %[1]s by <a href="/%[2]s">%[2]s</a>
issues.previous=Previous Page
issues.next=Next Page
issues.label_title=Label name
issues.label_color=Label color
issues.label_count=%d labels
issues.label_open_issues=%d open issues
issues.label_edit=Edit
issues.label_delete=Delete
issues.label_modify=Label Modification
issues.label_deletion=Label Deletion
issues.label_deletion_desc=Delete label will remove its information in all related issues. Do you want to continue?
issues.label_deletion_success=Label has been deleted successfully!
settings=Ustawienia
settings.options=Opcje
settings.collaboration=Współpraca
@ -354,9 +420,9 @@ settings.add_collaborator_success=Został dodany nowy współpracownik.
settings.remove_collaborator_success=Współpracownik został usunięty.
settings.user_is_org_member=Użytkownik jest członkiem organizacji, który nie może być dodany jako współpracownik.
settings.add_webhook=Dodaj Webhooka
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="%s">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.hooks_desc=Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
settings.githooks_desc=Doczepki Git są napędzane przez samego Git, można edytować pliki obsługiwanych doczepek z poniższej listy, aby wykonywać niestandardowe operacje.
settings.githook_edit_desc=Jeżeli doczepka jest nieaktywna, prezentowana będzie przykładowa treść. Pozostawienie pustej wartości wyłączy tą doczepkę.
settings.githook_name=Nazwa skryptu
settings.githook_content=Treść skryptu
settings.update_githook=Zaktualizuj skrypt
@ -432,6 +498,9 @@ team_name_helper=Będziesz używał tej nazwy do wywoływania tego zespołu w dy
team_desc_helper=Czym zajmuje się ten zespół?
team_permission_desc=Jaki poziom uprawnień powinien mieć ten zespół?
form.name_reserved=Nazwa organizacji "%s" jest zarezerwowana.
form.name_pattern_not_allowed=Wzorzec nazwy organizacji "%s" jest niedozwolony.
settings=Ustawienia
settings.options=Opcje
settings.full_name=Imię i Nazwisko
@ -439,14 +508,14 @@ settings.website=Strona
settings.location=Lolalizacja
settings.update_settings=Aktualizuj ustawienia
settings.change_orgname=Zmieniono nazwę organizacji
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 updated successfully.
settings.change_orgname_desc=Zmieniono nazwę organizacji. Wpływa to na powiązanie odnośników z organizacją. Czy chcesz kontynuować?
settings.update_setting_success=Ustawienia organizacji zostały pomyślnie zaktualizowane.
settings.delete=Usuń Organizację
settings.delete_account=Usuń tą organizację
settings.delete_prompt=The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
settings.delete_prompt=Organizacja zostanie trwale usunięta, a to <strong>NIE MOŻE</strong> być cofnięte!
settings.confirm_delete_account=Potwierdź usunięcie
settings.delete_org_title=Usunięcie organizacji
settings.delete_org_desc=This organization is going to be deleted permanently, do you want to continue?
settings.delete_org_desc=Ta organizacja zostanie trwale usunięta, czy chcesz kontynuować?
settings.hooks_desc=Add webhooks that will be triggered for <strong>all repositories</strong> under this organization.
members.public=Publiczne
@ -471,7 +540,7 @@ teams.admin_access=Uprawnienia admina
teams.admin_access_helper=Ten zespół będzie mógł wysyłać i pobierać swoje repozytoria, oraz dodawać do nich współpracowników.
teams.no_desc=Ten zespół nie ma opisu
teams.settings=Ustawienia
teams.owners_permission_desc=Owners have full access to <strong>all repositories</strong> and have <strong>admin rights</strong> to the organization.
teams.owners_permission_desc=Właściciele mają pełny dostęp do <strong>wszystkich repozytoriów</strong> i mają <strong>prawa administratora</strong> w organizacji.
teams.members=Członkowie zespołu
teams.update_settings=Aktualizuj ustawienia
teams.delete_team=Usuń ten zespół
@ -513,8 +582,8 @@ dashboard.delete_inactivate_accounts_success=Wszystkie nieaktywne konta zostały
dashboard.delete_repo_archives=Usuń wszystkie archiwa repozytoriów
dashboard.delete_repo_archives_success=Pomyślnie usunięto wszystkie archiwa repozytoriów.
dashboard.git_gc_repos=Usuń śmieci z repozytoriów
dashboard.git_gc_repos_success=All repositories have done garbage collection successfully.
dashboard.resync_all_sshkeys=Przeładuj klucze publiczne w pliku '.ssh/authorized_key' (uwaga: klucze poza Gogs zostaną usunięte)
dashboard.git_gc_repos_success=Wszystkie repozytoria zakończyły odśmiecanie pomyślnie.
dashboard.resync_all_sshkeys=Przeładuj klucze publiczne w pliku '.ssh/authorized_keys' (uwaga: klucze poza Gogs zostaną usunięte)
dashboard.resync_all_sshkeys_success=Przeładowanie kluczy publicznych zakończyło się sukcesem.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
@ -559,7 +628,7 @@ users.created=Utworzony
users.edit=Edytuj
users.auth_source=Źródła autoryzacji
users.local=Lokalne
users.auth_login_name=Authorization Login Name
users.auth_login_name=Login Autoryzacyjny
users.update_profile_success=Profil konta został pomyślnie zaktualizowany.
users.edit_account=Edytuj konto
users.is_activated=To konto jest aktywne
@ -583,7 +652,7 @@ repos.watches=Obserwujących
repos.stars=Polubienia
repos.issues=Problemy
auths.auth_manage_panel=Authorization Manage Panel
auths.auth_manage_panel=Zarzadzanie Autoryzacja
auths.new=Dodaj nowe źródło autoryzacji
auths.name=Nazwa
auths.type=Typ
@ -605,6 +674,7 @@ auths.smtp_auth=Typ autoryzacji SMTP
auths.smtphost=Serwer SMTP
auths.smtpport=Port SMTP
auths.enable_tls=Włącz szyfrowanie TLS
auths.pam_service_name=Nazwa usługi PAM
auths.enable_auto_register=Włącz automatyczną rejestrację
auths.tips=Wskazówki
auths.edit=Edytuj ustawienia autoryzacji
@ -653,6 +723,7 @@ config.deliver_timeout=Limit czasu zdarzenia
config.skip_tls_verify=Pomiń weryfikację protokołu TLS
config.mailer_config=Konfiguracja poczty
config.mailer_enabled=Aktywne
config.mailer_disable_helo=Wyłącz HELO
config.mailer_name=Nazwa
config.mailer_host=Host
config.mailer_user=Użytkownik

@ -39,10 +39,18 @@ issues=Problemas
cancel=Cancelar
[search]
search=Pesquisar...
repository=Repositório
user=Usuário
issue=Problema
code=Código
[install]
install=Instalação
title=Etapas de instalação para Primeira Execução
requite_db_desc=Gogs requer MySQL, PostgreSQL ou SQLite3.
db_title=Configurações de Banco de Dados
db_type=Tipo do Banco de Dados
host=Host
user=Usuário
@ -52,7 +60,11 @@ db_helper=Por favor, use o mecanismo INNODB com o conjunto de caracteres utf8_ge
ssl_mode=Modo SSL
path=Caminho
sqlite_helper=O caminho do arquivo do banco de dados do SQLite3.
err_empty_sqlite_path=O caminho do arquivo de banco de dados SQLite3 não pode estar em branco.
general_title=Configurações Gerais do Gogs
app_name=Nome do Aplicativo
app_name_helper=Coloque o nome da sua organização aqui!
repo_path=Caminho da Raiz do Repositório
repo_path_helper=Todos os repositórios remotos do Git serão salvos neste diretório.
run_user=Executar Usuário
@ -63,13 +75,24 @@ http_port=Porta HTTP
http_port_helper=Número da porta em que a aplicação irá executar.
app_url=URL do Aplicativo
app_url_helper=Isto afeta a URL de clonagem via HTTP/HTTPs e também o email.
email_title=Configurações do Serviço de E-mail(Opcionais)
optional_title=Configurações Opcionais
email_title=Configurações do Serviço de E-mail
smtp_host=Host SMTP
smtp_from=De
smtp_from_helper=O endereço de email deve atender a especificação RFC 5322. O formato deve ser um email ou "Nome" <email@example.com>.
mailer_user=E-mail do Remetente
mailer_password=Senha do Remetente
notify_title=Configurações de Notificação (Opcional)
register_confirm=Habilitar Confirmação de Registro
mail_notify=Habilitar Notificação de Correio
server_service_title=Configurações de Servidor e Outros Serviços
offline_mode=Ativar Modo Offline
offline_mode_popup=Desative o CDN mesmo em modo de produção, todos os recursos serão disponibilizados localmente.
disable_registration=Desativar auto-registro
disable_registration_popup=Desativar o auto-registro de usuário, para que somente o administrador possa criar contas.
require_sign_in_view=Requerer autenticação para a visualização de páginas
require_sign_in_view_popup=Somente usuários autenticados podem ver todas as páginas, visitantes somente podem entrar ou se cadastrar.
admin_setting_desc=Você não precisa criar uma conta de administrador agora, no entanto o primeiro usuário (ID=1) automaticamente terá acesso de administrador.
admin_title=Configurações da Conta de Administrador
admin_name=Nome de Usuário
admin_password=Senha
@ -120,6 +143,11 @@ invalid_code=Desculpe, seu código de confirmação expirou ou não é válido.
reset_password_helper=Clique aqui para redefinir sua senha
password_too_short=O comprimento da senha não pode ser menor que 6.
[modal]
yes=Sim
no=Não
modify=Alterar
[form]
UserName=Nome de usuário
RepoName=Nome do repositório
@ -136,6 +164,7 @@ AdminEmail=E-mail do Administrador
require_error=` não pode estar vazio.`
alpha_dash_error=` devem ser caracteres alfanuméricos ou hífen (-) ou sublinhado (_).`
alpha_dash_dot_error=` devem ser caracteres alfanuméricos ou hífen (-) ou sublinhado (_).`
size_error=` deve ter %s.`
min_size_error=` deve conter pelo menos %s caracteres.`
max_size_error=` deve conter no máximo %s caracteres.`
email_error=` não é um endereço de e-mail válido.`
@ -150,9 +179,6 @@ org_name_been_taken=Nome da organização já foi tomado.
team_name_been_taken=Nome da equipe já foi tomado.
email_been_used=Endereço de e-mail já foi usado.
ssh_key_been_used=Nome da chave pública foi usado.
illegal_username=Seu nome de usuário contém caracteres ilegais.
illegal_repo_name=Nome do repositório contém caracteres ilegais.
illegal_org_name=Nome da organização contém caracteres ilegais.
illegal_team_name=O nome da equipe contém caracteres ilegais.
username_password_incorrect=Usuário ou senha incorretos.
enterred_invalid_repo_name=Por favor certifique-se que informou o nome do repositório corretamente.
@ -183,6 +209,9 @@ followers=Seguidores
starred=Marcado
following=Seguindo
form.name_reserved=O nome de usuário '%s' não pode ser usado.
form.name_pattern_not_allowed=Não é permitido usar o padrão '%s' para o nome de usuário.
[settings]
profile=Perfil
password=Senha
@ -227,6 +256,7 @@ primary_email=Definir como principal
delete_email=Deletar
add_new_email=Adicionar novo endereço de e-mail
add_email=Adicionar e-mail
add_email_confirmation_sent=Um novo e-mail de confirmação foi enviado para <b>%s</b>. Por favor, verifique sua Caixa de Entrada dentro das próximas %d horas, para concluir o processo de confirmação.
add_email_success=Seu novo endereço de E-mail foi adicionado com sucesso.
manage_ssh_keys=Gerenciar Chaves SSH
@ -247,7 +277,7 @@ social_desc=Esta é uma lista de contas sociais. Remova qualquer ligação que v
unbind=Desvincular
unbind_success=A conta social foi desvinculada.
manage_access_token=Gerenciar Tokens de Acesso pessoais
manage_access_token=Gerenciar Tokens de Acesso Pessoal
generate_new_token=Gerar novo Token
tokens_desc=Tokens gerados por você que podem ser usados para acessar a API Gogs.
new_token_desc=Por enquanto, todo token terá acesso completo à sua conta.
@ -282,6 +312,9 @@ create_repo=Criar Repositório
default_branch=Ramo padrão
mirror_interval=Intervalo de Espelho (hora)
form.name_reserved=O nome de repositório '%s' não pode ser usado.
form.name_pattern_not_allowed=Não é permitido usar o padrão '%s' para o nome de repositório.
need_auth=Precisa de Autorização
migrate_type=Tipo de Migração
migrate_type_helper=Este repositório será um <span class="label label-blue label-radius">Espelho</span>
@ -289,6 +322,8 @@ migrate_repo=Migrar Repositório
migrate.clone_address=Endereço de Clone
migrate.invalid_local_path=Caminho local inválido, não existe ou não é um diretório.
forked_from=bifurcação de
fork_from_self=Você não pode criar fork de um repositório que já é seu!
copy_link=Copiar
click_to_copy=Copiar para a área de transferência
copied=Copiado com sucesso
@ -311,11 +346,14 @@ branch_and_tags=Ramos & Tags
branches=Ramos
tags=Tags
issues=Problemas
labels=Etiquetas
milestones=Marcos
commits=Commits
releases=Lançamentos
file_raw=Cru
file_history=Histórico
file_view_raw=Ver cru
file_permalink=Link permanente
commits.commits=Commits
commits.search=Pesquisar commits
@ -326,6 +364,34 @@ commits.date=Data
commits.older=Mais Antigo
commits.newer=Mais Novo
issues.new=Novo problema
issues.new_label=Nova etiqueta
issues.new_label_placeholder=Nome de etiqueta...
issues.open_tab=%d aberto
issues.close_tab=%d fechado
issues.filter_label=Etiqueta
issues.filter_label_no_select=Nenhuma etiqueta selecionada
issues.filter_milestone=Marco
issues.filter_assignee=Atribuído
issues.filter_type=Tipo
issues.filter_type.all_issues=Todos os problemas
issues.filter_type.assigned_to_you=Atribuídos a você
issues.filter_type.created_by_you=Criados por você
issues.filter_type.mentioning_you=Mencionando você
issues.opened_by=%[1]s foi aberto por <a href="/%[2]s">%[2]s</a>
issues.previous=Página anterior
issues.next=Próxima página
issues.label_title=Nome da etiqueta
issues.label_color=Cor da etiqueta
issues.label_count=%d etiquetas
issues.label_open_issues=%d problemas abertos
issues.label_edit=Editar
issues.label_delete=Excluir
issues.label_modify=Alteração de etiqueta
issues.label_deletion=Exclusão de etiqueta
issues.label_deletion_desc=Excluir uma etiqueta a retirará de todos os problemas que ela estiver marcando. Quer mesmo continuar?
issues.label_deletion_success=A etiqueta foi excluída com sucesso!
settings=Configurações
settings.options=Opções
settings.collaboration=Colaboração
@ -432,6 +498,9 @@ team_name_helper=Você usará este nome para mencionar esta equipe em conversas.
team_desc_helper=Do que trata essa equipe?
team_permission_desc=Que nível de permissão esta equipe deve ter?
form.name_reserved=O nome de organização '%s' não pode ser usado.
form.name_pattern_not_allowed=Não é permitido usar o padrão '%s' para o nome de organização.
settings=Configurações
settings.options=Opções
settings.full_name=Nome Completo
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=Excluir todos os arquivos dos repositórios
dashboard.delete_repo_archives_success=Todos os arquivos dos repositórios foram excluídos com sucesso.
dashboard.git_gc_repos=Fazer coleta de lixo nos repositórios
dashboard.git_gc_repos_success=Em todos repositórios, a coleta de lixo foi realizada com sucesso.
dashboard.resync_all_sshkeys=Reescrever o arquivo '.ssh/authorized_key' (atenção: chaves que não sejam do Gogs serão perdidas)
dashboard.resync_all_sshkeys=Reescrever o arquivo '.ssh/authorized_keys' (atenção: chaves que não sejam do Gogs serão perdidas)
dashboard.resync_all_sshkeys_success=Todas as chaves públicas foram reescritas com sucesso.
dashboard.resync_all_update_hooks=Reescrever todos os hooks de atualização dos repositórios (necessário quando o caminho de configuração customizado é alterado)
dashboard.resync_all_update_hooks_success=Os hooks de atualização de todos os repositórios foram reescritos com sucesso.
@ -605,6 +674,7 @@ auths.smtp_auth=Tipo de Autorização de SMTP
auths.smtphost=Host SMTP
auths.smtpport=Porta SMTP
auths.enable_tls=Habilitar Criptografia TLS
auths.pam_service_name=Nome de Serviço PAM
auths.enable_auto_register=Habilitar Registro Automático
auths.tips=Dicas
auths.edit=Editar Configuração da Autorização
@ -653,6 +723,7 @@ config.deliver_timeout=Intervalo de Entrega
config.skip_tls_verify=Pular Verificar TLS
config.mailer_config=Configuração de Correio
config.mailer_enabled=Habilitado
config.mailer_disable_helo=Desabilitar HELO
config.mailer_name=Nome
config.mailer_host=Host
config.mailer_user=Usuário

@ -39,10 +39,18 @@ issues=Вопросы
cancel=Отмена
[search]
search=Поиск...
repository=Репозиторий
user=Пользователь
issue=Проблема
code=Код
[install]
install=Установка
title=Установочные шаги для первого запуска
requite_db_desc=Для Gogs требуется MySQL, PostgreSQL или SQLite3.
db_title=Настройки базы данных
db_type=Тип базы данных
host=Хост
user=Пользователь
@ -52,7 +60,11 @@ db_helper=Для MySQL используйте тип таблиц InnoDB с ко
ssl_mode=Режим SSL
path=Путь
sqlite_helper=Путь к файлу базы данных SQLite3.
err_empty_sqlite_path=Путь к базе данных SQLite3 не может быть пустым.
general_title=Общие параметры Gogs
app_name=Имя приложения
app_name_helper=Укажите здесь название вашей потрясающей организации!
repo_path=Путь корня репозитория
repo_path_helper=Все удаленные репозитории Git будут сохранены в этой директории.
run_user=Пользователь
@ -63,13 +75,24 @@ http_port=Порт HTTP
http_port_helper=Номер порта, который приложение будет слушать.
app_url=URL приложения
app_url_helper=Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на адреса в электронной почте.
email_title=Настройки службы электронной почты (опционально)
optional_title=Расширенные настройки
email_title=Настройки службы электронной почты
smtp_host=Узел SMTP
smtp_from=Из
smtp_from_helper=Почта от адреса, RFC 5322. Это может быть email адрес или формат "Имя" <email@example.com>.
mailer_user=Электронная почта отправителя
mailer_password=Пароль отправителя
notify_title=Настройки уведомлений(опционально)
register_confirm=Включить подтверждение регистрации
mail_notify=Разрешить почтовые уведомления
server_service_title=Сервер и другие настройки служб
offline_mode=Включение офлайн режима
offline_mode_popup=Отключить CDN даже в производственном режиме, все файлы ресурсов будут раздаваться локально.
disable_registration=Отключить самостоятельную регистрацию
disable_registration_popup=Запретить пользователям самостоятельную регистрацию, только администратор может создавать аккаунты.
require_sign_in_view=Разрешить требовать авторизацию для просмотра страниц
require_sign_in_view_popup=Только авторизированные пользователи могут просматривать страницы, посетители смогут увидеть только ссылку на авторизацию вверху страницы.
admin_setting_desc=Вы не должны создать учетную запись администратора прямо сейчас, пользователь с ID = 1 получит доступ с правами администратора автоматически.
admin_title=Настройки учётной записи администратора
admin_name=Имя пользователя
admin_password=Пароль
@ -120,6 +143,11 @@ invalid_code=Извините, ваш код подтверждения исте
reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль
password_too_short=Длина пароля не менее 6 символов.
[modal]
yes=Да
no=Нет
modify=Изменить
[form]
UserName=Пользователь
RepoName=Имя репозитория
@ -128,7 +156,7 @@ Password=Пароль
Retype=Введите пароль еще раз
SSHTitle=Имя SSH ключа
HttpsUrl=URL HTTPS
PayloadUrl=Payload URL
PayloadUrl=URL обработчика
TeamName=Название команды
AuthName=Имя авторизации
AdminEmail=Электронная почта администратора
@ -136,6 +164,7 @@ AdminEmail=Электронная почта администратора
require_error=` не может быть пустым.`
alpha_dash_error=«должен быть допустимым символьным, числовым или dash(-_) значением.»
alpha_dash_dot_error=«должен быть допустимым символьным, числовым или dash(-_) символами, включая точку.»
size_error=` должен быть размер %s.`
min_size_error=«должен содержать по крайней мере %s символов.»
max_size_error=` должен содержать максимум %s символов.`
email_error=«не является адресом электронной почты.»
@ -150,9 +179,6 @@ org_name_been_taken=Название организации было уже пр
team_name_been_taken=Название команды было уже принято.
email_been_used=Адрес электронной почты уже используется.
ssh_key_been_used=Имя открытого ключа уже используется.
illegal_username=Ваше имя пользователя содержит недопустимые символы.
illegal_repo_name=Имя репозитория содержит недопустимые знаки.
illegal_org_name=Название организации содержит недопустимые знаки.
illegal_team_name=Имя группы содержит недопустимые знаки.
username_password_incorrect=Имя пользователя или пароль не правильный.
enterred_invalid_repo_name=Пожалуйста, убедитесь, что введенно правильное имя хранилища.
@ -183,6 +209,9 @@ followers=Подписчики
starred=Избранное
following=Подписан
form.name_reserved=Имя пользователя '%s' зарезервировано.
form.name_pattern_not_allowed=Имя пользователя «%s» не допускается.
[settings]
profile=Профиль
password=Пароль
@ -227,6 +256,7 @@ primary_email=Установить как основной
delete_email=Удалить
add_new_email=Добавить новый адрес электронной почты
add_email=Добавить электронную почту
add_email_confirmation_sent=Новое подтверждение по электронной почте было отправлено<b>%s</b>, пожалуйста, проверьте свой почтовый ящик в течение следующих %d часов, чтобы завершить процесс подтверждения.
add_email_success=Новый адрес электронной почты успешно добавлен.
manage_ssh_keys=Управление SSH ключами
@ -282,6 +312,9 @@ create_repo=Создать репозиторий
default_branch=Ветка по умолчанию
mirror_interval=Интервал зеркалирования (час)
form.name_reserved=Имя репозитория '%s' зарезервировано.
form.name_pattern_not_allowed=Шаблон имени репозитория '%s' не допускается.
need_auth=Требуется авторизация
migrate_type=Тип миграции
migrate_type_helper=Этот репозиторий будет <span class="label label-blue label-radius">зеркалом</span>
@ -289,6 +322,8 @@ migrate_repo=Перенос репозитория
migrate.clone_address=Скопировать адрес
migrate.invalid_local_path=Недопустимый локальный путь. Возможно он не существует или является не папкой.
forked_from=forked from
fork_from_self=Вы не можете форкнуть репозитарий, так как Вы уже его владелец!
copy_link=Скопировать
click_to_copy=Скопировать в буфер обмена
copied=Успешно скопировано
@ -311,11 +346,14 @@ branch_and_tags=Ветки и метки
branches=Ветки
tags=Метки
issues=Обсуждения
labels=Метки
milestones=Этапы
commits=Коммиты
releases=Релизы
file_raw=Исходник
file_history=История
file_view_raw=Посмотреть исходник
file_permalink=Постоянная ссылка
commits.commits=Коммиты
commits.search=Поиск коммитов
@ -326,12 +364,40 @@ commits.date=Дата
commits.older=Раньше
commits.newer=Новее
issues.new=Новая задача
issues.new_label=Новая метка
issues.new_label_placeholder=Имя метки...
issues.open_tab=%d Открыть
issues.close_tab=%d Закрыть
issues.filter_label=Метка
issues.filter_label_no_select=Нет выбранной метки
issues.filter_milestone=Этап
issues.filter_assignee=Назначено
issues.filter_type=Тип
issues.filter_type.all_issues=Все задачи
issues.filter_type.assigned_to_you=Назначено Вам
issues.filter_type.created_by_you=Созданные вами
issues.filter_type.mentioning_you=Вы упомянуты
issues.opened_by=opened %[1]s by <a href="/%[2]s">%[2]s</a>
issues.previous=Предыдущая страница
issues.next=Следующая страница
issues.label_title=Имя метки
issues.label_color=Цвет метки
issues.label_count=%d меток
issues.label_open_issues=%d открытых задач
issues.label_edit=Редактировать
issues.label_delete=Удалить
issues.label_modify=Изменение метки
issues.label_deletion=Удаление метки
issues.label_deletion_desc=Удаление ярлыка затронет все связанные задачи. Продолжить?
issues.label_deletion_success=Метка была удалена успешно!
settings=Настройки
settings.options=Опции
settings.collaboration=Сотрудничество
settings.hooks=Автоматическое обновление
settings.githooks=Git хуки
settings.deploy_keys=Deploy Keys
settings.deploy_keys=Ключи развертывания
settings.basic_settings=Основные параметры
settings.danger_zone=Опасная зона
settings.site=Официальный сайт
@ -355,23 +421,23 @@ settings.remove_collaborator_success=Соавтор был удален.
settings.user_is_org_member=Пользователь является членом организации, члены которой не могут быть добавлены в качестве соавтора.
settings.add_webhook=Добавить Webhook
settings.hooks_desc=Webhooks позволяют внешним службам получать уведомления при возникновении определенных событий на Gogs. При возникновении указанных событий мы отправим запрос POST на каждый заданный вами URL. Узнать больше можно в нашем <a target="_blank" href="%s">Руководстве по Webhooks</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.githooks_desc=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to perform custom operations.
settings.githook_edit_desc=If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
settings.githook_name=Название Hook'a
settings.githook_content=Перехватить содержание
settings.update_githook=Обновить 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="%s">Webhooks Guide</a>.
settings.payload_url=Payload URL
settings.remove_hook_success=Webhook удален.
settings.add_webhook_desc=Мы отправим запрос <code>POST</code> на указанный ниже URL с информацией о событиях. Можно также указать формат, в котором вы бы хотели получить данные (JSON, <code>x-www-form-urlencoded</code>, <em>и т.д.</em>). Дополнительную информацию можно найти в <a target="_blank" href="%s">Руководстве по Webhook</a>.
settings.payload_url=URL обработчика
settings.content_type=Тип содержимого
settings.secret=Secret
settings.event_desc=Which events would you like to trigger this webhook?
settings.event_desc=На какие события этот webhook должен срабатывать?
settings.event_push_only=Просто <code>push</code> событие.
settings.active=Активен
settings.active_helper=We will deliver event details when this hook is triggered.
settings.add_hook_success=New webhook has been added.
settings.update_webhook=Update Webhook
settings.update_hook_success=Webhook has been updated.
settings.active_helper=Details regarding the event which triggered the hook will be delivered as well.
settings.add_hook_success=Был добавлен новый webhook.
settings.update_webhook=Обновление Webhook
settings.update_hook_success=Webhook обновлен.
settings.delete_webhook=Удалить автоматическое обновление
settings.recent_deliveries=Недавние рассылки
settings.hook_type=Тип перехватчика
@ -407,7 +473,7 @@ release.preview=Предварительный просмотр
release.content_placeholder=Напишите что-нибудь
release.loading=Загрузка...
release.prerelease_desc=Это предварительный релиз
release.prerelease_helper=We’ll point out that this release is identified as non-production ready.
release.prerelease_helper=We’ll point out that this release is not production-ready.
release.publish=Опубликовать релиз
release.save_draft=Сохранить черновик
release.edit_release=Редактировать релиз
@ -432,6 +498,9 @@ team_name_helper=Вы будете использовать это имя для
team_desc_helper=What is this team all about?
team_permission_desc=Какой уровень разрешений должен быть у этой команды?
form.name_reserved=Наименование организации '%s' зарезервированно.
form.name_pattern_not_allowed=Шаблон организации '%s' не допускается.
settings=Настройки
settings.options=Опции
settings.full_name=Полное имя
@ -514,23 +583,23 @@ dashboard.delete_repo_archives=Удаление всех архивов репо
dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены.
dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях
dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена.
dashboard.resync_all_sshkeys=Переписать файл «.ssh/authorized_key» (осторожно: не Gogs ключи будут утеряны)
dashboard.resync_all_sshkeys=Переписать файл «.ssh/authorized_keys» (осторожно: не Gogs ключи будут утеряны)
dashboard.resync_all_sshkeys_success=Были успешно переписаны все открытые ключи.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Время непрерывной работы сервера
dashboard.current_goroutine=Current Goroutines
dashboard.current_goroutine=Текущий Goroutines
dashboard.current_memory_usage=Текущее использование памяти
dashboard.total_memory_allocated=Всего памяти выделено
dashboard.memory_obtained=Memory Obtained
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.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_in_use=Кучи памяти в работе
dashboard.heap_memory_released=Heap Memory Released
dashboard.heap_objects=Heap Objects
dashboard.bootstrap_stack_usage=Bootstrap Stack Usage
@ -568,7 +637,7 @@ users.allow_git_hook=Пользователь имеет право создат
users.update_profile=Обновить профиль учетной записи
users.delete_account=Удалить эту учетную запись
users.still_own_repo=На вашем аккаунте все еще остается как минимум один репозиторий, сначала вам нужно удалить или передать его.
users.still_has_org=This account still have membership of organization, you have to left or delete them first.
users.still_has_org=This account still has membership in at least one organization, you have to leave or delete the organizations first.
orgs.org_manage_panel=Управление группами
orgs.name=Имя
@ -605,6 +674,7 @@ auths.smtp_auth=Тип авторизации SMTP
auths.smtphost=Узел SMTP
auths.smtpport=SMTP-порт
auths.enable_tls=Включение шифрования TLS
auths.pam_service_name=PAM Service Name
auths.enable_auto_register=Включить автоматическую регистрацию
auths.tips=Советы
auths.edit=Редактировать параметры авторизации
@ -636,7 +706,7 @@ config.db_name=Имя
config.db_user=Пользователь
config.db_ssl_mode=Режим SSL
config.db_ssl_mode_helper=(только для «postgres»)
config.db_path=Path
config.db_path=Путь
config.db_path_helper=(for "sqlite3" only)
config.service_config=Service Configuration
config.register_email_confirm=Require E-mail Confirmation
@ -650,9 +720,10 @@ config.reset_password_code_lives=Reset Password Code Lives
config.webhook_config=Настройка автоматического обновления репозиции
config.task_interval=Интервал задания
config.deliver_timeout=Задержка доставки
config.skip_tls_verify=Skip TLS Verify
config.skip_tls_verify=Пропустить TLS проверка
config.mailer_config=Настройки почты
config.mailer_enabled=Включено
config.mailer_disable_helo=Отключить HELO
config.mailer_name=Имя
config.mailer_host=Сервер
config.mailer_user=Пользователь
@ -685,7 +756,7 @@ monitor.previous=Предыдущий раз
monitor.execute_times=Execute Times
monitor.process=Запущенные процессы
monitor.desc=Описание
monitor.start=Start Time
monitor.start=Момент начала
monitor.execute_time=Время выполнения
notices.system_notice_list=Система уведомлений
@ -705,7 +776,7 @@ push_tag=pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
compare_2_commits=Просмотреть сравнение двух коммитов
[tool]
ago=ago
ago=назад
from_now=from now
now=сейчас
1s=1 second %s

@ -39,10 +39,18 @@ issues=工单管理
cancel=取消
[search]
search=搜索...
repository=仓库
user=用户
issue=工单
code=代码
[install]
install=安装页面
title=首次运行安装程序
requite_db_desc=Gogs 允许后端数据库为 MySQL、PostgreSQL 或 SQLite3。
db_title=数据库设置
db_type=数据库类型
host=数据库主机
user=数据库用户
@ -52,7 +60,11 @@ db_helper=如果您使用 MySQL,请使用 INNODB 引擎以及 utf8_general_ci
ssl_mode=SSL 模式
path=数据库文件路径
sqlite_helper=SQLite3 数据库的文件路径。
err_empty_sqlite_path=SQLite 数据库文件路径不能为空。
general_title=应用基本设置
app_name=应用名称
app_name_helper=快用狂拽酷炫的组织名称闪瞎我们!
repo_path=仓库根目录
repo_path_helper=所有 Git 远程仓库都将被存放于该目录。
run_user=运行系统用户
@ -63,13 +75,24 @@ http_port=HTTP 端口号
http_port_helper=应用监听的端口号
app_url=应用 URL
app_url_helper=该设置影响 HTTP/HTTPS 克隆地址和一些邮箱中的链接。
email_title=邮件服务设置(可选)
optional_title=可选设置
email_title=邮件服务设置
smtp_host=SMTP 主机
smtp_from=邮件来自
smtp_from_helper=邮件来自地址,遵循 RFC 5322 标准。可以是一个单纯的邮箱地址或使用 "Name" <email@example.com> 的格式。
mailer_user=发送邮箱
mailer_password=发送邮箱密码
notify_title=通知提醒设置(可选)
register_confirm=启用注册邮箱确认
mail_notify=启用邮件通知提醒
server_service_title=服务器和其它服务设置
offline_mode=启用离线模式
offline_mode_popup=在部署模式下也禁用从 CDN 获取文件,所以的资源都将从本地服务器获取。
disable_registration=禁止用户自主注册
disable_registration_popup=禁止用户自行注册功能,只有管理员可以添加帐号。
require_sign_in_view=启用登录访问限制
require_sign_in_view_popup=只有已登录的用户才能够访问页面,否则将只能看到登录或注册页面。
admin_setting_desc=创建管理员帐号并不是必须的,因为 ID=1 的用户将自动获得管理员权限。
admin_title=管理员帐号设置
admin_name=管理员用户名
admin_password=管理员密码
@ -120,6 +143,11 @@ invalid_code=对不起,您的确认代码已过期或已失效。
reset_password_helper=单击此处重置密码
password_too_short=密码长度不能少于 6 位!
[modal]
yes=确认操作
no=取消操作
modify=确认修改
[form]
UserName=用户名
RepoName=仓库名称
@ -136,6 +164,7 @@ AdminEmail=管理员邮箱
require_error=不能为空。
alpha_dash_error=必须为英文字母、阿拉伯数字或横线(-_)。
alpha_dash_dot_error=必须为英文字母、阿拉伯数字、横线(-_)或点。
size_error=长度必须为 %s。
min_size_error=长度最小为 %s 个字符。
max_size_error=长度最大为 %s 个字符。
email_error=不是一个有效的邮箱地址。
@ -149,10 +178,6 @@ 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=请检查您输入的仓库名称是正确。
@ -183,6 +208,9 @@ followers=关注者
starred=已点赞
following=关注中
form.name_reserved=用户名 '%s' 是被保留的。
form.name_pattern_not_allowed=用户名不允许 '%s' 的格式。
[settings]
profile=个人信息
password=修改密码
@ -227,6 +255,7 @@ primary_email=设为主要
delete_email=删除
add_new_email=添加新的邮箱地址
add_email=添加邮箱
add_email_confirmation_sent=一封待确认的电子邮件已发送到 <b>%s</b>,请在 %d 小时内检查您的收件箱,并完成确认过程。
add_email_success=新的邮箱地址添加成功!
manage_ssh_keys=管理 SSH 密钥
@ -234,13 +263,16 @@ add_key=增加密钥
ssh_desc=以下是与您帐户所关联的 SSH 密钥,如果您发现有陌生的密钥,请立即删除它!
ssh_helper=<strong>需要帮助?</strong> 请查看有关 <a href="%s">如何生成 SSH 密钥</a> 或 <a href="%s">常见 SSH 问题</a> 寻找答案。
add_new_key=增加 SSH 密钥
ssh_key_been_used=公开密钥已经被使用!
ssh_key_name_used=使用相同名称的公开密钥已经存在!
key_name=密钥名称
key_content=密钥内容
add_key_success=新的 SSH 密钥添加成功!
add_key_success=新的 SSH 密钥 '%s' 添加成功!
delete_key=删除
add_on=增加于
last_used=上次使用在
no_activity=没有最近活动
key_state_desc=该密钥在 7 天内被使用过
manage_social=管理关联社交帐户
social_desc=以下是与您帐户所关联的社交帐号,如果您发现有陌生的关联,请立即解除绑定!
@ -282,6 +314,9 @@ create_repo=创建仓库
default_branch=默认分支
mirror_interval=镜像同步周期(小时)
form.name_reserved=仓库名称 '%s' 是被保留的。
form.name_pattern_not_allowed=仓库名称不允许 '%s' 的格式。
need_auth=需要授权验证
migrate_type=迁移类型
migrate_type_helper=本仓库将是 <span class="label label-blue label-radius">镜像</span>
@ -289,6 +324,8 @@ migrate_repo=迁移仓库
migrate.clone_address=克隆地址
migrate.invalid_local_path=无效的本地路径,不存在或不是一个目录!
forked_from=派生自
fork_from_self=无法派生已经拥有的仓库!
copy_link=复制链接
click_to_copy=复制到剪切板
copied=复制成功
@ -311,11 +348,14 @@ branch_and_tags=分支与标签
branches=分支列表
tags=标签列表
issues=工单管理
labels=标签管理
milestones=里程碑
commits=提交历史
releases=版本发布
file_raw=原始文件
file_history=文件历史
file_view_raw=查看原始文件
file_permalink=永久链接
commits.commits=次代码提交
commits.search=搜索提交历史
@ -326,12 +366,64 @@ commits.date=提交日期
commits.older=更旧的提交
commits.newer=更新的提交
issues.new=创建工单
issues.new_label=创建标签
issues.new_label_placeholder=标签名称...
issues.open_tab=%d 个开启中
issues.close_tab=%d 个已关闭
issues.filter_label=标签筛选
issues.filter_label_no_select=无筛选标签
issues.filter_milestone=里程碑筛选
issues.filter_milestone_no_select=取消选中里程碑
issues.filter_assignee=指派人筛选
issues.filter_type=类型筛选
issues.filter_type.all_issues=所有工单
issues.filter_type.assigned_to_you=指派给您的
issues.filter_type.created_by_you=由您创建的
issues.filter_type.mentioning_you=提及您的
issues.opened_by=由 <a href="/%[2]s">%[2]s</a> 于 %[1]s创建
issues.previous=上一页
issues.next=下一页
issues.label_title=标签名称
issues.label_color=标签颜色
issues.label_count=%d 个标签
issues.label_open_issues=%d 个开启的工单
issues.label_edit=编辑
issues.label_delete=删除
issues.label_modify=修改标签
issues.label_deletion=删除标签
issues.label_deletion_desc=删除该标签将会移除所有工单中相关的信息。是否继续?
issues.label_deletion_success=标签删除成功!
milestones.new=新的里程碑
milestones.open_tab=%d 开启中
milestones.close_tab=%d 已关闭
milestones.closed=于 %s关闭
milestones.no_due_date=暂无截止日期
milestones.open=开启
milestones.close=关闭
milestones.new_subheader=创建里程碑来更好地组织您的工单。
milestones.create=创建里程碑
milestones.title=标题
milestones.desc=描述
milestones.due_date=截止日期(可选)
milestones.clear=清除
milestones.invalid_due_date_format=截止日期的格式错误,必须是 'year-mm-dd' 的形式。
milestones.create_success=里程碑 '%s' 创建成功!
milestones.edit=编辑里程碑
milestones.edit_subheader=使用更加清晰的描述来帮助人们更好地理解里程碑的作用。
milestones.cancel=取消
milestones.modify=修改里程碑
milestones.edit_success=里程碑 '%s' 的修改内容已经生效!
milestones.deletion=删除里程碑
milestones.deletion_desc=删除该里程碑将会移除所有工单中相关的信息。是否继续?
milestones.deletion_success=里程碑删除成功!
settings=仓库设置
settings.options=基本设置
settings.collaboration=管理协作者
settings.hooks=管理 Web 钩子
settings.githooks=管理 Git 钩子
settings.deploy_keys=管理部署密钥
settings.basic_settings=基本设置
settings.danger_zone=危险操作区
settings.site=官方网站
@ -379,6 +471,17 @@ settings.add_slack_hook_desc=为您的仓库增加 <a href="%s">Slack</a> 集成
settings.slack_token=令牌
settings.slack_domain=域名
settings.slack_channel=频道
settings.deploy_keys=管理部署密钥
settings.add_deploy_key=添加部署密钥
settings.no_deploy_keys=您还没有添加任何部署密钥。
settings.title=标题
settings.deploy_key_content=密钥文本
settings.key_been_used=部署密钥已经被使用!
settings.key_name_used=使用相同名称的部署密钥已经存在!
settings.add_key_success=新的部署密钥 '%s' 添加成功!
settings.deploy_key_deletion=删除部署密钥
settings.deploy_key_deletion_desc=删除该部署密钥会移除本仓库所以相关的操作权限。是否继续?
settings.deploy_key_deletion_success=删除部署密钥成功!
diff.browse_source=浏览代码
diff.parent=父节点
@ -432,6 +535,9 @@ team_name_helper=您可以使用该名称来通知改组全体成员。
team_desc_helper=一句话描述这个团队是做什么的。
team_permission_desc=请选择该团队所具有的权限等级:
form.name_reserved=组织名称 '%s' 是被保留的。
form.name_pattern_not_allowed=组织名称不允许 '%s' 的格式。
settings=组织设置
settings.options=基本设置
settings.full_name=组织全名
@ -514,7 +620,7 @@ dashboard.delete_repo_archives=删除所有仓库存档
dashboard.delete_repo_archives_success=所有仓库存档清除成功!
dashboard.git_gc_repos=对仓库进行垃圾回收
dashboard.git_gc_repos_success=所有仓库垃圾回收成功!
dashboard.resync_all_sshkeys=重新生成 '.ssh/authorized_key' 文件(警告:不是 Gogs 的密钥也会被删除)
dashboard.resync_all_sshkeys=重新生成 '.ssh/authorized_keys' 文件(警告:不是 Gogs 的密钥也会被删除)
dashboard.resync_all_sshkeys_success=所有公钥重新生成成功!
dashboard.resync_all_update_hooks=重新生成所有仓库的 Update 钩子(用于自定义配置文件被修改)
dashboard.resync_all_update_hooks_success=所有仓库的 Update 钩子重新生成成功!
@ -605,6 +711,7 @@ auths.smtp_auth=SMTP 授权类型
auths.smtphost=SMTP 主机地址
auths.smtpport=SMTP 主机端口
auths.enable_tls=启用 TLS 加密
auths.pam_service_name=PAM 服务名称
auths.enable_auto_register=允许授权用户自动注册
auths.tips=帮助提示
auths.edit=修改授权认证设置
@ -648,11 +755,12 @@ config.enable_cache_avatar=开启缓存头像
config.active_code_lives=激活用户链接有效期
config.reset_password_code_lives=重置密码链接有效期
config.webhook_config=Web 钩子配置
config.task_interval=任务周期
config.queue_length=队列长度
config.deliver_timeout=推送超时
config.skip_tls_verify=忽略 TLS 验证
config.mailer_config=邮件配置
config.mailer_enabled=启用服务
config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=发送者名称
config.mailer_host=邮件主机地址
config.mailer_user=发送者帐号

@ -39,10 +39,18 @@ issues=問題管理
cancel=取消
[search]
search=搜尋...
repository=倉庫
user=用戶
issue=工單
code=程式碼
[install]
install=安裝頁面
title=首次執行安裝程序
requite_db_desc=Gogs 允許後端數據庫為 MySQL、PostgreSQL 或 SQLite3,但是 SQLite3 一般只有官方二進制發行版才支持。
db_title=數據庫設置
db_type=數據庫類型
host=數據庫主機
user=數據庫用戶
@ -52,7 +60,11 @@ db_helper=如果您使用 MySQL,請使用 INNODB 引擎以及 utf8_general_ci
ssl_mode=SSL 模式
path=數據庫文件路徑
sqlite_helper=SQLite3 數據庫的文件路徑。
err_empty_sqlite_path=SQLite 數據庫文件路徑不能為空。
general_title=應用基本設置
app_name=應用名稱
app_name_helper=為您的組織取個響亮而又偉大的名稱
repo_path=倉庫根目錄
repo_path_helper=所有 Git 遠程倉庫都將被存放於該目錄。
run_user=執行系統用戶
@ -63,13 +75,24 @@ http_port=HTTP 端口號
http_port_helper=應用監聽的端口號
app_url=應用 URL
app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。
email_title=電子郵件服務設定(可選)
optional_title=可選設置
email_title=電子郵件服務設定
smtp_host=SMTP 主機
smtp_from=郵件來自
smtp_from_helper=郵件來自地址,遵循 RFC 5322 標准。可以是一個單純的郵箱地址或使用 "name" <email@example.com> 的格式。
mailer_user=發送郵箱
mailer_password=發送郵箱密碼
notify_title=通知提醒設置(可選)
register_confirm=啟用註冊郵箱確認
mail_notify=啟用郵件通知提醒
server_service_title=伺服器和其他服務設置
offline_mode=啓用離線模式
offline_mode_popup=在部署模式下也禁用從 CDN 獲取文件,所有的資源將從本地伺服器獲取。
disable_registration=禁止用戶自主註冊
disable_registration_popup=禁止用戶自主註冊功能,只有管理員可以添加帳號。
require_sign_in_view=啓用登錄訪問限制
require_sign_in_view_popup=只有已登錄的用戶才能夠訪問頁面,否則將只能看到登錄或註冊頁面。
admin_setting_desc=創建管理員帳號並不是必須的,因為 ID=1 的用戶將自動獲得管理員權限。
admin_title=管理員帳號設置
admin_name=管理員用戶名
admin_password=管理員密碼
@ -120,6 +143,11 @@ invalid_code=對不起,您的確認代碼已過期或已失效。
reset_password_helper=單擊此處重置密碼
password_too_short=密碼長度不能少於 6 位!
[modal]
yes=確認操作
no=取消操作
modify=確認修改
[form]
UserName=用戶名
RepoName=倉庫名稱
@ -136,6 +164,7 @@ AdminEmail=管理員郵箱
require_error=不能為空。
alpha_dash_error=必須為英文字母、阿拉伯數字或橫線(-_)。
alpha_dash_dot_error=必須為英文字母、阿拉伯數字、橫線(-_)或點。
size_error=長度必須為 %s。
min_size_error=長度最小為 %s 個字符。
max_size_error=長度最大為 %s 個字符。
email_error=不是一個有效的郵箱地址。
@ -150,9 +179,6 @@ 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=請檢查您輸入的倉庫名稱是正確。
@ -183,6 +209,9 @@ followers=關註者
starred=已讚好
following=關註中
form.name_reserved=用戶名 '%s' 是被保留的。
form.name_pattern_not_allowed=用戶名不允許 '%s' 的格式。
[settings]
profile=個人信息
password=修改密碼
@ -227,6 +256,7 @@ primary_email=设为主要
delete_email=刪除
add_new_email=添加新的電子郵件地址
add_email=添加電子郵件
add_email_confirmation_sent=一封待確認的電子郵件已發送到<b>%s</b>,請在%d 小時內檢查您的收件箱,並完成確認過程。
add_email_success=新的邮箱地址添加成功。
manage_ssh_keys=管理 SSH 密鑰
@ -282,6 +312,9 @@ create_repo=創建倉庫
default_branch=默認分支
mirror_interval=鏡像同步周期(小時)
form.name_reserved=倉庫名稱 '%s' 是被保留的。
form.name_pattern_not_allowed=倉庫名稱不允許 '%s' 的格式。
need_auth=需要授權驗證
migrate_type=遷移類型
migrate_type_helper=本倉庫將是 <span class="label label-blue label-radius">鏡像</span>
@ -289,6 +322,8 @@ migrate_repo=遷移倉庫
migrate.clone_address=複製地址
migrate.invalid_local_path=無效的本地路徑,該路徑不存在或不是一個目錄!
forked_from=派生自
fork_from_self=無法派生已經擁有的倉庫!
copy_link=複製連結
click_to_copy=複製到剪切簿
copied=複製成功
@ -311,11 +346,14 @@ branch_and_tags=分支與標籤
branches=分支列表
tags=標籤列表
issues=問題管理
labels=標籤
milestones=里程碑
commits=提交歷史
releases=版本發佈
file_raw=原始文件
file_history=文件歷史
file_view_raw=查看原始文件
file_permalink=永久連結
commits.commits=次代碼提交
commits.search=搜索提交歷史
@ -326,6 +364,34 @@ commits.date=提交日期
commits.older=更舊的提交
commits.newer=更新的提交
issues.new=創建問題
issues.new_label=創建標籤
issues.new_label_placeholder=標籤名稱...
issues.open_tab=%d 個開啓中
issues.close_tab=%d 個已關閉
issues.filter_label=標籤篩選
issues.filter_label_no_select=無篩選標籤
issues.filter_milestone=里程碑篩選
issues.filter_assignee=指派人篩選
issues.filter_type=類型篩選
issues.filter_type.all_issues=所有問題
issues.filter_type.assigned_to_you=指派給您的
issues.filter_type.created_by_you=由您創建的
issues.filter_type.mentioning_you=提及您的
issues.opened_by=由 <a href="/%[2]s">%[2]s</a> 於%[1]s創建
issues.previous=上一頁
issues.next=下一頁
issues.label_title=標籤名稱
issues.label_color=標籤顏色
issues.label_count=%d 個標籤
issues.label_open_issues=%d 個開啓的問題
issues.label_edit=編輯
issues.label_delete=刪除
issues.label_modify=修改標籤
issues.label_deletion=刪除標籤
issues.label_deletion_desc=刪除該標籤將會移除所有問題中相關的訊息。是否繼續?
issues.label_deletion_success=標籤刪除成功!
settings=倉庫設置
settings.options=基本設置
settings.collaboration=管理協作者
@ -432,6 +498,9 @@ team_name_helper=您可以使用該名稱來通知改組全體成員。
team_desc_helper=一句話描述這個團隊是做什麼的。
team_permission_desc=請選擇該團隊所具有的權限等級:
form.name_reserved=組織名稱 '%s' 是被保留的。
form.name_pattern_not_allowed=組織名稱不允許 '%s' 的格式。
settings=組織設置
settings.options=基本設置
settings.full_name=組織全名
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=刪除所有倉庫存檔
dashboard.delete_repo_archives_success=所有倉庫存檔清除成功!
dashboard.git_gc_repos=對倉庫進行垃圾回收
dashboard.git_gc_repos_success=所有倉庫的垃圾回收已成功完成!
dashboard.resync_all_sshkeys=重新生成 '.ssh/authorized_key' 文件(警告:不是 Gogs 的密鑰也會被刪除)
dashboard.resync_all_sshkeys=重新生成 '.ssh/authorized_keys' 文件(警告:不是 Gogs 的密鑰也會被刪除)
dashboard.resync_all_sshkeys_success=所有公鑰重新生成成功!
dashboard.resync_all_update_hooks=重新生成所有倉庫的 Update 鈎子(用於被修改的自定義配置文件)
dashboard.resync_all_update_hooks_success=已成功重新生成所有倉庫的 Update 鈎子!
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP 授權類型
auths.smtphost=SMTP 主機地址
auths.smtpport=SMTP 主機端口
auths.enable_tls=啟用 TLS 加密
auths.pam_service_name=PAM 服務名稱
auths.enable_auto_register=允許授權用戶自動註冊
auths.tips=幫助提示
auths.edit=修改授權認證設置
@ -653,6 +723,7 @@ config.deliver_timeout=推送超時
config.skip_tls_verify=忽略 TLS 驗證
config.mailer_config=郵件配置
config.mailer_enabled=啟用服務
config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱
config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號

File diff suppressed because it is too large Load Diff

@ -3,13 +3,13 @@ Docker
TOOLS ARE WRITTEN FOR TESTING AND TO SEE WHAT IT IS!
For this to work you will need the nifty docker tool [fig].
For this to work you will need the nifty docker tool [docker-compose].
The most simple setup will look like this:
```sh
./assemble_blocks.sh docker_gogs w_db option_db_mysql
fig up
docker-compose up
```
@ -22,21 +22,21 @@ How does it work
----------------
`./assemble_blocks.sh` will look in `blocks` for subdirectories.
In the subdirectories there are three relevant files: `Dockerfile`, `config` and `fig`.
In the subdirectories there are three relevant files: `Dockerfile`, `config` and `docker-compose`.
`Dockerfile` will be copied to `docker/` (also means last `Dockerfile` wins).
The `config` file contains lines which will in the gogs docker container end up in `$GOGS_PATH/custom/config/app.ini` and by this gogs will be configured.
Here you can define things like the MySQL server for your database block.
The `fig` file will just be added to `fig.yml`, which is used by fig to manage your containers.
The `docker-compose` file will just be added to `docker-compose.yml`, which is used by docker-compose to manage your containers.
This includes container linking!
Just have a look at them and it will be clear how to write your own blocks.
Just some things
- all files (`Dockerfile`, `fig` and `config`) are optional
- all files (`Dockerfile`, `docker-compose` and `config`) are optional
- the gogs block should always be the first block
Currently the blocks are designed that, the blocks that start with `docker` pull in the base docker image.
@ -57,14 +57,11 @@ Here is a more elaborated example
```sh
./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql
fig up
docker-compose up
```
This will set up four containters and link them proberly. One for each of
- gogs
- database (postgresql)
- cache (redis)
docker-compose
- session (mysql)
WARNING: This will not work at the Moment! MySQL session is broken!
@ -73,7 +70,7 @@ WARNING: This will not work at the Moment! MySQL session is broken!
Remark
------
After you execute `assemble_blocks.sh` you should always trigger `fig build` to inculde the the new init script `init_gogs.sh` in the docker image.
After you execute `assemble_blocks.sh` you should always trigger `docker-compose build` to inculde the the new init script `init_gogs.sh` in the docker image.
If you want to use another GoGS docker file, but keep everything else the same, you can create a block, e.g. `docker_gogs_custom`, with only a `Dockerfile` and call
@ -86,4 +83,4 @@ This will pull in the `Dockerfile` from `docker_gogs` instead of the one from `d
`Dockerfile`s for the `master` and `dev` branch are provided as `docker_gogs` and `docker_gogs_dev`
[fig]:http://www.fig.sh/
[docker-compose]:https://docs.docker.com/compose/

@ -10,8 +10,8 @@ gogs_config_file=conf.tmp
gogs_config=config
gogs_init_file=$docker_dir/init_gogs.sh
fig_file=fig.yml
fig_config=fig
compose_file=docker-compose.yml
compose_config=docker-compose
gogs_init_template=$template_dir/init_gogs.sh.tpl
@ -28,7 +28,7 @@ if [ "$#" == 0 ]; then
exit 0
fi
for file in $gogs_config_file $fig_file; do
for file in $gogs_config_file $compose_file; do
if [ -e $file ]; then
echo "Deleting $file"
rm $file
@ -53,10 +53,10 @@ for dir in $@; do
echo "" >> $gogs_config_file
fi
if [ -e $current_dir/$fig_config ]; then
echo "Adding $current_dir/$fig_config to $fig_file"
cat $current_dir/fig >> $fig_file
echo "" >> $fig_file
if [ -e $current_dir/$compose_config ]; then
echo "Adding $current_dir/$compose_config to $compose_file"
cat $current_dir/$compose_config >> $compose_file
echo "" >> $compose_file
fi
done
@ -69,4 +69,4 @@ d
if [ -e $gogs_config_file ]; then
echo "Removing temporary GoGS config"
rm $gogs_config_file
fi
fi

@ -1,23 +1,20 @@
FROM ubuntu:14.04
FROM buildpack-deps:trusty-scm
# This part is taken from the official docker image --------------------
RUN apt-get update && apt-get install -y \
build-essential ca-certificates curl \
bzr git mercurial openssh-client\
--no-install-recommends
build-essential --no-install-recommends
ENV GOLANG_VERSION 1.3
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
| tar -v -C /usr/src -xz
WORKDIR /usr/src/go
RUN curl -sSL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
| tar -v -C /usr/src -xz
RUN cd src && ./make.bash --no-clean 2>&1
RUN cd /usr/src/go/src && ./make.bash --no-clean 2>&1
ENV PATH /usr/src/go/bin:$PATH
RUN mkdir -p /go/src
RUN mkdir -p /go/src /go/bin && chmod -R 777 /go
ENV GOPATH /go
ENV PATH /go/bin:$PATH
WORKDIR /go

@ -1,24 +1,20 @@
FROM ubuntu:14.04
FROM buildpack-deps:trusty-scm
# This part is derived from the official docker image ------------------
# This part is taken from the official docker image --------------------
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -qy \
build-essential ca-certificates curl \
bzr git mercurial openssh-client\
--no-install-recommends
RUN apt-get update && apt-get install -y \
build-essential --no-install-recommends
ENV GOLANG_VERSION 1.3
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
| tar -v -C /usr/src -xz
WORKDIR /usr/src/go
RUN curl -sSL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
| tar -v -C /usr/src -xz
RUN cd src && ./make.bash --no-clean 2>&1
RUN cd /usr/src/go/src && ./make.bash --no-clean 2>&1
ENV PATH /usr/src/go/bin:$PATH
RUN mkdir -p /go/src
RUN mkdir -p /go/src /go/bin && chmod -R 777 /go
ENV GOPATH /go
ENV PATH /go/bin:$PATH
WORKDIR /go

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.6.1.0325 Beta"
const APP_VER = "0.6.4.0809 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())

@ -145,6 +145,25 @@ func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int6
for _, c := range collaborators {
accessMap[c.Id] = ACCESS_MODE_WRITE
}
// Adds team members access.
if repo.Owner.IsOrganization() {
if err = repo.Owner.GetTeams(); err != nil {
return fmt.Errorf("GetTeams: %v", err)
}
for _, t := range repo.Owner.Teams {
if err = t.GetMembers(); err != nil {
return fmt.Errorf("GetMembers: %v", err)
}
for _, m := range t.Members {
if t.IsOwnerTeam() {
accessMap[m.Id] = ACCESS_MODE_OWNER
} else {
accessMap[m.Id] = maxAccessMode(accessMap[m.Id], t.Authorize)
}
}
}
}
return nil
}
@ -154,13 +173,12 @@ func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int6
func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err error) {
accessMap := make(map[int64]AccessMode, 20)
if err = repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
if err = repo.getOwner(e); err != nil {
return err
}
if err = repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
if repo.Owner.IsOrganization() {
if err = repo.Owner.getTeams(e); err != nil {
return err

@ -153,7 +153,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
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, COMMENT_TYPE_COMMIT, message, nil); err != nil {
if _, err = CreateComment(userId, issue.RepoID, issue.ID, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
return err
}
}
@ -183,7 +183,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
return err
}
if issue.RepoId == repoId {
if issue.RepoID == repoId {
if issue.IsClosed {
continue
}
@ -202,7 +202,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
} else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil {
return err
}
@ -211,7 +211,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil {
if _, err = CreateComment(userId, repoId, issue.ID, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil {
return err
}
}
@ -242,7 +242,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
return err
}
if issue.RepoId == repoId {
if issue.RepoID == repoId {
if !issue.IsClosed {
continue
}
@ -261,7 +261,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
} else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil {
return err
}
@ -270,7 +270,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil {
if _, err = CreateComment(userId, repoId, issue.ID, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil {
return err
}
}
@ -293,12 +293,12 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
// if not the first commit, set the compareUrl
if !strings.HasPrefix(oldCommitId, "0000000") {
commit.CompareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId)
commit.CompareUrl = fmt.Sprintf("%s/%s/compare/%s...%s", repoUserName, repoName, oldCommitId, newCommitId)
}
bs, err := json.Marshal(commit)
if err != nil {
return errors.New("action.CommitRepoAction(json): " + err.Error())
return errors.New("json: " + err.Error())
}
refName := git.RefEndName(refFullName)
@ -306,17 +306,17 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
// Change repository bare status and update last updated time.
repo, err := GetRepositoryByName(repoUserId, repoName)
if err != nil {
return errors.New("action.CommitRepoAction(GetRepositoryByName): " + err.Error())
return errors.New("GetRepositoryByName: " + err.Error())
}
repo.IsBare = false
if err = UpdateRepository(repo, false); err != nil {
return errors.New("action.CommitRepoAction(UpdateRepository): " + err.Error())
return errors.New("UpdateRepository: " + err.Error())
}
err = updateIssuesCommit(userId, repoId, repoUserName, repoName, commit.Commits)
if err != nil {
log.Debug("action.CommitRepoAction(updateIssuesCommit): ", err)
log.Debug("updateIssuesCommit: ", err)
}
if err = NotifyWatchers(&Action{
@ -331,18 +331,18 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
RefName: refName,
IsPrivate: repo.IsPrivate,
}); err != nil {
return errors.New("action.CommitRepoAction(NotifyWatchers): " + err.Error())
return errors.New("NotifyWatchers: " + err.Error())
}
// New push event hook.
if err := repo.GetOwner(); err != nil {
return errors.New("action.CommitRepoAction(GetOwner): " + err.Error())
return errors.New("GetOwner: " + err.Error())
}
ws, err := GetActiveWebhooksByRepoId(repoId)
if err != nil {
return errors.New("action.CommitRepoAction(GetActiveWebhooksByRepoId): " + err.Error())
return errors.New("GetActiveWebhooksByRepoId: " + err.Error())
}
// check if repo belongs to org and append additional webhooks
@ -350,7 +350,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
// get hooks for org
orgws, err := GetActiveWebhooksByOrgId(repo.OwnerId)
if err != nil {
return errors.New("action.CommitRepoAction(GetActiveWebhooksByOrgId): " + err.Error())
return errors.New("GetActiveWebhooksByOrgId: " + err.Error())
}
ws = append(ws, orgws...)
}
@ -408,7 +408,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
},
Before: oldCommitId,
After: newCommitId,
CompareUrl: commit.CompareUrl,
CompareUrl: setting.AppUrl + commit.CompareUrl,
}
for _, w := range ws {
@ -431,6 +431,8 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
if err = CreateHookTask(&HookTask{
RepoID: repo.Id,
HookID: w.Id,
Type: w.HookTaskType,
Url: w.Url,
BasePayload: payload,

@ -8,6 +8,32 @@ import (
"fmt"
)
type ErrNameReserved struct {
Name string
}
func IsErrNameReserved(err error) bool {
_, ok := err.(ErrNameReserved)
return ok
}
func (err ErrNameReserved) Error() string {
return fmt.Sprintf("name is reserved: [name: %s]", err.Name)
}
type ErrNamePatternNotAllowed struct {
Pattern string
}
func IsErrNamePatternNotAllowed(err error) bool {
_, ok := err.(ErrNamePatternNotAllowed)
return ok
}
func (err ErrNamePatternNotAllowed) Error() string {
return fmt.Sprintf("name pattern is not allowed: [pattern: %s]", err.Pattern)
}
// ____ ___
// | | \______ ___________
// | | / ___// __ \_ __ \
@ -15,6 +41,46 @@ import (
// |______//____ >\___ >__|
// \/ \/
type ErrUserAlreadyExist struct {
Name string
}
func IsErrUserAlreadyExist(err error) bool {
_, ok := err.(ErrUserAlreadyExist)
return ok
}
func (err ErrUserAlreadyExist) Error() string {
return fmt.Sprintf("user already exists: [name: %s]", err.Name)
}
type ErrUserNotExist struct {
UID int64
Name string
}
func IsErrUserNotExist(err error) bool {
_, ok := err.(ErrUserNotExist)
return ok
}
func (err ErrUserNotExist) Error() string {
return fmt.Sprintf("user does not exist: [uid: %d, name: %s]", err.UID, err.Name)
}
type ErrEmailAlreadyUsed struct {
Email string
}
func IsErrEmailAlreadyUsed(err error) bool {
_, ok := err.(ErrEmailAlreadyUsed)
return ok
}
func (err ErrEmailAlreadyUsed) Error() string {
return fmt.Sprintf("e-mail has been used: [email: %s]", err.Email)
}
type ErrUserOwnRepos struct {
UID int64
}
@ -41,6 +107,82 @@ func (err ErrUserHasOrgs) Error() string {
return fmt.Sprintf("user still has membership of organizations: [uid: %d]", err.UID)
}
// __________ ___. .__ .__ ____ __.
// \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__.
// | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | |
// | | | | / \_\ \ |_| \ \___ | | \ ___/\___ |
// |____| |____/|___ /____/__|\___ > |____|__ \___ > ____|
// \/ \/ \/ \/\/
type ErrKeyNotExist struct {
ID int64
}
func IsErrKeyNotExist(err error) bool {
_, ok := err.(ErrKeyNotExist)
return ok
}
func (err ErrKeyNotExist) Error() string {
return fmt.Sprintf("public key does not exist: [id: %d]", err.ID)
}
type ErrKeyAlreadyExist struct {
OwnerID int64
Content string
}
func IsErrKeyAlreadyExist(err error) bool {
_, ok := err.(ErrKeyAlreadyExist)
return ok
}
func (err ErrKeyAlreadyExist) Error() string {
return fmt.Sprintf("public key already exists: [owner_id: %d, content: %s]", err.OwnerID, err.Content)
}
type ErrKeyNameAlreadyUsed struct {
OwnerID int64
Name string
}
func IsErrKeyNameAlreadyUsed(err error) bool {
_, ok := err.(ErrKeyNameAlreadyUsed)
return ok
}
func (err ErrKeyNameAlreadyUsed) Error() string {
return fmt.Sprintf("public key already exists: [owner_id: %d, name: %s]", err.OwnerID, err.Name)
}
type ErrDeployKeyAlreadyExist struct {
KeyID int64
RepoID int64
}
func IsErrDeployKeyAlreadyExist(err error) bool {
_, ok := err.(ErrDeployKeyAlreadyExist)
return ok
}
func (err ErrDeployKeyAlreadyExist) Error() string {
return fmt.Sprintf("public key already exists: [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
}
type ErrDeployKeyNameAlreadyUsed struct {
RepoID int64
Name string
}
func IsErrDeployKeyNameAlreadyUsed(err error) bool {
_, ok := err.(ErrDeployKeyNameAlreadyUsed)
return ok
}
func (err ErrDeployKeyNameAlreadyUsed) Error() string {
return fmt.Sprintf("public key already exists: [repo_id: %d, name: %s]", err.RepoID, err.Name)
}
// ________ .__ __ .__
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
@ -82,3 +224,37 @@ func IsErrRepoNotExist(err error) bool {
func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name)
}
type ErrRepoAlreadyExist struct {
Uname string
Name string
}
func IsErrRepoAlreadyExist(err error) bool {
_, ok := err.(ErrRepoAlreadyExist)
return ok
}
func (err ErrRepoAlreadyExist) Error() string {
return fmt.Sprintf("repository already exists [uname: %d, name: %s]", err.Uname, err.Name)
}
// _____ .__.__ __
// / \ |__| | ____ _______/ |_ ____ ____ ____
// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
// / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/
// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
// \/ \/ \/ \/ \/
type ErrMilestoneNotExist struct {
ID int64
}
func IsErrMilestoneNotExist(err error) bool {
_, ok := err.(ErrMilestoneNotExist)
return ok
}
func (err ErrMilestoneNotExist) Error() string {
return fmt.Sprintf("milestone does not exist [id: %d]", err.ID)
}

@ -87,7 +87,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
leftLine, rightLine int
isTooLong bool
// FIXME: use first 30 lines to detect file encoding. Should use cache in the future.
// FIXME: Should use cache in the future.
buf bytes.Buffer
)
@ -106,16 +106,10 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
i = i + 1
// FIXME: use first 30 lines to detect file encoding.
if i <= 30 {
buf.WriteString(line)
}
// 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 {
@ -127,7 +121,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
continue
case line[0] == '@':
if isTooLong {
return diff, nil
break
}
curSection = &DiffSection{}
@ -137,9 +131,14 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
curSection.Lines = append(curSection.Lines, diffLine)
// Parse line number.
ranges := strings.Split(ss[len(ss)-2][1:], " ")
ranges := strings.Split(ss[1][1:], " ")
leftLine, _ = com.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int()
if len(ranges) > 1 {
rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int()
} else {
log.Warn("Parse line number failed: %v", line)
rightLine = leftLine
}
continue
case line[0] == '+':
curFile.Addition++
@ -164,11 +163,11 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
// Get new file.
if strings.HasPrefix(line, DIFF_HEAD) {
if isTooLong {
return diff, nil
break
}
fs := strings.Split(line[len(DIFF_HEAD):], " ")
a := fs[0]
beg := len(DIFF_HEAD)
a := line[beg : (len(line)-beg)/2+beg]
curFile = &DiffFile{
Name: a[strings.Index(a, "/")+1:],
@ -201,14 +200,19 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
}
}
// FIXME: use first 30 lines to detect file encoding.
charsetLabel, err := base.DetectEncoding(buf.Bytes())
if charsetLabel != "utf8" && err == nil {
encoding, _ := charset.Lookup(charsetLabel)
if encoding != nil {
d := encoding.NewDecoder()
for _, f := range diff.Files {
for _, f := range diff.Files {
buf.Reset()
for _, sec := range f.Sections {
for _, l := range sec.Lines {
buf.WriteString(l.Content)
buf.WriteString("\n")
}
}
charsetLabel, err := base.DetectEncoding(buf.Bytes())
if charsetLabel != "UTF-8" && err == nil {
encoding, _ := charset.Lookup(charsetLabel)
if encoding != nil {
d := encoding.NewDecoder()
for _, sec := range f.Sections {
for _, l := range sec.Lines {
if c, _, err := transform.String(d, l.Content); err == nil {
@ -219,7 +223,6 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
}
}
}
return diff, nil
}

@ -17,12 +17,12 @@ import (
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
var (
ErrIssueNotExist = errors.New("Issue does not exist")
ErrLabelNotExist = errors.New("Label does not exist")
ErrMilestoneNotExist = errors.New("Milestone does not exist")
ErrWrongIssueCounter = errors.New("Invalid number of issues for this milestone")
ErrAttachmentNotExist = errors.New("Attachment does not exist")
ErrAttachmentNotLinked = errors.New("Attachment does not belong to this issue")
@ -31,17 +31,18 @@ var (
// Issue represents an issue or pull request of repository.
type Issue struct {
Id int64
RepoId int64 `xorm:"INDEX"`
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
Index int64 // Index in one repository.
Name string
Repo *Repository `xorm:"-"`
PosterId int64
PosterID int64
Poster *User `xorm:"-"`
LabelIds string `xorm:"TEXT"`
Labels []*Label `xorm:"-"`
MilestoneId int64
AssigneeId int64
MilestoneID int64
Milestone *Milestone `xorm:"-"`
AssigneeID int64
Assignee *User `xorm:"-"`
IsRead bool `xorm:"-"`
IsPull bool // Indicates whether is a pull request or not.
@ -55,9 +56,20 @@ type Issue struct {
Updated time.Time `xorm:"UPDATED"`
}
func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
case "milestone_id":
i.Milestone, err = GetMilestoneByID(i.MilestoneID)
if err != nil {
log.Error(3, "GetMilestoneById: %v", err)
}
}
}
func (i *Issue) GetPoster() (err error) {
i.Poster, err = GetUserById(i.PosterId)
if err == ErrUserNotExist {
i.Poster, err = GetUserById(i.PosterID)
if IsErrUserNotExist(err) {
i.Poster = &User{Name: "FakeUser"}
return nil
}
@ -72,7 +84,7 @@ func (i *Issue) GetLabels() error {
strIds := strings.Split(strings.TrimSuffix(i.LabelIds[1:], "|"), "|$")
i.Labels = make([]*Label, 0, len(strIds))
for _, strId := range strIds {
id, _ := com.StrTo(strId).Int64()
id := com.StrTo(strId).MustInt64()
if id > 0 {
l, err := GetLabelById(id)
if err != nil {
@ -88,45 +100,41 @@ func (i *Issue) GetLabels() error {
}
func (i *Issue) GetAssignee() (err error) {
if i.AssigneeId == 0 {
if i.AssigneeID == 0 {
return nil
}
i.Assignee, err = GetUserById(i.AssigneeId)
if err == ErrUserNotExist {
i.Assignee, err = GetUserById(i.AssigneeID)
if IsErrUserNotExist(err) {
return nil
}
return err
}
func (i *Issue) Attachments() []*Attachment {
a, _ := GetAttachmentsForIssue(i.Id)
a, _ := GetAttachmentsForIssue(i.ID)
return a
}
func (i *Issue) AfterDelete() {
_, err := DeleteAttachmentsByIssue(i.Id, true)
_, err := DeleteAttachmentsByIssue(i.ID, true)
if err != nil {
log.Info("Could not delete files for issue #%d: %s", i.Id, err)
log.Info("Could not delete files for issue #%d: %s", i.ID, err)
}
}
// CreateIssue creates new issue for repository.
func NewIssue(issue *Issue) (err error) {
sess := x.NewSession()
defer sess.Close()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Insert(issue); err != nil {
sess.Rollback()
return err
}
rawSql := "UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?"
if _, err = sess.Exec(rawSql, issue.RepoId); err != nil {
sess.Rollback()
} else if _, err = sess.Exec("UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?", issue.RepoID); err != nil {
return err
}
@ -134,9 +142,9 @@ func NewIssue(issue *Issue) (err error) {
return err
}
if issue.MilestoneId > 0 {
if issue.MilestoneID > 0 {
// FIXES(280): Update milestone counter.
return ChangeMilestoneAssign(0, issue.MilestoneId, issue)
return ChangeMilestoneAssign(0, issue.MilestoneID, issue)
}
return
@ -167,7 +175,7 @@ func GetIssueByRef(ref string) (issue *Issue, err error) {
// GetIssueByIndex returns issue by given index in repository.
func GetIssueByIndex(rid, index int64) (*Issue, error) {
issue := &Issue{RepoId: rid, Index: index}
issue := &Issue{RepoID: rid, Index: index}
has, err := x.Get(issue)
if err != nil {
return nil, err
@ -179,7 +187,7 @@ func GetIssueByIndex(rid, index int64) (*Issue, error) {
// GetIssueById returns an issue by ID.
func GetIssueById(id int64) (*Issue, error) {
issue := &Issue{Id: id}
issue := &Issue{ID: id}
has, err := x.Get(issue)
if err != nil {
return nil, err
@ -189,31 +197,30 @@ func GetIssueById(id int64) (*Issue, error) {
return issue, nil
}
// GetIssues returns a list of issues by given conditions.
func GetIssues(uid, rid, pid, mid int64, page int, isClosed bool, labelIds, sortType string) ([]Issue, error) {
sess := x.Limit(20, (page-1)*20)
// Issues returns a list of issues by given conditions.
func Issues(uid, assigneeID, repoID, posterID, milestoneID int64, page int, isClosed, isMention bool, labelIds, sortType string) ([]*Issue, error) {
sess := x.Limit(setting.IssuePagingNum, (page-1)*setting.IssuePagingNum)
if rid > 0 {
sess.Where("repo_id=?", rid).And("is_closed=?", isClosed)
if repoID > 0 {
sess.Where("issue.repo_id=?", repoID).And("issue.is_closed=?", isClosed)
} else {
sess.Where("is_closed=?", isClosed)
sess.Where("issue.is_closed=?", isClosed)
}
if uid > 0 {
sess.And("assignee_id=?", uid)
} else if pid > 0 {
sess.And("poster_id=?", pid)
if assigneeID > 0 {
sess.And("issue.assignee_id=?", assigneeID)
} else if posterID > 0 {
sess.And("issue.poster_id=?", posterID)
}
if mid > 0 {
sess.And("milestone_id=?", mid)
if milestoneID > 0 {
sess.And("issue.milestone_id=?", milestoneID)
}
if len(labelIds) > 0 {
for _, label := range strings.Split(labelIds, ",") {
// Prevent SQL inject.
if com.StrTo(label).MustInt() > 0 {
sess.And("label_ids like '%$" + label + "|%'")
sess.And("label_ids like ?", "%$"+label+"|%")
}
}
}
@ -235,9 +242,16 @@ func GetIssues(uid, rid, pid, mid int64, page int, isClosed bool, labelIds, sort
sess.Desc("created")
}
var issues []Issue
err := sess.Find(&issues)
return issues, err
if isMention {
queryStr := "issue.id = issue_user.issue_id AND issue_user.is_mentioned=1"
if uid > 0 {
queryStr += " AND issue_user.uid = " + com.ToStr(uid)
}
sess.Join("INNER", "issue_user", queryStr)
}
issues := make([]*Issue, 0, setting.IssuePagingNum)
return issues, sess.Find(&issues)
}
type IssueStatus int
@ -248,10 +262,9 @@ const (
)
// GetIssuesByLabel returns a list of issues by given label and repository.
func GetIssuesByLabel(repoId int64, label string) ([]*Issue, error) {
func GetIssuesByLabel(repoID, labelID int64) ([]*Issue, error) {
issues := make([]*Issue, 0, 10)
err := x.Where("repo_id=?", repoId).And("label_ids like '%$" + label + "|%'").Find(&issues)
return issues, err
return issues, x.Where("repo_id=?", repoID).And("label_ids like '%$" + com.ToStr(labelID) + "|%'").Find(&issues)
}
// GetIssueCountByPoster returns number of issues of repository by poster.
@ -281,8 +294,9 @@ type IssueUser struct {
IsClosed bool
}
// FIXME: organization
// NewIssueUserPairs adds new issue-user pairs for new issue of repository.
func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID int64) (err error) {
func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID int64) error {
users, err := repo.GetCollaborators()
if err != nil {
return err
@ -295,6 +309,7 @@ func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID in
isNeedAddPoster := true
for _, u := range users {
iu.Id = 0
iu.Uid = u.Id
iu.IsPoster = iu.Uid == posterID
if isNeedAddPoster && iu.IsPoster {
@ -306,6 +321,7 @@ func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID in
}
}
if isNeedAddPoster {
iu.Id = 0
iu.Uid = posterID
iu.IsPoster = true
iu.IsAssigned = iu.Uid == assigneeID
@ -314,13 +330,24 @@ func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID in
}
}
// Add owner's as well.
if repo.OwnerId != posterID {
iu.Id = 0
iu.Uid = repo.OwnerId
iu.IsAssigned = iu.Uid == assigneeID
if _, err = x.Insert(iu); err != nil {
return err
}
}
return nil
}
// PairsContains returns true when pairs list contains given issue.
func PairsContains(ius []*IssueUser, issueId int64) int {
func PairsContains(ius []*IssueUser, issueId, uid int64) int {
for i := range ius {
if ius[i].IssueId == issueId {
if ius[i].IssueId == issueId &&
ius[i].Uid == uid {
return i
}
}
@ -387,53 +414,57 @@ type IssueStats struct {
// Filter modes.
const (
FM_ASSIGN = iota + 1
FM_ALL = iota
FM_ASSIGN
FM_CREATE
FM_MENTION
)
// GetIssueStats returns issue statistic information by given conditions.
func GetIssueStats(rid, uid int64, isShowClosed bool, filterMode int) *IssueStats {
func GetIssueStats(repoID, uid, labelID, milestoneID int64, isShowClosed bool, filterMode int) *IssueStats {
stats := &IssueStats{}
issue := new(Issue)
tmpSess := &xorm.Session{}
sess := x.Where("repo_id=?", rid)
*tmpSess = *sess
stats.OpenCount, _ = tmpSess.And("is_closed=?", false).Count(issue)
*tmpSess = *sess
stats.ClosedCount, _ = tmpSess.And("is_closed=?", true).Count(issue)
if isShowClosed {
stats.AllCount = stats.ClosedCount
} else {
stats.AllCount = stats.OpenCount
}
if filterMode != FM_MENTION {
sess = x.Where("repo_id=?", rid)
switch filterMode {
case FM_ASSIGN:
sess.And("assignee_id=?", uid)
case FM_CREATE:
sess.And("poster_id=?", uid)
default:
goto nofilter
queryStr := "issue.repo_id=? AND issue.is_closed=?"
if labelID > 0 {
queryStr += " AND issue.label_ids like '%$" + com.ToStr(labelID) + "|%'"
}
if milestoneID > 0 {
queryStr += " AND milestone_id=" + com.ToStr(milestoneID)
}
switch filterMode {
case FM_ALL:
stats.OpenCount, _ = x.Where(queryStr, repoID, false).Count(issue)
stats.ClosedCount, _ = x.Where(queryStr, repoID, true).Count(issue)
return stats
case FM_ASSIGN:
queryStr += " AND assignee_id=?"
stats.OpenCount, _ = x.Where(queryStr, repoID, false, uid).Count(issue)
stats.ClosedCount, _ = x.Where(queryStr, repoID, true, uid).Count(issue)
return stats
case FM_CREATE:
queryStr += " AND poster_id=?"
stats.OpenCount, _ = x.Where(queryStr, repoID, false, uid).Count(issue)
stats.ClosedCount, _ = x.Where(queryStr, repoID, true, uid).Count(issue)
return stats
case FM_MENTION:
queryStr += " AND uid=? AND is_mentioned=?"
if labelID > 0 {
stats.OpenCount, _ = x.Where(queryStr, repoID, false, uid, true).
Join("INNER", "issue", "issue.id = issue_id").Count(new(IssueUser))
stats.ClosedCount, _ = x.Where(queryStr, repoID, true, uid, true).
Join("INNER", "issue", "issue.id = issue_id").Count(new(IssueUser))
return stats
}
*tmpSess = *sess
stats.OpenCount, _ = tmpSess.And("is_closed=?", false).Count(issue)
*tmpSess = *sess
stats.ClosedCount, _ = tmpSess.And("is_closed=?", true).Count(issue)
} else {
sess := x.Where("repo_id=?", rid).And("uid=?", uid).And("is_mentioned=?", true)
*tmpSess = *sess
stats.OpenCount, _ = tmpSess.And("is_closed=?", false).Count(new(IssueUser))
*tmpSess = *sess
stats.ClosedCount, _ = tmpSess.And("is_closed=?", true).Count(new(IssueUser))
}
nofilter:
stats.AssignCount, _ = x.Where("repo_id=?", rid).And("is_closed=?", isShowClosed).And("assignee_id=?", uid).Count(issue)
stats.CreateCount, _ = x.Where("repo_id=?", rid).And("is_closed=?", isShowClosed).And("poster_id=?", uid).Count(issue)
stats.MentionCount, _ = x.Where("repo_id=?", rid).And("uid=?", uid).And("is_closed=?", isShowClosed).And("is_mentioned=?", true).Count(new(IssueUser))
queryStr = strings.Replace(queryStr, "issue.", "", 2)
stats.OpenCount, _ = x.Where(queryStr, repoID, false, uid, true).Count(new(IssueUser))
stats.ClosedCount, _ = x.Where(queryStr, repoID, true, uid, true).Count(new(IssueUser))
return stats
}
return stats
}
@ -448,7 +479,7 @@ func GetUserIssueStats(uid int64, filterMode int) *IssueStats {
// UpdateIssue updates information of issue.
func UpdateIssue(issue *Issue) error {
_, err := x.Id(issue.Id).AllCols().Update(issue)
_, err := x.Id(issue.ID).AllCols().Update(issue)
if err != nil {
return err
@ -518,7 +549,7 @@ func UpdateIssueUserPairsByMentions(uids []int64, iid int64) error {
// Label represents a label of repository for issues.
type Label struct {
Id int64
ID int64 `xorm:"pk autoincr"`
RepoId int64 `xorm:"INDEX"`
Name string
Color string `xorm:"VARCHAR(7)"`
@ -545,7 +576,7 @@ func GetLabelById(id int64) (*Label, error) {
return nil, ErrLabelNotExist
}
l := &Label{Id: id}
l := &Label{ID: id}
has, err := x.Get(l)
if err != nil {
return nil, err
@ -564,14 +595,13 @@ func GetLabels(repoId int64) ([]*Label, error) {
// UpdateLabel updates label information.
func UpdateLabel(l *Label) error {
_, err := x.Id(l.Id).AllCols().Update(l)
_, err := x.Id(l.ID).AllCols().Update(l)
return err
}
// DeleteLabel delete a label of given repository.
func DeleteLabel(repoId int64, strId string) error {
id, _ := com.StrTo(strId).Int64()
l, err := GetLabelById(id)
func DeleteLabel(repoID, labelID int64) error {
l, err := GetLabelById(labelID)
if err != nil {
if err == ErrLabelNotExist {
return nil
@ -579,27 +609,25 @@ func DeleteLabel(repoId int64, strId string) error {
return err
}
issues, err := GetIssuesByLabel(repoId, strId)
issues, err := GetIssuesByLabel(repoID, labelID)
if err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
for _, issue := range issues {
issue.LabelIds = strings.Replace(issue.LabelIds, "$"+strId+"|", "", -1)
if _, err = sess.Id(issue.Id).AllCols().Update(issue); err != nil {
sess.Rollback()
issue.LabelIds = strings.Replace(issue.LabelIds, "$"+com.ToStr(labelID)+"|", "", -1)
if _, err = sess.Id(issue.ID).AllCols().Update(issue); err != nil {
return err
}
}
if _, err = sess.Delete(l); err != nil {
sess.Rollback()
return err
}
return sess.Commit()
@ -614,9 +642,8 @@ func DeleteLabel(repoId int64, strId string) error {
// Milestone represents a milestone of repository.
type Milestone struct {
Id int64
RepoId int64 `xorm:"INDEX"`
Index int64
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
Name string
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
@ -627,9 +654,23 @@ type Milestone struct {
Completeness int // Percentage(1-100).
Deadline time.Time
DeadlineString string `xorm:"-"`
IsOverDue bool `xorm:"-"`
ClosedDate time.Time
}
func (m *Milestone) AfterSet(colName string, _ xorm.Cell) {
if colName == "deadline" {
if m.Deadline.Year() == 9999 {
return
}
m.DeadlineString = m.Deadline.Format("2006-01-02")
if time.Now().After(m.Deadline) {
m.IsOverDue = true
}
}
}
// CalOpenIssues calculates the open issues of milestone.
func (m *Milestone) CalOpenIssues() {
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
@ -638,101 +679,119 @@ func (m *Milestone) CalOpenIssues() {
// NewMilestone creates new milestone of repository.
func NewMilestone(m *Milestone) (err error) {
sess := x.NewSession()
defer sess.Close()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Insert(m); err != nil {
sess.Rollback()
return err
}
rawSql := "UPDATE `repository` SET num_milestones = num_milestones + 1 WHERE id = ?"
if _, err = sess.Exec(rawSql, m.RepoId); err != nil {
sess.Rollback()
if _, err = sess.Exec("UPDATE `repository` SET num_milestones=num_milestones+1 WHERE id=?", m.RepoID); err != nil {
return err
}
return sess.Commit()
}
// GetMilestoneById returns the milestone by given ID.
func GetMilestoneById(id int64) (*Milestone, error) {
m := &Milestone{Id: id}
// GetMilestoneByID returns the milestone of given ID.
func GetMilestoneByID(id int64) (*Milestone, error) {
m := &Milestone{ID: id}
has, err := x.Get(m)
if err != nil {
return nil, err
} else if !has {
return nil, ErrMilestoneNotExist
return nil, ErrMilestoneNotExist{id}
}
return m, nil
}
// GetMilestoneByIndex returns the milestone of given repository and index.
func GetMilestoneByIndex(repoId, idx int64) (*Milestone, error) {
m := &Milestone{RepoId: repoId, Index: idx}
has, err := x.Get(m)
if err != nil {
return nil, err
} else if !has {
return nil, ErrMilestoneNotExist
}
return m, nil
// GetAllRepoMilestones returns all milestones of given repository.
func GetAllRepoMilestones(repoID int64) ([]*Milestone, error) {
miles := make([]*Milestone, 0, 10)
return miles, x.Where("repo_id=?", repoID).Find(&miles)
}
// GetMilestones returns a list of milestones of given repository and status.
func GetMilestones(repoId int64, isClosed bool) ([]*Milestone, error) {
miles := make([]*Milestone, 0, 10)
err := x.Where("repo_id=?", repoId).And("is_closed=?", isClosed).Find(&miles)
return miles, err
func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error) {
miles := make([]*Milestone, 0, setting.IssuePagingNum)
sess := x.Where("repo_id=? AND is_closed=?", repoID, isClosed)
if page > 0 {
sess = sess.Limit(setting.IssuePagingNum, (page-1)*setting.IssuePagingNum)
}
return miles, sess.Find(&miles)
}
func updateMilestone(e Engine, m *Milestone) error {
_, err := e.Id(m.ID).AllCols().Update(m)
return err
}
// UpdateMilestone updates information of given milestone.
func UpdateMilestone(m *Milestone) error {
_, err := x.Id(m.Id).Update(m)
return err
return updateMilestone(x, m)
}
func countRepoMilestones(e Engine, repoID int64) int64 {
count, _ := e.Where("repo_id=?", repoID).Count(new(Milestone))
return count
}
// CountRepoMilestones returns number of milestones in given repository.
func CountRepoMilestones(repoID int64) int64 {
return countRepoMilestones(x, repoID)
}
func countRepoClosedMilestones(e Engine, repoID int64) int64 {
closed, _ := e.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone))
return closed
}
// CountRepoClosedMilestones returns number of closed milestones in given repository.
func CountRepoClosedMilestones(repoID int64) int64 {
return countRepoClosedMilestones(x, repoID)
}
// MilestoneStats returns number of open and closed milestones of given repository.
func MilestoneStats(repoID int64) (open int64, closed int64) {
open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone))
return open, CountRepoClosedMilestones(repoID)
}
// ChangeMilestoneStatus changes the milestone open/closed status.
func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
repo, err := GetRepositoryById(m.RepoId)
repo, err := GetRepositoryById(m.RepoID)
if err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
m.IsClosed = isClosed
if _, err = sess.Id(m.Id).AllCols().Update(m); err != nil {
sess.Rollback()
if err = updateMilestone(sess, m); err != nil {
return err
}
if isClosed {
repo.NumClosedMilestones++
} else {
repo.NumClosedMilestones--
}
if _, err = sess.Id(repo.Id).Update(repo); err != nil {
sess.Rollback()
repo.NumMilestones = int(countRepoMilestones(sess, repo.Id))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id))
if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
return err
}
return sess.Commit()
}
// ChangeMilestoneIssueStats updates the open/closed issues counter and progress for the
// milestone associated witht the given issue.
// ChangeMilestoneIssueStats updates the open/closed issues counter and progress
// for the milestone associated witht the given issue.
func ChangeMilestoneIssueStats(issue *Issue) error {
if issue.MilestoneId == 0 {
if issue.MilestoneID == 0 {
return nil
}
m, err := GetMilestoneById(issue.MilestoneId)
m, err := GetMilestoneByID(issue.MilestoneID)
if err != nil {
return err
}
@ -759,7 +818,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
}
if oldMid > 0 {
m, err := GetMilestoneById(oldMid)
m, err := GetMilestoneByID(oldMid)
if err != nil {
return err
}
@ -774,20 +833,20 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
m.Completeness = 0
}
if _, err = sess.Id(m.Id).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil {
if _, err = sess.Id(m.ID).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil {
sess.Rollback()
return err
}
rawSql := "UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?"
if _, err = sess.Exec(rawSql, issue.Id); err != nil {
if _, err = sess.Exec(rawSql, issue.ID); err != nil {
sess.Rollback()
return err
}
}
if mid > 0 {
m, err := GetMilestoneById(mid)
m, err := GetMilestoneByID(mid)
if err != nil {
return err
}
@ -802,13 +861,13 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
}
m.Completeness = m.NumClosedIssues * 100 / m.NumIssues
if _, err = sess.Id(m.Id).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil {
if _, err = sess.Id(m.ID).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil {
sess.Rollback()
return err
}
rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?"
if _, err = sess.Exec(rawSql, m.Id, issue.Id); err != nil {
if _, err = sess.Exec(rawSql, m.ID, issue.ID); err != nil {
sess.Rollback()
return err
}
@ -817,34 +876,40 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
return sess.Commit()
}
// DeleteMilestone deletes a milestone.
func DeleteMilestone(m *Milestone) (err error) {
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
// DeleteMilestoneByID deletes a milestone by given ID.
func DeleteMilestoneByID(mid int64) error {
m, err := GetMilestoneByID(mid)
if err != nil {
if IsErrMilestoneNotExist(err) {
return nil
}
return err
}
if _, err = sess.Delete(m); err != nil {
sess.Rollback()
repo, err := GetRepositoryById(m.RepoID)
if err != nil {
return err
}
rawSql := "UPDATE `repository` SET num_milestones = num_milestones - 1 WHERE id = ?"
if _, err = sess.Exec(rawSql, m.RepoId); err != nil {
sess.Rollback()
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
rawSql = "UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?"
if _, err = sess.Exec(rawSql, m.Id); err != nil {
sess.Rollback()
if _, err = sess.Id(m.ID).Delete(m); err != nil {
return err
}
rawSql = "UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?"
if _, err = sess.Exec(rawSql, m.Id); err != nil {
sess.Rollback()
repo.NumMilestones = int(countRepoMilestones(sess, repo.Id))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id))
if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
return err
}
if _, err = sess.Exec("UPDATE `issue` SET milestone_id=0 WHERE milestone_id=?", m.ID); err != nil {
return err
} else if _, err = sess.Exec("UPDATE `issue_user` SET milestone_id=0 WHERE milestone_id=?", m.ID); err != nil {
return err
}
return sess.Commit()
@ -890,7 +955,7 @@ type Comment struct {
// CreateComment creates comment of issue or commit.
func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType CommentType, content string, attachments []int64) (*Comment, error) {
sess := x.NewSession()
defer sess.Close()
defer sessionRelease(sess)
if err := sess.Begin(); err != nil {
return nil, err
}
@ -899,7 +964,6 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
CommitId: commitId, Line: line, Content: content}
if _, err := sess.Insert(comment); err != nil {
sess.Rollback()
return nil, err
}
@ -908,7 +972,6 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
case COMMENT_TYPE_COMMENT:
rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, issueId); err != nil {
sess.Rollback()
return nil, err
}
@ -922,20 +985,17 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
}
if _, err := sess.Exec(rawSql, comment.Id, strings.Join(astrs, ",")); err != nil {
sess.Rollback()
return nil, err
}
}
case COMMENT_TYPE_REOPEN:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
return nil, err
}
case COMMENT_TYPE_CLOSE:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
return nil, err
}
}

@ -17,6 +17,7 @@ import (
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/auth/ldap"
"github.com/gogits/gogs/modules/auth/pam"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/uuid"
)
@ -28,6 +29,7 @@ const (
PLAIN
LDAP
SMTP
PAM
)
var (
@ -39,12 +41,14 @@ var (
var LoginTypes = map[LoginType]string{
LDAP: "LDAP",
SMTP: "SMTP",
PAM: "PAM",
}
// Ensure structs implemented interface.
var (
_ core.Conversion = &LDAPConfig{}
_ core.Conversion = &SMTPConfig{}
_ core.Conversion = &PAMConfig{}
)
type LDAPConfig struct {
@ -74,6 +78,18 @@ func (cfg *SMTPConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
type PAMConfig struct {
ServiceName string // pam service (e.g. system-auth)
}
func (cfg *PAMConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, &cfg)
}
func (cfg *PAMConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
type LoginSource struct {
Id int64
Type LoginType
@ -97,6 +113,10 @@ func (source *LoginSource) SMTP() *SMTPConfig {
return source.Cfg.(*SMTPConfig)
}
func (source *LoginSource) PAM() *PAMConfig {
return source.Cfg.(*PAMConfig)
}
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
if colName == "type" {
ty := (*val).(int64)
@ -105,6 +125,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
source.Cfg = new(LDAPConfig)
case SMTP:
source.Cfg = new(SMTPConfig)
case PAM:
source.Cfg = new(PAMConfig)
}
}
}
@ -169,8 +191,8 @@ func UserSignIn(uname, passwd string) (*User, error) {
// For plain login, user must exist to reach this line.
// Now verify password.
if u.LoginType == PLAIN {
if !u.ValidtePassword(passwd) {
return nil, ErrUserNotExist
if !u.ValidatePassword(passwd) {
return nil, ErrUserNotExist{u.Id, u.Name}
}
return u, nil
}
@ -197,10 +219,17 @@ func UserSignIn(uname, passwd string) (*User, error) {
return u, nil
}
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
} else if source.Type == PAM {
u, err := LoginUserPAMSource(nil, uname, passwd,
source.Id, source.Cfg.(*PAMConfig), true)
if err == nil {
return u, nil
}
log.Warn("Fail to login(%s) by PAM(%s): %v", uname, source.Name, err)
}
}
return nil, ErrUserNotExist
return nil, ErrUserNotExist{u.Id, u.Name}
}
var source LoginSource
@ -218,6 +247,8 @@ func UserSignIn(uname, passwd string) (*User, error) {
return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false)
case SMTP:
return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false)
case PAM:
return LoginUserPAMSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*PAMConfig), false)
}
return nil, ErrUnsupportedLoginType
}
@ -230,7 +261,7 @@ func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAP
name, fn, sn, mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
if !logged {
// User not in LDAP, do nothing
return nil, ErrUserNotExist
return nil, ErrUserNotExist{u.Id, u.Name}
}
if !autoRegister {
return u, nil
@ -331,7 +362,7 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP
if err := SmtpAuth(cfg.Host, cfg.Port, auth, cfg.TLS); err != nil {
if strings.Contains(err.Error(), "Username and Password not accepted") {
return nil, ErrUserNotExist
return nil, ErrUserNotExist{u.Id, u.Name}
}
return nil, err
}
@ -359,3 +390,33 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP
err := CreateUser(u)
return u, err
}
// Query if name/passwd can login against PAM
// Create a local user if success
// Return the same LoginUserPlain semantic
func LoginUserPAMSource(u *User, name, passwd string, sourceId int64, cfg *PAMConfig, autoRegister bool) (*User, error) {
if err := pam.PAMAuth(cfg.ServiceName, name, passwd); err != nil {
if strings.Contains(err.Error(), "Authentication failure") {
return nil, ErrUserNotExist{u.Id, u.Name}
}
return nil, err
}
if !autoRegister {
return u, nil
}
// fake a local user creation
u = &User{
LowerName: strings.ToLower(name),
Name: strings.ToLower(name),
LoginType: PAM,
LoginSource: sourceId,
LoginName: name,
IsActive: true,
Passwd: passwd,
Email: name,
}
err := CreateUser(u)
return u, err
}

@ -5,6 +5,7 @@
package migrations
import (
"encoding/json"
"fmt"
"strings"
"time"
@ -51,11 +52,12 @@ type Version struct {
// If you want to "retire" a migration, remove it from the top of the list and
// update _MIN_VER_DB accordingly
var migrations = []Migration{
NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1:v0.5.13
NewMigration("make authorize 4 if team is owners", ownerTeamUpdate), // V1 -> V2:v0.5.13
NewMigration("refactor access table to use id's", accessRefactor), // V2 -> V3:v0.5.13
NewMigration("generate team-repo from team", teamToTeamRepo), // V3 -> V4:v0.5.13
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0
NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1:v0.5.13
NewMigration("make authorize 4 if team is owners", ownerTeamUpdate), // V1 -> V2:v0.5.13
NewMigration("refactor access table to use id's", accessRefactor), // V2 -> V3:v0.5.13
NewMigration("generate team-repo from team", teamToTeamRepo), // V3 -> V4:v0.5.13
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0
NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix), // V5 -> V6:v0.6.3
}
// Migrate database to current version
@ -389,3 +391,65 @@ func fixLocaleFileLoadPanic(_ *xorm.Engine) error {
setting.Langs = strings.Split(strings.Replace(strings.Join(setting.Langs, ","), "fr-CA", "fr-FR", 1), ",")
return nil
}
func trimCommitActionAppUrlPrefix(x *xorm.Engine) error {
type PushCommit struct {
Sha1 string
Message string
AuthorEmail string
AuthorName string
}
type PushCommits struct {
Len int
Commits []*PushCommit
CompareUrl string
}
type Action struct {
ID int64 `xorm:"pk autoincr"`
Content string `xorm:"TEXT"`
}
results, err := x.Query("SELECT `id`,`content` FROM `action` WHERE `op_type`=?", 5)
if err != nil {
return fmt.Errorf("select commit actions: %v", err)
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
var pushCommits *PushCommits
for _, action := range results {
actID := com.StrTo(string(action["id"])).MustInt64()
if actID == 0 {
continue
}
pushCommits = new(PushCommits)
if err = json.Unmarshal(action["content"], pushCommits); err != nil {
return fmt.Errorf("unmarshal action content[%s]: %v", actID, err)
}
infos := strings.Split(pushCommits.CompareUrl, "/")
if len(infos) <= 4 {
continue
}
pushCommits.CompareUrl = strings.Join(infos[len(infos)-4:], "/")
p, err := json.Marshal(pushCommits)
if err != nil {
return fmt.Errorf("marshal action content[%s]: %v", actID, err)
}
if _, err = sess.Id(actID).Update(&Action{
Content: string(p),
}); err != nil {
return fmt.Errorf("update action[%s]: %v", actID, err)
}
}
return sess.Commit()
}

@ -55,7 +55,7 @@ var (
func init() {
tables = append(tables,
new(User), new(PublicKey), new(Oauth2), new(AccessToken),
new(Repository), new(Collaboration), new(Access),
new(Repository), new(DeployKey), new(Collaboration), new(Access),
new(Watch), new(Star), new(Follow), new(Action),
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
@ -90,10 +90,10 @@ func getEngine() (*xorm.Engine, error) {
switch DbCfg.Type {
case "mysql":
if DbCfg.Host[0] == '/' { // looks like a unix socket
cnnstr = fmt.Sprintf("%s:%s@unix(%s)/%s?charset=utf8",
cnnstr = fmt.Sprintf("%s:%s@unix(%s)/%s?charset=utf8&parseTime=true",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
} else {
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=true",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
}
case "postgres":
@ -105,7 +105,7 @@ func getEngine() (*xorm.Engine, error) {
if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 {
port = fields[1]
}
cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
cnnstr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
DbCfg.User, DbCfg.Passwd, host, port, DbCfg.Name, DbCfg.SSLMode)
case "sqlite3":
if !EnableSQLite3 {
@ -122,7 +122,7 @@ func getEngine() (*xorm.Engine, error) {
func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("connect to database: %v", err)
return fmt.Errorf("Connect to database: %v", err)
}
x.SetMapper(core.GonicMapper{})
@ -132,7 +132,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
func SetEngine() (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("connect to database: %v", err)
return fmt.Errorf("Fail to connect to database: %v", err)
}
x.SetMapper(core.GonicMapper{})
@ -144,7 +144,7 @@ func SetEngine() (err error) {
f, err := os.Create(logPath)
if err != nil {
return fmt.Errorf("models.init(fail to create xorm.log): %v", err)
return fmt.Errorf("Fail to create xorm.log: %v", err)
}
x.SetLogger(xorm.NewSimpleLogger(f))

@ -105,23 +105,23 @@ func IsOrgEmailUsed(email string) (bool, error) {
}
// CreateOrganization creates record of a new organization.
func CreateOrganization(org, owner *User) (*User, error) {
if !IsLegalName(org.Name) {
return nil, ErrUserNameIllegal
func CreateOrganization(org, owner *User) (err error) {
if err = IsUsableName(org.Name); err != nil {
return err
}
isExist, err := IsUserExist(0, org.Name)
if err != nil {
return nil, err
return err
} else if isExist {
return nil, ErrUserAlreadyExist
return ErrUserAlreadyExist{org.Name}
}
isExist, err = IsOrgEmailUsed(org.Email)
if err != nil {
return nil, err
return err
} else if isExist {
return nil, ErrEmailAlreadyUsed
return ErrEmailAlreadyUsed{org.Email}
}
org.LowerName = strings.ToLower(org.Name)
@ -135,11 +135,11 @@ func CreateOrganization(org, owner *User) (*User, error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return nil, err
return err
}
if _, err = sess.Insert(org); err != nil {
return nil, err
return fmt.Errorf("insert organization: %v", err)
}
// Create default owner team.
@ -151,7 +151,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
NumMembers: 1,
}
if _, err = sess.Insert(t); err != nil {
return nil, err
return fmt.Errorf("insert owner team: %v", err)
}
// Add initial creator to organization and owner team.
@ -162,7 +162,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
NumTeams: 1,
}
if _, err = sess.Insert(ou); err != nil {
return nil, err
return fmt.Errorf("insert org-user relation: %v", err)
}
tu := &TeamUser{
@ -171,14 +171,14 @@ func CreateOrganization(org, owner *User) (*User, error) {
TeamID: t.ID,
}
if _, err = sess.Insert(tu); err != nil {
return nil, err
return fmt.Errorf("insert team-user relation: %v", err)
}
if err = os.MkdirAll(UserPath(org.Name), os.ModePerm); err != nil {
return nil, err
return fmt.Errorf("create directory: %v", err)
}
return org, sess.Commit()
return sess.Commit()
}
// GetOrgByName returns organization by given name.
@ -594,9 +594,9 @@ func (t *Team) RemoveRepository(repoID int64) error {
// NewTeam creates a record of new team.
// It's caller's responsibility to assign organization ID.
func NewTeam(t *Team) error {
if !IsLegalName(t.Name) {
return ErrTeamNameIllegal
func NewTeam(t *Team) (err error) {
if err = IsUsableName(t.Name); err != nil {
return err
}
has, err := x.Id(t.OrgID).Get(new(User))
@ -670,8 +670,8 @@ func GetTeamById(teamId int64) (*Team, error) {
// UpdateTeam updates information of team.
func UpdateTeam(t *Team, authChanged bool) (err error) {
if !IsLegalName(t.Name) {
return ErrTeamNameIllegal
if err = IsUsableName(t.Name); err != nil {
return err
}
if len(t.Description) > 255 {

@ -21,6 +21,7 @@ import (
"time"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
@ -33,8 +34,6 @@ const (
)
var (
ErrKeyAlreadyExist = errors.New("Public key already exists")
ErrKeyNotExist = errors.New("Public key does not exist")
ErrKeyUnableVerify = errors.New("Unable to verify public key")
)
@ -78,17 +77,34 @@ func init() {
}
}
// PublicKey represents a SSH key.
type KeyType int
const (
KEY_TYPE_USER = iota + 1
KEY_TYPE_DEPLOY
)
// PublicKey represents a SSH or deploy key.
type PublicKey struct {
Id int64
OwnerId int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"UNIQUE(s) NOT NULL"`
Fingerprint string `xorm:"INDEX NOT NULL"`
Content string `xorm:"TEXT NOT NULL"`
Created time.Time `xorm:"CREATED"`
Updated time.Time
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
Created time.Time `xorm:"CREATED"`
Updated time.Time // Note: Updated must below Created for AfterSet.
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
func (k *PublicKey) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created":
k.HasUsed = k.Updated.After(k.Created)
k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
}
// OmitEmail returns content of public key but without e-mail address.
@ -98,7 +114,7 @@ func (k *PublicKey) OmitEmail() string {
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, setting.CustomConf, key.Content)
return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.ID, setting.CustomConf, key.Content)
}
var minimumKeySizes = map[string]int{
@ -126,8 +142,8 @@ func extractTypeFromBase64Key(key string) (string, error) {
return string(b[4 : 4+keyLength]), nil
}
// Parse any key string in openssh or ssh2 format to clean openssh string (rfc4253)
func ParseKeyString(content string) (string, error) {
// parseKeyString parses any key string in openssh or ssh2 format to clean openssh string (rfc4253)
func parseKeyString(content string) (string, error) {
// Transform all legal line endings to a single "\n"
s := strings.Replace(strings.Replace(strings.TrimSpace(content), "\r\n", "\n", -1), "\r", "\n", -1)
@ -190,16 +206,21 @@ func ParseKeyString(content string) (string, error) {
}
// CheckPublicKeyString checks if the given public key string is recognized by SSH.
func CheckPublicKeyString(content string) (bool, error) {
func CheckPublicKeyString(content string) (_ string, err error) {
content, err = parseKeyString(content)
if err != nil {
return "", err
}
content = strings.TrimRight(content, "\n\r")
if strings.ContainsAny(content, "\n\r") {
return false, errors.New("only a single line with a single key please")
return "", errors.New("only a single line with a single key please")
}
// write the key to a file…
tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest")
if err != nil {
return false, err
return "", err
}
tmpPath := tmpFile.Name()
defer os.Remove(tmpPath)
@ -209,37 +230,36 @@ func CheckPublicKeyString(content string) (bool, error) {
// 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)
return "", 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: " + stdout)
return "", errors.New("ssh-keygen returned not enough output to evaluate the key: " + stdout)
}
// The ssh-keygen in Windows does not print key type, so no need go further.
if setting.IsWindows {
return true, nil
return content, nil
}
fmt.Println(stdout)
sshKeygenOutput := strings.Split(stdout, " ")
if len(sshKeygenOutput) < 4 {
return false, ErrKeyUnableVerify
return content, ErrKeyUnableVerify
}
// Check if key type and key size match.
if !setting.Service.DisableMinimumKeySizeCheck {
keySize := com.StrTo(sshKeygenOutput[0]).MustInt()
if keySize == 0 {
return false, errors.New("cannot get key size of the given key")
return "", errors.New("cannot get key size of the given key")
}
keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])
if minimumKeySize := minimumKeySizes[keyType]; minimumKeySize == 0 {
return false, errors.New("sorry, unrecognized public key type")
return "", errors.New("sorry, unrecognized public key type")
} else if keySize < minimumKeySize {
return false, fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
return "", fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
}
}
return true, nil
return content, nil
}
// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
@ -278,20 +298,23 @@ func saveAuthorizedKeyFile(keys ...*PublicKey) error {
return nil
}
// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(key *PublicKey) (err error) {
has, err := x.Get(key)
func checkKeyContent(content string) error {
// Same key can only be added once.
has, err := x.Where("content=?", content).Get(new(PublicKey))
if err != nil {
return err
} else if has {
return ErrKeyAlreadyExist
return ErrKeyAlreadyExist{0, content}
}
return nil
}
func addKey(e Engine, key *PublicKey) (err error) {
// Calculate fingerprint.
tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
"id_rsa.pub"), "\\", "/", -1)
os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), 0644); err != nil {
return err
}
stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath)
@ -301,32 +324,56 @@ func AddPublicKey(key *PublicKey) (err error) {
return errors.New("not enough output for calculating fingerprint: " + stdout)
}
key.Fingerprint = strings.Split(stdout, " ")[1]
if has, err := x.Get(&PublicKey{Fingerprint: key.Fingerprint}); err == nil && has {
return ErrKeyAlreadyExist
}
// Save SSH key.
if _, err = x.Insert(key); err != nil {
if _, err = e.Insert(key); err != nil {
return err
} else if err = saveAuthorizedKeyFile(key); err != nil {
// Roll back.
if _, err2 := x.Delete(key); err2 != nil {
return err2
}
}
return saveAuthorizedKeyFile(key)
}
// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(ownerID int64, name, content string) (err error) {
if err = checkKeyContent(content); err != nil {
return err
}
return nil
// Key name of same user cannot be duplicated.
has, err := x.Where("owner_id=? AND name=?", ownerID, name).Get(new(PublicKey))
if err != nil {
return err
} else if has {
return ErrKeyNameAlreadyUsed{ownerID, name}
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
key := &PublicKey{
OwnerID: ownerID,
Name: name,
Content: content,
Mode: ACCESS_MODE_WRITE,
Type: KEY_TYPE_USER,
}
if err = addKey(sess, key); err != nil {
return fmt.Errorf("addKey: %v", err)
}
return sess.Commit()
}
// GetPublicKeyById returns public key by given ID.
func GetPublicKeyById(keyId int64) (*PublicKey, error) {
// GetPublicKeyByID returns public key by given ID.
func GetPublicKeyByID(keyID int64) (*PublicKey, error) {
key := new(PublicKey)
has, err := x.Id(keyId).Get(key)
has, err := x.Id(keyID).Get(key)
if err != nil {
return nil, err
} else if !has {
return nil, ErrKeyNotExist
return nil, ErrKeyNotExist{keyID}
}
return key, nil
}
@ -334,16 +381,7 @@ func GetPublicKeyById(keyId int64) (*PublicKey, error) {
// ListPublicKeys returns a list of public keys belongs to given user.
func ListPublicKeys(uid int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5)
err := x.Where("owner_id=?", uid).Find(&keys)
if err != nil {
return nil, err
}
for _, key := range keys {
key.HasUsed = key.Updated.After(key.Created)
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
return keys, nil
return keys, x.Where("owner_id=?", uid).Find(&keys)
}
// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file.
@ -364,7 +402,7 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
defer fw.Close()
isFound := false
keyword := fmt.Sprintf("key-%d", key.Id)
keyword := fmt.Sprintf("key-%d", key.ID)
buf := bufio.NewReader(fr)
for {
line, errRead := buf.ReadString('\n')
@ -401,20 +439,19 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
// UpdatePublicKey updates given public key.
func UpdatePublicKey(key *PublicKey) error {
_, err := x.Id(key.Id).AllCols().Update(key)
_, err := x.Id(key.ID).AllCols().Update(key)
return err
}
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
func DeletePublicKey(key *PublicKey) error {
has, err := x.Get(key)
func deletePublicKey(e *xorm.Session, key *PublicKey) error {
has, err := e.Get(key)
if err != nil {
return err
} else if !has {
return ErrKeyNotExist
return nil
}
if _, err = x.Delete(key); err != nil {
if _, err = e.Id(key.ID).Delete(key); err != nil {
return err
}
@ -428,6 +465,21 @@ func DeletePublicKey(key *PublicKey) error {
return os.Rename(tmpPath, fpath)
}
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
func DeletePublicKey(key *PublicKey) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = deletePublicKey(sess, key); err != nil {
return err
}
return sess.Commit()
}
// RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
func RewriteAllPublicKeys() error {
sshOpLocker.Lock()
@ -461,3 +513,162 @@ func RewriteAllPublicKeys() error {
return nil
}
// ________ .__ ____ __.
// \______ \ ____ ______ | | ____ ___.__.| |/ _|____ ___.__.
// | | \_/ __ \\____ \| | / _ < | || <_/ __ < | |
// | ` \ ___/| |_> > |_( <_> )___ || | \ ___/\___ |
// /_______ /\___ > __/|____/\____// ____||____|__ \___ > ____|
// \/ \/|__| \/ \/ \/\/
// DeployKey represents deploy key information and its relation with repository.
type DeployKey struct {
ID int64 `xorm:"pk autoincr"`
KeyID int64 `xorm:"UNIQUE(s) INDEX"`
RepoID int64 `xorm:"UNIQUE(s) INDEX"`
Name string
Fingerprint string
Created time.Time `xorm:"CREATED"`
Updated time.Time // Note: Updated must below Created for AfterSet.
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
func (k *DeployKey) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created":
k.HasUsed = k.Updated.After(k.Created)
k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
}
func checkDeployKey(e Engine, keyID, repoID int64, name string) error {
// Note: We want error detail, not just true or false here.
has, err := e.Where("key_id=? AND repo_id=?", keyID, repoID).Get(new(DeployKey))
if err != nil {
return err
} else if has {
return ErrDeployKeyAlreadyExist{keyID, repoID}
}
has, err = e.Where("repo_id=? AND name=?", repoID, name).Get(new(DeployKey))
if err != nil {
return err
} else if has {
return ErrDeployKeyNameAlreadyUsed{repoID, name}
}
return nil
}
// addDeployKey adds new key-repo relation.
func addDeployKey(e *xorm.Session, keyID, repoID int64, name, fingerprint string) (err error) {
if err = checkDeployKey(e, keyID, repoID, name); err != nil {
return err
}
_, err = e.Insert(&DeployKey{
KeyID: keyID,
RepoID: repoID,
Name: name,
Fingerprint: fingerprint,
})
return err
}
// HasDeployKey returns true if public key is a deploy key of given repository.
func HasDeployKey(keyID, repoID int64) bool {
has, _ := x.Where("key_id=? AND repo_id=?", keyID, repoID).Get(new(DeployKey))
return has
}
// AddDeployKey add new deploy key to database and authorized_keys file.
func AddDeployKey(repoID int64, name, content string) (err error) {
if err = checkKeyContent(content); err != nil {
return err
}
key := &PublicKey{
Content: content,
Mode: ACCESS_MODE_READ,
Type: KEY_TYPE_DEPLOY,
}
has, err := x.Get(key)
if err != nil {
return err
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
// First time use this deploy key.
if !has {
if err = addKey(sess, key); err != nil {
return nil
}
}
if err = addDeployKey(sess, key.ID, repoID, name, key.Fingerprint); err != nil {
return err
}
return sess.Commit()
}
// GetDeployKeyByRepo returns deploy key by given public key ID and repository ID.
func GetDeployKeyByRepo(keyID, repoID int64) (*DeployKey, error) {
key := &DeployKey{
KeyID: keyID,
RepoID: repoID,
}
_, err := x.Get(key)
return key, err
}
// UpdateDeployKey updates deploy key information.
func UpdateDeployKey(key *DeployKey) error {
_, err := x.Id(key.ID).AllCols().Update(key)
return err
}
// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
func DeleteDeployKey(id int64) error {
key := &DeployKey{ID: id}
has, err := x.Id(key.ID).Get(key)
if err != nil {
return err
} else if !has {
return nil
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Id(key.ID).Delete(key); err != nil {
return fmt.Errorf("delete deploy key[%d]: %v", key.ID, err)
}
// Check if this is the last reference to same key content.
has, err = sess.Where("key_id=?", key.KeyID).Get(new(DeployKey))
if err != nil {
return err
} else if !has {
if err = deletePublicKey(sess, &PublicKey{ID: key.KeyID}); err != nil {
return err
}
}
return sess.Commit()
}
// ListDeployKeys returns all deploy keys by given repository ID.
func ListDeployKeys(repoID int64) ([]*DeployKey, error) {
keys := make([]*DeployKey, 0, 5)
return keys, x.Where("repo_id=?", repoID).Find(&keys)
}

@ -21,6 +21,7 @@ import (
"github.com/Unknwon/cae/zip"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata"
@ -35,12 +36,11 @@ const (
)
var (
ErrRepoAlreadyExist = errors.New("Repository already exist")
ErrRepoFileNotExist = errors.New("Repository file does not exist")
ErrRepoNameIllegal = errors.New("Repository name contains illegal characters")
ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
ErrMirrorNotExist = errors.New("Mirror does not exist")
ErrInvalidReference = errors.New("Invalid reference specified")
ErrNameEmpty = errors.New("Name is empty")
)
var (
@ -222,13 +222,17 @@ func (repo *Repository) DescriptionHtml() template.HTML {
return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize))
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
func IsRepositoryExist(u *User, repoName string) bool {
has, _ := x.Get(&Repository{
func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) {
has, err := e.Get(&Repository{
OwnerId: u.Id,
LowerName: strings.ToLower(repoName),
})
return has && com.IsDir(RepoPath(u.Name, repoName))
return has && com.IsDir(RepoPath(u.Name, repoName)), err
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
func IsRepositoryExist(u *User, repoName string) (bool, error) {
return isRepositoryExist(x, u, repoName)
}
// CloneLink represents different types of clone URLs of repository.
@ -243,34 +247,42 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil {
return cl, err
}
if setting.SSHPort != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.LowerName, repo.LowerName)
}
cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName)
return cl, nil
}
var (
illegalEquals = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
illegalSuffixs = []string{".git", ".keys"}
reservedNames = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
reservedPatterns = []string{"*.git", "*.keys"}
)
// IsLegalName returns false if name contains illegal characters.
func IsLegalName(repoName string) bool {
repoName = strings.ToLower(repoName)
for _, char := range illegalEquals {
if repoName == char {
return false
// IsUsableName checks if name is reserved or pattern of name is not allowed.
func IsUsableName(name string) error {
name = strings.TrimSpace(strings.ToLower(name))
if utf8.RuneCountInString(name) == 0 {
return ErrNameEmpty
}
for i := range reservedNames {
if name == reservedNames[i] {
return ErrNameReserved{name}
}
}
for _, char := range illegalSuffixs {
if strings.HasSuffix(repoName, char) {
return false
for _, pat := range reservedPatterns {
if pat[0] == '*' && strings.HasSuffix(name, pat[1:]) ||
(pat[len(pat)-1] == '*' && strings.HasPrefix(name, pat[:len(pat)-1])) {
return ErrNamePatternNotAllowed{pat}
}
}
return true
return nil
}
// Mirror represents a mirror information of repository.
@ -365,13 +377,22 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
// FIXME: this command could for both migrate and mirror
_, stderr, err := process.ExecTimeout(10*time.Minute,
fmt.Sprintf("MigrateRepository: %s", repoPath),
"git", "clone", "--mirror", "--bare", url, repoPath)
"git", "clone", "--mirror", "--bare", "--quiet", url, repoPath)
if err != nil {
return repo, fmt.Errorf("git clone --mirror --bare: %v", stderr)
return repo, fmt.Errorf("git clone --mirror --bare --quiet: %v", stderr)
} else if err = createUpdateHook(repoPath); err != nil {
return repo, fmt.Errorf("create update hook: %v", err)
}
// Check if repository has master branch, if so set it to default branch.
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
return repo, fmt.Errorf("open git repository: %v", err)
}
if gitRepo.IsBranchExist("master") {
repo.DefaultBranch = "master"
}
return repo, UpdateRepository(repo, false)
}
@ -406,13 +427,18 @@ func createUpdateHook(repoPath string) error {
// InitRepository initializes README and .gitignore if needed.
func initRepository(e Engine, repoPath string, u *User, repo *Repository, initReadme bool, repoLang, license string) error {
// Somehow the directory could exist.
if com.IsExist(repoPath) {
return fmt.Errorf("initRepository: path already exists: %s", repoPath)
}
// Init bare new repository.
os.MkdirAll(repoPath, os.ModePerm)
_, stderr, err := process.ExecDir(-1, repoPath,
fmt.Sprintf("initRepository(git init --bare): %s", repoPath),
"git", "init", "--bare")
if err != nil {
return errors.New("git init --bare: " + stderr)
return fmt.Errorf("git init --bare: %s", err)
}
if err := createUpdateHook(repoPath); err != nil {
@ -434,6 +460,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
// Clone to temprory path and do the init commit.
tmpDir := filepath.Join(os.TempDir(), com.ToStr(time.Now().Nanosecond()))
os.MkdirAll(tmpDir, os.ModePerm)
defer os.RemoveAll(tmpDir)
_, stderr, err = process.Exec(
fmt.Sprintf("initRepository(git clone): %s", repoPath),
@ -464,7 +491,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
}
} else if com.IsSliceContainsStr(Gitignores, repoLang) {
if err = ioutil.WriteFile(targetPath,
bindata.MustAsset(path.Join("conf/gitignore", repoLang)), os.ModePerm); err != nil {
bindata.MustAsset(path.Join("conf/gitignore", repoLang)), 0644); err != nil {
return fmt.Errorf("generate gitignore: %v", err)
}
} else {
@ -480,7 +507,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
}
} else if com.IsSliceContainsStr(Licenses, license) {
if err = ioutil.WriteFile(targetPath,
bindata.MustAsset(path.Join("conf/license", license)), os.ModePerm); err != nil {
bindata.MustAsset(path.Join("conf/license", license)), 0644); err != nil {
return fmt.Errorf("generate license: %v", err)
}
} else {
@ -502,16 +529,50 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
return initRepoCommit(tmpDir, u.NewGitSig())
}
// CreateRepository creates a repository for given user or organization.
func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) {
if !IsLegalName(name) {
return nil, ErrRepoNameIllegal
func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
if err = IsUsableName(repo.Name); err != nil {
return err
}
if IsRepositoryExist(u, name) {
return nil, ErrRepoAlreadyExist
has, err := isRepositoryExist(e, u, repo.Name)
if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{u.Name, repo.Name}
}
if _, err = e.Insert(repo); err != nil {
return err
} else if _, err = e.Exec("UPDATE `user` SET num_repos=num_repos+1 WHERE id=?", u.Id); err != nil {
return err
}
// Give access to all members in owner team.
if u.IsOrganization() {
t, err := u.getOwnerTeam(e)
if err != nil {
return fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(e, repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
}
} else {
// Organization automatically called this in addRepository method.
if err = repo.recalculateAccesses(e); err != nil {
return fmt.Errorf("recalculateAccesses: %v", err)
}
}
if err = watchRepo(e, u.Id, repo.Id, true); err != nil {
return fmt.Errorf("watchRepo: %v", err)
} else if err = newRepoAction(e, u, repo); err != nil {
return fmt.Errorf("newRepoAction: %v", err)
}
return nil
}
// CreateRepository creates a repository for given user or organization.
func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) {
repo := &Repository{
OwnerId: u.Id,
Owner: u,
@ -527,35 +588,10 @@ func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMi
return nil, err
}
if _, err = sess.Insert(repo); err != nil {
return nil, err
} else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
if err = createRepository(sess, u, repo); err != nil {
return nil, err
}
// TODO fix code for mirrors?
// Give access to all members in owner team.
if u.IsOrganization() {
t, err := u.getOwnerTeam(sess)
if err != nil {
return nil, fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(sess, repo); err != nil {
return nil, fmt.Errorf("addRepository: %v", err)
}
} else {
// Organization called this in addRepository method.
if err = repo.recalculateAccesses(sess); err != nil {
return nil, fmt.Errorf("recalculateAccesses: %v", err)
}
}
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
return nil, fmt.Errorf("watchRepo: %v", err)
} else if err = newRepoAction(sess, u, repo); err != nil {
return nil, fmt.Errorf("newRepoAction: %v", err)
}
// No need for init mirror.
if !isMirror {
repoPath := RepoPath(u.Name, repo.Name)
@ -599,7 +635,7 @@ func GetRepositoriesWithUsers(num, offset int) ([]*Repository, error) {
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
return nil, ErrUserNotExist{repo.OwnerId, ""}
}
}
@ -619,8 +655,11 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
}
// Check if new owner has repository with same name.
if IsRepositoryExist(newOwner, repo.Name) {
return ErrRepoAlreadyExist
has, err := IsRepositoryExist(newOwner, repo.Name)
if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{newOwnerName, repo.Name}
}
sess := x.NewSession()
@ -727,16 +766,22 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
}
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) {
userName = strings.ToLower(userName)
func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) {
oldRepoName = strings.ToLower(oldRepoName)
newRepoName = strings.ToLower(newRepoName)
if !IsLegalName(newRepoName) {
return ErrRepoNameIllegal
if err = IsUsableName(newRepoName); err != nil {
return err
}
has, err := IsRepositoryExist(u, newRepoName)
if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{u.Name, newRepoName}
}
// Change repository directory name.
return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName))
return os.Rename(RepoPath(u.LowerName, oldRepoName), RepoPath(u.LowerName, newRepoName))
}
func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
@ -833,7 +878,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err
} else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil {
return err
} else if _, err = sess.Delete(&Milestone{RepoId: repoID}); err != nil {
} else if _, err = sess.Delete(&Milestone{RepoID: repoID}); err != nil {
return err
} else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil {
return err
@ -847,12 +892,12 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err
}
for i := range issues {
if _, err = sess.Delete(&Comment{IssueId: issues[i].Id}); err != nil {
if _, err = sess.Delete(&Comment{IssueId: issues[i].ID}); err != nil {
return err
}
}
if _, err = sess.Delete(&Issue{RepoId: repoID}); err != nil {
if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil {
return err
}
@ -1008,6 +1053,7 @@ var (
// Prevent duplicate tasks.
isMirrorUpdating = false
isGitFscking = false
isCheckingRepos = false
)
// MirrorUpdate checks and updates mirror repositories.
@ -1029,7 +1075,7 @@ func MirrorUpdate() {
repoPath := filepath.Join(setting.RepoRootPath, m.RepoName+".git")
if _, stderr, err := process.ExecDir(10*time.Minute,
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
"git", "remote", "update"); err != nil {
"git", "remote", "update", "--prune"); err != nil {
desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil {
@ -1099,6 +1145,42 @@ func GitGcRepos() error {
})
}
func CheckRepoStats() {
if isCheckingRepos {
return
}
isCheckingRepos = true
defer func() { isCheckingRepos = false }()
// Check count watchers
results_watch, err := x.Query("SELECT r.id FROM `repository` r WHERE r.num_watches!=(SELECT count(*) FROM `watch` WHERE repo_id=r.id)")
if err != nil {
log.Error(4, "select repository check 'watch': %v", err)
}
for _, repo_id := range results_watch {
log.Info("updating repository count 'watch'")
repoID := com.StrTo(repo_id["id"]).MustInt64()
_, err := x.Exec("UPDATE `repository` SET num_watches=(SELECT count(*) FROM `watch` WHERE repo_id=?) WHERE id=?", repoID, repoID)
if err != nil {
log.Error(4, "update repository check 'watch', repo %v: %v", repo_id, err)
}
}
// Check count stars
results_star, err := x.Query("SELECT s.id FROM `repository` s WHERE s.num_stars!=(SELECT count(*) FROM `star` WHERE repo_id=s.id)")
if err != nil {
log.Error(4, "select repository check 'star': %v", err)
}
for _, repo_id := range results_star {
log.Info("updating repository count 'star'")
repoID := com.StrTo(repo_id["id"]).MustInt64()
_, err := x.Exec("UPDATE `repository` SET .num_stars=(SELECT count(*) FROM `star` WHERE repo_id=?) WHERE id=?", repoID, repoID)
if err != nil {
log.Error(4, "update repository check 'star', repo %v: %v", repo_id, err)
}
}
}
// _________ .__ .__ ___. __ .__
// \_ ___ \ ____ | | | | _____ \_ |__ ________________ _/ |_|__| ____ ____
// / \ \/ / _ \| | | | \__ \ | __ \ / _ \_ __ \__ \\ __\ |/ _ \ / \
@ -1339,19 +1421,14 @@ func IsStaring(uid, repoId int64) bool {
// \___ / \____/|__| |__|_ \
// \/ \/
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
if IsRepositoryExist(u, name) {
return nil, ErrRepoAlreadyExist
}
// In case the old repository is a fork.
if oldRepo.IsFork {
oldRepo, err = GetRepositoryById(oldRepo.ForkId)
if err != nil {
return nil, err
}
}
// HasForkedRepo checks if given user has already forked a repository with given ID.
func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
repo := new(Repository)
has, _ := x.Where("owner_id=? AND fork_id=?", ownerID, repoID).Get(repo)
return repo, has
}
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
repo := &Repository{
OwnerId: u.Id,
Owner: u,
@ -1369,32 +1446,8 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
return nil, err
}
if _, err = sess.Insert(repo); err != nil {
return nil, err
}
if err = repo.recalculateAccesses(sess); err != nil {
if err = createRepository(sess, u, repo); err != nil {
return nil, err
} else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
return nil, err
}
if u.IsOrganization() {
// Update owner team info and count.
t, err := u.getOwnerTeam(sess)
if err != nil {
return nil, fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(sess, repo); err != nil {
return nil, fmt.Errorf("addRepository: %v", err)
}
} else {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
return nil, fmt.Errorf("watchRepo: %v", err)
}
}
if err = newRepoAction(sess, u, repo); err != nil {
return nil, fmt.Errorf("newRepoAction: %v", err)
}
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.Id); err != nil {

@ -36,10 +36,7 @@ const (
)
var (
ErrUserAlreadyExist = errors.New("User already exist")
ErrUserNotExist = errors.New("User does not exist")
ErrUserNotKeyOwner = errors.New("User does not the owner of public key")
ErrEmailAlreadyUsed = errors.New("E-mail already used")
ErrEmailNotExist = errors.New("E-mail does not exist")
ErrEmailNotActivated = errors.New("E-mail address has not been activated")
ErrUserNameIllegal = errors.New("User name contains illegal characters")
@ -145,8 +142,8 @@ func (u *User) EncodePasswd() {
u.Passwd = fmt.Sprintf("%x", newPasswd)
}
// ValidtePassword checks if given password matches the one belongs to the user.
func (u *User) ValidtePassword(passwd string) bool {
// ValidatePassword checks if given password matches the one belongs to the user.
func (u *User) ValidatePassword(passwd string) bool {
newUser := &User{Passwd: passwd, Salt: u.Salt}
newUser.EncodePasswd()
return u.Passwd == newUser.Passwd
@ -261,6 +258,8 @@ func IsEmailUsed(email string) (bool, error) {
if len(email) == 0 {
return false, nil
}
email = strings.ToLower(email)
if has, err := x.Get(&EmailAddress{Email: email}); has || err != nil {
return has, err
}
@ -273,23 +272,23 @@ func GetUserSalt() string {
}
// CreateUser creates record of a new user.
func CreateUser(u *User) error {
if !IsLegalName(u.Name) {
return ErrUserNameIllegal
func CreateUser(u *User) (err error) {
if err = IsUsableName(u.Name); err != nil {
return err
}
isExist, err := IsUserExist(0, u.Name)
if err != nil {
return err
} else if isExist {
return ErrUserAlreadyExist
return ErrUserAlreadyExist{u.Name}
}
isExist, err = IsEmailUsed(u.Email)
if err != nil {
return err
} else if isExist {
return ErrEmailAlreadyUsed
return ErrEmailAlreadyUsed{u.Email}
}
u.LowerName = strings.ToLower(u.Name)
@ -315,19 +314,23 @@ func CreateUser(u *User) error {
return err
}
// Auto-set admin for user whose ID is 1.
if u.Id == 1 {
// Auto-set admin for the first user.
if CountUsers() == 1 {
u.IsAdmin = true
u.IsActive = true
_, err = x.Id(u.Id).UseBool().Update(u)
_, err = x.Id(u.Id).AllCols().Update(u)
}
return err
}
func countUsers(e Engine) int64 {
count, _ := e.Where("type=0").Count(new(User))
return count
}
// CountUsers returns number of users.
func CountUsers() int64 {
count, _ := x.Where("type=0").Count(new(User))
return count
return countUsers(x)
}
// GetUsers returns given number of user objects with offset.
@ -392,8 +395,15 @@ func VerifyActiveEmailCode(code, email string) *EmailAddress {
// ChangeUserName changes all corresponding setting from old user name to new one.
func ChangeUserName(u *User, newUserName string) (err error) {
if !IsLegalName(newUserName) {
return ErrUserNameIllegal
if err = IsUsableName(newUserName); err != nil {
return err
}
isExist, err := IsUserExist(0, newUserName)
if err != nil {
return err
} else if isExist {
return ErrUserAlreadyExist{newUserName}
}
return os.Rename(UserPath(u.LowerName), UserPath(newUserName))
@ -401,11 +411,12 @@ func ChangeUserName(u *User, newUserName string) (err error) {
// UpdateUser updates user's information.
func UpdateUser(u *User) error {
u.Email = strings.ToLower(u.Email)
has, err := x.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
if err != nil {
return err
} else if has {
return ErrEmailAlreadyUsed
return ErrEmailAlreadyUsed{u.Email}
}
u.LowerName = strings.ToLower(u.Name)
@ -498,7 +509,7 @@ func DeleteUser(u *User) error {
// Delete all SSH keys.
keys := make([]*PublicKey, 0, 10)
if err = sess.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
if err = sess.Find(&keys, &PublicKey{OwnerID: u.Id}); err != nil {
return err
}
for _, key := range keys {
@ -550,7 +561,7 @@ func getUserById(e Engine, id int64) (*User, error) {
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
return nil, ErrUserNotExist{id, ""}
}
return u, nil
}
@ -563,14 +574,14 @@ func GetUserById(id int64) (*User, error) {
// GetUserByName returns user by given name.
func GetUserByName(name string) (*User, error) {
if len(name) == 0 {
return nil, ErrUserNotExist
return nil, ErrUserNotExist{0, name}
}
u := &User{LowerName: strings.ToLower(name)}
has, err := x.Get(u)
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
return nil, ErrUserNotExist{0, name}
}
return u, nil
}
@ -637,11 +648,12 @@ func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
}
func AddEmailAddress(email *EmailAddress) error {
email.Email = strings.ToLower(email.Email)
used, err := IsEmailUsed(email.Email)
if err != nil {
return err
} else if used {
return ErrEmailAlreadyUsed
return ErrEmailAlreadyUsed{email.Email}
}
_, err = x.Insert(email)
@ -670,7 +682,7 @@ func DeleteEmailAddress(email *EmailAddress) error {
return ErrEmailNotExist
}
if _, err = x.Delete(email); err != nil {
if _, err = x.Id(email.Id).Delete(email); err != nil {
return err
}
@ -695,7 +707,7 @@ func MakeEmailPrimary(email *EmailAddress) error {
if err != nil {
return err
} else if !has {
return ErrUserNotExist
return ErrUserNotExist{email.Uid, ""}
}
// Make sure the former primary email doesn't disappear
@ -732,13 +744,15 @@ func ValidateCommitWithEmail(c *git.Commit) *User {
// ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
emails := map[string]*User{}
newCommits := list.New()
e := oldCommits.Front()
var (
u *User
emails = map[string]*User{}
newCommits = list.New()
e = oldCommits.Front()
)
for e != nil {
c := e.Value.(*git.Commit)
var u *User
if v, ok := emails[c.Author.Email]; !ok {
u, _ = GetUserByEmail(c.Author.Email)
emails[c.Author.Email] = u
@ -758,10 +772,12 @@ func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
// GetUserByEmail returns the user object by given e-mail if exists.
func GetUserByEmail(email string) (*User, error) {
if len(email) == 0 {
return nil, ErrUserNotExist
return nil, ErrUserNotExist{0, "email"}
}
email = strings.ToLower(email)
// First try to find the user by primary email
user := &User{Email: strings.ToLower(email)}
user := &User{Email: email}
has, err := x.Get(user)
if err != nil {
return nil, err
@ -771,7 +787,7 @@ func GetUserByEmail(email string) (*User, error) {
}
// Otherwise, check in alternative list for activated email addresses
emailAddress := &EmailAddress{Email: strings.ToLower(email), IsActivated: true}
emailAddress := &EmailAddress{Email: email, IsActivated: true}
has, err = x.Get(emailAddress)
if err != nil {
return nil, err
@ -780,7 +796,7 @@ func GetUserByEmail(email string) (*User, error) {
return GetUserById(emailAddress.Uid)
}
return nil, ErrUserNotExist
return nil, ErrUserNotExist{0, "email"}
}
// SearchUserByName returns given number of users whose name contains keyword.

@ -9,6 +9,7 @@ import (
"encoding/json"
"errors"
"io/ioutil"
"sync"
"time"
"github.com/gogits/gogs/modules/httplib"
@ -259,7 +260,9 @@ func (p Payload) GetJSONPayload() ([]byte, error) {
// HookTask represents a hook task.
type HookTask struct {
Id int64
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
HookID int64
Uuid string
Type HookTaskType
Url string
@ -269,6 +272,7 @@ type HookTask struct {
EventType HookEventType
IsSsl bool
IsDelivered bool
Delivered int64
IsSucceed bool
}
@ -287,87 +291,137 @@ func CreateHookTask(t *HookTask) error {
// UpdateHookTask updates information of hook task.
func UpdateHookTask(t *HookTask) error {
_, err := x.Id(t.Id).AllCols().Update(t)
_, err := x.Id(t.ID).AllCols().Update(t)
return err
}
var (
// Prevent duplicate deliveries.
// This happens with massive hook tasks cannot finish delivering
// before next shooting starts.
isShooting = false
)
type hookQueue struct {
// Make sure one repository only occur once in the queue.
lock sync.Mutex
repoIDs map[int64]bool
// DeliverHooks checks and delivers undelivered hooks.
// FIXME: maybe can use goroutine to shoot a number of them at same time?
func DeliverHooks() {
if isShooting {
queue chan int64
}
func (q *hookQueue) removeRepoID(id int64) {
q.lock.Lock()
defer q.lock.Unlock()
delete(q.repoIDs, id)
}
func (q *hookQueue) addRepoID(id int64) {
q.lock.Lock()
if q.repoIDs[id] {
q.lock.Unlock()
return
}
isShooting = true
defer func() { isShooting = false }()
q.repoIDs[id] = true
q.lock.Unlock()
q.queue <- id
}
tasks := make([]*HookTask, 0, 10)
// AddRepoID adds repository ID to hook delivery queue.
func (q *hookQueue) AddRepoID(id int64) {
go q.addRepoID(id)
}
var HookQueue *hookQueue
func deliverHook(t *HookTask) {
timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Header("X-Gogs-Delivery", t.Uuid).
Header("X-Gogs-Event", string(t.EventType)).
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
switch t.ContentType {
case JSON:
req = req.Header("Content-Type", "application/json").Body(t.PayloadContent)
case FORM:
req.Param("payload", t.PayloadContent)
}
req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Header("X-Gogs-Delivery", t.Uuid).
Header("X-Gogs-Event", string(t.EventType)).
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
t.IsDelivered = true
switch t.ContentType {
case JSON:
req = req.Header("Content-Type", "application/json").Body(t.PayloadContent)
case FORM:
req.Param("payload", t.PayloadContent)
}
// FIXME: record response.
switch t.Type {
case GOGS:
{
if _, err := req.Response(); err != nil {
log.Error(5, "Delivery: %v", err)
t.IsDelivered = true
// FIXME: record response.
switch t.Type {
case GOGS:
{
if resp, err := req.Response(); err != nil {
log.Error(5, "Delivery: %v", err)
} else {
resp.Body.Close()
t.IsSucceed = true
}
}
case SLACK:
{
if resp, err := req.Response(); err != nil {
log.Error(5, "Delivery: %v", err)
} else {
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error(5, "%s", err)
} else {
if string(contents) != "ok" {
log.Error(5, "slack failed with: %s", string(contents))
} else {
t.IsSucceed = true
}
}
case SLACK:
{
if res, err := req.Response(); err != nil {
log.Error(5, "Delivery: %v", err)
} else {
defer res.Body.Close()
contents, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Error(5, "%s", err)
} else {
if string(contents) != "ok" {
log.Error(5, "slack failed with: %s", string(contents))
} else {
t.IsSucceed = true
}
}
}
}
}
}
}
tasks = append(tasks, t)
t.Delivered = time.Now().UTC().UnixNano()
if t.IsSucceed {
log.Trace("Hook delivered(%s): %s", t.Uuid, t.PayloadContent)
}
}
if t.IsSucceed {
log.Trace("Hook delivered(%s): %s", t.Uuid, t.PayloadContent)
}
// DeliverHooks checks and delivers undelivered hooks.
func DeliverHooks() {
tasks := make([]*HookTask, 0, 10)
x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
deliverHook(t)
tasks = append(tasks, t)
return nil
})
// Update hook task status.
for _, t := range tasks {
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask(%d): %v", t.Id, err)
log.Error(4, "UpdateHookTask(%d): %v", t.ID, err)
}
}
HookQueue = &hookQueue{
lock: sync.Mutex{},
repoIDs: make(map[int64]bool),
queue: make(chan int64, setting.Webhook.QueueLength),
}
// Start listening on new hook requests.
for repoID := range HookQueue.queue {
HookQueue.removeRepoID(repoID)
tasks = make([]*HookTask, 0, 5)
if err := x.Where("repo_id=? AND is_delivered=?", repoID, false).Find(&tasks); err != nil {
log.Error(4, "Get repository(%d) hook tasks: %v", repoID, err)
continue
}
for _, t := range tasks {
deliverHook(t)
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask(%d): %v", t.ID, err)
}
}
}
}
func InitDeliverHooks() {
go DeliverHooks()
}

@ -11,6 +11,7 @@ import (
)
type AdminEditUserForm struct {
FullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `binding:"Required;Email;MaxSize(50)"`
Password string `binding:"OmitEmpty;MinSize(6);MaxSize(255)"`
Website string `binding:"MaxSize(50)"`

@ -21,6 +21,10 @@ import (
"github.com/gogits/gogs/modules/uuid"
)
func IsAPIPath(url string) bool {
return strings.HasPrefix(url, "/api/")
}
// SignedInId returns the id of signed in user.
func SignedInId(req *http.Request, sess session.Store) int64 {
if !models.HasEngine {
@ -28,7 +32,7 @@ func SignedInId(req *http.Request, sess session.Store) int64 {
}
// API calls need to check access token.
if strings.HasPrefix(req.URL.Path, "/api/") {
if IsAPIPath(req.URL.Path) {
auHead := req.Header.Get("Authorization")
if len(auHead) > 0 {
auths := strings.Fields(auHead)
@ -51,7 +55,7 @@ func SignedInId(req *http.Request, sess session.Store) int64 {
}
if id, ok := uid.(int64); ok {
if _, err := models.GetUserById(id); err != nil {
if err != models.ErrUserNotExist {
if !models.IsErrUserNotExist(err) {
log.Error(4, "GetUserById: %v", err)
}
return 0
@ -76,7 +80,7 @@ func SignedInUser(req *http.Request, sess session.Store) (*models.User, bool) {
if len(webAuthUser) > 0 {
u, err := models.GetUserByName(webAuthUser)
if err != nil {
if err != models.ErrUserNotExist {
if !models.IsErrUserNotExist(err) {
log.Error(4, "GetUserByName: %v", err)
return nil, false
}
@ -111,7 +115,7 @@ func SignedInUser(req *http.Request, sess session.Store) (*models.User, bool) {
u, err := models.UserSignIn(uname, passwd)
if err != nil {
if err != models.ErrUserNotExist {
if !models.IsErrUserNotExist(err) {
log.Error(4, "UserSignIn: %v", err)
}
return nil, false
@ -167,12 +171,16 @@ func AssignForm(form interface{}, data map[string]interface{}) {
func getSize(field reflect.StructField, prefix string) string {
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
if strings.HasPrefix(rule, prefix) {
return rule[8 : len(rule)-1]
return rule[len(prefix) : len(rule)-1]
}
}
return ""
}
func GetSize(field reflect.StructField) string {
return getSize(field, "Size(")
}
func GetMinSize(field reflect.StructField) string {
return getSize(field, "MinSize(")
}
@ -208,7 +216,14 @@ func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaro
if errs[0].FieldNames[0] == field.Name {
data["Err_"+field.Name] = true
trName := l.Tr("form." + field.Name)
trName := field.Tag.Get("locale")
if len(trName) == 0 {
trName = l.Tr("form." + field.Name)
} else {
trName = l.Tr(trName)
}
switch errs[0].Classification {
case binding.ERR_REQUIRED:
data["ErrorMsg"] = trName + l.Tr("form.require_error")
@ -216,6 +231,8 @@ func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaro
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
case binding.ERR_ALPHA_DASH_DOT:
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
case binding.ERR_SIZE:
data["ErrorMsg"] = trName + l.Tr("form.size_error", GetSize(field))
case binding.ERR_MIN_SIZE:
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))
case binding.ERR_MAX_SIZE:

@ -30,6 +30,7 @@ type AuthenticationForm struct {
SMTPPort int `form:"smtp_port"`
TLS bool `form:"tls"`
AllowAutoRegister bool `form:"allowautoregister"`
PAMServiceName string
}
func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

@ -26,7 +26,7 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) bind
}
type UpdateOrgSettingForm struct {
OrgUserName string `form:"uname" binding:"Required;MaxSize(35)"`
OrgUserName string `form:"uname" binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Description string `form:"desc" binding:"MaxSize(255)"`

@ -0,0 +1,35 @@
// +build pam
// 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 pam
import (
"errors"
"github.com/msteinert/pam"
)
func PAMAuth(serviceName, userName, passwd string) error {
t, err := pam.StartFunc(serviceName, userName, func(s pam.Style, msg string) (string, error) {
switch s {
case pam.PromptEchoOff:
return passwd, nil
case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo:
return "", nil
}
return "", errors.New("Unrecognized PAM message style")
})
if err != nil {
return err
}
if err = t.Authenticate(0); err != nil {
return err
}
return nil
}

@ -0,0 +1,15 @@
// +build !pam
// 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 pam
import (
"errors"
)
func PAMAuth(serviceName, userName, passwd string) error {
return errors.New("PAM not supported")
}

@ -117,9 +117,9 @@ func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
// \/ \/ \/ \/ \/
type CreateMilestoneForm struct {
Title string `form:"title" binding:"Required;MaxSize(50)"`
Content string `form:"content"`
Deadline string `form:"due_date"`
Title string `binding:"Required;MaxSize(50)"`
Content string
Deadline string
}
func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
@ -134,8 +134,9 @@ func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors
// \/ \/ \/ \/
type CreateLabelForm struct {
Title string `form:"title" binding:"Required;MaxSize(50)"`
Color string `form:"color" binding:"Required;Size(7)"`
ID int64
Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_name"`
Color string `binding:"Required;Size(7)" locale:"repo.issues.label_color"`
}
func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

@ -12,27 +12,36 @@ import (
)
type InstallForm struct {
DbType string `binding:"Required"`
DbHost string
DbUser string
DbPasswd string
DbName string
SSLMode string
DbPath string
RepoRootPath string `binding:"Required"`
RunUser string `binding:"Required"`
Domain string `binding:"Required"`
HTTPPort string `binding:"Required"`
AppUrl string `binding:"Required"`
SMTPHost string
SMTPEmail string
SMTPPasswd string
RegisterConfirm string
MailNotify string
AdminName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
AdminPasswd string `binding:"Required;MinSize(6);MaxSize(255)"`
AdminConfirmPasswd string `binding:"Required;MinSize(6);MaxSize(255)"`
AdminEmail string `binding:"Required;Email;MaxSize(50)"`
DbType string `binding:"Required"`
DbHost string
DbUser string
DbPasswd string
DbName string
SSLMode string
DbPath string
AppName string `binding:"Required" locale:"install.app_name"`
RepoRootPath string `binding:"Required"`
RunUser string `binding:"Required"`
Domain string `binding:"Required"`
HTTPPort string `binding:"Required"`
AppUrl string `binding:"Required"`
SMTPHost string
SMTPFrom string
SMTPEmail string `binding:"OmitEmpty;Email;MaxSize(50)" locale:"install.mailer_user"`
SMTPPasswd string
RegisterConfirm bool
MailNotify bool
OfflineMode bool
DisableRegistration bool
RequireSignInView bool
AdminName string `binding:"OmitEmpty;AlphaDashDot;MaxSize(30)" locale:"install.admin_name"`
AdminPasswd string `binding:"OmitEmpty;MinSize(6);MaxSize(255)" locale:"install.admin_password"`
AdminConfirmPasswd string
AdminEmail string `binding:"OmitEmpty;Email;MaxSize(50)" locale:"install.admin_email"`
}
func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
@ -107,7 +116,7 @@ func (f *AddEmailForm) Validate(ctx *macaron.Context, errs binding.Errors) bindi
}
type ChangePasswordForm struct {
OldPassword string `form:"old_password" binding:"Required;MinSize(6);MaxSize(255)"`
OldPassword string `form:"old_password" binding:"Required;MinSize(1);MaxSize(255)"`
Password string `form:"password" binding:"Required;MinSize(6);MaxSize(255)"`
Retype string `form:"retype"`
}
@ -117,8 +126,8 @@ func (f *ChangePasswordForm) Validate(ctx *macaron.Context, errs binding.Errors)
}
type AddSSHKeyForm struct {
SSHTitle string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Title string `binding:"Required;MaxSize(50)"`
Content string `binding:"Required"`
}
func (f *AddSSHKeyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

@ -20,6 +20,10 @@ import (
"github.com/gogits/gogs/modules/setting"
)
func Safe(raw string) template.HTML {
return template.HTML(raw)
}
func Str2html(raw string) template.HTML {
return template.HTML(Sanitizer.Sanitize(raw))
}
@ -55,6 +59,9 @@ func ShortSha(sha1 string) string {
func DetectEncoding(content []byte) (string, error) {
detector := chardet.NewTextDetector()
result, err := detector.DetectBest(content)
if result.Charset != "UTF-8" && len(setting.AnsiCharset) > 0 {
return setting.AnsiCharset, err
}
return result.Charset, err
}
@ -64,7 +71,7 @@ func ToUtf8WithErr(content []byte) (error, string) {
return err, ""
}
if charsetLabel == "utf8" {
if charsetLabel == "UTF-8" {
return nil, string(content)
}
@ -125,6 +132,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
},
"AvatarLink": AvatarLink,
"Safe": Safe,
"Str2html": Str2html,
"TimeSince": TimeSince,
"FileSize": FileSize,
@ -175,7 +183,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
"Oauth2Name": Oauth2Name,
"ToUtf8": ToUtf8,
"EscapePound": func(str string) string {
return strings.Replace(str, "#", "%23", -1)
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
},
"RenderCommitMessage": RenderCommitMessage,
}

File diff suppressed because one or more lines are too long

@ -15,10 +15,10 @@ var c = New()
func NewCronContext() {
c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate)
c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.Webhook.TaskInterval), models.DeliverHooks)
if setting.Git.Fsck.Enable {
c.AddFunc("Repository health check", fmt.Sprintf("@every %dh", setting.Git.Fsck.Interval), models.GitFsck)
}
c.AddFunc("Check repository statistics", "@every 24h", models.CheckRepoStats)
c.Start()
}

@ -27,7 +27,7 @@ func (repo *Repository) GetTags() ([]string, error) {
}
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l")
if err != nil {
return nil, errors.New(stderr)
return nil, concatenateError(err, stderr)
}
tags := strings.Split(stdout, "\n")
return tags[:len(tags)-1], nil

@ -7,6 +7,7 @@ package git
import (
"bytes"
"container/list"
"fmt"
"os"
"path/filepath"
"strings"
@ -67,3 +68,10 @@ func isFile(filePath string) bool {
}
return !f.IsDir()
}
func concatenateError(err error, stderr string) error {
if len(stderr) == 0 {
return err
}
return fmt.Errorf("%v: %s", err, stderr)
}

@ -214,7 +214,11 @@ func (l *Logger) writerMsg(skip, level int, msg string) error {
fnName = strings.TrimLeft(filepath.Ext(fn.Name()), ".") + "()"
}
lm.msg = fmt.Sprintf("[%s:%d %s] %s", filepath.Base(file), line, fnName, msg)
fileName := file
if len(fileName) > 20 {
fileName = "..." + fileName[len(fileName)-20:]
}
lm.msg = fmt.Sprintf("[%s:%d %s] %s", fileName, line, fnName, msg)
} else {
lm.msg = msg
}

@ -104,13 +104,18 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte)
return err
}
hostname, err := os.Hostname()
if err != nil {
return err
}
if !setting.MailService.DisableHelo {
hostname := setting.MailService.HeloHostname
if len(hostname) == 0 {
hostname, err = os.Hostname()
if err != nil {
return err
}
}
if err = client.Hello(hostname); err != nil {
return err
if err = client.Hello(hostname); err != nil {
return err
}
}
// If not using SMTPS, alway use STARTTLS if available

@ -10,6 +10,7 @@ import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/csrf"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/setting"
)
@ -49,6 +50,12 @@ func Toggle(options *ToggleOptions) macaron.Handler {
if options.SignInRequire {
if !ctx.IsSigned {
// Restrict API calls with error message.
if auth.IsAPIPath(ctx.Req.URL.Path) {
ctx.HandleAPI(403, "Only signed in user is allowed to call APIs.")
return
}
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
@ -69,6 +76,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
}
}
// Contexter middleware already checks token for user sign in process.
func ApiReqToken() macaron.Handler {
return func(ctx *Context) {
if !ctx.IsSigned {

@ -106,6 +106,12 @@ func (ctx *Context) HasError() bool {
return hasErr.(bool)
}
// HasValue returns true if value of given name exists.
func (ctx *Context) HasValue(name string) bool {
_, ok := ctx.Data[name]
return ok
}
// HTML calls Context.HTML and converts template name to string.
func (ctx *Context) HTML(status int, name base.TplName) {
ctx.Context.HTML(status, string(name))
@ -139,6 +145,13 @@ func (ctx *Context) Handle(status int, title string, err error) {
ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
}
func (ctx *Context) HandleText(status int, title string) {
if (status/100 == 4) || (status/100 == 5) {
log.Error(4, "%s", title)
}
ctx.RenderData(status, []byte(title))
}
func (ctx *Context) HandleAPI(status int, obj interface{}) {
var message string
if err, ok := obj.(error); ok {

@ -34,7 +34,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
var err error
ctx.Org.Organization, err = models.GetUserByName(orgName)
if err != nil {
if err == models.ErrUserNotExist {
if models.IsErrUserNotExist(err) {
ctx.Handle(404, "GetUserByName", err)
} else if redirect {
log.Error(4, "GetUserByName", err)
@ -47,6 +47,12 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
org := ctx.Org.Organization
ctx.Data["Org"] = org
// Force redirection when username is actually a user.
if !org.IsOrganization() {
ctx.Redirect("/" + org.Name)
return
}
if ctx.IsSigned {
ctx.Org.IsOwner = org.IsOwnedBy(ctx.User.Id)
if ctx.Org.IsOwner {

@ -10,6 +10,8 @@ import (
"strings"
"github.com/Unknwon/macaron"
"github.com/mcuadros/go-version"
"github.com/mssola/user_agent"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
@ -18,6 +20,11 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const (
FIREFOX_COPY_SUPPORT = "41.0"
CHROME_COPY_SUPPORT = "43.0.2356"
)
func ApiRepoAssignment() macaron.Handler {
return func(ctx *Context) {
userName := ctx.Params(":username")
@ -34,7 +41,7 @@ func ApiRepoAssignment() macaron.Handler {
} else {
u, err = models.GetUserByName(userName)
if err != nil {
if err == models.ErrUserNotExist {
if models.IsErrUserNotExist(err) {
ctx.Error(404)
} else {
ctx.JSON(500, &base.ApiJsonErr{"GetUserByName: " + err.Error(), base.DOC_URL})
@ -210,7 +217,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
} else {
u, err = models.GetUserByName(userName)
if err != nil {
if err == models.ErrUserNotExist {
if models.IsErrUserNotExist(err) {
ctx.Handle(404, "GetUserByName", err)
} else {
ctx.Handle(500, "GetUserByName", err)
@ -345,10 +352,17 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["BranchName"] = ctx.Repo.BranchName
ctx.Data["CommitId"] = ctx.Repo.CommitId
userAgent := ctx.Req.Header.Get("User-Agent")
ua := user_agent.New(userAgent)
browserName, browserVer := ua.Browser()
ctx.Data["BrowserSupportsCopy"] = (browserName == "Chrome" && version.Compare(browserVer, CHROME_COPY_SUPPORT, ">=")) ||
(browserName == "Firefox" && version.Compare(browserVer, FIREFOX_COPY_SUPPORT, ">="))
}
}
func RequireAdmin() macaron.Handler {
func RequireRepoAdmin() macaron.Handler {
return func(ctx *Context) {
if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN {
if !ctx.IsSigned {

@ -53,6 +53,7 @@ var (
HttpAddr, HttpPort string
DisableSSH bool
SSHPort int
SSHDomain string
OfflineMode bool
DisableRouterLog bool
CertFile, KeyFile string
@ -75,7 +76,7 @@ var (
// Webhook settings.
Webhook struct {
TaskInterval int
QueueLength int
DeliverTimeout int
SkipTLSVerify bool
}
@ -83,6 +84,10 @@ var (
// Repository settings.
RepoRootPath string
ScriptType string
AnsiCharset string
// UI settings.
IssuePagingNum int
// Picture settings.
PictureService string
@ -129,6 +134,7 @@ var (
// I18n settings.
Langs, Names []string
dateLangs map[string]string
// Other settings.
ShowFooterBranding bool
@ -143,6 +149,14 @@ var (
HasRobotsTxt bool
)
func DateLang(lang string) string {
name, ok := dateLangs[lang]
if ok {
return name
}
return "en"
}
func init() {
IsWindows = runtime.GOOS == "windows"
log.NewLogger(0, "console", `{"level": 0}`)
@ -163,7 +177,18 @@ func ExecPath() (string, error) {
// WorkDir returns absolute path of work directory.
func WorkDir() (string, error) {
execPath, err := ExecPath()
return path.Dir(strings.Replace(execPath, "\\", "/", -1)), err
if err != nil {
return execPath, err
}
// Note: we don't use path.Dir here because it does not handle case
// which path starts with two "/" in Windows: "//psf/Home/..."
execPath = strings.Replace(execPath, "\\", "/", -1)
i := strings.LastIndex(execPath, "/")
if i == -1 {
return execPath, nil
}
return execPath[:i], nil
}
func forcePathSeparator(path string) {
@ -187,11 +212,11 @@ func NewConfigContext() {
CustomPath = os.Getenv("GOGS_CUSTOM")
if len(CustomPath) == 0 {
CustomPath = path.Join(workDir, "custom")
CustomPath = workDir + "/custom"
}
if len(CustomConf) == 0 {
CustomConf = path.Join(CustomPath, "conf/app.ini")
CustomConf = CustomPath + "/conf/app.ini"
}
if com.IsFile(CustomConf) {
@ -232,6 +257,7 @@ func NewConfigContext() {
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HttpPort = sec.Key("HTTP_PORT").MustString("3000")
DisableSSH = sec.Key("DISABLE_SSH").MustBool()
SSHDomain = sec.Key("SSH_DOMAIN").MustString(Domain)
SSHPort = sec.Key("SSH_PORT").MustInt(22)
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
@ -307,6 +333,10 @@ func NewConfigContext() {
RepoRootPath = path.Clean(RepoRootPath)
}
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
AnsiCharset = sec.Key("ANSI_CHARSET").MustString("")
// UI settings.
IssuePagingNum = Cfg.Section("ui").Key("ISSUE_PAGING_NUM").MustInt(10)
sec = Cfg.Section("picture")
PictureService = sec.Key("SERVICE").In("server", []string{"server"})
@ -332,6 +362,7 @@ func NewConfigContext() {
Langs = Cfg.Section("i18n").Key("LANGS").Strings(",")
Names = Cfg.Section("i18n").Key("NAMES").Strings(",")
dateLangs = Cfg.Section("i18n.datelang").KeysHash()
ShowFooterBranding = Cfg.Section("other").Key("SHOW_FOOTER_BRANDING").MustBool()
@ -439,10 +470,10 @@ func newLogService() {
func newCacheService() {
CacheAdapter = Cfg.Section("cache").Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"})
if EnableRedis {
log.Info("Redis Enabled")
log.Info("Redis Supported")
}
if EnableMemcache {
log.Info("Memcache Enabled")
log.Info("Memcache Supported")
}
switch CacheAdapter {
@ -476,6 +507,8 @@ type Mailer struct {
Host string
From string
User, Passwd string
DisableHelo bool
HeloHostname string
SkipVerify bool
UseCertificate bool
CertFile, KeyFile string
@ -510,6 +543,8 @@ func newMailService() {
Host: sec.Key("HOST").String(),
User: sec.Key("USER").String(),
Passwd: sec.Key("PASSWD").String(),
DisableHelo: sec.Key("DISABLE_HELO").MustBool(),
HeloHostname: sec.Key("HELO_HOSTNAME").String(),
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(),
CertFile: sec.Key("CERT_FILE").String(),
@ -543,7 +578,7 @@ func newNotifyMailService() {
func newWebhookService() {
sec := Cfg.Section("webhook")
Webhook.TaskInterval = sec.Key("TASK_INTERVAL").MustInt(1)
Webhook.QueueLength = sec.Key("QUEUE_LENGTH").MustInt(1000)
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
}

@ -18,8 +18,6 @@ case "$1" in
chown ${APP_USER}.${APP_GROUP} $(dirname ${APP_CONFIG})
[ -f ${APP_CONFIG} ] || ${CLI} run cp conf/app.ini ${APP_CONFIG}
${CLI} config:set USER=${APP_USER}
PORT=$(${CLI} config:get PORT || echo "6000")
sed -i "s|HTTP_PORT = 3000|HTTP_PORT = ${PORT}|" ${APP_CONFIG}
sed -i "s|RUN_USER = git|RUN_USER = ${APP_USER}|" ${APP_CONFIG}
sed -i "s|RUN_MODE = dev|RUN_MODE = prod|" ${APP_CONFIG}

@ -1,9 +0,0 @@
/*!
* Bootstrap Colorpicker
* http://mjolnic.github.io/bootstrap-colorpicker/
*
* Originally written by (c) 2012 Stefan Petre
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
*/.colorpicker-saturation{float:left;width:100px;height:100px;cursor:crosshair;background-image:url("../img/bootstrap-colorpicker/saturation.png")}.colorpicker-saturation i{position:absolute;top:0;left:0;display:block;width:5px;height:5px;margin:-4px 0 0 -4px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-saturation i b{display:block;width:5px;height:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-hue,.colorpicker-alpha{float:left;width:15px;height:100px;margin-bottom:4px;margin-left:4px;cursor:row-resize}.colorpicker-hue i,.colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:100%;height:1px;margin-top:-1px;background:#000;border-top:1px solid #fff}.colorpicker-hue{background-image:url("../img/bootstrap-colorpicker/hue.png")}.colorpicker-alpha{display:none;background-image:url("../img/bootstrap-colorpicker/alpha.png")}.colorpicker{top:0;left:0;z-index:2500;min-width:130px;padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1}.colorpicker:before,.colorpicker:after{display:table;line-height:0;content:""}.colorpicker:after{clear:both}.colorpicker:before{position:absolute;top:-7px;left:6px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.colorpicker:after{position:absolute;top:-6px;left:7px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url("../img/bootstrap-colorpicker/alpha.png");background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-element .input-group-addon i,.colorpicker-element .add-on i{display:inline-block;width:16px;height:16px;vertical-align:text-top;cursor:pointer}.colorpicker.colorpicker-inline{position:relative;z-index:auto;display:inline-block;float:none}.colorpicker.colorpicker-horizontal{width:110px;height:auto;min-width:110px}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-hue,.colorpicker.colorpicker-horizontal .colorpicker-alpha{float:left;width:100px;height:15px;margin-bottom:4px;margin-left:0;cursor:col-resize}.colorpicker.colorpicker-horizontal .colorpicker-hue i,.colorpicker.colorpicker-horizontal .colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:1px;height:15px;margin-top:0;background:#fff;border:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url("../img/bootstrap-colorpicker/hue-horizontal.png")}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url("../img/bootstrap-colorpicker/alpha-horizontal.png")}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block}

@ -1,790 +0,0 @@
/*!
* Datepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datepicker {
padding: 4px;
border-radius: 4px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-top: 0;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-top: 0;
position: absolute;
}
.datepicker-dropdown.datepicker-orient-left:before {
left: 6px;
}
.datepicker-dropdown.datepicker-orient-left:after {
left: 7px;
}
.datepicker-dropdown.datepicker-orient-right:before {
right: 6px;
}
.datepicker-dropdown.datepicker-orient-right:after {
right: 7px;
}
.datepicker-dropdown.datepicker-orient-top:before {
top: -7px;
}
.datepicker-dropdown.datepicker-orient-top:after {
top: -6px;
}
.datepicker-dropdown.datepicker-orient-bottom:before {
bottom: -7px;
border-bottom: 0;
border-top: 7px solid #999;
}
.datepicker-dropdown.datepicker-orient-bottom:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #fff;
}
.datepicker > div {
display: none;
}
.datepicker.days div.datepicker-days {
display: block;
}
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.datepicker table tr td,
.datepicker table tr th {
text-align: center;
width: 30px;
height: 30px;
border-radius: 4px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover,
.datepicker table tr td.day.focused {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
color: #000000;
background-color: #ffdb99;
border-color: #ffb733;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:focus,
.datepicker table tr td.today:hover:focus,
.datepicker table tr td.today.disabled:focus,
.datepicker table tr td.today.disabled:hover:focus,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.today,
.open .dropdown-toggle.datepicker table tr td.today:hover,
.open .dropdown-toggle.datepicker table tr td.today.disabled,
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
color: #000000;
background-color: #ffcd70;
border-color: #f59e00;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.today,
.open .dropdown-toggle.datepicker table tr td.today:hover,
.open .dropdown-toggle.datepicker table tr td.today.disabled,
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
background-image: none;
}
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.today,
fieldset[disabled] .datepicker table tr td.today:hover,
fieldset[disabled] .datepicker table tr td.today.disabled,
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today:hover.disabled:hover,
.datepicker table tr td.today.disabled.disabled:hover,
.datepicker table tr td.today.disabled:hover.disabled:hover,
.datepicker table tr td.today[disabled]:hover,
.datepicker table tr td.today:hover[disabled]:hover,
.datepicker table tr td.today.disabled[disabled]:hover,
.datepicker table tr td.today.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.today:hover,
fieldset[disabled] .datepicker table tr td.today:hover:hover,
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today.disabled:focus,
.datepicker table tr td.today:hover.disabled:focus,
.datepicker table tr td.today.disabled.disabled:focus,
.datepicker table tr td.today.disabled:hover.disabled:focus,
.datepicker table tr td.today[disabled]:focus,
.datepicker table tr td.today:hover[disabled]:focus,
.datepicker table tr td.today.disabled[disabled]:focus,
.datepicker table tr td.today.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.today:focus,
fieldset[disabled] .datepicker table tr td.today:hover:focus,
fieldset[disabled] .datepicker table tr td.today.disabled:focus,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today:hover.disabled:active,
.datepicker table tr td.today.disabled.disabled:active,
.datepicker table tr td.today.disabled:hover.disabled:active,
.datepicker table tr td.today[disabled]:active,
.datepicker table tr td.today:hover[disabled]:active,
.datepicker table tr td.today.disabled[disabled]:active,
.datepicker table tr td.today.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.today:active,
fieldset[disabled] .datepicker table tr td.today:hover:active,
fieldset[disabled] .datepicker table tr td.today.disabled:active,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today:hover.disabled.active,
.datepicker table tr td.today.disabled.disabled.active,
.datepicker table tr td.today.disabled:hover.disabled.active,
.datepicker table tr td.today[disabled].active,
.datepicker table tr td.today:hover[disabled].active,
.datepicker table tr td.today.disabled[disabled].active,
.datepicker table tr td.today.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.today.active,
fieldset[disabled] .datepicker table tr td.today:hover.active,
fieldset[disabled] .datepicker table tr td.today.disabled.active,
fieldset[disabled] .datepicker table tr td.today.disabled:hover.active {
background-color: #ffdb99;
border-color: #ffb733;
}
.datepicker table tr td.today:hover:hover {
color: #000;
}
.datepicker table tr td.today.active:hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
color: #000000;
background-color: #f7ca77;
border-color: #f1a417;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:focus,
.datepicker table tr td.range.today:hover:focus,
.datepicker table tr td.range.today.disabled:focus,
.datepicker table tr td.range.today.disabled:hover:focus,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.range.today,
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
color: #000000;
background-color: #f4bb51;
border-color: #bf800c;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.range.today,
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
background-image: none;
}
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.range.today,
fieldset[disabled] .datepicker table tr td.range.today:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today:hover.disabled:hover,
.datepicker table tr td.range.today.disabled.disabled:hover,
.datepicker table tr td.range.today.disabled:hover.disabled:hover,
.datepicker table tr td.range.today[disabled]:hover,
.datepicker table tr td.range.today:hover[disabled]:hover,
.datepicker table tr td.range.today.disabled[disabled]:hover,
.datepicker table tr td.range.today.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.range.today:hover,
fieldset[disabled] .datepicker table tr td.range.today:hover:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today.disabled:focus,
.datepicker table tr td.range.today:hover.disabled:focus,
.datepicker table tr td.range.today.disabled.disabled:focus,
.datepicker table tr td.range.today.disabled:hover.disabled:focus,
.datepicker table tr td.range.today[disabled]:focus,
.datepicker table tr td.range.today:hover[disabled]:focus,
.datepicker table tr td.range.today.disabled[disabled]:focus,
.datepicker table tr td.range.today.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.range.today:focus,
fieldset[disabled] .datepicker table tr td.range.today:hover:focus,
fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today:hover.disabled:active,
.datepicker table tr td.range.today.disabled.disabled:active,
.datepicker table tr td.range.today.disabled:hover.disabled:active,
.datepicker table tr td.range.today[disabled]:active,
.datepicker table tr td.range.today:hover[disabled]:active,
.datepicker table tr td.range.today.disabled[disabled]:active,
.datepicker table tr td.range.today.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.range.today:active,
fieldset[disabled] .datepicker table tr td.range.today:hover:active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today:hover.disabled.active,
.datepicker table tr td.range.today.disabled.disabled.active,
.datepicker table tr td.range.today.disabled:hover.disabled.active,
.datepicker table tr td.range.today[disabled].active,
.datepicker table tr td.range.today:hover[disabled].active,
.datepicker table tr td.range.today.disabled[disabled].active,
.datepicker table tr td.range.today.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.range.today.active,
fieldset[disabled] .datepicker table tr td.range.today:hover.active,
fieldset[disabled] .datepicker table tr td.range.today.disabled.active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {
background-color: #f7ca77;
border-color: #f1a417;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
color: #ffffff;
background-color: #999999;
border-color: #555555;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:focus,
.datepicker table tr td.selected:hover:focus,
.datepicker table tr td.selected.disabled:focus,
.datepicker table tr td.selected.disabled:hover:focus,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.selected,
.open .dropdown-toggle.datepicker table tr td.selected:hover,
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
color: #ffffff;
background-color: #858585;
border-color: #373737;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.selected,
.open .dropdown-toggle.datepicker table tr td.selected:hover,
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
background-image: none;
}
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.selected,
fieldset[disabled] .datepicker table tr td.selected:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected:hover.disabled:hover,
.datepicker table tr td.selected.disabled.disabled:hover,
.datepicker table tr td.selected.disabled:hover.disabled:hover,
.datepicker table tr td.selected[disabled]:hover,
.datepicker table tr td.selected:hover[disabled]:hover,
.datepicker table tr td.selected.disabled[disabled]:hover,
.datepicker table tr td.selected.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.selected:hover,
fieldset[disabled] .datepicker table tr td.selected:hover:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected.disabled:focus,
.datepicker table tr td.selected:hover.disabled:focus,
.datepicker table tr td.selected.disabled.disabled:focus,
.datepicker table tr td.selected.disabled:hover.disabled:focus,
.datepicker table tr td.selected[disabled]:focus,
.datepicker table tr td.selected:hover[disabled]:focus,
.datepicker table tr td.selected.disabled[disabled]:focus,
.datepicker table tr td.selected.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.selected:focus,
fieldset[disabled] .datepicker table tr td.selected:hover:focus,
fieldset[disabled] .datepicker table tr td.selected.disabled:focus,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected:hover.disabled:active,
.datepicker table tr td.selected.disabled.disabled:active,
.datepicker table tr td.selected.disabled:hover.disabled:active,
.datepicker table tr td.selected[disabled]:active,
.datepicker table tr td.selected:hover[disabled]:active,
.datepicker table tr td.selected.disabled[disabled]:active,
.datepicker table tr td.selected.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.selected:active,
fieldset[disabled] .datepicker table tr td.selected:hover:active,
fieldset[disabled] .datepicker table tr td.selected.disabled:active,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected:hover.disabled.active,
.datepicker table tr td.selected.disabled.disabled.active,
.datepicker table tr td.selected.disabled:hover.disabled.active,
.datepicker table tr td.selected[disabled].active,
.datepicker table tr td.selected:hover[disabled].active,
.datepicker table tr td.selected.disabled[disabled].active,
.datepicker table tr td.selected.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.selected.active,
fieldset[disabled] .datepicker table tr td.selected:hover.active,
fieldset[disabled] .datepicker table tr td.selected.disabled.active,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {
background-color: #999999;
border-color: #555555;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
color: #ffffff;
background-color: #428bca;
border-color: #357ebd;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:focus,
.datepicker table tr td.active:hover:focus,
.datepicker table tr td.active.disabled:focus,
.datepicker table tr td.active.disabled:hover:focus,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.active,
.open .dropdown-toggle.datepicker table tr td.active:hover,
.open .dropdown-toggle.datepicker table tr td.active.disabled,
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
color: #ffffff;
background-color: #3276b1;
border-color: #285e8e;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.active,
.open .dropdown-toggle.datepicker table tr td.active:hover,
.open .dropdown-toggle.datepicker table tr td.active.disabled,
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
background-image: none;
}
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.active,
fieldset[disabled] .datepicker table tr td.active:hover,
fieldset[disabled] .datepicker table tr td.active.disabled,
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active:hover.disabled:hover,
.datepicker table tr td.active.disabled.disabled:hover,
.datepicker table tr td.active.disabled:hover.disabled:hover,
.datepicker table tr td.active[disabled]:hover,
.datepicker table tr td.active:hover[disabled]:hover,
.datepicker table tr td.active.disabled[disabled]:hover,
.datepicker table tr td.active.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.active:hover,
fieldset[disabled] .datepicker table tr td.active:hover:hover,
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active.disabled:focus,
.datepicker table tr td.active:hover.disabled:focus,
.datepicker table tr td.active.disabled.disabled:focus,
.datepicker table tr td.active.disabled:hover.disabled:focus,
.datepicker table tr td.active[disabled]:focus,
.datepicker table tr td.active:hover[disabled]:focus,
.datepicker table tr td.active.disabled[disabled]:focus,
.datepicker table tr td.active.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.active:focus,
fieldset[disabled] .datepicker table tr td.active:hover:focus,
fieldset[disabled] .datepicker table tr td.active.disabled:focus,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active:hover.disabled:active,
.datepicker table tr td.active.disabled.disabled:active,
.datepicker table tr td.active.disabled:hover.disabled:active,
.datepicker table tr td.active[disabled]:active,
.datepicker table tr td.active:hover[disabled]:active,
.datepicker table tr td.active.disabled[disabled]:active,
.datepicker table tr td.active.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.active:active,
fieldset[disabled] .datepicker table tr td.active:hover:active,
fieldset[disabled] .datepicker table tr td.active.disabled:active,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active:hover.disabled.active,
.datepicker table tr td.active.disabled.disabled.active,
.datepicker table tr td.active.disabled:hover.disabled.active,
.datepicker table tr td.active[disabled].active,
.datepicker table tr td.active:hover[disabled].active,
.datepicker table tr td.active.disabled[disabled].active,
.datepicker table tr td.active.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.active.active,
fieldset[disabled] .datepicker table tr td.active:hover.active,
fieldset[disabled] .datepicker table tr td.active.disabled.active,
fieldset[disabled] .datepicker table tr td.active.disabled:hover.active {
background-color: #428bca;
border-color: #357ebd;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
color: #ffffff;
background-color: #428bca;
border-color: #357ebd;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:focus,
.datepicker table tr td span.active:hover:focus,
.datepicker table tr td span.active.disabled:focus,
.datepicker table tr td span.active.disabled:hover:focus,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td span.active,
.open .dropdown-toggle.datepicker table tr td span.active:hover,
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
color: #ffffff;
background-color: #3276b1;
border-color: #285e8e;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td span.active,
.open .dropdown-toggle.datepicker table tr td span.active:hover,
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
background-image: none;
}
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td span.active,
fieldset[disabled] .datepicker table tr td span.active:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active:hover.disabled:hover,
.datepicker table tr td span.active.disabled.disabled:hover,
.datepicker table tr td span.active.disabled:hover.disabled:hover,
.datepicker table tr td span.active[disabled]:hover,
.datepicker table tr td span.active:hover[disabled]:hover,
.datepicker table tr td span.active.disabled[disabled]:hover,
.datepicker table tr td span.active.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td span.active:hover,
fieldset[disabled] .datepicker table tr td span.active:hover:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active.disabled:focus,
.datepicker table tr td span.active:hover.disabled:focus,
.datepicker table tr td span.active.disabled.disabled:focus,
.datepicker table tr td span.active.disabled:hover.disabled:focus,
.datepicker table tr td span.active[disabled]:focus,
.datepicker table tr td span.active:hover[disabled]:focus,
.datepicker table tr td span.active.disabled[disabled]:focus,
.datepicker table tr td span.active.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td span.active:focus,
fieldset[disabled] .datepicker table tr td span.active:hover:focus,
fieldset[disabled] .datepicker table tr td span.active.disabled:focus,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active:hover.disabled:active,
.datepicker table tr td span.active.disabled.disabled:active,
.datepicker table tr td span.active.disabled:hover.disabled:active,
.datepicker table tr td span.active[disabled]:active,
.datepicker table tr td span.active:hover[disabled]:active,
.datepicker table tr td span.active.disabled[disabled]:active,
.datepicker table tr td span.active.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td span.active:active,
fieldset[disabled] .datepicker table tr td span.active:hover:active,
fieldset[disabled] .datepicker table tr td span.active.disabled:active,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active:hover.disabled.active,
.datepicker table tr td span.active.disabled.disabled.active,
.datepicker table tr td span.active.disabled:hover.disabled.active,
.datepicker table tr td span.active[disabled].active,
.datepicker table tr td span.active:hover[disabled].active,
.datepicker table tr td span.active.disabled[disabled].active,
.datepicker table tr td span.active.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td span.active.active,
fieldset[disabled] .datepicker table tr td span.active:hover.active,
fieldset[disabled] .datepicker table tr td span.active.disabled.active,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
background-color: #428bca;
border-color: #357ebd;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker th.datepicker-switch {
width: 145px;
}
.datepicker thead tr:first-child th,
.datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr:first-child th:hover,
.datepicker tfoot tr th:hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr:first-child th.cw {
cursor: default;
background-color: transparent;
}
.input-group.date .input-group-addon i {
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
border-radius: 0 3px 3px 0;
}
.input-daterange .input-group-addon {
width: auto;
min-width: 16px;
padding: 4px 5px;
font-weight: normal;
line-height: 1.428571429;
text-align: center;
text-shadow: 0 1px 0 #fff;
vertical-align: middle;
background-color: #eeeeee;
border: solid #cccccc;
border-width: 1px 0;
margin-left: -5px;
margin-right: -5px;
}
.datepicker.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
float: left;
display: none;
min-width: 160px;
list-style: none;
background-color: #ffffff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 5px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
*border-right-width: 2px;
*border-bottom-width: 2px;
color: #333333;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
line-height: 1.428571429;
}
.datepicker.dropdown-menu th,
.datepicker.dropdown-menu td {
padding: 4px 5px;
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,545 @@
.xdsoft_datetimepicker {
box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.506);
background: #fff;
border-bottom: 1px solid #bbb;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-top: 1px solid #ccc;
color: #333;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
padding: 8px;
padding-left: 0;
padding-top: 2px;
position: absolute;
z-index: 9999;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: none;
}
.xdsoft_datetimepicker iframe {
position: absolute;
left: 0;
top: 0;
width: 75px;
height: 210px;
background: transparent;
border: none;
}
/*For IE8 or lower*/
.xdsoft_datetimepicker button {
border: none !important;
}
.xdsoft_noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.xdsoft_noselect::selection { background: transparent }
.xdsoft_noselect::-moz-selection { background: transparent }
.xdsoft_datetimepicker.xdsoft_inline {
display: inline-block;
position: static;
box-shadow: none;
}
.xdsoft_datetimepicker * {
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
}
.xdsoft_datetimepicker .xdsoft_datepicker, .xdsoft_datetimepicker .xdsoft_timepicker {
display: none;
}
.xdsoft_datetimepicker .xdsoft_datepicker.active, .xdsoft_datetimepicker .xdsoft_timepicker.active {
display: block;
}
.xdsoft_datetimepicker .xdsoft_datepicker {
width: 224px;
float: left;
margin-left: 8px;
}
.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_datepicker {
width: 256px;
}
.xdsoft_datetimepicker .xdsoft_timepicker {
width: 58px;
float: left;
text-align: center;
margin-left: 8px;
margin-top: 0;
}
.xdsoft_datetimepicker .xdsoft_datepicker.active+.xdsoft_timepicker {
margin-top: 8px;
margin-bottom: 3px
}
.xdsoft_datetimepicker .xdsoft_mounthpicker {
position: relative;
text-align: center;
}
.xdsoft_datetimepicker .xdsoft_label i,
.xdsoft_datetimepicker .xdsoft_prev,
.xdsoft_datetimepicker .xdsoft_next,
.xdsoft_datetimepicker .xdsoft_today_button {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Q0NBRjI1NjM0M0UwMTFFNDk4NkFGMzJFQkQzQjEwRUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Q0NBRjI1NjQ0M0UwMTFFNDk4NkFGMzJFQkQzQjEwRUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDQ0FGMjU2MTQzRTAxMUU0OTg2QUYzMkVCRDNCMTBFQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDQ0FGMjU2MjQzRTAxMUU0OTg2QUYzMkVCRDNCMTBFQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoNEP54AAAIOSURBVHja7Jq9TsMwEMcxrZD4WpBYeKUCe+kTMCACHZh4BFfHO/AAIHZGFhYkBBsSEqxsLCAgXKhbXYOTxh9pfJVP+qutnZ5s/5Lz2Y5I03QhWji2GIcgAokWgfCxNvcOCCGKqiSqhUp0laHOne05vdEyGMfkdxJDVjgwDlEQgYQBgx+ULJaWSXXS6r/ER5FBVR8VfGftTKcITNs+a1XpcFoExREIDF14AVIFxgQUS+h520cdud6wNkC0UBw6BCO/HoCYwBhD8QCkQ/x1mwDyD4plh4D6DDV0TAGyo4HcawLIBBSLDkHeH0Mg2yVP3l4TQMZQDDsEOl/MgHQqhMNuE0D+oBh0CIr8MAKyazBH9WyBuKxDWgbXfjNf32TZ1KWm/Ap1oSk/R53UtQ5xTh3LUlMmT8gt6g51Q9p+SobxgJQ/qmsfZhWywGFSl0yBjCLJCMgXail3b7+rumdVJ2YRss4cN+r6qAHDkPWjPjdJCF4n9RmAD/V9A/Wp4NQassDjwlB6XBiCxcJQWmZZb8THFilfy/lfrTvLghq2TqTHrRMTKNJ0sIhdo15RT+RpyWwFdY96UZ/LdQKBGjcXpcc1AlSFEfLmouD+1knuxBDUVrvOBmoOC/rEcN7OQxKVeJTCiAdUzUJhA2Oez9QTkp72OTVcxDcXY8iKNkxGAJXmJCOQwOa6dhyXsOa6XwEGAKdeb5ET3rQdAAAAAElFTkSuQmCC);
}
.xdsoft_datetimepicker .xdsoft_label i {
opacity: 0.5;
background-position: -92px -19px;
display: inline-block;
width: 9px;
height: 20px;
vertical-align: middle;
}
.xdsoft_datetimepicker .xdsoft_prev {
float: left;
background-position: -20px 0;
}
.xdsoft_datetimepicker .xdsoft_today_button {
float: left;
background-position: -70px 0;
margin-left: 5px;
}
.xdsoft_datetimepicker .xdsoft_next {
float: right;
background-position: 0 0;
}
.xdsoft_datetimepicker .xdsoft_next,
.xdsoft_datetimepicker .xdsoft_prev ,
.xdsoft_datetimepicker .xdsoft_today_button {
background-color: transparent;
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
display: block;
height: 30px;
opacity: 0.5;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
outline: medium none;
overflow: hidden;
padding: 0;
position: relative;
text-indent: 100%;
white-space: nowrap;
width: 20px;
min-width: 0;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev,
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_next {
float: none;
background-position: -40px -15px;
height: 15px;
width: 30px;
display: block;
margin-left: 14px;
margin-top: 7px;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev {
background-position: -40px 0;
margin-bottom: 7px;
margin-top: 0;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box {
height: 151px;
overflow: hidden;
border-bottom: 1px solid #ddd;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div {
background: #f5f5f5;
border-top: 1px solid #ddd;
color: #666;
font-size: 12px;
text-align: center;
border-collapse: collapse;
cursor: pointer;
border-bottom-width: 0;
height: 25px;
line-height: 25px;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div > div:first-child {
border-top-width: 0;
}
.xdsoft_datetimepicker .xdsoft_today_button:hover,
.xdsoft_datetimepicker .xdsoft_next:hover,
.xdsoft_datetimepicker .xdsoft_prev:hover {
opacity: 1;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
}
.xdsoft_datetimepicker .xdsoft_label {
display: inline;
position: relative;
z-index: 9999;
margin: 0;
padding: 5px 3px;
font-size: 14px;
line-height: 20px;
font-weight: bold;
background-color: #fff;
float: left;
width: 182px;
text-align: center;
cursor: pointer;
}
.xdsoft_datetimepicker .xdsoft_label:hover>span {
text-decoration: underline;
}
.xdsoft_datetimepicker .xdsoft_label:hover i {
opacity: 1.0;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select {
border: 1px solid #ccc;
position: absolute;
right: 0;
top: 30px;
z-index: 101;
display: none;
background: #fff;
max-height: 160px;
overflow-y: hidden;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_monthselect{ right: -7px }
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_yearselect{ right: 2px }
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover {
color: #fff;
background: #ff8000;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option {
padding: 2px 10px 2px 5px;
text-decoration: none !important;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current {
background: #33aaff;
box-shadow: #178fe5 0 1px 3px 0 inset;
color: #fff;
font-weight: 700;
}
.xdsoft_datetimepicker .xdsoft_month {
width: 100px;
text-align: right;
}
.xdsoft_datetimepicker .xdsoft_calendar {
clear: both;
}
.xdsoft_datetimepicker .xdsoft_year{
width: 48px;
margin-left: 5px;
}
.xdsoft_datetimepicker .xdsoft_calendar table {
border-collapse: collapse;
width: 100%;
}
.xdsoft_datetimepicker .xdsoft_calendar td > div {
padding-right: 5px;
}
.xdsoft_datetimepicker .xdsoft_calendar th {
height: 25px;
}
.xdsoft_datetimepicker .xdsoft_calendar td,.xdsoft_datetimepicker .xdsoft_calendar th {
width: 14.2857142%;
background: #f5f5f5;
border: 1px solid #ddd;
color: #666;
font-size: 12px;
text-align: right;
vertical-align: middle;
padding: 0;
border-collapse: collapse;
cursor: pointer;
height: 25px;
}
.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar td,.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar th {
width: 12.5%;
}
.xdsoft_datetimepicker .xdsoft_calendar th {
background: #f1f1f1;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_today {
color: #33aaff;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_default {
background: #ffe9d2;
box-shadow: #ffb871 0 1px 4px 0 inset;
color: #000;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_mint {
background: #c1ffc9;
box-shadow: #00dd1c 0 1px 4px 0 inset;
color: #000;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_default,
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current,
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_current {
background: #33aaff;
box-shadow: #178fe5 0 1px 3px 0 inset;
color: #fff;
font-weight: 700;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month,
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled,
.xdsoft_datetimepicker .xdsoft_time_box >div >div.xdsoft_disabled {
opacity: 0.5;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
cursor: default;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month.xdsoft_disabled {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
}
.xdsoft_datetimepicker .xdsoft_calendar td:hover,
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div:hover {
color: #fff !important;
background: #ff8000 !important;
box-shadow: none !important;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current.xdsoft_disabled:hover,
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current.xdsoft_disabled:hover {
background: #33aaff !important;
box-shadow: #178fe5 0 1px 3px 0 inset !important;
color: #fff !important;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled:hover,
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_disabled:hover {
color: inherit !important;
background: inherit !important;
box-shadow: inherit !important;
}
.xdsoft_datetimepicker .xdsoft_calendar th {
font-weight: 700;
text-align: center;
color: #999;
cursor: default;
}
.xdsoft_datetimepicker .xdsoft_copyright {
color: #ccc !important;
font-size: 10px;
clear: both;
float: none;
margin-left: 8px;
}
.xdsoft_datetimepicker .xdsoft_copyright a { color: #eee !important }
.xdsoft_datetimepicker .xdsoft_copyright a:hover { color: #aaa !important }
.xdsoft_time_box {
position: relative;
border: 1px solid #ccc;
}
.xdsoft_scrollbar >.xdsoft_scroller {
background: #ccc !important;
height: 20px;
border-radius: 3px;
}
.xdsoft_scrollbar {
position: absolute;
width: 7px;
right: 0;
top: 0;
bottom: 0;
cursor: pointer;
}
.xdsoft_scroller_box {
position: relative;
}
.xdsoft_datetimepicker.xdsoft_dark {
box-shadow: 0 5px 15px -5px rgba(255, 255, 255, 0.506);
background: #000;
border-bottom: 1px solid #444;
border-left: 1px solid #333;
border-right: 1px solid #333;
border-top: 1px solid #333;
color: #ccc;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box {
border-bottom: 1px solid #222;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box >div >div {
background: #0a0a0a;
border-top: 1px solid #222;
color: #999;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label {
background-color: #000;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label > .xdsoft_select {
border: 1px solid #333;
background: #000;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover {
color: #000;
background: #007fff;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current {
background: #cc5500;
box-shadow: #b03e00 0 1px 3px 0 inset;
color: #000;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label i,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_prev,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_next,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_today_button {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUExQUUzOTA0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUExQUUzOTE0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQTFBRTM4RTQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQTFBRTM4RjQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp0VxGEAAAIASURBVHja7JrNSgMxEMebtgh+3MSLr1T1Xn2CHoSKB08+QmR8Bx9A8e7RixdB9CKCoNdexIugxFlJa7rNZneTbLIpM/CnNLsdMvNjM8l0mRCiQ9Ye61IKCAgZAUnH+mU3MMZaHYChBnJUDzWOFZdVfc5+ZFLbrWDeXPwbxIqrLLfaeS0hEBVGIRQCEiZoHQwtlGSByCCdYBl8g8egTTAWoKQMRBRBcZxYlhzhKegqMOageErsCHVkk3hXIFooDgHB1KkHIHVgzKB4ADJQ/A1jAFmAYhkQqA5TOBtocrKrgXwQA8gcFIuAIO8sQSA7hidvPwaQGZSaAYHOUWJABhWWw2EMIH9QagQERU4SArJXo0ZZL18uvaxejXt/Em8xjVBXmvFr1KVm/AJ10tRe2XnraNqaJvKE3KHuUbfK1E+VHB0q40/y3sdQSxY4FHWeKJCunP8UyDdqJZenT3ntVV5jIYCAh20vT7ioP8tpf6E2lfEMwERe+whV1MHjwZB7PBiCxcGQWwKZKD62lfGNnP/1poFAA60T7rF1UgcKd2id3KDeUS+oLWV8DfWAepOfq00CgQabi9zjcgJVYVD7PVzQUAUGAQkbNJTBICDhgwYTjDYD6XeW08ZKh+A4pYkzenOxXUbvZcWz7E8ykRMnIHGX1XPl+1m2vPYpL+2qdb8CDAARlKFEz/ZVkAAAAABJRU5ErkJggg==);
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th {
background: #0a0a0a;
border: 1px solid #222;
color: #999;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th {
background: #0e0e0e;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_today {
color: #cc5500;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_default {
background: #ffe9d2;
box-shadow: #ffb871 0 1px 4px 0 inset;
color:#000;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_mint {
background: #c1ffc9;
box-shadow: #00dd1c 0 1px 4px 0 inset;
color:#000;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_default,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_current,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_current {
background: #cc5500;
box-shadow: #b03e00 0 1px 3px 0 inset;
color: #000;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td:hover,
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box >div >div:hover {
color: #000 !important;
background: #007fff !important;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th {
color: #666;
}
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright { color: #333 !important }
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a { color: #111 !important }
.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a:hover { color: #555 !important }
.xdsoft_dark .xdsoft_time_box {
border: 1px solid #333;
}
.xdsoft_dark .xdsoft_scrollbar >.xdsoft_scroller {
background: #333 !important;
}
.xdsoft_datetimepicker .xdsoft_save_selected {
display: block;
border: 1px solid #dddddd !important;
margin-top: 5px;
width: 100%;
color: #454551;
font-size: 13px;
}
.xdsoft_datetimepicker .blue-gradient-button {
font-family: "museo-sans", "Book Antiqua", sans-serif;
font-size: 12px;
font-weight: 300;
color: #82878c;
height: 28px;
position: relative;
padding: 4px 17px 4px 33px;
border: 1px solid #d7d8da;
background: -moz-linear-gradient(top, #fff 0%, #f4f8fa 73%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(73%, #f4f8fa));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fff 0%, #f4f8fa 73%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #fff 0%, #f4f8fa 73%);
/* Opera 11.10+ */
background: -ms-linear-gradient(top, #fff 0%, #f4f8fa 73%);
/* IE10+ */
background: linear-gradient(to bottom, #fff 0%, #f4f8fa 73%);
/* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff', endColorstr='#f4f8fa',GradientType=0 );
/* IE6-9 */
}
.xdsoft_datetimepicker .blue-gradient-button:hover, .xdsoft_datetimepicker .blue-gradient-button:focus, .xdsoft_datetimepicker .blue-gradient-button:hover span, .xdsoft_datetimepicker .blue-gradient-button:focus span {
color: #454551;
background: -moz-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4f8fa), color-stop(73%, #FFF));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
/* Opera 11.10+ */
background: -ms-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
/* IE10+ */
background: linear-gradient(to bottom, #f4f8fa 0%, #FFF 73%);
/* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f8fa', endColorstr='#FFF',GradientType=0 );
/* IE6-9 */
}

File diff suppressed because one or more lines are too long

@ -1,235 +1,408 @@
.markdown {
font-size: 14px;
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px;
line-height: 1.6;
word-wrap: break-word;
padding: 0 2em 2em !important;
}
.markdown > *:first-child {
margin-top: 0 !important;
}
.markdown > *:last-child {
margin-bottom: 0 !important;
}
.markdown a {
color: #4183C4;
.markdown a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown .absent {
color: #c00;
}
.markdown .anchor {
position: absolute;
top: 0;
left: 0;
display: block;
padding-right: 6px;
padding-left: 30px;
margin-left: -30px;
}
.markdown .anchor:focus {
outline: none;
}
.markdown h1,
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
line-height: 1.7;
padding: 15px 0 0;
margin: 0 0 15px;
color: #444;
position: relative;
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
line-height: 1.4;
}
.markdown h1 .octicon-link,
.markdown h2 .octicon-link,
.markdown h3 .octicon-link,
.markdown h4 .octicon-link,
.markdown h5 .octicon-link,
.markdown h6 .octicon-link {
display: none;
color: #000;
vertical-align: middle;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
padding-left: 8px;
margin-left: -30px;
text-decoration: none;
}
.markdown h1,
.markdown h2 {
border-bottom: 1px solid #EEE;
.markdown h1:hover .anchor .octicon-link,
.markdown h2:hover .anchor .octicon-link,
.markdown h3:hover .anchor .octicon-link,
.markdown h4:hover .anchor .octicon-link,
.markdown h5:hover .anchor .octicon-link,
.markdown h6:hover .anchor .octicon-link {
display: inline-block;
}
.markdown h2 {
border-bottom: 1px solid #EEE;
.markdown h1 tt,
.markdown h1 code,
.markdown h2 tt,
.markdown h2 code,
.markdown h3 tt,
.markdown h3 code,
.markdown h4 tt,
.markdown h4 code,
.markdown h5 tt,
.markdown h5 code,
.markdown h6 tt,
.markdown h6 code {
font-size: inherit;
}
.markdown h1 {
color: #000;
font-size: 33px
padding-bottom: 0.3em;
font-size: 2.25em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
.markdown h1 .anchor {
line-height: 1;
}
.markdown h2 {
color: #333;
font-size: 28px
padding-bottom: 0.3em;
font-size: 1.75em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
.markdown h2 .anchor {
line-height: 1;
}
.markdown h3 {
font-size: 22px
font-size: 1.5em;
line-height: 1.43;
}
.markdown h3 .anchor {
line-height: 1.2;
}
.markdown h4 {
font-size: 18px
font-size: 1.25em;
}
.markdown h4 .anchor {
line-height: 1.2;
}
.markdown h5 {
font-size: 14px
font-size: 1em;
}
.markdown h5 .anchor {
line-height: 1.1;
}
.markdown h6 {
font-size: 14px
font-size: 1em;
color: #777;
}
.markdown h6 .anchor {
line-height: 1.1;
}
.markdown p,
.markdown blockquote,
.markdown ul,
.markdown ol,
.markdown dl,
.markdown table,
.markdown pre {
margin-top: 0;
margin-bottom: 16px;
}
.markdown hr {
height: 4px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
}
.markdown ul,
.markdown ol {
padding-left: 2em;
}
.markdown ul.no-list,
.markdown ol.no-list {
padding: 0;
list-style-type: none;
}
.markdown ul ul,
.markdown ul ol,
.markdown ol ol,
.markdown ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown ol ol,
.markdown ul ol {
list-style-type: lower-roman;
}
.markdown li > p {
margin-top: 16px;
}
.markdown dl {
padding: 0;
}
.markdown dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: bold;
}
.markdown dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.markdown blockquote {
padding: 0 15px;
color: #777;
border-left: 4px solid #ddd;
}
.markdown blockquote > :first-child {
margin-top: 0;
}
.markdown blockquote > :last-child {
margin-bottom: 0;
}
.markdown table {
border-collapse: collapse;
border-spacing: 0;
display: block;
overflow: auto;
width: 100%;
margin: 0 0 9px;
overflow: auto;
word-break: normal;
word-break: keep-all;
}
.markdown table th {
font-weight: 700
font-weight: bold;
}
.markdown table th,
.markdown table td {
border: 1px solid #DDD;
padding: 6px 13px;
padding: 6px 13px !important;
border: 1px solid #ddd;
}
.markdown table tr {
background-color: #FFF;
border-top: 1px solid #CCC;
background-color: #fff;
border-top: 1px solid #ccc;
}
.markdown table tr:nth-child(2n) {
background-color: #F8F8F8
background-color: #f8f8f8;
}
.markdown li {
line-height: 1.6;
margin-top: 6px;
.markdown img {
max-width: 100%;
box-sizing: border-box;
}
.markdown li:first-child {
margin-top: 0;
.markdown .emoji {
max-width: none;
}
.markdown dl dt {
font-style: italic;
margin-top: 9px;
.markdown span.frame {
display: block;
overflow: hidden;
}
.markdown dl dd {
margin: 0 0 9px;
padding: 0 9px;
.markdown span.frame > span {
display: block;
float: left;
width: auto;
padding: 7px;
margin: 13px 0 0;
overflow: hidden;
border: 1px solid #ddd;
}
.markdown blockquote,
.markdown blockquote p {
font-size: 14px;
background-color: #f5f5f5;
.markdown span.frame span img {
display: block;
float: left;
}
.markdown > pre {
line-height: 1.6;
overflow: auto;
background: #f8f8f8;
border: 1px solid #ddd;
padding: 0;
.markdown span.frame span span {
display: block;
padding: 5px 0 0;
clear: both;
color: #333;
}
.markdown > pre.linenums {
padding: 0;
.markdown span.align-center {
display: block;
overflow: hidden;
clear: both;
}
.markdown > pre > ol.linenums {
list-style: none;
padding: 0;
.markdown span.align-center > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: center;
}
.markdown > pre > ol.linenums > li {
margin-top: 2px;
.markdown span.align-center span img {
margin: 0 auto;
text-align: center;
}
.markdown > pre.nums-style > ol.linenums {
list-style-type: decimal;
padding: 0 0 0 40px;
-webkit-box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc;
box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc;
.markdown span.align-right {
display: block;
overflow: hidden;
clear: both;
}
.markdown > pre > code {
white-space: pre;
word-wrap: normal;
.markdown span.align-right > span {
display: block;
margin: 13px 0 0;
overflow: hidden;
text-align: right;
}
.markdown span.align-right span img {
margin: 0;
text-align: right;
}
.markdown span.float-left {
display: block;
float: left;
margin-right: 13px;
overflow: hidden;
}
.markdown span.float-left span {
margin: 13px 0 0;
}
.markdown > pre > ol.linenums > li {
padding: 0 10px;
.markdown span.float-right {
display: block;
float: right;
margin-left: 13px;
overflow: hidden;
}
.markdown > pre > ol.linenums > li:first-child {
padding-top: 12px;
.markdown span.float-right > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: right;
}
.markdown > pre > ol.linenums > li:last-child {
padding-bottom: 12px;
.markdown code,
.markdown tt {
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin: 0;
font-size: 85%;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px;
}
.markdown code:before,
.markdown code:after,
.markdown tt:before,
.markdown tt:after {
letter-spacing: -0.2em;
content: "\00a0";
}
.markdown code br,
.markdown tt br {
display: none;
}
.markdown > pre.nums-style > ol.linenums > li {
border-left: 1px solid #ddd;
.markdown del code {
text-decoration: inherit;
}
.markdown hr {
border: none;
color: #ccc;
height: 4px;
.markdown pre > code {
padding: 0;
margin: 15px 0;
border-bottom: 2px solid #EEE;
}
.markdown blockquote:last-child,
.markdown ul:last-child,
.markdown ol:last-child,
.markdown > pre:last-child,
.markdown > pre:last-child,
.markdown p:last-child {
margin-bottom: 0;
margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}
.markdown img {
max-width: 100%;
.markdown .highlight {
margin-bottom: 16px;
}
.markdown .btn {
color: #fff;
.markdown .highlight pre,
.markdown pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border-radius: 3px;
}
.markdown .anchor-wrap {
/*margin-top: -50px;*/
/*padding-top: 50px;*/
.markdown .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.markdown h1 a, .markdown h2 a, .markdown h3 a {
text-decoration: none;
.markdown pre {
word-wrap: normal;
}
.markdown h1 a.anchor,
.markdown h2 a.anchor,
.markdown h3 a.anchor,
.markdown h4 a.anchor,
.markdown h5 a.anchor,
.markdown h6 a.anchor {
text-decoration:none;
line-height:1;
padding-left:0;
margin-left:5px;
top:15%;
}
.markdown a span.octicon {
font-size: 16px;
font-family: "FontAwesome";
line-height: 1;
.markdown pre code,
.markdown pre tt {
display: inline;
max-width: initial;
padding: 0;
margin: 0;
overflow: initial;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}
.markdown pre code:before,
.markdown pre code:after,
.markdown pre tt:before,
.markdown pre tt:after {
content: normal;
}
.markdown kbd {
display: inline-block;
text-decoration: none;
-webkit-font-smoothing: antialiased;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #fcfcfc;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbbbbb;
}
.markdown .csv-data td,
.markdown .csv-data th {
padding: 5px;
overflow: hidden;
font-size: 12px;
line-height: 1;
text-align: left;
white-space: nowrap;
}
.markdown a span.octicon-link {
display: none;
color: #000;
.markdown .csv-data .blob-num {
padding: 10px 8px 9px;
text-align: right;
background: #fff;
border: 0;
}
.markdown a span.octicon-link:before {
content: "\f0c1";
.markdown .csv-data tr {
border-top: 0;
}
.markdown h1:hover .octicon-link,
.markdown h2:hover .octicon-link,
.markdown h3:hover .octicon-link,
.markdown h4:hover .octicon-link,
.markdown h5:hover .octicon-link,
.markdown h6:hover .octicon-link {
display:inline-block
.markdown .csv-data th {
font-weight: bold;
background: #f8f8f8;
border-top: 0;
}
/* Author: jmblog */
/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */
/* GitHub Theme */
@ -239,74 +412,60 @@
.pln {
color: #333333;
}
@media screen {
/* string content */
.str {
color: #dd1144;
}
/* a keyword */
.kwd {
color: #333333;
}
/* a comment */
.com {
color: #999988;
font-style: italic;
}
/* a type name */
.typ {
color: #445588;
}
/* a literal value */
.lit {
color: #445588;
}
/* punctuation */
.pun {
color: #333333;
}
/* lisp open bracket */
.opn {
color: #333333;
}
/* lisp close bracket */
.clo {
color: #333333;
}
/* a markup tag name */
.tag {
color: navy;
}
/* a markup attribute name */
.atn {
color: teal;
}
/* a markup attribute value */
.atv {
color: #dd1144;
}
/* a declaration */
.dec {
color: #333333;
}
/* a variable name */
.var {
color: teal;
}
/* a function name */
.fun {
color: #990000;
@ -317,69 +476,39 @@
.str {
color: #006600;
}
.kwd {
color: #006;
font-weight: bold;
}
.com {
color: #600;
font-style: italic;
}
.typ {
color: #404;
font-weight: bold;
}
.lit {
color: #004444;
}
.pun, .opn, .clo {
.pun,
.opn,
.clo {
color: #444400;
}
.tag {
color: #006;
font-weight: bold;
}
.atn {
color: #440044;
}
.atv {
color: #006600;
}
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
}
/* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L4,
li.L5,
li.L6,
li.L7,
li.L8,
li.L9 {
/* */
}
/* Alternate shading for lines */
li.L1,
li.L3,
li.L5,
li.L7,
li.L9 {
/* */
}

File diff suppressed because one or more lines are too long

@ -269,36 +269,62 @@ var Gogits = {};
if ($(selector).hasClass('js-copy-bind')) {
return;
}
$(selector).zclip({
path: "/js/ZeroClipboard.swf",
copy: function () {
var t = $(this).data("copy-val");
var to = $($(this).data("copy-from"));
var str = "";
if (t == "txt") {
str = to.text();
}
if (t == 'val') {
str = to.val();
}
if (t == 'html') {
str = to.html();
}
return str;
},
afterCopy: function () {
if ( document.documentElement.classList.contains("is-copy-enabled") ) {
$(selector).click(function(event) {
var $this = $(this);
$this.tooltip('hide')
.attr('data-original-title', 'Copied OK');
var cfrom = $this.attr('data-copy-from');
$(cfrom).select();
document.execCommand('copy');
getSelection().removeAllRanges();
$this.tipsy("hide").attr('original-title', $this.data('after-title'));
setTimeout(function () {
$this.tooltip("show");
$this.tipsy("show");
}, 200);
setTimeout(function () {
$this.tooltip('hide')
.attr('data-original-title', 'Copy to Clipboard');
}, 3000);
}
}).addClass("js-copy-bind");
$this.tipsy('hide').attr('original-title', $this.data('original-title'));
}, 2000);
this.blur();
return;
});
$(selector).addClass("js-copy-bind");
} else {
$(selector).zclip({
path: Gogits.AppSubUrl + "/js/ZeroClipboard.swf",
copy: function () {
var t = $(this).data("copy-val");
var to = $($(this).data("copy-from"));
var str = "";
if (t == "txt") {
str = to.text();
}
if (t == 'val') {
str = to.val();
}
if (t == 'html') {
str = to.html();
}
return str;
},
afterCopy: function () {
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");
}
}
// api working
@ -770,6 +796,7 @@ function initIssue() {
$("#issue-edit-btn").on("click", function () {
$('#issue h1.title,#issue .issue-main > .issue-content .content,#issue-edit-btn').toggleHide();
$('#issue-edit-title,.issue-edit-content,.issue-edit-cancel,.issue-edit-save').toggleShow();
$('#issue-edit-content').focus();
});
$('.issue-edit-cancel').on("click", function () {
$('#issue h1.title,#issue .issue-main > .issue-content .content,#issue-edit-btn').toggleShow();

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -1,6 +1,135 @@
'use strict';
var csrf;
function initInstall() {
if ($('.install').length == 0) {
return;
}
// Database type change detection.
$("#db_type").change(function () {
var db_type = $('#db_type').val();
if (db_type === "SQLite3") {
$('#sql_settings').hide();
$('#pgsql_settings').hide();
$('#sqlite_settings').show();
return;
}
var mysql_default = '127.0.0.1:3306';
var postgres_default = '127.0.0.1:5432';
$('#sqlite_settings').hide();
$('#sql_settings').show();
if (db_type === "PostgreSQL") {
$('#pgsql_settings').show();
if ($('#db_host').val() == mysql_default) {
$('#db_host').val(postgres_default);
}
} else {
$('#pgsql_settings').hide();
if ($('#db_host').val() == postgres_default) {
$('#db_host').val(mysql_default);
}
}
});
};
function initRepository() {
if ($('.repository').length == 0) {
return;
}
// Labels
if ($('.repository.labels').length > 0) {
$('.color-picker').each(function () {
$(this).minicolors();
});
$('.precolors .color').click(function () {
var color_hex = $(this).data('color-hex')
$('.color-picker').val(color_hex);
$('.minicolors-swatch-color').css("background-color", color_hex);
});
$('.edit-label-button').click(function () {
$('#label-modal-id').val($(this).data('id'));
$('#label-modal-title').val($(this).data('title'));
$('#label-modal-color').val($(this).data('color'))
$('.minicolors-swatch-color').css("background-color", $(this).data('color'));
$('.edit-label.modal').modal({
onApprove: function () {
$('.edit-label.form').submit();
}
}).modal('show');
return false;
});
}
// Milestones
if ($('.repository.milestones').length > 0) {
}
if ($('.repository.new.milestone').length > 0) {
var $datepicker = $('.milestone.datepicker')
$datepicker.datetimepicker({
lang: $datepicker.data('lang'),
inline: true,
timepicker: false,
startDate: $datepicker.data('start-date'),
formatDate: 'Y-m-d',
onSelectDate: function (ct) {
$('#deadline').val(ct.dateFormat('Y-m-d'));
}
});
$('#clear-date').click(function () {
$('#deadline').val('');
return false;
});
}
// Settings
if ($('.repository.settings').length > 0) {
$('#add-deploy-key').click(function () {
$('#add-deploy-key-panel').show();
});
}
};
$(document).ready(function () {
// Semantic UI modules.
$('.dropdown').dropdown({
csrf = $('meta[name=_csrf]').attr("content");
// Semantic UI modules.
$('.dropdown').dropdown();
$('.jump.dropdown').dropdown({
action: 'hide'
});
$('.slide.up.dropdown').dropdown({
transition: 'slide up'
});
$('.ui.accordion').accordion();
$('.ui.checkbox').checkbox();
$('.ui.progress').progress({
showActivity: false
});
$('.poping.up').popup();
// Helpers.
$('.delete-button').click(function () {
var $this = $(this);
$('.delete.modal').modal({
closable: false,
onApprove: function () {
$.post($this.data('url'), {
"_csrf": csrf,
"id": $this.data("id")
}).done(function (data) {
window.location.href = data.redirect;
});
}
}).modal('show');
return false;
});
initInstall();
initRepository();
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save