Compare commits

...

155 Commits

Author SHA1 Message Date
Unknwon
54930c001d Prepare for v0.5.5 2014-10-10 16:22:49 -04:00
Unknwon
41dbb4c148 Hide org member in collar page 2014-10-10 06:15:27 -04:00
Unknwon
85c9f7c5f3 Issue: Show error prompt when add repository to team and it does not exist #533 2014-10-10 05:06:12 -04:00
无闻
c31606daf9 Merge pull request #544 from TonyTsangHK/dev
Add locale zh-HK (Traditional Chinese)
2014-10-10 03:41:39 -04:00
Unknwon
d78abd3561 Mirror fix on admin/orgs paging 2014-10-10 03:28:21 -04:00
Tony Tsang
8c71ab5094 Add locale zh-HK (Traditional Chinese) 2014-10-10 14:17:47 +08:00
Unknwon
79262173a6 Webhook delivery locking & Hide repo for org members if they don't have access 2014-10-09 19:01:22 -04:00
Unknwon
7b03b1df0e Allow custom locale 2014-10-09 18:35:09 -04:00
Unknwon
39931f8e00 Allow mail with self-signed certificates 2014-10-09 18:08:07 -04:00
Unknwon
1aa76bd279 Fix #532, add system notice 2014-10-08 18:29:18 -04:00
无闻
54c9844d66 Merge pull request #539 from Xefir/dev
Fix malformed address
2014-10-08 12:30:59 -04:00
Michel Roux
6705559ce0 Fix malformed address 2014-10-08 18:29:02 +02:00
无闻
8e8dfaf227 Merge pull request #538 from m0sth8/fix-timesince
Add omitted lang
2014-10-08 12:17:07 -04:00
Vyacheslav Bakhmutov
ce7422473a add omitted lang 2014-10-08 12:27:05 +04:00
Unknwon
fc18741cc7 Fix #524 2014-10-07 07:02:53 -04:00
Unknwon
fef09c2de6 Fix badges 2014-10-06 19:35:41 -04:00
Unknwon
1e1f9e7166 Update with macaron 2014-10-06 19:12:52 -04:00
Unknwon
64c68220d2 Fix #264 2014-10-06 17:50:00 -04:00
Unknwon
91e5c24a31 Fix #522 2014-10-06 10:36:32 -04:00
无闻
810ff480b8 Merge pull request #531 from basilfx/dev
Updated Dutch translations
2014-10-05 18:09:34 -04:00
无闻
de65c30770 Merge pull request #530 from chk1/master
Add and translate missing German strings for user page
2014-10-05 18:09:19 -04:00
Bas Stottelaar
bbf5bcdf99 Updated Dutch translations
Fixed some spelling mistakes.

* Number up to 20 are written as words instead of digits.
* Nouns are written without spaces.
* Fixed mixups between informal/formal language.
* Removal of extra spaces in sentences.
2014-10-05 21:03:07 +02:00
unknown
02b53aff0f Add and translate missing German strings for user page 2014-10-05 17:26:32 +02:00
无闻
b694cc88e4 Merge pull request #525 from linquize/tag-sort-reverse
sort tags in descending order by version number
2014-10-05 00:08:24 -04:00
Linquize
67c44b7d27 If git >= 2.0, sort tags in descending order by version number 2014-10-05 11:59:54 +08:00
Unknwon
263d409326 Basic xss prevention 2014-10-04 17:15:22 -04:00
无闻
6a79b76531 Merge pull request #529 from chk1/master
Translate missing entries & add German translation to homepage
2014-10-04 15:56:43 -04:00
unknown
da0fbbadc2 Fix memecache/memcache typo 2014-10-04 21:44:17 +02:00
unknown
1031271224 Add German translation to home page 2014-10-04 21:33:32 +02:00
unknown
8c70bcee99 Translate missing strings and some improvements 2014-10-04 21:32:55 +02:00
无闻
07c8925805 Merge pull request #527 from michaelboke/master
Dutch translations
2014-10-04 15:26:29 -04:00
Michael Boke
29a7d1ce61 updated some strange translated message so they will match their context on the website 2014-10-04 10:32:31 +02:00
Michael Boke
500b8a2a0f updated translations with the latest master version 2014-10-04 10:22:03 +02:00
Michael Boke
ba1270df2d Merge remote-tracking branch 'upstream/master'
Conflicts:
	conf/app.ini
2014-10-03 22:51:07 +02:00
Michael Boke
ba0feadc34 Added dutch translations 2014-10-03 22:43:42 +02:00
Unknwon
405ee14711 Fix SMTP auth logic 2014-10-03 13:12:54 -04:00
无闻
1126522a99 Merge pull request #521 from DerDackel/dev
Added some missing strings under the [action] category to german localization
2014-10-01 10:42:46 -04:00
Sebastian Jackel
1601b27ad3 Added some missing strings under the [action] category to german localization 2014-10-01 14:47:34 +02:00
Unknwon
f03b6be8f9 Work on #516 2014-10-01 07:40:48 -04:00
无闻
3ffa17c49a Merge pull request #519 from silverkorn/dev
Debian's "init.d" - Tentative to fix user's environment variables loading
2014-09-30 21:39:12 -04:00
Danny B
98c719c342 Debian's Init.d workaround for loading user's environment variables with start-stop-daemon command.
Implies 2 running child, so the `stop` command usually needs a `KILL` instead of a `TERM` to close properly so I reduced it to 1 second to get quickly with the `KILL` signal.
2014-09-30 21:30:16 -04:00
Unknwon
2a031c1365 Fix #515 2014-09-30 04:39:53 -04:00
无闻
198567eccb Merge pull request #517 from silverkorn/dev
Added "init.d" service script for Debian-based Linux.
2014-09-29 22:00:31 -04:00
Danny B
f7de6d2b86 Added "init.d" service script for Debian-based Linux.
Compatible with "/etc/default/gogs" configuration file for adding or overwriting values.
Based on "/etc/init.d/skeleton" and tested on Raspbian 2014-06-20 (Debian 7.5 [Wheezy] ARM)

[TO FIX] For some reason, it's necessary to remove the value of RUN_USER from the app.ini configuration file because the following error occurs:
2014/09/28 18:12:53 [setting.go:182 NewConfigContext()] [E] Expect user(git) but current user is:
2014-09-29 21:52:45 -04:00
Unknwon
86eac0842b Fix feeds display issue 2014-09-29 18:58:04 -04:00
Unknwon
a046a31d2b UI: Confirmation box 2014-09-29 18:52:28 -04:00
Unknwon
cd084dacf1 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-09-29 05:38:52 -04:00
Unknwon
ac2055e33c Fix #514 2014-09-29 05:38:46 -04:00
无闻
96f4c9045a Merge pull request #513 from lbeltrame/add-centos-init-script
Add CentOS init script
2014-09-29 05:06:32 -04:00
Luca Beltrame
d95e7065d9 s/USER/GOGS_USER/g 2014-09-29 10:43:51 +02:00
Luca Beltrame
5e48c89c5e Add a CentOS init script 2014-09-29 10:41:29 +02:00
Unknwon
3cfa4a581c Bug: 500 when transfer repository to collaborator 2014-09-29 04:04:48 -04:00
无闻
ce6931a046 Merge pull request #512 from fundon/feature_support_dsa_key
support dsa key format
2014-09-29 00:57:49 -04:00
fundon
eb1e6f8e3e support dsa key format 2014-09-29 12:37:34 +08:00
无闻
263fc76b87 Merge pull request #507 from codeskyblue/dev
update .gobuild.yml inorder to support sqlite for amd64 arch
2014-09-28 18:07:00 -04:00
无闻
c1d047d16e Merge pull request #508 from chadoe/homelink
Fix user HomeLink when using a suburl
2014-09-28 18:05:58 -04:00
无闻
38f71af363 Merge pull request #509 from chadoe/avatarlink
Fix AvatarLink when using a suburl
2014-09-28 18:05:35 -04:00
无闻
ecdbeea3f5 Merge pull request #510 from evolvedlight/master
Fix minor typo
2014-09-28 18:05:16 -04:00
evolvedlight
b7b0ee7df9 Fix minor typo 2014-09-28 22:01:05 +01:00
Martin van Beurden
bb05ef907b Fix AvatarLink when using a suburl and gravatar is disabled or avatars are cached 2014-09-28 14:27:13 +02:00
Martin van Beurden
204952439a Fix user HomeLink when using a suburl 2014-09-28 13:55:58 +02:00
codeskyblue
e2e362f2dc update .gobuild.yml remove start.bat 2014-09-28 16:38:59 +08:00
codeskyblue
26a0888bee Merge branch 'master' into dev 2014-09-28 16:38:19 +08:00
codeskyblue
9ce0bd043c update .gobulid.yml 2014-09-28 16:37:58 +08:00
Unknwon
5e747bc877 Clean old dockerfiles 2014-09-28 03:31:50 -04:00
Unknwon
11af8658cf Simple fix 2014-09-28 01:54:25 -04:00
Unknwon
e6e6aaeacb Delete verbose 2014-09-28 01:45:03 -04:00
Unknwon
e3b78c47e2 Merge branch 'master' of github.com:gogits/gogs
Conflicts:
	public/ng/less/gogs/repository.less
	templates/repo/home.tmpl
2014-09-28 01:44:09 -04:00
Unknwon
49193bebd2 UI: Confirmation box 2014-09-28 01:38:25 -04:00
shengxiang
3598c1435e Update .gobuild.yml 2014-09-28 13:02:17 +08:00
shengxiang
ab59165d2f Create start.bat 2014-09-28 12:45:21 +08:00
shengxiang
092b59a297 Update .gobuild.yml 2014-09-28 12:44:37 +08:00
fuxiaohei
7d48f811f1 add issue router for new issue page ui preview 2014-09-27 19:03:07 +08:00
fuxiaohei
e3a27aeb25 template and ui fix 2014-09-27 17:31:44 +08:00
fuxiaohei
dccc50e9d4 template and ui fix 2014-09-27 17:08:57 +08:00
Unknwon
ad2ab6d214 Add modal to change username
Signed-off-by: Unknwon <joe2010xtmf@163.com>
2014-09-26 22:33:30 -04:00
Unknwon
b8368f98ff Add directory level commit message 2014-09-26 08:55:13 -04:00
无闻
3164354255 Merge pull request #503 from fundon/fix_lastcommit_user_email_link
Fix last commit user email link
2014-09-26 08:35:41 -04:00
fundon
54724c33ec no neet for md5 email 2014-09-26 13:46:51 +08:00
lunnyxiao
d1911658e1 remove debug info 2014-09-26 12:17:46 +08:00
无闻
c8b50975bc Merge pull request #501 from fundon/fix_suburl_undefined
bugfix, suburl defaults to empty string when suburl is undefined
2014-09-25 22:51:31 -04:00
Unknwon
10673417dc Mirror fix on transfer repo 2014-09-25 22:42:31 -04:00
Unknwon
ad52b2d791 Mirror fix on transfer repo 2014-09-25 22:36:07 -04:00
fundon
09c3c4e70c bugfix, suburl defaults to empty string when suburl is undefined 2014-09-26 10:29:57 +08:00
Unknwon
977779cdcf Mirror template bug fix 2014-09-25 20:55:14 -04:00
Unknwon
71e4689d11 Page: User profile 2014-09-25 19:33:39 -04:00
Unknwon
f69761563b Fix bug on transfer repo 2014-09-25 16:36:19 -04:00
无闻
57d48fb6a2 Merge pull request #498 from cedricziel/translations
[TASK] Refine german string for authentification source
2014-09-25 15:11:33 -04:00
fuxiaohei
7c30ae7002 is utils improvement 2014-09-25 21:52:58 +08:00
lunnyxiao
089d934547 add action repousername for transfer 2014-09-25 16:43:14 +08:00
Cedric Ziel
b0f8b1147c [TASK] Refine german string for authentification source 2014-09-25 09:16:43 +02:00
Unknwon
25268577a5 Fix download archive issue 2014-09-24 17:43:33 -04:00
lunnyxiao
612fdb98df bug fixed for download 404 from repo's home page 2014-09-24 21:05:09 +08:00
Unknwon
bd55b78775 Page: Commits and fix #249 2014-09-23 23:18:14 -04:00
Unknwon
5bbeeb0f1b Page: Commits and fix #249 2014-09-23 15:30:04 -04:00
Unknwon
93ee0838eb Page: Repository home page 2014-09-23 13:51:10 -04:00
Unknwon
a1109e6fbc Page: Repository home page 2014-09-23 13:47:54 -04:00
Unknwon
ebb05475ed Fix #495 and cannot view repository by tag 2014-09-23 13:06:25 -04:00
fuxiaohei
a11ed51bbb resize star font size 2014-09-24 00:01:48 +08:00
fuxiaohei
e0493259a6 resize star font size 2014-09-23 23:59:44 +08:00
fuxiaohei
b3f0d25ce5 pull request ui review, change sidebar 2014-09-23 23:48:28 +08:00
fuxiaohei
d750d53422 Merge remote-tracking branch 'origin/dev' into dev 2014-09-23 23:36:25 +08:00
fuxiaohei
8d5a4cc9eb pull request ui review, change sidebar 2014-09-23 23:36:09 +08:00
Unknwon
1476a1a729 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-09-23 10:29:52 -04:00
Unknwon
e3eea745f4 UI fix 2014-09-23 10:29:48 -04:00
fuxiaohei
60c65415dd pull request page ui review, upgrade octicon icons 2014-09-23 22:28:03 +08:00
无闻
b92cac7038 Merge pull request #496 from domnikl/patch-1
fixed typos and English phrases in German translation
2014-09-23 09:56:26 -04:00
fuxiaohei
904f799c1a improve ui details 2014-09-23 21:43:45 +08:00
Dominik Liebler
de2a4f8f83 fixed typos and English phrases
fixed Typo "Hilef"
2014-09-23 13:15:52 +02:00
Unknwon
135d3733b3 Feature: Integrate crypto/tls/generate_cert.go command 2014-09-22 17:30:58 -04:00
Unknwon
3f707b3f32 Add basic submodule support 2014-09-22 17:01:19 -04:00
Unknwon
063aacd436 UI: Use tooltip not alert when copy clone URL 2014-09-22 14:47:47 -04:00
Unknwon
196efecaaa Fix #491 2014-09-22 11:04:46 -04:00
无闻
01e69af2c8 Merge pull request #494 from compressed/gt_2_commits
Increase max commits in payload to 5
2014-09-22 10:29:23 -04:00
Christopher Brickley
25c8d01676 increase max commits in payload to 5 2014-09-22 08:25:39 -04:00
lunnyxiao
7df60af60e submodule support and closed #478 2014-09-22 14:23:36 +08:00
lunnyxiao
79ec08141a Merge branch 'dev' of github.com:gogits/gogs into dev 2014-09-22 10:45:20 +08:00
lunnyxiao
150eef93b2 add submodule basic support & buf fixed #478 2014-09-22 10:43:16 +08:00
Unknwon
1273b3d3a9 Support custom robots.txt 2014-09-21 19:39:10 -04:00
Unknwon
b72d7c201a Mirror bug fix 2014-09-21 12:22:50 -04:00
Unknwon
4a01bb8fa4 Mirror bug fix 2014-09-21 12:19:50 -04:00
无闻
d325b23dbb Merge pull request #492 from chadoe/suburlcookie
Set cookiepath to AppSubUrl
2014-09-21 12:11:40 -04:00
Martin van Beurden
976f1486e0 Set cookiepath to AppSubUrl 2014-09-21 14:25:22 +02:00
无闻
cb0ea46d1e Merge pull request #490 from fanningert/patch-1
Update locale_de-DE.ini
2014-09-20 12:23:36 -04:00
fanningert
052ab30409 Update locale_de-DE.ini 2014-09-20 11:01:05 +02:00
Unknwon
7ba9257a7f Add suburl support 2014-09-19 20:11:34 -04:00
无闻
6a7bd097fe Merge pull request #463 from chadoe/urlroot
Allow Gogs to run from a suburl behind a reverse proxy.
2014-09-19 19:02:40 -04:00
Martin van Beurden
0055cbd365 Allow Gogs to run from a suburl behind a reverse proxy. e.g. http://mydomain.com/gogs/
Conflicts:
	modules/setting/setting.go

Conflicts:
	templates/repo/release/list.tmpl
	templates/user/dashboard/dashboard.tmpl

Conflicts:
	routers/repo/setting.go
2014-09-18 20:50:48 +02:00
无闻
4f74b4e657 Merge pull request #483 from pkgr/dev
Add new distributions on https://packager.io/gh/pkgr/gogs
2014-09-18 12:21:00 -04:00
Cyril Rohr
31d763bc1f Add new distributions on https://packager.io/gh/pkgr/gogs
* ubuntu 12.04
* debian 7
2014-09-18 13:56:44 +00:00
Unknwon
a596388ebf Add success message after transfer repository #481 2014-09-17 14:52:46 -04:00
Unknwon
8a09256941 Mirror fix and fix #481 2014-09-17 14:22:51 -04:00
无闻
c03f5a2c7c Merge pull request #480 from compressed/correct_push_user
clarify name/username/owner/pusher for webhook
2014-09-17 14:13:54 -04:00
Christopher Brickley
f94d7c3f51 clarify name/username/owner/pusher for webhook 2014-09-17 09:20:14 -04:00
lunnyxiao
061a879cea Merge branch 'dev' of github.com:gogits/gogs into dev
Conflicts:
	conf/app.ini
2014-09-17 12:04:18 +08:00
lunnyxiao
ed84adb679 toutf8 improved & add max git diff lines 2014-09-17 12:03:03 +08:00
无闻
9f015b4c73 Merge pull request #479 from quux/dev
French translation
2014-09-16 21:25:57 -04:00
Philippe Barsalou
bc3abb397f typos 2014-09-16 20:58:17 -04:00
Philippe Barsalou
9e10304ab2 started french localization 2014-09-16 20:58:17 -04:00
Unknwon
ae3639868e Quick fix on #476 2014-09-16 20:58:06 -04:00
无闻
d082e821a0 Merge pull request #477 from fanningert/dev
Intial commit for systemd support
2014-09-16 14:21:37 -04:00
Thomas Fanninger
78bd144c1c Intial commit for systemd support 2014-09-16 20:10:21 +02:00
Unknown
ebb4f1b78c Work #475 and #458 2014-09-16 13:34:09 -04:00
Unknwon
62f21ff3ed Work on #476 2014-09-16 11:29:53 -04:00
Unknwon
0d9c41be7d Work on #476 2014-09-16 10:10:33 -04:00
Unknwon
c1ceec45da Fix mirror UI style and work on #475 2014-09-16 08:32:13 -04:00
Unknwon
b162e565b3 Merge branch 'master' of github.com:gogits/gogs into dev 2014-09-16 08:04:29 -04:00
无闻
6516ecaa51 Merge pull request #473 from j100002ben/master
Fix TimeSince arguments error.
2014-09-16 07:35:33 -04:00
无闻
5163d368e3 Merge pull request #474 from tobyzxj/dev
fix user's actions on domain/org/name-of-organization/dashboard
2014-09-16 07:29:03 -04:00
tobyzxj
ad041167f7 fix user's actions on domain/org/name-of-organization/dashboard 2014-09-16 16:20:32 +08:00
Benjamin Peng
cff3ca23a5 Fix TimeSince arguments error. 2014-09-16 15:55:41 +08:00
Unknwon
41386fa91a Fix UI 2014-09-15 22:35:05 -04:00
Unknwon
ea309acdb2 Fix #468 2014-09-15 17:23:58 -04:00
Unknwon
0f037b430a Fix #464 2014-09-15 10:09:17 -04:00
Unknwon
632b1b694d Fix #465 2014-09-15 09:56:12 -04:00
192 changed files with 6396 additions and 2010 deletions

View File

