Conflicts:
	routers/repo/download.go
tokarchuk/v1.17
Don Bowman 9 years ago
commit 1cb46ede1a
  1. 4
      .bra.toml
  2. 1
      .gitignore
  3. 36
      .gopmfile
  4. 22
      .pkgr.yml
  5. 7
      .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. 35
      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. 5
      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. 14
      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 build_delay = 1500
cmds = [ cmds = [
#["go-bindata", "-o=modules/bindata/bindata.go", "-ignore=\\.DS_Store|README", "-pkg=bindata", "conf/..."], #["go-bindata", "-o=modules/bindata/bindata.go", "-ignore=\\.DS_Store|README", "-pkg=bindata", "conf/..."],
["go", "install", "-tags", "sqlite cert"],# redis memcache ["go", "install", "-tags", "sqlite"],# redis memcache cert pam
["go", "build", "-tags", "sqlite cert"], ["go", "build", "-tags", "sqlite"],
["./gogs", "web"] ["./gogs", "web"]
] ]

1
.gitignore vendored

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

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

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

@ -6,9 +6,12 @@ go:
- 1.4 - 1.4
- tip - 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: notifications:
email: email:

@ -7,7 +7,7 @@ Gogs (Go Git Service) is a painless self-hosted Git service.
![Demo](http://gogs.qiniudn.com/gogs_demo.gif) ![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### Current version: 0.6.1 Beta ##### Current version: 0.6.4 Beta
### NOTICES ### NOTICES
@ -52,13 +52,27 @@ The goal of this project is to make the easiest, fastest, and most painless way
- Drone CI integration - Drone CI integration
- Supports MySQL, PostgreSQL and SQLite3 - Supports MySQL, PostgreSQL and SQLite3
- Social account login (GitHub, Google, QQ, Weibo) - 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 ## System Requirements
- A cheap Raspberry Pi is powerful enough for basic functionality. - A cheap Raspberry Pi is powerful enough for basic functionality.
- At least 2 CPU cores and 1GB RAM would be the baseline for teamwork. - 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 ## Installation
Make sure you install the [prerequisites](http://gogs.io/docs/installation/) first. 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) - [Ship with Docker](https://github.com/gogits/gogs/tree/master/docker)
- [Install with Vagrant](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs) - [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 ## Acknowledgments
- Router and middleware mechanism of [Macaron](https://github.com/Unknwon/macaron). - Router and middleware mechanism of [Macaron](https://github.com/Unknwon/macaron).
@ -83,6 +109,7 @@ There are 5 ways to install Gogs:
## Contributors ## Contributors
- The [core team](http://gogs.io/team) of this project. - 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 [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
- See [TRANSLATORS](conf/locale/TRANSLATORS) for full list of translators. - 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 服务。 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。 Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。使用 Go 语言开发使得 Gogs 能够通过独立的二进制分发,并且支持 Go 语言支持的 **所有平台**,包括 Linux、Mac OS X 以及 Windows。
@ -39,13 +35,27 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- Drone CI 持续部署集成 - Drone CI 持续部署集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录(GitHub、Google、QQ、微博) - 社交帐号登录(GitHub、Google、QQ、微博)
- 多语言支持([11 种语言]([more](https://crowdin.com/project/gogs))) - 多语言支持([14 种语言]([more](https://crowdin.com/project/gogs)))
## 系统要求 ## 系统要求
- 最低的系统硬件要求为一个廉价的树莓派 - 最低的系统硬件要求为一个廉价的树莓派
- 如果用于团队项目,建议使用 2 核 CPU 及 1GB 内存 - 如果用于团队项目,建议使用 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/)。 在安装 Gogs 之前,您需要先安装 [基本环境](http://gogs.io/docs/installation/)。
@ -70,6 +80,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
## 贡献成员 ## 贡献成员
- 本项目的 [开发团队](http://gogs.io/team)。 - 本项目的 [开发团队](http://gogs.io/team)。
- 前团队成员 [@lunny](https://github.com/lunny) 和 [@fuxiaohei](https://github.com/fuxiaohei)。
- 您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。 - 您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
- 您可以通过查看 [TRANSLATORS](conf/locale/TRANSLATORS) 文件获取完整的翻译人员列表。 - 您可以通过查看 [TRANSLATORS](conf/locale/TRANSLATORS) 文件获取完整的翻译人员列表。

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

@ -16,6 +16,7 @@ import (
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/gogits/gogs/models" "github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/httplib"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/uuid" "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) { func runServ(c *cli.Context) {
if c.IsSet("config") { if c.IsSet("config") {
setting.CustomConf = c.String("config") setting.CustomConf = c.String("config")
} }
setup("serv.log") 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 { if len(c.Args()) < 1 {
fail("Not enough arguments", "Not enough arugments") fail("Not enough arguments", "Not enough arguments")
}
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)
} }
cmd := os.Getenv("SSH_ORIGINAL_COMMAND") cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" { if len(cmd) == 0 {
println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.") println("Hi there, 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.")
println("If this is unexpected, please log in with password and setup Gogs under another user.")
}
return return
} }
@ -113,29 +97,25 @@ func runServ(c *cli.Context) {
repoPath := strings.Trim(args, "'") repoPath := strings.Trim(args, "'")
rr := strings.SplitN(repoPath, "/", 2) rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 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] repoUserName := rr[0]
repoName := strings.TrimSuffix(rr[1], ".git") repoName := strings.TrimSuffix(rr[1], ".git")
repoUser, err := models.GetUserByName(repoUserName) repoUser, err := models.GetUserByName(repoUserName)
if err != nil { if err != nil {
if err == models.ErrUserNotExist { if models.IsErrUserNotExist(err) {
fail("Repository owner does not exist", "Unregistered owner: %s", repoUserName) 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) repo, err := models.GetRepositoryByName(repoUser.Id, repoName)
if err != nil { if err != nil {
if models.IsErrRepoNotExist(err) { if models.IsErrRepoNotExist(err) {
if user.Id == repoUser.Id || repoUser.IsOwnedBy(user.Id) { fail(_ACCESS_DENIED_MESSAGE, "Repository does not exist: %s/%s", repoUser.Name, repoName)
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("Internal error", "Fail to get repository: %v", err) fail("Internal error", "Failed to get repository: %v", err)
} }
requestedMode, has := COMMANDS[verb] requestedMode, has := COMMANDS[verb]
@ -143,17 +123,62 @@ func runServ(c *cli.Context) {
fail("Unknown git command", "Unknown git command %s", verb) fail("Unknown git command", "Unknown git command %s", verb)
} }
mode, err := models.AccessLevel(user, repo) // Allow anonymous clone for public repositories.
if err != nil { var (
fail("Internal error", "Fail to check access: %v", err) keyID int64
} else if mode < requestedMode { user *models.User
clientMessage := _ACCESS_DENIED_MESSAGE )
if mode >= models.ACCESS_MODE_READ { if requestedMode == models.ACCESS_MODE_WRITE || repo.IsPrivate {
clientMessage = "You do not have sufficient authorization for this action" 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() uuid := uuid.NewV4().String()
@ -171,7 +196,7 @@ func runServ(c *cli.Context) {
gitcmd.Stdin = os.Stdin gitcmd.Stdin = os.Stdin
gitcmd.Stderr = os.Stderr gitcmd.Stderr = os.Stderr
if err = gitcmd.Run(); err != nil { 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 { if requestedMode == models.ACCESS_MODE_WRITE {
@ -184,7 +209,7 @@ func runServ(c *cli.Context) {
err = models.Update(task.RefName, task.OldCommitId, task.NewCommitId, err = models.Update(task.RefName, task.OldCommitId, task.NewCommitId,
user.Name, repoUserName, repoName, user.Id) user.Name, repoUserName, repoName, user.Id)
if err != nil { 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. // Send deliver hook request.
key, err := models.GetPublicKeyById(keyId) resp, err := httplib.Head(setting.AppUrl + setting.AppSubUrl + repoUserName + "/" + repoName + "/hooks/trigger").Response()
if err != nil { if err == nil {
fail("Internal error", "GetPublicKeyById: %v", err) resp.Body.Close()
} }
key.Updated = time.Now()
if err = models.UpdatePublicKey(key); err != nil { // Update user key activity.
fail("Internal error", "UpdatePublicKey: %v", err) 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/Unknwon/macaron"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/go-xorm/xorm"
"github.com/macaron-contrib/binding" "github.com/macaron-contrib/binding"
"github.com/macaron-contrib/cache" "github.com/macaron-contrib/cache"
"github.com/macaron-contrib/captcha" "github.com/macaron-contrib/captcha"
@ -25,6 +26,7 @@ import (
"github.com/macaron-contrib/oauth2" "github.com/macaron-contrib/oauth2"
"github.com/macaron-contrib/session" "github.com/macaron-contrib/session"
"github.com/macaron-contrib/toolbox" "github.com/macaron-contrib/toolbox"
"github.com/mcuadros/go-version"
"gopkg.in/ini.v1" "gopkg.in/ini.v1"
api "github.com/gogits/go-gogs-client" api "github.com/gogits/go-gogs-client"
@ -35,7 +37,6 @@ import (
"github.com/gogits/gogs/modules/avatar" "github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata" "github.com/gogits/gogs/modules/bindata"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
@ -69,7 +70,7 @@ type VerChecker struct {
// checkVersion checks if binary matches the version of templates files. // checkVersion checks if binary matches the version of templates files.
func checkVersion() { func checkVersion() {
// Templates. // Templates.
data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION")) data, err := ioutil.ReadFile(setting.StaticRootPath + "/templates/.VERSION")
if err != nil { if err != nil {
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err) log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
} }
@ -79,18 +80,18 @@ func checkVersion() {
// Check dependency version. // Check dependency version.
checkers := []VerChecker{ 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/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/cache", cache.Version, "0.0.7"},
{"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"}, {"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"}, {"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"},
{"github.com/macaron-contrib/session", session.Version, "0.1.6"}, {"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 { for _, c := range checkers {
ver := strings.Join(strings.Split(c.Version(), ".")[:3], ".") if !version.Compare(c.Version(), c.Expected, ">=") {
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, c.Version(), c.Expected)
log.Fatal(4, "Package '%s' version is too old(%s -> %s), did you forget to update?", c.ImportPath, ver, c.Expected)
} }
} }
} }
@ -98,7 +99,9 @@ func checkVersion() {
// newMacaron initializes Macaron instance. // newMacaron initializes Macaron instance.
func newMacaron() *macaron.Macaron { func newMacaron() *macaron.Macaron {
m := macaron.New() m := macaron.New()
m.Use(macaron.Logger()) if !setting.DisableRouterLog {
m.Use(macaron.Logger())
}
m.Use(macaron.Recovery()) m.Use(macaron.Recovery())
if setting.EnableGzip { if setting.EnableGzip {
m.Use(macaron.Gziper()) m.Use(macaron.Gziper())
@ -109,14 +112,14 @@ func newMacaron() *macaron.Macaron {
m.Use(macaron.Static( m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public"), path.Join(setting.StaticRootPath, "public"),
macaron.StaticOptions{ macaron.StaticOptions{
SkipLogging: !setting.DisableRouterLog, SkipLogging: setting.DisableRouterLog,
}, },
)) ))
m.Use(macaron.Static( m.Use(macaron.Static(
setting.AvatarUploadPath, setting.AvatarUploadPath,
macaron.StaticOptions{ macaron.StaticOptions{
Prefix: "avatars", Prefix: "avatars",
SkipLogging: !setting.DisableRouterLog, SkipLogging: setting.DisableRouterLog,
}, },
)) ))
m.Use(macaron.Renderer(macaron.RenderOptions{ m.Use(macaron.Renderer(macaron.RenderOptions{
@ -242,7 +245,7 @@ func runWeb(ctx *cli.Context) {
ctx.HandleAPI(404, "Page not found") ctx.HandleAPI(404, "Page not found")
}) })
}) })
}) }, ignSignIn)
// User. // User.
m.Group("/user", func() { m.Group("/user", func() {
@ -328,7 +331,7 @@ func runWeb(ctx *cli.Context) {
m.Get("/template/*", dev.TemplatePreview) m.Get("/template/*", dev.TemplatePreview)
} }
reqAdmin := middleware.RequireAdmin() reqRepoAdmin := middleware.RequireRepoAdmin()
// Organization. // Organization.
m.Group("/org", func() { m.Group("/org", func() {
@ -380,8 +383,8 @@ func runWeb(ctx *cli.Context) {
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost) m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
m.Get("/migrate", repo.Migrate) m.Get("/migrate", repo.Migrate)
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost) m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
m.Get("/fork", repo.Fork) m.Combo("/fork/:repoid").Get(repo.Fork).
m.Post("/fork", bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
}, reqSignIn) }, reqSignIn)
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
@ -402,8 +405,15 @@ func runWeb(ctx *cli.Context) {
m.Get("/:name", repo.GitHooksEdit) m.Get("/:name", repo.GitHooksEdit)
m.Post("/:name", repo.GitHooksEditPost) m.Post("/:name", repo.GitHooksEditPost)
}, middleware.GitHookService()) }, 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.Group("/:username/:reponame", func() {
m.Get("/action/:action", repo.Action) m.Get("/action/:action", repo.Action)
@ -416,15 +426,20 @@ func runWeb(ctx *cli.Context) {
m.Post("/:index/milestone", repo.UpdateIssueMilestone) m.Post("/:index/milestone", repo.UpdateIssueMilestone)
m.Post("/:index/assignee", repo.UpdateAssignee) m.Post("/:index/assignee", repo.UpdateAssignee)
m.Get("/:index/attachment/:id", repo.IssueGetAttachment) 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) m.Post("/comment/:action", repo.Comment)
@ -433,21 +448,19 @@ func runWeb(ctx *cli.Context) {
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost) m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
m.Get("/edit/:tagname", repo.EditRelease) m.Get("/edit/:tagname", repo.EditRelease)
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, middleware.RepoRef()) }, reqRepoAdmin, middleware.RepoRef())
}, reqSignIn, middleware.RepoAssignment(true)) }, reqSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Get("/releases", middleware.RepoRef(), repo.Releases) 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/: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("/pulls", repo.Pulls)
m.Get("/branches", repo.Branches) m.Get("/branches", repo.Branches)
m.Get("/archive/*", repo.Download) m.Get("/archive/*", repo.Download)
m.Get("/issues2/", repo.Issues2)
m.Get("/pulls2/", repo.PullRequest2) m.Get("/pulls2/", repo.PullRequest2)
m.Get("/labels2/", repo.Labels2)
m.Get("/milestone2/", repo.Milestones2)
m.Group("", func() { m.Group("", func() {
m.Get("/src/*", repo.Home) m.Get("/src/*", repo.Home)
@ -460,8 +473,15 @@ func runWeb(ctx *cli.Context) {
}, ignSignIn, middleware.RepoAssignment(true)) }, ignSignIn, middleware.RepoAssignment(true))
m.Group("/:username", func() { m.Group("/:username", func() {
m.Get("/:reponame", ignSignIn, middleware.RepoAssignment(true, true), middleware.RepoRef(), repo.Home) m.Group("/:reponame", func() {
m.Any("/:reponame/*", ignSignInAndCsrf, repo.Http) 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 // robots.txt

@ -12,6 +12,10 @@ RUN_MODE = dev
ROOT = ROOT =
SCRIPT_TYPE = bash SCRIPT_TYPE = bash
[ui]
; Number of issues that are showed in one page
ISSUE_PAGING_NUM = 10
[server] [server]
PROTOCOL = http PROTOCOL = http
DOMAIN = localhost DOMAIN = localhost
@ -87,8 +91,8 @@ ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
DISABLE_MINIMUM_KEY_SIZE_CHECK = false DISABLE_MINIMUM_KEY_SIZE_CHECK = false
[webhook] [webhook]
; Cron task interval in minutes ; Hook task queue length
TASK_INTERVAL = 1 QUEUE_LENGTH = 1000
; Deliver timeout in seconds ; Deliver timeout in seconds
DELIVER_TIMEOUT = 5 DELIVER_TIMEOUT = 5
; Allow insecure certification ; Allow insecure certification
@ -105,13 +109,17 @@ SUBJECT = %(APP_NAME)s
; QQ: smtp.qq.com:25 ; 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. ; 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 ; Do not verify the certificate of the server. Only use this for self-signed certificates
SKIP_VERIFY = SKIP_VERIFY =
; Use client certificate ; Use client certificate
USE_CERTIFICATE = false USE_CERTIFICATE = false
CERT_FILE = custom/mailer/cert.pem CERT_FILE = custom/mailer/cert.pem
KEY_FILE = custom/mailer/key.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 = FROM =
; Mailer user name and password ; Mailer user name and password
USER = USER =
@ -288,8 +296,25 @@ INTERVAL = 24
ARGS = ARGS =
[i18n] [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 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 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] [other]
SHOW_FOOTER_BRANDING = false 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. # Order of name is meaningless.
Akihiro YAGASAKI <yaggytter@momiage.com> Akihiro YAGASAKI <yaggytter@momiage.com>
Alexander Steinhöfer <kontakt@lx-s.de>
Christoph Kisfeld <christoph.kisfeld@gmail.com> Christoph Kisfeld <christoph.kisfeld@gmail.com>
Daniel Speichert <daniel@speichert.pl>
Huimin Wang <wanghm2009@hotmail.co.jp> Huimin Wang <wanghm2009@hotmail.co.jp>
ilko <email>
Thomas Fanninger <gogs.thomas@fanninger.at> Thomas Fanninger <gogs.thomas@fanninger.at>
Łukasz Jan Niemier <lukasz@niemier.pl> Łukasz Jan Niemier <lukasz@niemier.pl>
Lafriks <lafriks@gmail.com> Lafriks <lafriks@gmail.com>
Luc Stepniewski <luc@stepniewski.fr>
Miguel de la Cruz <miguel@mcrx.me> 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 cancel=Abbrechen
[search]
search=Suchen...
repository=Repository
user=Benutzer
issue=Problem
code=Code
[install] [install]
install=Installation install=Installation
title=Installation für erstmaligen Start 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. 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 db_type=Datenbanktyp
host=Host host=Host
user=Benutzer user=Benutzer
@ -52,7 +60,11 @@ db_helper=Bitte verwenden InnoDB-Engine mit utf8_general_ci Zeichensatz für MyS
ssl_mode=SSL-Modus ssl_mode=SSL-Modus
path=Pfad path=Pfad
sqlite_helper=Der Dateipfad des SQLite3 Datenbank. 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 general_title=Allgemeine Einstellungen von Gogs
app_name=Anwendungsname
app_name_helper=Hier den Organisationsnamen einfügen.
repo_path=Repository Root-Verzeichnispfad repo_path=Repository Root-Verzeichnispfad
repo_path_helper=Alle Git-Repositorys werden in diesem Verzeichnis gespeichert. repo_path_helper=Alle Git-Repositorys werden in diesem Verzeichnis gespeichert.
run_user=Ausführender Benutzer run_user=Ausführender Benutzer
@ -63,13 +75,24 @@ http_port=HTTP Port
http_port_helper=Auf dieser Port Nummer ist die Apllikation erreichbar. http_port_helper=Auf dieser Port Nummer ist die Apllikation erreichbar.
app_url=Anwendungs-URL app_url=Anwendungs-URL
app_url_helper=Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails. 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_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_user=Sender E-mail
mailer_password=Sender Passwort mailer_password=Sender Passwort
notify_title=Benachrichtigungseinstellungen (optional)
register_confirm=Registrierungsbestätigung aktvieren register_confirm=Registrierungsbestätigung aktvieren
mail_notify=E-Mail-Benachrichtgung aktivieren 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_title=Konto-Einstellungen für den Administrator
admin_name=Benutzername admin_name=Benutzername
admin_password=Passwort 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 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 save_config_failed=Versuche die Konfiguration zu speichern ist fehlgeschlagen: %v
invalid_admin_setting=Admin-Konto Einstellungen sind ungültig: %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] [home]
uname_holder=Benutzername oder E-Mail 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 reset_password_helper=Hier klicken, um das Passwort zurückzusetzen
password_too_short=Das Passwort muss mindenstens 6 Zeichen lang sein password_too_short=Das Passwort muss mindenstens 6 Zeichen lang sein
[modal]
yes=Ja
no=Nein
modify=Ändern
[form] [form]
UserName=Benutzername UserName=Benutzername
RepoName=Repository-Name RepoName=Repository-Name
@ -136,6 +164,7 @@ AdminEmail=Admin E-mail
require_error=` darf nicht leer sein.` require_error=` darf nicht leer sein.`
alpha_dash_error=` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.` alpha_dash_error=` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
alpha_dash_dot_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.` min_size_error=` muss mindestens %s Zeichen enthalten.`
max_size_error=` darf höchstens %s Zeichen enthalten.` max_size_error=` darf höchstens %s Zeichen enthalten.`
email_error=` ist keine gültige E-Mail-Adresse.` 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. team_name_been_taken=Teamname ist bereits vergeben.
email_been_used=E-Mail-Adresse wird bereits verwendet. email_been_used=E-Mail-Adresse wird bereits verwendet.
ssh_key_been_used=SSH-Schlüsselname 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. illegal_team_name=Teamname enthält ungültige Zeichen.
username_password_incorrect=Benutzername oder Passwort ist nicht korrekt. 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_repo_name=Bitte stelle sicher, dass der eingegebene Repository-Name richtig ist.
enterred_invalid_owner_name=Bitte stelle sicher, dass der eingegeben Besitzername 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. enterred_invalid_password=Bitte stelle sicher, dass das eingegebene Passwort richtig ist.
user_not_exist=Angegebener Benutzer existiert nicht. 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 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. 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 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. 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. 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 target_branch_not_exist=Ziel-Branch existiert nicht
@ -183,6 +209,9 @@ followers=Folgen
starred=Markiert starred=Markiert
following=Folgt following=Folgt
form.name_reserved=Der Benutzername '%s' ist reserviert.
form.name_pattern_not_allowed=Benutzernamens-Muster "%s" ist nicht zulässig.
[settings] [settings]
profile=Profil profile=Profil
password=Passwort password=Passwort
@ -227,6 +256,7 @@ primary_email=Als primäre Adresse verwenden
delete_email=Löschen delete_email=Löschen
add_new_email=Neue E-Mail-Adresse hinzufügen add_new_email=Neue E-Mail-Adresse hinzufügen
add_email=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. add_email_success=Deine neue E-Mail-Adresse wurde erfolgreich hinzugefügt.
manage_ssh_keys=SSH-Schlüssel verwalten manage_ssh_keys=SSH-Schlüssel verwalten
@ -282,6 +312,9 @@ create_repo=Repository erstellen
default_branch=Standard-Branch default_branch=Standard-Branch
mirror_interval=Spiegel-Intervall (in Stunden) 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 need_auth=Authorisierung benötigt
migrate_type=Migrationstyp migrate_type=Migrationstyp
migrate_type_helper=Dieses Repository wird ein <span class="label label-blue label-radius">Spiegel</span> 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.clone_address=Adresse kopieren
migrate.invalid_local_path=Lokaler Pfad ist ungültig, er existiert nicht oder ist kein Ordner. 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 copy_link=Kopieren
click_to_copy=In Zwischenablage kopieren click_to_copy=In Zwischenablage kopieren
copied=Kopiert OK copied=Kopiert OK
@ -311,11 +346,14 @@ branch_and_tags=Branches & Tags
branches=Branches branches=Branches
tags=Markierungen tags=Markierungen
issues=Issues issues=Issues
labels=Label
milestones=Meilensteine
commits=Commits commits=Commits
releases=Veröffentlichungen releases=Veröffentlichungen
file_raw=Roh file_raw=Roh
file_history=Verlauf file_history=Verlauf
file_view_raw=Ansicht Roh file_view_raw=Ansicht Roh
file_permalink=Permalink
commits.commits=Commits commits.commits=Commits
commits.search=Durchsuche Commits commits.search=Durchsuche Commits
@ -326,6 +364,34 @@ commits.date=Datum
commits.older=Älter commits.older=Älter
commits.newer=Neuer 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=Einstellungen
settings.options=Optionen settings.options=Optionen
settings.collaboration=Zusammenarbeit settings.collaboration=Zusammenarbeit
@ -339,7 +405,7 @@ settings.update_settings=Aktualisierungseinstellungen
settings.change_reponame=Name des Repositories geändert 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.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=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.new_owner_has_same_repo=Neuer Eigentümer hat bereits ein Repository mit dem gleichen Namen.
settings.delete=Repository löschen settings.delete=Repository löschen
settings.delete_desc=Wenn dieses Repository gelöscht ist, gibt es keinen Weg zurück. Sei dir sicher! settings.delete_desc=Wenn dieses Repository gelöscht ist, gibt es keinen Weg zurück. Sei dir sicher!
@ -354,14 +420,14 @@ settings.add_collaborator_success=Mitarbeiter hinzugefügt
settings.remove_collaborator_success=Mitarbeiter entfernt settings.remove_collaborator_success=Mitarbeiter entfernt
settings.user_is_org_member=Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden. settings.user_is_org_member=Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
settings.add_webhook=Webhook hinzufügen 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.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_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_name=Hook-Name
settings.githook_content=Hook-Inhalt settings.githook_content=Hook-Inhalt
settings.update_githook=Aktualisiere Hook settings.update_githook=Aktualisiere Hook
settings.remove_hook_success=Webhook entfernt 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.payload_url=Payload-URL
settings.content_type=Inhaltstyp settings.content_type=Inhaltstyp
settings.secret=Secret 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_desc_helper=Was hat es mit diesem Team auf sich?
team_permission_desc=Welche Berechtigungsstufe soll das Team haben? 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=Einstellungen
settings.options=Optionen settings.options=Optionen
settings.full_name=Vollständiger Name 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.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=Führe Garbage Collection auf Repositories aus
dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt. 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_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=Ü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. 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.allow_git_hook=Dieses Konto ist berechtigt, Git-Hooks zu erstellen
users.update_profile=Kontoprofil aktualisieren users.update_profile=Kontoprofil aktualisieren
users.delete_account=Dieses Konto löschen 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. users.still_has_org=Dieses Konto ist noch Mitglied einer Organisation, bitte entferne diese Mitgliedschaft zuerst.
orgs.org_manage_panel=Organisationenverwaltung orgs.org_manage_panel=Organisationenverwaltung
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP-Authentifizierungstyp
auths.smtphost=SMTP-Host auths.smtphost=SMTP-Host
auths.smtpport=SMTP-Port auths.smtpport=SMTP-Port
auths.enable_tls=TLS-Verschlüsselung aktivieren auths.enable_tls=TLS-Verschlüsselung aktivieren
auths.pam_service_name=PAM Dienstname
auths.enable_auto_register=Automatische Registrierung aktivieren auths.enable_auto_register=Automatische Registrierung aktivieren
auths.tips=Tipps auths.tips=Tipps
auths.edit=Authentifizierungseinstellungen bearbeiten auths.edit=Authentifizierungseinstellungen bearbeiten
@ -653,6 +723,7 @@ config.deliver_timeout=Zeitlimit für Zustellung
config.skip_tls_verify=TLS verifikation überspringen config.skip_tls_verify=TLS verifikation überspringen
config.mailer_config=Mailer-Einstellungen config.mailer_config=Mailer-Einstellungen
config.mailer_enabled=Aktiviert config.mailer_enabled=Aktiviert
config.mailer_disable_helo=HELO Deaktivieren
config.mailer_name=Name config.mailer_name=Name
config.mailer_host=Host config.mailer_host=Host
config.mailer_user=Benutzer config.mailer_user=Benutzer

@ -50,6 +50,7 @@ code = Code
install = Installation install = Installation
title = Install Steps For First-time Run title = Install Steps For First-time Run
requite_db_desc = Gogs requires MySQL, PostgreSQL or SQLite3. requite_db_desc = Gogs requires MySQL, PostgreSQL or SQLite3.
db_title = Database Settings
db_type = Database Type db_type = Database Type
host = Host host = Host
user = User user = User
@ -59,7 +60,11 @@ db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL.
ssl_mode = SSL Mode ssl_mode = SSL Mode
path = Path path = Path
sqlite_helper = The file path of SQLite3 database. 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 = Repository Root Path
repo_path_helper = All Git remote repositories will be saved to this directory. repo_path_helper = All Git remote repositories will be saved to this directory.
run_user = Run User run_user = Run User
@ -70,13 +75,24 @@ http_port = HTTP Port
http_port_helper = Port number which application will listen on. http_port_helper = Port number which application will listen on.
app_url = Application URL app_url = Application URL
app_url_helper = This affects HTTP/HTTPS clone URL and somewhere in e-mail. 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_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_user = Sender E-mail
mailer_password = Sender Password mailer_password = Sender Password
notify_title = Notification Settings (Optional)
register_confirm = Enable Register Confirmation register_confirm = Enable Register Confirmation
mail_notify = Enable Mail Notification 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_title = Admin Account Settings
admin_name = Username admin_name = Username
admin_password = Password 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 reset_password_helper = Click here to reset your password
password_too_short = Password length cannot be less then 6. password_too_short = Password length cannot be less then 6.
[modal]
yes = Yes
no = No
modify = Modify
[form] [form]
UserName = Username UserName = Username
RepoName = Repository name RepoName = Repository name
@ -143,6 +164,7 @@ AdminEmail = Admin E-mail
require_error = ` cannot be empty.` require_error = ` cannot be empty.`
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.` 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.` 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.` min_size_error = ` must contain at least %s characters.`
max_size_error = ` must contain at most %s characters.` max_size_error = ` must contain at most %s characters.`
email_error = ` is not a valid e-mail address.` 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. org_name_been_taken = Organization name has been already taken.
team_name_been_taken = Team 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. 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. illegal_team_name = Team name contains illegal characters.
username_password_incorrect = Username or password is not correct. username_password_incorrect = Username or password is not correct.
enterred_invalid_repo_name = Please make sure that the repository name you entered is correct. enterred_invalid_repo_name = Please make sure that the repository name you entered is correct.
@ -190,6 +208,9 @@ followers = Followers
starred = Starred starred = Starred
following = Following following = Following
form.name_reserved = Username '%s' is reserved.
form.name_pattern_not_allowed = Username pattern '%s' is not allowed.
[settings] [settings]
profile = Profile profile = Profile
password = Password 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_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. 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 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_name = Key Name
key_content = Content 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 delete_key = Delete
add_on = Added on add_on = Added on
last_used = Last used on last_used = Last used on
no_activity = No recent activity no_activity = No recent activity
key_state_desc = This key is used in last 7 days
manage_social = Manage Associated Social Accounts manage_social = Manage Associated Social Accounts
social_desc = This is a list of associated social accounts. Remove any binding that you do not recognize. 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 = Repository Name
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords. repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
visibility = Visibility 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_repo = Fork Repository
fork_from = Fork From fork_from = Fork From
fork_visiblity_helper = You cannot alter the visibility of a forked repository. fork_visiblity_helper = You cannot alter the visibility of a forked repository.
@ -290,6 +314,9 @@ create_repo = Create Repository
default_branch = Default Branch default_branch = Default Branch
mirror_interval = Mirror Interval (hour) 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 need_auth = Need Authorization
migrate_type = Migration Type migrate_type = Migration Type
migrate_type_helper = This repository will be a <span class="label label-blue label-radius">mirror</span> 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.clone_address = Clone Address
migrate.invalid_local_path = Invalid local path, it does not exist or not a directory. 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 copy_link = Copy
click_to_copy = Copy to clipboard click_to_copy = Copy to clipboard
copied = Copied OK copied = Copied OK
@ -319,11 +348,14 @@ branch_and_tags = Branches & Tags
branches = Branches branches = Branches
tags = Tags tags = Tags
issues = Issues issues = Issues
labels = Labels
milestones = Milestones
commits = Commits commits = Commits
releases = Releases releases = Releases
file_raw = Raw file_raw = Raw
file_history = History file_history = History
file_view_raw = View Raw file_view_raw = View Raw
file_permalink = Permalink
commits.commits = Commits commits.commits = Commits
commits.search = Search commits commits.search = Search commits
@ -334,12 +366,64 @@ commits.date = Date
commits.older = Older commits.older = Older
commits.newer = Newer 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 = Settings
settings.options = Options settings.options = Options
settings.collaboration = Collaboration settings.collaboration = Collaboration
settings.hooks = Webhooks settings.hooks = Webhooks
settings.githooks = Git Hooks settings.githooks = Git Hooks
settings.deploy_keys = Deploy Keys
settings.basic_settings = Basic Settings settings.basic_settings = Basic Settings
settings.danger_zone = Danger Zone settings.danger_zone = Danger Zone
settings.site = Official Site 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_token = Token
settings.slack_domain = Domain settings.slack_domain = Domain
settings.slack_channel = Channel 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.browse_source = Browse Source
diff.parent = parent 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_desc_helper = What is this team all about?
team_permission_desc = What permission level should this team have? 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 = Settings
settings.options = Options settings.options = Options
settings.full_name = Full Name settings.full_name = Full Name
@ -449,7 +547,7 @@ settings.update_settings = Update Settings
settings.change_orgname = Organization Name Changed 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.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.update_setting_success = Organization settings were successfully updated.
settings.delete = Delete Organization settings.delete = Delete Organization
settings.delete_account = Delete This Organization settings.delete_account = Delete This Organization
settings.delete_prompt = The organization will be permanently removed, and this <strong>CANNOT</strong> be undone! settings.delete_prompt = The organization will be permanently removed, and this <strong>CANNOT</strong> be undone!
settings.confirm_delete_account = Confirm Deletion 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.delete_repo_archives_success = All repositories archives have been deleted successfully.
dashboard.git_gc_repos = Do garbage collection on repositories dashboard.git_gc_repos = Do garbage collection on repositories
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully. 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_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 = 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.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.smtphost = SMTP Host
auths.smtpport = SMTP Port auths.smtpport = SMTP Port
auths.enable_tls = Enable TLS Encryption auths.enable_tls = Enable TLS Encryption
auths.pam_service_name = PAM Service Name
auths.enable_auto_register = Enable Auto Registration auths.enable_auto_register = Enable Auto Registration
auths.tips = Tips auths.tips = Tips
auths.edit = Edit Authorization Setting auths.edit = Edit Authorization Setting
@ -656,11 +755,12 @@ config.enable_cache_avatar = Enable Cache Avatar
config.active_code_lives = Active Code Lives config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Reset Password Code Lives config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook Configuration config.webhook_config = Webhook Configuration
config.task_interval = Task Interval config.queue_length = Queue Length
config.deliver_timeout = Deliver Timeout config.deliver_timeout = Deliver Timeout
config.skip_tls_verify = Skip TLS Verify config.skip_tls_verify = Skip TLS Verify
config.mailer_config = Mailer Configuration config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled config.mailer_enabled = Enabled
config.mailer_disable_helo = Disable HELO
config.mailer_name = Name config.mailer_name = Name
config.mailer_host = Host config.mailer_host = Host
config.mailer_user = User config.mailer_user = User

@ -39,10 +39,18 @@ issues=Publicaciones
cancel=Cancelar cancel=Cancelar
[search]
search=Buscar...
repository=Repositorio
user=Usuario
issue=Incidencia
code=Código
[install] [install]
install=Instalación install=Instalación
title=Pasos de la instalación por primera vez title=Pasos de la instalación por primera vez
requite_db_desc=Gogs necesita MySQL, PostgreSQL o SQLite3. requite_db_desc=Gogs necesita MySQL, PostgreSQL o SQLite3.
db_title=Configuración de base de datos
db_type=Tipo de base de datos db_type=Tipo de base de datos
host=Anfitrión host=Anfitrión
user=Usuario user=Usuario
@ -52,7 +60,11 @@ db_helper=Por favor utilice el motor INNODB con la configuración de caracteres
ssl_mode=Modo SSL ssl_mode=Modo SSL
path=Ruta path=Ruta
sqlite_helper=Ruta del archivo de la base de datos de SQLite3. 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=Ruta del repositorio de Raiz (Root)
repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio. repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio.
run_user=Abrir el usuario run_user=Abrir el usuario
@ -63,13 +75,24 @@ http_port=Puerto HTTP
http_port_helper=Puerto en el que escuchará la aplicación. http_port_helper=Puerto en el que escuchará la aplicación.
app_url=URL de 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. 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_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_user=Remitente del Correo Electrónico
mailer_password=Contraseña del Remitente mailer_password=Contraseña del Remitente
notify_title=Configuración de Notificaciones (Opcional)
register_confirm=Habilitar la Confirmación en el Registro register_confirm=Habilitar la Confirmación en el Registro
mail_notify=Habilitar las Notificaciones de Correo 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_title=Configuración de la Cuenta de Administrador
admin_name=Nombre de usuario admin_name=Nombre de usuario
admin_password=Contraseña 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. 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. 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 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 send_reset_mail=Haga clic aquí para (re)enviar el correo para el restablecimiento de la contraseña
reset_password=Restablecer su contraseña reset_password=Restablecer su contraseña
invalid_code=Lo sentimos, su código de confirmación ha expirado o no es valido. 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 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. password_too_short=La longitud de la contraseña no puede ser menor a 6.
[modal]
yes=
no=No
modify=Editar
[form] [form]
UserName=Nombre de usuario UserName=Nombre de usuario
RepoName=Nombre del repositorio RepoName=Nombre del repositorio
@ -136,6 +164,7 @@ AdminEmail=Correo electrónico del administrador
require_error=` no puede estar vacío.` require_error=` no puede estar vacío.`
alpha_dash_error=` los caracteres deben ser Alfanumericos o dash(-_).` 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.` 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.` min_size_error=` debe contener al menos %s caracteres.`
max_size_error=` debe contener como máximo %s caracteres.` max_size_error=` debe contener como máximo %s caracteres.`
email_error=` no es una dirección de correo válida.` 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. 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. 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. 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. illegal_team_name=El nombre del equipo contiene caracteres inválidos.
username_password_incorrect=Nombre de usuario o contraseña incorrectos. 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. 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 starred=Destacados
following=Siguiendo 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] [settings]
profile=Perfil profile=Perfil
password=Contraseña password=Contraseña
@ -227,6 +256,7 @@ primary_email=Marcar como principal
delete_email=Eliminar delete_email=Eliminar
add_new_email=Añadir nueva dirección de correo electrónico add_new_email=Añadir nueva dirección de correo electrónico
add_email=Añadir 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. add_email_success=Tu nuevo correo electrónico se ha añadido correctamente.
manage_ssh_keys=Gestionar Claves SSH manage_ssh_keys=Gestionar Claves SSH
@ -282,6 +312,9 @@ create_repo=Crear Repositorio
default_branch=Rama por defecto default_branch=Rama por defecto
mirror_interval=Intervalo de mirror(en horas) 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 need_auth=Requiere Autorización
migrate_type=Tipo de Migración migrate_type=Tipo de Migración
migrate_type_helper=Este repositorio será un <span class="label label-blue label-radius">Mirror</span> 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.clone_address=Clonar Dirección
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio. 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 copy_link=Copiar
click_to_copy=Copiar al portapapeles click_to_copy=Copiar al portapapeles
copied=Copiado correctamente copied=Copiado correctamente
@ -311,11 +346,14 @@ branch_and_tags=Ramas y Etiquetas
branches=Ramas branches=Ramas
tags=Etiquetas tags=Etiquetas
issues=Incidencias issues=Incidencias
labels=Etiquetas
milestones=Milestones
commits=Commits commits=Commits
releases=Releases releases=Releases
file_raw=Raw file_raw=Raw
file_history=Histórico file_history=Histórico
file_view_raw=Ver Raw file_view_raw=Ver Raw
file_permalink=Permalink
commits.commits=Commits commits.commits=Commits
commits.search=Buscar Commits commits.search=Buscar Commits
@ -326,6 +364,34 @@ commits.date=Fecha
commits.older=Anterior commits.older=Anterior
commits.newer=Posterior 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=Configuración
settings.options=Opciones settings.options=Opciones
settings.collaboration=Colaboración 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_desc_helper=¿En qué consiste este equipo?
team_permission_desc=¿Qué nivel de permisos debería tener 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=Configuración
settings.options=Opciones settings.options=Opciones
settings.full_name=Nombre Completo 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.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=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.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_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=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. 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.smtphost=SMTP Host
auths.smtpport=Puerto SMTP auths.smtpport=Puerto SMTP
auths.enable_tls=Habilitar Cifrado TLS auths.enable_tls=Habilitar Cifrado TLS
auths.pam_service_name=Nombre del Servicio PAM
auths.enable_auto_register=Hablilitar Auto-Registro auths.enable_auto_register=Hablilitar Auto-Registro
auths.tips=Consejos auths.tips=Consejos
auths.edit=Editar la Configuración de Autorización 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.skip_tls_verify=Omitir la Verificación TLS
config.mailer_config=Configuración del Mailer config.mailer_config=Configuración del Mailer
config.mailer_enabled=Activado config.mailer_enabled=Activado
config.mailer_disable_helo=Desactivar HELO
config.mailer_name=Nombre config.mailer_name=Nombre
config.mailer_host=Host config.mailer_host=Host
config.mailer_user=Usuario config.mailer_user=Usuario

@ -39,10 +39,18 @@ issues=Problèmes
cancel=Annuler cancel=Annuler
[search]
search=Rechercher...
repository=Référentiel
user=Utilisateur
issue=Problème
code=Code
[install] [install]
install=Installation install=Installation
title=Instructions de Première Installation title=Instructions de Première Installation
requite_db_desc=Gogs nécessite MySQL, PostgreSQL ou SQLite3. 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 db_type=Type de Base de Données
host=Hôte host=Hôte
user=Utilisateur 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 ssl_mode=Mode SSL
path=Chemin path=Chemin
sqlite_helper=Emplacement du fichier de la base de données SQLite3. 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 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=Emplacement Racine du Référentiel
repo_path_helper=Tous les Référentiels Git distants seront sauvegardés ici. repo_path_helper=Tous les Référentiels Git distants seront sauvegardés ici.
run_user=Entrer un Utilisateur run_user=Entrer un Utilisateur
@ -63,13 +75,24 @@ http_port=Port HTTP
http_port_helper=Numéro de port que l'application écoutera. http_port_helper=Numéro de port que l'application écoutera.
app_url=URL de l'Application app_url=URL de l'Application
app_url_helper=Cela affecte les doublons d'URL HTTP/HTTPS et le contenu d'e-mail. 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_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_user=E-mail de l'Expéditeur
mailer_password=Mot de Passe 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 register_confirm=Activer la Confirmation d'Enregistrement
mail_notify=Activer la Notification des Mails reçus 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_title=Paramètres du Compte Administrateur
admin_name=Nom d'Utilisateur admin_name=Nom d'Utilisateur
admin_password=Mot de Passe admin_password=Mot de Passe
@ -112,14 +135,19 @@ sign_in_email=Connexion avec l'E-mail
active_your_account=Activer votre Compte 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. 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. 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. 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 reset_password=Réinitialiser le Mot de Passe
invalid_code=Désolé, code de confirmation invalide ou expiré. 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. password_too_short=Le mot de passe doit contenir 6 caractères minimum.
[modal]
yes=Oui
no=Non
modify=Modifier
[form] [form]
UserName=Nom d'Utilisateur UserName=Nom d'Utilisateur
RepoName=Nom du Référentiel RepoName=Nom du Référentiel
@ -131,11 +159,12 @@ HttpsUrl=URL HTTPS
PayloadUrl=URL des Données Utiles PayloadUrl=URL des Données Utiles
TeamName=Nom d'équipe TeamName=Nom d'équipe
AuthName=Nom d'autorisation AuthName=Nom d'autorisation
AdminEmail=E-mail d'admin AdminEmail=E-mail de l'administrateur
require_error=` Ne peut être vide ` require_error=` Ne peut être vide `
alpha_dash_error=` doivent être des caractères alpha, numeriques ou console (-_) valides ` 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 ` 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 ` min_size_error=` %s caractères minimum `
max_size_error=` %s caractères maximum ` max_size_error=` %s caractères maximum `
email_error=` adresse e-mail invalide ` 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. team_name_been_taken=Nom d'équipe déjà pris.
email_been_used=Adresse e-mail déjà utilisée. email_been_used=Adresse e-mail déjà utilisée.
ssh_key_been_used=Le nom de la clé publique a déjà servi. 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. illegal_team_name=Le nom de l'équipe contient des caractères interdits.
username_password_incorrect=Nom d'utilisateur ou mot de passe incorrect. 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. 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. 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 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_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 a toujours membres de l'organisation, vous avez à gauche ou supprimez tout d'abord. 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. 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. 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] [user]
change_avatar=Changez d'avatar via gravatar.com 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 join_on=Adhéré le
repositories=Référentiels repositories=Référentiels
activity=Activités publiques activity=Activités publiques
@ -183,6 +209,9 @@ followers=Abonnés
starred=Votés starred=Votés
following=Abonnements 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] [settings]
profile=Profil profile=Profil
password=Mot de Passe password=Mot de Passe
@ -205,13 +234,13 @@ change_username_desc=Nom d'utilisateur modifié. Cela affecte tous les liens rel
continue=Continuer continue=Continuer
cancel=Annuler 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 enable_custom_avatar_helper=Cette option désactive l'affichage via Gravatar
choose_new_avatar=Choisir nouvelle vignette choose_new_avatar=Sélectionner un nouvel avatar
update_avatar=Réglage de mise à jour de vignette update_avatar=Mettre l'Avatar à Jour
uploaded_avatar_not_a_image=Le fichier téléchargé n'est pas une image. 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. 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 change_password=Modifier le Mot de Passe
old_password=Mot de Passe actuel old_password=Mot de Passe actuel
@ -227,6 +256,7 @@ primary_email=Définir comme principale
delete_email=Supprimer delete_email=Supprimer
add_new_email=Ajouter une nouvelle adresse courriel add_new_email=Ajouter une nouvelle adresse courriel
add_email=Ajouter un 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. add_email_success=Votre courriel a été ajouté avec succès.
manage_ssh_keys=Gérer les clés SSH 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=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 ! 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=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_account=Supprimer le Compte
delete_prompt=Votre compte sera supprimé définitivement et cette opération est <strong>IRRÉVERSIBLE</strong> ! 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] [repo]
owner=Propriétaire owner=Propriétaire
repo_name=Nom du Référentiel 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é visibility=Visibilité
visiblity_helper=Ce Référentiel est <span class="label label-red label-radius">Privé</span> visiblity_helper=Ce Référentiel est <span class="label label-red label-radius">Privé</span>
fork_repo=Référentiel d'Embranchement fork_repo=Référentiel d'Embranchement
fork_from=Embranchement de 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_desc=Description
repo_lang=Langue repo_lang=Langue
repo_lang_helper=Sélectionner un fichier .gitignore 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 default_branch=Branche par défaut
mirror_interval=Intervalle du miroir (heure) 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 need_auth=Nécessite une Autorisation
migrate_type=Type de Migration 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_repo=Migrer le Référentiel
migrate.clone_address=Adresse du clone migrate.clone_address=Adresse du clone
migrate.invalid_local_path=Chemin local non valide, non existant ou n'étant pas un dossier. 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 copy_link=Copier
click_to_copy=Copier dans le presse-papier click_to_copy=Copier dans le presse-papiers
copied=Copié copied=Copié
clone_helper=Besoin d'aide pour le clonage ? Visitez <a target="_blank" href="%s"> l'aider</a> ! clone_helper=Besoin d'aide pour le clonage ? Visitez <a target="_blank" href="%s"> l'aider</a> !
unwatch=Ne plus suivre unwatch=Ne plus suivre
@ -311,11 +346,14 @@ branch_and_tags=Branches & Tags
branches=Branches branches=Branches
tags=Tags tags=Tags
issues=Problèmes issues=Problèmes
labels=Etiquettes
milestones=Étapes
commits=Commissions commits=Commissions
releases=Publications releases=Publications
file_raw=Raw file_raw=Raw
file_history=Historique file_history=Historique
file_view_raw=Voir le Raw file_view_raw=Voir le Raw
file_permalink=Lien permanent
commits.commits=Commissions commits.commits=Commissions
commits.search=Rechercher des commissions commits.search=Rechercher des commissions
@ -326,6 +364,34 @@ commits.date=Date
commits.older=Précédemment commits.older=Précédemment
commits.newer=Récemment 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=Paramètres
settings.options=Options settings.options=Options
settings.collaboration=Collaboration settings.collaboration=Collaboration
@ -337,10 +403,10 @@ settings.danger_zone=Zone de danger
settings.site=Site officiel settings.site=Site officiel
settings.update_settings=Valider settings.update_settings=Valider
settings.change_reponame=Référentiel renommé 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=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.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 Référentiel nommé ainsi. 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=Supprimer ce Référentiel
settings.delete_desc=Attention, action irréversible. Soyez sûre de vous. 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> 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_desc_helper=Présentation de l'équipe
team_permission_desc=Quel niveau d'accès cette équipe devrait-elle posséder ? 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=Paramètres
settings.options=Options settings.options=Options
settings.full_name=Non Complet settings.full_name=Non Complet
@ -477,7 +546,7 @@ teams.update_settings=Valider
teams.delete_team=Supprimer cette Équipe teams.delete_team=Supprimer cette Équipe
teams.add_team_member=Ajouter un Membre teams.add_team_member=Ajouter un Membre
teams.delete_team_title=Suppression de l'équipe 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.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.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. 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=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.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=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.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_key' (attention : les clés hors-Gogs vont être perdues) 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_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=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.server_uptime=Durée de Marche Serveur
dashboard.current_goroutine=Goroutines actuelles dashboard.current_goroutine=Goroutines actuelles
@ -554,7 +623,7 @@ users.new_account=Créer un nouveau compte
users.name=Nom users.name=Nom
users.activated=Activés users.activated=Activés
users.admin=Administrateur users.admin=Administrateur
users.repos=Repos users.repos=Dépôts
users.created=Créés users.created=Créés
users.edit=Éditer users.edit=Éditer
users.auth_source=Source d'Autorisation 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.allow_git_hook=Ce compte dispose des autorisations pour créer des crochets de Git
users.update_profile=Mettre le profil à jour users.update_profile=Mettre le profil à jour
users.delete_account=Supprimer ce Compte 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. 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 orgs.org_manage_panel=Gestion des Organisations
@ -605,6 +674,7 @@ auths.smtp_auth=Type d'Autorisation SMTP
auths.smtphost=Hôte SMTP auths.smtphost=Hôte SMTP
auths.smtpport=Port SMTP auths.smtpport=Port SMTP
auths.enable_tls=Activer le Chiffrement TLS auths.enable_tls=Activer le Chiffrement TLS
auths.pam_service_name=Nom du Service PAM
auths.enable_auto_register=Connexion Automatique auths.enable_auto_register=Connexion Automatique
auths.tips=Conseils auths.tips=Conseils
auths.edit=Modifier les Paramètres d'Autorisation 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.active_code_lives=Limites de Code Actif
config.reset_password_code_lives=Réinitialiser le Mot De Passe des Limites de Code config.reset_password_code_lives=Réinitialiser le Mot De Passe des Limites de Code
config.webhook_config=Configuration Webhook 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.deliver_timeout=Expiration d'Envoi
config.skip_tls_verify=Ne pas vérifier TLS config.skip_tls_verify=Ne pas vérifier TLS
config.mailer_config=Configuration du Maileur config.mailer_config=Configuration du Maileur
config.mailer_enabled=Activé config.mailer_enabled=Activé
config.mailer_disable_helo=Désactiver HELO
config.mailer_name=Nom config.mailer_name=Nom
config.mailer_host=Hôte config.mailer_host=Hôte
config.mailer_user=Utilisateur config.mailer_user=Utilisateur
@ -692,7 +763,7 @@ notices.system_notice_list=Notes Systèmes
notices.type=Type notices.type=Type
notices.type_1=Référentiel notices.type_1=Référentiel
notices.desc=Description notices.desc=Description
notices.op=Auteur notices.op=Opération
notices.delete_success=Note système supprimée avec succès. notices.delete_success=Note système supprimée avec succès.
[action] [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=ホーム home=ホーム
dashboard=ダッシュボード dashboard=ダッシュボード
@ -39,10 +39,18 @@ issues=課題
cancel=キャンセル cancel=キャンセル
[search]
search=検索...
repository=リポジトリ
user=ユーザ
issue=課題
code=コード
[install] [install]
install=インストール install=インストール
title=初回実行のインストール手順 title=初回実行のインストール手順
requite_db_desc=Gogs には、MySQL や PostgreSQL 、SQLite3 が必要です。 requite_db_desc=Gogs には、MySQL や PostgreSQL 、SQLite3 が必要です。
db_title=データベース設定
db_type=データベースの種類 db_type=データベースの種類
host=ホスト host=ホスト
user=ユーザ user=ユーザ
@ -52,7 +60,11 @@ db_helper=Mysql INNODB エンジン utf8_general_ci の文字セットを使用
ssl_mode=SSL モード ssl_mode=SSL モード
path=パス path=パス
sqlite_helper=SQLite3 データベースのファイル パス sqlite_helper=SQLite3 データベースのファイル パス
err_empty_sqlite_path=SQLite3 データベースのパスは、空にすることはできません。
general_title=Gogs の全般設定 general_title=Gogs の全般設定
app_name=アプリケーション名
app_name_helper=素晴らしい組織名を入れてください!
repo_path=リポジトリのルートパス repo_path=リポジトリのルートパス
repo_path_helper=すべての Git リモート リポジトリはこのディレクトリに保存されます。 repo_path_helper=すべての Git リモート リポジトリはこのディレクトリに保存されます。
run_user=実行ユーザ run_user=実行ユーザ
@ -63,13 +75,24 @@ http_port=HTTP ポート
http_port_helper=アプリケーションが待ち受けするポート番号。 http_port_helper=アプリケーションが待ち受けするポート番号。
app_url=アプリケーションの URL app_url=アプリケーションの URL
app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。 app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。
email_title=E-mailサービス設定(Optional)
optional_title=オプション設定
email_title=E-mailサービス設定
smtp_host=SMTP ホスト smtp_host=SMTP ホスト
smtp_from=差出人
smtp_from_helper=送信者メールアドレス、RFC 5322。フォーマットはメールアドレスのみ、または"Name" <email@example.com>。
mailer_user=送信者の電子メール mailer_user=送信者の電子メール
mailer_password=送信者のパスワード mailer_password=送信者のパスワード
notify_title=通知 Settings(Optional)
register_confirm=登録の確認を有効にする register_confirm=登録の確認を有効にする
mail_notify=メール通知を有効にする 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_title=管理者アカウントの設定
admin_name=ユーザ名 admin_name=ユーザ名
admin_password=パスワード admin_password=パスワード
@ -120,6 +143,11 @@ invalid_code=申し訳ありませんが、確認用コードが期限切れま
reset_password_helper=パスワードをリセットするにはここをクリック reset_password_helper=パスワードをリセットするにはここをクリック
password_too_short=6文字未満のパスワードは設定できません。 password_too_short=6文字未満のパスワードは設定できません。
[modal]
yes=はい
no=いいえ
modify=変更
[form] [form]
UserName=ユーザ名 UserName=ユーザ名
RepoName=リポジトリ名 RepoName=リポジトリ名
@ -136,6 +164,7 @@ AdminEmail=管理者の電子メール
require_error=空にできません require_error=空にできません
alpha_dash_error=アルファベット、数字、ハイフン"-"、アンダースコア"_"のいずれかの必要があります alpha_dash_error=アルファベット、数字、ハイフン"-"、アンダースコア"_"のいずれかの必要があります
alpha_dash_dot_error=' アルファベット、数値、ダッシュ(-)、アンダースコア(_) 、ドット(.)のいずれかを入力する必要があります。 ' alpha_dash_dot_error=' アルファベット、数値、ダッシュ(-)、アンダースコア(_) 、ドット(.)のいずれかを入力する必要があります。 '
size_error=`サイズは %s である必要があります`
min_size_error=' 少なくとも %s 文字の必要があります ' min_size_error=' 少なくとも %s 文字の必要があります '
max_size_error=' %s 文字以下の必要があります ' max_size_error=' %s 文字以下の必要があります '
email_error=' は有効な電子メール アドレスではない ' email_error=' は有効な電子メール アドレスではない '
@ -150,9 +179,6 @@ org_name_been_taken=組織名は既に使用されています。
team_name_been_taken=チーム名は既に使用されています。 team_name_been_taken=チーム名は既に使用されています。
email_been_used=電子メール アドレスは既に使用されています。 email_been_used=電子メール アドレスは既に使用されています。
ssh_key_been_used=パブリック キー名が使用されています。 ssh_key_been_used=パブリック キー名が使用されています。
illegal_username=あなたのユーザ名に無効な文字が含まれます。
illegal_repo_name=リポジトリ名には無効な文字が含まれています。
illegal_org_name=組織名に無効な文字が含まれています。
illegal_team_name=チーム名に無効な文字が含まれています。 illegal_team_name=チーム名に無効な文字が含まれています。
username_password_incorrect=ユーザー名またはパスワードが正しくありません。 username_password_incorrect=ユーザー名またはパスワードが正しくありません。
enterred_invalid_repo_name=入力したリポジトリの名前が正しいかどうかを確認してください。 enterred_invalid_repo_name=入力したリポジトリの名前が正しいかどうかを確認してください。
@ -183,6 +209,9 @@ followers=フォロワー
starred=スター starred=スター
following=フォロー following=フォロー
form.name_reserved=ユーザー名 '%s' は予約されています。
form.name_pattern_not_allowed=ユーザ名のパターン '%s' は許可されていません。
[settings] [settings]
profile=プロフィール profile=プロフィール
password=パスワード password=パスワード
@ -227,6 +256,7 @@ primary_email=プライマリに設定
delete_email=削除 delete_email=削除
add_new_email=新しいe-mailアドレスを追加 add_new_email=新しいe-mailアドレスを追加
add_email=電子メールを追加します。 add_email=電子メールを追加します。
add_email_confirmation_sent=<b>%s</b> に新しい確認メールを送信しました、次の %d 時間以内に受信トレイを確認し、確認プロセスを完了してください。
add_email_success=新しいe-mail アドレスが追加されました。 add_email_success=新しいe-mail アドレスが追加されました。
manage_ssh_keys=SSH キーを管理 manage_ssh_keys=SSH キーを管理
@ -282,6 +312,9 @@ create_repo=リポジトリを作成
default_branch=デフォルトのブランチ default_branch=デフォルトのブランチ
mirror_interval=ミラー 間隔(時) mirror_interval=ミラー 間隔(時)
form.name_reserved=リポジトリ名 '%s' は予約されています。
form.name_pattern_not_allowed=リポジトリ名のパターン '%s' は許可されていません。
need_auth=認証が必要 need_auth=認証が必要
migrate_type=マイグレーションの種類 migrate_type=マイグレーションの種類
migrate_type_helper=このリポジトリは <span class="label label-blue label-radius"> ミラー</span> になります migrate_type_helper=このリポジトリは <span class="label label-blue label-radius"> ミラー</span> になります
@ -289,6 +322,8 @@ migrate_repo=リポジトリを移行
migrate.clone_address=クローンアドレス migrate.clone_address=クローンアドレス
migrate.invalid_local_path=ローカルパスが無効です。存在しないかディレクトリではありません。 migrate.invalid_local_path=ローカルパスが無効です。存在しないかディレクトリではありません。
forked_from=フォーク元
fork_from_self=すでにあなたの所有しているリポジトリはフォークできません
copy_link=コピー copy_link=コピー
click_to_copy=クリップボードにコピー click_to_copy=クリップボードにコピー
copied=コピー成功 copied=コピー成功
@ -311,11 +346,14 @@ branch_and_tags=ブランチ& タグ
branches=ブランチ branches=ブランチ
tags=タグ tags=タグ
issues=課題 issues=課題
labels=ラベル
milestones=マイルストーン
commits=コミット commits=コミット
releases=リリース releases=リリース
file_raw=生データ file_raw=生データ
file_history=履歴 file_history=履歴
file_view_raw=生データを見る file_view_raw=生データを見る
file_permalink=パーマリンク
commits.commits=コミット commits.commits=コミット
commits.search=コミットの検索 commits.search=コミットの検索
@ -326,6 +364,34 @@ commits.date=日付
commits.older=古い commits.older=古い
commits.newer=新しい 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=設定
settings.options=オプション settings.options=オプション
settings.collaboration=コラボレーション settings.collaboration=コラボレーション
@ -432,6 +498,9 @@ team_name_helper=会話の時、この名前を使用しチーム名を表明し
team_desc_helper=このチームに関する全ての情報は? team_desc_helper=このチームに関する全ての情報は?
team_permission_desc=このチームに必要な権限レベルは? team_permission_desc=このチームに必要な権限レベルは?
form.name_reserved=組織名 '%s' は予約されています。
form.name_pattern_not_allowed=組織名のパターン '%s' は許可されていません。
settings=設定 settings=設定
settings.options=オプション settings.options=オプション
settings.full_name=フルネーム settings.full_name=フルネーム
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=リポジトリのすべてのアーカイブを
dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。 dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。
dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。 dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。
dashboard.git_gc_repos_success=すべてのリポジトリは正常にガベージ コレクションを行いました。 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_sshkeys_success=すべての公開鍵が正常に書き換えられました。
dashboard.resync_all_update_hooks=リポジトリの update フックをすべて再更新する(カスタムの設定パスが変更されたときに必要) dashboard.resync_all_update_hooks=リポジトリの update フックをすべて再更新する(カスタムの設定パスが変更されたときに必要)
dashboard.resync_all_update_hooks_success=リポジトリの update フックがすべて正常に再更新されました。 dashboard.resync_all_update_hooks_success=リポジトリの update フックがすべて正常に再更新されました。
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP 認証の種類
auths.smtphost=SMTP ホスト auths.smtphost=SMTP ホスト
auths.smtpport=SMTP ポート auths.smtpport=SMTP ポート
auths.enable_tls=TLS 暗号化を有効にする auths.enable_tls=TLS 暗号化を有効にする
auths.pam_service_name=PAMサービス名
auths.enable_auto_register=自動登録を有効にする auths.enable_auto_register=自動登録を有効にする
auths.tips=ヒント auths.tips=ヒント
auths.edit=認証設定を編集 auths.edit=認証設定を編集
@ -653,6 +723,7 @@ config.deliver_timeout=送信タイムアウト
config.skip_tls_verify=TLSの確認を省略 config.skip_tls_verify=TLSの確認を省略
config.mailer_config=メーラーの構成 config.mailer_config=メーラーの構成
config.mailer_enabled=有効にした config.mailer_enabled=有効にした
config.mailer_disable_helo=HELOコマンド無効
config.mailer_name=名前 config.mailer_name=名前
config.mailer_host=ホスト config.mailer_host=ホスト
config.mailer_user=ユーザ config.mailer_user=ユーザ

@ -39,10 +39,18 @@ issues=Problēmas
cancel=Atcelt cancel=Atcelt
[search]
search=Search...
repository=Repository
user=User
issue=Issue
code=Code
[install] [install]
install=Instalācija install=Instalācija
title=Instalācijas soļi pirmo reizi palaižot title=Instalācijas soļi pirmo reizi palaižot
requite_db_desc=Gogs ir nepieciešama MySQL, PostgreSQL vai SQLite3 datu bāze. requite_db_desc=Gogs ir nepieciešama MySQL, PostgreSQL vai SQLite3 datu bāze.
db_title=Database Settings
db_type=Datu bāzes veids db_type=Datu bāzes veids
host=Resursdators host=Resursdators
user=Lietotājs 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 ssl_mode=SSL režīms
path=Ceļš path=Ceļš
sqlite_helper=SQLite 3 datu bāzes faila atrašanās vieta. 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 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=Repozitoriju glabāšanas vieta
repo_path_helper=Visi Git attālinātie repozitoriji tiks glabāti šajā direktorijā. repo_path_helper=Visi Git attālinātie repozitoriji tiks glabāti šajā direktorijā.
run_user=Izpildes lietotājs 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. http_port_helper=Porta numurs pēc kura lietojumprogrammai būs iespējams pieslēgties.
app_url=Lietotnes URL app_url=Lietotnes URL
app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites. 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_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_user=Sūtītāja e-pasta adrese
mailer_password=Sūtītāja parole 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 register_confirm=Iespējot reģistrēšanās apstiprināšanu
mail_notify=Iespējot e-pasta paziņojumus 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_title=Admin konta iestatījumi
admin_name=Lietotājvārds admin_name=Lietotājvārds
admin_password=Parole 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 reset_password_helper=Nospiediet šeit, lai atjaunotu paroli
password_too_short=Paroles garums nedrīkst būt mazāks par 6. password_too_short=Paroles garums nedrīkst būt mazāks par 6.
[modal]
yes=Yes
no=No
modify=Modify
[form] [form]
UserName=Lietotājvārds UserName=Lietotājvārds
RepoName=Repozitorija nosaukums RepoName=Repozitorija nosaukums
@ -136,6 +164,7 @@ AdminEmail=Admin e-pasta adrese
require_error=` nedrīkst būt tukšs.` 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_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.` 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ā.` min_size_error=` jabūt vismaz %s simbolu garumā.`
max_size_error=` jabūt ne mazāk kā %s simbolu garumā.` max_size_error=` jabūt ne mazāk kā %s simbolu garumā.`
email_error=` nav derīga e-pasta adrese.` 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. team_name_been_taken=Komandas nosaukums ir jau aizņemts.
email_been_used=E-pasta adrese jau tiek izmantota. email_been_used=E-pasta adrese jau tiek izmantota.
ssh_key_been_used=Publiskās atslēgas nosaukums jau tiek izmantos. 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. illegal_team_name=Grupas nosaukums satur neatļautas rakstzīmes.
username_password_incorrect=Lietotājvārds vai parole nav pareiza. 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. 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 starred=Atzīmēti ar zvaigznīti
following=Seko following=Seko
form.name_reserved=Username '%s' is reserved.
form.name_pattern_not_allowed=Username pattern '%s' is not allowed.
[settings] [settings]
profile=Profils profile=Profils
password=Parole password=Parole
@ -227,6 +256,7 @@ primary_email=Iestatīt kā primāro
delete_email=Dzēst delete_email=Dzēst
add_new_email=Pievienot jaunu e-pasta adresi add_new_email=Pievienot jaunu e-pasta adresi
add_email=Pievienot e-pastu 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. add_email_success=Jūsu jaunā e-pasta adrese tika veiksmīgi pievienota.
manage_ssh_keys=Pārvaldīt SSH atslēgas manage_ssh_keys=Pārvaldīt SSH atslēgas
@ -282,6 +312,9 @@ create_repo=Izveidot repozitoriju
default_branch=Noklusējuma atzars default_branch=Noklusējuma atzars
mirror_interval=Spoguļošanas intervāls (stundās) 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 need_auth=Nepieciešama autorizācija
migrate_type=Migrācijas veids migrate_type=Migrācijas veids
migrate_type_helper=Šis repozitorijs būs <span class="label label-blue label-radius">Spoguļots</span> 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.clone_address=Clone Address
migrate.invalid_local_path=Invalid local path, it does not exist or not a directory. 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 copy_link=Kopēt
click_to_copy=Kopēt uz starpliktuvi click_to_copy=Kopēt uz starpliktuvi
copied=Kopēšana notikusi veiksmīgi copied=Kopēšana notikusi veiksmīgi
@ -311,11 +346,14 @@ branch_and_tags=Atzari un tagi
branches=Atzari branches=Atzari
tags=Tagi tags=Tagi
issues=Problēmas issues=Problēmas
labels=Labels
milestones=Milestones
commits=Revīzijas commits=Revīzijas
releases=Laidieni releases=Laidieni
file_raw=Neapstrādāts file_raw=Neapstrādāts
file_history=Vēsture file_history=Vēsture
file_view_raw=Rādīt neapstrādātu file_view_raw=Rādīt neapstrādātu
file_permalink=Permalink
commits.commits=Revīzijas commits.commits=Revīzijas
commits.search=Meklēt revīzijas commits.search=Meklēt revīzijas
@ -326,6 +364,34 @@ commits.date=Datums
commits.older=Vecāki commits.older=Vecāki
commits.newer=Jaunā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=Iestatījumi
settings.options=Opcijas settings.options=Opcijas
settings.collaboration=Sadarbība 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_desc_helper=Komandas apraksts
team_permission_desc=Kādām tiesībām šai komandai būtu jābūt? 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=Iestatījumi
settings.options=Opcijas settings.options=Opcijas
settings.full_name=Pilns vārds, uzvārds 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.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=Veikt repozitoriju datu sakārtošānu (git gc)
dashboard.git_gc_repos_success=Datu sakārtošana visiem repozitorijiem veiksmīgi pabeigta. 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_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=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. 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.smtphost=SMTP resursdators
auths.smtpport=SMTP ports auths.smtpport=SMTP ports
auths.enable_tls=Iespējot TLS šifrēšanu 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.enable_auto_register=Iespējot automātisko reģistrāciju
auths.tips=Padomi auths.tips=Padomi
auths.edit=Labot autorizācijas iestatījumus 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.skip_tls_verify=Izlaist TLS pārbaudi
config.mailer_config=Sūtītāja konfigurācija config.mailer_config=Sūtītāja konfigurācija
config.mailer_enabled=Iespējots config.mailer_enabled=Iespējots
config.mailer_disable_helo=Disable HELO
config.mailer_name=Nosaukums config.mailer_name=Nosaukums
config.mailer_host=Resursdators config.mailer_host=Resursdators
config.mailer_user=Lietotājs 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 home=Huis
dashboard=Dashboard dashboard=Dashboard
@ -39,10 +39,18 @@ issues=Kwesties
cancel=Annuleer cancel=Annuleer
[search]
search=Zoeken...
repository=Opslagplaats
user=Gebruiker
issue=Probleem
code=Code
[install] [install]
install=Installatie install=Installatie
title=Installatiestappen voor de eerste keer opstarten 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). 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 db_type=Database-type
host=Host host=Host
user=Gebruikersnaam user=Gebruikersnaam
@ -52,7 +60,11 @@ db_helper=Gebruik InnoDB engine met utf8_general_ci karakterset voor MySQL.
ssl_mode=SSL-modus ssl_mode=SSL-modus
path=Pad path=Pad
sqlite_helper=Het pad naar de SQLite3 database. 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=Repositories basis directorie
repo_path_helper=Alle remote Git repositories worden in deze directorie opgeslagen repo_path_helper=Alle remote Git repositories worden in deze directorie opgeslagen
run_user=Uitvoerende gebruikersnaam run_user=Uitvoerende gebruikersnaam
@ -63,13 +75,24 @@ http_port=HTTP-poort
http_port_helper=Poortnummer waar het programma naar luistert. http_port_helper=Poortnummer waar het programma naar luistert.
app_url=Applicatie URL 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 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_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_user=Afzender e-mail / gebruikersnaam
mailer_password=Wachtwoord mailer_password=Wachtwoord
notify_title=Notificatie-instelligen (optioneel)
register_confirm=Activeer registratie emails register_confirm=Activeer registratie emails
mail_notify=Activeer e-mailnotificaties 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_title=Instellingen beheerdersaccount
admin_name=Gebruikersnaam admin_name=Gebruikersnaam
admin_password=Wachtwoord 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. 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. password_too_short=De lengte van uw wachtwoord moet minimaal zes karakters zijn.
[modal]
yes=Ja
no=Nee
modify=Aanpassen
[form] [form]
UserName=Gebruikersnaam UserName=Gebruikersnaam
RepoName=Repositorie naam RepoName=Repositorie naam
@ -136,6 +164,7 @@ AdminEmail=E-mail beheerder
require_error=kan niet leeg zijn. require_error=kan niet leeg zijn.
alpha_dash_error=moet een valide alfanumeriek of dash(-_) karakter 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. 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. min_size_error=moet minimaal %s karakters bevatten.
max_size_error=mag maximaal %s karakters bevatten. max_size_error=mag maximaal %s karakters bevatten.
email_error=is niet een valide e-mail adres. 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. team_name_been_taken=Team naam is al in gebruik.
email_been_used=e-mailadres is al in gebruik. email_been_used=e-mailadres is al in gebruik.
ssh_key_been_used=Openbare sleutel naam 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. illegal_team_name=Team naam bevat illegale karakters.
username_password_incorrect=Gebruikersnaam of wachtwoord is niet correct. username_password_incorrect=Gebruikersnaam of wachtwoord is niet correct.
enterred_invalid_repo_name=U heeft een onjuiste repositorie naam ingevoerd. enterred_invalid_repo_name=U heeft een onjuiste repositorie naam ingevoerd.
@ -183,6 +209,9 @@ followers=Volgers
starred=Sterren starred=Sterren
following=Volgt following=Volgt
form.name_reserved=De gebruikersnaam '%s' is gereserveerd.
form.name_pattern_not_allowed=Het gebruikersnaam patroon '%s' is niet toegestaan.
[settings] [settings]
profile=Profiel profile=Profiel
password=Wachtwoord password=Wachtwoord
@ -227,6 +256,7 @@ primary_email=Instellen als primair
delete_email=Verwijder delete_email=Verwijder
add_new_email=Nieuw e-mailadres toevoegen add_new_email=Nieuw e-mailadres toevoegen
add_email=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. add_email_success=Het e-mailadres was toegevoegd.
manage_ssh_keys=Beheer SSH sleutels manage_ssh_keys=Beheer SSH sleutels
@ -282,13 +312,18 @@ create_repo=Nieuwe Repositorie
default_branch=Standaard branch default_branch=Standaard branch
mirror_interval=Mirror interval(uur) 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 need_auth=Autorisatie vereist
migrate_type=Migratie type migrate_type=Migratie type
migrate_type_helper=Deze repositorie zal een <span class="label label-blue label-radius">mirror</span> worden migrate_type_helper=Deze repositorie zal een <span class="label label-blue label-radius">mirror</span> worden
migrate_repo=Migreer repositorie migrate_repo=Migreer repositorie
migrate.clone_address=Clone Address migrate.clone_address=Clone adres
migrate.invalid_local_path=Invalid local path, it does not exist or not a directory. 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 copy_link=Kopieer
click_to_copy=Kopieer link naar plakbord click_to_copy=Kopieer link naar plakbord
copied=Gekopieerd copied=Gekopieerd
@ -311,11 +346,14 @@ branch_and_tags=Aftakkingen & labels
branches=Aftakkingen branches=Aftakkingen
tags=Labels tags=Labels
issues=Kwesties issues=Kwesties
labels=Labels
milestones=Mijlpalen
commits=Commits commits=Commits
releases=Publicaties releases=Publicaties
file_raw=Ruwe file_raw=Ruwe
file_history=Geschiedenis file_history=Geschiedenis
file_view_raw=Weergave ruwe file_view_raw=Weergave ruwe
file_permalink=Permalink
commits.commits=Commits commits.commits=Commits
commits.search=Zoeken commits.search=Zoeken
@ -326,6 +364,34 @@ commits.date=Datum
commits.older=Ouder commits.older=Ouder
commits.newer=Nieuwer 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=Instellingen
settings.options=Opties settings.options=Opties
settings.collaboration=Samenwerking 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_desc_helper=Waar gaat dit team doen?
team_permission_desc=Welke privileges zou dit team moeten hebben? 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=Instellingen
settings.options=Opties settings.options=Opties
settings.full_name=Volledige naam settings.full_name=Volledige naam
@ -595,16 +664,17 @@ auths.domain=Domein
auths.host=Host auths.host=Host
auths.port=Poort auths.port=Poort
auths.base_dn=Base DN auths.base_dn=Base DN
auths.attribute_username=Username attribute auths.attribute_username=Gebruikersnaam attribuut
auths.attribute_name=First name attribute auths.attribute_name=Voornaam attribuut
auths.attribute_surname=Surname attribute auths.attribute_surname=Achternaam attribuut
auths.attribute_mail=E-mail attribute auths.attribute_mail=E-mail attribuut
auths.filter=Zoek filter auths.filter=Zoek filter
auths.ms_ad_sa=MS Ad SA auths.ms_ad_sa=MS Ad SA
auths.smtp_auth=SMTP authenticatietype auths.smtp_auth=SMTP authenticatietype
auths.smtphost=SMTP host auths.smtphost=SMTP host
auths.smtpport=SMTP poort auths.smtpport=SMTP poort
auths.enable_tls=Activeer TLS-encryptie auths.enable_tls=Activeer TLS-encryptie
auths.pam_service_name=PAM servicenaam
auths.enable_auto_register=Activeer automatische registratie auths.enable_auto_register=Activeer automatische registratie
auths.tips=Tips auths.tips=Tips
auths.edit=Bewerk autorisatie-instellingen auths.edit=Bewerk autorisatie-instellingen
@ -653,6 +723,7 @@ config.deliver_timeout=Bezorging verlooptijd
config.skip_tls_verify=TLS certificaat controle overslaan config.skip_tls_verify=TLS certificaat controle overslaan
config.mailer_config=Mailerconfiguatie config.mailer_config=Mailerconfiguatie
config.mailer_enabled=Ingeschakeld config.mailer_enabled=Ingeschakeld
config.mailer_disable_helo=Schakel HELO uit
config.mailer_name=Naam config.mailer_name=Naam
config.mailer_host=Host config.mailer_host=Host
config.mailer_user=Gebruiker config.mailer_user=Gebruiker

@ -39,10 +39,18 @@ issues=Problemy
cancel=Anuluj cancel=Anuluj
[search]
search=Wyszukiwanie...
repository=Repozytorium
user=Użytkownik
issue=Zgłoszenie
code=Kod
[install] [install]
install=Instalacja install=Instalacja
title=Kroki instalacyjne dla pierwszego uruchomienia title=Kroki instalacyjne dla pierwszego uruchomienia
requite_db_desc=Gogs wymaga MySQL, PostgreSQL lub SQLite3. requite_db_desc=Gogs wymaga MySQL, PostgreSQL lub SQLite3.
db_title=Ustawienia bazy danych
db_type=Typ bazy danych db_type=Typ bazy danych
host=Host host=Host
user=Użytkownik 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 ssl_mode=Tryb SSL
path=Ścieżka path=Ścieżka
sqlite_helper=Ścieżka do bazy SQLite3. 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 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=Katalog repozytoriów
repo_path_helper=W tym katalogu zostaną zapisane wszystkie repozytoria Git. repo_path_helper=W tym katalogu zostaną zapisane wszystkie repozytoria Git.
run_user=Nazwa użytkownika uruchomieniowego 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. http_port_helper=Numer portu na którym aplikacja jest dostępna.
app_url=Adres URL aplikacji app_url=Adres URL aplikacji
app_url_helper=To wpłynie na adresy klonowania HTTP/HTTPS i w wiadomościach e-mail. 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_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_user=Nadawca wiadomości E-mail
mailer_password=Hasło nadawcy mailer_password=Hasło nadawcy
notify_title=Ustawienia powiadomień (opcjonalne)
register_confirm=Włącz potwierdzenia rejestracji register_confirm=Włącz potwierdzenia rejestracji
mail_notify=Włącz powiadomienia e-mail 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_title=Ustawienia konta administratora
admin_name=Nazwa Użytkownika admin_name=Nazwa Użytkownika
admin_password=Hasło 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 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. password_too_short=Długość hasła nie może być mniejsza niż 6 znaków.
[modal]
yes=Yes
no=No
modify=Modify
[form] [form]
UserName=Nazwa Użytkownika UserName=Nazwa Użytkownika
RepoName=Nazwa repozytorium RepoName=Nazwa repozytorium
@ -136,6 +164,7 @@ AdminEmail=E-mail administratora
require_error=` nie może być puste.` 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_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.` 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.` min_size_error=` musi zawierać co najwyżej %s znaków.`
max_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.` 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. team_name_been_taken=Nazwa zespołu jest już zajęta.
email_been_used=Adres e-mail jest już zarejestrowany. email_been_used=Adres e-mail jest już zarejestrowany.
ssh_key_been_used=Nazwa klucza publicznego jest już używana. 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. illegal_team_name=Nazwa zespołu zawiera niedozwolone znaki.
username_password_incorrect=Nazwa użytkownika lub hasło nie jest prawidłowe. 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. enterred_invalid_repo_name=Upewnij się, że wprowadzona nazwa repozytorium jest poprawna.
@ -183,6 +209,9 @@ followers=Obserwujący
starred=Polubionych starred=Polubionych
following=Obserwowani following=Obserwowani
form.name_reserved=Nazwa użytkownika "%s" jest zarezerwowana.
form.name_pattern_not_allowed=Wzorzec nazwy użytkownika "%s" jest niedozwolony.
[settings] [settings]
profile=Profil profile=Profil
password=Hasło password=Hasło
@ -227,6 +256,7 @@ primary_email=Ustaw jako podstawowy
delete_email=Usuń delete_email=Usuń
add_new_email=Dodaj nowy e-mail add_new_email=Dodaj nowy e-mail
add_email=Dodaj 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. add_email_success=Twój nowy e-mail został dodany pomyślnie.
manage_ssh_keys=Zarządzaj kluczami SSH manage_ssh_keys=Zarządzaj kluczami SSH
@ -282,6 +312,9 @@ create_repo=Utwórz repozytorium
default_branch=Domyślna gałąź default_branch=Domyślna gałąź
mirror_interval=Odświeżanie mirrorów (godziny) 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 need_auth=Wymaga autoryzacji
migrate_type=Typ migracji migrate_type=Typ migracji
migrate_type_helper=Repozytorium będzie <span class="label label-blue label-radius">mirrorem</span> 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.clone_address=Sklonuj adres
migrate.invalid_local_path=Ścieżka jest niepoprawna. Nie istnieje lub nie jest katalogiem. 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 copy_link=Kopiuj
click_to_copy=Kopiuj do schowka click_to_copy=Kopiuj do schowka
copied=Skopiowano copied=Skopiowano
@ -311,11 +346,14 @@ branch_and_tags=Gałęzie i tagi
branches=Gałęzie branches=Gałęzie
tags=Tagi tags=Tagi
issues=Problemy issues=Problemy
labels=Labels
milestones=Milestones
commits=Commity commits=Commity
releases=Wydania releases=Wydania
file_raw=Czysty file_raw=Czysty
file_history=Historia file_history=Historia
file_view_raw=Zobacz czysty file_view_raw=Zobacz czysty
file_permalink=Permalink
commits.commits=Commity commits.commits=Commity
commits.search=Przeszukaj commity commits.search=Przeszukaj commity
@ -326,6 +364,34 @@ commits.date=Data
commits.older=Starsze commits.older=Starsze
commits.newer=Nowsze 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=Ustawienia
settings.options=Opcje settings.options=Opcje
settings.collaboration=Współpraca 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.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.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.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.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=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations. 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=If hook is not active, sample content will be presented. Leave content to be blank will disable this hook. 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_name=Nazwa skryptu
settings.githook_content=Treść skryptu settings.githook_content=Treść skryptu
settings.update_githook=Zaktualizuj skrypt 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_desc_helper=Czym zajmuje się ten zespół?
team_permission_desc=Jaki poziom uprawnień powinien mieć 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=Ustawienia
settings.options=Opcje settings.options=Opcje
settings.full_name=Imię i Nazwisko settings.full_name=Imię i Nazwisko
@ -439,14 +508,14 @@ settings.website=Strona
settings.location=Lolalizacja settings.location=Lolalizacja
settings.update_settings=Aktualizuj ustawienia settings.update_settings=Aktualizuj ustawienia
settings.change_orgname=Zmieniono nazwę organizacji 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.change_orgname_desc=Zmieniono nazwę organizacji. Wpływa to na powiązanie odnośników z organizacją. Czy chcesz kontynuować?
settings.update_setting_success=Organization setting has been updated successfully. settings.update_setting_success=Ustawienia organizacji zostały pomyślnie zaktualizowane.
settings.delete=Usuń Organizację settings.delete=Usuń Organizację
settings.delete_account=Usuń tą 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.confirm_delete_account=Potwierdź usunięcie
settings.delete_org_title=Usunięcie organizacji 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. settings.hooks_desc=Add webhooks that will be triggered for <strong>all repositories</strong> under this organization.
members.public=Publiczne 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.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.no_desc=Ten zespół nie ma opisu
teams.settings=Ustawienia 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.members=Członkowie zespołu
teams.update_settings=Aktualizuj ustawienia teams.update_settings=Aktualizuj ustawienia
teams.delete_team=Usuń ten zespół 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=Usuń wszystkie archiwa repozytoriów
dashboard.delete_repo_archives_success=Pomyślnie usunięto 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=Usuń śmieci z repozytoriów
dashboard.git_gc_repos_success=All repositories have done garbage collection successfully. 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_key' (uwaga: klucze poza Gogs zostaną usunięte) 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_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=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.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
@ -559,7 +628,7 @@ users.created=Utworzony
users.edit=Edytuj users.edit=Edytuj
users.auth_source=Źródła autoryzacji users.auth_source=Źródła autoryzacji
users.local=Lokalne 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.update_profile_success=Profil konta został pomyślnie zaktualizowany.
users.edit_account=Edytuj konto users.edit_account=Edytuj konto
users.is_activated=To konto jest aktywne users.is_activated=To konto jest aktywne
@ -583,7 +652,7 @@ repos.watches=Obserwujących
repos.stars=Polubienia repos.stars=Polubienia
repos.issues=Problemy 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.new=Dodaj nowe źródło autoryzacji
auths.name=Nazwa auths.name=Nazwa
auths.type=Typ auths.type=Typ
@ -605,6 +674,7 @@ auths.smtp_auth=Typ autoryzacji SMTP
auths.smtphost=Serwer SMTP auths.smtphost=Serwer SMTP
auths.smtpport=Port SMTP auths.smtpport=Port SMTP
auths.enable_tls=Włącz szyfrowanie TLS auths.enable_tls=Włącz szyfrowanie TLS
auths.pam_service_name=Nazwa usługi PAM
auths.enable_auto_register=Włącz automatyczną rejestrację auths.enable_auto_register=Włącz automatyczną rejestrację
auths.tips=Wskazówki auths.tips=Wskazówki
auths.edit=Edytuj ustawienia autoryzacji 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.skip_tls_verify=Pomiń weryfikację protokołu TLS
config.mailer_config=Konfiguracja poczty config.mailer_config=Konfiguracja poczty
config.mailer_enabled=Aktywne config.mailer_enabled=Aktywne
config.mailer_disable_helo=Wyłącz HELO
config.mailer_name=Nazwa config.mailer_name=Nazwa
config.mailer_host=Host config.mailer_host=Host
config.mailer_user=Użytkownik config.mailer_user=Użytkownik

@ -39,10 +39,18 @@ issues=Problemas
cancel=Cancelar cancel=Cancelar
[search]
search=Pesquisar...
repository=Repositório
user=Usuário
issue=Problema
code=Código
[install] [install]
install=Instalação install=Instalação
title=Etapas de instalação para Primeira Execução title=Etapas de instalação para Primeira Execução
requite_db_desc=Gogs requer MySQL, PostgreSQL ou SQLite3. requite_db_desc=Gogs requer MySQL, PostgreSQL ou SQLite3.
db_title=Configurações de Banco de Dados
db_type=Tipo do Banco de Dados db_type=Tipo do Banco de Dados
host=Host host=Host
user=Usuário 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 ssl_mode=Modo SSL
path=Caminho path=Caminho
sqlite_helper=O caminho do arquivo do banco de dados do SQLite3. 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 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=Caminho da Raiz do Repositório
repo_path_helper=Todos os repositórios remotos do Git serão salvos neste diretório. repo_path_helper=Todos os repositórios remotos do Git serão salvos neste diretório.
run_user=Executar Usuá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. http_port_helper=Número da porta em que a aplicação irá executar.
app_url=URL do Aplicativo app_url=URL do Aplicativo
app_url_helper=Isto afeta a URL de clonagem via HTTP/HTTPs e também o email. 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_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_user=E-mail do Remetente
mailer_password=Senha do Remetente mailer_password=Senha do Remetente
notify_title=Configurações de Notificação (Opcional)
register_confirm=Habilitar Confirmação de Registro register_confirm=Habilitar Confirmação de Registro
mail_notify=Habilitar Notificação de Correio 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_title=Configurações da Conta de Administrador
admin_name=Nome de Usuário admin_name=Nome de Usuário
admin_password=Senha 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 reset_password_helper=Clique aqui para redefinir sua senha
password_too_short=O comprimento da senha não pode ser menor que 6. password_too_short=O comprimento da senha não pode ser menor que 6.
[modal]
yes=Sim
no=Não
modify=Alterar
[form] [form]
UserName=Nome de usuário UserName=Nome de usuário
RepoName=Nome do repositório RepoName=Nome do repositório
@ -136,6 +164,7 @@ AdminEmail=E-mail do Administrador
require_error=` não pode estar vazio.` require_error=` não pode estar vazio.`
alpha_dash_error=` devem ser caracteres alfanuméricos ou hífen (-) ou sublinhado (_).` 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 (_).` 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.` min_size_error=` deve conter pelo menos %s caracteres.`
max_size_error=` deve conter no máximo %s caracteres.` max_size_error=` deve conter no máximo %s caracteres.`
email_error=` não é um endereço de e-mail válido.` 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. team_name_been_taken=Nome da equipe já foi tomado.
email_been_used=Endereço de e-mail já foi usado. email_been_used=Endereço de e-mail já foi usado.
ssh_key_been_used=Nome da chave pública 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. illegal_team_name=O nome da equipe contém caracteres ilegais.
username_password_incorrect=Usuário ou senha incorretos. username_password_incorrect=Usuário ou senha incorretos.
enterred_invalid_repo_name=Por favor certifique-se que informou o nome do repositório corretamente. enterred_invalid_repo_name=Por favor certifique-se que informou o nome do repositório corretamente.
@ -183,6 +209,9 @@ followers=Seguidores
starred=Marcado starred=Marcado
following=Seguindo 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] [settings]
profile=Perfil profile=Perfil
password=Senha password=Senha
@ -227,6 +256,7 @@ primary_email=Definir como principal
delete_email=Deletar delete_email=Deletar
add_new_email=Adicionar novo endereço de e-mail add_new_email=Adicionar novo endereço de e-mail
add_email=Adicionar 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. add_email_success=Seu novo endereço de E-mail foi adicionado com sucesso.
manage_ssh_keys=Gerenciar Chaves SSH 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=Desvincular
unbind_success=A conta social foi desvinculada. 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 generate_new_token=Gerar novo Token
tokens_desc=Tokens gerados por você que podem ser usados para acessar a API Gogs. 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. 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 default_branch=Ramo padrão
mirror_interval=Intervalo de Espelho (hora) 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 need_auth=Precisa de Autorização
migrate_type=Tipo de Migração migrate_type=Tipo de Migração
migrate_type_helper=Este repositório será um <span class="label label-blue label-radius">Espelho</span> 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.clone_address=Endereço de Clone
migrate.invalid_local_path=Caminho local inválido, não existe ou não é um diretório. 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 copy_link=Copiar
click_to_copy=Copiar para a área de transferência click_to_copy=Copiar para a área de transferência
copied=Copiado com sucesso copied=Copiado com sucesso
@ -311,11 +346,14 @@ branch_and_tags=Ramos & Tags
branches=Ramos branches=Ramos
tags=Tags tags=Tags
issues=Problemas issues=Problemas
labels=Etiquetas
milestones=Marcos
commits=Commits commits=Commits
releases=Lançamentos releases=Lançamentos
file_raw=Cru file_raw=Cru
file_history=Histórico file_history=Histórico
file_view_raw=Ver cru file_view_raw=Ver cru
file_permalink=Link permanente
commits.commits=Commits commits.commits=Commits
commits.search=Pesquisar commits commits.search=Pesquisar commits
@ -326,6 +364,34 @@ commits.date=Data
commits.older=Mais Antigo commits.older=Mais Antigo
commits.newer=Mais Novo 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=Configurações
settings.options=Opções settings.options=Opções
settings.collaboration=Colaboração 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_desc_helper=Do que trata essa equipe?
team_permission_desc=Que nível de permissão esta equipe deve ter? 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=Configurações
settings.options=Opções settings.options=Opções
settings.full_name=Nome Completo 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.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=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.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_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=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. 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.smtphost=Host SMTP
auths.smtpport=Porta SMTP auths.smtpport=Porta SMTP
auths.enable_tls=Habilitar Criptografia TLS auths.enable_tls=Habilitar Criptografia TLS
auths.pam_service_name=Nome de Serviço PAM
auths.enable_auto_register=Habilitar Registro Automático auths.enable_auto_register=Habilitar Registro Automático
auths.tips=Dicas auths.tips=Dicas
auths.edit=Editar Configuração da Autorização 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.skip_tls_verify=Pular Verificar TLS
config.mailer_config=Configuração de Correio config.mailer_config=Configuração de Correio
config.mailer_enabled=Habilitado config.mailer_enabled=Habilitado
config.mailer_disable_helo=Desabilitar HELO
config.mailer_name=Nome config.mailer_name=Nome
config.mailer_host=Host config.mailer_host=Host
config.mailer_user=Usuário config.mailer_user=Usuário

@ -39,10 +39,18 @@ issues=Вопросы
cancel=Отмена cancel=Отмена
[search]
search=Поиск...
repository=Репозиторий
user=Пользователь
issue=Проблема
code=Код
[install] [install]
install=Установка install=Установка
title=Установочные шаги для первого запуска title=Установочные шаги для первого запуска
requite_db_desc=Для Gogs требуется MySQL, PostgreSQL или SQLite3. requite_db_desc=Для Gogs требуется MySQL, PostgreSQL или SQLite3.
db_title=Настройки базы данных
db_type=Тип базы данных db_type=Тип базы данных
host=Хост host=Хост
user=Пользователь user=Пользователь
@ -52,7 +60,11 @@ db_helper=Для MySQL используйте тип таблиц InnoDB с ко
ssl_mode=Режим SSL ssl_mode=Режим SSL
path=Путь path=Путь
sqlite_helper=Путь к файлу базы данных SQLite3. sqlite_helper=Путь к файлу базы данных SQLite3.
err_empty_sqlite_path=Путь к базе данных SQLite3 не может быть пустым.
general_title=Общие параметры Gogs general_title=Общие параметры Gogs
app_name=Имя приложения
app_name_helper=Укажите здесь название вашей потрясающей организации!
repo_path=Путь корня репозитория repo_path=Путь корня репозитория
repo_path_helper=Все удаленные репозитории Git будут сохранены в этой директории. repo_path_helper=Все удаленные репозитории Git будут сохранены в этой директории.
run_user=Пользователь run_user=Пользователь
@ -63,13 +75,24 @@ http_port=Порт HTTP
http_port_helper=Номер порта, который приложение будет слушать. http_port_helper=Номер порта, который приложение будет слушать.
app_url=URL приложения app_url=URL приложения
app_url_helper=Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на адреса в электронной почте. app_url_helper=Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на адреса в электронной почте.
email_title=Настройки службы электронной почты (опционально)
optional_title=Расширенные настройки
email_title=Настройки службы электронной почты
smtp_host=Узел SMTP smtp_host=Узел SMTP
smtp_from=Из
smtp_from_helper=Почта от адреса, RFC 5322. Это может быть email адрес или формат "Имя" <email@example.com>.
mailer_user=Электронная почта отправителя mailer_user=Электронная почта отправителя
mailer_password=Пароль отправителя mailer_password=Пароль отправителя
notify_title=Настройки уведомлений(опционально)
register_confirm=Включить подтверждение регистрации register_confirm=Включить подтверждение регистрации
mail_notify=Разрешить почтовые уведомления 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_title=Настройки учётной записи администратора
admin_name=Имя пользователя admin_name=Имя пользователя
admin_password=Пароль admin_password=Пароль
@ -120,6 +143,11 @@ invalid_code=Извините, ваш код подтверждения исте
reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль
password_too_short=Длина пароля не менее 6 символов. password_too_short=Длина пароля не менее 6 символов.
[modal]
yes=Да
no=Нет
modify=Изменить
[form] [form]
UserName=Пользователь UserName=Пользователь
RepoName=Имя репозитория RepoName=Имя репозитория
@ -128,7 +156,7 @@ Password=Пароль
Retype=Введите пароль еще раз Retype=Введите пароль еще раз
SSHTitle=Имя SSH ключа SSHTitle=Имя SSH ключа
HttpsUrl=URL HTTPS HttpsUrl=URL HTTPS
PayloadUrl=Payload URL PayloadUrl=URL обработчика
TeamName=Название команды TeamName=Название команды
AuthName=Имя авторизации AuthName=Имя авторизации
AdminEmail=Электронная почта администратора AdminEmail=Электронная почта администратора
@ -136,6 +164,7 @@ AdminEmail=Электронная почта администратора
require_error=` не может быть пустым.` require_error=` не может быть пустым.`
alpha_dash_error=«должен быть допустимым символьным, числовым или dash(-_) значением.» alpha_dash_error=«должен быть допустимым символьным, числовым или dash(-_) значением.»
alpha_dash_dot_error=«должен быть допустимым символьным, числовым или dash(-_) символами, включая точку.» alpha_dash_dot_error=«должен быть допустимым символьным, числовым или dash(-_) символами, включая точку.»
size_error=` должен быть размер %s.`
min_size_error=«должен содержать по крайней мере %s символов.» min_size_error=«должен содержать по крайней мере %s символов.»
max_size_error=` должен содержать максимум %s символов.` max_size_error=` должен содержать максимум %s символов.`
email_error=«не является адресом электронной почты.» email_error=«не является адресом электронной почты.»
@ -150,9 +179,6 @@ org_name_been_taken=Название организации было уже пр
team_name_been_taken=Название команды было уже принято. team_name_been_taken=Название команды было уже принято.
email_been_used=Адрес электронной почты уже используется. email_been_used=Адрес электронной почты уже используется.
ssh_key_been_used=Имя открытого ключа уже используется. ssh_key_been_used=Имя открытого ключа уже используется.
illegal_username=Ваше имя пользователя содержит недопустимые символы.
illegal_repo_name=Имя репозитория содержит недопустимые знаки.
illegal_org_name=Название организации содержит недопустимые знаки.
illegal_team_name=Имя группы содержит недопустимые знаки. illegal_team_name=Имя группы содержит недопустимые знаки.
username_password_incorrect=Имя пользователя или пароль не правильный. username_password_incorrect=Имя пользователя или пароль не правильный.
enterred_invalid_repo_name=Пожалуйста, убедитесь, что введенно правильное имя хранилища. enterred_invalid_repo_name=Пожалуйста, убедитесь, что введенно правильное имя хранилища.
@ -183,6 +209,9 @@ followers=Подписчики
starred=Избранное starred=Избранное
following=Подписан following=Подписан
form.name_reserved=Имя пользователя '%s' зарезервировано.
form.name_pattern_not_allowed=Имя пользователя «%s» не допускается.
[settings] [settings]
profile=Профиль profile=Профиль
password=Пароль password=Пароль
@ -227,6 +256,7 @@ primary_email=Установить как основной
delete_email=Удалить delete_email=Удалить
add_new_email=Добавить новый адрес электронной почты add_new_email=Добавить новый адрес электронной почты
add_email=Добавить электронную почту add_email=Добавить электронную почту
add_email_confirmation_sent=Новое подтверждение по электронной почте было отправлено<b>%s</b>, пожалуйста, проверьте свой почтовый ящик в течение следующих %d часов, чтобы завершить процесс подтверждения.
add_email_success=Новый адрес электронной почты успешно добавлен. add_email_success=Новый адрес электронной почты успешно добавлен.
manage_ssh_keys=Управление SSH ключами manage_ssh_keys=Управление SSH ключами
@ -282,6 +312,9 @@ create_repo=Создать репозиторий
default_branch=Ветка по умолчанию default_branch=Ветка по умолчанию
mirror_interval=Интервал зеркалирования (час) mirror_interval=Интервал зеркалирования (час)
form.name_reserved=Имя репозитория '%s' зарезервировано.
form.name_pattern_not_allowed=Шаблон имени репозитория '%s' не допускается.
need_auth=Требуется авторизация need_auth=Требуется авторизация
migrate_type=Тип миграции migrate_type=Тип миграции
migrate_type_helper=Этот репозиторий будет <span class="label label-blue label-radius">зеркалом</span> migrate_type_helper=Этот репозиторий будет <span class="label label-blue label-radius">зеркалом</span>
@ -289,6 +322,8 @@ migrate_repo=Перенос репозитория
migrate.clone_address=Скопировать адрес migrate.clone_address=Скопировать адрес
migrate.invalid_local_path=Недопустимый локальный путь. Возможно он не существует или является не папкой. migrate.invalid_local_path=Недопустимый локальный путь. Возможно он не существует или является не папкой.
forked_from=forked from
fork_from_self=Вы не можете форкнуть репозитарий, так как Вы уже его владелец!
copy_link=Скопировать copy_link=Скопировать
click_to_copy=Скопировать в буфер обмена click_to_copy=Скопировать в буфер обмена
copied=Успешно скопировано copied=Успешно скопировано
@ -311,11 +346,14 @@ branch_and_tags=Ветки и метки
branches=Ветки branches=Ветки
tags=Метки tags=Метки
issues=Обсуждения issues=Обсуждения
labels=Метки
milestones=Этапы
commits=Коммиты commits=Коммиты
releases=Релизы releases=Релизы
file_raw=Исходник file_raw=Исходник
file_history=История file_history=История
file_view_raw=Посмотреть исходник file_view_raw=Посмотреть исходник
file_permalink=Постоянная ссылка
commits.commits=Коммиты commits.commits=Коммиты
commits.search=Поиск коммитов commits.search=Поиск коммитов
@ -326,12 +364,40 @@ commits.date=Дата
commits.older=Раньше commits.older=Раньше
commits.newer=Новее 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=Настройки
settings.options=Опции settings.options=Опции
settings.collaboration=Сотрудничество settings.collaboration=Сотрудничество
settings.hooks=Автоматическое обновление settings.hooks=Автоматическое обновление
settings.githooks=Git хуки settings.githooks=Git хуки
settings.deploy_keys=Deploy Keys settings.deploy_keys=Ключи развертывания
settings.basic_settings=Основные параметры settings.basic_settings=Основные параметры
settings.danger_zone=Опасная зона settings.danger_zone=Опасная зона
settings.site=Официальный сайт settings.site=Официальный сайт
@ -355,23 +421,23 @@ settings.remove_collaborator_success=Соавтор был удален.
settings.user_is_org_member=Пользователь является членом организации, члены которой не могут быть добавлены в качестве соавтора. settings.user_is_org_member=Пользователь является членом организации, члены которой не могут быть добавлены в качестве соавтора.
settings.add_webhook=Добавить Webhook settings.add_webhook=Добавить Webhook
settings.hooks_desc=Webhooks позволяют внешним службам получать уведомления при возникновении определенных событий на Gogs. При возникновении указанных событий мы отправим запрос POST на каждый заданный вами URL. Узнать больше можно в нашем <a target="_blank" href="%s">Руководстве по Webhooks</a>. 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.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 hook is not active, sample content will be presented. Leave content to be blank will disable this hook. 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_name=Название Hook'a
settings.githook_content=Перехватить содержание settings.githook_content=Перехватить содержание
settings.update_githook=Обновить Hook settings.update_githook=Обновить Hook
settings.remove_hook_success=Webhook has been removed. settings.remove_hook_success=Webhook удален.
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.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=Payload URL settings.payload_url=URL обработчика
settings.content_type=Тип содержимого settings.content_type=Тип содержимого
settings.secret=Secret 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.event_push_only=Просто <code>push</code> событие.
settings.active=Активен settings.active=Активен
settings.active_helper=We will deliver event details when this hook is triggered. settings.active_helper=Details regarding the event which triggered the hook will be delivered as well.
settings.add_hook_success=New webhook has been added. settings.add_hook_success=Был добавлен новый webhook.
settings.update_webhook=Update Webhook settings.update_webhook=Обновление Webhook
settings.update_hook_success=Webhook has been updated. settings.update_hook_success=Webhook обновлен.
settings.delete_webhook=Удалить автоматическое обновление settings.delete_webhook=Удалить автоматическое обновление
settings.recent_deliveries=Недавние рассылки settings.recent_deliveries=Недавние рассылки
settings.hook_type=Тип перехватчика settings.hook_type=Тип перехватчика
@ -407,7 +473,7 @@ release.preview=Предварительный просмотр
release.content_placeholder=Напишите что-нибудь release.content_placeholder=Напишите что-нибудь
release.loading=Загрузка... release.loading=Загрузка...
release.prerelease_desc=Это предварительный релиз 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.publish=Опубликовать релиз
release.save_draft=Сохранить черновик release.save_draft=Сохранить черновик
release.edit_release=Редактировать релиз release.edit_release=Редактировать релиз
@ -432,6 +498,9 @@ team_name_helper=Вы будете использовать это имя для
team_desc_helper=What is this team all about? team_desc_helper=What is this team all about?
team_permission_desc=Какой уровень разрешений должен быть у этой команды? team_permission_desc=Какой уровень разрешений должен быть у этой команды?
form.name_reserved=Наименование организации '%s' зарезервированно.
form.name_pattern_not_allowed=Шаблон организации '%s' не допускается.
settings=Настройки settings=Настройки
settings.options=Опции settings.options=Опции
settings.full_name=Полное имя settings.full_name=Полное имя
@ -514,23 +583,23 @@ dashboard.delete_repo_archives=Удаление всех архивов репо
dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены. dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены.
dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях
dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена. 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_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=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.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Время непрерывной работы сервера dashboard.server_uptime=Время непрерывной работы сервера
dashboard.current_goroutine=Current Goroutines dashboard.current_goroutine=Текущий Goroutines
dashboard.current_memory_usage=Текущее использование памяти dashboard.current_memory_usage=Текущее использование памяти
dashboard.total_memory_allocated=Всего памяти выделено dashboard.total_memory_allocated=Всего памяти выделено
dashboard.memory_obtained=Memory Obtained dashboard.memory_obtained=Memory Obtained
dashboard.pointer_lookup_times=Pointer Lookup Times dashboard.pointer_lookup_times=Pointer Lookup Times
dashboard.memory_allocate_times=Memory Allocate Times dashboard.memory_allocate_times=Memory Allocate Times
dashboard.memory_free_times=Memory Free 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_obtained=Heap Memory Obtained
dashboard.heap_memory_idle=Heap Memory Idle 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_memory_released=Heap Memory Released
dashboard.heap_objects=Heap Objects dashboard.heap_objects=Heap Objects
dashboard.bootstrap_stack_usage=Bootstrap Stack Usage dashboard.bootstrap_stack_usage=Bootstrap Stack Usage
@ -568,7 +637,7 @@ users.allow_git_hook=Пользователь имеет право создат
users.update_profile=Обновить профиль учетной записи users.update_profile=Обновить профиль учетной записи
users.delete_account=Удалить эту учетную запись users.delete_account=Удалить эту учетную запись
users.still_own_repo=На вашем аккаунте все еще остается как минимум один репозиторий, сначала вам нужно удалить или передать его. 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.org_manage_panel=Управление группами
orgs.name=Имя orgs.name=Имя
@ -605,6 +674,7 @@ auths.smtp_auth=Тип авторизации SMTP
auths.smtphost=Узел SMTP auths.smtphost=Узел SMTP
auths.smtpport=SMTP-порт auths.smtpport=SMTP-порт
auths.enable_tls=Включение шифрования TLS auths.enable_tls=Включение шифрования TLS
auths.pam_service_name=PAM Service Name
auths.enable_auto_register=Включить автоматическую регистрацию auths.enable_auto_register=Включить автоматическую регистрацию
auths.tips=Советы auths.tips=Советы
auths.edit=Редактировать параметры авторизации auths.edit=Редактировать параметры авторизации
@ -636,7 +706,7 @@ config.db_name=Имя
config.db_user=Пользователь config.db_user=Пользователь
config.db_ssl_mode=Режим SSL config.db_ssl_mode=Режим SSL
config.db_ssl_mode_helper=(только для «postgres») config.db_ssl_mode_helper=(только для «postgres»)
config.db_path=Path config.db_path=Путь
config.db_path_helper=(for "sqlite3" only) config.db_path_helper=(for "sqlite3" only)
config.service_config=Service Configuration config.service_config=Service Configuration
config.register_email_confirm=Require E-mail Confirmation 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.webhook_config=Настройка автоматического обновления репозиции
config.task_interval=Интервал задания config.task_interval=Интервал задания
config.deliver_timeout=Задержка доставки config.deliver_timeout=Задержка доставки
config.skip_tls_verify=Skip TLS Verify config.skip_tls_verify=Пропустить TLS проверка
config.mailer_config=Настройки почты config.mailer_config=Настройки почты
config.mailer_enabled=Включено config.mailer_enabled=Включено
config.mailer_disable_helo=Отключить HELO
config.mailer_name=Имя config.mailer_name=Имя
config.mailer_host=Сервер config.mailer_host=Сервер
config.mailer_user=Пользователь config.mailer_user=Пользователь
@ -685,7 +756,7 @@ monitor.previous=Предыдущий раз
monitor.execute_times=Execute Times monitor.execute_times=Execute Times
monitor.process=Запущенные процессы monitor.process=Запущенные процессы
monitor.desc=Описание monitor.desc=Описание
monitor.start=Start Time monitor.start=Момент начала
monitor.execute_time=Время выполнения monitor.execute_time=Время выполнения
notices.system_notice_list=Система уведомлений 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=Просмотреть сравнение двух коммитов compare_2_commits=Просмотреть сравнение двух коммитов
[tool] [tool]
ago=ago ago=назад
from_now=from now from_now=from now
now=сейчас now=сейчас
1s=1 second %s 1s=1 second %s

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

@ -39,10 +39,18 @@ issues=問題管理
cancel=取消 cancel=取消
[search]
search=搜尋...
repository=倉庫
user=用戶
issue=工單
code=程式碼
[install] [install]
install=安裝頁面 install=安裝頁面
title=首次執行安裝程序 title=首次執行安裝程序
requite_db_desc=Gogs 允許後端數據庫為 MySQL、PostgreSQL 或 SQLite3,但是 SQLite3 一般只有官方二進制發行版才支持。 requite_db_desc=Gogs 允許後端數據庫為 MySQL、PostgreSQL 或 SQLite3,但是 SQLite3 一般只有官方二進制發行版才支持。
db_title=數據庫設置
db_type=數據庫類型 db_type=數據庫類型
host=數據庫主機 host=數據庫主機
user=數據庫用戶 user=數據庫用戶
@ -52,7 +60,11 @@ db_helper=如果您使用 MySQL,請使用 INNODB 引擎以及 utf8_general_ci
ssl_mode=SSL 模式 ssl_mode=SSL 模式
path=數據庫文件路徑 path=數據庫文件路徑
sqlite_helper=SQLite3 數據庫的文件路徑。 sqlite_helper=SQLite3 數據庫的文件路徑。
err_empty_sqlite_path=SQLite 數據庫文件路徑不能為空。
general_title=應用基本設置 general_title=應用基本設置
app_name=應用名稱
app_name_helper=為您的組織取個響亮而又偉大的名稱
repo_path=倉庫根目錄 repo_path=倉庫根目錄
repo_path_helper=所有 Git 遠程倉庫都將被存放於該目錄。 repo_path_helper=所有 Git 遠程倉庫都將被存放於該目錄。
run_user=執行系統用戶 run_user=執行系統用戶
@ -63,13 +75,24 @@ http_port=HTTP 端口號
http_port_helper=應用監聽的端口號 http_port_helper=應用監聽的端口號
app_url=應用 URL app_url=應用 URL
app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。 app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。
email_title=電子郵件服務設定(可選)
optional_title=可選設置
email_title=電子郵件服務設定
smtp_host=SMTP 主機 smtp_host=SMTP 主機
smtp_from=郵件來自
smtp_from_helper=郵件來自地址,遵循 RFC 5322 標准。可以是一個單純的郵箱地址或使用 "name" <email@example.com> 的格式。
mailer_user=發送郵箱 mailer_user=發送郵箱
mailer_password=發送郵箱密碼 mailer_password=發送郵箱密碼
notify_title=通知提醒設置(可選)
register_confirm=啟用註冊郵箱確認 register_confirm=啟用註冊郵箱確認
mail_notify=啟用郵件通知提醒 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_title=管理員帳號設置
admin_name=管理員用戶名 admin_name=管理員用戶名
admin_password=管理員密碼 admin_password=管理員密碼
@ -120,6 +143,11 @@ invalid_code=對不起,您的確認代碼已過期或已失效。
reset_password_helper=單擊此處重置密碼 reset_password_helper=單擊此處重置密碼
password_too_short=密碼長度不能少於 6 位! password_too_short=密碼長度不能少於 6 位!
[modal]
yes=確認操作
no=取消操作
modify=確認修改
[form] [form]
UserName=用戶名 UserName=用戶名
RepoName=倉庫名稱 RepoName=倉庫名稱
@ -136,6 +164,7 @@ AdminEmail=管理員郵箱
require_error=不能為空。 require_error=不能為空。
alpha_dash_error=必須為英文字母、阿拉伯數字或橫線(-_)。 alpha_dash_error=必須為英文字母、阿拉伯數字或橫線(-_)。
alpha_dash_dot_error=必須為英文字母、阿拉伯數字、橫線(-_)或點。 alpha_dash_dot_error=必須為英文字母、阿拉伯數字、橫線(-_)或點。
size_error=長度必須為 %s。
min_size_error=長度最小為 %s 個字符。 min_size_error=長度最小為 %s 個字符。
max_size_error=長度最大為 %s 個字符。 max_size_error=長度最大為 %s 個字符。
email_error=不是一個有效的郵箱地址。 email_error=不是一個有效的郵箱地址。
@ -150,9 +179,6 @@ org_name_been_taken=組織名稱已經被佔用。
team_name_been_taken=團隊名稱已經被佔用。 team_name_been_taken=團隊名稱已經被佔用。
email_been_used=郵箱地址已經被使用。 email_been_used=郵箱地址已經被使用。
ssh_key_been_used=SSH 密鑰已經被使用。 ssh_key_been_used=SSH 密鑰已經被使用。
illegal_username=您的用戶名包含不合法字符。
illegal_repo_name=倉庫名稱包含不合法字符。
illegal_org_name=組織名稱包含不合法字符。
illegal_team_name=團隊名稱包含不合法字符。 illegal_team_name=團隊名稱包含不合法字符。
username_password_incorrect=用戶名或密碼不正確。 username_password_incorrect=用戶名或密碼不正確。
enterred_invalid_repo_name=請檢查您輸入的倉庫名稱是正確。 enterred_invalid_repo_name=請檢查您輸入的倉庫名稱是正確。
@ -183,6 +209,9 @@ followers=關註者
starred=已讚好 starred=已讚好
following=關註中 following=關註中
form.name_reserved=用戶名 '%s' 是被保留的。
form.name_pattern_not_allowed=用戶名不允許 '%s' 的格式。
[settings] [settings]
profile=個人信息 profile=個人信息
password=修改密碼 password=修改密碼
@ -227,6 +256,7 @@ primary_email=设为主要
delete_email=刪除 delete_email=刪除
add_new_email=添加新的電子郵件地址 add_new_email=添加新的電子郵件地址
add_email=添加電子郵件 add_email=添加電子郵件
add_email_confirmation_sent=一封待確認的電子郵件已發送到<b>%s</b>,請在%d 小時內檢查您的收件箱,並完成確認過程。
add_email_success=新的邮箱地址添加成功。 add_email_success=新的邮箱地址添加成功。
manage_ssh_keys=管理 SSH 密鑰 manage_ssh_keys=管理 SSH 密鑰
@ -282,6 +312,9 @@ create_repo=創建倉庫
default_branch=默認分支 default_branch=默認分支
mirror_interval=鏡像同步周期(小時) mirror_interval=鏡像同步周期(小時)
form.name_reserved=倉庫名稱 '%s' 是被保留的。
form.name_pattern_not_allowed=倉庫名稱不允許 '%s' 的格式。
need_auth=需要授權驗證 need_auth=需要授權驗證
migrate_type=遷移類型 migrate_type=遷移類型
migrate_type_helper=本倉庫將是 <span class="label label-blue label-radius">鏡像</span> migrate_type_helper=本倉庫將是 <span class="label label-blue label-radius">鏡像</span>
@ -289,6 +322,8 @@ migrate_repo=遷移倉庫
migrate.clone_address=複製地址 migrate.clone_address=複製地址
migrate.invalid_local_path=無效的本地路徑,該路徑不存在或不是一個目錄! migrate.invalid_local_path=無效的本地路徑,該路徑不存在或不是一個目錄!
forked_from=派生自
fork_from_self=無法派生已經擁有的倉庫!
copy_link=複製連結 copy_link=複製連結
click_to_copy=複製到剪切簿 click_to_copy=複製到剪切簿
copied=複製成功 copied=複製成功
@ -311,11 +346,14 @@ branch_and_tags=分支與標籤
branches=分支列表 branches=分支列表
tags=標籤列表 tags=標籤列表
issues=問題管理 issues=問題管理
labels=標籤
milestones=里程碑
commits=提交歷史 commits=提交歷史
releases=版本發佈 releases=版本發佈
file_raw=原始文件 file_raw=原始文件
file_history=文件歷史 file_history=文件歷史
file_view_raw=查看原始文件 file_view_raw=查看原始文件
file_permalink=永久連結
commits.commits=次代碼提交 commits.commits=次代碼提交
commits.search=搜索提交歷史 commits.search=搜索提交歷史
@ -326,6 +364,34 @@ commits.date=提交日期
commits.older=更舊的提交 commits.older=更舊的提交
commits.newer=更新的提交 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=倉庫設置
settings.options=基本設置 settings.options=基本設置
settings.collaboration=管理協作者 settings.collaboration=管理協作者
@ -432,6 +498,9 @@ team_name_helper=您可以使用該名稱來通知改組全體成員。
team_desc_helper=一句話描述這個團隊是做什麼的。 team_desc_helper=一句話描述這個團隊是做什麼的。
team_permission_desc=請選擇該團隊所具有的權限等級: team_permission_desc=請選擇該團隊所具有的權限等級:
form.name_reserved=組織名稱 '%s' 是被保留的。
form.name_pattern_not_allowed=組織名稱不允許 '%s' 的格式。
settings=組織設置 settings=組織設置
settings.options=基本設置 settings.options=基本設置
settings.full_name=組織全名 settings.full_name=組織全名
@ -514,7 +583,7 @@ dashboard.delete_repo_archives=刪除所有倉庫存檔
dashboard.delete_repo_archives_success=所有倉庫存檔清除成功! dashboard.delete_repo_archives_success=所有倉庫存檔清除成功!
dashboard.git_gc_repos=對倉庫進行垃圾回收 dashboard.git_gc_repos=對倉庫進行垃圾回收
dashboard.git_gc_repos_success=所有倉庫的垃圾回收已成功完成! 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_sshkeys_success=所有公鑰重新生成成功!
dashboard.resync_all_update_hooks=重新生成所有倉庫的 Update 鈎子(用於被修改的自定義配置文件) dashboard.resync_all_update_hooks=重新生成所有倉庫的 Update 鈎子(用於被修改的自定義配置文件)
dashboard.resync_all_update_hooks_success=已成功重新生成所有倉庫的 Update 鈎子! dashboard.resync_all_update_hooks_success=已成功重新生成所有倉庫的 Update 鈎子!
@ -605,6 +674,7 @@ auths.smtp_auth=SMTP 授權類型
auths.smtphost=SMTP 主機地址 auths.smtphost=SMTP 主機地址
auths.smtpport=SMTP 主機端口 auths.smtpport=SMTP 主機端口
auths.enable_tls=啟用 TLS 加密 auths.enable_tls=啟用 TLS 加密
auths.pam_service_name=PAM 服務名稱
auths.enable_auto_register=允許授權用戶自動註冊 auths.enable_auto_register=允許授權用戶自動註冊
auths.tips=幫助提示 auths.tips=幫助提示
auths.edit=修改授權認證設置 auths.edit=修改授權認證設置
@ -653,6 +723,7 @@ config.deliver_timeout=推送超時
config.skip_tls_verify=忽略 TLS 驗證 config.skip_tls_verify=忽略 TLS 驗證
config.mailer_config=郵件配置 config.mailer_config=郵件配置
config.mailer_enabled=啟用服務 config.mailer_enabled=啟用服務
config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱 config.mailer_name=發送者名稱
config.mailer_host=郵件主機地址 config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號 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! 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: The most simple setup will look like this:
```sh ```sh
./assemble_blocks.sh docker_gogs w_db option_db_mysql ./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. `./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). `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. 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. 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! This includes container linking!
Just have a look at them and it will be clear how to write your own blocks. Just have a look at them and it will be clear how to write your own blocks.
Just some things 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 - 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. 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 ```sh
./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql ./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 This will set up four containters and link them proberly. One for each of
docker-compose
- gogs
- database (postgresql)
- cache (redis)
- session (mysql) - session (mysql)
WARNING: This will not work at the Moment! MySQL session is broken! 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 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 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` `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_config=config
gogs_init_file=$docker_dir/init_gogs.sh gogs_init_file=$docker_dir/init_gogs.sh
fig_file=fig.yml compose_file=docker-compose.yml
fig_config=fig compose_config=docker-compose
gogs_init_template=$template_dir/init_gogs.sh.tpl gogs_init_template=$template_dir/init_gogs.sh.tpl
@ -28,7 +28,7 @@ if [ "$#" == 0 ]; then
exit 0 exit 0
fi fi
for file in $gogs_config_file $fig_file; do for file in $gogs_config_file $compose_file; do
if [ -e $file ]; then if [ -e $file ]; then
echo "Deleting $file" echo "Deleting $file"
rm $file rm $file
@ -53,10 +53,10 @@ for dir in $@; do
echo "" >> $gogs_config_file echo "" >> $gogs_config_file
fi fi
if [ -e $current_dir/$fig_config ]; then if [ -e $current_dir/$compose_config ]; then
echo "Adding $current_dir/$fig_config to $fig_file" echo "Adding $current_dir/$compose_config to $compose_file"
cat $current_dir/fig >> $fig_file cat $current_dir/$compose_config >> $compose_file
echo "" >> $fig_file echo "" >> $compose_file
fi fi
done done

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

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

@ -145,6 +145,25 @@ func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int6
for _, c := range collaborators { for _, c := range collaborators {
accessMap[c.Id] = ACCESS_MODE_WRITE 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 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) { func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err error) {
accessMap := make(map[int64]AccessMode, 20) 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 { if err = repo.getOwner(e); err != nil {
return err return err
} }
if err = repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
if repo.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
if err = repo.Owner.getTeams(e); err != nil { if err = repo.Owner.getTeams(e); err != nil {
return err 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) 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) 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 return err
} }
} }
@ -183,7 +183,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
return err return err
} }
if issue.RepoId == repoId { if issue.RepoID == repoId {
if issue.IsClosed { if issue.IsClosed {
continue continue
} }
@ -202,7 +202,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if err = UpdateIssue(issue); err != nil { if err = UpdateIssue(issue); err != nil {
return err return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil { } else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil {
return err 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 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 return err
} }
} }
@ -242,7 +242,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
return err return err
} }
if issue.RepoId == repoId { if issue.RepoID == repoId {
if !issue.IsClosed { if !issue.IsClosed {
continue continue
} }
@ -261,7 +261,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if err = UpdateIssue(issue); err != nil { if err = UpdateIssue(issue); err != nil {
return err return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil { } else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil {
return err 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 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 return err
} }
} }
@ -293,12 +293,12 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName) repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
// if not the first commit, set the compareUrl // if not the first commit, set the compareUrl
if !strings.HasPrefix(oldCommitId, "0000000") { 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) bs, err := json.Marshal(commit)
if err != nil { if err != nil {
return errors.New("action.CommitRepoAction(json): " + err.Error()) return errors.New("json: " + err.Error())
} }
refName := git.RefEndName(refFullName) 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. // Change repository bare status and update last updated time.
repo, err := GetRepositoryByName(repoUserId, repoName) repo, err := GetRepositoryByName(repoUserId, repoName)
if err != nil { if err != nil {
return errors.New("action.CommitRepoAction(GetRepositoryByName): " + err.Error()) return errors.New("GetRepositoryByName: " + err.Error())
} }
repo.IsBare = false repo.IsBare = false
if err = UpdateRepository(repo, false); err != nil { 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) err = updateIssuesCommit(userId, repoId, repoUserName, repoName, commit.Commits)
if err != nil { if err != nil {
log.Debug("action.CommitRepoAction(updateIssuesCommit): ", err) log.Debug("updateIssuesCommit: ", err)
} }
if err = NotifyWatchers(&Action{ if err = NotifyWatchers(&Action{
@ -331,18 +331,18 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
RefName: refName, RefName: refName,
IsPrivate: repo.IsPrivate, IsPrivate: repo.IsPrivate,
}); err != nil { }); err != nil {
return errors.New("action.CommitRepoAction(NotifyWatchers): " + err.Error()) return errors.New("NotifyWatchers: " + err.Error())
} }
// New push event hook. // New push event hook.
if err := repo.GetOwner(); err != nil { if err := repo.GetOwner(); err != nil {
return errors.New("action.CommitRepoAction(GetOwner): " + err.Error()) return errors.New("GetOwner: " + err.Error())
} }
ws, err := GetActiveWebhooksByRepoId(repoId) ws, err := GetActiveWebhooksByRepoId(repoId)
if err != nil { 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 // 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 // get hooks for org
orgws, err := GetActiveWebhooksByOrgId(repo.OwnerId) orgws, err := GetActiveWebhooksByOrgId(repo.OwnerId)
if err != nil { if err != nil {
return errors.New("action.CommitRepoAction(GetActiveWebhooksByOrgId): " + err.Error()) return errors.New("GetActiveWebhooksByOrgId: " + err.Error())
} }
ws = append(ws, orgws...) ws = append(ws, orgws...)
} }
@ -408,7 +408,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}, },
Before: oldCommitId, Before: oldCommitId,
After: newCommitId, After: newCommitId,
CompareUrl: commit.CompareUrl, CompareUrl: setting.AppUrl + commit.CompareUrl,
} }
for _, w := range ws { for _, w := range ws {
@ -431,6 +431,8 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
} }
if err = CreateHookTask(&HookTask{ if err = CreateHookTask(&HookTask{
RepoID: repo.Id,
HookID: w.Id,
Type: w.HookTaskType, Type: w.HookTaskType,
Url: w.Url, Url: w.Url,
BasePayload: payload, BasePayload: payload,

@ -8,6 +8,32 @@ import (
"fmt" "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 { type ErrUserOwnRepos struct {
UID int64 UID int64
} }
@ -41,6 +107,82 @@ func (err ErrUserHasOrgs) Error() string {
return fmt.Sprintf("user still has membership of organizations: [uid: %d]", err.UID) 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 { func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name) 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 leftLine, rightLine int
isTooLong bool 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 buf bytes.Buffer
) )
@ -106,16 +106,10 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
i = i + 1 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 // Diff data too large, we only show the first about maxlines lines
if i == maxlines { if i == maxlines {
isTooLong = true isTooLong = true
log.Warn("Diff data too large") log.Warn("Diff data too large")
//return &Diff{}, nil
} }
switch { switch {
@ -127,7 +121,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
continue continue
case line[0] == '@': case line[0] == '@':
if isTooLong { if isTooLong {
return diff, nil break
} }
curSection = &DiffSection{} 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) curSection.Lines = append(curSection.Lines, diffLine)
// Parse line number. // 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() 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 continue
case line[0] == '+': case line[0] == '+':
curFile.Addition++ curFile.Addition++
@ -164,11 +163,11 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
// Get new file. // Get new file.
if strings.HasPrefix(line, DIFF_HEAD) { if strings.HasPrefix(line, DIFF_HEAD) {
if isTooLong { if isTooLong {
return diff, nil break
} }
fs := strings.Split(line[len(DIFF_HEAD):], " ") beg := len(DIFF_HEAD)
a := fs[0] a := line[beg : (len(line)-beg)/2+beg]
curFile = &DiffFile{ curFile = &DiffFile{
Name: a[strings.Index(a, "/")+1:], 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. for _, f := range diff.Files {
charsetLabel, err := base.DetectEncoding(buf.Bytes()) buf.Reset()
if charsetLabel != "utf8" && err == nil { for _, sec := range f.Sections {
encoding, _ := charset.Lookup(charsetLabel) for _, l := range sec.Lines {
buf.WriteString(l.Content)
if encoding != nil { buf.WriteString("\n")
d := encoding.NewDecoder() }
for _, f := range diff.Files { }
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 _, sec := range f.Sections {
for _, l := range sec.Lines { for _, l := range sec.Lines {
if c, _, err := transform.String(d, l.Content); err == nil { 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 return diff, nil
} }

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

@ -17,6 +17,7 @@ import (
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/auth/ldap" "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/log"
"github.com/gogits/gogs/modules/uuid" "github.com/gogits/gogs/modules/uuid"
) )
@ -28,6 +29,7 @@ const (
PLAIN PLAIN
LDAP LDAP
SMTP SMTP
PAM
) )
var ( var (
@ -39,12 +41,14 @@ var (
var LoginTypes = map[LoginType]string{ var LoginTypes = map[LoginType]string{
LDAP: "LDAP", LDAP: "LDAP",
SMTP: "SMTP", SMTP: "SMTP",
PAM: "PAM",
} }
// Ensure structs implemented interface. // Ensure structs implemented interface.
var ( var (
_ core.Conversion = &LDAPConfig{} _ core.Conversion = &LDAPConfig{}
_ core.Conversion = &SMTPConfig{} _ core.Conversion = &SMTPConfig{}
_ core.Conversion = &PAMConfig{}
) )
type LDAPConfig struct { type LDAPConfig struct {
@ -74,6 +78,18 @@ func (cfg *SMTPConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg) 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 { type LoginSource struct {
Id int64 Id int64
Type LoginType Type LoginType
@ -97,6 +113,10 @@ func (source *LoginSource) SMTP() *SMTPConfig {
return source.Cfg.(*SMTPConfig) return source.Cfg.(*SMTPConfig)
} }
func (source *LoginSource) PAM() *PAMConfig {
return source.Cfg.(*PAMConfig)
}
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
if colName == "type" { if colName == "type" {
ty := (*val).(int64) ty := (*val).(int64)
@ -105,6 +125,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
source.Cfg = new(LDAPConfig) source.Cfg = new(LDAPConfig)
case SMTP: case SMTP:
source.Cfg = new(SMTPConfig) 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. // For plain login, user must exist to reach this line.
// Now verify password. // Now verify password.
if u.LoginType == PLAIN { if u.LoginType == PLAIN {
if !u.ValidtePassword(passwd) { if !u.ValidatePassword(passwd) {
return nil, ErrUserNotExist return nil, ErrUserNotExist{u.Id, u.Name}
} }
return u, nil return u, nil
} }
@ -197,10 +219,17 @@ func UserSignIn(uname, passwd string) (*User, error) {
return u, nil return u, nil
} }
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err) 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 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) return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false)
case SMTP: case SMTP:
return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false) 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 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) name, fn, sn, mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
if !logged { if !logged {
// User not in LDAP, do nothing // User not in LDAP, do nothing
return nil, ErrUserNotExist return nil, ErrUserNotExist{u.Id, u.Name}
} }
if !autoRegister { if !autoRegister {
return u, nil 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 err := SmtpAuth(cfg.Host, cfg.Port, auth, cfg.TLS); err != nil {
if strings.Contains(err.Error(), "Username and Password not accepted") { if strings.Contains(err.Error(), "Username and Password not accepted") {
return nil, ErrUserNotExist return nil, ErrUserNotExist{u.Id, u.Name}
} }
return nil, err return nil, err
} }
@ -359,3 +390,33 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP
err := CreateUser(u) err := CreateUser(u)
return u, err 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 package migrations
import ( import (
"encoding/json"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -51,11 +52,12 @@ type Version struct {
// If you want to "retire" a migration, remove it from the top of the list and // If you want to "retire" a migration, remove it from the top of the list and
// update _MIN_VER_DB accordingly // update _MIN_VER_DB accordingly
var migrations = []Migration{ var migrations = []Migration{
NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1:v0.5.13 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("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("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("generate team-repo from team", teamToTeamRepo), // V3 -> V4:v0.5.13
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0 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 // 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), ",") setting.Langs = strings.Split(strings.Replace(strings.Join(setting.Langs, ","), "fr-CA", "fr-FR", 1), ",")
return nil 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() { func init() {
tables = append(tables, tables = append(tables,
new(User), new(PublicKey), new(Oauth2), new(AccessToken), 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(Watch), new(Star), new(Follow), new(Action),
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone), new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(Mirror), new(Release), new(LoginSource), new(Webhook),
@ -90,10 +90,10 @@ func getEngine() (*xorm.Engine, error) {
switch DbCfg.Type { switch DbCfg.Type {
case "mysql": case "mysql":
if DbCfg.Host[0] == '/' { // looks like a unix socket 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) DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
} else { } 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) DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
} }
case "postgres": case "postgres":
@ -105,7 +105,7 @@ func getEngine() (*xorm.Engine, error) {
if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 { if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 {
port = fields[1] 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) DbCfg.User, DbCfg.Passwd, host, port, DbCfg.Name, DbCfg.SSLMode)
case "sqlite3": case "sqlite3":
if !EnableSQLite3 { if !EnableSQLite3 {
@ -122,7 +122,7 @@ func getEngine() (*xorm.Engine, error) {
func NewTestEngine(x *xorm.Engine) (err error) { func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine() x, err = getEngine()
if err != nil { if err != nil {
return fmt.Errorf("connect to database: %v", err) return fmt.Errorf("Connect to database: %v", err)
} }
x.SetMapper(core.GonicMapper{}) x.SetMapper(core.GonicMapper{})
@ -132,7 +132,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
func SetEngine() (err error) { func SetEngine() (err error) {
x, err = getEngine() x, err = getEngine()
if err != nil { 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{}) x.SetMapper(core.GonicMapper{})
@ -144,7 +144,7 @@ func SetEngine() (err error) {
f, err := os.Create(logPath) f, err := os.Create(logPath)
if err != nil { 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)) x.SetLogger(xorm.NewSimpleLogger(f))

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

@ -21,6 +21,7 @@ import (
"time" "time"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/process"
@ -33,8 +34,6 @@ const (
) )
var ( var (
ErrKeyAlreadyExist = errors.New("Public key already exists")
ErrKeyNotExist = errors.New("Public key does not exist")
ErrKeyUnableVerify = errors.New("Unable to verify public key") 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 { type PublicKey struct {
Id int64 ID int64 `xorm:"pk autoincr"`
OwnerId int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"UNIQUE(s) NOT NULL"` Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"INDEX NOT NULL"` Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"` Content string `xorm:"TEXT NOT NULL"`
Created time.Time `xorm:"CREATED"` Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Updated time.Time Type KeyType `xorm:"NOT NULL DEFAULT 1"`
HasRecentActivity bool `xorm:"-"` Created time.Time `xorm:"CREATED"`
HasUsed bool `xorm:"-"` 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. // 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. // GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string { 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{ var minimumKeySizes = map[string]int{
@ -126,8 +142,8 @@ func extractTypeFromBase64Key(key string) (string, error) {
return string(b[4 : 4+keyLength]), nil return string(b[4 : 4+keyLength]), nil
} }
// Parse any key string in openssh or ssh2 format to clean openssh string (rfc4253) // parseKeyString parses any key string in openssh or ssh2 format to clean openssh string (rfc4253)
func ParseKeyString(content string) (string, error) { func parseKeyString(content string) (string, error) {
// Transform all legal line endings to a single "\n" // Transform all legal line endings to a single "\n"
s := strings.Replace(strings.Replace(strings.TrimSpace(content), "\r\n", "\n", -1), "\r", "\n", -1) 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. // 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") content = strings.TrimRight(content, "\n\r")
if strings.ContainsAny(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… // write the key to a file…
tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest") tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest")
if err != nil { if err != nil {
return false, err return "", err
} }
tmpPath := tmpFile.Name() tmpPath := tmpFile.Name()
defer os.Remove(tmpPath) defer os.Remove(tmpPath)
@ -209,37 +230,36 @@ func CheckPublicKeyString(content string) (bool, error) {
// Check if ssh-keygen recognizes its contents. // Check if ssh-keygen recognizes its contents.
stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath) stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath)
if err != nil { 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 { } 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. // The ssh-keygen in Windows does not print key type, so no need go further.
if setting.IsWindows { if setting.IsWindows {
return true, nil return content, nil
} }
fmt.Println(stdout)
sshKeygenOutput := strings.Split(stdout, " ") sshKeygenOutput := strings.Split(stdout, " ")
if len(sshKeygenOutput) < 4 { if len(sshKeygenOutput) < 4 {
return false, ErrKeyUnableVerify return content, ErrKeyUnableVerify
} }
// Check if key type and key size match. // Check if key type and key size match.
if !setting.Service.DisableMinimumKeySizeCheck { if !setting.Service.DisableMinimumKeySizeCheck {
keySize := com.StrTo(sshKeygenOutput[0]).MustInt() keySize := com.StrTo(sshKeygenOutput[0]).MustInt()
if keySize == 0 { 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]) keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])
if minimumKeySize := minimumKeySizes[keyType]; minimumKeySize == 0 { 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 { } 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. // saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
@ -278,20 +298,23 @@ func saveAuthorizedKeyFile(keys ...*PublicKey) error {
return nil return nil
} }
// AddPublicKey adds new public key to database and authorized_keys file. func checkKeyContent(content string) error {
func AddPublicKey(key *PublicKey) (err error) { // Same key can only be added once.
has, err := x.Get(key) has, err := x.Where("content=?", content).Get(new(PublicKey))
if err != nil { if err != nil {
return err return err
} else if has { } else if has {
return ErrKeyAlreadyExist return ErrKeyAlreadyExist{0, content}
} }
return nil
}
func addKey(e Engine, key *PublicKey) (err error) {
// Calculate fingerprint. // Calculate fingerprint.
tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()), tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
"id_rsa.pub"), "\\", "/", -1) "id_rsa.pub"), "\\", "/", -1)
os.MkdirAll(path.Dir(tmpPath), os.ModePerm) 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 return err
} }
stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath) 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) return errors.New("not enough output for calculating fingerprint: " + stdout)
} }
key.Fingerprint = strings.Split(stdout, " ")[1] key.Fingerprint = strings.Split(stdout, " ")[1]
if has, err := x.Get(&PublicKey{Fingerprint: key.Fingerprint}); err == nil && has {
return ErrKeyAlreadyExist
}
// Save SSH key. // Save SSH key.
if _, err = x.Insert(key); err != nil { if _, err = e.Insert(key); err != nil {
return err return err
} else if err = saveAuthorizedKeyFile(key); err != nil { }
// Roll back. return saveAuthorizedKeyFile(key)
if _, err2 := x.Delete(key); err2 != nil { }
return err2
} // 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 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. // GetPublicKeyByID returns public key by given ID.
func GetPublicKeyById(keyId int64) (*PublicKey, error) { func GetPublicKeyByID(keyID int64) (*PublicKey, error) {
key := new(PublicKey) key := new(PublicKey)
has, err := x.Id(keyId).Get(key) has, err := x.Id(keyID).Get(key)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, ErrKeyNotExist return nil, ErrKeyNotExist{keyID}
} }
return key, nil return key, nil
} }
@ -334,16 +381,7 @@ func GetPublicKeyById(keyId int64) (*PublicKey, error) {
// ListPublicKeys returns a list of public keys belongs to given user. // ListPublicKeys returns a list of public keys belongs to given user.
func ListPublicKeys(uid int64) ([]*PublicKey, error) { func ListPublicKeys(uid int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5) keys := make([]*PublicKey, 0, 5)
err := x.Where("owner_id=?", uid).Find(&keys) return keys, 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
} }
// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file. // 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() defer fw.Close()
isFound := false isFound := false
keyword := fmt.Sprintf("key-%d", key.Id) keyword := fmt.Sprintf("key-%d", key.ID)
buf := bufio.NewReader(fr) buf := bufio.NewReader(fr)
for { for {
line, errRead := buf.ReadString('\n') line, errRead := buf.ReadString('\n')
@ -401,20 +439,19 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
// UpdatePublicKey updates given public key. // UpdatePublicKey updates given public key.
func UpdatePublicKey(key *PublicKey) error { func UpdatePublicKey(key *PublicKey) error {
_, err := x.Id(key.Id).AllCols().Update(key) _, err := x.Id(key.ID).AllCols().Update(key)
return err return err
} }
// DeletePublicKey deletes SSH key information both in database and authorized_keys file. func deletePublicKey(e *xorm.Session, key *PublicKey) error {
func DeletePublicKey(key *PublicKey) error { has, err := e.Get(key)
has, err := x.Get(key)
if err != nil { if err != nil {
return err return err
} else if !has { } 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 return err
} }
@ -428,6 +465,21 @@ func DeletePublicKey(key *PublicKey) error {
return os.Rename(tmpPath, fpath) 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. // RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
func RewriteAllPublicKeys() error { func RewriteAllPublicKeys() error {
sshOpLocker.Lock() sshOpLocker.Lock()
@ -461,3 +513,162 @@ func RewriteAllPublicKeys() error {
return nil 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/cae/zip"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata" "github.com/gogits/gogs/modules/bindata"
@ -35,12 +36,11 @@ const (
) )
var ( var (
ErrRepoAlreadyExist = errors.New("Repository already exist")
ErrRepoFileNotExist = errors.New("Repository file does not exist") ErrRepoFileNotExist = errors.New("Repository file does not exist")
ErrRepoNameIllegal = errors.New("Repository name contains illegal characters")
ErrRepoFileNotLoaded = errors.New("Repository file not loaded") ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
ErrMirrorNotExist = errors.New("Mirror does not exist") ErrMirrorNotExist = errors.New("Mirror does not exist")
ErrInvalidReference = errors.New("Invalid reference specified") ErrInvalidReference = errors.New("Invalid reference specified")
ErrNameEmpty = errors.New("Name is empty")
) )
var ( var (
@ -222,13 +222,17 @@ func (repo *Repository) DescriptionHtml() template.HTML {
return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize)) 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(e Engine, u *User, repoName string) (bool, error) {
func IsRepositoryExist(u *User, repoName string) bool { has, err := e.Get(&Repository{
has, _ := x.Get(&Repository{
OwnerId: u.Id, OwnerId: u.Id,
LowerName: strings.ToLower(repoName), 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. // 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 { if err = repo.GetOwner(); err != nil {
return cl, err return cl, err
} }
if setting.SSHPort != 22 { 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 { } 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) cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName)
return cl, nil return cl, nil
} }
var ( var (
illegalEquals = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"} reservedNames = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
illegalSuffixs = []string{".git", ".keys"} reservedPatterns = []string{"*.git", "*.keys"}
) )
// IsLegalName returns false if name contains illegal characters. // IsUsableName checks if name is reserved or pattern of name is not allowed.
func IsLegalName(repoName string) bool { func IsUsableName(name string) error {
repoName = strings.ToLower(repoName) name = strings.TrimSpace(strings.ToLower(name))
for _, char := range illegalEquals { if utf8.RuneCountInString(name) == 0 {
if repoName == char { return ErrNameEmpty
return false }
for i := range reservedNames {
if name == reservedNames[i] {
return ErrNameReserved{name}
} }
} }
for _, char := range illegalSuffixs {
if strings.HasSuffix(repoName, char) { for _, pat := range reservedPatterns {
return false 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. // 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 // FIXME: this command could for both migrate and mirror
_, stderr, err := process.ExecTimeout(10*time.Minute, _, stderr, err := process.ExecTimeout(10*time.Minute,
fmt.Sprintf("MigrateRepository: %s", repoPath), fmt.Sprintf("MigrateRepository: %s", repoPath),
"git", "clone", "--mirror", "--bare", url, repoPath) "git", "clone", "--mirror", "--bare", "--quiet", url, repoPath)
if err != nil { 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 { } else if err = createUpdateHook(repoPath); err != nil {
return repo, fmt.Errorf("create update hook: %v", err) 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) return repo, UpdateRepository(repo, false)
} }
@ -406,13 +427,18 @@ func createUpdateHook(repoPath string) error {
// InitRepository initializes README and .gitignore if needed. // InitRepository initializes README and .gitignore if needed.
func initRepository(e Engine, repoPath string, u *User, repo *Repository, initReadme bool, repoLang, license string) error { 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. // Init bare new repository.
os.MkdirAll(repoPath, os.ModePerm) os.MkdirAll(repoPath, os.ModePerm)
_, stderr, err := process.ExecDir(-1, repoPath, _, stderr, err := process.ExecDir(-1, repoPath,
fmt.Sprintf("initRepository(git init --bare): %s", repoPath), fmt.Sprintf("initRepository(git init --bare): %s", repoPath),
"git", "init", "--bare") "git", "init", "--bare")
if err != nil { if err != nil {
return errors.New("git init --bare: " + stderr) return fmt.Errorf("git init --bare: %s", err)
} }
if err := createUpdateHook(repoPath); err != nil { 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. // Clone to temprory path and do the init commit.
tmpDir := filepath.Join(os.TempDir(), com.ToStr(time.Now().Nanosecond())) tmpDir := filepath.Join(os.TempDir(), com.ToStr(time.Now().Nanosecond()))
os.MkdirAll(tmpDir, os.ModePerm) os.MkdirAll(tmpDir, os.ModePerm)
defer os.RemoveAll(tmpDir)
_, stderr, err = process.Exec( _, stderr, err = process.Exec(
fmt.Sprintf("initRepository(git clone): %s", repoPath), 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) { } else if com.IsSliceContainsStr(Gitignores, repoLang) {
if err = ioutil.WriteFile(targetPath, 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) return fmt.Errorf("generate gitignore: %v", err)
} }
} else { } else {
@ -480,7 +507,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
} }
} else if com.IsSliceContainsStr(Licenses, license) { } else if com.IsSliceContainsStr(Licenses, license) {
if err = ioutil.WriteFile(targetPath, 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) return fmt.Errorf("generate license: %v", err)
} }
} else { } else {
@ -502,16 +529,50 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
return initRepoCommit(tmpDir, u.NewGitSig()) return initRepoCommit(tmpDir, u.NewGitSig())
} }
// CreateRepository creates a repository for given user or organization. func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) { if err = IsUsableName(repo.Name); err != nil {
if !IsLegalName(name) { return err
return nil, ErrRepoNameIllegal
} }
if IsRepositoryExist(u, name) { has, err := isRepositoryExist(e, u, repo.Name)
return nil, ErrRepoAlreadyExist 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{ repo := &Repository{
OwnerId: u.Id, OwnerId: u.Id,
Owner: u, Owner: u,
@ -527,35 +588,10 @@ func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMi
return nil, err return nil, err
} }
if _, err = sess.Insert(repo); 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 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. // No need for init mirror.
if !isMirror { if !isMirror {
repoPath := RepoPath(u.Name, repo.Name) repoPath := RepoPath(u.Name, repo.Name)
@ -599,7 +635,7 @@ func GetRepositoriesWithUsers(num, offset int) ([]*Repository, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } 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. // Check if new owner has repository with same name.
if IsRepositoryExist(newOwner, repo.Name) { has, err := IsRepositoryExist(newOwner, repo.Name)
return ErrRepoAlreadyExist if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{newOwnerName, repo.Name}
} }
sess := x.NewSession() 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. // ChangeRepositoryName changes all corresponding setting from old repository name to new one.
func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) { func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) {
userName = strings.ToLower(userName)
oldRepoName = strings.ToLower(oldRepoName) oldRepoName = strings.ToLower(oldRepoName)
newRepoName = strings.ToLower(newRepoName) newRepoName = strings.ToLower(newRepoName)
if !IsLegalName(newRepoName) { if err = IsUsableName(newRepoName); err != nil {
return ErrRepoNameIllegal 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. // 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) { func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
@ -833,7 +878,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err return err
} else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil { } else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil {
return err return err
} else if _, err = sess.Delete(&Milestone{RepoId: repoID}); err != nil { } else if _, err = sess.Delete(&Milestone{RepoID: repoID}); err != nil {
return err return err
} else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil { } else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil {
return err return err
@ -847,12 +892,12 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err return err
} }
for i := range issues { 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 return err
} }
} }
if _, err = sess.Delete(&Issue{RepoId: repoID}); err != nil { if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil {
return err return err
} }
@ -1008,6 +1053,7 @@ var (
// Prevent duplicate tasks. // Prevent duplicate tasks.
isMirrorUpdating = false isMirrorUpdating = false
isGitFscking = false isGitFscking = false
isCheckingRepos = false
) )
// MirrorUpdate checks and updates mirror repositories. // MirrorUpdate checks and updates mirror repositories.
@ -1029,7 +1075,7 @@ func MirrorUpdate() {
repoPath := filepath.Join(setting.RepoRootPath, m.RepoName+".git") repoPath := filepath.Join(setting.RepoRootPath, m.RepoName+".git")
if _, stderr, err := process.ExecDir(10*time.Minute, if _, stderr, err := process.ExecDir(10*time.Minute,
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath), 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) desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
log.Error(4, desc) log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil { 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) { // HasForkedRepo checks if given user has already forked a repository with given ID.
if IsRepositoryExist(u, name) { func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
return nil, ErrRepoAlreadyExist repo := new(Repository)
} has, _ := x.Where("owner_id=? AND fork_id=?", ownerID, repoID).Get(repo)
return repo, has
// In case the old repository is a fork. }
if oldRepo.IsFork {
oldRepo, err = GetRepositoryById(oldRepo.ForkId)
if err != nil {
return nil, err
}
}
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
repo := &Repository{ repo := &Repository{
OwnerId: u.Id, OwnerId: u.Id,
Owner: u, Owner: u,
@ -1369,32 +1446,8 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
return nil, err return nil, err
} }
if _, err = sess.Insert(repo); err != nil { if err = createRepository(sess, u, repo); err != nil {
return nil, err
}
if err = repo.recalculateAccesses(sess); err != nil {
return nil, err 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 { if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.Id); err != nil {

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

@ -9,6 +9,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"io/ioutil" "io/ioutil"
"sync"
"time" "time"
"github.com/gogits/gogs/modules/httplib" "github.com/gogits/gogs/modules/httplib"
@ -259,7 +260,9 @@ func (p Payload) GetJSONPayload() ([]byte, error) {
// HookTask represents a hook task. // HookTask represents a hook task.
type HookTask struct { type HookTask struct {
Id int64 ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
HookID int64
Uuid string Uuid string
Type HookTaskType Type HookTaskType
Url string Url string
@ -269,6 +272,7 @@ type HookTask struct {
EventType HookEventType EventType HookEventType
IsSsl bool IsSsl bool
IsDelivered bool IsDelivered bool
Delivered int64
IsSucceed bool IsSucceed bool
} }
@ -287,87 +291,137 @@ func CreateHookTask(t *HookTask) error {
// UpdateHookTask updates information of hook task. // UpdateHookTask updates information of hook task.
func UpdateHookTask(t *HookTask) error { func UpdateHookTask(t *HookTask) error {
_, err := x.Id(t.Id).AllCols().Update(t) _, err := x.Id(t.ID).AllCols().Update(t)
return err return err
} }
var ( type hookQueue struct {
// Prevent duplicate deliveries. // Make sure one repository only occur once in the queue.
// This happens with massive hook tasks cannot finish delivering lock sync.Mutex
// before next shooting starts. repoIDs map[int64]bool
isShooting = false
)
// DeliverHooks checks and delivers undelivered hooks. queue chan int64
// FIXME: maybe can use goroutine to shoot a number of them at same time? }
func DeliverHooks() {
if isShooting { 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 return
} }
isShooting = true q.repoIDs[id] = true
defer func() { isShooting = false }() 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 timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask), req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
func(idx int, bean interface{}) error { Header("X-Gogs-Delivery", t.Uuid).
t := bean.(*HookTask) Header("X-Gogs-Event", string(t.EventType)).
req := httplib.Post(t.Url).SetTimeout(timeout, timeout). SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
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)
}
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. t.IsDelivered = true
switch t.Type {
case GOGS: // FIXME: record response.
{ switch t.Type {
if _, err := req.Response(); err != nil { case GOGS:
log.Error(5, "Delivery: %v", err) {
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 { } else {
t.IsSucceed = true 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 { // DeliverHooks checks and delivers undelivered hooks.
log.Trace("Hook delivered(%s): %s", t.Uuid, t.PayloadContent) 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 return nil
}) })
// Update hook task status. // Update hook task status.
for _, t := range tasks { for _, t := range tasks {
if err := UpdateHookTask(t); err != nil { 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 { type AdminEditUserForm struct {
FullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `binding:"Required;Email;MaxSize(50)"` Email string `binding:"Required;Email;MaxSize(50)"`
Password string `binding:"OmitEmpty;MinSize(6);MaxSize(255)"` Password string `binding:"OmitEmpty;MinSize(6);MaxSize(255)"`
Website string `binding:"MaxSize(50)"` Website string `binding:"MaxSize(50)"`

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

@ -30,6 +30,7 @@ type AuthenticationForm struct {
SMTPPort int `form:"smtp_port"` SMTPPort int `form:"smtp_port"`
TLS bool `form:"tls"` TLS bool `form:"tls"`
AllowAutoRegister bool `form:"allowautoregister"` AllowAutoRegister bool `form:"allowautoregister"`
PAMServiceName string
} }
func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { 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 { 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)"` OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"` Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Description string `form:"desc" binding:"MaxSize(255)"` 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 { type CreateMilestoneForm struct {
Title string `form:"title" binding:"Required;MaxSize(50)"` Title string `binding:"Required;MaxSize(50)"`
Content string `form:"content"` Content string
Deadline string `form:"due_date"` Deadline string
} }
func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { 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 { type CreateLabelForm struct {
Title string `form:"title" binding:"Required;MaxSize(50)"` ID int64
Color string `form:"color" binding:"Required;Size(7)"` 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 { func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

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

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

File diff suppressed because one or more lines are too long

@ -15,10 +15,10 @@ var c = New()
func NewCronContext() { func NewCronContext() {
c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate) 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 { if setting.Git.Fsck.Enable {
c.AddFunc("Repository health check", fmt.Sprintf("@every %dh", setting.Git.Fsck.Interval), models.GitFsck) 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() c.Start()
} }

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

@ -7,6 +7,7 @@ package git
import ( import (
"bytes" "bytes"
"container/list" "container/list"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -67,3 +68,10 @@ func isFile(filePath string) bool {
} }
return !f.IsDir() 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()), ".") + "()" 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 { } else {
lm.msg = msg lm.msg = msg
} }

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

@ -10,6 +10,7 @@ import (
"github.com/Unknwon/macaron" "github.com/Unknwon/macaron"
"github.com/macaron-contrib/csrf" "github.com/macaron-contrib/csrf"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
@ -49,6 +50,12 @@ func Toggle(options *ToggleOptions) macaron.Handler {
if options.SignInRequire { if options.SignInRequire {
if !ctx.IsSigned { 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.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login") ctx.Redirect(setting.AppSubUrl + "/user/login")
return 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 { func ApiReqToken() macaron.Handler {
return func(ctx *Context) { return func(ctx *Context) {
if !ctx.IsSigned { if !ctx.IsSigned {

@ -106,6 +106,12 @@ func (ctx *Context) HasError() bool {
return hasErr.(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. // HTML calls Context.HTML and converts template name to string.
func (ctx *Context) HTML(status int, name base.TplName) { func (ctx *Context) HTML(status int, name base.TplName) {
ctx.Context.HTML(status, string(name)) 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))) 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{}) { func (ctx *Context) HandleAPI(status int, obj interface{}) {
var message string var message string
if err, ok := obj.(error); ok { if err, ok := obj.(error); ok {

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

@ -10,6 +10,8 @@ import (
"strings" "strings"
"github.com/Unknwon/macaron" "github.com/Unknwon/macaron"
"github.com/mcuadros/go-version"
"github.com/mssola/user_agent"
"github.com/gogits/gogs/models" "github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
@ -18,6 +20,11 @@ import (
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
const (
FIREFOX_COPY_SUPPORT = "41.0"
CHROME_COPY_SUPPORT = "43.0.2356"
)
func ApiRepoAssignment() macaron.Handler { func ApiRepoAssignment() macaron.Handler {
return func(ctx *Context) { return func(ctx *Context) {
userName := ctx.Params(":username") userName := ctx.Params(":username")
@ -34,7 +41,7 @@ func ApiRepoAssignment() macaron.Handler {
} else { } else {
u, err = models.GetUserByName(userName) u, err = models.GetUserByName(userName)
if err != nil { if err != nil {
if err == models.ErrUserNotExist { if models.IsErrUserNotExist(err) {
ctx.Error(404) ctx.Error(404)
} else { } else {
ctx.JSON(500, &base.ApiJsonErr{"GetUserByName: " + err.Error(), base.DOC_URL}) ctx.JSON(500, &base.ApiJsonErr{"GetUserByName: " + err.Error(), base.DOC_URL})
@ -210,7 +217,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
} else { } else {
u, err = models.GetUserByName(userName) u, err = models.GetUserByName(userName)
if err != nil { if err != nil {
if err == models.ErrUserNotExist { if models.IsErrUserNotExist(err) {
ctx.Handle(404, "GetUserByName", err) ctx.Handle(404, "GetUserByName", err)
} else { } else {
ctx.Handle(500, "GetUserByName", err) 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["BranchName"] = ctx.Repo.BranchName
ctx.Data["CommitId"] = ctx.Repo.CommitId 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) { return func(ctx *Context) {
if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN { if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN {
if !ctx.IsSigned { if !ctx.IsSigned {

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

@ -18,8 +18,6 @@ case "$1" in
chown ${APP_USER}.${APP_GROUP} $(dirname ${APP_CONFIG}) chown ${APP_USER}.${APP_GROUP} $(dirname ${APP_CONFIG})
[ -f ${APP_CONFIG} ] || ${CLI} run cp conf/app.ini ${APP_CONFIG} [ -f ${APP_CONFIG} ] || ${CLI} run cp conf/app.ini ${APP_CONFIG}
${CLI} config:set USER=${APP_USER} ${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_USER = git|RUN_USER = ${APP_USER}|" ${APP_CONFIG}
sed -i "s|RUN_MODE = dev|RUN_MODE = prod|" ${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 { .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:not([href]) {
.markdown a { color: inherit;
color: #4183C4; 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 h1,
.markdown h2, .markdown h2,
.markdown h3, .markdown h3,
.markdown h4, .markdown h4,
.markdown h5, .markdown h5,
.markdown h6 { .markdown h6 {
line-height: 1.7; position: relative;
padding: 15px 0 0; margin-top: 1em;
margin: 0 0 15px; margin-bottom: 16px;
color: #444;
font-weight: bold; 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:hover .anchor .octicon-link,
.markdown h1, .markdown h2:hover .anchor .octicon-link,
.markdown h2 { .markdown h3:hover .anchor .octicon-link,
border-bottom: 1px solid #EEE; .markdown h4:hover .anchor .octicon-link,
.markdown h5:hover .anchor .octicon-link,
.markdown h6:hover .anchor .octicon-link {
display: inline-block;
} }
.markdown h1 tt,
.markdown h2 { .markdown h1 code,
border-bottom: 1px solid #EEE; .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 { .markdown h1 {
color: #000; padding-bottom: 0.3em;
font-size: 33px font-size: 2.25em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
.markdown h1 .anchor {
line-height: 1;
} }
.markdown h2 { .markdown h2 {
color: #333; padding-bottom: 0.3em;
font-size: 28px font-size: 1.75em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
.markdown h2 .anchor {
line-height: 1;
} }
.markdown h3 { .markdown h3 {
font-size: 22px font-size: 1.5em;
line-height: 1.43;
}
.markdown h3 .anchor {
line-height: 1.2;
} }
.markdown h4 { .markdown h4 {
font-size: 18px font-size: 1.25em;
}
.markdown h4 .anchor {
line-height: 1.2;
} }
.markdown h5 { .markdown h5 {
font-size: 14px font-size: 1em;
}
.markdown h5 .anchor {
line-height: 1.1;
} }
.markdown h6 { .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 { .markdown table {
border-collapse: collapse;
border-spacing: 0;
display: block; display: block;
overflow: auto;
width: 100%; width: 100%;
margin: 0 0 9px; overflow: auto;
word-break: normal;
word-break: keep-all;
} }
.markdown table th { .markdown table th {
font-weight: 700 font-weight: bold;
} }
.markdown table th, .markdown table th,
.markdown table td { .markdown table td {
border: 1px solid #DDD; padding: 6px 13px !important;
padding: 6px 13px; border: 1px solid #ddd;
} }
.markdown table tr { .markdown table tr {
background-color: #FFF; background-color: #fff;
border-top: 1px solid #CCC; border-top: 1px solid #ccc;
} }
.markdown table tr:nth-child(2n) { .markdown table tr:nth-child(2n) {
background-color: #F8F8F8 background-color: #f8f8f8;
} }
.markdown img {
.markdown li { max-width: 100%;
line-height: 1.6; box-sizing: border-box;
margin-top: 6px;
} }
.markdown .emoji {
.markdown li:first-child { max-width: none;
margin-top: 0;
} }
.markdown span.frame {
.markdown dl dt { display: block;
font-style: italic; overflow: hidden;
margin-top: 9px;
} }
.markdown span.frame > span {
.markdown dl dd { display: block;
margin: 0 0 9px; float: left;
padding: 0 9px; width: auto;
padding: 7px;
margin: 13px 0 0;
overflow: hidden;
border: 1px solid #ddd;
} }
.markdown span.frame span img {
.markdown blockquote, display: block;
.markdown blockquote p { float: left;
font-size: 14px;
background-color: #f5f5f5;
} }
.markdown span.frame span span {
.markdown > pre { display: block;
line-height: 1.6; padding: 5px 0 0;
overflow: auto; clear: both;
background: #f8f8f8; color: #333;
border: 1px solid #ddd;
padding: 0;
} }
.markdown span.align-center {
.markdown > pre.linenums { display: block;
padding: 0; overflow: hidden;
clear: both;
} }
.markdown span.align-center > span {
.markdown > pre > ol.linenums { display: block;
list-style: none; margin: 13px auto 0;
padding: 0; overflow: hidden;
text-align: center;
} }
.markdown span.align-center span img {
.markdown > pre > ol.linenums > li { margin: 0 auto;
margin-top: 2px; text-align: center;
} }
.markdown span.align-right {
.markdown > pre.nums-style > ol.linenums { display: block;
list-style-type: decimal; overflow: hidden;
padding: 0 0 0 40px; clear: both;
-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 > span {
.markdown > pre > code { display: block;
white-space: pre; margin: 13px 0 0;
word-wrap: normal; overflow: hidden;
text-align: right;
} }
.markdown span.align-right span img {
.markdown > pre > ol.linenums > li { margin: 0;
padding: 0 10px; text-align: right;
} }
.markdown span.float-left {
.markdown > pre > ol.linenums > li:first-child { display: block;
padding-top: 12px; float: left;
margin-right: 13px;
overflow: hidden;
} }
.markdown span.float-left span {
.markdown > pre > ol.linenums > li:last-child { margin: 13px 0 0;
padding-bottom: 12px;
} }
.markdown span.float-right {
.markdown > pre.nums-style > ol.linenums > li { display: block;
border-left: 1px solid #ddd; float: right;
margin-left: 13px;
overflow: hidden;
} }
.markdown span.float-right > span {
.markdown hr { display: block;
border: none; margin: 13px auto 0;
color: #ccc; overflow: hidden;
height: 4px; text-align: right;
}
.markdown code,
.markdown tt {
padding: 0; padding: 0;
margin: 15px 0; padding-top: 0.2em;
border-bottom: 2px solid #EEE; padding-bottom: 0.2em;
} margin: 0;
font-size: 85%;
.markdown blockquote:last-child, background-color: rgba(0, 0, 0, 0.04);
.markdown ul:last-child, border-radius: 3px;
.markdown ol:last-child, }
.markdown > pre:last-child, .markdown code:before,
.markdown > pre:last-child, .markdown code:after,
.markdown p:last-child { .markdown tt:before,
margin-bottom: 0; .markdown tt:after {
letter-spacing: -0.2em;
content: "\00a0";
}
.markdown code br,
.markdown tt br {
display: none;
} }
.markdown del code {
.markdown img { text-decoration: inherit;
max-width: 100%;
} }
.markdown pre > code {
.markdown .btn { padding: 0;
color: #fff; margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
} }
.markdown .highlight {
.markdown .anchor-wrap { margin-bottom: 16px;
/*margin-top: -50px;*/
/*padding-top: 50px;*/
} }
.markdown .highlight pre,
.markdown h1 a, .markdown h2 a, .markdown h3 a { .markdown pre {
text-decoration: none; padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border-radius: 3px;
} }
.markdown .highlight pre {
.markdown h1 a.anchor, margin-bottom: 0;
.markdown h2 a.anchor, word-break: normal;
.markdown h3 a.anchor, }
.markdown h4 a.anchor, .markdown pre {
.markdown h5 a.anchor, word-wrap: normal;
.markdown h6 a.anchor { }
text-decoration:none; .markdown pre code,
line-height:1; .markdown pre tt {
padding-left:0; display: inline;
margin-left:5px; max-width: initial;
top:15%; padding: 0;
} margin: 0;
.markdown a span.octicon { overflow: initial;
font-size: 16px; line-height: inherit;
font-family: "FontAwesome"; word-wrap: normal;
line-height: 1; 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; display: inline-block;
text-decoration: none; padding: 3px 5px;
-webkit-font-smoothing: antialiased; 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 .csv-data .blob-num {
.markdown a span.octicon-link { padding: 10px 8px 9px;
display: none; text-align: right;
color: #000; background: #fff;
border: 0;
} }
.markdown .csv-data tr {
.markdown a span.octicon-link:before { border-top: 0;
content: "\f0c1";
} }
.markdown .csv-data th {
.markdown h1:hover .octicon-link, font-weight: bold;
.markdown h2:hover .octicon-link, background: #f8f8f8;
.markdown h3:hover .octicon-link, border-top: 0;
.markdown h4:hover .octicon-link,
.markdown h5:hover .octicon-link,
.markdown h6:hover .octicon-link {
display:inline-block
} }
/* Author: jmblog */ /* Author: jmblog */
/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */ /* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */
/* GitHub Theme */ /* GitHub Theme */
@ -239,74 +412,60 @@
.pln { .pln {
color: #333333; color: #333333;
} }
@media screen { @media screen {
/* string content */ /* string content */
.str { .str {
color: #dd1144; color: #dd1144;
} }
/* a keyword */ /* a keyword */
.kwd { .kwd {
color: #333333; color: #333333;
} }
/* a comment */ /* a comment */
.com { .com {
color: #999988; color: #999988;
font-style: italic; font-style: italic;
} }
/* a type name */ /* a type name */
.typ { .typ {
color: #445588; color: #445588;
} }
/* a literal value */ /* a literal value */
.lit { .lit {
color: #445588; color: #445588;
} }
/* punctuation */ /* punctuation */
.pun { .pun {
color: #333333; color: #333333;
} }
/* lisp open bracket */ /* lisp open bracket */
.opn { .opn {
color: #333333; color: #333333;
} }
/* lisp close bracket */ /* lisp close bracket */
.clo { .clo {
color: #333333; color: #333333;
} }
/* a markup tag name */ /* a markup tag name */
.tag { .tag {
color: navy; color: navy;
} }
/* a markup attribute name */ /* a markup attribute name */
.atn { .atn {
color: teal; color: teal;
} }
/* a markup attribute value */ /* a markup attribute value */
.atv { .atv {
color: #dd1144; color: #dd1144;
} }
/* a declaration */ /* a declaration */
.dec { .dec {
color: #333333; color: #333333;
} }
/* a variable name */ /* a variable name */
.var { .var {
color: teal; color: teal;
} }
/* a function name */ /* a function name */
.fun { .fun {
color: #990000; color: #990000;
@ -317,69 +476,39 @@
.str { .str {
color: #006600; color: #006600;
} }
.kwd { .kwd {
color: #006; color: #006;
font-weight: bold; font-weight: bold;
} }
.com { .com {
color: #600; color: #600;
font-style: italic; font-style: italic;
} }
.typ { .typ {
color: #404; color: #404;
font-weight: bold; font-weight: bold;
} }
.lit { .lit {
color: #004444; color: #004444;
} }
.pun,
.pun, .opn, .clo { .opn,
.clo {
color: #444400; color: #444400;
} }
.tag { .tag {
color: #006; color: #006;
font-weight: bold; font-weight: bold;
} }
.atn { .atn {
color: #440044; color: #440044;
} }
.atv { .atv {
color: #006600; color: #006600;
} }
} }
/* Specify class=linenums on a pre to get line numbering */ /* Specify class=linenums on a pre to get line numbering */
ol.linenums { ol.linenums {
margin-top: 0; margin-top: 0;
margin-bottom: 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')) { if ($(selector).hasClass('js-copy-bind')) {
return; return;
} }
$(selector).zclip({
path: "/js/ZeroClipboard.swf", if ( document.documentElement.classList.contains("is-copy-enabled") ) {
copy: function () {
var t = $(this).data("copy-val"); $(selector).click(function(event) {
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); 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 () { setTimeout(function () {
$this.tooltip("show"); $this.tipsy("show");
}, 200); }, 200);
setTimeout(function () { setTimeout(function () {
$this.tooltip('hide') $this.tipsy('hide').attr('original-title', $this.data('original-title'));
.attr('data-original-title', 'Copy to Clipboard'); }, 2000);
}, 3000);
} this.blur();
}).addClass("js-copy-bind"); 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 // api working
@ -770,6 +796,7 @@ function initIssue() {
$("#issue-edit-btn").on("click", function () { $("#issue-edit-btn").on("click", function () {
$('#issue h1.title,#issue .issue-main > .issue-content .content,#issue-edit-btn').toggleHide(); $('#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-title,.issue-edit-content,.issue-edit-cancel,.issue-edit-save').toggleShow();
$('#issue-edit-content').focus();
}); });
$('.issue-edit-cancel').on("click", function () { $('.issue-edit-cancel').on("click", function () {
$('#issue h1.title,#issue .issue-main > .issue-content .content,#issue-edit-btn').toggleShow(); $('#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 () { $(document).ready(function () {
// Semantic UI modules. csrf = $('meta[name=_csrf]').attr("content");
$('.dropdown').dropdown({
// Semantic UI modules.
$('.dropdown').dropdown();
$('.jump.dropdown').dropdown({
action: 'hide'
});
$('.slide.up.dropdown').dropdown({
transition: 'slide up' 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