Compare commits

..

150 Commits

Author SHA1 Message Date
Unknwon
3fb4f7f498 Prepare release 2016-03-19 14:51:41 -04:00
Unknwon
9e09e48502 #2850 fix potential SSH commands dislocation
When use builtin SSH server with concurrent operations, there are probabilities
One connection could use the command from another connections.

Fix this by set SSH_ORIGINAL_COMMAND for each command, not set in global scope.
2016-03-18 06:13:16 -04:00
Unknwon
c79774e8d4 Update locales 2016-03-18 04:03:13 -04:00
Unknwon
d6b09c35f7 Update .gopmfile and fix #2848 2016-03-17 14:29:45 -04:00
Unknwon
0048980da5 Merge pull request #2845 from moltam/feature/org-member-full-name-avatar
Display org member's full name in link title.
2016-03-16 17:17:45 -04:00
Tamás Molnár
d169d00be6 Display org member's full name in link title. 2016-03-16 22:04:19 +01:00
Unknwon
ff731ea07d #2814 LOWER() column value within search 2016-03-16 16:55:19 -04:00
Unknwon
9a5a27ea8d Improve repository lable style
- add border-radius to filter list items
- use color as background of label for issue/pull view page
2016-03-15 19:52:40 -04:00
Unknwon
94d7b62922 Merge pull request #2831 from odinuge/user-search-name
Make user search look in username, name and email
2016-03-15 19:39:12 -04:00
Unknwon
2df42e369e Merge pull request #2829 from odinuge/htmlmeta
Set description meta tag correctly
2016-03-15 17:54:44 -04:00
Unknwon
1f5bb08c25 Merge pull request #2836 from odinuge/markdown-links-rebase
Fix relative links in markdown files
2016-03-15 17:43:33 -04:00
Odin Ugedal
01ff65a93e Fix indent 2016-03-15 22:35:59 +01:00
Odin Ugedal
8540043c45 Make separate string variables for space 2016-03-15 21:28:55 +01:00
Odin Ugedal
f57adf3637 Fix relative links in markdown files
Replace spaces with "%20" in "urlPrefix", before markdon processing.
The spaces were causing blackfriday (markdown processor) to behave
strange. This fixes #2545.
2016-03-15 20:43:46 +01:00
Odin Ugedal
a75fa58e1c Make description meta tag golang 1.4 compatible 2016-03-15 19:57:19 +01:00
Odin Ugedal
6ccb2d36cf Remove email from user search 2016-03-15 19:44:58 +01:00
Unknwon
414e5f09c7 Merge pull request #2832 from dankm/build-flags
Make go's build flags a variable
2016-03-15 14:42:15 -04:00
Unknwon
a04596659b Merge pull request #2830 from odinuge/branchname-compare
Fix problems with '#' in branchname
2016-03-15 14:36:58 -04:00
Unknwon
149d62a648 #13 fix admin can't search private repos
- update glide info
2016-03-15 14:23:12 -04:00
Dan McGregor
db3905c0a3 Make go's build flags a variable
This allows the user to specify build flags from the make command
line. For example to force a complete rebuild one could use:

make BUILD_FLAGS='-v -a' TAGS="sqlite"
2016-03-15 07:55:06 -06:00
Odin Ugedal
3253e3c5aa Make user search look in username, name and email
Make user search function look in username (lower_name), full name
(full_name) and primary email (email). This will benefit searching after
user in "explore", admin panel and when adding new collaborators.
2016-03-15 14:16:58 +01:00
Odin Ugedal
c9321550e0 Add prorper escaping of url in issue form 2016-03-15 11:56:49 +01:00
Odin Ugedal
ac390d28b8 Fix problems with '#' in branchname
Add proper escaping of '#' in branchname in compare when doing pull
requests. This addresses issue #2822.
2016-03-15 11:36:23 +01:00
Odin Ugedal
561e5f9ccb Set description meta tag correctly
Set the description meta tag correctly when there is no repo
description. Also use the  ability to trim trailing whitespaces,
to make the template cleaner.
2016-03-15 10:17:23 +01:00
Unknwon
9df5c39bca Merge pull request #2824 from odinuge/repo-metadata
Set HTML meta values corresponding to repository
2016-03-14 16:47:23 -04:00
Unknwon
9976fc6782 Generate bindata for #2823 2016-03-14 16:46:36 -04:00
Unknwon
8966f5635d Merge pull request #2823 from zacheryph/feature/local-only-password-reset
Prevent `Forgot Password` for non local users
2016-03-14 16:44:05 -04:00
Odin Ugedal
85d7afeba0 Set HTML meta values corresponding to repository
Use the authors name, and the description of the repo in HTML meta.
Pages without repository context will display as before.
2016-03-14 17:32:24 +01:00
Zachery Hostens
63e21c146a ensure we don’t try changing LDAP passswords 2016-03-14 09:40:16 -05:00
Unknwon
9bd9ad4205 #1692 add CRUD issue APIs
- Fix go-gogs-client#10
- Related to #809
2016-03-13 23:20:22 -04:00
Unknwon
dd6faf7f9b Convert all API handers to use *context.APIContext 2016-03-13 18:49:16 -04:00
Unknwon
db4da7beec Add APIContext 2016-03-13 17:37:44 -04:00
Unknwon
b4f47a7623 #1891 attempt to fix invalid csrf token 2016-03-12 20:56:03 -05:00
Unknwon
af8eccc02e Update glide.lock 2016-03-12 14:44:28 -05:00
Unknwon
820be19cf5 Merge pull request #2796 from saboya/custom_app_data_path
Making AppDataPath customizable.
2016-03-12 13:53:37 -05:00
Unknwon
d733efc1cc #1286 #2098 Alpha support for custom templates
No guarantee for compatibility with future changes
2016-03-12 13:48:34 -05:00
Unknwon
985a0f3450 Generate css for #2816 2016-03-11 18:59:26 -05:00
Unknwon
322515a50b Merge pull request #2816 from MATTENN/custom_gogs_branch
Add Japanese Fonts
2016-03-11 18:58:45 -05:00
MATTENN
13e1fa6789 Add Japanese Fonts
By adding a Japanese font in the less file, easier to see the display in
Japanese.
2016-03-12 08:49:24 +09:00
Unknwon
c6277cce51 Minor fixes for #2761 2016-03-11 17:57:44 -05:00
Unknwon
6530375dbf Merge pull request #2761 from soudy/grey-out-merge-commit
Grey out merge commits
2016-03-11 17:51:17 -05:00
Unknwon
449a6e490b Merge pull request #2815 from allonsy/develop
remove errant debug statement
2016-03-11 17:49:13 -05:00
Alec S
ebea20b4e7 remove errant debug statement 2016-03-11 16:44:09 -06:00
Unknwon
f76d821bda fix #2804 2016-03-11 17:12:37 -05:00
Unknwon
263304b6b7 #13 fix postgres aggregate 2016-03-11 16:11:33 -05:00
Unknwon
73e98c91c3 Update locales 2016-03-11 15:47:49 -05:00
Unknwon
2bf8494332 #13 finish user and repository search
Both are possible on explore and admin panel
2016-03-11 15:33:12 -05:00
Unknwon
df2bdf7ea3 Use glide 2016-03-11 12:18:27 -05:00
Unknwon
514382e2eb Rename module: middleware -> context 2016-03-11 11:56:52 -05:00
Unknwon
cb1eadc276 Merge pull request #2810 from maxlazio/fix_updated_and_created
Update uses of updated and created
2016-03-11 10:15:55 -05:00
Marin Jankovski
1314ba219e Updated and created were appended with _unix. Fresh databases have only the newly named fields. 2016-03-11 12:43:35 +01:00
Unknwon
5267dce210 Fix ref comment from commit create empty feed 2016-03-11 05:11:58 -05:00
Unknwon
97c48da49f Merge pull request #2803 from Rukenshia/develop
Using HTML Description of repositories in the 'Explore' view. Fixes #…
2016-03-10 16:17:40 -05:00
Jan Christophersen
1e74ee51ff Using HTML Description of repositories in the 'Explore' view. Fixes #2800 2016-03-10 21:31:13 +01:00
Unknwon
067edcdb90 Merge pull request #2802 from allonsy/develop
readd 'dashboard' to title
2016-03-10 13:52:33 -05:00
Alec S
792c13cf0a readd 'dashboard' to title 2016-03-10 12:10:03 -06:00
Unknwon
3bd7d3b1c5 Merge pull request #2797 from allonsy/develop
Create custom dashboard title
2016-03-10 08:37:11 -05:00
Alec S
af847ef94e Merge branch 'develop' of github.com:gogits/gogs into develop 2016-03-09 22:56:52 -06:00
Alec S
bfed3ea7d3 fix indentation 2016-03-09 22:56:03 -06:00
Unknwon
b44e4d7cb0 Merge pull request #2785 from Rukenshia/develop
Allowing site admins to view private repositories in org/home
2016-03-09 23:20:08 -05:00
Unknwon
eed9966ad6 #2727 fix incompatible SQL in PostgreSQL 2016-03-09 23:18:39 -05:00
Alec S
affa3c2dbf Remove dashboard keyword from title 2016-03-09 21:01:43 -06:00
Alec S
6775ac7334 change page titles for user and org dashes 2016-03-09 20:46:36 -06:00
Rodrigo Saboya
2c626371b0 Adding APP_DATA_PATH entry to the default app.ini. 2016-03-09 23:16:43 -03:00
Rodrigo Saboya
3cacec9163 Making AppDataPath customizable. 2016-03-09 22:53:42 -03:00
Unknwon
ad513a20e9 #2302 Replace time.Time with Unix Timestamp (int64) 2016-03-09 19:53:30 -05:00
Jan Christophersen
72a8fa3bc8 Allowing site admins to view private repositories in org/home 2016-03-08 18:20:00 +01:00
Unknwon
0c9a616326 Update frontend resources 2016-03-07 00:11:12 -05:00
Unknwon
0e9bc2d410 Fix pull request availability check 2016-03-06 23:57:46 -05:00
Unknwon
0ea0c5ec4f Prepare release 2016-03-06 19:55:38 -05:00
Unknwon
58f0c68151 Some minor changes 2016-03-06 16:40:04 -05:00
Unknwon
12b5a76b0d Minor fix for #2772 2016-03-06 15:37:49 -05:00
Unknwon
a4452864ea Merge pull request #2772 from OhDaeto/master
Add ru-RU to home template
2016-03-06 15:36:40 -05:00
OhDaeto
d57be01485 Merge pull request #1 from xDShot/patch-1
Small correction
2016-03-06 23:02:55 +03:00
xDShot
d8738f5bfd минимальные -> низкие (системные требования) 2016-03-06 22:59:49 +03:00
Unknwon
9cf7f3e46f Remove duplicated of code 2016-03-06 14:44:22 -05:00
Lourens
14aba3489e Add ru-RU to home template 2016-03-06 22:22:41 +03:00
Unknwon
13bd16af92 Minor fixes for #2766 2016-03-06 13:24:42 -05:00
Unknwon
922a6f13a3 Merge pull request #2766 from moltam/feature/delete-org-avatar
Added: Ability to delete org avatar.
2016-03-06 13:20:37 -05:00
Tamás Molnár
9c91e27933 Added: Ability to delete org avatar. 2016-03-06 17:36:30 +01:00
Unknwon
c2ca103d30 #2623 fix wrong font for webhook history 2016-03-05 23:09:16 -05:00
Unknwon
c18f67ac6a Add Finnish support 2016-03-05 21:13:04 -05:00
Unknwon
a5b0400be7 #1146 finish new access rights for collaborators 2016-03-05 20:45:23 -05:00
Unknwon
045f14fbd0 #1146 finsih UI work for access mode of collaborators
Collaborators have write access as default, and can be changed via repository
collaboration settings page to change between read, write and admin.
2016-03-05 18:08:42 -05:00
Unknwon
05d8664f15 Merge pull request #2762 from rom1504/patch-1
Fix grammar in README
2016-03-05 14:18:17 -05:00
Romain Beaumont
52fdecf97b Fix grammar in README 2016-03-05 19:46:32 +01:00
Unknwon
9c0f84cee8 Update README notes 2016-03-05 13:09:31 -05:00
Unknwon
414eb22ef9 #1597 fix activitity feeds for pull requests 2016-03-05 12:58:51 -05:00
Steven Oud
1d3ec27cb7 Put if statement of grey merge commits on one line 2016-03-05 17:59:07 +01:00
Steven Oud
a0cd59bd0e Grey out merge commits 2016-03-05 17:00:38 +01:00
Unknwon
a2f13eae55 #1157 some avatar setting changes
- Allow to delete current avatar
2016-03-05 00:51:51 -05:00
Unknwon
2a931937a8 Update locales 2016-03-04 18:51:18 -05:00
Unknwon
dfd6f8f7ab Merge pull request #2757 from joshfng/fix-fork-relative-url
Use relative url when showing forked from
2016-03-04 18:37:42 -05:00
Josh Frye
275464e7fb Use relative url when showing forked from 2016-03-04 18:32:30 -05:00
Unknwon
e2d370f0da #1597 fix pull request remote head can't update with force push 2016-03-04 16:53:03 -05:00
Unknwon
4cb8bf1b75 #1597 fix premission logic check of pull request 2016-03-04 16:14:02 -05:00
Unknwon
5335e671be #2743 more fixes on SQL errors 2016-03-04 16:00:00 -05:00
Unknwon
2d2d85bba4 #1597 support pull requests in same repository 2016-03-04 15:43:01 -05:00
Unknwon
9df6ce48c5 Minor fixes for #2746 2016-03-04 13:32:17 -05:00
Unknwon
4d5911dbcf Merge pull request #2746 from joshfng/feature-delete-wiki-pages
Add ability to delete single wiki pages.
2016-03-04 13:14:37 -05:00
Unknwon
d57a2b908a #2743 and #2751 fix bad SQL generated by XORM
Use hand-written SQL to do complex query
2016-03-04 13:08:47 -05:00
Josh Frye
2f228ddf31 Update delete wiki page route 2016-03-04 09:26:52 -05:00
Josh Frye
1ca171dbe9 Add ability to delete single wiki pages. 2016-03-04 09:26:52 -05:00
Unknwon
f6759a731a #2748 fix redirect loop with auto-signin 2016-03-04 09:15:11 -05:00
Unknwon
dfbda48afc Merge pull request #2738 from andreynering/emogify
Render emojis in more places.
2016-03-03 23:38:20 -05:00
Unknwon
260723e2cc Minor fixes for #2745 2016-03-03 23:24:22 -05:00
Unknwon
1cbc5b49e3 Merge pull request #2745 from joshfng/delete-wiki-option
Repo setting to delete and disable wiki
2016-03-03 23:04:35 -05:00
Josh Frye
f3358f5927 Repo setting to delete and disable wiki 2016-03-03 16:12:48 -05:00
Unknwon
f946040fa9 #1891 attempt to fix expected invalid CSRF token
- Remove unused config settings `[picture] service`
2016-03-03 15:09:43 -05:00
Unknwon
434614506e Merge pull request #2744 from joshfng/mirror-default-branch
Set DefaultBranch to master when importing a new repo.
2016-03-03 14:22:45 -05:00
Josh Frye
7f2733fa1b Return errors instead of just logging them. 2016-03-03 12:43:23 -05:00
Josh Frye
edb7967dc7 Set DefaultBranch to master when importing a new repo if possible 2016-03-03 12:23:45 -05:00
Unknwon
c9901bbba5 #2743 workaround to fix XORM problem 2016-03-03 10:57:27 -05:00
Unknwon
4d930f3598 Merge pull request #2719 from mblacktree/patch-1
update README.md
2016-03-03 10:35:59 -05:00
Andrey Nering
13e71acadf Render emojis in more places. 2016-03-02 21:54:05 -03:00
Unknwon
37ac743da7 Update TRANSLATORS and remove tip for CI 2016-03-02 16:43:32 -05:00
Unknwon
c47a6c1510 Merge pull request #2736 from neolit123/patch
ISSUE_TEMPLATE: suggestion to test at try.gogs.io
2016-03-02 13:53:49 -05:00
Lubomir I. Ivanov
94f9ff1ac9 ISSUE_TEMPLATE: suggestion to test at try.gogs.io
I've noticed that a lot of issues cannot be reproduced on http://try.gogs.io,
which either hints about specific database type problems or
hints about bugs which are already solved in the newer version
(as http://try.gogs.io is usually a newer build).

This patch adds the suggestion to test the issue at http://try.gogs.io in
the Github "issue template". The user can answer: "Yes", "No", "Not relevant".

"Not relevant" is an option where testing on http://try.gogs.io makes no sense as
the bug is unrelated to the Web UI or is very specific in nature.
2016-03-02 20:12:14 +02:00
Unknwon
97429a25ab #2727 make IN clause compatible with Postgres 2016-03-01 14:39:28 -05:00
Unknwon
9e89584cb4 Allow setting git operations timeouts
- Migrate: #2704 #2653
- Clone: #2701
- Mirror, Pull
2016-02-29 19:29:49 -05:00
Unknwon
ea80274229 #2700 fix sqlite3 can't create issue with more than one label 2016-02-29 18:45:12 -05:00
Unknwon
42a556a082 Merge pull request #2722 from chriswatt/hidewikidlbutton
Hide the download archive button when viewing wiki pages
2016-02-29 13:36:22 -05:00
chriswatt
a71a5bfeb4 Remove download archive button on wiki pages 2016-02-29 15:45:55 +00:00
Unknwon
6cee434b04 Merge pull request #2717 from chriswatt/prtabs
Change colour of numbers on pull request tabs if greater than zero
2016-02-29 00:51:58 -05:00
Mike
9d44cd79ee update README.md
minor grammar fix
2016-02-28 21:17:19 -05:00
chriswatt
548440b48f Change colour of numbers on pull request tabs if greater than zero 2016-02-28 23:27:41 +00:00
Unknwon
8055a0bdac Post work for #2637
Improve test cases, config settings, also show SSH config settings on admin config panel.
2016-02-27 20:48:39 -05:00
Unknwon
83c74878df Merge pull request #2637 from Gibheer/ssh-publickeys
allow native and ssh-keygen public key check
2016-02-27 18:55:14 -05:00
Unknwon
d320915ad2 Minor fix for #2710 2016-02-27 11:31:24 -05:00
Unknwon
8e160edbd5 Merge pull request #2710 from lukasdietrich/develop
Add ForegroundColor for labels to resolve #2033
2016-02-27 11:10:57 -05:00
Lukas Dietrich
c0eaae200e Add ForegroundColor for labels 2016-02-27 13:59:11 +01:00
Unknwon
79ae163296 Merge pull request #2706 from ChubbyNinja/develop
Image attachments keep aspect ratio
2016-02-26 14:24:38 -05:00
Unknwon
7a91d7e776 Merge pull request #2694 from mhartkorn/pullrefs
Improved Pull Request refs
2016-02-26 14:21:31 -05:00
Unknwon
6465adfe5c Merge pull request #2707 from gogits/docker/update
Docker Container update
2016-02-26 12:25:32 -05:00
Jean-Philippe Roemer
db14949209 Update Docker REAMDE.md
- Remove the known issue about `.dockerignore` being ignored during DockerHub automated build as this has been fixed
- Added a note on the fact that we currently do no support building the container on RPi1
2016-02-26 17:07:31 +00:00
ChubbyNinja
ab4bc653ab Image attachments keep aspect ratio 2016-02-26 14:09:37 +00:00
Jean-Philippe Roemer
ab4eacd15f Update .dockerignore to add new unneeded files from the Docker Context 2016-02-25 20:43:41 +00:00
Jean-Philippe Roemer
7845075bd2 Dockerfile & Dockerfile.pi updates
- Upgrade of gosu to v1.7
- Change in docker/build.sh to use `--no-cache` to prevent APKINDEX creation when installing dev dependencies
- Manual upgrade of Alpine on Raspberry Pi when building to make sure the environment is the same as the standard Dockerfile
2016-02-25 20:43:40 +00:00
Unknwon
129638117f #2697 fix panic when close issue via commit message 2016-02-25 14:17:55 -05:00
Unknwon
4438b7793b Add new config option for builtin SSH server
Config option [server] SSH_LISTEN_PORT to the port the builtin SSH server will be listen.
It can be different from SSH_PORT which is supposed to be exposed in the clone URL.
This should solve the problem when user runs Gogs inside Docker container
and still want to use builtin SSH server.
2016-02-25 00:21:48 -05:00
Unknwon
baaf6046a1 Minor fix for #2660 2016-02-24 23:59:17 -05:00
Unknwon
5418c2c5e4 Merge pull request #2660 from joshfng/config-test-mailer
Test mailer button. Addresses #1531
2016-02-24 23:26:32 -05:00
Josh Frye
c27038e392 Test mailer button. Addresses #1531 2016-02-24 09:48:05 -05:00
Martin Hartkorn
51f15880d1 Call PushToBaseRepo() also on Pull Request creation and not only on git push 2016-02-24 13:56:54 +01:00
Gibheer
e721c5cf86 use StartSSHServer instead of DisableSSH
DisableSSH doesn't check the kind of ssh server to use, so that was
wrong. Use StartSSHServer instead.
2016-02-23 15:43:52 +01:00
Gibheer
e3570ae45d seperate ssh constants from schema constants
The contants were placed in the same section as the scheme ones, which
may lead to confusion.
2016-02-23 15:41:44 +01:00
Gibheer
2f27ee2232 variable should not use ALL_CAPS 2016-02-23 15:39:05 +01:00
Gibheer
dab74f21b7 remove ed25519 test for now
TravisCI is too old for ed25519, so it can't be tested correctly.
2016-02-17 11:30:48 +01:00
Gibheer
9eef2e706c fix ssh public key tests
The old API was using []byte, but was changed to string without running
the tests again.
It also sets the variables from the configuration to make them work.
Maybe there is a better way to do this.
2016-02-17 09:33:41 +01:00
Gibheer
12403bdfb0 allow native and ssh-keygen public key check
This commit adds the possibibility to use either the native golang
libraries or ssh-keygen to check public keys. The check is adjusted
depending on the settings, so that only supported keys are let through.

This commit also brings back the blacklist feature, which was removed in
7ef9a05588. This allows to blacklist
algorythms or keys based on the key length. This works with the native
and the ssh-keygen way.

Because of #2179 it also includes a way to adjust the path to
ssh-keygen and the working directory for ssh-keygen. With this,
sysadmins should be able to adjust the settings in a way, that SELinux
is okay with it. In the worst case, they can switch to the native
implementation and only loose support for ed25519 keys at the moment.
There are some other places which need adjustment to utilize the
parameters and the native implementation, but this sets the ground work.
2016-02-16 23:01:56 +01:00
183 changed files with 6961 additions and 3565 deletions

View File

@@ -1,7 +1,6 @@
[run]
init_cmds = [
#["grep", "-rn", "FIXME", "."],
["make", "build-dev"],
["make", "build-dev", "TAGS=sqlite"],
["./gogs", "web"]
]
watch_all = true
@@ -15,6 +14,6 @@ watch_exts = [".go"]
ignore_files = [".+_test.go"]
build_delay = 1500
cmds = [
["make", "build-dev"], # sqlite cert pam tidb
["make", "build-dev", "TAGS=sqlite"], # cert pam tidb
["./gogs", "web"]
]

View File

@@ -1,20 +1,21 @@
.git
.git/
.git/*
.git/**
conf
conf/
conf/*
conf/**
packager
packager/
packager/*
packager/**
scripts
scripts/
scripts/*
scripts/**
.github/
.github/**
config.codekit
LICENSE
Makefile
.dockerignore
*.yml
*.md
.bra.toml
.editorconfig
.gitignore
.gopmfile
config.codekit
LICENSE
Dockerfile*

View File

@@ -11,6 +11,10 @@ For bug reports, please give the relevant info:
- [ ] PostgreSQL
- [ ] MySQL
- [ ] SQLite
- Can you reproduce the bug at http://try.gogs.io:
- [ ] Yes
- [ ] No
- [ ] Not relevant
- Log gist:
## Description

22
.gitignore vendored
View File

@@ -8,31 +8,13 @@ data/
.idea/
*.iml
public/img/avatar/
files/
*.o
*.a
*.so
_obj
_test
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.exe~
/gogs
profile/
__pycache__
*.pem
output*
.brackets.json
docker/fig.yml
docker/docker/Dockerfile
docker/docker/init_gogs.sh
gogs.sublime-project
gogs.sublime-workspace
.tags*
release
/release
vendor

View File

@@ -3,35 +3,35 @@ path = github.com/gogits/gogs
[deps]
github.com/bradfitz/gomemcache = commit:fb1f79c
github.com/codegangsta/cli = commit:5db7419
github.com/codegangsta/cli = commit:aca5b04
github.com/go-macaron/binding = commit:a68f342
github.com/go-macaron/cache = commit:5617353
github.com/go-macaron/captcha = commit:8aa5919
github.com/go-macaron/csrf = commit:715bca0
github.com/go-macaron/csrf = commit:6a9a7df
github.com/go-macaron/gzip = commit:cad1c65
github.com/go-macaron/i18n = commit:d2d3329
github.com/go-macaron/inject = commit:c5ab7bf
github.com/go-macaron/session = commit:66031fc
github.com/go-macaron/toolbox = commit:82b5115
github.com/go-sql-driver/mysql = commit:1309049
github.com/go-xorm/core = commit:9ddf4ee
github.com/go-xorm/xorm = commit:e72082c
github.com/gogits/chardet = commit:2404f77725
github.com/go-sql-driver/mysql = commit:66312f7
github.com/go-xorm/core = commit:5021584
github.com/go-xorm/xorm = commit:769f6b3
github.com/gogits/chardet = commit:2404f77
github.com/gogits/cron = commit:3abc0f8
github.com/gogits/git-module = commit:a1c5096
github.com/gogits/go-gogs-client = commit:d584b1e
github.com/gogits/git-module = commit:76e8cce
github.com/gogits/go-gogs-client = commit:788ec59
github.com/issue9/identicon = commit:f8c0d2c
github.com/kardianos/minwinsvc = commit:cad6b2b
github.com/klauspost/compress = commit:f962535
github.com/klauspost/cpuid = commit:2c698c6
github.com/klauspost/compress = commit:006acde
github.com/klauspost/cpuid = commit:09cded8
github.com/klauspost/crc32 = commit:19b0b33
github.com/lib/pq = commit:69552e5
github.com/mattn/go-sqlite3 = commit:09d5c45
github.com/lib/pq = commit:165a352
github.com/mattn/go-sqlite3 = commit:76e335f
github.com/mcuadros/go-version = commit:d52711f
github.com/microcosm-cc/bluemonday = commit:4ac6f27
github.com/msteinert/pam = commit:02ccfbf
github.com/nfnt/resize = commit:4d93a29
github.com/russross/blackfriday = commit:006144a
github.com/russross/blackfriday = commit:b43df97
github.com/satori/go.uuid = commit:e673fdd
github.com/sergi/go-diff = commit:ec7fdbb
github.com/shurcooL/sanitized_anchor_name = commit:10ef21a
@@ -39,15 +39,18 @@ github.com/Unknwon/cae = commit:7f5e046
github.com/Unknwon/com = commit:28b053d
github.com/Unknwon/i18n = commit:3b48b66
github.com/Unknwon/paginater = commit:7748a72
golang.org/x/net = commit:4599ae7
golang.org/x/text = commit:07b9a78
golang.org/x/crypto = commit:1f22c01
golang.org/x/crypto = commit:c197bcf
golang.org/x/net = commit:35b06af
golang.org/x/sys = commit:9d4e42a
golang.org/x/text = commit:1b466db
gopkg.in/alexcesaro/quotedprintable.v3 = commit:2caba25
gopkg.in/asn1-ber.v1 = commit:4e86f43
gopkg.in/gomail.v2 = commit:fbb71dd
gopkg.in/bufio.v1 = commit:567b2bf
gopkg.in/gomail.v2 = commit:060a5f4
gopkg.in/ini.v1 = commit:776aa73
gopkg.in/ldap.v2 = commit:07a7330
gopkg.in/macaron.v1 = commit:b9eee38
gopkg.in/redis.v2 = commit:e617904962
gopkg.in/macaron.v1 = commit:94a5ef7
gopkg.in/redis.v2 = commit:e617904
[res]
include = public|scripts|templates

View File

@@ -4,7 +4,6 @@ go:
- 1.4
- 1.5
- 1.6
- tip
before_install:
- sudo apt-get update -qq

View File

@@ -2,7 +2,7 @@ FROM alpine:3.3
MAINTAINER jp@roemer.im
# Install system utils & Gogs runtime dependencies
ADD https://github.com/tianon/gosu/releases/download/1.6/gosu-amd64 /usr/sbin/gosu
ADD https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64 /usr/sbin/gosu
RUN chmod +x /usr/sbin/gosu \
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat

View File

@@ -2,13 +2,12 @@ FROM hypriot/rpi-alpine-scratch:v3.2
MAINTAINER jp@roemer.im, raxetul@gmail.com
# Install system utils & Gogs runtime dependencies
ADD https://github.com/tianon/gosu/releases/download/1.6/gosu-armhf /usr/sbin/gosu
RUN echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
ADD https://github.com/tianon/gosu/releases/download/1.7/gosu-armhf /usr/sbin/gosu
RUN chmod +x /usr/sbin/gosu \
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/community/" | tee -a /etc/apk/repositories \
&& echo "@edge http://dl-4.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories \
&& apk -U --no-progress upgrade \
&& apk -U --no-progress add ca-certificates bash git linux-pam s6@edge curl openssh socat \
&& chmod +x /usr/sbin/gosu
&& apk -U --no-progress upgrade && rm -f /var/cache/apk/APKINDEX.* \
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat
ENV GOGS_CUSTOM /data/gogs

View File

@@ -6,6 +6,7 @@ LESS_FILES := $(wildcard public/less/gogs.less public/less/_*.less)
GENERATED := modules/bindata/bindata.go public/css/gogs.css
TAGS = ""
BUILD_FLAGS = "-v"
RELEASE_ROOT = "release"
RELEASE_GOGS = "release/gogs"
@@ -16,14 +17,14 @@ NOW = $(shell date -u '+%Y%m%d%I%M%S')
.IGNORE: public/css/gogs.css
build: $(GENERATED)
go install -v -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
go install $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
cp '$(GOPATH)/bin/gogs' .
govet:
go tool vet -composites=false -methods=false -structtags=false .
build-dev: $(GENERATED) govet
go install -v -race -tags '$(TAGS)'
go install $(BUILD_FLAGS) -race -tags '$(TAGS)'
cp '$(GOPATH)/bin/gogs' .
pack:
@@ -53,3 +54,9 @@ clean-mac: clean
test:
go test -cover -race ./...
fixme:
grep -rnw "FIXME" routers models modules
todo:
grep -rnw "TODO" routers models modules

View File

@@ -1,9 +1,9 @@
Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs) [![Docker Repository on Quay](https://quay.io/repository/gogs/gogs/status "Docker Repository on Quay")](https://quay.io/repository/gogs/gogs) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/gogs/localized.svg)](https://crowdin.com/project/gogs) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gogits/gogs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/gogs/localized.svg)](https://crowdin.com/project/gogs) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gogits/gogs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
=====================
![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true)
##### Current version: 0.8.43
##### Current version: 0.9.13
| Web | UI | Preview |
|:-------------:|:-------:|:-------:|
@@ -11,15 +11,14 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
|![Profile](https://gogs.io/img/screenshots/4.png)|![Admin Dashboard](https://gogs.io/img/screenshots/5.png)|![Diff](https://gogs.io/img/screenshots/6.png)|
|![Issues](https://gogs.io/img/screenshots/7.png)|![Releases](https://gogs.io/img/screenshots/8.png)|![Organization](https://gogs.io/img/screenshots/9.png)|
### NOTICES
### Important Notes
1. :bangbang: You **MUST** **MUST** **MUST** read [CONTRIBUTING.md](https://github.com/gogits/gogs/blob/master/.github/CONTRIBUTING.md) for bug report and contributing code. :bangbang:
2. **PLEASE** **PLEASE** **PLEASE** [ask questions](https://discuss.gogs.io/c/getting-help) on [the forum](https://discuss.gogs.io/). GitHub issue tracker only keeps **bugs** and **feature requests**, all other topics will be closed without reason.
3. Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) was reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
4. The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
5. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
6. If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
7. If your team/company is using Gogs and would like to put your logo on [our website](http://gogs.io), contact us by any means.
1. **YOU MUST READ [Contributing Code](https://github.com/gogits/gogs/wiki/Contributing-Code) BEFORE STARTING TO WORK ON A PULL REQUEST**.
2. Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) was reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
3. The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
4. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
5. If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
6. If your team/company is using Gogs and would like to put your logo on [our website](http://gogs.io), contact us by any means.
[简体中文](README_ZH.md)
@@ -32,7 +31,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
- Please see the [Documentation](http://gogs.io/docs/intro) for common usages and change log.
- See the [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
- Want to try it before doing anything else? Do it [online](https://try.gogs.io/gogs/gogs)!
- Having trouble? Get help with [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.html).
- Having trouble? Get help with [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.html) or [User Forum](https://discuss.gogs.io/).
- Want to help with localization? Check out the [guide](http://gogs.io/docs/features/i18n.html)!
## Features
@@ -50,7 +49,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
- Mail service
- Administration panel
- Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) (experimental)
- Multi-language support ([14 languages](https://crowdin.com/project/gogs))
- Multi-language support ([15 languages](https://crowdin.com/project/gogs))
## System Requirements
@@ -106,6 +105,7 @@ There are 5 ways to install Gogs:
- [Puppet](https://forge.puppetlabs.com/Siteminds/gogs) (IT)
- [Kanboard](http://kanboard.net/plugin/gogs-webhook) (Project Management)
- [BearyChat](https://bearychat.com/) (Team Communication)
- [HiWork](http://www.hiwork.cc/) (Team Communication)
### Product Support

View File

@@ -12,7 +12,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- 有关基本用法和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
- 想要先睹为快?直接去 [在线体验](https://try.gogs.io/gogs/gogs) 。
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.html) 页面获取帮助。
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.html) 页面或 [用户论坛](https://discuss.gogs.io/) 获取帮助。
- 希望帮助多国语言界面的翻译吗?请立即访问 [详情页面](http://gogs.io/docs/features/i18n.html)
## 功能特性
@@ -30,7 +30,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- 支持邮件服务
- 支持后台管理面板
- 支持 MySQL、PostgreSQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb)(实验性支持) 数据库
- 支持多语言本地化([14 种语言]([more](https://crowdin.com/project/gogs))
- 支持多语言本地化([15 种语言]([more](https://crowdin.com/project/gogs))
## 系统要求
@@ -77,6 +77,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- [Puppet](https://forge.puppetlabs.com/Siteminds/gogs)IT
- [Kanboard](http://kanboard.net/plugin/gogs-webhook)(项目管理)
- [BearyChat](https://bearychat.com/)(团队交流)
- [HiWork](http://www.hiwork.cc/)(团队交流)
### 产品支持

View File

@@ -136,7 +136,7 @@ func runServ(c *cli.Context) {
setup("serv.log")
if setting.DisableSSH {
if setting.SSH.Disabled {
println("Gogs: SSH has been disabled")
return
}

View File

@@ -7,7 +7,6 @@ package cmd
import (
"crypto/tls"
"fmt"
gotmpl "html/template"
"io/ioutil"
"net/http"
"net/http/fcgi"
@@ -35,8 +34,8 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/bindata"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/template"
"github.com/gogits/gogs/routers"
@@ -79,17 +78,17 @@ func checkVersion() {
// Check dependency version.
checkers := []VerChecker{
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.4.4.1029"},
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.2.0304"},
{"github.com/go-macaron/binding", binding.Version, "0.2.1"},
{"github.com/go-macaron/cache", cache.Version, "0.1.2"},
{"github.com/go-macaron/csrf", csrf.Version, "0.0.3"},
{"github.com/go-macaron/csrf", csrf.Version, "0.1.0"},
{"github.com/go-macaron/i18n", i18n.Version, "0.2.0"},
{"github.com/go-macaron/session", session.Version, "0.1.6"},
{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
{"gopkg.in/ini.v1", ini.Version, "1.8.4"},
{"gopkg.in/macaron.v1", macaron.Version, "0.8.0"},
{"github.com/gogits/git-module", git.Version, "0.2.7"},
{"github.com/gogits/go-gogs-client", gogs.Version, "0.7.3"},
{"gopkg.in/macaron.v1", macaron.Version, "1.1.2"},
{"github.com/gogits/git-module", git.Version, "0.2.9"},
{"github.com/gogits/go-gogs-client", gogs.Version, "0.7.4"},
}
for _, c := range checkers {
if !version.Compare(c.Version(), c.Expected, ">=") {
@@ -125,9 +124,10 @@ func newMacaron() *macaron.Macaron {
},
))
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "templates"),
Funcs: []gotmpl.FuncMap{template.Funcs},
IndentJSON: macaron.Env != macaron.PROD,
Directory: path.Join(setting.StaticRootPath, "templates"),
AppendDirectories: []string{path.Join(setting.CustomPath, "templates")},
Funcs: template.NewFuncMap(),
IndentJSON: macaron.Env != macaron.PROD,
}))
localeNames, err := bindata.AssetDir("conf/locale")
@@ -158,6 +158,7 @@ func newMacaron() *macaron.Macaron {
m.Use(session.Sessioner(setting.SessionConfig))
m.Use(csrf.Csrfer(csrf.Options{
Secret: setting.SecretKey,
Cookie: setting.CSRFCookieName,
SetCookie: true,
Header: "X-Csrf-Token",
CookiePath: setting.AppSubUrl,
@@ -170,7 +171,7 @@ func newMacaron() *macaron.Macaron {
},
},
}))
m.Use(middleware.Contexter())
m.Use(context.Contexter())
return m
}
@@ -183,26 +184,28 @@ func runWeb(ctx *cli.Context) {
m := newMacaron()
reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true})
ignSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: setting.Service.RequireSignInView})
ignSignInAndCsrf := middleware.Toggle(&middleware.ToggleOptions{DisableCsrf: true})
reqSignOut := middleware.Toggle(&middleware.ToggleOptions{SignOutRequire: true})
reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView})
ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true})
reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true})
bindIgnErr := binding.BindIgnErr
// FIXME: not all routes need go through same middlewares.
// Especially some AJAX requests, we can reduce middleware number to improve performance.
// Routers.
m.Get("/", ignSignIn, routers.Home)
m.Get("/explore", ignSignIn, routers.Explore)
m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) {
ctx.Redirect(setting.AppSubUrl + "/explore/repos")
})
m.Get("/repos", routers.ExploreRepos)
m.Get("/users", routers.ExploreUsers)
}, ignSignIn)
m.Combo("/install", routers.InstallInit).Get(routers.Install).
Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Get("/^:type(issues|pulls)$", reqSignIn, user.Issues)
// ***** START: API *****
m.Group("/api", func() {
apiv1.RegisterRoutes(m)
}, ignSignIn)
// ***** END: API *****
// ***** START: User *****
m.Group("/user", func() {
m.Get("/login", user.SignIn)
@@ -217,6 +220,7 @@ func runWeb(ctx *cli.Context) {
m.Get("", user.Settings)
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
m.Combo("/email").Get(user.SettingsEmails).
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
m.Post("/email/delete", user.DeleteEmail)
@@ -229,7 +233,7 @@ func runWeb(ctx *cli.Context) {
Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
m.Post("/applications/delete", user.SettingsDeleteApplication)
m.Route("/delete", "GET,POST", user.SettingsDelete)
}, reqSignIn, func(ctx *middleware.Context) {
}, reqSignIn, func(ctx *context.Context) {
ctx.Data["PageIsUserSettings"] = true
})
@@ -244,12 +248,13 @@ func runWeb(ctx *cli.Context) {
})
// ***** END: User *****
adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true})
adminReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true})
// ***** START: Admin *****
m.Group("/admin", func() {
m.Get("", adminReq, admin.Dashboard)
m.Get("/config", admin.Config)
m.Post("/config/test_mail", admin.SendTestMail)
m.Get("/monitor", admin.Monitor)
m.Group("/users", func() {
@@ -292,7 +297,7 @@ func runWeb(ctx *cli.Context) {
m.Get("/stars", user.Stars)
})
m.Get("/attachments/:uuid", func(ctx *middleware.Context) {
m.Get("/attachments/:uuid", func(ctx *context.Context) {
attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid"))
if err != nil {
if models.IsErrAttachmentNotExist(err) {
@@ -329,8 +334,8 @@ func runWeb(ctx *cli.Context) {
m.Get("/template/*", dev.TemplatePreview)
}
reqRepoAdmin := middleware.RequireRepoAdmin()
reqRepoPusher := middleware.RequireRepoPusher()
reqRepoAdmin := context.RequireRepoAdmin()
reqRepoWriter := context.RequireRepoWriter()
// ***** START: Organization *****
m.Group("/org", func() {
@@ -344,14 +349,14 @@ func runWeb(ctx *cli.Context) {
m.Get("/members/action/:action", org.MembersAction)
m.Get("/teams", org.Teams)
}, middleware.OrgAssignment(true))
}, context.OrgAssignment(true))
m.Group("/:org", func() {
m.Get("/teams/:team", org.TeamMembers)
m.Get("/teams/:team/repositories", org.TeamRepositories)
m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction)
m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction)
}, middleware.OrgAssignment(true, false, true))
}, context.OrgAssignment(true, false, true))
m.Group("/:org", func() {
m.Get("/teams/new", org.NewTeam)
@@ -364,6 +369,7 @@ func runWeb(ctx *cli.Context) {
m.Combo("").Get(org.Settings).
Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), org.SettingsAvatar)
m.Post("/avatar/delete", org.SettingsDeleteAvatar)
m.Group("/hooks", func() {
m.Get("", org.Webhooks)
@@ -380,7 +386,7 @@ func runWeb(ctx *cli.Context) {
})
m.Route("/invitations/new", "GET,POST", org.Invitation)
}, middleware.OrgAssignment(true, true))
}, context.OrgAssignment(true, true))
}, reqSignIn)
// ***** END: Organization *****
@@ -398,7 +404,11 @@ func runWeb(ctx *cli.Context) {
m.Group("/settings", func() {
m.Combo("").Get(repo.Settings).
Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
m.Combo("/collaboration").Get(repo.Collaboration).Post(repo.CollaborationPost)
m.Group("/collaboration", func() {
m.Combo("").Get(repo.Collaboration).Post(repo.CollaborationPost)
m.Post("/access_mode", repo.ChangeCollaborationAccessMode)
m.Post("/delete", repo.DeleteCollaboration)
})
m.Group("/hooks", func() {
m.Get("", repo.Webhooks)
@@ -415,7 +425,7 @@ func runWeb(ctx *cli.Context) {
m.Get("", repo.GitHooks)
m.Combo("/:name").Get(repo.GitHooksEdit).
Post(repo.GitHooksEditPost)
}, middleware.GitHookService())
}, context.GitHookService())
})
m.Group("/keys", func() {
@@ -424,15 +434,15 @@ func runWeb(ctx *cli.Context) {
m.Post("/delete", repo.DeleteDeployKey)
})
}, func(ctx *middleware.Context) {
}, func(ctx *context.Context) {
ctx.Data["PageIsSettings"] = true
})
}, reqSignIn, middleware.RepoAssignment(), reqRepoAdmin, middleware.RepoRef())
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())
m.Get("/:username/:reponame/action/:action", reqSignIn, middleware.RepoAssignment(), repo.Action)
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
m.Group("/:username/:reponame", func() {
m.Group("/issues", func() {
m.Combo("/new", repo.MustEnableIssues).Get(middleware.RepoRef(), repo.NewIssue).
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
m.Combo("/:index/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
@@ -440,7 +450,7 @@ func runWeb(ctx *cli.Context) {
m.Post("/label", repo.UpdateIssueLabel)
m.Post("/milestone", repo.UpdateIssueMilestone)
m.Post("/assignee", repo.UpdateIssueAssignee)
}, reqRepoAdmin)
}, reqRepoWriter)
m.Group("/:index", func() {
m.Post("/title", repo.UpdateIssueTitle)
@@ -452,7 +462,7 @@ func runWeb(ctx *cli.Context) {
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
m.Post("/delete", repo.DeleteLabel)
}, reqRepoAdmin, middleware.RepoRef())
}, reqRepoWriter, context.RepoRef())
m.Group("/milestones", func() {
m.Combo("/new").Get(repo.NewMilestone).
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
@@ -460,7 +470,7 @@ func runWeb(ctx *cli.Context) {
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
m.Get("/:id/:action", repo.ChangeMilestonStatus)
m.Post("/delete", repo.DeleteMilestone)
}, reqRepoAdmin, middleware.RepoRef())
}, reqRepoWriter, context.RepoRef())
m.Group("/releases", func() {
m.Get("/new", repo.NewRelease)
@@ -468,11 +478,11 @@ func runWeb(ctx *cli.Context) {
m.Get("/edit/:tagname", repo.EditRelease)
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
m.Post("/delete", repo.DeleteRelease)
}, reqRepoAdmin, middleware.RepoRef())
}, reqRepoWriter, context.RepoRef())
m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest).
Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
}, reqSignIn, middleware.RepoAssignment(), repo.MustBeNotBare)
}, reqSignIn, context.RepoAssignment(), repo.MustBeNotBare)
m.Group("/:username/:reponame", func() {
m.Group("", func() {
@@ -481,7 +491,7 @@ func runWeb(ctx *cli.Context) {
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
m.Get("/milestones", repo.Milestones)
}, middleware.RepoRef())
}, context.RepoRef())
// m.Get("/branches", repo.Branches)
@@ -494,15 +504,16 @@ func runWeb(ctx *cli.Context) {
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
m.Combo("/:page/_edit").Get(repo.EditWiki).
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
}, reqSignIn, reqRepoPusher)
}, repo.MustEnableWiki, middleware.RepoRef())
m.Post("/:page/delete", repo.DeleteWikiPagePost)
}, reqSignIn, reqRepoWriter)
}, repo.MustEnableWiki, context.RepoRef())
m.Get("/archive/*", repo.Download)
m.Group("/pulls/:index", func() {
m.Get("/commits", middleware.RepoRef(), repo.ViewPullCommits)
m.Get("/files", middleware.RepoRef(), repo.ViewPullFiles)
m.Post("/merge", reqRepoAdmin, repo.MergePullRequest)
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
m.Get("/files", context.RepoRef(), repo.ViewPullFiles)
m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
}, repo.MustAllowPulls)
m.Group("", func() {
@@ -511,20 +522,20 @@ func runWeb(ctx *cli.Context) {
m.Get("/commits/*", repo.RefCommits)
m.Get("/commit/*", repo.Diff)
m.Get("/forks", repo.Forks)
}, middleware.RepoRef())
}, context.RepoRef())
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.CompareDiff)
}, ignSignIn, middleware.RepoAssignment(), repo.MustBeNotBare)
}, ignSignIn, context.RepoAssignment(), repo.MustBeNotBare)
m.Group("/:username/:reponame", func() {
m.Get("/stars", repo.Stars)
m.Get("/watchers", repo.Watchers)
}, ignSignIn, middleware.RepoAssignment(), middleware.RepoRef())
}, ignSignIn, context.RepoAssignment(), context.RepoRef())
m.Group("/:username", func() {
m.Group("/:reponame", func() {
m.Get("", repo.Home)
m.Get("\\.git$", repo.Home)
}, ignSignIn, middleware.RepoAssignment(true), middleware.RepoRef())
}, ignSignIn, context.RepoAssignment(true), context.RepoRef())
m.Group("/:reponame", func() {
m.Any("/*", ignSignInAndCsrf, repo.HTTP)
@@ -533,8 +544,12 @@ func runWeb(ctx *cli.Context) {
})
// ***** END: Repository *****
m.Group("/api", func() {
apiv1.RegisterRoutes(m)
}, ignSignIn)
// robots.txt
m.Get("/robots.txt", func(ctx *middleware.Context) {
m.Get("/robots.txt", func(ctx *context.Context) {
if setting.HasRobotsTxt {
ctx.ServeFileContent(path.Join(setting.CustomPath, "robots.txt"))
} else {

View File

@@ -1,7 +1,3 @@
Execute following command in ROOT directory when anything is changed:
$ go-bindata -o=modules/bindata/bindata.go -ignore="\\.DS_Store|README.md" -pkg=bindata conf/...
Add -debug flag to make life easier in development(somehow isn't working):
$ go-bindata -debug -o=modules/bindata/bindata.go -ignore="\\.DS_Store|README.md" -pkg=bindata conf/...
$ make bindata

View File

@@ -63,9 +63,21 @@ LOCAL_ROOT_URL = http://localhost:%(HTTP_PORT)s/
DISABLE_SSH = false
; Whether use builtin SSH server or not.
START_SSH_SERVER = false
; Domain name to be exposed in clone URL
SSH_DOMAIN = %(DOMAIN)s
; Port number to be exposed in clone URL
SSH_PORT = 22
; Root path of SSH directory
; Port number builtin SSH server listens on
SSH_LISTEN_PORT = %(SSH_PORT)s
; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
SSH_ROOT_PATH =
; Directory to create temporary files when test publick key using ssh-keygen,
; default is system temporary directory.
SSH_KEY_TEST_PATH =
; Path to ssh-keygen, default is 'ssh-keygen' and let shell find out which one to call.
SSH_KEYGEN_PATH = ssh-keygen
; Indicate whether to check minimum key size with corresponding type
MINIMUM_KEY_SIZE_CHECK = false
; Disable CDN even in "prod" mode
OFFLINE_MODE = false
DISABLE_ROUTER_LOG = false
@@ -81,11 +93,20 @@ KEY_FILE = custom/https/key.pem
; Upper level of template and static file path
; default is the path where Gogs is executed
STATIC_ROOT_PATH =
; Default path for App data
APP_DATA_PATH = data
; Application level GZIP support
ENABLE_GZIP = false
; Landing page for non-logged users, can be "home" or "explore"
LANDING_PAGE = home
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
[ssh.minimum_key_sizes]
ED25519 = 256
ECDSA = 256
RSA = 2048
DSA = 1024
[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
DB_TYPE = mysql
@@ -196,8 +217,6 @@ GC_INTERVAL_TIME = 86400
SESSION_LIFE_TIME = 86400
[picture]
; The place to picture data, either "server" or "qiniu", default is "server"
SERVICE = server
AVATAR_UPLOAD_PATH = data/avatars
; Chinese users can choose "duoshuo"
; or a custom avatar source, like: http://cn.gravatar.com/avatar/
@@ -312,9 +331,16 @@ MAX_GIT_DIFF_LINES = 10000
; see more on http://git-scm.com/docs/git-gc/1.7.5
GC_ARGS =
; Operation timeout in seconds
[git.timeout]
MIGRATE = 600
MIRROR = 300
CLONE = 300
PULL = 300
[i18n]
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen
; Used for datetimepicker
[i18n.datelang]
@@ -332,6 +358,7 @@ pt-BR = pt-BR
pl-PL = pl
bg-BG = bg
it-IT = it
fi-FI = fi
; Extension mapping to highlight class
; e.g. .toml=ini

View File

@@ -12,33 +12,44 @@ Andrey Nering <andrey AT nering DOT com DOT br>
Andrey Solomatin <toadron AT yandex DOT ru>
Antoine GIRARD <sapk AT sapk DOT fr>
Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
Cysioland
Daniel Speichert <daniel AT speichert DOT pl>
David Yzaguirre <dvdyzag AT gmail DOT com>
Dmitriy Nogay <me AT catwhocode DOT ga>
Enrico Testori hypertesto AT gmail DOT com
Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
Gregor Santner <gdev AT live DOT de>
Hamid Feizabadi <hamidfzm AT gmail DOT com>
Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp>
ilko <kontact-mr.k AT outlook DOT com">
Ilya Makarov
Robert Nuske <robert DOT nuske AT web DOT de>
Robin Hübner <profan AT prfn DOT se>
Jamie Mansfield <dev AT jamierocks DOT uk>
Jean THOMAS <contact AT tibounise DOT com>
Juraj Bubniak <contact AT jbub DOT eu>
Lafriks <lafriks AT gmail DOT com>
Lauri Ojansivu <x AT xet7 DOT org>
Luc Stepniewski <luc AT stepniewski DOT fr>
Luca Kröger <l DOT kroeger01 AT gmail DOT com>
Marc Schiller <marc AT schiller DOT im>
Marvin Menzerath <github AT marvin-menzerath DOT de>
Michael Härtl <haertl DOT mike AT gmail DOT com>
Miguel de la Cruz <miguel AT mcrx DOT me>
Mikhail Burdin <xdshot9000 AT gmail DOT com>
Morten Sørensen <klim8d AT gmail DOT com>
Muhammad Fawwaz Orabi <mfawwaz93 AT gmail DOT com>
Nakao Takamasa <at.mattenn AT gmail DOT com>
Natan Albuquerque <natanalbuquerque5 AT gmail DOT com>
Odilon Junior <odilon DOT junior93 AT gmail DOT com>
SeongJae Park <sj38 DOT park AT gmail DOT com>
Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>
Tilmann Bach <tilmann AT outlook DOT com>
Toni Villena Jiménez <tonivj5 AT gmail DOT com>
Vladimir Jigulin mogaika AT yandex DOT ru
Vladimir Vissoultchev <wqweto AT gmail DOT com>
YJSoft <yjsoft AT yjsoft DOT pe DOT kr>
Łukasz Jan Niemier <lukasz AT niemier DOT pl>

View File

@@ -44,13 +44,6 @@ issues=Задачи
cancel=Отказ
[search]
search=Търсене...
repository=Хранилище
user=Потребител
issue=Задача
code=Код
[install]
install=Инсталация
title=Стъпки за инсталиране при първоначално стартиране
@@ -140,6 +133,8 @@ issues.in_your_repos=Във Вашите хранилища
[explore]
repos=Хранилища
users=Потребители
search=Търсене
[auth]
create_new_account=Създай нов профил
@@ -221,8 +216,6 @@ still_own_repo=Вашият профил притежава поне едно х
still_has_org=Вашият профил все още участва в поне една организация. Първо трябва да напуснете или изтриете Вашите участия в организациите.
org_still_own_repo=Тази организация все още притежава хранилище. Първо трябва да го изтриете или да го прехвърлите на друга организация.
still_own_user=Това удостоверяване се използва от поне един потребител. Моля премахнете потребителите към него и опитайте отново.
target_branch_not_exist=Целевият клон не съществува.
[user]
@@ -264,11 +257,10 @@ continue=Продължи
cancel=Отказ
enable_custom_avatar=Разреши потребителски аватар
enable_custom_avatar_helper=Без зареждане от Gravatar
choose_new_avatar=Избор на нов аватар
update_avatar=Запази настройките на аватара
delete_current_avatar=Изтрий аватар
uploaded_avatar_not_a_image=Каченият файл не е изображение.
no_custom_avatar_available=Невъзможно използване на външен аватар, защото не е активирано.
update_avatar_success=Настройките на аватара са запазени успешно.
change_password=Промяна на собствената парола
@@ -479,7 +471,7 @@ issues.closed_at=`затвори <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`повторно отвори <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`посочи тази задача от ревизия <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Участник
issues.admin=Администратор
issues.collaborator=Сътрудник
issues.owner=Притежател
issues.sign_up_for_free=Регистрирай се безплатно
issues.sign_in_require_desc=за да се включите в този разговор. Вече имате профил? <a href="%s">Влезте, за да коментирате</a>
@@ -560,6 +552,8 @@ wiki.save_page=Запис на страница
wiki.last_commit_info=%s редактира тази страница %s
wiki.edit_page_button=Редакция
wiki.new_page_button=Нова страница
wiki.delete_page_button=Изтрий страница
wiki.delete_page_notice_1=Това ще изтрие страница <code>"%s"</code>. Моля, бъдете сигурни.
wiki.page_already_exists=Страница със същото име вече съществува.
wiki.pages=Страници
wiki.last_updated=Последна модификация на %s
@@ -595,6 +589,10 @@ settings.transfer_desc=Прехвърля това хранилище на др
settings.transfer_notices_1=- Вие ще загубите достъп, ако новият притежател е индивидуален потребител.
settings.transfer_notices_2=- Вие ще запазите достъпа си, ако новият притежател е организация и ако вие сте един от притежателите ѝ.
settings.transfer_form_title=Моля въведете следната информация за да потвърдите операцията:
settings.wiki_delete=Изтриване на данни на уики
settings.wiki_delete_desc=След като изтриете данни за уики, няма връщане назад. Моля, бъдете сигурни.
settings.wiki_delete_notices_1=- Това ще изтрие и ще деактивира уики за %s
settings.wiki_deletion_success=Данните за уики на това хранилище са изтрити успешно.
settings.delete=Изтрий това хранилище
settings.delete_desc=След като изтриете хранилището, няма връщане назад. Моля, бъдете сигурни.
settings.delete_notices_1=- Тази операция <strong>НЕ МОЖЕ</strong> да бъде отменена в последствие.
@@ -610,6 +608,9 @@ settings.transfer_succeed=Притежанието на хранилището
settings.confirm_delete=Потвърди изтриването
settings.add_collaborator=Добави нов сътрудник
settings.add_collaborator_success=Добавен е нов сътрудник.
settings.delete_collaborator=Премахни
settings.collaborator_deletion=Премахване на сътрудник
settings.collaborator_deletion_desc=Този потребител няма да има достъп на сътрудник до хранилището след изтриването. Желаете ли да продължите?
settings.remove_collaborator_success=Сътрудникът е премахнат.
settings.search_user_placeholder=Име на потребител...
settings.org_not_allowed_to_be_collaborator=Невъзможно добавяне на организация като сътрудник.
@@ -944,6 +945,7 @@ auths.update=Запази настройки за удостоверяване
auths.delete=Изтриване на това удостоверяване
auths.delete_auth_title=Изтрий удостоверяването
auths.delete_auth_desc=Това удостоверяване ще бъде изтрито. Желаете ли да продължите?
auths.still_in_used=Това удостоверяване все още се използва от някои потребители. Моля изтрийте ги или ги конвертирайте до друг тип на влизане първо.
auths.deletion_success=Удостоверяването е изтрито успешно!
config.server_config=Сървърни настройки
@@ -960,6 +962,19 @@ config.static_file_root_path=Път към статични файлове
config.log_file_root_path=Път към журнал
config.script_type=Тип на скрипта
config.reverse_auth_user=Потребителско име при обратно удостоверяване
config.ssh_config=SSH конфигурация
config.ssh_enabled=Активен
config.ssh_start_builtin_server=Стартирай вграден сървър
config.ssh_domain=Домейн
config.ssh_port=Порт
config.ssh_listen_port=Порт за слушане
config.ssh_root_path=Основен път
config.ssh_key_test_path=Път до ключове
config.ssh_keygen_path=Път до генератор ('ssh-keygen')
config.ssh_minimum_key_size_check=Проверка за минимален размер на ключове
config.ssh_minimum_key_sizes=Минимален размер на ключове
config.db_config=Настройки на базата данни
config.db_type=Тип
config.db_host=Сървър
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Изключи HELO
config.mailer_name=Име
config.mailer_host=Сървър
config.mailer_user=Потребител
config.send_test_mail=Изпрати тестово писмо
config.test_mail_failed=Невъзможно изпращане на тестово писмо до '%s': %v
config.test_mail_sent=Тестово писмо беше изпратено до '%s'.
config.oauth_config=OAuth конфигурация
config.oauth_enabled=Активна
config.cache_config=Конфигурация на кеша
@@ -1040,9 +1058,11 @@ create_repo=създаде хранилище <a href="%s"> %s</a>
rename_repo=преименува хранилище от <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
commit_repo=предаде към <a href="%[1]s/src/%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
create_issue=`отвори задача <a href="%s/issues/%s">%s#%[2]s"</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`затвори <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`повторно отвори <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`създаде заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`затвори заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`повторно отвори заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`коментира задача <a href="%s/issues/%s">%s#%[2]s"</a>`
merge_pull_request=`обедини заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=прехвърли хранилище <code>%s</code> към <a href="%s">%s</a>

File diff suppressed because it is too large Load Diff

View File

@@ -44,13 +44,6 @@ issues = Issues
cancel = Cancel
[search]
search = Search...
repository = Repository
user = User
issue = Issue
code = Code
[install]
install = Installation
title = Install Steps For First-time Run
@@ -140,6 +133,8 @@ issues.in_your_repos = In your repositories
[explore]
repos = Repositories
users = Users
search = Search
[auth]
create_new_account = Create New Account
@@ -162,6 +157,7 @@ reset_password = Reset Your Password
invalid_code = Sorry, your confirmation code has expired or not valid.
reset_password_helper = Click here to reset your password
password_too_short = Password length cannot be less then 6.
non_local_account = Non-local accounts cannot change passwords through Gogs.
[mail]
activate_account = Please activate your account
@@ -221,8 +217,6 @@ still_own_repo = Your account still has ownership over at least one repository,
still_has_org = Your account still has membership in at least one organization, you have to leave or delete your memberships first.
org_still_own_repo = This organization still has ownership of repositories, you must delete or transfer them first.
still_own_user = This authentication is still in use by at least one user, please remove them from the authentication and try again.
target_branch_not_exist = Target branch does not exist.
[user]
@@ -264,11 +258,10 @@ continue = Continue
cancel = Cancel
enable_custom_avatar = Enable Custom Avatar
enable_custom_avatar_helper = Disable fetch from Gravatar
choose_new_avatar = Choose new avatar
update_avatar = Update Avatar Setting
delete_current_avatar = Delete Current Avatar
uploaded_avatar_not_a_image = Uploaded file is not a image.
no_custom_avatar_available = No custom avatar available, cannot enable it.
update_avatar_success = Your avatar setting has been updated successfully.
change_password = Change Password
@@ -479,7 +472,7 @@ issues.closed_at = `closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at = `reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at = `referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster = Poster
issues.admin = Admin
issues.collaborator = Collaborator
issues.owner = Owner
issues.sign_up_for_free = Sign up for free
issues.sign_in_require_desc = to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
@@ -560,6 +553,8 @@ wiki.save_page = Save Page
wiki.last_commit_info = %s edited this page %s
wiki.edit_page_button = Edit
wiki.new_page_button = New Page
wiki.delete_page_button = Delete Page
wiki.delete_page_notice_1 = This will delete the page <code>"%s"</code>. Please be certain.
wiki.page_already_exists = Wiki page with same name already exists.
wiki.pages = Pages
wiki.last_updated = Last updated %s
@@ -595,6 +590,10 @@ settings.transfer_desc = Transfer this repository to another user or to an organ
settings.transfer_notices_1 = - You will lose access if new owner is a individual user.
settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners.
settings.transfer_form_title = Please enter following information to confirm your operation:
settings.wiki_delete = Erase Wiki Data
settings.wiki_delete_desc = Once you erase wiki data there is no going back. Please be certain.
settings.wiki_delete_notices_1 = - This will delete and disable the wiki for %s
settings.wiki_deletion_success = Repository wiki data have been erased successfully.
settings.delete = Delete This Repository
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
@@ -610,6 +609,9 @@ settings.transfer_succeed = Repository ownership has been transferred successful
settings.confirm_delete = Confirm Deletion
settings.add_collaborator = Add New Collaborator
settings.add_collaborator_success = New collaborator has been added.
settings.delete_collaborator = Delete
settings.collaborator_deletion = Collaborator Deletion
settings.collaborator_deletion_desc = This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
settings.remove_collaborator_success = Collaborator has been removed.
settings.search_user_placeholder = Search user...
settings.org_not_allowed_to_be_collaborator = Organization is not allowed to be added as a collaborator.
@@ -944,6 +946,7 @@ auths.update = Update Authentication Setting
auths.delete = Delete This Authentication
auths.delete_auth_title = Authentication Deletion
auths.delete_auth_desc = This authentication is going to be deleted, do you want to continue?
auths.still_in_used = This authentication is still used by some users, please delete or convert these users to another login type first.
auths.deletion_success = Authentication has been deleted successfully!
config.server_config = Server Configuration
@@ -960,6 +963,19 @@ config.static_file_root_path = Static File Root Path
config.log_file_root_path = Log File Root Path
config.script_type = Script Type
config.reverse_auth_user = Reverse Authentication User
config.ssh_config = SSH Configuration
config.ssh_enabled = Enabled
config.ssh_start_builtin_server = Start Builtin Server
config.ssh_domain = Domain
config.ssh_port = Port
config.ssh_listen_port = Listen Port
config.ssh_root_path = Root Path
config.ssh_key_test_path = Key Test Path
config.ssh_keygen_path = Keygen ('ssh-keygen') Path
config.ssh_minimum_key_size_check = Minimum Key Size Check
config.ssh_minimum_key_sizes = Minimum Key Sizes
config.db_config = Database Configuration
config.db_type = Type
config.db_host = Host
@@ -989,6 +1005,9 @@ config.mailer_disable_helo = Disable HELO
config.mailer_name = Name
config.mailer_host = Host
config.mailer_user = User
config.send_test_mail = Send Test Email
config.test_mail_failed = Fail to send test email to '%s': %v
config.test_mail_sent = Test email has been sent to '%s'.
config.oauth_config = OAuth Configuration
config.oauth_enabled = Enabled
config.cache_config = Cache Configuration
@@ -1043,6 +1062,8 @@ create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue = `closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue = `reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request = `created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request = `closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request = `reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request = `merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>

View File

@@ -8,7 +8,7 @@ sign_in=Iniciar sesión
sign_out=Cerrar sesión
sign_up=Suscripción
register=Registro
website=Página Web
website=Página web
version=Versión
page=Página
template=Plantilla
@@ -27,9 +27,9 @@ repository=Repositorio
organization=Organización
mirror=Mirror
new_repo=Nuevo repositorio
new_migrate=Nueva Migración
new_migrate=Nueva migración
new_mirror=Nueva réplica
new_fork=Nuevo Fork del Repositorio
new_fork=Nuevo fork del repositorio
new_org=Nueva organización
manage_org=Administrar organizaciones
admin_panel=Panel de administración
@@ -44,13 +44,6 @@ issues=Incidencias
cancel=Cancelar
[search]
search=Buscar...
repository=Repositorio
user=Usuario
issue=Incidencia
code=Código
[install]
install=Instalación
title=Pasos de la instalación por primera vez
@@ -89,8 +82,8 @@ app_url_helper=Esto afecta a las URLs para clonar por HTTP/HTTPS y a algunos cor
log_root_path=Ruta del registro
log_root_path_helper=Directorio donde almacenar los registros.
optional_title=Configuración Opcional
email_title=Configuración del Servicio de Correo
optional_title=Configuración opcional
email_title=Configuración del servicio de correo
smtp_host=SMTP Host
smtp_from=Desde
smtp_from_helper=Remitente del email, RFC 5322. Puede ser solamente una dirección de correo electrónico, o estar en el formato "Nombre" <email@example.com>.
@@ -98,10 +91,10 @@ mailer_user=Remitente del Correo Electrónico
mailer_password=Contraseña del Remitente
register_confirm=Habilitar la Confirmación en el Registro
mail_notify=Habilitar las Notificaciones de Correo
server_service_title=Configuración de Servidor y Otros Servicios
server_service_title=Configuración del servidor y otros servicios
offline_mode=Activar el modo Sin Conexión
offline_mode_popup=Desactivar el CDN incluso en el modo de producción, todos los recursos se servirán localmente.
disable_gravatar=Desactivar el Servicio Gravatar
disable_gravatar=Desactivar el servicio Gravatar
disable_gravatar_popup=Desactivar Gravatar y cualquier otra fuente personalizada. Todos los avatares deben ser cargados por los usuarios o en su defecto se mostrará el avatar predeterminado.
disable_registration=Desactivar Auto-Registro
disable_registration_popup=Desactivar auto-registro del usuario, solo el administrador podrá crear cuentas nuevas.
@@ -110,7 +103,7 @@ enable_captcha_popup=Requiere validar la captcha para el auto-registro de usuari
require_sign_in_view=Activar el Inicio de Sesión obligatorio para Ver Páginas
require_sign_in_view_popup=Solo los usuarios logados pueden ver páginas, los visitantes anónimos solo podrán ver las páginas de login/registro.
admin_setting_desc=No es necesario crear una cuenta de administrador ahora mismo, el usuario que tenga ID=1 obtendrá privilegios de administrador automáticamente.
admin_title=Configuración de la Cuenta de Administrador
admin_title=Configuración de la cuenta de administrador
admin_name=Nombre de usuario
admin_password=Contraseña
confirm_password=Confirmar Contraseña
@@ -131,7 +124,7 @@ uname_holder=Nombre de usuario o correo electrónico
password_holder=Contraseña
switch_dashboard_context=Cambiar el contexto del Dashboard
my_repos=Mis repositorios
collaborative_repos=Repositorios Colaborativos
collaborative_repos=Repositorios colaborativos
my_orgs=Mis organizaciones
my_mirrors=Mis réplicas
view_home=Ver %s
@@ -140,6 +133,8 @@ issues.in_your_repos=En tus repositorios
[explore]
repos=Repositorios
users=Usuarios
search=Buscar
[auth]
create_new_account=Crear una Nueva Cuenta
@@ -221,8 +216,6 @@ still_own_repo=Tu cuenta es la propietaria de uno o más repositorios, tienes qu
still_has_org=Tu cuenta es miembro de una o más organizaciones, tienes que abandonarlas o eliminarlas primero.
org_still_own_repo=Esta organización es dueña de uno o más repositorios, tienes que eliminarlos o transferirlos primero.
still_own_user=Esta autenticación está en uso por algunos usuarios, debes moverlos y antes de eliminarla.
target_branch_not_exist=La rama de destino no existe
[user]
@@ -250,25 +243,24 @@ orgs=Organizaciones
delete=Eliminar cuenta
uid=UUID
public_profile=Perfil Público
public_profile=Perfil público
profile_desc=Tu correo electrónico es público y será usado para todas las notificaciones relacionadas con cualquier cuenta y cualquier operación hecha a través de la web.
password_username_disabled=Los usuarios que no son locales no tienen permitido cambiar su nombre de usuario.
full_name=Nombre Completo
website=Página Web
full_name=Nombre completo
website=Página web
location=Localización
update_profile=Actualizar Perfil
update_profile=Actualizar perfil
update_profile_success=Tu perfil se ha actualizado correctamente.
change_username=Nombre de usuario modificado
change_username_prompt=Este cambio afectará a los enlaces que hacen referencia a su cuenta.
continue=Continuar
cancel=Cancelar
enable_custom_avatar=Activar Avatar Personalizado
enable_custom_avatar_helper=Activa esto para desactivar los avatares de Gravatar
enable_custom_avatar=Activar avatar personalizado
choose_new_avatar=Selecciona nuevo avatar
update_avatar=Actualizar Configuración del Avatar
update_avatar=Actualizar configuración del avatar
delete_current_avatar=Eliminar avatar
uploaded_avatar_not_a_image=El archivo enviado no es una imagen.
no_custom_avatar_available=No hay ningún avatar personalizado disponible, no se puede habilitar.
update_avatar_success=La configuración de tu avatar se ha actualizado correctamente.
change_password=Cambiar contraseña
@@ -341,7 +333,7 @@ owner=Propietario
repo_name=Nombre del repositorio
repo_name_helper=Los grandes nombres de repositorios son cortos, memorables y <strong>únicos</strong>.
visibility=Visibilidad
visiblity_helper=Este repositorio es <span class="ui red text">Privado</span>
visiblity_helper=Este repositorio es <span class="ui red text">privado</span>
visiblity_helper_forced=El administrador web ha obligado a todos los repositorios nuevos a ser <span class="ui red text"> privados</span>
visiblity_fork_helper=(Este cambio afectará a todos los forks)
clone_helper=¿Necesitas ayuda con el clone? ¡Consulta la <a target="_blank" href="%s">Ayuda</a>!
@@ -356,7 +348,7 @@ license_helper=Selecciona un fichero de licencia
readme=Readme
readme_helper=Seleccione una plantilla de archivo readme
auto_init=Inicializar los archivos seleccionados y plantillas de este repositorio
create_repo=Crear Repositorio
create_repo=Crear repositorio
default_branch=Rama por defecto
mirror_interval=Intervalo de la réplica (en horas)
mirror_address=Dirección de la réplica
@@ -369,11 +361,11 @@ form.reach_limit_of_creation=El propietario ha alcanzado el límite máximo de %
form.name_reserved=El nombre del repositorio '%s' está reservado.
form.name_pattern_not_allowed=El patrón del nombre del repositorio '%s' no está permitido.
need_auth=Requiere Autorización
migrate_type=Tipo de Migración
need_auth=Requiere autorización
migrate_type=Tipo de migración
migrate_type_helper=Este repositorio será una <span class="text blue">réplica</span>
migrate_repo=Migrar Repositorio
migrate.clone_address=Clonar Dirección
migrate.clone_address=Clonar dirección
migrate.clone_address_desc=Puede ser una URL HTTP/HTTPS/GIT o una ruta local del servidor.
migrate.permission_denied=No te está permitido importar repositorios locales.
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio.
@@ -381,7 +373,7 @@ migrate.failed=Migración fallida: %v
mirror_from=espejo de
forked_from=forked de
fork_from_self=Eres el propietario del repositorio, ¡no puedes hacer fork!
fork_from_self=¡No puedes crear un fork de un repositorio que ya es tuyo!
copy_link=Copiar
copy_link_success=¡Copiado!
copy_link_error=Presione ⌘ + C o Ctrl-C para copiar
@@ -425,7 +417,7 @@ commits.date=Fecha
commits.older=Anterior
commits.newer=Posterior
issues.new=Nueva Incidencia
issues.new=Nueva incidencia
issues.new.labels=Etiquetas
issues.new.no_label=Sin etiquetas
issues.new.clear_labels=Limpiar etiquetas
@@ -469,17 +461,17 @@ issues.open_title=Abierta
issues.closed_title=Cerrada
issues.num_comments=%d comentarios
issues.commented_at=`comentada <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.no_content=Aun no existe contenido.
issues.no_content=Aún no existe contenido.
issues.close_issue=Cerrar
issues.close_comment_issue=Comentar y cerrar
issues.reopen_issue=Reabrir
issues.reopen_comment_issue=Comentar y reabrir
issues.create_comment=Comentar
issues.closed_at=`cerrada <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`reabierta <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.closed_at=`cerró <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`reabrió <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`mencionada esta incidencia en un commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Autor
issues.admin=Administrador
issues.collaborator=Colaborador
issues.owner=Propietario
issues.sign_up_for_free=Registro gratuito
issues.sign_in_require_desc=para unirse a esta conversación. ¿Ya dispone de una cuenta? <a href="%s">Inicie sesión para comentar</a>
@@ -499,7 +491,7 @@ issues.label_deletion_success=Etiqueta borrada con éxito!
issues.num_participants=%d participantes
pulls.new=Nuevo Pull Request
pulls.compare_changes=Comparar Cambios
pulls.compare_changes=Comparar cambios
pulls.compare_changes_desc=Comparar dos ramas y generar un pull request con las diferencias.
pulls.compare_base=base
pulls.compare_compare=comparar con
@@ -513,7 +505,7 @@ pulls.merged_title_desc=fusionados %[1]d commits de <code>%[2]s</code> en <code>
pulls.tab_conversation=Conversación
pulls.tab_commits=Commits
pulls.tab_files=Archivos modificados
pulls.reopen_to_merge=Por favor reabra este pull request para proceder con la operación de fusionado.
pulls.reopen_to_merge=Por favor reabra este Pull Request para proceder con la operación de fusionado.
pulls.merged=Fuisionado
pulls.has_merged=¡Este pull request se ha completado con éxito!
pulls.data_broken=Los datos de este pull request ya no están disponibles porque se ha eliminado la información del fork.
@@ -560,6 +552,8 @@ wiki.save_page=Guardar página
wiki.last_commit_info=%s editó esta página %s
wiki.edit_page_button=Editar
wiki.new_page_button=Nueva página
wiki.delete_page_button=Eliminar página
wiki.delete_page_notice_1=Esto eliminará la página <code>"%s"</code>. Por favor, asegúrate de que es lo que quieres.
wiki.page_already_exists=Ya existe una página con el mismo nombre.
wiki.pages=Páginas
wiki.last_updated=Última actualización %s
@@ -595,6 +589,10 @@ settings.transfer_desc=Transferir este repositorio a otro usuario u organizació
settings.transfer_notices_1=- Perderá el permiso de acceso si el nuevo propietario es otro usuario.
settings.transfer_notices_2=- Conservará el privilegio de acceso si el nuevo propietario es una organización y usted es uno de los propietarios de dicha organización.
settings.transfer_form_title=Por favor introduzca esta información para confirmar la operación:
settings.wiki_delete=Eliminar datos de la wiki
settings.wiki_delete_desc=Una vez borrados los datos de la wiki no habrá vuelta atrás. Por favor, asegúrate de que es lo que quieres.
settings.wiki_delete_notices_1=- Esto eliminará y deshabilitará la wiki para %s
settings.wiki_deletion_success=Los datos de la wiki del repositorio han sido borrados correctamente.
settings.delete=Eliminar este repositorio
settings.delete_desc=Una vez has eliminado un repositorio, no hay vuelta atrás. Por favor, asegúrate de que es lo que quieres.
settings.delete_notices_1=- Esta operación <strong>NO PUEDE</strong> revertirse.
@@ -608,9 +606,12 @@ settings.transfer_owner=Nuevo Propietario
settings.make_transfer=Transferir
settings.transfer_succeed=La propiedad del repositorio ha sido transferida exitosamente.
settings.confirm_delete=Confirmar eliminación
settings.add_collaborator=Añadir Nuevo Colaborador
settings.add_collaborator_success=Se ha añadido el nuevo colaborador.
settings.remove_collaborator_success=Se ha eliminado el colaborador.
settings.add_collaborator=Añadir nuevo colaborador
settings.add_collaborator_success=El nuevo colaborador ha sido añadido.
settings.delete_collaborator=Eliminar
settings.collaborator_deletion=Eliminar colaborador
settings.collaborator_deletion_desc=Este usuario no podrá colaborar en este repositorio tras eliminarlo. ¿Desea continuar?
settings.remove_collaborator_success=El colaborador ha sido eliminado.
settings.search_user_placeholder=Buscar usuario...
settings.org_not_allowed_to_be_collaborator=Las organizaciones no tiene permitido ser añadidas como colaboradores.
settings.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
@@ -634,7 +635,7 @@ settings.githook_content=Contenido del Hook
settings.update_githook=Actualizar Hook
settings.add_webhook_desc=Enviaremos una petición <code>POST</code> a la siguiente URL con los detalles de cualquier evento suscrito. También puedes especificar qué formato de datos te gustaría recibir (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Puedes encontrar más información en la <a target="_blank" href="%s">Guía de Webhooks</a>.
settings.payload_url=URL de Payload
settings.content_type=Tipo de Contenido
settings.content_type=Tipo de contenido
settings.secret=Secreto
settings.slack_username=Nombre de usuario
settings.slack_icon_url=URL de icono
@@ -676,12 +677,12 @@ diff.browse_source=Explorar el Código
diff.parent=padre
diff.commit=commit
diff.data_not_available=Los datos del Diff no están disponibles.
diff.show_diff_stats=Mostrar Estadísticas de Diff
diff.show_diff_stats=Mostrar estadísticas de diff
diff.show_split_view=Dividir vista
diff.show_unified_view=Unificar vista
diff.stats_desc=Se han <strong>modificado %d ficheros</strong> con <strong>%d adiciones</strong> y <strong>%d borrados</strong>
diff.bin=BIN
diff.view_file=Ver Fichero
diff.view_file=Ver fichero
release.releases=Releases
release.new_release=Nueva Release
@@ -699,7 +700,7 @@ release.tag_helper=Escoge una etiqueta o crea una nueva al publicar.
release.title=Título
release.content=Contenido
release.write=Escribir
release.preview=Vista Previa
release.preview=Vista previa
release.loading=Cargando...
release.prerelease_desc=Esta es una pre-release
release.prerelease_helper=Esta release está marcada como no apta para producción.
@@ -715,8 +716,8 @@ release.tag_name_already_exist=Ya existe una Release con esta etiqueta.
release.downloads=Descargas
[org]
org_name_holder=Nombre de la Organización
org_full_name_holder=Nombre de la organización
org_name_holder=Nombre de la organización
org_full_name_holder=Nombre completo de la organización
org_name_helper=Los grandes nombres de organizaciones son cortos y memorables.
create_org=Crear Organización
repo_updated=Actualizado
@@ -725,9 +726,9 @@ invite_someone=Invitar a alguien
teams=Equipos
lower_members=miembros
lower_repositories=repositorios
create_new_team=Crear un Nuevo Equipo
create_new_team=Crear un nuevo equipo
org_desc=Descripción
team_name=Nombre del Equipo
team_name=Nombre del equipo
team_desc=Descripción
team_name_helper=Utiliza este nombre para mencionar a este equipo en las conversaciones.
team_desc_helper=¿En qué consiste este equipo?
@@ -738,8 +739,8 @@ form.name_pattern_not_allowed=El patrón de nombre de la organización '%s' no e
settings=Configuración
settings.options=Opciones
settings.full_name=Nombre Completo
settings.website=Página Web
settings.full_name=Nombre completo
settings.website=Página web
settings.location=Localización
settings.update_settings=Actualizar configuración
settings.update_setting_success=La configuración de la organización se ha actualizado correctamente.
@@ -772,24 +773,24 @@ teams.read_access=Acceso de Lectura
teams.read_access_helper=Este equipo podrá ver y clonar sus repositorios.
teams.write_access=Acceso de Escritura
teams.write_access_helper=Este equipo podrá leer sus repositorios, así como hacer push en ellos.
teams.admin_access=Acceso de Administrador
teams.admin_access=Acceso de administrador
teams.admin_access_helper=Este equipo podrá hacer push/pull en sus repositorios, así como añadir colaboradores a ellos.
teams.no_desc=Este equipo no tiene descripción
teams.settings=Configuración
teams.owners_permission_desc=Los propietarios tienen acceso completo a <strong>todos los repositorios</strong> y tienen <strong>derechos de administración</strong> en la organización.
teams.members=Miembros del Equipo
teams.members=Miembros del equipo
teams.update_settings=Actualizar configuración
teams.delete_team=Borrar este Equipo
teams.add_team_member=Añadir Miembro al Equipo
teams.delete_team_title=Eliminar Equipo
teams.delete_team=Eliminar este equipo
teams.add_team_member=Añadir miembro al equipo
teams.delete_team_title=Eliminar equipo
teams.delete_team_desc=Este equipo va a ser eliminado, ¿seguro que quieres continuar? Los miembros de este equipo pueden perder acceso a algunos repositorios.
teams.delete_team_success=El Equipo se ha eliminado correctamente.
teams.delete_team_success=El equipo ha sido eliminado correctamente.
teams.read_permission_desc=Este equipo tiene permisos de <strong>Lectura</strong>: sus miembros pueden ver y clonar los repositorios del equipo.
teams.write_permission_desc=Este equipo tiene permisos de <strong>Escritura</strong>: sus miembros pueden leer y hacer push a los repositorios del equipo.
teams.admin_permission_desc=Este equipo tiene permisos de <strong>Administración</strong>: sus miembros pueden leer, hacer push y añadir colaboradores a los repositorios del equipo.
teams.repositories=Repositorios del Equipo
teams.repositories=Repositorios del equipo
teams.search_repo_placeholder=Buscar repositorio...
teams.add_team_repository=Añadir Repositorio al Equipo
teams.add_team_repository=Añadir repositorio al equipo
teams.remove_repo=Eliminar
teams.add_nonexistent_repo=El repositorio que estás intentando añadir no existe, por favor, créalo primero.
@@ -810,7 +811,7 @@ dashboard.statistic=Estadísticas
dashboard.operations=Operaciones
dashboard.system_status=Estado del Monitor del Sistema
dashboard.statistic_info=La base de datos de Gogs contiene <b>%d</b> usuarios, <b>%d</b> organizaciones, <b>%d</b> claves públicas, <b>%d</b> repositorios, <b>%d</b> vigilados, <b>%d</b> destacados, <b>%d</b> acciones, <b>%d</b> accesos, <b>%d</b> incidencias, <b>%d</b> comentarios, <b>%d</b> cuentas de redes sociales, <b>%d</b> seguidores, <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> fuentes de login, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> etiquetas, <b>%d</b> hooks, <b>%d</b> equipos, <b>%d</b> tareas actualizadas, <b>%d</b> adjuntos.
dashboard.operation_name=Nombre de la Operación
dashboard.operation_name=Nombre de la operación
dashboard.operation_switch=Interruptor
dashboard.operation_run=Ejecutar
dashboard.clean_unbind_oauth=Limpiar solicitudes de OAuth sin confirmar
@@ -835,7 +836,7 @@ dashboard.current_goroutine=Gorutinas actuales
dashboard.current_memory_usage=Uso de memoria actual
dashboard.total_memory_allocated=Total de Memoria Reservada
dashboard.memory_obtained=Memoria Obtenida
dashboard.pointer_lookup_times=Tiempos de Búsqueda de Punteros
dashboard.pointer_lookup_times=Tiempos de búsqueda de punteros
dashboard.memory_allocate_times=Tiempos de Reserva de Memoria
dashboard.memory_free_times=Tiempos de Liberado de Memoria
dashboard.current_heap_usage=Uso de Heap actual
@@ -872,7 +873,7 @@ users.new_success=La cuenta '%s' ha sido creada con éxito.
users.edit=Editar
users.auth_source=Fuente de Autenticación
users.local=Local
users.auth_login_name=Nombre de Inicio de Sesión de Autenticación
users.auth_login_name=Nombre de Inicio de sesión de autenticación
users.password_helper=Deje el campo vacío si no desea cambiar la contraseña.
users.update_profile_success=El perfil de la cuenta se ha actualizado correctamente.
users.edit_account=Editar Cuenta
@@ -907,31 +908,31 @@ auths.name=Nombre
auths.type=Tipo
auths.enabled=Activo
auths.updated=Actualizado
auths.auth_type=Tipo de Autenticación
auths.auth_name=Nombre de Autenticación
auths.auth_type=Tipo de autenticación
auths.auth_name=Nombre de autenticación
auths.domain=Dominio
auths.host=Host
auths.port=Puerto
auths.bind_dn=Bind DN
auths.bind_password=Contraseña Bind
auths.bind_password_helper=Advertencia: La contraseña se almacena como texto plano. No utilice una cuenta con privilegios elevados.
auths.user_base=Base de Búsqueda de Usuarios
auths.user_base=Base de búsqueda de usuarios
auths.user_dn=DN de Usuario
auths.attribute_username=Atributo de nombre de usuario
auths.attribute_username_placeholder=Dejar vacío para usar el campo de inicio de sesión como nombre de usuario.
auths.attribute_name=Atributo nombre
auths.attribute_surname=Atributo apellido
auths.attribute_mail=Atributo correo electrónico
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.filter=Filtro de Usuario
auths.admin_filter=Filtro de Aministrador
auths.attributes_in_bind=Buscar atributos en el contexto del Bind DN
auths.filter=Filtro de usuario
auths.admin_filter=Filtro de aministrador
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Tipo de Autenticación SMTP
auths.smtp_auth=Tipo de autenticación SMTP
auths.smtphost=SMTP Host
auths.smtpport=Puerto SMTP
auths.allowed_domains=Dominios Permitidos
auths.allowed_domains_helper=Deje el campo vacío si no desea restringir ningún dominio. Para restringir más de uno, separe los dominios con una coma ','.
auths.enable_tls=Habilitar Cifrado TLS
auths.enable_tls=Habilitar cifrado TLS
auths.skip_tls_verify=Omitir la verificación TLS
auths.pam_service_name=Nombre del Servicio PAM
auths.enable_auto_register=Hablilitar Auto-Registro
@@ -944,9 +945,10 @@ auths.update=Actualizar la configuración de autenticación
auths.delete=Eliminar Autenticación
auths.delete_auth_title=Borrado de autenticación
auths.delete_auth_desc=Esta autenticación será eliminada. ¿Deseas continuar?
auths.still_in_used=Este método de autentificación aún es utilizado por algunos usuarios, por favor elimine o convierta estos usuarios a otro tipo de autentificación.
auths.deletion_success=¡La autenticación ha sido eliminada con éxito!
config.server_config=Configuración del Servidor
config.server_config=Configuración del servidor
config.app_name=Nombre de la Aplicación
config.app_ver=Versión de la Aplicación
config.app_url=URL de la Aplicación
@@ -960,16 +962,29 @@ config.static_file_root_path=Ruta de los Ficheros Estáticos
config.log_file_root_path=Ruta de los Ficheros de Log
config.script_type=Tipo de Script
config.reverse_auth_user=Autenticación Inversa de Usuario
config.ssh_config=Configuración SSH
config.ssh_enabled=Habilitado
config.ssh_start_builtin_server=Iniciar servidor integrado
config.ssh_domain=Dominio
config.ssh_port=Puerto
config.ssh_listen_port=Puerto de escucha
config.ssh_root_path=Ruta raíz
config.ssh_key_test_path=Ruta de la clave de prueba
config.ssh_keygen_path=Ruta del generador de claves ('ssh-keygen')
config.ssh_minimum_key_size_check=Tamaño mínimo de la clave de verificación
config.ssh_minimum_key_sizes=Tamaños de clave mínimos
config.db_config=Configuración de la Base de Datos
config.db_type=Tipo
config.db_host=Host
config.db_name=Nombre
config.db_user=Usuario
config.db_ssl_mode=Modo SSL
config.db_ssl_mode_helper=(solo para "postgres")
config.db_ssl_mode_helper=(sólo para "postgres")
config.db_path=Ruta
config.db_path_helper=(para "sqlite3" y "tidb")
config.service_config=Configuración del Servicio
config.service_config=Configuración del servicio
config.register_email_confirm=Solicitar Confirmación por Correo Electrónico
config.disable_register=Deshabilitar el Registro
config.show_registration_button=Mostrar Botón de Registro
@@ -983,12 +998,15 @@ config.webhook_config=Configuración de Webhooks
config.queue_length=Tamaño de Cola de Envío
config.deliver_timeout=Timeout de Entrega
config.skip_tls_verify=Omitir la Verificación TLS
config.mailer_config=Configuración del Mailer
config.mailer_config=Configuración del servidor de correo
config.mailer_enabled=Activado
config.mailer_disable_helo=Desactivar HELO
config.mailer_name=Nombre
config.mailer_host=Host
config.mailer_user=Usuario
config.send_test_mail=Enviar email de prueba
config.test_mail_failed=Fallo al enviar el email de prueba a '%s': %v
config.test_mail_sent=El email de prueba ha sido enviado a '%s'.
config.oauth_config=Configuración OAuth
config.oauth_enabled=Activado
config.cache_config=Configuración de la Caché
@@ -1040,9 +1058,11 @@ create_repo=creó el repositorio <a href="%s">%s</a>
rename_repo=repositorio renombrado de <code>%[1]s</code> a <a href="%[2]s">%[3]s</a>
commit_repo=hizo push a <a href="%[1]s/src/%[2]s">%[3]s</a> en <a href="%[1]s">%[4]s</a>
create_issue=`incidencia abierta <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`cerró la incidencia <a href="%s/issues/%s">%s#%[2]s"</a>`
close_issue=`cerró la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reabrió la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`creado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`cerró el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reabrió el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>

1098
conf/locale/locale_fi-FI.ini Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -44,13 +44,6 @@ issues=Tickets
cancel=Annuler
[search]
search=Rechercher...
repository=Dépôt
user=Utilisateur
issue=Ticket
code=Code
[install]
install=Installation
title=Instructions pour la première exécution
@@ -76,7 +69,7 @@ app_name=Nom de l'application
app_name_helper=Inscrivez fièrement le nom de votre organisation ici !
repo_path=Emplacement racine des dépôts
repo_path_helper=Tous les dépôts Git distants seront sauvegardés ici.
run_user=Entrer un utilisateur
run_user=Utilisateur système
run_user_helper=L'utilisateur doit avoir accès à la racine des dépôts et exécuter Gogs.
domain=Domaine
domain_helper=Cela affecte les doublons d'URL SSH.
@@ -140,6 +133,8 @@ issues.in_your_repos=Dans vos dépôts
[explore]
repos=Dépôts
users=Utilisateurs
search=Rechercher
[auth]
create_new_account=Créer un nouveau compte
@@ -221,8 +216,6 @@ still_own_repo=Votre compte comporte toujours des propriétés du dépôt. Vous
still_has_org=Votre compte contient toujours au moins une adhésion à une organisation, vous devez quitter ou supprimer votre adhésion.
org_still_own_repo=Cette organisation comporte toujours des propriétés du dépôt. Vous devez d'abord les supprimer ou les transférer.
still_own_user=Cette authentification a déjà servi à d'autres utilisateurs. Veuillez les déplacer puis supprimez à nouveau.
target_branch_not_exist=La branche cible n'existe pas.
[user]
@@ -230,8 +223,8 @@ change_avatar=Changez d'avatar via gravatar.com
change_custom_avatar=Changez votre avatar dans les paramètres
join_on=Inscrit le
repositories=Dépôts
activity=Activités publiques
followers=Abonnés
activity=Activité publique
followers=abonnés
starred=Votés
following=Abonnements
follow=Suivre
@@ -264,15 +257,14 @@ continue=Continuer
cancel=Annuler
enable_custom_avatar=Activer l'Avatar personnalisé
enable_custom_avatar_helper=Cette option désactive l'affichage via Gravatar
choose_new_avatar=Sélectionner un nouvel avatar
update_avatar=Mettre à jour l'avatar
delete_current_avatar=Supprimer l'avatar actuel
uploaded_avatar_not_a_image=Le fichier téléchargé n'est pas une image.
no_custom_avatar_available=Aucun avatar personnalisé disponible, activation impossible.
update_avatar_success=Votre avatar a été mis à jour avec succès.
change_password=Modifier le Mot de Passe
old_password=Mot de Passe actuel
change_password=Modifier le mot de passe
old_password=Mot de passe actuel
new_password=Nouveau Mot de Passe
retype_new_password=Retapez le nouveau mot de passe
password_incorrect=Mot de passe actuel incorrect.
@@ -288,10 +280,10 @@ delete_email=Supprimer
email_deletion=Suppression de l'adresse mél
email_deletion_desc=Supprimer cette adresse e-mail supprimera les informations associées à votre compte. Voulez-vous continuer ?
email_deletion_success=L'adresse mél a été supprimée avec succès !
add_new_email=Ajouter une nouvelle adresse courriel
add_email=Ajouter un courriel
add_new_email=Ajouter une nouvelle adresse e-mail
add_email=Ajouter un e-mail
add_email_confirmation_sent=Une nouvelle confirmation d'adresse e-mail a été envoyé à '%s', veuillez vérifier votre boîte de réception dans un délai de %d heures pour terminer le processus de confirmation.
add_email_success=Votre courriel a été ajouté avec succès.
add_email_success=Votre nouvelle adresse e-mail a été ajoutée avec succès.
manage_ssh_keys=Gérer les clés SSH
add_key=Ajouter une Clé
@@ -370,7 +362,7 @@ form.name_reserved=Le nom de dépôt '%s' est réservé.
form.name_pattern_not_allowed=Motif '%s' interdit pour les noms de dépôt.
need_auth=Nécessite une Autorisation
migrate_type=Type de Migration
migrate_type=Type de migration
migrate_type_helper=Ce dépôt sera un <span class="text blue"> miroir</span>
migrate_repo=Migrer le dépôt
migrate.clone_address=Adresse du clone
@@ -405,7 +397,7 @@ tree=Aborescence
filter_branch_and_tag=Filtrer une branche ou un tag
branches=Branches
tags=Tags
issues=Problèmes
issues=Tickets
pulls=Pull Requests
labels=Etiquettes
milestones=Étapes
@@ -425,7 +417,7 @@ commits.date=Date
commits.older=Précédemment
commits.newer=Récemment
issues.new=Nouveau Problème
issues.new=Nouveau ticket
issues.new.labels=Etiquettes
issues.new.no_label=Pas d'étiquette
issues.new.clear_labels=Effacer les étiquettes
@@ -450,9 +442,9 @@ issues.filter_milestone_no_select=Aucun jalon sélectionné
issues.filter_assignee=Assigné
issues.filter_assginee_no_select=Pas d'assignataire selectionné
issues.filter_type=Type
issues.filter_type.all_issues=Tous les problèmes
issues.filter_type.all_issues=Tous les tickets
issues.filter_type.assigned_to_you=Qui vous sont assignés
issues.filter_type.created_by_you=Créé(es) par vous
issues.filter_type.created_by_you=Crées par vous
issues.filter_type.mentioning_you=Vous mentionnant
issues.filter_sort=Trier
issues.filter_sort.latest=Plus récent
@@ -479,7 +471,7 @@ issues.closed_at=`fermé à <a id="%[1]s"href="#%[1]s"> %[2]s"</a>`
issues.reopened_at=`réouvert à <a id="%[1]s" href="#%[1]s"> %[2]s</a>`
issues.commit_ref_at=`a référencé ce problème à partir d'un commit <a id="%[1]s" href="#%[1]s"> %[2]s</a>`
issues.poster=Publier
issues.admin=Admin
issues.collaborator=Collaborateur
issues.owner=Propriétaire
issues.sign_up_for_free=Inscrivez-vous gratuitement
issues.sign_in_require_desc=pour rejoindre cette conversation. Vous avez déjà un compte ? <a href="%s">Connectez-vous commenter</a>
@@ -489,12 +481,12 @@ issues.save=Enregistrer
issues.label_title=Nom du Label
issues.label_color=Couleur du Label
issues.label_count=%d labels
issues.label_open_issues=%d problèmes ouverts
issues.label_open_issues=%d tickets ouverts
issues.label_edit=Éditer
issues.label_delete=Supprimer
issues.label_modify=Modification du Label
issues.label_deletion=Suppression du Label
issues.label_deletion_desc=Cette opération supprimera également toutes les informations relatives aux problèmes. Voulez-vous continuer ?
issues.label_deletion_desc=Cette opération supprimera également toutes les informations relatives aux tickets. Voulez-vous continuer ?
issues.label_deletion_success=Label supprimé avec succès !
issues.num_participants=%d Participants
@@ -531,7 +523,7 @@ milestones.closed=%s fermé
milestones.no_due_date=Aucune date d'échéance
milestones.open=Ouvrir
milestones.close=Fermer
milestones.new_subheader=Créez des jalons pour organiser vos problèmes.
milestones.new_subheader=Créez des jalons pour organiser vos tickets.
milestones.create=Créer un Jalon
milestones.title=Titre
milestones.desc=Description
@@ -545,7 +537,7 @@ milestones.cancel=Annuler
milestones.modify=Modifier le Jalon
milestones.edit_success=Le Jalon '%s' a été modifié avec succès !
milestones.deletion=Supprimer le Jalon
milestones.deletion_desc=Supprimer ce Jalon effacera ses informations dans tous les problèmes relatifs. Voulez-vous continuer ?
milestones.deletion_desc=Supprimer ce jalon effacera ses informations dans tous les tickets relatifs. Voulez-vous continuer ?
milestones.deletion_success=Le Jalon a été supprimé avec succès !
wiki=Wiki
@@ -560,6 +552,8 @@ wiki.save_page=Enregistrer la page
wiki.last_commit_info=%s a édité cette page %s
wiki.edit_page_button=Modifier
wiki.new_page_button=Nouvelle Page
wiki.delete_page_button=Supprimer la page
wiki.delete_page_notice_1=Cela supprimera la page <code>"%s"</code>. Soyez-en sûr.
wiki.page_already_exists=Une page de wiki avec le même nom existe déjà.
wiki.pages=Pages
wiki.last_updated=Dernière mise à jour: %s
@@ -587,7 +581,7 @@ settings.danger_zone=Zone de danger
settings.new_owner_has_same_repo=Le nouveau propriétaire a déjà un dépôt nommé ainsi.
settings.convert=Convertir en dépôt ordinaire
settings.convert_desc=Vous pouvez convertir ce miroir en dépôt ordinaire. Cela ne peut pas être inversée.
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
settings.convert_notices_1=- Cette opération va convertir ce dépôt miroir en un dépôt standard et ne peut être annulée.
settings.convert_confirm=Confirmer la conversion
settings.convert_succeed=Le dépôt a été converti avec succès en dépôt ordinaire.
settings.transfer=Changer de propriétaire
@@ -595,10 +589,14 @@ settings.transfer_desc=Transférer ce dépôt à un autre utilisateur ou une org
settings.transfer_notices_1=-Vous perdrez l'accès si le nouveau propriétaire est un utilisateur individuel.
settings.transfer_notices_2=- Vous conserverez l'accès si le nouveau propriétaire est une organisation et que vous y appartenez.
settings.transfer_form_title=Veuillez recopier le texte suivant afin de confirmer votre opération :
settings.wiki_delete=Effacer les données du Wiki
settings.wiki_delete_desc=Une fois que vous effacez les données du wiki, on ne peut revenir en arrière. Soyez-en sûr.
settings.wiki_delete_notices_1=- Cela va supprimer et désactiver le wiki pour %s
settings.wiki_deletion_success=Le dépôt de données wiki ont été effacés avec succès.
settings.delete=Supprimer ce dépôt
settings.delete_desc=Attention, cette action est action irréversible. Soyez sûr de vous.
settings.delete_notices_1=- Cette opération <strong>ne peut pas </strong> être annulée.
settings.delete_notices_2=- Cette opération supprimera définitivement le dépôt, y compris les données Git, les issues, les commentaires et les accès des collaborateurs.
settings.delete_notices_2=- Cette opération supprimera définitivement le dépôt, y compris les données Git, les tickets, les commentaires et les accès des collaborateurs.
settings.delete_notices_fork_1=- Si ce dépôt est public, tous les forks vont devenir indépendant après sa suppression.
settings.delete_notices_fork_2=-Si ce dépôt est privé, tous les forks seront supprimés en même temps.
settings.delete_notices_fork_3=-Si vous souhaitez conserver tous les forks après suppression, veuillez tout d'abord modifier la visibilité de ce dépôt en public.
@@ -610,9 +608,12 @@ settings.transfer_succeed=Le contrôle du dépôt a été transféré avec succ
settings.confirm_delete=Confirmer la suppression
settings.add_collaborator=Ajouter un collaborateur
settings.add_collaborator_success=Nouveau collaborateur ajouté.
settings.delete_collaborator=Supprimer
settings.collaborator_deletion=Suppression d'un collaborateur
settings.collaborator_deletion_desc=Cet utilisateur n'aura plus accès pour collaborer à ce dépôt après sa suppression. Voulez-vous continuer?
settings.remove_collaborator_success=Collaborateur supprimé.
settings.search_user_placeholder=Rechercher un utilisateur...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.org_not_allowed_to_be_collaborator=Une organisation n'est pas autorisée à être ajoutée en tant que collaborateur.
settings.user_is_org_member=Cet utilisateur ne peut pas être ajouté en tant que collaborateur car il fait partie d'une organisation.
settings.add_webhook=Ajouter un Webhook
settings.hooks_desc=Les Webhooks sont des déclencheurs de POST HTTP . Lorsque qu'un événement se produit dans Gogs, une notification sera envoyée vers l'hôte cible préalablement spécifié. Apprenez-en davantage dans le <a target="_blank" href="%s">Guide des Webhooks</a>.
@@ -809,7 +810,7 @@ total=Total : %d
dashboard.statistic=Statistiques
dashboard.operations=Opérations
dashboard.system_status=État du système
dashboard.statistic_info=La base de données Gogs contient <b>%d</b> utilisateurs, <b>%d</b> organisations, <b>%d</b> clés publiques, <b>%d</b> dépôts, <b>%d</b> surveillances de dépôts, <b>%d</b> votes, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> problèmes, <b>%d</b> commentaires, <b>%d</b> comptes de réseaux sociaux, <b>%d</b> abonnements, <b>%d</b> miroirs, <b>%d</b> versions, <b>%d</b> connexions d'origine, <b>%d</b> webhooks, <b>%d</b> versions, <b>%d</b> labels, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jour, <b>%d</b> fichiers.
dashboard.statistic_info=La base de données Gogs contient <b>%d</b> utilisateurs, <b>%d</b> organisations, <b>%d</b> clés publiques, <b>%d</b> dépôts, <b>%d</b> surveillances de dépôts, <b>%d</b> votes, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes de réseaux sociaux, <b>%d</b> abonnements, <b>%d</b> miroirs, <b>%d</b> versions, <b>%d</b> connexions d'origine, <b>%d</b> webhooks, <b>%d</b> versions, <b>%d</b> labels, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jour, <b>%d</b> fichiers.
dashboard.operation_name=Nom de l'Opération
dashboard.operation_switch=Basculer
dashboard.operation_run=Exécuter
@@ -899,7 +900,7 @@ repos.name=Nom
repos.private=Privé
repos.watches=Suivi par
repos.stars=Votes
repos.issues=Problèmes
repos.issues=Tickets
auths.auth_manage_panel=Panel d'administration des authentifications
auths.new=Ajouter une nouvelle source d'authentification
@@ -922,7 +923,7 @@ auths.attribute_username_placeholder=Laisser vide pour utiliser la valeur du for
auths.attribute_name=Attribut du prénom
auths.attribute_surname=Attribut du nom de famille
auths.attribute_mail=Attribut de l'e-mail
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.attributes_in_bind=Aller chercher les attributs dans le contexte de liaison DN
auths.filter=Filtre utilisateur
auths.admin_filter=Filtre administrateur
auths.ms_ad_sa=Ms Ad SA
@@ -944,6 +945,7 @@ auths.update=Mettre à jour les paramètres d'authentifications
auths.delete=Supprimer cette authentification
auths.delete_auth_title=Suppression de l'authentification
auths.delete_auth_desc=Cette authentification va être supprimée. voulez-vous continuer ?
auths.still_in_used=Cette authentification est encore utilisée par d'autres utilisateurs, supprimez-les ou convertir ces utilisateurs vers un autre type de session, avant.
auths.deletion_success=L'authentification a été supprimée avec succès !
config.server_config=Configuration du Serveur
@@ -953,13 +955,26 @@ config.app_url=URL de l'application
config.domain=Domaine
config.offline_mode=Mode hors-ligne
config.disable_router_log=Désactiver la Journalisation du Routeur
config.run_user=Entrer un Utilisateur
config.run_user=Utilisateur système
config.run_mode=Mode d'Éxécution
config.repo_root_path=Emplacement des Dépôts
config.static_file_root_path=Chemin statique des fichiers racines
config.log_file_root_path=Emplacement Racine du Fichier Journal
config.script_type=Type de Script
config.reverse_auth_user=Annuler l'Authentification de l'Utilisateur
config.ssh_config=Configuration SSH
config.ssh_enabled=Activé
config.ssh_start_builtin_server=Démarrer le serveur intégré
config.ssh_domain=Domaine
config.ssh_port=Port
config.ssh_listen_port=Port d'écoute
config.ssh_root_path=Emplacement racine
config.ssh_key_test_path=Chemin de test des clés
config.ssh_keygen_path=Chemin vers le générateur de clefs ("ssh-keygen")
config.ssh_minimum_key_size_check=Vérification de la longueur de clé minimale
config.ssh_minimum_key_sizes=Tailles de clé minimales
config.db_config=Configuration de la Base de Données
config.db_type=Type
config.db_host=Hôte
@@ -970,11 +985,11 @@ config.db_ssl_mode_helper=("postgres" uniquement)
config.db_path=Emplacement
config.db_path_helper=(pour « sqlite3 » et « TIDB »)
config.service_config=Configuration du Service
config.register_email_confirm=Nécessite une confirmation par courriel
config.register_email_confirm=Nécessite une confirmation par e-mail
config.disable_register=Désactiver les inscriptions
config.show_registration_button=Afficher le bouton d'enregistrement
config.require_sign_in_view=Connexion obligatoire pour visualiser
config.mail_notify=Mailer les Notifications
config.mail_notify=Notifier par mail
config.disable_key_size_check=Désactiver la vérification de la taille de clé minimale
config.enable_captcha=Activez le Captcha
config.active_code_lives=Limites de Code Actif
@@ -983,12 +998,15 @@ config.webhook_config=Configuration Webhook
config.queue_length=Longueur de la file d'attente
config.deliver_timeout=Expiration d'Envoi
config.skip_tls_verify=Ne pas vérifier TLS
config.mailer_config=Configuration du Maileur
config.mailer_config=Configuration du service de mail
config.mailer_enabled=Activé
config.mailer_disable_helo=Désactiver HELO
config.mailer_name=Nom
config.mailer_host=Hôte
config.mailer_user=Utilisateur
config.send_test_mail=Envoyer courriel de Test
config.test_mail_failed=Impossible d'envoyer un e-mail de test à '%s': %v
config.test_mail_sent=Un e-mail de test à été envoyé à '%s'.
config.oauth_config=Configuration OAuth
config.oauth_enabled=Activé
config.cache_config=Configuration du Cache
@@ -1040,9 +1058,11 @@ create_repo=a créé le dépôt <a href="%s">%s</a>
rename_repo=rebaptisé le dépôt de <code>%[1]s</code> à <a href="%[2]s">%[3]s</a>
commit_repo=a soumis à <a href="%[1]s/src/%[2]s">%[3]s</a> sur <a href="%[1]s">%[4]s</a>
create_issue=`a ouvert un problème <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`tickets clos <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`tickets ré-ouverts <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`pull request créée le <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`pull request fermé <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`pull request ré-ouverte <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`a commenté le problème <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`pull request fusionné le <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=a transféré le dépôt <code>%s</code> à <a href="%s">%s</a>

View File

@@ -38,19 +38,12 @@ settings=Impostazioni
your_profile=Il tuo profilo
your_settings=Impostazioni
activities=Activities
activities=Attivitá
pull_requests=Pull Request
issues=Problemi
cancel=Annulla
[search]
search=Ricerca...
repository=Repository
user=Utente
issue=Problema
code=Codice
[install]
install=Installazione
title=Passi d'installazione per il primo avvio
@@ -65,7 +58,7 @@ db_name=Nome del database
db_helper=Utilizza il motore INNODB con codifica utf8_general_ci per MySQL.
ssl_mode=Modalità SSL
path=Percorso
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
sqlite_helper=Il path assoluto per il database SQLite3 o TiDB. <br>Per favore usa il path assoluto quando lo avvii come servizio.
err_empty_db_path=Il percorso file del database SQLite3 o TiDB non può essere vuoto.
err_invalid_tidb_name=Il nome del database TiDB non ammette caratteri "." e "-".
no_admin_and_disable_registration=Non puoi disabilitare la registrazione senza aver creato un amministratore.
@@ -79,15 +72,15 @@ repo_path_helper=Tutti i repository Git remoti saranno salvati in questa directo
run_user=Esegui con l'utente
run_user_helper=L'utente deve avere accesso al percorso root del repository e avviare Gogs.
domain=Dominio
domain_helper=Questo modifica lo SSH clone URLs.
domain_helper=Questo influisce sugli URL per il clonaggio via SSH.
ssh_port=Porta SSH
ssh_port_helper=Numero di porta utilizzato dal server SSH, lasciare vuoto per disabilitare l'integrazione SSH.
http_port=Porta HTTP
http_port_helper=Porta di ascolto dell'applicazione.
app_url=URL Applicazione
app_url_helper=Questo influisce sugli URL per il clonaggio via HTTP/HTTPS e da qualche parte nella posta elettronica.
log_root_path=Log Path
log_root_path_helper=Directory to write log files to.
log_root_path=Percorso dei log
log_root_path_helper=Directory in cui scrivere i file di log.
optional_title=Impostazioni Facoltative
email_title=Impostazioni E-mail
@@ -140,6 +133,8 @@ issues.in_your_repos=Nei tuoi repository
[explore]
repos=Repository
users=Utenti
search=Cerca
[auth]
create_new_account=Crea un nuovo Account
@@ -221,8 +216,6 @@ still_own_repo=Il tuo account possiede ancora almeno un repository, dovete prima
still_has_org=Il tuo account è ancora associato ad almeno un'organizzazione, disassociarsi prima.
org_still_own_repo=Questa organizzazione ha ancora la proprietà del repository, dovete cancellarla o trasferirli prima.
still_own_user=Questa autenticazione è ancora in uso da almeno un utente, per favore rimuovili dall'autenticazione e riprova.
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
[user]
@@ -264,11 +257,10 @@ continue=Continua
cancel=Annulla
enable_custom_avatar=Abilita avatar personalizzato
enable_custom_avatar_helper=Seleziona per disabilitare il fetch da Gravatar
choose_new_avatar=Scegli un nuovo avatar
update_avatar=Aggiorna le impostazioni avatar
delete_current_avatar=Elimina Avatar attuale
uploaded_avatar_not_a_image=Il file caricato non è un'immagine.
no_custom_avatar_available=Nessun avatar personalizzato disponibile, impossibile abilitarlo.
update_avatar_success=Le tue impostazioni avatar sono state aggiornate con successo.
change_password=Cambia Password
@@ -469,7 +461,7 @@ issues.open_title=Aperto
issues.closed_title=Chiuso
issues.num_comments=%d commenti
issues.commented_at=`commented <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.no_content=There is no content yet.
issues.no_content=Non ci sono ancora contenuti.
issues.close_issue=Chiudi
issues.close_comment_issue=Commenta e chiudi
issues.reopen_issue=Riapri
@@ -479,12 +471,12 @@ issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Autore
issues.admin=Amministratore
issues.collaborator=Collaboratori
issues.owner=Proprietario
issues.sign_up_for_free=Registrati gratuitamente
issues.sign_in_require_desc=to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
issues.sign_in_require_desc=per partecipare a questa conversazione. Possiedi già un account?<a href="%s">Fai il login per commentare</a>
issues.edit=Modifica
issues.cancel=Cancel
issues.cancel=Annulla
issues.save=Salva
issues.label_title=Nome etichetta
issues.label_color=Colore etichetta
@@ -496,47 +488,47 @@ issues.label_modify=Modifica Etichetta
issues.label_deletion=Elimina Etichetta
issues.label_deletion_desc=Eliminare l'etichetta rimuovera le sue informazioni in tutti i problemi correlati. Vuoi continuare?
issues.label_deletion_success=Etichetta eliminata con successo!
issues.num_participants=%d Participants
issues.num_participants=%d Partecipanti
pulls.new=Nuova Pull Request
pulls.compare_changes=Confronta le modifiche
pulls.compare_changes_desc=Confronta due branch e fai una pull request per le modifiche.
pulls.compare_base=base
pulls.compare_compare=confronta
pulls.filter_branch=Filter branch
pulls.filter_branch=Filtra branch
pulls.no_results=Nessun risultato trovato.
pulls.nothing_to_compare=There is nothing to compare because base and head branches are even.
pulls.has_pull_request=`There is already a pull request between these two targets: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
pulls.nothing_to_compare=Non c'è niente da confrontare perchè i branch base e head uguali.
pulls.has_pull_request=`E' già presente una pull request tra questi due trargets: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
pulls.create=Crea Pull Request
pulls.title_desc=wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code>
pulls.merged_title_desc=merged %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> %[4]s
pulls.tab_conversation=Conversazione
pulls.tab_commits=Commits
pulls.tab_commits=Commit
pulls.tab_files=File modificati
pulls.reopen_to_merge=Riapri questa pull request per effettuare il merge.
pulls.merged=Merged
pulls.has_merged=This pull request has been merged successfully!
pulls.data_broken=Data of this pull request has been broken due to deletion of fork information.
pulls.is_checking=The conflict checking is still in progress, please refresh page in few moments.
pulls.can_auto_merge_desc=This pull request can be merged automatically.
pulls.cannot_auto_merge_desc=This pull request can't be merged automatically because there are conflicts.
pulls.merged=Unito
pulls.has_merged=Questa pull reqeust è stata mergiata con successo!
pulls.data_broken=I dati di questa pull request si sono rotti causa dell'eliminazione delle informazioni di fork.
pulls.is_checking=Il controllo dei conflitti è ancora in corso, per favore aggiorna pagina tra qualche istante.
pulls.can_auto_merge_desc=La pull request non può essere mergiata automaticamente.
pulls.cannot_auto_merge_desc=Questa pull request non può essere mergiata automaticamente perchè ci sono dei conflitti.
pulls.cannot_auto_merge_helper=Effettua il merge manualmente per risolvere i conflitti.
pulls.merge_pull_request=Unisci Pull Request
pulls.open_unmerged_pull_exists=`You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
milestones.new=Nuova Milestone
milestones.open_tab=%d Open
milestones.close_tab=%d Closed
milestones.closed=Closed %s
milestones.no_due_date=No due date
milestones.open=Open
milestones.close=Close
milestones.new_subheader=Create milestones to organize your issues.
milestones.open_tab=%d Aperti
milestones.close_tab=%d Chiusi
milestones.closed=Chiuso %s
milestones.no_due_date=Nessuna data di scadenza
milestones.open=Apri
milestones.close=Chiudi
milestones.new_subheader=Crea delle milestones per organizzare le tue issues.
milestones.create=Crea Milestone
milestones.title=Titolo
milestones.desc=Descrizione
milestones.due_date=Data di scadenza (opzionale)
milestones.clear=Clear
milestones.clear=Pulisci
milestones.invalid_due_date_format=Il formato della data di scadenza non è valido, deve essere 'yyyy-mm-dd'.
milestones.create_success=La Milestone '%s' è stata creata con successo!
milestones.edit=Modifica Milestone
@@ -560,6 +552,8 @@ wiki.save_page=Salva pagina
wiki.last_commit_info=%s ha modificato questa pagina %s
wiki.edit_page_button=Modifica
wiki.new_page_button=Nuova pagina
wiki.delete_page_button=Cancella Pagina
wiki.delete_page_notice_1=Questo cancellerà lapagina <code>"%s"</code>. Si prega di esserne certi.
wiki.page_already_exists=Esiste già una pagina Wiki con questo stesso nome.
wiki.pages=Pagine
wiki.last_updated=Ultimo aggiornamento: %s
@@ -578,30 +572,34 @@ settings.wiki_desc=Abilitare il wiki per consentire alle persone di scrivere doc
settings.use_external_wiki=Usa Wiki esterno
settings.external_wiki_url=URL Wiki esterno
settings.external_wiki_url_desc=I visitatori verranno reindirizzati all'URL quando cliccano sulla scheda.
settings.issues_desc=Enable builtin lightweight issue tracker
settings.issues_desc=Abilita l'issue tracker builtin leggero
settings.use_external_issue_tracker=Utilizza gestore di problemi esterno
settings.tracker_url_format=External Issue Tracker URL Format
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
settings.pulls_desc=Enable pull requests to accept public contributions
settings.pulls_desc=Abilita le pull requests per accettare contributi pubblici
settings.danger_zone=Zona Pericolosa
settings.new_owner_has_same_repo=Il nuovo proprietario ha già un repository con lo stesso nome. Per favore scegli un altro nome.
settings.convert=Convert To Regular Repository
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
settings.convert_confirm=Confirm Conversion
settings.convert=Converti in Repository Regolare
settings.convert_desc=Puoi convertire questo mirror in un repository regolare. Questa operazione non può essere annullata.
settings.convert_notices_1=- Questa operazione non potrà essere annullata e convertirà questo mirror in un repository regolare.
settings.convert_confirm=Conferma la conversione
settings.convert_succeed=Repository has been converted to regular type successfully.
settings.transfer=Trasferisci proprietà
settings.transfer_desc=Trasferisci questa repository a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore.
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
settings.transfer_form_title=Per favore inserisci le informazioni seguenti per confermare l'operazione:
settings.wiki_delete=Elimina i dati della Wiki
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
settings.wiki_deletion_success=I dati della wiki del repository sono stati eliminati con successo.
settings.delete=Elimina questo repository
settings.delete_desc=Una volta che hai cancellato il repository, non puoi tornare indietro. Si prega di fare attenzione.
settings.delete_notices_1=-Questa operazione <strong>NON PUÒ</strong> essere annullata.
settings.delete_notices_2=-Questa operazione eliminerà definitivamente il tutto il contenuto del repository, inclusi i dati di Git, incidenti, commenti e accessi dei collaboratori.
settings.delete_notices_fork_1=-Se questo repository è pubblico, tutti i fork diventeranno indipendenti dopo la sua cancellazione.
settings.delete_notices_fork_2=-Se questo repository è privato, tutti fork verranno rimossi assieme ad esso.
settings.delete_notices_fork_3=- If you want to keep all forks after deletion, please change visibility of this repository to public first.
settings.delete_notices_fork_3=- Se vuoi mantenere i forks dopo la cancellazione, per piacere cambia la visibilità di questo repository in pubblica.
settings.deletion_success=Il repository è stato eliminato con successo!
settings.update_settings_success=Le opzioni repository sono state aggiornate con successo.
settings.transfer_owner=Nuovo Proprietario
@@ -610,20 +608,23 @@ settings.transfer_succeed=Proprietà del repository trasferita con successo.
settings.confirm_delete=Conferma eliminazione
settings.add_collaborator=Aggiungi nuovo collaboratore
settings.add_collaborator_success=Il nuovo collaboratore è stato aggiunto.
settings.delete_collaborator=Elimina
settings.collaborator_deletion=Eliminazione collaboratore
settings.collaborator_deletion_desc=Questo utente non potrà più collaborare a questo repository dopo l'eliminazione. Si desidera continuare?
settings.remove_collaborator_success=Il collaboratore è stato rimosso.
settings.search_user_placeholder=Cerca utente...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.org_not_allowed_to_be_collaborator=Un'organizzazione non può essere aggiunta come collaboratore.
settings.user_is_org_member=L'utente è un membro dell'organizzazione che non può essere aggiunto come collaboratore.
settings.add_webhook=Aggiungi Webhook
settings.hooks_desc=I Webhooks sono molto simili a un basilare evento trigger HTTP POST. Ogni volta che qualcosa si verifica in Gogs, tratteremo la notifica all'host di destinazione specificato. Ulteriori informazioni in questa <a target="_blank" href="%s">Guida ai Webhooks</a>.
settings.webhook_deletion=Elimina Webhook
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
settings.webhook_deletion_success=Webhook has been deleted successfully!
settings.webhook.test_delivery=Test Delivery
settings.webhook.test_delivery=Test di consegna
settings.webhook.test_delivery_desc=Send a fake push event delivery to test your webhook settings
settings.webhook.test_delivery_success=Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
settings.webhook.request=Request
settings.webhook.response=Response
settings.webhook.request=Richiesta
settings.webhook.response=Risposta
settings.webhook.headers=Headers
settings.webhook.payload=Payload
settings.webhook.body=Body
@@ -636,17 +637,17 @@ settings.add_webhook_desc=Gogs manderà una richiesta <code>POST</code> all'URL
settings.payload_url=Payload URL
settings.content_type=Content Type
settings.secret=Secret
settings.slack_username=Username
settings.slack_username=Nome utente
settings.slack_icon_url=URL icona
settings.slack_color=Color
settings.slack_color=Colore
settings.event_desc=Quali eventi dovrebbero innescare questo webhook?
settings.event_push_only=Solo l'evento <code>push</code>.
settings.event_send_everything=I need <strong>everything</strong>.
settings.event_choose=Let me choose what I need.
settings.event_create=Create
settings.event_create_desc=Branch, or tag created
settings.event_send_everything=Ho bisogno di <strong>tutto</strong>.
settings.event_choose=Lasciami scegliere ciò di cui ho bisogno.
settings.event_create=Crea
settings.event_create_desc=Branch, o tag creato
settings.event_push=Push
settings.event_push_desc=Git push to a repository
settings.event_push_desc=Git push in un repository
settings.active=Attivo
settings.active_helper=Anche i dettagli riguardanti l'evento che ha innescato l'hook saranno inviati.
settings.add_hook_success=Il nuovo webhook è stato aggiunto.
@@ -660,25 +661,25 @@ settings.slack_token=Token
settings.slack_domain=Dominio
settings.slack_channel=Canale
settings.deploy_keys=Dispiega Chiavi
settings.add_deploy_key=Add Deploy Key
settings.deploy_key_desc=Deploy keys have read-only access. They are not the same as personal account SSH keys.
settings.no_deploy_keys=You haven't added any deploy keys.
settings.title=Title
settings.deploy_key_content=Content
settings.key_been_used=Deploy key content has been used.
settings.key_name_used=Deploy key with the same name already exists.
settings.add_key_success=New deploy key '%s' has been added successfully!
settings.deploy_key_deletion=Delete Deploy Key
settings.deploy_key_deletion_desc=Deleting this deploy key will remove all related accesses for this repository. Do you want to continue?
settings.deploy_key_deletion_success=Deploy key has been deleted successfully!
settings.add_deploy_key=Aggiungi Deploy Key
settings.deploy_key_desc=Le deploy keys hanno accesso in sola lettura. Non equivalgono alle chiavi SSH personali.
settings.no_deploy_keys=Non hai aggiunto alcuna deploy key.
settings.title=Titolo
settings.deploy_key_content=Contenuto
settings.key_been_used=La deploy key è già in uso.
settings.key_name_used=Esiste già una deploy key con questo nome.
settings.add_key_success=La nuova deploy key '%s' è stata aggiunta con successo!
settings.deploy_key_deletion=Elimina Deploy Key
settings.deploy_key_deletion_desc=Cancellando questa deploy key verrà rismosso ogni accesso relativo a questa repository. Vuoi continuare?
settings.deploy_key_deletion_success=Deploy key eliminata con successo!
diff.browse_source=Sfoglia il codice sorgente
diff.parent=parent
diff.commit=commit
diff.data_not_available=Diff Data non disponibile.
diff.show_diff_stats=Mostra Diff Stats
diff.show_split_view=Split View
diff.show_unified_view=Unified View
diff.show_split_view=Visualizzazione separata
diff.show_unified_view=Visualizzazione unificata
diff.stats_desc=<strong>%d ha cambiato i file</strong> con <strong>%d aggiunte</strong> e <strong>%d eliminazioni</strong>
diff.bin=BIN
diff.view_file=Vedi File
@@ -696,27 +697,27 @@ release.edit_subheader=Detailed change log can help users understand what has be
release.tag_name=Nome tag
release.target=Obbiettivo
release.tag_helper=Scegli un tag esistente o crea un nuovo tag una volta pubblicato.
release.title=Title
release.content=Content
release.title=Titolo
release.content=Contenuto
release.write=Scrivi
release.preview=Anteprima
release.loading=Caricamento...
release.prerelease_desc=Questo è un pre-rilascio
release.prerelease_helper=Precisiamo che questo rilascio non è pronta per la produzione.
release.cancel=Cancel
release.cancel=Annulla
release.publish=Pubblica Rilascio
release.save_draft=Salva Bozza
release.edit_release=Modifica Rilascio
release.delete_release=Delete This Release
release.deletion=Release Deletion
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
release.deletion_success=Release has been deleted successfully!
release.delete_release=Cancela questa Release
release.deletion=Eliminazione Release
release.deletion_desc=Eliminando questa release cancellarai anche i tag Git corrispondenti. Vuoi continuare?
release.deletion_success=La release è stata eliminata con successo!
release.tag_name_already_exist=Un rilascio con questo tag esiste già.
release.downloads=Download
[org]
org_name_holder=Nome dell'Organizzazione
org_full_name_holder=Organization Full Name
org_full_name_holder=Nome completo dell'organizzazione
org_name_helper=Le migliori organizzazioni hanno nomi brevi e memorabili.
create_org=Crea Organizzazione
repo_updated=Aggiornato
@@ -743,7 +744,7 @@ settings.website=Sito Web
settings.location=Residenza
settings.update_settings=Aggiorna Impostazioni
settings.update_setting_success=Impostazioni dell'organizzazione aggiornate con successo.
settings.change_orgname_prompt=This change will affect how links relate to the organization.
settings.change_orgname_prompt=Questa operazione modificherà il modo in cui i links sono in relazione con l'organizzazione.
settings.update_avatar_success=Organization avatar setting has been updated successfully.
settings.delete=Elimina organizzazione
settings.delete_account=Elimina questa organizzazione
@@ -758,7 +759,7 @@ members.public=Pubblico
members.public_helper=rendi privato
members.private=Privato
members.private_helper=rendi pubblico
members.member_role=Member Role:
members.member_role=Ruolo del membro:
members.owner=Proprietario
members.member=Membro
members.remove=Rimuovere
@@ -788,7 +789,7 @@ teams.read_permission_desc=Questo Team concede accesso di <strong>Lettura</stron
teams.write_permission_desc=Questo Team concede accesso di <strong>Scrittura</strong>: i membri possono leggere e pushare i repository del Team.
teams.admin_permission_desc=Questo Team concede accesso di <strong>Amministratore</strong>: i membri possono leggere i, pushare a, e aggiungere collaboratori ai repository del Team.
teams.repositories=Repository di Squadra
teams.search_repo_placeholder=Search repository...
teams.search_repo_placeholder=Cerca repository...
teams.add_team_repository=Aggiungere Repository di Squadra
teams.remove_repo=Rimuovi
teams.add_nonexistent_repo=Il repository che stai tentando di aggiungere non esiste, crealo prima.
@@ -802,8 +803,8 @@ authentication=Autenticazioni
config=Configurazione
notices=Avvisi di sistema
monitor=Monitoraggio
first_page=First
last_page=Last
first_page=Prima
last_page=Ultima
total=Totale: %d
dashboard.statistic=Statistiche
@@ -876,8 +877,8 @@ users.auth_login_name=Authentication Login Name
users.password_helper=Leave it empty to remain unchanged.
users.update_profile_success=Profilo dell'account aggiornato con successo.
users.edit_account=Modifica Account
users.max_repo_creation=Maximum Repository Creation Limit
users.max_repo_creation_desc=(Set -1 to use global default limit)
users.max_repo_creation=Limite massimo per la creazione di Repository
users.max_repo_creation_desc=(Inserire -1 per usare il limite globale di default)
users.is_activated=Questo account è attivato
users.is_admin=Questo account ha permessi di amministratore
users.allow_git_hook=Questo account ha il permesso di creare hooks di Git
@@ -902,48 +903,49 @@ repos.stars=Voti
repos.issues=Problemi
auths.auth_manage_panel=Authentication Manage Panel
auths.new=Add New Source
auths.new=Aggiungi Nuova Origine
auths.name=Nome
auths.type=Tipo
auths.enabled=Attivo
auths.updated=Aggiornato
auths.auth_type=Authentication Type
auths.auth_name=Authentication Name
auths.auth_type=Tipo di autenticazione
auths.auth_name=Nome di autenticazione
auths.domain=Dominio
auths.host=Host
auths.port=Porta
auths.bind_dn=Bind DN
auths.bind_password=Bind Password
auths.bind_password_helper=Warning: This password is stored in plain text. Do not use a high privileged account.
auths.bind_dn=Binda DN
auths.bind_password=Binda Password
auths.bind_password_helper=Attenzione: Questa password è salvata in chiaro. Non usare su un acount con alti privilegi.
auths.user_base=User Search Base
auths.user_dn=User DN
auths.attribute_username=Username attribute
auths.user_dn=DN dell'utente
auths.attribute_username=Attributo username
auths.attribute_username_placeholder=Leave empty to use sign-in form field value for user name.
auths.attribute_name=Attributo Nome
auths.attribute_surname=Attributo Cognome
auths.attribute_mail=Attributo Email
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.filter=User Filter
auths.admin_filter=Admin Filter
auths.filter=Fitro utente
auths.admin_filter=Filtro Amministratore
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP Authentication Type
auths.smtp_auth=Tipo di autenticazione SMTP
auths.smtphost=Host SMTP
auths.smtpport=Porta SMTP
auths.allowed_domains=Allowed Domains
auths.allowed_domains=Domini consentiti
auths.allowed_domains_helper=Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','.
auths.enable_tls=Abilitare Crittografia TLS
auths.skip_tls_verify=Salta verifica TLS
auths.pam_service_name=Nome del Servizio PAM
auths.enable_auto_register=Abilitare Registrazione Automatica
auths.tips=Consigli
auths.edit=Edit Authentication Setting
auths.edit=Modifica impostazioni di autenticazione
auths.activated=Questa Autenticazione è stata attivata
auths.new_success=New authentication '%s' has been added successfully.
auths.update_success=Authentication setting has been updated successfully.
auths.update=Update Authentication Setting
auths.delete=Delete This Authentication
auths.update=Aggiornare le impostazioni di autenticazione
auths.delete=Elimina questa autenticazione
auths.delete_auth_title=Authentication Deletion
auths.delete_auth_desc=This authentication is going to be deleted, do you want to continue?
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
auths.deletion_success=Authentication has been deleted successfully!
config.server_config=Configurazione Server
@@ -960,6 +962,19 @@ config.static_file_root_path=Percorso Root del File Statico
config.log_file_root_path=Percorso Root del File di Log
config.script_type=Tipo di Script
config.reverse_auth_user=Autenticazione Utente Inversa
config.ssh_config=Configurazione SSH
config.ssh_enabled=Attivo
config.ssh_start_builtin_server=Avvia server builtin
config.ssh_domain=Dominio
config.ssh_port=Porta
config.ssh_listen_port=Porta in ascolto
config.ssh_root_path=Percorso Root
config.ssh_key_test_path=Percorso chiave di test
config.ssh_keygen_path=Percorso Keygen ('ssh-keygen')
config.ssh_minimum_key_size_check=Verifica delle dimensioni minime della chiave
config.ssh_minimum_key_sizes=Dimensioni minime della chiave
config.db_config=Configurazione Database
config.db_type=Tipo
config.db_host=Host
@@ -968,19 +983,19 @@ config.db_user=Utente
config.db_ssl_mode=Modalità SSL
config.db_ssl_mode_helper=(solo per "postgres")
config.db_path=Percorso
config.db_path_helper=(for "sqlite3" and "tidb")
config.db_path_helper=(per "sqlite3" e "tidb")
config.service_config=Configurazione Servizio
config.register_email_confirm=Richiedono Conferma dell'Email
config.disable_register=Disabilita Registrazione
config.show_registration_button=Mostra Pulsane Registrazione
config.require_sign_in_view=Richiesto Accesso per Vedere
config.mail_notify=Email di Notifica
config.disable_key_size_check=Disable Minimum Key Size Check
config.disable_key_size_check=Disabilita controllo sulle dimensioni minime della chiave
config.enable_captcha=Abilita Captcha
config.active_code_lives=Attiva Vita del Codice
config.reset_password_code_lives=Reimpostare Password della Vita del Codice
config.webhook_config=Configurazione Webhook
config.queue_length=Queue Length
config.queue_length=Lunghezza della coda
config.deliver_timeout=Tempo Limite di Consegna
config.skip_tls_verify=Salta verifiche TLS
config.mailer_config=Configurazione Mailer
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Disattiva HELO
config.mailer_name=Nome
config.mailer_host=Host
config.mailer_user=Utente
config.send_test_mail=Invia email di test
config.test_mail_failed=Impossibile inviare mail a '%s': %v
config.test_mail_sent=Una mail di prova è stata inviata a '%s'.
config.oauth_config=Configurazione OAuth
config.oauth_enabled=Attivo
config.cache_config=Configurazione Cache
@@ -1022,18 +1040,18 @@ monitor.start=Orario Avvio
monitor.execute_time=Tempo di Esecuzione
notices.system_notice_list=Avvisi di Sistema
notices.view_detail_header=View Notice Detail
notices.actions=Actions
notices.select_all=Select All
notices.deselect_all=Deselect All
notices.inverse_selection=Inverse Selection
notices.delete_selected=Delete Selected
notices.delete_all=Delete All Notices
notices.view_detail_header=Visualizza dettagli dell'avviso
notices.actions=Azioni
notices.select_all=Seleziona tutto
notices.deselect_all=Deseleziona tutto
notices.inverse_selection=Inverti selezione
notices.delete_selected=Elimina selezionati
notices.delete_all=Elimina tutti gli avvisi
notices.type=Tipo
notices.type_1=Repository
notices.desc=Descrizione
notices.op=Op.
notices.delete_success=System notices have been deleted successfully.
notices.delete_success=Gli avvisi di sistema sono stati successivamente eliminati.
[action]
create_repo=ha creato il repository <a href="%s">%s</a>
@@ -1043,6 +1061,8 @@ create_issue=`ha aperto il problema <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`creata pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
@@ -1074,5 +1094,5 @@ raw_minutes=minuti
default_message=Drop files here or click to upload.
invalid_input_type=You can't upload files of this type.
file_too_big=File size ({{filesize}} MB) exceeds maximum size ({{maxFilesize}} MB).
remove_file=Remove file
remove_file=Rimuovi file

View File

@@ -38,23 +38,16 @@ settings=設定
your_profile=あなたのプロファイル
your_settings=あなたの設定
activities=Activities
activities=アクティビティ
pull_requests=プルリクエスト
issues=課題
cancel=キャンセル
[search]
search=検索...
repository=リポジトリ
user=ユーザ
issue=課題
code=コード
[install]
install=インストール
title=初回実行のインストール手順
docker_helper=DockerでGogsを稼動する場合、このページに変更を加えるまえに、 <a target="_blank" href="%s">Guidelines</a>をよく読んでください!
title=インストールをする前に必要な準備をしましょう
docker_helper=DockerでGogsを稼動する場合、このページに変更を加えるに、 <a target="_blank" href="%s">ガイドライン</a>をよく読んでください!
requite_db_desc=Gogs は、MySQL、PostgreSQL、SQLite3 または TiDB が必要です。
db_title=データベース設定
db_type=データベースの種類
@@ -62,10 +55,10 @@ host=ホスト
user=ユーザ
password=パスワード
db_name=データベース名
db_helper=Mysql INNODB エンジン utf8_general_ci の文字セットを使用してください
db_helper=MySQLではエンジンがINNODB、文字セットがutf8_general_ciである必要があります
ssl_mode=SSL モード
path=パス
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
sqlite_helper=SQLite3かTiDBのデータベースのファイルパス。<br>サービスとして開始する際には絶対パスを利用してください。
err_empty_db_path=SQLite3 または TiDB データベースのパスを空にすることはできません。
err_invalid_tidb_name=TiDB データベース名は文字"."と"-"を許可しない。
no_admin_and_disable_registration=管理者アカウントを作成せずに登録を無効にすることはできません。
@@ -86,8 +79,8 @@ http_port=HTTP ポート
http_port_helper=アプリケーションが待ち受けするポート番号。
app_url=アプリケーションの URL
app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。
log_root_path=Log Path
log_root_path_helper=Directory to write log files to.
log_root_path=ログのパス
log_root_path_helper=ログファイルを書き込むディレクトリ。
optional_title=オプション設定
email_title=E-mailサービス設定
@@ -99,10 +92,10 @@ mailer_password=送信者のパスワード
register_confirm=登録の確認を有効にする
mail_notify=メール通知を有効にする
server_service_title=サーバーとその他のサービスの設定
offline_mode=オフラインモード有効
offline_mode_popup=プロダクション モードでCDN を無効にし、すべてのリソースファイルをローカルで提供します
offline_mode=オフラインモード有効にする
offline_mode_popup=プロダクションモードでは、CDNを使用せずにローカルからリソースファイルを使用します。
disable_gravatar=Gravatarのサービスを無効にします
disable_gravatar_popup=Disable Gravatar and custom sources, all avatars are uploaded by users or default.
disable_gravatar_popup=Gravatarとカスタムソースを無効にして、全てのアバターをユーザーによってアップロードされたものかデフォルトなものにします。
disable_registration=自己登録を無効にする
disable_registration_popup=自己登録を無効にし、管理者のみがアカウント作成できる
enable_captcha=Captchaを有効にする
@@ -124,7 +117,7 @@ run_user_not_match=実行ユーザーは、現在のユーザーではない: %s
save_config_failed=構成の保存に失敗した: %v
invalid_admin_setting=管理者アカウントの設定が無効です: %v
install_success=ようこそ!我々はあなたが Gogs を選んでくれて嬉しいです!楽しみましょう!
invalid_log_root_path=Log root path is invalid: %v
invalid_log_root_path=ログのルートパスがむこうです: %v
[home]
uname_holder=ユーザー名またはEメール
@@ -140,6 +133,8 @@ issues.in_your_repos=あなたのリポジトリ
[explore]
repos=リポジトリ
users=Users
search=Search
[auth]
create_new_account=新規アカウントを作成
@@ -168,7 +163,7 @@ activate_account=あなたのアカウントを有効にしてください。
activate_email=電子メール アドレスを確認します。
reset_password=パスワードをリセットします.
register_success=ようこそ、登録成功
register_notify=Welcome on board
register_notify=ボードへようこそ
[modal]
yes=はい
@@ -221,8 +216,6 @@ still_own_repo=アカウント所有のリポジトリがあり、リポジト
still_has_org=アカウントはまだ組織のメンバーであり、組織から退出するか削除する必要があります。
org_still_own_repo=この組織はまだリポジトリの所有しています、リポジトリを削除または転送する必要があります。
still_own_user=この認証はまだ一部のユーザーによって使用されています。一部のユーザを移動させてから、もう一度削除してください。
target_branch_not_exist=ターゲットブランチが存在しない
[user]
@@ -264,11 +257,10 @@ continue=続行
cancel=キャンセル
enable_custom_avatar=カスタムのアバターを有効にする
enable_custom_avatar_helper=Gravatarからのフェッチを無効にするのを、有効にします
choose_new_avatar=新しいアバターを選択
update_avatar=アバターの設定を更新
delete_current_avatar=現在のアバターを削除
uploaded_avatar_not_a_image=アップロードされたファイルは画像ではない。
no_custom_avatar_available=利用可能なカスタム アバターがないため、有効にできません。
update_avatar_success=あなたのアバターの設定が更新されました。
change_password=パスワードを変更
@@ -479,7 +471,7 @@ issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=ポスター
issues.admin=アドミン
issues.collaborator=Collaborator
issues.owner=オーナー
issues.sign_up_for_free=無料でサインアップ
issues.sign_in_require_desc=to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
@@ -560,6 +552,8 @@ wiki.save_page=ページを保存
wiki.last_commit_info=%s このページを編集 %s
wiki.edit_page_button=編集
wiki.new_page_button=新規ページ
wiki.delete_page_button=Delete Page
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
wiki.page_already_exists=既に同じ名前のWiki ページが存在します。
wiki.pages=ページ
wiki.last_updated=最終更新 %s
@@ -595,12 +589,16 @@ settings.transfer_desc=リポジトリをあなたが管理者権限を持って
settings.transfer_notices_1=-新しい所有者が個人ユーザーの場合、あなたがアクセスできなくなります。
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
settings.transfer_form_title=操作を確認するために、以下の情報を入力してください。
settings.wiki_delete=Erase Wiki Data
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
settings.delete=このリポジトリを削除
settings.delete_desc=リポジトリを削除すると元に戻せません。確実に確認してください。
settings.delete_notices_1=-この操作は<strong>元に戻せません</strong> 。
settings.delete_notices_2=- This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
settings.delete_notices_fork_1=- If this repository is public, all forks will become independent after deletion.
settings.delete_notices_fork_2=- If this repository is private, all forks will be removed at the same time.
settings.delete_notices_fork_2=もしプライペートリポジトリの場合、全てのフォークも同時に削除されます。
settings.delete_notices_fork_3=- If you want to keep all forks after deletion, please change visibility of this repository to public first.
settings.deletion_success=Repository has been deleted successfully!
settings.update_settings_success=リポジトリ オプションが更新されました。
@@ -610,9 +608,12 @@ settings.transfer_succeed=リポジトリの所有権は正常に転送されま
settings.confirm_delete=削除の確認
settings.add_collaborator=新しい共同編集者を追加
settings.add_collaborator_success=新しい共同編集者が追加されました。
settings.delete_collaborator=Delete
settings.collaborator_deletion=Collaborator Deletion
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
settings.remove_collaborator_success=共同編集者が削除されました。
settings.search_user_placeholder=Search users
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.org_not_allowed_to_be_collaborator=組織を共同編集者として追加することはできません。
settings.user_is_org_member=ユーザーは組織の一員なので、共同編集者として追加することはできません。
settings.add_webhook=Webhook を追加
settings.hooks_desc=Webhooksは、Gogsで特定のイベントの発生時に指定された外部サービスに通知を許可します。イベントが発生すると、それぞれ指定されたUrlに、POSTリクエストが送られます。詳細はこちらのの <a target="_blank"href="%s"> Webhooks ガイド</a>をご覧ください。
@@ -677,7 +678,7 @@ diff.parent=親
diff.commit=コミット
diff.data_not_available=差分データは利用できません。
diff.show_diff_stats=差分情報を表示
diff.show_split_view=Split View
diff.show_split_view=分割表示
diff.show_unified_view=Unified View
diff.stats_desc=共有<strong>%d 個のファイルを変更した</strong>、<strong>%d 個の追加</strong> と <strong>%d 個の削除</strong>を含む
diff.bin=BIN
@@ -709,7 +710,7 @@ release.save_draft=下書きを保存
release.edit_release=リリースを編集
release.delete_release=このリリースを削除
release.deletion=リリースの削除
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
release.deletion_desc=このリリースを削除すると、対応するGitのタグも削除されます。よろしいですか
release.deletion_success=リリースが正常に削除されました。
release.tag_name_already_exist=このタグ名には既にリリースが存在します。
release.downloads=Downloads
@@ -944,6 +945,7 @@ auths.update=認証設定を更新
auths.delete=この認証を削除
auths.delete_auth_title=認証削除
auths.delete_auth_desc=認証を削除します、継続しますか?
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
auths.deletion_success=認証が正常に削除されました。
config.server_config=サーバーの構成
@@ -960,6 +962,19 @@ config.static_file_root_path=静的ファイルのルートパス
config.log_file_root_path=ログ ファイルのルート パス
config.script_type=スクリプトの種類
config.reverse_auth_user=リバース認証ユーザ
config.ssh_config=SSH Configuration
config.ssh_enabled=Enabled
config.ssh_start_builtin_server=Start Builtin Server
config.ssh_domain=Domain
config.ssh_port=Port
config.ssh_listen_port=Listen Port
config.ssh_root_path=Root Path
config.ssh_key_test_path=Key Test Path
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
config.ssh_minimum_key_size_check=Minimum Key Size Check
config.ssh_minimum_key_sizes=Minimum Key Sizes
config.db_config=データベースの構成
config.db_type=タイプ
config.db_host=ホスト
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=HELOコマンド無効
config.mailer_name=名前
config.mailer_host=ホスト
config.mailer_user=ユーザ
config.send_test_mail=Send Test Email
config.test_mail_failed=Fail to send test email to '%s': %v
config.test_mail_sent=Test email has been sent to '%s'.
config.oauth_config=OAuth 構成
config.oauth_enabled=Enabled
config.cache_config=キャッシュの構成
@@ -1043,6 +1061,8 @@ create_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> を開きました`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`プルリクエスト <a href="%s/pulls/%s"> %s[2]s</a>を作成`
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> のコメント`
merge_pull_request=`プルリクエスト <a href="%s/pulls/%s"> %s[2]s</a>をマージしました`
transfer_repo=リポジトリ <code>%s</code> を <a href="%s">%s</a> へ転送しました

View File

@@ -38,19 +38,12 @@ settings=Iestatījumi
your_profile=Tavs profils
your_settings=Tavi iestatījumi
activities=Activities
activities=Aktivitāte
pull_requests=Izmaiņu pieprasījumi
issues=Problēmas
cancel=Atcelt
[search]
search=Meklēt...
repository=Repozitorijs
user=Lietotājs
issue=Kļūda
code=Kods
[install]
install=Instalācija
title=Instalācijas soļi pirmo reizi palaižot
@@ -65,7 +58,7 @@ db_name=Datu bāzes nosaukums
db_helper=Nepieciešams izmantot MySQL INNODB dzini ar rakstzīmju kopu utf8_general_ci.
ssl_mode=SSL režīms
path=Ceļš
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
sqlite_helper=SQLite3 vai TiDB datu bāzēs faila ceļš.<br>Izmantojiet absolūto ceļu, startējot kā servisu.
err_empty_db_path=Nepieciešams norādīt SQLite3 vai TiDB datu bāzes atrašanās vietu.
err_invalid_tidb_name=TiDB datu bāzes nosaukums nevar saturēt simbolus "." un "-".
no_admin_and_disable_registration=Reģistrāciju nevar atslēgt, kamēr nav izveidots administratora konts.
@@ -86,8 +79,8 @@ http_port=HTTP ports
http_port_helper=Porta numurs pēc kura lietojumprogrammai būs iespējams pieslēgties.
app_url=Lietotnes URL
app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites.
log_root_path=Log Path
log_root_path_helper=Directory to write log files to.
log_root_path=Žurnalizēšanas direktorija
log_root_path_helper=Direktorija, kurā tiks glabāti žurnāla faili.
optional_title=Neobligātie iestatījumi
email_title=E-pasta pakalpojuma iestatījumi
@@ -124,7 +117,7 @@ run_user_not_match=Izpildes lietotājs nav pašreizējais lietotājs: %s -> %s
save_config_failed=Neizdevās saglabāt konfigurāciju: %v
invalid_admin_setting=Nekorekts admin konta iestatījums: %v
install_success=Laipni lūdzam! Mēs priecājamies, ka Jūs izvēlaties Gogs, patīkamu lietošanu!
invalid_log_root_path=Log root path is invalid: %v
invalid_log_root_path=Norādītā žurnalizēšanas direktorija ir kļūdaina: %v
[home]
uname_holder=Lietotājvārds vai e-pasts
@@ -140,6 +133,8 @@ issues.in_your_repos=Jūsu repozitorijos
[explore]
repos=Repozitoriji
users=Lietotāji
search=Meklēt
[auth]
create_new_account=Izveidot jaunu kontu
@@ -221,8 +216,6 @@ still_own_repo=Jūsu esat vismaz viena repozitorija īpašnieks, tos sākumā ir
still_has_org=Jūsu esat vismaz vienas organizācijas biedrs, sākumā nepieciešams pamest vai izdzēst šo organizāciju.
org_still_own_repo=Šī organizācija ir vismaz viena repozitorija īpašnieks, tos sākumā ir nepieciešams izdzēst vai nomainīt to īpašnieku.
still_own_user=Šo autentifikāciju joprojām izmanto vismaz viens lietotājs, nepieciešams šiem lietotājiem nomainīt autentifikācijas veidu vai tos izdzēst.
target_branch_not_exist=Mērķa atzars neeksistē
[user]
@@ -264,11 +257,10 @@ continue=Turpināt
cancel=Atcelt
enable_custom_avatar=Iespējot maināmu profila attēlu
enable_custom_avatar_helper=Iespējojiet šo, lai atslēgtu profilu attēlu ņemšanu no gravatar.com
choose_new_avatar=Izvēlēties jaunu profila attēlu
update_avatar=Saglabāt profila bildi
delete_current_avatar=Dzēst pašreizējo profila bildi
uploaded_avatar_not_a_image=Augšupielādētais fails nav attēls.
no_custom_avatar_available=Nav iespējams mainīt profila bildi.
update_avatar_success=Jūsu profila bilde tika veiksmīgi saglabāta.
change_password=Mainīt paroli
@@ -479,7 +471,7 @@ issues.closed_at=`aizvērts <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`atvērts atkārtoti <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`pieminēja šo problēmu revīzijā <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Autors
issues.admin=Administrators
issues.collaborator=Līdzstrādnieks
issues.owner=Īpašnieks
issues.sign_up_for_free=Pievienojieties
issues.sign_in_require_desc=, lai piedalītos diskusijā. Jau ir konts? <a href="%s">Pierakstieties, lai komentētu</a>
@@ -496,7 +488,7 @@ issues.label_modify=Etiķetes labošana
issues.label_deletion=Etiķetes dzēšana
issues.label_deletion_desc=Dzēšot šo etiķeti, tā tiks noņemta no visām saistītajām problēmām. Vai vēlaties turpināt?
issues.label_deletion_success=Etiķete tika veiksmīgi izdzēsta!
issues.num_participants=%d Participants
issues.num_participants=%d dalībnieki
pulls.new=Jauns izmaiņu pieprasījums
pulls.compare_changes=Salīdzināt izmaiņas
@@ -560,6 +552,8 @@ wiki.save_page=Saglabāt lapu
wiki.last_commit_info=%s laboja lapu %s
wiki.edit_page_button=Labot
wiki.new_page_button=Jauna lapa
wiki.delete_page_button=Dzēst lapu
wiki.delete_page_notice_1=Tiks izdzēsta lapa <code>"%s"</code>. Pārliecinieties, ka patiešām to vēlaties.
wiki.page_already_exists=Vikivietnes lapa ar šādu nosaukumu jau eksistē.
wiki.pages=Lapas
wiki.last_updated=Pēdējo reizi labota %s
@@ -585,16 +579,20 @@ settings.tracker_url_format_desc=Jūs varat izmantot <code>{user}{repo}{index}</
settings.pulls_desc=Iespējot izmaiņu pieprasījumus lai saņemtu publiskus ieguldījumus
settings.danger_zone=Bīstamā zona
settings.new_owner_has_same_repo=Jaunajam īpašniekam jau ir repozitorijs ar šādu nosaukumu.
settings.convert=Convert To Regular Repository
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
settings.convert_confirm=Confirm Conversion
settings.convert_succeed=Repository has been converted to regular type successfully.
settings.convert=Konvertēt uz parastu repozitoriju
settings.convert_desc=Šo spoguli ir iespējams konvertēt par parastu repozitoriju. Šī ir neatgriezeniska darbība.
settings.convert_notices_1=- Šī darbība konvertēs šo repozitoriju par parastu repozitoriju un to nebūs iespējams atcelt.
settings.convert_confirm=Apstiprināt konvertēšanu
settings.convert_succeed=Repozitorijs tika veiksmīgi konvertēts uz parastu repozitoriju.
settings.transfer=Mainīt īpašnieku
settings.transfer_desc=Mainīt šī repozitorija īpašnieku uz citu lietotāju vai organizāciju, kurai Jums ir administratora tiesībs.
settings.transfer_notices_1=- Jūs pazaudēsiet piekļuvi, ja jaunais īpašnieks ir lietotājs.
settings.transfer_notices_2=- Jūs saglabāsiet piekļuvi, ja jaunais īpašnieks ir organizācija un Jūs esat viens no tās īpašniekiem.
settings.transfer_form_title=Lūdzu, ievadiet sekojošu informāciju, lai apstiprinātu šo darbību:
settings.wiki_delete=Dzēst Vikivietnes datus
settings.wiki_delete_desc=Vikivietnes datu dzēšana ir neatgriezeniska. Pārliecinieties vai patiešām to vēlaties.
settings.wiki_delete_notices_1=- Šī darbība dzēsīs un atspējos %s Vikivietni
settings.wiki_deletion_success=Repozitorija Vikivietnes dati tika veiksmīgi izdzēsti.
settings.delete=Dzēst šo repozitoriju
settings.delete_desc=Dzēšot repozitoriju, tā datus vairs nebūs iespējams atgūt. Pirms dzēšanas pārliecinieites vai patiešām vēlaties to darīt.
settings.delete_notices_1=- Šī darbība ir <strong>NEATGRIEZENISKA</strong>.
@@ -610,9 +608,12 @@ settings.transfer_succeed=Repozitorija īpašnieks ir veiksmīgi nomainīts.
settings.confirm_delete=Apstiprināt dzēšanu
settings.add_collaborator=Pievienot jaunu līdzstrādnieku
settings.add_collaborator_success=Jauns līdzstrādnieks ir pievienots.
settings.delete_collaborator=Dzēst
settings.collaborator_deletion=Līdzstrādnieka dzēšana
settings.collaborator_deletion_desc=Šim lietotājam pēc dzēšanas vairs nebūs sadarbības pieejas šai krātuvei. Vai vēlaties turpināt?
settings.remove_collaborator_success=Līdzstrādnieks tika noņemts.
settings.search_user_placeholder=Meklēt lietotāju...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.org_not_allowed_to_be_collaborator=Organizāciju nav atļauts pievienot kā līdzstrādnieku.
settings.user_is_org_member=Lietotājs ir organizācijas biedrs, kas nevar tikt pievienots kā līdzstrādnieks.
settings.add_webhook=Pievienot tīmekļa āķi
settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikomiem, kas notiek Git servisā. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Lai uzzinātu sīkāk skatieties <a target="_blank" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
@@ -827,8 +828,8 @@ dashboard.resync_all_sshkeys=Pārrakstīt '.ssh/authorized_keys' failu (brīdin
dashboard.resync_all_sshkeys_success=Visas publiskās atslēgas tika veiksmīgi pārrakstītas.
dashboard.resync_all_update_hooks=Pārrakstīt visu repozitoriju izmaiņu āķus (nepieciešams, ja tiek mainīta konfigurācijas faila atrašanās vieta)
dashboard.resync_all_update_hooks_success=Visu repozitoriju izmaiņu āķi tika veiksmīgi pārrakstīti.
dashboard.reinit_missing_repos=Reinitialize all repository records that lost Git files
dashboard.reinit_missing_repos_success=All repository records that lost Git files have been reinitialized successfully.
dashboard.reinit_missing_repos=Atkārtoti inicializēt visus repozitorija ierakstus, kam trūkst Git failu
dashboard.reinit_missing_repos_success=Visi repozitorija ieraksti, kam trūkst Git faili, tika atkārtoti inicializēti.
dashboard.server_uptime=Servera darbības laiks
dashboard.current_goroutine=Izmantotās Gorutīnas
@@ -922,7 +923,7 @@ auths.attribute_username_placeholder=Atstājiet tukšu, lai izmantotu lietotājv
auths.attribute_name=Vārda atribūts
auths.attribute_surname=Uzvārda atribūts
auths.attribute_mail=E-pasta atribūts
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.attributes_in_bind=Nolasīt atribūtus no saistīšanas DN konteksta
auths.filter=Lietotāju filts
auths.admin_filter=Administratoru filtrs
auths.ms_ad_sa=MS Ad SA
@@ -944,6 +945,7 @@ auths.update=Mainīt autentifikācijas iestatījumus
auths.delete=Dzēst šo autentifikāciju
auths.delete_auth_title=Autentifikācijas dzēšana
auths.delete_auth_desc=Šī autentifikācija tiks dzēsta, vai vēlaties turpināt?
auths.still_in_used=Daži lietotāji joprojām izmanto šo autentifikācijas veidu. Nepieciešams veikt šo lietotāju konvertāciju vai dzēšanu.
auths.deletion_success=Autentifikācija tika veiksmīgi izdzēsta!
config.server_config=Servera konfigurācija
@@ -960,6 +962,19 @@ config.static_file_root_path=Statisko failu atrašanās vieta
config.log_file_root_path=Žurnalizēšanas failu glabāšanas vieta
config.script_type=Skripta veids
config.reverse_auth_user=Reversā lietotāja autentifikācija
config.ssh_config=SSH konfigurācija
config.ssh_enabled=Iespējots
config.ssh_start_builtin_server=Startēt iebūvēto serveri
config.ssh_domain=Domēns
config.ssh_port=Ports
config.ssh_listen_port=Klausīšanās ports
config.ssh_root_path=Saknes ceļš
config.ssh_key_test_path=Atslēgu pārbaudes ceļš
config.ssh_keygen_path=Keygen ('ssh-keygen') ceļš
config.ssh_minimum_key_size_check=Minimālā atslēgas lieluma pārbaude
config.ssh_minimum_key_sizes=Minimālais atslēgas lielums
config.db_config=Datu bāzes konfigurācija
config.db_type=Veids
config.db_host=Resursdators
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Atspējot HELO
config.mailer_name=Nosaukums
config.mailer_host=Resursdators
config.mailer_user=Lietotājs
config.send_test_mail=Nosūtīt pārbaudes e-pastu
config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pasta vēstuli uz '%s': %v
config.test_mail_sent=Pārbaudes e-pasta vēstule tika nosūtīta uz '%s'.
config.oauth_config=OAuth konfigurācija
config.oauth_enabled=Iespējota
config.cache_config=Kešatmiņas konfigurācija
@@ -1040,9 +1058,11 @@ create_repo=izveidoja repozitoriju <a href="%s">%s</a>
rename_repo=pārsauca repozitoriju no <code>%[1]s</code> uz <a href="%[2]s">%[3]s</a>
commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%[1]s/src/%[2]s">%[3]s</a> repozitorijā <a href="%[1]s">%[4]s</a>
create_issue=`reģistrēja problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`slēdza problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`atkārtoti atvēra problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`izveidoja izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`aizvēra izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`atkārtoti atvēra izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`sapludināja izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="%s">%s</a>

View File

@@ -5,9 +5,9 @@ dashboard=Dashboard
explore=Verkennen
help=Help
sign_in=Inloggen
sign_out=Afmelden
sign_out=Uitloggen
sign_up=Aanmelden
register=Registreer
register=Registreren
website=Website
version=Versie
page=Pagina
@@ -26,10 +26,10 @@ captcha=CAPTCHA
repository=Repository
organization=Organisatie
mirror=Spiegel
new_repo=Nieuwe repositorie
new_repo=Nieuwe repository
new_migrate=Nieuwe migratie
new_mirror=Nieuwe Kopie
new_fork=Nieuwe vork Repository
new_fork=Nieuwe Fork
new_org=Nieuwe organisatie
manage_org=Beheer organisaties
admin_panel=Adminpaneel
@@ -38,25 +38,18 @@ settings=Instellingen
your_profile=Uw profiel
your_settings=Uw instellingen
activities=Activities
pull_requests=Pull-aanvragen
activities=Activiteiten
pull_requests=Pull requests
issues=Kwesties
cancel=Annuleer
[search]
search=Zoeken...
repository=Opslagplaats
user=Gebruiker
issue=Probleem
code=Code
cancel=Annuleren
[install]
install=Installatie
title=Installatiestappen voor de eerste keer opstarten
docker_helper=Als u gebruik maakt Gogs binnen Docker, lees dan de <a target="_blank" href="%s">richtlijnen</a> voordat u iets veranderen op deze pagina!
requite_db_desc=Gogs vereist MySQL, PostgreSQL, SQite3 of TiDB.
db_title=Database instellingen
db_title=Database-instellingen
db_type=Database-type
host=Host
user=Gebruikersnaam
@@ -65,7 +58,7 @@ db_name=Database naam
db_helper=Gebruik InnoDB engine met utf8_general_ci karakterset voor MySQL.
ssl_mode=SSL-modus
path=Pad
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
sqlite_helper=Het pad van de SQLite3- of TiDB-database.<br>Als u Gogs start als een service, geef dan een absoluut pad op.
err_empty_db_path=SQLite3 of TiDB databankpad mag niet leeg.
err_invalid_tidb_name=TiDB databank naam niet tekens kunnen "." en "-".
no_admin_and_disable_registration=Je kunt niet de registratie uit te schakelen zonder een beheerders account.
@@ -86,8 +79,8 @@ http_port=HTTP-poort
http_port_helper=Poortnummer waar het programma naar luistert.
app_url=Applicatie URL
app_url_helper=Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt
log_root_path=Log Path
log_root_path_helper=Directory to write log files to.
log_root_path=Log-pad
log_root_path_helper=Directory waar logbestanden opgeslagen worden.
optional_title=Optionele instellingen
email_title=E-mail service instellingen
@@ -124,7 +117,7 @@ run_user_not_match=De uitvoerende gebruiker is niet de huidig gebruiker: %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
invalid_log_root_path=Log root path is invalid: %v
invalid_log_root_path=Ongeldig log-pad: %v
[home]
uname_holder=Gebruikersnaam of e-mail
@@ -140,6 +133,8 @@ issues.in_your_repos=In uw repositories
[explore]
repos=Repositories
users=Gebruikers
search=Zoeken
[auth]
create_new_account=Maak nieuw account aan
@@ -221,8 +216,6 @@ still_own_repo=Uw account heeft nog een eigendom op een repositorie. U moet deze
still_has_org=Uw account nog steeds lidmaatschap van organisatie, u hebt naar links of hen eerst verwijderen.
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.
target_branch_not_exist=Doel branch bestaat niet
[user]
@@ -264,11 +257,10 @@ continue=Doorgaan
cancel=Annuleren
enable_custom_avatar=Aangepaste avatar inschakelen
enable_custom_avatar_helper=Avatar niet ophalen van Gravatar
choose_new_avatar=Kies een nieuwe avatar
update_avatar=Avatar instelling bijwerken
delete_current_avatar=Verwijder huidige avatar
uploaded_avatar_not_a_image=Geüpload bestand is geen afbeelding.
no_custom_avatar_available=Geen aangepaste avatar beschikbaar, kan niet worden ingeschakeld.
update_avatar_success=Instellingen voor avatar succesvol bijgewerkt.
change_password=Verander wachtwoord
@@ -345,9 +337,9 @@ visiblity_helper=Deze repositorie is <span class="ui red text">privaat</span>
visiblity_helper_forced=Sitebeheerder heeft alle nieuwe repositories gedwongen <span class="ui red text">privé</span> te zijn
visiblity_fork_helper=(Verandering van deze waarde zal van invloed zijn op alle forks)
clone_helper=De behoeftehulp van klonen? Bezoek <a target="_blank" href="%s"> helpen</a>!
fork_repo=Vork Repository
fork_repo=Repository forken
fork_from=Afsplitsing van
fork_visiblity_helper=Gevorkte repository wijzigen zijn bereik potentiële kopers niet
fork_visiblity_helper=U kunt de zichtbaarheid van een geforkte repository niet aanpassen.
repo_desc=Omschrijving
repo_lang=Taal
repo_lang_helper=Selecteer .gitignore bestanden
@@ -434,7 +426,7 @@ issues.new.no_milestone=Geen mijlpaal
issues.new.clear_milestone=Verwijder mijlpaal
issues.new.open_milestone=Open mijlpalen
issues.new.closed_milestone=Gesloten mijlpalen
issues.new.assignee=Verantwoordelijke
issues.new.assignee=Toegewezen aan
issues.new.clear_assignee=Verwijder verantwoordelijke
issues.new.no_assignee=Geen verantwoordelijke
issues.create=Maak probleem
@@ -479,7 +471,7 @@ issues.closed_at=`gesloten om <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`heropend om <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at='verwees naar dit probleem vanuit een commit <a id="%[1]s" href="#%[1]s"> %[2]s'</a>
issues.poster=Poster
issues.admin=Admin
issues.collaborator=Collaborator
issues.owner=Eigenaar
issues.sign_up_for_free=Gratis aanmelden
issues.sign_in_require_desc=om deel te nemen in deze conversatie. Heeft u al een account? <a href="%s">Meld u aan om te reageren</a>
@@ -516,10 +508,10 @@ pulls.tab_files=Bestanden gewijzigd
pulls.reopen_to_merge=Heropen deze pull request aub om een een merge actie uit te voeren.
pulls.merged=Samengevoegd
pulls.has_merged=Dit pull-request is samengevoegd!
pulls.data_broken=Data of this pull request has been broken due to deletion of fork information.
pulls.data_broken=Omdat informatie over de fork is verwijderd, zijn de gegevens van dit pull-request niet beschikbaar.
pulls.is_checking=Controle van conflicten is nog bezig, ververs deze pagina in enkele ogenblikken.
pulls.can_auto_merge_desc=Dit pull-request kan automatisch samengevoegd worden.
pulls.cannot_auto_merge_desc=This pull request can't be merged automatically because there are conflicts.
pulls.cannot_auto_merge_desc=Dit pull-request kan niet worden gemerged omdat er conflicten zijn.
pulls.cannot_auto_merge_helper=Please merge manually in order to resolve the conflicts.
pulls.merge_pull_request=Samenvoegen van pull verzoek
pulls.open_unmerged_pull_exists=`You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
@@ -550,7 +542,7 @@ milestones.deletion_success=Mijlpaal is met succes verwijderd!
wiki=Wiki
wiki.welcome=Welkom op de Wiki!
wiki.welcome_desc=Wiki is the place where you would like to document your project together and make it better.
wiki.welcome_desc=In een wiki kunnen gebruikers samen een project documenteren en bediscussiëren.
wiki.create_first_page=Maak de eerste pagina
wiki.page=Pagina
wiki.filter_page=Filter pagina
@@ -560,41 +552,47 @@ wiki.save_page=Pagina opslaan
wiki.last_commit_info=%s heeft deze pagina aangepast %s
wiki.edit_page_button=Bewerken
wiki.new_page_button=Nieuwe pagina
wiki.page_already_exists=Wiki page with same name already exists.
wiki.pages=Pages
wiki.last_updated=Last updated %s
wiki.delete_page_button=Verwijder pagina
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
wiki.page_already_exists=Er bestaat al een wiki-pagina met deze naam.
wiki.pages=Paginas
wiki.last_updated=Laatst bijgewerkt: %s
settings=Instellingen
settings.options=Opties
settings.collaboration=Samenwerking
settings.hooks=Webhooks
settings.githooks=Git haken
settings.githooks=Git-hooks
settings.basic_settings=Basis instellingen
settings.site=Officiële site
settings.update_settings=Instellingen bewerken
settings.change_reponame_prompt=This change will affect how links relate to the repository.
settings.advanced_settings=Geavanceerde opties
settings.wiki_desc=Enable wiki to allow people write documents
settings.use_external_wiki=Use external wiki
settings.external_wiki_url=External Wiki URL
settings.external_wiki_url_desc=Visitors will be redirected to URL when they click on the tab.
settings.issues_desc=Enable builtin lightweight issue tracker
settings.use_external_issue_tracker=Use external issue tracker
settings.tracker_url_format=External Issue Tracker URL Format
settings.use_external_wiki=Externe wiki gebruiken
settings.external_wiki_url=Externe wiki-URL
settings.external_wiki_url_desc=Bezoekers worden doorgestuurd naar de URL als ze op het tabblad klikken.
settings.issues_desc=Ingebouwde compacte issuetracker inschakelen
settings.use_external_issue_tracker=Externe issuetracker gebruiken
settings.tracker_url_format=URL-formaat externe issuetracker
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
settings.pulls_desc=Enable pull requests to accept public contributions
settings.danger_zone=Gevaren zone
settings.new_owner_has_same_repo=De nieuwe eigenaar heeft al een repositorie met deze naam
settings.convert=Convert To Regular Repository
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
settings.convert=Converteren naar gewone repository
settings.convert_desc=U kunt deze mirror converteren naar een gewone repository. Dit kan niet ongedaan worden gemaakt.
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
settings.convert_confirm=Confirm Conversion
settings.convert_succeed=Repository has been converted to regular type successfully.
settings.convert_confirm=Conversie bevestigen
settings.convert_succeed=Deze repository is geconverteerd naar een normale repository.
settings.transfer=Eigendom overdragen
settings.transfer_desc=Draag deze repo over aan een andere gebruiker of een organisatie waar u beheerders rechten heeft.
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
settings.transfer_form_title=Please enter following information to confirm your operation:
settings.wiki_delete=Erase Wiki Data
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
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.delete_notices_1=- This operation <strong>CANNOT</strong> be undone.
@@ -610,6 +608,9 @@ settings.transfer_succeed=Eigendom repositorie succesvol overgedragen
settings.confirm_delete=Bevestig verwijdering
settings.add_collaborator=Nieuwe medewerker toevoegen
settings.add_collaborator_success=medewerker is toegevoegd.
settings.delete_collaborator=Verwijderen
settings.collaborator_deletion=Collaborator Deletion
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
settings.remove_collaborator_success=medewerker is verwijderd.
settings.search_user_placeholder=Zoek gebruiker...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
@@ -618,8 +619,8 @@ settings.add_webhook=Webhook toevoegen
settings.hooks_desc=Webhooks dat de externe diensten om kennisgevingen te ontvangen wanneer bepaalde gebeurtenissen op Gogs plaatsvinden. Wanneer de opgegeven gebeurtenissen plaatsvinden, sturen we een POST-aanvraag naar elk van de URL's die u opgeeft. Meer informatie vindt u in onze <a target="_blank" href="%s"> Webhooks gids</a>.
settings.webhook_deletion=Webhook verwijderen
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
settings.webhook_deletion_success=Webhook has been deleted successfully!
settings.webhook.test_delivery=Test Delivery
settings.webhook_deletion_success=Webhook is succesvol verwijderd!
settings.webhook.test_delivery=Test-bezorging
settings.webhook.test_delivery_desc=Send a fake push event delivery to test your webhook settings
settings.webhook.test_delivery_success=Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
settings.webhook.request=Verzoek
@@ -692,31 +693,31 @@ release.edit=bewerken
release.ahead=<strong>%d</strong> aanpassingen aan %s sinds deze versie
release.source_code=Broncode
release.new_subheader=Publish releases to iterate product.
release.edit_subheader=Detailed change log can help users understand what has been improved.
release.edit_subheader=Een gedetailleerd changelog helpt gebruikers te begrijpen wat er is verbeterd in deze release.
release.tag_name=Tagnaam
release.target=Doel
release.tag_helper=Kies een bestaande tag, of creëer een nieuwe tag bij publiceren.
release.title=Titel
release.content=Content
release.content=Inhoud
release.write=Schrijf
release.preview=Voorbeeld
release.loading=Laden...
release.prerelease_desc=Dit is een beta-versie
release.prerelease_helper=Wij wijzen u erop dat deze release is niet geschikt voor productie doeleinden.
release.cancel=Cancel
release.cancel=Annuleren
release.publish=Release publiceren
release.save_draft=Concept opslaan
release.edit_release=Release bewerken
release.delete_release=Delete This Release
release.deletion=Release Deletion
release.delete_release=Deze release verwijderen
release.deletion=Release verwijderen
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
release.deletion_success=Release has been deleted successfully!
release.deletion_success=Release is verwijderd!
release.tag_name_already_exist=Versie met deze naam bestaat al.
release.downloads=Downloads
[org]
org_name_holder=Organisatienaam
org_full_name_holder=Organization Full Name
org_full_name_holder=Volledige naam organisatie
org_name_helper=Een goede organisatienaam is kort en memorabel.
create_org=Nieuwe organisatie aanmaken
repo_updated=Geupdate
@@ -758,7 +759,7 @@ members.public=Openbaar
members.public_helper=maak prive
members.private=Prive
members.private_helper=maak openbaar
members.member_role=Member Role:
members.member_role=Rol van lid:
members.owner=Eigenaar
members.member=Lid
members.remove=Verwijderen
@@ -788,10 +789,10 @@ teams.read_permission_desc=Dit team heeft <strong>Lees</strong> rechten : leden
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.search_repo_placeholder=Search repository...
teams.search_repo_placeholder=Repository zoeken...
teams.add_team_repository=Nieuwe teamrepositorie aanmaken
teams.remove_repo=Verwijder
teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen niet bestaat, kunt u het eerst aanmaken.
teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen bestaat niet: maak deze eerst aan.
[admin]
dashboard=Dashboard
@@ -802,9 +803,9 @@ authentication=Autenticaties
config=Configuratie
notices=Systeem aankondigingen
monitor=Bijhouden
first_page=First
last_page=Last
total=Total: %d
first_page=Eerste
last_page=Laatste
total=Totaal: %d
dashboard.statistic=Statistieken
dashboard.operations=Bewerkingen
@@ -867,12 +868,12 @@ users.activated=Geactiveerd
users.admin=Admin
users.repos=Repos
users.created=Aangemaakt
users.send_register_notify=Send Registration Notification To User
users.new_success=New account '%s' has been created successfully.
users.send_register_notify=Stuur notificatie voor registratie naar gebruiker
users.new_success=Nieuw account '%s' is aangemaakt.
users.edit=Bewerken
users.auth_source=Authentication Source
users.auth_source=Authenticatiebron
users.local=Lokaal
users.auth_login_name=Authentication Login Name
users.auth_login_name=Authenticatie-loginnaam
users.password_helper=Leave it empty to remain unchanged.
users.update_profile_success=Profiel is succesvol bijgewerkt.
users.edit_account=Bewerk account
@@ -881,12 +882,12 @@ users.max_repo_creation_desc=(Set -1 to use global default limit)
users.is_activated=Dit account is geactiveerd
users.is_admin=Dit account heeft beheerdersrechten
users.allow_git_hook=Deze account beschikt over machtigingen voor het maken van Git haken
users.allow_import_local=This account has permissions to import local repositories
users.allow_import_local=Dit account mag lokale repositories importeren
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.
users.still_has_org=Deze account nog steeds lidmaatschap van organisatie, u hebt naar links of hen eerst verwijderen.
users.deletion_success=Account has been deleted successfully!
users.deletion_success=Het account is verwijderd!
orgs.org_manage_panel=Organisaties beheren
orgs.name=Naam
@@ -902,13 +903,13 @@ repos.stars=Sterren
repos.issues=Kwesties
auths.auth_manage_panel=Authentication Manage Panel
auths.new=Add New Source
auths.new=Nieuwe bron toevoegen
auths.name=Naam
auths.type=Type
auths.enabled=Ingeschakeld
auths.updated=Bijgewerkt
auths.auth_type=Authentication Type
auths.auth_name=Authentication Name
auths.auth_type=Authenticatietype
auths.auth_name=Authenticatienaam
auths.domain=Domein
auths.host=Host
auths.port=Poort
@@ -923,16 +924,16 @@ auths.attribute_name=Voornaam attribuut
auths.attribute_surname=Achternaam attribuut
auths.attribute_mail=E-mail attribuut
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.filter=User Filter
auths.admin_filter=Admin Filter
auths.filter=Gebruikersfilter
auths.admin_filter=Beheerdersfilter
auths.ms_ad_sa=MS Ad SA
auths.smtp_auth=SMTP Authentication Type
auths.smtp_auth=SMTP-authenticatietype
auths.smtphost=SMTP host
auths.smtpport=SMTP poort
auths.allowed_domains=Allowed Domains
auths.allowed_domains=Toegelaten domeinen
auths.allowed_domains_helper=Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','.
auths.enable_tls=Activeer TLS-encryptie
auths.skip_tls_verify=Skip TLS Verify
auths.skip_tls_verify=TLS-verificatie overslaan
auths.pam_service_name=PAM servicenaam
auths.enable_auto_register=Activeer automatische registratie
auths.tips=Tips
@@ -940,10 +941,11 @@ auths.edit=Edit Authentication Setting
auths.activated=Deze autorisatiemethode is geactiveerd
auths.new_success=New authentication '%s' has been added successfully.
auths.update_success=Authentication setting has been updated successfully.
auths.update=Update Authentication Setting
auths.delete=Delete This Authentication
auths.update=Authenticatie-instellingen bijwerken
auths.delete=Deze authenticatiewijze verwijderen
auths.delete_auth_title=Authentication Deletion
auths.delete_auth_desc=This authentication is going to be deleted, do you want to continue?
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
auths.deletion_success=Authentication has been deleted successfully!
config.server_config=Serverconfiguratie
@@ -960,6 +962,19 @@ 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=Omgekeerde verificatie gebruiker
config.ssh_config=SSH-configuratie
config.ssh_enabled=Ingeschakeld
config.ssh_start_builtin_server=Ingebouwde server starten
config.ssh_domain=Domein
config.ssh_port=Poort
config.ssh_listen_port=Luister op poort
config.ssh_root_path=Root-pad
config.ssh_key_test_path=Pad voor key-tests
config.ssh_keygen_path=Pad van keygen ('ssh-keygen')
config.ssh_minimum_key_size_check=Controleer minimale key-lengte
config.ssh_minimum_key_sizes=Minimale key-lengtes
config.db_config=Databaseconfiguratie
config.db_type=Type
config.db_host=Host
@@ -968,15 +983,15 @@ config.db_user=Gebruiker
config.db_ssl_mode=SSL modus
config.db_ssl_mode_helper=(alleen voor "postgres")
config.db_path=Pad
config.db_path_helper=(for "sqlite3" and "tidb")
config.db_path_helper=(voor "sqlite3" en "tidb")
config.service_config=Serviceconfiguratie
config.register_email_confirm=E-mailbevestiging registreren
config.disable_register=Registratie uitgeschakeld
config.show_registration_button=Registeren knop weergeven
config.require_sign_in_view=Inloggen vereist om te kunnen inzien
config.mail_notify=E-mailnotificaties
config.disable_key_size_check=Disable Minimum Key Size Check
config.enable_captcha=Enable Captcha
config.disable_key_size_check=Controle op key-lengte uitschakelen
config.enable_captcha=CAPTCHA inschakelen
config.active_code_lives=Actieve Code leven
config.reset_password_code_lives=Reset wachtwoord Code leven
config.webhook_config=Webhook configuratie
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Schakel HELO uit
config.mailer_name=Naam
config.mailer_host=Host
config.mailer_user=Gebruiker
config.send_test_mail=Testbericht verzenden
config.test_mail_failed=Verzending van een testmail naar '%s' is mislukt: %v
config.test_mail_sent=Test-email is verstuurd naar '%s'.
config.oauth_config=OAuth-configuratie
config.oauth_enabled=Ingeschakeld
config.cache_config=Cache-configuratie
@@ -1023,11 +1041,11 @@ monitor.execute_time=Uitvoertijd
notices.system_notice_list=Systeem aankondigingen
notices.view_detail_header=View Notice Detail
notices.actions=Actions
notices.select_all=Select All
notices.deselect_all=Deselect All
notices.inverse_selection=Inverse Selection
notices.delete_selected=Delete Selected
notices.actions=Acties
notices.select_all=Alles selecteren
notices.deselect_all=Alles deselecteren
notices.inverse_selection=Selectie omkeren
notices.delete_selected=Selectie verwijderen
notices.delete_all=Delete All Notices
notices.type=Type
notices.type_1=Opslagplaats
@@ -1043,11 +1061,13 @@ create_issue=`opende issue in <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`reactie op issue <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="%s">%s</a>
push_tag=geduwd label <a href="%s/src/%s"> %[2]s</a> naar <a href="%[1]s"> %[3]s</a>
compare_commits=View comparison for these %d commits
compare_commits=Toon vergelijking voor deze %d commits
[tool]
ago=geleden

View File

@@ -38,19 +38,12 @@ settings=Ustawienia
your_profile=Twój profil
your_settings=Twoje ustawienia
activities=Activities
activities=Aktywności
pull_requests=Oczekujące zmiany
issues=Problemy
cancel=Anuluj
[search]
search=Wyszukiwanie...
repository=Repozytorium
user=Użytkownik
issue=Problem
code=Kod
[install]
install=Instalacja
title=Kroki instalacyjne dla pierwszego uruchomienia
@@ -86,8 +79,8 @@ http_port=Port HTTP
http_port_helper=Numer portu na którym aplikacja jest dostępna.
app_url=Adres URL aplikacji
app_url_helper=To wpłynie na adresy klonowania HTTP/HTTPS i w wiadomościach e-mail.
log_root_path=Log Path
log_root_path_helper=Directory to write log files to.
log_root_path=Ścieżka dla logów
log_root_path_helper=Katalog do zapisu logów.
optional_title=Ustawienia opcjonalne
email_title=Ustawienia serwera e-mail
@@ -124,7 +117,7 @@ run_user_not_match=Użytkownik aplikacji nie jest aktualnym użytkownikiem: %s -
save_config_failed=Nie udało się zapisać konfiguracji: %v
invalid_admin_setting=Nieprawidłowe ustawienia konta admina: %v
install_success=Cześć! Cieszymy się, że wybierałeś Gogs, baw się dobrze.
invalid_log_root_path=Log root path is invalid: %v
invalid_log_root_path=Ścieżka dla logów jest niepoprawna: %v
[home]
uname_holder=Nazwa użytkownika lub e-mail
@@ -140,6 +133,8 @@ issues.in_your_repos=W Twoich repozytoriach
[explore]
repos=Repozytoria
users=Użytkownicy
search=Wyszukiwanie
[auth]
create_new_account=Załóż nowe konto
@@ -221,8 +216,6 @@ still_own_repo=Twoje konto dalej posiada przynajmniej jedno repozytorium, które
still_has_org=Twoje konto dalej posiada członkostwo w przynajmniej jednej organizacji, którą musisz najpierw opuścić.
org_still_own_repo=Ta organizacja dalej jest właścicielem repozytorium, które musisz usunąć bądź przekazać.
still_own_user=To uwierzytelnienie dalej jest używane przez kilku użytkowników, których musisz z niego usunąć i spróbować ponownie.
target_branch_not_exist=Gałąź docelowa nie istnieje.
[user]
@@ -264,11 +257,10 @@ continue=Kontynuuj
cancel=Anuluj
enable_custom_avatar=Włącz niestandardowe awatary
enable_custom_avatar_helper=Wyłącz pobieranie z Gravatar
choose_new_avatar=Wybierz nowy avatar
update_avatar=Zaktualizuj ustawienia awatara
delete_current_avatar=Usuń obecny Avatar
uploaded_avatar_not_a_image=Załadowany plik nie jest obrazem.
no_custom_avatar_available=Własny avatar niedostępny, nie można go włączyć.
update_avatar_success=Ustawienia awatarów zostały pomyślnie zaktualizowane.
change_password=Zmień hasło
@@ -479,7 +471,7 @@ issues.closed_at=`zamyka <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`otwiera ponownie <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`wspomina ten problem w commicie <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Autor
issues.admin=Admin
issues.collaborator=Współpracownik
issues.owner=Właściciel
issues.sign_up_for_free=Zarejestruj się za darmo
issues.sign_in_require_desc=do przyłączenia się do tej rozmowy. Masz już konto? <a href="%s">Zaloguj się by komentować</a>
@@ -560,6 +552,8 @@ wiki.save_page=Zapisz stronę
wiki.last_commit_info=%s edytuje tę stronę %s
wiki.edit_page_button=Edytuj
wiki.new_page_button=Nowa strona
wiki.delete_page_button=Usuń stronę
wiki.delete_page_notice_1=Strona zostanie usunięta <code>"%s"</code>. Bądź ostrożny.
wiki.page_already_exists=Strona Wiki o tej samej nazwie już istnieje.
wiki.pages=Strony
wiki.last_updated=Ostatnia aktualizacja %s
@@ -585,16 +579,20 @@ settings.tracker_url_format_desc=Symbole zastępcze <code>{user} {repo} {index}<
settings.pulls_desc=Włącz obsługę pull request, aby akceptować publiczny wkład
settings.danger_zone=Strefa niebezpieczeństwa
settings.new_owner_has_same_repo=Nowy właściciel już posiada repozytorium o tej samej nazwie.
settings.convert=Convert To Regular Repository
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
settings.convert_confirm=Confirm Conversion
settings.convert_succeed=Repository has been converted to regular type successfully.
settings.convert=Konwersja na repozytorium regularne
settings.convert_desc=Możesz przekonwertować ten mirror na repozytorium regularne. Ta czynność nie może być odwrócona.
settings.convert_notices_1=- Ta operacja przekonwertuje mirror tego repozytorium na repozytorium regularne. Ta czynność nie może być odwrócona.
settings.convert_confirm=Potwierdź konwers
settings.convert_succeed=Typ repozytorium został zamieniony na regularne.
settings.transfer=Przeniesienie własności
settings.transfer_desc=Przenieś to repozytorium do innego użytkownika lub organizacji gdzie masz uprawnienia administratora.
settings.transfer_notices_1=- Stracisz dostęp jeśli nowy właściciel jest indywidualnym użytkownikiem.
settings.transfer_notices_2=- Zachowasz dostęp jeśli nowym właścicielem jest organizacja, której jesteś współwłaścicielem.
settings.transfer_form_title=Proszę wpisz co następuje w celu potwierdzenia operacji:
settings.wiki_delete=Kasowanie danych Wiki
settings.wiki_delete_desc=Usunięcie danych z wiki jest nieodwracalne. Bądź ostrożny.
settings.wiki_delete_notices_1=- To usunie i wyłączy wiki dla %s
settings.wiki_deletion_success=Dane wiki zostały usunięte.
settings.delete=Usuń to repozytorium
settings.delete_desc=Po usunięciu repozytorium nie ma odwrotu. Upewnij się, że tego chcesz.
settings.delete_notices_1=- Ta operacja <strong>NIE MOŻE</strong> zostać cofnięta.
@@ -610,9 +608,12 @@ settings.transfer_succeed=Własność repozytorium została przeniesiona pomyśl
settings.confirm_delete=Potwierdź usunięcie
settings.add_collaborator=Dodaj nowego współpracownika
settings.add_collaborator_success=Został dodany nowy współpracownik.
settings.delete_collaborator=Usuń
settings.collaborator_deletion=Usunięcie współpracownika
settings.collaborator_deletion_desc=Ten użytkownik nie będzie miał dostępu współpracownika do repozytorium. Czy chcesz kontynuować?
settings.remove_collaborator_success=Współpracownik został usunięty.
settings.search_user_placeholder=Szukaj użytkownika...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.org_not_allowed_to_be_collaborator=Organizacji nie można dodać jako współpracownika.
settings.user_is_org_member=Użytkownik jest członkiem organizacji, który nie może być dodany jako współpracownik.
settings.add_webhook=Dodaj webhooka
settings.hooks_desc=Webooki działają tak jak proste wywołania HTTP POST. Jeśli cokolwiek zdarzy się w Gogs, wyślemy powiadomienie do wybranego hosta. Więcej informacji można znaleźć w <a target="_blank" href="%s">przewodniku webhooków</a>.
@@ -922,7 +923,7 @@ auths.attribute_username_placeholder=Zostaw puste aby użyć wartości podanej p
auths.attribute_name=Atrybut imienia
auths.attribute_surname=Atrybut nazwiska
auths.attribute_mail=Atrybut e-mail
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.attributes_in_bind=Pobierz atrybuty w kontekście Bind DN
auths.filter=Filtr użytkownika
auths.admin_filter=Filtr administratora
auths.ms_ad_sa=Ms Ad SA
@@ -944,6 +945,7 @@ auths.update=Aktualizuj ustawienia uwierzytelniania
auths.delete=Usuń to uwierzytelnienie
auths.delete_auth_title=Usunięcie uwierzytelnienia
auths.delete_auth_desc=To uwierzytelnienie zostanie usunięte, czy chcesz kontynuować?
auths.still_in_used=Ten rodzaj autentykacji jest wciąż wykorzystywany przez niektórych użytkowników. Usuń lub przekonwertuj użytkowników, aby wykorzystywali inny typ logowania.
auths.deletion_success=Uwierzytelnienie zostało usunięte pomyślnie!
config.server_config=Konfiguracja serwera
@@ -960,6 +962,19 @@ config.static_file_root_path=Ścieżka plików statycznych
config.log_file_root_path=Ścieżka plików dziennika
config.script_type=Typ skryptu
config.reverse_auth_user=Użytkownik dostarczony przez odwrotne proxy
config.ssh_config=Konfiguracja SSH
config.ssh_enabled=Aktywne
config.ssh_start_builtin_server=Uruchom serwer wbudowany
config.ssh_domain=Domena
config.ssh_port=Port
config.ssh_listen_port=Port nasłuchu
config.ssh_root_path=Ścieżka katalogu głównego
config.ssh_key_test_path=Ścieżka klucza testowego
config.ssh_keygen_path=Ścieżka generatora ('ssh-keygen')
config.ssh_minimum_key_size_check=Sprawdzanie minimalnej długości klucza
config.ssh_minimum_key_sizes=Minimalne rozmiary kluczy
config.db_config=Konfiguracja bazy danych
config.db_type=Typ
config.db_host=Host
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Wyłącz HELO
config.mailer_name=Nazwa
config.mailer_host=Host
config.mailer_user=Użytkownik
config.send_test_mail=Wyślij email testowy
config.test_mail_failed=Nieudane wysłanie wiadomości email do '%s': %v
config.test_mail_sent=Testowa wiadomość email została wysłana do '%s'.
config.oauth_config=Konfiguracja OAuth
config.oauth_enabled=Aktywne
config.cache_config=Konfiguracja cache
@@ -1040,9 +1058,11 @@ create_repo=tworzy repozytorium <a href="%s">%s</a>
rename_repo=zmienia nazwę repozytorium <code>%[1]s</code> na <a href="%[2]s">%[3]s</a>
commit_repo=wypycha do <a href="%[1]s/src/%[2]s">%[3]s</a> w <a href="%[1]s">%[4]s</a>
create_issue=`zgłasza problem <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`zamknięcie problemu <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`ponowne otwarcie problemu <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`tworzy pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`zamknięcie pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`ponowne otwarcie pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`komentuje problem <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`scala pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=przenosi repozytorium <code>%s</code> do <a href="%s">%s</a>

View File

@@ -20,7 +20,7 @@ signed_in_as=Você é
username=Usuário
email=E-mail
password=Senha
re_type=Redigite
re_type=Digite novamente
captcha=Captcha
repository=Repositório
@@ -44,20 +44,13 @@ issues=Problemas
cancel=Cancelar
[search]
search=Pesquisar...
repository=Repositório
user=Usuário
issue=Problema
code=Código
[install]
install=Instalação
title=Etapas de instalação para primeira execução
docker_helper=Se você está rodando o Gogs dentro do Docker, por favor leia os <a target="_blank" href="%s">Guias</a> cuidadosamente antes de mudar qualquer coisa nesta página!
requite_db_desc=Gogs requer MySQL, PostgreSQL, SQLite3 ou TiDB.
db_title=Configurações de Banco de Dados
db_type=Banco de bados
db_type=Tipo do Banco de Dados
host=Host
user=Usuário
password=Senha
@@ -140,6 +133,8 @@ issues.in_your_repos=Em seus repositórios
[explore]
repos=Repositórios
users=Usuários
search=Pesquisar
[auth]
create_new_account=Criar Nova Conta
@@ -221,8 +216,6 @@ still_own_repo=Sua conta ainda tem propriedade do repositório, você tem que ex
still_has_org=Sua conta ainda faz parte da organização, você deve sair ou excluí-la primeiro.
org_still_own_repo=Esta organização ainda tem a propriedade do repositório, você deve excluir ou transferí-la primeiro.
still_own_user=Esta autenticação ainda é usada por alguns usuários, você deve movê-los e depois apagar novamente.
target_branch_not_exist=O branch de destino não existe.
[user]
@@ -264,11 +257,10 @@ continue=Continuar
cancel=Cancelar
enable_custom_avatar=Habilitar Avatar Customizado
enable_custom_avatar_helper=Habilite para desativar a busca no Gravatar
choose_new_avatar=Escolha um novo avatar
update_avatar=Atualizar configuração de Avatar
delete_current_avatar=Excluir o Avatar atual
uploaded_avatar_not_a_image=O arquivo enviado não é uma imagem.
no_custom_avatar_available=Nenhum avatar personalizado disponível, não pode habilitá-lo.
update_avatar_success=Sua configuração de avatar foi atualizada com sucesso.
change_password=Mudança de senha
@@ -479,7 +471,7 @@ issues.closed_at=`fechado em <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`reaberto em <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`citou este problema em um commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Autor
issues.admin=Administrador
issues.collaborator=Colaboradores
issues.owner=Proprietário
issues.sign_up_for_free=Cadastre-se gratuitamente
issues.sign_in_require_desc=para participar nesta conversa. Já tem uma conta? <a href="%s">Faça login para comentar</a>
@@ -560,6 +552,8 @@ wiki.save_page=Salvar página
wiki.last_commit_info=%s editou esta página %s
wiki.edit_page_button=Editar
wiki.new_page_button=Nova página
wiki.delete_page_button=Excluir Página
wiki.delete_page_notice_1=Isto irá apagar a página <code>"%s"</code>. Por favor, certifique-se.
wiki.page_already_exists=já existe uma página de wiki com o mesmo nome.
wiki.pages=Páginas
wiki.last_updated=Última atualização %s
@@ -571,7 +565,7 @@ settings.hooks=Webhooks
settings.githooks=Hooks do Git
settings.basic_settings=Configurações Básicas
settings.site=Site Oficial
settings.update_settings=Configurações de Atualização
settings.update_settings=Atualizar configurações
settings.change_reponame_prompt=Este mudanças vai afetar os links para este repositório.
settings.advanced_settings=Configurações avançadas
settings.wiki_desc=Habilitar o wiki para permitir que as pessoas escrevam documentos
@@ -595,6 +589,10 @@ settings.transfer_desc=Transferir este repositório para outro usuário ou para
settings.transfer_notices_1=- Você vai perder acesso se o novo dono for um usuário individual.
settings.transfer_notices_2=- Você vai continuar tendo acesso se o novo dono é uma organização e você é um dos membros.
settings.transfer_form_title=Informe a seguinte informação para confirmar a sua operação:
settings.wiki_delete=Apagar dados do Wiki
settings.wiki_delete_desc=Uma vez que você apague os dados da wiki, não há volta. Por favor, certifique-se.
settings.wiki_delete_notices_1=- Isso irá excluir e desativar o wiki para %s
settings.wiki_deletion_success=Dados de wiki do repositório foram deletados com sucesso.
settings.delete=Deletar Este Repositório
settings.delete_desc=Uma vez que você deleta um repositório, não tem volta. Por favor, tenha certeza.
settings.delete_notices_1=-Esta operação <strong>NÃO PODERÁ</strong> ser desfeita.
@@ -610,9 +608,12 @@ settings.transfer_succeed=A posse do repositório foi transferido com sucesso.
settings.confirm_delete=Confirmar Deleção
settings.add_collaborator=Adicionar um Novo Colaborador
settings.add_collaborator_success=O novo colaborador foi adicionado.
settings.delete_collaborator=Deletar
settings.collaborator_deletion=Exclusão de colaborador
settings.collaborator_deletion_desc=Este usuário não terá mais acesso de colaboração neste repositório após a deleção. Você quer continuar?
settings.remove_collaborator_success=O colaborador foi removido.
settings.search_user_placeholder=Pesquisar usuário...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.org_not_allowed_to_be_collaborator=Organização não tem permissão para ser adicionada como um colaborador.
settings.user_is_org_member=O usuário é um membro da organização que não pode ser adicionado como um colaborador.
settings.add_webhook=Adicionar Webhook
settings.hooks_desc=Hooks da web ou Webhooks permitem serviços externos serem notificados quando certos eventos acontecem no Gogs. Quando acontecem os eventos especificados, enviaremos uma solicitação POST para cada uma das URLs que você fornecer. Saiba mais no nosso <a target="_blank" href="%s"> Guia de Webhooks</a>.
@@ -757,7 +758,7 @@ members.membership_visibility=Visibilidade da associação:
members.public=Público
members.public_helper=tornar privado
members.private=Privado
members.private_helper=torar público
members.private_helper=tornar público
members.member_role=Categoria de membro:
members.owner=Dono
members.member=Membro
@@ -922,7 +923,7 @@ auths.attribute_username_placeholder=Deixe vazio para usar o valor do campo de f
auths.attribute_name=Atributo primeiro nome
auths.attribute_surname=Atributo sobrenome
auths.attribute_mail=Atributo e-mail
auths.attributes_in_bind=Fetch attributes in Bind DN context
auths.attributes_in_bind=Buscar os atributos no contexto de Bind DN
auths.filter=Filtro de usuário
auths.admin_filter=Filtro de administrador
auths.ms_ad_sa=Ms Ad SA
@@ -944,6 +945,7 @@ auths.update=Atualizar a configuração da autenticação
auths.delete=Excluir esta autenticação
auths.delete_auth_title=Exclusão da autenticação
auths.delete_auth_desc=Esta autenticação esta prestes a ser deletada, deseja continuar?
auths.still_in_used=Esta autenticação ainda é usada por alguns usuários. Por favor delete ou converta esses usuários para outro tipo de login primeiro.
auths.deletion_success=Autenticação deletada com sucesso!
config.server_config=Configuração do Servidor
@@ -960,6 +962,19 @@ config.static_file_root_path=Caminho Raiz para Arquivo Estático
config.log_file_root_path=Caminho Raiz para Arquivo de Log
config.script_type=Tipo de Script
config.reverse_auth_user=Usuário de Autenticação Reversa
config.ssh_config=Configuração de SSH
config.ssh_enabled=Habilitado
config.ssh_start_builtin_server=Iniciar servidor embutido
config.ssh_domain=Domínio
config.ssh_port=Porta
config.ssh_listen_port=Porta de escuta
config.ssh_root_path=Caminho da raiz
config.ssh_key_test_path=Caminho da chave de teste
config.ssh_keygen_path=Caminho do keygen ('ssh-keygen')
config.ssh_minimum_key_size_check=Verificar tamanho mínimo da chave
config.ssh_minimum_key_sizes=Tamanhos mínimos da chave
config.db_config=Configuração do Banco de Dados
config.db_type=Tipo
config.db_host=Host
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Desabilitar HELO
config.mailer_name=Nome
config.mailer_host=Host
config.mailer_user=Usuário
config.send_test_mail=Enviar email de teste
config.test_mail_failed=Falha ao enviar o email de teste para '%s': %v
config.test_mail_sent=O email de teste foi enviado para '%s'.
config.oauth_config=Configuração do OAuth
config.oauth_enabled=Habilitado
config.cache_config=Configuração de Cache
@@ -1040,9 +1058,11 @@ create_repo=repositório criado <a href="%s"> %s</a>
rename_repo=renomeou o o repositório <code>%[1]s</code> para <a href="%[2]s">%[3]s</a>
commit_repo=pushed para <a href="%[1]s/src/%[2]s">%[3]s</a> em <a href="%[1]s">%[4]s</a>
create_issue=`questão aberta <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`questão fechada <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`questão reaberta <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`criou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`fechou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reabriu o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`comentou sobre a questão <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`mesclou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=repositório transferido de <code>%s</code> para <a href="%s">%s</a>

View File

@@ -1,4 +1,4 @@
app_desc=Удобная служба для собственного Git-репозитория, написанная на языке Go
app_desc=Удобная служба для собственного Git-репозитория
home=Главная
dashboard=Панель управления
@@ -14,14 +14,14 @@ page=Страница
template=Шаблон
language=Язык
create_new=Создать...
user_profile_and_more=Профиль и остальное
user_profile_and_more=Профиль пользователя и прочее
signed_in_as=Вы вошли как
username=Имя пользователя
email=Эл. почта
password=Пароль
re_type=Повтор
captcha=Captcha
re_type=Введите повторно
captcha=Капча
repository=Репозиторий
organization=Организация
@@ -29,9 +29,9 @@ mirror=Зеркало
new_repo=Новый репозиторий
new_migrate=Новая Миграция
new_mirror=Новое зеркало
new_fork=Новый проект из репозитория
new_fork=Новое ответвление репозитория
new_org=Новая организация
manage_org=Управление организацией
manage_org=Управление организациями
admin_panel=Панель администратора
account_settings=Настройки аккаунта
settings=Настройки
@@ -44,13 +44,6 @@ issues=Задачи
cancel=Отмена
[search]
search=Поиск...
repository=Репозиторий
user=Пользователь
issue=Задача
code=Код
[install]
install=Установка
title=Установочные шаги для первого запуска
@@ -132,7 +125,7 @@ password_holder=Пароль
switch_dashboard_context=Переключить контекст панели управления
my_repos=Мои репозитории
collaborative_repos=Совместные репозитории
my_orgs=Моя Организация
my_orgs=Мои организации
my_mirrors=Мои зеркала
view_home=Показать %s
@@ -140,6 +133,8 @@ issues.in_your_repos=В ваших репозиториях
[explore]
repos=Репозитории
users=Пользователи
search=Поиск
[auth]
create_new_account=Создать новый аккаунт
@@ -153,7 +148,7 @@ forget_password=Забыли пароль?
sign_up_now=Нужен аккаунт? Зарегистрируйтесь.
confirmation_mail_sent_prompt=Новое письмо для подтверждения было направлено на <b>%s</b>, пожалуйста, проверьте ваш почтовый ящик в течение %d часов для завершения регистрации.
active_your_account=Активируйте свой аккаунт
resent_limit_prompt=Вы слишком часто отправляете письмо с активацией. Подождите 3 минуты, пожалуйста.
resent_limit_prompt=Извините, вы уже запросили активацию по электронной почте недавно. Пожалуйста, подождите 3 минуты, а затем повторите попытку.
has_unconfirmed_mail=Здравствуйте, %s! У вас есть неподтвержденный адрес электронной почты (<b>%s</b>). Если вам не приходило письмо с подтверждением или нужно выслать новое письмо, нажмите на кнопку ниже.
resend_mail=Нажмите здесь, чтобы переотправить активационное письмо
email_not_associate=Этот адрес электронной почты не связан ни с одной учетной записью.
@@ -195,23 +190,23 @@ size_error=` должен быть размер %s.`
min_size_error=«должен содержать по крайней мере %s символов.»
max_size_error=` должен содержать максимум %s символов.`
email_error=«не является адресом электронной почты.»
url_error=«не является допустимым URL-адресом.»
include_error=` должен содержать '%s'`
url_error=` не является допустимым URL-адресом.`
include_error=` должен содержать '%s'.`
unknown_error=Неизвестная ошибка:
captcha_incorrect=CAPTCHA не совпадает.
password_not_match=Пароль и подтверждение пароля не совпадают.
captcha_incorrect=Капча не пройдена.
password_not_match=Пароли не совпадают.
username_been_taken=Имя пользователя уже принято.
repo_name_been_taken=Имя репозитория уже принято.
org_name_been_taken=Название организации было уже принято.
team_name_been_taken=Название команды было уже принято.
username_been_taken=Имя пользователя занято.
repo_name_been_taken=Имя репозитория занято.
org_name_been_taken=Название организации занято.
team_name_been_taken=Название команды занято.
email_been_used=Адрес электронной почты уже используется.
username_password_incorrect=Имя пользователя или пароль не правильный.
enterred_invalid_repo_name=Пожалуйста, убедитесь, что введенно правильное имя хранилища.
enterred_invalid_repo_name=Пожалуйста, убедитесь, что введено правильное имя репозитория.
enterred_invalid_owner_name=Убедитесь, что введенное имя владельца верное.
enterred_invalid_password=Убедитесь, что введенный пароль верен.
user_not_exist=Данный пользователь не существует.
last_org_owner=Удаляемый пользователь является последним в команде владельцев. Должен быть хотя бы один владелец.
last_org_owner=Удаление последнего пользователя из команды владельцев невозможно, поскольку всегда должен быть хотя бы один владелец в любой организации.
invalid_ssh_key=К сожалению, мы не смогли проверить ваш SSH-ключ: %s
unable_verify_ssh_key=Gogs не может проверить ваш SSH-ключ, но мы допускаем, что он действителен. Пожалуйста, удостоверьтесь самостоятельно, что ключ действителен.
@@ -221,8 +216,6 @@ still_own_repo=На вашем аккаунте все еще остается
still_has_org=Вы находитесь в организации, сперва Вам необходимо покинуть ее или удалить.
org_still_own_repo=Данная организация все еще является владельцем репозиториев, необходимо удалить или переместить их в начале.
still_own_user=Эта проверка подлинности по-прежнему используется некоторыми пользователями, вы должны переместить их и затем снова удалить.
target_branch_not_exist=Целевая ветка не существует
[user]
@@ -264,11 +257,10 @@ continue=Далее
cancel=Отмена
enable_custom_avatar=Включить собственный аватар
enable_custom_avatar_helper=Включите эту опцию, чтоб отключить загрузку с Gravatar
choose_new_avatar=Выбрать новый аватар
update_avatar=Обновить настройку аватара
delete_current_avatar=Удалить текущий аватар
uploaded_avatar_not_a_image=Загружаемый файл не является изображением.
no_custom_avatar_available=Собственный аватар недоступен, включить его невозможно.
update_avatar_success=Настройка вашего аватара обновлена успешно.
change_password=Сменить пароль
@@ -326,7 +318,7 @@ token_name=Имя маркера
generate_token=Генерировать маркер
generate_token_succees=Успешно создан новый токен доступа! Пожалуйста сделайте копию вашего нового токена персонального доступа. Вы не сможете увидеть его снова!
delete_token=Удалить
access_token_deletion=Удаление персонального токена доступа
access_token_deletion=Удаление личного токена доступа
access_token_deletion_desc=Удаление этого персонального токена доступа приведет к удалению всех связанных прав доступа к приложению. Вы хотите продолжить?
delete_token_success=Персональный токен доступа успешно удален! Не забудьте изменить настройки вашего приложения.
@@ -343,7 +335,7 @@ repo_name_helper=Лучшие названия репозиториев коро
visibility=Видимость
visiblity_helper=<span class="ui red text">Личный</span> репозиторий
visiblity_helper_forced=Все новые репозитории являются <span class="ui red text">Личными</span> по желанию администратора сайта
visiblity_fork_helper=(Изменение этого значения затронет все форки)
visiblity_fork_helper=(Изменение этого значения затронет все ответвления)
clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" href="%s">помощи</a>!
fork_repo=Ответвить репозиторий
fork_from=Ответвление от
@@ -363,7 +355,7 @@ mirror_address=Адрес зеркала
mirror_address_desc=Укажите необходимые учетные данные в адрес.
watchers=Наблюдатели
stargazers=Звездочеты
forks=Форки
forks=Ответвления
form.reach_limit_of_creation=У владельца достигнут максимальный предел в %d создаваемых репозиториев.
form.name_reserved=Имя репозитория '%s' зарезервировано.
@@ -380,8 +372,8 @@ migrate.invalid_local_path=Недопустимый локальный путь.
migrate.failed=Миграция не удалась: %v
mirror_from=зеркало из
forked_from=форк от
fork_from_self=Вы не можете форкнуть репозитарий, так как Вы уже его владелец!
forked_from=ответвлено от
fork_from_self=Вы не можете ответвить репозиторий, так как Вы уже его владелец!
copy_link=Скопировать
copy_link_success=Скопировано!
copy_link_error=Нажмите ⌘-C или Ctrl-C для копирования
@@ -479,7 +471,7 @@ issues.closed_at=`закрыл <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`открыл снова <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`упомянул эту задачу в коммите <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Автор
issues.admin=Администратор
issues.collaborator=Соавтор
issues.owner=Владелец
issues.sign_up_for_free=Зарегистрируйтесь бесплатно
issues.sign_in_require_desc=чтобы присоединиться к обсуждению. Уже есть аккаунт? <a href="%s">Войдите чтобы прокомментировать</a>
@@ -506,7 +498,7 @@ pulls.compare_compare=сравнить
pulls.filter_branch=Фильтр по ветке
pulls.no_results=Результатов не найдено.
pulls.nothing_to_compare=Нечего сравнивать, родительская и текущая ветка одинаковые.
pulls.has_pull_request=`Уже существует пулл-реквест между двумя целями <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
pulls.has_pull_request=`Уже существует запрос на слияние между двумя целями: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
pulls.create=Создать запрос на слияние
pulls.title_desc=хочет смерджить %[1]d коммит(ов) из <code>%[2]s</code> в <code>%[3]s</code>
pulls.merged_title_desc=слито %[1]d коммит(ов) из <code>%[2]s</code> в <code>%[3]s</code> %[4]s
@@ -516,7 +508,7 @@ pulls.tab_files=Измененные файлы
pulls.reopen_to_merge=Пожалуйста снова откройте этот запрос для слияния.
pulls.merged=Слито
pulls.has_merged=Слияние этого запроса успешно завершено!
pulls.data_broken=Содержимое этого пулл-реквеста было нарушено, вследствии удаления или клонирования информации.
pulls.data_broken=Содержимое этого запроса было нарушено вследствие удаления информации ответвления.
pulls.is_checking=Продолжается проверка конфликтов, пожалуйста обновите страницу несколько позже.
pulls.can_auto_merge_desc=Этот запрос на слияние может быть объединён автоматически.
pulls.cannot_auto_merge_desc=Этот запрос на слияние не может быть объединён автоматически.
@@ -550,7 +542,7 @@ milestones.deletion_success=Контрольная точка успешно у
wiki=Вики
wiki.welcome=Добро пожаловать в Вики!
wiki.welcome_desc=Вики это место, где вы хотели бы документировать проект вместе и сделать его лучше.
wiki.welcome_desc=Вики это место, где вы можете документировать проект вместе и сделать его лучше.
wiki.create_first_page=Создать первую страницу
wiki.page=Страница
wiki.filter_page=Фильтр страницы
@@ -560,6 +552,8 @@ wiki.save_page=Сохранить страницу
wiki.last_commit_info=%s редактировал эту страницу %s
wiki.edit_page_button=Редактировать
wiki.new_page_button=Новая страница
wiki.delete_page_button=Удалить страницу
wiki.delete_page_notice_1=Будьте внимательны! Это приведет к удалению страницы <code>«%s»</code>.
wiki.page_already_exists=Вики-страница с таким именем уже существует.
wiki.pages=Страницы
wiki.last_updated=Последнее обновление %s
@@ -576,7 +570,7 @@ settings.change_reponame_prompt=Это изменение повлияет на
settings.advanced_settings=Расширенные настройки
settings.wiki_desc=Включить Вики, чтобы позволить людям писать документы
settings.use_external_wiki=Использовать внешнюю Wiki
settings.external_wiki_url=URL-адрес внешней вики
settings.external_wiki_url=URL-адрес внешней Вики
settings.external_wiki_url_desc=Посетители будут перенаправлены на URL-адрес, когда они кликнут по вкладке.
settings.issues_desc=Включить встроенную, легковесную систему отслеживания ошибок
settings.use_external_issue_tracker=Использовать внешнюю систему отслеживания ошибок
@@ -595,13 +589,17 @@ settings.transfer_desc=Передать репозиторий другому п
settings.transfer_notices_1=- Вы можете потерять доступ, если новый владелец является отдельным пользователем.
settings.transfer_notices_2=- Вы сохраните доступ, если новым владельцем станет организация, владельцем которой вы являетесь.
settings.transfer_form_title=Введите сопутствующую информацию для подтверждения операции:
settings.wiki_delete=Стереть данные Вики
settings.wiki_delete_desc=Будьте внимательны! Как только вы удалите Вики — пути назад не будет.
settings.wiki_delete_notices_1=-Это будет удалено и отключит Вики для %s
settings.wiki_deletion_success=Данные Вики успешно стерты.
settings.delete=Удалить этот репозиторий
settings.delete_desc=Как только вы удалите репозиторий — пути назад не будет. Удостоверьтесь, что вам это точно нужно.
settings.delete_desc=Будьте внимательны! Как только вы удалите репозиторий — пути назад не будет.
settings.delete_notices_1=- Эта операция <strong>НЕ МОЖЕТ</strong> быть отменена.
settings.delete_notices_2=- Эта операция навсегда удалит всё из этого репозитория, включая данные Git, связанные с ним задачи, комментарии и права доступа для сотрудников.
settings.delete_notices_fork_1=- Если данный репозиторий является публичным, все склонированные репозитории останутся независимыми, после его удаления.
settings.delete_notices_fork_2=- Если данный репозиторий является приватным, все его форки будут удалены вместе с ним.
settings.delete_notices_fork_3=- Если вы хотите сохранить все форки после удаления репозитория, то сначала сделайте его публичным.
settings.delete_notices_fork_2=- Если данный репозиторий является приватным, все его ответвления будут удалены вместе с ним.
settings.delete_notices_fork_3=- Если вы хотите сохранить все ответвления после удаления репозитория, то сначала сделайте его публичным.
settings.deletion_success=Репозиторий был успешно удалён!
settings.update_settings_success=Настройка репозитория обновлена успешно.
settings.transfer_owner=Новый владелец
@@ -610,6 +608,9 @@ settings.transfer_succeed=Владение репозиторием было у
settings.confirm_delete=Подтвердить удаление
settings.add_collaborator=Добавить нового соавтора
settings.add_collaborator_success=Был добавлен новый соавтор.
settings.delete_collaborator=Удалить
settings.collaborator_deletion=Удаление соавтора
settings.collaborator_deletion_desc=Этот пользователь больше не будет иметь доступа для совместной работы в этом репозитории после удаления. Вы хотите продолжить?
settings.remove_collaborator_success=Соавтор был удален.
settings.search_user_placeholder=Поиск пользователя...
settings.org_not_allowed_to_be_collaborator=Организации не могут быть добавлены как соавторы.
@@ -686,7 +687,7 @@ diff.view_file=Просмотреть файл
release.releases=Релизы
release.new_release=Новый релиз
release.draft=Черновик
release.prerelease=Предрелиз
release.prerelease=Пре-релиз
release.stable=Стабильный
release.edit=Редактировать
release.ahead=<strong>%d</strong> коммитов %s начиная с этого релиза
@@ -709,9 +710,9 @@ release.save_draft=Сохранить черновик
release.edit_release=Редактировать релиз
release.delete_release=Удалить этот релиз
release.deletion=Удаление релиза
release.deletion_desc=Удаление данного релиза так же удалит все относящиеся к нему Git теги. Продолжить?
release.deletion_desc=Удаление этого релиза удалит соответствующую Git метку. Вы хотите продолжить?
release.deletion_success=Релиз был успешно удален!
release.tag_name_already_exist=Релиз с этим именем тега уже существует.
release.tag_name_already_exist=Релиз с этим именем метки уже существует.
release.downloads=Загрузки
[org]
@@ -944,6 +945,7 @@ auths.update=Обновить параметры аутентификации
auths.delete=Удалить этот канал аутентификации
auths.delete_auth_title=Удаление канала аутентификации
auths.delete_auth_desc=Этот канал аутентификации будет удален. Вы уверены что хотите продолжить?
auths.still_in_used=Эта проверка подлинности до сих пор используется некоторыми пользователями, удалите или преобразуйте этих пользователей в другой тип входа в систему.
auths.deletion_success=Канал аутентификации успешно удален!
config.server_config=Конфигурация сервера
@@ -960,6 +962,19 @@ config.static_file_root_path=Статичный путь до файла
config.log_file_root_path=Путь до папки с логами
config.script_type=Тип сценария
config.reverse_auth_user=Заголовок с именем пользователя для авторизации на reverse proxy
config.ssh_config=Конфигурация SSH
config.ssh_enabled=Включено
config.ssh_start_builtin_server=Запустить встроенный сервер
config.ssh_domain=Домен
config.ssh_port=Порт
config.ssh_listen_port=Прослушиваемый порт
config.ssh_root_path=Корневой путь
config.ssh_key_test_path=Путь к тестовому ключу
config.ssh_keygen_path=Путь к генератору ключей ('ssh-keygen')
config.ssh_minimum_key_size_check=Минимальный размер ключа проверки
config.ssh_minimum_key_sizes=Минимальные размеры ключа
config.db_config=Конфигурация базы данных
config.db_type=Тип
config.db_host=Хост
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=Отключить HELO
config.mailer_name=Имя
config.mailer_host=Сервер
config.mailer_user=Пользователь
config.send_test_mail=Отправить тестовое письмо
config.test_mail_failed=Не удалось отправить тестовое письмо «%s»: %v
config.test_mail_sent=Тестовое письмо было отправлено «%s».
config.oauth_config=Конфигурация OAuth
config.oauth_enabled=Включено
config.cache_config=Настройки кеша
@@ -1037,12 +1055,14 @@ notices.delete_success=Системное уведомление успешно
[action]
create_repo=создал(а) репозиторий <a href="%s"> %s</a>
rename_repo=репозиторий переименован из <code>%[1]s</code>на <a href="%[2]s">%[3]s</a>
rename_repo=переименовал(а) репозиторий из <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
commit_repo=запушил(а) <a href="%[1]s/src/%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
create_issue=`открыл(а) задачу <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`закрыл(а) задачу <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`возобновил(а) задачу <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`созданный пулл-реквест <a href="%s/pulls/%s">%s#%[2]s</a>`
create_pull_request=`создал запрос на слияние <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`закрыл запрос на слияние <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`открыл снова запрос на слияние <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`прокомментировал(а) вопрос <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`слил пул реквест <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=перенес репозиторий <code>%s</code> в <a href="%s">%s</a>

View File

@@ -44,13 +44,6 @@ issues=工单管理
cancel=取消
[search]
search=搜索...
repository=仓库
user=用户
issue=工单
code=代码
[install]
install=安装页面
title=首次运行安装程序
@@ -139,7 +132,9 @@ view_home=访问 %s
issues.in_your_repos=属于该用户仓库的
[explore]
repos=探索仓库
repos=仓库
users=用户
search=搜索
[auth]
create_new_account=创建帐户
@@ -221,8 +216,6 @@ still_own_repo=您的帐户仍然是某些仓库的拥有者,您必须先转
still_has_org=您的帐户仍旧是某些组织的成员,您必须先离开或删除组织。
org_still_own_repo=该组织仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除组织操作!
still_own_user=该授权认证依旧被部分用户使用,请先删除该部分用户后再试!
target_branch_not_exist=目标分支不存在。
[user]
@@ -264,11 +257,10 @@ continue=继续操作
cancel=取消操作
enable_custom_avatar=启动自定义头像
enable_custom_avatar_helper=激活该选项来禁止从 Gravatar 获取头像
choose_new_avatar=选择新的头像
update_avatar=更新头像设置
delete_current_avatar=删除当前头像
uploaded_avatar_not_a_image=上传的文件不是一张图片!
no_custom_avatar_available=未上传过自定义头像,无法激活该选项。
update_avatar_success=您的头像设置更新成功!
change_password=修改密码
@@ -479,7 +471,7 @@ issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭`
issues.reopened_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 重新开启`
issues.commit_ref_at=`在代码提交 <a id="%[1]s" href="#%[1]s">%[2]s</a> 中引用了该工单`
issues.poster=发布者
issues.admin=管理员
issues.collaborator=协作者
issues.owner=所有者
issues.sign_up_for_free=免费注册
issues.sign_in_require_desc=并加入到对话中来。如果您已经注册,可以直接 <a href="%s">登录并评论</a>
@@ -560,6 +552,8 @@ wiki.save_page=保存页面
wiki.last_commit_info=%s 于 %s 修改了此页面
wiki.edit_page_button=修改
wiki.new_page_button=新的页面
wiki.delete_page_button=删除页面
wiki.delete_page_notice_1=此操作将删除页面 <code>"%s"</code>,请三思而后行。
wiki.page_already_exists=相同名称的 Wiki 页面已经存在。
wiki.pages=所有页面
wiki.last_updated=最后更新于 %s
@@ -595,6 +589,10 @@ settings.transfer_desc=您可以将仓库转移至您拥有管理员权限的帐
settings.transfer_notices_1=- 如果您将仓库转移给个人用户,您将会丢失操作权限。
settings.transfer_notices_2=- 如果您将仓库转移给您是所有者的组织,您的操作权限将被保留。
settings.transfer_form_title=请输入以下信息以确认您的操作:
settings.wiki_delete=清除 Wiki 数据
settings.wiki_delete_desc=清除 Wiki 数据操作不可逆转,请三思而后行。
settings.wiki_delete_notices_1=- 此操作将会清除并禁用仓库 %s 的 Wiki
settings.wiki_deletion_success=仓库 Wiki 数据清除成功!
settings.delete=删除本仓库
settings.delete_desc=删除仓库操作不可逆转,请三思而后行。
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滚。
@@ -610,6 +608,9 @@ settings.transfer_succeed=仓库所有权转移成功!
settings.confirm_delete=确认删除仓库
settings.add_collaborator=增加新的协作者
settings.add_collaborator_success=成功添加新的协作者!
settings.delete_collaborator=删除
settings.collaborator_deletion=删除协作者
settings.collaborator_deletion_desc=此用户被删除后将不再拥有相关的协作权限。是否继续?
settings.remove_collaborator_success=被操作的协作者已经被收回权限!
settings.search_user_placeholder=搜索用户...
settings.org_not_allowed_to_be_collaborator=组织不允许被添加为仓库协作者!
@@ -944,6 +945,7 @@ auths.update=更新认证设置
auths.delete=删除该认证
auths.delete_auth_title=删除认证操作
auths.delete_auth_desc=该认证将被删除。是否继续?
auths.still_in_used=此认证仍旧与一些用户有关联,请先删除或者将这些用户转换为其它登录类型。
auths.deletion_success=授权源删除成功!
config.server_config=服务器配置
@@ -960,6 +962,19 @@ config.static_file_root_path=静态文件根目录
config.log_file_root_path=日志文件根目录
config.script_type=脚本类型
config.reverse_auth_user=反向代理认证
config.ssh_config=SSH 配置
config.ssh_enabled=启用服务
config.ssh_start_builtin_server=启用内置服务
config.ssh_domain=域名
config.ssh_port=端口
config.ssh_listen_port=监听端口
config.ssh_root_path=根目录
config.ssh_key_test_path=密钥测试路径
config.ssh_keygen_path=密钥生成器('ssh-keygen')路径
config.ssh_minimum_key_size_check=密钥最小长度检查
config.ssh_minimum_key_sizes=密钥最小长度限制
config.db_config=数据库配置
config.db_type=数据库类型
config.db_host=主机地址
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=发送者名称
config.mailer_host=邮件主机地址
config.mailer_user=发送者帐号
config.send_test_mail=发送测试邮件
config.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
config.test_mail_sent=测试邮件已经发送至 '%s'。
config.oauth_config=社交帐号配置
config.oauth_enabled=启用服务
config.cache_config=Cache 配置
@@ -1043,6 +1061,8 @@ create_issue=`创建了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`关闭了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`重新开启了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`创建了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`关闭了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`重新开启了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`评论了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`合并了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=将仓库 <code>%s</code> 转移至 <a href="%s">%s</a>

View File

@@ -44,13 +44,6 @@ issues=問題
cancel=取消
[search]
search=搜尋...
repository=倉庫
user=用戶
issue=工單
code=程式碼
[install]
install=安裝頁面
title=首次安裝步驟
@@ -140,6 +133,8 @@ issues.in_your_repos=屬於該用戶倉庫的
[explore]
repos=探索倉庫
users=Users
search=Search
[auth]
create_new_account=創建帳戶
@@ -221,8 +216,6 @@ still_own_repo=您的帳戶仍然是某些倉庫的擁有者,您必須先轉
still_has_org=您的帳戶仍舊是某些組織的成員,您必須先離開或刪除組織。
org_still_own_repo=該組織仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除組織操作!
still_own_user=該授權認證依舊被部分用戶使用,請先刪除該部分用戶後再試!
target_branch_not_exist=目標分支不存在
[user]
@@ -264,11 +257,10 @@ continue=繼續操作
cancel=取消操作
enable_custom_avatar=啟動自定義頭像
enable_custom_avatar_helper=激活該選項來禁止從 Gravatar 獲取頭像
choose_new_avatar=選擇新的頭像
update_avatar=更新頭像設置
delete_current_avatar=Delete Current Avatar
uploaded_avatar_not_a_image=上傳的文件不是一張圖片!
no_custom_avatar_available=沒有任何自定義頭像,無法激活該選項。
update_avatar_success=您的頭像設置更新成功!
change_password=修改密碼
@@ -479,7 +471,7 @@ issues.closed_at=`於 <a id="%[1]s" href="#%[1]s">%[2]s</a> 關閉`
issues.reopened_at=`於 <a id="%[1]s" href="#%[1]s">%[2]s</a> 重新開啟`
issues.commit_ref_at=`在代碼提交 <a id="%[1]s" href="#%[1]s">%[2]s</a> 中引用了該問題`
issues.poster=發佈者
issues.admin=管理員
issues.collaborator=Collaborator
issues.owner=所有者
issues.sign_up_for_free=免費註冊
issues.sign_in_require_desc=及加入到對話當中。如果您已經註冊,可以直接 <a href="%s">登錄及評論</a>
@@ -560,6 +552,8 @@ wiki.save_page=保存頁面
wiki.last_commit_info=%s 於 %s 修改了此頁面
wiki.edit_page_button=修改
wiki.new_page_button=新的頁面
wiki.delete_page_button=Delete Page
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
wiki.pages=所有頁面
wiki.last_updated=最後更新於 %s
@@ -595,6 +589,10 @@ settings.transfer_desc=您可以將倉庫轉移至您擁有管理員權限的帳
settings.transfer_notices_1=- 如果您將倉庫轉移給個人用戶,您將會丟失操作權限。
settings.transfer_notices_2=- 如果您將倉庫轉移給您是所有者的組織,您的操作權限將被保留。
settings.transfer_form_title=請輸入以下信息以確認您的操作:
settings.wiki_delete=Erase Wiki Data
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
settings.delete=刪除本倉庫
settings.delete_desc=刪除倉庫操作不可逆轉,請三思而後行。
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滾。
@@ -610,6 +608,9 @@ settings.transfer_succeed=倉庫所有權轉移成功!
settings.confirm_delete=確認刪除倉庫
settings.add_collaborator=增加新的協作者
settings.add_collaborator_success=成功添加新的協作者!
settings.delete_collaborator=Delete
settings.collaborator_deletion=Collaborator Deletion
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
settings.remove_collaborator_success=被操作的協作者已經被收回權限!
settings.search_user_placeholder=搜索用戶...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
@@ -944,6 +945,7 @@ auths.update=更新認證設置
auths.delete=刪除該認證
auths.delete_auth_title=刪除認證操作
auths.delete_auth_desc=該認證將被刪除。是否繼續?
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
auths.deletion_success=認證源刪除成功!
config.server_config=服務器配置
@@ -960,6 +962,19 @@ config.static_file_root_path=靜態文件根目錄
config.log_file_root_path=日志文件根目錄
config.script_type=腳本類型
config.reverse_auth_user=反向代理認證
config.ssh_config=SSH Configuration
config.ssh_enabled=Enabled
config.ssh_start_builtin_server=Start Builtin Server
config.ssh_domain=Domain
config.ssh_port=Port
config.ssh_listen_port=Listen Port
config.ssh_root_path=Root Path
config.ssh_key_test_path=Key Test Path
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
config.ssh_minimum_key_size_check=Minimum Key Size Check
config.ssh_minimum_key_sizes=Minimum Key Sizes
config.db_config=數據庫配置
config.db_type=數據庫類型
config.db_host=主機地址
@@ -989,6 +1004,9 @@ config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱
config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號
config.send_test_mail=Send Test Email
config.test_mail_failed=Fail to send test email to '%s': %v
config.test_mail_sent=Test email has been sent to '%s'.
config.oauth_config=社交帳號配置
config.oauth_enabled=啟用服務
config.cache_config=Cache 配置
@@ -1043,6 +1061,8 @@ create_issue=`創建了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`創建了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`合併了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>

View File

@@ -1,10 +1,10 @@
# Docker for Gogs
Visit [Docker Hub](https://hub.docker.com/r/gogs/gogs/) or [Quay](https://quay.io/repository/gogs/gogs) see all available tags.
Visit [Docker Hub](https://hub.docker.com/r/gogs/gogs/) see all available tags.
## Usage
To keep your data out of Docker container, we do a volume(`/var/gogs` -> `/data`) here, and you can change it based on your situation.
To keep your data out of Docker container, we do a volume (`/var/gogs` -> `/data`) here, and you can change it based on your situation.
```
# Pull image from Docker Hub.
@@ -64,10 +64,10 @@ Most of settings are obvious and easy to understand, but there are some settings
- **Repository Root Path**: keep it as default value `/home/git/gogs-repositories` because `start.sh` already made a symbolic link for you.
- **Run User**: keep it as default value `git` because `start.sh` already setup a user with name `git`.
- **Domain**: fill in with Docker container IP(e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
- **Domain**: fill in with Docker container IP (e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
- **SSH Port**: Use the exposed port from Docker container. For example, your SSH server listens on `22` inside Docker, but you expose it by `10022:22`, then use `10022` for this value. **Builtin SSH server is not recommended inside Docker Container**
- **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, and you expose it by `10080:3000`, but you still use `3000` for this value.
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values(e.g. `http://192.168.99.100:10080/`).
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values (e.g. `http://192.168.99.100:10080/`).
Full documentation of application settings can be found [here](http://gogs.io/docs/advanced/configuration_cheat_sheet.html).
@@ -88,4 +88,4 @@ Steps to upgrade Gogs with Docker:
## Known Issues
- `.dockerignore` seems to be ignored during Docker Hub Automated build
- The docker container can not currently be build on Raspberry 1 (armv6l) as our base image `alpine` does not have a `go` package available for this platform.

View File

@@ -7,7 +7,7 @@ export GOPATH=/tmp/go
export PATH=${PATH}:${GOPATH}/bin
# Install build deps
apk -U --no-progress add --virtual build-deps linux-pam-dev go gcc musl-dev
apk --no-cache --no-progress add --virtual build-deps linux-pam-dev go gcc musl-dev
# Init go environment to build Gogs
mkdir -p ${GOPATH}/src/github.com/gogits/

144
glide.lock generated Normal file
View File

@@ -0,0 +1,144 @@
hash: f2fa73b9a379e1fa12f2b48fb0b9942a545b4518a2d71cbd956ee81093347773
updated: 2016-03-19T14:44:26.835671547-04:00
imports:
- name: github.com/bradfitz/gomemcache
version: fb1f79c6b65acda83063cbc69f6bba1522558bfc
subpackages:
- memcache
- name: github.com/codegangsta/cli
version: aca5b047ed14d17224157c3434ea93bf6cdaadee
- name: github.com/go-macaron/binding
version: a68f34212fe257219981e43adfe4c96ab48f42cd
- name: github.com/go-macaron/cache
version: 56173531277692bc2925924d51fda1cd0a6b8178
subpackages:
- memcache
- redis
- name: github.com/go-macaron/captcha
version: 8aa5919789ab301e865595eb4b1114d6b9847deb
- name: github.com/go-macaron/csrf
version: 6a9a7df172cc1fcd81e4585f44b09200b6087cc0
- name: github.com/go-macaron/gzip
version: cad1c6580a07c56f5f6bc52d66002a05985c5854
- name: github.com/go-macaron/i18n
version: d2d3329f13b52314f3292c4cecb601fad13f02c8
- name: github.com/go-macaron/inject
version: c5ab7bf3a307593cd44cb272d1a5beea473dd072
- name: github.com/go-macaron/session
version: 66031fcb37a0fff002a1f028eb0b3a815c78306b
subpackages:
- redis
- name: github.com/go-macaron/toolbox
version: 82b511550b0aefc36b3a28062ad3a52e812bee38
- name: github.com/go-sql-driver/mysql
version: 66312f7fe2678aa0f5ec770f96702f4c4ec5aa8e
- name: github.com/go-xorm/core
version: 502158401cde814951eae62f064d9e5ff39e13ce
- name: github.com/go-xorm/xorm
version: 769f6b3ae663248e8f1b1d8fecbe1eb26ac77ac7
- name: github.com/gogits/chardet
version: 2404f777256163ea3eadb273dada5dcb037993c0
- name: github.com/gogits/cron
version: 3abc0f88f2062336bcc41b43a4febbd847a390ce
- name: github.com/gogits/git-module
version: 76e8cce6c7ef3ba1cf75752261c721ebf14cd129
- name: github.com/gogits/go-gogs-client
version: 788ec59749df076b98e208909b44fdef02779deb
- name: github.com/issue9/identicon
version: f8c0d2ce04db79c663b1da33d3a9f62be753ee88
- name: github.com/kardianos/minwinsvc
version: cad6b2b879b0970e4245a20ebf1a81a756e2bb70
- name: github.com/klauspost/compress
version: 006acde2c5d283d2f8b8aa03d8f0cd2891c680cf
subpackages:
- gzip
- flate
- name: github.com/klauspost/cpuid
version: 09cded8978dc9e80714c4d85b0322337b0a1e5e0
- name: github.com/klauspost/crc32
version: 19b0b332c9e4516a6370a0456e6182c3b5036720
- name: github.com/lib/pq
version: 165a3529e799da61ab10faed1fabff3662d6193f
subpackages:
- oid
- name: github.com/mattn/go-sqlite3
version: 76e335f60bbcee20755df9864f0153af1a80ad2d
- name: github.com/mcuadros/go-version
version: d52711f8d6bea8dc01efafdb68ad95a4e2606630
- name: github.com/microcosm-cc/bluemonday
version: 4ac6f27528d0a3f2a59e0b0a6f6b3ff0bb89fe20
- name: github.com/msteinert/pam
version: 02ccfbfaf0cc627aa3aec8ef7ed5cfeec5b43f63
- name: github.com/nfnt/resize
version: 4d93a29130b1b6aba503e2aa8b50f516213ea80e
- name: github.com/russross/blackfriday
version: b43df972fb5fdf3af8d2e90f38a69d374fe26dd0
- name: github.com/satori/go.uuid
version: e673fdd4dea8a7334adbbe7f57b7e4b00bdc5502
- name: github.com/sergi/go-diff
version: ec7fdbb58eb3e300c8595ad5ac74a5aa50019cc7
subpackages:
- diffmatchpatch
- name: github.com/shurcooL/sanitized_anchor_name
version: 10ef21a441db47d8b13ebcc5fd2310f636973c77
- name: github.com/Unknwon/cae
version: 7f5e046bc8a6c3cde743c233b96ee4fd84ee6ecd
subpackages:
- zip
- name: github.com/Unknwon/com
version: 28b053d5a2923b87ce8c5a08f3af779894a72758
- name: github.com/Unknwon/i18n
version: 3b48b6662051bed72d36efa3c1e897bdf96b2e37
- name: github.com/Unknwon/paginater
version: 7748a72e01415173a27d79866b984328e7b0c12b
- name: golang.org/x/crypto
version: c197bcf24cde29d3f73c7b4ac6fd41f4384e8af6
subpackages:
- ssh
- curve25519
- name: golang.org/x/net
version: 35b06af0720201bc2f326773a80767387544f8c4
subpackages:
- html
- html/charset
- html/atom
- name: golang.org/x/sys
version: 9d4e42a20653790449273b3c85e67d6d8bae6e2e
subpackages:
- windows/svc
- windows
- name: golang.org/x/text
version: 1b466db55e0ba5d56ef5315c728216b42f796491
subpackages:
- transform
- encoding
- encoding/charmap
- encoding/htmlindex
- encoding/internal/identifier
- encoding/internal
- encoding/japanese
- encoding/korean
- encoding/simplifiedchinese
- encoding/traditionalchinese
- encoding/unicode
- language
- internal/utf8internal
- runes
- internal/tag
- name: gopkg.in/alexcesaro/quotedprintable.v3
version: 2caba252f4dc53eaf6b553000885530023f54623
- name: gopkg.in/asn1-ber.v1
version: 4e86f4367175e39f69d9358a5f17b4dda270378d
- name: gopkg.in/bufio.v1
version: 567b2bfa514e796916c4747494d6ff5132a1dfce
- name: gopkg.in/gomail.v2
version: 060a5f4e98dbf37408cf0c745681e4001d877827
- name: gopkg.in/ini.v1
version: 776aa739ce9373377cd16f526cdf06cb4c89b40f
- name: gopkg.in/ldap.v2
version: 07a7330929b9ee80495c88a4439657d89c7dbd87
- name: gopkg.in/macaron.v1
version: 94a5ef7105036242f79e5e07a8eb8651d06c8533
- name: gopkg.in/redis.v2
version: e6179049628164864e6e84e973cfb56335748dea
devImports: []

56
glide.yaml Normal file
View File

@@ -0,0 +1,56 @@
package: github.com/gogits/gogs
import:
- package: github.com/Unknwon/cae
subpackages:
- zip
- package: github.com/Unknwon/com
- package: github.com/Unknwon/i18n
- package: github.com/Unknwon/paginater
- package: github.com/codegangsta/cli
- package: github.com/go-macaron/binding
- package: github.com/go-macaron/cache
subpackages:
- memcache
- redis
- package: github.com/go-macaron/captcha
- package: github.com/go-macaron/csrf
- package: github.com/go-macaron/gzip
- package: github.com/go-macaron/i18n
- package: github.com/go-macaron/session
subpackages:
- redis
- package: github.com/go-macaron/toolbox
- package: github.com/go-sql-driver/mysql
- package: github.com/go-xorm/core
- package: github.com/go-xorm/xorm
- package: github.com/gogits/chardet
- package: github.com/gogits/cron
- package: github.com/gogits/git-module
- package: github.com/gogits/go-gogs-client
- package: github.com/issue9/identicon
- package: github.com/kardianos/minwinsvc
- package: github.com/lib/pq
- package: github.com/mattn/go-sqlite3
- package: github.com/mcuadros/go-version
- package: github.com/microcosm-cc/bluemonday
- package: github.com/msteinert/pam
- package: github.com/nfnt/resize
- package: github.com/russross/blackfriday
- package: github.com/satori/go.uuid
- package: github.com/sergi/go-diff
subpackages:
- diffmatchpatch
- package: golang.org/x/crypto
subpackages:
- ssh
- package: golang.org/x/net
subpackages:
- html
- html/charset
- package: golang.org/x/text
subpackages:
- transform
- package: gopkg.in/gomail.v2
- package: gopkg.in/ini.v1
- package: gopkg.in/ldap.v2
- package: gopkg.in/macaron.v1

View File

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

View File

@@ -13,11 +13,11 @@ import (
type AccessMode int
const (
ACCESS_MODE_NONE AccessMode = iota
ACCESS_MODE_READ
ACCESS_MODE_WRITE
ACCESS_MODE_ADMIN
ACCESS_MODE_OWNER
ACCESS_MODE_NONE AccessMode = iota // 0
ACCESS_MODE_READ // 1
ACCESS_MODE_WRITE // 2
ACCESS_MODE_ADMIN // 3
ACCESS_MODE_OWNER // 4
)
// Access represents the highest access level of a user to the repository. The only access type
@@ -110,7 +110,7 @@ func (u *User) GetAccessibleRepositories() ([]*Repository, error) {
repoIDs = append(repoIDs, access.RepoID)
}
repos := make([]*Repository, 0, len(repoIDs))
return repos, x.Where("owner_id != ?", u.Id).In("id", repoIDs).Desc("updated").Find(&repos)
return repos, x.Where("owner_id != ?", u.Id).In("id", repoIDs).Desc("updated_unix").Find(&repos)
}
func maxAccessMode(modes ...AccessMode) AccessMode {
@@ -151,15 +151,14 @@ func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]AccessMode
return nil
}
// FIXME: should be able to have read-only access.
// Give all collaborators write access.
// refreshCollaboratorAccesses retrieves repository collaborations with their access modes.
func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]AccessMode) error {
collaborators, err := repo.getCollaborators(e)
collaborations, err := repo.getCollaborations(e)
if err != nil {
return fmt.Errorf("getCollaborators: %v", err)
return fmt.Errorf("getCollaborations: %v", err)
}
for _, c := range collaborators {
accessMap[c.Id] = ACCESS_MODE_WRITE
for _, c := range collaborations {
accessMap[c.UserID] = c.Mode
}
return nil
}

View File

@@ -41,6 +41,8 @@ const (
ACTION_MERGE_PULL_REQUEST // 11
ACTION_CLOSE_ISSUE // 12
ACTION_REOPEN_ISSUE // 13
ACTION_CLOSE_PULL_REQUEST // 14
ACTION_REOPEN_PULL_REQUEST // 15
)
var (
@@ -82,13 +84,18 @@ type Action struct {
RefName string
IsPrivate bool `xorm:"NOT NULL DEFAULT false"`
Content string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
Created time.Time `xorm:"-"`
CreatedUnix int64
}
func (a *Action) BeforeInsert() {
a.CreatedUnix = time.Now().UTC().Unix()
}
func (a *Action) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created":
a.Created = regulateTimeZone(a.Created)
case "created_unix":
a.Created = time.Unix(a.CreatedUnix, 0).Local()
}
}
@@ -368,7 +375,7 @@ func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string
continue
}
if err = issue.ChangeStatus(u, true); err != nil {
if err = issue.ChangeStatus(u, repo, true); err != nil {
return err
}
}
@@ -408,7 +415,7 @@ func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string
continue
}
if err = issue.ChangeStatus(u, false); err != nil {
if err = issue.ChangeStatus(u, repo, false); err != nil {
return err
}
}

View File

@@ -12,6 +12,7 @@ import (
"time"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
@@ -29,7 +30,19 @@ type Notice struct {
ID int64 `xorm:"pk autoincr"`
Type NoticeType
Description string `xorm:"TEXT"`
Created time.Time `xorm:"CREATED"`
Created time.Time `xorm:"-"`
CreatedUnix int64
}
func (n *Notice) BeforeInsert() {
n.CreatedUnix = time.Now().UTC().Unix()
}
func (n *Notice) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
n.Created = time.Unix(n.CreatedUnix, 0).Local()
}
}
// TrStr returns a translation format string.

View File

@@ -52,14 +52,28 @@ type Issue struct {
RenderedContent string `xorm:"-"`
Priority int
NumComments int
Deadline time.Time
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
Deadline time.Time `xorm:"-"`
DeadlineUnix int64
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
Attachments []*Attachment `xorm:"-"`
Comments []*Comment `xorm:"-"`
}
func (i *Issue) BeforeInsert() {
i.CreatedUnix = time.Now().UTC().Unix()
i.UpdatedUnix = i.CreatedUnix
}
func (i *Issue) BeforeUpdate() {
i.UpdatedUnix = time.Now().UTC().Unix()
i.DeadlineUnix = i.Deadline.UTC().Unix()
}
func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
@@ -74,6 +88,23 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
log.Error(3, "GetCommentsByIssueID[%d]: %v", i.ID, err)
}
i.Labels, err = GetLabelsByIssueID(i.ID)
if err != nil {
log.Error(3, "GetLabelsByIssueID[%d]: %v", i.ID, err)
}
case "poster_id":
i.Poster, err = GetUserByID(i.PosterID)
if err != nil {
if IsErrUserNotExist(err) {
i.PosterID = -1
i.Poster = NewFakeUser()
} else {
log.Error(3, "GetUserByID[%d]: %v", i.ID, err)
}
return
}
case "milestone_id":
if i.MilestoneID == 0 {
return
@@ -83,6 +114,7 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
if err != nil {
log.Error(3, "GetMilestoneById[%d]: %v", i.ID, err)
}
case "assignee_id":
if i.AssigneeID == 0 {
return
@@ -92,8 +124,13 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
if err != nil {
log.Error(3, "GetUserByID[%d]: %v", i.ID, err)
}
case "created":
i.Created = regulateTimeZone(i.Created)
case "deadline_unix":
i.Deadline = time.Unix(i.DeadlineUnix, 0).Local()
case "created_unix":
i.Created = time.Unix(i.CreatedUnix, 0).Local()
case "updated_unix":
i.Updated = time.Unix(i.UpdatedUnix, 0).Local()
}
}
@@ -102,21 +139,19 @@ func (i *Issue) HashTag() string {
return "issue-" + com.ToStr(i.ID)
}
// State returns string representation of issue status.
func (i *Issue) State() string {
if i.IsClosed {
return "closed"
}
return "open"
}
// IsPoster returns true if given user by ID is the poster.
func (i *Issue) IsPoster(uid int64) bool {
return i.PosterID == uid
}
func (i *Issue) GetPoster() (err error) {
i.Poster, err = GetUserByID(i.PosterID)
if IsErrUserNotExist(err) {
i.PosterID = -1
i.Poster = NewFakeUser()
return nil
}
return err
}
func (i *Issue) hasLabel(e Engine, labelID int64) bool {
return hasIssueLabel(e, i.ID, labelID)
}
@@ -157,11 +192,6 @@ func (i *Issue) getLabels(e Engine) (err error) {
return nil
}
// GetLabels retrieves all labels of issue and assign to corresponding field.
func (i *Issue) GetLabels() error {
return i.getLabels(x)
}
func (i *Issue) removeLabel(e *xorm.Session, label *Label) error {
return deleteIssueLabel(e, i, label)
}
@@ -218,7 +248,8 @@ func (i *Issue) ReadBy(uid int64) error {
return UpdateIssueUserByRead(uid, i.ID)
}
func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err error) {
func (i *Issue) changeStatus(e *xorm.Session, doer *User, repo *Repository, isClosed bool) (err error) {
// Nothing should be performed if current status is same as target status
if i.IsClosed == isClosed {
return nil
}
@@ -230,7 +261,7 @@ func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err er
return err
}
// Update labels.
// Update issue count of labels
if err = i.getLabels(e); err != nil {
return err
}
@@ -245,28 +276,28 @@ func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err er
}
}
// Update milestone.
// Update issue count of milestone
if err = changeMilestoneIssueStats(e, i); err != nil {
return err
}
// New action comment.
if _, err = createStatusComment(e, doer, i.Repo, i); err != nil {
// New action comment
if _, err = createStatusComment(e, doer, repo, i); err != nil {
return err
}
return nil
}
// ChangeStatus changes issue status to open/closed.
func (i *Issue) ChangeStatus(doer *User, isClosed bool) (err error) {
// ChangeStatus changes issue status to open or closed.
func (i *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = i.changeStatus(sess, doer, isClosed); err != nil {
if err = i.changeStatus(sess, doer, repo, isClosed); err != nil {
return err
}
@@ -284,6 +315,19 @@ func (i *Issue) GetPullRequest() (err error) {
// It's caller's responsibility to create action.
func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64, uuids []string, isPull bool) (err error) {
issue.Name = strings.TrimSpace(issue.Name)
issue.Index = repo.NextIssueIndex()
if issue.AssigneeID > 0 {
// Silently drop invalid assignee
valid, err := hasAccess(e, &User{Id: issue.AssigneeID}, repo, ACCESS_MODE_WRITE)
if err != nil {
return fmt.Errorf("hasAccess: %v", err)
} else if !valid {
issue.AssigneeID = 0
}
}
if _, err = e.Insert(issue); err != nil {
return err
}
@@ -297,20 +341,23 @@ func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64,
return err
}
var label *Label
for _, id := range labelIDs {
if id == 0 {
continue
if len(labelIDs) > 0 {
// During the session, SQLite3 dirver cannot handle retrieve objects after update something.
// So we have to get all needed labels first.
labels := make([]*Label, 0, len(labelIDs))
if err = e.In("id", labelIDs).Find(&labels); err != nil {
return fmt.Errorf("find all labels: %v", err)
}
label, err = getLabelByID(e, id)
if err != nil {
return err
}
if err = issue.addLabel(e, label); err != nil {
return fmt.Errorf("addLabel: %v", err)
}
for _, label := range labels {
if label.RepoID != repo.ID {
continue
}
if err = issue.addLabel(e, label); err != nil {
return fmt.Errorf("addLabel: %v", err)
}
}
}
if issue.MilestoneID > 0 {
@@ -359,6 +406,10 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
return fmt.Errorf("newIssue: %v", err)
}
if err = sess.Commit(); err != nil {
return fmt.Errorf("Commit: %v", err)
}
// Notify watchers.
act := &Action{
ActUserID: issue.Poster.Id,
@@ -371,11 +422,11 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
RepoName: repo.Name,
IsPrivate: repo.IsPrivate,
}
if err = notifyWatchers(sess, act); err != nil {
return err
if err = NotifyWatchers(act); err != nil {
log.Error(4, "notifyWatchers: %v", err)
}
return sess.Commit()
return nil
}
// GetIssueByRef returns an Issue specified by a GFM reference.
@@ -449,6 +500,10 @@ type IssuesOptions struct {
// Issues returns a list of issues by given conditions.
func Issues(opts *IssuesOptions) ([]*Issue, error) {
if opts.Page <= 0 {
opts.Page = 1
}
sess := x.Limit(setting.IssuePagingNum, (opts.Page-1)*setting.IssuePagingNum)
if opts.RepoID > 0 {
@@ -477,11 +532,11 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
switch opts.SortType {
case "oldest":
sess.Asc("created")
sess.Asc("created_unix")
case "recentupdate":
sess.Desc("updated")
sess.Desc("updated_unix")
case "leastupdate":
sess.Asc("updated")
sess.Asc("updated_unix")
case "mostcomment":
sess.Desc("num_comments")
case "leastcomment":
@@ -489,7 +544,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
case "priority":
sess.Desc("priority")
default:
sess.Desc("created")
sess.Desc("created_unix")
}
labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
@@ -860,7 +915,7 @@ func UpdateIssue(issue *Issue) error {
return updateIssue(x, issue)
}
// updateIssueCols updates specific fields of given issue.
// updateIssueCols only updates values of specific columns for given issue.
func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
_, err := e.Id(issue.ID).Cols(cols...).Update(issue)
return err
@@ -934,213 +989,6 @@ func UpdateIssueUsersByMentions(uids []int64, iid int64) error {
return nil
}
// .____ ___. .__
// | | _____ \_ |__ ____ | |
// | | \__ \ | __ \_/ __ \| |
// | |___ / __ \| \_\ \ ___/| |__
// |_______ (____ /___ /\___ >____/
// \/ \/ \/ \/
// Label represents a label of repository for issues.
type Label struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
Name string
Color string `xorm:"VARCHAR(7)"`
NumIssues int
NumClosedIssues int
NumOpenIssues int `xorm:"-"`
IsChecked bool `xorm:"-"`
}
// CalOpenIssues calculates the open issues of label.
func (m *Label) CalOpenIssues() {
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
}
// NewLabel creates new label of repository.
func NewLabel(l *Label) error {
_, err := x.Insert(l)
return err
}
func getLabelByID(e Engine, id int64) (*Label, error) {
if id <= 0 {
return nil, ErrLabelNotExist{id}
}
l := &Label{ID: id}
has, err := x.Get(l)
if err != nil {
return nil, err
} else if !has {
return nil, ErrLabelNotExist{l.ID}
}
return l, nil
}
// GetLabelByID returns a label by given ID.
func GetLabelByID(id int64) (*Label, error) {
return getLabelByID(x, id)
}
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
func GetLabelsByRepoID(repoID int64) ([]*Label, error) {
labels := make([]*Label, 0, 10)
return labels, x.Where("repo_id=?", repoID).Find(&labels)
}
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
issueLabels, err := getIssueLabels(e, issueID)
if err != nil {
return nil, fmt.Errorf("getIssueLabels: %v", err)
}
var label *Label
labels := make([]*Label, 0, len(issueLabels))
for idx := range issueLabels {
label, err = getLabelByID(e, issueLabels[idx].LabelID)
if err != nil && !IsErrLabelNotExist(err) {
return nil, fmt.Errorf("getLabelByID: %v", err)
}
labels = append(labels, label)
}
return labels, nil
}
// GetLabelsByIssueID returns all labels that belong to given issue by ID.
func GetLabelsByIssueID(issueID int64) ([]*Label, error) {
return getLabelsByIssueID(x, issueID)
}
func updateLabel(e Engine, l *Label) error {
_, err := e.Id(l.ID).AllCols().Update(l)
return err
}
// UpdateLabel updates label information.
func UpdateLabel(l *Label) error {
return updateLabel(x, l)
}
// DeleteLabel delete a label of given repository.
func DeleteLabel(repoID, labelID int64) error {
l, err := GetLabelByID(labelID)
if err != nil {
if IsErrLabelNotExist(err) {
return nil
}
return err
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = x.Where("label_id=?", labelID).Delete(new(IssueLabel)); err != nil {
return err
} else if _, err = sess.Delete(l); err != nil {
return err
}
return sess.Commit()
}
// .___ .____ ___. .__
// | | ______ ________ __ ____ | | _____ \_ |__ ____ | |
// | |/ ___// ___/ | \_/ __ \| | \__ \ | __ \_/ __ \| |
// | |\___ \ \___ \| | /\ ___/| |___ / __ \| \_\ \ ___/| |__
// |___/____ >____ >____/ \___ >_______ (____ /___ /\___ >____/
// \/ \/ \/ \/ \/ \/ \/
// IssueLabel represetns an issue-lable relation.
type IssueLabel struct {
ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"UNIQUE(s)"`
LabelID int64 `xorm:"UNIQUE(s)"`
}
func hasIssueLabel(e Engine, issueID, labelID int64) bool {
has, _ := e.Where("issue_id=? AND label_id=?", issueID, labelID).Get(new(IssueLabel))
return has
}
// HasIssueLabel returns true if issue has been labeled.
func HasIssueLabel(issueID, labelID int64) bool {
return hasIssueLabel(x, issueID, labelID)
}
func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
if _, err = e.Insert(&IssueLabel{
IssueID: issue.ID,
LabelID: label.ID,
}); err != nil {
return err
}
label.NumIssues++
if issue.IsClosed {
label.NumClosedIssues++
}
return updateLabel(e, label)
}
// NewIssueLabel creates a new issue-label relation.
func NewIssueLabel(issue *Issue, label *Label) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = newIssueLabel(sess, issue, label); err != nil {
return err
}
return sess.Commit()
}
func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
issueLabels := make([]*IssueLabel, 0, 10)
return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels)
}
// GetIssueLabels returns all issue-label relations of given issue by ID.
func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
return getIssueLabels(x, issueID)
}
func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
if _, err = e.Delete(&IssueLabel{
IssueID: issue.ID,
LabelID: label.ID,
}); err != nil {
return err
}
label.NumIssues--
if issue.IsClosed {
label.NumClosedIssues--
}
return updateLabel(e, label)
}
// DeleteIssueLabel deletes issue-label relation.
func DeleteIssueLabel(issue *Issue, label *Label) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = deleteIssueLabel(sess, issue, label); err != nil {
return err
}
return sess.Commit()
}
// _____ .__.__ __
// / \ |__| | ____ _______/ |_ ____ ____ ____
// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
@@ -1158,12 +1006,19 @@ type Milestone struct {
IsClosed bool
NumIssues int
NumClosedIssues int
NumOpenIssues int `xorm:"-"`
Completeness int // Percentage(1-100).
Deadline time.Time
DeadlineString string `xorm:"-"`
IsOverDue bool `xorm:"-"`
ClosedDate time.Time
NumOpenIssues int `xorm:"-"`
Completeness int // Percentage(1-100).
IsOverDue bool `xorm:"-"`
DeadlineString string `xorm:"-"`
Deadline time.Time `xorm:"-"`
DeadlineUnix int64
ClosedDate time.Time `xorm:"-"`
ClosedDateUnix int64
}
func (m *Milestone) BeforeInsert() {
m.DeadlineUnix = m.Deadline.UTC().Unix()
}
func (m *Milestone) BeforeUpdate() {
@@ -1172,25 +1027,38 @@ func (m *Milestone) BeforeUpdate() {
} else {
m.Completeness = 0
}
m.DeadlineUnix = m.Deadline.UTC().Unix()
m.ClosedDateUnix = m.ClosedDate.UTC().Unix()
}
func (m *Milestone) AfterSet(colName string, _ xorm.Cell) {
if colName == "deadline" {
switch colName {
case "num_closed_issues":
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
case "deadline_unix":
m.Deadline = time.Unix(m.DeadlineUnix, 0).Local()
if m.Deadline.Year() == 9999 {
return
}
m.Deadline = regulateTimeZone(m.Deadline)
m.DeadlineString = m.Deadline.Format("2006-01-02")
if time.Now().After(m.Deadline) {
if time.Now().Local().After(m.Deadline) {
m.IsOverDue = true
}
case "closed_date_unix":
m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local()
}
}
// CalOpenIssues calculates the open issues of milestone.
func (m *Milestone) CalOpenIssues() {
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
// State returns string representation of milestone status.
func (m *Milestone) State() string {
if m.IsClosed {
return "closed"
}
return "open"
}
// NewMilestone creates new milestone of repository.
@@ -1451,270 +1319,6 @@ func DeleteMilestoneByID(id int64) error {
return sess.Commit()
}
// _________ __
// \_ ___ \ ____ _____ _____ ____ _____/ |_
// / \ \/ / _ \ / \ / \_/ __ \ / \ __\
// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ |
// \______ /\____/|__|_| /__|_| /\___ >___| /__|
// \/ \/ \/ \/ \/
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
type CommentType int
const (
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
COMMENT_TYPE_COMMENT CommentType = iota
COMMENT_TYPE_REOPEN
COMMENT_TYPE_CLOSE
// References.
COMMENT_TYPE_ISSUE_REF
// Reference from a commit (not part of a pull request)
COMMENT_TYPE_COMMIT_REF
// Reference from a comment
COMMENT_TYPE_COMMENT_REF
// Reference from a pull request
COMMENT_TYPE_PULL_REF
)
type CommentTag int
const (
COMMENT_TAG_NONE CommentTag = iota
COMMENT_TAG_POSTER
COMMENT_TAG_ADMIN
COMMENT_TAG_OWNER
)
// Comment represents a comment in commit and issue page.
type Comment struct {
ID int64 `xorm:"pk autoincr"`
Type CommentType
PosterID int64
Poster *User `xorm:"-"`
IssueID int64 `xorm:"INDEX"`
CommitID int64
Line int64
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
Created time.Time `xorm:"CREATED"`
// Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"`
Attachments []*Attachment `xorm:"-"`
// For view issue page.
ShowTag CommentTag `xorm:"-"`
}
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
case "id":
c.Attachments, err = GetAttachmentsByCommentID(c.ID)
if err != nil {
log.Error(3, "GetAttachmentsByCommentID[%d]: %v", c.ID, err)
}
case "poster_id":
c.Poster, err = GetUserByID(c.PosterID)
if err != nil {
if IsErrUserNotExist(err) {
c.PosterID = -1
c.Poster = NewFakeUser()
} else {
log.Error(3, "GetUserByID[%d]: %v", c.ID, err)
}
}
case "created":
c.Created = regulateTimeZone(c.Created)
}
}
func (c *Comment) AfterDelete() {
_, err := DeleteAttachmentsByComment(c.ID, true)
if err != nil {
log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err)
}
}
// HashTag returns unique hash tag for comment.
func (c *Comment) HashTag() string {
return "issuecomment-" + com.ToStr(c.ID)
}
// EventTag returns unique event hash tag for comment.
func (c *Comment) EventTag() string {
return "event-" + com.ToStr(c.ID)
}
func createComment(e *xorm.Session, u *User, repo *Repository, issue *Issue, commitID, line int64, cmtType CommentType, content, commitSHA string, uuids []string) (_ *Comment, err error) {
comment := &Comment{
PosterID: u.Id,
Type: cmtType,
IssueID: issue.ID,
CommitID: commitID,
Line: line,
Content: content,
CommitSHA: commitSHA,
}
if _, err = e.Insert(comment); err != nil {
return nil, err
}
// Compose comment action, could be plain comment, close or reopen issue.
// This object will be used to notify watchers in the end of function.
act := &Action{
ActUserID: u.Id,
ActUserName: u.Name,
ActEmail: u.Email,
Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]),
RepoID: repo.ID,
RepoUserName: repo.Owner.Name,
RepoName: repo.Name,
IsPrivate: repo.IsPrivate,
}
// Check comment type.
switch cmtType {
case COMMENT_TYPE_COMMENT:
act.OpType = ACTION_COMMENT_ISSUE
if _, err = e.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", issue.ID); err != nil {
return nil, err
}
// Check attachments.
attachments := make([]*Attachment, 0, len(uuids))
for _, uuid := range uuids {
attach, err := getAttachmentByUUID(e, uuid)
if err != nil {
if IsErrAttachmentNotExist(err) {
continue
}
return nil, fmt.Errorf("getAttachmentByUUID[%s]: %v", uuid, err)
}
attachments = append(attachments, attach)
}
for i := range attachments {
attachments[i].IssueID = issue.ID
attachments[i].CommentID = comment.ID
// No assign value could be 0, so ignore AllCols().
if _, err = e.Id(attachments[i].ID).Update(attachments[i]); err != nil {
return nil, fmt.Errorf("update attachment[%d]: %v", attachments[i].ID, err)
}
}
case COMMENT_TYPE_REOPEN:
act.OpType = ACTION_REOPEN_ISSUE
if issue.IsPull {
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", repo.ID)
} else {
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", repo.ID)
}
if err != nil {
return nil, err
}
case COMMENT_TYPE_CLOSE:
act.OpType = ACTION_CLOSE_ISSUE
if issue.IsPull {
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", repo.ID)
} else {
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", repo.ID)
}
if err != nil {
return nil, err
}
}
// Notify watchers for whatever action comes in.
if err = notifyWatchers(e, act); err != nil {
return nil, fmt.Errorf("notifyWatchers: %v", err)
}
return comment, nil
}
func createStatusComment(e *xorm.Session, doer *User, repo *Repository, issue *Issue) (*Comment, error) {
cmtType := COMMENT_TYPE_CLOSE
if !issue.IsClosed {
cmtType = COMMENT_TYPE_REOPEN
}
return createComment(e, doer, repo, issue, 0, 0, cmtType, "", "", nil)
}
// CreateComment creates comment of issue or commit.
func CreateComment(doer *User, repo *Repository, issue *Issue, commitID, line int64, cmtType CommentType, content, commitSHA string, attachments []string) (comment *Comment, err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return nil, err
}
comment, err = createComment(sess, doer, repo, issue, commitID, line, cmtType, content, commitSHA, attachments)
if err != nil {
return nil, err
}
return comment, sess.Commit()
}
// CreateIssueComment creates a plain issue comment.
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
return CreateComment(doer, repo, issue, 0, 0, COMMENT_TYPE_COMMENT, content, "", attachments)
}
// CreateRefComment creates a commit reference comment to issue.
func CreateRefComment(doer *User, repo *Repository, issue *Issue, content, commitSHA string) error {
if len(commitSHA) == 0 {
return fmt.Errorf("cannot create reference with empty commit SHA")
}
// Check if same reference from same commit has already existed.
has, err := x.Get(&Comment{
Type: COMMENT_TYPE_COMMIT_REF,
IssueID: issue.ID,
CommitSHA: commitSHA,
})
if err != nil {
return fmt.Errorf("check reference comment: %v", err)
} else if has {
return nil
}
_, err = CreateComment(doer, repo, issue, 0, 0, COMMENT_TYPE_COMMIT_REF, content, commitSHA, nil)
return err
}
// GetCommentByID returns the comment by given ID.
func GetCommentByID(id int64) (*Comment, error) {
c := new(Comment)
has, err := x.Id(id).Get(c)
if err != nil {
return nil, err
} else if !has {
return nil, ErrCommentNotExist{id}
}
return c, nil
}
// GetCommentsByIssueID returns all comments of issue by given ID.
func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
comments := make([]*Comment, 0, 10)
return comments, x.Where("issue_id=?", issueID).Asc("created").Find(&comments)
}
// UpdateComment updates information of comment.
func UpdateComment(c *Comment) error {
_, err := x.Id(c.ID).AllCols().Update(c)
return err
}
// Attachment represent a attachment of issue/comment/release.
type Attachment struct {
ID int64 `xorm:"pk autoincr"`
@@ -1723,7 +1327,20 @@ type Attachment struct {
CommentID int64
ReleaseID int64 `xorm:"INDEX"`
Name string
Created time.Time `xorm:"CREATED"`
Created time.Time `xorm:"-"`
CreatedUnix int64
}
func (a *Attachment) BeforeInsert() {
a.CreatedUnix = time.Now().UTC().Unix()
}
func (a *Attachment) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
a.Created = time.Unix(a.CreatedUnix, 0).Local()
}
}
// AttachmentLocalPath returns where attachment is stored in local file system based on given UUID.

320
models/issue_comment.go Normal file
View File

@@ -0,0 +1,320 @@
// Copyright 2016 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 (
"fmt"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/log"
)
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
type CommentType int
const (
// Plain comment, can be associated with a commit (CommitID > 0) and a line (LineNum > 0)
COMMENT_TYPE_COMMENT CommentType = iota
COMMENT_TYPE_REOPEN
COMMENT_TYPE_CLOSE
// References.
COMMENT_TYPE_ISSUE_REF
// Reference from a commit (not part of a pull request)
COMMENT_TYPE_COMMIT_REF
// Reference from a comment
COMMENT_TYPE_COMMENT_REF
// Reference from a pull request
COMMENT_TYPE_PULL_REF
)
type CommentTag int
const (
COMMENT_TAG_NONE CommentTag = iota
COMMENT_TAG_POSTER
COMMENT_TAG_WRITER
COMMENT_TAG_OWNER
)
// Comment represents a comment in commit and issue page.
type Comment struct {
ID int64 `xorm:"pk autoincr"`
Type CommentType
PosterID int64
Poster *User `xorm:"-"`
IssueID int64 `xorm:"INDEX"`
CommitID int64
Line int64
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
Created time.Time `xorm:"-"`
CreatedUnix int64
// Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"`
Attachments []*Attachment `xorm:"-"`
// For view issue page.
ShowTag CommentTag `xorm:"-"`
}
func (c *Comment) BeforeInsert() {
c.CreatedUnix = time.Now().UTC().Unix()
}
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
case "id":
c.Attachments, err = GetAttachmentsByCommentID(c.ID)
if err != nil {
log.Error(3, "GetAttachmentsByCommentID[%d]: %v", c.ID, err)
}
case "poster_id":
c.Poster, err = GetUserByID(c.PosterID)
if err != nil {
if IsErrUserNotExist(err) {
c.PosterID = -1
c.Poster = NewFakeUser()
} else {
log.Error(3, "GetUserByID[%d]: %v", c.ID, err)
}
}
case "created_unix":
c.Created = time.Unix(c.CreatedUnix, 0).Local()
}
}
func (c *Comment) AfterDelete() {
_, err := DeleteAttachmentsByComment(c.ID, true)
if err != nil {
log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err)
}
}
// HashTag returns unique hash tag for comment.
func (c *Comment) HashTag() string {
return "issuecomment-" + com.ToStr(c.ID)
}
// EventTag returns unique event hash tag for comment.
func (c *Comment) EventTag() string {
return "event-" + com.ToStr(c.ID)
}
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
comment := &Comment{
Type: opts.Type,
PosterID: opts.Doer.Id,
IssueID: opts.Issue.ID,
CommitID: opts.CommitID,
CommitSHA: opts.CommitSHA,
Line: opts.LineNum,
Content: opts.Content,
}
if _, err = e.Insert(comment); err != nil {
return nil, err
}
// Compose comment action, could be plain comment, close or reopen issue/pull request.
// This object will be used to notify watchers in the end of function.
act := &Action{
ActUserID: opts.Doer.Id,
ActUserName: opts.Doer.Name,
ActEmail: opts.Doer.Email,
Content: fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]),
RepoID: opts.Repo.ID,
RepoUserName: opts.Repo.Owner.Name,
RepoName: opts.Repo.Name,
IsPrivate: opts.Repo.IsPrivate,
}
// Check comment type.
switch opts.Type {
case COMMENT_TYPE_COMMENT:
act.OpType = ACTION_COMMENT_ISSUE
if _, err = e.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID); err != nil {
return nil, err
}
// Check attachments
attachments := make([]*Attachment, 0, len(opts.Attachments))
for _, uuid := range opts.Attachments {
attach, err := getAttachmentByUUID(e, uuid)
if err != nil {
if IsErrAttachmentNotExist(err) {
continue
}
return nil, fmt.Errorf("getAttachmentByUUID[%s]: %v", uuid, err)
}
attachments = append(attachments, attach)
}
for i := range attachments {
attachments[i].IssueID = opts.Issue.ID
attachments[i].CommentID = comment.ID
// No assign value could be 0, so ignore AllCols().
if _, err = e.Id(attachments[i].ID).Update(attachments[i]); err != nil {
return nil, fmt.Errorf("update attachment[%d]: %v", attachments[i].ID, err)
}
}
case COMMENT_TYPE_REOPEN:
act.OpType = ACTION_REOPEN_ISSUE
if opts.Issue.IsPull {
act.OpType = ACTION_REOPEN_PULL_REQUEST
}
if opts.Issue.IsPull {
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", opts.Repo.ID)
} else {
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", opts.Repo.ID)
}
if err != nil {
return nil, err
}
case COMMENT_TYPE_CLOSE:
act.OpType = ACTION_CLOSE_ISSUE
if opts.Issue.IsPull {
act.OpType = ACTION_CLOSE_PULL_REQUEST
}
if opts.Issue.IsPull {
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", opts.Repo.ID)
} else {
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", opts.Repo.ID)
}
if err != nil {
return nil, err
}
}
// Notify watchers for whatever action comes in, ignore if no action type
if act.OpType > 0 {
if err = notifyWatchers(e, act); err != nil {
return nil, fmt.Errorf("notifyWatchers: %v", err)
}
}
return comment, nil
}
func createStatusComment(e *xorm.Session, doer *User, repo *Repository, issue *Issue) (*Comment, error) {
cmtType := COMMENT_TYPE_CLOSE
if !issue.IsClosed {
cmtType = COMMENT_TYPE_REOPEN
}
return createComment(e, &CreateCommentOptions{
Type: cmtType,
Doer: doer,
Repo: repo,
Issue: issue,
})
}
type CreateCommentOptions struct {
Type CommentType
Doer *User
Repo *Repository
Issue *Issue
CommitID int64
CommitSHA string
LineNum int64
Content string
Attachments []string // UUIDs of attachments
}
// CreateComment creates comment of issue or commit.
func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return nil, err
}
comment, err = createComment(sess, opts)
if err != nil {
return nil, err
}
return comment, sess.Commit()
}
// CreateIssueComment creates a plain issue comment.
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
return CreateComment(&CreateCommentOptions{
Type: COMMENT_TYPE_COMMENT,
Doer: doer,
Repo: repo,
Issue: issue,
Content: content,
Attachments: attachments,
})
}
// CreateRefComment creates a commit reference comment to issue.
func CreateRefComment(doer *User, repo *Repository, issue *Issue, content, commitSHA string) error {
if len(commitSHA) == 0 {
return fmt.Errorf("cannot create reference with empty commit SHA")
}
// Check if same reference from same commit has already existed.
has, err := x.Get(&Comment{
Type: COMMENT_TYPE_COMMIT_REF,
IssueID: issue.ID,
CommitSHA: commitSHA,
})
if err != nil {
return fmt.Errorf("check reference comment: %v", err)
} else if has {
return nil
}
_, err = CreateComment(&CreateCommentOptions{
Type: COMMENT_TYPE_COMMIT_REF,
Doer: doer,
Repo: repo,
Issue: issue,
CommitSHA: commitSHA,
Content: content,
})
return err
}
// GetCommentByID returns the comment by given ID.
func GetCommentByID(id int64) (*Comment, error) {
c := new(Comment)
has, err := x.Id(id).Get(c)
if err != nil {
return nil, err
} else if !has {
return nil, ErrCommentNotExist{id}
}
return c, nil
}
// GetCommentsByIssueID returns all comments of issue by given ID.
func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
comments := make([]*Comment, 0, 10)
return comments, x.Where("issue_id=?", issueID).Asc("created_unix").Find(&comments)
}
// UpdateComment updates information of comment.
func UpdateComment(c *Comment) error {
_, err := x.Id(c.ID).AllCols().Update(c)
return err
}

234
models/issue_label.go Normal file
View File

@@ -0,0 +1,234 @@
// Copyright 2016 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 (
"fmt"
"html/template"
"strconv"
"strings"
"github.com/go-xorm/xorm"
)
// Label represents a label of repository for issues.
type Label struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
Name string
Color string `xorm:"VARCHAR(7)"`
NumIssues int
NumClosedIssues int
NumOpenIssues int `xorm:"-"`
IsChecked bool `xorm:"-"`
}
// CalOpenIssues calculates the open issues of label.
func (m *Label) CalOpenIssues() {
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
}
// ForegroundColor calculates the text color for labels based
// on their background color.
func (l *Label) ForegroundColor() template.CSS {
if strings.HasPrefix(l.Color, "#") {
if color, err := strconv.ParseUint(l.Color[1:], 16, 64); err == nil {
r := float32(0xFF & (color >> 16))
g := float32(0xFF & (color >> 8))
b := float32(0xFF & color)
luminance := (0.2126*r + 0.7152*g + 0.0722*b) / 255
if luminance < 0.5 {
return template.CSS("#fff")
}
}
}
// default to black
return template.CSS("#000")
}
// NewLabel creates new label of repository.
func NewLabel(l *Label) error {
_, err := x.Insert(l)
return err
}
func getLabelByID(e Engine, id int64) (*Label, error) {
if id <= 0 {
return nil, ErrLabelNotExist{id}
}
l := &Label{ID: id}
has, err := x.Get(l)
if err != nil {
return nil, err
} else if !has {
return nil, ErrLabelNotExist{l.ID}
}
return l, nil
}
// GetLabelByID returns a label by given ID.
func GetLabelByID(id int64) (*Label, error) {
return getLabelByID(x, id)
}
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
func GetLabelsByRepoID(repoID int64) ([]*Label, error) {
labels := make([]*Label, 0, 10)
return labels, x.Where("repo_id=?", repoID).Find(&labels)
}
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
issueLabels, err := getIssueLabels(e, issueID)
if err != nil {
return nil, fmt.Errorf("getIssueLabels: %v", err)
}
var label *Label
labels := make([]*Label, 0, len(issueLabels))
for idx := range issueLabels {
label, err = getLabelByID(e, issueLabels[idx].LabelID)
if err != nil && !IsErrLabelNotExist(err) {
return nil, fmt.Errorf("getLabelByID: %v", err)
}
labels = append(labels, label)
}
return labels, nil
}
// GetLabelsByIssueID returns all labels that belong to given issue by ID.
func GetLabelsByIssueID(issueID int64) ([]*Label, error) {
return getLabelsByIssueID(x, issueID)
}
func updateLabel(e Engine, l *Label) error {
_, err := e.Id(l.ID).AllCols().Update(l)
return err
}
// UpdateLabel updates label information.
func UpdateLabel(l *Label) error {
return updateLabel(x, l)
}
// DeleteLabel delete a label of given repository.
func DeleteLabel(repoID, labelID int64) error {
l, err := GetLabelByID(labelID)
if err != nil {
if IsErrLabelNotExist(err) {
return nil
}
return err
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = x.Where("label_id=?", labelID).Delete(new(IssueLabel)); err != nil {
return err
} else if _, err = sess.Delete(l); err != nil {
return err
}
return sess.Commit()
}
// .___ .____ ___. .__
// | | ______ ________ __ ____ | | _____ \_ |__ ____ | |
// | |/ ___// ___/ | \_/ __ \| | \__ \ | __ \_/ __ \| |
// | |\___ \ \___ \| | /\ ___/| |___ / __ \| \_\ \ ___/| |__
// |___/____ >____ >____/ \___ >_______ (____ /___ /\___ >____/
// \/ \/ \/ \/ \/ \/ \/
// IssueLabel represetns an issue-lable relation.
type IssueLabel struct {
ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"UNIQUE(s)"`
LabelID int64 `xorm:"UNIQUE(s)"`
}
func hasIssueLabel(e Engine, issueID, labelID int64) bool {
has, _ := e.Where("issue_id=? AND label_id=?", issueID, labelID).Get(new(IssueLabel))
return has
}
// HasIssueLabel returns true if issue has been labeled.
func HasIssueLabel(issueID, labelID int64) bool {
return hasIssueLabel(x, issueID, labelID)
}
func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
if _, err = e.Insert(&IssueLabel{
IssueID: issue.ID,
LabelID: label.ID,
}); err != nil {
return err
}
label.NumIssues++
if issue.IsClosed {
label.NumClosedIssues++
}
return updateLabel(e, label)
}
// NewIssueLabel creates a new issue-label relation.
func NewIssueLabel(issue *Issue, label *Label) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = newIssueLabel(sess, issue, label); err != nil {
return err
}
return sess.Commit()
}
func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
issueLabels := make([]*IssueLabel, 0, 10)
return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels)
}
// GetIssueLabels returns all issue-label relations of given issue by ID.
func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
return getIssueLabels(x, issueID)
}
func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
if _, err = e.Delete(&IssueLabel{
IssueID: issue.ID,
LabelID: label.ID,
}); err != nil {
return err
}
label.NumIssues--
if issue.IsClosed {
label.NumClosedIssues--
}
return updateLabel(e, label)
}
// DeleteIssueLabel deletes issue-label relation.
func DeleteIssueLabel(issue *Issue, label *Label) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = deleteIssueLabel(sess, issue, label); err != nil {
return err
}
return sess.Commit()
}

View File

@@ -101,8 +101,20 @@ type LoginSource struct {
Name string `xorm:"UNIQUE"`
IsActived bool `xorm:"NOT NULL DEFAULT false"`
Cfg core.Conversion `xorm:"TEXT"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
}
func (s *LoginSource) BeforeInsert() {
s.CreatedUnix = time.Now().UTC().Unix()
s.UpdatedUnix = s.CreatedUnix
}
func (s *LoginSource) BeforeUpdate() {
s.UpdatedUnix = time.Now().UTC().Unix()
}
// Cell2Int64 converts a xorm.Cell type to int64,
@@ -132,6 +144,15 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
}
}
func (s *LoginSource) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
s.Created = time.Unix(s.CreatedUnix, 0).Local()
case "updated_unix":
s.Updated = time.Unix(s.UpdatedUnix, 0).Local()
}
}
func (source *LoginSource) TypeName() string {
return LoginNames[source.Type]
}

View File

@@ -13,6 +13,7 @@ import (
"path"
"path/filepath"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
@@ -65,6 +66,7 @@ var migrations = []Migration{
NewMigration("rename pull request fields", renamePullRequestFields), // V8 -> V9:v0.6.16
NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo), // V9 -> V10:v0.6.20
NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt), // V10 -> V11:v0.8.5
NewMigration("convert date to unix timestamp", convertDateToUnix), // V11 -> V12:v0.9.2
}
// Migrate database to current version
@@ -453,3 +455,221 @@ func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
return sess.Commit()
}
type TAction struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
func (t *TAction) TableName() string { return "action" }
type TNotice struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
func (t *TNotice) TableName() string { return "notice" }
type TComment struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
func (t *TComment) TableName() string { return "comment" }
type TIssue struct {
ID int64 `xorm:"pk autoincr"`
DeadlineUnix int64
CreatedUnix int64
UpdatedUnix int64
}
func (t *TIssue) TableName() string { return "issue" }
type TMilestone struct {
ID int64 `xorm:"pk autoincr"`
DeadlineUnix int64
ClosedDateUnix int64
}
func (t *TMilestone) TableName() string { return "milestone" }
type TAttachment struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
func (t *TAttachment) TableName() string { return "attachment" }
type TLoginSource struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TLoginSource) TableName() string { return "login_source" }
type TPull struct {
ID int64 `xorm:"pk autoincr"`
MergedUnix int64
}
func (t *TPull) TableName() string { return "pull_request" }
type TRelease struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
func (t *TRelease) TableName() string { return "release" }
type TRepo struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TRepo) TableName() string { return "repository" }
type TMirror struct {
ID int64 `xorm:"pk autoincr"`
UpdatedUnix int64
NextUpdateUnix int64
}
func (t *TMirror) TableName() string { return "mirror" }
type TPublicKey struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TPublicKey) TableName() string { return "public_key" }
type TDeployKey struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TDeployKey) TableName() string { return "deploy_key" }
type TAccessToken struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TAccessToken) TableName() string { return "access_token" }
type TUser struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TUser) TableName() string { return "user" }
type TWebhook struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
func (t *TWebhook) TableName() string { return "webhook" }
func convertDateToUnix(x *xorm.Engine) (err error) {
type Bean struct {
ID int64 `xorm:"pk autoincr"`
Created time.Time
Updated time.Time
Merged time.Time
Deadline time.Time
ClosedDate time.Time
NextUpdate time.Time
}
var tables = []struct {
name string
cols []string
bean interface{}
}{
{"action", []string{"created"}, new(TAction)},
{"notice", []string{"created"}, new(TNotice)},
{"comment", []string{"created"}, new(TComment)},
{"issue", []string{"deadline", "created", "updated"}, new(TIssue)},
{"milestone", []string{"deadline", "closed_date"}, new(TMilestone)},
{"attachment", []string{"created"}, new(TAttachment)},
{"login_source", []string{"created", "updated"}, new(TLoginSource)},
{"pull_request", []string{"merged"}, new(TPull)},
{"release", []string{"created"}, new(TRelease)},
{"repository", []string{"created", "updated"}, new(TRepo)},
{"mirror", []string{"updated", "next_update"}, new(TMirror)},
{"public_key", []string{"created", "updated"}, new(TPublicKey)},
{"deploy_key", []string{"created", "updated"}, new(TDeployKey)},
{"access_token", []string{"created", "updated"}, new(TAccessToken)},
{"user", []string{"created", "updated"}, new(TUser)},
{"webhook", []string{"created", "updated"}, new(TWebhook)},
}
for _, table := range tables {
log.Info("Converting table: %s", table.name)
if err = x.Sync2(table.bean); err != nil {
return fmt.Errorf("Sync [table: %s]: %v", table.name, err)
}
offset := 0
for {
beans := make([]*Bean, 0, 100)
if err = x.Sql(fmt.Sprintf("SELECT * FROM `%s` ORDER BY id ASC LIMIT 100 OFFSET %d",
table.name, offset)).Find(&beans); err != nil {
return fmt.Errorf("select beans [table: %s, offset: %d]: %v", table.name, offset, err)
}
log.Trace("Table [%s]: offset: %d, beans: %d", table.name, offset, len(beans))
if len(beans) == 0 {
break
}
offset += 100
baseSQL := "UPDATE `" + table.name + "` SET "
for _, bean := range beans {
valSQLs := make([]string, 0, len(table.cols))
for _, col := range table.cols {
fieldSQL := ""
fieldSQL += col + "_unix = "
switch col {
case "deadline":
if bean.Deadline.IsZero() {
continue
}
fieldSQL += com.ToStr(bean.Deadline.UTC().Unix())
case "created":
fieldSQL += com.ToStr(bean.Created.UTC().Unix())
case "updated":
fieldSQL += com.ToStr(bean.Updated.UTC().Unix())
case "closed_date":
fieldSQL += com.ToStr(bean.ClosedDate.UTC().Unix())
case "merged":
fieldSQL += com.ToStr(bean.Merged.UTC().Unix())
case "next_update":
fieldSQL += com.ToStr(bean.NextUpdate.UTC().Unix())
}
valSQLs = append(valSQLs, fieldSQL)
}
if len(valSQLs) == 0 {
continue
}
if _, err = x.Exec(baseSQL + strings.Join(valSQLs, ",") + " WHERE id = " + com.ToStr(bean.ID)); err != nil {
return fmt.Errorf("update bean [table: %s, id: %d]: %v", table.name, bean.ID, err)
}
}
}
}
return nil
}

View File

@@ -11,16 +11,13 @@ import (
"os"
"path"
"strings"
"time"
"github.com/Unknwon/com"
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
_ "github.com/lib/pq"
"github.com/gogits/gogs/models/migrations"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
@@ -44,27 +41,6 @@ func sessionRelease(sess *xorm.Session) {
sess.Close()
}
// Note: get back time.Time from database Go sees it at UTC where they are really Local.
// So this function makes correct timezone offset.
func regulateTimeZone(t time.Time) time.Time {
if !setting.UseMySQL {
return t
}
zone := t.Local().Format("-0700")
if len(zone) != 5 {
log.Error(4, "Unprocessable timezone: %s - %s", t.Local(), zone)
return t
}
hour := com.StrTo(zone[2:3]).MustInt()
minutes := com.StrTo(zone[3:5]).MustInt()
if zone[0] == '-' {
return t.Add(time.Duration(hour) * time.Hour).Add(time.Duration(minutes) * time.Minute)
}
return t.Add(-1 * time.Duration(hour) * time.Hour).Add(-1 * time.Duration(minutes) * time.Minute)
}
var (
x *xorm.Engine
tables []interface{}

View File

@@ -169,7 +169,7 @@ func GetOrgByName(name string) (*User, error) {
}
u := &User{
LowerName: strings.ToLower(name),
Type: ORGANIZATION,
Type: USER_TYPE_ORGANIZATION,
}
has, err := x.Get(u)
if err != nil {
@@ -1054,13 +1054,11 @@ func RemoveOrgRepo(orgID, repoID int64) error {
// GetUserRepositories gets all repositories of an organization,
// that the user with the given userID has access to.
func (org *User) GetUserRepositories(userID int64) (err error) {
teams := make([]*Team, 0, 10)
if err = x.Cols("`team`.id").
Where("`team_user`.org_id=?", org.Id).
And("`team_user`.uid=?", userID).
Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
Find(&teams); err != nil {
return fmt.Errorf("GetUserRepositories: get teams: %v", err)
teams := make([]*Team, 0, org.NumTeams)
if err = x.Sql(`SELECT team.id FROM team
INNER JOIN team_user ON team_user.team_id = team.id
WHERE team_user.org_id = ? AND team_user.uid = ?`, org.Id, userID).Find(&teams); err != nil {
return fmt.Errorf("get teams: %v", err)
}
teamIDs := make([]string, len(teams))
@@ -1072,19 +1070,14 @@ func (org *User) GetUserRepositories(userID int64) (err error) {
teamIDs = append(teamIDs, "-1") // there is no repo with id=-1
}
// Due to a bug in xorm using IN() together with OR() is impossible.
// As a workaround, we have to build the IN statement on our own, until this is fixed.
// https://github.com/go-xorm/xorm/issues/342
if err = x.Cols("`repository`.*").
Join("INNER", "`team_repo`", "`team_repo`.repo_id=`repository`.id").
Where("`repository`.owner_id=?", org.Id).
And("`repository`.is_private=?", false).
Or("`team_repo`.team_id=(?)", strings.Join(teamIDs, ",")).
GroupBy("`repository`.id").
Find(&org.Repos); err != nil {
return fmt.Errorf("GetUserRepositories: get repositories: %v", err)
repos := make([]*Repository, 0, 5)
if err = x.Sql(fmt.Sprintf(`SELECT repository.* FROM repository
INNER JOIN team_repo ON team_repo.repo_id = repository.id
WHERE (repository.owner_id = ? AND repository.is_private = ?) OR team_repo.team_id IN (%s)
GROUP BY repository.id`, strings.Join(teamIDs, ",")), org.Id, false).Find(&repos); err != nil {
return fmt.Errorf("get repositories: %v", err)
}
org.Repos = repos
// FIXME: should I change this value inside method,
// or only in location of caller where it's really needed?
@@ -1095,12 +1088,12 @@ func (org *User) GetUserRepositories(userID int64) (err error) {
// GetTeams returns all teams that belong to organization,
// and that the user has joined.
func (org *User) GetUserTeams(userID int64) error {
if err := x.Cols("`team`.*").
Where("`team_user`.org_id=?", org.Id).
And("`team_user`.uid=?", userID).
Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
Find(&org.Teams); err != nil {
return fmt.Errorf("GetUserTeams: %v", err)
teams := make([]*Team, 0, 5)
if err := x.Sql(`SELECT team.* FROM team
INNER JOIN team_user ON team_user.team_id = team.id
WHERE team_user.org_id = ? AND team_user.uid = ?`,
org.Id, userID).Find(&teams); err != nil {
return fmt.Errorf("get teams: %v", err)
}
// FIXME: should I change this value inside method,

View File

@@ -58,20 +58,25 @@ type PullRequest struct {
HasMerged bool
MergedCommitID string `xorm:"VARCHAR(40)"`
Merged time.Time
MergerID int64
Merger *User `xorm:"-"`
Merger *User `xorm:"-"`
Merged time.Time `xorm:"-"`
MergedUnix int64
}
func (pr *PullRequest) BeforeUpdate() {
pr.MergedUnix = pr.Merged.UTC().Unix()
}
// Note: don't try to get Pull because will end up recursive querying.
func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "merged":
case "merged_unix":
if !pr.HasMerged {
return
}
pr.Merged = regulateTimeZone(pr.Merged)
pr.Merged = time.Unix(pr.MergedUnix, 0).Local()
}
}
@@ -138,7 +143,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
return err
}
if err = pr.Issue.changeStatus(sess, doer, true); err != nil {
if err = pr.Issue.changeStatus(sess, doer, pr.Issue.Repo, true); err != nil {
return fmt.Errorf("Issue.changeStatus: %v", err)
}
@@ -484,10 +489,9 @@ func (pr *PullRequest) UpdatePatch() (err error) {
// PushToBaseRepo pushes commits from branches of head repository to
// corresponding branches of base repository.
// FIXME: could fail after user force push head repo, should we always force push here?
// FIXME: Only push branches that are actually updates?
func (pr *PullRequest) PushToBaseRepo() (err error) {
log.Trace("PushToBaseRepo[%[1]d]: pushing commits to base repo 'refs/pull/%[1]d/head'", pr.ID)
log.Trace("PushToBaseRepo[%d]: pushing commits to base repo 'refs/pull/%d/head'", pr.BaseRepoID, pr.Index)
headRepoPath := pr.HeadRepo.RepoPath()
headGitRepo, err := git.OpenRepository(headRepoPath)
@@ -502,7 +506,12 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
// Make sure to remove the remote even if the push fails
defer headGitRepo.RemoveRemote(tmpRemoteName)
if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:refs/pull/%d/head", pr.HeadBranch, pr.Index)); err != nil {
headFile := fmt.Sprintf("refs/pull/%d/head", pr.Index)
// Remove head in case there is a conflict.
os.Remove(path.Join(pr.BaseRepo.RepoPath(), headFile))
if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:%s", pr.HeadBranch, headFile)); err != nil {
return fmt.Errorf("Push: %v", err)
}

View File

@@ -33,13 +33,19 @@ type Release struct {
Note string `xorm:"TEXT"`
IsDraft bool `xorm:"NOT NULL DEFAULT false"`
IsPrerelease bool
Created time.Time `xorm:"CREATED"`
Created time.Time `xorm:"-"`
CreatedUnix int64
}
func (r *Release) BeforeInsert() {
r.CreatedUnix = time.Now().UTC().Unix()
}
func (r *Release) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created":
r.Created = regulateTimeZone(r.Created)
case "created_unix":
r.Created = time.Unix(r.CreatedUnix, 0).Local()
}
}
@@ -125,7 +131,7 @@ func GetReleaseByID(id int64) (*Release, error) {
// GetReleasesByRepoID returns a list of releases of repository.
func GetReleasesByRepoID(repoID int64) (rels []*Release, err error) {
err = x.Desc("created").Find(&rels, Release{RepoID: repoID})
err = x.Desc("created_unix").Find(&rels, Release{RepoID: repoID})
return rels, err
}

View File

@@ -27,7 +27,7 @@ import (
"github.com/mcuadros/go-version"
"gopkg.in/ini.v1"
"github.com/gogits/git-module"
git "github.com/gogits/git-module"
api "github.com/gogits/go-gogs-client"
"github.com/gogits/gogs/modules/bindata"
@@ -178,20 +178,38 @@ type Repository struct {
ForkID int64
BaseRepo *Repository `xorm:"-"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
}
func (repo *Repository) BeforeInsert() {
repo.CreatedUnix = time.Now().UTC().Unix()
repo.UpdatedUnix = repo.CreatedUnix
}
func (repo *Repository) BeforeUpdate() {
repo.UpdatedUnix = time.Now().UTC().Unix()
}
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "default_branch":
// FIXME: use models migration to solve all at once.
if len(repo.DefaultBranch) == 0 {
repo.DefaultBranch = "master"
}
case "num_closed_issues":
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
case "num_closed_pulls":
repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls
case "num_closed_milestones":
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
case "updated":
repo.Updated = regulateTimeZone(repo.Updated)
case "created_unix":
repo.Created = time.Unix(repo.CreatedUnix, 0).Local()
case "updated_unix":
repo.Updated = time.Unix(repo.UpdatedUnix, 0)
}
}
@@ -241,6 +259,14 @@ func (repo *Repository) ComposeMetas() map[string]string {
return repo.ExternalMetas
}
// DeleteWiki removes the actual and local copy of repository wiki.
func (repo *Repository) DeleteWiki() {
wikiPaths := []string{repo.WikiPath(), repo.LocalWikiPath()}
for _, wikiPath := range wikiPaths {
RemoveAllWithNotice("Delete repository wiki", wikiPath)
}
}
// GetAssignees returns all users that have write access of repository.
func (repo *Repository) GetAssignees() (_ []*User, err error) {
if err = repo.GetOwner(); err != nil {
@@ -313,6 +339,10 @@ func (repo *Repository) RepoLink() string {
return setting.AppSubUrl + "/" + repo.MustOwner().Name + "/" + repo.Name
}
func (repo *Repository) RepoRelLink() string {
return "/" + repo.MustOwner().Name + "/" + repo.Name
}
func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) string {
return fmt.Sprintf("%s/%s/compare/%s...%s", repo.MustOwner().Name, repo.Name, oldCommitID, newCommitID)
}
@@ -367,11 +397,16 @@ func (repo *Repository) LocalCopyPath() string {
func updateLocalCopy(repoPath, localPath string) error {
if !com.IsExist(localPath) {
if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{}); err != nil {
if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{
Timeout: time.Duration(setting.Git.Timeout.Clone) * time.Second,
}); err != nil {
return fmt.Errorf("Clone: %v", err)
}
} else {
if err := git.Pull(localPath, true); err != nil {
if err := git.Pull(localPath, git.PullRemoteOptions{
All: true,
Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
}); err != nil {
return fmt.Errorf("Pull: %v", err)
}
}
@@ -457,10 +492,10 @@ func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
repo.Owner = repo.MustOwner()
cl := new(CloneLink)
if setting.SSHPort != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.Name, repoName)
if setting.SSH.Port != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSH.Domain, setting.SSH.Port, repo.Owner.Name, repoName)
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.Name, repoName)
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSH.Domain, repo.Owner.Name, repoName)
}
cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.Name, repoName)
return cl
@@ -501,16 +536,28 @@ func IsUsableName(name string) error {
// Mirror represents a mirror information of repository.
type Mirror struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64
Repo *Repository `xorm:"-"`
Interval int // Hour.
Updated time.Time `xorm:"UPDATED"`
NextUpdate time.Time
ID int64 `xorm:"pk autoincr"`
RepoID int64
Repo *Repository `xorm:"-"`
Interval int // Hour.
Updated time.Time `xorm:"-"`
UpdatedUnix int64
NextUpdate time.Time `xorm:"-"`
NextUpdateUnix int64
address string `xorm:"-"`
}
func (m *Mirror) BeforeInsert() {
m.NextUpdateUnix = m.NextUpdate.UTC().Unix()
}
func (m *Mirror) BeforeUpdate() {
m.UpdatedUnix = time.Now().UTC().Unix()
m.NextUpdateUnix = m.NextUpdate.UTC().Unix()
}
func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
@@ -519,6 +566,10 @@ func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
if err != nil {
log.Error(3, "GetRepositoryByID[%d]: %v", m.ID, err)
}
case "updated_unix":
m.Updated = time.Unix(m.UpdatedUnix, 0).Local()
case "next_updated_unix":
m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local()
}
}
@@ -652,11 +703,36 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneRepoOptions{
Mirror: true,
Quiet: true,
Timeout: 10 * time.Minute,
Timeout: time.Duration(setting.Git.Timeout.Migrate) * time.Second,
}); err != nil {
return repo, fmt.Errorf("Clone: %v", err)
}
// Check if repository is empty.
_, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1")
if err != nil {
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") {
repo.IsBare = true
} else {
return repo, fmt.Errorf("check bare: %v - %s", err, stderr)
}
}
if !repo.IsBare {
// Try to get HEAD branch and set it as default branch.
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
return repo, fmt.Errorf("OpenRepository: %v", err)
}
headBranch, err := gitRepo.GetHEADBranch()
if err != nil {
return repo, fmt.Errorf("GetHEADBranch: %v", err)
}
if headBranch != nil {
repo.DefaultBranch = headBranch.Name
}
}
if opts.IsMirror {
if _, err = x.InsertOne(&Mirror{
RepoID: repo.ID,
@@ -691,31 +767,6 @@ func CleanUpMigrateInfo(repo *Repository, repoPath string) (*Repository, error)
return repo, fmt.Errorf("save config file: %v", err)
}
// Check if repository is empty.
_, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1")
if err != nil {
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") {
repo.IsBare = true
} else {
return repo, fmt.Errorf("check bare: %v - %s", err, stderr)
}
}
// Try to get HEAD branch and set it as default branch.
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
log.Error(4, "OpenRepository: %v", err)
return repo, nil
}
headBranch, err := gitRepo.GetHEADBranch()
if err != nil {
log.Error(4, "GetHEADBranch: %v", err)
return repo, nil
}
if headBranch != nil {
repo.DefaultBranch = headBranch.Name
}
return repo, UpdateRepository(repo, false)
}
@@ -998,11 +1049,16 @@ func CountPublicRepositories() int64 {
return countRepositories(false)
}
func Repositories(page, pageSize int) (_ []*Repository, err error) {
repos := make([]*Repository, 0, pageSize)
return repos, x.Limit(pageSize, (page-1)*pageSize).Asc("id").Find(&repos)
}
// RepositoriesWithUsers returns number of repos in given page.
func RepositoriesWithUsers(page, pageSize int) (_ []*Repository, err error) {
repos := make([]*Repository, 0, pageSize)
if err = x.Limit(pageSize, (page-1)*pageSize).Asc("id").Find(&repos); err != nil {
return nil, err
repos, err := Repositories(page, pageSize)
if err != nil {
return nil, fmt.Errorf("Repositories: %v", err)
}
for i := range repos {
@@ -1330,10 +1386,7 @@ func DeleteRepository(uid, repoID int64) error {
repoPath := repo.repoPath(sess)
RemoveAllWithNotice("Delete repository files", repoPath)
wikiPaths := []string{repo.WikiPath(), repo.LocalWikiPath()}
for _, wikiPath := range wikiPaths {
RemoveAllWithNotice("Delete repository wiki", wikiPath)
}
repo.DeleteWiki()
// Remove attachment files.
for i := range attachmentPaths {
@@ -1416,7 +1469,8 @@ func GetRepositoryByID(id int64) (*Repository, error) {
// GetRepositories returns a list of repositories of given user.
func GetRepositories(uid int64, private bool) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
sess := x.Desc("updated")
sess := x.Desc("updated_unix")
if !private {
sess.Where("is_private=?", false)
}
@@ -1425,9 +1479,9 @@ func GetRepositories(uid int64, private bool) ([]*Repository, error) {
}
// GetRecentUpdatedRepositories returns the list of repositories that are recently updated.
func GetRecentUpdatedRepositories(page int) (repos []*Repository, err error) {
return repos, x.Limit(setting.ExplorePagingNum, (page-1)*setting.ExplorePagingNum).
Where("is_private=?", false).Limit(setting.ExplorePagingNum).Desc("updated").Find(&repos)
func GetRecentUpdatedRepositories(page, pageSize int) (repos []*Repository, err error) {
return repos, x.Limit(pageSize, (page-1)*pageSize).
Where("is_private=?", false).Limit(pageSize).Desc("updated_unix").Find(&repos)
}
func getRepositoryCount(e Engine, u *User) (int64, error) {
@@ -1439,32 +1493,52 @@ func GetRepositoryCount(u *User) (int64, error) {
return getRepositoryCount(x, u)
}
type SearchOption struct {
Keyword string
Uid int64
Limit int
Private bool
type SearchRepoOptions struct {
Keyword string
OwnerID int64
OrderBy string
Private bool // Include private repositories in results
Page int
PageSize int // Can be smaller than or equal to setting.ExplorePagingNum
}
// SearchRepositoryByName returns given number of repositories whose name contains keyword.
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
if len(opt.Keyword) == 0 {
return repos, nil
// SearchRepositoryByName takes keyword and part of repository name to search,
// it returns results in given range and number of total results.
func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int64, _ error) {
if len(opts.Keyword) == 0 {
return repos, 0, nil
}
opt.Keyword = strings.ToLower(opt.Keyword)
opts.Keyword = strings.ToLower(opts.Keyword)
repos = make([]*Repository, 0, opt.Limit)
// Append conditions.
sess := x.Limit(opt.Limit)
if opt.Uid > 0 {
sess.Where("owner_id=?", opt.Uid)
if opts.PageSize <= 0 || opts.PageSize > setting.ExplorePagingNum {
opts.PageSize = setting.ExplorePagingNum
}
if !opt.Private {
if opts.Page <= 0 {
opts.Page = 1
}
repos = make([]*Repository, 0, opts.PageSize)
// Append conditions
sess := x.Where("LOWER(lower_name) LIKE ?", "%"+opts.Keyword+"%")
if opts.OwnerID > 0 {
sess.And("owner_id = ?", opts.OwnerID)
}
if !opts.Private {
sess.And("is_private=?", false)
}
sess.And("lower_name like ?", "%"+opt.Keyword+"%").Find(&repos)
return repos, err
var countSess xorm.Session
countSess = *sess
count, err := countSess.Count(new(Repository))
if err != nil {
return nil, 0, fmt.Errorf("Count: %v", err)
}
if len(opts.OrderBy) > 0 {
sess.OrderBy(opts.OrderBy)
}
return repos, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&repos)
}
// DeleteRepositoryArchives deletes all repositories' archives.
@@ -1610,7 +1684,8 @@ func MirrorUpdate() {
}
repoPath := m.Repo.RepoPath()
if _, stderr, err := process.ExecDir(10*time.Minute,
if _, stderr, err := process.ExecDir(
time.Duration(setting.Git.Timeout.Mirror)*time.Second,
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
"git", "remote", "update", "--prune"); err != nil {
desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
@@ -1776,105 +1851,6 @@ func CheckRepoStats() {
// ***** END: Repository.NumForks *****
}
// _________ .__ .__ ___. __ .__
// \_ ___ \ ____ | | | | _____ \_ |__ ________________ _/ |_|__| ____ ____
// / \ \/ / _ \| | | | \__ \ | __ \ / _ \_ __ \__ \\ __\ |/ _ \ / \
// \ \___( <_> ) |_| |__/ __ \| \_\ ( <_> ) | \// __ \| | | ( <_> ) | \
// \______ /\____/|____/____(____ /___ /\____/|__| (____ /__| |__|\____/|___| /
// \/ \/ \/ \/ \/
// A Collaboration is a relation between an individual and a repository
type Collaboration struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Created time.Time `xorm:"CREATED"`
}
// Add collaborator and accompanying access
func (repo *Repository) AddCollaborator(u *User) error {
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: u.Id,
}
has, err := x.Get(collaboration)
if err != nil {
return err
} else if has {
return nil
}
if err = repo.GetOwner(); err != nil {
return fmt.Errorf("GetOwner: %v", err)
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.InsertOne(collaboration); err != nil {
return err
}
if repo.Owner.IsOrganization() {
err = repo.recalculateTeamAccesses(sess, 0)
} else {
err = repo.recalculateAccesses(sess)
}
if err != nil {
return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err)
}
return sess.Commit()
}
func (repo *Repository) getCollaborators(e Engine) ([]*User, error) {
collaborations := make([]*Collaboration, 0)
if err := e.Find(&collaborations, &Collaboration{RepoID: repo.ID}); err != nil {
return nil, err
}
users := make([]*User, len(collaborations))
for i, c := range collaborations {
user, err := getUserByID(e, c.UserID)
if err != nil {
return nil, err
}
users[i] = user
}
return users, nil
}
// GetCollaborators returns the collaborators for a repository
func (repo *Repository) GetCollaborators() ([]*User, error) {
return repo.getCollaborators(x)
}
// Delete collaborator and accompanying access
func (repo *Repository) DeleteCollaborator(u *User) (err error) {
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: u.Id,
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if has, err := sess.Delete(collaboration); err != nil || has == 0 {
return err
} else if err = repo.recalculateAccesses(sess); err != nil {
return err
}
return sess.Commit()
}
// __ __ __ .__
// / \ / \_____ _/ |_ ____ | |__
// \ \/\/ /\__ \\ __\/ ___\| | \

View File

@@ -0,0 +1,159 @@
// Copyright 2016 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 (
"fmt"
)
// Collaboration represent the relation between an individual and a repository.
type Collaboration struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"`
}
func (c *Collaboration) ModeName() string {
switch c.Mode {
case ACCESS_MODE_READ:
return "Read"
case ACCESS_MODE_WRITE:
return "Write"
case ACCESS_MODE_ADMIN:
return "Admin"
}
return "Undefined"
}
// AddCollaborator adds new collaboration relation between an individual and a repository.
func (repo *Repository) AddCollaborator(u *User) error {
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: u.Id,
}
has, err := x.Get(collaboration)
if err != nil {
return err
} else if has {
return nil
}
collaboration.Mode = ACCESS_MODE_WRITE
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.InsertOne(collaboration); err != nil {
return err
}
if repo.Owner.IsOrganization() {
err = repo.recalculateTeamAccesses(sess, 0)
} else {
err = repo.recalculateAccesses(sess)
}
if err != nil {
return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err)
}
return sess.Commit()
}
func (repo *Repository) getCollaborations(e Engine) ([]*Collaboration, error) {
collaborations := make([]*Collaboration, 0)
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repo.ID})
}
// Collaborator represents a user with collaboration details.
type Collaborator struct {
*User
Collaboration *Collaboration
}
func (repo *Repository) getCollaborators(e Engine) ([]*Collaborator, error) {
collaborations, err := repo.getCollaborations(e)
if err != nil {
return nil, fmt.Errorf("getCollaborations: %v", err)
}
collaborators := make([]*Collaborator, len(collaborations))
for i, c := range collaborations {
user, err := getUserByID(e, c.UserID)
if err != nil {
return nil, err
}
collaborators[i] = &Collaborator{
User: user,
Collaboration: c,
}
}
return collaborators, nil
}
// GetCollaborators returns the collaborators for a repository
func (repo *Repository) GetCollaborators() ([]*Collaborator, error) {
return repo.getCollaborators(x)
}
// ChangeCollaborationAccessMode sets new access mode for the collaboration.
func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode AccessMode) error {
// Discard invalid input
if mode <= ACCESS_MODE_NONE || mode > ACCESS_MODE_OWNER {
return nil
}
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: uid,
}
has, err := x.Get(collaboration)
if err != nil {
return fmt.Errorf("get collaboration: %v", err)
} else if !has {
return nil
}
collaboration.Mode = mode
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Id(collaboration.ID).AllCols().Update(collaboration); err != nil {
return fmt.Errorf("update collaboration: %v", err)
} else if _, err = sess.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil {
return fmt.Errorf("update access table: %v", err)
}
return sess.Commit()
}
// DeleteCollaboration removes collaboration relation between the user and repository.
func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
collaboration := &Collaboration{
RepoID: repo.ID,
UserID: uid,
}
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if has, err := sess.Delete(collaboration); err != nil || has == 0 {
return err
} else if err = repo.recalculateAccesses(sess); err != nil {
return err
}
return sess.Commit()
}

View File

@@ -12,6 +12,7 @@ import (
"fmt"
"io"
"io/ioutil"
"math/big"
"os"
"path"
"path/filepath"
@@ -44,22 +45,36 @@ const (
// PublicKey represents a SSH or deploy key.
type PublicKey struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
Created time.Time `xorm:"CREATED"`
Updated time.Time // Note: Updated must below Created for AfterSet.
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
UpdatedUnix int64
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
func (k *PublicKey) BeforeInsert() {
k.CreatedUnix = time.Now().UTC().Unix()
}
func (k *PublicKey) BeforeUpdate() {
k.UpdatedUnix = time.Now().UTC().Unix()
}
func (k *PublicKey) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created":
case "created_unix":
k.Created = time.Unix(k.CreatedUnix, 0).Local()
case "updated_unix":
k.Updated = time.Unix(k.UpdatedUnix, 0).Local()
k.HasUsed = k.Updated.After(k.Created)
k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
@@ -78,19 +93,18 @@ func (key *PublicKey) GetAuthorizedString() string {
func extractTypeFromBase64Key(key string) (string, error) {
b, err := base64.StdEncoding.DecodeString(key)
if err != nil || len(b) < 4 {
return "", errors.New("Invalid key format")
return "", fmt.Errorf("Invalid key format: %v", err)
}
keyLength := int(binary.BigEndian.Uint32(b))
if len(b) < 4+keyLength {
return "", errors.New("Invalid key format")
return "", fmt.Errorf("Invalid key format: not enough length")
}
return string(b[4 : 4+keyLength]), nil
}
// parseKeyString parses any key string in openssh or ssh2 format to clean openssh string (rfc4253)
// parseKeyString parses any key string in OpenSSH or SSH2 format to clean OpenSSH string (RFC4253)
func parseKeyString(content string) (string, error) {
// Transform all legal line endings to a single "\n"
s := strings.Replace(strings.Replace(strings.TrimSpace(content), "\r\n", "\n", -1), "\r", "\n", -1)
@@ -153,8 +167,115 @@ func parseKeyString(content string) (string, error) {
return keyType + " " + keyContent + " " + keyComment, nil
}
// writeTmpKeyFile writes key content to a temporary file
// and returns the name of that file, along with any possible errors.
func writeTmpKeyFile(content string) (string, error) {
tmpFile, err := ioutil.TempFile(setting.SSH.KeyTestPath, "gogs_keytest")
if err != nil {
return "", fmt.Errorf("TempFile: %v", err)
}
defer tmpFile.Close()
if _, err = tmpFile.WriteString(content); err != nil {
return "", fmt.Errorf("tmpFile.WriteString: %v", err)
}
return tmpFile.Name(), nil
}
// SSHKeyGenParsePublicKey extracts key type and length using ssh-keygen.
func SSHKeyGenParsePublicKey(key string) (string, int, error) {
// The ssh-keygen in Windows does not print key type, so no need go further.
if setting.IsWindows {
return "", 0, nil
}
tmpName, err := writeTmpKeyFile(key)
if err != nil {
return "", 0, fmt.Errorf("writeTmpKeyFile: %v", err)
}
defer os.Remove(tmpName)
stdout, stderr, err := process.Exec("SSHKeyGenParsePublicKey", setting.SSH.KeygenPath, "-lf", tmpName)
if err != nil {
return "", 0, fmt.Errorf("Fail to parse public key: %s - %s", err, stderr)
}
if strings.Contains(stdout, "is not a public key file") {
return "", 0, ErrKeyUnableVerify{stdout}
}
fields := strings.Split(stdout, " ")
if len(fields) < 4 {
return "", 0, fmt.Errorf("Invalid public key line: %s", stdout)
}
keyType := strings.Trim(fields[len(fields)-1], "()\r\n")
return strings.ToLower(keyType), com.StrTo(fields[0]).MustInt(), nil
}
// SSHNativeParsePublicKey extracts the key type and length using the golang SSH library.
// NOTE: ed25519 is not supported.
func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
fields := strings.Fields(keyLine)
if len(fields) < 2 {
return "", 0, fmt.Errorf("not enough fields in public key line: %s", string(keyLine))
}
raw, err := base64.StdEncoding.DecodeString(fields[1])
if err != nil {
return "", 0, err
}
pkey, err := ssh.ParsePublicKey(raw)
if err != nil {
if strings.Contains(err.Error(), "ssh: unknown key algorithm") {
return "", 0, ErrKeyUnableVerify{err.Error()}
}
return "", 0, fmt.Errorf("ssh.ParsePublicKey: %v", err)
}
// The ssh library can parse the key, so next we find out what key exactly we have.
switch pkey.Type() {
case ssh.KeyAlgoDSA:
rawPub := struct {
Name string
P, Q, G, Y *big.Int
}{}
if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
return "", 0, err
}
// as per https://bugzilla.mindrot.org/show_bug.cgi?id=1647 we should never
// see dsa keys != 1024 bit, but as it seems to work, we will not check here
return "dsa", rawPub.P.BitLen(), nil // use P as per crypto/dsa/dsa.go (is L)
case ssh.KeyAlgoRSA:
rawPub := struct {
Name string
E *big.Int
N *big.Int
}{}
if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
return "", 0, err
}
return "rsa", rawPub.N.BitLen(), nil // use N as per crypto/rsa/rsa.go (is bits)
case ssh.KeyAlgoECDSA256:
return "ecdsa", 256, nil
case ssh.KeyAlgoECDSA384:
return "ecdsa", 384, nil
case ssh.KeyAlgoECDSA521:
return "ecdsa", 521, nil
case "ssh-ed25519": // TODO replace with ssh constant when available
return "ed25519", 256, nil
}
return "", 0, fmt.Errorf("Unsupported key length detection for type: %s", pkey.Type())
}
// CheckPublicKeyString checks if the given public key string is recognized by SSH.
//
// The function returns the actual public key line on success.
func CheckPublicKeyString(content string) (_ string, err error) {
if setting.SSH.Disabled {
return "", errors.New("SSH is disabled")
}
content, err = parseKeyString(content)
if err != nil {
return "", err
@@ -168,22 +289,29 @@ func CheckPublicKeyString(content string) (_ string, err error) {
// remove any unnecessary whitespace now
content = strings.TrimSpace(content)
fields := strings.Fields(content)
if len(fields) < 2 {
return "", errors.New("too less fields")
var (
keyType string
length int
)
if setting.SSH.StartBuiltinServer {
keyType, length, err = SSHNativeParsePublicKey(content)
} else {
keyType, length, err = SSHKeyGenParsePublicKey(content)
}
key, err := base64.StdEncoding.DecodeString(fields[1])
if err != nil {
return "", fmt.Errorf("StdEncoding.DecodeString: %v", err)
}
pkey, err := ssh.ParsePublicKey([]byte(key))
if err != nil {
return "", fmt.Errorf("ParsePublicKey: %v", err)
}
log.Trace("Key type: %s", pkey.Type())
log.Trace("Key info [native: %v]: %s-%d", setting.SSH.StartBuiltinServer, keyType, length)
return content, nil
if !setting.SSH.MinimumKeySizeCheck {
return content, nil
}
if minLen, found := setting.SSH.MinimumKeySizes[keyType]; found && length >= minLen {
return content, nil
} else if found && length < minLen {
return "", fmt.Errorf("Key length is not enough: got %d, needs %d", length, minLen)
}
return "", fmt.Errorf("Key type is not allowed: %s", keyType)
}
// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
@@ -191,7 +319,7 @@ func saveAuthorizedKeyFile(keys ...*PublicKey) error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
fpath := filepath.Join(setting.SSHRootPath, "authorized_keys")
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
@@ -247,7 +375,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
}
stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-lf", tmpPath)
if err != nil {
return errors.New("ssh-keygen -lf: " + stderr)
return fmt.Errorf("'ssh-keygen -lf %s' failed with error '%s': %s", tmpPath, err, stderr)
} else if len(stdout) < 2 {
return errors.New("not enough output for calculating fingerprint: " + stdout)
}
@@ -259,7 +387,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
}
// Don't need to rewrite this file if builtin SSH server is enabled.
if setting.StartSSHServer {
if setting.SSH.StartBuiltinServer {
return nil
}
return saveAuthorizedKeyFile(key)
@@ -267,6 +395,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(ownerID int64, name, content string) (*PublicKey, error) {
log.Trace(content)
if err := checkKeyContent(content); err != nil {
return nil, err
}
@@ -408,12 +537,12 @@ func deletePublicKey(e *xorm.Session, keyID int64) error {
}
// Don't need to rewrite this file if builtin SSH server is enabled.
if setting.StartSSHServer {
if setting.SSH.StartBuiltinServer {
return nil
}
fpath := filepath.Join(setting.SSHRootPath, "authorized_keys")
tmpPath := filepath.Join(setting.SSHRootPath, "authorized_keys.tmp")
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
tmpPath := fpath + ".tmp"
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
return err
} else if err = os.Remove(fpath); err != nil {
@@ -455,7 +584,8 @@ func RewriteAllPublicKeys() error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
tmpPath := filepath.Join(setting.SSHRootPath, "authorized_keys.tmp")
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
tmpPath := fpath + ".tmp"
f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
@@ -471,7 +601,6 @@ func RewriteAllPublicKeys() error {
return err
}
fpath := filepath.Join(setting.SSHRootPath, "authorized_keys")
if com.IsExist(fpath) {
if err = os.Remove(fpath); err != nil {
return err
@@ -493,21 +622,35 @@ func RewriteAllPublicKeys() error {
// DeployKey represents deploy key information and its relation with repository.
type DeployKey struct {
ID int64 `xorm:"pk autoincr"`
KeyID int64 `xorm:"UNIQUE(s) INDEX"`
RepoID int64 `xorm:"UNIQUE(s) INDEX"`
Name string
Fingerprint string
Content string `xorm:"-"`
Created time.Time `xorm:"CREATED"`
Updated time.Time // Note: Updated must below Created for AfterSet.
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
KeyID int64 `xorm:"UNIQUE(s) INDEX"`
RepoID int64 `xorm:"UNIQUE(s) INDEX"`
Name string
Fingerprint string
Content string `xorm:"-"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
UpdatedUnix int64
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
func (k *DeployKey) BeforeInsert() {
k.CreatedUnix = time.Now().UTC().Unix()
}
func (k *DeployKey) BeforeUpdate() {
k.UpdatedUnix = time.Now().UTC().Unix()
}
func (k *DeployKey) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created":
case "created_unix":
k.Created = time.Unix(k.CreatedUnix, 0).Local()
case "updated_unix":
k.Updated = time.Unix(k.UpdatedUnix, 0).Local()
k.HasUsed = k.Updated.After(k.Created)
k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}

45
models/ssh_key_test.go Normal file
View File

@@ -0,0 +1,45 @@
package models
import (
"fmt"
"testing"
. "github.com/smartystreets/goconvey/convey"
"github.com/gogits/gogs/modules/setting"
)
func init() {
setting.NewContext()
}
func Test_SSHParsePublicKey(t *testing.T) {
testKeys := map[string]struct {
typeName string
length int
content string
}{
"dsa-1024": {"dsa", 1024, "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment"},
"rsa-1024": {"rsa", 1024, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n"},
"rsa-2048": {"rsa", 2048, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMZXh+1OBUwSH9D45wTaxErQIN9IoC9xl7MKJkqvTvv6O5RR9YW/IK9FbfjXgXsppYGhsCZo1hFOOsXHMnfOORqu/xMDx4yPuyvKpw4LePEcg4TDipaDFuxbWOqc/BUZRZcXu41QAWfDLrInwsltWZHSeG7hjhpacl4FrVv9V1pS6Oc5Q1NxxEzTzuNLS/8diZrTm/YAQQ/+B+mzWI3zEtF4miZjjAljWd1LTBPvU23d29DcBmmFahcZ441XZsTeAwGxG/Q6j8NgNXj9WxMeWwxXV2jeAX/EBSpZrCVlCQ1yJswT6xCp8TuBnTiGWYMBNTbOZvPC4e0WI2/yZW/s5F nocomment"},
"ecdsa-256": {"ecdsa", 256, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFQacN3PrOll7PXmN5B/ZNVahiUIqI05nbBlZk1KXsO3d06ktAWqbNflv2vEmA38bTFTfJ2sbn2B5ksT52cDDbA= nocomment"},
"ecdsa-384": {"ecdsa", 384, "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBINmioV+XRX1Fm9Qk2ehHXJ2tfVxW30ypUWZw670Zyq5GQfBAH6xjygRsJ5wWsHXBsGYgFUXIHvMKVAG1tpw7s6ax9oA+dJOJ7tj+vhn8joFqT+sg3LYHgZkHrfqryRasQ== nocomment"},
"ecdsa-521": {"ecdsa", 521, "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACGt3UG3EzRwNOI17QR84l6PgiAcvCE7v6aXPj/SC6UWKg4EL8vW9ZBcdYL9wzs4FZXh4MOV8jAzu3KRWNTwb4k2wFNUpGOt7l28MztFFEtH5BDDrtAJSPENPy8pvPLMfnPg5NhvWycqIBzNcHipem5wSJFN5PdpNOC2xMrPWKNqj+ZjQ== nocomment"},
}
Convey("Parse public keys in both native and ssh-keygen", t, func() {
for name, key := range testKeys {
fmt.Println("\nTesting key:", name)
keyTypeN, lengthN, errN := SSHNativeParsePublicKey(key.content)
So(errN, ShouldBeNil)
So(keyTypeN, ShouldEqual, key.typeName)
So(lengthN, ShouldEqual, key.length)
keyTypeK, lengthK, errK := SSHKeyGenParsePublicKey(key.content)
So(errK, ShouldBeNil)
So(keyTypeK, ShouldEqual, key.typeName)
So(lengthK, ShouldEqual, key.length)
}
})
}

View File

@@ -7,6 +7,7 @@ package models
import (
"time"
"github.com/go-xorm/xorm"
gouuid "github.com/satori/go.uuid"
"github.com/gogits/gogs/modules/base"
@@ -14,16 +15,38 @@ import (
// AccessToken represents a personal access token.
type AccessToken struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX"`
Name string
Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
Created time.Time `xorm:"CREATED"`
Updated time.Time
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX"`
Name string
Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
UpdatedUnix int64
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
func (t *AccessToken) BeforeInsert() {
t.CreatedUnix = time.Now().UTC().Unix()
}
func (t *AccessToken) BeforeUpdate() {
t.UpdatedUnix = time.Now().UTC().Unix()
}
func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
t.Created = time.Unix(t.CreatedUnix, 0).Local()
case "updated_unix":
t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
t.HasUsed = t.Updated.After(t.Created)
t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
}
// NewAccessToken creates new access token.
func NewAccessToken(t *AccessToken) error {
t.Sha1 = base.EncodeSha1(gouuid.NewV4().String())
@@ -46,16 +69,7 @@ func GetAccessTokenBySHA(sha string) (*AccessToken, error) {
// ListAccessTokens returns a list of access tokens belongs to given user.
func ListAccessTokens(uid int64) ([]*AccessToken, error) {
tokens := make([]*AccessToken, 0, 5)
err := x.Where("uid=?", uid).Desc("id").Find(&tokens)
if err != nil {
return nil, err
}
for _, t := range tokens {
t.HasUsed = t.Updated.After(t.Created)
t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
return tokens, nil
return tokens, x.Where("uid=?", uid).Desc("id").Find(&tokens)
}
// UpdateAccessToken updates information of access token.

View File

@@ -36,8 +36,8 @@ import (
type UserType int
const (
INDIVIDUAL UserType = iota // Historic reason to make it starts at 0.
ORGANIZATION
USER_TYPE_INDIVIDUAL UserType = iota // Historic reason to make it starts at 0.
USER_TYPE_ORGANIZATION
)
var (
@@ -68,10 +68,13 @@ type User struct {
Repos []*Repository `xorm:"-"`
Location string
Website string
Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
// Remember visibility choice for convenience, true for private
LastRepoVisibility bool
@@ -103,18 +106,26 @@ type User struct {
Members []*User `xorm:"-"`
}
func (u *User) BeforeInsert() {
u.CreatedUnix = time.Now().UTC().Unix()
u.UpdatedUnix = u.CreatedUnix
}
func (u *User) BeforeUpdate() {
if u.MaxRepoCreation < -1 {
u.MaxRepoCreation = -1
}
u.UpdatedUnix = time.Now().UTC().Unix()
}
func (u *User) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "full_name":
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
case "created":
u.Created = regulateTimeZone(u.Created)
case "created_unix":
u.Created = time.Unix(u.CreatedUnix, 0).Local()
case "updated_unix":
u.Updated = time.Unix(u.UpdatedUnix, 0).Local()
}
}
@@ -346,28 +357,39 @@ func (u *User) UploadAvatar(data []byte) error {
return sess.Commit()
}
// DeleteAvatar deletes the user's custom avatar.
func (u *User) DeleteAvatar() error {
log.Trace("DeleteAvatar[%d]: %s", u.Id, u.CustomAvatarPath())
os.Remove(u.CustomAvatarPath())
u.UseCustomAvatar = false
if err := UpdateUser(u); err != nil {
return fmt.Errorf("UpdateUser: %v", err)
}
return nil
}
// IsAdminOfRepo returns true if user has admin or higher access of repository.
func (u *User) IsAdminOfRepo(repo *Repository) bool {
if err := repo.GetOwner(); err != nil {
log.Error(3, "GetOwner: %v", err)
return false
has, err := HasAccess(u, repo, ACCESS_MODE_ADMIN)
if err != nil {
log.Error(3, "HasAccess: %v", err)
}
return has
}
if repo.Owner.IsOrganization() {
has, err := HasAccess(u, repo, ACCESS_MODE_ADMIN)
if err != nil {
log.Error(3, "HasAccess: %v", err)
return false
}
return has
// IsWriterOfRepo returns true if user has write access to given repository.
func (u *User) IsWriterOfRepo(repo *Repository) bool {
has, err := HasAccess(u, repo, ACCESS_MODE_WRITE)
if err != nil {
log.Error(3, "HasAccess: %v", err)
}
return repo.IsOwnedBy(u.Id)
return has
}
// IsOrganization returns true if user is actually a organization.
func (u *User) IsOrganization() bool {
return u.Type == ORGANIZATION
return u.Type == USER_TYPE_ORGANIZATION
}
// IsUserOrgOwner returns true if user is in the owner team of given organization.
@@ -614,7 +636,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
}
func updateUser(e Engine, u *User) error {
// Organization does not need e-mail.
// Organization does not need email
if !u.IsOrganization() {
u.Email = strings.ToLower(u.Email)
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
@@ -631,16 +653,9 @@ func updateUser(e Engine, u *User) error {
}
u.LowerName = strings.ToLower(u.Name)
if len(u.Location) > 255 {
u.Location = u.Location[:255]
}
if len(u.Website) > 255 {
u.Website = u.Website[:255]
}
if len(u.Description) > 255 {
u.Description = u.Description[:255]
}
u.Location = base.TruncateString(u.Location, 255)
u.Website = base.TruncateString(u.Website, 255)
u.Description = base.TruncateString(u.Description, 255)
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
_, err := e.Id(u.Id).AllCols().Update(u)
@@ -1099,16 +1114,47 @@ func GetUserByEmail(email string) (*User, error) {
return nil, ErrUserNotExist{0, email}
}
// SearchUserByName returns given number of users whose name contains keyword.
func SearchUserByName(opt SearchOption) (us []*User, err error) {
if len(opt.Keyword) == 0 {
return us, nil
}
opt.Keyword = strings.ToLower(opt.Keyword)
type SearchUserOptions struct {
Keyword string
Type UserType
OrderBy string
Page int
PageSize int // Can be smaller than or equal to setting.ExplorePagingNum
}
us = make([]*User, 0, opt.Limit)
err = x.Limit(opt.Limit).Where("type=0").And("lower_name like ?", "%"+opt.Keyword+"%").Find(&us)
return us, err
// SearchUserByName takes keyword and part of user name to search,
// it returns results in given range and number of total results.
func SearchUserByName(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
if len(opts.Keyword) == 0 {
return users, 0, nil
}
opts.Keyword = strings.ToLower(opts.Keyword)
if opts.PageSize <= 0 || opts.PageSize > setting.ExplorePagingNum {
opts.PageSize = setting.ExplorePagingNum
}
if opts.Page <= 0 {
opts.Page = 1
}
searchQuery := "%" + opts.Keyword + "%"
users = make([]*User, 0, opts.PageSize)
// Append conditions
sess := x.Where("LOWER(lower_name) LIKE ?", searchQuery).
Or("LOWER(full_name) LIKE ?", searchQuery).
And("type = ?", opts.Type)
var countSess xorm.Session
countSess = *sess
count, err := countSess.Count(new(User))
if err != nil {
return nil, 0, fmt.Errorf("Count: %v", err)
}
if len(opts.OrderBy) > 0 {
sess.OrderBy(opts.OrderBy)
}
return users, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&users)
}
// ___________ .__ .__

View File

@@ -94,8 +94,20 @@ type Webhook struct {
HookTaskType HookTaskType
Meta string `xorm:"TEXT"` // store hook-specific attributes
LastStatus HookStatus // Last delivery status
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
}
func (w *Webhook) BeforeInsert() {
w.CreatedUnix = time.Now().UTC().Unix()
w.UpdatedUnix = w.CreatedUnix
}
func (w *Webhook) BeforeUpdate() {
w.UpdatedUnix = time.Now().UTC().Unix()
}
func (w *Webhook) AfterSet(colName string, _ xorm.Cell) {
@@ -106,8 +118,10 @@ func (w *Webhook) AfterSet(colName string, _ xorm.Cell) {
if err = json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
log.Error(3, "Unmarshal[%d]: %v", w.ID, err)
}
case "created":
w.Created = regulateTimeZone(w.Created)
case "created_unix":
w.Created = time.Unix(w.CreatedUnix, 0).Local()
case "updated_unix":
w.Updated = time.Unix(w.UpdatedUnix, 0).Local()
}
}

View File

@@ -7,12 +7,12 @@ package models
import (
"fmt"
"io/ioutil"
"net/url"
"os"
"path"
"path/filepath"
"strings"
"sync"
"net/url"
"github.com/Unknwon/com"
@@ -116,6 +116,23 @@ func (repo *Repository) UpdateLocalWiki() error {
return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath())
}
// discardLocalWikiChanges discards local commits make sure
// it is even to remote branch when local copy exists.
func discardLocalWikiChanges(localPath string) error {
if !com.IsExist(localPath) {
return nil
}
// No need to check if nothing in the repository.
if !git.IsBranchExist(localPath, "master") {
return nil
}
if err := git.ResetHEAD(localPath, true, "origin/master"); err != nil {
return fmt.Errorf("ResetHEAD: %v", err)
}
return nil
}
// updateWikiPage adds new page to repository wiki.
func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
@@ -126,18 +143,9 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes
}
localPath := repo.LocalWikiPath()
// Discard local commits make sure even to remote when local copy exists.
if com.IsExist(localPath) {
// No need to check if nothing in the repository.
if git.IsBranchExist(localPath, "master") {
if err = git.ResetHEAD(localPath, true, "origin/master"); err != nil {
return fmt.Errorf("Reset: %v", err)
}
}
}
if err = repo.UpdateLocalWiki(); err != nil {
if err = discardLocalWikiChanges(localPath); err != nil {
return fmt.Errorf("discardLocalWikiChanges: %v", err)
} else if err = repo.UpdateLocalWiki(); err != nil {
return fmt.Errorf("UpdateLocalWiki: %v", err)
}
@@ -178,3 +186,31 @@ func (repo *Repository) AddWikiPage(doer *User, title, content, message string)
func (repo *Repository) EditWikiPage(doer *User, oldTitle, title, content, message string) error {
return repo.updateWikiPage(doer, oldTitle, title, content, message, false)
}
func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) {
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
localPath := repo.LocalWikiPath()
if err = discardLocalWikiChanges(localPath); err != nil {
return fmt.Errorf("discardLocalWikiChanges: %v", err)
} else if err = repo.UpdateLocalWiki(); err != nil {
return fmt.Errorf("UpdateLocalWiki: %v", err)
}
title = ToWikiPageName(strings.Replace(title, "/", " ", -1))
filename := path.Join(localPath, title+".md")
os.Remove(filename)
message := "Delete page '" + title + "'"
if err = git.AddChanges(localPath, true); err != nil {
return fmt.Errorf("AddChanges: %v", err)
} else if err = git.CommitChanges(localPath, message, doer.NewGitSig()); err != nil {
return fmt.Errorf("CommitChanges: %v", err)
} else if err = git.Push(localPath, "origin", "master"); err != nil {
return fmt.Errorf("Push: %v", err)
}
return nil
}

View File

@@ -97,6 +97,7 @@ func GetRandomString(n int, alphabets ...byte) string {
}
// http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto
// FIXME: use https://godoc.org/golang.org/x/crypto/pbkdf2?
func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
prf := hmac.New(h, password)
hashLen := prf.Size()
@@ -464,6 +465,15 @@ func EllipsisString(str string, length int) string {
return str[:length-3] + "..."
}
// TruncateString returns a truncated string with given limit,
// it returns input string if length is not reached limit.
func TruncateString(str string, limit int) string {
if len(str) < limit {
return str
}
return str[:limit]
}
// StringsToInt64s converts a slice of string to a slice of int64.
func StringsToInt64s(strs []string) []int64 {
ints := make([]int64, len(strs))

File diff suppressed because one or more lines are too long

71
modules/context/api.go Normal file
View File

@@ -0,0 +1,71 @@
// Copyright 2016 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 context
import (
"fmt"
"strings"
"github.com/Unknwon/paginater"
"gopkg.in/macaron.v1"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
type APIContext struct {
*Context
}
// Error responses error message to client with given message.
// If status is 500, also it prints error to log.
func (ctx *APIContext) Error(status int, title string, obj interface{}) {
var message string
if err, ok := obj.(error); ok {
message = err.Error()
} else {
message = obj.(string)
}
if status == 500 {
log.Error(4, "%s: %s", title, message)
}
ctx.JSON(status, map[string]string{
"message": message,
"url": base.DOC_URL,
})
}
func (ctx *APIContext) SetLinkHeader(total, pageSize int) {
page := paginater.New(total, pageSize, ctx.QueryInt("page"), 0)
links := make([]string, 0, 4)
if page.HasNext() {
links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"next\"", setting.AppUrl, ctx.Req.URL.Path[1:], page.Next()))
}
if !page.IsLast() {
links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"last\"", setting.AppUrl, ctx.Req.URL.Path[1:], page.TotalPages()))
}
if !page.IsFirst() {
links = append(links, fmt.Sprintf("<%s%s?page=1>; rel=\"first\"", setting.AppUrl, ctx.Req.URL.Path[1:]))
}
if page.HasPrevious() {
links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"prev\"", setting.AppUrl, ctx.Req.URL.Path[1:], page.Previous()))
}
if len(links) > 0 {
ctx.Header().Set("Link", strings.Join(links, ","))
}
}
func APIContexter() macaron.Handler {
return func(c *Context) {
ctx := &APIContext{
Context: c,
}
c.Map(ctx)
}
}

87
modules/context/auth.go Normal file
View File

@@ -0,0 +1,87 @@
// 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 context
import (
"net/url"
"github.com/go-macaron/csrf"
"gopkg.in/macaron.v1"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/setting"
)
type ToggleOptions struct {
SignInRequired bool
SignOutRequired bool
AdminRequired bool
DisableCSRF bool
}
func Toggle(options *ToggleOptions) macaron.Handler {
return func(ctx *Context) {
// Cannot view any page before installation.
if !setting.InstallLock {
ctx.Redirect(setting.AppSubUrl + "/install")
return
}
// Checking non-logged users landing page.
if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageUrl != setting.LANDING_PAGE_HOME {
ctx.Redirect(setting.AppSubUrl + string(setting.LandingPageUrl))
return
}
// Redirect to dashboard if user tries to visit any non-login page.
if options.SignOutRequired && ctx.IsSigned && ctx.Req.RequestURI != "/" {
ctx.Redirect(setting.AppSubUrl + "/")
return
}
if !options.SignOutRequired && !options.DisableCSRF && ctx.Req.Method == "POST" && !auth.IsAPIPath(ctx.Req.URL.Path) {
csrf.Validate(ctx.Context, ctx.csrf)
if ctx.Written() {
return
}
}
if options.SignInRequired {
if !ctx.IsSigned {
// Restrict API calls with error message.
if auth.IsAPIPath(ctx.Req.URL.Path) {
ctx.JSON(403, map[string]string{
"message": "Only signed in user is allowed to call APIs.",
})
return
}
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
} else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
ctx.HTML(200, "user/auth/activate")
return
}
}
// Redirect to log in page if auto-signin info is provided and has not signed in.
if !options.SignOutRequired && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) &&
len(ctx.GetCookie(setting.CookieUserName)) > 0 {
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
}
if options.AdminRequired {
if !ctx.User.IsAdmin {
ctx.Error(403)
return
}
ctx.Data["PageIsAdmin"] = true
}
}
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package middleware
package context
import (
"fmt"
@@ -18,8 +18,6 @@ import (
"github.com/go-macaron/session"
"gopkg.in/macaron.v1"
"github.com/gogits/git-module"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base"
@@ -27,27 +25,6 @@ import (
"github.com/gogits/gogs/modules/setting"
)
type RepoContext struct {
AccessMode models.AccessMode
IsWatching bool
IsViewBranch bool
IsViewTag bool
IsViewCommit bool
Repository *models.Repository
Owner *models.User
Commit *git.Commit
Tag *git.Tag
GitRepo *git.Repository
BranchName string
TagName string
TreeName string
CommitID string
RepoLink string
CloneLink models.CloneLink
CommitsCount int64
Mirror *models.Mirror
}
// Context represents context of a request.
type Context struct {
*macaron.Context
@@ -60,38 +37,8 @@ type Context struct {
IsSigned bool
IsBasicAuth bool
Repo *RepoContext
Org struct {
IsOwner bool
IsMember bool
IsTeamMember bool // Is member of team.
IsTeamAdmin bool // In owner team or team that has admin permission level.
Organization *models.User
OrgLink string
Team *models.Team
}
}
// IsOwner returns true if current user is the owner of repository.
func (r *RepoContext) IsOwner() bool {
return r.AccessMode >= models.ACCESS_MODE_OWNER
}
// IsAdmin returns true if current user has admin or higher access of repository.
func (r *RepoContext) IsAdmin() bool {
return r.AccessMode >= models.ACCESS_MODE_ADMIN
}
// IsPusher returns true if current user has write or higher access of repository.
func (r *RepoContext) IsPusher() bool {
return r.AccessMode >= models.ACCESS_MODE_WRITE
}
// Return if the current user has read access for this repository
func (r *RepoContext) HasAccess() bool {
return r.AccessMode >= models.ACCESS_MODE_READ
Repo *Repository
Org *Organization
}
// HasError returns true if error occurs in form validation.
@@ -165,25 +112,6 @@ func (ctx *Context) HandleText(status int, title string) {
ctx.PlainText(status, []byte(title))
}
// APIError logs error with title if status is 500.
func (ctx *Context) APIError(status int, title string, obj interface{}) {
var message string
if err, ok := obj.(error); ok {
message = err.Error()
} else {
message = obj.(string)
}
if status == 500 {
log.Error(4, "%s: %s", title, message)
}
ctx.JSON(status, map[string]string{
"message": message,
"url": base.DOC_URL,
})
}
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
modtime := time.Now()
for _, p := range params {
@@ -211,7 +139,10 @@ func Contexter() macaron.Handler {
csrf: x,
Flash: f,
Session: sess,
Repo: &RepoContext{},
Repo: &Repository{
PullRequest: &PullRequest{},
},
Org: &Organization{},
}
// Compute current URL for real-time change language.
ctx.Data["Link"] = setting.AppSubUrl + strings.TrimSuffix(ctx.Req.URL.Path, "/")

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package middleware
package context
import (
"strings"
@@ -13,6 +13,17 @@ import (
"github.com/gogits/gogs/modules/setting"
)
type Organization struct {
IsOwner bool
IsMember bool
IsTeamMember bool // Is member of team.
IsTeamAdmin bool // In owner team or team that has admin permission level.
Organization *models.User
OrgLink string
Team *models.Team
}
func HandleOrgAssignment(ctx *Context, args ...bool) {
var (
requireMember bool
@@ -90,7 +101,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
if ctx.Org.IsMember {
if ctx.Org.IsOwner {
if err := org.GetTeams(); err != nil {
ctx.Handle(500, "GetUserTeams", err)
ctx.Handle(500, "GetTeams", err)
return
}
} else {

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package middleware
package context
import (
"fmt"
@@ -18,6 +18,56 @@ import (
"github.com/gogits/gogs/modules/setting"
)
type PullRequest struct {
BaseRepo *models.Repository
Allowed bool
SameRepo bool
HeadInfo string // [<user>:]<branch>
}
type Repository struct {
AccessMode models.AccessMode
IsWatching bool
IsViewBranch bool
IsViewTag bool
IsViewCommit bool
Repository *models.Repository
Owner *models.User
Commit *git.Commit
Tag *git.Tag
GitRepo *git.Repository
BranchName string
TagName string
TreeName string
CommitID string
RepoLink string
CloneLink models.CloneLink
CommitsCount int64
Mirror *models.Mirror
PullRequest *PullRequest
}
// IsOwner returns true if current user is the owner of repository.
func (r *Repository) IsOwner() bool {
return r.AccessMode >= models.ACCESS_MODE_OWNER
}
// IsAdmin returns true if current user has admin or higher access of repository.
func (r *Repository) IsAdmin() bool {
return r.AccessMode >= models.ACCESS_MODE_ADMIN
}
// IsWriter returns true if current user has write or higher access of repository.
func (r *Repository) IsWriter() bool {
return r.AccessMode >= models.ACCESS_MODE_WRITE
}
// HasAccess returns true if the current user has at least read access for this repository
func (r *Repository) HasAccess() bool {
return r.AccessMode >= models.ACCESS_MODE_READ
}
func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
// Non-fork repository will not return error in this method.
if err := repo.GetBaseRepo(); err != nil {
@@ -32,25 +82,6 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
ctx.Handle(500, "BaseRepo.GetOwner", err)
return
}
bsaeRepo := repo.BaseRepo
baseGitRepo, err := git.OpenRepository(models.RepoPath(bsaeRepo.Owner.Name, bsaeRepo.Name))
if err != nil {
ctx.Handle(500, "OpenRepository", err)
return
}
if len(bsaeRepo.DefaultBranch) > 0 && baseGitRepo.IsBranchExist(bsaeRepo.DefaultBranch) {
ctx.Data["BaseDefaultBranch"] = bsaeRepo.DefaultBranch
} else {
baseBranches, err := baseGitRepo.GetBranches()
if err != nil {
ctx.Handle(500, "GetBranches", err)
return
}
if len(baseBranches) > 0 {
ctx.Data["BaseDefaultBranch"] = baseBranches[0]
}
}
}
func RepoAssignment(args ...bool) macaron.Handler {
@@ -154,22 +185,14 @@ func RepoAssignment(args ...bool) macaron.Handler {
ctx.Data["Tags"] = tags
ctx.Repo.Repository.NumTags = len(tags)
if repo.IsFork {
RetrieveBaseRepo(ctx, repo)
if ctx.Written() {
return
}
}
ctx.Data["Title"] = owner.Name + "/" + repo.Name
ctx.Data["Repository"] = repo
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher()
ctx.Data["CanPullRequest"] = ctx.Repo.IsAdmin() && repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls()
ctx.Data["IsRepositoryWriter"] = ctx.Repo.IsWriter()
ctx.Data["DisableSSH"] = setting.DisableSSH
ctx.Data["DisableSSH"] = setting.SSH.Disabled
ctx.Data["CloneLink"] = repo.CloneLink()
ctx.Data["WikiCloneLink"] = repo.WikiCloneLink()
@@ -210,10 +233,40 @@ func RepoAssignment(args ...bool) macaron.Handler {
ctx.Repo.BranchName = brs[0]
}
}
ctx.Data["BranchName"] = ctx.Repo.BranchName
ctx.Data["CommitID"] = ctx.Repo.CommitID
if repo.IsFork {
RetrieveBaseRepo(ctx, repo)
if ctx.Written() {
return
}
}
// People who have push access and propose a new pull request.
if ctx.Repo.IsWriter() {
// Pull request is allowed if this is a fork repository
// and base repository accepts pull requests.
if repo.BaseRepo != nil {
if repo.BaseRepo.AllowsPulls() {
ctx.Data["BaseRepo"] = repo.BaseRepo
ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo
ctx.Repo.PullRequest.Allowed = true
ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName
}
} else {
// Or, this is repository accepts pull requests between branches.
if repo.AllowsPulls() {
ctx.Data["BaseRepo"] = repo
ctx.Repo.PullRequest.BaseRepo = repo
ctx.Repo.PullRequest.Allowed = true
ctx.Repo.PullRequest.SameRepo = true
ctx.Repo.PullRequest.HeadInfo = ctx.Repo.BranchName
}
}
}
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
if ctx.Query("go-get") == "1" {
ctx.Data["GoGetImport"] = path.Join(setting.Domain, setting.AppSubUrl, owner.Name, repo.Name)
prefix := setting.AppUrl + path.Join(owner.Name, repo.Name, "src", ctx.Repo.BranchName)
@@ -337,16 +390,16 @@ func RepoRef() macaron.Handler {
func RequireRepoAdmin() macaron.Handler {
return func(ctx *Context) {
if !ctx.Repo.IsAdmin() {
if !ctx.IsSigned || (!ctx.Repo.IsAdmin() && !ctx.User.IsAdmin) {
ctx.Handle(404, ctx.Req.RequestURI, nil)
return
}
}
}
func RequireRepoPusher() macaron.Handler {
func RequireRepoWriter() macaron.Handler {
return func(ctx *Context) {
if !ctx.Repo.IsPusher() {
if !ctx.IsSigned || (!ctx.Repo.IsWriter() && !ctx.User.IsAdmin) {
ctx.Handle(404, ctx.Req.RequestURI, nil)
return
}

View File

@@ -1,68 +0,0 @@
// 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 log
import (
"encoding/json"
"github.com/go-xorm/xorm"
)
type Log struct {
Id int64
Level int
Msg string `xorm:"TEXT"`
}
// DatabaseWriter implements LoggerInterface and is used to log into database.
type DatabaseWriter struct {
Driver string `json:"driver"`
Conn string `json:"conn"`
Level int `json:"level"`
x *xorm.Engine
}
func NewDatabase() LoggerInterface {
return &DatabaseWriter{Level: TRACE}
}
// init database writer with json config.
// config like:
// {
// "driver": "mysql"
// "conn":"root:root@tcp(127.0.0.1:3306)/gogs?charset=utf8",
// "level": 0
// }
// connection string is based on xorm.
func (d *DatabaseWriter) Init(jsonconfig string) (err error) {
if err = json.Unmarshal([]byte(jsonconfig), d); err != nil {
return err
}
d.x, err = xorm.NewEngine(d.Driver, d.Conn)
if err != nil {
return err
}
return d.x.Sync(new(Log))
}
// write message in database writer.
func (d *DatabaseWriter) WriteMsg(msg string, skip, level int) error {
if level < d.Level {
return nil
}
_, err := d.x.Insert(&Log{Level: level, Msg: msg})
return err
}
func (_ *DatabaseWriter) Flush() {
}
func (_ *DatabaseWriter) Destroy() {
}
func init() {
Register("database", NewDatabase)
}

View File

@@ -9,6 +9,7 @@ import (
"path"
"strings"
"gopkg.in/gomail.v2"
"gopkg.in/macaron.v1"
"github.com/gogits/gogs/models"
@@ -183,3 +184,7 @@ func SendCollaboratorMail(r macaron.Render, u, doer *models.User, repo *models.R
SendAsync(msg)
return nil
}
func SendTestMail(email string) error {
return gomail.Send(&Sender{}, NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
}

View File

@@ -159,6 +159,8 @@ var (
svgSuffixWithMark = []byte(".svg?")
spaceBytes = []byte(" ")
spaceEncodedBytes = []byte("%20")
space = " "
spaceEncoded = "%20"
)
// Image defines how images should be processed to produce corresponding HTML elements.
@@ -357,6 +359,7 @@ OUTER_LOOP:
// Render renders Markdown to HTML with special links.
func Render(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
urlPrefix = strings.Replace(urlPrefix, space, spaceEncoded, -1)
result := RenderRaw(rawBytes, urlPrefix)
result = PostProcess(result, urlPrefix, metas)
result = Sanitizer.SanitizeBytes(result)

View File

@@ -1,133 +0,0 @@
// 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 middleware
import (
"fmt"
"net/url"
"github.com/go-macaron/csrf"
"gopkg.in/macaron.v1"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
type ToggleOptions struct {
SignInRequire bool
SignOutRequire bool
AdminRequire bool
DisableCsrf bool
}
// AutoSignIn reads cookie and try to auto-login.
func AutoSignIn(ctx *Context) (bool, error) {
if !models.HasEngine {
return false, nil
}
uname := ctx.GetCookie(setting.CookieUserName)
if len(uname) == 0 {
return false, nil
}
isSucceed := false
defer func() {
if !isSucceed {
log.Trace("auto-login cookie cleared: %s", uname)
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl)
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl)
}
}()
u, err := models.GetUserByName(uname)
if err != nil {
if !models.IsErrUserNotExist(err) {
return false, fmt.Errorf("GetUserByName: %v", err)
}
return false, nil
}
if val, _ := ctx.GetSuperSecureCookie(
base.EncodeMD5(u.Rands+u.Passwd), setting.CookieRememberName); val != u.Name {
return false, nil
}
isSucceed = true
ctx.Session.Set("uid", u.Id)
ctx.Session.Set("uname", u.Name)
return true, nil
}
func Toggle(options *ToggleOptions) macaron.Handler {
return func(ctx *Context) {
// Cannot view any page before installation.
if !setting.InstallLock {
ctx.Redirect(setting.AppSubUrl + "/install")
return
}
// Checking non-logged users landing page.
if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageUrl != setting.LANDING_PAGE_HOME {
ctx.Redirect(setting.AppSubUrl + string(setting.LandingPageUrl))
return
}
// Redirect to dashboard if user tries to visit any non-login page.
if options.SignOutRequire && ctx.IsSigned && ctx.Req.RequestURI != "/" {
ctx.Redirect(setting.AppSubUrl + "/")
return
}
if !options.SignOutRequire && !options.DisableCsrf && ctx.Req.Method == "POST" && !auth.IsAPIPath(ctx.Req.URL.Path) {
csrf.Validate(ctx.Context, ctx.csrf)
if ctx.Written() {
return
}
}
if options.SignInRequire {
if !ctx.IsSigned {
// Restrict API calls with error message.
if auth.IsAPIPath(ctx.Req.URL.Path) {
ctx.APIError(403, "", "Only signed in user is allowed to call APIs.")
return
}
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
} else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
ctx.HTML(200, "user/auth/activate")
return
}
}
// Try auto-signin when not signed in.
if !options.SignOutRequire && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) {
succeed, err := AutoSignIn(ctx)
if err != nil {
ctx.Handle(500, "AutoSignIn", err)
return
} else if succeed {
log.Trace("Auto-login succeed: %s", ctx.Session.Get("uname"))
ctx.Redirect(setting.AppSubUrl + ctx.Req.RequestURI)
return
}
}
if options.AdminRequire {
if !ctx.User.IsAdmin {
ctx.Error(403)
return
}
ctx.Data["PageIsAdmin"] = true
}
}
}

View File

@@ -54,18 +54,13 @@ var (
AppSubUrl string
AppSubUrlDepth int // Number of slashes
AppPath string
AppDataPath = "data"
AppDataPath string
// Server settings
Protocol Scheme
Domain string
HttpAddr, HttpPort string
LocalURL string
DisableSSH bool
StartSSHServer bool
SSHDomain string
SSHPort int
SSHRootPath string
OfflineMode bool
DisableRouterLog bool
CertFile, KeyFile string
@@ -73,6 +68,19 @@ var (
EnableGzip bool
LandingPageUrl LandingPage
SSH struct {
Disabled bool `ini:"DISABLE_SSH"`
StartBuiltinServer bool `ini:"START_SSH_SERVER"`
Domain string `ini:"SSH_DOMAIN"`
Port int `ini:"SSH_PORT"`
ListenPort int `ini:"SSH_LISTEN_PORT"`
RootPath string `ini:"SSH_ROOT_PATH"`
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
MinimumKeySizeCheck bool `ini:"-"`
MinimumKeySizes map[string]int `ini:"-"`
}
// Security settings
InstallLock bool
SecretKey string
@@ -123,7 +131,6 @@ var (
}
// Picture settings
PictureService string
AvatarUploadPath string
GravatarSource string
DisableGravatar bool
@@ -149,12 +156,19 @@ var (
CacheConn string
// Session settings
SessionConfig session.Options
SessionConfig session.Options
CSRFCookieName = "_csrf"
// Git settings
Git struct {
MaxGitDiffLines int
GcArgs []string `delim:" "`
Timeout struct {
Migrate int
Mirror int
Clone int
Pull int
} `ini:"git.timeout"`
}
// Cron tasks
@@ -318,19 +332,10 @@ func NewContext() {
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HttpPort = sec.Key("HTTP_PORT").MustString("3000")
LocalURL = sec.Key("LOCAL_ROOT_URL").MustString("http://localhost:" + HttpPort + "/")
DisableSSH = sec.Key("DISABLE_SSH").MustBool()
if !DisableSSH {
StartSSHServer = sec.Key("START_SSH_SERVER").MustBool()
}
SSHDomain = sec.Key("SSH_DOMAIN").MustString(Domain)
SSHPort = sec.Key("SSH_PORT").MustInt(22)
SSHRootPath = sec.Key("SSH_ROOT_PATH").MustString(path.Join(homeDir, ".ssh"))
if err := os.MkdirAll(SSHRootPath, 0700); err != nil {
log.Fatal(4, "Fail to create '%s': %v", SSHRootPath, err)
}
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)
AppDataPath = sec.Key("APP_DATA_PATH").MustString("data")
EnableGzip = sec.Key("ENABLE_GZIP").MustBool()
switch sec.Key("LANDING_PAGE").MustString("home") {
@@ -340,6 +345,39 @@ func NewContext() {
LandingPageUrl = LANDING_PAGE_HOME
}
SSH.RootPath = path.Join(homeDir, ".ssh")
SSH.KeyTestPath = os.TempDir()
if err = Cfg.Section("server").MapTo(&SSH); err != nil {
log.Fatal(4, "Fail to map SSH settings: %v", err)
}
// When disable SSH, start builtin server value is ignored.
if SSH.Disabled {
SSH.StartBuiltinServer = false
}
if !SSH.Disabled && !SSH.StartBuiltinServer {
if err := os.MkdirAll(SSH.RootPath, 0700); err != nil {
log.Fatal(4, "Fail to create '%s': %v", SSH.RootPath, err)
} else if err = os.MkdirAll(SSH.KeyTestPath, 0644); err != nil {
log.Fatal(4, "Fail to create '%s': %v", SSH.KeyTestPath, err)
}
if !filepath.IsAbs(SSH.KeygenPath) {
if _, err := exec.LookPath(SSH.KeygenPath); err != nil {
log.Fatal(4, "Fail to test '%s' command: %v (forgotten install?)", SSH.KeygenPath, err)
}
}
}
SSH.MinimumKeySizeCheck = sec.Key("MINIMUM_KEY_SIZE_CHECK").MustBool()
SSH.MinimumKeySizes = map[string]int{}
minimumKeySizes := Cfg.Section("ssh.minimum_key_sizes").Keys()
for _, key := range minimumKeySizes {
if key.MustInt() != -1 {
SSH.MinimumKeySizes[strings.ToLower(key.Name())] = key.MustInt()
}
}
sec = Cfg.Section("security")
InstallLock = sec.Key("INSTALL_LOCK").MustBool()
SecretKey = sec.Key("SECRET_KEY").String()
@@ -411,7 +449,6 @@ func NewContext() {
ThemeColorMetaTag = sec.Key("THEME_COLOR_META_TAG").MustString("#ff5343")
sec = Cfg.Section("picture")
PictureService = sec.Key("SERVICE").In("server", []string{"server"})
AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString(path.Join(AppDataPath, "avatars"))
forcePathSeparator(AvatarUploadPath)
if !filepath.IsAbs(AvatarUploadPath) {

View File

@@ -62,12 +62,12 @@ func handleServerConn(keyID string, chans <-chan ssh.NewChannel) {
}
case "exec":
cmdName := strings.TrimLeft(payload, "'()")
os.Setenv("SSH_ORIGINAL_COMMAND", cmdName)
log.Trace("SSH: Payload: %v", cmdName)
args := []string{"serv", "key-" + keyID, "--config=" + setting.CustomConf}
log.Trace("SSH: Arguments: %v", args)
cmd := exec.Command(setting.AppPath, args...)
cmd.Env = append(os.Environ(), "SSH_ORIGINAL_COMMAND="+cmdName)
stdout, err := cmd.StdoutPipe()
if err != nil {

View File

@@ -22,86 +22,88 @@ import (
"github.com/gogits/gogs/modules/setting"
)
var Funcs template.FuncMap = map[string]interface{}{
"GoVer": func() string {
return strings.Title(runtime.Version())
},
"UseHTTPS": func() bool {
return strings.HasPrefix(setting.AppUrl, "https")
},
"AppName": func() string {
return setting.AppName
},
"AppSubUrl": func() string {
return setting.AppSubUrl
},
"AppUrl": func() string {
return setting.AppUrl
},
"AppVer": func() string {
return setting.AppVer
},
"AppDomain": func() string {
return setting.Domain
},
"DisableGravatar": func() bool {
return setting.DisableGravatar
},
"LoadTimes": func(startTime time.Time) string {
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
},
"AvatarLink": base.AvatarLink,
"Safe": Safe,
"Str2html": Str2html,
"TimeSince": base.TimeSince,
"RawTimeSince": base.RawTimeSince,
"FileSize": base.FileSize,
"Subtract": base.Subtract,
"Add": func(a, b int) int {
return a + b
},
"ActionIcon": ActionIcon,
"DateFmtLong": func(t time.Time) string {
return t.Format(time.RFC1123Z)
},
"DateFmtShort": func(t time.Time) string {
return t.Format("Jan 02, 2006")
},
"List": List,
"Mail2Domain": func(mail string) string {
if !strings.Contains(mail, "@") {
return "try.gogs.io"
}
func NewFuncMap() []template.FuncMap {
return []template.FuncMap{map[string]interface{}{
"GoVer": func() string {
return strings.Title(runtime.Version())
},
"UseHTTPS": func() bool {
return strings.HasPrefix(setting.AppUrl, "https")
},
"AppName": func() string {
return setting.AppName
},
"AppSubUrl": func() string {
return setting.AppSubUrl
},
"AppUrl": func() string {
return setting.AppUrl
},
"AppVer": func() string {
return setting.AppVer
},
"AppDomain": func() string {
return setting.Domain
},
"DisableGravatar": func() bool {
return setting.DisableGravatar
},
"LoadTimes": func(startTime time.Time) string {
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
},
"AvatarLink": base.AvatarLink,
"Safe": Safe,
"Str2html": Str2html,
"TimeSince": base.TimeSince,
"RawTimeSince": base.RawTimeSince,
"FileSize": base.FileSize,
"Subtract": base.Subtract,
"Add": func(a, b int) int {
return a + b
},
"ActionIcon": ActionIcon,
"DateFmtLong": func(t time.Time) string {
return t.Format(time.RFC1123Z)
},
"DateFmtShort": func(t time.Time) string {
return t.Format("Jan 02, 2006")
},
"List": List,
"Mail2Domain": func(mail string) string {
if !strings.Contains(mail, "@") {
return "try.gogs.io"
}
return strings.SplitN(mail, "@", 2)[1]
},
"SubStr": func(str string, start, length int) string {
if len(str) == 0 {
return ""
}
end := start + length
if length == -1 {
end = len(str)
}
if len(str) < end {
return str
}
return str[start:end]
},
"DiffTypeToStr": DiffTypeToStr,
"DiffLineTypeToStr": DiffLineTypeToStr,
"Sha1": Sha1,
"ShortSha": base.ShortSha,
"MD5": base.EncodeMD5,
"ActionContent2Commits": ActionContent2Commits,
"ToUtf8": ToUtf8,
"EscapePound": func(str string) string {
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
},
"RenderCommitMessage": RenderCommitMessage,
"ThemeColorMetaTag": func() string {
return setting.ThemeColorMetaTag
},
return strings.SplitN(mail, "@", 2)[1]
},
"SubStr": func(str string, start, length int) string {
if len(str) == 0 {
return ""
}
end := start + length
if length == -1 {
end = len(str)
}
if len(str) < end {
return str
}
return str[start:end]
},
"DiffTypeToStr": DiffTypeToStr,
"DiffLineTypeToStr": DiffLineTypeToStr,
"Sha1": Sha1,
"ShortSha": base.ShortSha,
"MD5": base.EncodeMD5,
"ActionContent2Commits": ActionContent2Commits,
"ToUtf8": ToUtf8,
"EscapePound": func(str string) string {
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
},
"RenderCommitMessage": RenderCommitMessage,
"ThemeColorMetaTag": func() string {
return setting.ThemeColorMetaTag
},
}}
}
func Safe(raw string) template.HTML {
@@ -233,7 +235,7 @@ func ActionIcon(opType int) string {
return "repo"
case 5, 9: // Commit repository
return "git-commit"
case 6, 13: // Create and reopen issue
case 6: // Create issue
return "issue-opened"
case 7: // New pull request
return "git-pull-request"
@@ -241,8 +243,10 @@ func ActionIcon(opType int) string {
return "comment"
case 11: // Merge pull request
return "git-merge"
case 12: // Close issue
case 12, 14: // Close issue or pull request
return "issue-closed"
case 13, 15: // Reopen issue or pull request
return "issue-reopened"
default:
return "invalid type"
}

View File

@@ -217,6 +217,7 @@
.octicon-triangle-up:before { content: '\f0aa'} /*  */
.octicon-unfold:before { content: '\f039'} /*  */
.octicon-unmute:before { content: '\f0ba'} /*  */
.octicon-unverified:before { content: '\f0e8'} /*  */
.octicon-verified:before { content: '\f0e6'} /*  */
.octicon-versions:before { content: '\f064'} /*  */
.octicon-watch:before { content: '\f0e0'} /*  */

View File

@@ -177,7 +177,8 @@ Applies to all other files
<glyph glyph-name="triangle-up" unicode="&#xf0aa;" d="M768 128L384 512 0 128h768z" horiz-adv-x="768" />
<glyph glyph-name="unfold" unicode="&#xf039;" d="M736 288l160-160c0-35-29-64-64-64H576v64h224L672 256H224L96 128h224v-64H64c-35 0-64 29-64 64l160 160L0 448c0 35 29 64 64 64h256v-64H96l128-128h448l128 128H576v64h256c35 0 64-29 64-64L736 288z m-352 96h128V576h128L448 768 256 576h128v-192z m128-192H384v-192H256l192-192 192 192H512V192z" horiz-adv-x="896" />
<glyph glyph-name="unmute" unicode="&#xf0ba;" d="M704 319c0-70-29-134-75-181l-43 43c35 36 57 84 57 138s-22 103-57 138l43 43c46-46 75-110 75-181zM430 686L192 448H64c-35 0-64-29-64-64v-128c0-35 29-64 64-64h128l238-238c30-30 82-9 82 34V652c0 43-52 64-82 34z m380-5l-43-43c82-82 132-194 132-319 0-124-50-237-132-319l43-43c93 93 150 221 150 362 0 142-57 270-150 362z m-90-90l-44-43c59-59 95-140 95-229s-36-170-95-228l44-43c69 69 112 165 112 271s-43 202-112 272z" horiz-adv-x="1024" />
<glyph glyph-name="verified" unicode="&#xf0e6;" d="M1002 361l-84 64c-30 22-50 71-45 108l14 104c5 37-21 63-58 58l-104-14c-37-5-86 15-108 45l-64 84c-23 29-59 29-82 0l-64-84c-22-30-71-50-108-45l-104 14c-37 5-63-21-58-58l14-104c5-37-15-86-45-108l-84-64c-29-23-29-59 0-82l84-64c30-22 50-71 45-108l-14-104c-5-37 21-63 58-58l104 14c37 5 86-15 108-45l64-84c23-29 59-29 82 0l64 84c22 30 71 50 108 45l104-14c37-5 63 21 58 58l-14 104c-5 37 15 86 45 108l84 64c29 23 29 59 0 82z m-234-9c0-53-43-96-96-96H512v-64l-64 32v-96l-64 32v-96H256V192l192 192v96c0 53 43 96 96 96h160c35 0 64-29 64-64v-160z m-64 92v-28c0-18-14-32-32-32h-64c-18 0-32 14-32 32v64c0 18 14 32 32 32h28c37 0 68-31 68-68z" horiz-adv-x="1024" />
<glyph glyph-name="unverified" unicode="&#xf0e8;" d="M1003 380l-69 86c-11 14-18 31-20 49l-12 109c-5 45-40 80-85 85l-109 12c-19 2-36 10-50 21l-86 69c-35 28-85 28-120 0l-86-69c-14-11-31-18-49-20l-109-12c-45-5-80-40-85-85l-12-109c-2-19-10-36-21-50l-69-86c-28-35-28-85 0-120l69-86c11-14 18-31 20-49l12-109c5-45 40-80 85-85l109-12c19-2 36-10 50-21l86-69c35-28 85-28 120 0l86 69c14 11 31 18 49 20l109 12c45 5 80 40 85 85l12 109c2 19 10 36 21 50l69 86c28 35 28 85 0 120zM576 96c0-18-14-32-32-32h-64c-17 0-32 14-32 32v64c0 18 15 32 32 32h64c18 0 32-14 32-32v-64z m100 313c-4-11-11-21-19-30-8-10-9-12-21-24-10-11-20-19-33-29-7-6-13-12-18-17s-9-11-12-17-5-12-7-19-2-8-2-16H456c0 14 0 20 2 31 2 12 5 23 9 33 4 9 9 18 16 27 7 8 15 16 26 24 17 12 23 19 31 33s13 24 13 38c0 17-4 29-13 37-8 8-20 12-37 12-6 0-12-1-19-3s-11-6-16-10-9-7-13-13-6-9-6-18H321c0 24 8 36 17 53 10 17 23 32 39 43s35 19 56 24 45 8 70 8c28 0 53-3 75-8 22-6 40-14 56-25 15-11 26-24 35-40 8-16 12-35 12-56 0-14 0-27-5-38z" horiz-adv-x="1024" />
<glyph glyph-name="verified" unicode="&#xf0e6;" d="M1003 380l-69 86c-11 14-18 31-20 49l-12 109c-5 45-40 80-85 85l-109 12c-19 2-36 10-50 21l-86 69c-35 28-85 28-120 0l-86-69c-14-11-31-18-49-20l-109-12c-45-5-80-40-85-85l-12-109c-2-19-10-36-21-50l-69-86c-28-35-28-85 0-120l69-86c11-14 18-31 20-49l12-109c5-45 40-80 85-85l109-12c19-2 36-10 50-21l86-69c35-28 85-28 120 0l86 69c14 11 31 18 49 20l109 12c45 5 80 40 85 85l12 109c2 19 10 36 21 50l69 86c28 35 28 85 0 120zM416 64L192 288l96 96 128-128 320 320 96-99-416-413z" horiz-adv-x="1024" />
<glyph glyph-name="versions" unicode="&#xf064;" d="M832 640H448c-35 0-64-29-64-64v-512c0-35 29-64 64-64h384c35 0 64 29 64 64V576c0 35-29 64-64 64z m-64-512H512V512h256v-384zM256 576h64v-64h-64v-384h64v-64h-64c-35 0-64 29-64 64V512c0 35 29 64 64 64zM64 512h64v-64H64v-256h64v-64H64c-35 0-64 29-64 64V448c0 35 29 64 64 64z" horiz-adv-x="896" />
<glyph glyph-name="watch" unicode="&#xf0e0;" d="M384 320h128v-64H320V512h64v-192z m384 0c0-142-77-266-192-332v-116c0-35-29-64-64-64H256c-35 0-64 29-64 64V-12C77 54 0 178 0 320s77 266 192 332V768c0 35 29 64 64 64h256c35 0 64-29 64-64v-116c115-66 192-190 192-332z m-64 0c0 177-143 320-320 320S64 497 64 320s143-320 320-320 320 143 320 320z" horiz-adv-x="768" />
<glyph glyph-name="x" unicode="&#xf081;" d="M479 320l240-240-95-95-240 240-240-240-95 95 240 240L49 560l95 95 240-240 240 240 95-95-240-240z" horiz-adv-x="768" />

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

View File

@@ -20,15 +20,6 @@
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0
},
"\/css\/gogs.min.css": {
"fileType": 16,
"ignore": 1,
"ignoreWasSetByUser": 0,
"inputAbbreviatedPath": "\/css\/gogs.min.css",
"outputAbbreviatedPath": "No Output Path",
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0
},
"\/css\/semantic-2.1.8.min.css": {
"fileType": 16,
"ignore": 0,
@@ -450,30 +441,30 @@
"outputStyle": 1,
"syntaxCheckerStyle": 1
},
"\/plugins\/highlight-9.1.0\/default.css": {
"\/plugins\/highlight-9.2.0\/default.css": {
"fileType": 16,
"ignore": 0,
"ignoreWasSetByUser": 0,
"inputAbbreviatedPath": "\/plugins\/highlight-9.1.0\/default.css",
"inputAbbreviatedPath": "\/plugins\/highlight-9.2.0\/default.css",
"outputAbbreviatedPath": "No Output Path",
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0
},
"\/plugins\/highlight-9.1.0\/github.css": {
"\/plugins\/highlight-9.2.0\/github.css": {
"fileType": 16,
"ignore": 0,
"ignoreWasSetByUser": 0,
"inputAbbreviatedPath": "\/plugins\/highlight-9.1.0\/github.css",
"inputAbbreviatedPath": "\/plugins\/highlight-9.2.0\/github.css",
"outputAbbreviatedPath": "No Output Path",
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0
},
"\/plugins\/highlight-9.1.0\/highlight.pack.js": {
"\/plugins\/highlight-9.2.0\/highlight.pack.js": {
"fileType": 64,
"ignore": 0,
"ignoreWasSetByUser": 0,
"inputAbbreviatedPath": "\/plugins\/highlight-9.1.0\/highlight.pack.js",
"outputAbbreviatedPath": "\/plugins\/highlight-9.1.0\/min\/highlight.pack-min.js",
"inputAbbreviatedPath": "\/plugins\/highlight-9.2.0\/highlight.pack.js",
"outputAbbreviatedPath": "\/plugins\/highlight-9.2.0\/min\/highlight.pack-min.js",
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0,
"outputStyle": 1,

View File

@@ -5,7 +5,7 @@
background-size: contain;
}
body {
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif, '微软雅黑';
font-family: "Helvetica Neue", "Meiryo Ui", "Microsoft YaHei", Arial, Helvetica, sans-serif !important;
background-color: #fff;
overflow-y: scroll;
}
@@ -104,6 +104,9 @@ code.wrap {
.ui.container.fluid.padded {
padding: 0 10px 0 10px;
}
.ui.form .ui.button {
font-weight: normal;
}
.ui .text.red {
color: #d95c5c !important;
}
@@ -234,6 +237,10 @@ code.wrap {
.ui.status.buttons .octicon {
margin-right: 4px;
}
.ui.inline.delete-button {
padding: 8px 15px;
font-weight: normal;
}
.overflow.menu .items {
max-height: 300px;
overflow-y: auto;
@@ -395,30 +402,30 @@ footer .container .links > *:first-child {
background: inherit !important;
padding: 0 !important;
}
.markdown {
.markdown:not(code) {
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px;
line-height: 1.6 !important;
word-wrap: break-word;
}
.markdown.file-view {
.markdown:not(code).file-view {
padding: 2em 2em 2em !important;
}
.markdown > *:first-child {
.markdown:not(code) > *:first-child {
margin-top: 0 !important;
}
.markdown > *:last-child {
.markdown:not(code) > *:last-child {
margin-bottom: 0 !important;
}
.markdown a:not([href]) {
.markdown:not(code) a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown .absent {
.markdown:not(code) .absent {
color: #c00;
}
.markdown .anchor {
.markdown:not(code) .anchor {
position: absolute;
top: 0;
left: 0;
@@ -427,217 +434,217 @@ footer .container .links > *:first-child {
padding-left: 30px;
margin-left: -30px;
}
.markdown .anchor:focus {
.markdown:not(code) .anchor:focus {
outline: none;
}
.markdown h1,
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
.markdown:not(code) h1,
.markdown:not(code) h2,
.markdown:not(code) h3,
.markdown:not(code) h4,
.markdown:not(code) h5,
.markdown:not(code) h6 {
position: relative;
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
line-height: 1.4;
}
.markdown h1:first-of-type,
.markdown h2:first-of-type,
.markdown h3:first-of-type,
.markdown h4:first-of-type,
.markdown h5:first-of-type,
.markdown h6:first-of-type {
.markdown:not(code) h1:first-of-type,
.markdown:not(code) h2:first-of-type,
.markdown:not(code) h3:first-of-type,
.markdown:not(code) h4:first-of-type,
.markdown:not(code) h5:first-of-type,
.markdown:not(code) h6:first-of-type {
margin-top: 0 !important;
}
.markdown h1 .octicon-link,
.markdown h2 .octicon-link,
.markdown h3 .octicon-link,
.markdown h4 .octicon-link,
.markdown h5 .octicon-link,
.markdown h6 .octicon-link {
.markdown:not(code) h1 .octicon-link,
.markdown:not(code) h2 .octicon-link,
.markdown:not(code) h3 .octicon-link,
.markdown:not(code) h4 .octicon-link,
.markdown:not(code) h5 .octicon-link,
.markdown:not(code) h6 .octicon-link {
display: none;
color: #000;
vertical-align: middle;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
.markdown:not(code) h1:hover .anchor,
.markdown:not(code) h2:hover .anchor,
.markdown:not(code) h3:hover .anchor,
.markdown:not(code) h4:hover .anchor,
.markdown:not(code) h5:hover .anchor,
.markdown:not(code) h6:hover .anchor {
padding-left: 8px;
margin-left: -30px;
text-decoration: none;
}
.markdown h1:hover .anchor .octicon-link,
.markdown h2:hover .anchor .octicon-link,
.markdown h3:hover .anchor .octicon-link,
.markdown h4:hover .anchor .octicon-link,
.markdown h5:hover .anchor .octicon-link,
.markdown h6:hover .anchor .octicon-link {
.markdown:not(code) h1:hover .anchor .octicon-link,
.markdown:not(code) h2:hover .anchor .octicon-link,
.markdown:not(code) h3:hover .anchor .octicon-link,
.markdown:not(code) h4:hover .anchor .octicon-link,
.markdown:not(code) h5:hover .anchor .octicon-link,
.markdown:not(code) h6:hover .anchor .octicon-link {
display: inline-block;
}
.markdown h1 tt,
.markdown h1 code,
.markdown h2 tt,
.markdown h2 code,
.markdown h3 tt,
.markdown h3 code,
.markdown h4 tt,
.markdown h4 code,
.markdown h5 tt,
.markdown h5 code,
.markdown h6 tt,
.markdown h6 code {
.markdown:not(code) h1 tt,
.markdown:not(code) h1 code,
.markdown:not(code) h2 tt,
.markdown:not(code) h2 code,
.markdown:not(code) h3 tt,
.markdown:not(code) h3 code,
.markdown:not(code) h4 tt,
.markdown:not(code) h4 code,
.markdown:not(code) h5 tt,
.markdown:not(code) h5 code,
.markdown:not(code) h6 tt,
.markdown:not(code) h6 code {
font-size: inherit;
}
.markdown h1 {
.markdown:not(code) h1 {
padding-bottom: 0.3em;
font-size: 2.25em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
.markdown h1 .anchor {
.markdown:not(code) h1 .anchor {
line-height: 1;
}
.markdown h2 {
.markdown:not(code) h2 {
padding-bottom: 0.3em;
font-size: 1.75em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
.markdown h2 .anchor {
.markdown:not(code) h2 .anchor {
line-height: 1;
}
.markdown h3 {
.markdown:not(code) h3 {
font-size: 1.5em;
line-height: 1.43;
}
.markdown h3 .anchor {
.markdown:not(code) h3 .anchor {
line-height: 1.2;
}
.markdown h4 {
.markdown:not(code) h4 {
font-size: 1.25em;
}
.markdown h4 .anchor {
.markdown:not(code) h4 .anchor {
line-height: 1.2;
}
.markdown h5 {
.markdown:not(code) h5 {
font-size: 1em;
}
.markdown h5 .anchor {
.markdown:not(code) h5 .anchor {
line-height: 1.1;
}
.markdown h6 {
.markdown:not(code) h6 {
font-size: 1em;
color: #777;
}
.markdown h6 .anchor {
.markdown:not(code) h6 .anchor {
line-height: 1.1;
}
.markdown p,
.markdown blockquote,
.markdown ul,
.markdown ol,
.markdown dl,
.markdown table,
.markdown pre {
.markdown:not(code) p,
.markdown:not(code) blockquote,
.markdown:not(code) ul,
.markdown:not(code) ol,
.markdown:not(code) dl,
.markdown:not(code) table,
.markdown:not(code) pre {
margin-top: 0;
margin-bottom: 16px;
}
.markdown blockquote {
.markdown:not(code) blockquote {
margin-left: 0;
}
.markdown hr {
.markdown:not(code) hr {
height: 4px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
}
.markdown ul,
.markdown ol {
.markdown:not(code) ul,
.markdown:not(code) ol {
padding-left: 2em;
}
.markdown ul.no-list,
.markdown ol.no-list {
.markdown:not(code) ul.no-list,
.markdown:not(code) ol.no-list {
padding: 0;
list-style-type: none;
}
.markdown ul ul,
.markdown ul ol,
.markdown ol ol,
.markdown ol ul {
.markdown:not(code) ul ul,
.markdown:not(code) ul ol,
.markdown:not(code) ol ol,
.markdown:not(code) ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown ol ol,
.markdown ul ol {
.markdown:not(code) ol ol,
.markdown:not(code) ul ol {
list-style-type: lower-roman;
}
.markdown li > p {
.markdown:not(code) li > p {
margin-top: 16px;
}
.markdown dl {
.markdown:not(code) dl {
padding: 0;
}
.markdown dl dt {
.markdown:not(code) dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: bold;
}
.markdown dl dd {
.markdown:not(code) dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.markdown blockquote {
.markdown:not(code) blockquote {
padding: 0 15px;
color: #777;
border-left: 4px solid #ddd;
}
.markdown blockquote > :first-child {
.markdown:not(code) blockquote > :first-child {
margin-top: 0;
}
.markdown blockquote > :last-child {
.markdown:not(code) blockquote > :last-child {
margin-bottom: 0;
}
.markdown table {
.markdown:not(code) table {
display: block;
width: 100%;
overflow: auto;
word-break: normal;
word-break: keep-all;
}
.markdown table th {
.markdown:not(code) table th {
font-weight: bold;
}
.markdown table th,
.markdown table td {
.markdown:not(code) table th,
.markdown:not(code) table td {
padding: 6px 13px !important;
border: 1px solid #ddd !important;
}
.markdown table tr {
.markdown:not(code) table tr {
background-color: #fff;
border-top: 1px solid #ccc;
}
.markdown table tr:nth-child(2n) {
.markdown:not(code) table tr:nth-child(2n) {
background-color: #f8f8f8;
}
.markdown img {
.markdown:not(code) img {
max-width: 100%;
box-sizing: border-box;
}
.markdown .emoji {
.markdown:not(code) .emoji {
max-width: none;
}
.markdown span.frame {
.markdown:not(code) span.frame {
display: block;
overflow: hidden;
}
.markdown span.frame > span {
.markdown:not(code) span.frame > span {
display: block;
float: left;
width: auto;
@@ -646,69 +653,69 @@ footer .container .links > *:first-child {
overflow: hidden;
border: 1px solid #ddd;
}
.markdown span.frame span img {
.markdown:not(code) span.frame span img {
display: block;
float: left;
}
.markdown span.frame span span {
.markdown:not(code) span.frame span span {
display: block;
padding: 5px 0 0;
clear: both;
color: #333;
}
.markdown span.align-center {
.markdown:not(code) span.align-center {
display: block;
overflow: hidden;
clear: both;
}
.markdown span.align-center > span {
.markdown:not(code) span.align-center > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: center;
}
.markdown span.align-center span img {
.markdown:not(code) span.align-center span img {
margin: 0 auto;
text-align: center;
}
.markdown span.align-right {
.markdown:not(code) span.align-right {
display: block;
overflow: hidden;
clear: both;
}
.markdown span.align-right > span {
.markdown:not(code) span.align-right > span {
display: block;
margin: 13px 0 0;
overflow: hidden;
text-align: right;
}
.markdown span.align-right span img {
.markdown:not(code) span.align-right span img {
margin: 0;
text-align: right;
}
.markdown span.float-left {
.markdown:not(code) span.float-left {
display: block;
float: left;
margin-right: 13px;
overflow: hidden;
}
.markdown span.float-left span {
.markdown:not(code) span.float-left span {
margin: 13px 0 0;
}
.markdown span.float-right {
.markdown:not(code) span.float-right {
display: block;
float: right;
margin-left: 13px;
overflow: hidden;
}
.markdown span.float-right > span {
.markdown:not(code) span.float-right > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: right;
}
.markdown code,
.markdown tt {
.markdown:not(code) code,
.markdown:not(code) tt {
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
@@ -717,21 +724,21 @@ footer .container .links > *:first-child {
background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px;
}
.markdown code:before,
.markdown code:after,
.markdown tt:before,
.markdown tt:after {
.markdown:not(code) code:before,
.markdown:not(code) code:after,
.markdown:not(code) tt:before,
.markdown:not(code) tt:after {
letter-spacing: -0.2em;
content: "\00a0";
}
.markdown code br,
.markdown tt br {
.markdown:not(code) code br,
.markdown:not(code) tt br {
display: none;
}
.markdown del code {
.markdown:not(code) del code {
text-decoration: inherit;
}
.markdown pre > code {
.markdown:not(code) pre > code {
padding: 0;
margin: 0;
font-size: 100%;
@@ -740,11 +747,11 @@ footer .container .links > *:first-child {
background: transparent;
border: 0;
}
.markdown .highlight {
.markdown:not(code) .highlight {
margin-bottom: 16px;
}
.markdown .highlight pre,
.markdown pre {
.markdown:not(code) .highlight pre,
.markdown:not(code) pre {
padding: 16px;
overflow: auto;
font-size: 85%;
@@ -752,15 +759,15 @@ footer .container .links > *:first-child {
background-color: #f7f7f7;
border-radius: 3px;
}
.markdown .highlight pre {
.markdown:not(code) .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.markdown pre {
.markdown:not(code) pre {
word-wrap: normal;
}
.markdown pre code,
.markdown pre tt {
.markdown:not(code) pre code,
.markdown:not(code) pre tt {
display: inline;
max-width: initial;
padding: 0;
@@ -771,13 +778,13 @@ footer .container .links > *:first-child {
background-color: transparent;
border: 0;
}
.markdown pre code:before,
.markdown pre code:after,
.markdown pre tt:before,
.markdown pre tt:after {
.markdown:not(code) pre code:before,
.markdown:not(code) pre code:after,
.markdown:not(code) pre tt:before,
.markdown:not(code) pre tt:after {
content: normal;
}
.markdown kbd {
.markdown:not(code) kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
@@ -790,11 +797,11 @@ footer .container .links > *:first-child {
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbb;
}
.markdown input[type="checkbox"] {
.markdown:not(code) input[type="checkbox"] {
vertical-align: middle !important;
}
.markdown .csv-data td,
.markdown .csv-data th {
.markdown:not(code) .csv-data td,
.markdown:not(code) .csv-data th {
padding: 5px;
overflow: hidden;
font-size: 12px;
@@ -802,16 +809,16 @@ footer .container .links > *:first-child {
text-align: left;
white-space: nowrap;
}
.markdown .csv-data .blob-num {
.markdown:not(code) .csv-data .blob-num {
padding: 10px 8px 9px;
text-align: right;
background: #fff;
border: 0;
}
.markdown .csv-data tr {
.markdown:not(code) .csv-data tr {
border-top: 0;
}
.markdown .csv-data th {
.markdown:not(code) .csv-data th {
font-weight: bold;
background: #f8f8f8;
border-top: 0;
@@ -1133,6 +1140,7 @@ footer .container .links > *:first-child {
border-bottom: none;
}
.repository .filter.menu .label.color {
border-radius: 3px;
margin-left: 15px;
padding: 0 8px;
}
@@ -1460,8 +1468,33 @@ footer .container .links > *:first-child {
.repository.view.issue .comment-list .comment .content > .bottom.segment {
background: #f3f4f5;
}
.repository.view.issue .comment-list .comment .content > .bottom.segment .ui.images::after {
clear: both;
content: ' ';
display: block;
}
.repository.view.issue .comment-list .comment .content > .bottom.segment a {
display: block;
float: left;
margin: 5px;
padding: 5px;
height: 150px;
border: solid 1px #eee;
border-radius: 3px;
max-width: 150px;
background-color: #fff;
}
.repository.view.issue .comment-list .comment .content > .bottom.segment a:before {
content: ' ';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.repository.view.issue .comment-list .comment .content > .bottom.segment .ui.image {
max-height: 150px;
max-height: 100%;
width: auto;
margin: 0;
vertical-align: middle;
}
.repository.view.issue .comment-list .comment .ui.form .field:first-child {
clear: none;
@@ -1576,6 +1609,9 @@ footer .container .links > *:first-child {
.repository .label.list .item a.open-issues {
margin-right: 30px;
}
.repository .label.list .item .ui.label {
font-size: 1em;
}
.repository .milestone.list {
list-style: none;
padding-top: 15px;
@@ -1956,10 +1992,11 @@ footer .container .links > *:first-child {
.repository.settings.collaboration .collaborator.list {
padding: 0;
}
.repository.settings.collaboration .collaborator.list .item {
padding: 10px 20px;
.repository.settings.collaboration .collaborator.list > .item {
margin: 0;
line-height: 2em;
}
.repository.settings.collaboration .collaborator.list .item:not(:last-child) {
.repository.settings.collaboration .collaborator.list > .item:not(:last-child) {
border-bottom: 1px solid #DDD;
}
.repository.settings.collaboration #repo-collab-form #search-user-box .results {
@@ -2340,6 +2377,9 @@ footer .container .links > *:first-child {
.user.settings .email.list .item:not(:first-child) .button {
margin-top: -10px;
}
.user.profile .ui.card #profile-avatar {
height: 290px;
}
.user.profile .ui.card .username {
display: block;
}
@@ -2551,10 +2591,17 @@ footer .container .links > *:first-child {
text-overflow: ellipsis;
white-space: nowrap;
}
.admin.config #test-mail-btn {
margin-left: 5px;
}
.explore {
padding-top: 15px;
padding-bottom: 80px;
}
.explore .navbar .octicon {
width: 16px;
text-align: center;
}
.ui.repository.list .item {
padding-bottom: 25px;
}
@@ -2581,3 +2628,26 @@ footer .container .links > *:first-child {
font-size: 12px;
color: #808080;
}
.ui.user.list .item {
padding-bottom: 25px;
}
.ui.user.list .item:not(:first-child) {
border-top: 1px solid #eee;
padding-top: 25px;
}
.ui.user.list .item .ui.avatar.image {
width: 40px;
height: 40px;
}
.ui.user.list .item .description {
margin-top: 5px;
}
.ui.user.list .item .description .octicon:not(:first-child) {
margin-left: 5px;
}
.ui.user.list .item .description a {
color: #333;
}
.ui.user.list .item .description a:hover {
text-decoration: underline;
}

File diff suppressed because one or more lines are too long

View File

@@ -18,7 +18,7 @@ function initCommentPreviewTab($form) {
var $preview_tab = $form.find('.tab.segment[data-tab="' + $tab_menu.data('preview') + '"]');
$preview_tab.html(data);
emojify.run($preview_tab[0]);
$('pre code', $preview_tab[0]).each(function(i, block) {
$('pre code', $preview_tab[0]).each(function (i, block) {
hljs.highlightBlock(block);
});
}
@@ -322,8 +322,7 @@ function initRepository() {
};
$('#edit-title').click(editTitleToggle);
$('#cancel-edit-title').click(editTitleToggle);
$('#save-edit-title').click(editTitleToggle).
click(function () {
$('#save-edit-title').click(editTitleToggle).click(function () {
if ($edit_input.val().length == 0 ||
$edit_input.val() == $issue_title.text()) {
$edit_input.val($issue_title.text());
@@ -385,7 +384,7 @@ function initRepository() {
} else {
$render_content.html(data.content);
emojify.run($render_content[0]);
$('pre code', $render_content[0]).each(function(i, block) {
$('pre code', $render_content[0]).each(function (i, block) {
hljs.highlightBlock(block);
});
}
@@ -459,6 +458,20 @@ function initRepository() {
}
}
function initRepositoryCollaboration(){
console.log('initRepositoryCollaboration');
// Change collaborator access mode
$('.access-mode.menu .item').click(function(){
var $menu = $(this).parent();
$.post($menu.data('url'), {
"_csrf": csrf,
"uid": $menu.data('uid'),
"mode": $(this).data('value')
})
});
}
function initWiki() {
if ($('.repository.wiki').length == 0) {
return;
@@ -521,10 +534,8 @@ function initOrganization() {
}
}
function initUser() {
if ($('.user').length == 0) {
return;
}
function initUserSettings() {
console.log('initUserSettings');
// Options
if ($('.user.settings.profile').length > 0) {
@@ -796,10 +807,7 @@ $(document).ready(function () {
// Show exact time
$('.time-since').each(function () {
$(this).addClass('poping up').
attr('data-content', $(this).attr('title')).
attr('data-variation', 'inverted tiny').
attr('title', '');
$(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', '');
});
// Semantic UI modules.
@@ -878,7 +886,10 @@ $(document).ready(function () {
img_dir: suburl + '/img/emoji',
ignore_emoticons: true
});
emojify.run();
var hasEmoji = document.getElementsByClassName('has-emoji');
for (var i = 0; i < hasEmoji.length; i++) {
emojify.run(hasEmoji[i]);
}
// Clipboard JS
var clipboard = new Clipboard('.clipboard');
@@ -925,6 +936,14 @@ $(document).ready(function () {
$('.show-modal.button').click(function () {
$($(this).data('modal')).modal('show');
});
$('.delete-post.button').click(function(){
var $this = $(this);
$.post($this.data('request-url'),{
"_csrf": csrf
}).done(function(){
window.location.href = $this.data('done-url');
});
});
// Set anchor.
$('.markdown').each(function () {
@@ -950,15 +969,26 @@ $(document).ready(function () {
searchUsers();
searchRepositories();
initCommentForm();
initInstall();
initRepository();
initWiki();
initOrganization();
initUser();
initWebhook();
initAdmin();
var routes = {
'div.user.settings': initUserSettings,
'div.repository.settings.collaboration': initRepositoryCollaboration
};
var selector;
for (selector in routes) {
if ($(selector).length > 0) {
routes[selector]();
break;
}
}
});
$(window).load(function () {
@@ -1050,11 +1080,12 @@ $(window).load(function () {
case 'ssh':
if ($('#repo-clone-ssh').click().length === 0) {
$('#repo-clone-https').click();
};
}
;
break;
default:
$('#repo-clone-https').click();
break;
}
}
});
});

File diff suppressed because one or more lines are too long

7
public/js/libs/clipboard-1.5.9.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -44,7 +44,7 @@
padding: 20px;
margin: 0;
dd{
dd {
margin-left: 240px;
}
dt {
@@ -57,4 +57,10 @@
white-space: nowrap;
}
}
&.config {
#test-mail-btn {
margin-left: 5px;
}
}
}

View File

@@ -1,7 +1,7 @@
@footer-margin: 40px;
body {
font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif,'微软雅黑';
font-family: "Helvetica Neue", "Meiryo Ui", "Microsoft YaHei", Arial, Helvetica, sans-serif !important;
background-color: #fff;
overflow-y: scroll;
}
@@ -109,6 +109,12 @@ pre, code {
}
}
&.form {
.ui.button {
font-weight: normal;
}
}
.text {
&.red {
color: #d95c5c !important;
@@ -260,6 +266,11 @@ pre, code {
margin-right: 4px;
}
}
&.inline.delete-button {
padding: 8px 15px;
font-weight: normal;
}
}
.overflow.menu {

View File

@@ -1,6 +1,13 @@
.explore {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
.navbar {
.octicon {
width: 16px;
text-align: center;
}
}
}
.ui.repository.list {
@@ -35,3 +42,34 @@
}
}
}
.ui.user.list {
.item {
padding-bottom: 25px;
&:not(:first-child) {
border-top: 1px solid #eee;
padding-top: 25px;
}
.ui.avatar.image {
width: 40px;
height: 40px;
}
.description {
margin-top: 5px;
.octicon:not(:first-child) {
margin-left: 5px;
}
a {
color: #333;
&:hover {
text-decoration: underline;
}
}
}
}
}

View File

@@ -1,4 +1,4 @@
.markdown {
.markdown:not(code) {
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px;

View File

@@ -80,6 +80,7 @@
}
.filter.menu {
.label.color {
border-radius: 3px;
margin-left: 15px;
padding: 0 8px;
}
@@ -413,8 +414,33 @@
}
> .bottom.segment {
background: #f3f4f5;
.ui.images::after {
clear: both;
content: ' ';
display: block;
}
a {
display: block;
float: left;
margin: 5px;
padding: 5px;
height: 150px;
border: solid 1px #eee;
border-radius: 3px;
max-width: 150px;
background-color: #fff;
&:before {
content:' ';
display: inline-block;
height: 100%;
vertical-align: middle;
}
}
.ui.image {
max-height: 150px;
max-height: 100%;
width: auto;
margin: 0;
vertical-align: middle;
}
}
}
@@ -528,6 +554,9 @@
margin-right: 30px;
}
}
.ui.label {
font-size: 1em;
}
}
}
@@ -998,8 +1027,9 @@
.collaborator.list {
padding: 0;
.item {
padding: 10px 20px;
>.item {
margin: 0;
line-height: 2em;
&:not(:last-child) {
border-bottom: 1px solid #DDD;

View File

@@ -23,6 +23,9 @@
&.profile {
.ui.card {
#profile-avatar {
height: 290px;
}
.username {
display: block;
}

File diff suppressed because one or more lines are too long

View File

@@ -11,11 +11,18 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
background: #F0F0F0;
}
/* Base color: saturation 0; */
.hljs,
.hljs-subst {
color: #444;
}
.hljs-comment {
color: #888888;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
@@ -25,23 +32,8 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
font-weight: bold;
}
.hljs-built_in,
.hljs-literal,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #1F811F;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}
/* User color: hue: 0 */
.hljs-type,
.hljs-string,
@@ -60,14 +52,44 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
font-weight: bold;
}
.hljs-comment {
color: #888888;
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}
.hljs-meta {
color: #2B6EA1;
/* Language color: hue: 90; */
.hljs-literal {
color: #78A960;
}
.hljs-built_in,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #397300;
}
/* Meta color: hue: 200 */
.hljs-meta {
color: #1f7199;
}
.hljs-meta-string {
color: #4d99bf;
}
/* Misc effects */
.hljs-emphasis {
font-style: italic;
}

File diff suppressed because one or more lines are too long

View File

@@ -15,8 +15,9 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/cron"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/mailer"
"github.com/gogits/gogs/modules/process"
"github.com/gogits/gogs/modules/setting"
)
@@ -123,7 +124,7 @@ const (
REINIT_MISSING_REPOSITORY
)
func Dashboard(ctx *middleware.Context) {
func Dashboard(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.dashboard")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminDashboard"] = true
@@ -174,7 +175,19 @@ func Dashboard(ctx *middleware.Context) {
ctx.HTML(200, DASHBOARD)
}
func Config(ctx *middleware.Context) {
func SendTestMail(ctx *context.Context) {
email := ctx.Query("email")
// Send a test email to the user's email address and redirect back to Config
if err := mailer.SendTestMail(email); err != nil {
ctx.Flash.Error(ctx.Tr("admin.config.test_mail_failed", email, err))
} else {
ctx.Flash.Info(ctx.Tr("admin.config.test_mail_sent", email))
}
ctx.Redirect(setting.AppSubUrl + "/admin/config")
}
func Config(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.config")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminConfig"] = true
@@ -191,6 +204,8 @@ func Config(ctx *middleware.Context) {
ctx.Data["ScriptType"] = setting.ScriptType
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
ctx.Data["SSH"] = setting.SSH
ctx.Data["Service"] = setting.Service
ctx.Data["DbCfg"] = models.DbCfg
ctx.Data["Webhook"] = setting.Webhook
@@ -207,7 +222,6 @@ func Config(ctx *middleware.Context) {
ctx.Data["SessionConfig"] = setting.SessionConfig
ctx.Data["PictureService"] = setting.PictureService
ctx.Data["DisableGravatar"] = setting.DisableGravatar
type logger struct {
@@ -222,7 +236,7 @@ func Config(ctx *middleware.Context) {
ctx.HTML(200, CONFIG)
}
func Monitor(ctx *middleware.Context) {
func Monitor(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.monitor")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminMonitor"] = true

View File

@@ -5,6 +5,8 @@
package admin
import (
"fmt"
"github.com/Unknwon/com"
"github.com/go-xorm/core"
@@ -12,8 +14,8 @@ import (
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/auth/ldap"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
@@ -23,7 +25,7 @@ const (
AUTH_EDIT base.TplName = "admin/auth/edit"
)
func Authentications(ctx *middleware.Context) {
func Authentications(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.authentication")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminAuthentications"] = true
@@ -51,7 +53,7 @@ var authSources = []AuthSource{
{models.LoginNames[models.LOGIN_PAM], models.LOGIN_PAM},
}
func NewAuthSource(ctx *middleware.Context) {
func NewAuthSource(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.auths.new")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminAuthentications"] = true
@@ -100,7 +102,7 @@ func parseSMTPConfig(form auth.AuthenticationForm) *models.SMTPConfig {
}
}
func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
ctx.Data["Title"] = ctx.Tr("admin.auths.new")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminAuthentications"] = true
@@ -145,7 +147,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
ctx.Redirect(setting.AppSubUrl + "/admin/auths")
}
func EditAuthSource(ctx *middleware.Context) {
func EditAuthSource(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.auths.edit")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminAuthentications"] = true
@@ -161,7 +163,7 @@ func EditAuthSource(ctx *middleware.Context) {
ctx.HTML(200, AUTH_EDIT)
}
func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
ctx.Data["Title"] = ctx.Tr("admin.auths.edit")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminAuthentications"] = true
@@ -208,7 +210,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + com.ToStr(form.ID))
}
func DeleteAuthSource(ctx *middleware.Context) {
func DeleteAuthSource(ctx *context.Context) {
source, err := models.GetLoginSourceByID(ctx.ParamsInt64(":authid"))
if err != nil {
ctx.Handle(500, "GetLoginSourceByID", err)
@@ -218,11 +220,13 @@ func DeleteAuthSource(ctx *middleware.Context) {
if err = models.DeleteSource(source); err != nil {
switch err {
case models.ErrAuthenticationUserUsed:
ctx.Flash.Error("form.still_own_user")
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"))
ctx.Flash.Error(ctx.Tr("admin.auths.still_in_used"))
default:
ctx.Handle(500, "DeleteSource", err)
ctx.Flash.Error(fmt.Sprintf("DeleteSource: %v", err))
}
ctx.JSON(200, map[string]interface{}{
"redirect": setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"),
})
return
}
log.Trace("Authentication deleted by admin(%s): %d", ctx.User.Name, source.ID)

View File

@@ -10,8 +10,8 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
@@ -19,7 +19,7 @@ const (
NOTICES base.TplName = "admin/notice"
)
func Notices(ctx *middleware.Context) {
func Notices(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.notices")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminNotices"] = true
@@ -42,7 +42,7 @@ func Notices(ctx *middleware.Context) {
ctx.HTML(200, NOTICES)
}
func DeleteNotices(ctx *middleware.Context) {
func DeleteNotices(ctx *context.Context) {
strs := ctx.QueryStrings("ids[]")
ids := make([]int64, 0, len(strs))
for i := range strs {
@@ -61,7 +61,7 @@ func DeleteNotices(ctx *middleware.Context) {
}
}
func EmptyNotices(ctx *middleware.Context) {
func EmptyNotices(ctx *context.Context) {
if err := models.DeleteNotices(0, 0); err != nil {
ctx.Handle(500, "DeleteNotices", err)
return

View File

@@ -5,39 +5,28 @@
package admin
import (
"github.com/Unknwon/paginater"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/routers"
)
const (
ORGS base.TplName = "admin/org/list"
)
func Organizations(ctx *middleware.Context) {
func Organizations(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.organizations")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminOrganizations"] = true
total := models.CountOrganizations()
page := ctx.QueryInt("page")
if page <= 1 {
page = 1
}
ctx.Data["Page"] = paginater.New(int(total), setting.AdminOrgPagingNum, page, 5)
orgs, err := models.Organizations(page, setting.AdminOrgPagingNum)
if err != nil {
ctx.Handle(500, "Organizations", err)
return
}
ctx.Data["Orgs"] = orgs
ctx.Data["Total"] = total
ctx.HTML(200, ORGS)
routers.RenderUserSearch(ctx, &routers.UserSearchOptions{
Type: models.USER_TYPE_ORGANIZATION,
Counter: models.CountOrganizations,
Ranger: models.Organizations,
PageSize: setting.AdminOrgPagingNum,
OrderBy: "id ASC",
TplName: ORGS,
})
}

View File

@@ -5,43 +5,34 @@
package admin
import (
"github.com/Unknwon/paginater"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/routers"
)
const (
REPOS base.TplName = "admin/repo/list"
)
func Repos(ctx *middleware.Context) {
func Repos(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.repositories")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminRepositories"] = true
total := models.CountRepositories()
page := ctx.QueryInt("page")
if page <= 1 {
page = 1
}
ctx.Data["Page"] = paginater.New(int(total), setting.AdminRepoPagingNum, page, 5)
repos, err := models.RepositoriesWithUsers(page, setting.AdminRepoPagingNum)
if err != nil {
ctx.Handle(500, "RepositoriesWithUsers", err)
return
}
ctx.Data["Repos"] = repos
ctx.Data["Total"] = total
ctx.HTML(200, REPOS)
routers.RenderRepoSearch(ctx, &routers.RepoSearchOptions{
Counter: models.CountRepositories,
Ranger: models.Repositories,
Private: true,
PageSize: setting.AdminRepoPagingNum,
OrderBy: "id ASC",
TplName: REPOS,
})
}
func DeleteRepo(ctx *middleware.Context) {
func DeleteRepo(ctx *context.Context) {
repo, err := models.GetRepositoryByID(ctx.QueryInt64("id"))
if err != nil {
ctx.Handle(500, "GetRepositoryByID", err)

View File

@@ -8,15 +8,15 @@ import (
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/paginater"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/mailer"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/routers"
)
const (
@@ -25,30 +25,22 @@ const (
USER_EDIT base.TplName = "admin/user/edit"
)
func Users(ctx *middleware.Context) {
func Users(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.users")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
total := models.CountUsers()
page := ctx.QueryInt("page")
if page <= 1 {
page = 1
}
ctx.Data["Page"] = paginater.New(int(total), setting.AdminUserPagingNum, page, 5)
users, err := models.Users(page, setting.AdminUserPagingNum)
if err != nil {
ctx.Handle(500, "Users", err)
return
}
ctx.Data["Users"] = users
ctx.Data["Total"] = total
ctx.HTML(200, USERS)
routers.RenderUserSearch(ctx, &routers.UserSearchOptions{
Type: models.USER_TYPE_INDIVIDUAL,
Counter: models.CountUsers,
Ranger: models.Users,
PageSize: setting.AdminUserPagingNum,
OrderBy: "id ASC",
TplName: USERS,
})
}
func NewUser(ctx *middleware.Context) {
func NewUser(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
@@ -66,7 +58,7 @@ func NewUser(ctx *middleware.Context) {
ctx.HTML(200, USER_NEW)
}
func NewUserPost(ctx *middleware.Context, form auth.AdminCrateUserForm) {
func NewUserPost(ctx *context.Context, form auth.AdminCrateUserForm) {
ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
@@ -132,7 +124,7 @@ func NewUserPost(ctx *middleware.Context, form auth.AdminCrateUserForm) {
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + com.ToStr(u.Id))
}
func prepareUserInfo(ctx *middleware.Context) *models.User {
func prepareUserInfo(ctx *context.Context) *models.User {
u, err := models.GetUserByID(ctx.ParamsInt64(":userid"))
if err != nil {
ctx.Handle(500, "GetUserByID", err)
@@ -160,7 +152,7 @@ func prepareUserInfo(ctx *middleware.Context) *models.User {
return u
}
func EditUser(ctx *middleware.Context) {
func EditUser(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
@@ -173,7 +165,7 @@ func EditUser(ctx *middleware.Context) {
ctx.HTML(200, USER_EDIT)
}
func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
@@ -231,7 +223,7 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
}
func DeleteUser(ctx *middleware.Context) {
func DeleteUser(ctx *context.Context) {
u, err := models.GetUserByID(ctx.ParamsInt64(":userid"))
if err != nil {
ctx.Handle(500, "GetUserByID", err)

View File

@@ -8,13 +8,13 @@ import (
api "github.com/gogits/go-gogs-client"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/routers/api/v1/convert"
"github.com/gogits/gogs/routers/api/v1/user"
)
// https://github.com/gogits/go-gogs-client/wiki/Administration-Organizations#create-a-new-organization
func CreateOrg(ctx *middleware.Context, form api.CreateOrgOption) {
func CreateOrg(ctx *context.APIContext, form api.CreateOrgOption) {
u := user.GetUserByParams(ctx)
if ctx.Written() {
return
@@ -27,18 +27,18 @@ func CreateOrg(ctx *middleware.Context, form api.CreateOrgOption) {
Website: form.Website,
Location: form.Location,
IsActive: true,
Type: models.ORGANIZATION,
Type: models.USER_TYPE_ORGANIZATION,
}
if err := models.CreateOrganization(org, u); err != nil {
if models.IsErrUserAlreadyExist(err) ||
models.IsErrNameReserved(err) ||
models.IsErrNamePatternNotAllowed(err) {
ctx.APIError(422, "CreateOrganization", err)
ctx.Error(422, "CreateOrganization", err)
} else {
ctx.APIError(500, "CreateOrganization", err)
ctx.Error(500, "CreateOrganization", err)
}
return
}
ctx.JSON(201, convert.ToApiOrganization(org))
ctx.JSON(201, convert.ToOrganization(org))
}

View File

@@ -7,13 +7,13 @@ package admin
import (
api "github.com/gogits/go-gogs-client"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/context"
"github.com/gogits/gogs/routers/api/v1/repo"
"github.com/gogits/gogs/routers/api/v1/user"
)
// https://github.com/gogits/go-gogs-client/wiki/Administration-Repositories#create-a-new-repository
func CreateRepo(ctx *middleware.Context, form api.CreateRepoOption) {
func CreateRepo(ctx *context.APIContext, form api.CreateRepoOption) {
owner := user.GetUserByParams(ctx)
if ctx.Written() {
return

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