@@ -1,5 +1,8 @@
[run]
init_cmds = [["./gogs", "web"]]
init_cmds = [
["grep", "-rn", "FIXME", "."],
["./gogs", "web"]
]
watch_all = true
watch_dirs = [
"$WORKDIR/conf/locale",
@@ -11,7 +14,7 @@ watch_dirs = [
watch_exts = [".go", ".ini"]
build_delay = 1500
cmds = [
["go", "install"],
["go", "build"],
["go", "install", "-tags", "sqlite cert"],
["go", "build", "-tags", "sqlite cert"],
["./gogs", "web"]
]

View File

@@ -1,12 +0,0 @@
{
"paths": ["."],
"depth": 2,
"exclude": [],
"include": ["\\.go$", "\\.ini$"],
"command": [
"bash", "-c", "go build && ./gogs web"
],
"env": {
"POWERED_BY": "github.com/shxsun/fswatch"
}
}

3
.gitignore vendored
View File

@@ -39,3 +39,6 @@ __pycache__
output*
config.codekit
.brackets.json
docker/fig.yml
docker/docker/Dockerfile
docker/docker/init_gogs.sh

View File

@@ -10,3 +10,12 @@ filesets:
- README_ZH.md
excludes:
- \.git
settings:
build: |
if test "$GOOS" = "windows" -a "$GOARCH" = "386"
then
go install -v
else
go get -v -tags "sqlite redis memcache cert" github.com/gogits/gogs
go install -v -tags "sqlite redis memcache cert"
fi

View File

@@ -8,7 +8,7 @@ github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:2cbcbc6916
github.com/Unknwon/goconfig = commit:0f8d8dc1c0
github.com/Unknwon/i18n = commit:47baeff8d0
github.com/Unknwon/macaron = commit:f22f45d79a
github.com/Unknwon/macaron = commit:4927b78ad9
github.com/codegangsta/cli = commit:7381bc4e62
github.com/go-sql-driver/mysql = commit:8111ee3ec3
github.com/go-xorm/core = commit:750aae0fa5
@@ -17,13 +17,14 @@ github.com/gogits/gfm = commit:40f747a9c0
github.com/gogits/oauth2 = commit:99cbec870a
github.com/lib/pq = commit:b021d0ef20
github.com/macaron-contrib/cache = commit:204d8e5137
github.com/macaron-contrib/captcha = commit:8f3f1ac0e3
github.com/macaron-contrib/csrf = commit:cd84c01723
github.com/macaron-contrib/i18n = commit:489cc194b5
github.com/macaron-contrib/session = commit:80a88a1bba
github.com/macaron-contrib/captcha = commit:d37d37eeea
github.com/macaron-contrib/csrf = commit:8e980822b0
github.com/macaron-contrib/i18n = commit:2246f45894
github.com/macaron-contrib/session = commit:42ad41e323
github.com/macaron-contrib/toolbox = commit:57127bcc89
github.com/mattn/go-sqlite3 = commit:a80c27ba33
github.com/nfnt/resize = commit:581d15cb53
github.com/russross/blackfriday = commit:05b8cefd6a
github.com/saintfish/chardet = commit:3af4cd4741
[res]

View File

@@ -1,6 +1,7 @@
buildpack: "https://github.com/kr/heroku-buildpack-go.git"
targets:
ubuntu-14.04:
ubuntu-12.04:
debian-7:
build_dependencies:
- mercurial
- bzr

View File

@@ -2,5 +2,4 @@ language: go
go:
- 1.2
- 1.3
- tip
- 1.3

View File

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

View File

@@ -1,11 +1,11 @@
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://drone.io/github.com/gogits/gogs/status.png)](https://drone.io/github.com/gogits/gogs/latest)
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs)
=====================
Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。
![Demo](https://gowalker.org/public/gogs_demo.gif)
##### 当前版本0.5.0 Beta
##### 当前版本0.5.5 Beta
## 开发目的
@@ -15,7 +15,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- 有关项目设计、已知问题和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
- 想要先睹为快?通过 [在线体验](http://try.gogits.org/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 想要先睹为快?通过 [在线体验](https://try.gogs.io/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.md) 页面获取帮助。
## 功能特性
@@ -35,7 +35,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- Slack Web 钩子集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录GitHub、Google、QQ、微博
- 多语言支持(英文、简体中文、语等等)
- 多语言支持(英文、简体中文、繁体中文、德语、法语、荷兰语等等)
## 系统要求
@@ -48,7 +48,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
然后,您可以通过以下 5 种方式来安装 Gogs
- [二进制安装](http://gogs.io/docs/installation/install_from_binary.md): **强烈推荐**
- [二进制安装](http://gogs.io/docs/installation/install_from_binary.md)
- [源码安装](http://gogs.io/docs/installation/install_from_source.md)
- [包管理安装](http://gogs.io/docs/installation/install_from_packages.md)
- [采用 Docker 部署](https://github.com/gogits/gogs/tree/master/docker)
@@ -56,10 +56,10 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
## 特别鸣谢
- [Macaron](https://github.com/Unknwon/macaron) 的路由与中间件机制。
- [beego](http://beego.me) 模块的使用与修改。
- 基于 [WeTalk](https://github.com/beego/wetalk) 修改的邮件服务和模块设计。
- 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。
- [beego](http://beego.me) 模块的使用与修改。
- [martini](http://martini.codegangsta.io/) 的路由与中间件机制。
- 感谢 [gobuild.io](http://gobuild.io) 提供二进制编译与下载服务。
- 感谢 [lavachen](http://www.lavachen.cn/) 和 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。

160
cmd/cert.go Normal file
View File

@@ -0,0 +1,160 @@
// +build cert
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"math/big"
"net"
"os"
"strings"
"time"
"github.com/codegangsta/cli"
)
var CmdCert = cli.Command{
Name: "cert",
Usage: "Generate self-signed certificate",
Description: `Generate a self-signed X.509 certificate for a TLS server.
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
Action: runCert,
Flags: []cli.Flag{
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
},
}
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &k.PublicKey
case *ecdsa.PrivateKey:
return &k.PublicKey
default:
return nil
}
}
func pemBlockForKey(priv interface{}) *pem.Block {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
case *ecdsa.PrivateKey:
b, err := x509.MarshalECPrivateKey(k)
if err != nil {
log.Fatal("unable to marshal ECDSA private key: %v", err)
}
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
default:
return nil
}
}
func runCert(ctx *cli.Context) {
if len(ctx.String("host")) == 0 {
log.Fatal("Missing required --host parameter")
}
var priv interface{}
var err error
switch ctx.String("ecdsa-curve") {
case "":
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits"))
case "P224":
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
case "P256":
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
case "P384":
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
case "P521":
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
default:
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve"))
}
if err != nil {
log.Fatalf("Failed to generate private key: %s", err)
}
var notBefore time.Time
if len(ctx.String("start-date")) == 0 {
notBefore = time.Now()
} else {
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date"))
if err != nil {
log.Fatalf("Failed to parse creation date: %s", err)
}
}
notAfter := notBefore.Add(ctx.Duration("duration"))
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %s", err)
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
hosts := strings.Split(ctx.String("host"), ",")
for _, h := range hosts {
if ip := net.ParseIP(h); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
} else {
template.DNSNames = append(template.DNSNames, h)
}
}
if ctx.Bool("ca") {
template.IsCA = true
template.KeyUsage |= x509.KeyUsageCertSign
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
if err != nil {
log.Fatalf("Failed to create certificate: %s", err)
}
certOut, err := os.Create("cert.pem")
if err != nil {
log.Fatalf("Failed to open cert.pem for writing: %s", err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
log.Println("Written cert.pem")
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatal("failed to open key.pem for writing: %v", err)
}
pem.Encode(keyOut, pemBlockForKey(priv))
keyOut.Close()
log.Println("Written key.pem")
}

34
cmd/cert_stub.go Normal file
View File

@@ -0,0 +1,34 @@
// +build !cert
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"fmt"
"time"
"github.com/codegangsta/cli"
)
var CmdCert = cli.Command{
Name: "cert",
Usage: "Generate self-signed certificate",
Description: `Generate a self-signed X.509 certificate for a TLS server.
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
Action: runCert,
Flags: []cli.Flag{
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
},
}
func runCert(ctx *cli.Context) {
fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
}

View File

@@ -171,7 +171,13 @@ func runServ(k *cli.Context) {
uuid := uuid.NewV4().String()
os.Setenv("uuid", uuid)
gitcmd := exec.Command(verb, repoPath)
var gitcmd *exec.Cmd
verbs := strings.Split(verb, " ")
if len(verbs) == 2 {
gitcmd = exec.Command(verbs[0], verbs[1], repoPath)
} else {
gitcmd = exec.Command(verb, repoPath)
}
gitcmd.Dir = setting.RepoRootPath
gitcmd.Stdout = os.Stdout
gitcmd.Stdin = os.Stdin

View File

@@ -11,6 +11,7 @@ import (
"net/http"
"os"
"path"
"strings"
"github.com/Unknwon/macaron"
"github.com/codegangsta/cli"
@@ -26,6 +27,7 @@ import (
"github.com/gogits/gogs/modules/auth/apiv1"
"github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/middleware/binding"
@@ -50,6 +52,7 @@ and it takes care of all the other things for you`,
// checkVersion checks if binary matches the version of templates files.
func checkVersion() {
// Templates.
data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION"))
if err != nil {
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
@@ -57,6 +60,20 @@ func checkVersion() {
if string(data) != setting.AppVer {
log.Fatal(4, "Binary and template file version does not match, did you forget to recompile?")
}
// Check dependency version.
macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ".")[:3], "."))
if macaronVer.LessThan(git.MustParseVersion("0.2.0")) {
log.Fatal(4, "Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)")
}
i18nVer := git.MustParseVersion(i18n.Version())
if i18nVer.LessThan(git.MustParseVersion("0.0.2")) {
log.Fatal(4, "Package i18n version is too old, did you forget to update?(github.com/macaron-contrib/i18n)")
}
sessionVer := git.MustParseVersion(session.Version())
if sessionVer.LessThan(git.MustParseVersion("0.0.1")) {
log.Fatal(4, "Package session version is too old, did you forget to update?(github.com/macaron-contrib/session)")
}
}
// newMacaron initializes Macaron instance.
@@ -64,7 +81,8 @@ func newMacaron() *macaron.Macaron {
m := macaron.New()
m.Use(macaron.Logger())
m.Use(macaron.Recovery())
m.Use(macaron.Static("public",
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public"),
macaron.StaticOptions{
SkipLogging: !setting.DisableRouterLog,
},
@@ -78,24 +96,30 @@ func newMacaron() *macaron.Macaron {
IndentJSON: macaron.Env != macaron.PROD,
}))
m.Use(i18n.I18n(i18n.Options{
Langs: setting.Langs,
Names: setting.Names,
Redirect: true,
SubURL: setting.AppSubUrl,
Directory: path.Join(setting.ConfRootPath, "locale"),
CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
Langs: setting.Langs,
Names: setting.Names,
Redirect: true,
}))
m.Use(cache.Cacher(cache.Options{
Adapter: setting.CacheAdapter,
Interval: setting.CacheInternal,
Conn: setting.CacheConn,
}))
m.Use(captcha.Captchaer())
m.Use(captcha.Captchaer(captcha.Options{
SubURL: setting.AppSubUrl,
}))
m.Use(session.Sessioner(session.Options{
Provider: setting.SessionProvider,
Config: *setting.SessionConfig,
}))
m.Use(csrf.Generate(csrf.Options{
Secret: setting.SecretKey,
SetCookie: true,
Header: "X-Csrf-Token",
Secret: setting.SecretKey,
SetCookie: true,
Header: "X-Csrf-Token",
CookiePath: setting.AppSubUrl,
}))
m.Use(toolbox.Toolboxer(m, toolbox.Options{
HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
@@ -124,7 +148,7 @@ func runWeb(*cli.Context) {
// Routers.
m.Get("/", ignSignIn, routers.Home)
m.Get("/explore", routers.Explore)
m.Get("/explore", ignSignIn, routers.Explore)
m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Group("", func(r *macaron.Router) {
@@ -185,7 +209,8 @@ func runWeb(*cli.Context) {
r.Get("/logout", user.SignOut)
})
m.Get("/user/:username", ignSignIn, user.Profile) // TODO: Legacy
// FIXME: Legacy
m.Get("/user/:username", ignSignIn, user.Profile)
// Gravatar service.
avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg")
@@ -224,6 +249,11 @@ func runWeb(*cli.Context) {
r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost)
r.Post("/:authid/delete", admin.DeleteAuthSource)
})
m.Group("/notices", func(r *macaron.Router) {
r.Get("", admin.Notices)
r.Get("/:id:int/delete", admin.DeleteNotice)
})
}, adminReq)
m.Get("/:username", ignSignIn, user.Profile)
@@ -298,6 +328,12 @@ func runWeb(*cli.Context) {
r.Get("/hooks/:id", repo.WebHooksEdit)
r.Post("/hooks/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
r.Post("/hooks/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
m.Group("/hooks/git", func(r *macaron.Router) {
r.Get("", repo.GitHooks)
r.Get("/:name", repo.GitHooksEdit)
r.Post("/:name", repo.GitHooksEditPost)
}, middleware.GitHookService())
})
}, reqSignIn, middleware.RepoAssignment(true), reqTrueOwner)
@@ -338,6 +374,8 @@ func runWeb(*cli.Context) {
r.Get("/issues/:index", repo.ViewIssue)
r.Get("/pulls", repo.Pulls)
r.Get("/branches", repo.Branches)
r.Get("/archive/*", repo.Download)
r.Get("/issues2/", repo.Issues2)
}, ignSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func(r *macaron.Router) {
@@ -350,23 +388,29 @@ func runWeb(*cli.Context) {
r.Get("/commit/:branchname", repo.Diff)
r.Get("/commit/:branchname/*", repo.Diff)
r.Get("/releases", repo.Releases)
r.Get("/archive/*.*", repo.Download)
r.Get("/compare/:before([a-z0-9]+)...:after([a-z0-9]+)", repo.CompareDiff)
}, ignSignIn, middleware.RepoAssignment(true, true))
m.Group("/:username", func(r *macaron.Router) {
r.Get("/:reponame", middleware.RepoAssignment(true, true, true), repo.Home)
m.Group("/:reponame", func(r *macaron.Router) {
r.Any("/*", repo.Http)
})
}, ignSignInAndCsrf)
r.Get("/:reponame", ignSignIn, middleware.RepoAssignment(true, true, true), repo.Home)
r.Any("/:reponame/*", ignSignInAndCsrf, repo.Http)
})
// robots.txt
m.Get("/robots.txt", func(ctx *middleware.Context) {
if setting.HasRobotsTxt {
ctx.ServeFile(path.Join(setting.CustomPath, "robots.txt"))
} else {
ctx.Error(404)
}
})
// Not found handler.
m.NotFound(routers.NotFound)
var err error
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
log.Info("Listen: %v://%s", setting.Protocol, listenAddr)
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
switch setting.Protocol {
case setting.HTTP:
err = http.ListenAndServe(listenAddr, m)

View File

@@ -21,7 +21,7 @@ OFFLINE_MODE = false
DISABLE_ROUTER_LOG = false
; Generate steps:
; $ cd path/to/gogs/custom/https
; $ go run $GOROOT/src/pkg/crypto/tls/generate_cert.go -ca=true -duration=8760h0m0s -host=myhost.example.com
; $ ./gogs cert -ca=true -duration=8760h0m0s -host=myhost.example.com
CERT_FILE = custom/https/cert.pem
KEY_FILE = custom/https/key.pem
; Upper level of template and static file path
@@ -70,6 +70,8 @@ ENABLE_CACHE_AVATAR = false
ENABLE_NOTIFY_MAIL = false
; More detail: https://github.com/gogits/gogs/issues/165
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
; Repository Git hooks
ENABLE_GIT_HOOKS = false
[webhook]
; Cron task interval in minutes
@@ -252,6 +254,9 @@ DRIVER =
; Based on xorm, e.g.: root:root@localhost/gogs?charset=utf8
CONN =
[git]
MAX_GITDIFF_LINES = 10000
[i18n]
LANGS = en-US,zh-CN,de-DE
NAMES = English,简体中文,Deutsch
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands

View File

@@ -5,9 +5,9 @@ dashboard = Dashboard
explore = Erkunden
help = Hilfe
sign_in = Anmelden
social_sign_in = Social Sign In: 2nd Step <small>associate account</small>
social_sign_in = Anmeldung über soziales Konto: zweiter Schritt <small>Konto verknüpfen</small>
sign_out = Abmelden
sign_up = Sign up
sign_up = Registrieren
register = Registrieren
website = Webseite
version = Version
@@ -18,7 +18,7 @@ language = Sprache
username = Benutzername
email = E-Mail
password = Passwort
re_type = wiederholen
re_type = Passwort bestätigen
captcha = Captcha
repository = Repository
@@ -38,15 +38,62 @@ issues = Issues
cancel = Abbrechen
[install]
install = Installation
title = Installation für erstmaligen Start
requite_db_desc = Gogs erfordert MySQL, PostgreSQL oder SQLite 3, aber SQLite3 ist in der offiziellen binären Version akiviert.
db_type = Datenbanktyp
host = Host
user = Benutzer
password = Passwort
db_name = Datenbankname
db_helper = Bitte verwenden InnoDB-Engine mit utf8_general_ci Zeichensatz für MySQL.
ssl_mode = SSL-Modus
path = Pfad
sqlite_helper = Der Dateipfad des SQLite3 Datenbank.
general_title = Allgemeine Einstellungen von Gogs
repo_path = Repository Root-Verzeichnispfad
repo_path_helper = Alle Git-Repositorys werden in diesem Verzeichnis gespeichert.
run_user = Ausführender Benutzer
run_user_helper = Der Benutzer muss die Zugriffsberechtigung für das Repository Root-Verzeichnis haben und der ausführende Benutzer von Gogs sein.
domain = Domain
domain_helper = Dies hat Auswirkung auf die SSH clone URLs.
app_url = Anwendungs-URL
app_url_helper = Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails.
email_title = E-Mail-Service-Einstellungen (optional)
smtp_host = SMTP Host
mailer_user = Sender E-mail
mailer_password = Sender Passwort
notify_title = Benachrichtigungseinstellungen (optional)
register_confirm = Registrierungsbestätigung aktvieren
mail_notify = E-Mail-Benachrichtgung aktivieren
admin_title = Konto-Einstellungen für den Administrator
admin_name = Benutzername
admin_password = Passwort
confirm_password = Passwort bestätigen
admin_email = E-Mail
install_gogs = Gogs installieren
test_git_failed = Fehler beim Test des 'git' Kommandos: %v
sqlite3_not_available = Deine Version unterstüzt nicht SQLite3, bitte downloade dir die offiziele binäre Version von http://gogs.io/docs/installation/install_from_binary.html, NICHT die gobuild Version.
invalid_db_setting = Datenbank-Einstellungen sind nicht korrekt: %v
invalid_repo_path = Repository Root-Verzeichnis ist ungültig: %v
run_user_not_match = Der ausführende Benutzer ist nicht der aktuelle Benutzer: %s -> %s
save_config_failed = Versuche die Konfiguration zu speichern ist fehlgeschlagen: %v
invalid_admin_setting = Admin-Konto Einstellungen sind ungültig: %v
install_success = Herzlich Willkommen! Wir sind froh, dass du dich für Gogs entschieden hast. Hab viel Vergnügen damit.
[home]
uname_holder = Benutzername oder E-Mail
password_holder = Passwort
switch_dashboard_context = Switch Dashboard Context
switch_dashboard_context = Dashboard Kontext wechseln
my_repos = Meine Repositorys
collaborative_repos = Gemeinschaftliche Repositorys
my_orgs = Meine Organisationen
my_mirrors = Meine Spiegel
[explore]
repos = Repositorys
[auth]
create_new_account = Neues Konto erstellen
register_hepler_msg = Du hast schon ein Konto? Jetzt anmelden!
@@ -57,9 +104,9 @@ remember_me = angemeldet bleiben
forgot_password= Passwort vergessen
forget_password = Passwort vergessen?
sign_up_now = Du willst ein Konto? Jetzt registrieren!
confirmation_mail_sent_prompt = Eine neu Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden um die Registrierung abzuschließen.
sign_in_email = Melden dich mit deiner E-Mail-Adresse an
active_your_account = Aktivieren dein Konto
confirmation_mail_sent_prompt = Eine neue Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden, um die Registrierung abzuschließen.
sign_in_email = Melde dich mit deiner E-Mail-Adresse an
active_your_account = Aktiviere dein Konto
resent_limit_prompt = Es tut uns leid, du sendest zu häufig Aktivierungs-E-Mails. Bitte warte 3 Minuten.
has_unconfirmed_mail = Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Falls du noch keine Bestätigungs-E-Mail erhalten hast oder eine neue senden musst, klicke auf den unteren Button.
resend_mail = Hier klicken, um deine Aktivierungs-E-Mail erneut zu versenden
@@ -75,12 +122,13 @@ UserName = Benutzername
RepoName = Repository-Name
Email = E-Mail-Adresse
Password = Passwort
Retype = Passwort erneut eingeben
Retype = Passwort bestätigen
SSHTitle = SSH-Schlüsselname
HttpsUrl = HTTPS-URL
PayloadUrl = Payload-URL
TeamName = Teamname
AuthName = Authentifizierungsname
AdminEmail = Admin E-mail
require_error = ` darf nicht leer sein.`
alpha_dash_error = ` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
@@ -110,7 +158,7 @@ enterred_invalid_password = Bitte stelle sicher, dass das eingegebene Passwort r
user_not_exist = Angegebener Benutzer existiert nicht.
last_org_owner = Der zu entfernende Benutzer ist der letzte Teambesitzer. Es muss einen anderen Besitzer geben.
invalid_ssh_key = Leider sind wir nicht in der Lage, Ihren SSH-Schlüssel zu überprüfen: %s
invalid_ssh_key = Leider sind wir nicht in der Lage, deinen SSH-Schlüssel zu überprüfen: %s
auth_failed = Authentifizierung fehlgeschlagen: %v
still_own_repo = Dein Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
@@ -118,6 +166,15 @@ org_still_own_repo = Diese Organisation besitzt noch Repositorys. Diese müssen
still_own_user = Diese Authentifizierung wird noch von einigen Benutzern genutzt. Entferne diese zuvor und lösche erneut.
[user]
change_avatar = Ändere dein Profilbild auf gravatar.com
join_on = Registriert
repositories = Repositorys
activity = Öffentliche Aktivität
followers = Folgen
starred = Markiert
following = Folgt
[settings]
profile = Profil
password = Passwort
@@ -125,6 +182,7 @@ ssh_keys = SSH-Schlüssel
social = Soziale Konten
orgs = Organisationen
delete = Konto löschen
uid = Uid
public_profile = Öffentliches Profil
profile_desc = Deine E-Mail-Adresse ist öffentlich und dient dazu, dir Benachrichtigungen bezüglich deines Kontos und deiner Repositorys zu schicken.
@@ -178,7 +236,6 @@ create_repo = Repository erstellen
default_branch = Standard-Branch
mirror_interval = Spiegel-Intervall (in Stunden)
goget_meta = Go-Get Meta
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
goget_meta_helper = Dieses Repository wird man mit <span class="label label-blue label-radius">go get</span> klonen können.
need_auth = Authorisierung benötigt
@@ -187,7 +244,7 @@ migrate_type_helper = Dieses Repository wird ein <span class="label label-blue l
migrate_repo = Repository migrieren
copy_link = Klonen
clone_helper = Du brauchst Hilef beim klonen? Hier gibt es<a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Hilfe</a>!
clone_helper = Du brauchst Hilfe beim Klonen? Hier gibt es <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Hilfe</a>!
unwatch = Beobachtung beenden
watch = Beobachtung
unstar = Markierung aufheben
@@ -197,7 +254,7 @@ fork = Abspaltung
quick_guide = Kurzanleitung
clone_this_repo = Dieses Repository klonen
create_new_repo_command = Erstelle ein neues Repository mittels der Kommandozeile
push_exist_repo = Push an existing repository from the command line
push_exist_repo = Übertrage ein existierendes Repository von der Kommandozeile
settings = Einstellungen
settings.options = Optionen
@@ -210,11 +267,13 @@ settings.site = Offizielle Webseite
settings.update_settings = Aktualisierungseinstellungen
settings.transfer = Besitz übertragen
settings.transfer_desc = Übertrage dieses Repository einem anderen Benutzer oder einer Organisation.
settings.new_owner_has_same_repo = Neuer Eigentümer hat bereits ein Repository mit dem gleichen Namen.
settings.delete = Repository löschen
settings.delete_desc = Wenn dieses Repository gelöschet ist, gibt es keinen Weg zurück. Sei dir sicher!
settings.delete_desc = Wenn dieses Repository gelöscht ist, gibt es keinen Weg zurück. Sei dir sicher!
settings.update_settings_success = Repository-Optionen aktualisiert
settings.transfer_owner = Neuer Besitzer
settings.make_transfer = übertragen
settings.transfer_succeed = Repository-Eigentum wurde erfolgreich übertragen.
settings.confirm_delete = Löschen
settings.add_collaborator = Mitarbeiter hinzufügen
settings.add_collaborator_success = Mitarbeiter hinzugefügt
@@ -235,7 +294,7 @@ settings.update_webhook = Webhook aktualisieren
settings.update_hook_success = Webhook aktualisiert
settings.delete_webhook = Webhook löschen
settings.recent_deliveries = letzte Zustellungen
settings.hook_type = Hook Type
settings.hook_type = Hook Typ
settings.add_slack_hook_desc = Add <a href="http://slack.com">Slack</a> integration to your repository.
settings.slack_token = Token
settings.slack_domain = Domain
@@ -271,6 +330,7 @@ settings.delete = Organisation löschen
settings.delete_account = Diese Organisation löschen
settings.delete_prompt = Die Organisation wird dauerhaft gelöscht. Dies kann <strong>NICHT</strong> rückgängig gemacht werden!
settings.confirm_delete_account = Löschen
settings.hooks_desc = Füge Webhooks hinzu, die für <strong>alle</strong> Repositorys dieser Organisation ausgelöst werden.
members.public = Öffentlich
members.public_helper = Privat machen
@@ -321,8 +381,8 @@ next = vor
dashboard.statistic = Statistik
dashboard.operations = Operationen
dashboard.system_status = System-Monitor-Status
dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organizationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> Zugriffe, <b>%d</b> issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> follows, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge.
dashboard.operation_name = Operation Name
dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organisationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> Beobachtungen, <b>%d</b> Markierungen, <b>%d</b> Aktionen, <b>%d</b> Zugriffe, <b>%d</b> Issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> Folgende, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge.
dashboard.operation_name = Name der Operation
dashboard.operation_switch = Switch
dashboard.operation_run = Ausführen
dashboard.clean_unbind_oauth = ungebundene OAuths bereinigen
@@ -385,12 +445,12 @@ repos.repo_manage_panel = Repositorys
repos.owner = Besitzer
repos.name = Name
repos.private = Privat
repos.watches = Watches
repos.stars = Stars
repos.watches = Beobachtungen
repos.stars = Markierungen
repos.issues = Issues
auths.auth_manage_panel = Authentifizierung
auths.new = Neu Authentifizierungsquelle hinzufügen
auths.new = Neue Authentifizierungsquelle hinzufügen
auths.name = Name
auths.type = Typ
auths.enabled = aktiviert
@@ -442,11 +502,11 @@ config.db_path_helper = (nur für "sqlite3")
config.service_config = Service-Einstellungen
config.register_email_confirm = E-Mail-Bestätigung bei Registrierung
config.disable_register = Registrierung deaktivieren
config.require_sign_in_view = Require Sign In View
config.require_sign_in_view = Ansehen erfordert Registrierung
config.mail_notify = E-Mail-Benachrichtigung
config.enable_cache_avatar = Avatar-Cache aktivieren
config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Reset Password Code Lives
config.active_code_lives = Aktivierungscode Lebensdauer
config.reset_password_code_lives = Passwortcode Lebensdauer
config.webhook_config = Webhook-Einstellungen
config.task_interval = Task-Intervall
config.deliver_timeout = Zeitlimit für Zustellung
@@ -465,7 +525,7 @@ config.session_config = Session-Einstellungen
config.session_provider = Session-Provider
config.provider_config = Provider-Einstellungen
config.cookie_name = Cookie-Name
config.enable_set_cookie = Enable Set Cookie
config.enable_set_cookie = Cookies einschalten
config.gc_interval_time = GC-Intervallzeit
config.session_life_time = Session-Lebensdauer
config.https_only = nur HTTPS
@@ -483,17 +543,18 @@ monitor.name = Name
monitor.schedule = Zeitplan
monitor.next = nächste Ausführung
monitor.previous = letzte Ausführung
monitor.execute_times = Execute Times
monitor.execute_times = Anzahl Ausführungen
monitor.process = Laufende Prozesse
monitor.desc = Beschreibung
monitor.start = Startzeit
monitor.execute_time = Ausführungszeit
[action]
create_repo = Repository erstellen <a href="/%s">%s</a>
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
create_issue = opened issue <a href="/%s/issues/%s">%s#%s</a>
comment_issue = commented on issue <a href="/%s/issues/%s">%s#%s</a>
create_repo = hat Repository <a href="%s/%s">%s</a> erstellt
commit_repo = hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht
create_issue = hat Issue <a href="%s/%s/issues/%s">%s#%s</a> eröffnet
comment_issue = hat Issue <a href="%s/%s/issues/%s">%s#%s</a> kommentiert
transfer_repo = hat Repository <code>%s</code> transferiert an <a href="/%s%s">%s</a>
[tool]
ago = vor

View File

@@ -166,6 +166,15 @@ org_still_own_repo = This organization still have ownership of repository, you h
still_own_user = This authentication still has used by some users, you should move them and then delete again.
[user]
change_avatar = Change your avatar at gravatar.com
join_on = Joined on
repositories = Repositories
activity = Public Activity
followers = Followers
starred = Starred
following = Following
[settings]
profile = Profile
password = Password
@@ -182,6 +191,10 @@ website = Website
location = Location
update_profile = Update Profile
update_profile_success = Your profile has been successfully updated.
change_username = Username Changed
change_username_desc = Username has been changed, do you want to continue? This will affect all links relate to your account.
continue = Continue
cancel = Cancel
change_password = Change Password
old_password = Current Password
@@ -210,6 +223,8 @@ unbind_success = Social account has been unbound.
delete_account = Delete Your Account
delete_prompt = The operation will delete your account permanently, and <strong>CANNOT</strong> be undone!
confirm_delete_account = Confirm Deletion
delete_account_title = Account Deletion
delete_account_desc = This account is going to be deleted permanently, do you want to continue?
[repo]
owner = Owner
@@ -235,6 +250,8 @@ migrate_type_helper = This repository will be a <span class="label label-blue la
migrate_repo = Migrate Repository
copy_link = Copy
click_to_copy = Copy to clipboard
copied = Copied OK
clone_helper = Need help cloning? Visit <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Help</a>!
unwatch = Unwatch
watch = Watch
@@ -242,34 +259,64 @@ unstar = Unstar
star = Star
fork = Fork
no_desc = No Description
quick_guide = Quick Guide
clone_this_repo = Clone this repository
create_new_repo_command = Create a new repository on the command line
push_exist_repo = Push an existing repository from the command line
branch = Branch
tree = Tree
branch_and_tags = Branches & Tags
branches = Branches
tags = Tags
issues = Issues
commits = Commits
releases = Releases
commits.commits = Commits
commits.search = Search commits
commits.find = Find
commits.author = Author
commits.message = Message
commits.date = Date
commits.older = Older
commits.newer = Newer
settings = Settings
settings.options = Options
settings.collaboration = Collaboration
settings.hooks = Webhooks
settings.githooks = Git Hooks
settings.deploy_keys = Deploy Keys
settings.basic_settings = Basic Settings
settings.danger_zone = Danger Zone
settings.site = Official Site
settings.update_settings = Update Settings
settings.change_reponame = Repository Name Changed
settings.change_reponame_desc = Repository name has been changed, do you want to continue? This will affect all links relate to this repository.
settings.transfer = Transfer Ownership
settings.transfer_desc = Transfer this repo to another user or to an organization where you have admin rights.
settings.new_owner_has_same_repo = New owner already has a repository with same name.
settings.delete = Delete This Repository
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
settings.transfer_notices = <p>- You will lose access if new owner is a individual user.</p><p>- You will remain access if new owner is an organization and you're one of the owners.</p>
settings.update_settings_success = Repository options has been successfully updated.
settings.transfer_owner = New Owner
settings.make_transfer = Make Transfer
settings.transfer_succeed = Repository ownership has been successfully transferred.
settings.confirm_delete = Confirm Deletion
settings.add_collaborator = Add New Collaborator
settings.add_collaborator_success = New collaborator has been added.
settings.remove_collaborator_success = Collaborator has been removed.
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
settings.add_webhook = Add Webhook
settings.hooks_desc = Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations.
settings.githook_edit_desc = If hook is not active, sample content will be presented. Leave content to be blank will disable this hook.
settings.githook_name = Hook Name
settings.githook_content = Hook Content
settings.update_githook = Update Hook
settings.remove_hook_success = Webhook has been removed.
settings.add_webhook_desc = Well send a <code>POST</code> request to the URL below with details of any subscribed events. You can also specify which data format you'd like to receive (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). More information can be found in <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
settings.payload_url = Payload URL
@@ -315,11 +362,15 @@ settings.full_name = Full Name
settings.website = Website
settings.location = Location
settings.update_settings = Update Settings
settings.change_orgname = Organization Name Changed
settings.change_orgname_desc = Organization name has been changed, do you want to continue? This will affect all links relate to this organization.
settings.update_setting_success = Organization setting has been successfully updated.
settings.delete = Delete Organization
settings.delete_account = Delete This Organization
settings.delete_prompt = The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
settings.confirm_delete_account = Confirm Deletion
settings.delete_org_title = Organization Deletion
settings.delete_org_desc = This organization is going to be deleted permanently, do you want to continue?
settings.hooks_desc = Add webhooks that will be triggered for <strong>all repositories</strong> under this organization.
members.public = Public
@@ -349,6 +400,8 @@ teams.members = Team Members
teams.update_settings = Update Settings
teams.delete_team = Delete This Team
teams.add_team_member = Add Team Member
teams.delete_team_title = Team Deletion
teams.delete_team_desc = This team is going to be deleted, do you want to continue? Members of this team may lose access to some repositories.
teams.delete_team_success = Given team has been successfully deleted.
teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
@@ -356,6 +409,7 @@ teams.admin_permission_desc = This team grants <strong>Admin</strong> access: me
teams.repositories = Team Repositories
teams.add_team_repository = Add Team Repository
teams.remove_repo = Remove
teams.add_nonexistent_repo = The repository you're trying to add does not exist, please create it first.
[admin]
dashboard = Dashboard
@@ -364,6 +418,7 @@ organizations = Organizations
repositories = Repositories
authentication = Authentications
config = Configuration
notices = System Notices
monitor = Monitoring
prev = Prev.
next = Next
@@ -465,6 +520,8 @@ auths.activated = This authentication has activated
auths.update_success = Authorization setting has been successfully updated.
auths.update = Update Authorization Setting
auths.delete = Delete This Authorization
auths.delete_auth_title = Authorization Deletion
auths.delete_auth_desc = This authorization is going to be deleted, do you want to continue?
config.server_config = Server Configuration
config.app_name = Application Name
@@ -539,11 +596,19 @@ monitor.desc = Description
monitor.start = Start Time
monitor.execute_time = Execution Time
notices.system_notice_list = System Notices
notices.type = Type
notices.type_1 = Repository
notices.desc = Description
notices.op = Op.
notices.delete_success = System notice has been successfully deleted.
[action]
create_repo = created repository <a href="/%s">%s</a>
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
create_issue = opened issue <a href="/%s/issues/%s">%s#%s</a>
comment_issue = commented on issue <a href="/%s/issues/%s">%s#%s</a>
create_repo = created repository <a href="%s/%s">%s</a>
commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue = opened issue <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue = commented on issue <a href="%s/%s/issues/%s">%s#%s</a>
transfer_repo = transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
[tool]
ago = ago

View File

@@ -0,0 +1,516 @@
app_desc = Un service Git écrit en Go auto-hébergé
home = Accueil
dashboard = Tableau de bord
explore = Explorer
help = Aide
sign_in = Connexion
social_sign_in = Authentification via Internet: 2ème étape <small>associé le compte</small>
sign_out = Déconnexion
sign_up = Créer un compte
register = S'inscrire
website = Site web
version = Version
page = Page
template = Gabarit
language = Langage
username = Usager
email = Courriel
password = Mot de passe
re_type = Saisir à nouveau
captcha = Captcha
repository = Dépôt
organization = Organisation
mirror = Mirroir
new_repo = Nouveau dépôt
new_migrate = Nouvelle migration
new_org = Nouvel organisation
manage_org = Gestion des organisations
admin_panel = Gestion
account_settings = Profil usager
settings = Configuration
news_feed = Fil de nouvelles
pull_requests = Demandes de fusion (pull requests)
issues = Suivi de problèmes
cancel = Annuler
[home]
uname_holder = Nom d'usager ou courriel
password_holder = Mot de passe
switch_dashboard_context = Changer de tableau de bord
my_repos = Mes dépôts
collaborative_repos = Dépôts partagés
my_orgs = Mes organisations
my_mirrors = Mes mirroirs
[auth]
create_new_account = Créer un nouveau compte
register_hepler_msg = Déjà inscrits? Connectez-vous maintenant!
social_register_hepler_msg = Déjà inscrits? Branchez-vous!
disable_register_prompt = Désolé, l'auto-inscription n'est pas activée. Contactez l'admnistrateur du site.
disable_register_mail = Désolé, la confirmation d'inscription par courriel est désactivée. Contactez l'administrateur du site.
remember_me = Se souvenir de moi
forgot_password= Mot de passe oublié
forget_password = Mot de passe oublié?
sign_up_now = Besoin d'un compte? Inscrivez-vous maintenant.
confirmation_mail_sent_prompt = Un courriel de confirmation à été envoyé à <b>%s</b>, consultez vos courriels d'ici %d heures pour terminer l'inscription.
sign_in_email = Connexion avec votre courriel
active_your_account = Activez votre compte
resent_limit_prompt = Désolé vous demandez trop souvent un courriel de confirmation. S.v.p. patientez 3 minutes.
has_unconfirmed_mail = Bonjour %s, votre adresse courriel n'est pas vérifiée(<b>%s</b>). Si vous n'avez pas reçu de courriel de confirmation ou si vous avez besoin d'en envoyer un maintenant, appuyez sur le bouton ci-dessous.
resend_mail = Appuyez ici pour envoyer de nouveau un courriel de confirmation.
email_not_associate = Ce courriel ne correspond à aucun compte.
send_reset_mail = Appuyez ici pour (ré)envoyer un courriel pour réinitialiser le mot de passe.
reset_password = Réinitialiser votre mot de passe
invalid_code = Désolé, ce code de confirmation est périmé ou non-valide.
reset_password_helper = Appuyez ici pour réinitialiser votre mot de passe
password_too_short = La longueur du mot de passe doit être d'au moins 6 caractères.
[form]
UserName = Nom d'usager
RepoName = Nom du dépôt
Email = Adresse de courriel
Password = Mot de passe
Retype = Mot de passe (confirmation)
SSHTitle = Nom de la clé SSH
HttpsUrl = URL HTTPS
PayloadUrl = URL cible
TeamName = Nom de l'équipe
AuthName = Nom d'usager
require_error = ` ne peut être vide.`
alpha_dash_error = ` doit être composé de caractères alpha-numériques et/ou d'un tiret(-_).`
alpha_dash_dot_error = ` doit être composé de caractères alpha-numérique, un point(.) et/ou tiret(-_).`
min_size_error = ` doit être composé d'au moins %s caractères.`
max_size_error = ` doit être conposé d'au plus %s caractères.`
email_error = ` n'est pas une adresse de courriel bien formée.`
url_error = ` n'est pas un URL valide.`
unknown_error = Erreur inconnue:
captcha_incorrect = Le captcha ne concorde pas.
password_not_match = Les deux mots de passe diffèrent.
username_been_taken = `Nom d'usager dèjà utilisé.`
repo_name_been_taken = Nom de dépôt déjà utilisé.
org_name_been_taken = Nom d'organisation déjà utilisé.
team_name_been_taken = Nom d'équipe déjà utilisé.
email_been_used = Adresse de courriel déjà utilisée.
ssh_key_been_used = Nom de clé publique déjà utilisé.
illegal_username = Votre nom d'usager contient des caractères interdits.
illegal_repo_name = Le nom du dépôt contient des caractères interdits.
illegal_org_name = Le nom de l'organisation contient des caractères interdits.
illegal_team_name = Le nom de l'équipe contient des caractères interdits.
username_password_incorrect = Nom d'usager ou mot de passe erroné.
enterred_invalid_repo_name = Nom de dépôt inexistant.
enterred_invalid_owner_name = Responsable de dépôt inexistant.
enterred_invalid_password = Mot de passe erroné.
user_not_exist = Nom d'usager inexistant.
last_org_owner = Ceci est le dernier responsable du dépôt. Il doit y avoir obligatoirement au moins un usager responsable.
invalid_ssh_key = Désolé, impossible de vérifier votre clé SSH: %
auth_failed = Erreur d'authentification : %v
still_own_repo = Votre compte est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager.
org_still_own_repo = Cette organisation est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager ou organisation.
still_own_user = Cette authentification est utilisée par un usager.
[settings]
profile = Profil
password = Mot de passe
ssh_keys = Clés SSH
social = Comptes Internet
orgs = Organisations
delete = Supprimer votre compte
public_profile = Profil public
profile_desc = Votre adresse de courriel est publique et sera utilisée pour les avis produits par le site.
full_name = Nom complet
website = Site web
location = Endroit
update_profile = Mettre à jour le profil
update_profile_success = Mise à jour du profil réussie.
change_password = Changer le mot de passe
old_password = Mot de passe actuel
new_password = Nouveau mot de passe
password_incorrect = Mot de passe actuel erroné.
change_password_success = Modification du mot de passe effectuée. Vous pouvez dorénavant vous connecter avec le nouveau mot de passe.
manage_ssh_keys = Gestion des clés SSH
add_key = Ajouter une clé
ssh_desc = Voici la liste de clés SSH associées à votre profil. Retirez les clés que vous ne reconnaissez pas.
ssh_helper = <strong>Beson d'aide?</strong> Consultez le guide au <a href="https://help.github.com/articles/generating-ssh-keys">generating SSH keys</a> ou vérifiez <a href="https://help.github.com/ssh-issues/">les problèmes SSH fréquents</a>.
add_new_key = Ajouter une clé SSH
key_name = Nom de la clé
key_content = Contenu
add_key_success = Clé SSH ajoutée!
delete_key = Détruire
add_on = Ajoutée le
last_used = Dernière utilisation le
no_activity = Pas d'activité récente
manage_social = Gestion des comptes Internets associés
social_desc = Ceci est une liste de comptes Internet associés. Retirez les comptes que vous ne reconnaissez pas.
unbind = Désassocier
unbind_success = Compte Internet déassocié.
delete_account = Detruire votre compte
delete_prompt = Cette opération détruira votre compte et <strong>ne pourra être annulée</strong>!
confirm_delete_account = Confirmez la suppression
[repo]
owner = Responsable
repo_name = Nom du dépôt
repo_name_helper = Les bons noms de dépôts sont courts, mémorables et <strong>uniques</strong>.
visibility = Visibilité
visiblity_helper = Ce dépôt est <span class="label label-red label-radius">privé</span>
repo_desc = Description
repo_lang = Langue
repo_lang_helper = Choisir un fichier .gitignore
license = License
license_helper = Choisir un fichier de licence
init_readme = Initialiser le dépôt avec un fichier README.md
create_repo = Créer le dépôt
default_branch = Branche par défaut
mirror_interval = Intervale de synchronisation (heures)
goget_meta = Métadonnées Go-Get
goget_meta_helper = Ce dépôt sera <span class="label label-blue label-radius">Go-Getable</span>
need_auth = Authorisation requise
migrate_type = Type de migration
migrate_type_helper = Ce dépôt sera un <span class="label label-blue label-radius">mirroir</span>
migrate_repo = Migrer le dépôt
copy_link = Copier
clone_helper = Besoin d'aide pour cloner? Obtenez de l' <a target="_blank" href="http://git-scm.com/book/fr/Les-bases-de-Git-Démarrer-un-dépôt-Git">aide</a>!
unwatch = Ne plus suivre
watch = Suivre
unstar = Retirer étoile
star = Étoile
fork = Fork
quick_guide = Guide rapide
clone_this_repo = Cloner ce dépôt
create_new_repo_command = Créer un nouveau dépôt à la ligne de commande
push_exist_repo = Pousser un dépôt existant depuis la ligne de commande
settings = Réglages
settings.options = Réglages de base
settings.collaboration = Collaboration
settings.hooks = Webhooks
settings.deploy_keys = Clé de déploiement
settings.basic_settings = réglages de base
settings.danger_zone = Danger!
settings.site = Site officiel
settings.update_settings = Réglage des mises à jour
settings.transfer = Transférer la responsabilité
settings.transfer_desc = Transférer ce dépôt à un autre usager ou organisation si vous en avez la responsabilité.
settings.delete = Détruire ce dépôt
settings.delete_desc = La destruction est irrémédiable, impossible d'annuler. Soyez sûr de votre décision.
settings.update_settings_success = Réglages modifiés
settings.transfer_owner = Nouveau responsable
settings.make_transfer = Faire le transfert
settings.confirm_delete = Confirmer la destruction
settings.add_collaborator = Ajouter un nouveau collaborateur
settings.add_collaborator_success = Nouveau collaborateur ajouté.
settings.remove_collaborator_success = Collaborateur supprimé.
settings.add_webhook = Ajouter un Webhook
settings.hooks_desc = Les Webhooks permettent à des services externes d'être avertis de certains changements sur Gogs. Lorque qu'un changement se produit, Gogs envoie une requête POST à chacun des URLs spécifiés. Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>.
settings.remove_hook_success = Webhook supprimé.
settings.add_webhook_desc = Gogs envoiera un POST à l'URL ci-dessous avec le détail de l'événement souscrit. Vous pouvez aussi spécifier dans quel format vous désirez recevoir les données (JSON,<code>x-www-form-urlencoded</code>, <em>etc</em>). Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>.
settings.payload_url = URL cible
settings.content_type = Content Type
settings.secret = Secret
settings.event_desc = Quels changements déclencheront le webhook?
settings.event_push_only = Uniquement les <code>push</code>.
settings.active = Activé
settings.active_helper = Gogs fournira le détail de l'événement lorsque ce webhook sera déclenché.
settings.add_hook_success = Nouveau webhook ajouté.
settings.update_webhook = Mettre à jour le webhook
settings.update_hook_success = Webhook mis à jour.
settings.delete_webhook = Détruire le webhook
settings.recent_deliveries = Livraisons récentes
settings.hook_type = Type de déclencheur
settings.add_slack_hook_desc = Ajouter la compatibilité <a href="http://slack.com">Slack</a> à ce dépôt.
settings.slack_token = Jeton (token)
settings.slack_domain = Domaine
settings.slack_channel = Canal
[org]
org_name_holder = Nom de l'organisation
org_name_helper = Les bons noms d'organisations sont courts, mémorables et uniques
org_email_helper = Le courriel de l'organisation recevra toutes les notifications et les confirmations.
create_org = Créer une organisation
repo_updated = Changement effectué
people = Personne
invite_someone = Inviter quelqu'un
teams = Équipes
lower_members = Membres
lower_repositories = Dépôts
create_new_team = Créer une nouvelle équipe
org_desc = Description
team_name = Nom de l'équipe
team_desc = Description
team_name_helper = Le nom qui sera utilisé pour mentionner cette équipe dans les conversations.
team_desc_helper = Quel est la raison d'être de cette équipe?
team_permission_desc = Quel niveau de permission attribuer à cette équipe?
settings = Réglages
settings.options = Paramètres
settings.full_name = Nom complet
settings.website = Site web
settings.location = Endroit
settings.update_settings = Mettre à jour les paramètres
settings.update_setting_success = Paramètres mis à jour.
settings.delete = Détruire l'organisation
settings.delete_account = Détruire cette organisation
settings.delete_prompt = La destruction de l'organisation est irrémédiable, impossible d'annuler. Soyez sûr de votre décision.
settings.confirm_delete_account = Confirmer la destruction
members.public = Publique
members.public_helper = Rendre privé
members.private = Privé
members.private_helper = Rendre publique
members.owner = Responsable
members.member = Membre
members.conceal = Caché
members.remove = Retirer
members.leave = Quitter
members.invite_desc = Commencez à saisir un nom d'usager pour l'inviter à %s:
members.invite_now = Inviter
teams.join = Rejoindre
teams.leave = Quitter
teams.read_access = Droits de lecture
teams.read_access_helper = Cette équipe pourra voir et cloner ses dépôts.
teams.write_access = Droits d'écriture
teams.write_access_helper = Cette équipe pourra voir et cloner ses dépôts ainsi que pousser vers ceux-ci.
teams.admin_access = Droits de gestion
teams.admin_access_helper = En plus des droits d'écriture, cette équipe pourra gérer les collaborateurs.
teams.no_desc = Cette équipe ne posséde pas de description
teams.settings = Réglages
teams.owners_permission_desc = Les responsables ont accès à <strong>tous</strong> les dépôts et en possédent les droits de gestion.
teams.members = Membre de l'équipe
teams.update_settings = Mettre à jour
teams.delete_team = Détruire cette équipe
teams.add_team_member = Ajouter un membre à l'équipe
teams.delete_team_success = Équipe détruite
teams.read_permission_desc = La participation à cette équipe confère les droits de lecture. Ses membres peuvent voir et cloner ses dépôts.
teams.write_permission_desc = La participation à cette équipe confère les droits d'écriture en plus des droits de lecture. Ses membres peuvent pousser vers les dépôts de l'équipe.
teams.admin_permission_desc = La participation à cette équire confère les droits de gestion. Ses membres peuvent voir, cloner, pousser et gérer les collaborateurs des dépôts.
teams.repositories = Dépôts de l'équipe
teams.add_team_repository = Ajouer un dépôt à l'équipe
teams.remove_repo = Enlever
[admin]
dashboard = Tableau de bord
users = Usagers
organizations = Organisations
repositories = Dépôts
authentication = Sources d'authentifications
config = Configuration
monitor = Monitoring
prev = Préc.
next = Suiv.
dashboard.statistic = Statistiques
dashboard.operations = Opérations
dashboard.system_status = État du monitoring système
dashboard.statistic_info = La BD Gogs compte <b>%d</b> usagers, <b>%d</b> organisations, <b>%d</b> clé SSH, <b>%d</b> dépôts, <b>%d</b> suivis, <b>%d</b> étoiles, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes Internet, <b>%d</b> suivis, <b>%d</b> mirroirs, <b>%d</b> publications, <b>%d</b> sources d'authentification, <b>%d</b> webhooks, <b>%d</b> jalons, <b>%d</b> tags, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jours, <b>%d</b> fichiers joints.
dashboard.operation_name = Nom de l'opération
dashboard.operation_switch = Commande
dashboard.operation_run = Lancer
dashboard.clean_unbind_oauth = Nettoyer les OAuths orphelins
dashboard.delete_inactivate_accounts = Détruire les comptes inactifs
dashboard.server_uptime = Démarré depuis
dashboard.current_goroutine = Nombre de Goroutines
dashboard.current_memory_usage = Usage mémoire actuel
dashboard.total_memory_allocated = Mémoire allouée totale
dashboard.memory_obtained = Memoire obtenue
dashboard.pointer_lookup_times = Accès pointeur
dashboard.memory_allocate_times = Allocation mémoire
dashboard.memory_free_times = Désallocation mémoire
dashboard.current_heap_usage = Taille du heap actuelle
dashboard.heap_memory_obtained = Mémoire heap obtenue
dashboard.heap_memory_idle = Mémoire heap inactive
dashboard.heap_memory_in_use = Mémoire heap utilisée
dashboard.heap_memory_released = Mémoire heap relachée
dashboard.heap_objects = Objets dans le heap
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
dashboard.stack_memory_obtained = Stack Memory Obtained
dashboard.mspan_structures_usage = MSpan Structures Usage
dashboard.mspan_structures_obtained = MSpan Structures Obtained
dashboard.mcache_structures_usage = MCache Structures Usage
dashboard.mcache_structures_obtained = MCache Structures Obtained
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
dashboard.gc_metadata_obtained = GC Metadada Obtained
dashboard.other_system_allocation_obtained = Other System Allocation Obtained
dashboard.next_gc_recycle = Next GC Recycle
dashboard.last_gc_time = Since Last GC Time
dashboard.total_gc_time = Total GC Pause
dashboard.total_gc_pause = Total GC Pause
dashboard.last_gc_pause = Last GC Pause
dashboard.gc_times = GC Times
users.user_manage_panel = Gestion des usager
users.new_account = Creér un nouveau compte
users.name = Nom
users.activated = Activé
users.admin = Gestionnaire
users.repos = Dépôts
users.created = Créé
users.edit = Editer
users.auth_source = Source d'authentification
users.local = Locale
users.auth_login_name = Identifiant d'authentification
users.update_profile_success = Compte crée.
users.edit_account = Éditer compte
users.is_activated = Ce compte est activé
users.is_admin = Ce compte a les droits de gestionnaire
users.update_profile = Mettre à jour le compte
users.delete_account = Détruire ce compte
users.still_own_repo = Ce compte est responsables d'un dépôt. I faut détruire le dépôt ou transférer la responsabilité avant de détruire ce compte.
orgs.org_manage_panel = Gestion des organisations
orgs.name = Nom
orgs.teams = Équipes
orgs.members = Membres
repos.repo_manage_panel = Gestion des dépôts
repos.owner = Responsable
repos.name = Nom
repos.private = Privé
repos.watches = Suivis
repos.stars = Étoiles
repos.issues = Ticket
auths.auth_manage_panel = Gestion des sources d'authentification
auths.new = Ajouter une nouvelle source d'authentification
auths.name = Nom
auths.type = Type
auths.enabled = Activé
auths.updated = Mis à jour
auths.auth_type = Type d'authentification
auths.auth_name = Nom de l'authentification
auths.domain = Domaine
auths.host = Serveur
auths.port = Port
auths.base_dn = DN de base
auths.attributes = Attributs de recherche
auths.filter = Filtre de recherche
auths.ms_ad_sa = Microsoft Active Directory
auths.smtp_auth = Authentification SMTP
auths.smtphost = Serveur SMTP
auths.smtpport = Port SMTP
auths.enable_tls = Chiffrement TLS
auths.enable_auto_register = Activer auto-abonnement
auths.tips = Trucs
auths.edit = Éditer réglages d'authentification
auths.activated = Source d'authentification activée
auths.update_success = Réglages mis à jour.
auths.update = Mettre à jour réglages
auths.delete = Détruire cette source
config.server_config = Configuration du serveur
config.app_name = Nom de l'applicaiton
config.app_ver = Version de l'application
config.app_url = URL de l'application
config.domain = Domaine
config.offline_mode = Mode hors-ligne
config.disable_router_log = Journal du routeur désactivé
config.run_user = Éxécuté en tant que
config.run_mode = Mode de fonctionnement
config.repo_root_path = Dossier contenant les dépôts
config.static_file_root_path = Dossier contenant les fichiers statiques
config.log_file_root_path = Dossier contenant les journaux
config.script_type = Type de script
config.reverse_auth_user = Usager d'authentification inversée
config.db_config = Configuration de la BD
config.db_type = Type
config.db_host = Serveur
config.db_name = Nom
config.db_user = Usager
config.db_ssl_mode = Mode SSL
config.db_ssl_mode_helper = (pour "postgres" seulement)
config.db_path = Path
config.db_path_helper = (pour "sqlite3" seulement)
config.service_config = Configuration du service
config.register_email_confirm = Confirmation d'abonnement par courriel
config.disable_register = Auto-inscription désactivée
config.require_sign_in_view = Connexion requise pour visualiser
config.mail_notify = Notifications par courriel
config.enable_cache_avatar = Cache avatar activée
config.active_code_lives = Jeton d'activation
config.reset_password_code_lives = Jeton de modification mot-de-passe
config.webhook_config = Configuration Webhook
config.task_interval = Intervalle
config.deliver_timeout = Expiration des appels
config.mailer_config = Configuration expédition de courriels
config.mailer_enabled = Activé
config.mailer_name = Nom
config.mailer_host = Serveur
config.mailer_user = Usager
config.oauth_config = Configuration OAuth
config.oauth_enabled = Activé
config.cache_config = Configuration du cache
config.cache_adapter = Mécanisme de cache
config.cache_interval = Intervalle
config.cache_conn = Chaîne de connexion
config.session_config = Configuration des session
config.session_provider = Mécanisme
config.provider_config = Configuration du mécanisme
config.cookie_name = Nom du fichier témoin
config.enable_set_cookie = Fichier témoin actvité
config.gc_interval_time = Intervalle GC
config.session_life_time = Durée de la session
config.https_only = HTTPS exigé
config.cookie_life_time = Expiration du fichier témoin
config.session_hash_function = Fonction de hashage ID de session
config.session_hash_key = Clé de hashage ID de session
config.picture_config = Configuration des avatars
config.picture_service = Service image
config.disable_gravatar = Désactivé Gravatar
config.log_config = Configuration du journal
config.log_mode = Mode de journal
monitor.cron = Cron Tasks
monitor.name = Name
monitor.schedule = Schedule
monitor.next = Next Time
monitor.previous = Previous Time
monitor.execute_times = Execute Times
monitor.process = Running Processes
monitor.desc = Description
monitor.start = Start Time
monitor.execute_time = Execution Time
[action]
create_repo = a créé le dépôt <a href="/%s">%s</a>
commit_repo = a poussé sur <a href="/%s/src/%s">%s</a> à <a href="/%s">%s</a>
create_issue = a ouvert le ticket <a href="/%s/issues/%s">%s#%s</a>
comment_issue = a commenté sur le ticket <a href="/%s/issues/%s">%s#%s</a>
[tool]
ago = auparavant
from_now = depuis
now = maintenant
1s = 1 seconde %s
1m = 1 minute %s
1h = 1 heure %s
1d = 1 jour %s
1w = 1 semaine %s
1mon = 1 mos %s
1y = 1 an %s
seconds = %d secondes %s
minutes = %d minutes %s
hours = %d heures %s
days = %d jours %s
weeks = %d semaines %s
months = %d mois %s
years = %d années %s
raw_seconds = secondes
raw_minutes = minutes

View File

@@ -0,0 +1,585 @@
app_desc = Een pijnloze self-hosted Git-dienst geschreven in Go
home = Home
dashboard = Dashboard
explore = Verkennen
help = Help
sign_in = Inloggen
social_sign_in = Social netwerk inlog: tweede stap <small>account koppelen</small>
sign_out = Afmelden
sign_up = Aanmelden
register = Registreer
website = Website
version = Versie
page = Pagina
template = Template
language = Taal
username = Gebruikersnaam
email = E-mail
password = Wachttwoord
re_type = Verificatie
captcha = Captcha
repository = Repositorie
organization = Organisatie
mirror = Mirror
new_repo = Nieuwe repositorie
new_migrate = Nieuwe migratie
new_org = Nieuwe organisatie
manage_org = Beheer organisaties
admin_panel = Adminpaneel
account_settings = Accountinstellingen
settings = Instellingen
news_feed = Nieuwsfeed
pull_requests = Pull-aanvragen
issues = Issues
cancel = Annuleer
[home]
uname_holder = Gebruikersnaam of e-mail
password_holder = Wachtwoord
switch_dashboard_context = Wissel voorpaginacontext
my_repos = Mijn repositories
collaborative_repos = Gedeelde repositories
my_orgs = Mijn organisaties
my_mirrors = Mijn mirrors
[auth]
create_new_account = Maak nieuw account aan
register_hepler_msg = Heeft u al een account? Meld u nu aan!
social_register_hepler_msg = Heeft u al een account? Koppel nu!
disable_register_prompt = Sorry, registratie is uitgeschakeld. Neem contact op met de beheerder van deze site.
disable_register_mail = Sorry, bevestiging van registratie per e-mail is uitgeschakeld.
remember_me = Onthoud mij
forgot_password = Wachtwoord vergeten
forget_password = Wachtwoord vergeten?
sign_up_now = Een account nodig? Meld u nu aan.
confirmation_mail_sent_prompt = Een bevestigingsemail is gestuurd naar <b>%s</b>, Bevestig u aanvraag binnen %d uren om uw registratie te voltooien.
sign_in_email = Meld u aan met uw e-mailadres
active_your_account = Activeer uw account
resent_limit_prompt = Sorry, u heeft te snel na elkaar een aanvraag gedaan voor een activatie mail. Wacht drie minuten voor uw volgende aanvraag.
has_unconfirmed_mail = Beste %s, u heeft een onbevestigde e-mailadres (<b>%s</b>). Als u nog geen bevestiging per e-mail heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
resend_mail = Klik hier om uw activatie mail nog een keer te verzenden
send_reset_mail = Klik hier om uw wachtwoord reset mail (nogmaals) te versturen
reset_password = Reset uw wachtwoord
invalid_code = Sorry, uw bevestigingscode is verlopen of niet meer geldig.
reset_password_helper = Klik hier om uw wachtwoord opnieuw in te stellen.
password_too_short = De lengte van uw wachtwoord moet minimaal zes karakters zijn.
email_not_associate = Dit e-mailadres is niet gekoppeld aan een account.
[form]
UserName = Gebruikersnaam
RepoName = Repositorie naam
Email = e-mailadres
Password = Wachtwoord
Retype = Verifieer wachtwoord
SSHTitle = SSH sleutel naam
HttpsUrl = HTTPS URL
PayloadUrl = Payload URL
TeamName = Team naam
AuthName = Autorisatienaam
require_error = kan niet leeg zijn.
alpha_dash_error = moet een valide alfanumeriek of dash(-_) karakter zijn.
alpha_dash_dot_error = moet een valide alfanumeriek, dash(-_) of (.) punt karakter zijn.
min_size_error = moet minimaal %s karakters bevatten.
max_size_error = mag maximaal %s karakters bevatten.
email_error = is niet een valide e-mail adres.
url_error = is niet een valide URL.
unknown_error = Onbekende fout:
captcha_incorrect = Captcha komt niet overeen.
password_not_match = Wachtwoord en verificatie wachtwoord komen niet overeen.
username_been_taken = Gebruikersnaam is al in gebruik.
repo_name_been_taken = Repositorie naam is al in gebruik.
org_name_been_taken = Organisatie naam is al in gebruik.
team_name_been_taken = Team naam is al in gebruik.
email_been_used = e-mailadres is al in gebruik.
ssh_key_been_used = Openbare sleutel naam is al in gebruik.
illegal_username = Gebruikersnaam bevat illegale karakters.
illegal_repo_name = Repositorie naam bevat illegale karakters.
illegal_org_name = Organisatie naam bevat illegale karakters.
illegal_team_name = Team naam bevat illegale karakters.
username_password_incorrect = Gebruikersnaam of wachtwoord is niet correct.
enterred_invalid_repo_name = U heeft een onjuiste repositorie naam ingevoerd.
enterred_invalid_owner_name = U heeft een onjuiste eigenaar ingevoerd.
enterred_invalid_password = U heeft een onjuiste wachtwoord ingevoerd.
user_not_exist = Gegeven gebruiker bestaat niet.
last_org_owner = De gebruiker die u probeert te verwijderen is het enige lid (eigenaar) van dit team. U moet eerst nieuwe lid (eigenaar) aanstellen.
invalid_ssh_key = Sorry, we zijn niet in staat om uw SSH-sleutel te verifiëren: %s
auth_failed = Verificatie mislukt: %v
still_own_repo = Uw account heeft nog een eigendom op een repositorie. U moet deze eerst verwijderen of overdragen.
org_still_own_repo = De organisatie heeft nog eigendomen op repositories. U moet deze eerst verwijderen of overdragen.
still_own_user = Deze authenticatie methode wordt nog gebruikt door sommige gebruikers. U moet hen eerst verplaatsen of verwijderen.
AdminEmail = E-mail beheerder
[settings]
profile = Profiel
password = Wachtwoord
ssh_keys = SSH-sleutels
social = Sociale netwerk-accounts
orgs = Organisaties
delete = Verwijder account
public_profile = Openbaar profiel
profile_desc = Uw e-mailadres is openbaar zichtbaar en zal gebruikt worden gebruikt voor alle account gerlateerde berichtgevingen en web bewerking gemaakt via de website.
full_name = Volledige naam
website = Website
location = Locatie
update_profile = Profile bijwerken
update_profile_success = Uw profiel is succesvol bijgewerkt.
change_password = Verander wachtwoord
old_password = Huidige wachtwoord
new_password = Nieuw wachtwoord
password_incorrect = Huidig wachtwoord is niet correct.
change_password_success = Wachtwoord is succesvol gewijzigd. U kunt nu met uw nieuwe wachtwoord inloggen.
manage_ssh_keys = Beheer SSH sleutels
add_key = Sleutel toevoegen
ssh_desc = Dit is een lijst van alle SSH sleutels die gekoppeld zijn aan uw account. Verwijder alle sleutels die u niet herkent.
ssh_helper = <strong>Hulp nodig?</strong> Bekijk onze help pagina's over <a href="https://help.github.com/articles/generating-ssh-keys">SSH sleutels genereeren</a> of over <a href="https://help.github.com/ssh-issues/">meest voorkomende SSH problemen</a>.
add_new_key = SSH sleutel toevoegen
key_name = Sleutel naam
key_content = Inhoud
add_key_success = Nieuwe SSH sleutel is toegevoegd!
delete_key = Verwijder
add_on = Toegevoegd op
last_used = Laatst gebruikt op
no_activity = Geen recente activiteiten
manage_social = Beheer gekoppelde sociale accounts
social_desc = Dit is een lijst van de bijbehorende sociale accounts koppelingen, Verwijder eventueel koppelingen die u niet herkent.
unbind = Loskoppelen
unbind_success = Sociaal account is ontkoppeld.
delete_account = Verwijder uw account
delete_prompt = Deze handeling zal uw account definitief verwijderen, u kunt dit <strong> NIET </strong> terug draaien!
confirm_delete_account = Bevestig verwijdering
uid = uid
change_username = Username veranderd
change_username_desc = Gebruikersnaam is gewijzigd. Wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op uw account.
continue = Doorgaan
cancel = Annuleren
delete_account_title = Account verwijderen
delete_account_desc = Dit account zal permanent worden verwijderd. Wilt u doorgaan?
[repo]
owner = Eigenaar
repo_name = Repositorie naam
repo_name_helper = Een goede repositorie naam is kort, memorabel en <strong>uniek</strong>.
visibility = Zichtbaarheid
visiblity_helper = Deze repositorie is <span class="label label-red label-radius">prive</span>
repo_desc = Omschrijving
repo_lang = Taal
repo_lang_helper = Selecteer een .gitignore bestand
license = Licentie
license_helper = Selecteer een licentie bestand
init_readme = Initialiseer deze repositorie met een README.md
create_repo = Nieuwe Repositorie
default_branch = Standaard branch
mirror_interval = Mirror interval(uur)
goget_meta = Go-Get Meta
goget_meta_helper = Deze repositorie is nu beschikbaar voor <span class="label label-blue label-radius">Go-Get</span>
need_auth = Autorisatie vereist
migrate_type = Migratie type
migrate_type_helper = Deze repositorie zal een <span class="label label-blue label-radius">mirror</span> worden
migrate_repo = Migreer repositorie
clone_helper = Hulp nodig bij het klonen? Kijk dan <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">hier</a> voor hulp!
unwatch = Negeren
watch = Volgen
unstar = Ontster
star = Ster
fork = Fork
settings = Instellingen
settings.options = Opties
settings.collaboration = Samenwerking
settings.hooks = Webhooks
settings.deploy_keys = Installeer sleutels
settings.basic_settings = Basis instellingen
settings.danger_zone = Gevaren zone
settings.site = Officiële site
settings.update_settings = Instellingen bewerken
settings.transfer = Eigendom overdragen
settings.transfer_desc = Draag deze repo over aan een andere gebruiker of een organisatie waar u beheerders rechten heeft.
settings.delete = Verwijder deze repositorie
settings.delete_desc = Als u eenmaal een repositorie verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties.
settings.update_settings_success = Repositorie instellingen zijn succesvol bijgewerkt.
settings.transfer_owner = Nieuwe eigenaar
settings.make_transfer = Maak overdracht
settings.confirm_delete = Bevestig verwijdering
settings.add_collaborator = Nieuwe medewerker toevoegen
settings.add_collaborator_success = medewerker is toegevoegd.
settings.remove_collaborator_success = medewerker is verwijderd.
settings.add_webhook = Webhook toevoegen
settings.hooks_desc = Webhooks maken het mogelijk om externe diensten te waaarschuwen wanneer zich bepaalde gebeurtenissen voordoen op Gogs . Wanneer de opgegeven gebeurtenissen gebeuren , zullen we een POST-aanvraag aan alle URL's die u verstrekt sturen . Lees meer in onze <a target="_blank" href="http://gogs.io/docs/features/webhook.html"> Webhooks gids </a>.
settings.remove_hook_success = Webhook is verwijderd.
settings.add_webhook_desc = We sturen een <code>POST</code> verzoek aan de onderstaande URL met de details van het geplaatste evenementen. U kunt ook aangeven welke data u wilt ontvangen (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). U kunt meer informatie vinden in onze <a target="_blank" href="http://gogs.io/docs/features/webhook.html"> webhooks gids</a>.
settings.payload_url = Payload URL
settings.content_type = Content type
settings.secret = Geheim
settings.event_desc = Bij welke gebeurtenissen wilt u dat deze webhook getriggerd wordt?
settings.event_push_only = Alleen bij de <code>push</code> event.
settings.active = Actief
settings.active_helper = We zullen details van de gebeurtenissen af leveren wanneer deze webhook wordt geactiveerd.
settings.add_hook_success = Nieuwe webhook toegevoegd.
settings.update_webhook = Bewerk webhook
settings.update_hook_success = Webhook is bijgewerkt.
settings.delete_webhook = Webhook verwijderen
settings.recent_deliveries = Recente bezorgingen
copy_link = Kopieer
click_to_copy = Kopieer link naar plakbord
copied = Gekopieerd
no_desc = Geen omschrijving
quick_guide = Snelstart gids
clone_this_repo = Kloon deze repositorie
create_new_repo_command = Maak een nieuwe repositorie aan vanaf de console
push_exist_repo = Push een bestaande repositorie vanaf de console
branch = Aftakking
tree = Boom
branch_and_tags = Aftakkingen & labels
branches = Aftakkingen
tags = Labels
issues = Issues
commits = Commits
releases = Publicaties
commits.commits = Commits
commits.search = Zoeken
commits.find = zoek
commits.author = Auteur
commits.message = Bericht
commits.date = Datum
commits.older = Ouder
commits.newer = Nieuwer
settings.change_reponame = Repositorienaam aangepast
settings.change_reponame_desc = De repositorienaam is veranderd. Wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op deze repositorie.
settings.new_owner_has_same_repo = De nieuwe eigenaar heeft al een repositorie met deze naam
settings.transfer_notices = <p> - U kan uw toegang verliezen als de nieuwe eigenaar een individuele gebruiker is</p> <p> - . . U zal uw toegang behouden als de nieuwe eigenaar een organisatie is en u één van de eigenaren bent</p>
settings.transfer_succeed = Eigendom repositorie succesvol overgedragen
settings.hook_type = Type hook
settings.add_slack_hook_desc = Voeg een <a href="http://slack.com">Slack</a> integratie toe aan uw repositorie.
settings.slack_token = Slack token
settings.slack_domain = Slack domein
settings.slack_channel = Slack kanaal
[org]
org_name_holder = Organisatienaam
org_name_helper = Een goede organisatienaam is kort en memorabel.
org_email_helper = Alle notificaties en bevestigingen worden op het e-mailadres van de organisatie ontvangen.
create_org = Nieuwe organisatie aanmaken
repo_updated = Geupdate
people = Mensen
invite_someone = Iemand uitnodigen
teams = Teams
lower_members = leden
lower_repositories = repositories
create_new_team = Nieuw team aanmaken
org_desc = Omschrijving
team_name = Teamnaam
team_desc = Omschrijving
team_name_helper = U gebruikt deze naam om dit team te vermelden in conversaties.
team_desc_helper = Waar gaat dit team doen?
team_permission_desc = Welke privileges zou dit team moeten hebben?
settings = Instellingen
settings.options = Opties
settings.full_name = Volledige naam
settings.website = Website
settings.location = Locatie
settings.update_settings = Instellingen bijwerken
settings.update_setting_success = Organisatie instellingen zijn succesvol bijgewerkt.
settings.delete = Verwijder organisatie
settings.delete_account = Verwijder deze organisatie
settings.delete_prompt = Deze actie zal de origanisatie permanent verwijderen. U kunt dit <strong>NIET</strong> terug draaien!
settings.confirm_delete_account = Bevestig verwijdering
members.public = Openbaar
members.public_helper = maak prive
members.private = Prive
members.private_helper = maak openbaar
members.owner = Eigenaar
members.member = Lid
members.conceal = Verbergen
members.remove = Verwijderen
members.leave = Verlaat
members.invite_desc = Begin met het typen van een gebruikersnaam om een nieuw lid aan %s uit te nodigen:
members.invite_now = Nu uitnodigen
teams.join = Lid worden
teams.leave = Vertlaat
teams.read_access = Leestoegang
teams.read_access_helper = Dit team is in staat om zijn repositories te bekijken en te klonen.
teams.write_access = Schrijf toegang
teams.write_access_helper = Dit team is in staat om zijn repositories te bekijken en push aanvragen te verwerken.
teams.admin_access = Beheerder toegang
teams.admin_access_helper = Dit team is in staat om push & pull aanvragen te verwerken en om nieuwe medewerkers toe te voegen.
teams.no_desc = Dit team heeft geen omschrijving
teams.settings = Instellingen
teams.owners_permission_desc = Eigenaren hebben volledige toegang tot <strong>alle repositories</strong> en hebben <strong>beheerder rechten</strong> over de organisatie.
teams.members = Team leden
teams.update_settings = Instellingen bijwerken
teams.delete_team = Verwijder deze team
teams.add_team_member = Nieuwe team lid aanmaken
teams.delete_team_success = Gekozen team is succesvol verwijderd.
teams.read_permission_desc = Dit team heeft <strong>Lees</strong> rechten : leden kunnen repositories lezen en klonen.
teams.write_permission_desc = Dit team heeft <strong>Schrijf</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken.
teams.admin_permission_desc = Dit team heeft <strong>Beheerders</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken en medewerkers toevoegen.
teams.repositories = Teamrepositories
teams.add_team_repository = Nieuwe teamrepositorie aanmaken
teams.remove_repo = Verwijder
settings.change_orgname = Organisatie naam veranderd
settings.change_orgname_desc = De naam van de organisatie is veranderd, wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op deze organisatie.
settings.delete_org_title = Verwijderen organsiatie
settings.delete_org_desc = Deze organisatie zal permanent worden verwijderd, wilt u doorgaan?
settings.hooks_desc = Een webhook toevoegen die door <strong>alle repositories</strong> in deze organisatie getriggerd kan worden.
teams.delete_team_title = Team verwijderen
teams.delete_team_desc = Dit team zal worden verwijderd. De leden van dit team zullen toegang tot alle repositories van het team verliezen. Wilt u doorgaan?
[admin]
dashboard = Dashboard
users = Gebruikers
organizations = Orgranisaties
repositories = Repositories
authentication = Autenticaties
config = Configuratie
monitor = Bijhouden
prev = Vorige
next = Volgende
dashboard.statistic = Statistieken
dashboard.operations = Bewerkingen
dashboard.system_status = Status Systeemmonitor
dashboard.statistic_info = Gogs database heeft <b>%d</b> gebruikers, <b>%d</b> organisaties, <b>%d</b> openbare sleutels, <b>%d</b> repositories, <b>%d</b> volgers, <b>%d</b> sterren, <b>%d</b> acties, <b>%d</b> participanten, <b>%d</b> issues, <b>%d</b> reacties, <b>%d</b> sociale accounten, <b>%d</b> volgers, <b>%d</b> mirrors, <b>%d</b> publicaties, <b>%d</b> login bronnen, <b>%d</b> webhooks, <b>%d</b> mijlpalen, <b>%d</b> labels, <b>%d</b> hook taken, <b>%d</b> teams, <b>%d</b> bijgewerkte taken, <b>%d</b> bijlagen.
dashboard.operation_name = Bewerking naam
dashboard.operation_switch = Omschakelen
dashboard.operation_run = Uitvoeren
dashboard.clean_unbind_oauth = Clean unbound OAuths
dashboard.delete_inactivate_accounts = Verwijder alle inactieve accounts
dashboard.server_uptime = Uptime server
dashboard.current_goroutine = Huidige Goroutines
dashboard.current_memory_usage = Huidige geheugen gebruik
dashboard.total_memory_allocated = Totaal toegewezen geheugen
dashboard.memory_obtained = Geheugen gebruikt
dashboard.pointer_lookup_times = Pointer Lookup Times
dashboard.memory_allocate_times = Memory Allocate Times
dashboard.memory_free_times = Memory Free Times
dashboard.current_heap_usage = Current Heap Usage
dashboard.heap_memory_obtained = Heap Memory Obtained
dashboard.heap_memory_idle = Heap Memory Idle
dashboard.heap_memory_in_use = Heap Memory In Use
dashboard.heap_memory_released = Heap Memory Released
dashboard.heap_objects = Heap Objects
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
dashboard.stack_memory_obtained = Stack Memory Obtained
dashboard.mspan_structures_usage = MSpan Structures Usage
dashboard.mspan_structures_obtained = MSpan Structures Obtained
dashboard.mcache_structures_usage = MCache Structures Usage
dashboard.mcache_structures_obtained = MCache Structures Obtained
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
dashboard.gc_metadata_obtained = GC Metadada Obtained
dashboard.other_system_allocation_obtained = Other System Allocation Obtained
dashboard.next_gc_recycle = Volgende GC recycle
dashboard.last_gc_time = Sinds vorige GC verwerkingstijd
dashboard.total_gc_time = Totaal GC verwerkingstijd
dashboard.total_gc_pause = Totaal GC verwerkingstijd
dashboard.last_gc_pause = Laatste GC verwerkingstijd
dashboard.gc_times = GC verwerkingen
users.user_manage_panel = Gebruikers beheren
users.new_account = Nieuw account aanmaken
users.name = Naam
users.activated = Geactiveerd
users.admin = Admin
users.repos = Repos
users.created = Aangemaakt
users.edit = Bewerken
users.auth_source = Autorisatiebron
users.local = Lokaal
users.auth_login_name = Autorisatie inlognaam
users.update_profile_success = Profiel is succesvol bijgewerkt.
users.edit_account = Bewerk account
users.is_activated = Dit account is geactiveerd
users.is_admin = Dit account heeft beheerdersrechten
users.update_profile = Account profiel bijwerken
users.delete_account = Dit account verwijderen
users.still_own_repo = Dit account is nog steeds eigendom van een repositorie. U moet deze repositorie eerst verwijderen of overdragen.
orgs.org_manage_panel = Organisaties beheren
orgs.name = Naam
orgs.teams = Teams
orgs.members = Leden
repos.repo_manage_panel = Repositoriebeheerpaneel
repos.owner = Eigenaar
repos.name = Naam
repos.private = Prive
repos.watches = Volgers
repos.stars = Sterren
repos.issues = Issues
auths.auth_manage_panel = Autorisatiebeheerpaneel
auths.new = Nieuwe autorisatiebron
auths.name = Naam
auths.type = Type
auths.enabled = Ingeschakeld
auths.updated = Bijgewerkt
auths.auth_type = Autorisatietype
auths.auth_name = Autorisatienaam
auths.domain = Domein
auths.host = Host
auths.port = Poort
auths.base_dn = Base DN
auths.attributes = Zoek attributen
auths.filter = Zoek filter
auths.ms_ad_sa = Ms Ad SA
auths.smtp_auth = SMTP authenticatietype
auths.smtphost = SMTP host
auths.smtpport = SMTP poort
auths.enable_tls = Activeer TLS-encryptie
auths.enable_auto_register = Activeer automatische registratie
auths.tips = Tips
auths.edit = Bewerk autorisatie-instellingen
auths.activated = Deze autorisatiemethode is geactiveerd
auths.update_success = Autorisatie-instellingen zijn succesvol bijgewerkt.
auths.update = Update autorisatie-instellingen
auths.delete = Verwijder deze autorisatie
config.server_config = Serverconfiguratie
config.app_name = Applicatienaam
config.app_ver = Applicatieversie
config.app_url = Applicatie-URL
config.domain = Domein
config.offline_mode = Offline-modus
config.disable_router_log = Router-log uitschakelen
config.run_user = Uitvoerende gebruiker
config.run_mode = Uitvoer modus
config.repo_root_path = Repositorie basis pad
config.static_file_root_path = Statische bestanden basis pad
config.log_file_root_path = Log bestand basis pad
config.script_type = Script type
config.reverse_auth_user = Reverse Authentication User
config.db_config = Databaseconfiguratie
config.db_type = Type
config.db_host = Host
config.db_name = Naam
config.db_user = Gebruiker
config.db_ssl_mode = SSL modus
config.db_ssl_mode_helper = (alleen voor "postgres")
config.db_path = Path
config.db_path_helper = (alleen voor "sqlite3")
config.service_config = Serviceconfiguratie
config.register_email_confirm = Register Email Confirmation
config.disable_register = Registratie uitgeschakeld
config.require_sign_in_view = Inloggen vereist om te kunnen inzien
config.mail_notify = E-mailnotificaties
config.enable_cache_avatar = Avatar Cache inschakelen
config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook configuratie
config.task_interval = Taakinterval
config.deliver_timeout = Bezorging verlooptijd
config.mailer_config = Mailerconfiguatie
config.mailer_enabled = Ingeschakeld
config.mailer_name = Naam
config.mailer_host = Host
config.mailer_user = Gebruiker
config.oauth_config = OAuth-configuratie
config.oauth_enabled = Ingeschakeld
config.cache_config = Cache-configuratie
config.cache_adapter = Cache-adapter
config.cache_interval = Cache-interval
config.cache_conn = Cache-connectie
config.session_config = Sessieconfiguratie
config.session_provider = Sessieprovider
config.provider_config = Provider config
config.cookie_name = Cookie naam
config.enable_set_cookie = Set Cookie inschakelen
config.gc_interval_time = GC interval time
config.session_life_time = Sessie duur
config.https_only = Alleen HTTPS
config.cookie_life_time = Cookie duur leeftijd
config.session_hash_function = Sessie ID Hash functie
config.session_hash_key = Sessie ID Hash sleutel
config.picture_config = Foto configuratie
config.picture_service = Foto service
config.disable_gravatar = Gravatar uitschakelen
config.log_config = Logconfiguratie
config.log_mode = Log-modus
monitor.cron = Cron-taken
monitor.name = Naam
monitor.schedule = Planning
monitor.next = Volgende
monitor.previous = Vorige
monitor.execute_times = Aantal keren uitgevoerd
monitor.process = Draaiende processen
monitor.desc = Omschrijving
monitor.start = Starttijd
monitor.execute_time = Uitvoertijd
auths.delete_auth_title = Verwijderings-autorisatie
auths.delete_auth_desc = Deze autorisatiemethode wordt verwijderd. Weet u zeker dat u wilt doorgaan?
[action]
create_repo = repositorie aangemaakt in <a href="%s/%s">%s</a>
commit_repo = push update naar <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a
create_issue = opende issue in <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue = reactie op issue <a href="%s/%s/issues/%s">%s#%s</a>
transfer_repo = repositorie verplaatst naar <code>%s</code> naar <a href="/%s%s">%s</a>
[tool]
ago = geleden
from_now = vanaf nu
now = nu
1s = 1 seconde %s
1m = 1 minuut %s
1h = 1 uur %s
1d = 1 dag %s
1w = 1 week %s
1mon = 1 maand %s
1y = 1 jaar %s
seconds = %d seconden %s
minutes = %d minuten %s
hours = %d uur %s
days = %d dagen %s
weeks = %d weken %s
months = %d maanden %s
years = %d jaren %s
raw_seconds = seconden
raw_minutes = minuten
[install]
install = Installatie
title = Installatiestappen voor de eerste keer opstarten
requite_db_desc = Om Gogs te gebruiken is MySQL, PostgreSQL of SQLite3 vereist (SQLite3 is beschikbaar in de officiële versie).
db_type = Database-type
host = Host
user = Gebruikersnaam
password = Wachtwoord
db_name = Database naam
db_helper = Gebruik InnoDB engine met utf8_general_ci karakterset voor MySQL.
ssl_mode = SSL-modus
path = Pad
sqlite_helper = Het pad naar de SQLite3 database.
general_title = Algemene instellingen van Gogs
repo_path = Repositories basis directorie
repo_path_helper = Alle remote Git repositories worden in deze directorie opgeslagen
run_user = Uitvoerende gebruikersnaam
run_user_helper = Deze gebruiker moet toegang hebben tot de git repositorie directorie en moet Gogs kunnen starten
domain = Domein
domain_helper = Dit heeft invloed op de SSH kloon URLs
app_url = Applicatie URL
app_url_helper = Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt
email_title = Email service instellingen (Optioneel)
smtp_host = SMTP host
mailer_user = Afzender e-mail / gebruikersnaam
mailer_password = Wachtwoord
notify_title = Notificatie-instelligen (optioneel)
register_confirm = Activeer registratie emails
mail_notify = Activeer e-mailnotificaties
admin_title = Instellingen beheerdersaccount
admin_name = Gebruikersnaam
admin_password = Wachtwoord
confirm_password = Verifieer wachtwoord
admin_email = E-mailadres
install_gogs = Installeer Gogs
test_git_failed = Git test niet gelukt: 'git' commando %v
sqlite3_not_available = SQLite3 wordt niet ondersteund in uw versie. Gelieve de officiële versie downloaden vanaf http://gogs.io/docs/installation/install_from_binary.html, niet de gobuild versie downloaden.
invalid_db_setting = Uw database instellingen zijn niet correct: %v
invalid_repo_path = Repositorie basis pad is niet correct: %v
run_user_not_match = De uitvoerende gebruiker is niet de huidig gebruiker: %s -> %s
save_config_failed = Kan de configuratie niet opslaan: %v
invalid_admin_setting = Uw admin-instellingen zijn niet geldig: %v
install_success = Welkom! Wij zijn veheugd dat u voor Gogs heeft gekozen, veel plezier en tot ziens
[explore]
repos = Repositories
[user]
change_avatar = Verander uw avatar op Gravatar.com
join_on = Aangemeld op
repositories = repositories
activity = Openbare activiteit
followers = Volgers
starred = Sterren
following = Volgt

View File

@@ -166,6 +166,15 @@ org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先
still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试!
[user]
change_avatar = 到 gravatar.com 上修改您的头像
join_on = 加入于
repositories = 仓库列表
activity = 公开活动
followers = 关注者
starred = 已点赞
following = 关注中
[settings]
profile = 个人信息
password = 修改密码
@@ -182,6 +191,10 @@ website = 个人网站
location = 所在地区
update_profile = 更新信息
update_profile_success = 您的个人信息更新成功!
change_username = 用户名将被修改
change_username_desc = 用户名被修改,您确定要继续操作吗?这将会影响到所有与您帐户有关的链接。
continue = 继续操作
cancel = 取消操作
change_password = 修改密码
old_password = 当前密码
@@ -210,6 +223,8 @@ unbind_success = 社交帐号解除绑定成功!
delete_account = 删除当前帐户
delete_prompt = 删除操作会永久清除您的帐户信息,并且 <strong>不可恢复</strong>
confirm_delete_account = 确认删除帐户
delete_account_title = 帐户删除操作
delete_account_desc = 该帐户将被永久性删除,您确定要继续操作吗?
[repo]
owner = 拥有者
@@ -235,6 +250,8 @@ migrate_type_helper = 本仓库将是 <span class="label label-blue label-radius
migrate_repo = 迁移仓库
copy_link = 复制链接
click_to_copy = 复制到剪切板
copied = 复制成功
clone_helper = 不知道如何操作?访问 <a target="_blank" href="http://git-scm.com/book/zh/Git-基础-取得项目的-Git-仓库">此处</a> 查看帮助!
unwatch = 取消关注
watch = 关注
@@ -242,36 +259,66 @@ unstar = 取消点赞
star = 点赞
fork = 派生
no_desc = 暂无描述
quick_guide = 快速帮助
clone_this_repo = 克隆当前仓库
create_new_repo_command = 从命令行创建一个新的仓库
push_exist_repo = 从命令行推送已经创建的仓库
branch = 分支
tree = 目录树
branch_and_tags = 分支与标签
branches = 分支列表
tags = 标签列表
issues = 工单管理
commits = 提交历史
releases = 版本发布
commits.commits = 次代码提交
commits.search = 搜索提交历史
commits.find = 查找
commits.author = 作者
commits.message = 备注
commits.date = 提交日期
commits.older = 更旧的提交
commits.newer = 更新的提交
settings = 仓库设置
settings.options = 基本设置
settings.collaboration = 管理协作者
settings.hooks = 管理 Web 钩子
settings.githooks = 管理 Git 钩子
settings.deploy_keys = 管理部署密钥
settings.basic_settings = 基本设置
settings.danger_zone = 危险操作区
settings.site = 官方网站
settings.update_settings = 更新仓库设置
settings.change_reponame = 仓库名称将被修改
settings.change_reponame_desc = 仓库名称被修改,您确定要继续操作吗?这将会影响到所有与该仓库有关的链接。
settings.transfer = 转移仓库所有权
settings.transfer_desc = 您可以将仓库转移至您拥有管理员权限的帐户或组织。
settings.new_owner_has_same_repo = 新的仓库拥有者已经存在同名仓库!
settings.delete = 删除本仓库
settings.delete_desc = 删除仓库操作不可逆转,请三思而后行。
settings.transfer_notices = <p>- 如果您转移给个人用户,您将对仓库失去所有权限。</p><p>- 如果您转移给您作为拥有者的组织,则可继续保持操作权限。</p>
settings.update_settings_success = 仓库设置更新成功!
settings.transfer_owner = 新拥有者
settings.make_transfer = 确认转移仓库
settings.transfer_succeed = 仓库所有权转移成功!
settings.confirm_delete = 确认删除仓库
settings.add_collaborator = 增加新的协作者
settings.add_collaborator_success = 成功添加新的协作者!
settings.remove_collaborator_success = 被操作的协作者已经被收回权限!
settings.user_is_org_member = 被操作的用户是组织成员,因此无法添加为协作者!
settings.add_webhook = 添加 Web 钩子
settings.hooks_desc = Web 钩子允许您设定在 Gogs 上发生指定事件时对指定 URL 发送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。
settings.remove_hook_success = Web 钩子删除成功!
settings.add_webhook_desc = 我们会通过 <code>POST</code> 请求将订阅事件信息发送至向指定 URL 地址。您可以设置不同的数据接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 请查阅 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。
settings.githooks_desc = Git 钩子是由 Git 本身提供的功能,以下为 Gogs 所支持的钩子列表。
settings.githook_edit_desc = 如果钩子未启动,则会显示样例文件中的内容。如果想要删除某个钩子,则提交空白文本即可。
settings.githook_name = 钩子名称
settings.githook_content = 钩子文本
settings.update_githook = 更新钩子设置
settings.payload_url = 推送地址
settings.content_type = 数据格式
settings.secret = 密钥文本
@@ -315,11 +362,16 @@ settings.full_name = 组织全名
settings.website = 官方网站
settings.location = 所在地区
settings.update_settings = 更新组织设置
settings.change_orgname = 组织名称将被修改
settings.change_orgname_desc = 组织名称被修改,您确定要继续操作吗?这将会影响到所有与该组织有关的链接。
settings.update_setting_success = 组织设置更新成功!
settings.delete = 删除组织
settings.delete_account = 删除当前组织
settings.delete_prompt = 删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>
settings.confirm_delete_account = 确认删除组织
settings.delete_org_title = 组织删除操作
settings.delete_org_desc = 该组织将被永久性删除,您确定要继续操作吗?
settings.hooks_desc = 在此处添加的 Web 钩子将会应用到该组织下的 <strong>所有仓库</strong>。
members.public = 公开成员
members.public_helper = 设为私有
@@ -348,6 +400,8 @@ teams.members = 团队成员
teams.update_settings = 更新团队设置
teams.delete_team = 删除当前团队
teams.add_team_member = 添加团队成员
teams.delete_team_title = 团队删除操作
teams.delete_team_desc = 删除操作会永久清除有关该团队的信息,您确定要继续操作吗?团队成员可能会失去对某些仓库的操作权限。
teams.delete_team_success = 指定团队删除成功!
teams.read_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 权限,团队成员可以进行查看和克隆等只读操作。
teams.write_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 和 <strong>写入</strong> 的权限。
@@ -355,6 +409,7 @@ teams.admin_permission_desc = 该团队拥有一定的 <strong>管理</strong>
teams.repositories = 团队仓库
teams.add_team_repository = 添加团队仓库
teams.remove_repo = 移除仓库
teams.add_nonexistent_repo = 您尝试添加到团队的仓库不存在,请先创建仓库!
[admin]
dashboard = 控制面板
@@ -363,6 +418,7 @@ organizations = 组织管理
repositories = 仓库管理
authentication = 授权认证管理
config = 应用配置管理
notices = 系统提示管理
monitor = 应用监控面板
prev = 上一页
next = 下一页
@@ -423,6 +479,7 @@ users.is_activated = 该用户已被激活
users.is_admin = 该用户具有管理员权限
users.update_profile = 更新用户信息
users.delete_account = 删除该用户
users.still_own_repo = 该帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作!
orgs.org_manage_panel = 组织管理面板
orgs.name = 组织名称
@@ -463,6 +520,8 @@ auths.activated = 该授权认证已经启用
auths.update_success = 授权认证设置更新成功!
auths.update = 更新授权认证信息
auths.delete = 删除该授权认证
auths.delete_auth_title = 授权认证删除操作
auths.delete_auth_desc = 该授权认证将被删除,您确定要继续吗?
config.server_config = 服务器配置
config.app_name = 应用名称
@@ -537,11 +596,19 @@ monitor.desc = 进程描述
monitor.start = 开始时间
monitor.execute_time = 已执行时间
notices.system_notice_list = 系统提示管理
notices.type = 提示类型
notices.type_1 = 仓库
notices.desc = 描述
notices.op = 操作
notices.delete_success = 系统提示删除成功!
[action]
create_repo = 创建了仓库 <a href="/%s">%s</a>
commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>
create_issue = 创建了工单 <a href="/%s/issues/%s">%s#%s</a>
comment_issue = 评论了工单 <a href="/%s/issues/%s">%s#%s</a>
create_repo = 创建了仓库 <a href="%s/%s">%s</a>
commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a>
create_issue = 创建了工单 <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue = 评论了工单 <a href="%s/%s/issues/%s">%s#%s</a>
transfer_repo = 将仓库 <code>%s</code> 转移至 <a href="/%s%s">%s</a>
[tool]
ago = 之前

View File

@@ -0,0 +1,642 @@
app_desc = 基於 Go 語言的自助 Git 服務
home = 首頁
dashboard = 控制面版
explore = 探索
help = 幫助
sign_in = 登錄
social_sign_in = 社交帳號登錄:第 2 步 <small>關聯帳號</small>
sign_out = 退出
sign_up = 註冊
register = 註冊
website = 官方網站
version = 當前版本
page = 頁面
template = 模版
language = 語言選項
username = 用戶名
email = 郵箱
password = 密碼
re_type = 確認密碼
captcha = 驗證碼
repository = 倉庫
organization = 組織
mirror = 鏡像
new_repo = 創建新的倉庫
new_migrate = 遷移外部倉庫
new_org = 創建新的組織
manage_org = 管理我的組織
admin_panel = 管理面版
account_settings = 帳戶設置
settings = 帳戶設置
news_feed = 最新活動
pull_requests = 合併請求
issues = 問題管理
cancel = 取消
[install]
install = 安裝頁面
title = 首次執行安裝程序
requite_db_desc = Gogs 允許後端數據庫為 MySQL、PostgreSQL 或 SQLite3但是 SQLite3 一般只有官方二進制發行版才支持。
db_type = 數據庫類型
host = 數據庫主機
user = 數據庫用戶
password = 數據庫用戶密碼
db_name = 數據庫名稱
db_helper = 如果您使用 MySQL請使用 INNODB 引擎以及 utf8_general_ci 字符集。
ssl_mode = SSL 模式
path = 數據庫文件路徑
sqlite_helper = SQLite3 數據庫的文件路徑。
general_title = 應用基本設置
repo_path = 倉庫根目錄
repo_path_helper = 所有 Git 遠程倉庫都將被存放於該目錄。
run_user = 執行系統用戶
run_user_helper = 該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。
domain = 域名
domain_helper = 該設置影響 SSH 克隆地址。
app_url = 應用 URL
app_url_helper = 該設置影響 HTTP/HTTPS 克隆地址和一些郵箱中的鏈接。
email_title = 郵件服務設置(可選)
smtp_host = SMTP 主機
mailer_user = 發送郵箱
mailer_password = 發送郵箱密碼
notify_title = 通知提醒設置(可選)
register_confirm = 啟用註冊郵箱確認
mail_notify = 啟用郵件通知提醒
admin_title = 管理員帳號設置
admin_name = 管理員用戶名
admin_password = 管理員密碼
confirm_password = 確認密碼
admin_email = 管理員郵箱
install_gogs = 立即安裝
test_git_failed = 無法識別 'git' 命令:%v
sqlite3_not_available = 您所使用的發行版本不支持 SQLite3請從 http://gogs.io/docs/installation/install_from_binary.html 下載官方二進制發行版本,而不是 gobuild 版本。
invalid_db_setting = 數據庫設置不正確:%v
invalid_repo_path = 倉庫根目錄設置不正確:%v
run_user_not_match = 執行系統用戶非當前用戶:%s -> %s
save_config_failed = 應用配置保存失敗:%v
invalid_admin_setting = 管理員帳戶設置不正確:%v
install_success = 您好!我們很高興您選擇使用 Gogs祝您使用愉快代碼從此無 BUG
[home]
uname_holder = 用戶名或郵箱
password_holder = 密碼
switch_dashboard_context = 切換控制面版用戶
my_repos = 我的倉庫
collaborative_repos = 參與協作的倉庫
my_orgs = 我的組織
my_mirrors = 我的鏡像
[explore]
repos = 探索倉庫
[auth]
create_new_account = 創建帳戶
register_hepler_msg = 已經註冊?立即登錄!
social_register_hepler_msg = 已經註冊?立即綁定!
disable_register_prompt = 對不起,註冊功能已被關閉。請聯系網站管理員。
disable_register_mail = 對不起,註冊郵箱確認功能已被關閉。
remember_me = 記住登錄
forgot_password = 忘記密碼
forget_password = 忘記密碼?
sign_up_now = 還沒帳戶?馬上註冊。
confirmation_mail_sent_prompt = 一封新的確認郵件已經被發送至 <b>%s</b>,請檢查您的收件箱並在 %d 小時內完成確認註冊操作。
sign_in_email = 登錄到您的郵箱
active_your_account = 激活您的帳戶
resent_limit_prompt = 對不起,您請求發送激活郵件過於頻繁,請等待 3 分鐘後再試!
has_unconfirmed_mail = %s 您好,系統檢測到您有一封發送至 <b>%s</b> 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。
resend_mail = 單擊此處重新發送確認郵件
email_not_associate = 您輸入的郵箱地址未被關聯到任何帳號!
send_reset_mail = 單擊此處(重新)發送您的密碼重置郵件
reset_password = 重置密碼
invalid_code = 對不起,您的確認代碼已過期或已失效。
reset_password_helper = 單擊此處重置密碼
password_too_short = 密碼長度不能少於 6 位!
[form]
UserName = 用戶名
RepoName = 倉庫名稱
Email = 郵箱地址
Password = 密碼
Retype = 確認密碼
SSHTitle = SSH 密鑰名稱
HttpsUrl = HTTPS URL 地址
PayloadUrl = 推送地址
TeamName = 團隊名稱
AuthName = 認證名稱
AdminEmail = 管理員郵箱
require_error = 不能為空。
alpha_dash_error = 必須為英文字母、阿拉伯數字或橫線(-_
alpha_dash_dot_error = 必須為英文字母、阿拉伯數字、橫線(-_或點。
min_size_error = 長度最小為 %s 個字符。
max_size_error = 長度最大為 %s 個字符。
email_error = 不是一個有效的郵箱地址。
url_error = 不是一個有效的 URL。
unknown_error = 未知錯誤:
captcha_incorrect = 驗證碼未匹配。
password_not_match = 密碼與確認密碼未匹配。
username_been_taken = 用戶名已經被佔用。
repo_name_been_taken = 倉庫名稱已經被佔用。
org_name_been_taken = 組織名稱已經被佔用。
team_name_been_taken = 團隊名稱已經被佔用。
email_been_used = 郵箱地址已經被使用。
ssh_key_been_used = SSH 密鑰已經被使用。
illegal_username = 您的用戶名包含不合法字符。
illegal_repo_name = 倉庫名稱包含不合法字符。
illegal_org_name = 組織名稱包含不合法字符。
illegal_team_name = 團隊名稱包含不合法字符。
username_password_incorrect = 用戶名或密碼不正確。
enterred_invalid_repo_name = 請檢查您輸入的倉庫名稱是正確。
enterred_invalid_owner_name = 請檢查您輸入的新所有者用戶名是否正確。
enterred_invalid_password = 請檢查您輸入的密碼是否正確。
user_not_exist = 被操作的用戶不存在!
last_org_owner = 被移除用戶為最後一位管理員。請添加一位新的管理員再進行移除成員操作!
invalid_ssh_key = 很抱歉,我們無法驗證您輸入的 SSH 密鑰:%s
auth_failed = 授權驗證失敗:%v
still_own_repo = 您的帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作!
org_still_own_repo = 該組織仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除組織操作!
still_own_user = 該授權認證依舊被部分用戶使用,請先刪除該部分用戶後再試!
[user]
change_avatar = 到 gravatar.com 上修改您的頭像
join_on = 加入於
repositories = 倉庫列表
activity = 公開活動
followers = 關註者
starred = 已點讚
following = 關註中
[settings]
profile = 個人信息
password = 修改密碼
ssh_keys = 管理 SSH 密鑰
social = 社交帳號綁定
orgs = 管理組織
delete = 刪除帳戶
uid = 用戶 ID
public_profile = 公開信息
profile_desc = 您的郵箱地址將會被公開,並被用於接收帳戶的所有提醒和通知。
full_name = 自定義名稱
website = 個人網站
location = 所在地區
update_profile = 更新信息
update_profile_success = 您的個人信息更新成功!
change_username = 用戶名將被修改
change_username_desc = 用戶名被修改,您確定要繼續操作嗎?這將會影響到所有與您帳戶有關的鏈接。
continue = 繼續操作
cancel = 取消操作
change_password = 修改密碼
old_password = 當前密碼
new_password = 新的密碼
password_incorrect = 當前密碼不正確!
change_password_success = 密碼修改成功!您現在可以使用新的密碼登錄。
manage_ssh_keys = 管理 SSH 密鑰
add_key = 增加密鑰
ssh_desc = 以下是與您帳戶所關聯的 SSH 密鑰,如果您發現有陌生的密鑰,請立即刪除它!
ssh_helper = <strong>需要幫助?</strong> 請查看有關 <a href="https://help.github.com/articles/generating-ssh-keys">如何生成 SSH 密鑰</a> 或 <a href="https://help.github.com/ssh-issues/">常見 SSH 問題</a> 尋找答案。
add_new_key = 增加 SSH 密鑰
key_name = 密鑰名稱
key_content = 密鑰內容
add_key_success = 新的 SSH 密鑰添加成功!
delete_key = 刪除
add_on = 增加於
last_used = 上次使用在
no_activity = 沒有最近活動
manage_social = 管理關聯社交帳戶
social_desc = 以下是與您帳戶所關聯的社交帳號,如果您發現有陌生的關聯,請立即解除綁定!
unbind = 解除綁定
unbind_success = 社交帳號解除綁定成功!
delete_account = 刪除當前帳戶
delete_prompt = 刪除操作會永久清除您的帳戶信息,並且 <strong>不可恢復</strong>
confirm_delete_account = 確認刪除帳戶
delete_account_title = 帳戶刪除操作
delete_account_desc = 該帳戶將被永久性刪除,您確定要繼續操作嗎?
[repo]
owner = 擁有者
repo_name = 倉庫名稱
repo_name_helper = 偉大的倉庫名稱一般都較短、令人深刻並且 <strong>獨一無二</strong> 的。
visibility = 可見度
visiblity_helper = 本倉庫將是 <span class="label label-red label-radius">私有的</span>
repo_desc = 倉庫描述
repo_lang = 倉庫語言
repo_lang_helper = 請選擇 .gitignore 文件
license = 授權許可
license_helper = 請選擇授權許可文件
init_readme = 使用 README.md 文件初始化倉庫
create_repo = 創建倉庫
default_branch = 默認分支
mirror_interval = 鏡像同步周期(小時)
goget_meta = Go-Get 支持
goget_meta_helper = 本倉庫將可以通過 <span class="label label-blue label-radius">Go Get</span> 獲取
need_auth = 需要授權驗證
migrate_type = 遷移類型
migrate_type_helper = 本倉庫將是 <span class="label label-blue label-radius">鏡像</span>
migrate_repo = 遷移倉庫
copy_link = 復製鏈接
click_to_copy = 復製到剪切簿
copied = 復製成功
clone_helper = 不知道如何操作?訪問 <a target="_blank" href="http://git-scm.com/book/zh/Git-基礎-取得項目的-Git-倉庫">此處</a> 查看幫助!
unwatch = 取消關註
watch = 關註
unstar = 取消點讚
star = 點讚
fork = 派生
no_desc = 暫無描述
quick_guide = 快速幫助
clone_this_repo = 克隆當前倉庫
create_new_repo_command = 從命令行創建一個新的倉庫
push_exist_repo = 從命令行推送已經創建的倉庫
branch = 分支
tree = 目錄樹
branch_and_tags = 分支與標籤
branches = 分支列表
tags = 標籤列表
issues = 問題管理
commits = 提交歷史
releases = 版本發佈
commits.commits = 次代碼提交
commits.search = 搜索提交歷史
commits.find = 查找
commits.author = 作者
commits.message = 備註
commits.date = 提交日期
commits.older = 更舊的提交
commits.newer = 更新的提交
settings = 倉庫設置
settings.options = 基本設置
settings.collaboration = 管理協作者
settings.hooks = 管理 Web 鉤子
settings.githooks = 管理 Git 鉤子
settings.deploy_keys = 管理部署密鑰
settings.basic_settings = 基本設置
settings.danger_zone = 危險操作區
settings.site = 官方網站
settings.update_settings = 更新倉庫設置
settings.change_reponame = 倉庫名稱將被修改
settings.change_reponame_desc = 倉庫名稱被修改,您確定要繼續操作嗎?這將會影響到所有與該倉庫有關的鏈接。
settings.transfer = 轉移倉庫所有權
settings.transfer_desc = 您可以將倉庫轉移至您擁有管理員權限的帳戶或組織。
settings.new_owner_has_same_repo = 新的倉庫擁有者已經存在同名倉庫!
settings.delete = 刪除本倉庫
settings.delete_desc = 刪除倉庫操作不可逆轉,請三思而後行。
settings.transfer_notices = <p>- 如果您轉移給個人用戶,您將對倉庫失去所有權限。</p><p>- 如果您轉移給您作為擁有者的組織,則可繼續保持操作權限。</p>
settings.update_settings_success = 倉庫設置更新成功!
settings.transfer_owner = 新擁有者
settings.make_transfer = 確認轉移倉庫
settings.transfer_succeed = 倉庫所有權轉移成功!
settings.confirm_delete = 確認刪除倉庫
settings.add_collaborator = 增加新的協作者
settings.add_collaborator_success = 成功添加新的協作者!
settings.remove_collaborator_success = 被操作的協作者已經被收回權限!
settings.add_webhook = 添加 Web 鉤子
settings.hooks_desc = Web 鉤子允許您設定在 Gogs 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文檔</a> 獲取更多信息。
settings.remove_hook_success = Web 鉤子刪除成功!
settings.add_webhook_desc = 我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文檔</a> 獲取更多信息。
settings.githooks_desc = Git 鉤子是由 Git 本身提供的功能,以下為 Gogs 所支持的鉤子列表。
settings.githook_edit_desc = 如果鉤子未啟動,則會顯示樣例文件中的內容。如果想要刪除某個鉤子,則提交空白文本即可。
settings.githook_name = 鉤子名稱
settings.githook_content = 鉤子文本
settings.update_githook = 更新鉤子設置
settings.payload_url = 推送地址
settings.content_type = 數據格式
settings.secret = 密鑰文本
settings.event_desc = 請設置您希望觸發 Web 鉤子的事件:
settings.event_push_only = 只推送 <code>push</code> 事件。
settings.active = 是否激活
settings.active_helper = 當指定事件發生時我們將會觸發此 Web 鉤子。
settings.add_hook_success = Web 鉤子添加成功!
settings.update_webhook = 更新 Web 鉤子
settings.update_hook_success = Web 鉤子更新成功!
settings.delete_webhook = 刪除 Web 鉤子
settings.recent_deliveries = 最近推送記錄
settings.hook_type = 鉤子類型
settings.add_slack_hook_desc = 為您的倉庫增加 <a href="http://slack.com">Slack</a> 集成
settings.slack_token = 令牌
settings.slack_domain = 域名
settings.slack_channel = 頻道
[org]
org_name_holder = 組織名稱
org_name_helper = 偉大的組織都有一個簡短而寓意深刻的名字。
org_email_helper = 組織的郵箱用於接收所有通知和確認郵件。
create_org = 創建組織
repo_updated = 最後更新於
people = 組織成員
invite_someone = 邀請他人加入
teams = 組織團隊
lower_members = 名成員
lower_repositories = 個倉庫
create_new_team = 創建新的團隊
org_desc = 組織描述
team_name = 團隊名稱
team_desc = 團隊描述
team_name_helper = 您可以使用該名稱來通知改組全體成員。
team_desc_helper = 一句話描述這個團隊是做什麼的。
team_permission_desc = 請選擇該團隊所具有的權限等級:
settings = 組織設置
settings.options = 基本設置
settings.full_name = 組織全名
settings.website = 官方網站
settings.location = 所在地區
settings.update_settings = 更新組織設置
settings.change_orgname = 組織名稱將被修改
settings.change_orgname_desc = 組織名稱被修改,您確定要繼續操作嗎?這將會影響到所有與該組織有關的鏈接。
settings.update_setting_success = 組織設置更新成功!
settings.delete = 刪除組織
settings.delete_account = 刪除當前組織
settings.delete_prompt = 刪除操作會永久清除該組織的信息,並且 <strong>不可恢復</strong>
settings.confirm_delete_account = 確認刪除組織
settings.delete_org_title = 組織刪除操作
settings.delete_org_desc = 該組織將被永久性刪除,您確定要繼續操作嗎?
settings.hooks_desc = 在此處添加的 Web 鉤子將會應用到該組織下的 <strong>所有倉庫</strong>。
members.public = 公開成員
members.public_helper = 設為私有
members.private = 私有成員
members.private_helper = 設為公開
members.owner = 管理員
members.member = 普通成員
members.conceal = 隱藏身份
members.remove = 移除成員
members.leave = 離開組織
members.invite_desc = 請輸入被邀請到組織 %s 的用戶名稱:
members.invite_now = 立即邀請
teams.join = 加入團隊
teams.leave = 離開團隊
teams.read_access = 讀取權限
teams.read_access_helper = 這個團隊將擁有查看和克隆所屬倉庫的權限。
teams.write_access = 寫入權限
teams.write_access_helper = 這個團隊將擁有查看、克隆和推送所屬倉庫的權限。
teams.admin_access = 管理權限
teams.admin_access_helper = 這個團隊將擁有查看、克隆、推送和添加其他組織成員到團隊的權限。
teams.no_desc = 該團隊暫無描述
teams.settings = 團隊設置
teams.owners_permission_desc = 管理員團隊對 <strong>所有倉庫</strong> 具有操作權限,且對組織具有 <strong>管理員權限</strong>。
teams.members = 團隊成員
teams.update_settings = 更新團隊設置
teams.delete_team = 刪除當前團隊
teams.add_team_member = 添加團隊成員
teams.delete_team_title = 團隊刪除操作
teams.delete_team_desc = 刪除操作會永久清除有關該團隊的信息,您確定要繼續操作嗎?團隊成員可能會失去對某些倉庫的操作權限。
teams.delete_team_success = 指定團隊刪除成功!
teams.read_permission_desc = 該團隊擁有對所屬倉庫的 <strong>讀取</strong> 權限,團隊成員可以進行查看和克隆等只讀操作。
teams.write_permission_desc = 該團隊擁有對所屬倉庫的 <strong>讀取</strong> 和 <strong>寫入</strong> 的權限。
teams.admin_permission_desc = 該團隊擁有一定的 <strong>管理</strong> 權限,團隊成員可以讀取、克隆、推送以及添加其它倉庫協作者。
teams.repositories = 團隊倉庫
teams.add_team_repository = 添加團隊倉庫
teams.remove_repo = 移除倉庫
[admin]
dashboard = 控制面版
users = 用戶管理
organizations = 組織管理
repositories = 倉庫管理
authentication = 授權認證管理
config = 應用配置管理
notices = 系統提示管理
monitor = 應用監控面版
prev = 上一頁
next = 下一頁
dashboard.statistic = 應用統計數據
dashboard.operations = 管理員操作
dashboard.system_status = 系統監視狀態
dashboard.statistic_info = Gogs 數據庫統計:<b>%d</b> 位用戶,<b>%d</b> 個組織,<b>%d</b> 個公鑰,<b>%d</b> 個倉庫,<b>%d</b> 個倉庫關註,<b>%d</b> 個贊,<b>%d</b> 次行為,<b>%d</b> 條權限記錄,<b>%d</b> 個問題,<b>%d</b> 次評論,<b>%d</b> 個社交帳號,<b>%d</b> 個用戶關註,<b>%d</b> 個鏡像,<b>%d</b> 個版本發佈,<b>%d</b> 個登錄源,<b>%d</b> 個 Web 鉤子,<b>%d</b> 個里程碑,<b>%d</b> 個標籤,<b>%d</b> 個鉤子任務,<b>%d</b> 個團隊,<b>%d</b> 個更新任務,<b>%d</b> 個附件。
dashboard.operation_name = 操作名稱
dashboard.operation_switch = 開關
dashboard.operation_run = 執行
dashboard.clean_unbind_oauth = 清理未綁定社交帳號
dashboard.delete_inactivate_accounts = 刪除所有未激活帳戶
dashboard.server_uptime = 服務執行時間
dashboard.current_goroutine = 當前 Goroutines 數量
dashboard.current_memory_usage = 當前內存使用量
dashboard.total_memory_allocated = 所有被分配的內存
dashboard.memory_obtained = 內存佔用量
dashboard.pointer_lookup_times = 指針查找次數
dashboard.memory_allocate_times = 內存分配次數
dashboard.memory_free_times = 內存釋放次數
dashboard.current_heap_usage = 當前 Heap 內存使用量
dashboard.heap_memory_obtained = Heap 內存佔用量
dashboard.heap_memory_idle = Heap 內存空閒量
dashboard.heap_memory_in_use = 正在使用的 Heap 內存
dashboard.heap_memory_released = 被釋放的 Heap 內存
dashboard.heap_objects = Heap 對象數量
dashboard.bootstrap_stack_usage = 啟動 Stack 使用量
dashboard.stack_memory_obtained = 被分配的 Stack 內存
dashboard.mspan_structures_usage = MSpan 結構內存使用量
dashboard.mspan_structures_obtained = 被分配的 MSpan 結構內存
dashboard.mcache_structures_usage = MCache 結構內存使用量
dashboard.mcache_structures_obtained = 被分配的 MCache 結構內存
dashboard.profiling_bucket_hash_table_obtained = 被分配的剖析哈希表內存
dashboard.gc_metadata_obtained = 被分配的垃圾收集元數據內存
dashboard.other_system_allocation_obtained = 其它被分配的系統內存
dashboard.next_gc_recycle = 下次垃圾收集內存回收量
dashboard.last_gc_time = 距離上次垃圾收集時間
dashboard.total_gc_time = 垃圾收集執行時間總量
dashboard.total_gc_pause = 垃圾收集暫停時間總量
dashboard.last_gc_pause = 上次垃圾收集暫停時間
dashboard.gc_times = 垃圾收集執行次數
users.user_manage_panel = 用戶管理面版
users.new_account = 創建新的帳戶
users.name = 用戶名
users.activated = 已激活
users.admin = 管理員
users.repos = 倉庫數
users.created = 創建時間
users.edit = 編輯
users.auth_source = 認證源
users.local = 本地
users.auth_login_name = 認證登錄名
users.update_profile_success = 該用戶信息更新成功!
users.edit_account = 編輯用戶信息
users.is_activated = 該用戶已被激活
users.is_admin = 該用戶具有管理員權限
users.update_profile = 更新用戶信息
users.delete_account = 刪除該用戶
users.still_own_repo = 該帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作!
orgs.org_manage_panel = 組織管理面版
orgs.name = 組織名稱
orgs.teams = 團隊數
orgs.members = 成員數
repos.repo_manage_panel = 倉庫管理界面
repos.owner = 所有者
repos.name = 倉庫名稱
repos.private = 私有庫
repos.watches = 關註數
repos.stars = 點讚數
repos.issues = 問題數
auths.auth_manage_panel = 授權認證管理面版
auths.new = 添加新的認證源
auths.name = 認證名稱
auths.type = 認證類型
auths.enabled = 已啟用
auths.updated = 最後更新時間
auths.auth_type = 授權類型
auths.auth_name = 授權名稱
auths.domain = 域名
auths.host = 主機地址
auths.port = 主機端口
auths.base_dn = Base DN
auths.attributes = 搜尋屬性
auths.filter = 搜尋過濾
auths.ms_ad_sa = Ms Ad SA
auths.smtp_auth = SMTP 授權類型
auths.smtphost = SMTP 主機地址
auths.smtpport = SMTP 主機端口
auths.enable_tls = 啟用 TLS 加密
auths.enable_auto_register = 允許授權用戶自動註冊
auths.tips = 幫助提示
auths.edit = 修改授權認證設置
auths.activated = 該授權認證已經啟用
auths.update_success = 授權認證設置更新成功!
auths.update = 更新授權認證信息
auths.delete = 刪除該授權認證
auths.delete_auth_title = 授權認證刪除操作
auths.delete_auth_desc = 該授權認證將被刪除,您確定要繼續嗎?
config.server_config = 服務器配置
config.app_name = 應用名稱
config.app_ver = 應用版本
config.app_url = 應用 URL
config.domain = 應用域名
config.offline_mode = 離線模式
config.disable_router_log = 關閉路由日志
config.run_user = 執行用戶
config.run_mode = 執行模式
config.repo_root_path = 倉庫根目錄
config.static_file_root_path = 靜態文件根目錄
config.log_file_root_path = 日志文件根目錄
config.script_type = 腳本類型
config.reverse_auth_user = 反向代理認證
config.db_config = 數據庫配置
config.db_type = 數據庫類型
config.db_host = 主機地址
config.db_name = 數據庫名稱
config.db_user = 連接用戶
config.db_ssl_mode = SSL 模式
config.db_ssl_mode_helper = (僅限 "postgres" 使用)
config.db_path = 數據庫路徑
config.db_path_helper = (僅限 "sqlite3" 使用)
config.service_config = 服務配置
config.register_email_confirm = 註冊郵件確認
config.disable_register = 關閉註冊功能
config.require_sign_in_view = 強制登錄瀏覽
config.mail_notify = 郵件通知提醒
config.enable_cache_avatar = 開啟緩存頭像
config.active_code_lives = 激活用戶鏈接有效期
config.reset_password_code_lives = 重置密碼鏈接有效期
config.webhook_config = Web 鉤子配置
config.task_interval = 任務周期
config.deliver_timeout = 推送超時
config.mailer_config = 郵件配置
config.mailer_enabled = 啟用服務
config.mailer_name = 發送者名稱
config.mailer_host = 郵件主機地址
config.mailer_user = 發送者帳號
config.oauth_config = 社交帳號配置
config.oauth_enabled = 啟用服務
config.cache_config = Cache 配置
config.cache_adapter = Cache 適配器
config.cache_interval = Cache 周期
config.cache_conn = Cache 連接字符串
config.session_config = Session 配置
config.session_provider = Session 提供者
config.provider_config = 提供者配置
config.cookie_name = Cookie 名稱
config.enable_set_cookie = 啟用設置 Cookie
config.gc_interval_time = 垃圾收集周期
config.session_life_time = Session 生命周期
config.https_only = 僅限 HTTPS
config.cookie_life_time = Cookie 生命周期
config.session_hash_function = Session ID 哈希函數
config.session_hash_key = Session ID 哈希健值
config.picture_config = 圖片配置
config.picture_service = 圖片服務
config.disable_gravatar = 禁用 Gravatar 頭像
config.log_config = 日誌配置
config.log_mode = 日誌模式
monitor.cron = Cron 任務
monitor.name = 任務名稱
monitor.schedule = 任務安排
monitor.next = 下次執行時間
monitor.previous = 上次執行時間
monitor.execute_times = 執行次數
monitor.process = 執行中進程
monitor.desc = 進程描述
monitor.start = 開始時間
monitor.execute_time = 已執行時間
notices.system_notice_list = 系統提示管理
notices.type = 提示類型
notices.type_1 = 倉庫
notices.desc = 描述
notices.op = 操作
notices.delete_success = 系統提示刪除成功!
[action]
create_repo = 創建了倉庫 <a href="%s/%s">%s</a>
commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代碼到 <a href="%s/%s">%s</a>
create_issue = 創建了問題 <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue = 評論了問題 <a href="%s/%s/issues/%s">%s#%s</a>
transfer_repo = 將倉庫 <code>%s</code> 轉移至 <a href="/%s%s">%s</a>
[tool]
ago = 之前
from_now = 之後
now = 現在
1s = 1 秒%s
1m = 1 分鐘%s
1h = 1 小時%s
1d = 1 天%s
1w = 1 周%s
1mon = 1 月%s
1y = 1 年%s
seconds = %d 秒%s
minutes = %d 分鐘%s
hours = %d 小時%s
days = %d 天%s
weeks = %d 周%s
months = %d 月%s
years = %d 年%s
raw_seconds =
raw_minutes = 分鐘

View File

@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.5.0.0913 Beta"
const APP_VER = "0.5.5.1010 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
@@ -35,6 +35,7 @@ func main() {
cmd.CmdUpdate,
cmd.CmdFix,
cmd.CmdDump,
cmd.CmdCert,
}
app.Flags = append(app.Flags, []cli.Flag{}...)
app.Run(os.Args)

View File

@@ -137,7 +137,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
return err
}
url := fmt.Sprintf("/%s/%s/commit/%s", repoUserName, repoName, c.Sha1)
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
@@ -243,15 +243,29 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
if !strings.HasPrefix(oldCommitId, "0000000") {
compareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId)
}
pusher_email, pusher_name := "", ""
pusher, err := GetUserByName(userName)
if err == nil {
pusher_email = pusher.Email
pusher_name = pusher.GetFullNameFallback()
}
commits := make([]*PayloadCommit, len(commit.Commits))
for i, cmt := range commit.Commits {
author_username := ""
author, err := GetUserByEmail(cmt.AuthorEmail)
if err == nil {
author_username = author.Name
}
commits[i] = &PayloadCommit{
Id: cmt.Sha1,
Message: cmt.Message,
Url: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1),
Author: &PayloadAuthor{
Name: cmt.AuthorName,
Email: cmt.AuthorEmail,
Name: cmt.AuthorName,
Email: cmt.AuthorEmail,
UserName: author_username,
},
}
}
@@ -266,14 +280,16 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
Website: repo.Website,
Watchers: repo.NumWatches,
Owner: &PayloadAuthor{
Name: repoUserName,
Email: actEmail,
Name: repo.Owner.GetFullNameFallback(),
Email: repo.Owner.Email,
UserName: repo.Owner.Name,
},
Private: repo.IsPrivate,
},
Pusher: &PayloadAuthor{
Name: repo.Owner.LowerName,
Email: repo.Owner.Email,
Name: pusher_name,
Email: pusher_email,
UserName: userName,
},
Before: oldCommitId,
After: newCommitId,
@@ -334,13 +350,29 @@ func NewRepoAction(u *User, repo *Repository) (err error) {
// TransferRepoAction adds new action for transfering repository.
func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
OpType: TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name,
IsPrivate: repo.IsPrivate}); err != nil {
action := &Action{
ActUserId: u.Id,
ActUserName: u.Name,
ActEmail: u.Email,
OpType: TRANSFER_REPO,
RepoId: repo.Id,
RepoUserName: newUser.Name,
RepoName: repo.Name,
IsPrivate: repo.IsPrivate,
Content: path.Join(repo.Owner.LowerName, repo.LowerName),
}
if err = NotifyWatchers(action); err != nil {
log.Error(4, "NotifyWatchers: %d/%s", u.Id, repo.Name)
return err
}
// Remove watch for organization.
if repo.Owner.IsOrganization() {
if err = WatchRepo(repo.Owner.Id, repo.Id, false); err != nil {
log.Error(4, "WatchRepo", err)
}
}
log.Trace("action.TransferRepoAction: %s/%s", u.Name, repo.Name)
return err
}
@@ -350,7 +382,7 @@ func GetFeeds(uid, offset int64, isProfile bool) ([]*Action, error) {
actions := make([]*Action, 0, 20)
sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", uid)
if isProfile {
sess.Where("is_private=?", false).And("act_user_id=?", uid)
sess.And("is_private=?", false).And("act_user_id=?", uid)
}
err := sess.Find(&actions)
return actions, err

64
models/admin.go Normal file
View File

@@ -0,0 +1,64 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"time"
"github.com/Unknwon/com"
)
type NoticeType int
const (
NOTICE_REPOSITORY NoticeType = iota + 1
)
// Notice represents a system notice for admin.
type Notice struct {
Id int64
Type NoticeType
Description string `xorm:"TEXT"`
Created time.Time `xorm:"CREATED"`
}
// TrStr returns a translation format string.
func (n *Notice) TrStr() string {
return "admin.notices.type_" + com.ToStr(n.Type)
}
// CreateNotice creates new system notice.
func CreateNotice(tp NoticeType, desc string) error {
n := &Notice{
Type: tp,
Description: desc,
}
_, err := x.Insert(n)
return err
}
// CreateRepositoryNotice creates new system notice with type NOTICE_REPOSITORY.
func CreateRepositoryNotice(desc string) error {
return CreateNotice(NOTICE_REPOSITORY, desc)
}
// CountNotices returns number of notices.
func CountNotices() int64 {
count, _ := x.Count(new(Notice))
return count
}
// GetNotices returns given number of notices with offset.
func GetNotices(num, offset int) ([]*Notice, error) {
notices := make([]*Notice, 0, num)
err := x.Limit(num, offset).Desc("id").Find(&notices)
return notices, err
}
// DeleteNotice deletes a system notice by given ID.
func DeleteNotice(id int64) error {
_, err := x.Id(id).Delete(new(Notice))
return err
}

View File

@@ -70,7 +70,7 @@ func (diff *Diff) NumFiles() int {
const DIFF_HEAD = "diff --git "
func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
scanner := bufio.NewScanner(reader)
var (
curFile *DiffFile
@@ -79,6 +79,7 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
}
leftLine, rightLine int
isTooLong bool
)
diff := &Diff{Files: make([]*DiffFile, 0)}
@@ -90,18 +91,19 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
continue
}
i = i + 1
// Diff data too large.
if i == 5000 {
log.Warn("Diff data too large")
return &Diff{}, nil
}
if line == "" {
continue
}
i = i + 1
// Diff data too large, we only show the first about maxlines lines
if i == maxlines {
isTooLong = true
log.Warn("Diff data too large")
//return &Diff{}, nil
}
switch {
case line[0] == ' ':
diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine}
@@ -110,6 +112,10 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
curSection.Lines = append(curSection.Lines, diffLine)
continue
case line[0] == '@':
if isTooLong {
return diff, nil
}
curSection = &DiffSection{}
curFile.Sections = append(curFile.Sections, curSection)
ss := strings.Split(line, "@@")
@@ -143,6 +149,10 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
// Get new file.
if strings.HasPrefix(line, DIFF_HEAD) {
if isTooLong {
return diff, nil
}
fs := strings.Split(line[len(DIFF_HEAD):], " ")
a := fs[0]
@@ -174,7 +184,7 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
return diff, nil
}
func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string) (*Diff, error) {
func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string, maxlines int) (*Diff, error) {
repo, err := git.OpenRepository(repoPath)
if err != nil {
return nil, err
@@ -228,9 +238,9 @@ func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string) (*Diff,
}
}()
return ParsePatch(pid, cmd, rd)
return ParsePatch(pid, maxlines, cmd, rd)
}
func GetDiffCommit(repoPath, commitId string) (*Diff, error) {
return GetDiffRange(repoPath, "", commitId)
func GetDiffCommit(repoPath, commitId string, maxlines int) (*Diff, error) {
return GetDiffRange(repoPath, "", commitId, maxlines)
}

View File

@@ -161,12 +161,8 @@ func UserSignIn(uname, passwd string) (*User, error) {
return nil, err
}
if u.LoginType == NOTYPE {
if has {
u.LoginType = PLAIN
} else {
return nil, ErrUserNotExist
}
if u.LoginType == NOTYPE && has {
u.LoginType = PLAIN
}
// For plain login, user must exist to reach this line.

View File

@@ -32,12 +32,12 @@ var (
)
func init() {
tables = append(tables, new(User), new(PublicKey),
tables = append(tables, new(User), new(PublicKey), new(Follow), new(Oauth2),
new(Repository), new(Watch), new(Star), new(Action), new(Access),
new(Issue), new(Comment), new(Oauth2), new(Follow),
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
new(UpdateTask), new(Attachment))
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
new(Notice))
}
func LoadModelsConfig() {
@@ -87,7 +87,7 @@ func getEngine() (*xorm.Engine, error) {
func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to conntect database): %v", err)
return fmt.Errorf("models.init(fail to connect to database): %v", err)
}
return x.Sync(tables...)
@@ -96,7 +96,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
func SetEngine() (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to conntect database): %v", err)
return fmt.Errorf("models.init(fail to connect to database): %v", err)
}
// WARNNING: for serv command, MUST remove the output to os.stdout,

View File

@@ -22,6 +22,7 @@ import (
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -100,6 +101,7 @@ var (
"(MCE)": 1702,
"(McE)": 1702,
"(RSA)": 2048,
"(DSA)": 1024,
}
)
@@ -119,23 +121,30 @@ func CheckPublicKeyString(content string) (bool, error) {
tmpFile.WriteString(content)
tmpFile.Close()
// … see if ssh-keygen recognizes its contents
// Check if ssh-keygen recognizes its contents.
stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath)
if err != nil {
return false, errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
return false, errors.New("ssh-keygen returned not enough output to evaluate the key")
}
// The ssh-keygen in Windows does not print key type, so no need go further.
if setting.IsWindows {
return true, nil
}
sshKeygenOutput := strings.Split(stdout, " ")
if len(sshKeygenOutput) < 4 {
return false, errors.New("Not enough fields returned by ssh-keygen -l -f")
}
// Check if key type and key size match.
keySize, err := com.StrTo(sshKeygenOutput[0]).Int()
if err != nil {
return false, errors.New("Cannot get key size of the given key")
}
keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])
if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 {
return false, errors.New("Sorry, unrecognized public key type")
} else if keySize < minimumKeySize {
@@ -160,10 +169,14 @@ func saveAuthorizedKeyFile(key *PublicKey) error {
if err != nil {
return err
}
if finfo.Mode().Perm() > 0600 {
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String())
if err = f.Chmod(0600); err != nil {
return err
// FIXME: following command does not support in Windows.
if !setting.IsWindows {
if finfo.Mode().Perm() > 0600 {
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String())
if err = f.Chmod(0600); err != nil {
return err
}
}
}

View File

@@ -23,6 +23,7 @@ import (
"github.com/Unknwon/cae/zip"
"github.com/Unknwon/com"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
@@ -48,7 +49,7 @@ var (
)
var (
DescriptionPattern = regexp.MustCompile(`https?://\S+`)
DescPattern = regexp.MustCompile(`https?://\S+`)
)
func LoadRepoConfig() {
@@ -95,8 +96,13 @@ func NewRepoContext() {
if err != nil {
log.Fatal(4, "Fail to get Git version: %v", err)
}
if ver.Major < 2 && ver.Minor < 8 {
log.Fatal(4, "Gogs requires Git version greater or equal to 1.8.0")
reqVer, err := git.ParseVersion("1.7.1")
if err != nil {
log.Fatal(4, "Fail to parse required Git version: %v", err)
}
if ver.LessThan(reqVer) {
log.Fatal(4, "Gogs requires Git version greater or equal to 1.7.1")
}
// Check if server has basic git setting and set if not.
@@ -160,7 +166,9 @@ type Repository struct {
}
func (repo *Repository) GetOwner() (err error) {
repo.Owner, err = GetUserById(repo.OwnerId)
if repo.Owner == nil {
repo.Owner, err = GetUserById(repo.OwnerId)
}
return err
}
@@ -169,6 +177,14 @@ func (repo *Repository) GetMirror() (err error) {
return err
}
func (repo *Repository) HasAccess(uname string) bool {
if err := repo.GetOwner(); err != nil {
return false
}
has, _ := HasAccess(uname, path.Join(repo.Owner.Name, repo.Name), READABLE)
return has
}
// DescriptionHtml does special handles to description and return HTML string.
func (repo *Repository) DescriptionHtml() template.HTML {
sanitize := func(s string) string {
@@ -176,7 +192,7 @@ func (repo *Repository) DescriptionHtml() template.HTML {
ss := html.EscapeString(s)
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss)
}
return template.HTML(DescriptionPattern.ReplaceAllStringFunc(repo.Description, sanitize))
return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize))
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
@@ -651,7 +667,7 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
}
// Check if new owner has repository with same name.
has, err := IsRepositoryExist(u, repo.Name)
has, err := IsRepositoryExist(newUser, repo.Name)
if err != nil {
return err
} else if has {
@@ -664,17 +680,34 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
return err
}
if _, err = sess.Where("repo_name = ?", u.LowerName+"/"+repo.LowerName).
And("user_name = ?", u.LowerName).Update(&Access{UserName: newUser.LowerName}); err != nil {
sess.Rollback()
return err
owner := repo.Owner
oldRepoLink := path.Join(owner.LowerName, repo.LowerName)
// Delete all access first if current owner is an organization.
if owner.IsOrganization() {
if _, err = sess.Where("repo_name=?", oldRepoLink).Delete(new(Access)); err != nil {
sess.Rollback()
return fmt.Errorf("fail to delete current accesses: %v", err)
}
} else {
// Delete current owner access.
if _, err = sess.Where("repo_name=?", oldRepoLink).And("user_name=?", owner.LowerName).
Delete(new(Access)); err != nil {
sess.Rollback()
return fmt.Errorf("fail to delete access(owner): %v", err)
}
// In case new owner has access.
if _, err = sess.Where("repo_name=?", oldRepoLink).And("user_name=?", newUser.LowerName).
Delete(new(Access)); err != nil {
sess.Rollback()
return fmt.Errorf("fail to delete access(new user): %v", err)
}
}
if _, err = sess.Where("repo_name = ?", u.LowerName+"/"+repo.LowerName).Update(&Access{
RepoName: newUser.LowerName + "/" + repo.LowerName,
}); err != nil {
// Change accesses to new repository path.
if _, err = sess.Where("repo_name=?", oldRepoLink).
Update(&Access{RepoName: path.Join(newUser.LowerName, repo.LowerName)}); err != nil {
sess.Rollback()
return err
return fmt.Errorf("fail to update access(change reponame): %v", err)
}
// Update repository.
@@ -690,17 +723,17 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
return err
}
if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", u.Id); err != nil {
if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", owner.Id); err != nil {
sess.Rollback()
return err
}
mode := WRITABLE
if repo.IsMirror {
mode = READABLE
}
// New owner is organization.
if newUser.IsOrganization() {
mode := WRITABLE
if repo.IsMirror {
mode = READABLE
}
access := &Access{
RepoName: path.Join(newUser.LowerName, repo.LowerName),
Mode: mode,
@@ -732,10 +765,20 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
sess.Rollback()
return err
}
} else {
access := &Access{
RepoName: path.Join(newUser.LowerName, repo.LowerName),
UserName: newUser.LowerName,
Mode: mode,
}
if _, err = sess.Insert(access); err != nil {
sess.Rollback()
return fmt.Errorf("fail to insert access: %v", err)
}
}
// Change repository directory name.
if err = os.Rename(RepoPath(u.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
sess.Rollback()
return err
}
@@ -744,14 +787,8 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
return err
}
// Add watch of new owner to repository.
if !newUser.IsOrganization() {
if err = WatchRepo(newUser.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo", err)
}
}
if err = WatchRepo(u.Id, repo.Id, false); err != nil {
log.Error(4, "WatchRepo2", err)
if err = WatchRepo(newUser.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo", err)
}
if err = TransferRepoAction(u, newUser, repo); err != nil {
@@ -907,9 +944,14 @@ func DeleteRepository(uid, repoId int64, userName string) error {
sess.Rollback()
return err
}
// Remove repository files.
if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil {
sess.Rollback()
return err
desc := fmt.Sprintf("Fail to delete repository files(%s/%s): %v", userName, repo.Name, err)
log.Warn(desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "Fail to add notice: %v", err)
}
}
return sess.Commit()
}
@@ -1076,6 +1118,13 @@ func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
return repos, err
}
// __ __ __ .__
// / \ / \_____ _/ |_ ____ | |__
// \ \/\/ /\__ \\ __\/ ___\| | \
// \ / / __ \| | \ \___| Y \
// \__/\ / (____ /__| \___ >___| /
// \/ \/ \/ \/
// Watch is connection request for receiving repository notifycation.
type Watch struct {
Id int64
@@ -1146,6 +1195,13 @@ func NotifyWatchers(act *Action) error {
return nil
}
// _________ __
// / _____// |______ _______
// \_____ \\ __\__ \\_ __ \
// / \| | / __ \| | \/
// /_______ /|__| (____ /__|
// \/ \/
type Star struct {
Id int64
Uid int64 `xorm:"UNIQUE(s)"`
@@ -1160,16 +1216,20 @@ func StarRepo(uid, repoId int64, star bool) (err error) {
}
if _, err = x.Insert(&Star{Uid: uid, RepoId: repoId}); err != nil {
return err
} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoId); err != nil {
return err
}
_, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoId)
_, err = x.Exec("UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", uid)
} else {
if !IsStaring(uid, repoId) {
return nil
}
if _, err = x.Delete(&Star{0, uid, repoId}); err != nil {
return err
} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoId); err != nil {
return err
}
_, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoId)
_, err = x.Exec("UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", uid)
}
return err
}

View File

@@ -23,6 +23,10 @@ type UpdateTask struct {
NewCommitId string
}
const (
MAX_COMMITS int = 5
)
func AddUpdateTask(task *UpdateTask) error {
_, err := x.Insert(task)
return err
@@ -132,7 +136,6 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
// if commits push
commits := make([]*base.PushCommit, 0)
var maxCommits = 2
var actEmail string
for e := l.Front(); e != nil; e = e.Next() {
commit := e.Value.(*git.Commit)
@@ -145,7 +148,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
commit.Message(),
commit.Author.Email,
commit.Author.Name})
if len(commits) >= maxCommits {
if len(commits) >= MAX_COMMITS {
break
}
}

View File

@@ -5,6 +5,7 @@
package models
import (
"container/list"
"crypto/sha256"
"encoding/hex"
"errors"
@@ -82,22 +83,22 @@ type User struct {
// DashboardLink returns the user dashboard page link.
func (u *User) DashboardLink() string {
if u.IsOrganization() {
return "/org/" + u.Name + "/dashboard/"
return setting.AppSubUrl + "/org/" + u.Name + "/dashboard/"
}
return "/"
return setting.AppSubUrl + "/"
}
// HomeLink returns the user home page link.
func (u *User) HomeLink() string {
return "/user/" + u.Name
return setting.AppSubUrl + "/" + u.Name
}
// AvatarLink returns user gravatar link.
func (u *User) AvatarLink() string {
if setting.DisableGravatar {
return "/img/avatar_default.jpg"
return setting.AppSubUrl + "/img/avatar_default.jpg"
} else if setting.Service.EnableCacheAvatar {
return "/avatar/" + u.Avatar
return setting.AppSubUrl + "/avatar/" + u.Avatar
}
return "//1.gravatar.com/avatar/" + u.Avatar
}
@@ -167,6 +168,14 @@ func (u *User) GetOrganizations() error {
return nil
}
// GetFullNameFallback returns Full Name if set, otherwise username
func (u *User) GetFullNameFallback() string {
if u.FullName == "" {
return u.Name
}
return u.FullName
}
// IsUserExist checks if given user name exist,
// the user name should be noncased unique.
func IsUserExist(name string) (bool, error) {
@@ -505,6 +514,49 @@ func GetUserIdsByNames(names []string) []int64 {
return ids
}
// UserCommit represtns a commit with validation of user.
type UserCommit struct {
UserName string
*git.Commit
}
// ValidateCommitWithEmail chceck if author's e-mail of commit is corresponsind to a user.
func ValidateCommitWithEmail(c *git.Commit) (uname string) {
u, err := GetUserByEmail(c.Author.Email)
if err == nil {
uname = u.Name
}
return uname
}
// ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
emails := map[string]string{}
newCommits := list.New()
e := oldCommits.Front()
for e != nil {
c := e.Value.(*git.Commit)
uname := ""
if v, ok := emails[c.Author.Email]; !ok {
u, err := GetUserByEmail(c.Author.Email)
if err == nil {
uname = u.Name
}
emails[c.Author.Email] = uname
} else {
uname = v
}
newCommits.PushBack(UserCommit{
UserName: uname,
Commit: c,
})
e = e.Next()
}
return newCommits
}
// GetUserByEmail returns the user object by given e-mail if exists.
func GetUserByEmail(email string) (*User, error) {
if len(email) == 0 {
@@ -548,27 +600,27 @@ type Follow struct {
// FollowUser marks someone be another's follower.
func FollowUser(userId int64, followId int64) (err error) {
session := x.NewSession()
defer session.Close()
session.Begin()
sess := x.NewSession()
defer sess.Close()
sess.Begin()
if _, err = session.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil {
session.Rollback()
if _, err = sess.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil {
sess.Rollback()
return err
}
rawSql := "UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?"
if _, err = session.Exec(rawSql, followId); err != nil {
session.Rollback()
if _, err = sess.Exec(rawSql, followId); err != nil {
sess.Rollback()
return err
}
rawSql = "UPDATE `user` SET num_followings = num_followings + 1 WHERE id = ?"
if _, err = session.Exec(rawSql, userId); err != nil {
session.Rollback()
if _, err = sess.Exec(rawSql, userId); err != nil {
sess.Rollback()
return err
}
return session.Commit()
return sess.Commit()
}
// UnFollowUser unmarks someone be another's follower.

View File

@@ -154,8 +154,9 @@ const (
)
type PayloadAuthor struct {
Name string `json:"name"`
Email string `json:"email"`
Name string `json:"name"`
Email string `json:"email"`
UserName string `json:"username"`
}
type PayloadCommit struct {
@@ -172,7 +173,7 @@ type PayloadRepo struct {
Description string `json:"description"`
Website string `json:"website"`
Watchers int `json:"watchers"`
Owner *PayloadAuthor `json:"author"`
Owner *PayloadAuthor `json:"owner"`
Private bool `json:"private"`
}
@@ -234,8 +235,22 @@ func UpdateHookTask(t *HookTask) error {
return err
}
var (
// Prevent duplicate deliveries.
// This happens with massive hook tasks cannot finish delivering
// before next shooting starts.
isShooting = false
)
// DeliverHooks checks and delivers undelivered hooks.
// FIXME: maybe can use goroutine to shoot a number of them at same time?
func DeliverHooks() {
if isShooting {
return
}
isShooting = true
defer func() { isShooting = false }()
tasks := make([]*HookTask, 0, 10)
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask),
@@ -254,7 +269,7 @@ func DeliverHooks() {
t.IsDelivered = true
// TODO: record response.
// FIXME: record response.
switch t.Type {
case GOGS:
{

View File

@@ -102,7 +102,7 @@ func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs *binding.Errors,
// \/ \/ \/
type CreateIssueForm struct {
IssueName string `form:"title" binding:"Required;MaxSize(50)"`
IssueName string `form:"title" binding:"Required;MaxSize(255)"`
MilestoneId int64 `form:"milestoneid"`
AssigneeId int64 `form:"assigneeid"`
Labels string `form:"labels"`

View File

@@ -13,7 +13,9 @@ import (
"regexp"
"strings"
"github.com/gogits/gfm"
"github.com/russross/blackfriday"
"github.com/gogits/gogs/modules/setting"
)
func isletter(c byte) bool {
@@ -73,7 +75,7 @@ func IsReadmeFile(name string) bool {
}
type CustomRender struct {
gfm.Renderer
blackfriday.Renderer
urlPrefix string
}
@@ -112,7 +114,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
ms := MentionPattern.FindAll(line, -1)
for _, m := range ms {
line = bytes.Replace(line, m,
[]byte(fmt.Sprintf(`<a href="/user/%s">%s</a>`, m[1:], m)), -1)
[]byte(fmt.Sprintf(`<a href="%s/user/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
}
}
@@ -153,39 +155,40 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
htmlFlags := 0
// htmlFlags |= gfm.HTML_USE_XHTML
// htmlFlags |= gfm.HTML_USE_SMARTYPANTS
// htmlFlags |= gfm.HTML_SMARTYPANTS_FRACTIONS
// htmlFlags |= gfm.HTML_SMARTYPANTS_LATEX_DASHES
// htmlFlags |= gfm.HTML_SKIP_HTML
htmlFlags |= gfm.HTML_SKIP_STYLE
htmlFlags |= gfm.HTML_SKIP_SCRIPT
htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE
htmlFlags |= gfm.HTML_OMIT_CONTENTS
// htmlFlags |= gfm.HTML_COMPLETE_PAGE
// htmlFlags |= blackfriday.HTML_USE_XHTML
// htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
// htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
// htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
// htmlFlags |= blackfriday.HTML_SKIP_HTML
htmlFlags |= blackfriday.HTML_SKIP_STYLE
// htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
// htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
// htmlFlags |= blackfriday.HTML_COMPLETE_PAGE
renderer := &CustomRender{
Renderer: gfm.HtmlRenderer(htmlFlags, "", ""),
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
urlPrefix: urlPrefix,
}
// set up the parser
extensions := 0
extensions |= gfm.EXTENSION_NO_INTRA_EMPHASIS
extensions |= gfm.EXTENSION_TABLES
extensions |= gfm.EXTENSION_FENCED_CODE
extensions |= gfm.EXTENSION_AUTOLINK
extensions |= gfm.EXTENSION_STRIKETHROUGH
extensions |= gfm.EXTENSION_HARD_LINE_BREAK
extensions |= gfm.EXTENSION_SPACE_HEADERS
extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
extensions |= blackfriday.EXTENSION_TABLES
extensions |= blackfriday.EXTENSION_FENCED_CODE
extensions |= blackfriday.EXTENSION_AUTOLINK
extensions |= blackfriday.EXTENSION_STRIKETHROUGH
extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK
extensions |= blackfriday.EXTENSION_SPACE_HEADERS
extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
body = gfm.Markdown(body, renderer, extensions)
body = blackfriday.Markdown(body, renderer, extensions)
return body
}
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
body := RenderSpecialLink(rawBytes, urlPrefix)
body = RenderRawMarkdown(body, urlPrefix)
body = XSS(body)
return body
}

View File

@@ -8,13 +8,16 @@ import (
"bytes"
"container/list"
"encoding/json"
"errors"
"fmt"
"html/template"
"runtime"
"strings"
"time"
"github.com/gogits/gogs/modules/mahonia"
"github.com/gogits/gogs/modules/setting"
"github.com/saintfish/chardet"
)
func Str2html(raw string) template.HTML {
@@ -45,6 +48,29 @@ func ShortSha(sha1 string) string {
return sha1
}
func ToUtf8WithErr(content []byte) (error, string) {
detector := chardet.NewTextDetector()
result, err := detector.DetectBest(content)
if err != nil {
return err, ""
}
if result.Charset == "utf8" {
return nil, string(content)
}
decoder := mahonia.NewDecoder(result.Charset)
if decoder != nil {
return nil, decoder.ConvertString(string(content))
}
return errors.New("unknow char decoder"), string(content)
}
func ToUtf8(content string) string {
_, res := ToUtf8WithErr([]byte(content))
return res
}
var mailDomains = map[string]string{
"gmail.com": "gmail.com",
}
@@ -56,6 +82,9 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
"AppName": func() string {
return setting.AppName
},
"AppSubUrl": func() string {
return setting.AppSubUrl
},
"AppVer": func() string {
return setting.AppVer
},
@@ -103,6 +132,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
"ActionContent2Commits": ActionContent2Commits,
"Oauth2Icon": Oauth2Icon,
"Oauth2Name": Oauth2Name,
"ToUtf8": ToUtf8,
}
type Actioner interface {
@@ -119,14 +149,12 @@ type Actioner interface {
// and returns a icon class name.
func ActionIcon(opType int) string {
switch opType {
case 1: // Create repository.
case 1, 8: // Create, transfer repository.
return "repo"
case 5, 9: // Commit repository.
return "git-commit"
case 6: // Create issue.
return "issue-opened"
case 8: // Transfer repository.
return "share"
case 10: // Comment issue.
return "comment"
default:
@@ -134,16 +162,16 @@ func ActionIcon(opType int) string {
}
}
// TODO: Legacy
// FIXME: Legacy
const (
TPL_CREATE_REPO = `<a href="/user/%s">%s</a> created repository <a href="/%s">%s</a>`
TPL_COMMIT_REPO = `<a href="/user/%s">%s</a> pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>%s`
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="/%s/commit/%s" rel="nofollow">%s</a> %s</div>`
TPL_CREATE_ISSUE = `<a href="/user/%s">%s</a> opened issue <a href="/%s/issues/%s">%s#%s</a>
TPL_CREATE_REPO = `<a href="%s/user/%s">%s</a> created repository <a href="%s">%s</a>`
TPL_COMMIT_REPO = `<a href="%s/user/%s">%s</a> pushed to <a href="%s/src/%s">%s</a> at <a href="%s">%s</a>%s`
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="%s/commit/%s" rel="nofollow">%s</a> %s</div>`
TPL_CREATE_ISSUE = `<a href="%s/user/%s">%s</a> opened issue <a href="%s/issues/%s">%s#%s</a>
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>`
TPL_TRANSFER_REPO = `<a href="/user/%s">%s</a> transfered repository <code>%s</code> to <a href="/%s">%s</a>`
TPL_PUSH_TAG = `<a href="/user/%s">%s</a> pushed tag <a href="/%s/src/%s" rel="nofollow">%s</a> at <a href="/%s">%s</a>`
TPL_COMMENT_ISSUE = `<a href="/user/%s">%s</a> commented on issue <a href="/%s/issues/%s">%s#%s</a>
TPL_TRANSFER_REPO = `<a href="%s/user/%s">%s</a> transfered repository <code>%s</code> to <a href="%s">%s</a>`
TPL_PUSH_TAG = `<a href="%s/user/%s">%s</a> pushed tag <a href="%s/src/%s" rel="nofollow">%s</a> at <a href="%s">%s</a>`
TPL_COMMENT_ISSUE = `<a href="%s/user/%s">%s</a> commented on issue <a href="%s/issues/%s">%s#%s</a>
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>`
)
@@ -167,7 +195,7 @@ func ActionContent2Commits(act Actioner) *PushCommits {
return push
}
// TODO: Legacy
// FIXME: Legacy
// ActionDesc accepts int that represents action operation type
// and returns the description.
func ActionDesc(act Actioner) string {
@@ -180,7 +208,7 @@ func ActionDesc(act Actioner) string {
content := act.GetContent()
switch act.GetOpType() {
case 1: // Create repository.
return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, repoLink, repoName)
return fmt.Sprintf(TPL_CREATE_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, repoName)
case 5: // Commit repository.
var push *PushCommits
if err := json.Unmarshal([]byte(content), &push); err != nil {
@@ -191,22 +219,22 @@ func ActionDesc(act Actioner) string {
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n")
}
if push.Len > 3 {
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s" rel="nofollow">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
buf.WriteString(fmt.Sprintf(`<div><a href="{{AppRootSubUrl}}/%s/%s/commits/%s" rel="nofollow">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
}
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink,
return fmt.Sprintf(TPL_COMMIT_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink,
buf.String())
case 6: // Create issue.
infos := strings.SplitN(content, "|", 2)
return fmt.Sprintf(TPL_CREATE_ISSUE, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
return fmt.Sprintf(TPL_CREATE_ISSUE, setting.AppSubUrl, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
AvatarLink(email), infos[1])
case 8: // Transfer repository.
newRepoLink := content + "/" + repoName
return fmt.Sprintf(TPL_TRANSFER_REPO, actUserName, actUserName, repoLink, newRepoLink, newRepoLink)
return fmt.Sprintf(TPL_TRANSFER_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, newRepoLink, newRepoLink)
case 9: // Push tag.
return fmt.Sprintf(TPL_PUSH_TAG, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink)
return fmt.Sprintf(TPL_PUSH_TAG, setting.AppSubUrl, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink)
case 10: // Comment issue.
infos := strings.SplitN(content, "|", 2)
return fmt.Sprintf(TPL_COMMENT_ISSUE, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
return fmt.Sprintf(TPL_COMMENT_ISSUE, setting.AppSubUrl, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0],
AvatarLink(email), infos[1])
default:
return "invalid type"

View File

@@ -14,6 +14,7 @@ import (
"hash"
"html/template"
"math"
"regexp"
"strings"
"time"
@@ -146,9 +147,9 @@ func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string
// AvatarLink returns avatar link by given e-mail.
func AvatarLink(email string) string {
if setting.DisableGravatar {
return "/img/avatar_default.jpg"
return setting.AppSubUrl + "/img/avatar_default.jpg"
} else if setting.Service.EnableCacheAvatar {
return "/avatar/" + EncodeMd5(email)
return setting.AppSubUrl + "/avatar/" + EncodeMd5(email)
}
return "//1.gravatar.com/avatar/" + EncodeMd5(email)
}
@@ -446,3 +447,29 @@ func DateFormat(t time.Time, format string) string {
format = replacer.Replace(format)
return t.Format(format)
}
type xssFilter struct {
reg *regexp.Regexp
repl []byte
}
var (
whiteSpace = []byte(" ")
xssFilters = []xssFilter{
{regexp.MustCompile(`\ [ONon]\w*=["]*`), whiteSpace},
{regexp.MustCompile(`<[SCRIPTscript]{6}`), whiteSpace},
{regexp.MustCompile(`=[` + "`" + `'"]*[JAVASCRIPTjavascript \t\0&#x0D;]*:`), whiteSpace},
}
)
// XSS goes through all the XSS filters to make user input content as safe as possible.
func XSS(in []byte) []byte {
for _, filter := range xssFilters {
in = filter.reg.ReplaceAll(in, filter.repl)
}
return in
}
func XSSString(in string) string {
return string(XSS([]byte(in)))
}

View File

@@ -5,6 +5,7 @@
package git
import (
"bufio"
"container/list"
"strings"
)
@@ -17,7 +18,8 @@ type Commit struct {
Committer *Signature
CommitMessage string
parents []sha1 // sha1 strings
parents []sha1 // sha1 strings
submodules map[string]*SubModule
}
// Return the commit message. Same as retrieving CommitMessage directly.
@@ -84,3 +86,49 @@ func (c *Commit) CommitsByRange(page int) (*list.List, error) {
func (c *Commit) GetCommitOfRelPath(relPath string) (*Commit, error) {
return c.repo.getCommitOfRelPath(c.Id, relPath)
}
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
moduels, err := c.GetSubModules()
if err != nil {
return nil, err
}
return moduels[entryname], nil
}
func (c *Commit) GetSubModules() (map[string]*SubModule, error) {
if c.submodules != nil {
return c.submodules, nil
}
entry, err := c.GetTreeEntryByPath(".gitmodules")
if err != nil {
return nil, err
}
rd, err := entry.Blob().Data()
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(rd)
c.submodules = make(map[string]*SubModule)
var ismodule bool
var path string
for scanner.Scan() {
if strings.HasPrefix(scanner.Text(), "[submodule") {
ismodule = true
continue
}
if ismodule {
fields := strings.Split(scanner.Text(), "=")
k := strings.TrimSpace(fields[0])
if k == "path" {
path = strings.TrimSpace(fields[1])
} else if k == "url" {
c.submodules[path] = &SubModule{path, strings.TrimSpace(fields[1])}
ismodule = false
}
}
}
return c.submodules, nil
}

111
modules/git/hooks.go Normal file
View File

@@ -0,0 +1,111 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package git
import (
"errors"
"io/ioutil"
"os"
"path"
"strings"
)
// hookNames is a list of Git hooks' name that are supported.
var hookNames = []string{
"pre-applypatch",
"applypatch-msg",
"prepare-commit-msg",
"commit-msg",
"pre-commit",
"pre-rebase",
"post-commit",
"post-receive",
"post-update",
}
var (
ErrNotValidHook = errors.New("not a valid Git hook")
)
// IsValidHookName returns true if given name is a valid Git hook.
func IsValidHookName(name string) bool {
for _, hn := range hookNames {
if hn == name {
return true
}
}
return false
}
// Hook represents a Git hook.
type Hook struct {
name string
IsActive bool // Indicates whether repository has this hook.
Content string // Content of hook if it's active.
Sample string // Sample content from Git.
path string // Hook file path.
}
// GetHook returns a Git hook by given name and repository.
func GetHook(repoPath, name string) (*Hook, error) {
if !IsValidHookName(name) {
return nil, ErrNotValidHook
}
h := &Hook{
name: name,
path: path.Join(repoPath, "hooks", name),
}
if isFile(h.path) {
data, err := ioutil.ReadFile(h.path)
if err != nil {
return nil, err
}
h.IsActive = true
h.Content = string(data)
} else if isFile(h.path + ".sample") {
data, err := ioutil.ReadFile(h.path + ".sample")
if err != nil {
return nil, err
}
h.Sample = string(data)
}
return h, nil
}
func (h *Hook) Name() string {
return h.name
}
// Update updates hook settings.
func (h *Hook) Update() error {
if len(strings.TrimSpace(h.Content)) == 0 {
return os.Remove(h.path)
}
return ioutil.WriteFile(h.path, []byte(h.Content), os.ModePerm)
}
// ListHooks returns a list of Git hooks of given repository.
func ListHooks(repoPath string) (_ []*Hook, err error) {
if !isDir(path.Join(repoPath, "hooks")) {
return nil, errors.New("hooks path does not exist")
}
hooks := make([]*Hook, len(hookNames))
for i, name := range hookNames {
hooks[i], err = GetHook(repoPath, name)
if err != nil {
return nil, err
}
}
return hooks, nil
}
func (repo *Repository) GetHook(name string) (*Hook, error) {
return GetHook(repo.Path, name)
}
func (repo *Repository) Hooks() ([]*Hook, error) {
return ListHooks(repo.Path)
}

View File

@@ -40,11 +40,11 @@ func (repo *Repository) GetCommitIdOfTag(tagName string) (string, error) {
}
func (repo *Repository) GetCommitOfTag(tagName string) (*Commit, error) {
commitId, err := repo.GetCommitIdOfTag(tagName)
tag, err := repo.GetTag(tagName)
if err != nil {
return nil, err
}
return repo.GetCommit(commitId)
return tag.Commit()
}
// Parse commit information from the (uncompressed) raw
@@ -137,6 +137,14 @@ func (repo *Repository) GetCommit(commitId string) (*Commit, error) {
}
func (repo *Repository) commitsCount(id sha1) (int, error) {
if gitVer.LessThan(MustParseVersion("1.8.0")) {
stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", "--pretty=format:''", id.String())
if err != nil {
return 0, errors.New(string(stderr))
}
return len(bytes.Split(stdout, []byte("\n"))), nil
}
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "rev-list", "--count", id.String())
if err != nil {
return 0, errors.New(stderr)

View File

@@ -22,6 +22,9 @@ func (repo *Repository) IsTagExist(tagName string) bool {
// GetTags returns all tags of given repository.
func (repo *Repository) GetTags() ([]string, error) {
if gitVer.AtLeast(MustParseVersion("2.0.0")) {
return repo.getTagsReversed()
}
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l")
if err != nil {
return nil, errors.New(stderr)
@@ -30,6 +33,15 @@ func (repo *Repository) GetTags() ([]string, error) {
return tags[:len(tags)-1], nil
}
func (repo *Repository) getTagsReversed() ([]string, error) {
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l", "--sort=-v:refname")
if err != nil {
return nil, errors.New(stderr)
}
tags := strings.Split(stdout, "\n")
return tags[:len(tags)-1], nil
}
func (repo *Repository) CreateTag(tagName, idStr string) error {
_, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", tagName, idStr)
if err != nil {
@@ -52,6 +64,7 @@ func (repo *Repository) getTag(id sha1) (*Tag, error) {
if err != nil {
return nil, errors.New(stderr)
}
tp = strings.TrimSpace(tp)
// Tag is a commit.
if ObjectType(tp) == COMMIT {

58
modules/git/submodule.go Normal file
View File

@@ -0,0 +1,58 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package git
import (
"strings"
)
type SubModule struct {
Name string
Url string
}
// SubModuleFile represents a file with submodule type.
type SubModuleFile struct {
*Commit
refUrl string
refId string
}
func NewSubModuleFile(c *Commit, refUrl, refId string) *SubModuleFile {
return &SubModuleFile{
Commit: c,
refUrl: refUrl,
refId: refId,
}
}
// RefUrl guesses and returns reference URL.
func (sf *SubModuleFile) RefUrl() string {
url := strings.TrimSuffix(sf.refUrl, ".git")
// git://xxx/user/repo
if strings.HasPrefix(url, "git://") {
return "http://" + strings.TrimPrefix(url, "git://")
}
// http[s]://xxx/user/repo
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
return url
}
// sysuser@xxx:user/repo
i := strings.Index(url, "@")
j := strings.LastIndex(url, ":")
if i > -1 && j > -1 {
return "http://" + url[i+1:j] + "/" + url[j+1:]
}
return url
}
// RefId returns reference ID.
func (sf *SubModuleFile) RefId() string {
return sf.refId
}

View File

@@ -51,6 +51,8 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
case "160000":
entry.mode = ModeCommit
entry.Type = COMMIT
step = 8
case "040000":
entry.mode = ModeTree
entry.Type = TREE
@@ -107,9 +109,12 @@ func (t *Tree) ListEntries(relpath string) (Entries, error) {
}
t.entriesParsed = true
stdout, _, err := com.ExecCmdDirBytes(t.repo.Path,
stdout, stderr, err := com.ExecCmdDirBytes(t.repo.Path,
"git", "ls-tree", t.Id.String())
if err != nil {
if strings.Contains(err.Error(), "exit status 128") {
return nil, errors.New(strings.TrimSpace(string(stderr)))
}
return nil, err
}
t.entries, err = parseTreeData(t, stdout)

View File

@@ -61,6 +61,10 @@ func (te *TreeEntry) Size() int64 {
return te.size
}
func (te *TreeEntry) IsSubModule() bool {
return te.mode == ModeCommit
}
func (te *TreeEntry) IsDir() bool {
return te.mode == ModeTree
}
@@ -80,7 +84,7 @@ type Entries []*TreeEntry
var sorter = []func(t1, t2 *TreeEntry) bool{
func(t1, t2 *TreeEntry) bool {
return t1.IsDir() && !t2.IsDir()
return (t1.IsDir() || t1.IsSubModule()) && !t2.IsDir() && !t2.IsSubModule()
},
func(t1, t2 *TreeEntry) bool {
return t1.name < t2.name

View File

@@ -7,6 +7,7 @@ package git
import (
"bytes"
"container/list"
"os"
"path/filepath"
"strings"
)
@@ -46,3 +47,23 @@ func RefEndName(refStr string) string {
func filepathFromSHA1(rootdir, sha1 string) string {
return filepath.Join(rootdir, "objects", sha1[:2], sha1[2:])
}
// isDir returns true if given path is a directory,
// or returns false when it's a file or does not exist.
func isDir(dir string) bool {
f, e := os.Stat(dir)
if e != nil {
return false
}
return f.IsDir()
}
// isFile returns true if given path is a file,
// or returns false when it's a directory or does not exist.
func isFile(filePath string) bool {
f, e := os.Stat(filePath)
if e != nil {
return false
}
return !f.IsDir()
}

View File

@@ -11,33 +11,89 @@ import (
"github.com/Unknwon/com"
)
var (
// Cached Git version.
gitVer *Version
)
// Version represents version of Git.
type Version struct {
Major, Minor, Patch int
}
// GetVersion returns current Git version installed.
func GetVersion() (Version, error) {
stdout, stderr, err := com.ExecCmd("git", "version")
if err != nil {
return Version{}, errors.New(stderr)
}
infos := strings.Split(stdout, " ")
func ParseVersion(verStr string) (*Version, error) {
infos := strings.Split(verStr, ".")
if len(infos) < 3 {
return Version{}, errors.New("not enough output")
return nil, errors.New("incorrect version input")
}
v := Version{}
for i, s := range strings.Split(strings.TrimSpace(infos[2]), ".") {
v := &Version{}
for i, s := range infos {
switch i {
case 0:
v.Major, _ = com.StrTo(s).Int()
case 1:
v.Minor, _ = com.StrTo(s).Int()
case 2:
v.Patch, _ = com.StrTo(s).Int()
v.Patch, _ = com.StrTo(strings.TrimSpace(s)).Int()
}
}
return v, nil
}
func MustParseVersion(verStr string) *Version {
v, _ := ParseVersion(verStr)
return v
}
// Compare compares two versions,
// it returns 1 if original is greater, -1 if original is smaller, 0 if equal.
func (v *Version) Compare(that *Version) int {
if v.Major > that.Major {
return 1
} else if v.Major < that.Major {
return -1
}
if v.Minor > that.Minor {
return 1
} else if v.Minor < that.Minor {
return -1
}
if v.Patch > that.Patch {
return 1
} else if v.Patch < that.Patch {
return -1
}
return 0
}
func (v *Version) LessThan(that *Version) bool {
return v.Compare(that) < 0
}
func (v *Version) AtLeast(that *Version) bool {
return v.Compare(that) >= 0
}
// GetVersion returns current Git version installed.
func GetVersion() (*Version, error) {
if gitVer != nil {
return gitVer, nil
}
stdout, stderr, err := com.ExecCmd("git", "version")
if err != nil {
return nil, errors.New(stderr)
}
infos := strings.Split(stdout, " ")
if len(infos) < 3 {
return nil, errors.New("not enough output")
}
gitVer, err = ParseVersion(infos[2])
return gitVer, err
}

View File

@@ -87,6 +87,12 @@ func Fatal(skip int, format string, v ...interface{}) {
os.Exit(1)
}
func Close() {
for _, l := range loggers {
l.Close()
}
}
// .___ __ _____
// | | _____/ |_ ____________/ ____\____ ____ ____
// | |/ \ __\/ __ \_ __ \ __\\__ \ _/ ___\/ __ \

View File

@@ -5,7 +5,9 @@
package mailer
import (
"crypto/tls"
"fmt"
"net"
"net/smtp"
"strings"
@@ -33,7 +35,7 @@ func (m Message) Content() string {
}
// create mail content
content := "From: " + m.From + "<" + m.User +
content := "From: \"" + m.From + "\" <" + m.User +
">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
return content
}
@@ -64,6 +66,53 @@ func processMailQueue() {
}
}
// sendMail allows mail with self-signed certificates.
func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipients []string, msgContent []byte) error {
client, err := smtp.Dial(hostAddressWithPort)
if err != nil {
return err
}
host, _, _ := net.SplitHostPort(hostAddressWithPort)
tlsConn := &tls.Config{
InsecureSkipVerify: true,
ServerName: host,
}
if err = client.StartTLS(tlsConn); err != nil {
return err
}
if auth != nil {
if err = client.Auth(auth); err != nil {
return err
}
}
if err = client.Mail(from); err != nil {
return err
}
for _, rec := range recipients {
if err = client.Rcpt(rec); err != nil {
return err
}
}
w, err := client.Data()
if err != nil {
return err
}
if _, err = w.Write([]byte(msgContent)); err != nil {
return err
}
if err = w.Close(); err != nil {
return err
}
return client.Quit()
}
// Direct Send mail message
func Send(msg *Message) (int, error) {
log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
@@ -85,7 +134,7 @@ func Send(msg *Message) (int, error) {
num := 0
for _, to := range msg.To {
body := []byte("To: " + to + "\r\n" + content)
err := smtp.SendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
err := sendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
if err != nil {
return num, err
}
@@ -96,7 +145,7 @@ func Send(msg *Message) (int, error) {
body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
// send to multiple emails in one message
err := smtp.SendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
err := sendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
if err != nil {
return 0, err
} else {

View File

@@ -25,13 +25,13 @@ func Toggle(options *ToggleOptions) macaron.Handler {
return func(ctx *Context) {
// Cannot view any page before installation.
if !setting.InstallLock {
ctx.Redirect("/install")
ctx.Redirect(setting.AppSubUrl + "/install")
return
}
// Redirect to dashboard if user tries to visit any non-login page.
if options.SignOutRequire && ctx.IsSigned && ctx.Req.RequestURI != "/" {
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
return
}
@@ -48,8 +48,8 @@ func Toggle(options *ToggleOptions) macaron.Handler {
if strings.HasSuffix(ctx.Req.RequestURI, "watch") {
return
}
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
ctx.Redirect("/user/login")
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
} else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")

View File

@@ -9,7 +9,6 @@ import (
"html/template"
"io"
"net/http"
"path"
"strings"
"time"
@@ -30,7 +29,6 @@ import (
// Context represents context of a request.
type Context struct {
*macaron.Context
i18n.Locale
Cache cache.Cache
csrf csrf.CSRF
Flash *session.Flash
@@ -140,23 +138,6 @@ func (ctx *Context) Handle(status int, title string, err error) {
ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
}
func (ctx *Context) ServeFile(file string, names ...string) {
var name string
if len(names) > 0 {
name = names[0]
} else {
name = path.Base(file)
}
ctx.Resp.Header().Set("Content-Description", "File Transfer")
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name)
ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary")
ctx.Resp.Header().Set("Expires", "0")
ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
ctx.Resp.Header().Set("Pragma", "public")
http.ServeFile(ctx.Resp, ctx.Req, file)
}
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
modtime := time.Now()
for _, p := range params {
@@ -180,14 +161,13 @@ func Contexter() macaron.Handler {
return func(c *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) {
ctx := &Context{
Context: c,
Locale: l,
Cache: cache,
csrf: x,
Flash: f,
Session: sess,
}
// Compute current URL for real-time change language.
link := ctx.Req.RequestURI
link := setting.AppSubUrl + ctx.Req.RequestURI
i := strings.Index(link, "?")
if i > -1 {
link = link[:i]

View File

@@ -9,6 +9,7 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
@@ -37,7 +38,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Handle(404, "GetUserByName", err)
} else if redirect {
log.Error(4, "GetUserByName", err)
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "GetUserByName", err)
}
@@ -67,7 +68,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
}
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
ctx.Org.OrgLink = "/org/" + org.Name
ctx.Org.OrgLink = setting.AppSubUrl + "/org/" + org.Name
ctx.Data["OrgLink"] = ctx.Org.OrgLink
// Team.
@@ -79,7 +80,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Handle(404, "GetTeam", err)
} else if redirect {
log.Error(4, "GetTeam", err)
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "GetTeam", err)
}

View File

@@ -60,7 +60,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Handle(404, "GetUserByName", err)
} else if redirect {
log.Error(4, "GetUserByName", err)
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "GetUserByName", err)
}
@@ -72,7 +72,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
if u == nil {
if redirect {
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
return
}
ctx.Handle(404, "RepoAssignment", errors.New("invliad user account for single repository"))
@@ -92,7 +92,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Handle(404, "GetRepositoryByName", err)
return
} else if redirect {
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
return
}
ctx.Handle(500, "GetRepositoryByName", err)
@@ -160,7 +160,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
return
}
ctx.Repo.GitRepo = gitRepo
ctx.Repo.RepoLink = "/" + u.Name + "/" + repo.Name
ctx.Repo.RepoLink = setting.AppSubUrl + "/" + u.Name + "/" + repo.Name
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
tags, err := ctx.Repo.GitRepo.GetTags()
@@ -168,6 +168,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Handle(500, "GetTags", err)
return
}
ctx.Data["Tags"] = tags
ctx.Repo.Repository.NumTags = len(tags)
ctx.Data["Title"] = u.Name + "/" + repo.Name
@@ -199,7 +200,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(refName)
if err != nil {
ctx.Handle(404, "RepoAssignment invalid branch", nil)
ctx.Handle(500, "RepoAssignment invalid branch", err)
return
}
ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
@@ -207,13 +208,11 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
} else if gitRepo.IsTagExist(refName) {
ctx.Repo.IsTag = true
ctx.Repo.BranchName = refName
ctx.Repo.Tag, err = gitRepo.GetTag(refName)
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommitOfTag(refName)
if err != nil {
ctx.Handle(404, "RepoAssignment invalid tag", nil)
ctx.Handle(500, "Fail to get tag commit", err)
return
}
ctx.Repo.Commit, _ = ctx.Repo.Tag.Commit()
ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
} else if len(refName) == 40 {
ctx.Repo.IsCommit = true
@@ -226,7 +225,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
return
}
} else {
ctx.Handle(404, "RepoAssignment invalid repo", errors.New("branch or tag not exist"))
ctx.Handle(404, "RepoAssignment invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
return
}
@@ -247,6 +246,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
}
ctx.Data["IsBranch"] = ctx.Repo.IsBranch
ctx.Data["IsTag"] = ctx.Repo.IsTag
ctx.Data["IsCommit"] = ctx.Repo.IsCommit
ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
@@ -274,7 +274,8 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["TagName"] = ctx.Repo.TagName
brs, err := ctx.Repo.GitRepo.GetBranches()
if err != nil {
log.Error(4, "GetBranches: %v", err)
ctx.Handle(500, "GetBranches", err)
return
}
ctx.Data["Branches"] = brs
ctx.Data["BrancheCount"] = len(brs)
@@ -298,8 +299,8 @@ func RequireTrueOwner() macaron.Handler {
return func(ctx *Context) {
if !ctx.Repo.IsTrueOwner && !ctx.Repo.IsAdmin {
if !ctx.IsSigned {
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
ctx.Redirect("/user/login")
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
}
ctx.Handle(404, ctx.Req.RequestURI, nil)
@@ -307,3 +308,13 @@ func RequireTrueOwner() macaron.Handler {
}
}
}
// GitHookService checks if repsitory Git hooks service has been enabled.
func GitHookService() macaron.Handler {
return func(ctx *Context) {
if !setting.Service.EnableGitHooks {
ctx.Handle(404, "GitHookService", nil)
return
}
}
}

View File

@@ -6,10 +6,12 @@ package setting
import (
"fmt"
"net/url"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strings"
"time"
@@ -30,9 +32,10 @@ const (
var (
// App settings.
AppVer string
AppName string
AppUrl string
AppVer string
AppName string
AppUrl string
AppSubUrl string
// Server settings.
Protocol Scheme
@@ -92,18 +95,24 @@ var (
SessionProvider string
SessionConfig *session.Config
// Git settings.
MaxGitDiffLines int
// I18n settings.
Langs, Names []string
// Global setting objects.
Cfg *goconfig.ConfigFile
ConfRootPath string
CustomPath string // Custom directory path.
ProdMode bool
RunUser string
// I18n settings.
Langs, Names []string
IsWindows bool
HasRobotsTxt bool
)
func init() {
IsWindows = runtime.GOOS == "windows"
log.NewLogger(0, "console", `{"level": 0}`)
}
@@ -159,6 +168,13 @@ func NewConfigContext() {
AppUrl += "/"
}
// Check if has app suburl.
url, err := url.Parse(AppUrl)
if err != nil {
log.Fatal(4, "Invalid ROOT_URL(%s): %s", AppUrl, err)
}
AppSubUrl = strings.TrimSuffix(url.Path, "/")
Protocol = HTTP
if Cfg.MustValue("server", "PROTOCOL") == "https" {
Protocol = HTTPS
@@ -241,8 +257,12 @@ func NewConfigContext() {
[]string{"server"})
DisableGravatar = Cfg.MustBool("picture", "DISABLE_GRAVATAR")
MaxGitDiffLines = Cfg.MustInt("git", "MAX_GITDIFF_LINES", 10000)
Langs = Cfg.MustValueArray("i18n", "LANGS", ",")
Names = Cfg.MustValueArray("i18n", "NAMES", ",")
HasRobotsTxt = com.IsFile(path.Join(CustomPath, "robots.txt"))
}
var Service struct {
@@ -255,6 +275,7 @@ var Service struct {
LdapAuth bool
ActiveCodeLives int
ResetPwdCodeLives int
EnableGitHooks bool
}
func newService() {
@@ -264,6 +285,7 @@ func newService() {
Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW")
Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR")
Service.EnableReverseProxyAuth = Cfg.MustBool("service", "ENABLE_REVERSE_PROXY_AUTHENTICATION")
Service.EnableGitHooks = Cfg.MustBool("service", "ENABLE_GIT_HOOKS")
}
var logLevels = map[string]string{
@@ -363,6 +385,7 @@ func newSessionService() {
SessionConfig = new(session.Config)
SessionConfig.ProviderConfig = strings.Trim(Cfg.MustValue("session", "PROVIDER_CONFIG"), "\" ")
SessionConfig.CookieName = Cfg.MustValue("session", "COOKIE_NAME", "i_like_gogits")
SessionConfig.CookiePath = AppSubUrl
SessionConfig.Secure = Cfg.MustBool("session", "COOKIE_SECURE")
SessionConfig.EnableSetCookie = Cfg.MustBool("session", "ENABLE_SET_COOKIE", true)
SessionConfig.Gclifetime = Cfg.MustInt64("session", "GC_INTERVAL_TIME", 86400)

View File

@@ -20,9 +20,6 @@ APP_USER=$(${CLI} config:get APP_USER)
APP_GROUP=$(${CLI} config:get APP_GROUP)
APP_CONFIG="/etc/${APP_NAME}/conf/app.ini"
# source debconf library
. /usr/share/debconf/confmodule
case "$1" in
configure)

View File

@@ -7,9 +7,6 @@ body {
width: 16px;
text-align: center;
}
.fa {
font-size: 14px;
}
.container {
max-width: 1170px;
padding: 0 1.5em;
@@ -20,6 +17,11 @@ img.avatar-16 {
height: 16px;
vertical-align: middle;
}
img.avatar-20 {
width: 20px;
height: 20px;
vertical-align: middle;
}
img.avatar-24 {
width: 24px;
height: 24px;
@@ -45,6 +47,9 @@ img.avatar-100 {
height: 100px;
vertical-align: middle;
}
.drop-down .panel-header {
font-size: 14px;
}
#wrapper {
padding: 0;
margin: 0 0 -55px 0;
@@ -83,6 +88,7 @@ img.avatar-100 {
z-index: 100;
font-size: 12px;
width: 120%;
min-width: 100px;
}
#footer-lang .drop-down li > a {
padding: 3px 9px;
@@ -294,6 +300,12 @@ img.avatar-100 {
.markdown li:first-child {
margin-top: 0;
}
.markdown code {
padding: 0.2em 0.5em;
margin: 0;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px;
}
.markdown > pre {
font-size: 14px;
line-height: 1.6;
@@ -304,6 +316,10 @@ img.avatar-100 {
padding: 10px;
background-color: #f8f8f8;
}
.markdown > pre code {
padding: 0;
background-color: inherit;
}
.markdown img {
padding: 10px 0;
max-width: 100%;
@@ -686,18 +702,20 @@ ol.linenums {
width: auto;
}
/*
The dashboard page style
The dashboard page style
*/
#dashboard-header {
border-bottom: 1px solid #d6d6d6;
height: 69px;
background-color: #FFF;
}
#dashboard-header > .menu-line > li {
padding: 12px 0;
padding: 12px 6px;
}
#dashboard-header > .menu-line > li.right > a {
font-size: 1.2em;
color: #444444;
padding: .4em .8em;
}
#dashboard-header > .menu-line > li.right > a:hover {
background-color: transparent;
@@ -727,7 +745,7 @@ The dashboard page style
border-top-left-radius: .3em;
border-top-right-radius: .3em;
width: 100%;
height: 35px;
height: 32px;
}
#dashboard-sidebar-menu > li {
border: 1px solid #d6d6d6;
@@ -736,8 +754,8 @@ The dashboard page style
border-bottom: none;
}
#dashboard-sidebar-menu > li > a {
padding-top: .4em;
padding-bottom: .4em;
padding-top: .3em;
padding-bottom: .3em;
}
#dashboard-sidebar-menu > li.first {
border-top-left-radius: .3em;
@@ -805,6 +823,11 @@ The dashboard page style
#dashboard-my-repo .repo-contrib-header {
border-top: 1px solid #d6d6d6;
}
#dashboard-my-mirror .panel-header,
#dashboard-my-org .panel-header,
#dashboard-my-repo .panel-header {
font-size: 14px;
}
#dashboard-my-repo .panel-header .octicon {
margin-right: 6px;
font-size: 12px;
@@ -818,7 +841,7 @@ The dashboard page style
}
#dashboard-new-repo {
width: 50px;
height: 35px;
height: 33px;
padding-top: 6px;
margin-right: 1px;
border-top-left-radius: .3em;
@@ -828,7 +851,7 @@ The dashboard page style
font-size: 2em;
}
#dashboard-new-repo-menu {
top: 35px;
top: 33px;
width: 180px;
background-color: #FFF;
left: -132px;
@@ -878,6 +901,9 @@ The dashboard page style
#dashboard-switch-menu > li.checked > a .octicon {
opacity: 1;
}
#dashboard-news {
padding-bottom: 60px;
}
#dashboard-news .news {
margin-right: 2.4em;
padding-bottom: 1em;
@@ -984,8 +1010,8 @@ The register and sign-in page style
}
#repo-header-meta a > .btn {
line-height: 16px;
font-size: 1.05em;
margin-left: 16px;
font-size: 13px;
}
#repo-header-meta a > .btn i {
margin-right: 6px;
@@ -1030,9 +1056,13 @@ The register and sign-in page style
#repo-content {
padding: 18px 0;
}
.repo-wide-wrapper {
padding: 18px 0;
position: relative;
}
#repo-clone-url {
border-right: none;
width: 200px;
width: 190px;
border-left: none;
}
#repo-clone-help {
@@ -1054,6 +1084,9 @@ The register and sign-in page style
#repo-desc {
font-size: 1.2em;
}
#repo-desc .no-description {
color: #999;
}
#repo-sidebar-nav .label {
font-size: 12px;
line-height: 1.4em;
@@ -1062,6 +1095,37 @@ The register and sign-in page style
#repo-sidebar-nav i {
margin-right: 6px;
}
#repo-sidebar-mini {
margin-top: 6px;
width: 60px;
}
#repo-sidebar-mini li {
margin-bottom: 4px;
}
#repo-sidebar-mini li > a {
position: relative;
padding-left: 12px;
width: 24px;
text-align: center;
}
#repo-sidebar-mini li > a > i.octicon {
font-size: 21px;
}
#repo-sidebar-mini .num {
position: absolute;
font-size: 12px;
top: 0;
left: 36px;
padding: 0 2px;
min-width: 16px;
height: 16px;
text-align: center;
line-height: 16px;
border-radius: 4px;
opacity: 0.7;
-webkit-transform: scale(0.9);
font-weight: bold;
}
#repo-file-nav {
padding: .6em 0 1em 0;
}
@@ -1107,6 +1171,10 @@ The register and sign-in page style
background-color: #EEE;
font-weight: bold;
}
#repo-branch-tag .switching-list {
max-height: 300px;
overflow-y: auto;
}
#repo-branch-list li i,
#repo-tag-list li i {
margin-right: 12px;
@@ -1116,9 +1184,6 @@ The register and sign-in page style
#repo-tag-list li.checked i {
opacity: 1;
}
#repo-tag-list {
display: none;
}
#repo-bread .bread {
padding-right: 0;
font-size: 16px;
@@ -1189,7 +1254,8 @@ The register and sign-in page style
font-weight: normal;
color: #888;
}
#repo-readme {
#repo-readme,
#repo-read-file {
margin-bottom: 80px;
}
#repo-bare-start {
@@ -1396,6 +1462,31 @@ The register and sign-in page style
width: 100%;
list-style: none;
}
#commits-list {
padding-top: 20px;
}
#commits-list h4 {
line-height: 30px;
margin-bottom: 0;
}
.commit-list th {
background-color: #FFF;
line-height: 28px !important;
}
.commit-list .date {
width: 120px;
}
.commit-list .author {
padding-left: 20px;
min-width: 180px;
}
.commit-list .author img {
margin-top: -4px;
}
.commit-list .sha a {
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
font-size: 14px;
}
#admin-wrapper,
#setting-wrapper {
padding-bottom: 100px;
@@ -1559,39 +1650,18 @@ The register and sign-in page style
#user-ssh-add-form .field {
margin-bottom: 24px;
}
.repo-issue-wrapper {
padding: 18px 0;
}
.pr-main {
padding-right: 40px;
box-sizing: border-box;
margin-right: 100px;
}
.pr-sidebar {
border-left: 1px solid #DDD;
box-sizing: border-box;
position: absolute;
right: 0;
top: 12px;
}
#pr-sidebar-nav {
margin-top: 6px;
}
#pr-sidebar-nav li {
margin-bottom: 4px;
}
#pr-sidebar-nav li > a {
border: 1px solid transparent;
border-left: none;
}
#pr-sidebar-nav li > a:hover {
background-color: #FFF;
border-color: #DDD;
}
#pr-sidebar-nav .label {
font-size: 12px;
line-height: 1.4em;
margin-top: 1px;
}
#pr-sidebar-nav li.current a {
background-color: #FFF;
border-color: #DDD;
.pr-title {
padding: 4px 0;
}
.pr-title .pr-num {
font-weight: normal;
@@ -1599,6 +1669,7 @@ The register and sign-in page style
}
.pr-meta {
color: #888;
padding: 4px 0 8px 0;
}
.pr-meta .pr-author {
margin: 0 8px;
@@ -1672,7 +1743,7 @@ The register and sign-in page style
.issue-line,
.issue-merge,
.issue-add-comment {
margin-bottom: 16px;
margin-bottom: 24px;
}
.issue-comment .author-avatar img {
margin-right: 12px;
@@ -1776,6 +1847,7 @@ textarea#issue-add-content {
width: 100%;
box-sizing: border-box;
height: 120px;
resize: vertical;
}
.org-header-alert .alert {
margin-top: 10px;
@@ -1810,7 +1882,10 @@ textarea#issue-add-content {
color: #d9453d;
}
#org-header > div > .menu-line > li.right > a .octicon {
margin-right: 6px;
margin-right: 4px;
}
#org-header > div > .menu-line > li.right > a .label {
margin-left: 4px;
}
#org-header > div > .menu-line > li.right .current {
border-bottom: 2px solid #D26911;
@@ -2009,3 +2084,56 @@ textarea#issue-add-content {
.admin-dl-horizontal > dd {
margin-left: 240px;
}
.profile-avatar {
width: 200px;
height: 200px;
border-radius: 6px;
}
#profile-name {
padding: 10px 0;
}
#profile-fullname {
font-size: 1.6em;
}
#profile-username {
font-size: 1.6em;
font-weight: bold;
}
.profile-info {
padding: 0 50px;
font-size: 14px;
}
.profile-info ul {
padding-bottom: 10px;
}
.profile-info ul .list-group-item {
background-color: transparent;
padding-top: 5px;
color: #666;
}
.profile-info ul .profile-rel {
width: 31%;
text-align: center;
display: inline-block;
}
.profile-info ul .profile-rel strong {
display: block;
font-size: 28px;
font-weight: bold;
line-height: 1;
}
.profile-info ul .profile-rel p {
font-size: 12px;
}
#profile-header li a {
font-size: 1.2em;
color: #444444;
padding: .4em .8em;
}
#profile-header li a:hover {
background-color: transparent;
color: #d9453d;
}
#profile-header li .current {
border-bottom: 2px solid #D26911;
}

View File

@@ -0,0 +1,368 @@
/* Magnific Popup CSS */
.mfp-bg {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1042;
overflow: hidden;
position: fixed;
background: #0b0b0b;
opacity: 0.8;
filter: alpha(opacity=80); }
.mfp-wrap {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1043;
position: fixed;
outline: none !important;
-webkit-backface-visibility: hidden; }
.mfp-container {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 8px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.mfp-container:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle; }
.mfp-align-top .mfp-container:before {
display: none; }
.mfp-content {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 0 auto;
text-align: left;
z-index: 1045; }
.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
width: 100%;
cursor: auto; }
.mfp-ajax-cur {
cursor: progress; }
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
cursor: -moz-zoom-out;
cursor: -webkit-zoom-out;
cursor: zoom-out; }
.mfp-zoom {
cursor: pointer;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in; }
.mfp-auto-cursor .mfp-content {
cursor: auto; }
.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none; }
.mfp-loading.mfp-figure {
display: none; }
.mfp-hide {
display: none !important; }
.mfp-preloader {
color: #cccccc;
position: absolute;
top: 50%;
width: auto;
text-align: center;
margin-top: -0.8em;
left: 8px;
right: 8px;
z-index: 1044; }
.mfp-preloader a {
color: #cccccc; }
.mfp-preloader a:hover {
color: white; }
.mfp-s-ready .mfp-preloader {
display: none; }
.mfp-s-error .mfp-content {
display: none; }
button.mfp-close, button.mfp-arrow {
overflow: visible;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
display: block;
outline: none;
padding: 0;
z-index: 1046;
-webkit-box-shadow: none;
box-shadow: none; }
button::-moz-focus-inner {
padding: 0;
border: 0; }
.mfp-close {
width: 44px;
height: 44px;
line-height: 44px;
position: absolute;
right: 0;
top: 0;
text-decoration: none;
text-align: center;
opacity: 0.65;
filter: alpha(opacity=65);
padding: 0 0 18px 10px;
color: white;
font-style: normal;
font-size: 28px;
font-family: Arial, Baskerville, monospace; }
.mfp-close:hover, .mfp-close:focus {
opacity: 1;
filter: alpha(opacity=100); }
.mfp-close:active {
top: 1px; }
.mfp-close-btn-in .mfp-close {
color: #333333; }
.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
color: white;
right: -6px;
text-align: right;
padding-right: 6px;
width: 100%; }
.mfp-counter {
position: absolute;
top: 0;
right: 0;
color: #cccccc;
font-size: 12px;
line-height: 18px; }
.mfp-arrow {
position: absolute;
opacity: 0.65;
filter: alpha(opacity=65);
margin: 0;
top: 50%;
margin-top: -55px;
padding: 0;
width: 90px;
height: 110px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
.mfp-arrow:active {
margin-top: -54px; }
.mfp-arrow:hover, .mfp-arrow:focus {
opacity: 1;
filter: alpha(opacity=100); }
.mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
left: 0;
top: 0;
margin-top: 35px;
margin-left: 35px;
border: medium inset transparent; }
.mfp-arrow:after, .mfp-arrow .mfp-a {
border-top-width: 13px;
border-bottom-width: 13px;
top: 8px; }
.mfp-arrow:before, .mfp-arrow .mfp-b {
border-top-width: 21px;
border-bottom-width: 21px;
opacity: 0.7; }
.mfp-arrow-left {
left: 0; }
.mfp-arrow-left:after, .mfp-arrow-left .mfp-a {
border-right: 17px solid white;
margin-left: 31px; }
.mfp-arrow-left:before, .mfp-arrow-left .mfp-b {
margin-left: 25px;
border-right: 27px solid #3f3f3f; }
.mfp-arrow-right {
right: 0; }
.mfp-arrow-right:after, .mfp-arrow-right .mfp-a {
border-left: 17px solid white;
margin-left: 39px; }
.mfp-arrow-right:before, .mfp-arrow-right .mfp-b {
border-left: 27px solid #3f3f3f; }
.mfp-iframe-holder {
padding-top: 40px;
padding-bottom: 40px; }
.mfp-iframe-holder .mfp-content {
line-height: 0;
width: 100%;
max-width: 900px; }
.mfp-iframe-holder .mfp-close {
top: -40px; }
.mfp-iframe-scaler {
width: 100%;
height: 0;
overflow: hidden;
padding-top: 56.25%; }
.mfp-iframe-scaler iframe {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: black; }
/* Main image in popup */
img.mfp-img {
width: auto;
max-width: 100%;
height: auto;
display: block;
line-height: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 40px 0 40px;
margin: 0 auto; }
/* The shadow behind the image */
.mfp-figure {
line-height: 0; }
.mfp-figure:after {
content: '';
position: absolute;
left: 0;
top: 40px;
bottom: 40px;
display: block;
right: 0;
width: auto;
height: auto;
z-index: -1;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #444444; }
.mfp-figure small {
color: #bdbdbd;
display: block;
font-size: 12px;
line-height: 14px; }
.mfp-figure figure {
margin: 0; }
.mfp-bottom-bar {
margin-top: -36px;
position: absolute;
top: 100%;
left: 0;
width: 100%;
cursor: auto; }
.mfp-title {
text-align: left;
line-height: 18px;
color: #f3f3f3;
word-wrap: break-word;
padding-right: 36px; }
.mfp-image-holder .mfp-content {
max-width: 100%; }
.mfp-gallery .mfp-image-holder .mfp-figure {
cursor: pointer; }
@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
/**
* Remove all paddings around the image on small screen
*/
.mfp-img-mobile .mfp-image-holder {
padding-left: 0;
padding-right: 0; }
.mfp-img-mobile img.mfp-img {
padding: 0; }
.mfp-img-mobile .mfp-figure:after {
top: 0;
bottom: 0; }
.mfp-img-mobile .mfp-figure small {
display: inline;
margin-left: 5px; }
.mfp-img-mobile .mfp-bottom-bar {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
margin: 0;
top: auto;
padding: 3px 5px;
position: fixed;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.mfp-img-mobile .mfp-bottom-bar:empty {
padding: 0; }
.mfp-img-mobile .mfp-counter {
right: 5px;
top: 3px; }
.mfp-img-mobile .mfp-close {
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
background: rgba(0, 0, 0, 0.6);
position: fixed;
text-align: center;
padding: 0; } }
@media all and (max-width: 900px) {
.mfp-arrow {
-webkit-transform: scale(0.75);
transform: scale(0.75); }
.mfp-arrow-left {
-webkit-transform-origin: 0;
transform-origin: 0; }
.mfp-arrow-right {
-webkit-transform-origin: 100%;
transform-origin: 100%; }
.mfp-container {
padding-left: 6px;
padding-right: 6px; } }
.mfp-ie7 .mfp-img {
padding: 0; }
.mfp-ie7 .mfp-bottom-bar {
width: 600px;
left: 50%;
margin-left: -300px;
margin-top: 5px;
padding-bottom: 5px; }
.mfp-ie7 .mfp-container {
padding: 0; }
.mfp-ie7 .mfp-content {
padding-top: 44px; }
.mfp-ie7 .mfp-close {
top: 0;
right: 0;
padding-top: 0; }

25
public/ng/css/tipsy.css Normal file
View File

@@ -0,0 +1,25 @@
.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
.tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
/* Rounded corners */
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
/* Uncomment for shadow */
/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
/* Rules to colour arrows */
.tipsy-arrow-n { border-bottom-color: #000; }
.tipsy-arrow-s { border-top-color: #000; }
.tipsy-arrow-e { border-left-color: #000; }
.tipsy-arrow-w { border-right-color: #000; }
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }

View File

@@ -277,9 +277,6 @@ hr {
border-bottom: 1px solid #dddddd;
margin-bottom: .75em;
}
p code {
color: #b63b2c;
}
.radius {
border-radius: .25em;
}
@@ -483,6 +480,10 @@ dt {
.ipt-large {
font-size: 14.4px;
}
.ipt-textarea {
height: auto !important;
width: auto;
}
.ipt-disabled,
input[disabled] {
background-color: #f2f2f2 !important;
@@ -735,6 +736,10 @@ ul.menu-radius > li:last-child > a {
.label-green {
background-color: #65ad4e;
}
.label-green:hover {
background-color: #71bf57;
color: #FFF;
}
.label-orange {
background-color: #df7514;
}
@@ -795,6 +800,17 @@ ul.menu-radius > li:last-child > a {
border: 1px solid #b05c10;
background-color: #fcecdd;
}
.white-popup-block {
background: #FFF;
padding: 20px 30px;
text-align: left;
max-width: 650px;
margin: 40px auto;
position: relative;
}
.white-popup-block p {
font-size: 14px;
}
table th,
table td {
padding: .3em .6em;

View File

@@ -14,22 +14,20 @@
.mega-octicon is optimized for 32px but can be used larger.
*/
.octicon {
font: normal normal 16px octicons;
line-height: 1;
display: inline-block;
text-decoration: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.mega-octicon {
font: normal normal 32px octicons;
line-height: 1;
.octicon, .mega-octicon {
font: normal normal normal 16px/1 octicons;
display: inline-block;
text-decoration: none;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.mega-octicon { font-size: 32px; }
.octicon-alert:before { content: '\f02d'} /*  */
.octicon-alignment-align:before { content: '\f08a'} /*  */

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,8 @@
// @codekit-prepend "lib/jquery-1.11.1.min.js"
// @codekit-prepend "lib/lib.js"
// @codekit-prepend "lib/tabs.js"
// @codekit-prepend "utils/tabs.js"
// @codekit-prepend "utils/preview.js"
// @codekit-prepend "lib/jquery.tipsy.js"
var Gogs = {};
@@ -202,7 +204,7 @@ var Gogs = {};
// Search users by keyword.
Gogs.searchUsers = function (val, $target) {
$.ajax({
url: '/api/v1/users/search?q=' + val,
url: Gogs.AppSubUrl + '/api/v1/users/search?q=' + val,
dataType: "json",
success: function (json) {
if (json.ok && json.data.length) {
@@ -222,7 +224,7 @@ var Gogs = {};
// Search repositories by keyword.
Gogs.searchRepos = function (val, $target, $param) {
$.ajax({
url: '/api/v1/repos/search?q=' + val + '&' + $param,
url: Gogs.AppSubUrl + '/api/v1/repos/search?q=' + val + '&' + $param,
dataType: "json",
success: function (json) {
if (json.ok && json.data.length) {
@@ -245,7 +247,7 @@ var Gogs = {};
return;
}
$(selector).zclip({
path: "/js/ZeroClipboard.swf",
path: Gogs.AppSubUrl + "/js/ZeroClipboard.swf",
copy: function () {
var t = $(this).data("copy-val");
var to = $($(this).data("copy-from"));
@@ -262,17 +264,14 @@ var Gogs = {};
return str;
},
afterCopy: function () {
alert("Clone URL has copied!");
// var $this = $(this);
// $this.tooltip('hide')
// .attr('data-original-title', 'Copied OK');
// setTimeout(function () {
// $this.tooltip("show");
// }, 200);
// setTimeout(function () {
// $this.tooltip('hide')
// .attr('data-original-title', 'Copy to Clipboard');
// }, 3000);
var $this = $(this);
$this.tipsy("hide").attr('original-title', $this.data('after-title'));
setTimeout(function () {
$this.tipsy("show");
}, 200);
setTimeout(function () {
$this.tipsy('hide').attr('original-title', $this.data('original-title'));
}, 2000);
}
}).addClass("js-copy-bind");
}
@@ -281,17 +280,51 @@ var Gogs = {};
function initCore() {
Gogs.renderMarkdown();
Gogs.renderCodeView();
// Switch list.
$('.js-tab-nav').click(function (e) {
if (!$(this).hasClass('js-tab-nav-show')) {
$(this).parent().find('.js-tab-nav-show').each(function () {
$(this).removeClass('js-tab-nav-show');
$($(this).data('tab-target')).hide();
});
$(this).addClass('js-tab-nav-show');
$($(this).data('tab-target')).show();
}
e.preventDefault();
});
// Popup.
$(document).on('click', '.popup-modal-dismiss', function (e) {
e.preventDefault();
$.magnificPopup.close();
});
}
function initUserSetting() {
// Confirmation of change username in user profile page.
$('#user-profile-form').submit(function (e) {
var $username = $('#username');
if (($username.data('uname') != $username.val()) && !confirm('Username has been changed, do you want to continue?')) {
var $username = $('#username');
var $profile_form = $('#user-profile-form');
$('#change-username-btn').magnificPopup({
modal: true,
callbacks: {
open: function () {
if (($username.data('uname') == $username.val())) {
$.magnificPopup.close();
$profile_form.submit();
}
}
}
}).click(function () {
if (($username.data('uname') != $username.val())) {
e.preventDefault();
return true;
}
});
$('#change-username-submit').click(function () {
$.magnificPopup.close();
$profile_form.submit();
});
// Show add SSH key panel.
$('#ssh-add').click(function () {
@@ -299,11 +332,15 @@ function initUserSetting() {
});
// Confirmation of delete account.
$('#delete-account-button').click(function (e) {
if (!confirm('This account is going to be deleted, do you want to continue?')) {
e.preventDefault();
return true;
}
$('#delete-account-btn').magnificPopup({
modal: true
}).click(function (e) {
e.preventDefault();
return true;
});
$('#delete-account-submit').click(function () {
$.magnificPopup.close();
$('#delete-account-form').submit();
});
}
@@ -343,48 +380,79 @@ function initRepo() {
$('#repo-clone-url').val($(this).data('link'));
$('.clone-url').text($(this).data('link'))
});
// Copy URL.
$('#repo-clone-copy').hover(function () {
var $clone_btn = $('#repo-clone-copy');
$clone_btn.hover(function () {
Gogs.bindCopy($(this));
})
$clone_btn.tipsy({
fade: true
});
}
// when user changes hook type, hide/show proper divs
function initHookTypeChange() {
// web hook type change
$('select#hook-type').on("change", function () {
hookTypes = ['Gogs','Slack'];
hookTypes = ['Gogs', 'Slack'];
var curHook = $(this).val();
hookTypes.forEach(function(hookType) {
if (curHook === hookType) {
$('div#'+hookType.toLowerCase()).toggleShow();
}
else {
$('div#'+hookType.toLowerCase()).toggleHide();
}
});
var curHook = $(this).val();
hookTypes.forEach(function (hookType) {
if (curHook === hookType) {
$('div#' + hookType.toLowerCase()).toggleShow();
}
else {
$('div#' + hookType.toLowerCase()).toggleHide();
}
});
});
}
function initRepoSetting() {
// Options.
// Confirmation of changing repository name.
$('#repo-setting-form').submit(function (e) {
var $reponame = $('#repo_name');
if (($reponame.data('repo-name') != $reponame.val()) && !confirm('Repository name has been changed, do you want to continue?')) {
var $reponame = $('#repo_name');
var $setting_form = $('#repo-setting-form');
$('#change-reponame-btn').magnificPopup({
modal: true,
callbacks: {
open: function () {
if (($reponame.data('repo-name') == $reponame.val())) {
$.magnificPopup.close();
$setting_form.submit();
}
}
}
}).click(function () {
if (($reponame.data('repo-name') != $reponame.val())) {
e.preventDefault();
return true;
}
});
$('#change-reponame-submit').click(function () {
$.magnificPopup.close();
$setting_form.submit();
});
initHookTypeChange();
$('#transfer-button').click(function () {
$('#transfer-form').show();
// Transfer repository.
$('#transfer-repo-btn').magnificPopup({
modal: true
});
$('#delete-button').click(function () {
$('#delete-form').show();
$('#transfer-repo-submit').click(function () {
$.magnificPopup.close();
$('#transfer-repo-form').submit();
});
// Delete repository.
$('#delete-repo-btn').magnificPopup({
modal: true
});
$('#delete-repo-submit').click(function () {
$.magnificPopup.close();
$('#delete-repo-form').submit();
});
// Collaboration.
@@ -412,19 +480,39 @@ function initRepoSetting() {
function initOrgSetting() {
// Options.
// Confirmation of changing organization name.
$('#org-setting-form').submit(function (e) {
var $orgname = $('#orgname');
if (($orgname.data('orgname') != $orgname.val()) && !confirm('Organization name has been changed, do you want to continue?')) {
var $orgname = $('#orgname');
var $setting_form = $('#org-setting-form');
$('#change-orgname-btn').magnificPopup({
modal: true,
callbacks: {
open: function () {
if (($orgname.data('orgname') == $orgname.val())) {
$.magnificPopup.close();
$setting_form.submit();
}
}
}
}).click(function () {
if (($orgname.data('orgname') != $orgname.val())) {
e.preventDefault();
return true;
}
});
$('#change-orgname-submit').click(function () {
$.magnificPopup.close();
$setting_form.submit();
});
// Confirmation of delete organization.
$('#delete-org-button').click(function (e) {
if (!confirm('This organization is going to be deleted, do you want to continue?')) {
e.preventDefault();
return true;
}
$('#delete-org-btn').magnificPopup({
modal: true
}).click(function (e) {
e.preventDefault();
return true;
});
$('#delete-org-submit').click(function () {
$.magnificPopup.close();
$('#delete-org-form').submit();
});
initHookTypeChange();
@@ -454,11 +542,14 @@ function initInvite() {
function initOrgTeamCreate() {
// Delete team.
$('#org-team-delete').click(function (e) {
if (!confirm('This team is going to be deleted, do you want to continue?')) {
e.preventDefault();
return true;
}
$('#org-team-delete').magnificPopup({
modal: true
}).click(function (e) {
e.preventDefault();
return true;
});
$('#delete-team-submit').click(function () {
$.magnificPopup.close();
var $form = $('#team-create-form');
$form.attr('action', $form.data('delete-url'));
});
@@ -522,15 +613,20 @@ function initAdmin() {
$('.auth-name').toggleShow();
}
});
// Delete account.
$('#user-delete').click(function (e) {
if (!confirm('This account is going to be deleted, do you want to continue?')) {
e.preventDefault();
return true;
}
$('#delete-account-btn').magnificPopup({
modal: true
}).click(function (e) {
e.preventDefault();
return true;
});
$('#delete-account-submit').click(function () {
$.magnificPopup.close();
var $form = $('#user-profile-form');
$form.attr('action', $form.data('delete-url'));
});
// Create authorization.
$('#auth-type').on("change", function () {
var v = $(this).val();
@@ -543,13 +639,17 @@ function initAdmin() {
$('.ldap').toggleHide();
}
});
// Delete authorization.
$('#auth-delete').click(function (e) {
if (!confirm('This authorization is going to be deleted, do you want to continue?')) {
e.preventDefault();
return true;
}
var $form = $('auth-setting-form');
$('#delete-auth-btn').magnificPopup({
modal: true
}).click(function (e) {
e.preventDefault();
return true;
});
$('#delete-auth-submit').click(function () {
$.magnificPopup.close();
var $form = $('#auth-setting-form');
$form.attr('action', $form.data('delete-url'));
});
}
@@ -591,7 +691,15 @@ function initInstall() {
}());
}
function initProfile() {
// Avatar.
$('#profile-avatar').tipsy({
fade: true
});
}
$(document).ready(function () {
Gogs.AppSubUrl = $('head').data('suburl') || '';
initCore();
if ($('#user-profile-setting').length) {
initUserSetting();
@@ -626,8 +734,12 @@ $(document).ready(function () {
if ($('#install-form').length) {
initInstall();
}
if ($('#user-profile-page').length) {
initProfile();
}
Tabs('#dashboard-sidebar-menu');
$('#dashboard-sidebar-menu').tabs();
$('#pull-issue-preview').markdown_preview(".issue-add-comment");
homepage();
@@ -644,7 +756,7 @@ function homepage() {
$('#promo-form').submit(function (e) {
if ($('#username').val() === "") {
e.preventDefault();
window.location.href = '/user/login';
window.location.href = Gogs.AppSubUrl + '/user/login';
return true
}
});
@@ -652,9 +764,9 @@ function homepage() {
$('#register-button').click(function (e) {
if ($('#username').val() === "") {
e.preventDefault();
window.location.href = '/user/sign_up';
window.location.href = Gogs.AppSubUrl + '/user/sign_up';
return true
}
$('#promo-form').attr('action', '/user/sign_up');
$('#promo-form').attr('action', Gogs.AppSubUrl + '/user/sign_up');
});
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,258 @@
// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// released under the MIT license
(function($) {
function maybeCall(thing, ctx) {
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
};
function isElementInDOM(ele) {
while (ele = ele.parentNode) {
if (ele == document) return true;
}
return false;
};
function Tipsy(element, options) {
this.$element = $(element);
this.options = options;
this.enabled = true;
this.fixTitle();
};
Tipsy.prototype = {
show: function() {
var title = this.getTitle();
if (title && this.enabled) {
var $tip = this.tip();
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
var pos = $.extend({}, this.$element.offset(), {
width: this.$element[0].offsetWidth,
height: this.$element[0].offsetHeight
});
var actualWidth = $tip[0].offsetWidth,
actualHeight = $tip[0].offsetHeight,
gravity = maybeCall(this.options.gravity, this.$element[0]);
var tp;
switch (gravity.charAt(0)) {
case 'n':
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
break;
case 's':
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
break;
case 'e':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
break;
case 'w':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
break;
}
if (gravity.length == 2) {
if (gravity.charAt(1) == 'w') {
tp.left = pos.left + pos.width / 2 - 15;
} else {
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
}
}
$tip.css(tp).addClass('tipsy-' + gravity);
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
if (this.options.className) {
$tip.addClass(maybeCall(this.options.className, this.$element[0]));
}
if (this.options.fade) {
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
} else {
$tip.css({visibility: 'visible', opacity: this.options.opacity});
}
}
},
hide: function() {
if (this.options.fade) {
this.tip().stop().fadeOut(function() { $(this).remove(); });
} else {
this.tip().remove();
}
},
fixTitle: function() {
var $e = this.$element;
if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
$e.attr('original-title', $e.attr('title') || '').removeAttr('title');
}
},
getTitle: function() {
var title, $e = this.$element, o = this.options;
this.fixTitle();
var title, o = this.options;
if (typeof o.title == 'string') {
title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
} else if (typeof o.title == 'function') {
title = o.title.call($e[0]);
}
title = ('' + title).replace(/(^\s*|\s*$)/, "");
return title || o.fallback;
},
tip: function() {
if (!this.$tip) {
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
this.$tip.data('tipsy-pointee', this.$element[0]);
}
return this.$tip;
},
validate: function() {
if (!this.$element[0].parentNode) {
this.hide();
this.$element = null;
this.options = null;
}
},
enable: function() { this.enabled = true; },
disable: function() { this.enabled = false; },
toggleEnabled: function() { this.enabled = !this.enabled; }
};
$.fn.tipsy = function(options) {
if (options === true) {
return this.data('tipsy');
} else if (typeof options == 'string') {
var tipsy = this.data('tipsy');
if (tipsy) tipsy[options]();
return this;
}
options = $.extend({}, $.fn.tipsy.defaults, options);
function get(ele) {
var tipsy = $.data(ele, 'tipsy');
if (!tipsy) {
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
$.data(ele, 'tipsy', tipsy);
}
return tipsy;
}
function enter() {
var tipsy = get(this);
tipsy.hoverState = 'in';
if (options.delayIn == 0) {
tipsy.show();
} else {
tipsy.fixTitle();
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
}
};
function leave() {
var tipsy = get(this);
tipsy.hoverState = 'out';
if (options.delayOut == 0) {
tipsy.hide();
} else {
setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
}
};
if (!options.live) this.each(function() { get(this); });
if (options.trigger != 'manual') {
var binder = options.live ? 'live' : 'bind',
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
this[binder](eventIn, enter)[binder](eventOut, leave);
}
return this;
};
$.fn.tipsy.defaults = {
className: null,
delayIn: 0,
delayOut: 0,
fade: false,
fallback: '',
gravity: 'n',
html: false,
live: false,
offset: 0,
opacity: 0.8,
title: 'title',
trigger: 'hover'
};
$.fn.tipsy.revalidate = function() {
$('.tipsy').each(function() {
var pointee = $.data(this, 'tipsy-pointee');
if (!pointee || !isElementInDOM(pointee)) {
$(this).remove();
}
});
};
// Overwrite this method to provide options on a per-element basis.
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
// (remember - do not modify 'options' in place!)
$.fn.tipsy.elementOptions = function(ele, options) {
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
};
$.fn.tipsy.autoNS = function() {
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
};
$.fn.tipsy.autoWE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
};
/**
* yields a closure of the supplied parameters, producing a function that takes
* no arguments and is suitable for use as an autogravity function like so:
*
* @param margin (int) - distance from the viewable region edge that an
* element should be before setting its tooltip's gravity to be away
* from that edge.
* @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
* if there are no viewable region edges effecting the tooltip's
* gravity. It will try to vary from this minimally, for example,
* if 'sw' is preferred and an element is near the right viewable
* region edge, but not the top edge, it will set the gravity for
* that element's tooltip to be 'se', preserving the southern
* component.
*/
$.fn.tipsy.autoBounds = function(margin, prefer) {
return function() {
var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
boundTop = $(document).scrollTop() + margin,
boundLeft = $(document).scrollLeft() + margin,
$this = $(this);
if ($this.offset().top < boundTop) dir.ns = 'n';
if ($this.offset().left < boundLeft) dir.ew = 'w';
if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
return dir.ns + (dir.ew ? dir.ew : '');
}
};
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,53 @@
/**
* preview plugin
* @param selector
* @param target_selector
*/
function Preview(selector, target_selector) {
// get input element
function get_input($e) {
return $e.find(".js-preview-input").eq(0);
}
// get result html container element
function get_container($t) {
if ($t.hasClass("js-preview-container")) {
return $t
}
return $t.find(".js-preview-container").eq(0);
}
var $e = $(selector);
var $t = $(target_selector);
var $ipt = get_input($t);
if (!$ipt.length) {
console.log("[preview]: no preview input");
return
}
var $cnt = get_container($t);
if (!$cnt.length) {
console.log("[preview]: no preview container");
return
}
// call api via ajax
$e.on("click", function () {
$.post("/api/v1/markdown", {
text: $ipt.val()
}, function (html) {
$cnt.html(html);
})
});
console.log("[preview]: init preview @", selector, "&", target_selector);
}
$.fn.extend({
markdown_preview: function (target) {
Preview(this, target);
}
});

View File

@@ -1,7 +1,6 @@
/**
* Created by fuxiaohei on 14-6-26.
/*
js tabs and tabbed content plugin
*/
function Tabs(selector) {
function hide($nav) {
@@ -24,7 +23,8 @@ function Tabs(selector) {
$($current.data("tab-target")).addClass("js-tab-show");
}
// bind nav click
$e.on("click", ".js-tab-nav", function () {
$e.on("click", ".js-tab-nav", function (e) {
e.preventDefault();
var $this = $(this);
// is showing, not change.
if ($this.hasClass("js-tab-nav-show")) {
@@ -36,4 +36,10 @@ function Tabs(selector) {
});
console.log("init tabs @", selector)
}
}
}
$.fn.extend({
tabs: function () {
Tabs(this);
}
});

View File

@@ -7,4 +7,5 @@
@import "gogs/settings";
@import "gogs/issue";
@import "gogs/organization";
@import "gogs/admin";
@import "gogs/admin";
@import "gogs/profile";

View File

@@ -17,9 +17,6 @@ body {
width: 16px;
text-align: center;
}
.fa {
font-size: 14px;
}
.container {
max-width: 1170px;
padding: 0 1.5em;
@@ -30,6 +27,11 @@ img.avatar-16 {
height: 16px;
vertical-align: middle;
}
img.avatar-20 {
width: 20px;
height: 20px;
vertical-align: middle;
}
img.avatar-24 {
width: 24px;
height: 24px;
@@ -55,6 +57,11 @@ img.avatar-100{
height: 100px;
vertical-align: middle;
}
.drop-down{
.panel-header{
font-size: 14px;
}
}
#wrapper {
padding: 0;
margin: 0 0 -55px 0;
@@ -95,6 +102,7 @@ clear: both;
z-index: 100;
font-size: 12px;
width: 120%;
min-width: 100px;
li > a {
padding: 3px 9px;
}

View File

@@ -1,9 +1,7 @@
@import "../ui/var";
/*
The dashboard page style
The dashboard page style
*/
@dashboardHeaderBorderColor: #D6D6D6;
@dashboardHeaderLinkColor: #444;
@dashboardHeaderLinkHoverColor: #D9453D;
@@ -14,14 +12,16 @@ The dashboard page style
#dashboard-header {
border-bottom: 1px solid @dashboardHeaderBorderColor;
height: 69px;
background-color: #FFF;
> .menu-line {
> li {
padding: 12px 0;
padding: 12px 6px;
}
> li.right {
> a {
font-size: 1.2em;
color: @dashboardHeaderLinkColor;
padding: .4em .8em;
&:hover {
background-color: transparent;
color: @dashboardHeaderLinkHoverColor;
@@ -36,18 +36,15 @@ The dashboard page style
}
}
}
// dashboard context switch selection
#dashboard-selection-menu {
a img {
margin: -4px 10px 0 0;
}
}
#dashboard {
padding: 24px 0;
}
// dashboard sidebar contains contributed repositories panel,
// and my repositories panel
#dashboard-sidebar {
@@ -60,7 +57,6 @@ The dashboard page style
border-bottom-right-radius: .3em;
}
}
#dashboard-sidebar-menu {
border-top-left-radius: .3em;
border-top-right-radius: .3em;
@@ -70,8 +66,8 @@ The dashboard page style
margin-right: -1px;
border-bottom: none;
> a {
padding-top: .4em;
padding-bottom: .4em;
padding-top: .3em;
padding-bottom: .3em;
}
}
> li.first {
@@ -85,7 +81,7 @@ The dashboard page style
float: right;
}
width: 100%;
height: 35px;
height: 32px;
> li.js-tab-nav-show {
background-color: #EEEEEE;
}
@@ -96,7 +92,6 @@ The dashboard page style
}
}
}
#dashboard-my-mirror,
#dashboard-my-org,
#dashboard-my-repo {
@@ -131,8 +126,10 @@ The dashboard page style
.repo-contrib-header {
border-top: 1px solid #d6d6d6;
}
.panel-header{
font-size: 14px;
}
}
#dashboard-my-repo {
.panel-header {
.octicon {
@@ -144,16 +141,14 @@ The dashboard page style
margin-left: 4px;
}
}
#dashboard-my-org,
#dashboard-my-mirror {
display: none;
}
// the button of new repository in my repositories panel
#dashboard-new-repo {
width: 50px;
height: 35px;
height: 33px;
padding-top: 6px;
margin-right: 1px;
.octicon {
@@ -162,10 +157,9 @@ The dashboard page style
border-top-left-radius: .3em;
border-top-right-radius: .3em;
}
// the drop-down menu of #dashboard-new-repo
#dashboard-new-repo-menu {
top: 35px;
top: 33px;
width: 180px;
background-color: #FFF;
left: -132px;
@@ -174,28 +168,26 @@ The dashboard page style
font-size: 1.1em;
}
}
#dashboard-selection-menu {
width: auto;
max-width: 300px;
> .drop-down {
top: 56px;
width: auto;
max-width: 300px;
> .drop-down {
top: 56px;
}
li {
white-space: nowrap;
&.checked {
.octicon {
opacity: 1;
}
}
li {
white-space: nowrap;
&.checked {
.octicon {
opacity: 1;
}
}
a {
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
a {
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
}
}
// the drop-down menu of #dashboard-selection-menu
#dashboard-switch-menu {
> li {
@@ -228,8 +220,8 @@ The dashboard page style
border-bottom-left-radius: .3em;
border-bottom-right-radius: .3em;
}
#dashboard-news {
padding-bottom: 60px;
.news {
margin-right: 2.4em;
.mega-octicon {

View File

@@ -1,54 +1,26 @@
@import "../ui/var";
.repo-issue-wrapper {
padding: 18px 0;
}
// pull request main content
.pr-main {
padding-right: 40px;
box-sizing: border-box;
margin-right: 100px;
}
// right bar in pull request page
.pr-sidebar {
border-left: 1px solid #DDD;
box-sizing: border-box;
position: absolute;
right: 0;
top: 12px;
}
#pr-sidebar-nav {
margin-top: 6px;
li {
margin-bottom: 4px;
}
li > a {
border: 1px solid transparent;
border-left: none;
&:hover {
background-color: #FFF;
border-color: #DDD;
}
}
.label {
font-size: 12px;
line-height: 1.4em;
margin-top: 1px;
}
li.current {
a {
background-color: #FFF;
border-color: #DDD;
}
}
}
.pr-title {
.pr-num {
font-weight: normal;
color: #888;
}
padding: 4px 0;
}
.pr-meta {
color: #888;
padding: 4px 0 8px 0;
.pr-author {
margin: 0 8px;
color: #444;
@@ -62,7 +34,6 @@
padding: 4px 6px;
}
}
.pr-nav {
border-bottom: 1px solid #DDD;
margin-top: 16px;
@@ -89,7 +60,6 @@
}
}
}
.diff-bar {
.diff-add {
color: @btnGreenColor;
@@ -114,26 +84,22 @@
border-bottom-left-radius: .2em;
}
}
#pr-commit,
#pr-file-diff,
#issue-add-comment-preview {
display: none;
}
#pr-conversation-list {
padding-right: 30px;
box-sizing: border-box;
}
.issue-comment,
.issue-commit,
.issue-line,
.issue-merge,
.issue-add-comment {
margin-bottom: 16px;
margin-bottom: 24px;
}
.issue-comment {
.author-avatar {
img {
@@ -165,7 +131,6 @@
}
}
}
.issue-commit {
line-height: 32px;
i, .author-avatar img {
@@ -181,7 +146,6 @@
line-height: 24px;
}
}
.issue-merge {
.ico {
width: 40px;
@@ -202,7 +166,6 @@
font-size: 13px;
}
}
.issue-merge-ok {
.ico {
background-color: #65AD4E;
@@ -217,12 +180,10 @@
color: darken(#65AD4E, 10%);
}
}
.issue-line {
height: 4px;
background-color: #E6E6E6;
}
.issue-add-comment {
.panel {
margin-left: 60px;
@@ -254,9 +215,9 @@
}
}
}
textarea#issue-add-content {
width: 100%;
box-sizing: border-box;
height: 120px;
resize: vertical;
}

View File

@@ -26,7 +26,13 @@
margin-top: 0;
}
}
> pre {
code {
padding: 0.2em 0.5em;
margin: 0;
background-color: rgba(0,0,0,0.04);
border-radius: 3px;
}
>pre {
font-size: 14px;
line-height: 1.6;
overflow: auto;
@@ -35,6 +41,10 @@
margin: 5px 0;
padding: 10px;
background-color: #f8f8f8;
code {
padding: 0;
background-color: inherit;
}
}
img {
padding: 10px 0;

View File

@@ -1,229 +1,232 @@
@import "../ui/var";
.org-header-alert .alert {
margin-top: 10px;
margin-top: 10px;
}
.org-header {
padding: 16px 0;
background-color: #FFF;
border-bottom: 1px solid #DDD;
img {
padding-right: 10px;
}
padding: 16px 0;
background-color: #FFF;
border-bottom: 1px solid #DDD;
img {
padding-right: 10px;
}
}
#org-home-header {
min-height: 100px;
min-height: 100px;
}
#org-header {
height: 48px;
.org-name {
padding-left: 10px;
font-size: 1.4em;
height: 50px;
line-height: 50px;
margin-bottom: 0;
}
> div {
> .menu-line {
> li {
&.right {
> a {
font-size: 1.2em;
color: @dashboardHeaderLinkColor;
&:hover {
background-color: transparent;
color: @dashboardHeaderLinkHoverColor;
}
.octicon {
margin-right: 6px;
}
}
.current {
border-bottom: 2px solid #D26911;
}
}
}
}
}
height: 48px;
.org-name {
padding-left: 10px;
font-size: 1.4em;
height: 50px;
line-height: 50px;
margin-bottom: 0;
}
> div {
> .menu-line {
> li {
&.right {
> a {
font-size: 1.2em;
color: @dashboardHeaderLinkColor;
&:hover {
background-color: transparent;
color: @dashboardHeaderLinkHoverColor;
}
.octicon {
margin-right: 4px;
}
.label{
margin-left: 4px;
}
}
.current {
border-bottom: 2px solid #D26911;
}
}
}
}
}
}
#org-home-header-info {
padding-top: 10px;
h2 {
font-size: 30px;
}
ul {
list-style: none;
li {
float: left;
padding-right: 5px;
}
}
padding-top: 10px;
h2 {
font-size: 30px;
}
ul {
list-style: none;
li {
float: left;
padding-right: 5px;
}
}
}
#org-home-repo-list {
padding: 10px 0;
padding: 10px 0;
}
#org-repo-list {
padding: 10px 0;
.org-repo-item {
border-top: 1px solid #eee;
padding: 30px 20px;
.org-repo-status {
list-style: none;
color: #888;
li {
float: left;
margin-right: 6px;
}
}
h2 {
margin-bottom: 5px;
}
.org-repo-description {
margin: 0;
font-size: 14px;
color: #666;
}
.org-repo-updated {
font-size: 12px;
display: block;
margin: 5px 0 0;
color: #808080;
}
}
padding: 10px 0;
.org-repo-item {
border-top: 1px solid #eee;
padding: 30px 20px;
.org-repo-status {
list-style: none;
color: #888;
li {
float: left;
margin-right: 6px;
}
}
h2 {
margin-bottom: 5px;
}
.org-repo-description {
margin: 0;
font-size: 14px;
color: #666;
}
.org-repo-updated {
font-size: 12px;
display: block;
margin: 5px 0 0;
color: #808080;
}
}
}
.org-sidebar {
margin: -80px 0 0 20px;
.panel-footer {
padding: .8em 1.2em;
}
.member-avatar-group {
padding: 15px;
img {
width: 59px;
height: 59px;
border-radius: 3px;
}
}
margin: -80px 0 0 20px;
.panel-footer {
padding: .8em 1.2em;
}
.member-avatar-group {
padding: 15px;
img {
width: 59px;
height: 59px;
border-radius: 3px;
}
}
}
#org-home-team-list {
padding: 0 15px;
ul {
list-style: none;
padding-top: 10px;
li {
padding: 10px 0;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: 0;
}
}
}
padding: 0 15px;
ul {
list-style: none;
padding-top: 10px;
li {
padding: 10px 0;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: 0;
}
}
}
}
.team-name {
display: block;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.team-meta {
margin-top: 0;
margin-bottom: 0;
color: #777;
margin-top: 0;
margin-bottom: 0;
color: #777;
}
.org-toolbar {
padding: 10px 0;
border-bottom: 1px solid #eee;
padding: 10px 0;
border-bottom: 1px solid #eee;
}
#org-member-list {
.org-member-item {
height: 50px;
line-height: 50px;
border-bottom: 1px solid #eee;
padding: 15px 20px;
.member-name {
padding-left: 15px;
}
ul {
list-style: none;
li {
text-align: center;
display: inline-block;
}
}
}
.org-member-item {
height: 50px;
line-height: 50px;
border-bottom: 1px solid #eee;
padding: 15px 20px;
.member-name {
padding-left: 15px;
}
ul {
list-style: none;
li {
text-align: center;
display: inline-block;
}
}
}
}
.invite-box {
padding: 50px 0;
min-height: 130px;
margin: 0 auto;
width: 50%;
input {
width: 300px;
}
padding: 50px 0;
min-height: 130px;
margin: 0 auto;
width: 50%;
input {
width: 300px;
}
}
#org-member-list-block {
padding-top: 2px;
padding-top: 2px;
}
.org-team-list {
.org-team-list-item {
float: left;
padding: 15px;
width: 555px;
.member-avatar-group {
padding: 5px 15px;
img {
width: 38px;
height: 38px;
border-radius: 3px;
}
}
}
.org-team-list-item {
float: left;
padding: 15px;
width: 555px;
.member-avatar-group {
padding: 5px 15px;
img {
width: 38px;
height: 38px;
border-radius: 3px;
}
}
}
}
#team-create-form {
.note {
margin-left: 153px;
}
.note {
margin-left: 153px;
}
}
#org-team-card {
.desc {
font-size: 14px;
padding: 10px 20px;
}
.team-stats {
padding: 0 20px 10px 20px;
text-transform: uppercase;
border-bottom: 1px solid #dddddd;
}
.panel-footer {
padding: 10px 20px;
}
.desc {
font-size: 14px;
padding: 10px 20px;
}
.team-stats {
padding: 0 20px 10px 20px;
text-transform: uppercase;
border-bottom: 1px solid #dddddd;
}
.panel-footer {
padding: 10px 20px;
}
}
#team-repositories-list,
#team-members-list {
.panel-body .search {
padding: 4px 0 10px 10px;
border-bottom: 1px solid #dddddd;
}
li {
&.collab {
padding-top: 10px !important;
border-bottom: 1px solid #dddddd;
}
&:last-child {
border-bottom: 0 !important;
}
}
.panel-body .search {
padding: 4px 0 10px 10px;
border-bottom: 1px solid #dddddd;
}
li {
&.collab {
padding-top: 10px !important;
border-bottom: 1px solid #dddddd;
}
&:last-child {
border-bottom: 0 !important;
}
}
}
#team-repositories-list {
li {
a .octicon {
color: #888;
}
.member {
color: @linkColor;
font-size: 14px;
height: 40px;
line-height: 40px;
}
}
li {
a .octicon {
color: #888;
}
.member {
color: @linkColor;
font-size: 14px;
height: 40px;
line-height: 40px;
}
}
}

View File

@@ -0,0 +1,57 @@
.profile-avatar {
width: 200px;
height: 200px;
border-radius: 6px;
}
#profile-name {
padding: 10px 0;
}
#profile-fullname {
font-size: 1.6em;
}
#profile-username {
font-size: 1.6em;
font-weight: bold;
}
.profile-info {
padding: 0 50px;
font-size: 14px;
ul {
padding-bottom: 10px;
.list-group-item {
background-color: transparent;
padding-top: 5px;
color: #666;
}
.profile-rel {
width: 31%;
text-align: center;
display: inline-block;
strong {
display: block;
font-size: 28px;
font-weight: bold;
line-height: 1;
}
p {
font-size: 12px;
}
}
}
}
#profile-header {
li {
a {
font-size: 1.2em;
color: #444444;
padding: .4em .8em;
&:hover {
background-color: transparent;
color: @dashboardHeaderLinkHoverColor;
}
}
.current {
border-bottom: 2px solid #D26911;
}
}
}

View File

@@ -6,460 +6,525 @@
/* repository main */
#repo-wrapper {
padding-bottom: 100px;
padding-bottom: 100px;
}
#repo-header {
height: 69px;
border-bottom: 1px solid@repoHeaderBorderColor;
background-color: @repoHeaderBgColor;
height: 69px;
border-bottom: 1px solid@repoHeaderBorderColor;
background-color: @repoHeaderBgColor;
}
#repo-header-name {
line-height: 66px;
color: @repoHeaderNameColor;
font-size: 1.6em;
font-weight: normal;
margin-bottom: 0;
i {
margin-right: 12px;
vertical-align: middle;
}
.divider {
margin: 0 4px;
}
line-height: 66px;
color: @repoHeaderNameColor;
font-size: 1.6em;
font-weight: normal;
margin-bottom: 0;
i {
margin-right: 12px;
vertical-align: middle;
}
.divider {
margin: 0 4px;
}
}
#repo-header-meta {
line-height: 66px;
li {
> a {
padding: 0;
&:hover {
background-color: transparent;
}
}
}
a {
&>.btn {
line-height: 16px;
font-size: 1.05em;
margin-left: 16px;
i {
margin-right: 6px;
}
.num {
margin-left: 6px;
}
}
}
line-height: 66px;
li {
> a {
padding: 0;
&:hover {
background-color: transparent;
}
}
}
a {
& > .btn {
line-height: 16px;
margin-left: 16px;
font-size: 13px;
i {
margin-right: 6px;
}
.num {
margin-left: 6px;
}
}
}
}
#repo-header-download-btn {
> .btn > i {
margin-right: 0 !important;
}
&:hover {
&:after, .btn {
background-color: @btnHoverBlackColor;
color: #FFF;
}
}
&:after {
background-color: @btnBlackColor;
padding: 9px 16px 8px 0;
margin-left: -8px !important;
color: #FFF;
border-top: 1px solid@btnBlackColor;
border-bottom: 1px solid@btnBlackColor;
border-top-right-radius: .25em;
border-bottom-right-radius: .25em;
}
> .btn > i {
margin-right: 0 !important;
}
&:hover {
&:after, .btn {
background-color: @btnHoverBlackColor;
color: #FFF;
}
}
&:after {
background-color: @btnBlackColor;
padding: 9px 16px 8px 0;
margin-left: -8px !important;
color: #FFF;
border-top: 1px solid@btnBlackColor;
border-bottom: 1px solid@btnBlackColor;
border-top-right-radius: .25em;
border-bottom-right-radius: .25em;
}
}
#repo-header-download-drop {
line-height: 24px;
width: 440px;
top: 50px;
left: -370px;
padding: 20px;
box-sizing: border-box;
z-index: 1;
.btn > i {
margin-right: 6px;
}
button,
input {
font-size: 11px;
}
line-height: 24px;
width: 440px;
top: 50px;
left: -370px;
padding: 20px;
box-sizing: border-box;
z-index: 1;
.btn > i {
margin-right: 6px;
}
button,
input {
font-size: 11px;
}
}
#repo-content {
padding: 18px 0;
padding: 18px 0;
}
.repo-wide-wrapper {
padding: 18px 0;
position: relative;
}
#repo-clone-url {
border-right: none;
width: 200px;
border-left: none;
border-right: none;
width: 190px;
border-left: none;
}
#repo-clone-help {
clear: both;
line-height: 48px;
clear: both;
line-height: 48px;
}
#repo-clone-zip {
line-height: 48px;
a {
cursor: pointer;
color: white;
overflow: visible;
padding: .6em 1.2em;
}
.btn {
margin: 0 6px;
}
line-height: 48px;
a {
cursor: pointer;
color: white;
overflow: visible;
padding: .6em 1.2em;
}
.btn {
margin: 0 6px;
}
}
#repo-desc {
font-size: 1.2em;
font-size: 1.2em;
.no-description{
color: #999;
}
}
#repo-sidebar-nav {
.label {
font-size: 12px;
line-height: 1.4em;
margin-top: 2px;
}
i {
margin-right: 6px;
}
.label {
font-size: 12px;
line-height: 1.4em;
margin-top: 2px;
}
i {
margin-right: 6px;
}
}
#repo-sidebar-mini {
margin-top: 6px;
width: 60px;
li {
margin-bottom: 4px;
}
li > a {
position: relative;
padding-left: 12px;
width: 24px;
text-align: center;
> i.octicon {
font-size: 21px;
}
}
.num {
position: absolute;
font-size: 12px;
top: 0;
left: 36px;
padding: 0 2px;
min-width: 16px;
height: 16px;
text-align: center;
line-height: 16px;
border-radius: 4px;
opacity: 0.7;
-webkit-transform: scale(0.9);
font-weight: bold;
}
}
#repo-file-nav {
padding: .6em 0 1em 0;
> li > a {
padding-left: 0;
&:hover {
background-color: transparent;
}
}
li.repo-jump > a {
padding-right: 0;
.btn {
margin-left: -1px;
}
}
padding: .6em 0 1em 0;
> li > a {
padding-left: 0;
&:hover {
background-color: transparent;
}
}
li.repo-jump > a {
padding-right: 0;
.btn {
margin-left: -1px;
}
}
}
#repo-branch-switch {
> a {
.btn {
padding-right: 30px;
}
&:after {
position: absolute;
top: 12px;
right: 30px;
margin-left: 0;
color: @baseFontColor;
> a {
.btn {
padding-right: 30px;
}
&:after {
position: absolute;
top: 12px;
right: 30px;
margin-left: 0;
color: @baseFontColor;
}
}
> .drop-down {
top: 40px;
left: 0;
}
}
}
> .drop-down {
top: 40px;
left: 0;
}
}
#repo-branch-filter-ipt {
width: 100%;
border-left: none;
border-right: none;
box-sizing: border-box;
width: 100%;
border-left: none;
border-right: none;
box-sizing: border-box;
}
#repo-branch-tag {
.tab-nav {
border-bottom: 1px solid #EAEAEA;
a {
padding: .3em .8em;
}
.js-tab-nav-show {
background-color: #EEE;
font-weight: bold;
}
}
.tab-nav {
border-bottom: 1px solid #EAEAEA;
a {
padding: .3em .8em;
}
.js-tab-nav-show {
background-color: #EEE;
font-weight: bold;
}
}
.switching-list {
max-height: 300px;
overflow-y: auto;
}
}
#repo-branch-list,
#repo-tag-list {
li {
i {
margin-right: 12px;
opacity: 0;
}
}
li.checked {
i {
opacity: 1;
}
}
}
#repo-tag-list {
display: none;
li {
i {
margin-right: 12px;
opacity: 0;
}
}
li.checked {
i {
opacity: 1;
}
}
}
#repo-bread {
.bread {
padding-right: 0;
font-size: 16px;
font-weight: bold;
}
.bread {
padding-right: 0;
font-size: 16px;
font-weight: bold;
}
}
#repo-main {
padding-right: 40px;
box-sizing: border-box;
padding-right: 40px;
box-sizing: border-box;
}
#repo-files-table {
margin-bottom: 20px;
th, td {
text-align: left;
line-height: 32px;
}
td.icon {
width: 16px;
padding-right: .1em;
padding-left: 1em;
}
td.name {
max-width: 120px;
.text-truncate {
max-width: 100%;
}
}
td.age {
max-width: 120px;
text-align: right;
}
td.msg {
max-width: 440px;
.text-truncate {
max-width: 100%;
}
}
td.age,
td.size,
td.msg a {
color: #888;
}
td.msg a:hover {
color: #428BCA;
text-decoration: underline;
}
tbody {
background-color: #FFF;
tr:hover {
background-color: #ffffEE;
}
}
thead {
background-color: #F0F0F0;
.author {
a {
margin: 0 .4em;
}
}
.last-commit {
strong {
color: #444;
}
.text-truncate {
margin-left: .4em;
}
}
.last-commit .text-truncate,
.age {
font-weight: normal;
color: #888;
}
}
margin-bottom: 20px;
th, td {
text-align: left;
line-height: 32px;
}
td.icon {
width: 16px;
padding-right: .1em;
padding-left: 1em;
}
td.name {
max-width: 120px;
.text-truncate {
max-width: 100%;
}
}
td.age {
max-width: 120px;
text-align: right;
}
td.msg {
max-width: 440px;
.text-truncate {
max-width: 100%;
}
}
td.age,
td.size,
td.msg a {
color: #888;
}
td.msg a:hover {
color: #428BCA;
text-decoration: underline;
}
tbody {
background-color: #FFF;
tr:hover {
background-color: #ffffEE;
}
}
thead {
background-color: #F0F0F0;
.author {
a {
margin: 0 .4em;
}
}
.last-commit {
strong {
color: #444;
}
.text-truncate {
margin-left: .4em;
}
}
.last-commit .text-truncate,
.age {
font-weight: normal;
color: #888;
}
}
}
#repo-readme {
margin-bottom: 80px;
#repo-readme,
#repo-read-file {
margin-bottom: 80px;
}
#repo-bare-start {
margin-bottom: 100px;
.panel-content {
background-color: #FFF;
}
pre {
margin: 0 40px;
padding: 6px 10px;
border: 1px solid #ddd;
background: #f8f8f8;
}
margin-bottom: 100px;
.panel-content {
background-color: #FFF;
}
pre {
margin: 0 40px;
padding: 6px 10px;
border: 1px solid #ddd;
background: #f8f8f8;
}
}
.repo-bare {
#repo-bare-start {
h2 {
margin-top: 30px;
margin-bottom: 24px;
}
}
#repo-header-meta {
display: none;
}
#repo-clone-ssh {
margin-left: 200px;
}
#repo-clone-copy {
margin-right: 200px;
}
#repo-clone-help {
clear: both;
width: 100%;
}
#repo-clone-url {
width: 520px;
}
#repo-bare-start {
h2 {
margin-top: 30px;
margin-bottom: 24px;
}
}
#repo-header-meta {
display: none;
}
#repo-clone-ssh {
margin-left: 200px;
}
#repo-clone-copy {
margin-right: 200px;
}
#repo-clone-help {
clear: both;
width: 100%;
}
#repo-clone-url {
width: 520px;
}
}
/* repository create */
#team-create-form,
#repo-migrate-form,
#repo-create-form {
width: 800px;
margin: 60px auto auto auto;
background: white;
h2 {
margin: .5em 1em;
}
.field {
margin: 1.2em 0 2em 0;
}
.ipt {
width: 540px;
}
textarea {
height: 120px;
}
.avatar {
vertical-align: middle;
margin-right: .6em;
width: 28px;
height: 28px;
}
&:hover {
box-shadow: 0px 0px 6px #CCC;
}
width: 800px;
margin: 60px auto auto auto;
background: white;
h2 {
margin: .5em 1em;
}
.field {
margin: 1.2em 0 2em 0;
}
.ipt {
width: 540px;
}
textarea {
height: 120px;
}
.avatar {
vertical-align: middle;
margin-right: .6em;
width: 28px;
height: 28px;
}
&:hover {
box-shadow: 0px 0px 6px #CCC;
}
}
#repo-create-cancel {
margin-left: 4em;
margin-left: 4em;
}
#repo-create-owner-list {
top: 30px;
left: 0;
width: auto;
max-width: 300px;
.octicon {
margin-right: 12px;
opacity: 0;
}
.avatar {
width: 20px;
height: 20px;
}
li {
white-space: nowrap;
&.checked {
.octicon {
opacity: 1;
}
}
a {
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
}
top: 30px;
left: 0;
width: auto;
max-width: 300px;
.octicon {
margin-right: 12px;
opacity: 0;
}
.avatar {
width: 20px;
height: 20px;
}
li {
white-space: nowrap;
&.checked {
.octicon {
opacity: 1;
}
}
a {
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
}
}
.file-name {
margin-left: 1em;
margin-left: 1em;
}
.file-size {
font-size: 13px;
color: #888;
margin-left: 1em;
font-size: 13px;
color: #888;
margin-left: 1em;
}
.code-view {
overflow: auto;
overflow-x: auto;
overflow-y: hidden;
background: white;
.view-raw {
min-height: 40px;
text-align: center;
padding-top: 20px;
.btn {
font-size: 1.05em;
line-height: 16px;
padding: 6px 8px;
}
}
table {
width: 100%;
td {
padding: 0;
}
}
.lines-num {
vertical-align: top;
text-align: right;
color: #999;
background: #f5f5f5;
width: 1%;
span {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
line-height: 18px;
padding: 0 8px 0 10px;
cursor: pointer;
display: block;
margin-top: 2px;
font-size: 12px;
}
}
.lines-code > pre {
border: none;
border-left: 1px solid #ddd;
> ol.linenums > li {
padding: 0 10px;
&.active {
background: #ffffdd;
}
}
}
overflow: auto;
overflow-x: auto;
overflow-y: hidden;
background: white;
.view-raw {
min-height: 40px;
text-align: center;
padding-top: 20px;
.btn {
font-size: 1.05em;
line-height: 16px;
padding: 6px 8px;
}
}
table {
width: 100%;
td {
padding: 0;
}
}
.lines-num {
vertical-align: top;
text-align: right;
color: #999;
background: #f5f5f5;
width: 1%;
span {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
line-height: 18px;
padding: 0 8px 0 10px;
cursor: pointer;
display: block;
margin-top: 2px;
font-size: 12px;
}
}
.lines-code > pre {
border: none;
border-left: 1px solid #ddd;
> ol.linenums > li {
padding: 0 10px;
&.active {
background: #ffffdd;
}
}
}
}
.repo-setting-zone {
padding: 30px;
padding: 30px;
}
#team-repositories-list,
#team-members-list,
#repo-collab-list {
list-style: none;
padding: 10px 0 5px 0;
li.collab {
clear: both;
height: 50px;
padding: 0 15px 0 15px;
}
a.member {
color: #444;
height: 50px;
line-height: 50px;
&:hover {
color: #4183C4;
}
}
.avatar {
margin-right: 1em;
width: 40px;
}
.remove-collab {
color: #DD4B39;
}
list-style: none;
padding: 10px 0 5px 0;
li.collab {
clear: both;
height: 50px;
padding: 0 15px 0 15px;
}
a.member {
color: #444;
height: 50px;
line-height: 50px;
&:hover {
color: #4183C4;
}
}
.avatar {
margin-right: 1em;
width: 40px;
}
.remove-collab {
color: #DD4B39;
}
}
.repo-user-list-block {
position: relative;
top: 5px;
position: relative;
top: 5px;
}
.setting-list {
width: 100%;
list-style: none;
width: 100%;
list-style: none;
}
#commits-list {
padding-top: 20px;
h4{
line-height: 30px;
margin-bottom: 0;
}
}
.commit-list {
th {
background-color: #FFF;
line-height: 28px !important;
}
.date {
width: 120px;
}
.author {
padding-left: 20px;
min-width: 180px;
img {
margin-top: -4px;
}
}
.sha a {
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
font-size: 14px;
}
}

View File

@@ -41,7 +41,15 @@
border: 1px solid darken(@alertOrangeColor,10%);
background-color: lighten(@alertOrangeColor,45%);
}
.white-popup-block {
background: #FFF;
padding: 20px 30px;
text-align: left;
max-width: 650px;
margin: 40px auto;
position: relative;
p {
font-size: 14px;
}
}

View File

@@ -116,25 +116,24 @@
}
// input form elements
.ipt {
&:focus {
border-color: @iptFocusBorderColor;
}
&:focus {
border-color: @iptFocusBorderColor;
}
}
.ipt-radius {
border-radius: .25em;
border-radius: .25em;
}
.ipt-small {
font-size: .8*@baseFontSize;
font-size: .8*@baseFontSize;
}
.ipt-large {
font-size: 1.2*@baseFontSize;
font-size: 1.2*@baseFontSize;
}
.ipt-textarea {
height: auto !important;
width: auto;
}
.ipt-disabled,
input[disabled] {
background-color: @iptDisabledColor !important;
@@ -144,14 +143,12 @@ input[disabled] {
color: #888;
cursor: not-allowed;
}
.ipt-readonly,
input[readonly] {
&:focus {
background-color: @iptDisabledColor !important;
}
}
.ipt-error {
border-color: @iptErrorBorderColor !important;
background-color: @iptErrorFocusColor !important;

View File

@@ -16,11 +16,13 @@
.label-gray {
background-color: @labelGrayColor;
}
.label-green {
background-color: @labelGreenColor;
background-color: @labelGreenColor;
&:hover {
background-color: @btnHoverGreenColor;
color: #FFF;
}
}
.label-orange {
background-color: @labelOrangeColor;
}

View File

@@ -193,22 +193,19 @@ code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
font-family: monospace, monospace;
font-size: 1em;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}
.list-no-style {
list-style: none;
}
@@ -342,15 +339,6 @@ hr {
border-bottom: 1px solid @hrColor;
margin-bottom: .75em;
}
// code element
p {
code {
color: @inlineCodeColor;
}
}
// radius element
.radius {

View File

@@ -143,7 +143,7 @@ func Dashboard(ctx *middleware.Context) {
} else {
ctx.Flash.Success(success)
}
ctx.Redirect("/admin")
ctx.Redirect(setting.AppSubUrl + "/admin")
return
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -99,7 +100,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
}
log.Trace("Authentication created by admin(%s): %s", ctx.User.Name, form.AuthName)
ctx.Redirect("/admin/auths")
ctx.Redirect(setting.AppSubUrl + "/admin/auths")
}
func EditAuthSource(ctx *middleware.Context) {
@@ -180,7 +181,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
log.Trace("Authentication changed by admin(%s): %s", ctx.User.Name, form.AuthName)
ctx.Flash.Success(ctx.Tr("admin.auths.update_success"))
ctx.Redirect("/admin/auths/" + ctx.Params(":authid"))
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"))
}
func DeleteAuthSource(ctx *middleware.Context) {
@@ -200,12 +201,12 @@ func DeleteAuthSource(ctx *middleware.Context) {
switch err {
case models.ErrAuthenticationUserUsed:
ctx.Flash.Error("form.still_own_user")
ctx.Redirect("/admin/auths/" + ctx.Params(":authid"))
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"))
default:
ctx.Handle(500, "DelLoginSource", err)
}
return
}
log.Trace("Authentication deleted by admin(%s): %s", ctx.User.Name, a.Name)
ctx.Redirect("/admin/auths")
ctx.Redirect(setting.AppSubUrl + "/admin/auths")
}

46
routers/admin/notice.go Normal file
View File

@@ -0,0 +1,46 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package admin
import (
"github.com/Unknwon/com"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
)
const (
NOTICES base.TplName = "admin/notice"
)
func Notices(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("admin.notices")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminNotices"] = true
pageNum := 50
p := pagination(ctx, models.CountNotices(), pageNum)
notices, err := models.GetNotices(pageNum, (p-1)*pageNum)
if err != nil {
ctx.Handle(500, "GetNotices", err)
return
}
ctx.Data["Notices"] = notices
ctx.HTML(200, NOTICES)
}
func DeleteNotice(ctx *middleware.Context) {
id := com.StrTo(ctx.Params(":id")).MustInt64()
if err := models.DeleteNotice(id); err != nil {
ctx.Handle(500, "DeleteNotice", err)
return
}
log.Trace("System notice deleted by admin(%s): %d", ctx.User.Name, id)
ctx.Flash.Success(ctx.Tr("admin.notices.delete_success"))
ctx.Redirect("/admin/notices")
}

View File

@@ -25,7 +25,7 @@ func Organizations(ctx *middleware.Context) {
var err error
ctx.Data["Orgs"], err = models.GetOrganizations(pageNum, (p-1)*pageNum)
if err != nil {
ctx.Handle(500, "GetUsers", err)
ctx.Handle(500, "GetOrganizations", err)
return
}
ctx.HTML(200, ORGS)

View File

@@ -14,6 +14,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -23,14 +24,14 @@ const (
)
func pagination(ctx *middleware.Context, count int64, pageNum int) int {
p := com.StrTo(ctx.Query("p")).MustInt()
p := ctx.QueryInt("p")
if p < 1 {
p = 1
}
curCount := int64((p-1)*pageNum + pageNum)
if curCount > count {
if curCount >= count {
p = int(count) / pageNum
} else if count > curCount {
} else {
ctx.Data["NextPageNum"] = p + 1
}
if p > 1 {
@@ -47,12 +48,12 @@ func Users(ctx *middleware.Context) {
pageNum := 50
p := pagination(ctx, models.CountUsers(), pageNum)
var err error
ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum)
users, err := models.GetUsers(pageNum, (p-1)*pageNum)
if err != nil {
ctx.Handle(500, "GetUsers", err)
return
}
ctx.Data["Users"] = users
ctx.HTML(200, USERS)
}
@@ -120,7 +121,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
return
}
log.Trace("Account created by admin(%s): %s", ctx.User.Name, u.Name)
ctx.Redirect("/admin/users")
ctx.Redirect(setting.AppSubUrl + "/admin/users")
}
func EditUser(ctx *middleware.Context) {
@@ -197,7 +198,7 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
ctx.Data["User"] = u
ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
ctx.Redirect("/admin/users/" + ctx.Params(":userid"))
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
}
func DeleteUser(ctx *middleware.Context) {
@@ -217,12 +218,12 @@ func DeleteUser(ctx *middleware.Context) {
switch err {
case models.ErrUserOwnRepos:
ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
ctx.Redirect("/admin/users/" + ctx.Params(":userid"))
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
default:
ctx.Handle(500, "DeleteUser", err)
}
return
}
log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name)
ctx.Redirect("/admin/users")
ctx.Redirect(setting.AppSubUrl + "/admin/users")
}

View File

@@ -33,7 +33,7 @@ func Home(ctx *middleware.Context) {
// Check auto-login.
uname := ctx.GetCookie(setting.CookieUserName)
if len(uname) != 0 {
ctx.Redirect("/user/login")
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
}

View File

@@ -253,5 +253,5 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
log.Info("First-time run install finished!")
ctx.Flash.Success(ctx.Tr("install.install_success"))
ctx.Redirect("/user/login")
ctx.Redirect(setting.AppSubUrl + "/user/login")
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -86,7 +87,7 @@ func MembersAction(ctx *middleware.Context) {
if ctx.Params(":action") != "leave" {
ctx.Redirect(ctx.Org.OrgLink + "/members")
} else {
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
}
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -82,5 +83,5 @@ func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) {
}
log.Trace("Organization created: %s", org.Name)
ctx.Redirect("/org/" + form.OrgName + "/dashboard")
ctx.Redirect(setting.AppSubUrl + "/org/" + form.OrgName + "/dashboard")
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -48,7 +49,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
} else if err = models.ChangeUserName(org, form.OrgUserName); err != nil {
if err == models.ErrUserNameIllegal {
ctx.Flash.Error(ctx.Tr("form.illegal_username"))
ctx.Redirect("/org/" + org.LowerName + "/settings")
ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings")
return
} else {
ctx.Handle(500, "ChangeUserName", err)
@@ -72,7 +73,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
}
log.Trace("Organization setting updated: %s", org.Name)
ctx.Flash.Success(ctx.Tr("org.settings.update_setting_success"))
ctx.Redirect("/org/" + org.Name + "/settings")
ctx.Redirect(setting.AppSubUrl + "/org/" + org.Name + "/settings")
}
func SettingsDelete(ctx *middleware.Context) {
@@ -86,13 +87,13 @@ func SettingsDelete(ctx *middleware.Context) {
switch err {
case models.ErrUserOwnRepos:
ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
ctx.Redirect("/org/" + org.LowerName + "/settings/delete")
ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings/delete")
default:
ctx.Handle(500, "DeleteOrganization", err)
}
} else {
log.Trace("Organization deleted: %s", ctx.User.Name)
ctx.Redirect("/")
log.Trace("Organization deleted: %s", org.Name)
ctx.Redirect(setting.AppSubUrl + "/")
}
return
}

View File

@@ -124,6 +124,11 @@ func TeamsRepoAction(ctx *middleware.Context) {
var repo *models.Repository
repo, err = models.GetRepositoryByName(ctx.Org.Organization.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo"))
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
return
}
ctx.Handle(500, "GetRepositoryByName", err)
return
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -55,12 +56,14 @@ func Commits(ctx *middleware.Context) {
}
// Both `git log branchName` and `git log commitId` work.
ctx.Data["Commits"], err = ctx.Repo.Commit.CommitsByRange(page)
commits, err := ctx.Repo.Commit.CommitsByRange(page)
if err != nil {
ctx.Handle(500, "CommitsByRange", err)
return
}
commits = models.ValidateCommitsWithEmails(commits)
ctx.Data["Commits"] = commits
ctx.Data["Username"] = userName
ctx.Data["Reponame"] = repoName
ctx.Data["CommitCount"] = commitsCount
@@ -93,9 +96,10 @@ func SearchCommits(ctx *middleware.Context) {
commits, err := ctx.Repo.Commit.SearchCommits(keyword)
if err != nil {
ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err)
ctx.Handle(500, "SearchCommits", err)
return
}
commits = models.ValidateCommitsWithEmails(commits)
ctx.Data["Keyword"] = keyword
ctx.Data["Username"] = userName
@@ -114,7 +118,8 @@ func Diff(ctx *middleware.Context) {
commit := ctx.Repo.Commit
diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName), commitId)
diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName),
commitId, setting.MaxGitDiffLines)
if err != nil {
ctx.Handle(404, "GetDiffCommit", err)
return
@@ -157,8 +162,8 @@ func Diff(ctx *middleware.Context) {
ctx.Data["Diff"] = diff
ctx.Data["Parents"] = parents
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", commitId)
ctx.Data["RawPath"] = "/" + path.Join(userName, repoName, "raw", commitId)
ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", commitId)
ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", commitId)
ctx.HTML(200, DIFF)
}
@@ -176,7 +181,8 @@ func CompareDiff(ctx *middleware.Context) {
return
}
diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitId, afterCommitId)
diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitId,
afterCommitId, setting.MaxGitDiffLines)
if err != nil {
ctx.Handle(404, "GetDiffRange", err)
return

View File

@@ -54,8 +54,8 @@ func Issues(ctx *middleware.Context) {
isShowClosed := ctx.Query("state") == "closed"
if viewType != "all" && !ctx.IsSigned {
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
ctx.Redirect("/user/login")
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
}
@@ -312,7 +312,7 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
}
log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.Id)
send(200, fmt.Sprintf("/%s/%s/issues/%d", ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
}
func checkLabels(labels, allLabels []*models.Label) {
@@ -1119,3 +1119,9 @@ func IssueGetAttachment(ctx *middleware.Context) {
// We must put the name in " manually.
ctx.ServeFile(attachment.Path, "\""+attachment.Name+"\"")
}
// testing route handler for new issue ui page
// todo : move to Issue() function
func Issues2(ctx *middleware.Context){
ctx.HTML(200,"repo/issue2/list")
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -95,7 +96,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
form.Gitignore, form.License, form.Private, false, form.InitReadme)
if err == nil {
log.Trace("Repository created: %s/%s", ctxUser.Name, form.RepoName)
ctx.Redirect("/" + ctxUser.Name + "/" + form.RepoName)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
return
} else if err == models.ErrRepoAlreadyExist {
ctx.Data["Err_RepoName"] = true
@@ -179,7 +180,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
form.Mirror, url)
if err == nil {
log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
ctx.Redirect("/" + ctxUser.Name + "/" + form.RepoName)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
return
} else if err == models.ErrRepoAlreadyExist {
ctx.Data["Err_RepoName"] = true
@@ -243,18 +244,25 @@ func Action(ctx *middleware.Context) {
}
func Download(ctx *middleware.Context) {
ext := "." + ctx.Params(":ext")
var (
uri = ctx.Params("*")
refName string
ext string
archivePath string
)
var archivePath string
switch ext {
case ".zip":
switch {
case strings.HasSuffix(uri, ".zip"):
ext = ".zip"
archivePath = path.Join(ctx.Repo.GitRepo.Path, "archives/zip")
case ".tar.gz":
case strings.HasSuffix(uri, ".tar.gz"):
ext = ".tar.gz"
archivePath = path.Join(ctx.Repo.GitRepo.Path, "archives/targz")
default:
ctx.Error(404)
return
}
refName = strings.TrimSuffix(uri, ext)
if !com.IsDir(archivePath) {
if err := os.MkdirAll(archivePath, os.ModePerm); err != nil {
@@ -263,13 +271,42 @@ func Download(ctx *middleware.Context) {
}
}
// Get corresponding commit.
var (
commit *git.Commit
err error
)
gitRepo := ctx.Repo.GitRepo
if gitRepo.IsBranchExist(refName) {
commit, err = gitRepo.GetCommitOfBranch(refName)
if err != nil {
ctx.Handle(500, "Download", err)
return
}
} else if gitRepo.IsTagExist(refName) {
commit, err = gitRepo.GetCommitOfTag(refName)
if err != nil {
ctx.Handle(500, "Download", err)
return
}
} else if len(refName) == 40 {
commit, err = gitRepo.GetCommit(refName)
if err != nil {
ctx.Handle(404, "Download", nil)
return
}
} else {
ctx.Error(404)
return
}
archivePath = path.Join(archivePath, ctx.Repo.CommitId+ext)
if !com.IsFile(archivePath) {
if err := ctx.Repo.Commit.CreateArchive(archivePath, git.ZIP); err != nil {
if err := commit.CreateArchive(archivePath, git.ZIP); err != nil {
ctx.Handle(500, "Download -> CreateArchive "+archivePath, err)
return
}
}
ctx.ServeFile(archivePath, ctx.Repo.Repository.Name+"-"+base.ShortSha(ctx.Repo.CommitId)+ext)
ctx.ServeFile(archivePath, ctx.Repo.Repository.Name+"-"+base.ShortSha(commit.Id.String())+ext)
}

View File

@@ -16,6 +16,7 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/mailer"
"github.com/gogits/gogs/modules/middleware"
@@ -26,6 +27,8 @@ const (
SETTINGS_OPTIONS base.TplName = "repo/settings/options"
COLLABORATION base.TplName = "repo/settings/collaboration"
HOOKS base.TplName = "repo/settings/hooks"
GITHOOKS base.TplName = "repo/settings/githooks"
GITHOOK_EDIT base.TplName = "repo/settings/githook_edit"
HOOK_NEW base.TplName = "repo/settings/hook_new"
ORG_HOOK_NEW base.TplName = "org/settings/hook_new"
)
@@ -97,7 +100,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
ctx.Redirect(fmt.Sprintf("%s/%s/%s/settings", setting.AppSubUrl, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
case "transfer":
if ctx.Repo.Repository.Name != form.RepoName {
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
@@ -112,7 +115,10 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
} else if !isExist {
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), SETTINGS_OPTIONS, nil)
return
} else if err = models.TransferOwnership(ctx.Repo.Owner, newOwner, ctx.Repo.Repository); err != nil {
} else if !ctx.User.ValidtePassword(ctx.Query("password")) {
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_OPTIONS, nil)
return
} else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil {
if err == models.ErrRepoAlreadyExist {
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), SETTINGS_OPTIONS, nil)
} else {
@@ -121,7 +127,8 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
return
}
log.Trace("Repository transfered: %s/%s -> %s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newOwner)
ctx.Redirect("/")
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
ctx.Redirect(setting.AppSubUrl + "/")
case "delete":
if ctx.Repo.Repository.Name != form.RepoName {
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
@@ -150,9 +157,9 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
log.Trace("Repository deleted: %s/%s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
if ctx.Repo.Owner.IsOrganization() {
ctx.Redirect("/org/" + ctx.Repo.Owner.Name + "/dashboard")
ctx.Redirect(setting.AppSubUrl + "/org/" + ctx.Repo.Owner.Name + "/dashboard")
} else {
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
}
}
}
@@ -166,7 +173,7 @@ func SettingsCollaboration(ctx *middleware.Context) {
if ctx.Req.Method == "POST" {
name := strings.ToLower(ctx.Query("collaborator"))
if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
ctx.Redirect(ctx.Req.URL.Path)
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
return
}
has, err := models.HasAccess(name, repoLink, models.WRITABLE)
@@ -174,7 +181,7 @@ func SettingsCollaboration(ctx *middleware.Context) {
ctx.Handle(500, "HasAccess", err)
return
} else if has {
ctx.Redirect(ctx.Req.URL.Path)
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
return
}
@@ -182,16 +189,23 @@ func SettingsCollaboration(ctx *middleware.Context) {
if err != nil {
if err == models.ErrUserNotExist {
ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
ctx.Redirect(ctx.Req.URL.Path)
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
} else {
ctx.Handle(500, "GetUserByName", err)
}
return
}
// Check if user is organization member.
if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) {
ctx.Flash.Info(ctx.Tr("repo.settings.user_is_org_member"))
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
return
}
if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink,
Mode: models.WRITABLE}); err != nil {
ctx.Handle(500, "AddAccess2", err)
ctx.Handle(500, "AddAccess", err)
return
}
@@ -203,7 +217,7 @@ func SettingsCollaboration(ctx *middleware.Context) {
}
ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
ctx.Redirect(ctx.Req.URL.Path)
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
return
}
@@ -240,16 +254,20 @@ func SettingsCollaboration(ctx *middleware.Context) {
return
}
us := make([]*models.User, len(names))
for i, name := range names {
us[i], err = models.GetUserByName(name)
collaborators := make([]*models.User, 0, len(names))
for _, name := range names {
u, err := models.GetUserByName(name)
if err != nil {
ctx.Handle(500, "GetUserByName", err)
return
}
// Does not show organization members.
if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) {
continue
}
collaborators = append(collaborators, u)
}
ctx.Data["Collaborators"] = us
ctx.Data["Collaborators"] = collaborators
ctx.HTML(200, COLLABORATION)
}
@@ -587,3 +605,54 @@ func getOrgRepoCtx(ctx *middleware.Context) (*OrgRepoCtx, error) {
return &OrgRepoCtx{}, errors.New("Unable to set OrgRepo context")
}
}
func GitHooks(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsGitHooks"] = true
hooks, err := ctx.Repo.GitRepo.Hooks()
if err != nil {
ctx.Handle(500, "Hooks", err)
return
}
ctx.Data["Hooks"] = hooks
ctx.HTML(200, GITHOOKS)
}
func GitHooksEdit(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsGitHooks"] = true
name := ctx.Params(":name")
hook, err := ctx.Repo.GitRepo.GetHook(name)
if err != nil {
if err == git.ErrNotValidHook {
ctx.Handle(404, "GetHook", err)
} else {
ctx.Handle(500, "GetHook", err)
}
return
}
ctx.Data["Hook"] = hook
ctx.HTML(200, GITHOOK_EDIT)
}
func GitHooksEditPost(ctx *middleware.Context) {
name := ctx.Params(":name")
hook, err := ctx.Repo.GitRepo.GetHook(name)
if err != nil {
if err == git.ErrNotValidHook {
ctx.Handle(404, "GetHook", err)
} else {
ctx.Handle(500, "GetHook", err)
}
return
}
hook.Content = ctx.Query("content")
if err = hook.Update(); err != nil {
ctx.Handle(500, "hook.Update", err)
return
}
ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks/git")
}

View File

@@ -11,12 +11,10 @@ import (
"path/filepath"
"strings"
"github.com/saintfish/chardet"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/mahonia"
"github.com/gogits/gogs/modules/middleware"
)
@@ -24,21 +22,6 @@ const (
HOME base.TplName = "repo/home"
)
func toUtf8(content []byte) (error, string) {
detector := chardet.NewTextDetector()
result, err := detector.DetectBest(content)
if err != nil {
return err, ""
}
if result.Charset == "utf8" {
return nil, string(content)
}
decoder := mahonia.NewDecoder(result.Charset)
return nil, decoder.ConvertString(string(content))
}
func Home(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Repo.Repository.Name
@@ -117,7 +100,7 @@ func Home(ctx *middleware.Context) {
if readmeExist {
ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, ""))
} else {
if err, content := toUtf8(buf); err != nil {
if err, content := base.ToUtf8WithErr(buf); err != nil {
if err != nil {
log.Error(4, "Convert content encoding: %s", err)
}
@@ -135,6 +118,7 @@ func Home(ctx *middleware.Context) {
ctx.Handle(404, "SubTree", err)
return
}
entries, err := tree.ListEntries(treename)
if err != nil {
ctx.Handle(500, "ListEntries", err)
@@ -145,13 +129,27 @@ func Home(ctx *middleware.Context) {
files := make([][]interface{}, 0, len(entries))
for _, te := range entries {
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
if err != nil {
ctx.Handle(404, "GetCommitOfRelPath", err)
return
}
if te.Type != git.COMMIT {
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
if err != nil {
ctx.Handle(500, "GetCommitOfRelPath", err)
return
}
files = append(files, []interface{}{te, c})
} else {
sm, err := ctx.Repo.Commit.GetSubModule(path.Join(treename, te.Name()))
if err != nil {
ctx.Handle(500, "GetSubModule", err)
return
}
files = append(files, []interface{}{te, c})
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
if err != nil {
ctx.Handle(500, "GetCommitOfRelPath", err)
return
}
files = append(files, []interface{}{te, git.NewSubModuleFile(c, sm.Url, te.Id.String())})
}
}
ctx.Data["Files"] = files
@@ -199,6 +197,18 @@ func Home(ctx *middleware.Context) {
}
}
}
lastCommit := ctx.Repo.Commit
if len(treePath) > 0 {
c, err := ctx.Repo.Commit.GetCommitOfRelPath(treePath)
if err != nil {
ctx.Handle(500, "GetCommitOfRelPath", err)
return
}
lastCommit = c
}
ctx.Data["LastCommit"] = lastCommit
ctx.Data["LastCommitUser"] = models.ValidateCommitWithEmail(lastCommit)
}
ctx.Data["Username"] = userName
@@ -219,7 +229,6 @@ func Home(ctx *middleware.Context) {
}
}
ctx.Data["LastCommit"] = ctx.Repo.Commit
ctx.Data["Paths"] = Paths
ctx.Data["TreeName"] = treename
ctx.Data["Treenames"] = treenames

View File

@@ -52,8 +52,8 @@ func SignIn(ctx *middleware.Context) {
defer func() {
if !isSucceed {
log.Trace("auto-login cookie cleared: %s", uname)
ctx.SetCookie(setting.CookieUserName, "", -1)
ctx.SetCookie(setting.CookieRememberName, "", -1)
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl)
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl)
return
}
}()
@@ -77,12 +77,12 @@ func SignIn(ctx *middleware.Context) {
ctx.Session.Set("uid", u.Id)
ctx.Session.Set("uname", u.Name)
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1)
ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
ctx.Redirect(redirectTo)
return
}
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
}
func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
@@ -113,9 +113,9 @@ func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
if form.Remember {
days := 86400 * setting.LogInRememberDays
ctx.SetCookie(setting.CookieUserName, u.Name, days)
ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubUrl)
ctx.SetSuperSecureCookie(base.EncodeMd5(u.Rands+u.Passwd),
setting.CookieRememberName, u.Name, days)
setting.CookieRememberName, u.Name, days, setting.AppSubUrl)
}
// Bind with social account.
@@ -135,12 +135,12 @@ func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
ctx.Session.Set("uid", u.Id)
ctx.Session.Set("uname", u.Name)
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1)
ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
ctx.Redirect(redirectTo)
return
}
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
}
func SignOut(ctx *middleware.Context) {
@@ -149,9 +149,9 @@ func SignOut(ctx *middleware.Context) {
ctx.Session.Delete("socialId")
ctx.Session.Delete("socialName")
ctx.Session.Delete("socialEmail")
ctx.SetCookie(setting.CookieUserName, "", -1)
ctx.SetCookie(setting.CookieRememberName, "", -1)
ctx.Redirect("/")
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl)
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/")
}
func oauthSignUp(ctx *middleware.Context, sid int64) {
@@ -280,7 +280,7 @@ func SignUpPost(ctx *middleware.Context, cpt *captcha.Captcha, form auth.Registe
ctx.Data["IsSendRegisterMail"] = true
ctx.Data["Email"] = u.Email
ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
ctx.HTML(200, "user/activate")
ctx.HTML(200, ACTIVATE)
if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
@@ -288,7 +288,7 @@ func SignUpPost(ctx *middleware.Context, cpt *captcha.Captcha, form auth.Registe
return
}
ctx.Redirect("/user/login")
ctx.Redirect(setting.AppSubUrl + "/user/login")
}
func Activate(ctx *middleware.Context) {
@@ -335,7 +335,7 @@ func Activate(ctx *middleware.Context) {
ctx.Session.Set("uid", user.Id)
ctx.Session.Set("uname", user.Name)
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
return
}
@@ -437,7 +437,7 @@ func ResetPasswdPost(ctx *middleware.Context) {
}
log.Trace("User password reset: %s", u.Name)
ctx.Redirect("/user/login")
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -94,7 +95,7 @@ func Dashboard(ctx *middleware.Context) {
feeds := make([]*models.Action, 0, len(actions))
for _, act := range actions {
if act.IsPrivate {
if has, _ := models.HasAccess(ctxUser.Name, act.RepoUserName+"/"+act.RepoName,
if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
models.READABLE); !has {
continue
}
@@ -126,7 +127,7 @@ func Profile(ctx *middleware.Context) {
uname := ctx.Params(":username")
// Special handle for FireFox requests favicon.ico.
if uname == "favicon.ico" {
ctx.Redirect("/img/favicon.png")
ctx.Redirect(setting.AppSubUrl + "/img/favicon.png")
return
}
@@ -141,7 +142,7 @@ func Profile(ctx *middleware.Context) {
}
if u.IsOrganization() {
ctx.Redirect("/org/" + u.Name)
ctx.Redirect(setting.AppSubUrl + "/org/" + u.Name)
return
}
@@ -181,7 +182,7 @@ func Email2User(ctx *middleware.Context) {
}
return
}
ctx.Redirect("/user/" + u.Name)
ctx.Redirect(setting.AppSubUrl + "/user/" + u.Name)
}
const (

View File

@@ -14,6 +14,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
@@ -55,7 +56,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
} else if err = models.ChangeUserName(ctx.User, form.UserName); err != nil {
if err == models.ErrUserNameIllegal {
ctx.Flash.Error(ctx.Tr("form.illegal_username"))
ctx.Redirect("/user/settings")
ctx.Redirect(setting.AppSubUrl + "/user/settings")
return
} else {
ctx.Handle(500, "ChangeUserName", err)
@@ -78,7 +79,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
}
log.Trace("User setting updated: %s", ctx.User.Name)
ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
ctx.Redirect("/user/settings")
ctx.Redirect(setting.AppSubUrl + "/user/settings")
}
func SettingsPassword(ctx *middleware.Context) {
@@ -119,7 +120,7 @@ func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm)
ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
}
ctx.Redirect("/user/settings/password")
ctx.Redirect(setting.AppSubUrl + "/user/settings/password")
}
func SettingsSSHKeys(ctx *middleware.Context) {
@@ -160,7 +161,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
ctx.Handle(500, "DeletePublicKey", err)
} else {
log.Trace("SSH key deleted: %s", ctx.User.Name)
ctx.Redirect("/user/settings/ssh")
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
}
return
}
@@ -177,7 +178,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
if ok, err := models.CheckPublicKeyString(cleanContent); !ok {
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
ctx.Redirect("/user/settings/ssh")
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
return
}
@@ -196,7 +197,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
} else {
log.Trace("SSH key added: %s", ctx.User.Name)
ctx.Flash.Success(ctx.Tr("settings.add_key_success"))
ctx.Redirect("/user/settings/ssh")
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
return
}
}
@@ -217,7 +218,7 @@ func SettingsSocial(ctx *middleware.Context) {
return
}
ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
ctx.Redirect("/user/settings/social")
ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
return
}
@@ -248,13 +249,13 @@ func SettingsDelete(ctx *middleware.Context) {
switch err {
case models.ErrUserOwnRepos:
ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
ctx.Redirect("/user/settings/delete")
ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
default:
ctx.Handle(500, "DeleteUser", err)
}
} else {
log.Trace("Account deleted: %s", ctx.User.Name)
ctx.Redirect("/")
ctx.Redirect(setting.AppSubUrl + "/")
}
return
}

View File

@@ -22,7 +22,7 @@ import (
func extractPath(next string) string {
n, err := url.Parse(next)
if err != nil {
return "/"
return setting.AppSubUrl + "/"
}
return n.Path
}
@@ -88,7 +88,7 @@ func SocialSignIn(ctx *middleware.Context) {
return
}
case models.ErrOauth2NotAssociated:
next = "/user/sign_up"
next = setting.AppSubUrl + "/user/sign_up"
default:
ctx.Handle(500, "social.SocialSignIn(GetOauth2)", err)
return

View File

@@ -1,56 +0,0 @@
### Install Gogs With Docker
Deploying gogs using [Docker](http://www.docker.io/) is as easy as pie. Simple
open the `/dockerfiles/build.sh` file and replace the initial configuration
settings:
```
DB_TYPE="YOUR_DB_TYPE" # type of database, supports either 'mysql' or 'postgres'
MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, supports either 'redis' or 'memcache'
DB_PASSWORD="YOUR_DB_PASSWORD" # The database password
DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value to use when running the database image
MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value to use when running the memory database image
HOST_PORT="YOUR_HOST_PORT" # The port to expose the app on (redirected to 3000 inside the gogs container)
```
And run:
```
cd dockerfiles
./build.sh
```
The build will take some time, just be patient. After it finishes, it will
display a message that looks like this (the content may be different, depending
on your configuration options):
```
Now we have the MySQL image(running) and gogs image, use the follow command to start gogs service:
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs
```
To run the container, just copy the above command:
```
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs
```
Now gogs should be running! Open your browser and navigate to:
```
http://YOUR_HOST_IP:YOUR_HOST_PORT
```
During the installation procedure, use the following information:
- The database type should be whichever `DB_TYPE` you selected above
- The database host should be either `db:5432` or `db:3306` for PostgreSQL and
MySQL respectively
- The `RUN_USER` should be whichever user you're running the container with.
Ideally that's `git`, but your individual configuration may vary
- Everything else is configured like a normal gogs installation
Let's 'gogs'!
Ouya~

View File

@@ -1,77 +0,0 @@
# Configs of the docker images, you might have specify your own configs here.
DB_TYPE="YOUR_DB_TYPE" # type of database, support 'mysql' and 'postgres'
MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, support 'redis' and 'memcache'
DB_PASSWORD="YOUR_DB_PASSWORD" # The database password.
DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value when run the database image.
MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value when run the mem database image.
HOST_PORT="YOUR_HOST_PORT" # The port on host, which will be redirected to the port 3000 inside gogs container.
# apt source, you can select 'nchc'(mirror in Taiwan) or 'aliyun'(best for mainlance China users) according to your network, if you could connect to the official unbunt mirror in a fast speed, just leave it to "".
APT_SOURCE=""
# fail immediately if anything goes wrong
set -e
DOCKER_BIN=$(which docker.io || which docker)
if [ -z "$DOCKER_BIN" ] ; then
echo "Please install docker. You can install docker by running \"wget -qO- https://get.docker.io/ | sh\"."
exit 1
fi
# Replace the database root password in database image Dockerfile.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/$DB_TYPE/Dockerfile
# Replace the database root password in gogits image deploy.sh file.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/gogits/deploy.sh
# Replace the apt source in gogits image Dockerfile.
sed -i "s/#$APT_SOURCE#//" images/gogits/Dockerfile
# Uncomment the installation of database lib in gogs Dockerfile
sed -i "s/#$DB_TYPE#//" images/gogits/Dockerfile
# Replace the database type in gogits image deploy.sh file.
sed -i "s/THE_DB_TYPE/$DB_TYPE/g" images/gogits/deploy.sh
if [ $MEM_TYPE != "" ]
then
# Replace the mem configs in deploy.sh
sed -i "s/THE_MEM_TYPE/$MEM_TYPE/g" images/gogits/deploy.sh
# Uncomment the installation of go mem lib
sed -i "s/#$MEM_TYPE#//" images/gogits/Dockerfile
# Add the tags when get gogs
sed -i "s#RUN go get -u -d github.com/gogits/gogs#RUN go get -u -d -tags $MEM_TYPE github.com/gogits/gogs#g" images/gogits/Dockerfile
# Append the tag in gogs build
GOGS_BUILD_LINE=`awk '$0 ~ str{print NR}' str="go build" images/gogits/Dockerfile`
# Append the build tags
sed -i "${GOGS_BUILD_LINE}s/$/ -tags $MEM_TYPE/" images/gogits/Dockerfile
cd images/$MEM_TYPE
$DOCKER_BIN build -t gogits/$MEM_TYPE .
$DOCKER_BIN run -d --name $MEM_RUN_NAME gogits/$MEM_TYPE
MEM_LINK=" --link $MEM_RUN_NAME:mem "
cd ../../
fi
# Build the database image
cd images/$DB_TYPE
$DOCKER_BIN build -t gogits/$DB_TYPE .
#
## Build the gogits image
cd ../gogits
$DOCKER_BIN build -t gogits/gogs .
#sed -i "s#RUN go get -u -tags $MEM_TYPE github.com/gogits/gogs#RUN go get -u github.com/gogits/gogs#g" Dockerfile
# Remove the appended tags in go build line(if there is any)
sed -i "s/ -tags $MEM_TYPE//" Dockerfile
#
## Run MySQL image with name
$DOCKER_BIN run -d --name $DB_RUN_NAME gogits/$DB_TYPE
#
## Run gogits image and link it to the database image
echo "Now we have the $DB_TYPE image(running) and gogs image, use the follow command to start gogs service:"
echo -e "\033[33m $DOCKER_BIN run -i -t --link $DB_RUN_NAME:db $MEM_LINK -p $HOST_PORT:3000 gogits/gogs \033[0m"

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